You are currently viewing a snapshot of taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to, please file a bug.

Overview of a Package

A hunk of UI machinery (including the description of its structure, appearance, behavior, and localizable strings) is called a package. Sample packages in the Communicator product include Navigator, Messenger, Preferences, Bookmarks and Composer. Packages can communicate with one another and may share functionality (which can be abstracted into a common package).

The contents of a package can be divided into five primary components.

1. Content

An XML-based description of the UI structure. This XML description will typically make use of two namespaces to define the UI. The first is HTML, as defined in the XHTML working draft. The second namespace is called XUL. XUL stands for XML-based User Interface Language, and this namespace provides additional widgets, features, and capabilities above and beyond what is available in HTML (e.g., menubars, tab widgets, toolbars, etc.).

A dialog has a (DOM) content tree

When Gecko's layout engine walks over this content tree, it instantiates widgets that correspond to the given tags (e.g., Gecko knows to make a menubar when it sees the tag "menubar"). In Gecko, these widgets are referred to as frames (not to be confused with the HTML frames found in framesets). These frames own pixels (and other presentation facilities, e.g., sound channels). They are the building blocks from which user interfaces are constructed. A radio-button is a widget, as is a menu, or a scrollbar. Widgets hook into the underlying document object model (DOM) and can use JavaScript to communicate with services when actions are performed on the widgets. E.g., a button (which is a widget) labeled "Print", might be configured to call the printPage method of an underlying browser service.

XPToolkit provides a cross-platform implementation for all of the XUL tags. It is the intent that one day these implementations will be pluggable, so that a third party will be able to drop in a completely different implementation of a given widget, but for now that is not the case.

Widgets can be simple or complex. They can even be composed of other widgets. A toolbar-widget, for example, can contain several button widgets.

Widgets are a `layer' above content tree

2. Appearance

The appearance of the content can be customized using Cascading Style Sheets. Just as style can be applied to HTML content, it can also be applied to XUL content. The individual widgets defined in XUL are responsive to CSS1 (and even some CSS2) properties, and their appearance is therefore highly customizable.

3. Behavior

The behavior of the package is defined using JavaScript, services, and the application object model.

The Application Object Model

The XPToolkit is a collection of facilities that cooperate through a shared model of their environment. Much as the Document Object Model defines a shared environment that can be assumed by any script or service that wants to work with a document, the Application Object Model (AOM) defines the environment assumed by components of the XPToolkit. This is a major part of the overall XPToolkit architecture.

The AOM defines (some of) the objects and relationships that compose the UI and related services of an application built on the XPToolkit. This object model is a super-set of the DOM, as a running app is expected to have one or more documents whose content is accessed through a strictly DOM compliant API. In the same way that we provide access to the DOM API both internally, e.g., to compiled C or C++, and externally, e.g., to a Java applet or to a hunk of JavaScript, the AOM is the primary mechanism for working with the XPToolkit, for both compiled code and scripts.


Services are the work-horses of an application. Services perform actual application-specific tasks, such as printing, fetching a the data at the other end of a URL, or sequencing some DNA. Services are controlled and directed with messages, usually sent by widgets, e.g., when the user pushes the "Print" button.

The implementation of a service is typically ignorant of the details of its own user interface, if it even has one (e.g., it might be `faceless'). It merely exposes functions that enable messages to be sent to the service. In fact, the same service may be exploited by different UIs, even at the same time.

It is permissible of course for a service to know how to operate on a certain type of widget, e.g., a service might know how to populate a listbox with some data, but it is bad form for the service to contain any hardcoded knowledge of a content tree's internal structure (e.g., a service shouldn't assume that it is operating on the second frame in a window's frames array).

A service can be written entirely in JavaScript or it can be a mixture of JavaScript and C++. The service permits access to its C++ code by exposing a scriptable interface using XPIDL and XPConnect. The service can therefore be instantiated and used entirely from JavaScript, even though the bulk of its implementation might be in C++.

Services are a layer code below the content tree

4. Locale

The fourth component of the package is that of locale. The locale component includes all localizable strings as well as other information necessary to supply the appropriate appearance and behavior for the package.

Locale therefore overlaps with the previous three components, as it may overlay content, appearance, and behavior as necessary to ensure that the package conforms to a specific locale.

String resources are maintained in an external DTD, which allows the strings to be referenced using entities in XML. By separating the locale information from the rest of the package components, it becomes easier to switch between different locales without having to alter the other components of the package.

5. Platform

The final component of a package is platform-specific information. Like the locale component, this component overlaps with the first three, as it may be necessary to overlay different content, appearance, and behavior on top of the rest of the package components in order to ensure that the UI conforms to the desired look and feel on a given platform.

The Whole Package

Together, all five of these components make up a complete package. By enforcing this separation among the components of the package, it becomes possible to swap out individual pieces of the package. For example, new "skins" can be applied to an existing package by swapping out its appearance component with another. Platform looks and feels can be swapped out by replacing the platform component. Different behavior can even be defined for the same content.