How to write an add-on for Firefox 4.0

I recently watched a great tutorial that walks through how to write a “hello world” app for Firefox.  The demo was written for Firefox 3.5 and I have Firefox 4.0 but I manged to get past the one hiccup that caused and successfully made the app.

Here’s the coles notes version of that journey, I of course did my app on a windows machine so these notes are specific to windows.  If you want to view the original video in it’s entirety it’s available here (there are non windows instructions in it if you’re interested):
http://design-challenge.mozillalabs.com/resources/#extension_bootcamp
Scroll down the page to the video entitled “Zero to Hello World! in 45 Minutes”, that is the video I followed through on.

Follow these steps to create your own app / set up your environment:
Download and install Firefox 4.0 if you don’t already have it.
Create a separate profile in Firefox for testing – this helps you not make a mess of your personal profile.  To do so run this command:

cd %USERPROFILE%
md Profiles\helloworld-dev

Run Firefox with this command line (forces a specific profile, and a separate process (run two separate Firefox’s at the same time!) and the command window to open)
“c:\program files\mozilla firefox\firefox.exe” -profile “%USERPROFILE%\Profiles\helloworld-dev” -no-remote -console
Open advanced options in your new Firefox window by typing this into the URL:
about:config
Change these settings to true if they aren’t already (double clicking will work)
extensions.logging.enabled
javascript.options.showInConsole
Create this next setting as a boolean = true (it probably won’t already exist), to do so r-click in the window.
browser.dom.window.dump.enabled
You now need to install two Add-ons:
DOM Inspector
and
Console2
If those links don’t work searching the inter net for their name and “Firefox Add-on” should do the trick.
Create a extension directory, a good option is: (run this)

cd %USERPROFILE%
md Projects\helloworld

To navigate to any of the directories created try this at the command line:

explorer.exe %USERPROFILE%\Projects\helloworld

explorer.exe %USERPROFILE%\Profiles\helloworld-dev
Create the basic file layout in the “%USERPROFILE%\Projects\helloworld” directory:

helloworld/
    install.rdf
    chrome.manifest
    chrome/
        content/
        locale/
            en-US/

Where names ending in “/” are folders, the others are empty files.
This is where things differ somewhat from the tutorial as it appears some changes were made in Firefox 4, or at least it seems they were as the example files wouldn’t work for me as is.  I had to open an existing add-on that was on my machine to get the syntax correct.
Populate the install.rdf file using:

<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.mozilla.org/2004/em-rdf#">
<RDF:Description about="urn:mozilla:install-manifest">
<id>{77614715-3043-4CCC-9C73-23EE9C9ACB0A}</id><!-- This is the GUID of our add-on -->
<name>Hello world!</name>
<version>0.1</version>
<targetApplication>
<RDF:Description>
<id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</id><!-- This GUID means Firefox -->
<minVersion>3.0</minVersion>
<maxVersion>5.0.*</maxVersion>
</RDF:Description>
</targetApplication>
</RDF:Description>
</RDF:RDF>

Populate the chrome.manifest file using:

content  helloworld         chrome/content/
locale   helloworld  en-US  chrome/locale/en-US/

overlay  chrome://browser/content/browser.xul chrome://helloworld/content/browser.xul

Let’s create some more files for a fully functioning add-on.  Create:
%USERPROFILE%\Projects\helloworld\chrome\content\browser.xul
Contents:

<?xml-stylesheet href="chrome://helloworld/content/browser.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://helloworld/locale/browser.dtd">
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<stringbundleset id="stringbundleset">
<stringbundle id="helloWorldBundle"
src="chrome://helloworld/locale/browser.properties"/>
</stringbundleset>
<script type="application/javascript"
src="chrome://helloworld/content/browser.js"/>
<statusbar id="status-bar">
<button id="helloWorldButton" label="&helloWorldButton.label;" insertafter="statusbar-display"
oncommand="HelloWorld.onCommand(event)"
style="color: green"/>
</statusbar>
</overlay>

Create:
%USERPROFILE%\Projects\helloworld\chrome\content\browser.js
Contents:

let HelloWorld = {
onCommand: function(event) {
let stringBundle = document.getElementById("helloWorldBundle");
let hours = new Date().getHours();
let greeting = (hours < 12) ? stringBundle.getString("morningGreeting")
: stringBundle.getString("eveningGreeting");
let message = stringBundle.getFormattedString("helloWorld", [greeting]);
dump(message + "\n");
}
};

Create:
%USERPROFILE%\Projects\helloworld\chrome\content\browser.css
Contents:

#helloWorldButton {
font-weight: bold;
}

Create:
%USERPROFILE%\Projects\helloworld\chrome\locale\en-US\browser.dtd
Contents:

<!ENTITY  helloWorldButton.label  "Hello world!">

Create:
%USERPROFILE%\Projects\helloworld\chrome\locale\en-US\browser.properties
Contents:

helloWorld = %1$S world!
morningGreeting = Good morning
eveningGreeting = Good evening

To get our new instance of Firefox to load our add-on the simplest way to do so for development purposes is:
Create:
“%USERPROFILE%\Profiles\helloworld-dev\extensions\{77614715-3043-4CCC-9C73-23EE9C9ACB0A}”
NOTE: This is a file that is named the exact same thing as the id for our app in the RDF file.
Contents:
C:\… your file path here …\Projects\helloworld\

After all that is done close your Firefox you opened via command line earlier, then re-open using the same command, that is:
“c:\program files\mozilla firefox\firefox.exe” -profile “%USERPROFILE%\Profiles\helloworld-dev” -no-remote -console

If you created all the files correctly you should have a button in Firefox with green text you can click on.  When clicked on it will send text to the command window that is probably in the background.  Thanks to the good people at mozillalabs for this.  If you have any questions feel free to post here, or take a look at the original lab available here:
http://design-challenge.mozillalabs.com/resources/#extension_bootcamp
Scroll down the page to the video entitled “Zero to Hello World! in 45 Minutes”.
View the supporting pdf here.
Or take a look at the source code here: (may not work in Firefox 4, it didn’t for me.)

Some definitions:
content is the web page loaded in Firefox
chrome is the Firefox UI, i.e. everything that’s not content
chrome privileges Add-ons have the same privileges Firefox does, making them a bit scary from a security perspective.

Technology used by Firefox that a Add-on developer needs to know (at least a little of)
XUL and XHTML for structure, widgets
CSS – appearance
JavaScript – behaviour
DTDs and properties files for localization (support for different languages)
JavaScript and C++ for modules/components

NOTE:
%USERPROFILE% does not consistently work for me and I’ve not figured out why as yet. The lines above did work for me when I wrote this article, yet today I try to re-create and this command:
“c:\program files\mozilla firefox\firefox.exe” -profile “%USERPROFILE%\Profiles\helloworld-dev” -no-remote -console
is having issues. The issue is the mix of spaces in the variable and quotes around the input. The fix I believe is either to only allow 8.3 file names (so spaces are dropped) or to just type the entire path instead of using this nice shortcut.

Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: