The Wall of Text on My Business Card

July 19th, 2009

At Mozilla we get the opportunity to design the back of our business card. As I’ve written about before, Mozilla is a unique hybrid organization with a mission that lots of people don’t know about. It’s often hard to communicate to others in passing, so I decided to put it on my business card:

I don’t really expect many people to read it, but at least it’s out there for anyone who wants to learn more. Mozilla gives us a “budget” of 250 cards to order, so I’ve only ordered 75 of these; I’ll come up with something more visual and fun for the other cards.

Fun with SpiderMonkey

July 18th, 2009

Over the past few weeks I’ve had the pleasure of working with Dion Almaer on a Browser Memory Tool Prototype. This has been a lot of fun for me; for one thing, I’ve always wanted to help developers diagnose the problem of “I’ve been running my web app/Firefox extension for 8 hours, why’s it taking up 800 megabytes of RAM?”. And I’ve also always wanted to have an excuse to learn about the internals of SpiderMonkey, Mozilla’s JavaScript engine, and play with its C API. So working on this tool has helped me kill two birds with one stone.

The architecture we decided to use for the memory tool was particularly fun to design and implement. Because much of Firefox itself is implemented in JavaScript, we need to freeze the whole application in order to profile its memory use. The problem with this, though, is that being barred from using JS to implement the memory profiler itself would be a bummer—especially considering that we didn’t know the problem domain terribly well and would therefore need the freedom to easily experiment to find the best solution.

Fortunately, it turns out that SpiderMonkey was designed to support multiple instances of what’s called a JavaScript Runtime. From the JSAPI User Guide:

A JSRuntime, or runtime, is the space in which the JavaScript variables, objects, scripts, and contexts used by your application are allocated. Every JSContext and every object in an application lives within a JSRuntime. They cannot travel to other runtimes or be shared across runtimes. Most applications only need one runtime.

All the JavaScript code in Firefox—whether it belongs to the Mozilla platform, an extension, or a web page—executes in the same runtime. We’ll call that runtime the “Firefox runtime”. The trick to implementing a memory profiler in JavaScript itself was just to “freeze” the Firefox runtime and create a new runtime, which we’ll call the “memory profiling runtime”, to peek into the Firefox runtime via a simple API. We also added a simple blocking socket object to the memory profiling runtime, which allows it to embed a web server that a separate process could connect to—in this case, the cool Memory Tool Ajax Application that Dion made.

Since Dion and I were really the only ones writing code for the memory profiling runtime, we haven’t actually documented the API yet. It’s pretty simple, though; every object in the Firefox runtime is referred to by a unique integer ID, and various functions can be used to get metadata about an object. For instance, getObjectInfo(id) returns a JSON-able data structure containing information about the object with the given ID, such as its prototype, its parent (i.e., its global scope), what other objects it points to, and so forth. Dion then used this API to write a memory profiler server.

One nice thing about the memory profiling runtime, though, is that it doesn’t have to embed a web server: it could just get some information about the heap and return it as a JSON object to the Firefox runtime, which could then do something useful with it. There’s lots of interesting things we’d like to eventually see—for instance, a visualization of the JS heap over time would be pretty cool.

Of course, we also ran into our own share of problems, many of which we’re still trying to resolve. They’re pretty technical in nature, but you’re welcome to read the write-up on our Memory Profiling Notes from July 2009 on the wiki.

Creating this tool wouldn’t have been possible without the excellent SpiderMonkey documentation on the Mozilla Developer Center or the friendly folks on #jsapi at irc.mozilla.org—particularly David Baron and Blake Kaplan. I’m definitely looking forward to tinkering more with the JSAPI in the future, and working with Dion and Ben to make developing for the Open Web a lot more fun.

Update: I’ve since documented the API for the memory profiling binary component and runtime.

Jetpack: Summer 2009 State of Security, Part 1

July 13th, 2009

Security is hard! It’s tough enough designing a platform that’s powerful, well-documented, and easy to use; but what about security? If we aren’t careful, adding a incorrectly tuned or naive security model negatively affects generativity and usability. Jetpack needs to balance all three.

The following is something I wrote at the beginning of June, but didn’t post until now because I’ve had my head in code for a bit too long. What follows is still accurate, except in cases where noted otherwise. In my next post, I’ll explain the research and tools we’ve created so far to solve the problem of security.

In order to understand Jetpack’s current security model, one has to first understand how Jetpack got to where it is.

Previous History

In May of 2009, I implemented the initial Jetpack prototype. This was originally intended to be securable in the sense that a Jetpack Feature (sometimes called “a Jetpack”) should be sandboxed within either a standard Web page or a Components.utils.Sandbox with a limited principal and be given only the objects that it needed to do what it wanted to accomplish.

However, this quickly met with difficulties due to either limitations in the Mozilla platform or limitations in my understanding of it. For instance, the simple use case of a single JS script communicating securely with two open Web pages via XPCNativeWrapper objects proved difficult. Here’s some code from the Unad demo included with the Jetpack prototype:

  $(widget).click(toggleState);

In this case, widget is the XPCNativeWrapped contentDocument property of an iframe XUL element with content privileges embedded in the status bar, which contains an HTML file on the server hosting the Jetpack. The $() function is a jQuery-like interface to simplify DOM manipulation at a level that is possible with XPCNativeWrapped objects.

Elsewhere in the same script, we have the following function:

  function removeAds(doc) {
    if (doc.location.protocol == "http:" ||
        doc.location.protocol == "https:")
      $(doc).find("[src]").filter(function() {
        var el = $(this);
        if (blocklist && blocklist.match(el.attr("src")))
          el.remove();
        });
   }

In this case, doc is the XPCNativeWrapped HTML document object for a browser tab whose DOMContentLoaded event has just fired. blocklist is a simple interface for detecting whether a URL matches a known list of domains whose content should be removed from the page (presumably because they contain unwanted advertisements).

Ideally, to make this as easy on the developer as possible while remaining secure, both of the above code snippets should be contained in the same script, and executed within the same global object so that variables and so forth can be freely accessed without having to go through a cumbersome low-level barrier, such as a JSON message-passing bridge.

As far as I could find, however, such a solution wasn’t possible due to the Mozilla platform’s “binary” approach to codebase principals: either a script’s security principal could be associated with a single domain, in which case it could access the contents of pages on a single domain easily but not those of pages on other domains; or it could be associated with chrome, in which case it had free access to everything on the end-user’s system via the Components global. There appeared to be no “in-between” principal allowing for more granular permissions that would allow unfettered access to certain things (for instance, the DOM structures of pages on two or three explicitly-mentioned domains) while restricting access to others.

Above all, the Jetpack team believed that the initial prototype should focus on making the platform as easy and generative as possible. The main reason for this was simply that we didn’t actually know what people were going to do with such creative power once they had immediate access to it: better in the early stages to allow them to experiment unfettered, which allows us to see what they build and develop clean, secure APIs to encapsulate the kind of functionality they need.

For the reasons outlined above, we decided to go the route of giving Jetpacks a chrome codebase principal.

The Original Security Model

The original, highly-tentative plan was simply to allow Jetpacks to remain chrome-privileged, but introduce lightweight sandboxing mechanisms that would ultimately allow the Jetpack script to function as a high-privileged broker between less-privileged code. An early attempt at this can be seen in the Unad demo previously mentioned: the status bar panel is a content-space iframe, and the block-listing logic is contained in a locked-down script—actually a naive implementation of a SecurableModule, which I’ll talk about later—and the Jetpack script itself manages everything else.

It was then envisioned that Jetpacks could be made secure by encouraging developers to minimize the amount of code placed into their chrome-privileged Jetpack script; we could then rely on a healthy code review community to perform reviews of Jetpacks to ensure they were non-malicious. Further easing this process would be the simplicity and power of the Jetpack API: the benefit of replacing 20 lines of XPCOM boilerplate code to retrieve the clipboard contents with a simple call to jetpack.os.clipboard.get() not only makes the developer’s life easier, but the code reviewer’s as well.

After discussing this model with Mike Connor and Lucas Adamski on June 1, 2009, however, it was quickly found that this model had a number of vulnerabilities:

  1. Code reviews don’t scale well in relation to the magnitude of code created in an extension model. Even in a heathy code review community where members have excellent social incentives to perform good reviews, performing a meaningful review of code that runs in the context of a high-privileged broker requires significant understanding about the technical details of security.
  2. Even assuming that the intent of a Jetpack is completely benign, running a Jetpack in a chrome context still means that it’s very easy for its code to accidentally crash the user’s browser, break something important, or—perhaps most worrisome—create a new security hole through which untrusted web pages can exploit an end-user’s system. Further exacerbating this potential is the fact that because Jetpack’s development model is designed to make extending Firefox as easy as writing a webpage, more developers with very little knowledge of security fundamentals will be extending Firefox than ever before.

Given the above points, it was determined that the original security plan, taken as a whole, was untenable.

A New Plan

A tenable security model for Jetpack involves the following components:

  • A mechanism for extensible, securable code reuse. The Mozilla platform is incredibly powerful, and wrapping it in a secure, versioned/backwards-compatible, and elegant API is time-consuming but parallelizable. In the short-term, we need a straightforward way for modules that encapsulate parts of the platform to define their own privilege levels and parameters, as this will allow the community to contribute to the creation of Jetpack’s core API via Jetpack Enhancement Proposals and their reference implementations.

    In the long term, however, the ability to easily share and reuse code is the foundation for any healthy development ecosystem. To do this securely, we need to follow the principle of least privilege: for instance, even though my Jetpack Feature may need access to the local filesystem, I want to make sure that the Twitter library I load doesn’t have access to the filesystem, and that it has the ability to contact twitter.com on the user’s behalf even if the rest of my Jetpack doesn’t.

    I’m not sure what the best way to do this is. One compelling standard I’ve seen is the ServerJS group’s SecurableModules. Brendan Eich also discussed the notion of object tainting at the Mozilla All-Hands in April 2009, and another potential solution may be an object-capability model like that of Caja (though perhaps SecurableModules are a variant as well, I’m not sure). Yet another key to the solution may involve implementing a new, extensible codebase principal whose capabilities can be defined as a set of key-value pairs by the Jetpack Runtime. I honestly don’t know enough about security or the internals of Spidermonkey/XPConnect to know what the ultimate solution is—but given the volatility of the domain, it’s preferable that it be something that’s malleable from JS chrome code, so that the details of the security model can be rapidly changed without building and distributing new binary components. (Note: we’ve since made a lot more progress on this, which will be explained in part 2.)

  • A humane user interface for presenting risk and trust information to end-users. This can be done either before the user first installs a Jetpack or when an installed Jetpack tries to do something that requires privilege escalation, but it clearly needs to avoid the pitfalls presented by solutions like Vista’s User Account Control. This is an unsolved problem, and ideally the solution will be something that’s technical as well as social: for instance, imagine a visual that displays both the privileges required by the Jetpack as well as head-shots of the user’s trusted friends who use it. Striking artwork based on the security profile of the Jetpack could be used to make the user pay attention and not simply perceive the presentation as “yet another click-through”. As this is also a volatile domain, it needs to be easy to change; it’s also open enough to iteration by designers that we could expose this UI to Extensions and hold a Design Challenge for it. There’s plenty of room to leverage the community here.

The Immediate Future

Most importantly, we need to define the interface through which Jetpacks and Jetpack modules declare their security requirements and dependencies, so that we can at least mock it out in the Jetpack extension. For the time being, all that’s needed is a mechanism to tell Jetpack authors that they’re doing things “the right way”, so that once the security model is fully implemented, their Jetpack will work without requiring any changes. While a preview page of what the Jetpack risk UI will look like once the security mechanism is implemented will be useful for authors and will also allow us to iterate on the UI, the actual page that will be displayed when users try installing Jetpacks—the one that looks eerily familiar to Ubiquity’s red screen of death—will remain the same, since the Jetpacks are actually insecure until the security model is fully implemented.

Furthermore, for the immediate future, we’d actually like to promote the fact that Jetpacks have chrome privileges, and encourage developers to copy-and-paste snippets from MDC into their Jetpacks and use Components to their heart’s content, because only once we see what they want to make can we know what APIs need to be made to securely wrap them. In fact, we’d ideally like to always make it possible for Jetpacks to be run in a sort of “developer mode” context, so that it’s possible for a developer to create their Jetpack in a setting where security is a concern but not an impediment, and deal with locking-down the Jetpack once they’re done experimenting, possibly even delegating the creation of an appropriate “security manifest” to another person or party.

Couches in Browsers

April 16th, 2009

A little while ago, Vladimir Vukićević wrote an excellent blog post outlining the reasons why he’s not a fan of exposing a specific implementation of SQL to Web Content.

I agree with everything he says in his post; I’ve also been a fan of CouchDB for some time. A CouchDB-like API seems like a nice solution to persistent storage on the Web because so many of its semantics are delegated out to the JavaScript language, which makes it potentially easy to standardize, as well as easy to learn for Web developers. Furthermore, CouchDB’s MapReduce paradigm also naturally takes advantage of multiple processor cores—something that is increasingly common in today’s computing devices.

To explore the possibility, I decided to spend some time prototyping a JavaScript implementation of CouchDB, which I’ve dubbed BrowserCouch. It’s intended to work across all browsers, gracefully upgrading its functionality when support for features like Web Workers and DOM Storage are detected.

Right now this is very much a work-in-progress and there isn’t anything particularly shiny to see; just the test suite and the semi-large data set test. In the future, it’d be great to make CouchDB’s Futon client work entirely using BrowserCouch as its backend instead of a CouchDB server, but that’s a ways away.

If you’d like to see some code samples of what the BrowserCouch API currently looks like, check out the annotated source code for the test suite. You can also read the primary source code documentation for more on BrowserCouch’s implementation. And if you’re interested in hacking on the code, the Mercurial repository is right here.

Design Challenge Tutorials

April 4th, 2009

Over the last two weeks, I gave two tutorials to our Design Challenge students.

The first was called Engineering Prototypes, and centers on the most challenging part of working on prototypes for me, which is the balance between expediency of implementation and robustness. Prototyping involves prioritizing the former over the latter, but it’s unwise to throw engineering principles out the door: for instance, a prototype that constantly crashes or runs slowly may not be usable enough to dogfood, and one whose implementation is poorly designed can be difficult to iterate and evolve. My tutorial attempts to present some of the factors one should take into account to produce prototypes that are both quick to implement and robust enough to dogfood.

The other session was called Prototyping with jQuery but it included a heavy dose of Firebug as well.

For the second session, I created a prototype of something that I’ve wanted to make for a while: Open Web Challenges.

These are essentially a series of interactive web-based problems that require “hacking the page” using real-world tools to solve. They’re inspired by a number of my favorite pedagogical dilemmas, such as the time someone in LambdaMOO made me program my way out of a paper bag; the inventive exercises from Graham Nelson’s Inform Designer’s Manual 4th Edition; the labs from Bryant and O’Hallaron’s Computer Systems: A Programmer’s Perspective; and the mathematical proofs from Carol Schumacher’s Chapter Zero. Obviously, being a one-day hack, these Open Web Challenges pale in comparison, but the prototype was fun to build and I’d like to continue creating more interactive exercises like this.

All in all, I thought the Design Challenge was an awesome opportunity for students around the world to learn more about open-source design and development, as well as a great way for Mozilla folks to get a chance to talk to students, teach, and obtain a better understanding of what we need to do to make the Web as a platform easier to learn. If you’re interested, I recommend checking out the rest of the tutorials at design-challenge.mozilla.com/spring09.

I’d also like to thank Pascal Finette for putting the Design Challenge together—it’s unquestionably a success and I’m looking forward to participating in more Mozilla Education projects in the future.

Redesigning Planets and Project Dashboards

March 3rd, 2009

The Ubiquity project has been moving pretty quickly and despite the fact that I spend most of my time working on it, I actually have a hard time keeping track of its progress. At Labs we’ve talked about the idea of having “project dashboards” that present the latest developments on our projects, so I thought it might be a good opportunity to play around with new ways of visualizing community activity.

Most of the information I actually need to know about where Ubiquity’s at is actually contained in Planet Ubiquity; the problem for me is that some of the most important information I need, such as recent code commits, is actually contained way down in the sidebar of the page. And while I want different types of information to be spatially separated—so that I can just look at code commits without having to see blog posts, for instance—I also want them to be chronologically grouped so that it’s possible for me to see what’s happened with the project in the last 8 hours.

Here’s a screenshot of what I’ve got so far:

This visualization presents a grid whose columns represent different types of information for the project, and whose rows represent chronological “bins”. Each row is further colored to provide visual indication of how old the information is. The actual aesthetics here aren’t fully-formed yet—they’re actually just a modification of the stylesheet for my about:mozilla redesign—but the general grid concept is something that’s been simmering in my head for a while. As an active project contributor, it works well for me, though I’m not sure how suitable it is for the casual passerby who’s curious about where the project’s going.

Under the hood, everything’s implemented using client-side JavaScript and Google’s AJAX Feed API. Each column can include information from more than one feed; for instance, the “Code” column displays a colored square next to each HG commit indicating the result of the automated Buildbot tests for that revision.

Although this implementation is merely a prototype, I’ve tried making it decoupled enough to be reused as a general dashboard for any project; I’ve already spoken about this to Dan Mills, so we should have a Weave project dashboard soon.

To see the prototype in action, check out the Planet Ubiquity Redesign. I’ve tried it out in Firefox and Safari and it seems to work fine, but I wouldn’t be surprised if MSIE barfs on it at the moment. And because everything’s done on the client-side, JavaScript needs to be enabled.

I’ve also documented the code for anyone who’s interested.

An Experiment in Redesigning about:mozilla

March 1st, 2009

With Deb Richardson’s recent posts on the evolution of the about:mozilla newsletter, I decided to try my hand at a new layout for the existing issues, in the hopes that experimenting with new designs could help shed some light on the situation.

For reference, this is how the February 24th issue looks:

One of the notable things about this layout is that there isn’t actually much useful information in the first screen: there’s a table of contents that has headlines, but the user needs to click on a headline or scroll down to learn more. The length of each line is also quite long: at over 130 characters, it can be difficult for the reader’s eye to move from the end of one line to the beginning of another.

Here’s my redesign of the same issue:

This layout takes advantage of the fact that all the articles in about:mozilla are pretty short—short enough to fit on most PC/laptop screens in a narrow column without forcing the user to scroll vertically.

Since most computer screens these days are much wider than they are tall, I thought it’d be useful to have the articles placed horizontally next to one another rather than vertically: that way the horizontal space is used efficiently, and each article remains easy to read because it’s in a column about 40 characters wide. It also places the headlines in the same visual line, so that it’s easy for readers to scan through the issue and filter out articles that they’re not interested in. The top and bottom margins of the page are black so as to focus the user’s eyes on the content (the same reason a theater’s lights are turned off during a show).

This design was inspired in part by the Swiss Grid System. In an attempt to make it somewhat resolution-independent, the CSS doesn’t use pixels as a measurement unit for anything other than borders; everything else is specified in points and ems.

I’ve also hooked up this layout to pull its content from the Atom feed for the newsletter using Google’s AJAX Feed API; if you’re interested in reading the latest issues of about:mozilla using this alternative layout, you’re welcome to use this page. Although there isn’t currently an interface for viewing back-issues, you can change the number at the end of the URL to read them if you need to.

Automatic Bug Reporting for Firefox Extensions

February 27th, 2009

We want to make Ubiquity awesome at reporting errors. In our original release, a transparent message with JavaScript exception information was displayed, which wasn’t very useful to the average user, and was downright annoying when dozens of exceptions were logged in the same instant.

At present, running a command that raises an error just results in that message being logged to the JS Error console, which very few people know how to access—so most people are left scratching their heads and wondering why their command is taking so long to run.

For the next release of Ubiquity, we’re going to be trying something more user-friendly: if a command encounters an error, a transparent message will be displayed telling the user that it didn’t work. The message will also recommend using the “report-bug” command to send information about the bug to the Ubiquity team. If the user decides to run this command, a page is opened that looks like this:

Aside from inviting the user to describe their problem, a lot of information is included about their system: what OS they’re using, what extensions and plugins they have installed, what recent exceptions were thrown, and so forth. We’re hoping this will lower the barrier to entry both for receiving and providing technical support, since most of the information needed to describe and investigate a problem is contained in a single link.

We don’t yet have an interface for browsing existing bugs, but we do have a display for viewing them. It looks pretty similar to the page for submitting a bug:

One interesting aspect of our bug reporting system is that we’re not using numbers to identify bug reports: they get big fast as many reports are submitted, and big numbers are hard to remember. Instead, we’re mashing two random words from the dictionary together. For instance, the first bug I reported using this system was called anaphorically-spinach.

Under The Hood

The bug reporting system is pretty lightweight: mostly it’s just static HTML/JavaScript code that talks to a web service that’s implemented in under 100 lines of Python. The actual bug report is just a JSON object, and is deposited into a CouchDB server.

The big advantage of using CouchDB here is that we’ll be able to easily create really rich queries using plain old JavaScript. For instance, here’s a query that shows all reported error messages that contain the text “Invalid chrome URI”. It won’t be hard to create complex queries that, for instance, give us all the bug reports in which the user had a certain extension installed and had a command crash at a particular line in a particular file.

A Public Asset

Right now all reports are submitted to the public domain, and as such the report database is a public asset; users are informed of this before they submit the bug, and encouraged to look at the additional data that’s being sent with their report to ensure that there’s nothing sensitive in there. In the future, it’d be nice to allow the user to click on any parts of the data that are personally identifying, so that they can submit a version of the report that masks out the sensitive information.

Reuse

The bug report system has been designed to be decoupled from Ubiquity itself. For instance, the report viewing application is designed as a reusable JavaScript component, so it should ultimately be easy to embed into any web page. In other words, it should be easy to use as a bug reporting mechanism for any Firefox extension—and possibly for any web application in general. If you’re interested in adding the component to your own project, please let us know; the code is still a work-in-progress, and any contributions or comments are appreciated.

Ubiquity 0.1.6 and Release Scheduling

February 17th, 2009

As we’ve mentioned before, Ubiquity 0.2 has fairly broad, visionary goals that won’t be fully satisfied for some time. So we’re going to be pushing its changes to the 0.1 line at more regular intervals as we continue to develop it.

By “pushing its changes” we mean that we’ll effectively be disguising our work-in-progress 0.2 as a 0.1.x release. For instance, Ubiquity 0.1.5, which we released about a month ago, is essentially the same thing as 0.2pre7; similarly, Ubiquity 0.1.6 will basically be the same thing as 0.2pre13, only with our more experimental features—such as locked-down feeds and python feeds—disabled by default and unadvertised on Ubiquity’s front page.

There’s a couple reasons for this:

  • Ensuring that the general public is using the same codebase as testers and developers means that our code gets to be used by “the real world” more quickly, and means we’ll know about bugs closer to the time that they were introduced into the software.
  • Releasing new public updates at a regular interval is a direct way of letting our users know that Ubiquity is still alive and kicking, and getting better all the time.
  • We can get feedback from the broad public more quickly, so that if we’re really going the wrong direction with something, we can know about it before we’ve invested too much time and effort into it.

So we’re aiming to release a new public update to Ubiquity at least once every two weeks.

Things you can do to help

Ubiquity is a community effort, and we welcome contributions!

  • Testing. Please try out the release candidate and bang on it! Try it out on every operating system that’s convenient for you to try it out on, and on every version of Firefox too (3.0, 3.1 beta, or 3.2 alpha). Any comments to this post about where it works or doesn’t will be very appreciated.
  • Release Notes Documentation. The 0.1.6 release notes can always use more help; please feel free to edit that page and fix a TODO if you enjoy technical writing, and leave a comment here or on IRC if you have any questions. Keep in mind that the wiki tracks all changes, so even if you mess up, we can always revert the changes. Experimentation is good!
  • Ubiquity Tutorial Documentation/Testing. Feel free to try out the user tutorial or the author tutorial with the release candidate and make sure everything still works. Regardless of the outcome, post back here to let us know what you found!

Thanks for reading this. If you have any questions, please don’t hesitate to reply to this post or poke us on #ubiquity on irc.mozilla.org.

PyXPCOM vs. jsbridge

February 11th, 2009

Yesterday Tempura left a good question as a comment on my blog post concerning Ubiquity’s experimental support for Python:

What about http://pyxpcomext.mozdev.org ? They bring Python in an xpi for all major plattforms, without the need of an local installed interpreter.

Using PyXPCOM was actually a potential option we had considered, but we ended up going with jsbridge for a number of reasons:

  • PyXPCOM uses XPCOM as its means of communication between Python and the Mozilla platform. Unfortunately, XPCOM is super heavyweight and it’s a particularly difficult hurdle to get through when all you really want is for two very dynamic languages to communicate with each other. For instance, Ubiquity itself implements very few XPCOM interfaces, and most of its functionality is exposed through JS Modules; jsbridge allows us to access these JS Modules directly, while accessing them from PyXPCOM would require us to create verbose XPCOM wrappers around them—a particularly egregious amount of work when you think about how similar JavaScript and Python are.
  • One advantage of using the local system’s Python installation is that we inherit whatever packages come with it, which means that on OS X 10.5, for instance, we automatically get access to Python’s bindings to Objective C and Cocoa, whereas with PyXPCOM we really have to manage the user’s distribution manually. It could similarly be said that PyXPCOM takes an embedding approach, while jsbridge takes an extending approach; a very good analysis between these two approaches has been written by Glyph Lefkowitz here.
  • In regards to Windows, putting a distribution of Python on the end-users system that any other application can leverage is a good thing—much better than requiring the user to download a big package and then only allowing Firefox to use it. This gets into the idea of Python as Platform that I’ve written about before.
  • In regards to OS X and Linux, using the pre-existing installation of Python is obviously nice because it doesn’t require the end-user to download anything (aside from mozrunner and jsbridge, which are pretty small).
  • jsbridge has no binary components, which makes it a lot easier to maintain and experiment with than PyXPCOM, which is difficult to compile and extend.

PyXPCOM is definitely useful for a lot of things, though—for instance, manipulating the DOM of a page—so I think there’s still some things we can leverage there. And jsbridge certainly presents its own hurdles and limitations, too, but hopefully this post sheds some light on the thought processes that went into deciding which mechanism to use.