Getting started with extension development

From MozillaZine Knowledge Base
Revision as of 11:48, 7 June 2005 by Asqueella (talk | contribs) (→‎Setting up your environment: link to 1.1a downloads)
Jump to navigationJump to search

This page is part of the extension development documentation project.

Ask your questions in MozillaZine Forums. Also try browsing example code.

Note: development documentation is in process of being moved to Mozilla Development Center (MDC).

Two new major extension developers' features introduced in Firefox 1.1a are the greatly simplified chrome registration scheme and reworked Extension Manager. It is now even easier to start writing extensions than it was before.

This article describes steps needed to get started with extensions development. Last two sections have a few development tips and packaging information. Most of it is targeted at beginners in extension development, although the setup tips should be useful for everybody.

It's a wiki page, so feel free to make improvements to this page and to add your feedback on the Talk page. However questions and requests for help are better suited for the forums.

Extensions created in this way will only work on Firefox 1.1 and later, but you should be able to make changes to make your extension compatible with Firefox 1.0 quite easily later.

Setting up your environment

This article focuses on Firefox extensions, although it also applies to other Toolkit applications, such as Thunderbird.

The first thing you need to do is download a recent version of your application. You can get Firefox here. As it was mentioned above, you need Firefox 1.1a or later, setup tips from this article may not work in earlier versions.

For further instructions, see Setting up extension development environment.

Creating stub extension files

As you should already know extensions usually modify application's UI ("chrome") and behavior by providing overlays to already existent windows/documents. Those overlays are a part of extension's content package (content provider). Most extensions also have one or more locales and skins. (If you didn't know that, we advise you to read XUL Structure chapter from XULPlanet's XUL Tutorial and Configurable Chrome document).

This section describes what directory structure and what files are needed in order to make Firefox register your extension's files.

You can download the ZIP file with all needed stub files and appropriate folder structure and skip to Registering your extension in the Extension Manager. It's recommended that you still read the subsections below though, as they contain explanations of what is the function of each file in the package and provide links to other resources.

Folder structure

Below is the folder structure we will use. You may use different structure, as long as you update your chrome.manifest (see below) accordingly. Create this in the folder where you intend to develop your project:

helloworld/
  chrome.manifest
  install.rdf
  content/
    overlay.js
    overlay.xul
  locale/
    en-US/
      overlay.dtd
  skin/
      overlay.css

The folders are traditionally named "content", "locale" and "skin", and you should follow the tradition. You may call the files inside those folders whatever you want (except chrome.manifest and install.rdf).

Note: This folder structure is for development, you'll need different folder structure when packaging your extension.

Stub files

chrome.manifest

Recent versions of Firefox read simple plaintext chrome.manifest file (instead of old and confusing contents.rdf) to determine what packages and overlays your extension provides. The format of this file is described in the Configurable Chrome document, we'll create an example chrome.manifest file for our folder structure.

It looks like this (assuming your extension's package name is "helloworld"):

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

locale	helloworld	en-US	locale/en-US/

skin	helloworld	classic/1.0	skin/
style	chrome://global/content/customizeToolbar.xul	chrome://helloworld/skin/overlay.css

What each line of the file does:

  • Line 1 registers a content provider: it maps contents of chrome://helloworld/content/ to the content folder.
  • Line 2 registers an overlay for chrome://browser/content/browser.xul location, allowing you to add/modify Firefox main window UI from your overlay.xul file.
  • Line 4 registers a en-US locale provider.
  • Line 6 registers a default skin provider.
  • Line 7 applies your overlay.css style file to chrome://global/content/customizeToolbar.xul document (used, for example, when creating toolbar buttons). You could instead register an overlay and include the stylesheet in the overlay using the <?xml-stylesheet?> processing instruction.

Note: this file will be a bit different when you create an XPI for your extension, see the Packaging section below.

overlay.xul

overlay.xul is a simple XUL overlay. You can read more about overlays at XUL Planet, although that page describes using overlays for a different purpose.

An simple overlay looks like this:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://helloworld/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://helloworld/locale/overlay.dtd">
<overlay id="helloworld-overlay"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="overlay.js"/>

  <menupopup id="menu_ToolsPopup">
    <menuitem id="helloworld-hello" label="&helloworld;" 
              oncommand="HelloWorld.onMenuItemCommand(event);"/>
  </menupopup>
</overlay>

What each line of the file does:

  • Line 1 is the XML declaration, specifying the version of XML being used. It can also be used to specify file's encoding, but that should seldom be needed, as you should put localizable strings in the DTD file.
  • Line 2 is optional and can be used to apply a stylesheet to the base document.
  • Line 3 is also optional, but recommended if you include any user-visible strings in your overlay. It is used to make your overlay localizable.
  • Lines 4-5 define the root element of the overlay. It is must be a XUL <overlay> element.
  • Line 6 is optional and can be used to attach a JavaScript file to the base document. See next section for more information.
  • Lines 8-10 add a menu item to the Tools menu in Firefox main window. See Adding items to menus for more information.

overlay.js

As you may know, JavaScript files are used to define application's behavior. Please refer to the list of JavaScript development resources for information on JavaScript in general.

An important issue you should be aware of is that all scripts that are loaded for a given document (the scripts used by the window itself, and scripts loaded from overlays to that document) share the same scope. This means you should use unique names for global identifiers in your extensions to avoid clashing with other extensions. It's usually accomplished by prefixing all global identifiers with the name of your extension or by putting most/all of your variables and functions in an object with an unique name.

Typical JavaScript file for an overlay looks like this:

var HelloWorld = {
  onLoad: function() {
    // initialization code
    this.initialized = true;
  },

  onMenuItemCommand: function() {
    if(this.initialized)
      alert("Hi!");
  }
};

window.addEventListener("load", function(e) { HelloWorld.onLoad(e); }, false); 

overlay.dtd

DTD files are used to make XUL/XBL/XHTML and other XML files in Mozilla chrome localizable. Basically, instead of hard-coding the strings in your XUL file, you use XML entities, which expand to the values declared in the DTD file referenced at the top of the XUL file.

It makes your extension localizable, because there may be a few different locale providers for your extension, and Mozilla is able to choose between them at run-time.

DTD files used for localization purposes consist of entity declarations like the one below:

<!ENTITY helloworld "Hello World!">

install.rdf

install.rdf file is used by the Extension Manager when installing an XPI file and when registering an extension at specified location. In Firefox 1.1a and later it's only used to provide EM metadata, such as extension's GUID, version, description, author etc. For more information, see install.rdf article.

Registering your extension in the Extension Manager

Once you created the files described above and put them in the appropriate folder structure, registering them in the Extension Manager is trivial. Just create a file with the same name as your extension's GUID in profile folder/extensions/, edit it so that it contains the path to your folder containing install.rdf and chrome.manifest files, and restart Firefox.

E.g. helloworld's GUID is {71e95839-6f7e-470d-be54-77012fec6313} and we would like to register it in X:\Dev\helloworld\ (i.e. there is X:\Dev\helloworld\install.rdf file etc.), I just put a single line in file located at profile folder/extensions/{71e95839-6f7e-470d-be54-77012fec6313}:

X:\Dev\helloworld

(But note bug 291807 and bug 291791 (dataloss).)

Development cycle

Once you have registered your extension following the steps above, developing your extension is quite easy. If you've set the development preferences, your development cycle will be like this:

  1. Edit your extension files.
  2. Reopen the window(s), that modified files apply to, or use Reload chrome feature of Extension Developer Extension.
    • If you changed chrome.manifest, you'll have to restart.
    • If you changed install.rdf, you need to touch the extension folder specified if your "GUID" file (update its Last modified time) and restart.

It's much more convenient compared to the edit-rezip-restart cycle many extension authors were using or the pleasure of editing chrome.rdf file or similar setup tricks.

Packaging

As it was mentioned, the folder structure and chrome.manifest file must be changed before packaging. Cf.:

DevelopingPackaging
Folder structure
helloworld/
  chrome.manifest
  install.rdf
  components/
  defaults/
    preferences/
      mydefaults.js
  content/
    overlay.js
    overlay.xul
  locale/
    en-US/
      overlay.dtd
  skin/
    overlay.css
helloworld.xpi/
  chrome.manifest
  install.rdf
  components/
  defaults/
    preferences/
      mydefaults.js
  chrome/
    helloworld.jar
      content/
        overlay.js
        overlay.xul
      locale/
        en-US/
          overlay.dtd
      skin/
        overlay.css
chrome.manifest (note extra "chrome/helloworld.jar!/" in the right column)
content	helloworld content/
overlay	chrome://browser/content/browser.xul	chrome://helloworld/content/overlay.xul

locale	helloworld	en-US	locale/en-US/

skin	helloworld	classic/1.0	skin/
style	chrome://global/content/customizeToolbar.xul	chrome://helloworld/skin/overlay.css
content	helloworld jar:chrome/helloworld.jar!/content/
overlay	chrome://browser/content/browser.xul	chrome://helloworld/content/overlay.xul

locale	helloworld	en-US	jar:chrome/helloworld.jar!/locale/en-US/

skin	helloworld	classic/1.0	jar:chrome/helloworld.jar!/skin/
style	chrome://global/content/customizeToolbar.xul	chrome://helloworld/skin/overlay.css

TODO: Packaging extensions

Resources