Warning: The content of this article may be out of date. This method of packaging applies to older applications, like Mozilla Suite, Firefox 1.0. See Building an Extension for updated instructions.
Now that we have a static overlay we're in good shape to create a XPI package that installs our extension as a dynamic overlay. XPIs have a complex structure designed to separate UI layers from each other. To make our XPI we'll start out by creating a directory to hold the files we're going to add to the XPI. Then we'll modify URLs in our files so they point to the right place. After that we'll create a contents.rdf
file describing the tinderstatus component for the chrome registry and an install.js
script to perform the installation. Finally we'll zip the files into an archive.
Start out by creating a directory called tinderstatus-installer
. Create a tinderstatus
subdirectory in it and a content
sub-subdirectory in that subdirectory. Copy the following files into the content
sub-subdirectory:
tinderstatusOverlay.xul
tinderstatus.js
tinderstatus.css
tb-busted.png
tb-nostatus.png
tb-success.png
tb-testfailed.png
These are the files we're going to put into the XPI. We need to change some URLs in the copy of tinderstatusOverlay.xul
to point to the new locations the files will be in when they get installed via the XPI:
<?xml version="1.0"?> <?xml-stylesheet href="chrome://tinderstatus/content/tinderstatus.css" type="text/css"?> <overlay id="tinderstatusOverlay" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/javascript" src="chrome://tinderstatus/content/tinderstatus.js" /> <statusbar id="status-bar"> <statusbarpanel class="statusbarpanel-iconic" id="tinderbox-status" insertbefore="offline-status" status="none"/> </statusbar> </overlay>
We also need to change the URLs in the copy of tinderstatus.css
:
statusbarpanel#tinderbox-status { list-style-image: url("chrome://tinderstatus/content/tb-nostatus.png"); } statusbarpanel#tinderbox-status[status="success"] { list-style-image: url("chrome://tinderstatus/content/tb-success.png"); } statusbarpanel#tinderbox-status[status="testfailed"] { list-style-image: url("chrome://tinderstatus/content/tb-testfailed.png"); } statusbarpanel#tinderbox-status[status="busted"] { list-style-image: url("chrome://tinderstatus/content/tb-busted.png"); }
Then we need to create two files in the directory, one called contents.rdf
which contains information for the chrome registry about the component being installed and one called install.js
that contains the code to install the component. contents.rdf
goes in the content
sub-subdirectory:
<?xml version="1.0"?> <RDF:RDF xmlns:RDF="https://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="https://www.mozilla.org/rdf/chrome#"> <RDF:Seq about="urn:mozilla:package:root"> <RDF:li resource="urn:mozilla:package:tinderstatus"/> </RDF:Seq> <RDF:Description about="urn:mozilla:package:tinderstatus" chrome:displayName="Mozilla Tinderstatus Extension" chrome:author="Myk Melez" chrome:name="tinderstatus" chrome:extension="true" chrome:description="Displays tinderbox status for the Mozilla codebase."> </RDF:Description> <RDF:Seq about="urn:mozilla:overlays"> <RDF:li resource="chrome://navigator/content/navigator.xul"/> </RDF:Seq> <RDF:Seq about="chrome://navigator/content/navigator.xul"> <RDF:li>chrome://tinderstatus/content/tinderstatusOverlay.xul</RDF:li> </RDF:Seq> </RDF:RDF>
install.js
, on the other hand, goes into the tinderstatus-installer
directory:
initInstall( "Mozilla Tinderstatus Extension", "/mozdev/tinderstatus", "0.1"); var installDir = getFolder("Chrome","tinderstatus"); setPackageFolder(installDir); addDirectory("tinderstatus"); registerChrome( CONTENT | DELAYED_CHROME, getFolder(installDir, "content")); var result = performInstall(); if ( result != SUCCESS ) cancelInstall(result);
Once all the files are in place, use your zip utility from within the tinderstatus-installer
directory to create a ZIP archive called tinderstatus.xpi
with install.js
and the entire contents of the tinderstatus/
directory. Make sure that file and directory are on the top level of the archive.