An Introduction to XUL Part 6

Learn about XUL, a subset of XML used to describe user interfaces, that helps you to make rich user interfaces with nothing more complicated than a text editor. In the sixth part of this series learn about XBL, another of XML’s many faces and a partner in crime with XUL, also called XML Binding Language.

CSS, as you know, will change the appearance of any given element on screen.  XBL is a method of changing the behavior of any given element.  You could use a binding to add specific elements that were rendered automatically when your binding element was described in the XUL file.  XBL is used in conjunction with both XUL and CSS.

Like all XML documents, XBL documents must begin with the XML declaration.  The root element is the <bindings> element which contains the XBL namespace. Separate binding elements are then defined as children of this element and the elements you wish to add bindings for are then added as children of this element.  XBL files do not have their own extension, they are saved as XML files.

Once your binding file has been created, you then need to create a CCS rule that specifies a class of the element you are creating the bind for and a style rule telling the XUL file were to look to get the binding.  This is typically a chrome URL with a fragment identifier pointing the binding element. 

For example, you may want to define a binding that adds a default menu bar to the top of your window elements.  First, create the XBL file:

<?xml version=”1.0″?>
<bindings xmlns=”http://www.mozilla.org/xbl”
  xmlns:xul=”http://www.mozilla.org/keymaster/gatekeeper/
  there.is.only.xul”>
  <binding id=”defaultmenu”>

    <content>
      <xul:menu value=”file” label=”file”/>
      <xul:menu label=”edit”/>
      <xul:menu label=”view”/>
      <xul:menu label=”help”/>
    </content>
  </binding>
</bindings>

You start with the xml declaration, add the root bindings element with the XBL namespace and the XUL namespace with appropriate prefix.  The binding element specifies how the binding will work and holds the content element.  The content element contains the elements that you want to add to the element you are binding to, in this case, your default menus.  Each of the menus are declared with the XUL prefix, this is because they are XUL elements and not XBL elements.  All elements added inside the content element are added anonymously which means that Mozilla treats them as one element.  There are implications to this that we won’t worry about for this example, but that you might need to know for future use, namely that because they are added anonymously, they are not accessible through a script in the normal way.  Save this file as bindexample.xml.

{mospagebreak title=Stylesheet}

Next up, you need to create the stylesheet that will point to the binding:

menubar.mymenu { 
    -moz-binding: url(‘example.xml#defaultmenu’);
}

This simply defines a class of a menubar pointing at the binding id.  This is done with the filename of the binding file followed by the # symbol followed by the id of the binding element you wish to use.  The –moz-binding: prefix is a special CSS property that tells the stylesheet file that you’re binding to an XBL file.  Because the binding file we are using is very basic and contains only one binding element, this could be omitted.  Save this file as bindingexample.css in the same location that the first file was saved.

Finally, create the XUL file that references the binding style sheet:

<?xml version=”1.0″?>
<?xml-stylesheet href=”example.css” type=”text/css”?>
<window xmlns=”http://www.mozilla.org/keymaster/gatekeeper/
  there.is.only.xul”>
  <menubar id=”xblmenu” class=”mymenu”></menubar>
</window>

The xml-stylesheet reference points at the CSS file, which in turn points to the binding.  Save this file as bindingexample.XUL, again in the same location as the above two.  You needn’t open this via a chrome URL (although for real-world XBL usage it is advisable), so revert to the command line call used in the first couple of articles.  You should get a very small window containing the default menubar at the top.  As the class has been assigned specifically to the menubar tag, you are free to define menubars in the XUL file that will not inherit the menu items defined in the binding tag.  Add another menubar element to the XUL file without declaring the style class and it should appear as normal beneath the XBL menu:

<menubar id=”nonxblmenu”>
    <menu label=”special”/>
</menubar>

However, if you then assign the second menu to the mymenu class, the menu you have added manually will override the menu elements defined in the XBL file and they will not appear in the second menu.  You can get around this by using the <children/> element in the XBL file.  Add the element beneath the <XUL:menu> elements and then execute the file again.  Now the menus defined in the XBL will be there, with the special menu in the location that the children element appears (i.e. after the other menus).  The power this gives you when designing applications is phenomenal; you can define a default menu set that you want to appear in all of your applications, and then just tweak the XUL files to add any additional menus relevant to the application you’re building.  This promotes code reuse, which is something pushed by all modern programming languages.

{mospagebreak title=Customization}

One of the things that make Mozilla and many other application great is the fact that they are highly customizable through the use of skins to change the appearance of the application, and locales to change the language.  Mozilla manages its skins and locales by packaging them all up into a series of JAR files; look in the application directory of Mozilla and in the chrome directory, you will see these files.  JAR files are compressed archives of stylesheets that handle the appearance of the application, or DTDs that contain all of the text strings in the application.  Both skin and locale archives contain RDF files describe them to Mozilla and all of the JARs are listed in the installed-chrome text file and chrome.rdf files. 

When changing the skin or language of Mozilla, the relevant files are accessed via a chrome URL, and using your skins or locales in this way gives them far more control and flexibility, for example, you can use XBL not just to inherit elements into your XUL files but attributes, properties, methods and event handlers when using chrome URLs in the place of standard path names to reference the XML and CSS files.  You can add a stylesheet in your working directory and modify the skin of any of the examples we have worked on, simply linking the XUL file and the stylesheet using just a standard reference.

In order to use a chrome reference, you need to register the relevant files using an RDF file and tell Mozilla where it is by adding details of its location to the installed-chrome.txt file.  You could alter the appearance of the menu in the created in the previous article.  First of all, create a new folder in the folder you have been working from called mystyle.  Now create a very basic stylesheet, something along the following lines:

menubar {
    color:white ; background-color:red ;
}

menu {
   color:white ; background-color:maroon ; font-weight:bold ;
}

menuitem {
   color:white ; background-color:blue ;
}

Save it as mystle.css in the folder you have just created.  Go back to the Mozilla chrome directory and open the JAR file called classic (you may need a copy winRAR to do this).  In this file will be all of the classic skins for each of the different components of Mozlla; in the location skinclassicnavigator within the JAR file, will be another contents RDF file, copy this to the myskin folder that contains your CSS file.  Now open the RDF file.  It will contain an RDF description of the skin and component it was describing so you need to change all of the references of classic/1.o to mystyle/1.o and change the references of navigator to openclose.   Before you save this file, you’ll also need to change the two RDF:Seq elements to RDF:Bag elements. 

Once this is done, go back to the Mozilla chrome directory once again and open the installed-chrome.txt file.  At the end of the file, add the following line:

skin,install,url,file:///C|XUL/chrome/myskin/

Remember to hit return after adding this line and then save the file.

{mospagebreak title=Adding the Code to our XUL}

Finally, open the XUL file created in the example from the last article.  Add this code to the top of the file, just below the XML declaration:

<?xml-stylesheet href=”chrome://openclose/skin/myskin.css”
type=”text/css”?>

Once that is saved delete the chrome.rdf file from the Mozilla chrome directory and then launch Mozilla.  The XUL file is reference in the same was as before, and once open, you will see the changes laid out in the example stylesheet.  Adding alternative locale files to you applications is done in a similar way, using contents.rdf files to describe them and DTD instead of CSS Files. 

If you’re creating multiple skins, it would be wise to package them up in JAR files yourself.  When doing this, the format that you use to register them in the installed-chrome.txt file changes.  You should store your own JAR archive in the Mozilla chrome folder along with the others and add the next line of code to the bottom of the file:

skin,install,url,jar:resource:/chrome/yourjarname.jar!

If you have a directory structure within the JAR file, the location of the stylesheet will need to come directly are the exclamation mark, so if there was  folder inside the JAR file called skin, then a folder inside that called metallic, which contained a stylesheet that gave interface elements a silver and grey colour scheme, the line of code would need to read:

skin,install,url,jar:resource:/chrome/yourjarname.jar!/
  skin/metallic/

The concepts in this article have related to defining element bindings using XBL and stylesheets, and changing the theme of your applications by using skins.  What I’ve shown you is just the beginning, there is far more than the scope of these articles can hope to include.

XUL is an incredibly easy language to learn and is effective and powerful in what it can do.  I hope that this introduction to it will inspire you to learn more and to put this newfound knowledge into projects of your own to create new applications.

Google+ Comments

Google+ Comments