# XML - Managing Data Exchange/XUL

+-----------------------------------------------+
| **Learning objectives**                       |
|                                               |
| -   Get a brief overview of what XUL is.      |
| -   Learn about the basic tag/widget library. |
| -   Create some simple, static XUL web pages. |
| -   Add event handlers to a XUL page.         |
+-----------------------------------------------+
|                                               |
+-----------------------------------------------+

## Introduction

XUL (pronounced zool and rhymes with cool), which stands for eXtensible
User interface Language, is an XML-based user interface language
originally developed for use in the Netscape browser. It is now
maintained by Mozilla. It is a part of Mozilla Firefox and many other
Mozilla applications, and is available as part of Gecko, the rendering
engine developed by Mozilla. In fact, XUL is powerful enough that the
entire user interface in the Firefox application is implemented in XUL.

Like HTML, in XUL you can create an interface using a relatively simple
markup language, define the appearance with CSS style sheets, and use
JavaScript to manipulate behavior. Unlike HTML, however, XUL provides a
rich set of user interface widgets to create, for example, menus,
toolbars and tabbed panels.

To put it in simple terms, XUL can be used to create lightweight,
cross-platform, cross-device user interfaces.

Many applications are developed using features of a specific platform
that makes building cross-platform software time-consuming and costly.
Some users may want to use an application on technologies other than
traditional computers, such as small handheld devices. To date, there
have been some cross-platform solutions already developed. Java, for
example, was created just for such a purpose. However, creating GUIs
with Java is cumbersome at best. Alternatively, XUL has been designed
for building portable user interfaces easily and quickly. It is
available on most versions of Windows, Mac OS X, Linux and Unix. Yahoo!
currently uses XUL and related technologies for its Yahoo! tool bar (a
Firefox extension) and Photomail application.

To illustrate XUL's potential, this chapter will work through a few
examples. Potential is the correct word here. The full capabilities of
XUL are beyond the scope of this chapter but it is designed to give the
reader a first look at the power of XUL. One more thing needs to be
noted: you'll need a Gecko-based browser (such as Firefox or the Mozilla
Suite) or XULRunner to
work with XUL.

## The Basics

XUL is XML, and like all good XML files, a good XUL file begins with the
standard XML version declaration. Currently, XUL is using the XML
version 1.0.

To make your XUL page look good, you must include a *global* stylesheet
in it. The URI of the default stylesheet is *href =
\"<chrome://global/skin/>\"*. While you can load as many stylesheets as
you like, it is best practice to load the global stylesheet initially.
Look at Fig.1. Notice the reference to "chrome". 'The chrome is the part
of the application window that lies outside of a window\'s content area.
Toolbars, menu bars, progress bars, and window title bars are all
examples of elements that are typically part of the chrome.'(1) Chrome
is the descriptive term used to name all of the elements in a XUL
application. Think of it like the chrome on the outside of a car. It's
what catches your eye. The elements in a XUL file are what you see in
the browser window.

All XML documents must have a namespace declaration. The developers of
XUL have provided a namespace that shows where they came up with the
name XUL. (The reference is from the movie 'Ghostbusters' for the
uninitiated)

``` XML
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
   id="window identifier"
   title="XUL page"
   orient="horizontal"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   . . . (add elements here)
</window>
```

The next thing to note is the tag `<window>`{=html}. This tag is
analogous to the

```{=html}
<body>
```
tag in HTML. All the elements will live inside the window tag. In Fig. 1
the window tag has three attributes that are very important. The 'id'
attribute is important in that it is the way to identify the window so
that scripts can refer to it. While the title attribute is not
necessary, it is good practice to provide a descriptive name. The value
of title will be displayed in the title bar of the window. The next
attribute is very important. This tells the browser in what direction to
lay out the elements described in the XUL file. Horizontal means just
that. Lay out in succession across the window. Vertical is the opposite;
it adds the elements in column format. Vertical is the default value so
if you do not declare this attribute you'll get vertical orientation.

As was stated earlier, a XUL document is used to create user interfaces.
UI\'s are generally full of interactive components such as text boxes,
buttons and the like. A XUL document accomplishes this with the use of
widgets, which are self-contained components with pre-defined behavior.
For example buttons will respond to mouse clicks and menu bars can hold
buttons. All the normally accepted actions of GUI components are built
in to the widgets. There is already a rich library of predefined
widgets, but because this is open source, any one can define a widget or
a set of widgets for themselves.

The widgets are 'disconnected' until they are programmed to work
together. This can be done simply with JavaScript or a more complex
application can be made using something like C++ or Java. In this
chapter we will use JavaScript to illustrate XUL's uses and potential.

Also, a XUL file should have .xul extension. The Mozilla browser will
automatically recognize it and know what to do with it when you click on
it. Optionally, an .xml extension could be used but you would have to
open the file within the browser.

One more thing needs to be mentioned. There are a few syntax rules to
follow and they are:

-   All events and attributes must be written in lowercase.
-   All strings must be double quoted.
-   Every XUL widget must use close tags (either
    `<tag>`{=html}`</tag>`{=html} or `<tag/>`{=html}) to be well-formed.
-   All attributes must have a value.

## A First Example

What better way to start then with the good old 'Hello World' example.
Open up a text editor (not MS Word) like notepad or TextPad and type in:

``` XML
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window
id="Hello"
title="Hello World Example"
orient="vertical"
persist="screenX screenY width height"
xmlns= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<description style='font-size:24pt'>Hello World</description>
<description value='Hello World' style='font-size:24pt'/>
<label value = 'Hello World'  style='font-size:24pt'/>
</window>
```

Save it anywhere but be sure to give the file the .xul extension. Now
just double click on it and it should open in your Mozilla or Netscape
browser. You should get 'Hello World' three times, one on top of the
other. Notice the different ways that 'Hello World' was printed: twice
from a description tag and once from a label tag. Both
`<description>`{=html} and `<label>`{=html} are text related tags. Using
the description tag is the only way to write text that is not contents
of a 'value' attribute. This means that you can write text that isn\'t
necessarily assigned to a variable. In the second and third examples the
text is expressed as an attribute to the tag description or label,
respectively. You can see here that the orient attribute in window is
set to 'vertical'. That is why the text is output in a column.
Otherwise, if orient was set to 'horizontal', all the text would be on
one line. Try it.

Now let's start adding some more interesting elements.

## Adding Widgets

As stated earlier, XUL has an existing rich library of elements fondly
called widgets. These include buttons, text boxes, progress bars,
sliders and a host of other useful items. One good listing is the XUL
Programmer\'s Reference.

Let us take a look at some simple buttons. Enter the following code and
place it into a Notepad or other text editor that is not MS Word.

``` XML
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<button id="find-button" label="Find" default="true"/>
<button id="cancel-button" label="Cancel"/>

</window>
```

Save it and give the file the .xul extension. Open a Mozilla or Netscape
browser and open the file from the browser. You should see a \"find\"
button and a \"cancel button\". From here it is possible to add more
functionality and build up elaborate interfaces.

There has to be some place to put all of these things and like the

```{=html}
<body>
```
tag in HTML, the `<box>`{=html} tag in XUL is used to house the widgets.
In other words, boxes are containers that encapsulate other elements.
There are a number of different `<box>`{=html} types. In this example
we'll use `<hbox>`{=html}, `<vbox>`{=html}, `<toolbox>`{=html} and
`<tabbox>`{=html}.

`<hbox>`{=html} and `<vbox>`{=html} are synonymous with the attributes
\'orient = \"horizontal\"\' and \'orient = \"vertical\"\', which
respectively form the `<window>`{=html} tag. By using these two boxes,
discrete sections of the window can have their own orientation. These
two elements can hold all of the other elements and can even be nested.

The tags `<toolbox>`{=html} and `<tabbox>`{=html} serve special
purposes. `<toolbox>`{=html} is used to create tool bars at the top or
bottom of the window while `<tabbox>`{=html} sets up a series of tabbed
sheets in the window.

Take the XUL framework from Fig. 1 and replace \". . .( add elements
here)\" with a `<vbox>`{=html} tag pair (that\'s both open and close
tags). This will be the outside container for the rest of the elements.
Remember, the `<vbox>`{=html} means that elements will be positioned
vertically in order of appearance. Add the attribute \'flex=\"1\"\'.
This will make the menu bar extend all the way across the window.

``` XML
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<vbox flex="1">
    (... add elements here)
</vbox>

</window>
```

The \'flex\' attribute needs some explanation since it is a primary way
of sizing and positioning the elements on a page. Flex is a dynamic way
of sizing and positioning widgets in a window. The higher the flex
number (1 being highest), the more that widget gets priority sizing and
placement over widgets with lower flex settings. All elements have size
attributes, such as width and/or height, that can be set to an exact
number of pixels but using flex insures the same relative sizing and
positioning when resizing a window occurs.

Now put a pair each of `<toolbox>`{=html} and `<tabbox>`{=html} tags
inside of the `<vbox>`{=html} tags with `<toolbox>`{=html} first. As was
said `<toolbox>`{=html} is used to create tool bars so lets add a
toolbar similar to the one at the top of the browser.

This is the code so far:

``` XML
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<vbox flex="1">

<toolbox>

<menubar id="MenuBar">
<menu id="File" label="File" accesskey="f">
<menupopup id="FileMenu">
<menuitem label="New" accesskey="n"/>
<menuitem label="Open..." accesskey="o"/>
<menuitem label="Save" accesskey="s"/> 
<menuitem label="Save As..." accesskey="s"/>  
<menuitem label=" ... "/> 
<menuseparator/>
<menuitem label="Close" accesskey="c" />
</menupopup>
</menu>

<menu id="Edit" label="Edit" accesskey="e">
<menupopup id="EditMenu">
<menuitem label="Cut" accesskey="t" acceltext="Ctrl + X"/>
<menuitem label="Copy" accesskey="c"  acceltext="Ctrl + C"/>
<menuitem label="Paste" accesskey="p" disabled="true"/>
</menupopup>
</menu>

<menu id="View" label="View" accesskey="v">
<menupopup id="ViewMenu">
<menuitem id="Tool Bar1" label="Tool Bar1"
type="checkbox" accesskey="1" checked="true"/>
<menuitem id="Tool Bar2" label="Tool Bar2"
type="checkbox" accesskey="2" checked="false"/>
</menupopup>
</menu>
</menubar>

</toolbox>

<tabbox>

</tabbox>

</vbox>

</window>
```

There should now be a menu bar with "File Edit View" in it and they
should each expand when you click on them. Let's examine the elements
and their attributes more closely to see how they work.

First the `<menubar>`{=html} holds all of the menu items (File, Edit
,View). Next there are the three different menu items. Each menu has a
set of elements and attributes. The `<menupopup>`{=html} does just it
says. It creates the popup menu that occurs when the menu label is
clicked. In the popup menu is the list of menu items. Each of these has
an \'accesskey\' attribute. This attribute underlines the letter and
provides the reference for making a hot key for that menu item. Notice
in the Edit menu, both \'Cut\' and \'Copy\' have accelerator text
labels. In the File menu there is a `<menuseperator/>`{=html} tag. This
places a line across the menu that acts as a visual separator. In the
Edit menu, notice the menu item labeled \'Paste\' has an attribute:
disabled=\"true\". This causes the Paste label to be grayed out in that
menu and finally in the View menu the menu items there are actually
checkboxes. The first one is checked by default and the second one is
not.

Now on to the `<tabbox>`{=html}. Let\'s make three different sheets with
different elements on them. Put this code in between the
`<tabbox>`{=html} tags:

``` XML
<tabbox flex="1">
<tabs>
   <tab id="Tab1" label="Sheet1" selected="true"/>
   <tab id="Tab2" label="Sheet2"/>
   <tab id="Tab3" label="Sheet3"/>
</tabs>

<tabpanels flex="1">
   <tabpanel flex="1" id="Tab1Sheet" orient="vertical" >
   <description style="color:teal;">
      This doesn't do much.
      Just shows some of the style attributes.
   </description>
   </tabpanel>

   <tabpanel flex="1" id="Tab2Sheet" orient="vertical">
   <description class="normal">
      Hey, the slider works (for free).
   </description>
   <scrollbar/>
   </tabpanel>

   <tabpanel flex="1" id="Tab3Sheet" orient="vertical">
   <hbox>
      <text value="Progress Meter" id="txt" style="display:visible;"/>
      <progressmeter id="prgmeter" mode="undetermined"
         style="display:visible;" label="Progress Bar"/>          
   </hbox>
   <description value="Wow, XUL! I mean cool!"/>   
   </tabpanel>
</tabpanels>
</tabbox>
```

The tabs **are first defined** with `<tab>`{=html}. They are given an id
and label. Next, a set of associated panels is created, each with
different content. The first one is to show that like HTML style sheets
can be applied in line. The second two sheets have component type
elements in them. See how the slider works and the progress bar is
running on its own.

XUL has a number of types of elements for creating list boxes. A list
box displays items in the form of a list. Any item in such a particular
list can be selected. XUL provides two types of elements to create
lists, a listbox element to create multi-row list boxes, and a menulist
element to create drop-down list boxes, as we have already seen.

The simplest list box uses the listbox element for the box itself, and
the listitem element for each item. For example, this list box will have
four rows, one for each item.

``` XML
<listbox>
  <listitem label="Butter Pecan"/>
  <listitem label="Chocolate Chip"/>
  <listitem label="Raspberry Ripple"/>
  <listitem label="Squash Swirl"/>
</listbox>
```

Like with the HTML option element, you a value can be assigned using the
value attribute. The list box will set to a normal size, but you can
alter the size to a certain level using the row attributes. Set it to
the number of rows to display in the list box. A scroll bar will
automatically come up to let the user be able to see the rest of the
items in the list box if the box is too small.

``` XML
<listbox rows="3">
  <listitem label="Butter Pecan" value="bpecan"/>
  <listitem label="Chocolate Chip" value="chocchip"/>
  <listitem label="Raspberry Ripple" value="raspripple"/>
  <listitem label="Squash Swirl" value="squash"/>
</listbox>
```

Assigning values to each of the listitems lets the user be able to
reference them later using script. This way, other elements can be
reference this items to be used for alternative purposes.

All these elements are very nice and easy to put into a window, but by
themselves they don\'t do anything. Now we have to connect things with
some other code.

## Adding Event Handlers and Responding to Events

To make things really useful, some type of scripting or application
level coding has to be done. In our example, JavaScript will be used to
add functionality to the components. This is done in a similar fashion
as to scripting with HTML. With HTML, an event handler is associated
with an element and some action is initiated when that handler is
activated. Most of the handlers used with HTML are also found in XUL, in
addition to some unique ones. Scripting can be done in additional lines
of code, but a more efficient way is to create a separate file with the
needed scripts inside of it. This allows the page to load faster since
the rendering engine doesn't have to decide what to do with the embedded
script tags.

That being said, we'll first add a simple script, in line, as a first
example.

Let's add an 'onclick' event handler to fire an alert box when an
element is selected. Inside the `<window>`{=html} tag add the line
beginning with onclick:

``` XML
<window
   onclick="alert(event.target.tagName); return false;"
   id="findfile-window"
   title="Find Files"
   orient="horizontal"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
       (... add elements here)
</window>
```

Now when you click on any element in the window, you created an alert
box that pops up telling you the name of the element. One interesting
thing to note: When you click on the text enclosed by the description
tag the response is undefined but when you click on the text wrapped by
the label tag you get the tabName label.

This implies that a description tag is not really an element. After
playing with the alert box, delete that line and add this inside the
opening tag of the 'Close' menu item in the 'File' menu:

``` XML
oncommand="window.close()"
```

Now when you click on 'Close' or use the 'C' as a hot key, the entire
window will close. The oncommand event handler is actually preferred
over onclick because oncommand can handle hot keys and other non-mouse
events.

Let's try one more thing. Add this right after the opening
`<window>`{=html} tag.

``` javascript
<script>
function show()
{
  var meter=document.getElementById('prgmeter');
  meter.setAttribute("style","display: visible;");
  var tx=document.getElementById('txt');
  tx.setAttribute("style","display: visible;");
}

function hide()
{
  var meter=document.getElementById('prgmeter');
  meter.setAttribute("style","display: none;");
  var tx=document.getElementById('txt');
  tx.setAttribute("style","display: none;");
}

</script>
```

These two functions first retrieve a reference to the progress meter and
the text element using their ids. Then both functions set the style
attributes of the progress meter and text element to have a display of
\'visible\' or 'none' which will do just that: hide or display those two
elements. (The tabpanel for the progress meter has to be displayed in
order to see these actions)

Now add two buttons that will provide the event to fire these two
methods. First, add a new box element to hold the buttons. The width
attribute of the box needs to be set otherwise the buttons will be laid
out to extend the length of the window.

``` XML
<box width="200px">
  <button id="show" label="Show" default="true" oncommand="show();"/>
  <button id="hide" label="Hide" default="true" oncommand="hide();"/>
</box>
```

### Style Sheets

Style sheets may be used both for creating themes, as well as modifying
elements for a more elaborate user interfaces. XUL uses CSS (Cascading
Style Sheets) for this. A style sheet is a file which contains style
information for elements. The style sheet makes it possible to apply
certain fonts, colors, borders, and size to the elements of your choice.
Mozilla applies a default style sheet to each XUL window. So far, this
is the style sheet that has been used for all the XUL documents:

``` XML
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
```

That line gives the XUL document the default <chrome://global/skin/>
style sheet. In Mozilla, this will be translated as the file global.css,
which contains default style information for XUL elements. The file will
still show is this line is left out but it will not be as aesthetically
pleasing. The style sheet applies theme-specific fonts, colors and
borders to make the elements look more suitable. Even though style
sheets can provide a better looking file, adding styles cannot always
provide a better view. Some CSS properties do not affect the appearance
of a widget, such as those that change the size or margins. In XUL, the
use of the \"flex: attribute should be used instead of using specific
sizes. There are other ways that CSS does not apply, and may be to
advanced for this tutorial.

Using a style sheet that you perhaps have already made, you just have to
insert one extra line of code pointing to the CSS file you have already
made.

``` XML
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="findfile.css" type="text/css"?>
```

This second line of code references the style sheet, and will take over
as the default style sheet used for the XUL document. Sometimes it is
desired not to have the style that comes with the default CSS file.

### Answers

## Conclusion

The examples shown in this chapter merely scratch the surface of XUL's
capabilities. Even though these examples are very simple, one can see
how easy it would be to create more complex UI's with XUL. With a
complete set of the standard components such as buttons and text boxes
at the programmer's disposal, the programmer can code anything in XUL
that can be coded in HTML. The cross-platform ability of XUL is another
bonus but the fact that it doesn't work with Microsoft's Internet
Explorer may suppress XUL's widespread use. There is some hope that due
to the delay in the development of the next version of IE that XUL may
find it's way into IE, but don't hold your breath..

## References

1.  \'Configurable
    Chrome\' by Dave
    Hyatt (hyatt@netscape.com) (Last Modified 4/7/99)
2.  XML User Interface Language
    (XUL) - The Mozilla
    Organization
3.  XulPlanet
4.  XUL Programmer\'s Reference Manual, Fifth Draft: Updated for XUL
    1.0

fr:Programmation XML/XUL
