Restartless Firefox add-ons, part 1: Giving your add-on the bootstrap
Intro
Firefox 4 will introduce a new type of add-on to users, the restartless add-on! It's true that there are many problems that need to be resolved before all add-ons can be made restartless, which should help illustrate why it has taken as long as it has for Mozilla to introduce the feature. The capability is available now, and although it is more difficult to write a restartless add-on than it is to write a add-on that requires a restart to be installed/uninstalled/enabled/disabled I think most would agree that a restartless add-on is usually superior to one that requires a restart. So I've decided to start a short blog series on how to write restartless add-ons for Firefox in order to help those that are interested along the way as much as I can.
You should note that Mozilla is working on a add-on sdk which makes writing restartless add-ons much easier by providing APIs which allow you to abstract away most of the painful parts, which are the parts that I plan to describe in this series. So if you're interested in writing a restartless add-on without the add-on sdk, or if you're planning on writing modules/packages to be used by add-ons made with the add-on sdk, then you may find this series useful.
The Bootstrap
The core of a restartless add-on is it's bootstrap.js file, because it's this file which Firefox loads at startup, and it's this file that Firefox will notify about install/uninstall/enable/disable/etc events which are key to making a add-on restartless. In order to notify Firefox that your add-on includes a bootstrap.js file, and that you want it to be used you must include a em:bootstrap="true" in your install.rdf file. If you're unfamiliar with a add-on's install manifest file (aka install.rdf) then you can read about it here (it's basically just a metadata file for add-ons).
The bootstrap.js are a bit like a Web Worker in that it has it's own scope which has a special set of global variables and it is notified of events by defining specially named functions which are meant to receive these events. They are disimilar from Web Workers in that they don't run in their own thread, they can pass objects in and out (not just strings), and they have access to pretty much everything using the Components global object which is made available to them.
For a complete list of the functions bootstrap.js uses, there parameters, etc, then I suggest reading this article on Bootstrapped Extensions. The bottom line is that you need to define functions which will handle install/uninstall/enable/disable/startup type events. For instance the first function that you'll want to define is startup(), because this is the function which would be called after the add-on is installed, after it is enabled, or after the browser starts up. Because a add-on typically needs to know why the startup function was called there is an aReason argument passed in to the function (read the docs on how to use aReason). The second function that you'll likely require is the shutdown() function, this is a very important part of restartless add-ons, it's basically the cleanup function, it has to remove any evidence that your add-on was ever present in a live browser session. In other words if your add-on adds/does X to the browser, then the shutdown() function will remove/undo X, where X can be stuff like adding xul elements and/or attributes, adding javascript variables to other scopes, adding observers/event listeners, creating background operations, and various other things; all of which are extremely easy to forget to remove.
Note: If you'd like to make your add-on restartless and backwards compatible, then read this.
Summary
We now know a restartless add-on needs two files: first a install.rdf file, and second a bootstrap.js file; we also know that the latter will be notified of install/uninstall/enable/disable type events related to the add-on which we are expected to define in order to use.
It may surprise you how many add-ons could be made with these two files alone. Most user chrome scripts or jetpack prototype scripts could be written as a bootstrap.js file and made into a extension simply by adding a install.rdf file and zipping the two together as a .xpi file.
Next
In part 2 I'll describe a couple of options for adding default preferences.
