Rebooting Bespin: Embedded and SproutCore

This post is a collection of random thoughts about the Bespin Reboot project so far.

The past summer, the Bespin team at Mozilla (Ben, Dion, Joe and me) started thinking that the time had come to make some significant changes to the Bespin project code. These changes would make it easier for others to use and contribute to Bespin and also make it easier for Bespin core contributors to add new features. We did a collection of releases during the summer and then slammed on the brakes for what we’ve called the “Reboot“.

The Reboot involves a serious refactoring of the code, plus changes in priorities and processes. We started fresh with a new source code repository (two, actually, since the Python server has been pushed into a separate repo). Then, we poured the code from the old repository into a new structure of CommonJS modules. We changed our underlying GUI framework to use SproutCore, so that we could spend less time thinking about getting things on the screen and more time with features that help people write their code.

Once you get into the groove of doing releases and adding good stuff for your users, it’s really painful to stop doing releases. I’ve been itching to ship since the beginning of October when we shifted full-time to the Reboot repository. Our goal all along has been to get the editor running again as soon as possible. Our initial thought was “get it running on a mix of old infrastructure and new and evolve from there over time”. That was a nice thought, but it didn’t work out very well that way.

SproutCore’s event model is based on adding a small number of global event listeners and delegating events to the proper components. Bespin had been using Dojo with the far more common model of attaching events to DOM nodes directly. In order to take advantage of what SproutCore has to offer, we very quickly ended up on the slippery slope of doing other refactorings to the editor, which is something we had not initially planned to do.

I’m thankful that we decided to go ahead with those changes, though! For example, the editor’s event handlers all had code in them to figure out “is the cursor over the scrollbars?” because the editor itself was responsible for painting the scrollbars! The editor had one canvas and it managed everything on there itself. We had discussed the possibility of using the Thunderhead project to manage the different pieces that appear in the editor canvas, but we’re a small team and don’t have time to work on a GUI toolkit in addition to our other ambitions for Bespin.

And so it came to pass that we started down the road of refactoring the editor into separate SproutCore components. Patrick Walton joined Mozilla last month and immediately dove into the task of breaking the scrollbars out into separate components. In the process, Bespin’s editor is now a scrollable SproutCore component, so you could even use the standard scrollbars with the editor. Bespin’s scrollbars are a bit tricky, though… rather than living just outside of the scrolled area, they are actually drawn on top of the scrolled area. We also found that the gutter of the editor really should be a separate component (or maybe even more than one), which is why the horizontal scrollbar is not positioned properly right now. Patrick is actively working on fixing that.

Meanwhile, Joe has been hard at work fixing lots of other things: random uses of Dojo, how our singleton components are managed (since we ultimately want to be able to support multiple editors on a single page), copy and paste issues, etc. I’ve spent a bunch of time working through building, module loading and documentation issues.

From where we sit now, the code is shaping up quite nicely. Soon enough, if you have a SproutCore app, you’ll be able to just drop an editor right into your app. As of today, anyone with a website can grab a copy of Bespin and include the editor component very simply in their pages. We figure that we’ve got another month of work to do before we’re ready to update bespin.mozilla.com. We have a whole bunch of features to port over from the old code and we need to make good on another big part of the Reboot promise: opening Bespin up for plugins. It’s been hard even for Bespin core people to contribute because of the state of the code, and I’m looking forward to getting past that hurdle soon. Before I know it, we’ll be back to shipping new features regularly (and quicker than before!) at bespin.mozilla.com. I can’t wait!

5 thoughts on “Rebooting Bespin: Embedded and SproutCore”

  1. Kevin, I’m interested in knowing more about what prompted the switch from Dojo to SproutCore. Were there feature gaps? Particular snags or frustrations?

  2. Hi Sam,

    Regarding Dojo vs. SproutCore, it all comes back at looking at what we’re doing… Bespin is not at all a “normal webapp”, in that we’re working with DOM nodes and HTML interface elements, but it’s not in the context of a “page” sort of thing at all. Many things that matter a great deal to people putting together Ajax-enhanced websites matter not at all to us.

    We weren’t really using much of Dojo: we used the module system and the basic DOM stuff (all just dojo base functionality). For the Reboot, we decided that we wanted to use CommonJS modules, with an ultimate goal of having plugins that offer both client-side and server-side functionality. And, the DOM stuff frankly doesn’t matter a whole lot. Dojo does just great there…

    What we really wanted was a consistent, performant GUI toolkit that would take away a lot of bookkeeping work and let us focus on the functionality. More than one of us working on Bespin has a high opinion of certain Cocoa features at doing just that. SproutCore gives us those sorts of features in a well-constructed GUI toolkit.

    So, starting from the notion of wanting to create the entire UI via JavaScript code, I prefer the way SproutCore lets us manage the UI to the way that Dijit does it. (Bindings and things of that nature do a great job at eliminating code for connecting up the various bits of UI.)

Comments are closed.