We'll begin by looking at how the XUL is handled in Mozilla.
How XUL is Handled
In Mozilla, XUL is handled much in the same way that HTML or other types of content are handled. When you type the URL of an HTML page into the browser's address field, the browser locates the web site and downloads the content. The Mozilla rendering engine takes the content in the form of HTML source and transforms it into a document tree. The tree is then converted into a set of objects that can be displayed on the screen. CSS, images and other technologies are used to control the presentation. XUL functions in much the same way.
In fact, in Mozilla, all document types, whether they are HTML or XUL, or even SVG are all handled by the same underlying code. This means that the same CSS properties may be used to style both HTML and XUL, and many of the features can be shared between both. However, there are some features that are specific to HTML such as forms, and others which are specific to XUL such as overlays. Since XUL and HTML are handled in the same way, you can load both from either your local file system, from a web page, or from an extension or standalone XULRunner application.
Content from remote sources, regardless or whether they are HTML or XUL or another document type, are limited in the type of operations they can perform, for security reasons. For this, reason, Mozilla provides a method of installing content locally and registering the installed files as part of its chrome system. This allows a special URL form to be used called a chrome URL. By accessing a file using a chrome URL, the files receive elevated privileges to access local files, access preferences and bookmarks and perform other privileged operations. Obviously, web pages do not get these privileges, unless they are signed with a digital certificate and the user has granted permission to perform these operations.
Standalone XUL applications may include XUL code in a similar way, but, of course, the XUL for application will be included will be included as part of the installation, instead of having to be installed separately as an extension. However, this XUL code will be registered in the chrome system such that the application can display the UI.
The chrome URL always begins with 'chrome://'. Much like how the 'http://' URL always refers to remote web sites accessed using HTTP and the 'file://' URL always refers to local files, the 'chrome://' URL always refers to installed packages and extensions. We'll look more at the syntax of a chrome URL in the next section. It is important to note that when accessing content through a chrome URL, it gains the enhanced privileges described above that other kinds of URLs do not. For instance, an HTTP URL does not have any special privileges, and an error will occur if a web page tries, for example, to read a local file. However, a file loaded via a chrome URL will be able to read files without restriction.
This distinction is important. This means that there are certain things that content of web pages cannot do, such as read the user's bookmarks. This distinction is not based on the kind of content being displayed; only on the type of URL used. Both HTML and XUL placed on a web site have no extra permissions; however both HTML and XUL loaded through a chrome URL have enhanced permissions.
If you are going to use XUL on a web site, you can just put the XUL file on the web site as you would an HTML file, and then load its URL in a browser. Ensure that your web server is configured to send XUL files with the content type of 'application/vnd.mozilla.xul+xml'. This content type is how Mozilla knows the difference between HTML and XUL. Mozilla does not use the file extension, unless reading files from the file system, but you should use the .xul extension for all XUL files. You can load XUL files from your own machine by opening them in the browser, or by double-clicking the file in your file manager. Remember that remote XUL will have significant restrictions on what it can do.
Mozilla uses a distinctly different kind of document object for HTML and XUL, although they share most of their functionality. There are three main types of document in Mozilla: HTML, XML and XUL. Naturally, the HTML document is used for HTML documents, the XUL document is used for XUL documents, and the XML document is used for other types of XML documents. Since XUL is also XML, the XUL document is a subtype of the more generic XML document. There are subtle differences in functionality. For example while the form controls on an HTML page are accessible via the 'document.forms' property, this property isn't available for XUL documents since XUL doesn't have forms in the HTML sense. On the other hand, XUL specific features such as overlays and templates are only available in XUL documents.
This distinction between documents is important. It is possible to use many XUL features in HTML or XML documents since they aren't document type specifc, however other features require the right kind of document. For instance, you can use the XUL layout types in other documents since they don't rely on the XUL document type to function.
To summarize the points made above:
- Mozilla renders both HTML and XUL using the same underlying engine and uses CSS to specify their presentation.
- XUL may be loaded from a remote site, the local file system, or installed as a package and accessed using a chrome URL. This is what browser extensions do.
- Chrome URLs may be used to access installed packages and open them with enhanced privileges.
- HTML, XML and XUL each have a different document type. Some features may be used in any document type whereas some features are specific to one kind of document.
The next few sections describe the basic structure of a chrome package which can be installed into Mozilla. However, if you just want to get started building a simple application, you may skip ahead to section 2 and save this section for later.
Mozilla is organized in such a way that you can have as many components as you want pre-installed. Each extension is also a component with a separate chrome URL. It will also have one component for each installed theme and locale. Each of these components, or packages, is made up of a set of files that describe the user interface for it. For example, the messenger component will have descriptions of the mail messages list window, the composition window and the address book dialogs.
The packages that are provided with Mozilla are located within the chrome directory, which you will find in the directory where you installed Mozilla. The chrome directory is where you will find all the files that describe the user interface used by the Mozilla browser, mail client and other applications. You will typically put all of the XUL files for an application in this directory, except for extensions which will be installed in the extensions directory for a particular user. Just copying a XUL file into the 'chrome' directory doesn't give the file any extra permissions nor can it be accessed via a chrome URL. To gain the extra privileges, you will need to create a manifest file and put that in the chrome directory. This file is easy to create, as it is typically only a couple of lines long. It is used to map a chrome URL to a file or directory path on the disk where the XUL files are located. Details of how to create this file will be discussed in the next section.
The only way to create content that can be accessed through a chrome URL is by creating a package as described in the next few sections. This directory is called 'chrome' likely because it seemed like a convenient name to use for the directory where the chrome packages that are included with Mozilla are kept.
To further the confusion, there are two other places where the word chrome might appear. The first is the '-chrome' command line argument, and the chrome modifier to the 'window.open' function. Neither of these features grant extra privileges; instead they are used to open a new top-level window without the browser UI such as the menu and toolbar. You will commonly use this feature in more complex XUL applications since you wouldn't want the browser UI to exist around your dialog boxes.
The files for a package are usually combined into a single JAR file. A JAR file may created and examined using a ZIP utility. For instance, you can open the JAR files in Mozilla's chrome directory to see the basic structure of a package. Although it's normal to combine the files into a JAR file, packages may also be accessed in expanded form into a directory. Although you don't normally distribute a package this way, it is handy during development since you can edit the file directly and then reload the XUL file without having to repackage or reinstall the files.
There are usually three different parts to a chrome package, although they are all optional. Each part is stored in a different directory. These three sets are the content, the skin and the locale, described below. A particular package might provide one or more skins and locales, but a user can replace them with their own. In addition, the package might include several different applications each accessible via different chrome URLs. The packaging system is flexible enough so that you can include whatever parts you need, and allow other parts, such as the text for different languages, to be downloaded separately.
The three types of chrome packages are:
- Content - Windows and scripts
The declarations of the windows and the user interface elements contained within them. These are stored in XUL files, which have a xul extension. A content package can have multiple XUL files, but the main window should have a filename that is the same as the package name. For example, the editor package will have a file within it called editor.xul. Scripts are placed in separate files alongside the XUL files.
- Skin - Style sheets, images and other theme specific files
Style sheets describe details of the appearance of a window. They are stored separately from XUL files to facilitate modifying the skin (theme) of an application. Any images used are stored here also.
- Locale - Locale specific files
All the text that is displayed within a window is stored separately. This way, a user can have a set for their own language.
The name of the JAR file might describe what it contains, but you can't be sure unless you view its contents. Let's use the browser package included with Firefox as an example. If you extract the files in browser.jar, you will find that it contains a directory structure much like the following:
content browser browser.xul browser.js -- other mail XUL and JS files goes here -- bookmarks -- bookmarks files go here -- preferences -- preferences files go here -- . . .
This is easily recognizable as a content package, as the top-level directory is called 'content'. For skins, this directory will usually be called 'skin' and for locales, it will usually be called 'locale'. This naming scheme isn't necessary but this is a common convention to make the parts of a package clearer. Some packages may include a content section, a skin and a locale. In this case, you will find a subdirectory for each type. For example, Chatzilla is distributed in this way.
In the listing above, two files have been shown. There are others of course, but for simplicity they aren't shown. The file browser.xul is the XUL file that describes the main browser window. The main window for a content package should have the same name as the package with a xul extension. In this case, the package name is 'browser', so we expect to find 'browser.xul'. Some of the other XUL files describe separate windows. For example, the file pageInfo.xul describes the page info dialog.
Many packages will include a contents.rdf, which describes the package, its author and the overlays it uses. However, this file is obsolete and has been replaced with a simpler mechanism. This newer method is the manifest file mentioned earlier, and you will find these as files with the .manifest extension in the chrome directory. For instance, browser.manifest describes the browser package.
Several subdirectories, such as bookmarks and preferences, describe additional sections of the browser component. They are placed in different directories only to keep the files more organized.
Skins or Themes
The underlying code of Mozilla calls them skins, although the user interface calls them themes, but they both refer to the same thing. The classic.jar file describes the default theme provided with Firefox. The structure is similar to the content packages. For example, examining classic.jar:
skin classic browser -- browser skin files go here -- global contents.rdf -- global skin files go here -- . . .
Again, this directory structure isn't necessary and is used for convenience. You can actually put all the files in one directory at the top level and not use subdirectories. However, for larger applications, subdirectories are used to separate the different components. In the example above, a directory exists for theme related files for the browser and another for global theme related files. The global directory contains skin files that are general to all packages. These files will apply to all components and will be included with your own standalone applications. The global part defines the appearance of all of the common XUL widgets, whereas the other directories have files that are specific to those applications. Firefox includes both the global and browser theme files in one archive, but they can be included separately.
A skin is made up of CSS files and a number of images used to define the look of an interface. The file browser.css is used by browser.xul and contains styles which define the appearance of various parts of the browser interface. Again, note how the file browser.css has the same name as the package. By changing the CSS files, you can adjust the appearance of a window without changing its function. This is how you can create a new theme. The XUL part remains the same but the skin part changes independently.
The file en-US.jar describes the language information for each component, in this case for US English. Like the skins, each language will contain files that specify text used by the package but for a specific language. The locale structure is similar to the others, so it won't be listed it here.
The localized text is stored in two types of files, DTD files, and properties files. The DTD files have a dtd extension and contain entity declarations, one for each text string that is used in a window. For example, the file browser.dtd contains entity declarations for each menu command. In addition, keyboard shortcuts for each command are also defined, because they may be different for each language. DTD files are used by XUL files so, in general, you will have one per XUL file. The locale part also contains properties files, which are similar, but are used by script files. The file browser.properties contains a few such localized strings.
This structure allows you to translate Mozilla or a component into a different language by just adding a new locale for that language. You don't have to change the XUL part. In addition, another person could supply a separate package that applies a skin or locale to your content part, thus providing support for a new theme or language without having to change the original package.
There is a one special package called toolkit (or global). We saw the global directory earlier for skins. The file toolkit.jar contains the corresponding content part for it. It contains some global dialogs and definitions. It also defines the default appearance and functionality of the various common XUL widgets such as textboxes and buttons. The files located in the global part of a skin package contain the default look for all of the XUL interface elements. The toolkit package is used by all XUL applications.
Adding a Package
Mozilla places the packages that are included with the installation in the chrome directory. However, they do not need to be placed there. If you have another package installed, it can be placed anywhere on the disk, as long as a manifest file points to it. It is common to place packages into the chrome directory simply because it is convenient, however they will work just as well from another directory or somewhere on your local network. You cannot store them on a remote site, unless the remote site is mounted through the local file system.
There are two chrome directories used for XUL applications, one is installed in the same place where the application is installed, while the other is part of user's profile. The former allows packages that are shared by all users while the latter allows packages to be created only for a specific user or users. Extensions, while installed in a separate extensions directory, are also usually user specific. Any manifest files located in either chrome directory will be examined to see which packages are installed.
(Next) In the next section, we'll look at how to refer to chrome packages using the chrome URL.