Biz & IT —

Developing Firefox Extensions with GNU/Linux

Ever wanted to try extending Firefox on your own? Now's your chance. Linux.Ars …

Introduction

I'm sure many of you are excited about today's GNOME release and the release of Firefox 1.5 beta 1. Kris and I decided to write Linux.Ars sections about GNOME and Firefox customization in order to celebrate the releases. In this edition of Linux.Ars, Kris will teach you how to use command line build tools to construct a complete Firefox extension, I will teach you how to add context menu items to Nautilus using the Nautilus Actions extension, and Ian introduces an LDAP utility called Luma.

I want to personally thank those of you who sent me e-mails with comments and suggestions! Linux.Ars is all about you, so don't be afraid to get involved! Want to do a section for a future edition? Have a suggestion for a topic that you want us to write about? I would love some feedback. Feel free to send me or post in the discussion thread comments, complaints, suggestions, requests, free hardware, death threats, or disparaging remarks about my assorted deficiencies. Keep those comments coming!

Developers Corner

Developing Firefox Extensions with GNU/Linux

In '89, an ancient Sumerian deity named Zuul razed downtown New York with her avatar, a flaming, Stay-puft Mallowzilla. In related news, the aptly named "Mozilla Foundation" has released Firefox 1.5 Beta, a web browser built on an easily extended, cross-platform application framework called XUL (pronounced "Zuul"). In this article, I will provide insight into how to professionally develop a Firefox Extension with GNU/Linux. For demonstration, I'll develop an application called Stantz.

This article is directed to anybody who wants to extend Firefox. Experience writing HTML, Javascript, and CSS should be all you need to understand XUL. Some knowledge about the Linux command line and the Python programming language are desirable, but not necessary. You may want to play with an Apache web server's configuration, and experience handling a neutron accelerator pack would certainly help. Thankfully, you won't need to build Mozilla and you won't have to compile any C or C++.

What can you do with a Firefox Extension? Firefox extensions can modify the Firefox user interface. This includes adding buttons to tool bars and menus; changing fonts, colors, and icons; capturing events in the client interface like page loads and clicks; and modifying web pages after the browser loads them and before the user sees them. All of this functionality comes with the aspect-oriented facility of overlays. Extensions also have as much access to the file system as the user running Firefox. Extensions can add protocol handlers, hooking actions to URLs like icq://, aim://, or stantz://. Extensions have UniversalXPConnect privileges, allowing them to harness any XPCOM component. Firefox comes with a rich library of XPCOM components that permit your extension to drive very low-level functionality like sockets from Javascript. You can also augment the XPCOM library with Firefox extensions by adding Javascript, linkable libraries, or XPIDL.

What can you do without a Firefox Extension? Any web page can be a rich application by using Ajax and even XUL. Just as DHTML is the hip word for creatively applying HTML, Javascript, DOM, and CSS, Ajax is the hip word for what you could always do with DHTML, plus XMLHttpRequest. Using XMLHttpRequests, any web page can query a dynamically created web page and replace all or any part of a web page, for example, populating a selection box or updating a stock quote ticker. Normal Javascript can dispatch XMLHttpRequests. Also, XUL does not require any special privileges to render in Firefox. Web pages can ask permission for UniversalXPConnect privileges and use any XPCOM components they like, but this permission only affects the function and thread that asks, rendering the exercise impractical.

When should you use a Firefox Extension? Only when you must. Installation of a Firefox extension has a substantial "barrier of entry" since extensions require draconian permission from the user to deter the web's criminal element from using them as a virus delivery platform.

Here follows stantz.xpi

Starting from the top, the vibrant denizens of the web will install Stantz by clicking on a link to stantz.xpi, a cross platform installer, pronounced "zippy." XPI files are no more complicated than a way to organize a common zip archive. Broadly, stantz.xpi has the following structure:


stantz.xpi

install.rdf is an XML file that contains information about the Stantz application. chrome.manifest is a flat text file that directs Firefox to use the overlays, stylesheets and locales Stantz provides, as applicable. chrome/stantz.jar contains all of the files that will appear on the chrome:// URL. components/ contains any XPCOM components that Stantz provides. defaults/ contains a default preferences file.

Creating extensions for growing applications, of course, requires some scaffolding to support agéd versions. The new, 1.5 release of Firefox, code named Deer Park, supports the plain text chrome.manifest format for declaring where your extension's overlays, locales, and skins are. Firefox 1.0 requires bulky contents.rdf files in content/, locale/, and skin/, as applicable. Very early releases of Firefox and the Mozilla Suite require an install.js script instead of an install.rdf, but that is beyond the scope of this article. Stantz will support all browsers that use install.rdf and chrome.manifest or **/contents.rdf.

Anybody can publish their Firefox extension at https://addons.mozilla.org/. This avoids quite a bit of hassle on your part and your users'. However, I intend to publish Stantz on my own web server. If you plan to do the same, you will need to add a MIME type to your apache configuration. While this may be possible with a .htaccess file, it is this developer's experience that this does not work, so you will need root access on your distribution server. My server's configuration allows me to add mini configuration files in /etc/apache2/conf.d, so I've added xpi.conf to enable XPI. Without this line, the client browsers will not recognize the file as an installer.


/etc/apache2/conf.d/xpi.conf

AddType application/x-xpinstall .xpi

Here Follows chrome/stantz.jar

chrome/stantz.jar is a zip archive, as well. Per the instructions in chrome.manifest and contents.rdf files, Firefox will map directories in chrome/stantz.jar to chrome:// URL's. The chrome:// protocol provides access to all of Firefox's internal user interface and that of all installed extensions. For example the XUL file, chrome://browser/content/browser.xul, defines Firefox's main interface window. You can unpack this file from your Firefox installation directory (perhaps /usr/lib/mozilla-firefox). The archive, chrome/browser.jar, contains the browser interface file, content/browser/browser.xul.


chrome/stantz.jar

content/ will contain your XUL and Javascript. It may also contain any other "content" your extension will need. Agile developers, hackers, and academics who have lost their grant money and have a penchant for entrepreneurship will be inclined to, at least at first, write all of the user-readable text in their native language and put all of their images and style sheets in the content section as well. However, Firefox is a pro-social platform and provides easy means for locales and skins. The skin/ directory will contain images and style sheets that define the appearance of your user interface. locale/ will contain a directory for each language and locale your extension supports. Supporting these facilities makes it easy for you, or other extension developers, to tailor your extension's functionality to their favorite language and appearance using overlays.

The project directory, stantz/

Your project should be laid out with all of the directories that will appear in the chrome jar and the installer xpi. If you are publishing this project on your own, you should also have a www/ directory.


stantz/

For this project, I used a Subversion repository. You can use svn if you choose, or you could go with the very capable Concurrent Version System, CVS. My own preference is for Subversion, so the tutorial is Subversion-centric; as always, your mileage may vary. While managing a Subversion repository is beyond the scope of this article, Stantz's publish script makes use of svn commands to version stantz.xpi and update.rdf. Even if you work alone, a version management system provides a very big "Undo" button for your entire project that will remember how your project looked every time you committed changes. To get you started, here are some Subversion commands you will need.

svnadmin create /svn/stantz # done once to create the repository
svn co file://svn/stantz # done once to obtain a "working copy"

cd stantz

# a typical session
svn up # done before you start working to acquire the most recent changes

svn stat # see what files have changed since you last updated
svn ci -m "Fixed bug 0" # to "check in" or commit changes
                        # when you're done and everything works

Here's the entire layout for Stantz.


stantz/

Build scripts generate the files denoted in bold. You should not add these files to your version management system.

PDF Download the PDF
(This feature for Premier subscribers only.)

Channel Ars Technica