In this section, we'll see how to put chrome and XUL files into a package and create the manifest files for them.
A package is a set of XUL files and scripts that define the functionality of a user interface. Packages may be installed into Mozilla and referenced with chrome URLs. A package can contain any kinds of files and may be split into subdirectories for different parts of the package. A package can be stored either as a directory or as a JAR archive.
A manifest file describes a package and maps its location on disk to a chrome URL. The manifest files in the chrome directory will be examined when a Mozilla application starts up to see what packages are installed. That means that all you need to do to install a new package is add a new manifest file either into the application chrome directory or the user specific chrome directory. This latter chrome directory is normally the one used since the application directory might not have sufficient permissions to write into it.
If you just want to try testing a privileged XUL code in the Firefox browser, you can do this easily by just using a manifest with only one line in it:
- Create a new directory somewhere. For example, on a Windows machine, you might use C:\testfiles
- Create a new file called test.manifest in the chrome directory. It doesn't actually matter what the file is called as long as it has the .manifest extension.
- Add the following line to it:
content tests file:///C:/testfiles/The file path in that line should point to the directory created above. If you aren't sure what the file path is, open that directory in a browser and copy the URL from the address field.
That's it! Now, all you need to do is add some XUL files into that new directory, and you will be able to load them by typing in a chrome URL of the form chrome://tests/content/<filename>. Of course, you will need to restart the browser for the changes to take effect. If the file doesn't load, make sure that the file path is correct.
The basic syntax of the lines in the manifest file for content packages is:
content <packagename> <filepath>
The first field 'content' indiciates a content package. For themes, 'skin' is used while 'locale' is used for locales. The packagename is the example above is 'tests', which means that the first field in the chrome URL is 'tests' as in chrome://tests/content/sample.xul. If the package name was 'browser', the chrome URL would be chrome://browser/content/. The final field is the path where the files are located. This can be either a local file path using a file URL or a JAR archive using a jar URL, which will be described in a moment. You can specify multiple packages by including another line in the manifest file.
The browser.manifest file used by Firefox looks like this:
content branding jar:browser.jar!/content/branding/ xpcnativewrappers=yes content browser jar:browser.jar!/content/browser/ xpcnativewrappers=yes overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul overlay chrome://browser/content/pageInfo.xul chrome://pippki/content/PageInfoOverlay.xul
Two packages are listed here, 'branding' and 'browser'. Three overlays are also specified, which allow content from different packages to combine together. Extensions will make the most use of overlays, since they merge their UI with the browser UI.
The file paths for the branding and browser packages use jar URLs as the content is packaged up into an archive. A JAR archive can be created with a ZIP utility. For a JAR file located in the chrome directory, the syntax is fairly simple:
For the browser package, the archive is browser.jar, located alongside the manifest file in the chrome directory. The path 'content/browser' specifies the path inside the archive where the XUL files are located. You won't need to specify a path if you don't have any directories in the archive. In this case, there is, since the files for the branding package are stored in a different path in the same archive.
For the 'tests' package created above, the files are not packaged into an archive, so a direct file path is used instead. This is good for development since you don't have to package up all the files every time you change them. However, when distributing an application or extension, you will want to package them into an archive to avoid having to install lots of smaller files.
Themes and Locales
The themes and locales, the syntax is similar as for content packages, but you also need to specify the content package you are providing a theme or locale for. For example:
skin browser classic/1.0 jar:classic.jar!/skin/classic/browser/ locale browser en-US jar:en-US.jar!/locale/browser/
For these, the extra field has been added to indicate that the skin and locale applies to the browser. The skin name is 'classic/1.0'. In this case, a version number is being used as part of the theme name, but that is optional if you are making your own theme. Mozilla doesn't handle the version number in a special way; the version number is just part of the theme name. The locale is 'en-US'. The chrome URLs that these would map to would be chrome://browser/skin and chrome://browser/locale. If you were creating your own theme or locale for the browser, all you need to do is create a manifest file with one of these two lines in it, modified to suit your theme or locale.
You can also combine all of the three types into a single file if you wish. This may be done when creating an extension such that all of the parts are in one file. We will do this for the find files dialog. Create a file findfiles.manifest in the chrome directory. Add the following to the file:
content findfiles file:///findfiles/content/ skin findfiles classic/1.0 file:///findfiles/skin/ locale findfiles en-US findfiles file:///findfiles/locale/
Naturally, you will want to use directory paths suitable for your system. In this case, we are just creating test directories. If we were distributing the package, we would want to package them up into a JAR file, and modify the paths. Note how the second field of the skin and locale lines specifies 'findfiles'. This means that the skin and locale modify the findfiles package, which was specified on the first line.
The three paths above specify subdirectories for each part. You will want to create these subdirectories to keep each part's files separate.
Installing a Package
For an application to be installed, you will need to create an installer for it, or include it as part of another application. The method used depends on what kind of application you are creating. For extensions, you will need to create an install file install.rdf which describes what will be installed, the author of the extension and which versions of the browser or other applications it is compatible with. A specific directory structure is needed as well since extensions are limited in where the files may be installed to. An extension is packaged up into an XPI file. XPI is short for XPInstall and is used by Mozilla to install components. Like a JAR file, an XPI file is just a ZIP file with a different extension, so you can create and view XPI files with a ZIP utility.
Firefox's extension manager handles installing extensions packaged into XPI files automatically. It is recommended to upload extensions to the Mozilla Add-ons site, where users can locate them for installation. While they may be installed from any site, other sites are not configured to allow installations by default.
For standalone applications, they can be packaged up using XULRunner. This allows a separate executable file, and the application may be distributed independently of a browser.
If you are creating applications for older versions of Mozilla software, that is, before Firefox 1.5 or Mozilla 1.8, the process is a bit more involved. The following describes how to set up a package for earlier versions. This section may be skipped if you are writing new extensions or XUL applications.
- Create a directory somewhere on your disk. Many people put this as a subdirectory inside Mozilla's chrome directory, but this isn't necessary. The directory could be anywhere and on any disk. Put your XUL files in this directory.
- Create a file called contents.rdf and place it in this directory. Copy the text in the box below into the new contents.rdf file. This file is used to identify the application id, its name, author, version and so on.
- Change the highlighted parts of the file above to your own information. The red text 'myapplication' should be the ID of your application. You make this up, but typically, the ID is similar to your application's name. Replace the blue highlighted text above with your application's title and author.
- If the 'chrome:extension' field is true, the application is a Mozilla Firefox Extension and it will show up in the Extensions window of the browser. If false, it will not appear.
- Save the contents.rdf and make sure it is in the directory you created in step 1.
- Open the file <mozilla-directory>/chrome/installed-chrome.txt, where <mozilla-directory> is the directory where Mozilla is installed. Exit Mozilla before you do this.
Next, you are going to register the new application with Mozilla so it will know where to
find it. Add a line at the end of installed-chrome.txt pointing to the new directory you
created in step 1.
Change the highlighted text to the file URL of the directory. Make sure that it URL ends with a slash and that you press enter at the end of the line. If you aren't sure what the URL is, open the directory created in step 1 into a Mozilla browser and copy the URL from the location field. Note that the reference should always be a directory, not a file.
- Delete the file <mozilla-directory>/chrome/chrome.rdf.
- Start Mozilla. You should be able to view any XUL files you put into the directory using a URL of the form: chrome://applicationid/content/file.xul where file.xul is the filename. Your main XUL file should be applicationid.xul which you can load using the shortcut URL chrome://applicationid/content/.
<?xml version="1.0"?> <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#"> <RDF:Seq about="urn:mozilla:package:root"> <RDF:li resource="urn:mozilla:package:myapplication"/> </RDF:Seq> <RDF:Description about="urn:mozilla:package:myapplication" chrome:displayName="Application Title" chrome:author="Author Name" chrome:name="myapplication" chrome:extension="true"/> </RDF:RDF>
If you are creating skin and/or locale portions, repeat the steps above, except that the format of the contents.rdf file is slightly different. Look at the contents.rdf files in other applications for details.
Creating a chrome package can often be tricky and it is difficult to diagnose problems. Here are a few tips in case you get stuck.
- Open the file <mozilla-directory>/chrome/chrome.rdf. You should find references to your application ID in there. If not, something is wrong with registration. If it is there, you are probably using the wrong chrome URL when you load the file.
- Try deleting the <mozilla-directory>/chrome/chrome.rdf file. It will get regenerated. Also delete the entire <mozilla-directory>/chrome/overlayinfo/ directory if you are using overlays.
- Make sure that the URL in the line you added to installed-chrome.txt ends with a slash and the file itself ends with a blank line.
- On Windows, file URLs are of the form file:///C|/files/app/, where C is the drive letter.
- Make sure the contents.rdf file is in the right directory and is well-formed. Open the contents.rdf file in Mozilla to see if it parses as well-formed XML. If not, you will see an error on a yellow background.
- If you are using a debug build of Mozilla, some info will be printed to the terminal when starting up indicating what chrome applications are being checked. Check if your application is listed.
(Next) In the next section, we will start looking into the XUL language.