This note outlines the XML Binding Language. XBL is a.
This NOTE was submitted to the World Wide Web Consortium (see Submission Request, W3C Staff Comment) on 2001-01-12 with the intention that the W3C use it as a basis for furthering the work on BECSS. For a full list of all acknowledged Submissions, please see Acknowledged Submissions to W3C.
Inquiries from the public about this submission should be directed to the mozilla.org community. The forum most appropriate for discussion of XBL and related matters in the context of Mozilla is the newsgroup netscape.public.mozilla.xbl (which may soon change to mozilla.dev.tech.xbl). The W3C forum most appropriate for discussing this submission is the www-style mailing list..
1. XBL Elements
1.1. The bindings Element
1.2. The binding Element
1.3. The content Element
1.4. The children Element
1.5. The element Element
1.6. The implementation Element
1.7. The method Element
1.8. The parameter Element
1.9. The body Element
1.10. The property Element
1.11. The getter Element
1.12. The setter Element
1.13. The handlers Element
1.14. The handler Element
1.15. The script Element
1.16. The stylesheet Element
2. Binding Attachment and Detachment
2.1. Attachment using CSS
2.2. Attachment using the DOM
2.3. The bindingattached Event
2.4. The bindingdetached Event
2.5. Binding Documents
3. DOM Interfaces
3.1. The DocumentXBL Interface
3.2. The ElementXBL Interface
4. Anonymous Content
4.1. Scoping and Access using the DOM
4.2. Content Generation
4.2.1. Rules for Generation
4.2.2. The contentgenerated Event
4.2.3. The contentdestroyed Event
4.3. Attribute Forwarding
4.4. Insertion Points
4.4.1. <children> and <element>
4.4.2. Handling DOM Changes
4.5. Event Flow and Targeting
4.5.1. Flow and Targeting Across Scopes
4.5.2. Focus and Blur Events
4.5.3. Mouseover and Mouseout Events
4.6. Anonymous Content and CSS
4.6.1. Selectors and Scopes
4.6.2. Binding Stylesheets
5. Binding Implementations
5.1. Methods
5.2. Properties
5.3. Inheritance of Implementations
6. Event Handlers
7. Example - Sticky Notes
A. References
<!ENTITY % bindings-content "(binding|scriptattribute is a document-unique identifier. The value of this identifier is often used to manipulate the element through a DOM interface (e.g., using document.getElementById).
typeattribute specifies the scripting language used by all bindings in the document. Bindings can selectively override this default by specifying
typeattributes of their own.
<!ENTITY % binding-content "(content?,implementation?,handlers?)"> <!ELEMENT binding %binding-content;> <!ATTLIST binding id ID #REQUIRED extends CDATA #IMPLIED display CDATA #IMPLIED >
The
binding element describes a single XBL binding
that dynamically binds new information to XML elements in other
documents. Each binding has three optional components.
Content: A binding can specify new content that is placed under the bound element. This content is anonymous and is hidden from the bound element's DOM.
Methods and Properties: A binding can specify additional methods that can be invoked on the element. It can also specify additional properties that can be retrieved or set on the element. In this way the functionality of the bound element becomes extensible.
Behavior: A binding can specify event handlers for specific actions like key and mouse events that can make use of the new functionality applied in the binding.
idattribute is a document-unique identifier. For the
bindingelement, this attribute is required, since it is used to uniquely identify a binding.
extendsattribute is used to specify the URL of a binding that this binding inherits from. The URL specifies a particular binding document. The # notation must be used to point to a specific binding
idwithin a binding document.
<!ELEMENT content ANY> <!ATTLIST content id ID #IMPLIED applyauthorsheets false  under the bound element. Because the nodes
are hidden from their parent and exist outside the normal document
tree, they are referred to as anonymous content.
idattribute is a document-unique identifier.
applyauthorsheetsattribute indicates whether or not rules in author style sheets associated with the bound element's document apply to the anonymous content generated by the binding. If omitted, a value of
falseis assumed. See section 4.6 for more information.
<!ELEMENT children EMPTY> <!ATTLIST children id ID #IMPLIED includes CDATA #IMPLIED type (explicit|inherited) explicit applybindingsheets false attribute is a document-unique identifier.
includesattribute can be used to indicate that only certain content should be placed at the insertion point specified by the
childrenelement. Its value is an XPath selector as described in the XPath 1.0 specification. For the purposes of the evaluation, the bound element is treated as the context node. If the selector evaluates to anything other than a node set, it is ignored. A child can only be placed within the insertion point if it is matched by the XPath selector. Only immediate children are matched against the selector.
typeattribute can be used to indicate the type of the insertion point. There are two types of insertion points. An explicit insertion point is for the explicit children of the bound element only. An inherited insertion point is used to specify that anonymous content from the base binding can be generated and placed at the insertion point.
applybindingsheetsattribute indicates whether or not style sheets loaded from an XBL document are applied to a bound element's explicit children (in addition to the bound element itself) that are inserted below this insertion point. If omitted, a value of
falseis assumed. See section 4.6 for more information.
<!ELEMENT element ANY> <!ATTLIST element id ID #IMPLIED >
The
element tag specifies the position of the bound
element within the anonymous content of a binding. Normally
anonymous content is generated underneath the bound element. If
the
element tag is used inside anonymous content it
indicates the position at which the bound element should be placed
relative to its anonymous content. This allows anonymous content
ancestors to be generated by the binding (in addition to
children).
If no
element tag is specified, all anonymous
content is generated underneath the bound element.
idattribute is a document-unique identifier.
<!ENTITY % implementation-content "(method|property)*"> <!ELEMENT implementation %implementation-content;> <!ATTLIST implementation id ID #IMPLIED name CDATA #IMPLIED implements CDATA #IMPLIED type CDATA #IMPLIED >
The
implementation element describes a set of
methods and properties that are attached to the bound element.
Once the binding is attached, these methods and properties can be
invoked directly from the bound element.
idattribute is a document-unique identifier.attribute can be used to describe.
typeattribute indicates the language used to describe the methods and properties of the implementation, e.g.,
text/javascript.
<attribute is a document-unique identifier.
nameattribute's value is the name given to the method when it is attached to the bound element. The method can be invoked directly from the bound element using this value.
typeattribute indicates the language used for the body of the method, e.g.,
text/javascript.
<!ELEMENT parameter EMPTY> <!ATTLIST parameter id ID #IMPLIED name CDATA #REQUIRED >
The
parameter element is used inside a
method element. It represents a single parameter of a
method.
[Editor's Note: Should we support the capability to specify types? Assuming that only dynamic scripting languages are used, this may not be a requirement.]
idattribute is a document-unique identifier.
nameattribute is used by script within a method's
bodyelement to reference this parameter.
<!ELEMENT body CDATA> <!ATTLIST body id ID #IMPLIED >
The
body element represents the implementation of its corresponding
method. Its contents are the script that is executed when the method
is invoked.
idattribute is a document-unique identifier.
<attribute is a document-unique identifier.
nameof the property. This is the name used to refer to the property on the bound element.
readonlyattribute is used to designate a property as read-only. If set to
true, the value of the property cannot be altered. If this attribute is omitted, the property will be readable and writable...
elementattribute, the
propertyattribute links the property named by the attribute to the property specifed on the bound element. Its value is used when the bound element's property is accessed, and its value is set when the bound element's property is set.
elementattribute, this attribute links the specified attribute to the property specifed on the bound element. Its value is obtained when the bound element's property is accessed, and its value is set when the bound element's property is set.
typeattribute indicates the language used to describe the getters/setters for the property or the initial value of the property, e.g.,
text/javascript.
<attribute is a document-unique identifier.
typeattribute indicates the language used to describe the getattribute is a document-unique identifier.
typeattribute indicates the language used to describe the setter.
<attribute is a document-unique identifier.
typeattribute is the language used by all scripts specified in the child
handlerelements.
<attribute is a document-unique identifier.
eventattribute describes the specific event that this handler is listening for. Its value can be any legal DOM event name (including custom events created using the DocumentEvent interface of the DOM).
actionattribute contains script that is invoked when the handler fires. The
typeattribute on the enclosing
handlerselement determines the language of the script. The handler script can also be specified as a child of the
handlerelement.
capturing,
bubbling, and
target. If a phase is specified, the handler will only be invoked during that phase of the event handling process. If no phase is specified, a default of
bubblingis assumed..
[Editor's Note: Should window be mentioned in the spec? The DOM makes no mention of windows.]
buttonattribute imposes a filter on the handler. It is used with mouse handlers to specify a particular button. The event handler will only be matched if the value of the button field in the DOM mouse event object matches the value of the attribute.attribute imposes a filter on key handlers. Its value is a key identifier for a specific keycode, e.g.,
vk_enter.
[Editor's Note: A forthcoming DOM events specification will presumably outline the list of valid keycode strings.]
If this attribute is
present, then its value must match the
keycode field of the DOM
key event object in order for the handler to fire.
charcodeattribute imposes a filter on key handlers. Its value is a single character, e.g.,
"z". If this attribute is present, then its value must match the
charcodefield of the DOM key event object in order for the handler to fire.
[Editor's Note: As DOM Events mature more attributes may be added. For example, mutation events define several new fields such as relatedTarget that could be supported in the filtering syntax.]
typeattribute is the language used for the script specified in the
handlerelement.
The
script element is equivalent to its HTML counterpart. The
supported attributes and content can be found here.
The way in which the script block gets applied, however, is different.
The element defines a script that is evaluated by a given document (e.g., an HTML document)
the first time a binding in the XBL file is attached to a bound element in
the document. The script is always evaluated only once per document.
The
stylesheet element supports the same attributes as the
xml-stylesheet
processing instruction with the exception of the
title and
alternate
attributes..
bindingproperty.
The value of the.
Whenever an element is removed from a document, any bindings attached via CSS loaded by the document will be detached.
DocumentXBLinterface. The method
addBindingtakes an element and a binding URL and attaches the binding to the element.
var checkbox = document.getElementById("mycheckbox"); document.addBinding(checkbox, "");
This attachment is not necessarily synchronous. Scripts that invoke this method should not assume that the binding is installed immediately after this method returns. See 2.5 Binding Documents for more information.
When a binding is attached using the DOM, it inherits from the current most derived
binding that may already be attached to the element. Any bindings attached
to an element using the
addBinding method will remain on the element
until the element is destroyed or a corresponding
removeBinding call is
made.
If a binding is attached using
addBinding
addBinding
addBinding method.
loadevent for the bound document. When the
loadevent fires, and if all binding documents loaded successfully, it can be assumed that all bindings are attached to all elements in the page. For elements that are created during or after the
loadevent is fired, no assumptions can be made regarding order of binding attachment.
When a binding is attached, the following events occur:
If the binding needs to execute any initialization code following its attachment
to an element, it can do so using a
bindingattached handler.
This handler contains script that executes upon completion of the binding attachment.
bindingattached handlers
can only be attached directly to bound elements. If an
attachto attribute
is specified on a
bindingattached handler, it will be ignored.
bindingattached handlers for bound elements constructed prior to the
completion of the bound document load will be executed before the
load
event of the bound document fires.
When a binding is attached that extends another binding, the bindingattached handler
of the base binding executes first, and then the derived binding's handler executes.
For bindings attached prior to the firing of the
load event, the following
partial order applies:
for any bound element, the bindingattached handlers for all the descendants of
that element will execute before the bindingattached handler on the bound
element executes. In the script for the handler, the author can thus guarantee
that all children of the bound element are fully initialized. After the
load event fires, however, this partial order is no longer
guaranteed.
[Editor's Note: A recent idea is to replace bindingattached (and bindingdetached) with a <constructor> (and matching <destructor>) element. That would remove the need for any special XBL-only events.]
Bindings attached through the DOM are detached when the following conditions are met:
removeBindingis called on a specific binding
bindingdetachedhandler that executes prior to the binding detachment. Using a
bindingdetachedhandler, a binding can perform any necessary cleanup before it is torn down.
Bindings in an inheritance chain are always detached from the most derived binding
to the base. Therefore the
bindingdetached handler of the derived binding
will execute, and then the base binding's handler
removeBinding, any base bindings that were
attached through the
extends attribute on the binding will also be
removed. In other
words, a call to
removeBinding will remove the same group of bindings
that were installed via the original call to
addBinding.
The rule for detachment can be summarized as follows. Whenever a binding is detached, all bindings that it explicitly inherits from are also detached.
A binding attached through CSS cannot be removed using
removeBinding..
DocumentXBLinterface contains methods for loading and obtaining binding documents. The interface is implemented by DOM documents that support XBL.
interface DocumentXBL { Document loadBindingDocument(in DOMString documentURL); readonly attribute NamedNodeMap bindingDocuments; };
bindingDocuments
bindingDocumentsproperty is a NamedNodeMap of all binding documents loaded by the bound document. Documents are referenced using their URLs.
loadBindingDocument
loadBindingDocumentmethod can be used to synchronously obtain the specified binding document for use within a particular document (the one on which the
loadBindingDocumentmethod was invoked). The binding document can then be modified programmatically using the DOM. Any subsequent bindings that are attached to elements within the document will be constructed from the modified binding document.
Document
loadBindingDocumentis the binding document used by the calling document to attach bindings that are defined in the binding document.
ElementXBLinterface contains methods for accessing anonymous content and for obtaining anonymous parents in the altered model. The interface is implemented by DOM elements that support XBL.
interface ElementXBL { readonly attribute NodeList xblChildNodes; readonly attribute Element bindingOwner; readonly attribute Element anonymousParent; void addBinding(in DOMString bindingURL); void removeBinding(in DOMString bindingURL); };
xblChildNodes
xblChildNodesproperty is a NodeList that represents the true children of the element after insertion points and
elementtags have been applied. This property can be used to navigate the content model according to XBL after bindings have moved explicit and anonymous children using
elementand
childrentags.
bindingOwner
bindingOwnerproperty is used to obtain the bound element with the binding attached that is responsible for the generation of the specified anonymous node. This property enables an author to determine the scope of any content node. When content at the document-level scope is passed in as an argument, the property's value is
null. See section 4.1 for more information.
anonymousParent
anonymousParentproperty's value is the anonymous parent for an element that was placed underneath an insertion point using the
childrenelement in XBL or for a bound element that was repositioned using the
elementtag. When an element that was not repositioned is passed in as an argument, the property's value is
null.
addBinding
addBindingmethod attaches the specified binding (and any bindings that the binding inherits from) to an element. This call is not necessarily synchronous. The binding may not be attached yet when the call completes. See section 2.2 for more information.
removeBinding
removeBindingmethod detaches the specified binding (and any bindings that the binding inherits from explicitly using the
extendsattribute) from the element. See section 2.4 for more information.
A binding can specify an anonymous content template
using the
content element. This
template describes a content tree that will be generated
under.
contentelement are cloned. Elements and attributes in the XBL namespace are never cloned. For content generated underneath the bound element, the topmost nodes'
parentNodepointers are set to the bound element. When anonymous content elements are built above the bound element, the topmost elements'
parentNodepointers are set to the bound element's
parentNode. All anonymous nodes'
ownerDocumentpointers.
Whenever bindings are attached to an element, anonymous content will potentially be generated or destroyed. When a new binding is attached, the bindings in its explicit.
Whenever content is built from a binding's template, a
contentgenerated event
fires. A binding can specify a
contentgenerated handler that contains script
to be executed after the binding has generated content.
Content generation handlers fire whenever the primary generating binding changes and it is determined that the binding should generate content under the bound element. The handlers for a binding chain always fire from the base binding down to the most derived binding. No handlers fire until the content from all bindings in the chain has been generated.
Whenever the primary generating binding changes (either to another binding or to nothing at all),
and if anonymous content is already currently in place under the bound element, that content
is destroyed. Prior to the destruction of the content, a
contentdestroyed event is fired.
The handlers execute from the most derived binding up to the base binding in the chain. All handlers fire before any content is actually destroyed. At the time the handlers fire, the primary generating binding has not yet changed..
XBL
bindings can interleave anonymous content between bound elements
and their explicit children. They do so using XBL
children tags and the XBL
element tag..
Any number of <element> tags may also be present. The <element> element represents an anonymous clone of the bound element. This exists so that anonymous content can conceptually decorate the bound element as well as fill it. It also bears an inherits attribute, with a default value of "*", to indicate attribute forwarding for the anonymous copy of the element.
Under no circumstances can the element generated in place of the <element> element itself be a bound element.
Note that
element and
children elements are never cloned
when content is generated from a template.
Similarly for any attributes in the XBL namespace, such as
xbl:inherits.
[Editor's Note: A possible extension to this is that if the insertion point is empty, then default content specified under the <children> element could be cloned and placed at the insertion point.]
Insertion points continue?]
Events flow through the final transformed content model after all elements have been repositioned
through the usage of
children and
element.
Bindings can interleave anonymous elements between the bound element and its
explicit children. See 4 or
element tags binding two attributes. The first,
applyauthorsheets,. A second attribute,
applybindingsheets can be used to indicate that all children of the bound element,
both anonymous and explicit, can be styled by the sheets in the binding's document.
This can be controlled on a per-insertion-point basis.
User agent sheets and user sheets are always applied to all scopes.. A setter should also
return
val as a result in order to allow for chained assignment (e.g.,
a = this.b = c;) operations to succeed..?].
Event handlers are defined using
handler elements. A handler specifies what
event it is listening for using the
event attribute. The handler contains
script that is executed when an event flows to the object the handler is attached to
and if that event matches all of the criteria specified by
the handler.
The most basic handler specifies the event to listen for and an action to take when
the handler fires. This action can be specified either using an
action attribute
or by specifying the script as a child of the
handler element. If both are
specified, the attribute wins.
By default handlers are attached to the bound element, and they are registered as bubbling events. This means that
<handler event="click" action="foo()"/>is analagous to
onclick="foo()"defined on the bound element.
Event handlers can be attached to the window, the bound sdocument, or to
the bound element using the
attachto attribute. Bindings can use this
attribute to register handlers that listen for
events like
load on the bound document. The value of the attribute is
window,
document or
element.
The
phase attribute specifies the phase of event flow that the handler
is registered for. The default value is
bubbling, which means that the
event handler will fire during the bubbling phase. The other possible values are
target, which means the handler will only fire if
event.target
is the same as the target to which the handler is attached, and
capturing,
which indicates the handler should fire during the capturing phase of event flow.
XBL event handlers always fire last, after all other event handlers at the same position in the event flow. Since XBL handlers usually constitute the default actions for a widget, this allows authors in the bound document to write events that potentially suppress the default actions taken by the XBL handlers.
Within an XBL inheritance chain, event handlers always fire first on the derived binding and then on the base binding in the chain. A derived handler then has a way of preventing the event from flowing to its base binding handlers.
Mouse and key handlers have certain additional properties that are supported by XBL. Additional attributes can be used to impose a filter on the event handler. When a filter is imposed, additional conditions must be met before the event handler will fire.
For both mouse and key events, modifier keys can be specified using the
modifiers attribute. This attribute is a comma-separated list of
modifier keys that must be down at the time the key or mouse event occurs in order
for the handler to execute. Examples of common keys in the list are
shift
and
control.
In addition, mouse events can specify the
button and the
clickcount.
This allows XBL authors to easily define handlers for right-click, or for left double-click,
without having to write script on the same handler to differentiate those cases.
Key events support the
charcode and
keycode attributes. When
set, the corresponding fields in the
event object must match for the event
to fire.
[Editor's Note: Should we have section on error-handling? Probably.]
[Warning this example is now slightly wrong since it applied to a previous version of XBL and some things that are used by it were changed.]
<html> <head> <style> body { background-color: black; color: white; font-size: 10pt; font-family: Verdana; } .board { binding: url(notes.xml#board); } </style> <title>Sticky Notes</title> <body> <h1>Demo - Sticky Notes</h1> The following demo uses XBL to create a widget that functions as a board for PostIt notes. In this example, we create a binding that enables the user to define a board and to supply notes that can be dragged around on the board. <div class="board" style="width: 600px; height: 600px;"> <div flex="1" class="note" style="left: 5; top: 5"> <div class="caption">Pre-Checkin Tests</div> <ul> <li>Compose and send mail. <li>Read and sort mail. <li>Bookmark a page. <li>Send an instant message. <p> <font face="Jokerman" size="+1"> The Ones In Charge </font> </p> </ul> </div> <div class="note" style="left: 250; top: 200;"> <div class="caption">Grocery Order</div> Apples, oranges, milk, orange juice, bread. <p> <i>Don't forget the eggs!</i> </p> <font face="Jokerman" size="+1">SWMBO</font> </div> </div> </body> </html>
<?xml version="1.0"?> <?xml-stylesheet <binding id="board" styleexplicitcontent="true"> <implementation> <property name="dragging"> null </property> <property name="currX"> 0 </property> <property name="currY"> 0 </property> </implementation> <handlers> <handler event="mousedown"> if (event.originalTarget.parentNode.className == 'caption') { this.dragging = event.originalTarget.parentNode.parentNode; this.currX = event.clientX; this.currY = event.clientY; } </handler> <handler event="mouseup"> this.dragging = null; </handler> <handler event="mousemove"> if (!this.dragging) return; deltaX = event.clientX - this.currX; deltaY = event.clientY - this.currY; leftV = parseInt(this.dragging.style.left); topV = parseInt(this.dragging.style.top); leftV += deltaX; topV += deltaY; if (leftV < 0) leftV = 0; if (topV < 0) topV = 0; if (leftV > 390) leftV = 390; if (topV > 390) topV = 390; this.dragging.style.left = leftV; this.dragging.style.top = topV; this.currX = event.clientX; this.currY = event.clientY; </handler> </handlers> </binding>
.board { background-color: #808080; position: relative; } .note { background-color : #FFFFCC; border : 1px outset #FFFFCC; color : #000000; font : smaller; padding : 3px; width: 200px; height: 200px; position: absolute; } .caption { cursor: pointer; font-weight: bold; background-color: #ccccaa; })))))))))