411 REFERENCE · Wikibooks
XML - Managing Data Exchange/XUL
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Parsing XML files AJAX
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 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>. This tag is analogous to the
<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 or ) 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 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> and <label> 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 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 <body>
tag in HTML, the <box> 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> types. In this example we’ll use <hbox>, <vbox>,
<toolbox> and <tabbox>.
<hbox> and <vbox> are synonymous with the attributes 'orient = "horizontal"' and
'orient = "vertical"', which respectively form the <window> 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> and <tabbox> serve special purposes. <toolbox> is
used to create tool bars at the top or bottom of the window while <tabbox>
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> tag pair (that's both open and close tags). This will
be the outside container for the rest of the elements. Remember, the <vbox>
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 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> and <tabbox> tags inside of the
<vbox> tags with <toolbox> first. As was said <toolbox> 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 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> 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> 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 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>. Let's make three different sheets with
different elements on them. Put this code in between the <tabbox> tags:
<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>. 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.
<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.
<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> tag add the line beginning with onclick:
<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:
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> tag.
<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.
<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-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-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
'Configurable Chrome' by Dave Hyatt (hyatt@netscape.com) (Last Modified 4/7/99)
XML User Interface Language (XUL) - The Mozilla Organization
XulPlanet
XUL Programmer's Reference Manual, Fifth Draft: Updated for XUL 1.0
fr:Programmation XML/XUL