Creating a Firefox sidebar

  • Revision slug: Creating_a_Firefox_sidebar
  • Revision title: Creating a Firefox sidebar
  • Revision id: 94311
  • Created:
  • Creator: MarkFinkle
  • Is current revision? No
  • Comment Converted to FF2 extension mechanism

Revision Content

This article describes how to create a registered sidebar for the Firefox browser.

Introduction

This article is a quick start for the creation of a new sidebar for Firefox. What we will do is create a sidebar and register it so it will be available in the menu. The goal is creating an empty sidebar that can be used as start for new sidebar applications.

Creating a sidebar requires some GUI creation and registration in the destination application. First a simple XUL page is created. Then the registration files are made and finally the sidebar is packed into an installable XPI file.

Pre-requisites

This article is a quick start, it won't explain all elements of XUL, packaging and XPI's. It's preferable you have some basic knowledge of how XUL works and how Firefox handles extensions.

Packages

Additions to Firefox are installed with packages. A packages exists of the XUL and application logics. Optionally locales and skins can be included. Most additions are provided with a default tree structure, although not required it is recommended to use this structure. Here the package for the sidebar is created, the files included are listed below.

Example 1. Package structure

emptysidebar
\- chrome
   |- content
   |- locale
   | \- en-US 
   \- skin

Create all folders, except for <tt>skin</tt>. It is not used for this tutorial.

The <tt>locale</tt> holds the locale, only the <tt>en-US</tt> locale is created. It is listed in Example 2. The locale includes the name and shortcut keys for the sidebar.

Example 2. chrome/locale/en-US/emptysidebar.dtd

<!ENTITY emptysidebar.title "EmptySidebar">
<!ENTITY openEmptySidebar.commandkey "E">
<!ENTITY openEmptySidebar.modifierskey "shift accel">

The content folder includes our sidebar, the <tt>emptysidebar.xul</tt> is printed in Example 3. It creates a page holding one label. Other elements can be included, please read the XUL tutorials for more information.

Example 3. chrome/content/emptysidebar.xul

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type"text/css" ?>
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css" ?>
<!DOCTYPE page SYSTEM "chrome://emptysidebar/locale/emptysidebar.dtd">

<page id="sbEmptySidebar" title="&emptysidebar.title;"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
  <vbox flex="1">
    <label id="atest" value="&emptysidebar.title;" />
  </vbox>
</page>

New extensions can be registered in the menus or popups, Firefox uses an overlays for extending menus. This is an separate XUL file that specifies the location of menu items. The sidebar here is added to the View | Sidebar menu. The overlay file is listed in Example 4.

Example 4. chrome/contents/firefoxOverlay.xul

<?xml version="1.0"?>

<!DOCTYPE overlay SYSTEM "chrome://emptysidebar/locale/emptysidebar.dtd">
<overlay id="emptySidebarOverlay"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  
  <menupopup id="viewSidebarMenu">
    <menuitem key="key_openEmptySidebar" observes="viewEmptySidebar"  />
  </menupopup>
  
  <keyset id="mainKeyset">
    <key id="key_openEmptySidebar" command="viewEmptySidebar"
         key="&openEmptySidebar.commandkey;" 
         modifiers="&openEmptySidebar.modifierskey;" />
  </keyset>
  
  <broadcasterset id="mainBroadcasterSet"> 
    <broadcaster id="viewEmptySidebar" 
                 label="&emptysidebar.title;"
                 autoCheck="false"
                 type="checkbox"
                 group="sidebar"
                 sidebarurl="chrome://emptysidebar/content/emptysidebar.xul"
                 sidebartitle="&emptysidebar.title;"
                 oncommand="toggleSidebar('viewEmptySidebar');" />
  </broadcasterset>
</overlay>

The overlay file consists of three entries, the menu definition, shortcut keys and the event handler for UI elements. The broadcaster is linked to an UI element with the observes attribute. The broadcaster viewEmptySidebar defines how a click on the menu is handled or the shortcut keys are pressed.

The extension needs to provide some special manifest files that control how it is installed and where it's chrome resources are stored. The first is <tt>install.rdf</tt>, the install manifest. See Install Manifests for a complete listing of the required and optional properties. The install manifest is listed in Example 5.

Example 5. install.rdf

<?xml version="1.0" encoding="UTF-8"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
 xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  <Description about="urn:mozilla:install-manifest">
    <em:id>emptysidebar@yourdomain.com</em:id>
    <em:name>EmptySidebar Extension</em:name>
    <em:version>1.0</em:version>
    <em:creator>Your Name</em:creator>
    <em:description>Example extension for creation and registration of a sidebar.</em:description>
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->
        <em:minVersion>1.5</em:minVersion>
        <em:maxVersion>2.0.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>
  </Description>
</RDF>

The other manifest file is <tt>chrome.manifest</tt>, the chrome manifest file. The chrome manifest creates a lookup for all the resource types used by the extensions. The manifest also tells Firefox that the extension has an overlay that needs to be merged into the browser. For more information on chrome manifests and the properties they support, see the Chrome Manifest Reference. The install manifest is listed in Example 6.

Example 6. chrome.manifest

content	emptysidebar	content/
locale	emptysidebar	en-US	locale/en-US/
skin	emptysidebar	classic/1.0	skin/
overlay	chrome://browser/content/browser.xul	chrome://emptysidebar/content/firefoxOverlay.xul

Test

First, we need to tell Firefox about your extension.

  1. Open your Profile Folder
  2. Open the extensions folder (create it if it doesn't exist)
  3. Create a new text file, and put the path to your extension folder inside, e.g. C:\extensions\myExtension\ or ~/extensions/myExtension. Save the file with the id of your extension as its name, e.g. emptysidebar@yourdomain.com

Now you're ready to test your extension! Restart Firefox and the sidebar is included in the menu.

Image:sidebar-test.png

You can now go back and make changes to the .xul file, close and restart Firefox and they should appear.

Deployment

Now that we have a sidebar it is time to make it availible to the world. Installation requires the creation of an XPI file which is identified as extension in Firefox. The XPI is a ZIP file containing the content, locale and manifest files.

The content, locale and skin folders are packed into <tt>emptysidebar.jar</tt>, create this file in the <tt>chrome</tt> folder. On unix systems:

~/src/emptysidebar$ cd chrome
~/src/emptysidebar/chrome$ zip -r emptysidebar.jar content/ locale/

On Windows systems, just use a ZIP tool to create <tt>emptysidebar.zip</tt> and then rename to <tt>emptysidebar.jar</tt>.

Since we are packaging the extension with a JAR file, we need to update the chrome.manifest file to take to JAR file into consideration:

Example 7. chrome.manifest

content emptysidebar	jar:chrome/emptysidebar.jar!/content/
locale  emptysidebar	en-US	jar:chrome/emptysidebar.jar!/locale/en-US/
skin    emptysidebar	classic/1.0	jar:chrome/emptysidebar.jar!/skin/
overlay chrome://browser/content/browser.xul	chrome://emptysidebar/content/firefoxOverlay.xul

Finally, create the XPI file. This is a ZIP file containing the JAR file in the chrome folder and the manifest files. On unix systems:

~/src/emptysidebar/chrome$ cd ..
~/src/emptysidebar$ zip emptysidebar.xpi install.rdf chrome.manifest chrome/emptysidebar.jar

Open Firefox and browse to the folder containing <tt>emptysidebar.xpi</tt>. Click on the file and the Extension installation window pops up. After a restart of Firefox the sidebar is installed. Or click here for the XPI.

Image:sidebar-installed.png
The EmptySidebar extension

Resources

Revision Source

<p>
</p><p>This article describes how to create a registered sidebar for the Firefox browser.
</p>
<h2 name="Introduction"> Introduction </h2>
<p>This article is a quick start for the creation of a new sidebar for Firefox. What we will do is create a sidebar and register it so it will be available in the menu. The goal is creating an empty sidebar that can be used as start for new sidebar applications.
</p><p>Creating a sidebar requires some GUI creation and registration in the destination application. First a simple XUL page is created. Then the registration files are made and finally the sidebar is packed into an installable XPI file.
</p>
<h2 name="Pre-requisites"> Pre-requisites </h2>
<p>This article is a quick start, it won't explain all elements of XUL, packaging and XPI's. It's preferable you have some basic knowledge of how XUL works and how Firefox handles extensions.
</p>
<h2 name="Packages"> Packages </h2>
<p>Additions to Firefox are installed with packages. A packages exists of the XUL and application logics. Optionally locales and skins can be included. Most additions are provided with a default tree structure, although not required it is recommended to use this structure. Here the package for the sidebar is created, the files included are listed
below.
</p>
<div class="example" id="package_structure">
<p><b>Example 1. Package structure</b>
</p>
<pre>emptysidebar
\- chrome
   |- content
   |- locale
   | \- en-US 
   \- skin
</pre>
</div>
<p>Create all folders, except for <tt>skin</tt>. It is not used for this tutorial.
</p><p>The <tt>locale</tt> holds the locale, only the <tt>en-US</tt> locale is created. It is listed in <a href="#en-us_emptysidebar.dtd">Example 2</a>. The locale includes the name and shortcut keys for the sidebar.
</p>
<div class="example" id="en-us_emptysidebar.dtd">
<p><b>Example 2. chrome/locale/en-US/emptysidebar.dtd</b>
</p>
<pre class="eval">&lt;!ENTITY emptysidebar.title "EmptySidebar"&gt;
&lt;!ENTITY openEmptySidebar.commandkey "E"&gt;
&lt;!ENTITY openEmptySidebar.modifierskey "shift accel"&gt;
</pre>
<p>The content folder includes our sidebar, the <tt>emptysidebar.xul</tt> is printed in <a href="#emptysidebar_xul">Example 3</a>. It
creates a <a class="external" href="http://books.mozdev.org/html/appc-77238.html">page</a> holding one label. Other elements can be included, please read the XUL tutorials for more information.
</p>
<div class="example" id="emptysidebar_xul">
<p><b>Example 3. chrome/content/emptysidebar.xul</b>
</p>
<pre>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet href="chrome://global/skin/" type"text/css" ?&gt;
&lt;?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css" ?&gt;
&lt;!DOCTYPE page SYSTEM "chrome://emptysidebar/locale/emptysidebar.dtd"&gt;

&lt;page id="sbEmptySidebar" title="&amp;emptysidebar.title;"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" &gt;
  &lt;vbox flex="1"&gt;
    &lt;label id="atest" value="&amp;emptysidebar.title;" /&gt;
  &lt;/vbox&gt;
&lt;/page&gt;
</pre>
</div>
<p>New extensions can be registered in the menus or popups, Firefox uses an overlays for extending menus. This is an separate XUL file that specifies the location of menu items. The sidebar here is added to the View | Sidebar menu. The overlay file is listed in <a href="#overlay_xul">Example 4</a>.
</p>
<div class="example" id="overlay_xul">
<p><b>Example 4. chrome/contents/firefoxOverlay.xul</b>
</p>
<pre>&lt;?xml version="1.0"?&gt;

&lt;!DOCTYPE overlay SYSTEM "chrome://emptysidebar/locale/emptysidebar.dtd"&gt;
&lt;overlay id="emptySidebarOverlay"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
  
  &lt;menupopup id="viewSidebarMenu"&gt;
    &lt;menuitem key="key_openEmptySidebar" observes="viewEmptySidebar"  /&gt;
  &lt;/menupopup&gt;
  
  &lt;keyset id="mainKeyset"&gt;
    &lt;key id="key_openEmptySidebar" command="viewEmptySidebar"
         key="&amp;openEmptySidebar.commandkey;" 
         modifiers="&amp;openEmptySidebar.modifierskey;" /&gt;
  &lt;/keyset&gt;
  
  &lt;broadcasterset id="mainBroadcasterSet"&gt; 
    &lt;broadcaster id="viewEmptySidebar" 
                 label="&amp;emptysidebar.title;"
                 autoCheck="false"
                 type="checkbox"
                 group="sidebar"
                 sidebarurl="chrome://emptysidebar/content/emptysidebar.xul"
                 sidebartitle="&amp;emptysidebar.title;"
                 oncommand="toggleSidebar('viewEmptySidebar');" /&gt;
  &lt;/broadcasterset&gt;
&lt;/overlay&gt;
</pre>
</div>
<p>The overlay file consists of three entries, the menu definition, shortcut keys and the event handler for UI elements. The broadcaster is linked to an UI element with the <code>observes</code> attribute. The broadcaster <code>viewEmptySidebar</code> defines how a click on the menu is handled or the shortcut keys are pressed.
</p><p>The extension needs to provide some special manifest files that control how it is installed and where it's chrome resources are stored. The first is <tt>install.rdf</tt>, the install manifest. See <a href="en/Install_Manifests"> Install Manifests</a> for a complete listing of the required and optional properties. The install manifest is listed in <a href="#install_manifest">Example 5</a>.
</p>
<div class="example" id="install_manifest">
<p><b>Example 5. install.rdf</b>
</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
 xmlns:em="http://www.mozilla.org/2004/em-rdf#"&gt;
  &lt;Description about="urn:mozilla:install-manifest"&gt;
    &lt;em:id&gt;emptysidebar@yourdomain.com&lt;/em:id&gt;
    &lt;em:name&gt;EmptySidebar Extension&lt;/em:name&gt;
    &lt;em:version&gt;1.0&lt;/em:version&gt;
    &lt;em:creator&gt;Your Name&lt;/em:creator&gt;
    &lt;em:description&gt;Example extension for creation and registration of a sidebar.&lt;/em:description&gt;
    &lt;em:targetApplication&gt;
      &lt;Description&gt;
        &lt;em:id&gt;{ec8030f7-c20a-464f-9b0e-13a3a9e97384}&lt;/em:id&gt; &lt;!-- firefox --&gt;
        &lt;em:minVersion&gt;1.5&lt;/em:minVersion&gt;
        &lt;em:maxVersion&gt;2.0.0.*&lt;/em:maxVersion&gt;
      &lt;/Description&gt;
    &lt;/em:targetApplication&gt;
  &lt;/Description&gt;
&lt;/RDF&gt;
</pre>
</div>
<p>The other manifest file is <tt>chrome.manifest</tt>, the chrome manifest file. The chrome manifest creates a lookup for all the resource types used by the extensions. The manifest also tells Firefox that the extension has an overlay that needs to be merged into the browser. For more information on chrome manifests and the properties they support, see the <a href="en/Chrome_Manifest"> Chrome Manifest</a> Reference.  The install manifest is listed in <a href="#chrome_manifest">Example 6</a>.
</p>
<div class="example" id="chrome_manifest">
<p><b>Example 6. chrome.manifest</b>
</p>
<pre>content	emptysidebar	content/
locale	emptysidebar	en-US	locale/en-US/
skin	emptysidebar	classic/1.0	skin/
overlay	chrome://browser/content/browser.xul	chrome://emptysidebar/content/firefoxOverlay.xul
</pre>
</div>
<h2 name="Test"> Test </h2>
<p>First, we need to tell Firefox about your extension.
</p>
<ol><li> Open your Profile Folder
</li><li> Open the extensions folder (create it if it doesn't exist)
</li><li> Create a new text file, and put the path to your extension folder inside, e.g. C:\extensions\myExtension\ or ~/extensions/myExtension. Save the file with the id of your extension as its name, e.g. emptysidebar@yourdomain.com 
</li></ol>
<p>Now you're ready to test your extension! Restart Firefox and the sidebar is included in the menu.
</p><p><img alt="Image:sidebar-test.png" src="File:en/Media_Gallery/Sidebar-test.png">
</p><p>You can now go back and make changes to the .xul file, close and restart Firefox and they should appear. 
</p>
<h2 name="Deployment"> Deployment </h2>
<p>Now that we have a sidebar it is time to make it availible to the world. Installation requires the creation of an XPI file which is identified as extension in Firefox. The XPI is a ZIP file containing the content, locale and manifest files.
</p><p>The content, locale and skin folders are packed into <tt>emptysidebar.jar</tt>, create this file in the <tt>chrome</tt> folder. On unix systems:
</p>
<pre class="eval">~/src/emptysidebar$ <b>cd chrome</b>
~/src/emptysidebar/chrome$ <b>zip -r emptysidebar.jar content/ locale/</b>
</pre>
<p>On Windows systems, just use a ZIP tool to create <tt>emptysidebar.zip</tt> and then rename to <tt>emptysidebar.jar</tt>.
</p><p>Since we are packaging the extension with a JAR file, we need to update the chrome.manifest file to take to JAR file into consideration:
</p>
<div class="example" id="chrome_manifest_jar">
<p><b>Example 7. chrome.manifest</b>
</p>
<pre>content emptysidebar	jar:chrome/emptysidebar.jar!/content/
locale  emptysidebar	en-US	jar:chrome/emptysidebar.jar!/locale/en-US/
skin    emptysidebar	classic/1.0	jar:chrome/emptysidebar.jar!/skin/
overlay chrome://browser/content/browser.xul	chrome://emptysidebar/content/firefoxOverlay.xul
</pre>
</div>
<p>Finally, create the XPI file. This is a ZIP file containing the JAR file in the chrome folder and the manifest files. On unix systems:
</p>
<pre class="eval">~/src/emptysidebar/chrome$ <b>cd ..</b>
~/src/emptysidebar$ <b>zip emptysidebar.xpi install.rdf chrome.manifest chrome/emptysidebar.jar</b>
</pre>
<p>Open Firefox and browse to the folder containing <tt>emptysidebar.xpi</tt>. Click on the file and the Extension installation window pops up. After a restart of Firefox the sidebar is installed. Or click <a class="external" href="http://occidopagus.nl/firefox/emptysidebar/examples/emptysidebar.xpi">here</a> for the XPI.
</p>
<div class="figure" id="emptysidebar_extension">
<p><img alt="Image:sidebar-installed.png" src="File:en/Media_Gallery/Sidebar-installed.png"><br>
<b>The EmptySidebar extension</b>
</p>
</div>
<h2 name="Resources"> Resources </h2>
<ul><li> <a href="en/Building_an_Extension"> Building an Extension</a>
</li><li> <a class="external" href="http://books.mozdev.org/html/index.html">Creating Applications with Mozilla</a>
</li><li> <a class="external" href="http://www.bengoodger.com/software/mb/extensions/packaging/extensions.html">Packaging Firefox/Thunderbird Extensions</a>
</li><li> <a class="external" href="http://occidopagus.nl/firefox/emptysidebar/">Creating a Firefox 1 Sidebar</a></li></ul></div>

Revert to this revision