Chapter 2. Getting Started- P3
2.5. Creating a Package
The previous two main sections introduced the concept of chrome and the
prospect of creating standalone application windows. The next step is to
make the example into an actual package a modularized collection of files
that can be installed in Mozilla as a new application.
In the earlier section Section 2.3
, you added features and complexity to your
XUL file. In this section, you pull those features into separate files a CSS
file, JS file, and a DTD file register these files together, and make them
installable as a single package.
Only when you have packaged your work will your files have access to
Mozilla files, such as CSS and scripts, be accessible from the special
chrome:// type URLs, be able to accept new themes, and be able to get to
the XPCOM objects in which much of the application for Mozilla is defined.
Tools are available that help set up the files that form the basis of a new
package. Appendix B
provides information about XULKit, which is a
collection of scripts that automates part of the package creation process. It is
recommended that you try to set up your own package by hand first to
understand how packages are put together before using the XULKit scripts.
2.5.1. Architecture of a Chrome Package
The architecture of the Mozilla XPFE is component- or layer-based. One of
the primary aims of the design was the separation of each different
component of an application, namely content, functionality, and layout. This
design results in greater modularization, making it easy to create and change
a UI to change skins for your application, for example, update the
language in which the user interface is presented, or bring in new script
elements.
When a package is modularized like it can be in Mozilla, design
determinations can be left to the designer, language in the user interface can
themselves absolutely in their allotted space, and of more complex widgets
that act as containers, draw on top of others, or accept input. A <label>
widget is an example of the former, while <stack> is of the latter, more
complex group. If the parser does not find an element in the content files, it
fails to load and returns an error. Errors vary by type. An XML syntax error,
for example, displays in the window in place of the expected content. It
gives you the file the error originated in, along with the line number and
column number.
Built as a complementary description language to XUL, XBL allows you to
create your own widgets or add new behavior to existing XUL widgets. You
may attach scripting and create (anonymous) content in a single binding or
in many. With a little imagination, you can extend the content available to
you infinitely by adding your own styling and behavior with XBL.
2.5.2.2. Chrome appearance
Loading up a XUL file with no styles attached to the XUL elements will
render the UI as a plain, disproportioned group of widgets. While plain text
on a web page can be effective for simply relaying information, the situation
is not analogous in user interfaces.
Mozilla user interfaces without style are not very usable. Even to achieve the
traditional plain gray interface that so many applications use, you must use
CSS to style the Mozilla front end, and subtle effects, such as color grades or
3D button effects, often make even the most basic interface look and work
better.
Themes and the ability to customize the look of an application are becoming
more prominent. Mozilla developers realized this prominence during the
design phase of Mozilla, and it's reflected in the architecture: the appearance
of the interface is almost entirely separate from the structural representation
in the content.
2.5.2.3. Chrome behavior
Mozilla currently supports only JavaScript as the bridge between the UI and
• RDF files.
2.5.3. Directory Structure
Files can be organized in many different ways. If your application is small
say a single window with a simple structure that needs to be available only
in one language then having all your files in one directory may be easier.
As the size of an application goes over a certain threshold, however,
logically grouping your files into subdirectories is a good practice to make
the files more accessible.
Most applications use a directory structure that mirrors the package
component descriptions described earlier: XUL and JavaScript in a
content subdirectory, CSS and images in a skin subdirectory, and DTDs
and other resources for localizing the interface in a locale subdirectory.
Figure 2-4
shows this common grouping.
Figure 2-4. A sample package layout in the directory system
These three different directories usually contain the following type of files:
content
The content directory is the home for the XUL files that contain
the widgets to be drawn for you application. It is common practice to
also place files related to behavior, namely JavaScript files, in this
directory.
locale
This directory contains the files that contain localized strings for your
package. Most files are DTD files that contain the entities referenced
in XUL files. There is a subdirectory for each language, and the
naming convention is code-region, such as en-US.
skin
The term "skin" is an internal name for a theme. The skin directory
contains all CSS files and images that contribute to the appearance of
. Create these files in your xFly content, skin, and
locale subdirectories, respectively.
Example 2-5. chrome/xfly/content/contents.rdf file
<?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#">
<! list all the packages being supplied >
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:xfly"/>
</RDF:Seq>
<! package information >
<RDF:Description about="urn:mozilla:package:xfly"
chrome:displayName="xFly"
chrome:author="xfly.mozdev.org"
chrome:name="xfly">
</RDF:Description>
</RDF:RDF>
In the content manifest in Example 2-5
, note the chrome:name,
chrome:author, and the other metadata that the manifest provides to
Mozilla. This information can be used by others to identify what your
application is and who wrote it. For example, the name, author, and short
description information for each browser theme you have installed is
viewable by going to Preferences and selecting Appearance > Themes.
In Example 2-6
, which describes the skin for xFly only, note that new skin
resources for the Classic theme are all that is supplied, as indicated in the
RDF:Seq, which lists only classic as affected by this new package.
rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<RDF:Seq about="urn:mozilla:locale:root">
<RDF:li resource="urn:mozilla:locale:en-US"/>
</RDF:Seq>
<! locale information >
<RDF:Description about="urn:mozilla:locale:en-US"
chrome:displayName="English(US)"
chrome:author="xfly.mozdev.org"
chrome:name="en-US"
chrome:previewURL="http://www.mozilla.org/locales/e
n-US.gif">
<chrome:packages>
<RDF:Seq about="urn:mozilla:locale:en-
US:packages">
<RDF:li resource="urn:mozilla:locale:en-
US:xfly"/>
</RDF:Seq>
</chrome:packages>
</RDF:Description>
</RDF:RDF>
Manifests are detailed in Chapter 6
. For now, it's enough to see that each
manifest describes the subdirectory in which it is located, and that the
contents of those subdirectories make up the package collectively.
The content describes the content of the xFly package, the XUL, and the
JavaScript. The skin describes the theme of xFly, or the CSS and images
used to lay out the XUL. The third part describes the locale, or the strings in
shows the updated XUL
that uses xfly.css.
Example 2-9. XUL using external style data
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin"
type="text/css"?>
<?xml-stylesheet href="chrome://xfly/skin"
type="text/css"?>
<!DOCTYPE window>
<window title="Hello xFly"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/
there.is.only.xul"
width="300"
height="215"
onload="centerWindowOnScreen( )">
<script type="application/x-javascript"
<vbox align="left" id="vb">
<label id="xlabel"
value="Hello, Welcome to the xFly" />
<image src="http://books.mozdev.org/xfly.gif" />
<button label="hello xFly"
oncommand="alert('hello.');" />
</vbox>
</window>
Note the extra stylesheet import statement at the top and the use of the new
id attribute on the label. When you register the new files in your package
with Mozilla, the xfly directory in that stylesheet processing instruction
will point into your application directory structure (at the skin
value="Hello, Welcome to the xFly" />
<image src="http://books.mozdev.org/xfly.gif" />
<button label="hello xFly" oncommand="greet( );"
/>
</vbox>
</window>
Note that the function greet( ) is used to name the action that is
performed when the button is clicked. The greet( ) function is now
defined in the xfly.js file that the XUL file picks up with the script
import statement:
<script type="application/x-javascript"
src="chrome://xfly/content/xfly.js" />
Example 2-11
contains all of the code needed for the xfly.js file.
Example 2-11. The contents of the xfly.js file
function greet( ) {
alert("Hello World");
}
Save xfly.js in the content subdirectory of the xFly application
(chrome/xfly/content/). The script import statement above uses the
chrome:// URL to locate scripts from directories that were registered
with Mozilla.
2.5.5.3. The xFly DTD
The final step in a basic application setup is to generalize parts of the
interface that are written in a particular language, such as English. When you
create a locale subdirectory for your package and place a DTD file that
contains the English strings in the user interface, you can refer to and load
that DTD just as you do with the CSS and script files.
For example, to localize the text of the label and button elements in the
"hello xFly" example, you can use a special syntax to tell Mozilla to use an
onload="centerWindowOnScreen( )">
<script type="application/x-javascript"
src="chrome://global/content/dialogOverlay.js" />
<script type="application/x-javascript"
src="chrome://xfly/content/xfly.js" />
<vbox align="left" id="vb">
<label id="xlabel"
value="&label.val;" />
<image src="http://books.mozdev.org/xfly.gif" />
<button label="&btn.lbl;" oncommand="greet( );"
/>
</vbox>
</window>
Like the CSS and script file imports, the updated DOCTYPE definition at the
top of the file tells Mozilla to load additional entities as part of the xFly
package. Those entities the English strings that display in the user
interface are defined so they can be localized or internationalized without
affecting the application's structure.
All three of these imports use the chrome:// URL to refer to resources
that are internal to the xFly package. These type of URLs can also refer to
resources elsewhere in Mozilla, such as image resources, strings that have
already been defined in entities, and functions from scripts such as
centerWindowOnScreen( ).
When you finish setting things up in the package directories, you should
have a structure that looks like the tree structure in Example 2-14
.
Example 2-14. Tree structure of a completed sample xFly package
chrome/
xfly/
content/
content,install,url,resource:/chrome/xfly/content/
skin,install,url,resource:/chrome/xfly/skin/
locale,install,url,resource:/chrome/xfly/locale/en-
US/
When Mozilla starts up, it looks for the package manifests, reads them, and
registers the xFly package.
When others install your application and use it on their machines (but do not
use the hack to installed-chrome.txt), you can provide them with a
JavaScript installation file that downloads and registers your package from a
web page. See Chapter 6
for more information about these installation files
and the XPInstall technology they are based upon.
2.6. Launching the Application
Once your package is registered, you can use these startup options to access
your package directly.
2.6.1. Windows launch
In the Mozilla install directory, launch xFly at the command prompt with:
mozilla -chrome chrome://xfly/content/
You can also launch xFly from a shortcut on your desktop by right-clicking
on the existing Mozilla icon and selecting Properties. In the Target area of
the Properties box, add the following text at the end of the line:
-chrome chrome://xfly/content/
Figure 2-6
shows what the new properties box should look like.
Figure 2-6. Modified shortcut properties
2.6.1.1. Unix launch
In the Mozilla install directory, launch xFly with:
./mozilla -chrome chrome://xfly/content/
2.6.1.2. Macintosh launch