Daily Archives: July 14, 2010

Getting your Firefox extension version number

Sometimes you just want to show the version number (or any other meta data) of your own Firefox addon as specified in the install.rdf. You want to display this in your about page for example. In Firefox 2 and 3, you can to use this function:

function getVersion(addonID) {
		var extMan = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
		var ext = extMan.getItemForID(addonID);
		ext.QueryInterface(Components.interfaces.nsIUpdateItem);
		return ext.version;
}

// usage
var version = getVersion("{my addon id}");

Inputting your addon ID, you will get your version number back. Inside the method, the variable ext (nsIUpdateItem) has a lot more metadata properties you can use as well if you so choose.

However, in the new Firefox version 4, the addon APIs have totally changed. The call to get the addon metadata has changed from synchronous to asynchronous which tends throws a spanner into the works. There seems to be a tendency to migrate all javascript data calls to asynchronous to avoid freezing the UI. Thus, rewriting getVersion means rewriting all the consumers to expect asynchronous operations. Here’s the new version that supports Firefox versions 2 to 4.

function getVersion(addonID, callback) {
	var ascope = { };

	if (typeof(Components.classes["@mozilla.org/extensions/manager;1"]) != 'undefined') {
		var extMan = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
		var ext = extMan.getItemForID(addonID);
		ext.QueryInterface(Components.interfaces.nsIUpdateItem);
		callback(ext.version);
		return;
	}

	if (typeof(Components.utils) != 'undefined' && typeof(Components.utils.import) != 'undefined') {
		Components.utils.import("resource://gre/modules/AddonManager.jsm", ascope);
	}

	ascope.AddonManager.getAddonByID(addonID, function (addon) { callback(addon.version); } );

}

// usage:
var version;
getVersion("{my addon id}", function(ver) { version = ver; });
// you don't know when version will be populated

Generally, in my use cases, I need to get the version and I don’t want to continue on until I have the version. Other than rewriting, the only workaround is to fetch the version number on extension start up and cache it somewhere. Thus all subsequent get version calls will get that cached number synchronously. Such a pain :/