This article needs a technical review. How you can help.
There are a variety of ways you can install extensions and themes from web pages, including direct linking to the XPI files and using the InstallTrigger object.
Extension and web authors are encouraged to use the method described below to install XPIs, as it provides the best experience to users.
Web Script Example
<script type="application/javascript"> <!-- function install (aEvent) { for (var a = aEvent.target; a.href === undefined;) a = a.parentNode; var params = { "Foo": { URL: aEvent.target.href, IconURL: aEvent.target.getAttribute("iconURL"), Hash: aEvent.target.getAttribute("hash"), toString: function () { return this.URL; } } }; InstallTrigger.install(params); return false; } --> </script> <a href="https://www.example.com/foo.xpi" iconURL="https://www.example.com/foo.png" hash="sha1:28857e60d043447c5f4550853f2d40770b326a13" onclick="return install(event);">Install Extension!</a>
Let's go through this piece by piece. The HTML <a> is the install link. The href attribute contains a direct link to the extension XPI file, this is what will show in the location bar when the link is moused over. Users can save the XPI file to disk easily by right clicking on the link and choosing "Save Link As..."
When the link is clicked it calls the function install
passing the event object as the parameter.
The install first creates a parameter block:
var params = { "Foo": { URL: aEvent.target.href, IconURL: aEvent.target.getAttribute("iconURL"), Hash: aEvent.target.getAttribute("hash"), toString: function () { return this.URL; } };
This specifies the display name (Foo) for use in the confirmation dialog, the URL to the extension (which is the link href
, recall), the Icon URL to display in the confirmation dialog, a hash of the xpi file contents (to protect against corrupted downloads), and a toString
function which will allow this code to work with versions of Firefox 0.8 and earlier. You could also use the old style parameter block ({ "Foo": aEvent.target.href }
) if you wanted - and didn't have an Icon to use for the confirmation dialog.
InstallTrigger.install
is then called to install the item with the parameter block.
return false;
This last part is the most important - the install function must return false
so that when the link is clicked, only the script is run, and the link href is not navigated to. If you omit this step, the user may see two installation dialogs—since you've effectively invoked two install requests, one from the InstallTrigger
, one from trying to load the XPI file directly.
Available Parameters for the install object
The InstallTrigger.install
method accepts a JavaScript object as a parameter, with several properties on that object used to affect the install.
URL
The URL
property specifies the URL of the XPI to install. This property is required.
IconURL
The IconURL
property specifies an icon to be displayed in the installation dialog. This property is optional. If you do not specify an icon, the default icon will be used, usually a green puzzle piece. The icon can be any image format supported by Firefox, and should be 32x32 pixels in size.
Hash
The Hash
property specifies a cryptographic hash of the XPI file contents. This is used to verify the downloaded file, to protect against a corrupted file being served by a mirror download server, for example. You can use any hash function supported by nsICryptoHash. The hash is specified as hash function:hash value
, for example, sha1:28857e60d043447c5f4550853f2d40770b326a13
.
toString()
The toString()
property should return the XPI URL, for compatibility with Firefox browsers older than version 1.0, and other applications such as Seamonkey.
Themes
Pretty much everything I've described applies to themes too, except you'll use the installChrome
function. Because so many sites installed extensions by direct-linking the XPI file and relying on content handling to invoke the confirmation UI, many sites are (incorrectly) doing so for theme JAR files too and wondering why they aren't auto-detected and installed. Well, XPI is a Mozilla-specific extension and so we can have special handling for it, but JAR is not - not all .jar files are Firefox themes, so if you click on a .jar link you'll be shown the Save As decision dialog. For this reason you should always use the InstallTrigger
API to install themes.
A Note on updateEnabled()
InstallTrigger
exposes a function called updateEnabled
that some of you may be calling before you call InstallTrigger.install
. This is not necessary as install calls updateEnabled
itself internally. Furthermore, calling updateEnabled
may lead to problems if your distribution site is not in the user's whitelist, because Firefox only displays the "Installation Blocked" message when install or installChrome
are called, or when a XPI file is loaded. So, if you have code that looks like this:
if (InstallTrigger.updateEnabled()) InstallTrigger.install({"Foo": "foo.xpi"});
... and your site is not in the whitelist, when the user invokes that code, updateEnabled
will return false
because your site isn't whitelisted, and since it was updateEnabled
that discovered this, not a call to install, there will be no notification to the user.
Thus you should only use updateEnabled
to display content in the page to alert the user that software installation is disabled, or your site is not in the whitelist—do not place it in the install code path.
(* by all means don't let this stop you from developing more ambitious install systems, I am providing this documentation only as a guide that I hope most extension distributors will use since it handles most cases well)