Diff for /books/www/chapters/ch06.html between versions 1.7 and 1.8

version 1.7, 2002/12/04 06:07:15 version 1.8, 2002/12/11 18:57:10
Line 1 Line 1
<HTML>    <style type="text/css">
<HEAD><TITLE>Chapter 6</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 6</H2>      div.c17 {font-weight: bold; text-align: center}
<H1><A NAME="77063"></A> Packaging and Installing Applications</H1>      div.c16 {text-align: center}
<P>The previous chapters covered the basic parts of building an application. Now that you've seen how to create an application with XUL, CSS, and JavaScript that can be used on your local computer, we will show you how to turn your program into something that can be installed by other users. This chapter discusses the technologies Mozilla provides for packaging and installing applications.    </style>
<P>Until your project is packaged for distribution, it can't be fully considered a finished application (unless it was designed to work only on the computer where it was created). Making your application distributable, installable, and registrable allows others to use what you have created.
<P>This chapter is divided into four main sections. It starts with a quick overview of the basics of packaging and installing applications. The second section provides details about how to get your application packaged and described so that Mozilla recognizes what it is. The next section specifies how to put your package into a cross-platform installation file that can be installed over the Web onto other machines. The last section provides tips for customizing how your application will look once it is installed.    <h2>Chapter 6</h2>
<H2><A NAME="77064"></A> Packaging and Installing Overview</H2>    <h1><a name="77063"></a> Packaging and Installing
<P>Several different pieces comprise  <!--INDEX STARTRANGE--packaging:overview;installation:overview --> Mozilla's distribution technology. In fact, Mozilla may have a few more moving parts than other packaging systems because it needs a way to package and install new software uniformly across several different platforms. <A HREF="#77002">Figure 6-1</A> shows the major components of Mozilla's packaging system outlined in black.    Applications</h1>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <p>The previous chapters covered the basic parts of building an
<P><I>Figure 6-1: <A NAME="77002"></A></I>    application. Now that you've seen how to create an application
<I>Mozilla packaging components</I>    with XUL, CSS, and JavaScript that can be used on your local
    computer, we will show you how to turn your program into
<P>As you can see in <A HREF="#77002">Figure 6-1</A>, the  <!--INDEX XPI (Cross-Platform Installer);distribution:XPI --> Cross-Platform Installer (XPI), pronounced zippy or X-P-I, is the archive format used to distribute Mozilla applications. The XPI file contains a script that downloads and installs the application. The package inside the XPI has a manifest that is used to register the new Mozilla-based software with the Mozilla chrome registry.    something that can be installed by other users. This chapter
<P>When a XPI contains a  <!--INDEX packages:installation script;XPI (Cross-Platform Installer):package installation script --> Mozilla-based     discusses the technologies Mozilla provides for packaging and
package such as the xFly sample discussed in <A HREF="ch02.html#77048">Chapter 2</A> and the following chapters, the installation script also takes care of the package registration process, described in the <A HREF="#77070">"Registering Packages</A>" section later in this chapter. <A HREF="#77020">Example 6-1</A> shows a simple installation script and the kind of information it contains. The <A HREF="#77085">"Installation Scripts</A>" section, also later in this chapter, discusses other scripts that may need to be used in the installation process, such as trigger scripts.    installing applications.</p>
    <p>Until your project is packaged for distribution, it can't be
<P><I>Example 6-1: <A NAME="77020"></A></I>    fully considered a finished application (unless it was designed
<I>Package installation script</I>    to work only on the computer where it was created). Making your
<PRE> var myFile = "xFly.jar";    application distributable, installable, and registrable allows
     others to use what you have created.</p>
     <p>This chapter is divided into four main sections. It starts
     with a quick overview of the basics of packaging and installing
     applications. The second section provides details about how to
     get your application packaged and described so that Mozilla
     recognizes what it is. The next section specifies how to put
     your package into a cross-platform installation file that can
     be installed over the Web onto other machines. The last section
     provides tips for customizing how your application will look
     once it is installed.</p>
     <h2><a name="77064"></a> Packaging and Installing Overview</h2>
     <p>Several different pieces comprise 
     <!--INDEX STARTRANGE==packaging:overview;installation:overview -->
     Mozilla's distribution technology. In fact, Mozilla may have a
     few more moving parts than other packaging systems because it
     needs a way to package and install new software uniformly
     across several different platforms. <a href="#77002">Figure
     6-1</a> shows the major components of Mozilla's packaging
     system outlined in black.</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-1: <a name="77002"></a></i> <i>Mozilla packaging
     components</i></p>
     <p>As you can see in <a href="#77002">Figure 6-1</a>, the 
     <!--INDEX XPI (Cross-Platform Installer);distribution:XPI -->
     Cross-Platform Installer (XPI), pronounced zippy or X-P-I, is
     the archive format used to distribute Mozilla applications. The
     XPI file contains a script that downloads and installs the
     application. The package inside the XPI has a manifest that is
     used to register the new Mozilla-based software with the
     Mozilla chrome registry.</p>
     <p>When a XPI contains a 
     <!--INDEX packages:installation script;XPI (Cross-Platform Installer):package installation script -->
     Mozilla-based package such as the xFly sample discussed in <a
     href="ch02.html#77048">Chapter 2</a> and the following
     chapters, the installation script also takes care of the
     package registration process, described in the <a href=
     "#77070">"Registering Packages</a>" section later in this
     chapter. <a href="#77020">Example 6-1</a> shows a simple
     installation script and the kind of information it contains.
     The <a href="#77085">"Installation Scripts</a>" section, also
     later in this chapter, discusses other scripts that may need to
     be used in the installation process, such as trigger
     scripts.</p>
     <p><i>Example 6-1: <a name="77020"></a></i> <i>Package
     installation script</i></p>
 <pre>
  var myFile = "xFly.jar";
  initInstall(                      // initialize the installation   initInstall(                      // initialize the installation
    "Install xFly",                 // display name of installation     "Install xFly",                 // display name of installation
    "xFly",                         // package name     "xFly",                         // package name
Line 32  package such as the xFly sample discusse Line 81  package such as the xFly sample discusse
  if (0 == getLastError( ))   // if there have been no errors:   if (0 == getLastError( ))   // if there have been no errors:
    performInstall( );        // install "xfly.jar"     performInstall( );        // install "xfly.jar"
  else                       // otherwise   else                       // otherwise
   cancelInstall( );         // cancel the installation.</PRE>   cancelInstall( );         // cancel the installation.
</pre>
<P>The installation process requires a few different steps. First an installation must be initialized. Then the software to be installed is added to the specified target directory. Finally, packages in the installation  <!--INDEX registration:packages;packages:registration;installation:packages:registration --> are registered. At this point, the application is installed on a user's computer.    <p>The installation process requires a few different steps.
<P>When you install new packages or  <!--INDEX chrome:registry, package installation --> Mozilla-based software, the chrome registry on the Mozilla side brokers the deal-reading the manifest, executing the installation script(s), and updating the package information that it maintains internally (storing this information using RDF).    First an installation must be initialized. Then the software to
<P>The relationship of the packaging, installation, and registration-and all pieces involved-may seem a little complex and idiosyncratic at first, but bear with it. The upshot of this powerful but somewhat diffuse packaging technology is that you can bundle your software, put it on a server, and have users install it by simply clicking a link on a web page when using Mozilla.    be installed is added to the specified target directory.
<P>It is possible to use this  <!--INDEX bundling, packaging and;packages:bundling and --> packaging system to bundle any sort of application or     Finally, packages in the installation 
extension to an existing Mozilla application. You can install a XPI that adds functionality to the Mozilla browser, such  <!--INDEX XPI (Cross-Platform Installer):Mouse Gestures;Mouser Gestures --> as Mouse Gestures (<I><A HREF="http://optimoz.mozdev.org/gestures/">http://optimoz.mozdev.org/gestures/</A> </I>), which enables the execution of common browser commands with mouse movements. You can package new Mozilla development tools and libraries like JSLib (see <A HREF="ch05.html#77037">Chapter 5</A>). You can also  <!--INDEX ENDRANGE--packaging:overview;installation:overview --> create installations for entirely new Mozilla applications.    <!--INDEX registration:packages;packages:registration;installation:packages:registration -->
<H2><A NAME="77065"></A> Packaging Mozilla Applications</H2>    are registered. At this point, the application is installed on
<P><I>Packaging</I> simply  <!--INDEX packaging:Mozilla applications;applications:packaging --> means organizing your files into a Mozilla application structure. Packaging your application is required to make it installable and to make it something that Mozilla recognizes as one of its own. Whether your Mozilla-based becomes a part of an existing Mozilla application, like Mouse Gestures, or will exist as a standalone application, like JabberZilla, you will need to package it.    a user's computer.</p>
<P>When you are done with this packaging section, package your Mozilla-based applications in the same way that we packaged the xFly example in <    <p>When you install new packages or 
HREF="ch02.html#77048">Chapter 2</A>. This chapter describes the manifests and other necessary files. Then the Installation section shows how you can put your package in a XPI file and create installation script(s) so it can be distributed and installed.    <!--INDEX chrome:registry, package installation -->
<H3><A NAME="77066"></A> Package Manifests</H3>    Mozilla-based software, the chrome registry on the Mozilla side
<P>All new packages  <!--INDEX packages:manifests;manifests:packages --> must have manifests describing their contents, skin information, and locale information. These manifests are formatted in RDF, which makes them easy to combine with the RDF data that makes up the chrome registry and makes it easy to fit the package into the Mozilla software. There is some flexibility about where in the package the manifest must appear, but the registration process must find and read it regardless of where it is.    brokers the deal-reading the manifest, executing the
<P>The installation script points out the manifest locations so the package can be registered properly. Note that  <!--INDEX JAR (Java Archive) files:manifests --> manifests appear in JARs, but they do not appear in XPIs, since the latter is a temporary file that gets deleted once the files it contains, including JARs, are installed (see the <A HREF="#77081">"Installing Mozilla Applications</A>" section later in this chapter for more information about XPI install files).    installation script(s), and updating the package information
<H4><A NAME="77067"></A> Theme package manifests</H4>    that it maintains internally (storing this information using
<P><A HREF="#77022">Example 6-2</A> shows  <!--INDEX themes:package manifests;manifests:packages:themes and;packages:manifests:themes --> a manifest for a new theme to be installed in Mozilla. It is simple because it describes only one type of package, the "fly skin," and the existing component it interacts with, the communicator-the default Mozilla browser (the syntax and structure is the same for all manifests, however). The manifest says, in effect, this is what I have here (the metadata about the theme-its name, a description, etc.), and this is what it affects (the list of <TT>chrome:packages</TT> to which the theme should be applied).    RDF).</p>
    <p>The relationship of the packaging, installation, and
<P><I>Example 6-2: <A NAME="77022"></A></I>    registration-and all pieces involved-may seem a little complex
<I>Simple theme package manifest</I>    and idiosyncratic at first, but bear with it. The upshot of
<PRE> &lt;?xml version="1.0"?&gt;    this powerful but somewhat diffuse packaging technology is that
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    you can bundle your software, put it on a server, and have
   xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;    users install it by simply clicking a link on a web page when
     using Mozilla.</p>
     <p>It is possible to use this 
     <!--INDEX bundling, packaging and;packages:bundling and -->
     packaging system to bundle any sort of application or extension
     to an existing Mozilla application. You can install a XPI that
     adds functionality to the Mozilla browser, such 
     <!--INDEX XPI (Cross-Platform Installer):Mouse Gestures;Mouser Gestures -->
     as Mouse Gestures (<i><a href=
     "http://optimoz.mozdev.org/gestures/">http://optimoz.mozdev.org/gestures/</a></i>
     ), which enables the execution of common browser commands with
     mouse movements. You can package new Mozilla development tools
     and libraries like JSLib (see <a href="ch05.html#77037">Chapter
     5</a>). You can also 
     <!--INDEX ENDRANGE==packaging:overview;installation:overview -->
     create installations for entirely new Mozilla applications.</p>
     <h2><a name="77065"></a> Packaging Mozilla Applications</h2>
     <p><i>Packaging</i> simply 
     <!--INDEX packaging:Mozilla applications;applications:packaging -->
     means organizing your files into a Mozilla application
     structure. Packaging your application is required to make it
     installable and to make it something that Mozilla recognizes as
     one of its own. Whether your Mozilla-based becomes a part of an
     existing Mozilla application, like Mouse Gestures, or will
     exist as a standalone application, like JabberZilla, you will
     need to package it.</p>
     <p>When you are done with this packaging section, package your
     Mozilla-based applications in the same way that we packaged the
     xFly example in <a href="ch02.html#77048">Chapter 2</a>. This
     chapter describes the manifests and other necessary files. Then
     the Installation section shows how you can put your package in
     a XPI file and create installation script(s) so it can be
     distributed and installed.</p>
     <h3><a name="77066"></a> Package Manifests</h3>
     <p>All new packages 
     <!--INDEX packages:manifests;manifests:packages --> must have
     manifests describing their contents, skin information, and
     locale information. These manifests are formatted in RDF, which
     makes them easy to combine with the RDF data that makes up the
     chrome registry and makes it easy to fit the package into the
     Mozilla software. There is some flexibility about where in the
     package the manifest must appear, but the registration process
     must find and read it regardless of where it is.</p>
     <p>The installation script points out the manifest locations so
     the package can be registered properly. Note that 
     <!--INDEX JAR (Java Archive) files:manifests --> manifests
     appear in JARs, but they do not appear in XPIs, since the
     latter is a temporary file that gets deleted once the files it
     contains, including JARs, are installed (see the <a href=
     "#77081">"Installing Mozilla Applications</a>" section later in
     this chapter for more information about XPI install files).</p>
     <h4><a name="77067"></a> Theme package manifests</h4>
     <p><a href="#77022">Example 6-2</a> shows 
     <!--INDEX themes:package manifests;manifests:packages:themes and;packages:manifests:themes -->
     a manifest for a new theme to be installed in Mozilla. It is
     simple because it describes only one type of package, the "fly
     skin," and the existing component it interacts with, the
     communicator-the default Mozilla browser (the syntax and
     structure is the same for all manifests, however). The manifest
     says, in effect, this is what I have here (the metadata about
     the theme-its name, a description, etc.), and this is what it
     affects (the list of <tt>chrome:packages</tt> to which the
     theme should be applied).</p>
     <p><i>Example 6-2: <a name="77022"></a></i> <i>Simple theme
     package manifest</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
    xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
    &lt;!-- List all the skins being supplied by this theme --&gt;     &lt;!-- List all the skins being supplied by this theme --&gt;
    &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;     &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
      &lt;RDF:li resource="urn:mozilla:skin:flyskin/1.0" /&gt;       &lt;RDF:li resource="urn:mozilla:skin:flyskin/1.0" /&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
   
    &lt;!-- Fly Skin Information --&gt;     &lt;!-- Fly Skin Information --&gt;
    &lt;RDF:Description about="urn:mozilla:skin:flyskin/1.0"     &lt;RDF:Description about="urn:mozilla:skin:flyskin/1.0"
      chrome:displayName="Fly Skin"       chrome:displayName="Fly Skin"
Line 70  HREF="ch02.html#77048">Chapter 2</A>. Th Line 188  HREF="ch02.html#77048">Chapter 2</A>. Th
       &lt;/RDF:Seq&gt;        &lt;/RDF:Seq&gt;
     &lt;/chrome:packages&gt;      &lt;/chrome:packages&gt;
    &lt;/RDF:Description&gt;     &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<H4><A NAME="77068"></A> Language pack manifests</H4>    <h4><a name="77068"></a> Language pack manifests</h4>
<P>When you look at  <!--INDEX language pack manifests;manifests:language pack manifests;packages:manifests:language pack manifests --> a package manifest that describes a new locale, as shown in <A HREF="#77024">Example 6-3</A> (which is for a  <!--INDEX German language pack manifest --> German language pack in Mozilla), you see a similar structure. Again, the manifest describes the new package first and then lists the existing components to which this new package applies.    <p>When you look at 
    <!--INDEX language pack manifests;manifests:language pack manifests;packages:manifests:language pack manifests -->
<P><I>Example 6-3: <A NAME="77024"></A></I>    a package manifest that describes a new locale, as shown in <a
<I>Locale package manifest</I>    href="#77024">Example 6-3</a> (which is for a 
<PRE> &lt;?xml version="1.0"?&gt;    <!--INDEX German language pack manifest --> German language
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    pack in Mozilla), you see a similar structure. Again, the
  xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;    manifest describes the new package first and then lists the
     existing components to which this new package applies.</p>
     <p><i>Example 6-3: <a name="77024"></a></i> <i>Locale package
     manifest</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
   xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
   &lt;!-- list all the skins being supplied by this package --&gt;    &lt;!-- list all the skins being supplied by this package --&gt;
   &lt;RDF:Seq about="urn:mozilla:locale:root"&gt;    &lt;RDF:Seq about="urn:mozilla:locale:root"&gt;
   &lt;RDF:li resource="urn:mozilla:locale:en-DE"/&gt;    &lt;RDF:li resource="urn:mozilla:locale:en-DE"/&gt;
Line 89  HREF="ch02.html#77048">Chapter 2</A>. Th Line 216  HREF="ch02.html#77048">Chapter 2</A>. Th
    chrome:displayName="English (German)"     chrome:displayName="English (German)"
    chrome:author="mozilla.org"     chrome:author="mozilla.org"
    chrome:name="en-DE"     chrome:name="en-DE"
   chrome:previewURL="<A HREF="http://www.mozilla.org/locales/en-DE.gif">http://www.mozilla.org/locales/en-DE.gif</A>"&gt;   chrome:previewURL="<a href=
 "http://www.mozilla.org/locales/en-DE.gif">http://www.mozilla.org/locales/en-DE.gif</a>"&gt;
    &lt;chrome:packages&gt;     &lt;chrome:packages&gt;
     &lt;RDF:Seq about="urn:mozilla:locale:en-DE:packages"&gt;      &lt;RDF:Seq about="urn:mozilla:locale:en-DE:packages"&gt;
       &lt;RDF:li resource="urn:mozilla:locale:en-DE:communicator"/&gt;        &lt;RDF:li resource="urn:mozilla:locale:en-DE:communicator"/&gt;
Line 100  HREF="ch02.html#77048">Chapter 2</A>. Th Line 228  HREF="ch02.html#77048">Chapter 2</A>. Th
     &lt;/RDF:Seq&gt;      &lt;/RDF:Seq&gt;
    &lt;/chrome:packages&gt;     &lt;/chrome:packages&gt;
   &lt;/RDF:Description&gt;    &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>Note that in <A HREF="#77024">Example 6-3</A>'s package manifest, all major components are affected by this new locale package. When the package is installed and the manifest is read, the chrome registry is made aware of a German language pack that it can use to display German in the interface of each Mozilla component.    <p>Note that in <a href="#77024">Example 6-3</a>'s package
<BLOCKQUOTE><HR><B>contents.rdf Type Manifests</B>    manifest, all major components are affected by this new locale
<P>Package manifests are an area where Mozilla browser itself may not be the best model for learning about the best application development practice. Mozilla is such a large and modular application that it uses several manifests instead of one application-wide <I>manifest.rdf </I>file.    package. When the package is installed and the manifest is
<P>Although they have the same format, these distributed manifests are found in several <I>contents.rdf</I> files. In a single theme (e.g., the <I>modern.jar</I>), you can see as many as eight manifests (for major component to which the theme applies).    read, the chrome registry is made aware of a German language
<P>These two types of manifests-the <I>contents.rdf</I> file, which typically describes a single package-component relationship; and the <I>manifest.rdf</I> file, which describes the package's relationship to all affected components-are functionally equivalent. In both cases, the chrome registry reads all RDF/XML data and registers the package.    pack that it can use to display German in the interface of each
<P>Because the manifest data format is RDF/XML, you can use either type of manifest in your own package development, although using a single <I>manifest.rdf </I>is generally much easier, especially if you want to change the list of affected components of any other metadata later.<HR></BLOCKQUOTE>    Mozilla component.</p>
    <blockquote>
<P>The package manifests for content and new applications-which may include new content, skin, and locale information-have an identical syntax and a very similar structure, as you will see in the following sections. The manifest for a full Mozilla-based application like xFly describes the content, the skin, and the locale in a single file that sits at the top of that package.      <hr>
<H4><A NAME="77069"></A> Application manifests</H4>      <b>contents.rdf Type Manifests</b> 
<P>When you create new  <!--INDEX application manifests;manifests:application manifests;packages:manifests:application manifests --> applications on top of Mozilla, you will often create new content, new skins, and your own localizable language elements, such as DTDs. For applications, the manifest must describe these parts of your application if Mozilla is to find and register them properly.      <p>Package manifests are an area where Mozilla browser itself
<P><A HREF="#77026">Example 6-4</A>, the package  <!--INDEX XMLTerm extension, package manifest --> manifest from the XMLTerm<I> </I>Mozilla extension, describes the contents, skin, and locale in a single file, which is most common for Mozilla-based applications.      may not be the best model for learning about the best
      application development practice. Mozilla is such a large and
<P><I>Example 6-4: <A NAME="77026"></A></I>      modular application that it uses several manifests instead of
<I>manifest.rdf describing the XMLTerm extension</I>      one application-wide <i>manifest.rdf</i> file.</p>
<PRE> &lt;?xml version="1.0"?&gt;      <p>Although they have the same format, these distributed
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"      manifests are found in several <i>contents.rdf</i> files. In
          xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;      a single theme (e.g., the <i>modern.jar</i>), you can see as
       many as eight manifests (for major component to which the
       theme applies).</p>
       <p>These two types of manifests-the <i>contents.rdf</i> file,
       which typically describes a single package-component
       relationship; and the <i>manifest.rdf</i> file, which
       describes the package's relationship to all affected
       components-are functionally equivalent. In both cases, the
       chrome registry reads all RDF/XML data and registers the
       package.</p>
       <p>Because the manifest data format is RDF/XML, you can use
       either type of manifest in your own package development,
       although using a single <i>manifest.rdf</i> is generally much
       easier, especially if you want to change the list of affected
       components of any other metadata later.</p>
       <hr>
     </blockquote>
     <p>The package manifests for content and new applications-which
     may include new content, skin, and locale information-have an
     identical syntax and a very similar structure, as you will see
     in the following sections. The manifest for a full
     Mozilla-based application like xFly describes the content, the
     skin, and the locale in a single file that sits at the top of
     that package.</p>
     <h4><a name="77069"></a> Application manifests</h4>
     <p>When you create new 
     <!--INDEX application manifests;manifests:application manifests;packages:manifests:application manifests -->
     applications on top of Mozilla, you will often create new
     content, new skins, and your own localizable language elements,
     such as DTDs. For applications, the manifest must describe
     these parts of your application if Mozilla is to find and
     register them properly.</p>
     <p><a href="#77026">Example 6-4</a>, the package 
     <!--INDEX XMLTerm extension, package manifest --> manifest from
     the XMLTerm Mozilla extension, describes the contents, skin,
     and locale in a single file, which is most common for
     Mozilla-based applications.</p>
     <p><i>Example 6-4: <a name="77026"></a></i> <i>manifest.rdf
     describing the XMLTerm extension</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
           xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
    &lt;!-- list all the packages being supplied by this jar --&gt;     &lt;!-- list all the packages being supplied by this jar --&gt;
    &lt;RDF:Seq about="urn:mozilla:package:root"&gt;     &lt;RDF:Seq about="urn:mozilla:package:root"&gt;
      &lt;RDF:li resource="urn:mozilla:package:xmlterm"/&gt;       &lt;RDF:li resource="urn:mozilla:package:xmlterm"/&gt;
Line 147  HREF="ch02.html#77048">Chapter 2</A>. Th Line 319  HREF="ch02.html#77048">Chapter 2</A>. Th
          chrome:displayName="English(US)"           chrome:displayName="English(US)"
          chrome:author="mozilla.org"           chrome:author="mozilla.org"
          chrome:name="en-US"           chrome:name="en-US"
         chrome:previewURL="<A HREF="http://www.mozilla.org/locales/en-US.gif">http://www.mozilla.org/locales/en-US.gif</A>"&gt;         chrome:previewURL="<a href=
 "http://www.mozilla.org/locales/en-US.gif">http://www.mozilla.org/locales/en-US.gif</a>"&gt;
      &lt;chrome:packages&gt;       &lt;chrome:packages&gt;
        &lt;RDF:Seq about="urn:mozilla:locale:en-US:packages"&gt;         &lt;RDF:Seq about="urn:mozilla:locale:en-US:packages"&gt;
          &lt;RDF:li resource="urn:mozilla:locale:en-US:xmlterm"/&gt;           &lt;RDF:li resource="urn:mozilla:locale:en-US:xmlterm"/&gt;
Line 165  HREF="ch02.html#77048">Chapter 2</A>. Th Line 338  HREF="ch02.html#77048">Chapter 2</A>. Th
        &lt;/RDF:Seq&gt;         &lt;/RDF:Seq&gt;
      &lt;/chrome:packages&gt;       &lt;/chrome:packages&gt;
    &lt;/RDF:Description&gt;     &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>The structure in <A HREF="#77026">Example 6-4</A> is exactly the same as that in more focused manifests (<A HREF="#77022">Example 6-2</A> and <A HREF="#77024">Example 6-3</A>), but all of the skin, content, and locale structures sit together in a single <I>manifest.rdf</I> file. This manifest follows the Mozilla convention of introducing the package contents at the top and then expanding upon the basic listing of each separate sections, providing the necessary metadata about the items in the middle, and then listing the components that are affected by the items at the end. However, the flexibility of the RDF format means you could just as easily order this information differently-which is why RDF is sometimes described as creating a "soup" of statements about resources.    <p>The structure in <a href="#77026">Example 6-4</a> is exactly
<P>Note that the overlay section in the middle of the example is part of the content description. It tells the chrome registry that the contents of the file <I>xmltermOverlay.xul</I> should be overlaid into the <I>tasksOverlay.xul</I> file in Mozilla, in which much of the Tools menu is defined. The package manifest for the xFly sample application that we discuss here, also a single file, is very similar to the manifest in <A HREF="#77026">Example 6-4</A>.    the same as that in more focused manifests (<a href=
<H3><A NAME="77070"></A> Registering Packages</H3>    "#77022">Example 6-2</a> and <a href="#77024">Example 6-3</a>),
<P>Typically, registration occurs  <!--INDEX packages:registration;registration:packages --> during installation, which is why the <A HREF="#77081">"Installing Mozilla Applications</A>" section of this chapter goes into more detail about the specific methods and objects available for package registration. The registration process deals with packages and package manifests, however, so the following two sections describe the two types of package registration that are possible in Mozilla. The first provides an overview of how to register a package on installation, as is typically done, and the second describes how to use a special file to register your work with Mozilla as you develop it so that you can view your work as it progresses.    but all of the skin, content, and locale structures sit
<H4><A NAME="77071"></A> Registering packages on installation</H4>    together in a single <i>manifest.rdf</i> file. This manifest
<P>Generally, the registration process  <!--INDEX registration:packages:on installation[registration:packages:installation] -->  <!--INDEX packages:registration:on installation[packages:registration:installation] -->  <!--INDEX installation:packages:registration and --> is a transaction that takes place between your installation scripts, the chrome registry, and the manifests that describe the package. Usually, registration happens upon installation. You can approach this transaction in many ways, but the general relationship is shown in <A HREF="#77004">Figure 6-2</A>.    follows the Mozilla convention of introducing the package
<P><CENTER><IMG SRC="foo.gif"></CENTER>    contents at the top and then expanding upon the basic listing
<P><I>Figure 6-2: <A NAME="77004"></A></I>    of each separate sections, providing the necessary metadata
<I>Package interaction overview</I>    about the items in the middle, and then listing the components
    that are affected by the items at the end. However, the
<P>In this relationship, the install script is responsible for managing the transfer of files to a specified location on the local disk and alerting the chrome registry to the new files and their manifests. The chrome registry then finds and reads those manifests. If the information there is formatted correctly, then that information is added to the sum of package information that the chrome registry manages-a single, overarching datasource of all packages in Mozilla, including skins, locales, overlays, and other software. In this way, the package is added to Mozilla. The major players in this interaction between the packages, the package descriptions, and the chrome registry are shown in the following list.    flexibility of the RDF format means you could just as easily
<UL><P><LI>Manifests in the archives themselves<P>    order this information differently-which is why RDF is
<P><LI>XPInstall, the technology that performs the downloading and resource installation<P>    sometimes described as creating a "soup" of statements about
<P><LI>The chrome registry, the database of packages, and user information that is read and written to when new software is installed<P></UL>    resources.</p>
<H4><A NAME="77072"></A> Registering packages as you develop them (installed-chrome.txt)</H4>    <p>Note that the overlay section in the middle of the example
<P>The file <I>installed-chrome.txt</I> is a  <!--INDEX registration:packages:at development[registration:packages:development] -->  <!--INDEX packages:registration:at development[packages:registration:development] --> convenience for developers who want to create and test new packages without  <!--INDEX installed-chrome.txt file --> having to install them with installation scripts and manifests. Some earlier xFly examples in this book already used this method. The <I>installed-chrome.txt</I> file is a list of entries that point to package manifests. Each line provides the chrome registry with a pointer to a manifest in which new software is described: new skin information, new packages, and new locales.    is part of the content description. It tells the chrome
<P>In the following snippet from the <I>installed-chrome.txt</I> file in the Mozilla <I>chrome</I> directory, five entries point to <I>contents.rdf</I> type manifests that describe the modern skin resources particular to the application's major components. The first line in this list, for example, tells the chrome registry to find a <I>contents.rdf</I> file in the subdirectory <I>skin/modern/communicator</I> contained in the <I>modern.jar</I> file, which describes the resources present there to skin the communicator component. When the chrome registry reads this line, it uses those resources to skin the communicator component, shown here:    registry that the contents of the file
<PRE>skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/communicator/    <i>xmltermOverlay.xul</i> should be overlaid into the
     <i>tasksOverlay.xul</i> file in Mozilla, in which much of the
     Tools menu is defined. The package manifest for the xFly sample
     application that we discuss here, also a single file, is very
     similar to the manifest in <a href="#77026">Example
     6-4</a>.</p>
     <h3><a name="77070"></a> Registering Packages</h3>
     <p>Typically, registration occurs 
     <!--INDEX packages:registration;registration:packages -->
     during installation, which is why the <a href=
     "#77081">"Installing Mozilla Applications</a>" section of this
     chapter goes into more detail about the specific methods and
     objects available for package registration. The registration
     process deals with packages and package manifests, however, so
     the following two sections describe the two types of package
     registration that are possible in Mozilla. The first provides
     an overview of how to register a package on installation, as is
     typically done, and the second describes how to use a special
     file to register your work with Mozilla as you develop it so
     that you can view your work as it progresses.</p>
     <h4><a name="77071"></a> Registering packages on
     installation</h4>
     <p>Generally, the registration process 
     <!--INDEX registration:packages:on installation[registration:packages:installation] -->
     <!--INDEX packages:registration:on installation[packages:registration:installation] -->
     <!--INDEX installation:packages:registration and --> is a
     transaction that takes place between your installation scripts,
     the chrome registry, and the manifests that describe the
     package. Usually, registration happens upon installation. You
     can approach this transaction in many ways, but the general
     relationship is shown in <a href="#77004">Figure 6-2</a>.</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-2: <a name="77004"></a></i> <i>Package
     interaction overview</i></p>
     <p>In this relationship, the install script is responsible for
     managing the transfer of files to a specified location on the
     local disk and alerting the chrome registry to the new files
     and their manifests. The chrome registry then finds and reads
     those manifests. If the information there is formatted
     correctly, then that information is added to the sum of package
     information that the chrome registry manages-a single,
     overarching datasource of all packages in Mozilla, including
     skins, locales, overlays, and other software. In this way, the
     package is added to Mozilla. The major players in this
     interaction between the packages, the package descriptions, and
     the chrome registry are shown in the following list.</p>
     <ul>
       <li>Manifests in the archives themselves</li>
       <li>XPInstall, the technology that performs the downloading
       and resource installation</li>
       <li>The chrome registry, the database of packages, and user
       information that is read and written to when new software is
       installed</li>
     </ul>
     <h4><a name="77072"></a> Registering packages as you develop
     them (installed-chrome.txt)</h4>
     <p>The file <i>installed-chrome.txt</i> is a 
     <!--INDEX registration:packages:at development[registration:packages:development] -->
     <!--INDEX packages:registration:at development[packages:registration:development] -->
     convenience for developers who want to create and test new
     packages without <!--INDEX installed-chrome.txt file --> having
     to install them with installation scripts and manifests. Some
     earlier xFly examples in this book already used this method.
     The <i>installed-chrome.txt</i> file is a list of entries that
     point to package manifests. Each line provides the chrome
     registry with a pointer to a manifest in which new software is
     described: new skin information, new packages, and new
     locales.</p>
     <p>In the following snippet from the
     <i>installed-chrome.txt</i> file in the Mozilla <i>chrome</i>
     directory, five entries point to <i>contents.rdf</i> type
     manifests that describe the modern skin resources particular to
     the application's major components. The first line in this
     list, for example, tells the chrome registry to find a
     <i>contents.rdf</i> file in the subdirectory
     <i>skin/modern/communicator</i> contained in the
     <i>modern.jar</i> file, which describes the resources present
     there to skin the communicator component. When the chrome
     registry reads this line, it uses those resources to skin the
     communicator component, shown here:</p>
 <pre>
 skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/communicator/
 skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/editor/  skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/editor/
 skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/global/  skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/global/
 skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/messenger/  skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/messenger/
skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/navigator/</PRE>skin,install,url,jar:resource:/chrome/modern.jar!/skin/modern/navigator/
<P>Instead of installing your package with installation scripts, you can add the appropriate entries to this file, as seen in the following examples. Adding these entries only registers local content on your machine. When you use the <I>installed-chrome.txt</I> file, you neither install a new package nor make that package installable by others. Editing the <I>installed-chrome.txt</I> file directly is a shortcut for making Mozilla aware of packages so that you can check your progress as you develop. You probably need to create an installer for packages you want to distribute and install on other systems.</pre>
<P>To register a local copy of  <!--INDEX registration:xFly application, chrome directory;xFly:registration, chrome directory --> the xFly application with the Mozilla <I>chrome</I> directory, you would add the following three entries, where the <I>xFly</I> directory and the appropriate subdirectories sit directly under the <I>chrome</I> directory:    <p>Instead of installing your package with installation
<PRE>content,install,url,resource:/chrome/xfly/content/    scripts, you can add the appropriate entries to this file, as
     seen in the following examples. Adding these entries only
     registers local content on your machine. When you use the
     <i>installed-chrome.txt</i> file, you neither install a new
     package nor make that package installable by others. Editing
     the <i>installed-chrome.txt</i> file directly is a shortcut for
     making Mozilla aware of packages so that you can check your
     progress as you develop. You probably need to create an
     installer for packages you want to distribute and install on
     other systems.</p>
     <p>To register a local copy of 
     <!--INDEX registration:xFly application, chrome directory;xFly:registration, chrome directory -->
     the xFly application with the Mozilla <i>chrome</i> directory,
     you would add the following three entries, where the
     <i>xFly</i> directory and the appropriate subdirectories sit
     directly under the <i>chrome</i> directory:</p>
 <pre>
 content,install,url,resource:/chrome/xfly/content/
 skin,install,url,resource:/chrome/xfly/skin/  skin,install,url,resource:/chrome/xfly/skin/
locale,install,url,resource:/chrome/xfly/locale/en-US/</PRE>locale,install,url,resource:/chrome/xfly/locale/en-US/
<P>The first line tells the chrome registry that the content is found in the directory <I>chrome/xfly/content</I>. The next line points to the skin resources at <I>chrome/xfly/skin</I>, and so on. Note that creating a single entry for the xFly skin and locating its resources underneath the xFly application directory (as opposed to a subdirectory in the modern and/or classic JARs) means that the xFly skin will not change when the user changes skins.</pre>
<P>If we had the same structure archived in a JAR file called <I>xfly.jar</I> rather than in a directory, the <I>installed-chrome.txt</I> entries would look like this:    <p>The first line tells the chrome registry that the content is
<PRE>content,install,url,jar:resource:/chrome/xfly.jar!/content/    found in the directory <i>chrome/xfly/content</i>. The next
     line points to the skin resources at <i>chrome/xfly/skin</i>,
     and so on. Note that creating a single entry for the xFly skin
     and locating its resources underneath the xFly application
     directory (as opposed to a subdirectory in the modern and/or
     classic JARs) means that the xFly skin will not change when the
     user changes skins.</p>
     <p>If we had the same structure archived in a JAR file called
     <i>xfly.jar</i> rather than in a directory, the
     <i>installed-chrome.txt</i> entries would look like this:</p>
 <pre>
 content,install,url,jar:resource:/chrome/xfly.jar!/content/
 skin,install,url,jar:resource:/chrome/xfly.jar!/skin/  skin,install,url,jar:resource:/chrome/xfly.jar!/skin/
locale,install,url,jar:resource:/chrome/xfly.jar!/locale/en-US/</PRE>locale,install,url,jar:resource:/chrome/xfly.jar!/locale/en-US/
<P>This code tells the chrome registry to look in the <I>content</I>, <I>skin</I>, and <I>locale/en-US</I> directories in the JAR file to locate the manifests.</pre>
<P>This skin entry seems to indicate that only one set of skin information is available for the xFly sample, and that it always applies. If the     <p>This code tells the chrome registry to look in the
xFly skin inherits, as many skins do, from one or another of the preinstalled theme (e.g., Modern), it may look very bad or even break when that     <i>content</i>, <i>skin</i>, and <i>locale/en-US</i>
theme is not selected. See the section <A HREF="ch04.html#77088">"Skin inheritance and skin modularization</A>" in <A HREF="ch04.html#77060">Chapter 4</A> for a discussion of skin inheritance and tips on how to make sure your skin is structured to best take advantage of it.    directories in the JAR file to locate the manifests.</p>
<P>When you make these additions to the <I>installed-chrome.txt</I> file and restart Mozilla, the chrome registry looks for manifests in the directories you specify and registers the packages described there. The <I>installed-chrome.txt</I> entries in this section do not necessarily need to be included on your final XPI resource, but you will see them in some XPIs bundled in their own <I>installed-chrome.txt</I> file separate form the main one. See the section <A HREF="#77078">"The Chrome Registry</A>" for more information about this process.    <p>This skin entry seems to indicate that only one set of skin
<H3><A NAME="77073"></A> Creating a Package</H3>    information is available for the xFly sample, and that it
<P>The xFly sample package  <!--INDEX packages:xFly;xFly package --> is a relatively straightforward arrangement of content, skin, and locale. You     always applies. If the xFly skin inherits, as many skins do,
have already seen how to set up most preliminaries you need to make it a package in <A HREF="ch02.html#77048">Chapter 2</A>, but this section will discuss the process in detail.    from one or another of the preinstalled theme (e.g., Modern),
<H4><A NAME="77074"></A> Setting up xFly</H4>    it may look very bad or even break when that theme is not
<P>To start working immediately  <!--INDEX xFly package:setup;packages:xFly:setup --> with tools like XUL and CSS, you can move some things around and hack one of the chrome registry files, as you have already seen. This section reviews those important preliminary application development steps in more detail.    selected. See the section <a href="ch04.html#77088">"Skin
<P>Because it has its own interface and is not worried (for now) about being made available in languages other than English, the only one for which it has a language pack, the xFly package is self-contained:    inheritance and skin modularization</a>" in <a href=
<PRE>chrome    "ch04.html#77060">Chapter 4</a> for a discussion of skin
     inheritance and tips on how to make sure your skin is
     structured to best take advantage of it.</p>
     <p>When you make these additions to the
     <i>installed-chrome.txt</i> file and restart Mozilla, the
     chrome registry looks for manifests in the directories you
     specify and registers the packages described there. The
     <i>installed-chrome.txt</i> entries in this section do not
     necessarily need to be included on your final XPI resource, but
     you will see them in some XPIs bundled in their own
     <i>installed-chrome.txt</i> file separate form the main one.
     See the section <a href="#77078">"The Chrome Registry</a>" for
     more information about this process.</p>
     <h3><a name="77073"></a> Creating a Package</h3>
     <p>The xFly sample package 
     <!--INDEX packages:xFly;xFly package --> is a relatively
     straightforward arrangement of content, skin, and locale. You
     have already seen how to set up most preliminaries you need to
     make it a package in <a href="ch02.html#77048">Chapter 2</a>,
     but this section will discuss the process in detail.</p>
     <h4><a name="77074"></a> Setting up xFly</h4>
     <p>To start working immediately 
     <!--INDEX xFly package:setup;packages:xFly:setup --> with tools
     like XUL and CSS, you can move some things around and hack one
     of the chrome registry files, as you have already seen. This
     section reviews those important preliminary application
     development steps in more detail.</p>
     <p>Because it has its own interface and is not worried (for
     now) about being made available in languages other than
     English, the only one for which it has a language pack, the
     xFly package is self-contained:</p>
 <pre>
 chrome
 xfly  xfly
 content  content
 skin  skin
locale</PRE>locale
<P>All parts of the package can be held in a single JAR file or a single <I>chrome</I> subdirectory. Contrast this with a large component-like communicator that, when you include its content, skin, localized information, and the Mozilla services it uses via XPConnect, is spread out into all of the main JAR files that make up the distribution:</pre>
<PRE>chrome/modern.jar!/skins/modern/communicator/    <p>All parts of the package can be held in a single JAR file or
     a single <i>chrome</i> subdirectory. Contrast this with a large
     component-like communicator that, when you include its content,
     skin, localized information, and the Mozilla services it uses
     via XPConnect, is spread out into all of the main JAR files
     that make up the distribution:</p>
 <pre>
 chrome/modern.jar!/skins/modern/communicator/
 chrome/comm.jar!/content/communicator/  chrome/comm.jar!/content/communicator/
chrome/en-US.jar!/locale/en-US/communicator/</PRE>chrome/en-US.jar!/locale/en-US/communicator/
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER></pre>
<P>When you develop your application, it's typical to work within a regular directory. As you finish the application and make it available for distribution and installation, however, you may want to use one of the installation archive formats to package your work, such as a JAR file. See the section <A HREF="#77082">"The XPI File Format</A>" later in this chapter for more details.<P></BLOCKQUOTE>    <blockquote>
<P>When your application is large and distributed in this way, the RDF-based manifests "compose" all of the metadata and treat all files as a single component.      <div class="c17">
<H4><A NAME="77075"></A> Hacking the installed-chrome.txt file</H4>        NOTE
<P>The entries you made  <!--INDEX installed-chrome.txt file:xFly and;xFly:installed-chrome.txt file --> to the <I>installed-chrome.txt</I> in <      </div>
HREF="ch02.html#77048">Chapter 2</A> tell the chrome registry that a new package must be registered:      <p>When you develop your application, it's typical to work
<PRE>content,install,url,resource:/chrome/xfly/content/      within a regular directory. As you finish the application and
       make it available for distribution and installation, however,
       you may want to use one of the installation archive formats
       to package your work, such as a JAR file. See the section <a
       href="#77082">"The XPI File Format</a>" later in this chapter
       for more details.</p>
     </blockquote>
     <p>When your application is large and distributed in this way,
     the RDF-based manifests "compose" all of the metadata and treat
     all files as a single component.</p>
     <h4><a name="77075"></a> Hacking the installed-chrome.txt
     file</h4>
     <p>The entries you made 
     <!--INDEX installed-chrome.txt file:xFly and;xFly:installed-chrome.txt file -->
     to the <i>installed-chrome.txt</i> in <a href=
     "ch02.html#77048">Chapter 2</a> tell the chrome registry that a
     new package must be registered:</p>
 <pre>
 content,install,url,resource:/chrome/xfly/content/
 skin,install,url,resource:/chrome/xfly/skin/  skin,install,url,resource:/chrome/xfly/skin/
locale,install,url,resource:/chrome/xfly/locale/en-US/</PRE>locale,install,url,resource:/chrome/xfly/locale/en-US/
<P>These entries tell the chrome registry that, in addition to all of the packages that make up the main Mozilla browser (e.g., the communicator skin in the Modern theme, the en-US locale, and the content that makes up the navigator), the xFly <TT>content</TT>, <TT>skin</TT>, and <TT>locale</TT> should be registered as components of a new package. When the chrome registry reads these entries, it tries to find the manifests for these parts of the xFly package. When it finds them, it registers the package, overlays any files it finds in that package (see the next section), and makes it accessible via the special <I>chrome://</I> URLs given in the manifests.</pre>
<H4><A NAME="77076"></A> Adding the xFly application to the Mozilla Tools menu</H4>    <p>These entries tell the chrome registry that, in addition to
<P>Adding your application  <!--INDEX xFly:Tools menu --> to one of the Mozilla browser menus (so users can easily launch your application once it is installed) makes your application feel official. <A HREF="#77006">Figure 6-3</A> shows the presence of the xFly item in the Tools menu. The Tools menu lists various extra components in Mozilla, including the DOM Inspector and the JavaScript Debugger (if they are installed).    all of the packages that make up the main Mozilla browser
<P><CENTER><IMG SRC="foo.gif"></CENTER>    (e.g., the communicator skin in the Modern theme, the en-US
<P><I>Figure 6-3: <A NAME="77006"></A></I>    locale, and the content that makes up the navigator), the xFly
<I>xFly item in Tools menu</I>    <tt>content</tt>, <tt>skin</tt>, and <tt>locale</tt> should be
    registered as components of a new package. When the chrome
<P>It is also possible to add an item to the Window menu that includes links to Navigator (the default browser), the Mail and Newsgroup client, the Chatzilla IRC client, Composer, and the Address Book (which only show up if they were added as part of the Mozilla installation process or if they were added separately afterwards).    registry reads these entries, it tries to find the manifests
<P>Here we describe how you can use special constructions in your package's manifest to tell the chrome registry about files from your package that should be overlaid into the main browser. Overlaying these files lets you add interface items, such as this link to xFly, in an existing application. <A HREF="#77028">Example 6-5</A> shows the simple overlay file that puts xFly in the Tools menu.    for these parts of the xFly package. When it finds them, it
<P>The top-level element is an <TT>&lt;overlay/&gt;</TT> rather than a <TT>&lt;window/&gt;</TT>. Direct children of the overlay are associated with certain elements in the main browser (in this case, the <TT>&lt;menupopup/&gt;</TT> of the Tools menu) and their contents are interpolated into the list of children there. This file overlays an extra <TT>&lt;menuitem/&gt;</TT> into the Tools menu. In this case, the <TT>menuitem</TT> has an <TT>oncommand</TT> event handler that calls <TT>toOpenWindowByType-</TT>a function for opening new chrome defined in the <I>tasksOverlay.js</I> that much of the chrome in the Mozilla UI imports.    registers the package, overlays any files it finds in that
    package (see the next section), and makes it accessible via the
<P><I>Example 6-5: <A NAME="77028"></A></I>    special <i>chrome://</i> URLs given in the manifests.</p>
<I>The xFly overlay</I>    <h4><a name="77076"></a> Adding the xFly application to the
<PRE> &lt;?xml version="1.0"?&gt;    Mozilla Tools menu</h4>
     <p>Adding your application <!--INDEX xFly:Tools menu --> to one
     of the Mozilla browser menus (so users can easily launch your
     application once it is installed) makes your application feel
     official. <a href="#77006">Figure 6-3</a> shows the presence of
     the xFly item in the Tools menu. The Tools menu lists various
     extra components in Mozilla, including the DOM Inspector and
     the JavaScript Debugger (if they are installed).</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-3: <a name="77006"></a></i> <i>xFly item in
     Tools menu</i></p>
     <p>It is also possible to add an item to the Window menu that
     includes links to Navigator (the default browser), the Mail and
     Newsgroup client, the Chatzilla IRC client, Composer, and the
     Address Book (which only show up if they were added as part of
     the Mozilla installation process or if they were added
     separately afterwards).</p>
     <p>Here we describe how you can use special constructions in
     your package's manifest to tell the chrome registry about files
     from your package that should be overlaid into the main
     browser. Overlaying these files lets you add interface items,
     such as this link to xFly, in an existing application. <a href=
     "#77028">Example 6-5</a> shows the simple overlay file that
     puts xFly in the Tools menu.</p>
     <p>The top-level element is an <tt>&lt;overlay/&gt;</tt> rather
     than a <tt>&lt;window/&gt;</tt>. Direct children of the overlay
     are associated with certain elements in the main browser (in
     this case, the <tt>&lt;menupopup/&gt;</tt> of the Tools menu)
     and their contents are interpolated into the list of children
     there. This file overlays an extra <tt>&lt;menuitem/&gt;</tt>
     into the Tools menu. In this case, the <tt>menuitem</tt> has an
     <tt>oncommand</tt> event handler that calls
     <tt>toOpenWindowByType-</tt>a function for opening new chrome
     defined in the <i>tasksOverlay.js</i> that much of the chrome
     in the Mozilla UI imports.</p>
     <p><i>Example 6-5: <a name="77028"></a></i> <i>The xFly
     overlay</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;overlay id="xflyTasksOverlay"   &lt;overlay id="xflyTasksOverlay"
    xmlns="<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"&gt;    xmlns="<a href=
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
    &lt;menupopup id="taskPopup"&gt;     &lt;menupopup id="taskPopup"&gt;
      &lt;menuitem label="xFly"       &lt;menuitem label="xFly"
          oncommand="toOpenWindowByType(`xfly:main', `chrome://xfly/content/');" /&gt;           oncommand="toOpenWindowByType(`xfly:main', `chrome://xfly/content/');" /&gt;
    &lt;/menupopup&gt;     &lt;/menupopup&gt;
 &lt;/overlay&gt;</PRE> &lt;/overlay&gt;
</pre>
<P>But how does the overlay know where to overlay itself? The IDs of the overlay children and the original XUL are matched to find the target within the files, but the manifest that accompanies the overlay in your package tells Mozilla which overlays are associated with which XUL files. The part of the manifest that deals with an overlay looks like the code in <A HREF="#77030">Example 6-6</A>. This code is put in the <I>contents.rdf</I> file in the <I>content</I> directory of the xFly package.    <p>But how does the overlay know where to overlay itself? The
    IDs of the overlay children and the original XUL are matched to
<P><I>Example 6-6: <A NAME="77030"></A></I>    find the target within the files, but the manifest that
<I>Overlay information in the manifest</I>    accompanies the overlay in your package tells Mozilla which
<PRE> &lt;!-- overlay information --&gt;    overlays are associated with which XUL files. The part of the
     manifest that deals with an overlay looks like the code in <a
     href="#77030">Example 6-6</a>. This code is put in the
     <i>contents.rdf</i> file in the <i>content</i> directory of the
     xFly package.</p>
     <p><i>Example 6-6: <a name="77030"></a></i> <i>Overlay
     information in the manifest</i></p>
 <pre>
  &lt;!-- overlay information --&gt;
    &lt;RDF:Seq about="urn:mozilla:overlays"&gt;     &lt;RDF:Seq about="urn:mozilla:overlays"&gt;
      &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;       &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
    &lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;     &lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;
      &lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;       &lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;
   &lt;/RDF:Seq&gt;</PRE>   &lt;/RDF:Seq&gt;
</pre>
<P>The first RDF element in the manifest is a list of affected target files and the second is a list of files that should be overlayed into those targets. Do not be confused by the names of the files in this case: the <I>tasksOverlay.xul</I> file is a target-though it is an overlay, as described in the following section-and <I>xflyOverlay.xul</I> is the overlay with the xFly menu item.    <p>The first RDF element in the manifest is a list of affected
<H4><A NAME="77077"></A> Overlaying Mozilla files into your application</H4>    target files and the second is a list of files that should be
<P>In the previous section, we  <!--INDEX files:overlaying into application;applications:overlaying files to;overlays:overlaying files into application --> described how to use the XUL overlay technology to put information from your application into the Mozilla browser. When developers use overlays in this way, they usually add a <TT>menuitem</TT> or a new UI to the browser that provides access to the application.    overlayed into those targets. Do not be confused by the names
<P>But overlays can also add interface elements and other data from Mozilla into the application itself. In fact, each component in Mozilla imports a lot of its own user interface from such XUL overlay mainstays as <I>globalOverlay.xul</I>, <I>tasksOverlay.xul</I> (the file into which the xFly <TT>menuitem</TT> is overlaid), and <I>navigatorOverlay.xul</I>. As you can see when you look at the main browser file, <I>navigator.xul</I>, shown in <A HREF="#77032">Example 6-7</A>, most user interface is actually brought in from these reusable overlays. A relatively small percentage of all that appears in the browser is defined within that particular <I>navigator.xul</I> file.    of the files in this case: the <i>tasksOverlay.xul</i> file is
    a target-though it is an overlay, as described in the following
<P><I>Example 6-7: <A NAME="77032"></A></I>    section-and <i>xflyOverlay.xul</i> is the overlay with the xFly
<I>Overlays in navigator.xul</I>    menu item.</p>
<PRE> &lt;?xul-overlay href="chrome://navigator/content/navigatorOverlay.xul"?&gt;    <h4><a name="77077"></a> Overlaying Mozilla files into your
     application</h4>
     <p>In the previous section, we 
     <!--INDEX files:overlaying into application;applications:overlaying files to;overlays:overlaying files into application -->
     described how to use the XUL overlay technology to put
     information from your application into the Mozilla browser.
     When developers use overlays in this way, they usually add a
     <tt>menuitem</tt> or a new UI to the browser that provides
     access to the application.</p>
     <p>But overlays can also add interface elements and other data
     from Mozilla into the application itself. In fact, each
     component in Mozilla imports a lot of its own user interface
     from such XUL overlay mainstays as <i>globalOverlay.xul</i>,
     <i>tasksOverlay.xul</i> (the file into which the xFly
     <tt>menuitem</tt> is overlaid), and
     <i>navigatorOverlay.xul</i>. As you can see when you look at
     the main browser file, <i>navigator.xul</i>, shown in <a href=
     "#77032">Example 6-7</a>, most user interface is actually
     brought in from these reusable overlays. A relatively small
     percentage of all that appears in the browser is defined within
     that particular <i>navigator.xul</i> file.</p>
     <p><i>Example 6-7: <a name="77032"></a></i> <i>Overlays in
     navigator.xul</i></p>
 <pre>
  &lt;?xul-overlay href="chrome://navigator/content/navigatorOverlay.xul"?&gt;
  &lt;?xul-overlay href="chrome://navigator/content/navExtraOverlay.xul"?&gt;   &lt;?xul-overlay href="chrome://navigator/content/navExtraOverlay.xul"?&gt;
  &lt;?xul-overlay href="chrome://navigator/content/linkToolbarOverlay.xul"?&gt;   &lt;?xul-overlay href="chrome://navigator/content/linkToolbarOverlay.xul"?&gt;
  &lt;?xul-overlay href="chrome://communicator/content/sidebar/sidebarOverlay.xul"?&gt;   &lt;?xul-overlay href="chrome://communicator/content/sidebar/sidebarOverlay.xul"?&gt;
  &lt;?xul-overlay href="chrome://communicator/content/securityOverlay.xul"?&gt;   &lt;?xul-overlay href="chrome://communicator/content/securityOverlay.xul"?&gt;
  &lt;?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?&gt;   &lt;?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?&gt;
 &lt;?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?&gt;</PRE> &lt;?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?&gt;
</pre>
<P>Of these overlays, those with  <!--INDEX communicatorOverlay.xul file;overlays:communicatorOverlay.xul file --> the most value for application developers are the <I>communicatorOverlay.xul</I>, which defines many of browser menus; the <I>tasksOverlay.xul</I>, which adds the Tools menu  <!--INDEX tasksOverlay.xul file;overlays:tasksOverlay.xul file --> and brings in all of its application <TT>menuitems</TT> as well as a lot of important browser functions like <TT>toOpenWindowByType</TT> and <TT>toNavigator</TT> (for returning to the main browser window); and the <TT>globalOverlay</TT> (which is overlaid into <I>navigatorOverlay.xul</I>, so it gets loaded there), which defines even more general and low-level features like pop ups and functions for quitting the application or setting tooltip text.    <p>Of these overlays, those with 
<P>Once files are divided into subdirectories and the manifests for each subdirectory, your application is technically a package-although until you compress it and create an install script, it's a package only for your computer and the environment in which it was created. See the section <A HREF="#77096">"Finishing Things Up</A>" later in this chapter to see how you can use the file format and installation information to make the xFly something you can put on a web server and have users install with a single click on a web page.    <!--INDEX communicatorOverlay.xul file;overlays:communicatorOverlay.xul file -->
<H3><A NAME="77078"></A> The Chrome Registry</H3>    the most value for application developers are the
<P>The chrome registry was briefly  <!--INDEX chrome:registry;registration:chrome registry --> mentioned several times in this book. It plays an important (but sometimes invisible) role in the way Mozilla applications, including the Mozilla browser itself, deal with user information, new components, skins, and other resources.    <i>communicatorOverlay.xul</i>, which defines many of browser
<P>At the beginning of the book, you had to create RDF files that would describe your application to Mozilla. Special entries also needed to be made to the <I>installed-chrome.txt</I> file in the <I>chrome </I>application directory. These entries are just two of the most common ways to address the chrome registry, which is what Mozilla uses to persist configurable aspects of the browser and its other applications.    menus; the <i>tasksOverlay.xul</i>, which adds the Tools menu 
<H4><A NAME="77079"></A> Where is the chrome registry?</H4>    <!--INDEX tasksOverlay.xul file;overlays:tasksOverlay.xul file -->
<P>The chrome registry is not a single file and it's not stored in a single place. Rather, it is a distributed collection of data and interfaces for data manipulation. The data itself generally lives in RDF files, many of which are in the <I>chrome</I> application directory. The chrome registry APIs-principally <TT>nsIChromeRegistry-</TT>are used by installation scripts when they register new  <!--INDEX nsIChromeRegistry --> software, by the skin-switching UI, and by the language selection facility. The chrome registry is the means through which packages are registered.    and brings in all of its application <tt>menuitems</tt> as well
<P>In some cases, especially when you create and debug your Mozilla application, you may want to edit the RDF files that make up the chrome registry directly. But more often, you can use external scripts, inline JavaScript, or the <I>installed-chrome.txt</I> file to get what you need from the registry. Procedures for doing so are described in the section <A HREF="#77070">"Registering Packages</A>" earlier in this chapter, and in the section <A HREF="#77085">"Installation Scripts</A>" later in this chapter.    as a lot of important browser functions like
<H4><A NAME="77080"></A> Accessing the chrome registry in installation scripts</H4>    <tt>toOpenWindowByType</tt> and <tt>toNavigator</tt> (for
<P>An install script is a  <!--INDEX installation scripts:chrome registry access;chrome:registry:installation scripts;scripts:installation scripts:chrome registry --> required part of a software package like the xFly. The two main functions of an installation script are the physical download and installation of files in the package and registration of that software with the chrome registry. Install scripts use functions from the XPInstall API to install the files and functions from the chrome registry interface to handle the latter, as seen in this snippet:    returning to the main browser window); and the
<PRE>registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome", "help"), "content/");</PRE>    <tt>globalOverlay</tt> (which is overlaid into
<P>The registration process is typically something that happens between the install initialization and the actual execution of the install:    <i>navigatorOverlay.xul</i>, so it gets loaded there), which
<PRE>initInstall( ) // initialize the overall installation    defines even more general and low-level features like pop ups
     and functions for quitting the application or setting tooltip
     text.</p>
     <p>Once files are divided into subdirectories and the manifests
     for each subdirectory, your application is technically a
     package-although until you compress it and create an install
     script, it's a package only for your computer and the
     environment in which it was created. See the section <a href=
     "#77096">"Finishing Things Up</a>" later in this chapter to see
     how you can use the file format and installation information to
     make the xFly something you can put on a web server and have
     users install with a single click on a web page.</p>
     <h3><a name="77078"></a> The Chrome Registry</h3>
     <p>The chrome registry was briefly 
     <!--INDEX chrome:registry;registration:chrome registry -->
     mentioned several times in this book. It plays an important
     (but sometimes invisible) role in the way Mozilla applications,
     including the Mozilla browser itself, deal with user
     information, new components, skins, and other resources.</p>
     <p>At the beginning of the book, you had to create RDF files
     that would describe your application to Mozilla. Special
     entries also needed to be made to the
     <i>installed-chrome.txt</i> file in the <i>chrome</i>
     application directory. These entries are just two of the most
     common ways to address the chrome registry, which is what
     Mozilla uses to persist configurable aspects of the browser and
     its other applications.</p>
     <h4><a name="77079"></a> Where is the chrome registry?</h4>
     <p>The chrome registry is not a single file and it's not stored
     in a single place. Rather, it is a distributed collection of
     data and interfaces for data manipulation. The data itself
     generally lives in RDF files, many of which are in the
     <i>chrome</i> application directory. The chrome registry
     APIs-principally <tt>nsIChromeRegistry-</tt>are used by
     installation scripts when they register new 
     <!--INDEX nsIChromeRegistry --> software, by the skin-switching
     UI, and by the language selection facility. The chrome registry
     is the means through which packages are registered.</p>
     <p>In some cases, especially when you create and debug your
     Mozilla application, you may want to edit the RDF files that
     make up the chrome registry directly. But more often, you can
     use external scripts, inline JavaScript, or the
     <i>installed-chrome.txt</i> file to get what you need from the
     registry. Procedures for doing so are described in the section
     <a href="#77070">"Registering Packages</a>" earlier in this
     chapter, and in the section <a href="#77085">"Installation
     Scripts</a>" later in this chapter.</p>
     <h4><a name="77080"></a> Accessing the chrome registry in
     installation scripts</h4>
     <p>An install script is a 
     <!--INDEX installation scripts:chrome registry access;chrome:registry:installation scripts;scripts:installation scripts:chrome registry -->
     required part of a software package like the xFly. The two main
     functions of an installation script are the physical download
     and installation of files in the package and registration of
     that software with the chrome registry. Install scripts use
     functions from the XPInstall API to install the files and
     functions from the chrome registry interface to handle the
     latter, as seen in this snippet:</p>
 <pre>
 registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome", "help"), "content/");
 </pre>
     <p>The registration process is typically something that happens
     between the install initialization and the actual execution of
     the install:</p>
 <pre>
 initInstall( ) // initialize the overall installation
 // add items to installed using:  // add items to installed using:
 // addFolder, addDirectory, getFolder, and others  // addFolder, addDirectory, getFolder, and others
 registerChrome(TYPE, dir, subdir)  registerChrome(TYPE, dir, subdir)
performInstall( );</PRE>performInstall( );
<P>Scripts and the installation process, including the registration of installed packages, are detailed in the next section.</pre>
<H2><A NAME="77081"></A> Installing Mozilla Applications</H2>    <p>Scripts and the installation process, including the
<P>Once your application  <!--INDEX applications:installation;installation:applications --> is packaged, the next step is to create a cross-platform installation, or XPI. A XPI is a special file archive that contains your Mozilla package(s) and its own installation instructions. The relationship of the various parts of the installation process-the XPI itself, the internal installation script, the trigger script that begins the installation, and the Mozilla browser-can be visualized in <A HREF="#77008">Figure 6-4</A>.    registration of installed packages, are detailed in the next
<P><CENTER><IMG SRC="foo.gif"></CENTER>    section.</p>
<P><I>Figure 6-4: <A NAME="77008"></A></I>    <h2><a name="77081"></a> Installing Mozilla Applications</h2>
<I>Installation process overview</I>    <p>Once your application 
    <!--INDEX applications:installation;installation:applications -->
<H3><A NAME="77082"></A> The XPI File Format</H3>    is packaged, the next step is to create a cross-platform
<P>Mozilla cross-platform installations  <!--INDEX XPI files:formats;installation:applications:XPI file formats;applications:installation:XPI file formats --> use XPIs as the file format in which to organize, compress, and automate software installations and software updates. A XPI is a PKZIP-compressed archive (like ZIP and JAR files) with a special script at the highest level that manages the installation. A quick scan of the contents of a XPI file (which you can open using with any unzip utility) reveals the high-level directory structure shown in <A HREF="#77034">Example 6-8</A>.    installation, or XPI. A XPI is a special file archive that
    contains your Mozilla package(s) and its own installation
<P><I>Example 6-8: <A NAME="77034"></A></I>    instructions. The relationship of the various parts of the
<I>Top level of the browser.xpi archive</I>    installation process-the XPI itself, the internal installation
<PRE> install.js    script, the trigger script that begins the installation, and
     the Mozilla browser-can be visualized in <a href=
     "#77008">Figure 6-4</a>.</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-4: <a name="77008"></a></i> <i>Installation
     process overview</i></p>
     <h3><a name="77082"></a> The XPI File Format</h3>
     <p>Mozilla cross-platform installations 
     <!--INDEX XPI files:formats;installation:applications:XPI file formats;applications:installation:XPI file formats -->
     use XPIs as the file format in which to organize, compress, and
     automate software installations and software updates. A XPI is
     a PKZIP-compressed archive (like ZIP and JAR files) with a
     special script at the highest level that manages the
     installation. A quick scan of the contents of a XPI file (which
     you can open using with any unzip utility) reveals the
     high-level directory structure shown in <a href=
     "#77034">Example 6-8</a>.</p>
     <p><i>Example 6-8: <a name="77034"></a></i> <i>Top level of the
     browser.xpi archive</i></p>
 <pre>
  install.js
  bin\   bin\
    chrome\     chrome\
    components     components
    defaults\     defaults\
    icons\     icons\
    plugins\     plugins\
   res\</PRE>   res\
</pre>
<P>Note that the high-level structure in <A HREF="#77034">Example 6-8</A> parallels the installed browser's directory structure very closely. The <I>bin</I> directory at the highest level of the archive corresponds to the Mozilla application directory. On Unix, this directory is actually called bin, where all of the resources are stored. On other platforms, the installation puts these resources in the application directory itself.    <p>Note that the high-level structure in <a href=
<P>In the case of the Mozilla browser, the XPIs manage the transfer and registry of all components-the chrome files in the JARs, the executables, the default user information, and the libraries. As you will see in the installation script, the contents of the archive are installed onto the filesystem in much the same way as they are stored in the archive itself, although it's possible to rearrange things arbitrarily upon installation-to create new directories, install files in system folders and other areas, or execute software that handles other aspects of the installation, such as third-party installers.    "#77034">Example 6-8</a> parallels the installed browser's
<H4><A NAME="77083"></A> XPI example</H4>    directory structure very closely. The <i>bin</i> directory at
<P>When the items to be installed are very simple, XPIs may contain nothing more than a single executable and the install script itself, as shown in <A HREF="#77010">Figure 6-5</A>. In this figure, the WinZip utility has been used to display the contents of a XPI that installs a text editor on a Win32 system.    the highest level of the archive corresponds to the Mozilla
<P><CENTER><IMG SRC="foo.gif"></CENTER>    application directory. On Unix, this directory is actually
<P><I>Figure 6-5: <A NAME="77010"></A></I>    called bin, where all of the resources are stored. On other
<I>Simplest XPI archive</I>    platforms, the installation puts these resources in the
    application directory itself.</p>
<P>This example uses XPInstall technology to install something that may or may not be a Mozilla application. The <I>install.js</I> script in <A HREF="#77034">Example 6-8</A> would look like this. In Mozilla application development, however, XPIs often contain JAR files that are installed as new packages in the Mozilla distribution. To make a XPI for your package, use any zip software (applications or extensions that will be part of the main Mozilla distribution are required to use the free <I>zip</I> utility from InfoTools so that they can be run as part of the build process) to archive your files.    <p>In the case of the Mozilla browser, the XPIs manage the
<H4><A NAME="77084"></A> JARs versus XPIs</H4>    transfer and registry of all components-the chrome files in the
<P>Technically, only the internal  <!--INDEX JAR (Java Archive) files:XPIs and;XPIs, JARs and --> installation script distinguishes JARs and XPIs. However, Mozilla treats them differently. Since JARs do not include this installation script, they cannot install full content or applications by themselves. In this case, "content" means XUL, XBL, or JavaScript files that have script access to XPCOM. Files of this kind that are in JARs are denied access to XPConnect and are not registered as content in the chrome registry. JARs are used primarily to install locales, or language packs, and skins.    JARs, the executables, the default user information, and the
<P>Skins that contain scripts  <!--INDEX skins:scripts and;skins:bindings and;bindings:skins;scripts:skins --> and bindings (see the section <    libraries. As you will see in the installation script, the
HREF="ch04.html#77103">"Theme Security Restrictions</A>" and the <A HREF="ch04.html#62192">"Evil Skins</A>" sidebar, both in <    contents of the archive are installed onto the filesystem in
HREF="ch04.html#77060">Chapter 4</A>) are seen more as chrome content and must be installed in XPIs if they are to be fully functional. Like     much the same way as they are stored in the archive itself,
executables that are fetched from the Web, XPIs can cause trouble when downloaded by unprepared users since the software in XPIs are given the same privileges on the Mozilla platform that the browser chrome itself has.    although it's possible to rearrange things arbitrarily upon
<P>The characteristics and usage  <!--INDEX XPI files:characteristics;JAR (Java Archive) files:characteristics --> of an XPI are:    installation-to create new directories, install files in system
<UL><P><LI>Has an <I>install.js</I> file<P>    folders and other areas, or execute software that handles other
<P><LI>Can install anything via XPInstall API<P>    aspects of the installation, such as third-party
<P><LI>PKZip-compressed<P>    installers.</p>
<P><LI>May contain one or more JAR packages<P>    <h4><a name="77083"></a> XPI example</h4>
<P><LI>Mozilla installation<P>    <p>When the items to be installed are very simple, XPIs may
<P><LI>Used for new packages<P></UL>    contain nothing more than a single executable and the install
<P>The characteristics and usage of a JAR are:    script itself, as shown in <a href="#77010">Figure 6-5</a>. In
<UL><P><LI>Contains only the resources themselves<P>    this figure, the WinZip utility has been used to display the
<P><LI>Installed with an external script<P>    contents of a XPI that installs a text editor on a Win32
<P><LI>May be installed inside a XPI<P>    system.</p>
<P><LI>PKZip-compressed<P>    <div class="c16">
<P><LI>Themes<P>      <img src="foo.gif">
<P><LI>Languages packs<P>    </div>
<P><LI>Storage archive for installed components<P></UL>    <p><i>Figure 6-5: <a name="77010"></a></i> <i>Simplest XPI
<P>Mozilla uses the presence of this internal installation script and not the file suffix (which can be changed easily enough) to determine what type of archive it is. Accordingly, JARs are most often used to install new themes and new language packs, which can be done by using just a brief trigger script on a web page loaded into Mozilla. When they contain new chrome-new XUL and JavaScript that will access the Mozilla objects via XPConnect-JAR files must be put within a XPI that can register them properly.    archive</i></p>
<H3><A NAME="77085"></A> Installation Scripts</H3>    <p>This example uses XPInstall technology to install something
<P>Most new packages in  <!--INDEX installation scripts;scripts;installation scripts --> Mozilla are  <!--INDEX JavaScript:installation scripts --> installed by means of installation scripts. These scripts are written in JavaScript. Unlike regular web page JavaScript, however, which uses <TT>window</TT> as the top-level object, installation scripts have a special install object context. As you will see in the following examples, the <TT>Install</TT> object-even when it's implicit and not prefixed to the object methods-is the top-level object upon which most methods are called.    that may or may not be a Mozilla application. The
<H4><A NAME="77086"></A> Script examples</H4>    <i>install.js</i> script in <a href="#77034">Example 6-8</a>
<P>At their very simplest, installation scripts look something like <A HREF="#77036">Example 6-9</A>.    would look like this. In Mozilla application development,
    however, XPIs often contain JAR files that are installed as new
<P><I>Example 6-9: <A NAME="77036"></A></I>    packages in the Mozilla distribution. To make a XPI for your
<I>Simple install script</I>    package, use any zip software (applications or extensions that
<PRE> // initialize the installation first    will be part of the main Mozilla distribution are required to
     use the free <i>zip</i> utility from InfoTools so that they can
     be run as part of the build process) to archive your files.</p>
     <h4><a name="77084"></a> JARs versus XPIs</h4>
     <p>Technically, only the internal 
     <!--INDEX JAR (Java Archive) files:XPIs and;XPIs, JARs and -->
     installation script distinguishes JARs and XPIs. However,
     Mozilla treats them differently. Since JARs do not include this
     installation script, they cannot install full content or
     applications by themselves. In this case, "content" means XUL,
     XBL, or JavaScript files that have script access to XPCOM.
     Files of this kind that are in JARs are denied access to
     XPConnect and are not registered as content in the chrome
     registry. JARs are used primarily to install locales, or
     language packs, and skins.</p>
     <p>Skins that contain scripts 
     <!--INDEX skins:scripts and;skins:bindings and;bindings:skins;scripts:skins -->
     and bindings (see the section <a href="ch04.html#77103">"Theme
     Security Restrictions</a>" and the <a href=
     "ch04.html#62192">"Evil Skins</a>" sidebar, both in <a href=
     "ch04.html#77060">Chapter 4</a>) are seen more as chrome
     content and must be installed in XPIs if they are to be fully
     functional. Like executables that are fetched from the Web,
     XPIs can cause trouble when downloaded by unprepared users
     since the software in XPIs are given the same privileges on the
     Mozilla platform that the browser chrome itself has.</p>
     <p>The characteristics and usage 
     <!--INDEX XPI files:characteristics;JAR (Java Archive) files:characteristics -->
     of an XPI are:</p>
     <ul>
       <li>Has an <i>install.js</i> file</li>
       <li>Can install anything via XPInstall API</li>
       <li>PKZip-compressed</li>
       <li>May contain one or more JAR packages</li>
       <li>Mozilla installation</li>
       <li>Used for new packages</li>
     </ul>
     <p>The characteristics and usage of a JAR are:</p>
     <ul>
       <li>Contains only the resources themselves</li>
       <li>Installed with an external script</li>
       <li>May be installed inside a XPI</li>
       <li>PKZip-compressed</li>
       <li>Themes</li>
       <li>Languages packs</li>
       <li>Storage archive for installed components</li>
     </ul>
     <p>Mozilla uses the presence of this internal installation
     script and not the file suffix (which can be changed easily
     enough) to determine what type of archive it is. Accordingly,
     JARs are most often used to install new themes and new language
     packs, which can be done by using just a brief trigger script
     on a web page loaded into Mozilla. When they contain new
     chrome-new XUL and JavaScript that will access the Mozilla
     objects via XPConnect-JAR files must be put within a XPI that
     can register them properly.</p>
     <h3><a name="77085"></a> Installation Scripts</h3>
     <p>Most new packages in 
     <!--INDEX installation scripts;scripts;installation scripts -->
     Mozilla are <!--INDEX JavaScript:installation scripts -->
     installed by means of installation scripts. These scripts are
     written in JavaScript. Unlike regular web page JavaScript,
     however, which uses <tt>window</tt> as the top-level object,
     installation scripts have a special install object context. As
     you will see in the following examples, the <tt>Install</tt>
     object-even when it's implicit and not prefixed to the object
     methods-is the top-level object upon which most methods are
     called.</p>
     <h4><a name="77086"></a> Script examples</h4>
     <p>At their very simplest, installation scripts look something
     like <a href="#77036">Example 6-9</a>.</p>
     <p><i>Example 6-9: <a name="77036"></a></i> <i>Simple install
     script</i></p>
 <pre>
  // initialize the installation first
  initInstall("My Package Install", "package_name", "1.0", 1);   initInstall("My Package Install", "package_name", "1.0", 1);
  // add files to the installation   // add files to the installation
  f = getFolder("Program");   f = getFolder("Program");
  setPackageFolder(f);   setPackageFolder(f);
  addFile("package.xpi")   addFile("package.xpi")
  // perform the installation   // perform the installation
 performInstall( );</PRE> performInstall( );
</pre>
<P>These methods are being called on the <TT>Install</TT> object, which is implicit in an installation script. <A HREF="#77038">Example 6-10</A> is an equivalent (and still very compact) installation script. The <TT>Install</TT> object is prefixed explicitly to the install functions.    <p>These methods are being called on the <tt>Install</tt>
    object, which is implicit in an installation script. <a href=
Example 6-10<A NAME="77038"></A>    "#77038">Example 6-10</a> is an equivalent (and still very
<I>Script that explicitly prefixes the Install object</I>    compact) installation script. The <tt>Install</tt> object is
<PRE> Install.initInstall("My Package Install", "package_name", "1.0", 1);    prefixed explicitly to the install functions. Example 6-10<a
     name="77038"></a> <i>Script that explicitly prefixes the
     Install object</i></p>
 <pre>
  Install.initInstall("My Package Install", "package_name", "1.0", 1);
  f = Install.getFolder("Program");   f = Install.getFolder("Program");
  Install.setPackageFolder(f);   Install.setPackageFolder(f);
  Install.addFile("package.xpi")   Install.addFile("package.xpi")
 Install.performInstall( );</PRE> Install.performInstall( );
</pre>
<P>As they become more complicated, install scripts may set up and arrange target directories in more specific ways, do more error checking, and include variables to make the code more readable and reusable, as seen in the longer install script in <A HREF="#77040">Example 6-11</A>.    <p>As they become more complicated, install scripts may set up
    and arrange target directories in more specific ways, do more
Example 6-11<A NAME="77040"></A>    error checking, and include variables to make the code more
<I>A more complicated install script</I>    readable and reusable, as seen in the longer install script in
<PRE> var vi = "10.10.10.10";    <a href="#77040">Example 6-11</a>. Example 6-11<a name=
     "77040"></a> <i>A more complicated install script</i></p>
 <pre>
  var vi = "10.10.10.10";
  var xpiSrc = "adddir1";   var xpiSrc = "adddir1";
  initInstall("addFileNoVers1", "adddir_1", vi, 1);   initInstall("addFileNoVers1", "adddir_1", vi, 1);
  f = getFolder("Program");   f = getFolder("Program");
Line 387  Example 6-11<A NAME="77040"></A> Line 968  Example 6-11<A NAME="77040"></A>
  if (0 == getLastError( ))   if (0 == getLastError( ))
    performInstall( );     performInstall( );
  else   else
   cancelInstall( );</PRE>   cancelInstall( );
</pre>
<H4><A NAME="77087"></A> Web page installations</H4>    <h4><a name="77087"></a> Web page installations</h4>
<P>XPInstall technology makes software installation  <!--INDEX installation:from web page[installation:web page];XPInstall:installation from web page --> from a web page very easy. When a link on a web page kicks off the installation of new software, "trigger" code on the web page starts the process and gets the XPI onto the local system. Once this is done, the <I>install.js</I> file in the XPI can take up the full installation and registration of new files.    <p>XPInstall technology makes software installation 
<P>In <A HREF="#77042">Example 6-12</A>, the trigger script-placed in an <TT>onclick</TT> event handler on the page-starts the installation of a new theme on the local machine, where the XPI can be unpacked and its installation script executed in full.    <!--INDEX installation:from web page[installation:web page];XPInstall:installation from web page -->
    from a web page very easy. When a link on a web page kicks off
Example 6-12<A NAME="77042"></A>    the installation of new software, "trigger" code on the web
<I>Trigger script on a web page</I>    page starts the process and gets the XPI onto the local system.
<PRE> &lt;a href="#"    Once this is done, the <i>install.js</i> file in the XPI can
     take up the full installation and registration of new
     files.</p>
     <p>In <a href="#77042">Example 6-12</a>, the trigger
     script-placed in an <tt>onclick</tt> event handler on the
     page-starts the installation of a new theme on the local
     machine, where the XPI can be unpacked and its installation
     script executed in full. Example 6-12<a name="77042"></a>
     <i>Trigger script on a web page</i></p>
 <pre>
  &lt;a href="#"
     onclick="InstallTrigger.installChrome(      onclick="InstallTrigger.installChrome(
     InstallTrigger.SKIN,      InstallTrigger.SKIN,
    '<A HREF="http://wildskins/newblue.xpi">http://wildskins/newblue.xpi</A>',    '<a href=
 "http://wildskins/newblue.xpi">http://wildskins/newblue.xpi</a>',
     'newblue/1.0');"&gt;      'newblue/1.0');"&gt;
    Install the New Blue theme&lt;/a&gt;</PRE>    Install the New Blue theme&lt;/a&gt;
</pre>
<P>Later, we discuss in more detail the <TT>Install</TT> object, whose methods are typically called in installation scripts.    <p>Later, we discuss in more detail the <tt>Install</tt>
<H4><A NAME="77088"></A> Scriptless installations</H4>    object, whose methods are typically called in installation
<P>When you have a simple Mozilla package like a  <!--INDEX installation:scriptless;scriptless installations --> theme, which does not need special security privileges and which is always installed in a particular location, you can leave out the XPI and its internal installation script altogether and use a trigger script like <A HREF="#77044">Example 6-13</A> and a regular JAR file to download and register the new package.    scripts.</p>
    <h4><a name="77088"></a> Scriptless installations</h4>
Example 6-13<A NAME="77044"></A>    <p>When you have a simple Mozilla package like a 
<I>Scriptless install of a JAR</I>    <!--INDEX installation:scriptless;scriptless installations -->
<PRE> &lt;a href="#"    theme, which does not need special security privileges and
     which is always installed in a particular location, you can
     leave out the XPI and its internal installation script
     altogether and use a trigger script like <a href=
     "#77044">Example 6-13</a> and a regular JAR file to download
     and register the new package. Example 6-13<a name="77044"></a>
     <i>Scriptless install of a JAR</i></p>
 <pre>
  &lt;a href="#"
     onclick="InstallTrigger.installChrome(      onclick="InstallTrigger.installChrome(
     InstallTrigger.SKIN,      InstallTrigger.SKIN,
    '<A HREF="http://wildskins/newblue.jar">http://wildskins/newblue.jar</A>',    '<a href=
 "http://wildskins/newblue.jar">http://wildskins/newblue.jar</a>',
     'newblue/1.0');"&gt;      'newblue/1.0');"&gt;
    Install the New Blue theme&lt;/a&gt;</PRE>    Install the New Blue theme&lt;/a&gt;
</pre>
<P>The only difference here is that the item to be installed is a JAR and not a XPI file. Also, no internal installation script is present (since of the two, only XPIs carry their own <I>install.js</I> file). When the <TT>InstallTrigger</TT> object gets a JAR with a package manifest it can read and a package type that doesn't break the security boundary for applications (i.e., a new theme, a new language pack, or new content that doesn't use XPConnect), it can download and register that package with the chrome registry and make it available to users. The JAR and a trigger script like the one just shown are all you need in this case. See the earlier section, <A HREF="#77084">"JARs versus XPIs</A>" for more detail on the limitations of scriptless installs.    <p>The only difference here is that the item to be installed is
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    a JAR and not a XPI file. Also, no internal installation script
<P>The xFly application accesses XPCOM objects in Mozilla, which makes it a full-blown XPConnected application. Thus, it needs to be installed in a XPI file that has its own internal installation script.<P></BLOCKQUOTE>    is present (since of the two, only XPIs carry their own
<H4><A NAME="77089"></A> Platform-dependent installation</H4>    <i>install.js</i> file). When the <tt>InstallTrigger</tt>
<P>Though the XPI format is by definition cross-platform,  <!--INDEX installation:platform-dependent;platform-dependent installation --> the files you distribute within it may need to be installed on a per-platform basis. The platform can be retrieved using the <TT>platform</TT> property of the <TT>Install</TT> object or the <TT>getFolder</TT> function. <A HREF="#77046">Example 6-14</A> shows a JavaScript function for <I>install.js</I> for returning the platform that the script is running on.    object gets a JAR with a package manifest it can read and a
    package type that doesn't break the security boundary for
Example 6-14<A NAME="77046"></A>    applications (i.e., a new theme, a new language pack, or new
<I>Getting the operating system in an install script</I>    content that doesn't use XPConnect), it can download and
<PRE> function getPlatform( )    register that package with the chrome registry and make it
     available to users. The JAR and a trigger script like the one
     just shown are all you need in this case. See the earlier
     section, <a href="#77084">"JARs versus XPIs</a>" for more
     detail on the limitations of scriptless installs.</p>
     <blockquote>
       <div class="c17">
         NOTE
       </div>
       <p>The xFly application accesses XPCOM objects in Mozilla,
       which makes it a full-blown XPConnected application. Thus, it
       needs to be installed in a XPI file that has its own internal
       installation script.</p>
     </blockquote>
     <h4><a name="77089"></a> Platform-dependent installation</h4>
     <p>Though the XPI format is by definition cross-platform, 
     <!--INDEX installation:platform-dependent;platform-dependent installation -->
     the files you distribute within it may need to be installed on
     a per-platform basis. The platform can be retrieved using the
     <tt>platform</tt> property of the <tt>Install</tt> object or
     the <tt>getFolder</tt> function. <a href="#77046">Example
     6-14</a> shows a JavaScript function for <i>install.js</i> for
     returning the platform that the script is running on. Example
     6-14<a name="77046"></a> <i>Getting the operating system in an
     install script</i></p>
 <pre>
  function getPlatform( )
  {   {
      var platformStr;       var platformStr;
      var platformNode;       var platformNode;
Line 451  Example 6-14<A NAME="77046"></A> Line 1078  Example 6-14<A NAME="77046"></A>
              platformNode = 'unix';               platformNode = 'unix';
      }       }
      return platformNode;       return platformNode;
 }</PRE> }
</pre>
<P>It's often necessary to check the platform when you install new language packs. At the time of this writing, issues related to write access to the chrome folder on Unix systems require some forking in the install script. There are also certain JAR files that are installed on a per-platform basis in language packs. <A HREF="#77046">Example 6-14</A> covers the three major platforms (Windows, Mac, and *nix). Here is how you use it:    <p>It's often necessary to check the platform when you install
<PRE>platformNode = getPlatform( );    new language packs. At the time of this writing, issues related
     to write access to the chrome folder on Unix systems require
     some forking in the install script. There are also certain JAR
     files that are installed on a per-platform basis in language
     packs. <a href="#77046">Example 6-14</a> covers the three major
     platforms (Windows, Mac, and *nix). Here is how you use it:</p>
 <pre>
 platformNode = getPlatform( );
 if (platformNode != 'unix') {  if (platformNode != 'unix') {
 // do Unix script and files  // do Unix script and files
 }  }
Line 463  else if (platformNode != 'win') { Line 1097  else if (platformNode != 'win') {
 }  }
 else {  // mac  else {  // mac
 // do Mac script and files  // do Mac script and files
}</PRE>}
<H4><A NAME="77090"></A> The install log</H4></pre>
<P>When you are testing your XPI or need a way  <!--INDEX installation:logs;logging installation --> to troubleshoot installation problems, one of the best methods is to consult  <!--INDEX install.log file --> the installation log file. This file is called <I>install.log</I> and lives in the <I>bin</I> directory.    <h4><a name="77090"></a> The install log</h4>
<P>The <I>install.log</I> file is generated the first time you try to install software in Mozilla and appended to for each subsequent installation. The format of the file-in which the URL and date of the installation appear as a heading-makes it easy to find the installation you are checking on in the install log.    <p>When you are testing your XPI or need a way 
<P><A HREF="#77048">Example 6-15</A> shows the output in <I>install.log</I> after a single successful installation.    <!--INDEX installation:logs;logging installation --> to
    troubleshoot installation problems, one of the best methods is
Example 6-15<A NAME="77048"></A>    to consult <!--INDEX install.log file --> the installation log
<I>install.log</I>    file. This file is called <i>install.log</i> and lives in the
<PRE> -------------------------------------------------------------------------------    <i>bin</i> directory.</p>
 <A HREF="http://books.mozdev.org/examples/xfly.xpi">http://books.mozdev.org/examples/xfly.xpi</A>  --  06/28/2002 19:12:59    <p>The <i>install.log</i> file is generated the first time you
     try to install software in Mozilla and appended to for each
     subsequent installation. The format of the file-in which the
     URL and date of the installation appear as a heading-makes it
     easy to find the installation you are checking on in the
     install log.</p>
     <p><a href="#77048">Example 6-15</a> shows the output in
     <i>install.log</i> after a single successful installation.
     Example 6-15<a name="77048"></a> <i>install.log</i></p>
 <pre>
  -------------------------------------------------------------------------------
  <a href=
 "http://books.mozdev.org/examples/xfly.xpi">http://books.mozdev.org/examples/xfly.xpi</a>  --  06/28/2002 19:12:59
  -------------------------------------------------------------------------------   -------------------------------------------------------------------------------
       Install xFly (version 0.0.1)        Install xFly (version 0.0.1)
       ------------        ------------
      </TD>[1/4]    Installing: C:\MOZILLA\BIN\chrome\xfly.jar      &lt;/td&gt;[1/4]    Installing: C:\MOZILLA\BIN\chrome\xfly.jar
       [2/4]    Register Content: jar:resource:/chrome/xfly.jar!/content/        [2/4]    Register Content: jar:resource:/chrome/xfly.jar!/content/
       [3/4]    Register Skin: jar:resource:/chrome/xfly.jar!/skin/        [3/4]    Register Skin: jar:resource:/chrome/xfly.jar!/skin/
       [4/4]    Register Locale: jar:resource:/chrome/xfly.jar!/locale/en-US/        [4/4]    Register Locale: jar:resource:/chrome/xfly.jar!/locale/en-US/
      Install completed successfully  --  06/28/2002 19:13:03</PRE>      Install completed successfully  --  06/28/2002 19:13:03
</pre>
<P>In your <I>install.js</I> file, you can use  <!--INDEX logComment( ) method;methods:logComment( ) --> the method <TT>logComment</TT> to create output other than these standard logging messages. This can be very useful for debugging your install scripts or providing extra feedback:    <p>In your <i>install.js</i> file, you can use 
<PRE>logComment( "Installation started ..." );</PRE>    <!--INDEX logComment( ) method;methods:logComment( ) --> the
<P>The output for this call will appear in <I>install.log</I> formatted like this:    method <tt>logComment</tt> to create output other than these
<PRE>** Installation started ...</PRE>    standard logging messages. This can be very useful for
<P>When installation is not smooth, Mozilla  <!--INDEX errors, installation and;installation:error codes --> outputs an error code to track down what is happening. For example, if you declare a constant variable twice in your install script, you will receive notification of an script error in the UI, and this error will be logged in <I>install.log</I>:    debugging your install scripts or providing extra feedback:</p>
<PRE>** Line: 4    redeclaration of const X_JAR_FILE<pre>
Install **FAILED** with error -229  --  07/01/2002 11:47:53</PRE>logComment( "Installation started ..." );
<P>A full list of error codes can be found at <I><A HREF="http://lxr.mozilla.org/seamonkey/source/xpinstall/src/nsInstall.h">http://lxr.mozilla.org/seamonkey/source/xpinstall/src/nsInstall.h</A></I> or in the <I>XPInstall API Reference</I> at <I><A HREF="http://developer.netscape.com/docs/manuals/xpinstall/err.html">http://developer.netscape.com/docs/manuals/xpinstall/err.html</A></I>.</pre>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    <p>The output for this call will appear in <i>install.log</i>
<P>Though XPInstall is enabled by default, there is preference to turn it on and off in the user profile preferences file (<I>prefs.js</I>). To disable XPInstall, set the preference like this:<P></BLOCKQUOTE>    formatted like this:</p>
user_pref("xpinstall.enabled", false);<pre>
<BLOCKQUOTE><P>And be aware that target installation platforms may have this preference turned off, which prevents you from installing any new software in Mozilla.<P></BLOCKQUOTE>** Installation started ...
<H3><A NAME="77091"></A> XPInstall</H3></pre>
<P>XPInstall is a technology used for  <!--INDEX XPInstall -->  <!--INDEX installation:(see also XPInstall)[installation:zz(see also XPInstall)] --> cross-platform installation. Mozilla uses it extensively to install new packages, but as a general-purpose technology, it can be used to install anything on your computer. The XPI file format we described in the section <A HREF="#77082">"The XPI File Format</A>" earlier in this chapter is the basic unit of exchange in an XPInstall and the installation script manages the installation.    <p>When installation is not smooth, Mozilla 
<P>Installation scripts-whether they appear within the XPI, on a web page as an external "trigger script," or elsewhere in JavaScript-use the XPInstall API to do all the heavy lifting. The XPInstall API includes installation functions (<A HREF="#77050">Example 6-16</A>) organized into such high-level objects as the <TT>Install</TT> object, the <TT>InstallTrigger</TT> object, and the <TT>File</TT> object, which you can use to install new Mozilla  <!--INDEX XPInstall:functions;functions:XPInstall --> packages.    <!--INDEX errors, installation and;installation:error codes -->
    outputs an error code to track down what is happening. For
Example 6-16<A NAME="77050"></A>    example, if you declare a constant variable twice in your
<I>Common XPInstall functions</I>    install script, you will receive notification of an script
<PRE> initInstall( )      // initializes every installation    error in the UI, and this error will be logged in
     <i>install.log</i>:</p>
 <pre>
 ** Line: 4    redeclaration of const X_JAR_FILE
 Install **FAILED** with error -229  --  07/01/2002 11:47:53
 </pre>
     <p>A full list of error codes can be found at <i><a href=
     "http://lxr.mozilla.org/seamonkey/source/xpinstall/src/nsInstall.h">
     http://lxr.mozilla.org/seamonkey/source/xpinstall/src/nsInstall.h</a></i>
     or in the <i>XPInstall API Reference</i> at <i><a href=
     "http://developer.netscape.com/docs/manuals/xpinstall/err.html">
     http://developer.netscape.com/docs/manuals/xpinstall/err.html</a></i>.</p>
     <blockquote>
       <div class="c17">
         NOTE
       </div>
       <p>Though XPInstall is enabled by default, there is
       preference to turn it on and off in the user profile
       preferences file (<i>prefs.js</i>). To disable XPInstall, set
       the preference like this:</p>
     </blockquote>
     user_pref("xpinstall.enabled", false); 
     <blockquote>
       <p>And be aware that target installation platforms may have
       this preference turned off, which prevents you from
       installing any new software in Mozilla.</p>
     </blockquote>
     <h3><a name="77091"></a> XPInstall</h3>
     <p>XPInstall is a technology used for <!--INDEX XPInstall --> 
     <!--INDEX installation:(see also XPInstall)[installation:zz(see also XPInstall)] -->
     cross-platform installation. Mozilla uses it extensively to
     install new packages, but as a general-purpose technology, it
     can be used to install anything on your computer. The XPI file
     format we described in the section <a href="#77082">"The XPI
     File Format</a>" earlier in this chapter is the basic unit of
     exchange in an XPInstall and the installation script manages
     the installation.</p>
     <p>Installation scripts-whether they appear within the XPI, on
     a web page as an external "trigger script," or elsewhere in
     JavaScript-use the XPInstall API to do all the heavy lifting.
     The XPInstall API includes installation functions (<a href=
     "#77050">Example 6-16</a>) organized into such high-level
     objects as the <tt>Install</tt> object, the
     <tt>InstallTrigger</tt> object, and the <tt>File</tt> object,
     which you can use to install new Mozilla 
     <!--INDEX XPInstall:functions;functions:XPInstall --> packages.
     Example 6-16<a name="77050"></a> <i>Common XPInstall
     functions</i></p>
 <pre>
  initInstall( )      // initializes every installation
  getFolder( )        // creates a new folder on the target system   getFolder( )        // creates a new folder on the target system
  addFile( )          // adds files and directories to the install   addFile( )          // adds files and directories to the install
  performInstall( )   // executes the installation   performInstall( )   // executes the installation
 cancelInstall( )    // cancels installation if there are errors</PRE> cancelInstall( )    // cancels installation if there are errors
</pre>
<P>In addition to the XPInstall API installation functions, installation scripts often call methods on the chrome registry itself. As described earlier in this chapter in the <A HREF="#77078">"The Chrome Registry</A>" section, the chrome registry handles the registration of new files and packages on the local system, the maintenance of user configurable data (such as what skin or theme you currently selected), and several utility functions used to make installations easier and more successful.    <p>In addition to the XPInstall API installation functions,
<H4><A NAME="77092"></A> The Install object</H4>    installation scripts often call methods on the chrome registry
<P>The <TT>Install</TT> object is the main object  <!--INDEX Install object, XPInstall;objects:Install (XPInstall);XPInstall:Install object --> in the XPInstall API. It provides most of the methods and properties used in installation scripts.    itself. As described earlier in this chapter in the <a href=
<PRE>initInstall(displayName, name, version, flags)</PRE>    "#77078">"The Chrome Registry</a>" section, the chrome registry
<P>The <TT>initInstall( )</TT> method that  <!--INDEX initInstall( ) method, XPInstall;XPInstall:iniInstall( ) method --> initializes the installation process takes the following parameters: <I>displayName</I> is the name you give to the installation itself; <I>name</I> is the name of the package to be installed (which must match the name given to the package in the manifests); <I>version</I> is the version of the package being installed (also specified in the manifest); and <I>flags</I> is an optional parameter reserved for future use (which is set to "0" by default and about which you don't have to worry).    handles the registration of new files and packages on the local
<PRE>Example: initInstall("Example Installation", "xfly", "0.9", 0);    system, the maintenance of user configurable data (such as what
addFile(file)</PRE>    skin or theme you currently selected), and several utility
<P>The <TT>addFile( )</TT> method adds a  <!--INDEX addFile( ) method, XPInstall;methods:addFile( ), XPInstall;XPInstall:addFile( ) method --> single file to the initialized installation. <TT>file</TT> is a pointer to the file in the XPI that will be installed.    functions used to make installations easier and more
<PRE>Example: addFile("simple.exe");    successful.</p>
err = performInstall( )</PRE>    <h4><a name="77092"></a> The Install object</h4>
<P>The <TT>performInstall( )</TT> method starts  <!--INDEX performInstall( ) method, XPInstall;XPInstall:performInstall( ) method;methods:XPInstall:performInstall( ) --> the installation that you set up.    <p>The <tt>Install</tt> object is the main object 
<PRE>Example: performInstall( );</PRE>    <!--INDEX Install object, XPInstall;objects:Install (XPInstall);XPInstall:Install object -->
<P>The <TT>Install</TT> object exposes the methods listed in <A HREF="#77016">Table 6-1</A>.    in the XPInstall API. It provides most of the methods and
    properties used in installation scripts.</p>
<P><I>Table 6-1: <A NAME="77016"></A></I><pre>
<I>Install object methods</I>initInstall(displayName, name, version, flags)
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Method</B></TD> <TD><B>  Description</B></TD></TR></pre>
<TR><TD> AddDirectory</TD>     <TD>  Unpacks an entire subdirectory.</TD></TR>    <p>The <tt>initInstall( )</tt> method that 
<TR><TD> AddFile</TD>     <TD>  Unpacks a single file.</TD></TR>    <!--INDEX initInstall( ) method, XPInstall;XPInstall:iniInstall( ) method -->
<TR><TD> Alert</TD>     <TD>  Displays an Alert dialog box with a message and an OK button.</TD></TR>    initializes the installation process takes the following
<TR><TD> CancelInstall</TD>     <TD>  Aborts the installation of the software.</TD></TR>    parameters: <i>displayName</i> is the name you give to the
<TR><TD> Confirm</TD>     <TD>  Displays a Confirm dialog box with the specified message and OK and Cancel buttons.</TD></TR>    installation itself; <i>name</i> is the name of the package to
<TR><TD> deleteRegisteredFile</TD>     <TD>  Deletes the specified file and its entry in the Client Version Registry.</TD></TR>    be installed (which must match the name given to the package in
<TR><TD> Execute</TD>     <TD>  Extracts a file from the XPI file to a temporary location and schedules it for later execution.</TD></TR>    the manifests); <i>version</i> is the version of the package
<TR><TD> Gestalt</TD>     <TD>  Retrieves information about the operating environment (Mac OS only).</TD></TR>    being installed (also specified in the manifest); and
<TR><TD> GetComponentFolder</TD>     <TD>  Returns an object representing the directory in which a component is installed.</TD></TR>    <i>flags</i> is an optional parameter reserved for future use
<TR><TD> GetFolder</TD>     <TD>  Returns an object representing a directory, for use with the </TD><TT>addFile</TT> method.</TR>    (which is set to "0" by default and about which you don't have
<TR><TD> GetLastError</TD>     <TD>  Returns the most recent nonzero error code.</TD></TR>    to worry).</p>
<TR><TD> getWinProfile</TD>     <TD>  Constructs an object for working with a Windows </TD><I>.ini</I> file.</TR><pre>
<TR><TD> getWinRegistry</TD>     <TD>  Constructs an object for working with the Windows registry.</TD></TR>Example: initInstall("Example Installation", "xfly", "0.9", 0);
<TR><TD> InitInstall</TD>     <TD>  Initializes installation for the given software and version.</TD></TR>addFile(file)
<TR><TD> LoadResources</TD>     <TD>  Returns an object whose properties are localized strings loaded from the specified property file.</TD></TR></pre>
<TR><TD> LogComment</TD>     <TD>  Adds a comment line to the install log.</TD></TR>    <p>The <tt>addFile( )</tt> method adds a 
<TR><TD> Patch</TD>     <TD>  Applies a set of differences between two versions.</TD></TR>    <!--INDEX addFile( ) method, XPInstall;methods:addFile( ), XPInstall;XPInstall:addFile( ) method -->
<TR><TD> PerformInstall</TD>     <TD>  Finalizes the installation of software.</TD></TR>    single file to the initialized installation. <tt>file</tt> is a
<TR><TD> RegisterChrome</TD>     <TD>  Registers chrome with the chrome registry.</TD></TR>    pointer to the file in the XPI that will be installed.</p>
<TR><TD> ResetError</TD>     <TD>  Resets a saved error code to zero.</TD></TR><pre>
<TR><TD> setPackageFolder</TD>     <TD>  Sets the default package folder that is saved with the root node.</TD></TR></TABLE><P>Example: addFile("simple.exe");
err = performInstall( )
<H4><A NAME="77093"></A> The InstallTrigger object</H4></pre>
<P>When you have very simple  <!--INDEX InstallTrigger object, XPInstall;XPInstall:InstallTrigger object --> installations-such as when you want to install a new skin-you may not need to use the services from the <TT>Install</TT> object. Besides providing the services necessary for "triggering" the downloading of a package from a web site, the <TT>InstallTrigger</TT> object offers some simple methods for installing when you do not need to rearrange of the disk, register complications, or do other install-type preparation (see <A HREF="#77018">Table 6-2</A>).    <p>The <tt>performInstall( )</tt> method starts 
    <!--INDEX performInstall( ) method, XPInstall;XPInstall:performInstall( ) method;methods:XPInstall:performInstall( ) -->
<P><I>Table 6-2: <A NAME="77018"></A></I>    the installation that you set up.</p>
<I>InstallTrigger interface showing the role of the InstallTrigger object in the overall installation process</I><pre>
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Method</B></TD>      <TD><B>  Description</B></TD></TR>Example: performInstall( );
<TR><TD> compareVersion</TD>    <TD>  Compares the version of a file or package with the version of an existing file or package.</TD></TR></pre>
<TR><TD> Enabled</TD>   <TD>  Indicates whether the Software Installation is enabled for this client machine.</TD></TR>    <p>The <tt>Install</tt> object exposes the methods listed in <a
<TR><TD> getVersionInfo</TD>    <TD>  Returns an </TD><TT>InstallVersion</TT> object representing the version number from the Client Version Registry for the specified software or component.</TR>    href="#77016">Table 6-1</a>.</p>
<TR><TD> Install</TD>     <TD>  Installs one or more XPI files on the local machine.</TD></TR>    <p><i>Table 6-1: <a name="77016"></a></i> <i>Install object
<TR><TD> installChrome</TD>     <TD>  Installs new skin or locale packages in Netscape 6 and Mozilla.</TD></TR>    methods</i></p>
<TR><TD> startSoftwareUpdate</TD>     <TD>  Initiates the download and installation of specified software. Note: deprecated in favor of install.</TD></TR></TABLE><P>    <tt>addFile</tt>method.<i>.ini</i>file.
    <table width="100%" border="1">
<P>This web page installation script defines its own <TT>install</TT> method in which a callback parameter on the <TT>InstallTrigger</TT>'s own <TT>install( )</TT> method checks the success of the installation and displays a relevant alert for the user (as shown in <A HREF="#77052">Example 6-17</A>).      <tr>
        <td><b>Method</b></td>
Example 6-17<A NAME="77052"></A>        <td><b>Description</b></td>
<I>Install script callback</I>      </tr>
<PRE> function doneFn (name, result)      <tr>
         <td>AddDirectory</td>
         <td>Unpacks an entire subdirectory.</td>
       </tr>
       <tr>
         <td>AddFile</td>
         <td>Unpacks a single file.</td>
       </tr>
       <tr>
         <td>Alert</td>
         <td>Displays an Alert dialog box with a message and an OK
         button.</td>
       </tr>
       <tr>
         <td>CancelInstall</td>
         <td>Aborts the installation of the software.</td>
       </tr>
       <tr>
         <td>Confirm</td>
         <td>Displays a Confirm dialog box with the specified
         message and OK and Cancel buttons.</td>
       </tr>
       <tr>
         <td>deleteRegisteredFile</td>
         <td>Deletes the specified file and its entry in the Client
         Version Registry.</td>
       </tr>
       <tr>
         <td>Execute</td>
         <td>Extracts a file from the XPI file to a temporary
         location and schedules it for later execution.</td>
       </tr>
       <tr>
         <td>Gestalt</td>
         <td>Retrieves information about the operating environment
         (Mac OS only).</td>
       </tr>
       <tr>
         <td>GetComponentFolder</td>
         <td>Returns an object representing the directory in which a
         component is installed.</td>
       </tr>
       <tr>
         <td>GetFolder</td>
         <td>Returns an object representing a directory, for use
         with the</td>
       </tr>
       <tr>
         <td>GetLastError</td>
         <td>Returns the most recent nonzero error code.</td>
       </tr>
       <tr>
         <td>getWinProfile</td>
         <td>Constructs an object for working with a Windows</td>
       </tr>
       <tr>
         <td>getWinRegistry</td>
         <td>Constructs an object for working with the Windows
         registry.</td>
       </tr>
       <tr>
         <td>InitInstall</td>
         <td>Initializes installation for the given software and
         version.</td>
       </tr>
       <tr>
         <td>LoadResources</td>
         <td>Returns an object whose properties are localized
         strings loaded from the specified property file.</td>
       </tr>
       <tr>
         <td>LogComment</td>
         <td>Adds a comment line to the install log.</td>
       </tr>
       <tr>
         <td>Patch</td>
         <td>Applies a set of differences between two versions.</td>
       </tr>
       <tr>
         <td>PerformInstall</td>
         <td>Finalizes the installation of software.</td>
       </tr>
       <tr>
         <td>RegisterChrome</td>
         <td>Registers chrome with the chrome registry.</td>
       </tr>
       <tr>
         <td>ResetError</td>
         <td>Resets a saved error code to zero.</td>
       </tr>
       <tr>
         <td>setPackageFolder</td>
         <td>Sets the default package folder that is saved with the
         root node.</td>
       </tr>
     </table>
     <h4><a name="77093"></a> The InstallTrigger object</h4>
     <p>When you have very simple 
     <!--INDEX InstallTrigger object, XPInstall;XPInstall:InstallTrigger object -->
     installations-such as when you want to install a new skin-you
     may not need to use the services from the <tt>Install</tt>
     object. Besides providing the services necessary for
     "triggering" the downloading of a package from a web site, the
     <tt>InstallTrigger</tt> object offers some simple methods for
     installing when you do not need to rearrange of the disk,
     register complications, or do other install-type preparation
     (see <a href="#77018">Table 6-2</a>).</p>
     <p><i>Table 6-2: <a name="77018"></a></i> <i>InstallTrigger
     interface showing the role of the InstallTrigger object in the
     overall installation process</i></p>
     <tt>InstallVersion</tt>object representing the version number
     from the Client Version Registry for the specified software or
     component.
     <table width="100%" border="1">
       <tr>
         <td><b>Method</b></td>
         <td><b>Description</b></td>
       </tr>
       <tr>
         <td>compareVersion</td>
         <td>Compares the version of a file or package with the
         version of an existing file or package.</td>
       </tr>
       <tr>
         <td>Enabled</td>
         <td>Indicates whether the Software Installation is enabled
         for this client machine.</td>
       </tr>
       <tr>
         <td>getVersionInfo</td>
         <td>Returns an</td>
       </tr>
       <tr>
         <td>Install</td>
         <td>Installs one or more XPI files on the local
         machine.</td>
       </tr>
       <tr>
         <td>installChrome</td>
         <td>Installs new skin or locale packages in Netscape 6 and
         Mozilla.</td>
       </tr>
       <tr>
         <td>startSoftwareUpdate</td>
         <td>Initiates the download and installation of specified
         software. Note: deprecated in favor of install.</td>
       </tr>
     </table>
     <p>This web page installation script defines its own
     <tt>install</tt> method in which a callback parameter on the
     <tt>InstallTrigger</tt>'s own <tt>install( )</tt> method checks
     the success of the installation and displays a relevant alert
     for the user (as shown in <a href="#77052">Example 6-17</a>).
     Example 6-17<a name="77052"></a> <i>Install script
     callback</i></p>
 <pre>
  function doneFn (name, result)
  {   {
     if (result != 0 &amp;&amp; result != 999)      if (result != 0 &amp;&amp; result != 999)
       alert("The install didn't seem to work, you could maybe try " +        alert("The install didn't seem to work, you could maybe try " +
Line 573  Example 6-17<A NAME="77052"></A> Line 1424  Example 6-17<A NAME="77052"></A>
  function install(packageName, fileName)   function install(packageName, fileName)
  {   {
     var xpi = new Object( );      var xpi = new Object( );
    xpi</TD>[packageName] = fileName;    xpi&lt;/td&gt;[packageName] = fileName;
     InstallTrigger.install(xpi, doneFn);      InstallTrigger.install(xpi, doneFn);
  }   }
 &lt;a href="javascript:install('xFly','xfly.xpi');"&gt;install&lt;/a&gt;</PRE> &lt;a href="javascript:install('xFly','xfly.xpi');"&gt;install&lt;/a&gt;
</pre>
<H4><A NAME="77094"></A> Installing non-Mozilla software</H4>    <h4><a name="77094"></a> Installing non-Mozilla software</h4>
<P>The XPInstall technology downloads  <!--INDEX installation:non-Mozilla software;software installation, non-Mozilla software --> and installs any software on any machine using Mozilla or Netscape 6/7. The same <TT>Install</TT> object methods that download, register, and install new Mozilla packages (e.g., new themes or new Mozilla applications like xFly) can be used to download other executables and software into any location on the local machine.    <p>The XPInstall technology downloads 
<P>As with Mozilla application installs, you use an installation script within a XPI to initialize the installation, add the files you want to the installation, and then perform the install and put the software in the designated locations. Note that non-Mozilla software installations do not include a registration step, since the chrome registry does not track non-Mozilla software or any more general additions to the operating system. <A HREF="#77054">Example 6-18</A> shows a simple and typical non-Mozilla installation.    <!--INDEX installation:non-Mozilla software;software installation, non-Mozilla software -->
    and installs any software on any machine using Mozilla or
Example 6-18<A NAME="77054"></A>    Netscape 6/7. The same <tt>Install</tt> object methods that
<I>Non-Mozilla software installation script</I>    download, register, and install new Mozilla packages (e.g., new
<PRE> var xpiSrc = "file.txt";    themes or new Mozilla applications like xFly) can be used to
     download other executables and software into any location on
     the local machine.</p>
     <p>As with Mozilla application installs, you use an
     installation script within a XPI to initialize the
     installation, add the files you want to the installation, and
     then perform the install and put the software in the designated
     locations. Note that non-Mozilla software installations do not
     include a registration step, since the chrome registry does not
     track non-Mozilla software or any more general additions to the
     operating system. <a href="#77054">Example 6-18</a> shows a
     simple and typical non-Mozilla installation. Example 6-18<a
     name="77054"></a> <i>Non-Mozilla software installation
     script</i></p>
 <pre>
  var xpiSrc = "file.txt";
  initInstall(   initInstall(
    "Adding A File",     "Adding A File",
    "testFile",     "testFile",
Line 598  Example 6-18<A NAME="77054"></A> Line 1464  Example 6-18<A NAME="77054"></A>
  if (0 == getLastError( ))   if (0 == getLastError( ))
      performInstall( );       performInstall( );
  else   else
     cancelInstall( );</PRE>     cancelInstall( );
</pre>
<P>Refer to the "XPInstall API Reference" on <I><A HREF="http://developer.netscape.com">http://developer.netscape.com</A></I> for more detailed information about the XPInstall API and how it can be used in more complex installations.    <p>Refer to the "XPInstall API Reference" on <i><a href=
<H3><A NAME="77095"></A> Uninstalling Applications</H3>    "http://developer.netscape.com">http://developer.netscape.com</a></i>
<P>You may have noticed an <TT>uninstall( )</TT>  <!--INDEX applications:installation:uninstalling;installation:applications:unstalling;unstalling applications -->  <!--INDEX uninstall( ) method, XPInstall;XPInstall:uninstall( ) methods;methods:XPInstall:uninstall( ) --> method on the <TT>Install</TT> object in the XPInstall API. This method does some of the work you need to do to uninstall packages from Mozilla, but it's a buggy process and doesn't finish the job.<A NAME="b279"></A><A HREF="#279">[*]</A> Beyond the physical removal of the package resources during the uninstall, several RDF files in the chrome registry need to be updated, and the XPInstall <TT>uninstall( )</TT> does not get to some of these files.    for more detailed information about the XPInstall API and how
<P>Fortunately, the JSLib JavaScript developer's library has a well-implemented uninstall function, which you can use by importing the <I>uninstall.js</I> file and calling uninstall on the package you want uninstalled. <I>uninstall.js</I> is one of the JS file collections that comprise the JSLib.    it can be used in more complex installations.</p>
<P>Once you install JSLib, using the uninstall method is simple:    <h3><a name="77095"></a> Uninstalling Applications</h3>
<PRE>include("chrome://jslib/install/uninstall.js");    <p>You may have noticed an <tt>uninstall( )</tt> 
     <!--INDEX applications:installation:uninstalling;installation:applications:unstalling;unstalling applications -->
     <!--INDEX uninstall( ) method, XPInstall;XPInstall:uninstall( ) methods;methods:XPInstall:uninstall( ) -->
     method on the <tt>Install</tt> object in the XPInstall API.
     This method does some of the work you need to do to uninstall
     packages from Mozilla, but it's a buggy process and doesn't
     finish the job.<a name="b279"></a><a href="#279">[*]</a> Beyond
     the physical removal of the package resources during the
     uninstall, several RDF files in the chrome registry need to be
     updated, and the XPInstall <tt>uninstall( )</tt> does not get
     to some of these files.</p>
     <p>Fortunately, the JSLib JavaScript developer's library has a
     well-implemented uninstall function, which you can use by
     importing the <i>uninstall.js</i> file and calling uninstall on
     the package you want uninstalled. <i>uninstall.js</i> is one of
     the JS file collections that comprise the JSLib.</p>
     <p>Once you install JSLib, using the uninstall method is
     simple:</p>
 <pre>
 include("chrome://jslib/install/uninstall.js");
 var p = new Uninstall('myPackageName');  var p = new Uninstall('myPackageName');
p.removePkg( );</PRE>p.removePkg( );
<P>You might want to put this uninstall routine in a function so you can reuse it.</pre>
<PRE>function unInstall(pkg) {    <p>You might want to put this uninstall routine in a function
     so you can reuse it.</p>
 <pre>
 function unInstall(pkg) {
 var p = new Uninstall(pkg);  var p = new Uninstall(pkg);
 p.removePkg( );  p.removePkg( );
}</PRE>}
<P>This method removes the resources themselves and deletes all references to the package in the chrome registry. The <TT>pkg</TT> parameter is the name of the package as defined in the manifest for that package. The xFly package manifest, for example, defines "xfly" as the name of the package, as shown in <A HREF="#77056">Example 6-19</A>.</pre>
    <p>This method removes the resources themselves and deletes all
Example 6-19<A NAME="77056"></A>    references to the package in the chrome registry. The
<I>Package metadata in the xFly manifest</I>    <tt>pkg</tt> parameter is the name of the package as defined in
<PRE> &lt;!-- xFly package information --&gt;    the manifest for that package. The xFly package manifest, for
     example, defines "xfly" as the name of the package, as shown in
     <a href="#77056">Example 6-19</a>. Example 6-19<a name=
     "77056"></a> <i>Package metadata in the xFly manifest</i></p>
 <pre>
  &lt;!-- xFly package information --&gt;
    &lt;RDF:Description about="urn:mozilla:package:xfly"     &lt;RDF:Description about="urn:mozilla:package:xfly"
          chrome:displayName="xFly"           chrome:displayName="xFly"
          chrome:author="frillies"           chrome:author="frillies"
          chrome:name="xfly"&gt;           chrome:name="xfly"&gt;
   &lt;/RDF:Description&gt;</PRE>   &lt;/RDF:Description&gt;
</pre>
<P><A HREF="#77036">Example 6-9</A> comes from the content package manifest for xFly, which is similar to the full content manifest for the XMLTerm application you saw in <A HREF="#77026">Example 6-4</A>.    <p><a href="#77036">Example 6-9</a> comes from the content
<P>To uninstall the xFly package,  <!--INDEX xFly package:uninstalling;packages:xFly:uninstalling --> then-as you should do to the working version you have as you develop before installing the final version-hook up a menuitem to call the uninstall routine:    package manifest for xFly, which is similar to the full content
<PRE>&lt;menuitem id="uninstall-item" label="Uninstall xFly" oncommand="unInstall("xfly")" /&gt;</PRE>    manifest for the XMLTerm application you saw in <a href=
<P>This menuitem should have access to a JavaScript file and contains the following code:    "#77026">Example 6-4</a>.</p>
<PRE>include("chrome://jslib/install/uninstall.js");    <p>To uninstall the xFly package, 
     <!--INDEX xFly package:uninstalling;packages:xFly:uninstalling -->
     then-as you should do to the working version you have as you
     develop before installing the final version-hook up a menuitem
     to call the uninstall routine:</p>
 <pre>
 &lt;menuitem id="uninstall-item" label="Uninstall xFly" oncommand="unInstall("xfly")" /&gt;
 </pre>
     <p>This menuitem should have access to a JavaScript file and
     contains the following code:</p>
 <pre>
 include("chrome://jslib/install/uninstall.js");
 function unInstall(pkg) {  function unInstall(pkg) {
 var p = new Uninstall(pkg);  var p = new Uninstall(pkg);
 p.removePkg( );  p.removePkg( );
}</PRE>}
<H2><A NAME="77096"></A> Finishing Things Up</H2></pre>
<P>We dealt with the xFly example earlier in this chapter and then discussed general information about file formats, installation scripts, and xpinstall. You now have everything you need to make the xFly package an installable application. Borrowing liberally from the examples in the earlier sections <A HREF="#77082">"The XPI File Format</A>" and <A HREF="#77085">"Installation Scripts</A>," you can bundle a JAR file or the entire subdirectory structure you already created for xFly in the <I>chrome</I> directory:    <h2><a name="77096"></a> Finishing Things Up</h2>
<PRE>chrome    <p>We dealt with the xFly example earlier in this chapter and
     then discussed general information about file formats,
     installation scripts, and xpinstall. You now have everything
     you need to make the xFly package an installable application.
     Borrowing liberally from the examples in the earlier sections
     <a href="#77082">"The XPI File Format</a>" and <a href=
     "#77085">"Installation Scripts</a>," you can bundle a JAR file
     or the entire subdirectory structure you already created for
     xFly in the <i>chrome</i> directory:</p>
 <pre>
 chrome
 xfly      content  xfly      content
 skin  skin
locale</PRE>locale
<P>Bundle the JAR file into a ZIP file, add an installation script to that ZIP file (and a web trigger script to the application's web page), and make your application available to Mozilla users everywhere.</pre>
<H3><A NAME="77097"></A> Creating the xFly XPI</H3>    <p>Bundle the JAR file into a ZIP file, add an installation
<P>An XPI file is nothing more  <!--INDEX xFly API:creating --> than a ZIP file with its own installation script. Using a ZIP utility, you can archive the <I>xfly</I> directory and preserve the subdirectory structure so it's installed in the user's <I>chrome</I> directory as it is in your own. Make sure that the ZIP file, whatever it's called, contains the top-level <I>xfly</I> subdirectory as part of this structure. If it is a JAR file you are distributing for your package, make the JAR file (<I>xfly.jar</I>) the top level, with the <I>content</I>, <I>skin</I>, and <I>locale</I> directories contained within:    script to that ZIP file (and a web trigger script to the
<PRE>xfly.jar    application's web page), and make your application available to
     Mozilla users everywhere.</p>
     <h3><a name="77097"></a> Creating the xFly XPI</h3>
     <p>An XPI file is nothing more <!--INDEX xFly API:creating -->
     than a ZIP file with its own installation script. Using a ZIP
     utility, you can archive the <i>xfly</i> directory and preserve
     the subdirectory structure so it's installed in the user's
     <i>chrome</i> directory as it is in your own. Make sure that
     the ZIP file, whatever it's called, contains the top-level
     <i>xfly</i> subdirectory as part of this structure. If it is a
     JAR file you are distributing for your package, make the JAR
     file (<i>xfly.jar</i>) the top level, with the <i>content</i>,
     <i>skin</i>, and <i>locale</i> directories contained
     within:</p>
 <pre>
 xfly.jar
 content  content
 skin  skin
locale</PRE>locale
<P>The URLs you used to refer to various parts of your xFly application (e.g., <I>chrome://xfly/content/xfly.js</I> as part of the command that imports the external script file into the main XUL file) will be registered during the installation process with that <I>xfly</I> directory or JAR file directly underneath the Mozilla <I>chrome</I> directory.</pre>
<H3><A NAME="77098"></A> Adding the Installation Script</H3>    <p>The URLs you used to refer to various parts of your xFly
<P>Once you understand the <A HREF="#77085">"Installation Scripts</A>" section (earlier in this chapter), creating an installation script for  <!--INDEX installation scripts:xFly API;xFly API:installation scripts;scripts:installation scripts:xFly API --> the xFly application is straightforward, as <A HREF="#77058">Example 6-20</A> shows. In this case, we bundled all the xFly subdirectories in a single JAR file, <I>xfly.jar</I>.    application (e.g., <i>chrome://xfly/content/xfly.js</i> as part
    of the command that imports the external script file into the
Example 6-20<A NAME="77058"></A>    main XUL file) will be registered during the installation
<I>xFly installation script</I>    process with that <i>xfly</i> directory or JAR file directly
<PRE> const X_MSG             = "Install xFly";    underneath the Mozilla <i>chrome</i> directory.</p>
     <h3><a name="77098"></a> Adding the Installation Script</h3>
     <p>Once you understand the <a href="#77085">"Installation
     Scripts</a>" section (earlier in this chapter), creating an
     installation script for 
     <!--INDEX installation scripts:xFly API;xFly API:installation scripts;scripts:installation scripts:xFly API -->
     the xFly application is straightforward, as <a href=
     "#77058">Example 6-20</a> shows. In this case, we bundled all
     the xFly subdirectories in a single JAR file, <i>xfly.jar</i>.
     Example 6-20<a name="77058"></a> <i>xFly installation
     script</i></p>
 <pre>
  const X_MSG             = "Install xFly";
  const X_NAME            = "xFly";   const X_NAME            = "xFly";
  const X_VER             = "0.0.1";   const X_VER             = "0.0.1";
  const X_JAR_FILE        = "xfly.jar";   const X_JAR_FILE        = "xfly.jar";
Line 674  Example 6-20<A NAME="77058"></A> Line 1615  Example 6-20<A NAME="77058"></A>
  }   }
  else  {                       // otherwise   else  {                       // otherwise
    cancelInstall( );            // cancel the installation.     cancelInstall( );            // cancel the installation.
 }</PRE> }
</pre>
<P>Save the installation code in <A HREF="#77058">Example 6-20</A> as <I>install.js</I> and add it to the ZIP file you created out of the <I>xfly</I> subdirectory. Name this zip file <I>xfly.xpi</I>. The installation script should be archived at the top level of the XPI file and appear next to the <I>xfly</I> subdirectory or JAR file. Another feature of this script is the declaration of constant variables at the top, for various values used in the script. This feature is good for re-use and organizing your script.    <p>Save the installation code in <a href="#77058">Example
<H3><A NAME="77099"></A> Web Page Installer</H3>    6-20</a> as <i>install.js</i> and add it to the ZIP file you
<P>The XPI file you created  <!--INDEX installation:web page installer;web page installer;XPInstall:web page installer --> in the last two sections, with its internal <I>install.js</I> file, is all you need to make your Mozilla application portable and installable. The final step creates a link on a regular web page that tells Mozilla where this file is, as shown in <A HREF="#77060">Example 6-21</A>.    created out of the <i>xfly</i> subdirectory. Name this zip file
    <i>xfly.xpi</i>. The installation script should be archived at
Example 6-21<A NAME="77060"></A>    the top level of the XPI file and appear next to the
<I>Web page trigger</I>    <i>xfly</i> subdirectory or JAR file. Another feature of this
<PRE> &lt;a href="#"    script is the declaration of constant variables at the top, for
     various values used in the script. This feature is good for
     re-use and organizing your script.</p>
     <h3><a name="77099"></a> Web Page Installer</h3>
     <p>The XPI file you created 
     <!--INDEX installation:web page installer;web page installer;XPInstall:web page installer -->
     in the last two sections, with its internal <i>install.js</i>
     file, is all you need to make your Mozilla application portable
     and installable. The final step creates a link on a regular web
     page that tells Mozilla where this file is, as shown in <a
     href="#77060">Example 6-21</a>. Example 6-21<a name=
     "77060"></a> <i>Web page trigger</i></p>
 <pre>
  &lt;a href="#"
     onclick="InstallTrigger.install(      onclick="InstallTrigger.install(
     {`xfly' :      {`xfly' :
     'xfly.xpi'});"&gt;      'xfly.xpi'});"&gt;
    Install my cool xFly Application&lt;/a&gt;</PRE>    Install my cool xFly Application&lt;/a&gt;
</pre>
<P>When the user browses the application web page and clicks the "Install my cool xFly Application" link shown above, Mozilla finds and downloads <I>xfly.xpi</I> in the same directory. It then opens the archive, reads the install script, creates the <I>xfly</I> subdirectory on the local machine or moves the JAR file onto the local machine, and registers it with the chrome registry. When the user restarts the browser, the xFly application is integrated into Mozilla and ready for use. The user can access it with any overlays that put it into the browser's interface (e.g., as an item in the Tools menu) or invoke it directly by using the special chrome option for pointing to a registered chrome:    <p>When the user browses the application web page and clicks
<PRE>mozilla -chrome chrome://xfly/content</PRE>    the "Install my cool xFly Application" link shown above,
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    Mozilla finds and downloads <i>xfly.xpi</i> in the same
<P>You don't need to have an install page to install a XPI in Mozilla. If, instead of a web page, you provide a URL that points directly to a XPI, Mozilla displays a dialog that asks the user whether they want to initiate the installation of that XPI. As with any new software installation, however, a page that describes the package and what it does can help allay fears and promote use.<P></BLOCKQUOTE>    directory. It then opens the archive, reads the install script,
<H2><A NAME="77100"></A> Extra Tricks for Customizing an Application</H2>    creates the <i>xfly</i> subdirectory on the local machine or
<P>If the Mozilla application  <!--INDEX applications:customizing;customizing applications --> you are working on is more autonomous than a     moves the JAR file onto the local machine, and registers it
package that sits up on a Mozilla installation, you may want to add extra customization. Here are two common features: the program icon and the splash screen. Some features require that you build the source code yourself, even just a particular module instead of the whole tree. Refer to <A HREF="appa.html#90096">Appendix A</A> for more details on obtaining and building the source code.    with the chrome registry. When the user restarts the browser,
<H3><A NAME="77101"></A> Icons</H3>    the xFly application is integrated into Mozilla and ready for
<P>Program icons are important  <!--INDEX icons, application customization;applications:customizing:icons --> for several reasons. Primarily, however, they are a visual representation of your application on the system that it runs on, whether it runs in a file explorer, a taskbar, or an application selector. This section tells you where to locate the current icons in the Mozilla application and what files or resources need to be changed to make your icon the default for Mozilla.    use. The user can access it with any overlays that put it into
<H4><A NAME="77102"></A> Windows</H4>    the browser's interface (e.g., as an item in the Tools menu) or
<P>In Windows, create your own icon  <!--INDEX icons, application customization:Windows;applications:customizing:icons;Windows:icons --> and then follow these steps:    invoke it directly by using the special chrome option for
<OL><P><LI>Go to the <I>mozilla/xpfe/bootstrap</I> folder in the source tree.<P>    pointing to a registered chrome:</p>
<P><LI>Open the <I>splash.rc</I> resource file. This can be done in the text editor of your choice or in any program with special handling for Windows resource files.<P><pre>
<P><LI>Change the icon resource to the file of your choice.<P></OL>mozilla -chrome chrome://xfly/content
// Program icon.</pre>
IDI_APPLICATION ICON    <blockquote>
"mozdev.ico"      <div class="c17">
<OL><P><LI>Recompile the bootstrap module. This recompilation regenerates the <I>mozilla.exe</I> executable file.<P></OL>        NOTE
C:\mozilla\src&gt;cd mozilla\xpfe\bootstrap      </div>
C:\mozilla\src\mozilla\xpfe\bootstrap&gt;nmake -f makefile.win      <p>You don't need to have an install page to install a XPI in
<P>An alternative to Steps 2 and 3 is to give your icon the same name as the Mozilla icon (<I>mozilla.ico</I>) and just drop it into the tree, replacing the existing one shown in <A HREF="#77012">Figure 6-6</A>.      Mozilla. If, instead of a web page, you provide a URL that
<P><CENTER><IMG SRC="foo.gif"></CENTER>      points directly to a XPI, Mozilla displays a dialog that asks
<P><I>Figure 6-6: <A NAME="77012"></A></I>      the user whether they want to initiate the installation of
<I>Windows taskbar with Mozilla icon</I>      that XPI. As with any new software installation, however, a
      page that describes the package and what it does can help
<H4><A NAME="77103"></A> Unix</H4>      allay fears and promote use.</p>
<P>X Windows uses the  <!--INDEX icons, application customization:Unix;applications:customizing:icons;Unix:icons --> common X Pixmap (XPM) format for icons. XPM files are C source code files, with each pixmap defined as a static character array. The window manager expects to find two XPM files for each icon specified in the configuration files as <I>ICON</I>. Mozilla has two files for icons located in <I>mozilla/src/gtk</I>: <I>mozicon16.xpm</I> and <I>mozicon50.xpm</I>. Many utilities, such as the GIMP, PaintShopPro, and Xview, can transform images from other common formats.    </blockquote>
<H4><A NAME="77104"></A> Macintosh</H4>    <h2><a name="77100"></a> Extra Tricks for Customizing an
<P>The Macintosh BNDL  <!--INDEX icons, application customization:Macintosh;applications:customizing:icons;Macintosh:icons --> resource (OS icons for files and applications) and related resource types (4bit, 8bit, large, small icons, masks, and FREF) are contained in <I>nsMacBundle.rsrc,</I> located at <I>mozilla/xpfe/bootstrap</I>. It also contains a <TT>MOZZ</TT> resource that references the Mozilla software license. All Macintosh software have this set of resources.    Application</h2>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    <p>If the Mozilla application 
<P>If you want to change icons on a window-by-window basis, do it only in Mozilla on the Windows platform. In the chrome root, there exists a directory <I>\icons\default\</I>. Within this directory, you can place any number of icons for windows in your application. The filename has to be the same as the XUL window ID: <TT>&lt;window_id&gt;.ico</TT>. One example of an icon being used in this way is the DOM Inspector window in Mozilla. In the <I>\icons\default\</I> directory you will find the file <I>winInspectorMain.ico</I> on Windows. This option is good for package authors who add windows to the Mozilla application and do not want to hijack this resource completely. Icons can be installed as part of an XPI.<P></BLOCKQUOTE>    <!--INDEX applications:customizing;customizing applications -->
<H3><A NAME="77105"></A> Splash Screen</H3>    you are working on is more autonomous than a package that sits
<P>Are splash screens a  <!--INDEX splash screen, application customization;applications:customizing:splash screen --> necessary startup feature for a program or a shameless plug? The answer is probably somewhere in between, leaning toward the necessary in the case of Mozilla (<A HREF="#77014">Figure 6-7</A> shows Mozilla's splash screen).    up on a Mozilla installation, you may want to add extra
<P><CENTER><IMG SRC="foo.gif"></CENTER>    customization. Here are two common features: the program icon
<P><I>Figure 6-7: <A NAME="77014"></A></I>    and the splash screen. Some features require that you build the
<I>Mozilla's splash screen</I>    source code yourself, even just a particular module instead of
    the whole tree. Refer to <a href="appa.html#90096">Appendix
<P>Because Mozilla is a large application and needs to process so much (including profiles, initialization code, and theme/locale selection from the chrome registry) before you actually see the first window appear, users need a visual clue that something is happening when Mozilla starts up.    A</a> for more details on obtaining and building the source
<P>If your application also requires a lot of processing at startup or if you would like to customize your application, then creating and using your own unique splash screen is essential.    code.</p>
<H4><A NAME="77106"></A> Windows</H4>    <h3><a name="77101"></a> Icons</h3>
<P>The splash screen file  <!--INDEX splash screen, application customization:Windows;applications:customizing:splash screen;Windows:splash screen --> is a bitmap image that also lives in the same <I>splash.rc</I> file that houses the icon file, perhaps more appropriately named in this case.    <p>Program icons are important 
<PRE>// Splash screen bitmap.    <!--INDEX icons, application customization;applications:customizing:icons -->
     for several reasons. Primarily, however, they are a visual
     representation of your application on the system that it runs
     on, whether it runs in a file explorer, a taskbar, or an
     application selector. This section tells you where to locate
     the current icons in the Mozilla application and what files or
     resources need to be changed to make your icon the default for
     Mozilla.</p>
     <h4><a name="77102"></a> Windows</h4>
     <p>In Windows, create your own icon 
     <!--INDEX icons, application customization:Windows;applications:customizing:icons;Windows:icons -->
     and then follow these steps:</p>
     <ol>
       <li>Go to the <i>mozilla/xpfe/bootstrap</i> folder in the
       source tree.</li>
       <li>Open the <i>splash.rc</i> resource file. This can be done
       in the text editor of your choice or in any program with
       special handling for Windows resource files.</li>
       <li>Change the icon resource to the file of your choice.</li>
     </ol>
     // Program icon. IDI_APPLICATION ICON "mozdev.ico" 
     <ol>
       <li>Recompile the bootstrap module. This recompilation
       regenerates the <i>mozilla.exe</i> executable file.</li>
     </ol>
     C:\mozilla\src&gt;cd mozilla\xpfe\bootstrap
     C:\mozilla\src\mozilla\xpfe\bootstrap&gt;nmake -f makefile.win 
     <p>An alternative to Steps 2 and 3 is to give your icon the
     same name as the Mozilla icon (<i>mozilla.ico</i>) and just
     drop it into the tree, replacing the existing one shown in <a
     href="#77012">Figure 6-6</a>.</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-6: <a name="77012"></a></i> <i>Windows taskbar
     with Mozilla icon</i></p>
     <h4><a name="77103"></a> Unix</h4>
     <p>X Windows uses the 
     <!--INDEX icons, application customization:Unix;applications:customizing:icons;Unix:icons -->
     common X Pixmap (XPM) format for icons. XPM files are C source
     code files, with each pixmap defined as a static character
     array. The window manager expects to find two XPM files for
     each icon specified in the configuration files as <i>ICON</i>.
     Mozilla has two files for icons located in
     <i>mozilla/src/gtk</i>: <i>mozicon16.xpm</i> and
     <i>mozicon50.xpm</i>. Many utilities, such as the GIMP,
     PaintShopPro, and Xview, can transform images from other common
     formats.</p>
     <h4><a name="77104"></a> Macintosh</h4>
     <p>The Macintosh BNDL 
     <!--INDEX icons, application customization:Macintosh;applications:customizing:icons;Macintosh:icons -->
     resource (OS icons for files and applications) and related
     resource types (4bit, 8bit, large, small icons, masks, and
     FREF) are contained in <i>nsMacBundle.rsrc,</i> located at
     <i>mozilla/xpfe/bootstrap</i>. It also contains a <tt>MOZZ</tt>
     resource that references the Mozilla software license. All
     Macintosh software have this set of resources.</p>
     <blockquote>
       <div class="c17">
         NOTE
       </div>
       <p>If you want to change icons on a window-by-window basis,
       do it only in Mozilla on the Windows platform. In the chrome
       root, there exists a directory <i>\icons\default\</i>. Within
       this directory, you can place any number of icons for windows
       in your application. The filename has to be the same as the
       XUL window ID: <tt>&lt;window_id&gt;.ico</tt>. One example of
       an icon being used in this way is the DOM Inspector window in
       Mozilla. In the <i>\icons\default\</i> directory you will
       find the file <i>winInspectorMain.ico</i> on Windows. This
       option is good for package authors who add windows to the
       Mozilla application and do not want to hijack this resource
       completely. Icons can be installed as part of an XPI.</p>
     </blockquote>
     <h3><a name="77105"></a> Splash Screen</h3>
     <p>Are splash screens a 
     <!--INDEX splash screen, application customization;applications:customizing:splash screen -->
     necessary startup feature for a program or a shameless plug?
     The answer is probably somewhere in between, leaning toward the
     necessary in the case of Mozilla (<a href="#77014">Figure
     6-7</a> shows Mozilla's splash screen).</p>
     <div class="c16">
       <img src="foo.gif">
     </div>
     <p><i>Figure 6-7: <a name="77014"></a></i> <i>Mozilla's splash
     screen</i></p>
     <p>Because Mozilla is a large application and needs to process
     so much (including profiles, initialization code, and
     theme/locale selection from the chrome registry) before you
     actually see the first window appear, users need a visual clue
     that something is happening when Mozilla starts up.</p>
     <p>If your application also requires a lot of processing at
     startup or if you would like to customize your application,
     then creating and using your own unique splash screen is
     essential.</p>
     <h4><a name="77106"></a> Windows</h4>
     <p>The splash screen file 
     <!--INDEX splash screen, application customization:Windows;applications:customizing:splash screen;Windows:splash screen -->
     is a bitmap image that also lives in the same <i>splash.rc</i>
     file that houses the icon file, perhaps more appropriately
     named in this case.</p>
 <pre>
 // Splash screen bitmap.
 IDB_SPLASH BITMAP  IDB_SPLASH BITMAP
"splash.bmp"</PRE>"splash.bmp"
<P>Again, you have the option of changing the resource file or calling the image file the same name as the Mozilla splash (<I>splash.bmp</I>) and dropping it into the tree. Both of options require recompilation of the bootstrap module.</pre>
<H4><A NAME="77107"></A> Unix</H4>    <p>Again, you have the option of changing the resource file or
<P>The splash screen uses  <!--INDEX splash screen, application customization:Unix;applications:customizing:splash screen;Unix:splash screen --> the same XPM format as is used for the icons. The file is called <I>splash.xpm</I> and is located in <I>mozilla/xpfe/bootstrap</I>. Note that the splash display is turned off by default on this platform and can be displayed by using the <TT>-splash</TT> switch in a command shell.    calling the image file the same name as the Mozilla splash
<PRE>/mozilla -splash</PRE>    (<i>splash.bmp</i>) and dropping it into the tree. Both of
<H4><A NAME="77108"></A> Macintosh</H4>    options require recompilation of the bootstrap module.</p>
<P>The file <I>Splash.rsrc</I> (located  <!--INDEX splash screen, application customization:Macintosh;applications:customizing:splash screen;Macintosh:splash screen --> in the source tree at <I>mozilla/xpfe/bootstrap</I>) contains Macintosh resources to display the splash screen (native DLOG, DITL, PICT) during startup while the shared libraries are loaded and before the profile manager is shown.    <h4><a name="77107"></a> Unix</h4>
<HR>    <p>The splash screen uses 
<HR><A NAME="279"></A><A HREF="#b279">[Back]</A>    <!--INDEX splash screen, application customization:Unix;applications:customizing:splash screen;Unix:splash screen -->
<A NAME="77062"></A>    the same XPM format as is used for the icons. The file is
Currently, some open bugs in Bugzilla are tracking    called <i>splash.xpm</i> and is located in
the progress of this method and its improvement.    <i>mozilla/xpfe/bootstrap</i>. Note that the splash display is
<HR><BR><BR>    turned off by default on this platform and can be displayed by
File a <a href="http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a> for chapter 6.    using the <tt>-splash</tt> switch in a command shell.</p>
<!-- ?php require(NOTES); ? --><pre>
<?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch06'; require(NOTES); ?>/mozilla -splash
</BODY></pre>
</HTML>    <h4><a name="77108"></a> Macintosh</h4>
     <p>The file <i>Splash.rsrc</i> (located 
     <!--INDEX splash screen, application customization:Macintosh;applications:customizing:splash screen;Macintosh:splash screen -->
     in the source tree at <i>mozilla/xpfe/bootstrap</i>) contains
     Macintosh resources to display the splash screen (native DLOG,
     DITL, PICT) during startup while the shared libraries are
     loaded and before the profile manager is shown.</p>
     <hr>
     <hr>
     <a name="279"></a><a href="#b279">[Back]</a> <a name=
     "77062"></a> Currently, some open bugs in Bugzilla are tracking
     the progress of this method and its improvement. 
     <hr>
     <br>
     <br>
     File a <a href=
     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
     for chapter 6. <!-- ?php require(NOTES); ? -->
     <?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch06'; require(NOTES); ?>

Removed from v.1.7  
changed lines
  Added in v.1.8


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>