In this section, we'll see how to put chrome and XUL files into a package and create the contents.rdf 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. For example, the bookmarks and history viewer are part of the communicator package, but are stored in different sub-directories.
A package can be stored either as a directory or as a JAR archive. Each package will have a file, contents.rdf, that describes the package. This file will be placed inside the JAR file alongside the files that it describes. The file must be named contents.rdf and be a file in RDF (Resource Description Framework) format. We'll learn more about RDF later.
The contents.rdf file describes the contents of a package. It can also be used to describe a skin or locale. These files are fairly easy to create once you know how. The template below can be used as a starting point.
<?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="My Application" chrome:author="name" chrome:name="myapplication"> </RDF:Description> </RDF:RDF>
You can use this template and make some minor changes specific to your package. Let's break this down to understand what each piece does.
<?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#">
These three lines should be placed at the top of the contents.rdf file. Because RDF is an XML format, it contains the standard first line that XML files usually have. Next, we declare the namespaces that are being used, one for RDF and the other for the chrome system. If you don't understand what this means, don't worry. Just add them at the beginning of the file.
<RDF:Seq about="urn:mozilla:package:root"> <RDF:li resource="urn:mozilla:package:myapplication"/> </RDF:Seq>
These lines are used to declare what packages, skins and locales are described by the file. In this case, a content package is being described (as indicated by the word 'package' in the text). If you were creating a skin, you would use 'skin' instead of 'package', and if you were creating a locale, you would use 'locale'. The name of the package is 'myapplication'. Of course, you would replace this with the name of the package you were creating. For example, the Mozilla mail application has a name of 'messenger'. The name should be short and meaningful. This name will be used in chrome URLs for the package.
The RDF:li tag above is much like the li tag of HTML as it declares an element of a list. Thus, you can declare multiple packages by using multiple RDF:li tags.
For skins, replace the two occurances of 'package' with 'skin'; for locales, replace the two occurances of 'package' with 'locale'. For example, the following specifies a skin:
<RDF:Seq about="urn:mozilla:skin:root"> <RDF:li resource="urn:mozilla:skin:blueswayedshoes"/> </RDF:Seq>
Next, the descriptive part that specifies the name and author of the application:
<RDF:Description about="urn:mozilla:package:myapplication" chrome:displayName="My Application" chrome:author="name" chrome:name="myapplication"> </RDF:Description>
This block is used to provide more details of the package, skin or locale. You will need a description for each li that you have. The value of the about attribute should be equal to the resource attribute on the li tag.
The three extra attributes describe extra information about the package:
The title of the package as it would be displayed to the user. For example, 'Messenger'.
The name of the author of the package.
The name of the package, skin or locale. This should be the same value as what comes after 'urn:mozilla:package:' that was specfied earlier. This name is used as the first part of the chrome URL.
You can also use a variety of other values as well. When Mozilla registers your package, these values will be added into the chrome registry.
Let's create a contents.rdf file for the find files dialog we'll be creating. It will need to describe the package. Because there are no sub-packages, skins or locales included, it is fairly similar to the template above.
<?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:findfile"/> </RDF:Seq> <RDF:Description about="urn:mozilla:package:findfile" chrome:displayName="Find Files" chrome:author="Whoever" chrome:name="findfile"> </RDF:Description> </RDF:RDF>
Here, the component is named 'findfile' which means that we'll be able to refer to it using the following chrome URL:
Installing a Package
The list of installed packages is stored in the chrome directory in the file chrome.rdf. You shouldn't edit this file directly. It will be automatically changed when you install a new package. Like the contents.rdf files, it is an RDF format file. On first inspection, it looks quite different than the contents.rdf files, but if you are familiar with RDF, you should notice that it is actually very similar.
Whenever Mozilla starts up, it checks the chrome directory for a file called 'installed-chrome.txt'. This file contains a list, in a very simple format, of all the content packages, skins and locales that are installed. If this file is changed, Mozilla scans each entry in the list and registers or updates each one as necessary so that they can be used.
The file 'installed-chrome.txt' is in the chrome directory. The file contains a list of entries to install, one per line. For example:
The above will be used to install the findfiles package and also a skin for it. The format of each line is fairly simple. It's just four values separated by commas:
Set to 'content' for content packages, 'skin' for skins or 'locale' for locales.
Set to the text 'install' to have the entry installed. For skins and locales, you can also set it to 'profile' to have the entry installed in the user profile directory. This would mean that it would only be installed for a particular user.
- URL Type
Set to the text 'url' to specify a URL where the new package, skin or locale is stored. If you use 'path' instead, you can use a file path (which should be in the path format of your operating system).
Set to the URL or file path of the location of the package. This should be the directory which contains the contents.rdf file or the path and name of the JAR file. Because it refers to a directory, make sure there is a slash at the end, otherwise the package will not be found correctly.
Notice that the URLs used are 'resource:/' URLs. You could use a file URL as well. The resource URL is similar to a file URL except that it begins with 'resource:' instead of 'file:' and its top-level directory is the directory where Mozilla is installed instead of the root of the file system. This means that it can be used to refer to files in the Mozilla directory or its subdirectories, regardless of where Mozilla has been installed. The resource URL should only have one slash after the colon since its always a relative path.
The line added should point to the directory where the contents.rdf file is located. If you have multiple packages, add a line for each one.
Although Mozilla follows a directory naming convention, you can put the files anywhere you want. For example, the following will install a new package that is located in the directory /main/calculator/.
You might notice that the existing lines in installed-chrome.txt have yet another URL type, the 'jar:' URL type. If you are packing your files into a JAR file, you can use a JAR URL to refer to it. It has two parts, separated by an exclamation mark (!). The part before is the URL of the JAR file and the part after is the directory or file within the archive. The example below might refer to the find files dialog:
However, you don't usually need to worry about JAR URLs when creating your own packages. Instead, you would keep the package expanded and refer to it using file or resource URL types.
The information above may have been a little confusing. Here is a quick guide to creating a simple package. You may wish to simply follow the steps below and try to work out the details of how package installation works once you are more familiar with XUL.
- 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.
Changed it to `testapp` and it worked fine. Well better anyway.
Turned out that there was a dead instance of Firefox stuck. After I killed it and started Firefox, the file was regenerated properly.
Which, of course, is acceptable. - Neil