XML - Managing Data Exchange/XUL
XML - Managing Data Exchange
|
Related Topics
|
Get Involved
|
Previous Chapter | Next Chapter |
← Parsing XML files | AJAX → |
Learning objectives
|
Introduction
editXUL (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
editXUL 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 <tag></tag> or <tag/>) to be well-formed.
- All attributes must have a value.
A First Example
editWhat 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
editAs 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 <menuseperator/> 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
editTo 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
editStyle 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.
Conclusion
editThe 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
edit- '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