firefox toolbar tutorial

48
Table of Contents Chapter 1: Getting Started Before We Start Tools You Will Need File Structure Layout Chapter 2: Creating the Framework Installer Manifest Chrome Manifest Chapter 3: Structuring the Toolbar The Toolbox and Toolbar Toolbar Buttons Drop Down Edit Box Resizing Gripper Chapter 4: Dynamic Development A Word of Warning How to Develop Dynamically The Development Process Chapter 5: Skinning the Toolbar Updating the File Structure Updating the Chrome Manifest Creating the Image Files Applying the Images with CSS Using the Style Sheet Chapter 6: Scripting the Toolbar Tying XUL to JavaScript Adding Functionality to the Buttons Adding Functionality to the Search Box Dynamically Populating a Menu Dynamically Adding Toolbar Buttons Disabling and Enabling Buttons Dynamically Showing and Hiding Buttons Reading and Storing User Preferences

Upload: mukesh-kumar

Post on 21-Apr-2015

65 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Firefox Toolbar Tutorial

Table of Contents

Chapter 1: Getting Started

Before We Start Tools You Will Need File Structure Layout

Chapter 2: Creating the Framework

Installer Manifest Chrome Manifest

Chapter 3: Structuring the Toolbar

The Toolbox and Toolbar Toolbar Buttons Drop Down Edit Box Resizing Gripper

Chapter 4: Dynamic Development

A Word of Warning How to Develop Dynamically The Development Process

Chapter 5: Skinning the Toolbar

Updating the File Structure Updating the Chrome Manifest Creating the Image Files Applying the Images with CSS Using the Style Sheet

Chapter 6: Scripting the Toolbar

Tying XUL to JavaScript Adding Functionality to the Buttons Adding Functionality to the Search Box Dynamically Populating a Menu Dynamically Adding Toolbar Buttons Disabling and Enabling Buttons Dynamically Showing and Hiding Buttons Reading and Storing User Preferences

Chapter 7: Packaging the Toolbar

Updating the Chrome Manifest Creating the JAR File Creating the XPI File Test Installing Your Extension Speeding Up the Packaging Process Ant Support

Page 2: Firefox Toolbar Tutorial

Chapter 8: Testing Our Extension

What to Do if Firefox Breaks Useful Browser Settings Logging to the JavaScript Console Logging to the Standard Console The DOM Inspector

Chapter 1: Getting Started

Before We StartThere are a number of highly useful items that you need to be aware of before we begin making our first Firefox toolbar extension.

Tutorial Downloads

Throughout the course of this tutorial, we will be creating a skeleton version of Googlebar Lite. To aid in the learning process, a working version of this toolbar is available for you to download. There are two files available:

Example Toolbar XPI : This is the installable version of the toolbar we will create. Example Toolbar Source Code : This zip file contains all of the source files used to create the

above toolbar.

Note that the XPI file also contains the source code (as we will learn a little later), so you technically only need to download that one file. The second file is provided for the sake of convenience.

Useful References

I highly recommend that you bookmark the following sites. They were incredibly helpful to me as I learned about extension development, and I am sure that you will find them helpful as well.

XUL Hub at the Mozilla Developer’s Center MozillaZine Extension Development Forum Search the Firefox Source Code roachfiend.com Extension Tutorial

Learning the Prerequisites

As I previously mentioned, extension development in Firefox requires that you know a little about XML, JavaScript, and CSS. Each of these topics are fairly easy to pick up on your own. I have provided here a few tutorials covering each of these topics.

Learn XML Learn JavaScript Learn CSS

Tools You Will NeedSeveral software tools are required to create a Firefox extension, and all of them are freely available. Every file that we work with (except for images) will be a plain text file. As such, you

Page 3: Firefox Toolbar Tutorial

will need a good text editor. I recommend against using a word processor like Microsoft Word. There are a number of excellent “programmer” text editors available for free on the web, which will help you out tremendously with features like automatic indentation, syntax highlighting, and more. Several popular editors include Crimson Editor, TextPad, and JCreator.

The second tool you need is a zip-file utility. I personally use WinZip, although there are plenty of others available (7-Zip, WinRAR, etc.). We will make use of our zip tool when packaging our extension. If you plan on doing a lot of extension development, I recommend you find a zip-file tool that has a command line interface. Using the command line will allow you to easily automate the packaging process, which will save you a tremendous amount of time.

File Structure LayoutFirefox extensions require a specific internal structure, so we need to make sure that we get this step right. Otherwise, things will not work the way they should. First, let us create a top-level folder with the name of our extension. For this tutorial, we will use the name TutToolbar (let’s avoid using spaces in the name). Inside of this newly created folder, we need to create a second folder. This one should be named chrome (using all lowercase letters). Since we are having so much fun creating folders, let’s create a third one, this time inside of the chrome folder we just created. Name this one content (again, using all lowercase letters). Here is how our directory structure looks at this point in time:

+- TutToolbar/ +- chrome/ +- content/

------------------------------------------------------------------------------

Chapter 2: Creating the FrameworkAn extension’s framework is used to tell Firefox about the extension: how its files are structured, who created it, its GUID, etc. Beginning with Firefox 1.5, this area of extension development changed greatly. The old mechanisms used by Firefox 1.0.x were clunky at best; the new means of creating the framework is much simpler.

Installer ManifestThe installer manifest is how we provide details on our extension to Firefox. There are some important items that are placed in this file, so we need to make sure we get this right. Create a new file in your top level folder, and give it the name install.rdf. Here is how the directory structure should look once you’ve created the file:

+- TutToolbar/ +- install.rdf +- chrome/ +- content/

Before we begin working with our installer manifest, let us take a look at a sample. All of the data which we will need to edit has been highlighted, while all the data we must not edit is displayed in plain text. After we look at the file’s contents, I will explain each piece in detail (and we can begin creating our own).

<?xml version="1.0"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

Page 4: Firefox Toolbar Tutorial

xmlns:em="http://www.mozilla.org/2004/em-rdf#">

<Description about="urn:mozilla:install-manifest">

<!-- Required Items --> <em:id>[email protected]</em:id> <em:name>Your Extension's Name</em:name> <em:version>1.0</em:version>

<em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>3.0.*</em:maxVersion> </Description> </em:targetApplication>

<!-- Optional Items --> <em:creator>Your Name</em:creator> <em:description>A description of the extension</em:description> <em:homepageURL>http://www.yoursite.com/</em:homepageURL>

</Description></RDF>

The first line above indicates that this is nothing more than an XML file. The second line, which begins with the opening <RDF> tag, is the root element of the document. Its responsibility is to identify this as an RDF (Resource Description Framework) file. The next tag (<Description>) likewise identifies this is an installer manifest. Now that all of the boilerplate is out of the way, let’s look at the first part of what we need to edit (all of which is required):

<em:id>[email protected]</em:id><em:name>Your Extension's Name</em:name><em:version>1.0</em:version>

The first thing we need to worry about is the extension ID. Prior to Firefox 1.5, an extension’s ID had to be specified using a globally unique identifier (GUID). Although GUID’s are still supported, the new format is much easier to use. Simply use the name of your extension (all one word), an @ symbol, and the URL to the top level domain of your website. For the toolbar we are building in this tutorial, let’s use the value [email protected].

Next up is the extension’s name (as it will appear in the Extension Manager). For our example, let’s use the name Toolbar Tutorial. Make sure that you do not include the version number as a part of this name, because the version number has its own tag. That tag happens to be the next one we need to edit. Since this is our first attempt at a toolbar extension, let’s use the value of 1.0. Keep in mind that, in the real world, you need to update this value each time you release an updated version of your extension. Scripters should have no problem writing a small program to automate the version updating process. I utilize such a script (written in Perl) for all of my extensions. In chapter 7 of this tutorial, I will show you how I do it.

The next block of code in this file, which is also required, is one of the most important pieces of the installer manifest. Let’s take a look at it now:

<em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>3.0.*</em:maxVersion> </Description></em:targetApplication>

Page 5: Firefox Toolbar Tutorial

This block is responsible for saying what application our extension is intended for. In our case, we are developing an extension for Firefox. As such, the value within the <em:id> element specifies the Firefox GUID. You should not change this value! Doing so will prevent your extension from installing correctly.

The only two sections in this block that we need to touch are the <em:minVersion> and <em:maxVersion> elements. These two elements specify what versions of Firefox our extension should be compatible with (the minVersion being the lowest supported version, and the maxVersion being the highest supported version). For our example, we will be using the value 1.5 for the minVersion and 3.0.* for the maxVersion. Because we are making use of extension development improvements available only in Firefox 1.5, we cannot set the the minVersion value to less than 1.5; otherwise we would have to throw out all of the improvements that we now have available to us.

Note that the version values you use for these two elements must follow a standard convention. For example, a value of "1.5 Release Candidate 1" will not suffice. The current Firefox versioning scheme is fairly strict, and is detailed in the Toolkit Version Format article at the Mozilla Developer Center. I recommend you read the article, to get a feel for what version strings are (and are not) allowed. Also, be sure to take a look at the valid application versions document at the Mozilla add-ons website. This document lists all of the "officially approved" version strings.

The rest of our installer manifest is simply meta-data that describes our extension:

<!-- Optional Items --><em:creator>Your Name</em:creator><em:description>A description of the extension</em:description><em:homepageURL>http://www.yoursite.com/</em:homepageURL>

As the comment suggests, all of these elements are optional. I have chosen three elements to use for this tutorial. The first element, <em:creator>, allows the extension author to specify his name (so that others will know who created the extension). Next, the <em:description> element allows us to provide a short description of our extension. This description will appear in the Extension Manager, underneath our extension’s name. Finally, the <em:homepageURL> element allows us to specify where people can find our extension on the web.

Note that these aren’t the only meta-data elements available to us; a number of other optional ones also exist. For example, there is an element to let us use our own icon in the Extension Manager. Another element allows us to specify the location of a custom options or about dialog. For an entire list of the available elements (they are also known as properties), take a look at the Installer Manifests article at the Mozilla Developer Center. And one final note: all of these elements are not order dependent. In other words, you can place them in any order you like in this file; they simply have to be direct descendants of the first <Description> element that we created.

Now that we know about the installer manifest, let’s take a look at our finalized version, which we will be using in this tutorial. Feel free to copy the code below and place it in the install.rdf file that we created moments ago.

<?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">

<!-- Required Items --> <em:id>[email protected]</em:id> <em:name>Tutorial Toolbar</em:name> <em:version>1.0</em:version>

<em:targetApplication>

Page 6: Firefox Toolbar Tutorial

<Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>3.0.*</em:maxVersion> </Description> </em:targetApplication>

<!-- Optional Items --> <em:creator>Jonah Bishop</em:creator> <em:description>An example toolbar extension.</em:description> <em:homepageURL>http://www.borngeek.com/firefox/</em:homepageURL>

</Description></RDF>

Chrome ManifestThe chrome manifest is new to Firefox 1.5. Previously, all of the data contained in this file appeared in two places: some of it in the installer manifest, and other portions in a contents.rdf file. The new format is much simpler. Create another file, again in the top level folder, and name it chrome.manifest. Here is how our directory structure should now look:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/

A chrome manifest is how we tell Firefox what packages and overlays our extension provides. Let us again take a look at a sample file before we begin creating our own:

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

locale myextension en-US chrome/locale/en-US/

skin myextension classic/1.0 chrome/skin/

Compared to the old contents.rdf file (which was usually on the order of 20 lines long), this is incredibly simple! The first line registers a content package using the package name you specify (the above sample uses myextension), as well as the location to the content folder. Note that the package name must use lowercase letters; a mixed case package name is not allowed (nor is all uppercase). This first line allows chrome s like chrome://myextension/content/ to point to the appropriate place in our extension’s hierarchy. Note that the content folder’s location is relative to the root folder of our extension. For our tutorial, we will use a package name of tuttoolbar. The rest of the data shown will stay the same.

The second line registers an overlay for chrome://browser/content/browser.xul. This allows you to add to or modify the user interface in the main Firefox window. In the sample above, the file used as the overlay is specified by chrome://myextension/content/overlay.xul. In other words, the file overlay.xul located in our extension’s content folder is how we will be adding our new user interface controls (our toolbar). The overlay value we will be using for this tutorial is chrome://tuttoolbar/content/tuttoolbar.xul.

The next line demonstrates how a locale can be created. We will not be creating a locale in this tutorial (although it’s a very simple process). The final line sets up a skin, the mechanism we will

Page 7: Firefox Toolbar Tutorial

use to make our toolbar look pretty. For now, let’s ignore it (we will come back to this in chapter 5).

That was easy, wasn’t it? Below is the final chrome manifest we will use for our tutorial (well, it’s the semi-final version; we’ll come back and add skinning information later). Again, feel free to copy the code below and paste it into the chrome manifest file we created moments ago:

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

Now that the framework is in place, let’s have some fun creating our toolbar!

----------------------------------------------------------------------------------------------------------------------

Chapter 3: Structuring the ToolbarThe user interface portion of a Firefox extension is created using XUL (pronounced "zool"), a markup language used in creating user interfaces. XUL can be thought of as a flavor of XML, simply because XUL is nothing more than XML that makes use of predefined elements (also called widgets). The beauty of XUL comes through the use of what it calls dynamic overlays. A dynamic overlay allows a developer to modify the behavior of a window’s user interface, without having to change the original interface’s code. Not having to change the code base allows us to focus on our extension, rather than having to worry about reinventing the wheel.

In this chapter of the tutorial, we will take a look at the necessary XUL markup required to create a toolbar. Keep in mind that XUL is simply how we structure our toolbar. To make our toolbar actually do something, we need to make use of JavaScript, which is the subject of the chapter 6. But we’re getting ahead of ourselves. Let’s start creating our example toolbar.

Create a file in the content directory of our extension’s file structure, and name it tuttoolbar.xul. After you create this file, the directory structure should look like the following:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul

Now that we’ve created the file, we can begin discussing the contents line by line. As we go along, I will provide sample XUL files at each step, showing the entire file’s contents. This should make it easier to see what’s going on. By the end of this chapter, our XUL file will be quite robust.

Because XUL is simply an XML flavor, the first line of the file needs to be the XML declaration:

<?xml version="1.0"?>

Now that we have declared this an XML file, we can begin to create the overlay itself. We do so by creating an overlay element. This element will be the root element of the entire document. In other words, everything else we place in this file must be a child of this element (between the opening and closing tags). Here’s how our overlay element will look:

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

This element has two attributes: id and xmlns. As those familiar with HTML will already know, the value of the id attribute must be unique. And what may be more surprising is that it must be unique across the entire browser system. There are a number of strategies that you can employ to

Page 8: Firefox Toolbar Tutorial

make sure that your ID’s are unique. In the example above, you will note that I used the TutTB- prefix in the id attribute’s value. Choosing a prefix that corresponds to your extension’s name will help improve the odds that your ID’s will be unique. Also note that the actual value need not include the word "overlay"; I simply do that to help me keep track of what element is what.

The second attribute in this element, xmlns, specifies the XML namespace that will be used in the overlay. Since this is a XUL document, we must point to the XUL namespace definition. The value shown is the value you should always use.

The Toolbox and ToolbarAll toolbars in Firefox should live within a toolbox. We specify a toolbox using the aptly named toolbox element like so (remember that this element gets placed inside the overlay element we created moments ago):

<toolbox id="navigator-toolbox"></toolbox>

Note that the id attribute here has a predefined value: navigator-toolbox. This special value represents the primary toolbox element in the Firefox window, which houses the navigation toolbar, menu bar, URL bar, and other similar controls. By specifying this particular toolbox, we ensure that our toolbar will show up alongside all of the others. I recommend that you always place your toolbars within this particular toolbox. Not only will you be consistent with the standard toolbars, but your custom toolbar gets added to the View » Toolbars menu, allowing you to quickly hide or show it (a very handy feature you get for free).

Let us now turn our attention to the toolbar element, which we will place inside the toolbox we just specified. Here’s how our element looks:

<toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"></toolbar>

Let’s take a look at the new attributes in this element:

toolbarname - This attribute specifies the name of our toolbar (that is, the text that a user will see in the View » Toolbars menu).

accesskey - Specifies the letter in the toolbar name (that we just specified) which will be underlined for use as a keyboard access key. For this tutorial toolbar, we will use the capital letter T. Note that although this is an optional attribute, it is highly recommended that you make use of it (so that users who only make use of the keyboard will be able to toggle your toolbar’s visibility).

class - Specifies the particular style class to apply to the toolbar. The predefined value shown (chromeclass-toolbar) is the class used for the standard Firefox toolbar look and feel. Again, this is an optional, but recommended, attribute.

context - Specifies the context menu that we want to display when the user right-clicks our toolbar. You can provide the ID of your own menu here, or you can provide the value for the standard View » Toolbars menu, which is shown in the example above (toolbar-context-menu).

hidden - Specifies whether or not the toolbar should be hidden. By default, we want our toolbar to be visible to the user, so we set the value to false.

persist - This attribute is a space separated list of attributes that should persist across browser sessions. In the example shown above, I have provided a value of "hidden", telling Firefox that it should remember the hidden state of our toolbar between sessions. Note that if

Page 9: Firefox Toolbar Tutorial

your toolbar element does not have an id attribute set, the persist attribute will not work! So make sure you have specified an id for your toolbar element.

You can find a complete reference on all of the toolbar element’s attributes at the Mozilla Developer Center.

Let us now take a look at the XUL overlay we have created so far: [View XUL Overlay Revision 1]

Toolbar ButtonsToolbar buttons have three flavors in Firefox: normal, menu, and button-menu. These flavors are all created using the same toolbarbutton element. Let’s examine each one individually. Keep in mind that these elements get placed within the toolbar element that we just created.

Normal Buttons

Here is the XUL markup used to create your standard, run-of-the-mill toolbar button:

<toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" />

As we have been doing, let’s take a look at this element’s new attributes:

tooltiptext - Specifies what the tooltip will say when the user hovers their mouse pointer over the button.

label - Specifies the text to be displayed on the toolbar button itself. oncommand - Specifies what code you want to execute when the oncommand event is

fired (i.e. the toolbar button is clicked/activated). In this example, we call the TutTB_Search() function. We will discuss this function in greater detail in chapter 6 of this tutorial.

You can find a complete reference on the toolbarbutton element’s attributes at the Mozilla Developer’s Center.

Menu Buttons

The second button flavor, the menu button, displays a drop-down menu when it is clicked. Although the markup for this button is similar to the normal button’s markup, we must add an embedded menupopup element to represent the menu that we want to show. For the sake of brevity, the following example only contains two menu items.

<toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" />

<menuseparator />

<menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup></toolbarbutton>

The toolbarbutton element has had two significant changes made to it. First is the new type attribute which, in our example, has been given a value of "menu" (specifying that this is a menu

Page 10: Firefox Toolbar Tutorial

button, not a normal button). Second, you will notice that there is no oncommand attribute, as there was with the normal button. Because a menu button’s sole purpose in life is to display a popup menu, there is no need for it to execute any code (showing the menu will be handled automatically by Firefox).

Also note the new menupopup, menuitem, and menuseparator elements. The menupopup element is a container into which all menu items go, and is responsible for creating and displaying the actual menu. In the example, this element has no attributes. Likewise, the menuseparator element is very simple: it simply places a horizontal separator in the drop-down menu (to help visually separate different menu regions).

The menuitem element is somewhat more complex. Here are the new attributes we specified in the above example:

label - Specifies the text to be displayed for the menu item. tooltiptext - This attribute is exactly the same as we saw with the toolbarbutton

element earlier, but there is one caveat. Due to an unfortunate bug in Firefox (bug #147670), this attribute is rather necessary. If you decide to omit this attribute from the menuitem element, be warned that an empty tooltip box will appear when the user hovers their mouse over the menu item. Because menus do not traditionally have tooltips, this is an unpleasant ‘feature’.

You can find a complete reference on the menuitem element’s attributes at the Mozilla Developer’s Center.

Button-Menu Buttons

The third and final button flavor, the "button-menu" button, is the most complex of the three. It essentially combines the ideas from the previous two flavors, providing both a clickable button region as well as a drop-down menu. The backward and forward navigation buttons are examples of this type of button. Here’s the markup required to create one:

<toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.stopPropagation();" />

<menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.stopPropagation();" /> </menupopup></toolbarbutton>

There are two notable changes between the markup for this button type and the previous two: the type attribute in the toolbarbutton element has been given a value of menu-button, and there’s an extra line of code in the oncommand attribute. I will explain what that extra code is responsible for in chapter 6. Note that the toolbarbutton element has an oncommand attribute, just like normal buttons do, and it includes all of the nested menupopup and menuitem elements that we saw with the menu button.

Now that we have discussed the various button flavors, let’s again take a look at our XUL overlay file: [View XUL Overlay Revision 2]. In this sample, I have ordered the buttons differently than we discussed them in the text above: the menu button appears first, the button-menu button second, and

Page 11: Firefox Toolbar Tutorial

the normal button third. Otherwise, everything is exactly as it is shown above.

Drop-Down Edit BoxThe next item we will add to our toolbar is a drop-down edit box. This type of control is created using the menulist element, and the markup looks like this:

<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist></toolbaritem>

Note that we have surrounded the menulist element with a toolbaritem element. Any item you place within a toolbar that is not a toolbarbutton, should be wrapped in a toolbaritem element. Also note that we have specified an id for the toolbaritem element, and we have asked it to remember its width (through the use of the persist attribute). More on why we do this in a moment.

The menulist element is what actually creates the drop-down edit box. There are a few new attributes shown within the markup for this element:

editable - When set to true, the user can type inside the edit box. flex - Indicates that this element is flexible. The value is an integer specifying the relative

"flexibility" of the element in relation to other toolbar elements. A element with a flex value of 2 will therefore try to become twice as wide as an element with a flex value of 1. A value of 0 indicates that the element can not flex (it is fixed width).

minwidth - Specifies the minimum allowable width of this element, in pixels. width - Specifies the initial width of this element, in pixels. onkeypress - Specifies the code to be executed when the user presses a key within the

element (i.e. typing in the edit box).

You can find a complete reference on the menulist element’s attributes at the Mozilla Developer’s Center.

Within the menulist element is a menupopup element. As with the menu button we looked at earlier, the menupopup is the container that will hold all of our menuitem elements. The onpopupshowing event is fired right before the drop-down box is shown to the user. The code snippet shown is a function that we will write to dynamically populate the menu with items, something we will discuss later in the tutorial. You can add static menu items if you like; the process is exactly the same as for the menu button earlier.

Let’s take another look at our XUL overlay at this point: [View XUL Overlay Revision 3]. Our extension is really starting to take shape!

Chapter 3: Structuring the ToolbarThe user interface portion of a Firefox extension is created using XUL (pronounced "zool"), a markup language used in creating user interfaces. XUL can be thought of as a flavor of XML, simply because XUL is nothing more than XML that makes use of predefined elements (also called widgets). The beauty of XUL comes through the use of what it calls dynamic overlays. A dynamic

Page 12: Firefox Toolbar Tutorial

overlay allows a developer to modify the behavior of a window’s user interface, without having to change the original interface’s code. Not having to change the code base allows us to focus on our extension, rather than having to worry about reinventing the wheel.

In this chapter of the tutorial, we will take a look at the necessary XUL markup required to create a toolbar. Keep in mind that XUL is simply how we structure our toolbar. To make our toolbar actually do something, we need to make use of JavaScript, which is the subject of the chapter 6. But we’re getting ahead of ourselves. Let’s start creating our example toolbar.

Create a file in the content directory of our extension’s file structure, and name it tuttoolbar.xul. After you create this file, the directory structure should look like the following:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul

Now that we’ve created the file, we can begin discussing the contents line by line. As we go along, I will provide sample XUL files at each step, showing the entire file’s contents. This should make it easier to see what’s going on. By the end of this chapter, our XUL file will be quite robust.

Because XUL is simply an XML flavor, the first line of the file needs to be the XML declaration:

<?xml version="1.0"?>

Now that we have declared this an XML file, we can begin to create the overlay itself. We do so by creating an overlay element. This element will be the root element of the entire document. In other words, everything else we place in this file must be a child of this element (between the opening and closing tags). Here’s how our overlay element will look:

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

This element has two attributes: id and xmlns. As those familiar with HTML will already know, the value of the id attribute must be unique. And what may be more surprising is that it must be unique across the entire browser system. There are a number of strategies that you can employ to make sure that your ID’s are unique. In the example above, you will note that I used the TutTB- prefix in the id attribute’s value. Choosing a prefix that corresponds to your extension’s name will help improve the odds that your ID’s will be unique. Also note that the actual value need not include the word "overlay"; I simply do that to help me keep track of what element is what.

The second attribute in this element, xmlns, specifies the XML namespace that will be used in the overlay. Since this is a XUL document, we must point to the XUL namespace definition. The value shown is the value you should always use.

The Toolbox and ToolbarAll toolbars in Firefox should live within a toolbox. We specify a toolbox using the aptly named toolbox element like so (remember that this element gets placed inside the overlay element we created moments ago):

<toolbox id="navigator-toolbox"></toolbox>

Note that the id attribute here has a predefined value: navigator-toolbox. This special value

Page 13: Firefox Toolbar Tutorial

represents the primary toolbox element in the Firefox window, which houses the navigation toolbar, menu bar, URL bar, and other similar controls. By specifying this particular toolbox, we ensure that our toolbar will show up alongside all of the others. I recommend that you always place your toolbars within this particular toolbox. Not only will you be consistent with the standard toolbars, but your custom toolbar gets added to the View » Toolbars menu, allowing you to quickly hide or show it (a very handy feature you get for free).

Let us now turn our attention to the toolbar element, which we will place inside the toolbox we just specified. Here’s how our element looks:

<toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"></toolbar>

Let’s take a look at the new attributes in this element:

toolbarname - This attribute specifies the name of our toolbar (that is, the text that a user will see in the View » Toolbars menu).

accesskey - Specifies the letter in the toolbar name (that we just specified) which will be underlined for use as a keyboard access key. For this tutorial toolbar, we will use the capital letter T. Note that although this is an optional attribute, it is highly recommended that you make use of it (so that users who only make use of the keyboard will be able to toggle your toolbar’s visibility).

class - Specifies the particular style class to apply to the toolbar. The predefined value shown (chromeclass-toolbar) is the class used for the standard Firefox toolbar look and feel. Again, this is an optional, but recommended, attribute.

context - Specifies the context menu that we want to display when the user right-clicks our toolbar. You can provide the ID of your own menu here, or you can provide the value for the standard View » Toolbars menu, which is shown in the example above (toolbar-context-menu).

hidden - Specifies whether or not the toolbar should be hidden. By default, we want our toolbar to be visible to the user, so we set the value to false.

persist - This attribute is a space separated list of attributes that should persist across browser sessions. In the example shown above, I have provided a value of "hidden", telling Firefox that it should remember the hidden state of our toolbar between sessions. Note that if your toolbar element does not have an id attribute set, the persist attribute will not work! So make sure you have specified an id for your toolbar element.

You can find a complete reference on all of the toolbar element’s attributes at the Mozilla Developer Center.

Let us now take a look at the XUL overlay we have created so far: [View XUL Overlay Revision 1]

Toolbar ButtonsToolbar buttons have three flavors in Firefox: normal, menu, and button-menu. These flavors are all created using the same toolbarbutton element. Let’s examine each one individually. Keep in mind that these elements get placed within the toolbar element that we just created.

Normal Buttons

Here is the XUL markup used to create your standard, run-of-the-mill toolbar button:

<toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" />

Page 14: Firefox Toolbar Tutorial

As we have been doing, let’s take a look at this element’s new attributes:

tooltiptext - Specifies what the tooltip will say when the user hovers their mouse pointer over the button.

label - Specifies the text to be displayed on the toolbar button itself. oncommand - Specifies what code you want to execute when the oncommand event is

fired (i.e. the toolbar button is clicked/activated). In this example, we call the TutTB_Search() function. We will discuss this function in greater detail in chapter 6 of this tutorial.

You can find a complete reference on the toolbarbutton element’s attributes at the Mozilla Developer’s Center.

Menu Buttons

The second button flavor, the menu button, displays a drop-down menu when it is clicked. Although the markup for this button is similar to the normal button’s markup, we must add an embedded menupopup element to represent the menu that we want to show. For the sake of brevity, the following example only contains two menu items.

<toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" />

<menuseparator />

<menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup></toolbarbutton>

The toolbarbutton element has had two significant changes made to it. First is the new type attribute which, in our example, has been given a value of "menu" (specifying that this is a menu button, not a normal button). Second, you will notice that there is no oncommand attribute, as there was with the normal button. Because a menu button’s sole purpose in life is to display a popup menu, there is no need for it to execute any code (showing the menu will be handled automatically by Firefox).

Also note the new menupopup, menuitem, and menuseparator elements. The menupopup element is a container into which all menu items go, and is responsible for creating and displaying the actual menu. In the example, this element has no attributes. Likewise, the menuseparator element is very simple: it simply places a horizontal separator in the drop-down menu (to help visually separate different menu regions).

The menuitem element is somewhat more complex. Here are the new attributes we specified in the above example:

label - Specifies the text to be displayed for the menu item. tooltiptext - This attribute is exactly the same as we saw with the toolbarbutton

element earlier, but there is one caveat. Due to an unfortunate bug in Firefox (bug #147670), this attribute is rather necessary. If you decide to omit this attribute from the menuitem element, be warned that an empty tooltip box will appear when the user hovers their mouse over the menu item. Because menus do not traditionally have tooltips, this is an unpleasant

Page 15: Firefox Toolbar Tutorial

‘feature’.

You can find a complete reference on the menuitem element’s attributes at the Mozilla Developer’s Center.

Button-Menu Buttons

The third and final button flavor, the "button-menu" button, is the most complex of the three. It essentially combines the ideas from the previous two flavors, providing both a clickable button region as well as a drop-down menu. The backward and forward navigation buttons are examples of this type of button. Here’s the markup required to create one:

<toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.stopPropagation();" />

<menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.stopPropagation();" /> </menupopup></toolbarbutton>

There are two notable changes between the markup for this button type and the previous two: the type attribute in the toolbarbutton element has been given a value of menu-button, and there’s an extra line of code in the oncommand attribute. I will explain what that extra code is responsible for in chapter 6. Note that the toolbarbutton element has an oncommand attribute, just like normal buttons do, and it includes all of the nested menupopup and menuitem elements that we saw with the menu button.

Now that we have discussed the various button flavors, let’s again take a look at our XUL overlay file: [View XUL Overlay Revision 2]. In this sample, I have ordered the buttons differently than we discussed them in the text above: the menu button appears first, the button-menu button second, and the normal button third. Otherwise, everything is exactly as it is shown above.

Drop-Down Edit BoxThe next item we will add to our toolbar is a drop-down edit box. This type of control is created using the menulist element, and the markup looks like this:

<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist></toolbaritem>

Note that we have surrounded the menulist element with a toolbaritem element. Any item you place within a toolbar that is not a toolbarbutton, should be wrapped in a toolbaritem element. Also note that we have specified an id for the toolbaritem element, and we have asked it to remember its width (through the use of the persist attribute). More on

Page 16: Firefox Toolbar Tutorial

why we do this in a moment.

The menulist element is what actually creates the drop-down edit box. There are a few new attributes shown within the markup for this element:

editable - When set to true, the user can type inside the edit box. flex - Indicates that this element is flexible. The value is an integer specifying the relative

"flexibility" of the element in relation to other toolbar elements. A element with a flex value of 2 will therefore try to become twice as wide as an element with a flex value of 1. A value of 0 indicates that the element can not flex (it is fixed width).

minwidth - Specifies the minimum allowable width of this element, in pixels. width - Specifies the initial width of this element, in pixels. onkeypress - Specifies the code to be executed when the user presses a key within the

element (i.e. typing in the edit box).

You can find a complete reference on the menulist element’s attributes at the Mozilla Developer’s Center.

Within the menulist element is a menupopup element. As with the menu button we looked at earlier, the menupopup is the container that will hold all of our menuitem elements. The onpopupshowing event is fired right before the drop-down box is shown to the user. The code snippet shown is a function that we will write to dynamically populate the menu with items, something we will discuss later in the tutorial. You can add static menu items if you like; the process is exactly the same as for the menu button earlier.

Let’s take another look at our XUL overlay at this point: [View XUL Overlay Revision 3]. Our extension is really starting to take shape!

Resizing GripperRemember the persist attribute we added to the toolbaritem element that surrounds the menulist? We specified that attribute so that the width of our search box could be saved between browser sessions. In order for the user to be able to change the width, however, we need to provide them with a resizing gripper. The XUL element responsible for this is the splitter element, and the markup for ours looks like this:

<splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /></splitter>

Here is a list of the splitter element’s new attributes:

state - Indicates whether or not the splitter has collapsed (hidden) content. A value of "open" indicates that the content either before or after the splitter (in our case both), is visible.

collapse - Determines which side of the splitter is collapsed. We have specified a value of "none" since we don’t want either side of the splitter to be hidden.

resizebefore - Indicates which element to the left of the splitter should be resized when the splitter is repositioned. A value of "closest" indicates that we want our edit box (the closest element to the left of the splitter) to be resized when the splitter moves.

resizeafter - Indicates which element to the right of the splitter should be resized when the splitter is repositioned. In this sample, we use the value of "farthest" since we want the "free space" on the far right of the toolbar to be resized.

Page 17: Firefox Toolbar Tutorial

The vbox element inside of the splitter has been placed there for styling purposes. We’ll come back to this when we discuss how to skin our toolbar in chapter 5.

You can find a complete reference on the splitter element’s attributes at the Mozilla Developer’s Center.

A splitter element should always appear either before, after, or between containers (in the case of a toolbar, it should lie between two toolbaritem elements). Our example toolbar only has one such element so far, wrapping the menulist. We need to place another one around our two search buttons (the "button-menu" button and the normal button). Here’s the markup we will use:

<toolbaritem flex="0"></toolbaritem>

Let’s take a look at our XUL overlay with these new splitter and toolbaritem elements:[View XUL Overlay Revision 4].

In order to prevent a slightly annoying cosmetic problem with the resizing gripper, we need to place yet another toolbaritem element, exactly as we just did with the search buttons, around our first toolbar element (the menu button). Again, make sure that the flex attribute has a value of 0. This will prevent our menu button from being pushed off the left side of the toolbar when the gripper is dragged all the way to the left.

While we are adding this element, let’s go ahead and add two more. First, let’s place a toolbarseparator element between the last two buttons (this is just for cosmetic purposes). Second, let’s place a toolbarspring element right after the closing tag for the final toolbaritem element. This spring will allow us to drag the resizer all the way to the right, so that we can see the full resizing effect in action. The markup for each of these two elements is incredibly simple:

<toolbarseparator />

<toolbarspring />

Let’s take a look at our completed XUL overlay: [View XUL Overlay Revision 5].

Chapter 4: Dynamic DevelopmentFirefox 1.5 introduced the single most useful feature for developers: dynamic extension development. This new capability allows you to work on your extension and see the results in real time! You no longer have to repackage your extension every time you want to test changes to either your XUL overlays or JavaScript code. Not only does this reduce your development time, but it makes debugging even easier than before.

How does this feature work? Well, we can thank the chrome manifest that we created in chapter 2 for this capability. You see, up until now, I haven’t told you everything there is to know about the chrome manifest. The version we created back at the beginning of this tutorial was created specifically for dynamic development. In other words, we won’t be packaging our extension with that version of the chrome manifest (there are some changes we need to make to it before we can package things up). There are a few steps we have to take to "enable" dynamic development for our extension, but first I’d like to present you with some sound advice.

Page 18: Firefox Toolbar Tutorial

A Word of WarningExtension development can be a somewhat dangerous thing, especially when working with XUL overlay files. I highly recommend that you avoid developing your extensions in the same profile that you normally use for web surfing. In other words, you should create a brand new profile in which you do all of your development and testing. This will prevent you from losing key browser data: stored passwords, cookies, bookmarks, and any other stuff you would hate to lose.

To learn more about how profiles work in Firefox, consult either the tutorial I offer on the subject, or the official profile documentation. Creating and using a new profile is an easy task, and it will save you a great deal of headache down the road.

How to Develop DynamicallyThe majority of our work has already been completed in the chrome manifest (even though you may not have realized what we were doing at the time). Now all that we need is a file to point Firefox to our extension’s location on our hard drive. We will do so through the use of a "pointer" file.

First, create a text file anywhere on your computer and give it the same name as the GUID we used in the install manifest. For this tutorial, the value we chose was [email protected]; so our text file should use that exact same name. Unfortunately for Windows users, the ".com" file extension usually indicates an executable. In our case, it will just be a simple text file. If you would like to keep the ".com" portion out of the filename for now you may do so; just remember to update the GUID value in the install manifest to match your altered name (and remember to change it back when you package your extension).

Inside of this file we will place exactly one line of text: the absolute path to the folder where your extension is stored (that is, the folder that contains your install.rdf and chrome.manifest files). In my case, this tutorial extension is stored in the following location on my computer:

C:\Born Geek\TutToolbar

You should clearly use the path to the extension on your computer, unless the path happens to exactly match the one above (and I doubt that it does). After typing the absolute path to your extension, save the file.

We now must move this file to our development profile’s folder. The profile documentation I mentioned earlier discusses exactly how to locate your profile folder. Once you find where the profile is located, place the pointer file we just created in the extensions folder within the profile folder. Here is how my sample profile file structure looks (trimmed down for brevity’s sake):

+- tl5wlpz3.Nightly/ +- bookmarkbackups/ +- chrome/ +- extensions/ +- [email protected] +- (... other files and folders ...)

As you can see from the name of my profile’s top folder, I use a "Nightly" profile to try out nightly Firefox builds as well as to do my extension development. Once the pointer file you have created has been placed in the proper location, start Firefox, making sure that you use your development profile (again the profile documentation mentioned earlier will show you how to do this). If you have done everything right up until this point, you should see your toolbar, in all of its un-skinned glory!

Page 19: Firefox Toolbar Tutorial

The Development CycleSo now that we have enabled dynamic extension development, how do we use it? The process is actually very simple:

1. Edit your extension files. 2. Reopen the window(s) that the modified files apply to, or use the Reload Chrome feature of

the Extension Developer’s Extension.

There are two special cases you should be aware of:

If you change the chrome.manifest file, you will have to restart Firefox (this file only gets parsed on startup).

If you change the install.rdf file, you will have to alter the modified time of the folder that your "pointer file" points to. In Linux you can simply use the touch command to do this. In Windows, it’s somewhat more difficult (unless you have the Cygwin tools installed, in which case you can simply use the touch command). One simple way to handle this case is to create a new folder within the extension’s top level folder, then delete that new folder.

As you can already see, this will be an incredibly handy tool as we develop and debug our extension. It sure beats having to repackage everything for each development cycle, which was the standard process before release 1.5. Now let’s make this ugly toolbar we’ve created look a little better!

Chapter 5: Skinning the ToolbarA "skin" is a collection of styling rules (specified with CSS) and images that get used to change the appearance of chrome (in our case, the toolbar we are building). Keep in mind that although skinning is entirely optional, it can greatly improve the quality of your extension. After all, a user’s first impression of your toolbar will be its appearance, not its functionality. However, if you are comfortable using only text labels for your toolbar buttons (or your extension doesn’t make use of a chrome overlay at all), you can skip this step.

Updating the File StructureThe first step in creating a skin for our toolbar is to create the folder that will hold all of our skin files. Create a folder named skin inside of the chrome folder. The resulting file structure should look like the following:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/

Now that we have a place to store our skin’s files, we need to register this location with our chrome.

Updating the Chrome ManifestRemember the chrome manifest file we created in chapter 2? We need to add a line of code to that file which will register our skin. Let’s take a look at the line of code that is necessary (it has been highlighted below):

Page 20: Firefox Toolbar Tutorial

content tuttoolbar chrome/content/overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xulskin tuttoolbar classic/1.0 chrome/skin/

This additional line of code is quite simple, and has only four parts. The first part, which is simply the word "skin", states that what follows is the skin’s registration information. Next up is the package name which, in this tutorial, is tuttoolbar. The third part indicates the name of an installed skin which we will be extending. The value shown (classic/1.0) is the value you should always use for Firefox extensions. Finally comes the most important part: the relative path name to the folder that contains our skin’s files. This path is always relative to the chrome directory. It is very important that you note the trailing slash (/) in the given path above. That slash is required, so make sure you include it.

Creating the Image FilesTo keep things simple for this tutorial, we will be using one image for each toolbar button. Note that this is neither the most efficient nor elegant way of skinning a toolbar, but it makes things incredibly easier to understand. For those that are curious, image sheets are the best way to skin an extension, but they are outside the scope of this tutorial.

We need a total of five images for our toolbar as it is currently designed: one for our "main menu" (the menu button), one for the combined search button, one for our web search button, one for the resizing gripper, and one for the image search menu item in the combined search menu. The following list shows each of the five images I have chosen to use for our extension. Note that these images are in a transparent PNG format, so if you are using Internet Explorer 6 or earlier to view this tutorial, the images will not be displayed properly.

Main Menu Icon (main.png): Combined Search Icon (combined.png): Web Search Icon (web.png): Images Search Icon (images.png): Resizing Gripper Icon (gripper.png):

Let’s save these images to our skin folder that we created moments ago. Our resulting file structure will look like this:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png

Applying the Images With CSSNow that we have some images to use, and our skin directory has been registered, we can begin applying the images to our toolbar buttons. We will do so through the use of a Cascading Style Sheet (CSS). As I mentioned at the beginning of this tutorial, W3Schools has an excellent CSS tutorial if you are unfamiliar with how style sheets work.

Page 21: Firefox Toolbar Tutorial

Let’s create our CSS file, naming it tuttoolbar.css and placing it inside of the skin folder, along with our images. Here is the resulting file structure:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css

Let’s take a look at the contents of our style sheet before we go into any detail:

#TutTB-MainMenu { list-style-image: url("chrome://tuttoolbar/skin/main.png");}

#TutTB-Combined-Button { list-style-image: url("chrome://tuttoolbar/skin/combined.png");}

#TutTB-Combined-Button > .toolbarbutton-menubutton-button { -moz-box-orient: horizontal;}

#TutTB-Web-Button,#TutTB-Combined-Web { list-style-image: url("chrome://tuttoolbar/skin/web.png");}

#TutTB-Combined-Image { list-style-image: url("chrome://tuttoolbar/skin/images.png");}

#TutTB-ResizeBar { background-image: url("chrome://tuttoolbar/skin/gripper.png"); min-height: 22px; min-width: 3px;}

#TutTB-ResizeSplitter { background: transparent; border: none !important;}

The first rule shown specifies the image to be used for the "main menu" button. Back in chapter 3, we gave that button an ID value of TutTB-MainMenu, and we use that ID here to set up the rule. The preceding hash mark (#) is called the ID selector, and is how one specifies rules in CSS for elements with a particular ID value. For toolbar buttons, we make use of the list-style-image CSS property to specify the image to be displayed. You will note that the path we use is a chrome path; that is, the path to the image within your extension’s file structure. The general format for these paths is as follows:

chrome://<packagename>/skin/<image_file_name>

For our example, the package name is tuttoolbar and the image we want to use for the main

Page 22: Firefox Toolbar Tutorial

menu is named main.png. As you can see, we use similar rules for all of the toolbar buttons, as well as our menu items in our combined search button’s menu. There’s one caveat to handling menu item icons, however. If you recall, we made use of a special class value for the menu items in our combined search menu. That special class was menuitem-iconic, and it is a built-in class provided by Firefox. In a sense it "enables" icon support for each menu item that uses it.

You undoubtedly also noticed the special rule for the combined search button:

#TutTB-Combined-Button > .toolbarbutton-menubutton-button { -moz-box-orient: horizontal;}

The special CSS property used here (-moz-box-orient) specifies how the label for our button should appear: aligned vertically or horizontally. By default, toolbar button labels are aligned vertically, meaning that the label shows up underneath the icon. We don’t want that in this case, so we use the horizontal value to force the label to show up after the icon.

There are two rules in our style sheet that deal with the resizing gripper. Remember that vbox element that we placed inside of our splitter element? We use the ID of that vbox to display a background image for our gripper. This time we use the background-image property. We also must provide a minimum height and width (using the min-height and min-width properties), so that our gripper shows up. By default, the vbox and hbox elements size to the smallest value possible for their content. Since our vbox is empty, it sizes to a default of 0, which prevents us from seeing the background image.

We also provide a rule for the splitter element itself. We tell the background to become transparent (so that we can see the vbox image), and we tell it to not use a border (by default, all splitter elements have a border). Now that our CSS file is complete, we need to tell our overlay how to use it.

Using the Style SheetOnly one line of code needs to be added to our XUL overlay to enable the style sheet we just created. It must be placed underneath the XML directive at the top of the file, but before the actual overlay element. Below I show the first few lines of our XUL overlay file, highlighting the line we need to add:

<?xml version="1.0"?><?xml-stylesheet href="chrome://tuttoolbar/skin/tuttoolbar.css" type="text/css"?>

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

(... rest of XUL overlay file ...)

Like we saw with the images in the style sheet, a chrome path gets used to specify the location to the style sheet. The type attribute simply tells the parser that the file being referenced is a CSS file. And that’s all there is to it! Let’s take a look at the entire XUL overlay file as it appears with this additional line: [View XUL Overlay Revision 6].

And don’t forget to test it out! Open the Firefox instance that includes your dynamic extension installation (which we discussed in the previous chapter), and see what the extension looks like. Next up, we’ll be bringing the toolbar to life.

Page 23: Firefox Toolbar Tutorial

Chapter 6: Scripting the ToolbarFirefox extensions are usually driven by JavaScript, a programming language that is fairly easy to learn. As you will soon find out, the code that our toolbar extension will use is very straightforward. We will make fairly heavy use of the Firefox chrome’s DOM, which allows us to access the individual elements of our toolbar.

Before we write any code, there is one very important point you should be aware of. Just as the id attributes for our XUL elements needed to be unique across the entire browser system, so too must our JavaScript variables and functions be unique. All JavaScript included in a browser overlay is global, hence this unique name constraint. We will again employ the same technique here that we used for our XUL elements: all variable and function names will be prefixed with a short identifier created from our extension’s name. The prefix we will use for this tutorial is TutTB_. So, our search function will be named TutTB_Search().

Let’s now create our JavaScript file. Place it inside of the content folder, and name it tuttoolbar.js. Our resulting file structure now looks like this:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css

Before we place any code within this file, let’s first tell our XUL markup how to use our JavaScript.

Tying XUL to JavaScriptOur XUL markup (stored in the tuttoolbar.xul file) needs to be told where to find the corresponding JavaScript. We can tell it where to look by making use of the script element:

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

This element should be placed inside the overlay element in our XUL markup. The type attribute indicates that we are pointing to a JavaScript file, and src attribute simply specifies the chrome path to our JavaScript file (that we just created). Let’s take a look at what our XUL overlay looks like after we insert this element: [View XUL Overlay Revision 7].

Adding Functionality to the ButtonsRemember the oncommand attribute we supplied for each toolbar button back in our XUL markup? That attribute is how we specify what code to execute when the command event gets fired (i.e. the user activates the toolbar button). We could have used the onclick event instead, but it doesn’t respond to the keyboard; oncommand responds to both the keyboard and the mouse. Let’s

Page 24: Firefox Toolbar Tutorial

take a look back at the value we supplied for this attribute for our web search button:

oncommand="TutTB_Search(event, 'web')"

This value shows a call to the TutTB_Search() function, passing in two values: the event that generated this function call, and our own custom value that indicates what type of search to do (in this case, a web search). We won’t be making use of the event parameter at the moment; we’ve simply included it here for future use.

Because the code is rather lengthy, I have decided not to show it within the text of this article. Instead, I will present the code to you in sample code files, which you can examine at your leisure. The code is well commented, so I won’t go into a great deal of explanation on what each line does. Let’s take a look at the first sample file now (copy the contents of this file and paste them into the JavaScript file you created moments ago): [View JavaScript Revision 1].

Start up Firefox (with your development profile), enter a search term into our toolbar’s search box, and click one of the web search buttons. The code should execute and the Google search results page should appear! This dynamic development stuff is pretty handy!

A Special Note About Button-Menu Buttons

Before we move on to the next topic, one very important note must be made concerning "button-menu" style buttons. Recall that this type of button provides both a clickable button as well as a popup menu (the forward and backward navigation buttons are prime examples). Also recall that the toolbarbutton sub-element of this button style, as well as each individual menuitem element, contains an oncommand attribute. When the toolbar button portion is activated, the code specified in the toolbarbutton element’s oncommand attribute gets executed, just as you would expect. But what happens when the user activates one of the menuitem elements?

Not only does the menuitem element’s oncommand event fire, the toolbarbutton element’s event also fires! So two events fire at once, even though you only wanted one of them to be triggered. Because the toolbarbutton’s event fires last, its code is what gets executed. In other words, the menuitem’s event never gets a chance. So how can we fix this problem? Well, truth be told, we already have. Let’s look back at the markup for one of our menuitem elements (the interesting piece is highlighted):

<menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.stopPropagation();" />

By making use of the DOM function stopPropagation(), we are able to prevent the oncommand event from propagating up the DOM tree. This effect is why the toolbarbutton’s code was always getting executed. To make a long story short, always keep the following rule in mind: when creating a "button-menu" type toolbar button, always add event.stopPropagation() to the oncommand attribute of each menuitem element.

Adding Functionality to the Search BoxNow that we have the search buttons working, we need to add some capability to the search box itself. The user should be able to enter a search term and press the [Enter] key to execute a search. How can we do that? Well, let’s look back at our XUL markup to see what function we anticipated on using:

<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250"

Page 25: Firefox Toolbar Tutorial

onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist></toolbaritem>

This time, instead of using the oncommand event, we rely on the onkeypress event. This event gets fired each time the user presses a key inside of the search box. In this example, we are making a call to the TutTB_KeyHandler() function, which is surprisingly simple:

function TutTB_KeyHandler(event){ if(event.keyCode == event.DOM_VK_RETURN) TutTB_Search(event, 'web');}

This function simply checks to see if the key that was pressed is the [Enter] key. If it is, it calls the TutTB_Search() function that we just looked at. If the [Enter] key wasn’t pressed, the function simply does nothing. Let’s add this function to our JavaScript file (I’ve placed it at the bottom of the file): [View JavaScript Revision 2].

Again, start Firefox with your development profile, type some search terms into the toolbar’s search box, and press the [Enter] key on your keyboard. A web search should take place, just like clicking the button before. Our extension has really come to life!

Dynamically Populating a MenuBeing able to dynamically populate a menu with menu items is surprisingly useful. Thankfully, this feature is quite easy to implement. For our tutorial toolbar, we will dynamically add some items to the search box drop-down menu. Let’s again look back at the XUL markup we used to create our search box:

<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist></toolbaritem>

Note the highlighted onpopupshowing attribute in the menupopup element. We have specified that a function named TutTB_Populate() should be executed each time the popup menu is about to be displayed. This function will be responsible for creating our dynamic menu items. Let’s take a look at that function’s code (again, the code is well commented to explain exactly what’s going on): [View TutTB_Populate() Code].

This example function does not show how to instruct each menuitem element to execute some code when it is selected. To tell each menuitem what code it should execute, we simply make an additional call to the setAttribute() function, passing in the event to be handled and the code to be executed. Here is an example of handling the oncommand event:

tempItem.setAttribute("oncommand", "TutTB_SomeFunction()");

Let’s add the TutTB_Populate() function to the end of our JavaScript file and take a look at the results:[View JavaScript Revision 3]. That’s all there is to dynamic menu population!

Page 26: Firefox Toolbar Tutorial

Dynamically Adding Toolbar Buttons(This section is being provided for informational purposes only; it does not appear in the example toolbar’s source code).

Adding dynamic toolbar buttons to a toolbar is just as easy as dynamically populating a menu, and it’s done in a very similar fashion. We first need a container to hold our dynamic buttons. The toolbaritem element is the perfect fit for this, and the markup would look like the following:

<toolbaritem id="TutTB-DynButtonContainer" />

Now that this container is available to us, we can use it to add our dynamic toolbarbutton elements. Let’s examine a sample function that we could use to add dynamic buttons:

function TutTB_AddDynamicButtons(){ // Get the toolbaritem "container" that we added to our XUL markup var container = document.getElementById("TutTB-DynButtonContainer");

// Remove all of the existing buttons for(i=container.childNodes.length; i > 0; i--) { container.removeChild(container.childNodes[0]); }

// Add 5 dynamic buttons for(var i=0; i<5; i++) { var tempButton = null; tempButton = document.createElement("toolbarbutton"); tempButton.setAttribute("label", "Button " + i); tempButton.setAttribute("tooltiptext", "Button " + i); tempButton.setAttribute("oncommand", "TutTB_SomeFunction()"); container.appendChild(tempButton); }}

This function looks very similar to the one we used to populate our dynamic menu. We remove all of the existing dynamic buttons from the container (the way shown here is different that we used in the dynamic menu code), then we create the new buttons to add to the container, appending them as we go.

Optional Programming Exercise: Try to use this general idea to add "search word buttons" to our example toolbar. As the user types search words into the search word box, dynamically add buttons to the end of the toolbar, one button for each word the user types. Here are a few hints to get you started:

1. You’ll need to add a toolbaritem "container" to the end of our toolbar’s XUL markup (right before the toolbarspring element is a good choice). Make sure to give it a unique ID.

2. Make use of the oninput event in the menulist (search box) element. This event gets fired as the user types text into the search box (which is just what we want).

3. The JavaScript function you call will need to do the following: (a) Obtain the search words from the search box, (b) remove all previously created dynamic buttons, (c) split up the search words based on whitespace, and (d) create a button for each individual word.

This is (almost) exactly how I handle this feature in Googlebar Lite.

Disabling and Enabling Buttons(This section is being provided for informational purposes only; it does not appear in the example

Page 27: Firefox Toolbar Tutorial

toolbar’s source code).

You may occasionally want to dynamically disable or enable a toolbar button. For example, the highlighter button in Googlebar Lite is disabled when no search words are present in the search box, and enabled when there are search words.

The following example shows how to create a menu item that toggles the disabled status of a normal toolbar button. Again, this isn’t the most practical example in the world, but it demonstrates how the effect is achieved. Here is the markup for our menu item:

<menuitem label="Toggle Web Search Button" tooltiptext="Toggle Web Search Button" oncommand="TutTB_ToggleWebSearchButton()" />

And here is the code for TutTB_ToggleWebSearchButton() function:

function TutTB_ToggleWebSearchButton(){ var button = document.getElementById("TutTB-Web-Button"); var value = button.disabled; if(value == true) button.disabled = false; else button.disabled = true;}

We first get the toolbar button we are interested in by using its ID value and the getElementById() function. Once we have the button, we can get its current state (enabled or disabled) using the disabled property of the button object. If the value is true, we set it to false, and vice-versa. Firefox takes care of disabling the button for us, so that it is no longer clickable (note that the button’s image may not appeared grayed out: we must rely on skinning for that).

Dynamically Showing and Hiding Buttons(This section is being provided for informational purposes only; it does not appear in the example toolbar’s source code).

Googlebar Lite allows the user to choose the buttons they wish to see on their toolbar. This means that the toolbar must be able to dynamically show or hide the available buttons. Here is a snippet of JavaScript code that will accomplish exactly what we want:

var TB_Web = document.getElementById("TutTB-Web-Button");TB_Web.setAttribute("hidden", !TutTB_ShowWebButton);

We first get the toolbar button element itself using the getElementById() function. Then we make a call to the setAttribute() function to change the value of the hidden attribute. You’ll note that I set the value of the hidden attribute to the opposite value of a variable I have called TutTB_ShowWebButton. This variable is simply a boolean flag, telling us whether or not the user wants to see the "web search" button. The actual value stored in this variable comes from reading the user’s preference for the "Show Web Search Button" option. Read on to see how we can do that.

Reading and Storing User Preferences(This section is being provided for informational purposes only; it does not appear in the example toolbar’s source code).

In order to read a stored preference, we need to get access to the Firefox preferences service

Page 28: Firefox Toolbar Tutorial

interface. We do so by creating a variable like the following (note that this code has been formatted to fit this site’s layout):

const TutTB_PrefService = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefService);

Once we have access to the preferences interface, we can obtain our extension’s preferences branch (i.e. the location in the preferences "registry" where our extension’s settings are kept):

const TutTB_Branch = TutTB_PrefService.getBranch("tuttoolbar.");

Let us assume that all of our example toolbar’s preferences begin with the text tuttoolbar. (note the trailing period). As a result, we must pass this string into getBranch() (a built-in Firefox function). This function gives us access to our extension’s preferences, so we can finally obtain the value for an individual option. Here is how we can obtain the value for the "Show Web Search Button" option we mentioned a moment ago:

if(TutTB_Branch.prefHasUserValue("show.button.web")) TutTB_ShowWebButton = TutTB_Branch.getBoolPref("show.button.web");else{ TutTB_Branch.setBoolPref("show.button.web", false); TutTB_ShowWebButton = false;}

We first test to see if the preference exists in the preferences tree. If it does, we use the getBoolPref() function to read its value (storing it in the variable TutTB_ShowWebButton). If the preference does not exist, we set the default value (both in the preferences tree and in our global variable).

So storing a preference is just as easy as reading one. You simply supply the name of the preference to set, and then the value to use:

TutTB_Branch.setBoolPref("show.button.web", TutTB_ShowWebButton);

Reading and writing preferences is a handy way to store your toolbar’s settings. Most extensions utilize this feature, so there are certainly plenty of working examples out there for you to examine. In addition, an excellent expanded tutorial on preferences is available at the Mozilla Developer’s Center.

Chapter 7: Packaging the ToolbarUp to this point in the tutorial, we have been relying on the dynamic development system to handle installation responsibility for our extension. The end-user doesn’t want to go to all of this trouble to install your extension, so we must package everything up into one installable file. We will actually be creating two files: an XPI (cross platform installer) and a JAR. Don’t let these file extension names fool you; both files are simply zip files in disguise.

This is where our zip tool comes in handy. For the purposes of this tutorial, I will make use of the standard UNIX zip tool, available for Windows in the Cygwin tool set.

Page 29: Firefox Toolbar Tutorial

Updating the Chrome ManifestThe first step in the packaging process involves updating the chrome manifest. Note that if you want to continue doing dynamic development, you’ll need to keep two chrome manifests around: one to package the extension with, and one for dynamic development purposes. Dealing with two files can be tricky, so we will only work with our existing chrome manifest for this tutorial. Note that after we modify our manifest, we won’t be able to do dynamic development any more (unless we revert the modifications). Let’s first take a look back at the contents of our chrome manifest:

content tuttoolbar chrome/content/overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xulskin tuttoolbar classic/1.0 chrome/skin/

All of the file-system paths in this file need to be updated (there are 2 total). Let’s take a look at the updated version of the first line (the changes have been highlighted):

content tuttoolbar jar:chrome/tuttoolbar.jar!/content/

You’ll note that we’ve added two items. The first is the jar: directive placed at the beginning of the path. This indicates to Firefox that it needs to look inside of a JAR file to find the content of this extension. The second item we added is the tuttoolbar.jar!/ bit of text, right between the chrome/ and content/ folder names. This bit of text tells the installer which JAR file it needs to look in. The filename of the JAR we have specified uses the exact same name as our package name (a requirement of the installer). As such, the filename must be all lowercase, just like the package name. Note that the exclamation point at the end of the name is no typo; that character is required. The other path we need to update for our chrome manifest is on the skin registration line. Here is the final version of our updated chrome manifest:

content tuttoolbar jar:chrome/tuttoolbar.jar!/content/overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xulskin tuttoolbar classic/1.0 jar:chrome/tuttoolbar.jar!/skin/

Creating the JAR FileThe first package we need to create is our JAR file. This file will live within the chrome directory, and will contain all of our XUL, JavaScript, image, and CSS files. After we create this file, our file structure will look like the following:

+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- tuttoolbar.jar +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css

The biggest mistake that people make when packaging a JAR or XPI file is omitting the relative path names of the files. If we were to pretend that our JAR file was a folder, this is what its

Page 30: Firefox Toolbar Tutorial

contents would look like when we were finished:

+- content/ +- tuttoolbar.xul +- tuttoolbar.js+- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css

In other words, each individual file has to have an associated relative path name. Here is how I would create the JAR file for this tutorial using the UNIX zip tool:

I would first change to the chrome directory in my extension’s folder (in a command prompt window), then I would issue the following command:

zip -r tuttoolbar.jar content/* skin/*

Creating the XPI FileNow that we have a JAR file created, we need to create our XPI file. This is what you will actually distribute to the end-user. We should create this file in the top-level folder of our extension’s file structure. Once the file is created, our file structure will look like the following:

+- TutToolbar/ +- tuttoolbar.xpi +- install.rdf +- chrome.manifest +- chrome/ +- tuttoolbar.jar +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css

Like the JAR file before it, the XPI must retain relative path information. We only need to include 3 files in our XPI file for this tutorial: the installer manifest, the chrome manifest, and the JAR file we created moments ago. Again, if we consider our XPI file to be a folder, this is what its contents would look like:

+- install.rdf+- chrome.manifest+- chrome/ +- tuttoolbar.jar

To create the XPI file using the UNIX zip tool, change to the top-level folder of your extension’s file hierarchy (the same folder where the installer and chrome manifests live), and use the following command:

zip tuttoolbar.xpi install.rdf chrome.manifest chrome/tuttoolbar.jar

Page 31: Firefox Toolbar Tutorial

Test Installing Your ExtensionNow that we have an XPI file, we can test out the installation process. This is something you should always do before you release an extension to the public: make sure it installs! We must not use our development profile to do installation testing, since we already have an "installed" version of our extension in that profile. In either your normal Firefox profile, or in yet another test profile, take the following action to install your extension:

1. Select the File » Open File… menu item (or press the Ctrl+O keyboard accelerator). 2. In the file selection dialog, browse to the location of your XPI file, select it, and click the

Open button.

If you’ve done everything correctly, the extension installer should appear. Tell it that you want to install, close Firefox when it’s finished installing, and start Firefox back up. Your toolbar should appear alongside all of the others. Congratulations on creating your first toolbar extension!

Speeding Up the Packaging ProcessPackaging your extension by hand can quickly become tiresome. Why not write a script to do it? If you have a zip tool with a command line interface, you can easily automate the process. The following example shows a simple way to build our example toolbar using a DOS batch file and the UNIX zip tool.

First create two text files: one in the top level folder (named xpizip.txt), and one in the chrome folder (named jarzip.txt). Each text file is a simple listing of the items we want to include in each package: xpizip.txt lists the files to go in the XPI file, while jarzip.txt lists the files to go in the JAR file. Feel free to take a look at the following two example files: [View xpizip.txt] [View jarzip.txt]

Next, create a DOS batch file (in the extension’s top-level folder) which you can run from the command line. The code I used in the batch file is shown below:

cd chromezip -r tuttoolbar.jar -@ < jarzip.txtcd ..zip -r tuttoolbar.xpi -@ < xpizip.txt

As you can see, this script is extremely simple. Your scripts can be much more complex than this, however. The Perl script I use to build Googlebar Lite does a number of things: it automatically updates all the version numbers for me, updates my chrome manifest, then packages the files. For the curious, I’ve provided the script for you to look at. [View the Googlebar Lite Build Script]

Ant SupportIf you would rather use an Ant task to build your extension, take a look at the sample XML file sent in by Brett Clippingdale. The script should be placed in the same folder as the installer manifest, and can be run using the ant command.

------------------------------------------------------------------------------------------------------------------------

Chapter 8: Testing Our ExtensionThe dynamic development feature we discussed back in chapter 4 has improved extension testing greatly, but there are a few other tricks a developer should know to get the most out of the testing process. JavaScript is a notoriously bad language to debug, and thankfully Firefox offers us some

Page 32: Firefox Toolbar Tutorial

features that we can use to avoid those annoying alert() calls.

What to Do if Firefox BreaksSometimes an extension can have a bug so catastrophic, that Firefox refuses to start. When this happens, you first need to check for hung Firefox processes, killing off any that you find. Once you are sure that no Firefox instances are running, you need to uninstall your problematic extension. How you do this depends on whether or not you are using the dynamic development system.

If you are developing dynamically, simply navigate to the extensions folder in your development profile (as we discussed in chapter 4), and move your extension’s pointer file (in our case the file was named [email protected]) to a temporary location. Restart Firefox using your development profile (allowing it to ‘purge’ itself of the newly uninstalled extension), and close the browser again. After you fix the problem that was causing Firefox to hang, move your pointer file back to the extensions directory, and restart Firefox.

If you are not developing dynamically, uninstalling your problematic extension involves starting Firefox in safe mode. You can do this in one of two ways:

1. Use the "Start Firefox in Safe Mode" shortcut that got created by the Firefox installer. In Windows XP, the default shortcut location is: Start » All Programs » Mozilla Firefox » Mozilla Firefox (Safe Mode).

2. Add the -safe-mode command line parameter to an existing Firefox shortcut.

In safe-mode, Firefox will not load any extensions or themes. Once in safe-mode, you can simply uninstall your problematic extension by using the extension manager as you normally would. After you have uninstalled the extension, remember to remove the -safe-mode command line parameter (if you manually added it to an existing shortcut).

Useful Browser SettingsThere are two rather obscure browser settings that can make your development life much easier. Both can be set through the about:config interface, and both affect the output that gets sent to the JavaScript console.

The first preference is javascript.options.showInConsole. When set to true, any errors or warnings that appear in your extension’s chrome files will be sent to the JavaScript console. By default, this preference is set to false (so you’ll need to enable it). It’s a handy way to track down existing problems.

Next is the javascript.options.strict preference, which is also set to false by default. When true, the JavaScript parser within Firefox will be placed into strict mode, placing tighter restraints on your extension’s code. This helps to improve your code’s integrity and makes it easier to track down subtle code problems.

Logging to the JavaScript ConsoleOne useful way to test JavaScript code is by printing out debug values to the JavaScript console, which you can access through the Tools » JavaScript Console menu item. In order to do this, we must first obtain an instance of the nsIConsoleService interface. The following snippet of code does just that:

const TutTB_ConsoleService = Components. classes['@mozilla.org/consoleservice;1']. getService(Components.interfaces.nsIConsoleService);

Page 33: Firefox Toolbar Tutorial

Note that I have once again prefixed the variable’s name with "TutTB_", just as I did for all our other JavaScript functions and variables. Once we have obtained this console instance, we can use it to write our own messages. The following function will do the work for us:

function TutTB_Log(aMessage){ TutTB_ConsoleService.logStringMessage('Tut_Toolbar: ' + aMessage);}

In practice, you should change the ‘My_Extension:’ portion of the message to whatever the name of your extension is. By prefixing each message with your extension’s name, you can better tell which output messages are yours. Now that we have this function available, we can simply call it from anywhere in our code to print out a debug message:

TutTB_Log("The value of the URL variable is: " + URL);

Remember to always remove all calls to this function before releasing your extension to the public. Not only does logging to the console slow things down, it adds unnecessary clutter to the user’s JavaScript console window. For further reading on the JavaScript console, consult this Mozilla Developer’s Center article.

Logging to the Standard ConsoleAn alternative method of logging debug information is available through the standard console mechanism. Before this method can be used, several modifications to the browser must be made. First, we need to add a new browser preference. In the URL bar in Firefox, type about:config and press enter. Right click in the list control and select the New » Boolean menu item to create a new boolean preference. Give the preference a name of browser.dom.window.dump.enabled and set the value to true.

The next step is to add the "-console" command line parameter to your Firefox startup shortcut. Using this parameter will cause the standard output console window to appear each time you run Firefox. Once this has been done, and Firefox has been started, any output produced by the dump() function will appear in this console window. The dump() function works just like the standard JavaScript alert() function, so the syntax is similar.

The DOM InspectorOne of the greatest aids to anyone designing a toolbar (or any other chrome for that matter) is the DOM (Document Object Model) Inspector, a tool which allows you to examine the structure of XML documents (which includes XUL and HTML). This tool comes with Firefox, but is not selected for install by default. You must perform an "Advanced" install to be able to select this tool for installation. Once the tool is available, a wealth of information can be harvested, so make sure you learn how to use it.

A few guides on how to use the DOM Inspector are available on the web:

The DOM Inspector (from Creating Applications with Mozilla) DOM Inspector FAQ

This tool is best used to help troubleshoot XUL layout problems, as it allows you to view the styles being applied to various XUL elements. I highly recommend learning how to use the DOM Inspector. It’s simple to pick up, and you will be glad you learned how to use it.