Jim's
Tutorials

Fall 2011
course
navigation
Last week I made a very simple Firefox extension (that could certainly have been done more easily/straightforwardly in html/javascript) that implements a chess clock. The code still needs a bit of refactoring but the exorcize proved a good introduction to XUL and developing for Firefox.
I spent some time looking through various documentations with various degrees of success. I finally found this tool: https://addons.mozilla.org/en-US/developers/tools/builder/, that generates a shell of an extension as a starting point. A copy of this shell is attached (chessclockblank.zip).
This tool also pointed me towards some developer guides. The one that proved most useful was a screen-cast called Extensions Bootcamp: Zero to “Hello World” in 45 Minutes. The screen-cast went over a lot basics I already new at this point but it did point out a few things that proved invaluable.
It explained that building a separate development Firefox profile was a good idea to avoid conflicts with existing extensions. To do this:
$ mkdir -pv ~/profiles/dev $ /Applications/Firefox.app/Contents/MacOS/firefox -profile ~/profiles/dev -no-remote &
The -profile flag specifies that Firefox should open with the specified profile (creating it if it's an empty folder) and the -no-remote flag creates a new instance of Firefox so that you can continue to browse the web in you own copy of Firefox while you debug the new extension. In this case the idea was that this would allow you to continue watching the screen-cast.
I created an alias for the latter command.
The other key thing this screen-cast pointed out was that re packaging the extension every time I made a change to the code would be extremely time consuming. Instead, it suggested:
$ echo "{PATH TO EXTENSION}" > ~/profiles/dev/extensions/{UNIQUE ID}
{PATH TO EXTENSION} is the directory where my extension files are. In my case the directory created by unpacking the chessclockblank.zip file created by the generator. {UNIQUE ID} is the unique identifier I specified to the generator tool, Firefox uses this to differentiate all extensions from one another.
During the developing process, after each change to the code, all I had to do was quit the development instance of Firefox and call my alias again and the extension was already installed.
I used a number of tutorials and reference sites including https://developer.mozilla.org/en/XUL_School and https://developer.mozilla.org/en/XUL_Tutorial, to actually build the XUL extension. One of the nice features of the XUL I employed to add my extension to the tools menu was the overlay system. Most of this was setup for me by the generator tool but the chrome.manifest file specified that my file, ff-overlay.xul extends the file chrome://browser/content/browser.xul (This is not a normal path, it's Mozilla format that finds a file in a way that is defined by these .manifest files) which defines the entire Firefox interface. The XUL tags in my file contain elements that are added to parts of the interface, in this case the menu-bar. I then specified that my new menu item uses JavaScript to open a new window which contains the content described by my clock.xul file. This in turn uses JavaScript to run a simple chess clock application.
I initially ran into some snags packaging the extension as a .xpi file. A lot of the documentation talked about creating a .zip file and then renaming it to .xpi. This resulted in the error "This add-on could not be installed because it appears to be corrupt." This was when I tried using the Finder's built in zip feature to create a zip archive of the extension directory. I'm not entirely certain why, but I was able to make the extension work with the following:
$ zip -r chessclock.xpi chrome chrome.manifest defaults install.rdf
I'm guessing that making it a zip of the files in the directory instead of a zip of the directory was the key difference.
I've attached the working .xpi file as well as a zip of the final extension directory.
http://cs.marlboro.edu/ courses/ fall2011/jims_tutorials/ sam/ Chessclock_Docs
last modified Sunday September 18 2011 11:50 am EDT

attachments [paper clip]

     name last modified size
   chessclock.xpi Sep 18 2011 11:49 am 5.80kB    chessclock.zip Sep 18 2011 11:49 am 15.9kB    chessclockblank.zip Sep 18 2011 10:54 am 3.34kB