Status: Jetpack, async bookmark folders

Started a Firefox project page to track Jetpack and its integration into Firefox. Atul typed up a reboot glossary. Anyone who talks to other human beings about Jetpack going forward should read it. Preview:

Jetpack: Synonym for Cuddlefish. Currently, we prefer using the term “Cuddlefish” to disambiguate it from the Jetpack Prototype, which is a completely different animal.

Began a couple of API proposals for the reboot, context menus and simple persistent storage. Others on the Jetpack team have started proposals also. Met today to discuss and shape what we’ve got so far. Plan: Iterate on them together in the coming weeks.

Talked with Mano and Marco about async bookmark folders, new WIP patch. Mano is working on a new view-related bug that now blocks. Once his is done, should be fairly straightforward to finish.

Recently used tabs extension

Firefox’s tab strip is necessary, I think, but its usefulness degrades when you open lots of tabs. In those cases I usually tap the tabs menu, which sits quietly at the end of the strip. The menu works well with a moderate number of tabs, but I often open enough to actually force it to scroll. It’s annoying to have to frequently mouse to its bottom.

So I wrote an extension that sorts the tabs menu in most recently used (MRU) order. Like, if you select tab A, then B, and then C, the tabs menu will show C, B, and A, in that order. Tabs that you often use rise to the top, those that you don’t sink to the bottom. (Like how Ctrl- or Cmd-Tab works for applications in your OS. Dão implemented something similar for tabs in Firefox.)

Screenshot

After using it for a week, I’ve found that the new menu is nice when I forget what I’m doing and need a reminder: The top tabs tell me. It’s also nice when switching to a different task: I know its tabs aren’t at top. But I’m still occasionally surprised when I open the menu and see an ordering different from the tab strip’s. That happens mostly when all tabs are visible in the strip. And the use case I hypothesized would be best served by an MRU menu—selecting one tab when many aren’t visible—sometimes isn’t. The tabs related to a single task usually end up clumped together, so using the strip or key shortcuts is better.

I tried to be smart about performance. You don’t pay for MRU when you open or select tabs. You pay when you open the menu, and then it’s O(n log n), n = number of open tabs. (You were already paying O(n) for the standard, non-MRU menu.) It’s easy to imagine other approaches with different time-space trade-offs.

I’ve been working on Jetpack. Different people have different ideas of what Jetpack is supposed to be, but one of its early goals was to make extension development simpler than it is now. It took me an evening and 250 lines to write this. The menupopup is an XBL binding, so all I had to do was write a replacement and hook it up with a single CSS rule. A reminder that traditional extensions can be both powerful and simple to make, if only for a certain group of people.

No progress

No progress at all. Another week closer to being dead.

Status update, January 22, 2010: Async Places containers, Places in content, Jetpack

Async bookmark folders got its second review. Currently trying to convince Mano that my design is good, which it totally is.

Bookmarks and history in content was supposed to be easy, but there are wrinkles. A new WIP patch but not much forward movement. Think I’ll have to take a different approach.

Epic meetings with Atul and the Jetpack team. Is there a meeting instruction booklet? There are two distinct APIs we’re developing. Still working out the terminology, which is stunningly important, but one is Cuddlefish, and the other is Jetpack.

Cuddlefish is the Mozilla standard library. It wraps the Mozilla platform—or at least the parts that extensions commonly use—in XPCOMless APIs packaged as CommonJS modules. Cuddlefish is chrome-privileged and ignores security. You can write traditional extensions using Cuddlefish or use Cuddlefish in your traditional extensions. Cuddlefish will make it easy to write no-restart-needed extensions, which is an upcoming mechanism altogether independent of Cuddlefish and Jetpack. Anyone can write CommonJS modules, so if the standard library doesn’t expose a certain part of the platform, you can write a new module. You can keep that module to yourself, share it with others, or submit it to the standard library so everyone can benefit. There are other interesting aspects to Cuddlefish, but it’s not my intention to enumerate them all.

Jetpack securely exposes Cuddlefish and provides UI hooks. I’m not sure whether the Cuddlefish API is a subset of Jetpack’s. Maybe Jetpack’s API is fairly impotent, I don’t know. Atul has mentioned keeping Jetpack’s surface small, so that might be the case. One idea we discussed this week is making it dead simple for jetpacks to hook into the UI: They provide some UI bits, like an icon and title, and a callback. No statusbar, no toolbar, no sidebar, no UI power. In return they get ease of implementation and a spiffy presentation that fits in well with the rest of the browser and the user’s other jetpacks. If they need more power, they can write a UI-oriented Cuddlefish module, expose it securely, and use it. (More likely, they can find such a module that someone else has written.)

It’s possible to simultaneously dislike Jetpack and find Cuddlefish exciting. Jetpack might fail while Cuddlefish succeeds. I think that Cuddlefish, if it does succeed independently of Jetpack, will be really, really large, and that’s quite a daunting task. Atul, however, has described it as a sleek and svelte kernel.

Is it our immediate priority to build Cuddlefish broadly or only enough for Jetpack’s needs? I think we should start at Jetpack and build downward.

To that end, wrote a patch that adds byte streams to Cuddlefish, so it’s now possible to read and write files. Once it lands we can implement simple JSON-backed storage in Jetpack, if indeed we want to bring over that API from the prototype.

Status update: January 15, 2010

Offmainthreading the opening of bookmark folders awaits a second review. After that, superreview. After that, history and bookmark searches off the main thread, the patch for which is mostly written but may change depending on the upcoming reviews.

Bookmarks and history in content swerved off road and struck a mailbox. Our current architecture was not designed to show single bookmark and history items in isolation, outside of their hierarchy. Only recently do I realize this. We can design a new architecture, modify the current one, or build on top of it. That last option is simplest if simplest means least invasive and is what I’ve been working on. It’s a good thing that, although this new webby UI is not scheduled to arrive in full until Firefox humphfrahumph, we’re exploring it now. Alex made a mockup of what the first-pass implementation will look like.

Wrote some file-handling code for the Jetpack reboot. It won’t be used but helped me learn more about how the new platform works. Started a reboot FAQ with Atul and submitted a small patch. Would like to port the prototype’s simple JSON-backed storage to the reboot, and doing that will require writing some file-handling code. It’s cool, the reboot is heavily influenced by CommonJS, a specification for a cross-platform JavaScript standard library. As I understand it at this moment in time, the reboot’s platform—what Atul has named Cuddlefish—will be made up of various privileged modules that implement the CommonJS API. There may be modules for streams, module for XHRs, modules for sockets, just as there are such modules in an installation of Python or Ruby or Perl. On top of this Mozilla standard library sits the Jetpack API, and in between the two a security model. People have asked about a cross-browser extension platform ever since Atul and Aza started Jetpack. An interesting thing about using CommonJS is that Cuddlefish is born standardized. An interesting thing about the architecture as a whole is its modularity. Potentially you could use Cuddlefish to make traditional extensions while avoiding Jetpack altogether.

Status update: December 31, 2009

Landed Places protocol handler. Next: Finish patch for and land Places data should be visible in content. Despite the fact that Places UI work has slipped to 4.0, Dietrich wants a first-pass implementation of Places-in-content on trunk so people can play with it.

New bug Asynchronous API for opening nsNavHistoryFolderResultNodes and patches for it, the first of which Marco has reviewed. It moves opening bookmark folders off the main thread, sans batching. Started on the non-bookmark folder counterpart—history and searches and such—but progress there depends on the aforementioned bug. I am going to land async Places containers before the end of Q1 fer sher. No one will stop me. NO ONE. Am thinking it would be nice to get Clear Recent History completely off the main thread next; it wasn’t when I touched it, but Marco’s recent work on async history expiration might have covered most of it. I want to make you faster and more responsive, Firefox, and I will work the levers my fat tiny hands can grasp.

Various Jetpack things. Landed two bugs related to the in vivo API reference, API Reference broken in 0.7 (nice) and API Reference should link to MDC docs, and menu bug menu.remove() and menu.replace() don’t work with regular expressions. Worked on the documentation: Stubbed out missing docs to point to the appropriate JEPs, cleaned up the front page and subpages a little, wrote the simple storage doc complete with a full example people can install. A few Jetpack Gallery user-friendliness bugs I filed landed: Make page titles more friendly, since they become the names of jetpacks, Source code should be viewable without having to log in, and Share Jetpack popup obscures View Source Code link.

Status update: December 19, 2009

Spent most of the week on Jetpack. Landed support for letting jetpacks tailor their first-run experience. They can define some HTML or point to a URL that will be shown on their installation and register a callback to perform arbitrary work on installation. Wrote up docs for these also, here and here.

Finally a patch that should pass Marco’s review on bug 529597, Places protocol handler.

The more I work on making Places containers async, the dumber I feel. Been working on this how long? Whittling it down how much? Trying to move some sorting to SQL, but since it can’t all be moved there, it’s important that the sorting there is equivalent to the sorting we do in C++. Problem is, the C++ sorting has some conditionals that are hard to do in SQL. Marco suggested writing a SQLite function that does the same. That’s a possibility, but its performance characteristics are unknown. A solution I like better is to simply change the semantics of the sorts to something simpler that can be done in SQL without jumping through hoops.

A third possibility is to kick the can down the road. SQL sorting is only necessary for returning batches of results to consumers as they asynchronously load from the database. It is not necessary for simply moving off the main thread queries and their associated I/O—a Q1 goal. This approach is easier to implement, and I think it could be done on the way to batch loading. The difference to the user is this: With batch loading, the first results will load and display fairly quickly, and as new batches come in they’ll fill the view batch-by-batch. Without batch loading, you’ll be waiting for the entire result set to load, and when it does all results will be displayed at once.

Status update: December 11, 2009

Back to async Places containers, sorting in SQL this week, in between all-hands events. New patch for bug 530236, nsNavHistoryFolderResultNode sorting should be done entirely in SQL. Getting close. Next, do all sorting entirely in SQL. The problem, though, with breaking large problems into many smaller problems is that they are many.

Last weekend a patch for review on bug 529597, Places protocol handler. Marco commented, need to address with new patch.

Also last weekend a work-in-progress patch for bug 529605, Places data should be visible in content. It’s early still, but already you can browse around your bookmarks and history right there in the page. It’s neat. Pinched off a little helper to generate DOM called Cheeseburger. Predict it will make me internetrich.

Status update: December 4, 2009

Shifted gears this week to work specific to the new Places UI in Firefox 3.7.

Wrote a patch for a Places protocol handler. A protocol handler makes any Places object—a single bookmark folder, a tag, a bookmark or history search, a history range—browsable. Right now they’re stuck in the bookmarks organizer and sidebar. The patch is awaiting Places review and netwerk or security review after that.

Related is the work of writing the HTML, CSS, and JavaScript that renders these objects in the page. It’s part of a larger Firefox trend, if Alex and UX have their way, of moving user data out of separate windows and sidebars and into content: bookmarks, history, the home tab, new tab, the page media tab. As a consequence, a certain chunk of Firefox development is becoming web development.

I wrote a proof-of-concept patch for the entire package. When you browse to place:folder=1, you’ll get a list of your top-level bookmark folders. You can click around and browse your bookmarks right in the page.

Status update: November 20, 2009

Made some progress on async Places containers. After last week, decided to think small and focus on moving sorting of folder node children to SQL. Spun bug 530236, with a WIP patch, from bug 499985 to track this work.

Biggest snag so far is figuring out how to either do nsNavHistoryContainerResultNode::FillStats’s work inside the database, rather than C++, or avoid the work altogether. FillStats recursively calculates a couple of members of a node and its descendants, and these members are then used to subsequently sort the children, if the selected sort requires those members.

Also filed a couple of bugs for tracking work on 3.7’s new Places UI:

Wanted to work on the former this week but just didn’t get around to it.

And all the while I wonder, do people still use bookmarks in Firefox?