This article explains how to add a toolbar button to a Toolkit application (such as Firefox, Thunderbird, or Kompozer) using overlays. Its intended audience is extension developers with a basic knowledge of XUL and CSS.
We assume that you're also familiar with the basics of creating Firefox extensions and have the Hello World extension working. Another tutorial, which walks you through the entire process from the beginning, is also available.
Creating an overlay
The first step is to create an overlay for the document containing the toolbar you wish to enhance. Explaining overlays is beyond the scope of this tutorial -- you can read about them in the XUL Tutorial.
To overlay a document, you need to know its URI. You can find a list of URIs for the most commonly overlaid documents at the bottom of this page.
chrome://messenger/content/mailWindowOverlay.xul
. that should cause the button to appear on all windows that mailWindowOverlay.xul
is applied to (i.e. Main window and View Message window). This needs to be looked into.Adding the toolbar button
Toolkit applications have customizable toolbars; therefore, it's common practice for extensions to add their toolbar buttons to the toolbar palette, rather than adding them directly to the toolbar. The latter is possible, but is not recommended and is harder to implement.
Adding a button to the toolbar palette is very easy. Just add code like this to your overlay:
<toolbarpalette id="BrowserToolbarPalette"> <toolbarbutton id="myextension-button" class="toolbarbutton-1" label="&toolbarbutton.label;" tooltiptext="&toolbarbutton.tooltip;" oncommand="MyExtension.onToolbarButtonCommand(event);"/> </toolbarpalette>
Notes:
- The
id
of the palette (BrowserToolbarPalette
in the example) depends on the window (the parent window of the toolbar you wish to insert a button). See below for the list of common palette IDs. class="toolbarbutton-1"
makes the toolbar button appear correctly in Icons and Text mode; it also adjusts padding.- Set the command to be executed when the button is clicked in the
oncommand
attribute. - If you need to handle middle-click, add this line after the oncommand line.
onclick="checkForMiddleClick(this, event)"
- you can also handle middle-click and right-click using
onclick
handler and checkevent.button
in it like this:
<toolbarpalette id="BrowserToolbarPalette"> <toolbarbutton id="myextension-button" class="toolbarbutton-1" label="&toolbarbutton.label;" tooltiptext="&toolbarbutton.tooltip;" onclick="MyExtension.onclick(event);"/> </toolbarpalette>
onclick: function(event) { switch(event.button) { case 0: // Left click break; case 1: // Middle click break; case 2: // Right click break; } }
To add more buttons, put more <toolbarbutton>
elements inside the <toolbarpalette>
element. Wrap elements other than <toolbarbutton>
in <toolbaritem>
.
Adding the Button Bootstrap Style
Adding a button to the BrowserPalette
on runtime in a Bootstrap addon is a bit different because the BrowserPalette
is indirectly reached. A simple document.getElementById('BrowserToolbarPalette') will not work. This is the code to create and add it in.
let button = doc.createElement("toolbarbutton");
button.setAttribute("id", BUTTON_ID);
button.setAttribute("label", "Replace Bookmark");
button.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
button.setAttribute("tooltiptext", "Replace an existing bookmark");
button.style.listStyleImage = "url(" + icon + ")";
button.addEventListener("command", main.action, false);
toolbox.palette.appendChild(button);
This code is thanks to dgutov and is seen in full context at his repository here at GitHub: dgutov / bmreplace / bootstrap.js.
Watch for a snippet that you can copy and paste into Scratchpad, and then run on Gists@GitHub here: _ff-addon-snippet-AddToolbarButtonToPalette.js . It is based on the code from the repo above.
Here are some discussions at Mozillazine about adding a toolbar button in a Bootstrap addon: Programmatically add a button to toolbar palette?
The advantage to adding the toolbar button to the palette rather than creating an element and then appendChild to the toolbar (document.getElementById('nav-bar')
) or appendChild to the addon bar (document.getElementById('addon-bar')
) is that once in the toolbar palette, users can configure it through the customize menu. They can drag it to the addon bar or to the toolbar.
Styling the button
Most toolbar buttons have icons. To attach an image to the button we use standard Mozilla skinning facilities. If you're unfamiliar with how that works, read the skinning section of Jonah Bishop's excellent Toolbar Tutorial. Although the article covers creating an entire toolbar, rather than just a button, it has a great explanation of the techniques we'll use here.
Icon size
Toolbar buttons can have two different sizes -- big and small. This means you'll need to provide two icons for each of your toolbar buttons. The dimensions of the icons in various applications for both modes are summarized in the following table (feel free to add information about other applications):
Application (Theme name) | Big icon size | Small icon size |
---|---|---|
Firefox 1.0 (Winstripe) | 24x24 | 16x16 |
Thunderbird 1.0 (Qute) | 24x24 | 16x16 |
The stylesheet
To set the image for your toolbar button, use the following CSS rules:
/* skin/toolbar-button.css */ #myextension-button { list-style-image: url("chrome://myextension/skin/btn_large.png"); } toolbar[iconsize="small"] #myextension-button { list-style-image: url("chrome://myextension/skin/btn_small.png"); }
Applying the stylesheet
Remember to attach the stylesheet you created to both the overlay file and the Customize Toolbar window. To attach it to the overlay, put this processing instruction (PI) at the top of the overlay file:
<?xml-stylesheet href="chrome://myextension/skin/toolbar-button.css" type="text/css"?>
chrome.manifest
file. This is very important because the toolbar customization dialog won't work correctly without this.To include the style on your chrome.manifest file:
style chrome://global/content/customizeToolbar.xul chrome://myextension/skin/toolbar-button.css
If you are developing for Firefox 1.0, attach it to the Customize Toolbar window (chrome://global/content/customizeToolbar.xul
) using skin/contents.rdf
. The code looks like this:
<?xml version="1.0"?> <RDF xmlns="https://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="https://www.mozilla.org/rdf/chrome#"> <Seq about="urn:mozilla:skin:root"> <li resource="urn:mozilla:skin:classic/1.0"/> </Seq> <Description about="urn:mozilla:skin:classic/1.0"> <chrome:packages> <Seq about="urn:mozilla:skin:classic/1.0:packages"> <li resource="urn:mozilla:skin:classic/1.0:myextension"/> </Seq> </chrome:packages> </Description> <Seq about="urn:mozilla:stylesheets"> <li resource="chrome://global/content/customizeToolbar.xul"/> </Seq> <Seq about="chrome://global/content/customizeToolbar.xul"> <li>chrome://myextension/skin/toolbar-button.css</li> </Seq> </RDF>
The skin/contents.rdf
file is denigrated in developing for later releases of Firefox. Extensions for Firefox/Thunderbird 1.5 and above should instead use something like this in their chrome.manifest:
skin myextension classic/1.0 chrome/skin/ style chrome://global/content/customizeToolbar.xul chrome://myextension/skin/toolbar-button.css ia
Take note of the Packaging section in this article; you may need to include .jar references if you are delivering your extension as an .xpi file.
Common mistakes
This is a list of the most common mistakes made by extension authors, including both symptoms and solutions.
Problem: The whole set of default buttons is painted on the toolbar or in the Customize Toolbars window, instead of your own icon.
Caused by: Malformed or not applied stylesheet.
Solution: Check to be sure your stylesheet is correct, make sure your contents.rdf
(or chrome.manifest
) is correct, and be sure you didn't forget to apply the stylesheet to customizeToolbar.xul
.
A list of commonly overlayed windows with toolbars
URL | Application and affected window(s) | Palette id |
---|---|---|
chrome://browser/content/browser.xul | Firefox - Main window | BrowserToolbarPalette |
chrome://navigator/content/navigator.xul | SeaMonkey 2.0 - Browser window | BrowserToolbarPalette |
chrome://messenger/content/messenger.xul | Thunderbird - Main window | MailToolbarPalette |
chrome://messenger/content/messenger...gercompose.xul | Thunderbird - Compose window | MsgComposeToolbarPalette |
chrome://messenger/content/addressbo...ddressbook.xul | Thunderbird - Address book | AddressBookToolbarPalette |
chrome://editor/content/editor.xul | Kompozer - Main window | NvuToolbarPalette |
chrome://calendar/content/calendar.xul | Sunbird - Main window | calendarToolbarPalette |
More information
- XulPlanet.com references:
<toolbarbutton>
,<toolbaritem>
. - How to adjust toolbar button's label position
- A forum thread about adding an item to the toolbar (instead of just adding it to palette) right after an extension is installed. Note that this is not recommended.
- There is another page on mdc with information about adding buttons to various windows in SeaMonkey. Includes useful information about overlays for ChatZilla.