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.
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:
- create a XBL document to specify which elements receive user interface enhancements
- include the XBL document with a link or style element in the document head (similar to including a CSS document)
- 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
- your standards layer
libXBLUI.js
- initialization code
Samples are available for the following projects:
- SLAB
-
Standards Layer for APIs in Browsers -
this is the default layer inXBLUI.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.