No browser is perfect -- eventually enough annoyances will build up to the point that you wish you could do something about it. Thanks to Firefox's extendable architecture and a healthy dose of JavaScript knowledge, you can begin bending the browser to your will.

Despite recent improvements to its JavaScript engine, Mozilla browsers have been regarded as slower than their WebKit or Opera brethren. The overpowering reason that Firefox is so successful is the ability to extend the browser with XUL; if performance was the only reason people choose browsers, Opera would have cleaned up the competition years ago.

There is only XUL

XUL (XML User Interface Language) is what allows Firefox to be so extensible. The useful part of the specification to extension developers is that XUL allows you to overwrite (or overlay) parts of the UI with your own code.

There's plenty of documentation for XUL on its project page. But enough background, it's time to get straight into creating extensions.

Essential details

First thing that we are going to need is a reason to have an extension. I'm going to attempt to reproduce the start-up page that appears in Chrome/Opera with the nine most visited sites appearing as thumbnails in a page.

Next we'll need a name for the extension, I'll choose to call it chromenewtab, as I want this extension to create a new tab with the most visited sites in it every time that the extension is invoked.

Now we need to create a directory called chromenewtab, which will hold all versions of our code, and within it we'll create a directory called chromenewtab-0.1.

install.rdf

Every extension needs an install.rdf file to provide metadata about the extension. Inside the chromenewtab-0.1 directory, create an install.rdf file and put the following information:

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  <Description about>urn:mozilla:install-manifest">
                   <em:id>chromenewtab@builderau.com.au</em:id>
                   <em:version>0.1</em:version>
                   <em:type>2</em:type>
                   <em:name>Chrome-like New Tab</em:name>
                   <em:description>A new tab interface like Opera, which Chrome then "borrowed"</em:description>
                   <em:creator>Chris Duckett</em:creator>
                   <em:homepageURL>http://www.builderau.com.au/labs/cnt/chromenewtab.htm</em:homepageURL>
                   <em:iconURL>chrome://chromenewtab/skin/icon.png</em:iconURL>
                   <em:updateURL>http://www.builderau.com.au/labs/cnt/update.htm</em:updateURL>
                   <em:targetApplication>
                      <Description>
                        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                        <em:minVersion>3.0</em:minVersion>
                        <em:maxVersion>3.*</em:maxVersion>
                      </Description>
                  </em:targetApplication>
  <Description>
</RDF>

The above XML needs some explanation:

  • The first bit can be taken as information that is needed:
     <?xml version="1.0"?>
    <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
      <Description about>urn:mozilla:install-manifest">
  • The id of an extension must be unique. Prior to Firefox 1.5 it had to be a GUID, but nowadays you can use an email-like format. The suggested formatting is extensionname@organisation.tld.
  • The type property is 2, as that is what Firefox expects for extensions.
  • The name property is the name that will appear in the Add-Ons dailog within Firefox.
  • updateURL is needed if we wish to update the extension -- which given that our final code will not be feature complete and probably has bugs, we will need. If you host your extension on addons.mozilla.org, you do not need this property.
  • targetApplication specifies which Mozilla applications and the versions of them to target. {ec8030f7-c20a-464f-9b0e-13a3a9e97384} is the id for Firefox and we are targeting from version 3.0 to any version of the Firefox 3 series. If we wish to restrict the extension to the Firefox 3.0.x branch, we would use:
    <em:minVersion>3.0</em:minVersion>
    <em:maxVersion>3.0.*</em:maxVersion>
  • Version, description, creator and homepageURL should all be self-explanatory.
  • iconURL is the 32x32 icon that will be shown on the Add-Ons dialog, it uses a chrome:// protocol address, which will be explained in the next section.

chrome.manifest

Inside the chromenewtab-0.1 folder, we need to create a chrome.manifest file and paste in the following:

content         chromenewtab chrome/content/
skin            chromenewtab classic chrome/skin/
overlay         chrome://browser/content/browser.xul chrome://chromenewtab/content/overlay.xul
style           chrome://global/content/customizeToolbar.xul    chrome://chromenewtab/content/chromenewtab.css

The first line tells Firefox that a content package named chromenewtab will have its content directory linked to the chrome/content directory within the package -- so that chrome://content/ will link to chromenewtab-0.1/chrome/content/.

Similarly the next line links chrome://skin to chromenewtab-0.1/chrome/skin/ with the addition of classic telling Firefox to make it part of the theme named classic.

For the manifest to make any sense though, we will need to create the directories and files to which we refer. Inside of the chromenewtab-0.1 folder, we run the following commands in a terminal (Linux and OS X only -- on Windows create the directories and empty files however you choose).

mkdir -p chrome/content
mkdir -p chrome/skin
touch chrome/content/overlay.xul
touch chrome/content/overlay.js
touch chrome/content/chromenewtab.css

The last two lines in the chrome.manifest tell Firefox that it should merge our overlay.xul with Firefox's own browser.xul. It is via these overlays that extensions do the things that they want to do.

overlay.xul

Now that the groundwork is complete, it's time to actually make our extension do things.

Copy into the overlay.xul file the following code:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="chrome://chromenewtab/content/chromenewtab.css"?>

<!DOCTYPE overlay >
<overlay id="chromenewtab-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<script type="application/x-javascript" src="chrome://chromenewtab/content/chromenewtab.js"/>

<toolbarpalette id="BrowserToolbarPalette">
  <toolbarbutton id="custom-button-1"
  label="New Tab with Chrome-like bookmarks"
  tooltiptext="New Tab with Chrome-like bookmarks"
  oncommand="create_chromenewtab()"
  class="toolbarbutton-1 chromeclass-toolbar-additional chromenewtabbutton"
/>
</toolbarpalette>
</overlay>

In this file, we are telling Firefox that we are going to create a toolbar button and style it with the CSS in chromenewtab.css, and the method to perform when the button is pressed is found in chromenewtab.js.

Before we look at the CSS, we need to add the images we will use. Copy the below images into the skin directory.

This is the icon image that will appear in the Add-Ons dialog:

Below is the image that we will use on our toolbar:

Now we can add the stylings -- add the following code to chromenewtab.css:

 #chromenewtab-button
  {list-style-image: url("chrome://chromenewtab/skin/chromenewtab_button.png");}

/* common style for all custom buttons */
.chromenewtabbutton                  
  {-moz-image-region: rect( 0px 24px 24px  0px);}

.chromenewtabbutton:hover     
  {-moz-image-region: rect(24px 24px 48px  0px);}

[iconsize="small"] .chromenewtabbutton
  {-moz-image-region: rect( 0px 40px 16px 24px);}

[iconsize="small"] .chromenewtabbutton:hover
  {-moz-image-region: rect(24px 40px 40px 24px);}
All the CSS does, is restrict the size of the region shown in our button image. Hover images being on the bottom row, default icon sizes on the left and small icon images on the right. Now we need to add some functionality to the button. All we'll do in the first instance, is create an alert so that we know that everything is behaving as it should. Add the following code to overlay.js
function create_chromenewtab() {
  alert("Do stuff here");
}

Do you need help with XML? Gain advice from Builder AU forums

Comments

1

Edward - 23/05/09

I wish i could stay on the topic! I can't change my theme on my sisters web page. It says java script void! Everyone else can , but i can't can someone hepl me at this ?

» Report offensive content

Leave a comment

You must read and type the 6 chars within 0..9 and A..F

* indicates mandatory fields.

1

Edward - 23/05/09

I wish i could stay on the topic! I can't change my theme on my sisters web page. It says java ... more

Log in


Sign up | Forgot your password?

  • Staff Aussies to pay more for Win 7

    If you are looking to make some money in these troubled times, perhaps importing copies of Windows 7 could be for you. Read more »

    -- posted by Staff

  • Staff Firefox: Greens want it, 3.5rc2 not up to par

    This week's roundup looks at the situation surrounding a campaign to change Outlook HTML renderer, a Greens MP wants to install Firefox but is restricted and all the photos from the iPhone 3GS launch. Read more »

    -- posted by Staff

  • Chris Duckett Microsoft misses the Outlook point

    Ask designers which mail program is the bane of their existence, and you'll find that Outlook tops the list. The reason why the most popular email reader is also the most painful is simple: it uses Word to render HTML emails. Read more »

    -- posted by Chris Duckett

What's on?