Introducing XBLUI

XBLUI is a Javascript library that provides UI enhancements for HTML. Enhancements are implemented as element behaviours, or bindings, using XBL - the W3C's XML Binding Language. XBL provides a simple method of applying and extending the built-in enhancements.

If you aren't familiar with XBL you could read my intro to XBL or the official spec or the (incomplete) primer.

XBLUI consists of three layers:

SLAB
SLAB provides Javascript and DOM fixes and enhancements to the browser. This enables the other layers to be standards-based and still work cross-browser.
XBL engine
Since no current browser has a native XBL implementation XBLUI has its own partial implementation. Native XBL implementations will improve the performance of XBLUI enhancements.
UI enhancements
These are written in XML and precompiled into the XBLUI library.
There is also a library containing just the XBL engine if you want to provide the other layers separately.

The XBL engine

A fully compliant implementation of XBL would simplify web-apps, especially because XBL bindings can add content and modify layout without messing up the DOM or CSS settings. XBLUI will never implement all of the spec but will gradually improve. The following features are currently supported.

<handlers>

The XBL engine in XBLUI is basically an event delegation system that reads configuration info from XBL files. Thus the following binding would ask for confirmation for every submission attempt on forms.

 <binding element="form">
  <handlers>
	<handler event="submit">
var rc = confirm("Are you sure you want to submit that form?");
if (!rc) event.preventDefault();
    </handler>
  </handlers>
 </binding>

<implementation>

The engine also makes available a binding object (prototyped on the binding implementation) as the 'this' argument in handler functions. This feature is used in the following to provide a data encoding helper for forms.

 <binding element="form">
  <implementation>
({
  encode: function() {
    var result = "";
    Array.forEach(this.boundElement.elements, function(elt) {
      if (elt.name) result += elt.name + ": " + elt.value + "\n";
    }
    return result;
  }
})
  </implementation>
  <handlers>
	<handler event="submit">
var data = this.encode();
var rc = confirm("Are you sure you want to submit that form? \n" + data);
if (!rc) event.preventDefault();
    </handler>
  </handlers>
 </binding>

According to the XBL spec the binding object is meant to persist for as long as the binding is attached to the element. This allows state information to be stored in the binding object.

XBLUI currently does not support persistent binding objects. If you want the binding to maintain state you can modify attributes on the element.

<html:style>

XBLUI also extends the spec in one way:
if there is a html:style block that is a child of the xbl element then the contents of the style block are used as a stylesheet for the bound-document. This allows the setting of styles only if the XBL engine being available. These styles would presumably interact with attached bindings.

For details on features supported by the XBL engine see the status page.

Usage

Using XBLUI in your web-page is typically a three step process:

  1. create a XBL document to specify which elements receive user interface enhancements
  2. include the XBL document with a link or style element in the document head (similar to including a CSS document)
  3. include the XBLUI script (place it at the end of the document head)

The following example illustrates the simple case of adding the form-element binding above to a page:

<!DOCTYPE html>
<html>
 <head>
  <style type="application/xml">
<xbl xmlns="http://www.w3.org/ns/xbl">

 <binding element="form">
  <implementation>
({
  encode: function() {
    var result = "";
    Array.forEach(this.boundElement.elements, function(elt) {
      if (elt.name) result += elt.name + ": " + elt.value + "\n";
    });
    return result;
  }
})
  </implementation>
  <handlers>
	<handler event="submit">
var data = this.encode();
var rc = confirm("Are you sure you want to submit that form? \n" + data);
if (!rc) event.preventDefault();
    </handler>
  </handlers>
 </binding>
	
</xbl>
  </style>
  <script src="http://dist.meekostuff.net/XBLUI/1.1-default/XBLUI.js"></script>
 </head>
 <body>
  <form action="" method="GET">
   <label>First name <input type="text" name="firstName" /></label><br />
   <label>Last name <input type="text" name="lastName" /></label><br />
   <input type="submit" />
  </form>  
 </body>
</html>

And here is a demo.

UI enhancements

XBLUI provides several bindings in a file typically accessed as http://dist.meekostuff.net/XBLUI/default/UI.xml. If you are using the full XBLUI library - XBLUI.js - then UI.xml is already prefetched.

Applying bindings from this file is done using XBL inheritance. Thus the following would apply features from HTML5 numeric input to appropriate elements. (Note that WF2 is WebForms2, a subset of HTML5)

<binding element="input[type=number]"
  extends="http://dist.meekostuff.net/XBLUI/default/UI.xml#WF2NumberInput"/>

Most of the bindings have demos and their source code will be instructive. The bindings are not yet suitable for common use, as they need refactoring and the documentation is incomplete.

The Standards Layer

The XBL engine doesn't require a comprehensive standards layer, and can be re-configured with functions to provide those features that aren't currently cross-browser. It would be possible to provide a minimal, even non-standard, layer. However, bindings would also have to use the non-standard layer.

The required functions are:

Element.matchesSelector
indicates whether an element matches a CSS selector
Element.bind
add DOM enhancements to an element before it is used
Document.addEventListener
attaches handler for specific events
URL.load
fetch a URL, returning the text data
XMLDocument.load
fetch a URL, returning the XML data
XMLDocument.loadXML
parse a text string to XML

Whatever layer is used will require a little initialization code. You can swap in a different standards layer by replacing XBLUI.js with

  1. your standards layer
  2. libXBLUI.js
  3. initialization code

Samples are available for the following projects:

SLAB
Standards Layer for APIs in Browsers -
this is the default layer in XBLUI.js.
init.js demos
base2
Dean Edward's base2 Javascript and DOM enhancements
init.js demos
NWEvents
Diego Perini's event and selector libraries (NWEvents and NWMatcher)
init.js demos

Other stuff

Project page

XBLUI has its own project page with more documentation. I'm using Assembla for bug-reporting and feature-requests - registration is fairly straight-forward if you want to give feedback there.

Distribution

XBLUI is currently hosted on the Amazon CloudFront CDN.

You can follow default release with http://dist.meekostuff.net/XBLUI/default/XBLUI.js or a branch (only 1.1 for now) with http://dist.meekostuff.net/XBLUI/1.1-default/XBLUI.js. You can also link to individual snapshots. More details on the project page.

Licensing

At this stage XBLUI is available under the Creative-Commons Attribution, No-Derivatives license. You can include it with a script element sourcing the original file (see the sample code above), or you can copy it to your server and source it from there.