Updating extensions for Firefox 3.5

  • Revision slug: Updating_extensions_for_Firefox_3.5
  • Revision title: Updating extensions for Firefox 3.5
  • Revision id: 63969
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment 60 words added, 11 words removed

Revision Content

{{ fx_minversion_header("3") }}

This article provides helpful information to extension developers trying to update their extensions to work properly in Firefox 3.5.

Note: Because Firefox 3.5 was previously planned to be Firefox 3.1, there are some minor quirks here.  In particular, until Firefox 3.5 beta 4 builds begin, the version number will be Firefox 3.1b2 or 3.1b3.  Keep this in mind as you read this.

Update basics

This section covers the basics of what you need to do whenever you update an extension for a new version of Firefox.

Test your extension

Start by editing your extension's install.rdf file, updating maxVersion to 3.1b2 (if you're testing on Firefox 3.1 beta 2), and increase your extension's version.

Then create a new Firefox profile so that your testing doesn't risk your usual profile.  Navigate to the directory containing Firefox, then issue the command:

firefox -createProfile testBeta2

On the Mac, you need to navigate all the way into the Firefox application bundle:

cd /Applications/Firefox.app/Contents/MacOS/
firefox -createProfile testBeta2

Launch Firefox using the new profile by issuing this command on the command line:

firefox -P testBeta2

Test your extension thoroughly.  We suggest you set the following preferences to true in order to be alerted to any JavaScript warnings or exceptions:

  • javascript.options.strict
  • javascript.options.showInConsole

Update your extension

If you run into any problems while testing, update your code to fix the issues.  This article contains useful information about things that may require some work.

Once you've done that, try using your extension again, this time with your regular profile.  This will help to ensure compatibility with any existing saved data.

Update your extension on addons.mozilla.org

Finally, it's time to release your updated extension.  If your extension didn't need any code changes you can simply log into the AMO dashboard and update the compatibility version there.  Otherwise, you'll need to upload a new version to AMO.

See Submitting an add-on to AMO for additional information.

Accessing the Places database

Prior to Firefox 3.5, accessing the Places database directly using the Storage API required a little bit of trickery:

var places = Components.classes["@mozilla.org/file/directory_service;1"].
                        getService(Components.interfaces.nsIProperties).
                        get("ProfD", Components.interfaces.nsIFile);
places.append("places.sqlite");
var db = Components.classes["@mozilla.org/storage/service;1"].
                    getService(Components.interfaces.mozIStorageService).openDatabase(places);

This builds a path to the places.sqlite database file manually, then opens the file for Storage access.

Firefox 3.5 adds a dedicated service that offers a convenient way to access the Places database; the above technique does not work in Firefox 3.1 or later.

var db = Components.classes["@mozilla.org/browser/nav-history-service;1"].
                    getService(Components.interfaces.nsPIPlacesDatabase).DBConnection;

Search textboxes

The textbox type timed is deprecated; instead, you should use search.

In Firefox 3, you might have used:

<textbox type="timed" timeout="1000" oncommand="alert(this.value);"/>

In Firefox 3.5, you should change this to:

<textbox type="search" timeout="1000" oncommand="alert(this.value);"/>

JSON

The JSON.jsm JavaScript module was dropped in Firefox 3.5 in favor of native JSON object support.  For details, see Using JSON in Firefox and the article on JSON for a more general overview of JSON and how to use it in various versions of Firefox.

To ensure compatibility with both Firefox 3 and Firefox 3.5, you can do the following:

if (typeof(JSON) == "undefined") {
  Components.utils.import("resource://gre/modules/JSON.jsm");
  JSON.parse = JSON.fromString;
  JSON.stringify = JSON.toString;
}

This works by importing the JSON.jsm JavaScript module if JSON isn't supported natively, then mapping the methods provided by that module to the ones used by native JSON, so that the same calls work.

You can also bypass this issue by using the {{ interface("nsIJSON") }} interface directly.

Changes to chrome registration

Firefox 3.5 closes a security hole that made it possible to use remote chrome.  This will affect any add-on that includes a resource in their chrome.manifest file that references a web site.  See Security changes in Firefox 3.1 for details.

Getting a load context from a request

Previously, it was possible to get a load context from a request by querying various docShell APIs.  This correct and reliable way to do this is to use an {{ interface("nsILoadContext") }}.

From C++, you can do it like this:

nsCOMPtr<nsILoadContext> loadContext;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
NS_QueryNotificationCallbacks(channel, loadContext);

From JavaScript, you do it like this:

var loadContext;
try {
  loadContext = 
    aRequest.queryInterface(Components.interfaces.nsIChannel)
            .notificationCallbacks
            .getInterface(Components.interfaces.nsILoadContext);
} catch (ex) {
  try {
    loadContext =
      aRequest.loadGroup.notificationCallbacks
              .getInterface(Components.interfaces.nsILoadContext);
  } catch (ex) {
    loadContext = null;
  }
}

Customizable toolbars

In Firefox 3.5, customizable toolbar behavior has changed such that the <xul:toolbar/> binding now removes toolbar items from its associated <xul:toolbarpalette/> and  adds them to the toolbar, rather than cloning them and copying them to the toolbar. This means that the palette will now only contain items not present on the toolbar, as opposed to the previous behavior of containing all customizable elements whether or not they were displayed on the toolbar. This might cause trouble for addons that depend on being able to retrieve all customizable toolbar items from the <xul:toolbarpalette/>, or who attempt to dynamically insert items into the palette to make them available during toolbar customization. More information is available in {{ Bug("407725") }} and {{ Bug("467045") }}.

New capabilities of interest

Listening to events on all tabs

Firefox 3.5 introduces support for adding and removing progress listeners that listen on all tabs.  See Listening to events on all tabs for details.

For Theme developers:

  • Check Theme changes in Firefox 3.1.
  • Go to the Mozillazine forum Theme changes for FF3.1 to get an overview / listing of all changes between 3.0 and 3.1 that impact theme developers. This concerns new CSS features (like nth-child, -moz-box-shadow, etc), changes to existing widgets, overall UI improvements, and new FF3.1 features (audio/video support, private browsing, extended session restore, box/window/text shadows).

Revision Source

<p>{{ fx_minversion_header("3") }}</p>
<p>This article provides helpful information to extension developers trying to update their extensions to work properly in Firefox 3.5.</p>
<div class="note"><strong>Note:</strong> Because Firefox 3.5 was previously planned to be Firefox 3.1, there are some minor quirks here.  In particular, until Firefox 3.5 beta 4 builds begin, the version number will be Firefox 3.1b2 or 3.1b3.  Keep this in mind as you read this.</div>
<h2>Update basics</h2>
<p>This section covers the basics of what you need to do whenever you update an extension for a new version of Firefox.</p>
<h3>Test your extension</h3>
<p>Start by editing your extension's <code>install.rdf</code> file, updating <code>maxVersion</code> to 3.1b2 (if you're testing on Firefox 3.1 beta 2), and increase your extension's <code>version</code>.</p>
<p>Then create a new Firefox profile so that your testing doesn't risk your usual profile.  Navigate to the directory containing Firefox, then issue the command:</p>
<pre>firefox -createProfile testBeta2
</pre>
<p>On the Mac, you need to navigate all the way into the Firefox application bundle:</p>
<pre>cd /Applications/Firefox.app/Contents/MacOS/
firefox -createProfile testBeta2
</pre>
<p>Launch Firefox using the new profile by issuing this command on the command line:</p>
<pre>firefox -P testBeta2
</pre>
<p>Test your extension thoroughly.  We suggest you set the following preferences to true in order to be alerted to any JavaScript warnings or exceptions:</p>
<ul> <li><code>javascript.options.strict</code></li> <li><code>javascript.options.showInConsole</code></li>
</ul>
<h3>Update your extension</h3>
<p>If you run into any problems while testing, update your code to fix the issues.  This article contains useful information about things that may require some work.</p>
<p>Once you've done that, try using your extension again, this time with your regular profile.  This will help to ensure compatibility with any existing saved data.</p>
<h3>Update your extension on addons.mozilla.org</h3>
<p>Finally, it's time to release your updated extension.  If your extension didn't need any code changes you can simply log into the AMO dashboard and update the compatibility version there.  Otherwise, you'll need to upload a new version to AMO.</p>
<p>See <a class="internal" href="/en/Submitting_an_add-on_to_AMO" title="En/Submitting an add-on to AMO">Submitting an add-on to AMO</a> for additional information.</p>
<h2>Accessing the Places database</h2>
<p>Prior to Firefox 3.5, accessing the Places database directly using the <a class="internal" href="/en/Storage" title="En/Storage">Storage API</a> required a little bit of trickery:</p>
<pre class="brush: js">var places = Components.classes["@mozilla.org/file/directory_service;1"].
                        getService(Components.interfaces.nsIProperties).
                        get("ProfD", Components.interfaces.nsIFile);
places.append("places.sqlite");
var db = Components.classes["@mozilla.org/storage/service;1"].
                    getService(Components.interfaces.mozIStorageService).openDatabase(places);
</pre>
<p>This builds a path to the <code>places.sqlite</code> database file manually, then opens the file for Storage access.</p>
<p>Firefox 3.5 adds a dedicated service that offers a convenient way to access the Places database; the above technique does not work in Firefox 3.1 or later.</p>
<pre class="brush: js">var db = Components.classes["@mozilla.org/browser/nav-history-service;1"].
                    getService(Components.interfaces.nsPIPlacesDatabase).DBConnection;
</pre>
<h2>Search textboxes</h2>
<p>The <a class="internal" href="/en/XUL/textbox" title="En/XUL/Textbox"><code>textbox</code></a> type <code>timed</code> is deprecated; instead, you should use <code>search</code>.</p>
<p>In Firefox 3, you might have used:</p>
<pre>&lt;textbox type="timed" timeout="1000" oncommand="alert(this.value);"/&gt;
</pre>
<p>In Firefox 3.5, you should change this to:</p>
<pre>&lt;textbox type="search" timeout="1000" oncommand="alert(this.value);"/&gt;
</pre>
<h2>JSON</h2>
<p>The JSON.jsm JavaScript module was dropped in Firefox 3.5 in favor of native JSON object support.  For details, see <a class="internal" href="/En/Using_JSON_in_Firefox" title="/en/Using JSON in Firefox">Using JSON in Firefox</a> and the article on <a class="internal" href="/en/JSON" title="En/JSON">JSON</a> for a more general overview of JSON and how to use it in various versions of Firefox.</p>
<p>To ensure compatibility with both Firefox 3 and Firefox 3.5, you can do the following:</p>
<pre class="brush: js">if (typeof(JSON) == "undefined") {
  Components.utils.import("resource://gre/modules/JSON.jsm");
  JSON.parse = JSON.fromString;
  JSON.stringify = JSON.toString;
}
</pre>
<p>This works by importing the JSON.jsm JavaScript module if JSON isn't supported natively, then mapping the methods provided by that module to the ones used by native JSON, so that the same calls work.</p>
<p>You can also bypass this issue by using the {{ interface("nsIJSON") }} interface directly.</p>
<h2>Changes to chrome registration</h2>
<p>Firefox 3.5 closes a security hole that made it possible to use remote chrome.  This will affect any add-on that includes a resource in their <code>chrome.manifest</code> file that references a web site.  See <a class="internal" href="/En/Security_changes_in_Firefox_3.1" title="En/Security changes in Firefox 3.1">Security changes in Firefox 3.1</a> for details.</p>
<h2>Getting a load context from a request</h2>
<p>Previously, it was possible to get a load context from a request by querying various docShell APIs.  This correct and reliable way to do this is to use an {{ interface("nsILoadContext") }}.</p>
<p>From C++, you can do it like this:</p>
<pre class="brush: cpp">nsCOMPtr&lt;nsILoadContext&gt; loadContext;
nsCOMPtr&lt;nsIChannel&gt; channel = do_QueryInterface(aRequest);
NS_QueryNotificationCallbacks(channel, loadContext);
</pre>
<p>From JavaScript, you do it like this:</p>
<pre class="brush: js">var loadContext;
try {
  loadContext = 
    aRequest.queryInterface(Components.interfaces.nsIChannel)
            .notificationCallbacks
            .getInterface(Components.interfaces.nsILoadContext);
} catch (ex) {
  try {
    loadContext =
      aRequest.loadGroup.notificationCallbacks
              .getInterface(Components.interfaces.nsILoadContext);
  } catch (ex) {
    loadContext = null;
  }
}
</pre>
<h2>Customizable toolbars</h2>
<p>In Firefox 3.5, customizable toolbar behavior has changed such that the <code>&lt;xul:toolbar/&gt; </code>binding now removes toolbar items from its associated <code>&lt;xul:toolbarpalette/&gt;</code> and  adds them to the toolbar, rather than cloning them and copying them to the toolbar. This means that the palette will now only contain items not present on the toolbar, as opposed to the previous behavior of containing all customizable elements whether or not they were displayed on the toolbar. This might cause trouble for addons that depend on being able to retrieve all customizable toolbar items from the <code>&lt;xul:toolbarpalette/&gt;</code>, or who attempt to dynamically insert items into the palette to make them available during toolbar customization. More information is available in {{ Bug("407725") }} and {{ Bug("467045") }}.</p>
<h2>New capabilities of interest</h2>
<h3>Listening to events on all tabs</h3>
<p>Firefox 3.5 introduces support for adding and removing progress listeners that listen on all tabs.  See <a class="internal" href="/En/Listening_to_events_on_all_tabs" title="en/Listening to events on all tabs">Listening to events on all tabs</a> for details.</p>
<h2>For Theme developers:</h2>
<ul> <li>Check <a class="internal" href="../../../../En/Theme_changes_in_Firefox_3.1" rel="internal">Theme changes in Firefox 3.1</a>.</li> <li>Go to the Mozillazine forum <a class="topictitle external" href="http://forums.mozillazine.org/viewtopic.php?f=18&amp;t=665138" title="http://forums.mozillazine.org/viewtopic.php?f=18&amp;t=665138">Theme changes for FF3.1</a> to get an overview / listing of all changes between 3.0 and 3.1 that impact theme developers. This concerns new CSS features (like nth-child, -moz-box-shadow, etc), changes to existing widgets, overall UI improvements, and new FF3.1 features (audio/video support, private browsing, extended session restore, box/window/text shadows).</li>
</ul>
Revert to this revision