Infinite Extensibility with XBL
Pages: 1, 2, 3, 4
The tag: <jack>
I came up with a name for this tag: the <jack> tag. I imagined something I could "jack" up and down like a car jack -- where you have this piece of equipment that expands or contracts when you apply force on it. I could have come up with some special attributes for this tag, like maxflex or something like that, but I wanted something simple. So here's an example of a <jack> tag:
<jack flex="1" id="somename" />
Very similar to a <spring> tag -- so far.
Creating the XUL
Creating a test XUL file
To illustrate how a <jack> might work, I created a simple XUL file that places <jack>s around a set of buttons. One on the left, right, top and bottom:
<box flex="1">
<jack flex="4" id="jack1"/>
<box flex="1" orient="vertical" style="border:2px solid">
<jack flex="4" id="jack2"/>
<button value="go up" oncommand="slider('up')" flex="1"/>
<button value="go down" oncommand="slider('down')"
flex="1"/>
<button value="go left" oncommand="slider('left')"
flex="1"/>
<button value="go right" oncommand="slider('right')"
flex="1"/>
<jack flex="4" id="jack3"/>
</box>
<jack flex="4" id="jack4"/>
</box>
Now wait a minute! Aren't I doing this backward? Wouldn't I first create the binding and then build the code? Perhaps, but I'm doing it in this order to show you that you can build a syntax in XML (XUL, specifically) before you get the implementation down. This way you can create your abstraction free from the ideas and limitations that the actual implementation might unconsciously impose on you.
Creating the CSS
The behavior: css expression
XBL bindings are attached to tags in XUL via the style mechanism. What I mean is that just like you might set some text to be bold or left-justified, you can tell the browser to make it render as a blinking table with an animated gif in the background (not recommended, mind you). You do this by the expression in CSS of:
behavior: url("someURL.XML#idname")
Where someURL.XML is the name of the file that contains the bindings, and the #idname is the ID of the binding element you wish to use.
For example, here is the CSS style rule for our <jack> tag:
jack {
behavior: url("testxbl.xml#jack");
}
Note that you can use CSS to bind to the tagname itself, as is the case above, or you can bind it via ID or CLASS, or any other way that CSS can select an element.
Creating the XBL
The bindings tag
An XBL document looks something like this:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl">
<binding> ... </binding>
<binding> ... </binding>
...
</bindings>
It is a "true" XML document, in that you need to declare all of the namespaces you wish to use, and you can interleave other kinds of XML documents in this file by adding other namespaces. For instance, you might create an XBL binding that mixes XUL elements with SVG elements.
The binding syntax
Here is the actual binding for our <jack> tag:
<binding id="jack" extends="xul:box">
<content>
<spring inherits="flex" />
</content>
<interface>
<method name="flexto" >
<argument name="start" />
<argument name="finish" />
<argument name="step" />
<argument name="interval" />
<argument name="theid" />
<body>
<![CDATA[
if(start!=finish){
this.setAttribute("flex",start+step);
var theString="document.getElementById('"+theid+"')
.flexto("+(start+step)+","+finish+","+step+","+interval+",
\""+theid+"\")"
//alert(theString)
setTimeout(theString,interval)
}
]]>
</body>
</method>
</interface>
</binding>
There's a lot of information here, so I'll go through it step by step. First you see the <binding> tag, which tells XBL we are starting a new binding. Inside this you see an attribute called extends. Extends is an attribute that can tell a binding to inherit the properties of another tag, or even the properties of another binding! This allows you to do something like "take all the properties of some basic element and now build upon it."
The next thing you see is the <content> tag. Everything inside the content tag will be displayed in place of the tag you are binding to. In a future article I will discuss how a binding can handle any tags that may be "inside" the tag you are binding to (called children). Right now, it is sufficient to just assume that whatever you place inside the content tag will show up in the XUL. I'm using a spring in this case. You see an attribute called inherits. This is the method XBL uses to transfer attributes from the bound tag to the anonymous content.
The next tag you see is the <interface> tag. Everything inside the interface defines this binding's properties and methods, which will be used in JavaScript. I have created a method called flexto, which needs the properties start, finish, step, interval, and theid. If the terminology of property and method are foreign to you, I'd recommend getting a good programming book, or reading the documentation on JavaScript. I'm making the assumption here that you have some knowledge of JavaScript and programming. You can create an unlimited number of properties and methods.


