Building an extension

  • Revision slug: Building_an_Extension
  • Revision title: Building an extension
  • Revision id: 33284
  • Created:
  • Creator: Pile0nades
  • Is current revision? No
  • Comment /* Setting up the Development Environment */ added /chrome/chromeFiles/content/

Revision Content

Introduction

This tutorial will take you through the steps required to build a very basic extension - one which adds a status bar panel to the Firefox browser containing the text "Hello, World!"

Note This tutorial is about building extensions for Firefox 1.5. Other tutorials exist for building extensions for earlier versions of Firefox.

Setting up the Development Environment

Extensions are packaged and distributed in ZIP files with the <tt>xpi</tt> (pronounced “zippy”) file extension. The layout of content within the XPI file is like so:

extension.xpi:
              /chrome/
              /chrome/chromeFiles/
              /chrome/chromeFiles/content/
              /components/
              /defaults/
              /defaults/preferences/
              chrome.manifest
              install.rdf

Because of this, it is easiest if we lay out our source files in a similar fashion, unless you want to write some sort of Makefile or shell script to package and zip all of your files. Even if you are prepared to do that, testing is much simpler if you lay out your files like this because of a feature of Firefox 1.5's Addon System.

So let's get started. Create a folder for your extension somewhere on your hard disk, e.g. <tt>c:\extensions\myExtension\</tt>. Inside this folder create another folder called <tt>chrome</tt>, inside the <tt>chrome</tt> folder create a folder called <tt>chromeFiles</tt> and inside the <tt>chromeFiles</tt> folder create a folder called <tt>content</tt>.

Inside the root of your extension folder, alongside the <tt>chrome</tt> folder create two new empty text files, one called <tt>chrome.manifest</tt> and the other called <tt>install.rdf</tt>.

Create the Install Manifest

Open the file called <tt>install.rdf</tt> that you created at the top of your extension's folder hierarchy and put this inside:

<?xml version="1.0"?>

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

  <Description about="urn:mozilla:install-manifest">
    <em:id>sample@foo.net</em:id>
    <em:version>1.0</em:version>
    <em:type>2</em:type>
   
    <!-- Target Application this extension can install into, 
         with minimum and maximum supported versions. --> 
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>1.0+</em:minVersion>
        <em:maxVersion>1.5</em:maxVersion>
      </Description>
    </em:targetApplication>
   
    <!-- Front End MetaData -->
    <em:name>Sample!</em:name>
    <em:description>A test extension</em:description>
    <em:creator>Your Name Here</em:creator>
    <em:homepageURL>http://www.foo.com/</em:homepageURL>
  </Description>      
</RDF>

sample@foo.net - the ID of the extension. This is some value you come up with to identify your extension in email address format. Make it unique. You could also use a GUID.

{ec8030f7-c20a-464f-9b0e-13a3a9e97384} - Firefox's application ID.

1.0+ - the minimum version of Firefox you're saying this extension will work with. Set this as the minimum version you're going to commit to testing and fixing bugs with.

1.5 - the maximum version of Firefox you're saying this extension will work with. Set this to be no newer than the newest currently available version!

See Install Manifests for a complete listing of the required and optional properties.

Save the file.

Extending the Browser with XUL

Firefox's user interface is written in XUL and JavaScript. XUL is an XML grammar that provides user interface widgets like buttons, menus, toolbars, trees etc. User actions are bound to functionality using JavaScript.

To extend the browser, we modify parts of the browser UI by adding or modifying widgets. We add widgets by inserting new XUL DOM elements into the browser window, and modify them by using script and attaching event handlers.

The browser is implemented in a XUL file called <tt>browser.xul</tt>. In browser.xul we can find the status bar, which looks something like this:

<statusbar id="status-bar">
 ... <statusbarpanel>s ...
</statusbar>

<tt><statusbar id="status-bar"></tt> is a "merge point" for a XUL Overlay.

XUL Overlays

XUL Overlays are a way of attaching other UI widgets to a XUL document at run time. A XUL Overlay is a .xul file that specifies XUL fragments to insert at specific merge points within a "master" document. These fragments can specify widgets to be inserted, removed, or modified.

Example XUL Overlay Document

<?xml version="1.0"?>
<overlay id="sample" 
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 <statusbar id="status-bar">
  <statusbarpanel id="my-panel" label="Hello, World"/>
 </statusbar>
</overlay>

The <tt><statusbar></tt> called <tt>status-bar</tt> specifies the "merge point" within the browser window that we want to attach to.

The <tt><statusbarpanel></tt> child is a new widget that we want to insert within the merge point.

Take this sample code above and save it into a file called <tt>sample.xul</tt> inside the <tt>chrome/chromeFiles/content</tt> folder you created.

For more information about merging widgets and modifying user interface using Overlays, see below.

Chrome URIs

XUL files are part of "Chrome Packages" - bundles of user interface components which are loaded via <tt>chrome://</tt> URIs. Rather than load the browser from disk using a <tt>file://</tt> URI (since the location of Firefox on the system can change from platform to platform and system to system), Mozilla developers came up with a solution for creating URIs to XUL content that the installed application knows about.

The browser is: <tt>chrome://browser/content/browser.xul</tt> Try typing this URL into the location bar in Firefox!

Chrome URIs consist of several components:

  • Firstly, the URI scheme (<tt>chrome</tt>) which tells Firefox's networking library that this is a Chrome URI and that content being loaded from one needs to be handled specially.
  • Secondly, a package name (in the example above, <tt>browser</tt>) which identifies the bundle of user interface components. This should be as unique to your application as possible to avoid collisions between extensions.
  • Thirdly, the type of data being requested. There are three types: <tt>content</tt> (XUL, JavaScript, XML XBL bindings etc that form the structure and behavior of an application UI), <tt>locale</tt> (DTD, .properties files etc that contain strings for the UI's localization), and <tt>skin</tt> (CSS and images that form the theme of the UI)
  • Finally, a file name to load.

So, <tt>chrome://foo/skin/bar.png</tt> loads the file <tt>bar.png</tt> from <tt>foo</tt>'s theme <tt>skin</tt> section.

When you load content using a Chrome URI, Firefox uses the Chrome Registry to translate these URIs into the actual source files on disk (or in JAR packages).

Create a Chrome Manifest

For more information on Chrome Manifests and the properties they support, see the Chrome Manifest Reference.

Open the file called <tt>chrome.manifest</tt> that you created alongside the <tt>chrome</tt> directory at the root of your extension's source folder hierarchy.

Add in this code:

content     sample    chrome/chromeFiles/content/

This specifies the:

  1. type of material within a chrome package
  2. name of the chrome package
  3. location of the chrome packages' files

So, this line says that for a chrome package sample, we can find its content files at the location <tt>chrome/chromeFiles/content</tt> which is a path relative to the location of <tt>chrome.manifest</tt>.

Note that content, locale and skin files must be kept inside folders called content, locale and skin within your <tt>chrome</tt> subdirectory.

Save the file. When you launch Firefox with your extension, this will register the chrome package.

Register an Overlay

You need Firefox to merge your overlay with the browser window whenever it displays one. So add this line to your <tt>chrome.manifest</tt> file:

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

This tells Firefox to merge <tt>sample.xul</tt> into <tt>browser.xul</tt> when <tt>browser.xul</tt> loads.

Test

First, we need to tell Firefox about your extension. In the bad old days of Firefox 1.0 this meant packaging your extension as a XPI and installing it through the user interface, which was a real pain. Now, it's much simpler.

  1. Open your Profile Folder http://kb.mozillazine.org/Profile_folder
  2. Open the extensions folder (create it if it doesn't exists)
  3. Create a new text file, and put the path to your extension folder inside, e.g. <tt>C:\extensions\myExtension\</tt>. Save the file with the id of your extension as its name, e.g. <tt>sample@foo.net</tt>

Now you're ready to test your extension!

Start Firefox. Firefox will detect the text link to your extension directory and install the Extension. When the browser window appears you should see the Hello, World! status bar panel.

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

Package

Now that your extension works, you can package it for deployment and installation.

Zip up the contents of your extension's folder, and rename the zip file to have a .xpi extension. In Windows, you can do this easily by selecting all the files and subfolders in your extension folder, right click and choose "Send To -> Compressed (Zipped) Folder". A .zip file will be created for you. Just rename it and you're done!

Now upload the .xpi file to your server, making sure it's served as <tt>application/x-xpinstall</tt>. You can link to it and allow people to download and install it in Firefox.

Using addons.mozilla.org

Mozilla Update is a distribution site where you can host your extension for free. Your extension will be hosted on Mozilla's mirror network to guarantee your download even though it might be very popular. Mozilla's site also provides users easier installation, and will automatically make your newer versions available to users of your existing versions when you upload them. In addition Mozilla Update allows users to comment and provide feedback on your extension. It is highly recommended that you use Mozilla Update to distribute your extensions!

Visit http://addons.mozilla.org/developers/ to create an account and begin distributing your extensions!

Registering Extensions in the Windows Registry

On Windows, information about extensions can be added to the registry, and the extensions will automatically be picked up the next time the applications starts. This allows application installers to easily add integration hooks as extensions. See Adding Extensions using the Windows Registry for more information.

More on XUL Overlays

In addition to appending UI widgets to the merge point, you can use XUL fragments within Overlays to:

  • Modify attributes on the merge point, e.g. <tt><statusbar id="status-bar" hidden="true"/></tt> (hides the status bar)
  • Remove the merge point from the master document, e.g. <tt><statusbar id="status-bar" removeelement="true"/></tt>
  • Control the position of the inserted widgets:
<statusbarpanel position="1" .../>

<statusbarpanel insertbefore="other-id" .../>

<statusbarpanel insertafter="other-id" .../>

Creating New User Interface Components

You can create your own windows and dialog boxes as separate .xul files, provide functionality by implementing user actions in .js files, using DOM methods to manipulate UI widgets. You can use style rules in .css files to attach images, set colors etc.

View the XUL documentation for more resources for XUL developers.

Defaults Files

Defaults files that you use to seed a user's profile with should be placed in <tt>defaults/</tt> under the root of your extension's folder hierarchy. Default preferences .js files should be stored in <tt>defaults/preferences/</tt> - when you place them here they will be automatically loaded by Firefox's preferences system when it starts so that you can access them using the Preferences API.

XPCOM Components

Firefox supports XPCOM components in extensions. You can implement interfaces easily in JavaScript, or in C++ (using the Gecko SDK: http://wiki.mozilla.org/Gecko:SDK ).

Place all of your .js or .dll files in the <tt>components/</tt> directory - they are automatically registered the first time Firefox runs after your extension is installed.

Localization

To support more than one language, you should separate strings from your content using entities and string bundles. It is much easier to do this as you are developing your extension than to come back and do it later!

To create localizable attribute values in XUL, you put the values in a <tt>.ent</tt> (or a <tt>.dtd</tt>) file, which looks like this:

<!ENTITY  button.label     "Click Me!">
<!ENTITY  button.accesskey "C">

And then include it at the top of your XUL document like so:

<!DOCTYPE window SYSTEM "chrome://packagename/locale/filename.ent">

window is the <tt>localName</tt> value of the root element of the XUL document, and the value of the <tt>SYSTEM</tt> property is the chrome URI to the entity file.

To use the entities, modify your XUL to look like this:

<button label="&button.label;" accesskey="&button.accesskey;"/>

The Chrome Registry will make sure the entity file is loaded from the localization bundle corresponding to the selected locale.

For strings that you use in script, create a .properties file, a text file that has a string on each line in this format:

key=value

and then use <tt>nsIStringBundleService</tt>/<tt>nsIStringBundle</tt> or the <tt><stringbundle></tt> tag to load the values into script.

Understanding the Browser

Use the DOM Inspector (not part of the Standard Firefox installation, you must reinstall with the Custom install path and choose Developer Tools if there is not a "DOM Inspector" item in your browser's Tools menu) to inspect the browser window or any other XUL window you want to extend.

Use the point-and-click node finder button at the top left of the DOM Inspector's toolbar to click on a node in the XUL window visually to select it. When you do this the DOM inspector's DOM hierarchy tree view will jump to the node you clicked on.

Use the DOM Inspector's right side panel to discover merge points with ids that you can use to insert your elements from overlays. If you cannot discover an element with an id that you can merge into, you may need to attach a script in your overlay and insert your elements when the <tt>load</tt> event fires on the master XUL window.

Debugging Extensions

Analytical Tools for Debugging

  • The DOM Inspector - inspect attributes, DOM structure, CSS style rules that are in effect (e.g. find out why your style rules don't seem to be working for an element - an invaluable tool!)
  • Venkman - set breakpoints in JavaScript and inspect call stacks
  • arguments.callee.caller in JavaScript - access a function's call stack

printf debugging

  • Run an optimized build of Firefox with <tt>-console</tt> at the command line and use dump("string")
  • Use <tt>nsIConsoleService</tt> to log to the Script console

Advanced debugging

  • Run a debug Firefox build and set breakpoints in Firefox itself, or your C++ components. For the experienced developer, this is often the fastest way to diagnose a problem.
{{ wiki.languages( { "de": "de/Erweiterung_erstellen" } ) }}

Revision Source

<h4 name="Introduction"> Introduction </h4>
<p>This tutorial will take you through the steps required to build a very basic extension - one which adds a status bar panel to the Firefox browser containing the text "Hello, World!"
</p><p><b>Note</b> This tutorial is about building extensions for Firefox 1.5. Other tutorials exist for building extensions for earlier versions of Firefox. 
</p>
<h4 name="Setting_up_the_Development_Environment"> Setting up the Development Environment </h4>
<p>Extensions are packaged and distributed in ZIP files with the <tt>xpi</tt> (<i>pronounced “zippy”</i>) file extension. The layout of content within the XPI file is like so:
</p>
<pre class="eval">extension.xpi:
              /chrome/
              /chrome/chromeFiles/
              /chrome/chromeFiles/content/
              /components/
              /defaults/
              /defaults/preferences/
              chrome.manifest
              install.rdf
</pre>
<p>Because of this, it is easiest if we lay out our source files in a similar fashion, unless you want to write some sort of Makefile or shell script to package and zip all of your files. Even if you are prepared to do that, testing is much simpler if you lay out your files like this because of a feature of Firefox 1.5's Addon System. 
</p><p>So let's get started. Create a folder for your extension somewhere on your hard disk, e.g. <tt>c:\extensions\myExtension\</tt>. Inside this folder create another folder called <tt>chrome</tt>, inside the <tt>chrome</tt> folder create a folder called <tt>chromeFiles</tt> and inside the <tt>chromeFiles</tt> folder create a folder called <tt>content</tt>. 
</p><p>Inside the root of your extension folder, alongside the <tt>chrome</tt> folder create two new empty text files, one called <tt>chrome.manifest</tt> and the other called <tt>install.rdf</tt>.
</p>
<h4 name="Create_the_Install_Manifest"> Create the Install Manifest </h4>
<p>Open the file called <tt><a href="en/Install_Manifests">install.rdf</a></tt> that you created at the top of your extension's folder hierarchy and put this inside:
</p>
<pre class="eval">&lt;?xml version="1.0"?&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;<b>sample@foo.net</b>&lt;/em:id&gt;
    &lt;em:version&gt;<b>1.0</b>&lt;/em:version&gt;
    &lt;em:type&gt;2&lt;/em:type&gt;
   
    &lt;!-- Target Application this extension can install into, 
         with minimum and maximum supported versions. --&gt; 
    &lt;em:targetApplication&gt;
      &lt;Description&gt;
        &lt;em:id&gt;<b>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</b>&lt;/em:id&gt;
        &lt;em:minVersion&gt;<b>1.0+</b>&lt;/em:minVersion&gt;
        &lt;em:maxVersion&gt;<b>1.5</b>&lt;/em:maxVersion&gt;
      &lt;/Description&gt;
    &lt;/em:targetApplication&gt;
   
    &lt;!-- Front End MetaData --&gt;
    &lt;em:name&gt;<b>Sample!</b>&lt;/em:name&gt;
    &lt;em:description&gt;<b>A test extension</b>&lt;/em:description&gt;
    &lt;em:creator&gt;<b>Your Name Here</b>&lt;/em:creator&gt;
    &lt;em:homepageURL&gt;<b>http://www.foo.com/</b>&lt;/em:homepageURL&gt;
  &lt;/Description&gt;      
&lt;/RDF&gt;
</pre>
<p><b>sample@foo.net</b> - the ID of the extension. This is some value you come up with to identify your extension in email address format. Make it unique. You could also use a GUID. 
</p><p><b>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</b> - Firefox's application ID.
</p><p><b>1.0+</b> - the minimum version of Firefox you're saying this extension will work with. Set this as the minimum version you're going to commit to testing and fixing bugs with. 
</p><p><b>1.5</b> - the maximum version of Firefox you're saying this extension will work with. Set this to be no newer than the newest currently available version!
</p><p>See <a href="en/Install_Manifests">Install Manifests</a> for a complete listing of the required and optional properties. 
</p><p>Save the file.
</p>
<h4 name="Extending_the_Browser_with_XUL"> Extending the Browser with XUL </h4>
<p>Firefox's user interface is written in XUL and JavaScript. <a href="en/XUL">XUL</a> is an XML grammar that provides user interface widgets like buttons, menus, toolbars, trees etc. User actions are bound to functionality using JavaScript. 
</p><p>To extend the browser, we modify parts of the browser UI by adding or modifying widgets. We add widgets by inserting new XUL DOM elements into the browser window, and modify them by using script and attaching event handlers. 
</p><p>The browser is implemented in a XUL file called <tt>browser.xul</tt>. In browser.xul we can find the status bar, which looks something like this:
</p>
<pre class="eval">&lt;statusbar id="status-bar"&gt;
 ... &lt;statusbarpanel&gt;s ...
&lt;/statusbar&gt;
</pre>
<p><tt>&lt;statusbar id="status-bar"&gt;</tt> is a "merge point" for a XUL Overlay.
</p>
<h5 name="XUL_Overlays"> XUL Overlays </h5>
<p>XUL Overlays are a way of attaching other UI widgets to a XUL document at run time. A XUL Overlay is a .xul file that specifies XUL fragments to insert at specific merge points within a "master" document. These fragments can specify widgets to be inserted, removed, or modified. 
</p><p><b>Example XUL Overlay Document</b>
</p>
<pre class="eval">&lt;?xml version="1.0"?&gt;
&lt;overlay id="sample" 
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
 &lt;statusbar id="<b>status-bar</b>"&gt;
  &lt;statusbarpanel id="my-panel" label="Hello, World"/&gt;
 &lt;/statusbar&gt;
&lt;/overlay&gt;
</pre>
<p>The <tt>&lt;statusbar&gt;</tt> called <tt><b>status-bar</b></tt> specifies the "merge point" within the browser window that we want to attach to. 
</p><p>The <tt>&lt;statusbarpanel&gt;</tt> child is a new widget that we want to insert within the merge point. 
</p><p>Take this sample code above and save it into a file called <tt><b>sample.xul</b></tt> inside the <tt>chrome/chromeFiles/content</tt> folder you created.
</p><p>For more information about merging widgets and modifying user interface using Overlays, see below.
</p>
<h4 name="Chrome_URIs"> Chrome URIs </h4>
<p>XUL files are part of "Chrome Packages" - bundles of user interface components which are loaded via <tt>chrome://</tt> URIs. Rather than load the browser from disk using a <tt>file://</tt> URI (since the location of Firefox on the system can change from platform to platform and system to system), Mozilla developers came up with a solution for creating URIs to XUL content that the installed application knows about. 
</p><p>The browser is: <tt>chrome://browser/content/browser.xul</tt> Try typing this URL into the location bar in Firefox!
</p><p>Chrome URIs consist of several components:
</p>
<ul><li> Firstly, the <b>URI scheme</b> (<tt>chrome</tt>) which tells Firefox's networking library that this is a Chrome URI and that content being loaded from one needs to be handled specially. 
</li><li> Secondly, a package name (in the example above, <tt><b>browser</b></tt>) which identifies the bundle of user interface components. This should be as unique to your application as possible to avoid collisions between extensions. 
</li><li> Thirdly, the type of data being requested. There are three types: <tt>content</tt> (XUL, JavaScript, XML XBL bindings etc that form the structure and behavior of an application UI), <tt>locale</tt> (DTD, .properties files etc that contain strings for the UI's localization), and <tt>skin</tt> (CSS and images that form the theme of the UI)
</li><li> Finally, a file name to load. 
</li></ul>
<p>So, <tt>chrome://foo/skin/bar.png</tt> loads the file <tt>bar.png</tt> from <tt>foo</tt>'s theme <tt>skin</tt> section. 
</p><p>When you load content using a Chrome URI, Firefox uses the Chrome Registry to translate these URIs into the actual source files on disk (or in JAR packages).
</p>
<h4 name="Create_a_Chrome_Manifest"> Create a Chrome Manifest </h4>
<p>For more information on Chrome Manifests and the properties they support, see the <a href="en/Chrome_Manifest">Chrome Manifest</a> Reference.
</p><p>Open the file called <tt><b>chrome.manifest</b></tt> that you created alongside the <tt>chrome</tt> directory at the root of your extension's source folder hierarchy. 
</p><p>Add in this code:
</p>
<pre class="eval">content     sample    chrome/chromeFiles/content/
</pre>
<p>This specifies the:
</p>
<ol><li> type of material within a chrome package
</li><li> name of the chrome package
</li><li> location of the chrome packages' files
</li></ol>
<p>So, this line says that for a chrome package <b>sample</b>, we can find its <b>content</b> files at the location <tt>chrome/chromeFiles/content</tt> which is a path relative to the location of <tt>chrome.manifest</tt>. 
</p><p>Note that content, locale and skin files must be kept inside folders called content, locale and skin within your <tt>chrome</tt> subdirectory.
</p><p>Save the file. When you launch Firefox with your extension, this will register the chrome package.
</p>
<h4 name="Register_an_Overlay"> Register an Overlay </h4>
<p>You need Firefox to merge your overlay with the browser window whenever it displays one. So add this line to your <tt>chrome.manifest</tt> file:
</p>
<pre class="eval">overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
</pre>
<p>This tells Firefox to merge <tt>sample.xul</tt> into <tt>browser.xul</tt> when <tt>browser.xul</tt> loads.
</p>
<h4 name="Test"> Test </h4>
<p>First, we need to tell Firefox about your extension. In the bad old days of Firefox 1.0 this meant packaging your extension as a XPI and installing it through the user interface, which was a real pain. Now, it's much simpler. 
</p>
<ol><li> Open your Profile Folder http://kb.mozillazine.org/Profile_folder
</li><li> Open the <b>extensions</b> folder (create it if it doesn't exists)
</li><li> Create a new text file, and put the path to your extension folder inside, e.g. <tt>C:\extensions\myExtension\</tt>. Save the file with the id of your extension as its name, e.g. <tt>sample@foo.net</tt>
</li></ol>
<p>Now you're ready to test your extension!
</p><p>Start Firefox. Firefox will detect the text link to your extension directory and install the Extension. When the browser window appears you should see the Hello, World! status bar panel. 
</p><p>You can now go back and make changes to the .xul file, close and restart Firefox and they should appear.
</p>
<h4 name="Package"> Package </h4>
<p>Now that your extension works, you can package it for deployment and installation. 
</p><p>Zip up the contents of your extension's folder, and rename the zip file to have a .xpi extension. In Windows, you can do this easily by selecting all the files and subfolders in your extension folder, right click and choose "Send To -&gt; Compressed (Zipped) Folder". A .zip file will be created for you. Just rename it and you're done!
</p><p>Now upload the .xpi file to your server, making sure it's served as <tt>application/x-xpinstall</tt>. You can link to it and allow people to download and install it in Firefox. 
</p>
<h5 name="Using_addons.mozilla.org"> Using addons.mozilla.org </h5>
<p>Mozilla Update is a distribution site where you can host your extension for free. Your extension will be hosted on Mozilla's mirror network to guarantee your download even though it might be very popular. Mozilla's site also provides users easier installation, and will automatically make your newer versions available to users of your existing versions when you upload them. In addition Mozilla Update allows users to comment and provide feedback on your extension. It is highly recommended that you use Mozilla Update to distribute your extensions!
</p><p>Visit http://addons.mozilla.org/developers/ to create an account and begin distributing your extensions!
</p>
<h5 name="Registering_Extensions_in_the_Windows_Registry"> Registering Extensions in the Windows Registry </h5>
<p>On Windows, information about extensions can be added to the registry, and the extensions will automatically be picked up the next time the applications starts. This allows application installers to easily add integration hooks as extensions. See <a href="en/Adding_Extensions_using_the_Windows_Registry">Adding Extensions using the Windows Registry</a> for more information.
</p>
<h4 name="More_on_XUL_Overlays"> More on XUL Overlays </h4>
<p>In addition to appending UI widgets to the merge point, you can use XUL fragments within Overlays to:
</p>
<ul><li> Modify attributes on the merge point, e.g. <tt>&lt;statusbar id="status-bar" hidden="true"/&gt;</tt> (hides the status bar)
</li><li> Remove the merge point from the master document, e.g. <tt>&lt;statusbar id="status-bar" removeelement="true"/&gt;</tt>
</li><li> Control the position of the inserted widgets:
</li></ul>
<pre class="eval">&lt;statusbarpanel position="1" .../&gt;

&lt;statusbarpanel insertbefore="other-id" .../&gt;

&lt;statusbarpanel insertafter="other-id" .../&gt;
</pre>
<h4 name="Creating_New_User_Interface_Components"> Creating New User Interface Components </h4>
<p>You can create your own windows and dialog boxes as separate .xul files, provide functionality by implementing user actions in .js files, using DOM methods to manipulate UI widgets. You can use style rules in .css files to attach images, set colors etc.
</p><p>View the <a href="en/XUL">XUL</a> documentation for more resources for XUL developers.
</p>
<h4 name="Defaults_Files"> Defaults Files </h4>
<p>Defaults files that you use to seed a user's profile with should be placed in <tt>defaults/</tt> under the root of your extension's folder hierarchy. Default preferences .js files should be stored in <tt>defaults/preferences/</tt> - when you place them here they will be automatically loaded by Firefox's preferences system when it starts so that you can access them using the Preferences API.
</p>
<h4 name="XPCOM_Components"> XPCOM Components </h4>
<p>Firefox supports <a href="en/XPCOM">XPCOM</a> components in extensions. You can implement interfaces easily in JavaScript, or in C++ (using the Gecko SDK: http://wiki.mozilla.org/Gecko:SDK ). 
</p><p>Place all of your .js or .dll files in the <tt>components/</tt> directory - they are automatically registered the first time Firefox runs after your extension is installed.
</p>
<h4 name="Localization"> Localization </h4>
<p>To support more than one language, you should separate strings from your content using entities and string bundles. It is much easier to do this as you are developing your extension than to come back and do it later!
</p><p>To create localizable attribute values in XUL, you put the values in a <tt>.ent</tt> (or a <tt>.dtd</tt>) file, which looks like this:
</p>
<pre class="eval">&lt;!ENTITY  button.label     "Click Me!"&gt;
&lt;!ENTITY  button.accesskey "C"&gt;
</pre>
<p>And then include it at the top of your XUL document like so:
</p>
<pre class="eval">&lt;!DOCTYPE <b>window</b> SYSTEM "chrome://packagename/locale/filename.ent"&gt;
</pre>
<p><b>window</b> is the <tt>localName</tt> value of the root element of the XUL document, and the value of the <tt>SYSTEM</tt> property is the chrome URI to the entity file. 
</p><p>To use the entities, modify your XUL to look like this:
</p>
<pre class="eval">&lt;button label="&amp;button.label;" accesskey="&amp;button.accesskey;"/&gt;
</pre>
<p>The Chrome Registry will make sure the entity file is loaded from the localization bundle corresponding to the selected locale. 
</p><p>For strings that you use in script, create a .properties file, a text file that has a string on each line in this format:
</p>
<pre class="eval">key=value
</pre>
<p>and then use <tt>nsIStringBundleService</tt>/<tt>nsIStringBundle</tt> or the <tt>&lt;stringbundle&gt;</tt> tag to load the values into script.
</p>
<h4 name="Understanding_the_Browser"> Understanding the Browser </h4>
<p>Use the DOM Inspector (not part of the <b>Standard</b> Firefox installation, you must reinstall with the Custom install path and choose <b>Developer Tools</b> if there is not a "DOM Inspector" item in your browser's Tools menu) to inspect the browser window or any other XUL window you want to extend. 
</p><p>Use the point-and-click node finder button at the top left of the DOM Inspector's toolbar to click on a node in the XUL window visually to select it. When you do this the DOM inspector's DOM hierarchy tree view will jump to the node you clicked on. 
</p><p>Use the DOM Inspector's right side panel to discover merge points with ids that you can use to insert your elements from overlays. If you cannot discover an element with an id that you can merge into, you may need to attach a script in your overlay and insert your elements when the <tt>load</tt> event fires on the master XUL window.
</p>
<h4 name="Debugging_Extensions"> Debugging Extensions </h4>
<p><b>Analytical Tools for Debugging</b>
</p>
<ul><li> The <a href="en/DOM_Inspector">DOM Inspector</a> - inspect attributes, DOM structure, CSS style rules that are in effect (e.g. find out why your style rules don't seem to be working for an element - an invaluable tool!)
</li><li> <a href="en/Venkman">Venkman</a> - set breakpoints in JavaScript and inspect call stacks
</li><li> <code><a href="en/Core_JavaScript_1.5_Reference/Objects/Function/arguments/callee">arguments.callee</a>.<a href="en/Core_JavaScript_1.5_Reference/Objects/Function/caller">caller</a></code> in JavaScript - access a function's call stack
</li></ul>
<p><b>printf debugging</b>
</p>
<ul><li> Run an optimized build of Firefox with <tt>-console</tt> at the command line and use <code><a href="en/Window.dump">dump</a>("string")</code>
</li><li> Use <tt><a href="en/NsIConsoleService">nsIConsoleService</a></tt> to log to the Script console
</li></ul>
<p><b>Advanced debugging</b>
</p>
<ul><li> Run a debug Firefox build and set breakpoints in Firefox itself, or your C++ components. For the experienced developer, this is often the fastest way to diagnose a problem.
</li></ul>
{{ wiki.languages( { "de": "de/Erweiterung_erstellen" } ) }}
Revert to this revision