MathJax

SyntaxHighlighter

Highlight

Custom CSS

Thursday, March 25, 2010

The Anatomy of a Firefox 3.5 Extension

The directory structure of a Firefox 3.5.x extension looks like this:

.
   |-chrome
   |---content
   |---modules
   |---skin
   |-----css
   |-----images
   |-defaults
   |---preferences
   |-locale
   |---en-US
   |-chrome.manifest
   |-install.rdf

chrome.manifest

This structure is not mandated by Firefox; you'll have to let it know in your chrome.manifest, which looks like this:

content  myextension chrome/content/
content  myextension chrome/content/ contentaccessible=yes
locale   myextension en-US locale/en-US/
skin     myextension classic/1.0 chrome/skin/
resource myextension chrome/modules/
overlay  chrome://browser/content/browser.xul chrome://myextension/content/myOverlay.xul

Old versions of Firefox allowed you to serve up images with chrome URI's (ie, starting with chrome://), but that feature was removed in Firefox 3.x. To emulate the old behavior, you'll need to add contentaccessible=yes. Since older versions of Firefox don't recognize that contentaccessible (in fact, they ignore it; see below), you'll need to put both lines in the manifest.

install.rdf

The manifest is for describing some things about your extension, but you'll have to put the rest of the information in a file called install.rdf. Here's a sample:

<?xml version="1.0"?>                            
<RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#" 
     xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <Description about="urn:mozilla:install-manifest">
    <em:id>myextension@lousycoder.com</em:id>
    <em:name>My Extension</em:name>
    <em:version>1.0.0</em:version>
    <em:type>2</em:type>
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>3.5</em:minVersion>
        <em:maxVersion>3.6.*</em:maxVersion>
      </Description>  
    </em:targetApplication>
    <em:aboutURL>chrome://myextension/content/about.xul</em:aboutURL>
    <em:iconURL>chrome://myextension/skin/images/logo.png</em:iconURL>
    <em:updateURL>https://www.lousycoder.com/update.rdf</em:updateURL>
    <em:creator>Me!</em:creator>
    <em:description>
      A test extension for funsies.
    </em:description>
    <em:homepageURL>http://www.writeonglass.com</em:homepageURL>
  </Description>
</RDF>

Most of the data there is self explanatory, but the version numbers can be tricky when it comes to auto update. Extension versions must follow a very specific format, and auto-update does some very complicated logic to determine which version is greater than another. For example, version 1.0 is considered the same as version 1.1-1 (because 1 - 1 = 0); yes arithmetic is conveniently done for you! Also, strings are compared bytewise instead of alphabetically. For this reason, I would advise extension version strings to only consist of numbers and periods... unless the extension is being hosted by AMO in the beta channel (in which case, version strings are ignored, and the newest version is the one last uploaded).

Overlays

XUL overlays are "merged" with whatever XUL document you are overlaying onto; in the case above it would be chrome://browser/content/browser.xul. In this way, you can add menus and/or buttons to Firefox's UI. There are special considerations for Javascript executing in the context of a browser overlay; for example, the window refers to a chrome window, and the document object refers to a XUL document, as opposed to their normal web page counterparts. Additionally, setting any global variables on window makes them available for other overlays (and extensions), so it's quite easy to clobber other extensions if you are not careful.

Modules

Code modules are executed in their own context, and the global object is not any window. In fact, the window and document objects are not even defined within code modules. There is no way to clobber variables with other extensions, as the only variables exposed by a module are the ones declared in the special EXPORTED_SYMBOLS array (see modules at MDC).

Gotchas

If you have any syntax errors in your XUL files (eg the overlay files), your extension will be shown as installed, but no errors will appear in the Error Console. If you open the XUL file directly in Firefox, via File -> Open -> file://path/to/xul/file.xul, you'll see any errors that Firefox did not report.

If you do not place the trailing slash after any path in chrome.manifest (eg chrome/content instead of chrome/content/), then Firefox will silently ignore that line in the manifest.

References

https://developer.mozilla.org/en/Chrome_Registration
https://developer.mozilla.org/en/Toolkit_version_format
https://developer.mozilla.org/index.php?title=en/Extension_Versioning,_Update_and_Compatibility
https://addons.mozilla.org/en-US/developers/docs/policies/maintenance#beta-addons
https://developer.mozilla.org/En/Code_snippets/Modules
Post a Comment