Contents

A New Package

Meet your first XUL application

The Package System

A package is loosely defined as a set of resources of a given type that make up a XUL application. It can also be used to refer to the collection of packages that form a XUL app. (I think. The truth is it's an antiquated term that I probably shouldn't be using here. But for out purposes it means what I just said it means.) The three types of packages currently defined and used are content, skin, and locale.

The content package--containing XUL files, javascript files, image files, etc--forms the basis of any XUL app. This is where all the program functions and user interface are defined.

The skin package contains style information for the app; it is separate for the content so that different skin packages can be defined for a given content package, which is how skinning functionality works.

The locale package contains all the localizable text strings in the entire app. This makes it very easy to create different language packs for an application, which the user can switch to and from at will. All three types of package combine to form what we would call a XUL Application.

In this section we are going to setup a content and a locale package for XulNote. The skin package is more complicated, and will be dealt with at a late time.

Package Directories

Before we write the files that will form the beginning of the XulNote app, we first need to create the directories in which those files will go. (And while we're at it, we're going to create the directories for the locale package, so we don't have to do this all again later.)

Go into your mozilla chrome directory (i.e., the directory called chrome that is a subdirectory of the directory in which your mozilla executable lives) and create a subdirectory called xulnote. Inside of that create two new directories called content and locale. Inside of the content directory create a subdirectory called xulnote. Inside of the locale directory create a directory called en-US with a subdirectory called xulnote.

In other words, create a directory structure that looks like this:
An image of the directory structure described above

Throughout the remainder of this tutorial I will referrer to the content/xulnote directory as the content directory and the locale/en-US/xulnote directory as the locale directory. While this may seem like a stupid thing to do, it will prevent me from having to referr to "the xulnote directory which is a subdirectory of content, not to be confused with the xulnote directory that is a subdirectory of the chrome directory or the xulote directory that is a subdirectory of locale/en-Us or any other directories named xulnote that happen to be on your hard drive" over and over again. Trust me. That would be way more confusing.

Content Package

Well, this is it: time to create your very first XUL file. Go into your content directory, and create a file called xulnote.xul, with the following code inside.

Example 3.3.1
Main XUL File
<?xml version="1.0"?>
<?xml-stylesheet href="xulnote.css" type="text/css"?>

<!DOCTYPE window [
<!ENTITY % xulnoteDTD SYSTEM "chrome://xulnote/locale/xulnote.dtd">
%xulnoteDTD;
]>

<window
   title      = "&window.title;"
   id         = "xulnote-main-window"
   xmlns      = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   width      = "640"
   height     = "480"
   orient     = "vertical"
   persist    = "screenX screenY width height sizemode">

<script type="application/x-javascript" src="xulnote.js"/>

<commandset id="maincommands">
  <command id="menu-file-close:command" oncommand="closeWindow();"/>
</commandset>

<keyset id="mainkeys">
  <key
     id        =  "menu-file-close:key"
     key       = "&menu-file-close:key;"
     observes  =  "menu-file-close:command"
     modifiers =  "accel" />
</keyset>

<toolbox id="main-toolbox">
  <menubar id="menu">
    <menu id="menu-file" label="&menu-file:label;" accesskey="&menu-file:accesskey;">
      <menupopup id="menu-file-popup">
        <menuitem
           id        =  "menu-file-close"
           key       =  "menu-file-close:key"
           label     = "&menu-file-close:label;"
           command   =  "menu-file-close:command"
           accesskey = "&menu-file-close:accesskey;"/>
      </menupopup>
    </menu>
  </menubar>
</toolbox>


<textbox id="document" multiline="true" flex="1"/>

</window>

This is the code that defines the main (and only) window in the XulNote application. I won't go into too much detail about what exactly everything does (most of it is pretty straight forward) but one thing you should note is that there are no text strings in the file. All the labels and titles are in the &entity-reference; format. These text strings will be defined in the xulnote.dtd file that we will create in a few minutes.

The next file we need to create for the content section of xulnote is the script file, xulnote.js. If you'll look at the main xul file, you'll notice that there is only one javascript function defined in the file, the closeWindow() function that is called when someone clicks on the File->Close menuitem. Thus the script file, which will be called xulnote.js, need only contain one function, which should look like this:

Example 3.3.2
Main JavaScript File
function closeWindow()
{
  window.close();
}

This file will be the most complex file in the entire app by the time we are finished, but like any great think, it starts off small. (We'll start adding real functionality to XulNote in the next section.)

Finally, we need to create the content manifest file to add the XulNote application to the mozilla chrome registry. To do that, make a file called contents.rdf, with the following code inside:

Example 3.3.3
Content Manifest File
<?xml version="1.0"?>

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

  <RDF:Seq about="urn:mozilla:package:root">
    <RDF:li resource="urn:mozilla:package:xulnote"/>
  </RDF:Seq>

  <RDF:Description about="urn:mozilla:package:xulnote"
        chrome:displayName="XulNote Text Editor"
        chrome:author="Your Name Here"
        chrome:name="xulnote">
  </RDF:Description>

</RDF:RDF>

Skin Package

As I mentioned earlier, making a skin package for a new XUL application is a little bit trickier than the other two. Therefore, we will put that off until a later date. For now we will just make a xulnote.css file in the content directory, with the following static styles inside:

Example 3.4.1
Main Stylesheet File
@import url("chrome://communicator/skin/");

#document
{
  font-size: 10pt;
}

The first line of code in the file imports the main communicator styles, so that our menus and dialogs will look like whatever communicator skin is currently being used. The rest of the file sets the font size in our editor to ten points. (That style really wasn't necessary, I just didn't want to add a css file without any styles in it.)

Locale Package

Now its time to define all those text strings we referenced back in xulnote.xul. For this tutorial we will make our main localization be US English, since that's the only language I speak (except for Latin, which I don't think there is a mozilla translation for.)

Now, go into your locale directory, and create a file called xulnote.dtd, with the following code inside:

Example 3.5.1
Main Locale File
<!ENTITY window.title               "XulNote">

<!ENTITY menu-file:label              "File">
<!ENTITY menu-file:accesskey           "F">
<!ENTITY menu-file-close:key           "W">
<!ENTITY menu-file-close:label         "Close">
<!ENTITY menu-file-close:accesskey     "C">

Now, last (and probably least) we need to register the locale so that mozilla knows about it. Create in your locale directory another file called contents.rdf, and put the following code inside:

Example 3.5.2
Locale Manifest File
<?xml version="1.0"?>

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

  <RDF:Seq about="urn:mozilla:locale:root">
    <RDF:li resource="urn:mozilla:locale:en-US"/>
  </RDF:Seq>

  <RDF:Description about="urn:mozilla:locale:en-US">
    <chrome:packages>
      <RDF:Seq about="urn:mozilla:locale:en-US:packages">
        <RDF:li resource="urn:mozilla:locale:en-US:xulnote"/>
      </RDF:Seq>
    </chrome:packages>
  </RDF:Description>

</RDF:RDF>

Package Registration

Your application is now complete! The only thing that remains is to register it with the chrome registry. We'll learn how to use the XPInstall engine later, but for now the best way to do this is to manually edit the mozilla chrome list file. Do to that, find the file called installed-chrome.txt in the mozilla chrome directory, and add the following code to the end of the file (be sure there is a hard return after the last line, especially if you're using windows):

content,install,url,resource:/chrome/xulnote/content/xulnote/
locale,install,url,resource:/chrome/xulnote/locale/en-US/xulnote/

And that's it, we're finished. If you did everything correctly you should now have a xulnote directory that looks something like the image to the right of this paragraph.

If your application does not work correctly, there are a number of things to do. First, make sure you are using the correct mozilla build. This code should work without problems in Mozilla 1.0 through Mozilla 1.2. If you are using mozilla 0.9.8, or mozilla 1.5 (at some future date) there is a good chance some of this code won't work. If you are using the correct mozilla build and are still seeing problems, make sure you copied the code over correctly. Try using the zip archives to if you're not sure.

If you do all that and still can't get it to work, you can always email me and I'll do my best to figure out what's going on.

To see your new XUL Application, launch mozilla with the following command line:
mozilla -chrome chrome://xulnote/content

I have a zip archive for this section here. Note that you will still have to add the installed-chrome.txt lines yourself, since that can't be included in the zip.

Contents

Copyright © 2002 XulPlanet.com