We'll begin by looking at how the XUL is handled in Mozilla.
How XUL is Handled
In Mozilla, XUL is handled in much the same way as 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. Style sheets (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
(e.g. http://localhost/~username/ ), regardless of 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, called a
chrome:// URL, to be used. 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 the application 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://'. In much the same way as an '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 with the same access privileges as the installed extension.
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.
Remote XUL was disabled in Firefox 8, so the following is of historic interest only.
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 http://localhost/xul.php. Ensure that your web server is configured to send XUL files with the content type of
application/vnd.mozilla.xul+xml (eg with PHP
header('Content-type: 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.
Document types: HTML XML XUL CSS
Mozilla uses a distinctly different kind of document object (DOM) for HTML and XUL, although they share much of the same 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. Likewise, 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 specific; 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, from the local file system, or installed as a package and accessed using a chrome URL. This last option 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 Creating a Window and save this section for later.
Mozilla is organized such that you can have as many components as you want pre-installed. Each extension is something of a standalone component with a separate chrome URL. Mozilla also has 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 has 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 is in the directory where you built Mozilla. The chrome directory is where you find all the files that describe the user interface used by the Mozilla browser, mail client, and other applications. Typically, you put all the XUL files for an application in this directory, although extensions are 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 a later 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' probably because it seemed like a convenient name to use in keeping with the chrome packages that are included with Mozilla.
To further the confusion, there are two other places where the word "chrome" might appear. These are 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 be 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.
By default, Mozilla applications parse XUL files and scripts, and store a pre-compiled version in memory for the remainder of the application session. This improves performance. However, because of this, the XUL will be not be reloaded even when the source files are changed. To disable this mechanism, it is necessary to change the preference
nglayout.debug.disable_xul_cache. In Firefox, this preference may be added to the user preferences by typing "about:config" in the address field, and setting this value to true. Or, just manually edit your
user.js preferences file and add the following line:
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, which are all 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
.xulextension. 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 browser 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.
content/browser directory contains a number of files with
.js extensions. The XUL files are the ones with the
.xul extension. The files with
In the listing above, two files have been shown. There are of course others, 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 file, 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
preferences, describe additional sections of the browser component. They are placed in different directories only to keep the files more organized.
Skins or Themes
Although the underlying code for Mozilla calls them skins and the user interface calls them themes, they're both referring 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
skin classic browser browser.css -- other browser skin files go here -- global -- 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 that 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.
en-US.jar describes the language information for each component, in this case for US English. Like the skins, each language file contains files that specify text used by the package for a specific language. The locale structure is similar to the others, so it won't be listed 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 code at all. 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 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. When installing another package, you can place it 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 in the same place where the application is built, 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.
In the next section, we'll look at how to refer to chrome packages using the chrome URL.