This tutorial will take you through the steps required to build a very basic extension - one which adds a status bar panel to the Firefox browser containing the text "Hello, World!"
Note This tutorial is about building extensions for Firefox 1.5. Other tutorials exist for building extensions for earlier versions of Firefox.
Setting up the Development Environment
Extensions are packaged and distributed in ZIP files with the <tt>xpi</tt> (pronounced “zippy”) extension. The layout of content within the XPI file is like so:
extension.xpi: /chrome/chromeFiles/ /components/ /defaults/ /defaults/preferences/ chrome.manifest install.rdf
Because of this, it is easiest if we lay out our source files in a similar fashion, unless you want to write some sort of Makefile or shell script to package and zip all of your files. Even if you are prepared to do that, testing is much simpler if you lay out your files like this because of a feature of Firefox 1.5's Addon System.
So let's get started. Create a folder for your extension somewhere on your hard disk, e.g. <tt>c:\extensions\myExtension\</tt>. Inside this folder create another folder called <tt>chrome</tt>, inside the <tt>chrome</tt> folder create a folder called <tt>chromeFiles</tt> and inside the <tt>chromeFiles</tt> folder create a folder called <tt>content</tt>.
Inside the root of your extension folder, alongside the <tt>chrome</tt> folder create two new empty text files, one called <tt>chrome.manifest</tt> and the other called <tt>install.rdf</tt>.
Create the Install Manifest
Extending the Browser with XUL
To extend the browser, we modify parts of the browser UI by adding or modifying widgets. We add widgets by inserting new XUL DOM elements into the browser window, and modify them by using script and attaching event handlers.
The browser is implemented in a XUL file called <tt>browser.xul</tt>. In browser.xul we can find the status bar, which looks something like this:
<statusbar id="status-bar"> ... <statusbarpanel>s ... </statusbar>
<tt><statusbar id="status-bar"></tt> is a "merge point" for a XUL Overlay.
XUL Overlays are a way of attaching other UI widgets to a XUL document at run time. A XUL Overlay is a .xul file that specifies XUL fragments to insert at specific merge points within a "master" document. These fragments can specify widgets to be insreted, removed, or modified.
Example XUL Overlay Document
<?xml version="1.0"> <overlay id="sample" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <statusbar id="status-bar"> <statusbarpanel id="my-panel" label="Hello, World"/> </statusbar> </overlay>
The <tt><statusbarpanel></tt> called <tt>status-bar</tt> specifies the "merge point" within the browser window that we want to attach to.
The <tt><statusbarpanel></tt> child is a new widget that we want to insert within the merge point.
Take this sample code above and save it into a file called <tt>sample.xul</tt> inside the <tt>chrome/chromeFiles/content</tt> folder you created.
For more information about merging widgets and modifying user interface using Overlays, see below.
XUL files are part of "Chrome Packages" - bundles of user interface components which are loaded via <tt>chrome://</tt> URIs. Rather than load the browser from disk using a <tt>file://</tt> URI (since the location of Firefox on the system can change from platform to platform and system to system), Mozilla developers came up with a solution for creating URIs to XUL content that the installed application knows about.
The browser is: <tt>chrome://browser/content/browser.xul</tt> Try typing this URL into the location bar in Firefox!
Chrome URIs consist of several components:
- Firstly, the URI scheme (<tt>chrome</tt>) which tells Firefox's networking library that this is a Chrome URI and that content being loaded from one needs to be handled specially.
- Secondly, a package name (in the example above, <tt>browser</tt>) which identifies the bundle of user interface components. This should be as unique to your application as possible to avoid collisions between extensions.
- Finally, a file name to load.
So, <tt>chrome://foo/skin/bar.png</tt> loads the file <tt>bar.png</tt> from <tt>foo</tt>'s theme <tt>skin</tt> section.
When you load content using a Chrome URI, Firefox uses the Chrome Registry to translate these URIs into the actual source files on disk (or in JAR packages).
Create a Chrome Manifest
For more information on Chrome Manifests and the properties they support, see the Chrome Manifest Reference.
Open the file called <tt>chrome.manifest</tt> that you created alongside the <tt>chrome</tt> directory at the root of your extension's source folder hierarchy.
Add in this code:
content sample chrome/chromeFiles/content
This specifies the:
- type of material within a chrome package
- name of the chrome package
- location of the chrome packages' files
So, this line says that for a chrome package sample, we can find its content files at the location <tt>chrome/chromeFiles/content</tt> which is a path relative to the location of <tt>chrome.manifest</tt>.
Note that content, locale and skin files must be kept inside folders called content, locale and skin within your <tt>chrome</tt> subdirectory.
Save the file. When you launch Firefox with your extension, this will register the chrome package.
Register an Overlay
You need Firefox to merge your overlay with the browser window whenever it displays one. So add this line to your <tt>chrome.manifest</tt> file:
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
This tells Firefox to merge <tt>sample.xul</tt> into <tt>browser.xul</tt> when <tt>browser.xul</tt> loads.