Sign In/My Account | View Cart  
advertisement


Print

XUL-Enhanced Web Apps

by Cedric Savarese
February 06, 2007

This article presents a little-known use of XUL (Mozilla's user-interface language) and shows how to take advantage of its superior performance and accessibility over HTML while maintaining cross-browser compatibility. I will illustrate this using a proof-of-concept JavaScript library that can render UI widgets using either XUL or DHTML.

If possible, you will want to open this page in Firefox. The side-by-side examples below will not make much sense otherwise.

Side-by-Side Tabbed Panel Example

  • On the left we have a (very) basic DHTML implementation of tabbed panels.
  • On the right, provided you are using Firefox, you will see the same panel rendered with XUL.
  • In any other browser, the second panel degrades to the DHTML implementation and therefore looks identical to the one on the left.
DHTML Tabbed Panel XUL Tabbed Panel
First tab content
Second tab content
Third tab content
First tab content
Second tab content
Third tab content

What is XUL?

From The Joy of XUL:

XUL (pronounced "zool") is Mozilla's XML-based user interface language that lets you build feature-rich cross-platform applications that can run connected to or disconnected from the Internet.

The user interfaces of Firefox, Thunderbird, and other Mozilla applications are written in XUL. As you might expect, XUL contains elements for the most common UI widgets, such as menus, toolbars, buttons, lists, and so on (Firefox-only link).

The rendering engine for XUL is called Gecko. If that sounds familiar, it's because Gecko is the same engine that renders HTML web pages in Mozilla's browsers. This means two things:

  1. You can run XUL-based applications in Firefox. They're known as "remote xul" applications.
  2. You can mix XUL and HTML markup in Firefox, and this approach is known as writing "XUL-in-HTML" applications.

XUL-in-HTML is that "little-known" technique that we're interested in here.

Cross-Browser Compatibility

The most obvious drawback to XUL is that it is not supported by most browsers (Internet Explorer, Safari, Opera...). Any web application relying on XUL needs to fall back on DHTML widgets for cross-browser compatibility. So the question is not about choosing XUL or DHTML, but if XUL and DHTML is a worthy development approach.

The last thing a developer wants is to maintain two different code-bases to support different browsers. And isn't that why JavaScript libraries and frameworks were created in the first place? There are so many differences among browsers that any web-based application these days relies on a JavaScript framework of some sort to abstract those annoying browser quirks.

So if you are already using a JavaScript library, could that library handle XUL for you? The response is yes. Would that lead to a bloated and slow library? Well, no, but allow me to demonstrate.

XUL vs. DHTML widgets

There are plenty of DHMTL-based widget libraries (you may also call them JavaScript or Ajax widgets). Yahoo's YUI Library, Dojo's widgets, Adobe's Spry to name just a few, so why would you want to bother with XUL?

XUL widgets are faster, more accessible, and come with more built-in behaviors than their DHTML counterparts. Simply put, with XUL the user experience feels much more like a desktop application than a web-based one.

The difference in performance is more striking with complex widgets, so let's compare a DHTML tree with a XUL tree.

Side-by-Side Tree Example

Again, the XUL tree on the right is only visible in Firefox. In any other browser it degrades to DHTML and looks identical to the one on the left.

DHTML Tree XUL Tree
Render Again Render Again

 

Rendering Speed Comparison

The time measured here is the time necessary to render the tree once all the required resources have been loaded. If you have the Firebug extension for Firefox, you can easily run a profiling test on your own using the "render again" links.

Here are the results for different sizes of tree. You can see that the XUL widget renders two to six times faster than the DHTML widget.

Rendering Speed DHTML Tree XUL Tree
Small Tree (20 nodes) 30 ms 15ms
Medium Tree (200 nodes) 421 ms 62 ms
Large Tree (2000 nodes) 4400 ms 650 ms

File Size Comparison

Now, what about the overhead induced by adding the XUL implementation on top of the DHTML code? Here's the comparison.

Loaded Resources DHTML Only DHTML+XUL
javascript 19Kb 24Kb
css 2 Kb 3 Kb
images 2 Kb 1 Kb
Total 23 Kb 28 Kb

First, the XUL implementation adds only 5Kb of code and 1Kb of css styling. Secondly, XUL actually loads fewer images than the DHTML version. This is interesting because the XUL widget looks much nicer and uses more graphics. This is possible because XUL widgets inherit the browser's theme. The images, stylesheets, and JavaScript code used by XUL are therefore already present in the browser and don't need to be downloaded from the website.

Feature Comparison

If you play a bit with the XUL tree, you can see that:

  • you can open and collapse branches,
  • you can resize the columns,
  • the alternated row colors are maintained regardless of the state of the tree.

These are all built-in behaviors; no additional code was required.

In comparison, in DHTML, I implemented the expand/collapse functionality and left out the other behaviors to keep the code lean and fast. Of course, it is possible to create a DHTML tree that implements all the features offered by XUL and more (see, for example, Jack Slocum's improved YUI Tree widget).

The point of this comparison is to suggest that you could take some of XUL's built-in features as an enhancement reserved for users with a XUL-compatible browser (Firefox, that is) and keep an efficient, trimmed-down, DHTML version for your other users.

Accessibility Comparison

XUL comes with built-in accessibility features. You can select the XUL tree with the Tab key. You can navigate up and down the tree by using the up and down arrow keys. You can expand and collapse tree branches with the left and right arrow keys.

These are the kinds of features that are often overlooked by developers, so it's nice to get them for free when using XUL.

The Tabbed Panels Example Deconstructed

Let's dive into the code now to see how the UI library can manage both XUL and DHTML with very little overhead.

Here is the markup we are working with:

<div id="myTabBox">    
    <div id="tabPanelA" class="tabPanel" title="First Tab">First tab content</div>    
    <div id="tabPanelB" class="tabPanel" title="Second Tab">Second tab content</div>    
    <div id="tabPanelC" class="tabPanel" title="Third Tab">Third tab content</div>        
</div>

Each div with the class "tabPanel" represents a different panel. The title attribute will be used as the label of the tab. Note that if JavaScript is disabled, the widget will not be rendered but the content will still be accessible.

With a simple script, we can parse that HTML and find our tabs.

var tabbox     = document.getElementById("myTabBox");
var tabcontent = tabbox.childNodes; 
var tabcount   = tabcontent.length;

By the way, this was edited for clarity; the code used in the UI library is a more complex and more flexible.

Select the Right Implementation

Now we need to figure out if the browser supports XUL. You can do this by checking the userAgent string. We'll look for the "Gecko/" string, which uniquely identifies Mozilla's Gecko-based browsers. Note that "Gecko" alone is not enough since Apple's Safari browser includes the word "Gecko" in its user-agent string ("...KHTML, like Gecko...").

function hasSupportForXUL() {
  if(navigator.userAgent && navigator.userAgent.indexOf("Gecko") != -1) 
    return true;
  else
    return false;    
}

DHTML Implementation

If the browser doesn't support XUL, we'll use JavaScript to create some additional markups and implement the tab-switching behavior.

if (!hasSupportForXUL()) {
  var tabdiv = document.createElement("div"); 
  tabbox.insertBefore(tabdiv, tabbox.firstChild);
  for(var i=0;i<tabcount;i++) {
      var label = tabcontent[i].getAttribute("title");
    var tab = document.createElement("a");
    tab.onclick = switchtab;
    tab.className = "tab";
    tab.appendChild(document.createTextNode(label));
    tabdiv.appendChild(tab);
  }
}

This code, simplified for clarity, creates a DIV element around the three panels. Then it loops through each panel and adds the tab (a CSS-styled link).

Here is the tab-switching function: :

function switchtab() {
  var tabdiv = this.parentNode;
  for(var i=0;i < tabdiv.childNodes.length; i++) {
    if (tabdiv.childNodes[i]!=this) 
      tabcontent[i].style.display = "none";      
    else
      tabcontent[i].style.display = "block";      
  }
}

XUL implementation

If the browser is XUL compatible, we need to replace the HTML markup with XUL markup. The result should look like this:  

<xul:tabbox>
  <xul:tabs>
    <xul:tab label="First tab"/>
    <xul:tab label="Second tab"/>
    <xul:tab label="Third tab"/>
  </xul:tabs>
  <xul:tabpanels>
    <xul:tabpanel><div>First tab content</div></xul:tabpanel>
    <xul:tabpanel><div>Second tab content</div></xul:tabpanel>
    <xul:tabpanel><div>Third tab content</div></xul:tabpanel>
  </xul:tabpanels>
</xul:tabbox>

Here's the JavaScript that will take care of this (abbreviated for clarity; see the source for complete code).

if (hasSupportForXUL()) {
  var tabBox = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","tabbox");    
  var tabs = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","tabs");    
  tabBox.appendChild(tabs);
  var tabpanels = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","tabpanels");    
  tabBox.appendChild(tabpanels);

  for(var i=0;i<tabcount;i++) {
    var tab = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","tab");
    tabs.appendChild(tabs);    
    tab.appendChild(tabcontent[i]); 
    var tabpanel = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","tabpanel");    
    tabpanels.appendChild(tabpanel);
  }
// remove unused HTML markup
document.getElmentById("myTabBox").innerHTML = "";
// insert XUL markup in page
document.getElmentById("myTabBox").appendChild(tabBox);

The implementation logic is about the same, but you'll notice two big differences. First, we use createElementNS, and we specify the XUL namespace. This lets the browser know that it needs to handle this markup as XUL and not HTML.

The second difference is that we don't have a switchtab function. We don't need it because tab switching is a built-in behavior of the XUL tabbox element.

 

Just a Few More Things to Consider

Theme Inheritance

XUL widgets inherit by default the look and feel of your browser. On one hand, this is nice because it requires less work, less styling, and fewer resources to download. I could also argue that it improves usability since we are adopting the browser UI standards.

On the other hand, the application designer may not agree with surrendering all control over the look and feel of the application. Well, it doesn't have to be this way. It is possible to fully customize the XUL widgets with CSS. Unfortunately, this is one situation where you will end up with two different versions of the same stylesheet, making maintenance more difficult.

Security Restrictions

XUL is generally intended to run with high security privileges, as the browser user interface itself or as a browser extension. When writing XUL-in-HTML, we are running with the most restricted security setting and some XUL widgets may not work as expected in this context. This requires jumping through a few hoops to work around the restrictions. The tree widget, for instance, comes with a very nice drag-and-drop functionality. Unfortunately, this feature simply won't work when used in a web page. It must be reimplemented without using the functions that require higher security privileges.

Conclusion

This article uses a proof-of-concept library, named hXUL (for lack of a better idea). This library implements the tabbed panel and tree widgets in both XUL and DHTML (including the drag and drop for the tree). You can download it here. There are few more widgets that would be good candidates for inclusion--the combo-box, for instance. But maybe a better approach would be to build upon an existing library. Dojo's multiple renderer approach could make it a good fit, but it is certainly not the only one. With such a library, any developer could deliver a XUL-enhanced application with a fast and accessible user interface for Firefox users without sacrificing cross-browser compatibility.

 




Titles Only Titles Only Newest First
  • fiwedding
    2010-06-18 20:07:48 fiwedding

    good job

  • Los Angeles Locksmith Locks 323-678-2704
    2010-06-16 12:30:24 carpetcare

    Los Angeles Locksmith 323-678-2704 Los Angeles Locksmith
    Los Angeles locksmith services
    All automotive, home and commercial requirements become routine with our range of keys, locks, alarm systems, CCTV, keyless entry systems, video surveillance systems and access control systems. Get your free estimate now and join the growing list of those satisfies with our state of the art affordable services.
    Emergency lockout/opening
    Installation/ repair / change /upgrade any type of lock
    Key replacing
    Key making


    Find our local locksmith
    in your area
    LOS ANGELES SANTA CLARITA SAN FERNANDO BURBANK GLENDALE TORRANCE REDONDO BEACH HERMOSA BEACH GARDENA MANHATTAN BEACH HAWTHORNE INGLEWOOD SANTA MONICA BEVERLY HILLS WEST HOLLYWOOD, ORANGE COUNTY
    Los Angeles locksmith provides services in most of California. Because of the excellent service guaranteed to the local residents, our business has expanded and now provides solutions to householders and business people alike throughout the great state of California. We are available 24hr in the Greater Los Angeles area. Our locksmiths are directed from:
    For our locksmith service call toll free (877) 364-5264 or (213) 804-8726
    LVH SYSTEMS Locksmith, a family owned company brings more then 20 years experience to a diverse residential, business and commercial clientele in the Los Angeles area. LVH SYSTEMS locksmith security technicians are licensed bonded and insured with an average of ten years experience bringing unequivocal excellence to their work. We provide 24 hour 7 days a week service to meet all of your security needs. LVH SYSTEMS Locksmith technician’s vehicles are fully equipped so we can finish the job the same day. When calling for service, you will be speaking to a professional locksmith and not a dispatcher. At LVH SYSTEMS Locksmith we stand by our work and all parts and labor are backed with a full 90-day warranty.
    Our staff is professionally trained and would be happy to assist you with all aspects of your security needs including your home, business and automobiles. Price guide or verbal quotes are available upon request. If you have any questions or require immediate service please contact us.
    LVH Systems Locksmith is the largest independent 24 hour emergency locksmith service in California. All our locksmiths are fully trained and will use NON-DISTRUCTIVE methods to gain you
    entry to your home, business or vehicle. Our locksmiths will be with you in 30-60mins after your call all prices are fixed. no matter what time or day of
    the week you need our services.
    Emergency lockout opening
    Change/install/upgrade any type of lock
    door specialist
    Patio doors
    No call out charge.
    Lowest Prices Guaranteed
    Our skilled locksmith technicians will deliver these services at affordable prices.
    More and more people are placing their trust in LVH Systems Locksmith to meet their security needs.


    Call us Toll Free Phone at 1- 877-364-5264 We’ll be happy to answer all your questions and suggest those solutions that are right for you.



    LVH Systems Locksmith — All your security solutions at prices you can live with.




    "Perfect Lock Pick services - Emergency Mobile Locksmiths Service" Performed by Licensed, Insured & Bonded Professional Locksmiths. by the California BUREAU OF SECURITY AND INVESTIGATIVE SERVICES


    Locks Installation by Our trained professionals locksmiths.


    Medeco Security Locks
    Medeco Locks - Medeco High Security Locks is the market leader in locks and locking systems for security, safety, and control.


    Mortise Locks & Cylindrical Locksets


    Baldwin Locks & Hardware
    Baldwin Locks - For more than 60 years, Baldwin Hardware Corporation has been developing the finest and most complete range of hardware for new and restoration construction.


    Mul-T-lock Locks & Hardware
    Mu-T-lock Locks - Manufacturing and marketing of high security locks products for institutional, commercial, industrial and residential applications.


    Kwikset Locks & Hardware. Manufacturer of Residential Door Locks and Door Hardware
    Kwikset Locks - Kwikset – Manufacturer of residential door locks and door hardware including door knobs, door levers, door handles, deadbolts, handlesets, pocket door.


    Schlage Locks & Hardware
    Schlage locks - Today, Schlage offers home security solutions from a wide selection of mechanical and electronic security locks and accessories in touch with modern look.


    Master Lock®- Tough Under Fire
    Master Lock offers residential, automotive, commercial and locker lock products. Master Lock carries multiple product lines including; Master Lock
    locksmith, emergency locksmith, Los Angeles locksmith, Santa Monica locksmith, Hollywood locksmith, Culver City locksmith, Venice locksmith, Malibu locksmith, Glendale locksmith, Downtown locksmith, Beverly Hills locksmith, Westwood locksmith, car locks, doors locks, home locks, locks install,locks repair, house locks, gate locks, commercial locks, residential locks, lost keys, duplicate keys, open car door
    Call US (877) 364-5264 or (213) 804-8726 (323) 678-2704 (310) 925-1720 (818) 386-1022





  • Excellent article
    2007-02-09 10:41:31 Benjamin Young

    It's good to hear that it's possible to get some use out of XUL. It has so much potential, but gets so little use or press.


    One side note: I tried the tree example on your hXUL page, and I was able to drag and drop items within the tree. Is that page implemented differently?


    Also, do you think it would be possible to implement a XUL rendering engine in JavaScript? That would allow XUL to be completely cross-browser (probably with some limitations) and all developers to code in XUL natively rather than rewriting HTML. Just wondering.


    Thanks again for the great article.

    • Excellent article
      2007-02-09 11:09:36 cedric_savarese

      Hi Benjamin,


      The code on the hXUL page (linked at the end of the article) has a bit more features, including the drag&drop, but it's not really finalized yet so I left it out of the article.


      Regarding your question about a cross-browser XUL engine. I think it would be overkill to do it in javascript (and very slow), but check out XUL Explorer: http://starkravingfinkle.org/blog/2006/12/xul-explorer-02/


  • 2007-02-07 14:28:44 cedric_savarese

    Thanks for the correction. The code has been heavily edited for the article and not really tested as is. For a working (and better) code, please refer to the download link at the end of the article.

  • Little mistake in the code
    2007-02-07 14:15:50 LucieLejard

    Your article is really interesting and easy to read. I just wanted to let you know that you did a mistake in the "XUL implementation" part, in the second blue square, you have written "tabs.appendChild(tabs)" instead of "tabs.appendChild(tab)".


  • xulfaces
    2007-02-07 03:18:23 Alessandro Petrozzelli

    I think xulfaces (http://xulfaces.sourceforge.net/) could be a good tool in a Java server environment.