W3C

XML Binding Language (XBL) 2.0

W3C Working Draft 17 January 2007

This Version:
http://www.w3.org/TR/2007/WD-xbl-20070117/
Latest Version:
http://www.w3.org/TR/xbl/
Previous Versions:
http://www.w3.org/TR/2006/WD-xbl-20060907/
http://www.w3.org/TR/2006/WD-xbl-20060619/
http://www.mozilla.org/projects/xbl/xbl.html
http://www.w3.org/TR/2001/NOTE-xbl-20010223/
Editor:
Ian Hickson, Google, Inc.

Abstract

The XML Binding Language (XBL) describes the ability to associate elements in one document with script, event handlers, CSS, and more complex content models in another document. This can be used to re-order and wrap content so that, for instance, simple HTML or XHTML markup can have complex CSS styles applied without requiring that the markup be polluted with multiple semantically neutral div elements.

It can also be used to implement new DOM interfaces, and, in conjunction with other specifications, enables arbitrary tag sets to be implemented as widgets. For example, XBL could be used to implement the form controls in XForms or HTML.

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This is the 17 January 2007 Last Call Working Draft of XBL 2.0. The last call for comments resulted in a number of process clarifications, and changes to various method and attribute names. This working draft is intended to allow commentors on the previous draft to verify their changes were correctly made before the specification advances to Candidate Recommendation. The deadline for Last Call comments is the 9 February 2007, after which time this draft will progress to Candidate Recommendation stage unless major issues have been found.

If you wish to make comments regarding this document, please send them to dev-tech-xbl@mozilla.org (subscribe, archives) and public-appformats@w3.org (subscribe, archives). All feedback is welcome. The editor guarantees that all feedback sent to the above lists will receive responses before this specification advances to the next stage of the W3C process.

This specification is considered stable. No major normative changes will be made to this specification going forward. However, publication as a Working Draft does not imply endorsement by the W3C Membership.

The editor's copy of this specification is available in W3C CVS. A detailed list of changes is available from the CVS server.

This specification is a (non-backwards-compatible) revision of Mozilla's XBL 1.0 language, originally developed at Netscape in 2000, and originally implemented in the Gecko rendering engine. [XBL10]

This specification was developed by the Mozilla Foundation and its contributors, in conjunction with individuals from Opera Software ASA, Google, Inc, and Apple Computer, Inc, to address problems found in the original language and to allow for implementation in a broader range of Web browsers.

This document is also based, in part, on work done in the W3C's Bindings Task Force. However, no text from that collaboration, other than that written by the aforementioned contributors, remains in this specification. Inspiration was similarly taken from other efforts, such as HTML Components. [HTC]

Although they have had related histories, this specification is separate from the W3C's "sXBL" drafts, and is not compatible with them. (The two efforts use different namespaces, for one.)

While the body of this specification was created outside the W3C, the W3C Web Application Formats Working Group is now guiding this specification along the W3C Recommendation track.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents


1. Introduction

This specification defines the XML Binding Language and some supporting DOM interfaces and CSS features. XBL is a mechanism for overriding the standard presentation and interactive behavior of particular elements by attaching those elements to appropriate definitions, called bindings. Bindings can be attached to elements using either CSS, the DOM, or by declaring, in XBL, that elements matching a specific selector are implemented by a particular binding. The element that the binding is attached to, called the bound element, acquires the new behavior and presentation specified by the binding.

Bindings can contain event handlers that watch for events on the bound element, an implementation of new methods and properties that become accessible from the bound element, shadow content that is inserted underneath the bound element, and associated resources such as scoped style sheets and precached images, sounds, or videos.

XBL cannot be used to give a document new semantics. The meaning of a document is not changed by any bindings that are associated with it, only its presentation and interactive behavior.

To help readers understand how certain features can be used, this specification includes some examples.

In these examples, a long ellipsis ("...") is used to indicate elided content that would be present in a full example but has been removed for clarity.

Here we see a simple binding being used to reorder content in an HTML page, so that the element with class="nav" is positioned before the element with class="main". CSS associated with the binding is then used to position the two elements.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="nav-then-main">
  <template>
   <div id="wrapper">
    <div id="col2"><content includes=".nav"/></div>
    <div id="col1"><content includes=".main"/></div>
   </div>
  </template>
  <resources>
   <style>
    #wrapper { display: table-row; }
    #col1, #col2 { display: table-cell; }
   </style>
  </resources>
 </binding>
</xbl>

The HTML page associated with such a binding might look like:

<!DOCTYPE HTML>
<html>
 <head>
  <title>Demo</title>
  <link rel="stylesheet" href="example.css">
 </head>
 <body>
  <div class="main">
   <h1>Demo</h1>
   ...
  </div>
  <div class="nav">
   <p><a href="http://example.com/">Home</a></p>
   ...
  </div>
 </body>
</html>

The CSS stylesheet referred to from that document would include various stylistic rules, and would in particular contain a link to the XBL file, making it apply to the body element so as to reorder the two child elements:

/* Colors and Fonts */
h1 { font: 2em sans-serif; color: green; background: white; }
...

/* Reorder content */
body { -xbl-binding: url(example.xml#nav-then-main); }

The result of all the above is equivalent to the result one would get if one simply placed the div element with class="nav" before the div element with class="main". However, the effect is achieved without needing any changes to the markup. This allows the same markup to be given different presentations dynamically. It also allows changes to be applied across entire sites by merely changing global stylesheet and binding files, much as CSS can be used to change the layout and presentation of a site even without XBL.

Here is another example, this time of an inaccessible implementation of the proposed HTML5 details disclosure element: it opens and closes when clicked, and reflects its current state in the element's "open" attribute.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding element="details">
  <template>
   <div state="hidden" id="container">
    <div id="header"><content includes="legend:first-child">Details...</content></div>
    <div id="container"><content/></div>
   </div>
  </template>
  <handlers>
   <handler event="click" phase="default-action">
    this.open = !this.open;
   </handler>
   <handler event="DOMAttrModified" attr-name="open" attr-change="addition">
    this.shadowTree.getElementById('container').setAttribute('state', 'visible');
   </handler>
   <handler event="DOMAttrModified" attr-name="open" attr-change="removal">
    this.shadowTree.getElementById('container').setAttribute('state', 'hidden');
   </handler>
  </handlers>
  <implementation>
   ({
     get open() { return this.boundElement.hasAttribute('open'); },
     set open(val) {
       if (val)
         this.boundElement.setAttribute('open', 'open');
       else
         this.boundElement.removeAttribute('open');
       return this.open;
     },
   })
  </implementation>
  <resources>
   <style>
    #container[state=hidden] { display: none; }
   </style>
  </resources>
 </binding>
</xbl>

Since the examples are all untested (there are no XBL2 implementations at the time of writing), it is quite possible that they have errors. Please report any errors you think you see, so that we can correct the examples.

1.1. Relationship to XBL1

This specification is not backwards compatible with XBL1.

There are numerous changes. However, of particular importance to readers familiar with XBL1, there have been some changes to the element names. In particular, the XBL1 element content is now called template, and the XBL1 element children is now called content.

1.2. Relationship to XSLT

This specification has a similar scope to XSLT. The main differences are:

In addition, XBL can be used for component creation, which is not covered by XSLT.

1.3. Terminology and Conventions

An XBL user agent is an implementation that attempts to support this specification.

A binding is the definition of behavior that can be applied to an element so as to augment its presentation.

The namespace of all the XBL elements and XBL global attributes must be: http://www.w3.org/ns/xbl

An XBL document is an XML document that has the xbl element at its root.

A non-XBL document is an XML document whose root element is from a namespace other than XBL (e.g. XHTML). A non-XBL document can include XBL, if the other languages involved allow it.

An XBL subtree is a subtree in an XML document, the subtree having as its root node an xbl element in the XBL namespace, which is used to define bindings. XBL subtrees can stand alone in XBL documents, or can be included in non-XBL documents.

The term binding document is used to mean either an XBL document or a non-XBL document containing one or more XBL subtrees.

In the following XHTML example, the XBL subtree is the portion of the markup that is emphasized. It is in a non-XBL document, since the root element is an XHTML element.

<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>Demo</title>
  <xbl xmlns="http://www.w3.org/ns/xbl">
   <script><![CDATA[
     function fmt(n) {
       if (n < 10)
         return "0" + n;
       else
         return n;
     }
   ]]></script>
   <binding element=".date">
    <implementation>
      ({
        xblBindingAttached: function() {
          var tm = /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d) UTC$/.exec(this.boundElement.textContent);
          var date = new Date();
          date.setUTCFullYear(parseInt(tm[1], 10));
          date.setUTCMonth(parseInt(tm[2], 10) - 1);
          date.setUTCDate(parseInt(tm[3], 10));
          date.setUTCHours(parseInt(tm[4], 10));
          date.setUTCMinutes(parseInt(tm[5], 10));
          date.setUTCSeconds(0);
          this.boundElement.textContent = date.getFullYear() + "-" +
                                      fmt(date.getMonth() + 1) + "-" +
                                      fmt(date.getDate()) + " " +
                                      fmt(date.getHours()) + ":" +
                                      fmt(date.getMinutes()) + " LT";
          this.boundElement.title = "Adjusted to local time zone"
        },
      })
    </implementation>
   </binding>
  </xbl>
 </head>
 <body>
  <h1>Demo</h1>
  <p class="date">2006-08-10 18:40 UTC</p>
  <p>...</p>
 </body>
</html>

(As an aside, the binding defined in this example causes elements with class="date" to have their content parsed into a UTC date and converted into a local time. The binding mutates the original DOM to do this, and it doesn't reflect any dynamic changes made to the element's content; there are better, albeit slightly more involved, ways of achieving the same effect that don't have these problems.)

A bound element is an XML or HTML element to which a binding has been applied.

In the example above, the first p element is the bound element.

A bound document is an XML or HTML document containing one or more bound elements.

In the example at the top of this section, the document is both the binding document (because it contains the definition of the binding), and the bound document (because it contains the affected bound element). In the example in the introduction section, the HTML file is the bound document, and the XBL file is the binding document.

In this specification, the term in error, typically used of an element or attribute, means that the element, attribute, or other construct is not conformant according to the rules of this specification. Rules for exactly how the construct must be treated when it is in error are always given when the term is used. Typically this will involve ignoring the erroneous nodes, meaning the UA must, for the purposes of XBL processing, act as if those nodes were absent. UAs must not, however, remove such nodes from the DOM in order to ignore them, nor should it change what DOM interfaces those nodes implement. The nodes retain all their non-XBL semantics.

UAs should report all errors to users, although they may do this in an unobtrusive way, for example in an error console.

In addition to the error handling rules given in this specification, UAs may abort all processing when encountering an error.

Aborting is only likely to be a viable error handling mechanism in controlled environments, e.g. in conformance checkers. Web browsers are expected to use the error recovery mechanisms described in this specification, not abort.

A correct element, attribute, value, or binding is one which is not in error.

The following sample XBL document is in error because the script element in XBL is only allowed as a child of the xbl element:

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="demo">
  <script>
   // This example is in error.
   // You are not allowed to put a script element inside
   // a binding element, only inside an xbl element.
   // This is because scripts evaluate in the scope of the
   // entire XBL document, and are therefore not associated
   // with a particular binding.
   function life() {
     return 42;
   }
  </script>
 </binding>
</xbl>

The correct way of doing this would be:

<xbl xmlns="http://www.w3.org/ns/xbl">
 <script>
  // This example is correct.
  function life() {
    return 42;
  }
 </script>
 <binding id="demo">
  <!-- Now you can see that this binding actually does nothing. -->
 </binding>
</xbl>

The term "semantics" is used to refer to the intrinsic meaning or processing model of elements, attributes, events, and DOM interface members. Semantics are defined by specifications; for example, this specification defines the semantics of XBL elements.

XBL elements are frequently referred to by just their local name in this specification. In real documents, they must be associated with the XBL namespace as per the rules given in the Namespaces in XML specification [XMLNS].

For convenience, elements and attributes from specific namespaces are sometimes referred to simply in the form prefix:localname, without explicitly stating which namespace the prefix is bound to. When this occurs, readers should assume the following prefix declarations are in scope:

xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:html="http://www.w3.org/1999/xhtml"

When this specification refers to elements in a namespace, it does not exclude elements in no namespace; the null namespace is considered a namespace like any other for the purposes of XBL processing.

All element names, attribute names, and attribute values in XBL are case sensitive, with the exception of attribute values defined by other specifications (those have the sensitivity defined by those other specifications).

An XML MIME type is text/xml, application/xml, or any MIME type ending with the string +xml (ignoring any MIME parameters).

The terms "author style sheets", "user style sheets", "user agent style sheets", and "pseudo-element" are used as defined by the CSS specifications. [CSS21]

The term "QName" is used as defined by the Namespaces in XML specification. [XMLNS]

The term "view" is used as defined by the DOM2 Views specification. [DOM2VIEWS]

1.4. Conformance

As well as sections marked as non-normative, all diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]

There are two classes of products that can claim conformance to this implementation: XBL subtrees, and XBL user agents.

XBL subtrees must satisfy the constraints described in this specification in order to be considered conformant.

Products that generate XBL subtrees cannot claim conformance to this specification, though they can claim to only produce XBL subtrees that themselves are conformant to this specification.

XBL user agents must behave as described by this specification in order to be considered conformant, even when faced with non-conformant XBL subtrees.

User agents may optimize any algorithm given in this specification, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms. (The algorithms in this specification are generally written with more concern for clarity than over efficiency.)

This specification is defined in terms of the DOM. The language in this specification assumes that the user agent expands all entity references, and therefore does not include entity reference nodes in the DOM. If user agents do include entity reference nodes in the DOM, then user agents must handle them as if they were replaced by their DOM replacement values when implementing this specification.

For example, if a requirement talks about an element's child text nodes, then any text nodes that are children of an entity reference that is a child of that element would be used as well.

1.4.1. Error Handling

This specification describes the rules for processing of XBL elements and related features, whether they are used in a conformant manner or not. Conformant implementations, therefore, will interoperably handle any content, whether valid or not.

1.4.2. Attributes Containing Selectors

The element attribute of the binding element and the includes attribute of the content element, if specified, must have their values parsed according to the rules in the Selectors specification. [SELECTORS]

This specification does not specify what level of Selectors support is required.

Namespace prefixes can be used with selectors. In XBL attributes that take selectors, the namespace prefixes that may be used are the prefixes that are in scope using the xmlns:* syntax. User agents must use the XML namespace prefixes in scope on the attribute's element when parsing selectors with namespace prefixes. The default namespace in selectors in XBL attributes is always unbound. [XMLNS]

The "xml" prefix is defined to always be declared (and bound to the http://www.w3.org/XML/1998/namespace namespace), as is the "xmlns" prefix (which is bound to http://www.w3.org/2000/xmlns/).

Selectors are case-insensitive, but namespace prefixes are case-sensitive. Thus, there could be multiple namespace prefixes declared that match a particular namespace prefix as used in a selector. User agents must act as if all namespace prefixes in scope were lexically sorted by Unicode codepoint, with the first namespace prefix of each group of namespace prefixes differing only by case (using case folding as defined by Unicode) being the one assumed to be in scope for the purposes of selector matching. [UNICODE]

The following excerpt from an XBL document defines a binding that is bound to elements declaring links (e.g. the a element in HTML).

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding element=":link, :visited">
  ...
 </binding>
</xbl>

The following excerpt defines a binding bound to any element in the http://example.com/ namespace that is the child of an element in the http://www.example.net/ namespace with the name parent. (Note that the > character does not have to be escaped.)

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:eg1="http://www.example.net/"
     xmlns:eg2="http://example.com/">
 <binding element="eg1|parent > eg2|*">
  ...
 </binding>
</xbl>

Finally this third example defines a binding that matches elements with the name blockquote, regardless of what namespace they are in. If it is known that the binding document is only ever going to be used from documents that use one namespace, for example if the bindings are always to be imported into HTML documents, then it is easier to just specify the local name (as in this example) and ignore the namespaces.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding element="blockquote">
  ...
 </binding>
</xbl>

1.4.3. Attributes Containing Space-Separated Values

Some attributes are defined as taking space-separated values. The list of values for such attributes must be obtained by taking the attribute's value, replacing any sequences of U+0020, U+000A, and U+000D characters (in any order) with a single U+0020 SPACE character, dropping any leading or trailing U+0020 SPACE character, and then chopping the resulting string at each occurrence of a U+0020 character, dropping that character in the process.

A space-separated attribute whose value is the empty string, or which consists of only U+0020, U+000A, and U+000D characters, has no values.

In the attribute button="1 2", the values are "1" and "2".

In the attribute class="  key - note - rocks", there are five keywords: "key", "note", "rocks", and two occurrences of the single-character keyword "-".

1.4.4. Attributes Containing MIME Types

Some attributes are defined as containing MIME types. A valid MIME type is one that matches the production for valid-MIME-type in the following EBNF:

valid-MIME-type := type "/" subtype *(";" parameter)

...where the type, subtype, and parameter tokens are those defined in RFC 2045. [RFC2045]

1.4.5. Attributes Containing URIs

Some attributes, pseudo-attributes, and method arguments are defined as specifying URIs. Such attributes must have values that match the URI token of RFC 3986 or the IRI token of RFC 3987. If they do not, they are in error (though the processing of erroneous URIs varies depending on the context). [RFC3986] [RFC3987]

1.4.6. Attributes Containing Keywords

Certain attributes are defined as requiring certain values, e.g. true or false. For such attributes, the values must be specified exactly, in the case given in this specification, and with no leading or trailing whitespace. Implementations must only perform literal comparisons, and must not use case-insensitive comparisons nor trim attribute values before comparison.

1.4.7. Extension Mechanisms

XBL2 does not have an extension mechanism; implementations that recognise elements in the XBL namespace that aren't part of this specification, or attributes that aren't part of this specification in the per-element partition of elements in the XBL namespace, are non-conforming. If UAs support features in other namespaces that affect the XBL processing model in a way that contradicts this specification, then they are not conforming either.

1.4.8. Feature Strings for the DOM and SVG

XBL2 user agents must recognise the string "XBL" as being a DOM feature corresponding to support of XBL2 and its corresponding DOM APIs. Support for this specification must be treated as support for versions "1.0" and "2.0" of the "XBL" feature in terms of versions for the hasFeature() DOM Core method.

XBL2 user agents that also implement SVG must recognise the following string as being a language extension URI for the purposes of SVG requiredExtensions evaluation: http://www.w3.org/ns/xbl#v2

1.5. Security Concerns

This section is non-normative.

XBL raises a number of security concerns.

Data theft: A naïve implementation of XBL would allow any document to bind to bindings defined in any other document, and (since referencing a binding allows full access to that binding document's DOM) thereby allow access to any remote file, including those on intranet sites or on authenticated extranet sites.

XBL itself does not do anything to prevent this. However, it is strongly suggested that an access control mechanism (such as that described in [ACCESSCONTROL]) be used to prevent such cross-domain accesses unless the remote site has allowed accesses.

Privilege escalation: In conjunction with data theft, there is the concern that a page could bind to a binding document on a remote site, and then use the privileges of that site to obtain further information. XBL prevents this by requiring that the bindings all run in the security context of the bound document, so that accessing a remote binding document does not provide the bound document with any extra privileges on the remote domain.

Cookie theft: Related to privilege escalation is the risk that once an access-controlled binding document hosted on a remote site has been loaded, authentication information stored in cookies for that domain would become accessible to the bound document. XBL prevents this by requiring that the cookie attribute on the DocumentWindow interface be set to null.

Secure bindings: Using XBL for bindings that need access to the local filesystem, e.g. for implementing File Upload form controls, is not yet handled by this specification. However, a future version will provide a secure way to define an XBL binding that can be used to implement privileged mechanisms that can then be used by other bindings to provide such controls.

2. XBL Elements

The start of any XBL subtree is an xbl element, which is described below.

When an XBL element is found inside an element other than those listed under the "Expected contexts" list in the definitions below, it is in error. When an XBL element has a child node that does not satisfy the "Expected children" list in its definition (for instance because it is the wrong node type, wrong element type, or because too many elements of its type preceded it), the child is in error. In both cases, being in error means that the UA must, for the purposes of XBL evaluation, treat the XBL subtree as it would if the erroneous node and all its descendants were not present in the DOM.

However, non-XBL elements retain their semantics, even when considered to be in error for the purposes of XBL.

Regardless of the requirements of the last few paragraphs and of the "expected children" lines, comment nodes, and text and CDATA nodes containing only whitespace characters, may always be given as children of XBL elements.

For cases where attributes on XBL elements do not conform to this specification or (for namespaced attributes) to another specification, and for cases where attributes in the XBL namespace are found on elements other than those listed as their "Expected element" in the definitions below, the error handling is similar: the attributes must be considered to be in error and the UA must ignore them, meaning that the presence of these non-conforming attributes in no way affects the XBL processing.

Further error handling rules for more specific cases are given where appropriate.

XBL user agents that support CSS should act as if they had the following rules in their UA style sheet:

@namespace xbl url(http://www.w3.org/ns/xbl);
xbl|* { display: none; }
xbl|div { display: block; }

XBL user agents that do not support CSS should not render the XBL elements other than the div element, which they should render as a paragraph-like element.

The following sections describe the content model of XBL elements, but not their actual processing model. The processing model for XBL is described in later sections.

2.1. The xbl Element

Expected contexts:
In an XBL document, none (this is the root element).
In a non-XBL document, any non-XBL element whose specification allows the xbl element as a child.
Expected children (in any order):
binding: zero or more.
script: zero or more.
Any non-XBL element.

The xbl element is the root element of all XBL subtrees.

Attributes

id
The id attribute.
script-type
The script-type attribute specifies the MIME type of the scripting language used by all bindings and XBL script blocks in the XBL subtree. The value must be a valid MIME type. If the attribute is not specified, the default language is ECMAScript. [ECMA262]
style-type
The style-type attribute specifies the MIME type of the styling language used by all bindings and XBL style blocks in the XBL subtree. The value must be a valid MIME type. If the attribute is not specified, the default language is CSS (text/css).

UAs must consider any xbl elements that have another xbl element as an ancestor as being in error and must then ignore them, meaning those elements must never be considered to declare any bindings.

For example, conforming UAs will never bind elements to bindings defined by binding elements that have two xbl ancestors.

Similarly, XBL elements (other than the xbl element itself) that do not have a correct xbl element as an ancestor are in error too, and UAs must ignore them.

For example, conformant UAs will never bind elements to bindings defined by binding elements that have no xbl ancestors at all.

The same does not apply to the style-type and script-type attributes. If the UA does not support the specified styling language (or has styling disabled), it must still apply bindings as appropriate; only style blocks must be ignored. Similarly, if the UA does not support the specified scripting language (or has scripting disabled), it must still apply bindings as appropriate; only script, handler and implementation sections must be ignored.

The empty string is not a special value for these attributes. Setting the style-type attribute to the empty string, e.g., will result in all style blocks being ignored, since the empty string is not a valid MIME type that the UA supports.

The following document defines two bindings, one using Perl as the scripting language and the other using JavaScript. The second one extends the first one. (This example assumes that text/x-perl refers to Perl. Note that this specification doesn't actually define how Perl-based bindings are to be supported by the UA; the code below assumes that an implementation element takes an anonymous Perl package and blesses a hash to that package for each binding, but this is nothing but conjecture.)

<root>
 <xbl xmlns="http://www.w3.org/ns/xbl"
      script-type="text/x-perl">
  <binding id="validityImplementor">
   <implementation>
    use strict;
    use vars qw(@ISA);
    @ISA = qw(XBLImplementation);
    sub validate {
      my $self = shift;
      my $data = $self->{boundElement}->getAttribute('value');
      my $pattern = $self->{boundElement}->getAttribute('pattern');
      return $data =~ m/^(?:$pattern)$/s;
    }
   </implementation>
  </binding>
 </xbl>
 <xbl xmlns="http://www.w3.org/ns/xbl">
  <binding id="validityClassifier" extends="#validityImplementor">
   <handlers>
    <handler event="change">
     if (this.baseBinding.validate())
       this.boundElement.className = 'valid';
     else
       this.boundElement.className = 'invalid';
    </handler>
   </handlers>
  </binding>
 </xbl>
</root>

(What these bindings do is somewhat boring. The first does nothing except expose a "validate()" method that returns true if the contents of the element's value attribute matches the regular expression in the element's pattern attribute. The second makes the binding call this method every time the change event bubbles through the element, and changes the element's class attribute based on the return value.)

2.2. The binding Element

Expected context:
xbl
Expected children (in any order):
implementation: zero or one.
template: zero or one.
handlers: zero or one.
resources: zero or one.
Any non-XBL element

The binding element describes a single XBL binding that adds presentation and interactive behavior to XML or HTML elements. Each binding has these optional components:

Methods, Properties, and Fields: A binding can specify additional methods that can be invoked on the element. It can also specify additional properties and fields that can be retrieved or set on the element. In this way the functionality of the bound element becomes extensible. (See: binding implementations.)

Template: The optional template defines the initial shadow content for the bound element.

Behavior: A binding can define event listeners for various types of events. Some examples are: UI events (e.g., key and mouse events) on the bound element or on elements within the shadow content, and mutation events on the bound element and its descendants. (See: event handlers.)

Resources: A binding can list style sheets that are scoped to the bound element, and images, sounds, videos, or other files that a user agent can pre-cache in order to improve performance. (See: binding style sheets, prefetching resources.)

Bindings can act as an attachment mechanism, specifying a namespace and local name of elements to associate with the given binding when the binding is imported, using the element attribute.

In addition to the above, the binding element's child nodes may include any element outside the XBL namespace. These are handled as they would be in any other context, and are ignored by the XBL processing model.

Attributes

id
The id attribute.
extends
The extends attribute is used to specify the URI of a binding that this binding inherits from. (See: interpretation of URIs to XBL bindings.) If the URI is in error or does not refer to another binding, the UA must ignore it, meaning that this binding does not explicitly inherit from another binding. (See: explicit inheritance.) Only one URI can be specified.
element

This attribute, if specified, must contain a selector. All elements in the binding document, and in any documents that import the binding document, that match the given selector, must be bound to the binding defined by this binding element. (The element's own shadow tree, if any, must not be taken into account when determining if it matches a selector for the purposes of this attribute.)

If an element attribute contains an invalid selector, it is in error and must be ignored, meaning that while the binding is still parsed and may be referenced using other attachment mechanisms, the binding is not attached to any element by its element attribute, as if the attribute had simply been omitted.

The binding element defines a presentation and behavior binding. It does not define an element's semantics. If an element has no semantics when processed alone, then it has no semantics when processed with XBL.

Sending markup that does not have well-defined semantics over the network is bad practice. XBL is intended to be used to augment the user experience, for instance by providing better quality widgets or enhancing aesthetics. If the document being sent is unusable without XBL, then XBL is being abused.

This binding extends a binding defined in an external file. The binding in the other file defines a value property, and fires events when that property is changed. This binding just implements a check box that all checkbox elements in the http://ui.example.com/ namespace will be bound to.

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:ui="http://ui.example.com/">
 <binding element="ui|checkbox" id="checkbox"
          extends="http://www.example.org/resources/ui-core.xml#valuedControl">
  <template>
   <div id="wrapper">
    <div id="control"/>
    <div id="label"><content/></div>
   </div>
  </template>
  <resources>
   <style>
    #wrapper > div { display: inline-block; }
   </style>
  </resources>
  <handlers>
   <handler event="click" phase="default-action">
    if (this.baseBinding.value == 'on')
      this.baseBinding.value = 'off';
    else
      this.baseBinding.value = 'on';
   </handler>
   <handler event="change" phase="target">
    if (this.baseBinding.value == 'on')
      this.shadowTree.getElementById('control').textContent = '☑';
    else
      this.shadowTree.getElementById('control').textContent = '☐';
   </handler>
  </handlers>
 </binding>
</xbl>

2.3. The implementation Element

Expected context:
binding
Expected children:
If the element has no src attribute: depends on the scripting language.
If the element does have a src attribute: none.

The implementation element describes a set of methods, properties, and fields that are attached to the bound element. Once the binding is attached, these methods, properties, and fields can be invoked directly from the bound element.

The implementation element, if present, must either contain code in the language specified by the XBL subtree's script-type attribute, or have a src attribute that points to a resource containing code in the language specified by the script-type attribute. The syntax and semantics of this code depend on the specific language. This specification defines the semantics for ECMAScript implementations. (See: binding implementations.)

Attributes

id
The id attribute.
src
The src attribute specifies the URI to a resource of the type given by the XBL subtree's script-type attribute. If the attribute is specified, the contents of the element must be ignored (even if the resource could not be fetched or was of the wrong type). (See: binding implementations.)

If an implementation element is marked (via the script-type attribute of the xbl element) as being in a language that the UA does not support, then the UA must ignore it. Similarly, if the implementation element points (using the src attribute) to a resource that is either unavailable, or not of the type specified by the script-type attribute of the xbl element (or implied by its absence), then it is in error and the UA must ignore it. In both cases, "ignoring it" means it must not be used as an implementation definition for any binding.

How UAs must handle nodes inside implementation elements depends on the language used. (See: loading and running scripts, binding implementations.)

implementation blocks are evaluated once, on first use. Changes to an implementation element or its contents have no effect once the element has been evaluated. (See: binding implementations.)

The following example shows a binding that defines a new method, two new properties (one with a custom getter and setter, one without), an internal field (used to back the property), and some hooks to initialize the binding and to handle the bound element being inserted and removed from the document. The binding applies to any element with the class "demo" (in the files into which it is imported, that is).

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding element=".demo">
  <implementation>
   ({
      add: function (op1, op2) {
        return op1+op2;
      },
      get memory() {
        return this._memory.toString();
      },
      set memory(value) {
        this._memory = parseInt(value, 10);
      },
      xblBindingAttached: function() {
        this._memory = 0; // private property to back "memory" public property
        this.public.state = 'initialized'; // public property
      },
      xblEnteredDocument: function() {
        this.public.state = 'in document';
      },
      xblLeftDocument: function() {
        this.public.state = 'out of document';
      },
   })
  </implementation>
 </binding>
</xbl>

The get field() {} and set field(syntax) {} features are part of JavaScript 1.5 and will probably be in ECMAScript 4. The examples in this specification assume an implementation that supports ECMAScript 4, but any language could be supported in real implementations.

The following example shows how to refer to an external file for the implementation of a binding. In this example, the handlers simply defer to methods defined in that implementation, so that all the code is in that file.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="demo">
  <implementation src="demo.js"/>
  <handlers>
   <handler event="click"> this.clicked(event); </handler>
   <handler event="focus"> this.focused(event); </handler>
   <handler event="blur">  this.blurred(event); </handler>
  </handlers>
 </binding>
</xbl>

The demo.js file for this might look like this, to ensure that the methods defined are in fact internal methods, not exposed on the public object:

({
  xblBindingAttached: function () {
    this.clicked = function (event) { ... };
    this.focused = function (event) { ... };
    this.blurred = function (event) { ... };
  },
  // ... other methods and fields ...
})

2.4. The template Element

Expected context:
binding
Expected children:
Anything. Of particular interest, the content and inherited elements may occur as descendants, and non-XBL descendant elements may host xbl:attr and xbl:pseudo attributes.

The template element contains child nodes that can be in any namespace. When a binding is attached, the template element's child nodes are cloned and attached to the bound document under the bound element. Dynamic changes to the descendants of template elements are reflected in bindings. (See: shadow content.)

Attributes

id
The id attribute.
apply-author-sheets
The apply-author-sheets attribute indicates whether or not rules in author style sheets associated with the bound element's document apply to the shadow content generated by the binding. Its value must be either true (indicating that they do) or false (indicating that they do not). The default behavior, which is used when the attribute is omitted or has a value other than the two allowed values, is to not apply the bound document's author style sheets (same as false). (See: binding style sheets.)
allow-selectors-through
The allow-selectors-through attribute indicates whether or not rules in CSS can cross scopes. Its value must be either true (indicating that they can) or false (indicating that they cannot). The default behavior, which is used when the attribute is omitted or has a value other than the two allowed values, is to not let selectors cross scopes (same as false). (See: selectors and shadow scopes.)

The semantics of non-XBL elements inside this element are untouched, which can lead to unintuitive results. (See: semantics of non-XBL elements in XBL contexts.)

The following binding defines a shadow tree that wraps the contents of the bound element in four blocks. It uses the apply-author-sheets attribute to allow the bound document to style the nodes directly, and uses the allow-selectors-through attribute to allow the bound document to pretend (for the purposes of selector matching) that the shadow tree actually is descended from the bound element.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="wrapBy4">
  <template apply-author-sheets="true" allow-selectors-through="true">
   <div class="wrap1">
    <div class="wrap2">
     <div class="wrap3">
      <div class="wrap4">
       <content/>
      </div>
     </div>
    </div>
   </div>
  </template>
 </binding>
</xbl>

Using this binding could take the following document:

<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>Pretty Title</title>
  <style>
   h1 span { display: block; }
   h1 { border: solid red; }
   h1 .wrap1 { border: solid orange; }
   h1 .wrap2 { border: solid yellow; }
   h1 .wrap3 { border: solid green; }
   h1 .wrap4 { border: solid blue; }
  </style>
 </head>
 <body>
  <h1>
   <span class="wrap1">
    <span class="wrap2">
     <span class="wrap3">
      <span class="wrap4">
       Pretty Title
      </span>
     </span>
    </span>
   </span>
  </h1>
  ...
 </body>
</html>

...and shrink it to this:

<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>Pretty Title</title>
  <style>
   h1 { -xbl-binding: url(cool.xml#wrapBy4); }
   h1 { border: solid red; }
   h1 .wrap1 { border: solid orange; }
   h1 .wrap2 { border: solid yellow; }
   h1 .wrap3 { border: solid green; }
   h1 .wrap4 { border: solid blue; }
  </style>
 </head>
 <body>
  <h1>Pretty Title</h1>
  ...
 </body>
</html>

...which removes the semantic-free elements used as presentation hooks from the content markup layer, and places them in the presentation layer where they belong.

2.5. The content Element

Expected context:
Any, but there must be a correct template element somewhere in the ancestor chain, and there must not be any correct content elements anywhere in the ancestor chain.
Expected children:
Anything.

The content element is used inside shadow content to specify where explicit children that might already exist underneath the bound element are inserted into the shadow tree. As far as the presentation model is concerned, any shadow content the binding places between the bound element and the content elements is interleaved between the bound element and its explicit children without affecting the document model.

If the includes attribute has children of the bound element assigned to it, then those children are inserted into the final flattened tree in place of the content element. Otherwise, the child elements of the content element are inserted into the final flattened tree in place of the content element instead. (See: processing content elements.)

Attributes

id
The id attribute.
includes
The includes attribute can be used to indicate that only certain content should be placed at the content element. Its value must be a valid selector. (See: processing content elements.)
apply-binding-sheets
The apply-binding-sheets attribute indicates whether or not scoped style sheets loaded for an XBL binding are applied to a bound element's explicit children (in addition to the bound element itself) that are inserted below this content element when it is processed. Its value must be either true (indicating that they are) or false (indicating that they are not). The default behavior, which is used when the attribute is omitted or has a value other than the two allowed values, is that they are not applied (same as false). (See: binding style sheets.)
locked
The locked attribute indicates whether or not new children may be inserted below this content element when it is processed. Its value must be either true (indicating that they may not) or false (indicating that they may). The default behavior, which is used when the attribute is omitted or has a value other than the two allowed values, is that they may be inserted (same as false). Elements already assigned to a content element whose locked attribute is dynamically changed are not removed from that element. (See: processing content elements.)

This sample extract from a binding document shows how to use the includes attribute to distribute children to different parts of a shadow content template.

<xbl:xbl xmlns:xbl="http://www.w3.org/ns/xbl"
         xmlns:data="http://example.com/data-language">
 <xbl:binding element="data|grid">
  <xbl:template>
   <xbl:div class="caption" xbl:attr="xbl:text=title"/>
   <xbl:div class="outer-table">
    <xbl:div class="columns">
     <xbl:content includes="data|column">
      <!-- default to have just one column if none are declared -->
      <data:column/>
     </xbl:content>
    </xbl:div>
    <xbl:div class="rows">
     <xbl:content includes="data|heading"/>
     <xbl:div class="body">
      <xbl:content includes="data|row:not([hidden])"/>
     </xbl:div>
    </xbl:div>
   </xbl:div>
  </xbl:template>
  ...
 </xbl:binding>
 ...
</xbl:xbl>

The above template would be used with markup such as the following:

<data xmlns="http://example.com/data-language">
 ...
  <grid title="The Lesser of Two Evils">
   <column id="product" sort="alphabetic primary"/>
   <column id="catchphrase" sort="alphabetic secondary"/>
   <heading>
    <item>Product</item>
    <item>Catchphrase</item>
   </heading>
   <row>
    <item>Arachno Spores</item>
    <item>The fatal spore with the funny name</item>
   </row>
   <row>
    <item>Pastorama</item>
    <item>Located on the former site of Brooklyn</item>
   </row>
  </grid>
 ...
</data>

The following illustrates how the above markup would get redistributed.

The two column elements would get put under the div with
     class columns; the heading element and its descendants would end up at
     the start of the div with class rows, and the two row elements would end
     up under the div with class rows.

In this example, the binding uses the apply-binding-sheets attribute to let its stylesheet affect the explicit children of the bound element.

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:ui="http://example.org/ui-language/">
 <binding element="ui|listbox">
  <template allow-selectors-through="true">
   <div id="listbox-focus">
    <content includes="ui|listitem" apply-binding-sheets="true"/>
   </div>
  </template>
  <resources>
   <style>
    @namespace xbl url(http://www.w3.org/ns/xbl);
    @namespace uil url(http://example.org/ui-language/);
    uil|listbox { display: block; background: white; color: black; }
    uil|listbox > xbl|div#listbox-focus { border: ridge silver; }
    uil|listbox:focus > xbl|div#listbox-focus { border: inset silver; }
    uil|listitem { display: block; background: white; color: black; }
    uil|listitem[selected] { display: block; background: navy; color: white;}
   </style>
  </resources>
  ...
 </binding></xbl>

In the following example, the locked attribute is used to keep the children of the bound element in the location that the user has selected. By default, the listitem elements would be placed in the first content element, but because it is locked, they will instead go into the second one.

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:ui="http://example.org/ui-language/">
 <binding element="ui|duallist">
  <template>
   <div>
    <ui:listbox id="left" title="Selected Items">
     <content includes="ui|listitem" locked="true" id="leftList"/>
    </ui:listbox>
   </div>
   <div id="buttons">
    <ui:button id="move-right"> Move Right </ui:button>
    <ui:button id="move-left"> Move Left </ui:button>
   </div>
   <div>
    <ui:listbox id="right" title="Available Items">
     <content includes="ui|listitem" id="rightList"/>
    </ui:listbox>
   </div>
  </template>
  <implementation>
   ({
     xblBindingAttached: function() {
       this.shadowTree.getElementById('move-right').addEventListener(
         'click', this.moveRight, false
       );
       this.shadowTree.getElementById('move-left').addEventListener(
         'click', this.moveLeft, false
       );
     },
     moveRight: function(event) {
       this.shadowTree.getElementById('rightList').setInsertionPoint(
         this.shadowTree.getElementById('left').selectedElement
       );
     },
     moveLeft: function(event) {
       this.shadowTree.getElementById('leftList').setInsertionPoint(
         this.shadowTree.getElementById('right').selectedElement
       );
     },
   })
  </implementation>
 </binding>
</xbl>

2.6. The inherited Element

Expected context:
Any, but there must be a correct template element somewhere in the ancestor chain.
Expected children:
Anything.

The inherited element represents where the next inherited shadow tree is to be inserted. If the binding is the base binding (and thus has no inherited bindings) or if none of the bindings it inherits from have shadow trees, or if this is not the first inherited element in the binding's shadow tree, then the contents of the inherited element (if any) will be used instead. (See: the final flattened tree.)

Attributes

id
The id attribute.

While it is legal to nest inherited elements, it is pointless, since if one inherited element used its fallback content, any subsequent such elements will too.

The following binding wraps the bound element's children in a set of divs for extra styling. By using the inherited element, it has been designed such that it must be used in conjunction with other bindings: it will (if applied after the others) wrap the shadow trees of those templates. Contrast this with the example in the template section, which would not interact with other bindings. However, if this binding is not applied in conjunction with a binding that has a content element giving a place for the element's explicit children, then those children will not be in the final flattened tree.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="wrapBy4">
  <template apply-author-sheets="true" allow-selectors-through="true">
   <div class="wrap1">
    <div class="wrap2">
     <div class="wrap3">
      <div class="wrap4">
       <inherited/>
      </div>
     </div>
    </div>
   </div>
  </template>
 </binding>
</xbl>

2.7. The xbl:attr Attribute

Expected element:
Any, but there must be a correct template element somewhere in the ancestor chain.

The xbl:attr attribute is a global attribute in the XBL namespace that specifies which attributes on the bound element should be forwarded to the element on which the attribute is found when the shadow content template is cloned. It is a space-separated list of QNames or QName pairs separated by equal signs, each possibly suffixed by a hash character ("#") and a type designation. (See: attribute forwarding.)

The value of the xbl:attr attribute must be a space-separated value of items that match the pattern given in the attribute forwarding section.

One of the major uses of the xbl:attr attribute is to implement one element in terms of another element which already has special behavior in user agents. This example shows how a ui:text element can be implemented in terms of an html:input element, with certain attributes being forwarded to that element directly.

<xbl:xbl xmlns:xbl="http://www.w3.org/ns/xbl"
         xmlns:ui="http://example.com/ui-language/"
         xmlns:html="http://www.w3.org/1999/xhtml">
 <xbl:binding element="ui|text">
  <xbl:template>
   <html:label>
    <html:span xbl:attr="xbl:text=label"/>
    <html:input xbl:attr="value=default disabled readonly" id="input"/>
   </html:label>
  </xbl:template>
  <xbl:implementation>
   ({
    get value () { return this.shadowTree.getElementById('input').value; },
    set value (val) { this.shadowTree.getElementById('input').value = val; },
   })
  </xbl:implementation>
 </xbl:binding>
</xbl:xbl>

2.8. The xbl:pseudo Attribute

Expected element:
Any, but there must be a correct template element somewhere in the ancestor chain.

The xbl:pseudo attribute is a global attribute in the XBL namespace that specifies the pseudo-element that, when used on the bound element, must be mapped to the element on which the attribute is found.

The value of the xbl:pseudo attribute must be a valid pseudo-element name, in lowercase, without the leading "::". The valid pseudo-elements are defined by the CSS specifications, and are "value", "choices", "label", "repeat-item", and "icon". Future versions of CSS might introduce new values. (See: matching pseudo-elements.)

The xbl:pseudo attribute is useful as a way to let author styles affect the insides of a shadow tree without exposing the exact construction of the tree. Here, the binding represents a composite widget with an icon, a label, a text field, and some buttons. Pseudo-elements are used for each part allowing the author to style each part separately.

<xbl:xbl xmlns:xbl="http://www.w3.org/ns/xbl"
         xmlns:html="http://www.w3.org/1999/xhtml">
 <xbl:binding id="input-dialog">
  <xbl:template>
   <xbl:div class="root">
    <xbl:div class="icon-block">
     <html:img xbl:pseudo="icon" xbl:attr="src=icon alt=alt"/>
    </xbl:div>
    <xbl:div xbl:pseudo="label" xbl:attr="xbl:text=label"/>
    <xbl:div class="field-block">
     <html:input xbl:pseudo="value" xbl:attr="value" id="field"/>
    </xbl:div>
    <xbl:div class="buttons-block">
     <html:button xbl:pseudo="choices" id="ok"> OK </html:button>
     <html:button xbl:pseudo="choices" id="cancel"> Cancel </html:button>
    </xbl:div>
   </xbl:div>
  </xbl:template>
  ...
 </xbl:binding>
</xbl:xbl>

An author-level stylesheet for a document using the binding might look like:

textDialog { -xbl-binding: url(dialogs.xml#input-dialog); }
textDialog::value { background: white; color: black; }
textDialog::choices { border: outset; }

2.9. The div Element

Expected contexts:
template
content
inherited
div
Expected children:
Anything. Of particular interest, the content and inherited elements may occur as descendants, and non-XBL descendant elements may host xbl:attr and xbl:pseudo attributes.

The div element has no intrinsic meaning. It is intended to be used as a styling hook for presentational bindings.

Attributes

id
The id attribute.
class
A space-separated list of keywords relevant to the element that could be useful as stylistic hooks. This is a "class" attribute (which means, for example, that the CSS "." shorthand can be used to match div elements based on their class attribute). The class attribute doesn't apply to other XBL elements, only to div.
state
A free-form attribute with no predefined meaning that can be used as a stylistic hook, to store state, or for other purposes as desired by the binding author.
title
Text representing advisory information that the user agent should show to the user upon request (e.g., on a graphical browser, the contents of this attribute could be shown as a tooltip when the user indicates the element with a mouse pointer). The title attribute doesn't apply to other XBL elements, only to div.

The div element in XBL is not the same element type as the div element in HTML, but it is intended to be used in similar ways (and shares the name for that reason).

Many of the examples in this specification use the div element.

The following example uses the state attribute so that the CSS style sheet can render the shadow tree differently based on whether the switch that the binding represents is turned on or off.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="switch">
  <template>
   <div class="wrapper">
    <div id="main" state="off"/>
   </div>
  </template>
  <handlers>
   <handler event="click">
    this.shadowTree.getElementById('main').setAttribute('state',
      this.shadowTree.getElementById('main').getAttribute('state') == 'on' ?
      'off' : 'on');
   </handler>
  </handlers>
  <resources>
   <style>
    #main[state=off] { ... }
    #main[state=on] { ... }
   </style>
  </resources>
 </binding>
</xbl>

2.10. The handlers Element

Expected context:
binding
Expected children:
handler: zero or more.

The handlers element's event handlers can be called for events that flow through the bound element. During capture, target, bubbling, and default phases, when a given event is received by a bound element, if a corresponding event listener has been attached to the handlers element, then the event will be forwarded to that event listener. (See: event forwarding, binding attachment and detachment.)

Typically, event handlers are defined using handler elements.

Attributes

id
The id attribute.

The following example shows how handlers can be used with any event listener mechanism.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="test">
  <handlers id="test-handlers"/>
  ...
 </binding>
 <script>
  document.getElementById('test-handlers').addEventListener('click', function (event) {
    // this will get called for every click event that bubbles through 
    // any element that is bound to the "test" binding above.
    ...
  }, false);
 </script>
</xbl>

2.11. The handler Element

Expected context:
handlers
Expected children:
Depends on the scripting language.

The handler element describes a single event handler. This handler is attached to its parent handlers element, which is used as an event forwarding target when handling events on the bound element. (See: event handlers.) It wraps a script that is executed when the event handler is matched.

Attributes

id
The id attribute.
event
The event attribute describes the specific event that this handler is listening for. (See: registering event handlers with the handler element.)
phase
This attribute specifies the phase of the event flow that this handler should monitor. When specified, the value must be one of capture, target, bubble, or default-action. If capture is specified, then the event handler must only be fired during the capturing phase of event propagation. If target is specified, then the event handler must only be fired during the target phase. If default-action is specified, then the event handler must only be fired during the default phase (if it occurs). Otherwise, the handler must only be fired during the bubbling phase. (See: registering event handlers with the handler element.)
trusted
This attribute specifies whether the handler should be limited to trusted events. When specified, it must have the value true or the value false. If true is specified, then the event handler must only be fired if the event's trusted attribute is true. Otherwise, the value of the trusted flag does not affect the event handler. (See: registering event handlers with the handler element.)
propagate
The propagate attribute specifies whether after processing all listeners at the current node, the event is allowed to continue on its path (either in the capture or the bubble phase). When specified, it must have the value stop or the value continue. If the value is stop, then propagation will be stopped, otherwise it won't. It has no effect if the phase attribute has the value default-action. (See: registering event handlers with the handler element.)
default-action
The default-action attribute specifies whether after processing of all listeners for the event, the default action for the event (if any) should be performed or not. (See: registering event handlers with the handler element.)
button
The button attribute imposes a filter on the handler. It is used with mouse handlers to specify a particular button. (See: mouse event handler filters.)
click-count
The click-count attribute imposes a filter on the handler. It is used with mouse handlers to specify how many clicks must have occurred. (See: mouse event handler filters.)
modifiers
The modifiers attribute imposes a filter on key and mouse handlers. It is used with mouse and key handlers to specify particular modifier keys. (See: mouse event handler filters, key event handler filters, modifiers.)
key
The key attribute imposes a filter on key handlers. It is used with key handlers to specify which keys to listen for. (See: key event handler filters.)
key-location
The key-location attribute imposes a filter on key handlers. It is used with key handlers to specify which keys to listen for. (See: key event handler filters.)
text
The text attribute imposes a filter on text input handlers. It is used with text input handlers to specify which characters to listen for. (See: text input event handler filters.)
prev-value
The prev-value attribute imposes a filter on mutation handlers. It is used with mutation handlers to specify what prev-value to listen for. (See: mutation event handler filters.)
new-value
The new-value attribute imposes a filter on mutation handlers. It is used with mutation handlers to specify what new-value to listen for. (See: mutation event handler filters)
attr-name
The attr-name attribute imposes a filter on mutation handlers. It is used with attribute mutation handlers to specify which attribute to listen to for changes. (See: mutation event handler filters)
attr-change
The attr-change attribute imposes a filter on mutation handlers. It is used with attribute mutation handlers to specify the type of change to listen for. (See: mutation event handler filters.)

If a handler element is marked (via the script-type attribute of the xbl element) as being in a language that the UA does not support then the UA must ignore it, meaning it must not be used for the event handler definitions of any binding.

How UAs must handle nodes inside handler elements depends on the language used. (See: loading and running scripts, event handlers.)

handler blocks are evaluated each time they are fired. Changes to the handler elements therefore take effect the next time the event is fired.

The following binding implements a link which, when clicked once with the primary button and with no key modifiers, or, when focused and sent a keypress of the Enter key with no modifiers, will cause the link to be followed.

It will only do this if the click or the keypress is a real event triggered by the user; it won't do it for events faked by script. However, if the event faked by script is a DOMActivate event, then it will follow the link, because the handler for the DOMActivate event doesn't check that the event is trusted. (If it did, it would never fire, because the event is dispatched by the binding, and therefore is not trusted.)

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="events">
  <handlers>
   <handler event="click" phase="default-action"
            button="1" click-count="1" modifiers="none"
            trusted="true">
    this.activate();
   </handler>
   <handler event="keypress" phase="default-action"
            key="Enter" modifiers="none"
            trusted="true">
    this.activate();
   </handler>
   <handler event="DOMActivate" phase="default-action">
    if (event.target == this.boundElement)
      this.boundElement.document.location.href = this.href;
   </handler>
  </handlers>
  ...
  <!-- it is assumed that the implementation for this binding
       implements a .activate() method that fires the DOMActivate
       event on itself. -->
 </binding>
</xbl>

2.12. The resources Element

Expected context:
binding
Expected children (in any order):
style: zero or more.
prefetch: zero or more.

The resources element contains a list of style sheets to apply when using this binding, as well as a list of files (images, videos, sound files, etc) to optionally preload.

Attributes

id
The id attribute.

2.13. The style Element

Expected context:
resources
Expected children:
If the element has no src attribute: depends on the styling language.
If the element does have a src attribute: none.

The style element is used to specify a style sheet that is to be applied to the bound element and to the shadow content generated by the binding, as well as to any explicit children (and their descendants) assigned to content elements in the shadow content whose apply-binding-sheets attribute is set.

The style element in XBL never applies styles to elements in the bound document other than the bound element (and possibly its children). It never affects any ancestors of the bound element, or any nodes in any other bindings or binding templates.

Attributes

id
The id attribute.
media
The media attribute specifies the intended destination medium for style information. If specified, the value of the attribute must be a valid Media Query (media_query token). How the value of this attribute is interpreted is defined by Media Queries. If this attribute is not specified, then there is no restriction on which media the style sheet should be applied to (same as specifying media="all"). [MQ]
src
The src attribute specifies the URI to a resource of the type given by the XBL subtree's style-type attribute. If the attribute is specified, the contents of the element must be ignored (even if the resource could not be fetched or was of the wrong type). (See: binding style sheets.)

If a style element is marked (via the style-type attribute of the xbl element) as being in a language that the UA does not support, the UA must ignore it. Similarly, if the style element points (using the src attribute) to a resource that is either unavailable, or not of the type specified by the style-type attribute of the xbl element (or implied by its absence), then it is in error and the UA must ignore it. In both cases, "ignoring it" means it must not be used to style anything.

How UAs must handle nodes inside style elements depends on the language used. (See: binding style sheets.)

For a summary of the various ways that content can be styled in the presence of XBL, see the styling summary section.

2.14. The prefetch Element

Expected context:
resources
Expected children:
None.

The prefetch element can be used to list resources that may be pre-loaded for performance reasons.

Support for this element is optional. UAs may ignore it.

Attributes

id
The id attribute.
src
A URI to a resource (such as an image) that the binding might use later.

The following binding uses two images; it sets the source of an HTML img element programatically to refer to those images. To increase the chance that the "green.png" image is available straight away when it is used, it uses a prefetch element and specifies that that image will be needed.

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:html="http://www.w3.org/1999/xhtml">
 <binding id="light">
  <template>
   <html:img id="l" src="red.png" alt=""/>
  </template>
  <resources>
   <prefetch src="red.png"/> <!-- this one isn't necessary, since
    the UA will fetch this one as soon as it sees the <img> element -->
   <prefetch src="green.png"/>
  </resources>
  <implementation>
   ({
      red: function() {
        this.shadowTree.getElementById('l').src = 'red.png';
      },
      green: function() {
        this.shadowTree.getElementById('l').src = 'green.png';
      },
   })
  </implementation>
 </binding>
</xbl>

This binding might be used as follows:

<!DOCTYPE HTML>
<html>
 <head>
  <title>Light Demo</title>
  <style>
   #light { -xbl-binding: url(demo.xml#light); }
  </style>
 </head>
 <body>
  <p id="light">Red</p>
  <p>
   <input type="button" onclick="doRed()" value="red">
   <input type="button" onclick="doGreen()" value="green">
  </p>
  <script>
   var light = document.getElementById('light');
   function doRed() {
     light.textContent = "Red";
     if (light.red)
       // binding might not be applied, so only call the method if it is defined
       light.red();
   }
   function doGreen() {
     light.textContent = "Green";
     if (light.green) // same
       light.green();
   }
  </script>
 </body>
</html>

Ok, so this example is a little far fetched. So are most of the examples in this spec. They're just examples!

2.15. The script Element

Expected context:
xbl
Expected children:
If the element has no src attribute: depends on the scripting language.
If the element does have a src attribute: none.

The script element contains code that is executed when the XBL subtree is loaded. It can therefore be used to define helper functions used by the bindings.

The script element, when present, must either contain code in the language specified by the XBL subtree's script-type attribute, or have a src attribute that points to a resource containing code in the language specified by the script-type attribute. The syntax and semantics of this code depend on the specific language. (See: loading and running scripts.)

Attributes

id
The id attribute.
src
The src attribute specifies the URI to a resource of the type given by the XBL subtree's script-type attribute. If the attribute is specified, the contents of the element must be ignored (even if the resource could not be fetched or was of the wrong type). (See: loading and running scripts.)

If an script element is marked (via the script-type attribute of the xbl element) as being in a language that the UA does not support, the UA must ignore it. Similarly, if the script element points (using the src attribute) to a resource that is either unavailable, or not of the type specified by the script-type attribute of the xbl element (or implied by its absence), then it is in error and the UA must ignore it. In both cases, "ignoring it" means that the script must not be executed.

How UAs must handle nodes inside script elements depends on the language used. (See: loading and running scripts.)

script blocks must be evaluated when their end-tag is parsed, or, for dynamically created elements, when they are first inserted into a document. This is the case whether or not the elements are in error. Once evaluation has started, a script block is dead and changes to its contents or attributes have no effect.

2.16. The id Attribute of XBL Elements

Expected element:
Any element in the XBL namespace.

The id attribute assigns an identifier to an element.

The given identifier must be unique in the binding document. The id attribute is of type ID. [XML].

If the attribute's value is the empty string, the attribute must not set an ID. Otherwise, the attribute's value must be treated as (one of) the element's ID(s).

3. Binding Attachment and Detachment

Bindings can be attached and detached dynamically, using several mechanisms.

Bindings must be attached as soon as the following conditions have all been met:

In particular, binding can happen before the element is inserted into its document.

If the binding document was already loaded when the element was created, or when it became known that the element matched the binding (e.g. because the binding's element attribute is mutated in a script), then the binding must be applied such that to any running scripts it appears that the binding was applied immediately.

If the binding document has yet to be (fully) loaded when it becomes known that the binding applies, then the user agent must wait until all running scripts have completed before attaching the binding.

If the binding attachment mechanism is the '-xbl-binding' property, then it does not become known to the user agent that the binding applies (or does not apply) until the next time style resolution is performed. This specification does not define when style resolution happens.

Assume that foo.xml defines a binding that applies to all "foo" elements. The following script uses loadBindingDocument() to ensure that foo.xml is loaded, then creates a foo element and uses it.

// load the binding document
document.loadBindingDocument('foo.xml'); // this is synchronous

// create an element <foo>
var foo = document.createElement('foo'); // binds synchronously too
foo.myCustomMethod(); // calls the binding's implementation

Without the call to loadBindingDocument(), if the binding document wasn't loaded yet the element wouldn't be bound straight away, and the last line would fail.

Bindings must be detached as soon as it is known that the binding no longer applies to the element.

When it becomes known that a binding is to be detached, it must happen such that to any running scripts it appears that the binding was removed immediately, except if the script in question is running as part of the last step of the binding attachment process, in which case the detachment happens after all the bindings being attached have had their methods called. (See: binding attachment model.)

3.1. The Bindings-Are-Ready State

XBL implementations must have a bindings-are-ready counter (for each Document) that keeps track of when there are outstanding bindings to bind. This counter is set at the times given in the following sections. (It is not set for all kinds of attachments.)

If the bound document is being parsed by the user agent, then, as soon as all the following conditions have been met, the user agent must fire an xbl-bindings-are-ready event on the document's root element. The conditions are:

The event must use the Event interface, must bubble, must not be cancelable, and must not have a default action. [DOM3EVENTS]

Initially, the bindings-are-ready counter must be set to zero.

The bound document's load event must not fire until after the xbl-bindings-are-ready event has fired. The xbl-bindings-are-ready event must fire even in the complete absence of any use of XBL in the document.

3.2. Attachment using <binding element="">

The simplest binding mechanism is the binding element's element attribute. It declares which bindings should be attached to which elements. (See: attributes containing selectors, the binding element.)

While an element matches the element attribute of one or more of the binding elements that is imported into, or defined in, the element's document, the bindings defined by each such binding element must be bound to the element. This applies to all elements that are associated with a document, even when they have not yet been inserted into the document, or are not in the final flattened tree.

3.2.1. Importing Binding Documents

There are two ways to import binding documents (and thus have their <binding element=""> bindings apply): the <?xbl?> processing instruction, and the loadBindingDocument() method. The latter is defined in the section on the DocumentXBL interface.

The <?xbl?> processing instruction specifies a binding document to load. Any bindings defined in that document must be applied to matching elements in the document with the processing instruction.

<?xbl?> processing instructions that occur after the root element's start tag in the markup are in error. <?xbl?> PIs that are dynamically inserted through the DOM after the root element's start tag has been parsed or the root element has been attached to the document are in error too.

A <?xbl?> processing instruction that is not in error according to the above must be parsed using the same syntax as the XML Stylesheet PI. [XMLSSPI] If there are any parse errors, then the entire processing instruction is in error.

Otherwise, if it has an href pseudo-attribute then it specifies the URI of the binding document to import. If the URI cannot be resolved, or returns an error, or does not point to a resource with an XML MIME type, or has any other problem that makes it unusable, then the processing instruction is in error.

If a processing instruction is in error (as described in the previous few paragraphs) then it must be ignored.

Otherwise, the referenced document must be loaded (unless it has already been loaded), and any bindings defined by that document must be applied to matching elements in the document that contained the PI. Once loaded, the binding document is added to the bindingDocuments list of the document with the PI.

Dynamic changes to <?xbl?> processing instructions must be ignored from an XBL standpoint.

An imported binding document is live.

For example, if new binding elements are added to an imported binding document (via the DOM), then the new bindings are immediately applied to the document that had the PI importing that binding document.

XBL bindings are always implicitly imported into the document in which they are defined.

Whenever an <?xbl?> PI causes a binding document to be loaded, the document's bindings-are-ready counter must be increased by one. Once the binding document is loaded, the counter must be decreased by one.

An XBL subtree that defines some bindings is automatically imported in that document, so such mappings are always used. The following example demonstrates this.

example.xml

<...>
 <xbl xmlns="http://www.w3.org/ns/xbl" ...>
  <binding element="foo">
   ...
  </binding>
  <binding element="bar">
   ...
  </binding>
 </xbl ...>
 <foo xmlns=""/> <!-- this will have a binding applied -->
 <bar xmlns=""/> <!-- this will have a binding applied -->
</...>

If the binding definitions are in a separate file, then that file needs to be imported explicitly:

widgets.xml

<...>
 <xbl xmlns="http://www.w3.org/ns/xbl" ...>
  <binding element="foo">
   ...
  </binding>
  <binding element="bar">
   ...
  </binding>
 </xbl ...>
</...>
example.xml

<?xbl href="widgets.xml"?>
<...>
 <foo/> <!-- bound -->
 <bar/> <!-- bound -->
</...>

If a file imports some bindings and the file containing those bindings has its own <?xbl?> processing instructions, that second PI only affects nodes in the binding document, not the original document. For example:

foo.xml

<...>
 <xbl xmlns="http://www.w3.org/ns/xbl" ...>
  <binding element="foo">
   <content>
    <bar xmlns=""/> <!-- not bound, not even when in shadow content -->
   </content>
  </binding>
 </xbl>
</...>
bar.xml

<?xbl href="foo.xml"?>
<...>
 <xbl xmlns="http://www.w3.org/ns/xbl" ...>
  <binding element="bar">
   <content>
    <foo xmlns=""/> <!-- bound: this document imports foo.xml -->
    <bar xmlns=""/> <!-- bound: bar binding is defined locally -->
   </content>
  </binding>
 </xbl>
</...>
example.xml

<?xbl href="bar.xml"?>
<...>
 <foo/> <!-- not bound: foo.xml not imported here -->
 <bar/> <!-- bound -->
</...>

3.3. Attachment using CSS

Bindings can be attached to elements through CSS using the '-xbl-binding' property.

In the following example, a binding is referenced that will be attached to all XHTML checkbox elements.

input[type="checkbox"] {
  -xbl-binding: url("http://www.example.org/xbl/htmlBindings.xml#checkbox");
}

Bindings attached through CSS must only remain on the bound element as long as the element continues to match the style rule. If at any time a resolution of style on the element determines that a different binding should be attached, the old binding (and all bindings that it explicitly extends in its explicit inheritance chain) must be detached.

Whenever an element is removed from a document, any bindings attached to that element via CSS must be detached.

Attaching a binding using CSS does not import the binding document. The element attributes of binding elements in the binding document do not take effect unless the binding document is imported. (See: importing binding documents.)

Attaching using CSS does not affect the bindings-are-ready counter.

3.3.1. The '-xbl-binding' Property

A property to attach a binding to a particular element.

'-xbl-binding'
Value: none | [ <uri> ]* <uri>
Initial: none
Applies To: all elements (but not pseudo-elements)
Inherited: no
Percentages: n/a
Media: all
Computed Value: specified value, with URIs resolved to absolute URIs
none
No bindings are to be attached through CSS.
<uri>
The specified binding is attached. More than one binding can be specified, resulting in the bindings being attached in the specified order, with the last binding implicitly inheriting from the previous one, and so forth, up to the first binding. (See: binding inheritance.)

3.3.2. Processing Model

User agents may perform the CSS cascade, inheritance, and computation stages either across the entire tree, or per element, or per property per element, and either before applying bindings, or simultaneously, while applying bindings. In any case, for each element the computed value of '-xbl-binding' must be found and then used to apply the bindings to the element (when the element is first styled, and each subsequent time the styles that match the element change).

Since each time a binding is applied it can change the computed values of properties of elements that are descendants of the bound element, this may require several passes. This may be avoided by computing the value of the '-xbl-binding' property for the element, and then applying any bindings, before any of its descendants.

3.3.3. Examples

The following XBL document defines two bindings for use in SVG. The first renders an isosceles triangle in place of bound elements that use it, the other renders a right-angled triangle in place of bound elements that use it.

<xbl xmlns="http://www.w3.org/ns/xbl"
     xmlns:xbl="http://www.w3.org/ns/xbl">
 <binding id="isosceles">
  <template>
   <polygon xbl:attr="transform" points="0 -1, 1 0, -1 0" xmlns="http://www.w3.org/2000/svg"/>
  </template>
 </binding>
 <binding id="rightangle">
  <template>
   <polygon xbl:attr="transform" points="0 0, 1 0, 0 -1" xmlns="http://www.w3.org/2000/svg"/>
  </template>
 </binding>
</xbl>

Assuming the above file was called triangles.xml, these bindings could be bound to elements using CSS like so:

@namespace triangles url(http://triangles.example.com/);
triangles|isosceles { -xbl-binding: url(triangles.xml#isosceles); }
triangles|rightangle { -xbl-binding: url(triangles.xml#rightangle); }

If the stylesheet was called triangles.css, an SVG file using these elements might look like:

<?xml-stylesheet href="triangles.css"?>
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:t="http://triangles.example.com/">
 <circle cx="10" cy="10" r="5"/>
 <rect x="20" y="20" height="5" width="10"/>
 <t:isosceles transform="translate(10 20) scale(10)"/>
 <t:rightangle transform="translate(20 20) scale(10)"/>
</svg>

The same example could also be done all in one file like this:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:t="http://triangles.example.com/">
 <defs>
  <xbl xmlns="http://www.w3.org/ns/xbl"
       xmlns:xbl="http://www.w3.org/ns/xbl">
   <binding id="isosceles">
    <template>
     <polygon xbl:attr="transform" points="0 -1, 1 0, -1 0" xmlns="http://www.w3.org/2000/svg"/>
    </template>
   </binding>
   <binding id="rightangle">
    <template>
     <polygon xbl:attr="transform" points="0 0, 1 0, 0 -1" xmlns="http://www.w3.org/2000/svg"/>
    </template>
   </binding>
  </xbl>
  <style type="text/css">
   @namespace triangles url(http://triangles.example.com/);
   triangles|isosceles { -xbl-binding: url(#isosceles); }
   triangles|rightangle { -xbl-binding: url(#rightangle); }
  </style>
 </defs>
 <circle cx="10" cy="10" r="5"/>
 <rect x="20" y="20" height="5" width="10"/>
 <t:isosceles transform="translate(10 20) scale(10)"/>
 <t:rightangle transform="translate(20 20) scale(10)"/>
</svg>

3.4. Attachment using the DOM

Bindings can be attached to elements through the DOM using the ElementXBL interface. The method addBinding takes a binding URI and attaches the binding to the element (in all views).

var checkbox = document.getElementById("mycheckbox");
checkbox.addBinding("http://www.example.org/xbl/htmlBindings.xml#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. (An xbl-bound event is fired when the binding is installed.)

When a binding is attached using the DOM, it inherits from the current most derived binding that is already attached to the element, if any. (See: binding inheritance.)

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.

Attaching a binding using the addBinding() DOM APIs does not import the binding document. The element attributes of binding elements in the binding document do not take effect unless the binding document is imported. (See: importing binding documents.)

Attaching using the addBinding() API does not affect the bindings-are-ready counter.

3.5. Binding Attachment Model

When a new binding is attached, the UA must perform the following steps in order (or act as if it did). Implementations may choose to suspend redraw during this process.

  1. If the binding has an extends attribute, then the user agent must immediately consider the binding that the attributes references (if any) to apply to the bound element as well, and must attach that binding first, recursively applying these steps to that binding. If this causes a loop — that is, if a binding directly or indirectly derives from itself through a chain of one or more extends attributes — then the user agent must only apply each binding in the chain once. (See: explicit inheritance, interpretation of URIs to XBL bindings.)
  2. If the binding has a template, the binding's shadow tree must be generated. This may cause other bindings to be applied synchronously, if their binding documents are already loaded. (See: rules for shadow content generation, binding attachment and detachment.)
  3. If other bindings are already attached to the bound element, then the newly added binding will add a new explicit inheritance chain to the element's list of bindings (its implicit inheritance chain). (See: implicit inheritance.)
  4. If the new binding has an implementation, it must be made available to scripts. Language-specific constructors for the binding implementation must run at this point. (See: binding implementations.)
  5. Events must start being routed through the binding's handlers element, when there is one. (See: event forwarding.)
  6. If the new binding changes which shadow trees contribute to the final flattened tree then the explicit children must be redistributed. (See: processing content elements.)

The attachment process for the binding must then wait for the above steps to have been completed for all bindings that are known to apply to elements. When all the new bindings have reached this point, then, for each newly attached binding, the xblBindingAttached() method must be invoked on the binding's implementation, immediately followed, if that bound element is in a document, by the invocation of the xblEnteredDocument() method.

The order that bindings on different bound elements have these methods called must be the relative tree order of all their bound elements, as returned by the compareDocumentPosition() function. In certain cases (e.g. bound elements in disconnected fragments), this order is implementation-specific; however, it must always be consistent with the return values of that function. [DOM3CORE]

The order that bindings on the same bound element have these methods called must be the derivation order, with less derived bindings being initialized before more derived bindings.

After all the appropriate methods have been called, an xbl-bound event that bubbles, is not cancelable, has no default action, and uses the Event interface, must be fired on every bound element that just got bound, in the same order as their xblBindingAttached() methods were invoked. (See: binding inheritance.) [DOM3EVENTS]

If a binding stops applying to a document while the above steps are being applied, the binding is not removed until after the steps above have all been completed. Once they have been completed, any bindings that no longer apply must be detached. (See: binding detachment model.)

3.6. Handling Insertion and Removal from the Document

A bound element is in a document if it has a Document node as an ancestor, or it is in a shadow tree and that shadow tree's bound element is itself in a document.

When a bound element that is not in a document is affected in such a way that it subsequently is in a document, then the xblEnteredDocument() method must be invoked on the binding's implementation.

Similarly in reverse: when a bound element that is in a document is affected in such a way that it subsequently is not in a document, then the xblLeftDocument() method must be invoked on the binding's implementation.

These methods must be invoked as soon as the DOM is in a stable state, after any mutation events have fired, and after all running scripts have finished executing. If a bound element is removed and then reinserted into a document (or vice versa) during script execution, or while mutation events are being fired, the user agent must coalesce all the notifications into zero or one method calls (i.e. matching pairs of insertions and removals must not cause bindings to be notified).

3.7. Binding Inheritance

Bindings can inherit from each other explicitly using the extends attribute. They can also inherit from each other implicitly if multiple bindings are attached to an element.

The implicit inheritance link can be pictured as having several explicit chains adjacent to each other, with the implicit inheritance chain going down each explicit inheritance chain sequentially.

Consider a case where seven bindings are defined, "a", which inherits from "b" which inherits from "c"; "d", which stands alone; and "e", which inherits from "f" which inherits from "g". If a bound element E is bound to "a", "b", "d", and "e" (with "e" bound last), then there would be nine bindings attached to E. Four of them would be explicitly bound, and five would be part of explicit inheritance chains from those four.

In such an example, you would also get implicit inheritance from "g" to "d", from "d" to "b", and from one of the instances of "c" to "a".

An explicit inheritance chain is a chain of bindings connected using the extends attribute.

An implicit inheritance chain is a chain of explicit inheritance chains. There can be at most one implicit inheritance chain per bound element.

A base binding is a binding that does not inherit from any other binding, either explicitly or implicitly. The base binding of a bound element is at one end of the bound element's implicit inheritance chain.

A base binding of the explicit chain is any binding that does not inherit explicitly from another, but may inherit implicitly from other bindings.

A most derived binding is a binding that no other binding inherits from. The most derived binding of a bound element is the binding at the other end of the bound element's implicit inheritance chain from the base binding.

If Bi is the ith binding in a group of N chains, where B1 is the base binding and BN is the most derived binding, then Bi-1 is the the next most derived binding of Bi.

In this specification, inheritance is represented as an arrow pointing to the binding that is being inherited. Thus, in the chain A→B, the A binding is the most derived binding, and the B binding is the next most derived binding, in this case also the base binding.

In the example above, the base binding is the first "c", the four base bindings of the explicit chains are "c", "c", "d", and "g", and the most derived binding is "e".

The results of inheritance are described in the sections on binding implementations and shadow content.

3.7.1. Explicit Inheritance

The binding element's extends attribute gives an explicit inheritance chain for a binding, ensuring that whenever the binding is bound to an element, the named binding also gets bound. (See: binding attachment model, binding detachment model.)

The extends attribute thus creates an explicit inheritance chain.

If a binding element's extends attribute is changed, then, for each time the binding is bound to an element, the user agent must follow these steps:

  1. Let binding be the instace of the binding that is attached to the bound element.

  2. If binding is not directly attached to the bound element, but is instead attached to the bound element because another binding is inheriting from it using the extends attribute, then let binding be that binding instead, and repeat this step.

    Otherwise, binding was attached to the bound element directly, and is not being inherited by another binding using the extends attribute.

  3. Detach binding. (See: binding detachment model.)

  4. Attach a new instance of binding so that it is in the same place in the binding chain as the old instance was. (See: binding attachment model, implicit inheritance.)

It is possible to form a loop with the extends attribute. For example, a binding A can inherit from B which inherits from C which inherits from B again. The attachment algorithm is defined in a way that makes the loop stop as soon as a duplicate binding would be bound. In this case, the user agent will form a chain starting with A (the most derived binding), derived from B, derived from C, with C as the base binding (chain A→B→C). If, given the same definitions, the element was bound directly to C, then the chain would be C→B.

3.7.2. Implicit Inheritance

When two bindings are both attached to the same element, the base binding at the end of the explicit inheritance chain of the second binding implicitly inherits from the most derived binding of the explicit inheritance chain of the first.

If one of the explicit inheritance chains is removed, then the remaining binding chains are reconnected so that the base binding of the explicit chain after the break now inherits from the most derived binding before the break.

The order of bindings is always such that bindings added via the binding element are first (in the order the bindings are specified in the file, with the files, if there are more than one, ordered in the same order that they are referred to, traversed pre-order, depth-first), the bindings attached via CSS are second (in the order specified on the '-xbl-binding' property), and the bindings added via addBinding are third (in the order they were attached, most recently attached being the most derived binding).

For example, take a binding d1, which specifies a base binding d2 using the extends attribute such that its explicit inheritance chain is:

d1d2

If binding d1 is attached to an element using addBinding that already has a binding chain of:

s1s2s3

...then the base binding at the end of the inheritance chain, d2, is the one that will inherit from the most derived binding that is already attached to the element, s1. The resulting binding chain following the addition of the binding is therefore:

d1d2s1s2s3

The inheritance between d2 and s1 is implicit, meaning that there is no connection in the XBL subtrees between the two bindings. The inheritance link has been forged dynamically through the invocation of the addBinding method.

An element can be bound to the same binding multiple times, in which case a binding can end up inheriting from itself. (This can only happen via implicit inheritance, though.)

3.7.3. Mixing Implicit and Explicit Inheritance

Consider the following completely useless but short bindings:

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="a">
  <template> l <inherited> l <content> o </content> - </inherited> W </template>
 </binding> 
 <binding id="b" element="[X]" extends="#a">
  <template> e <inherited> error </inherited> o <content> r </content> </template>
 </binding>
 <binding id="c" element="[Y]">
  <template> H <inherited> error </inherited> l <content> error </content> ! </template>
 </binding>
</xbl>

When imported by the following equally silly but simple document:

<?xbl href="test.xml"?>
<root X="" Y=""> d </root>

The resulting flattened tree would spell "H e l l o - W o r l d !".

The binding "c" that attaches because of the Y attribute implicitly inherits from the binding "b" that is bound because of the X attribute, and that latter binding explicitly inherits from the "a" binding. Since the "Y" binding has a content element, the "d" explicit child node of the bound element ends up assigned to the content element in the "Y" binding.

The following table shows the source of each character:

Output: H e l l o - W o r l d !
Source: c b a a a a a b b c R c

...where R represents the bound document.

The inheritance chain of the bindings attached to the root element in this example is:

c → b → a

...where the first arrow is an implicit inheritance, and the second is an explicit inheritance.

3.8. Views and Attachment

Only one set of bindings is attached to the document, and they must affect all views in a multi-view UA. Bindings attached via style sheets must be attached based on the style sheets that apply to the default view.

3.9. Attachment During Document Load

Binding loads are asynchronous. That is to say, when a binding is added (either via style sheet, script, or some other method), and the relevant binding document is not yet loaded, the load must be started in the background and the binding only attached once the binding document is available. An author can ensure that all bindings are synchronously attached by calling loadBindingDocument to pre-fetch any binding documents that are required.

The bound document must wait until all XBL dependencies have loaded before firing its load event.

3.10. Binding Detachment Model

When a binding is detached, the xblLeftDocument() method must be invoked on the binding's implementation. Then, the shadow tree must be removed, the implementation must be removed from the bound element's list of binding implementations, and any forwarding of events to the binding must be stopped for this bound element.

If the binding had an extends attribute when it was bound to the element (it may have changed since then, in which case the binding is being detached precisely for that reason), then the user agent must then detach the binding that was attached because of that attribute (if any). (See: explicit inheritance, interpretation of URIs to XBL bindings.)

If the binding had a shadow tree, the explicit children must then be redistributed. (See: processing content elements.)

4. Shadow Content

The subtree specified by the template element is referred to as the shadow content template. This template describes a content tree that will be generated under the bound element during binding attachment. An element declared in a bound document using a single element can then be constructed out of multiple child elements, and this implementation is hidden from the bound document.

A shadow tree is a tree of nodes created by cloning a binding's shadow content template. A bound element can have zero, one, or more shadow trees. If a bound element has any, they are combined by the user agent, along with the element's explicit children, to form the final flattened tree. Shadow trees are hidden from normal DOM processing (hence the name "shadow"); they are not accessible via Core DOM navigation facilities such as firstChild or nextSibling. (See: shadow content.)

The term shadow content refers to the various nodes in the shadow tree(s) of a bound element. Shadow content is created by cloning shadow content templates during binding attachment.

For example, the HTML file upload control appears in most browsers as a composite widget consisting of a text field and a button. A sample XBL binding for the file widget might look as follows:

<binding id="fileupload">
  <template>
    <html:input type="text"/>
    <html:input type="button"/>
  </template>
</binding>

Because this content is not visible to its parent element, it is said to be shadow content.

The file control is actually a special case. Due to security considerations, untrusted bindings will typically not be able to extend the file upload control in UAs intended for use with untrusted content.

Whenever bindings are attached to an element, shadow content will potentially be generated. Similarly, when a binding is removed from an element, its shadow content, if any, is destroyed.

A shadow tree must be generated if a template element is added to a binding element that had no template element. If the template element is removed, then the shadow tree must be destroyed.

The template element used to generate a binding is always the first such element in a binding element. If the binding element is mutated in a way which changes which template element is the first, then the corresponding shadow tree must be regenerated.

Similarly, when a template element or any of its descendants is mutated in any way, any bindings whose shadow tree was constructed from that element must be regenerated.

Regenerating a shadow tree consists of first destroying the existing shadow tree and then generating a new one.

4.1. Rules for Shadow Content Generation

When a shadow tree is generated, user agents must act as follows:

If the binding element has no template element, then no shadow content will be generated for this binding.

Otherwise, its first template element must be deeply cloned.

The xml:base data of the cloned template element must be set so that the baseURI of nodes in the resulting shadow tree is the same as their pre-cloning counterparts. All shadow nodes' ownerDocument pointers are left pointing at their binding documents' Document node(s).

No mutation events must be fired during the above steps.

Any bindings that apply to elements in the shadow tree must be applied.

For bindings with ECMAScript implementations: the shadowTree member of the private object must be set to be a reference to the template element clone (the root of the shadow tree).

The shadow tree is then applied to the bound element: the binding's shadow tree is placed in the appropriate place in the final flattened tree, explicit children are (re)distributed to the appropriate content elements, and the CSS cascade and inheritance is be computed along the new tree. (See: processing content elements.)

After this point, further bindings may need to be applied, or certain bindings may need to be removed (because of CSS inheritance or because the selectors that decide which elements match which bindings can be affected by the shadow tree being associated with the bound element).

Everything described in this section must be completed atomically — that is, the UA must not execute author scripts during this process.

Some implementations might optimize this algorithm, such as using "lazy evaluation" approaches and thereby postpone the cascade and inheritance operations.

4.2. Rules for Shadow Content Destruction

The destruction of a shadow tree consists of recreating the final flattened tree without the influence of that binding's shadow tree by redistributing the explicit children to the remaining shadow trees' content elements (or, if there are none, putting the nodes back directly under the bound element).

For bindings with ECMAScript implementations: the shadowTree member of the private object must be set to null.

4.3. Attribute Forwarding

Attributes on shadow content elements can be tied to attributes on the bound element; then, whenever the attribute is set or removed on the bound element, the corresponding attribute on the shadow content is also set or removed. On any shadow content element, an xbl:attr attribute can be used to specify a space-separated list of attributes that should be inherited. Attributes with namespaces can be defined using a namespace prefix and the attribute name separate by a colon.

For example, returning to the HTML file upload control example above, the shadow text field can be set up to automatically inherit the value attribute from the bound element.

<xbl:binding id="fileUploadControl">
  <xbl:template>
    <html:input type="text" xbl:attr="value"/>
    <html:input type="button" value="Browse..."/>
  </xbl:template>
</xbl:binding>

Each entry in the xbl:attr list can either simply list an attribute (a QName, such as value in the example above), or it can specify an =-separated pair of QNames consisting of the attribute on the shadow content that should be tied to the attribute on the bound element. When two names are specified, the attribute to be added on the shadow content node is listed first, and the attribute of the bound element is second.

Each entry may also be suffixed by a single hash mark (#) followed by a type designation.

The xbl:attr attribute's value must be parsed as follows. First, it must be split on spaces (treated as a space-separated value). Next, each resulting item must be matched against the following pattern (given here in pseudo-BNF, where square brackets indicate optional terms):

xbl inherits item := [s1 ':'] s2 ['=' [s3 ':'] s4] ['#' s5]

...where s1..s5 are strings of characters not containing any of ":". "=", or "#".

If any item does not match this pattern, then the item is in error and must be ignored. Other items in the list, if any, are not affected by this.

The values s1:s2 and s3:s4 (if present) must be resolved to fully qualified names using the attribute QName resolving semantics and the namespaces prefix declarations in scope on the element on which the xbl:attr attribute is found, at the time that the attribute is parsed. Any value in the list that does not resolve to a fully qualified name is in error and must be ignored. [XMLNS]

Changes to namespace prefix definitions in the shadow tree that affect QNames used in xbl:attr attributes take effect the next time the attribute is parsed (which must be the next time the attribute is changed, but may be earlier).

4.3.1. Forwarding to and from text nodes

The special value xbl:text can be used in an =-separated pair, where the prefix is associated with the XBL namespace. (The value is not a literal; it represents the fictional "text" attribute in the XBL namespace.)

When specified on the left-hand side of the pair it indicates that the value of the attribute on the right-hand side are to be represented as text nodes underneath the shadow element in the final flattened tree. If the element has any child nodes in the DOM (any nodes, including comment nodes, whitespace text nodes, or even empty CDATA nodes) then the pair is in error and UAs must ignore it, meaning the attribute value is not forwarded. Otherwise, a text node must be created, and that text node will be placed under the element in the final flattened tree.

Text nodes created in this way are orphans; their parentNode, nextSibling, previousSibling, childNodes, firstChild, and lastChild attributes are all null or empty. Their ownerDocument attribute is set to the same as the shadow content node that generated them. (The only way one of these text nodes can be accessed is if the element is itself bound: the text node might then appear in a content element's xblChildNodes list.)

When used on the right-hand side, it indicates that any text nodes (including CDATA nodes and whitespace text nodes) that are explicit children of the bound element must have their data concatenated and the resulting value stored as the attribute on the left-hand side.

The xbl:text value cannot occur by itself in the list. If it occurs by itself, it is in error and UAs must ignore that value in the space-separated list that is the xbl:attr attribute.

4.3.2. Forwarding language metadata

The special value xbl:lang can also be used in an =-separated pair. (Again, this is just the fictional "lang" attribute in the XBL namespace, not the literal string "xbl:lang", so the "xbl" prefix, or whatever prefix is used, must be declared as the XBL namespace.)

When used on the right-hand side, it indicates that the value to be copied is the natural language of the bound element, typically given by the attribute xml:lang of that element or an ancestor, or by HTTP headers, or similar. If no language is defined, then the value to be copied must be the empty string.

The xbl:lang value cannot occur by itself or on the left-hand side. If it does, it is in error and UAs must ignore that value in the element's xbl:attr attribute.

4.3.3. Error handling

Any other values in the XBL namespace in the list are in error and must be ignored. (In particular, trying to change or set the value of xbl:pseudo or, worse, xbl:attr, must not result in any changes to any attributes.)

If an attribute is listed multiple times on the left hand side (or on its own), then the last designation wins (as if the attributes were each forwarded in turn, an earlier forwarding being overwritten by a later one).

4.3.4. Type specifiers

If the attribute or attribute pair is followed by a type designation, in the form of a hash mark character ("#") and by a type name, then the value must be processed as described for its type below before being forwarded.

If the type is url
The value must be resolved to an absolute URI using the base URI of the source element before being forwarded.
If the type is text (default)
The value is forwarded unchanged.
If the type is any other value
The attribute must not be forwarded. The value is in error and UAs must ignore that value in the element's xbl:attr attribute.

In the following shadow template, the "src" attribute on the bound element is forwarded to the "src" attribute on the image element in the shadow tree, and the link will work even if the original attribute had a relative URI and the base URIs of the various nodes are different:

<xbl:template>
  <xul:image xbl:attr="src#url title alt=xbl:text xml:lang=xbl:lang"/>
</xbl:template>
    

This example also shows how to turn the value of an attribute on the bound element, in this case the "alt" attribute, into child nodes of the element in the shadow tree, using xbl:text. For accessibility reasons, the language of the element is also explicitly forwarded.

4.3.5. Dynamic changes

The xbl:attr attribute must be parsed when the binding is first applied and whenever the attribute's value changes. It must be applied (causing the relevant attributes and text nodes to be updated) when the shadow tree is generated, when the attribute is changed, and whenever any of the bound element's attributes or text nodes referred to by the xbl:attr attribute change.

4.3.6. How Attribute Forwarding Affects the Shadow Tree

The element to which the attributes are forwarded has its attributes mutated. Whenever attribute forwarding happens: existing attributes to which values are being forwarded must have their values changed, attributes that are being forwarded that do not yet exist on the shadow tree element must be added to the shadow tree element, attributes to which values would be forwarded but whose source attributes are not present on the bound element must be removed from the shadow tree element.

The shadow tree element's attributes can be changed dynamically, and this doesn't affect the attribute forwarding, until dynamic changes cause attribute forwarding to be performed again. When attribute forwarding is performed, all attributes are forwarded, even those that haven't changed on the bound element, thus blowing away any dynamic changes to the shadow tree element's attributes that are referenced by the xbl:attr attribute.

4.4. Processing content Elements

A node is said to match a content element when the content element has no includes attribute, or when the element in question matches the selector given by that includes attribute.

A node is inserted into the first content element that it matches. If it is moved (using setInsertionPoint), then it remains in the new content element while it matches it. If it stops matching that new content element, it gets placed into the first content element that it matches. (If it doesn't match any, then the entire shadow content is removed.) In other words, changes to the content element are "sticky".

If an element is inserted into an content element with an empty filter ("includes" list) then it will always match it while that content element exists, and will therefore never move to another content element unless the content element is dynamically removed.

4.4.1. Formal definition

XBL bindings can interleave shadow content between bound elements and their explicit children. They do so using XBL's content element. Any number of content nodes may be used in a binding's shadow content template.

In addition, the shadow trees of inherited bindings get inserted into the first inherited element in the binding.

The explicit children of an element are the nodes that are listed in the element's childNodes array, with the exception that any content elements in that array are instead replaced by whatever nodes they currently have assigned to them, or, if no nodes match that content element, by the child nodes of that content element. If an element's childNodes list is empty but the element has an xbl:attr attribute that uses the xbl:text value on the left hand side in a way that is not in error then its "explicit children" is the text node generated during attribute forwarding.

Consider the following simple document:

<X><A/></X>

Now, if the element X in that document is bound to a binding with the following shadow tree template:

<template>
 <my:T>
  <my:P/>
  <content/>
  <my:Q/>
 </my:T>
</template>

The explicit children of the T element, ignoring whitespace nodes, are, in order, P, A, and Q. This is because the children of T are P, a content element, and Q, and the content element has just one node associated with it, namely the A element.

When the explicit children are distributed and assigned to the content elements in the bound element's shadow trees, the includes attribute determines which content element a given child is to be placed under.

If no includes attribute is specified, a content element is considered generic and will match on all content, including text nodes, CDATA nodes, comments, and so on.

If the includes attribute is specified, it must be interpreted as a selector, and only elements that match the selector apply to that content element. If the selector is invalid, the content element is in error and does not match any nodes. Matching of the elements to the selector is done without taking into account the shadow tree in which the content element itself is found. [SELECTORS]

Each node that is to be distributed (each explicit child node) must be assigned to a content element as follows:

  1. If the node is already assigned to a content element for this binding, and the content element is locked, then that is the content element to which the node must be assigned, stop here.
  2. Otherwise: if the node is already assigned to a content element for this binding, unassign it.
  3. Let T be the shadow tree of the most derived binding with a shadow tree for the bound element.
  4. If T contains a correct content element that is not locked and to which the node in question applies, then the first such element in a depth-first, pre-order traversal of the shadow tree T is the content element to which the node must be assigned, stop here.
  5. Otherwise, if this binding has no correct inherited element in its shadow tree, then the node is not assigned to a content element, and does not appear in the final flattened tree; stop here.
  6. Otherwise, if the binding has a correct inherited element in its shadow tree but it is the least derived binding with a shadow tree, then the node is not assigned to a content element, and does not appear in the final flattened tree; stop here.
  7. Otherwise, let T be the shadow tree of the next most derived binding with a shadow tree and return to step 4.

The explicit children must be processed in order, so if two nodes are assigned to a content element, their order in the xblChildNodes list is the same as their relative order in the explicit children list.

Consider the following simple document:

<X><A/><B/><C/></X>

Imagine that the element X in that document is bound to a binding with the following shadow tree template:

<template>
 <my:T>
  <my:M/>
  <content/>
  <my:N/>
 </my:T>
</template>

Imagine further that the element T is itself bound to a binding with the following template:

<template>
 <my:R>
  <content includes="N"/>
  <content includes="B"/>
 </my:R>
</template>

The resulting final flattened tree would be:

 X
 |
 `-- T
     |
     `-- R
         |
         +-- N
         |
         `-- B

In this example, there are two selectors, "N" and "B", both of which match just elements with the given local name.

4.4.2. When nodes are redistributed

The algorithm described in the previous section is applied when:

Consider the following binding shadow tree:

<template>
 <div>As: <content includes="A, AA"/></div>
 <div>Other: <content/></div>
</template>

If an element is bound to this binding while it has three elements A, AA, and B, then the A and AA elements would end up under the first content element, and the B element would end up under the second content element. But if the includes attribute of the first content element in the shadow tree was then dynamically modified to just have the value "A", then the AA element would be reassigned to the second content element.

4.5. The Final Flattened Tree

The final flattened tree is the view of the document and shadow trees after XBL has been fully applied.

The final flattened tree must be constructed by taking the bound document's core DOM tree and performing the equivalent of the following steps on each bound element, until there are no more bound elements in the tree that have not been processed:

  1. If the bound element has no shadow trees, move on to the next bound element.
  2. Otherwise, replace the child nodes of the bound element with the child nodes of the most derived shadow tree's root template element.
  3. For any element in the shadow tree that has an xbl:attr attribute that uses the xbl:text value on the left hand side in a way that is not in error, let the element's only child node be the attribute-forwarding text node. (If the element in question has any child nodes, then the xbl:text value will be in error.)
  4. Replace any content elements in the shadow tree with the nodes that were assigned to them in the previous section, unless there are no such nodes, in which case replace them with their child nodes.
  5. Replace the second and subsequent inherited elements in the shadow tree with their child nodes.
  6. Replace the first inherited element in the shadow tree, if any, with the child nodes of the next most derived binding's shadow tree's root template element, or, if there is no less-derived binding with a shadow tree, with the child nodes of the inherited element itself.
  7. If the previous step added a shadow tree to the flattened tree, then return to step 3 to deal with that newly added shadow tree. Otherwise, move on to the next bound element.

Imagine the following document fragment:

...
 <A>
  <B>
   <C/>
   <D/>
  </B>
 </A>
...

...is bound to the following XBL:

<xbl:xbl xmlns:xbl="http://www.w3.org/ns/xbl">
 <xbl:binding element="B">
  <xbl:template>
   <P>
    <Q>
     <xbl:content includes="C">
      <R/>
     </xbl:content>
    </Q>
    <xbl:content includes="D">
     <S/>
    </xbl:content>
   </P>
  </xbl:template>
 </xbl:binding>
 <xbl:binding element="Q">
  <xbl:template>
   <X>
    <Y>
     <xbl:content>
      <Z1/>
     </xbl:content>
     <xbl:content>
      <Z2/>
     </xbl:content>
    </Y>
   </X>
  </xbl:template>
 </xbl:binding>
</xbl:xbl>

The resulting DOM would look like the following. To read these diagrams, use the following key:

      |    Solid/dashed lines represent normal DOM traversal attribute
   ---+--- relationships using childNodes, parentNode, nextSibling,
      |    previousSibling, firstChild, lastChild, etc.

      :
   ...:... Dotted lines represent the final flattened tree.
      :

White-space nodes have, for sanity, been left out of these diagrams.

DOM view:

   |
   +-- A
       |
       +-- B
           |
           +-- C
           |
           +-- D

The shadow trees of B elements:

   template
    |
    +-- P
        |
        +-- Q
        |   |
        |   +-- content
        |       |
        |       +-- R
        |
        +-- content
            |
            +-- S

The shadow trees of Q elements:

   template
    |
    +-- X
        |
        +-- Y
            |
            +-- content
            |   |
            |   +-- Z1
            |
            +-- content
                |
                +-- Z2

The final flattened tree:

   :
   :.. A
       :
       :.. B
           :
           :.. P
               :
               :.. Q
               :   :
               :   :.. X
               :       :
               :       :.. Y
               :           :
               :           :.. C
               :           :
               :           :.. Z2
               :
               :.. D

The final flattened tree overlayed with the core DOM (the "*" and "#" characters here identify which content elements the two explicit children are assigned to):

   :|___
   :....A      template
        :|___     |
        :... B    |
            :|    |
            :|... P       template
             |   :|____      |
             |   :|... Q     |
             |   :|   :|     |
             |   :|   :|.... X
             |   :|    |     :\_______
             |   :|    |     :....... Y __
             |   :|    |              :   \
             |   :|    +-- content*   :    |
             |   :|         |         :    |
             |   :|         +-- R     :    +-- content*
             |   :|                   :    |    |
             +---:|--------- C* ......:    |    `-- Z1
             |   :|                   :    |
             |   :|                   :    `-- content
             |   :|                   :         |___
             |   :|                   :............ Z2
             |   :`-- content#
             |   :     |
             |   :     `-- S
             |___:____
                 :... D#

4.5.1. Terminology

Shadow content introduces the concept of shadow scope to nodes within a document. Because shadow content elements can also have bindings attached that generate their own shadow content, this scoping can be taken to an arbitrary level of nesting.

Shadow content nodes are in binding-level shadow scopes. Binding scopes are determined by the bound element to which the binding responsible for the generation of the shadow nodes is attached. The bound element itself is in the shadow scope of the content around it, and its binding's shadow content is in a deeper shadow scope. Shadow content that contains no elements that are themselves bound is said to be in the deepest, or innermost, shadow scope.

4.6. Handling DOM Changes

All of the nodes in the shadow tree are live. Whenever an element is inserted into, removed from, or appended to the DOM, and whenever its attributes or pseudo-class states are changed, all the children of bound elements must check that their assigned content element is still appropriate, following all the same rules that applied when first placing explicit children during shadow content generation. If one or more nodes stop fitting into any of the content elements then they no longer appear in the final flattened tree. Similarly, nodes that previously did not appear in the final flattened tree may start matching a content element and thus be inserted into the flattened tree.

It is possible to manipulate the shadow content contained underneath a bound element using standard DOM APIs. If shadow content that contains a content element is removed, then any explicit children assigned to that element are relocated to the first unlocked content elements that match them. If a content element's includes attribute is changed, then the explicit children of the binding's bound element must be redistributed appropriately.

content elements may be dynamically locked by manipulating their locked attribute. A locked content element cannot accept new children unless they are explicitly assigned to it using the setInsertionPoint() method. However, children already under a locked content element remain there while the element's includes attribute (or lack thereof) matches them.

Whenever the subtree of a template element in a binding document is dynamically modified, any shadow trees that were constructed by cloning that element must be regenerated.

4.7. Shadow Content and CSS

4.7.1. Selectors and Shadow Scopes

Bindings can interleave shadow elements between the bound element and its explicit children. (See: processing content elements.) In this situation, a new tree emerges that is different from the explicit content node tree. In addition to having a single explicit parent (the bound element) and a single set of children (the explicit children in the DOM tree), elements also have a set of shadow parents and shadow children (introduced by bindings when content elements were used). This necessarily affects the CSS model.

Combinators: CSS combinators, in the presence of XBL, must act as follows. This is intended to match the definitions of CSS in all cases other than when a selector would involve one or more XBL elements.

A>B

If "B" is in a shadow tree and "B.parentNode" is a content element or an inherited element, let "X" be "B.parentNode.parentNode", otherwise let "X" be "B.parentNode".

Now if "X" is the root of a shadow tree, but the binding's "allow-selectors-through" is not true, the selector doesn't match "B". Otherwise, if "X" is the root of a shadow tree and the binding's "allow-selectors-through" is true and the binding is the bound element's most derived binding with a shadow tree, then let "X" be the bound element for which the shadow tree was generated. Otherwise, if "X" is the root of a shadow tree and the binding's "allow-selectors-through" is true but the binding is not the bound element's most derived binding with a shadow tree, then let "X" be the parent node of the inherited element into which the shadow tree was placed during the construction of the final flattened tree; if this is itself the root of a shadow tree, then repeat the steps described in this paragraph using that element as "X".

Then, the selector matches "B" if the "X" element is the "A" element.

A B
Matches "B" if either "A>B" matches "B", or "C>B" matches "B" and "A C" matches "C".
A+B
If "B" is in a shadow tree and "B.previousSibling" is a content element or an inherited element, the selector doesn't match "B", otherwise, it matches if "B.previousSibling" is "A".
A~B
Matches "B" if either "A+B" matches "B", or if "C+B" matches "B" and "A~C" matches "C".

The selector p ~ p never matches any elements in the following example, even if the content element has a p element assigned to it:

<template>
 <html:p>...</html:p>
 <content includes="p"><html:p>...</html:p></content>
 <html:p>...</html:p>
</template>
   

Pseudo-classes and pseudo-elements: Pseudo-classes and pseudo-elements are unchanged in the presence of XBL. They operate exclusively on the core DOM.

In particular, note that this means that the selector :nth-child(odd) would match both the A and B nodes in the following example:

<xbl:template>
  <A/>
  <xbl:content/>
  <B/>
</xbl:template>

...regardless of the number of nodes that are inserted at the point given by the content element (whether that be 0, 1, 2, or more nodes).

4.7.2. CSS Property Inheritance and Rendering

The final flattened tree determines how CSS properties (e.g., fonts and colors) are inherited. Elements must inherit from their parent node in the final flattened tree, regardless of what their DOM Core parent node is.

Similarly, the rendering is performed using the final flattened tree. Nodes that do not appear in the final flattened tree have no computed style (as if they were orphan nodes) and are not rendered.

4.7.3. The :-xbl-bound-element Pseudo-Class

The :-xbl-bound-element pseudo-class, when used from a binding, must match the bound element of that binding. If the selector is used somewhere other than in a binding's style sheet (i.e. with a style element in XBL) or in a content element's includes attribute, then it must match any bound element. [SELECTORS]

In the following example, the binding uses this pseudo-class to to draw a border around each of the children of the bound element, but no other elements:

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding>
  <template><content allow-selectors-through="true"/></template>
  <style>
   :-xbl-bound-element > * { border: solid; }
  </style>
 </binding>
</xbl>

4.7.4. Matching Pseudo-Elements

Shadow nodes may be associated with various pre-defined pseudo-elements of the bound element. On any element in the shadow content template, an xbl:pseudo attribute (in the XBL namespace) can be used to specify the name of the pseudo to associate with that element.

For example, once more returning to the HTML file upload control example above, the shadow text field can be set up to be considered a match for the selector input[type=file]::value as follows.

<xbl:binding id="fileUploadControl">
  <xbl:template>
    <html:input type="text" xbl:pseudo="value"/>
    <html:input type="button" value="Browse..."/>
  </xbl:template>
</xbl:binding>

The pseudo must be given without its leading double colon.

If the pseudo-element name is not recognized, it is in error and the UA must ignore the attribute. User agents must not automatically recognize any pseudo-element (as this will break forwards-compatibility).

If an element has multiple nodes with the same pseudo-element, then they all match the relevant selector. Matching of nodes based on their pseudo-element is unaffected by the apply-author-sheets attribute.

The allowed pseudo-elements are:

::value
Intended to represent the entire rectangular 'interactive area' (or the nearest equivalent in non-visual environments) of a text-entry form control, specifically excluding the caption.
::choices
Intended to represent the entire rectangular 'selection area' (or the nearest equivalent in non-visual environments) of a list form control, specifically excluding the caption.
::label
Intended to represent the non-interactive area (or the nearest equivalent in non-visual environments) of control, typically the caption.
::repeat-item
Within a repeating sequence, for example generated by the repeat construct in XForms, each repeated item could be labeled as matching a pseudo-element ::repeat-item.
::icon
Intended to represent the icon part of a control, for example the picture in a toolbar button or the icon next to a menu item.

These pseudo-element descriptions are purely advisory, and while authors are encouraged to use them for their predefined roles, it is valid to use them for other purposes.

The following XBL is part of the definition of a button control.

  <xbl:binding id="imageButton">
    <xbl:template>
      <html:span xbl:pseudo="icon"/>
      <html:span xbl:attr="xbl:text=title"/>
    </xbl:template>
  </xbl:binding>

This control could then be used like this:

<button title="Save" class="save-button"/>

...and styled like this:

  button { -xbl-binding: url(buttons.xml#imageButton); }
  button.save-button::icon {
     content: url(icons/save.png);
  }
  

In property descriptions, the term "all elements" in the "Applies To:" line includes these pseudo-elements, as they map directly to real elements in the binding.

User agents are required to support the above pseudo-element identifiers, in so far as they interact with XBL2. User agents may also support these same pseudo-elements for other purposes, e.g. as described in the CSS3 UI specification. [CSS3UI]

4.8. Shadow Content and xml:base

This section is intended to re-iterate what the xml:base specification already states, in case there is any question about how xml:base processing should work in shadow trees.

Relative xml:bases on nodes in shadow trees are resolved relative to their parentNode, or the ownerDocument if there is no parentNode.

4.9. Shadow Content and Other Things

Since the processing rules of all non-XBL elements found while processing a binding document are not affected by their being part of an XBL subtree, there are certain elements that are unlikely to have the desired effect when included in shadow content templates. Some of these cases are described below.

While some of these effects may seem peculiar, it must be emphasized that they are merely the result of XBL not affecting the semantics of these elements at all. It would have been possible to define XBL in such a way that the semantics of various elements from the XHTML, XML Events, etc, namespaces were modified, but this would have required XBL knowing about special elements from a large number of namespaces, causing XBL implementations to have large interdependencies.

4.9.1. General Rules

Shadow content is not considered part of a document, so elements that are defined to trigger when they are "inserted into the document" do not trigger during binding attachment.

IDs used in shadow content, as seen on XML Events nodes, in XHTML on the html:label element's for attribute, and in many other places, must be resolved in the context of the shadow scope and (failing that) the binding document, not the scope of the document into which the shadow content is inserted.

If a shadow template has an html:img element that has its usemap attribute set:

<template ...>
  <html:img src="..." usemap="#test" alt="..."/>
</template>

If the binding is applied to an element in a document containing an html:map element with ID "test", that image map will not be associated with this image. If the binding document itself contains an html:map element with ID "test", however, that would be associated with the element (even if it was, say, in another binding's template).

If the template looked like this:

<template ...>
  <html:img src="..." usemap="#test" alt="..."/>
  <html:map id="test"> ... </html:map>
</template>

...then the img element would always be attached to that map element, regardless of the existence of other map elements in the binding document.

When an element's processing model is defined in terms of the element's child nodes or descendants, shadow trees do not affect the processing model (unless this is called out explicitly below). For instance, an HTML title element's behavior in determining the document title is unaffected by XBL, even if the title element is bound or has bound elements in its descendants.

When the nodes are cloned, their xml:base data remains as it was in the bindings document (see rules for content generation). Therefore URIs consisting of just fragment identifiers (such as those in url() notation in style attributes of, e.g., XHTML nodes) refer to resources in the bindings document, not content in the bound document or the shadow tree.

This would cause trouble with attribute forwarding, so the attribute forwarding syntax allows attributes to be marked as being of type "url".

4.9.2. Style Blocks

The semantics of html:style elements is that they introduce new styles for their document. Since the document, in the case of anything in an XBL subtree, is the bindings document (or the non-XBL document in which the XBL subtree is found), that is the document that must be affected by such a style sheet.

Since the style sheets of such resource documents generally have no effect, placing html:style blocks in XBL binding documents is usually redundant. Such an element placed in a shadow content template does not affect the documents into which the shadow content is later inserted during binding attachment.

4.9.3. Script Blocks

Script elements, such as html:script and its ilk, are typically evaluated only during parsing, or during parsing and when inserted into a document. In all cases, however, they are evaluated in the context of their owner document. Therefore such elements must only be evaluated during initial parsing, in the context of the XBL subtree's document, and not during binding attachment.

4.9.4. Event Handler Blocks

XML Events elements in the binding document must result in event handlers being registered as event listeners on the nodes in the original bindings document (including possibly the template node) as described in XML Events. They may be included in shadow content templates, but when the shadow content template is cloned, the newly cloned event handlers must cause new event listeners to be added to their new DOM Core parent nodes. Thus an event handler that is the child of an template element in the shadow content template will never fire once it has been cloned, since the events do not bubble into the template elements. [XMLEVENTS]

Event handler blocks that are children of handlers elements (in particular XML Events handler blocks) cause event listeners to be fired when event forwarding happens, just like with XBL handler elements.

4.9.5. HTML Forms

Forms and form controls in shadow trees don't interact with form controls and form elements in the bound document. Each document and shadow tree creates a new scope for forms and form controls.

Here's an extract from an HTML document with a form:

...
<form action="register" method="post">
 <h2>Customer Registration</h2>
 <p>Please enter your details.</p>
 <fieldset>
  <legend>Contact Information</legend>
  <p>Name: <input name="name" title="Enter your full name (first name first)."></p>
  <p>Job Title: <input name="title" title="Enter your job title, e.g. 'Software Engineer'."></p>
  <p>E-mail: <input name="email" title="Enter your e-mail address, in the form 'user@example.com'."></p>
 </fieldset>
 <fieldset>
  <legend>Company Information</legend>
  <p>Name: <input name="company" title="Enter the name of your employer."></p>
  <p>Address: <textarea name="address" title="Enter the full street address of your employer, including postal code."></p>
 </fieldset>
 <fieldset>
  <legend>Additional Information</legend>
  <p>Birthday: <input name="dob" title="Enter your birthdate in the form YYYY-MM-DD, e.g. 1975-03-29."></p>
  <p>Favourite animal: <input name="animal" title="Enter the word 'Cat'."></p>
 </fieldset>
 <fieldset>
  <legend>Submission</legend>
  <p><button title="Only submit the form when you are sure it is complete.">Submit</button></p>
 </fieldset>
</form>
...

The first binding, shown below as an extract from an XBL document, could be attached to the form above, through CSS, to provide a help box that shows the help text associated with the currently focussed control:

...
<binding id="form-with-help">
 <template>
  <div>
   <div class="header">Form:</div>
   <div class="form"><content/></div>
  </div>
  <div>
   <div class="header">Help:</div>
   <div id="help"/>
  </div>
 </template>
 <resources>
  <style>
   .header { font-size: larger; }
   .form { height: 15em; overflow: scroll; }
  </style>
 </resources>
 <handlers>
  <handler event="focus">
   this.shadowTree.getElementById('help').textContent = event.target.getAttribute('title');
  </handler>
 </handlers>
</binding>
...

The help could be positioned more usefully by a slightly more advanced binding that positioned the div when setting the help.

The last binding isn't particularly interesting. However, the important thing to note is that if it was extended to include form controls of its own, as in the following example, the form controls in the binding would not interact with the form in the markup:

...
<binding id="form-with-help">
 <template>
  <div class="header">
   <div class="title"><content includes=":-xbl-bound-element > h2:first-of-type"/></div>
   <div class="tagline"><content includes=":-xbl-bound-element > h2:first-of-type ~ p:first-of-type"/></div>
  </div>
  <div>
   <div class="panel"><content locked="true" id="current"/></div>
  </div>
  <div>
   <div class="buttons">
    <button id="back">Back</button>
    <button id="next">Next</button>
   </div>
  </div>
  <div class="hidden"><content includes=":-xbl-bound-element > fieldset" id="not-current"/></div>
 </template>
 <implementation>
  ({
    set current(fieldset) {
      if (this._current)
        this.shadowTree.getElementById('not-current').setInsertionPoint(this._current);
      this._current = fieldset;
      if (this._current)
        this.shadowTree.getElementById('current').setInsertionPoint(this._current);
    },
    back: function() {
      if (!this._current) return;
      var notCurrent = this.shadowTree.getElementById('not-current');
      notCurrent.setInsertionPoint(this._current);
      var last = this._current;
      var index = 0;
      while (index &lt; notCurrent.xblChildNodes.length &&
             notCurrent.xblChildNodes[index] != this._current)
        last = notCurrent.xblChildNodes[index++];
      this._current = last;
      this.shadowTree.getElementById('current').setInsertionPoint(this._current);
    }
    next: function() {
      if (!this._current) return;
      var notCurrent = this.shadowTree.getElementById('not-current');
      notCurrent.setInsertionPoint(this._current);
      var last = this._current;
      var index = notCurrent.xblChildNodes.length-1;
      while (index > 0 && notCurrent.xblChildNodes[index] != this._current)
        last = notCurrent.xblChildNodes[index++];
      this._current = last;
      this.shadowTree.getElementById('current').setInsertionPoint(this._current);
    }
    get current() {
      return this._current;
    },
    xblBindingAttached: function() {
      this.current = this.getElementById('not-current').xblChildNodes[0];
      this.shadowTree.getElementById('back').addEventListener('click', this.back, false);
      this.shadowTree.getElementById('next').addEventListener('click', this.next, false);
    },
  })
 </implementation>
 <resources>
  <style> ... </style>
 </resources>
</binding>
...

Again, the binding could be made cleaner, e.g. by disabling the "back" button when on the first page, and by hiding the last fieldset and instead having a "finish" button, but these improvements are left as exercises for the reader.

4.9.6. SVG

Painting: When painting groups, for child elements that have shadow trees, instead of painting the child element itself, the group must paint the child nodes of the element's shadow tree's root template element.

Text: When rendering text, for descendant elements that have shadow trees, instead of using the element or its children directly, the user agent must use the child nodes of the element's shadow tree's root template element. (All other processing, e.g. handling of combining characters, must then be done as defined for SVG.)

ID references and URIs: When a URI identifies an element with a shadow tree, the SVG processor must use the first element node in the element's shadow tree's root template element's childNodes list instead of the element itself. If there are no elements, then the SVG document is in error. The SVG specification defines how to handle documents that are in error.

In the following example, the UA would render the string "Hello Cruel World".

<svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <b:xbl xmlns:b="http://www.w3.org/ns/xbl">
      <b:binding element="|world">
        <b:template>
          <tspan b:attr="b:text=data"/> World
        </b:template>
      </b:binding>
    </b:xbl>
  </defs>
  <text y="50" font-size="12">
    Hello <world xmlns="" data="Cruel"/>
  </text>
</svg>

4.10. Binding Style Sheets

Shadow content nodes and bound elements are styled using style sheets from a number of sources, depending on the values of certain attributes. When multiple bindings are applied to the same bound element, the sheets from each binding all contribute to the final set of style sheets to apply, the style sheets of the most derived binding being walked first. For each binding, the style sheets that apply are as follows, in the order given:

Scoped style sheets: A binding file can load style sheets using the style element. (See: loading style sheets.) These style sheets must be applied to the bound element and to all shadow content attached to the bound element.

If the binding was attached using CSS, the scoped style sheets have the same CSS origin as the sheet with the rule responsible for the binding. Style sheets used by bindings that are attached using the DOM or using <?xbl?> are treated as author-level sheets.

When bindings from multiple levels are applied to the same bound element, the style sheets that apply must cascade according to their own levels.

An element E is attached to binding U from the user agent style sheet, and binding A from the DOM, which places A in the author level. When the style sheets that apply to E are sorted, U must be applied at the UA level and A at the author level.

Author style sheets: While the apply-author-sheets attribute on the template element found at the root of the element's shadow tree is set to true, the rules specified in any author style sheets at outer shadow scopes must be applied to the shadow content. Otherwise, only those matched through predefined pseudo-elements are used, and other author-level sheets in higher shadow scopes must not be applied to the shadow content. (The bound element is always styled using the sheets of higher shadow scopes.)

By default, style sheets specified in bindings (as described above) are applied only to shadow content generated by bindings attached to the bound element and to the bound element itself. A second attribute, apply-binding-sheets, can be used to indicate that all children of the bound element, both shadow and explicit, can be styled by the sheets in the binding's document. This can be controlled on a per-insertion-point basis. While this attribute is set to true on a content node in the shadow tree DOM, any nodes that are assigned to that element, and any descendants of those nodes, must have the scoped style sheets of the binding (those that apply to the shadow content as described above) applied to them too.

Sheets are always walked from the innermost shadow scope to the outermost shadow scope (with rules in the outermost shadow scope therefore overriding rules of equal specificity in the innermost shadow scope). With this ordering a binding that defines a widget can define a default look for the widget that can then be easily overridden by a client of the widget. For multiple bindings attached to the same element, the sheets are walked from the base binding to the most derived binding.

User agent style sheets and user style sheets: These are always applied to all shadow scopes.

Since styles from both author style sheets and binding style sheets are applied to the bound element, it is possible for an infinite loop to form where an author sets the '-xbl-binding' property to a particular binding that then explicitly sets the '-xbl-binding' property to 'none' (or another binding). This specification does not take any precautions to avoid this, any more than it takes precautions to avoid loops caused by binding constructors explicitly calling removeBinding() to remove the binding itself and binding detachment event handlers reattaching the bindings. Similar potential loops exist also in underlying technologies, for example :hover rules that cause elements to no longer be hovered, or focus event handlers that move focus to an element and blur event handlers that move focus back to the element.

In so far as XBL is concerned, authors must avoid constructing such loops, and implementers must ensure that such loops do not prevent users from interacting with the user agent.

4.10.1. Summary of styling rules

This section is non-normative.

The <style> is applied only to the bound element and the shadow content that was generated by the binding. The <style> is also applied to explicit children whose <content>'s apply-binding-sheets is set to true.

Continuing from the above, author sheets (styles from the bound document) are applied to the shadow content only if apply-author-sheets is set to true for the <template>.

Last, but not least, one can use author sheets to change the style of elements in the shadow content that use the xbl:pseudo attribute, as long as it matches them with pseudo-elements (irrespective of the apply-author-sheets setting).

5. Binding Implementations

Bindings can define methods and properties on a bound element using the implementation element. A binding implementation provides a new set of methods and properties that can be invoked from the bound element.

How the binding implementation is defined depends on the scripting language used; the details for ECMAScript are defined below.

In general, however, each binding has an object that implements the XBLImplementation interface, along with any other interfaces that the implementation might implement. This is the implementation object for that instance of the binding. All elements implement the ElementXBL interface, whose xblImplementations member returns an object implementing XBLImplementationList. This object lists all the implementation objects for that bound element. (If the element is not a bound element, the list is empty.)

5.1. The XBLImplementation Interface

All implementation objects support the XBLImplementation interface (in addition to any other interfaces specific to the binding). By implementing the methods defined in this interface, bindings can be notified of the binding's state with respect to its environment.

interface XBLImplementation {
  void xblBindingAttached();
  void xblEnteredDocument();
  void xblLeftDocument();
};

The xblBindingAttached() method is called by the user agent after the binding has been attached. (See: binding attachment model.)

The xblEnteredDocument() method is called by the user agent in two cases:

Thus, it can be used to perform initialisation steps that depend upon being in a document. (See: binding attachment model, handling insertion and removal from the document.)

The xblLeftDocument() method is called by the user agent when the bound element, or one of its ancestors, or one of the elements in a higher shadow scope, is removed from the document. (See: handling insertion and removal from the document.)

If the implementation does not define one of these methods, then when that method is invoked, nothing must happen (as if all bindings had default implementations of those methods that were no-ops).

Authors should not start their own methods with the three letters "xbl". Future versions of this specification might add new callbacks to this interface, and if they do, those methods will start with the prefix "xbl".

This binding implements a clock. However, to save resources, the clock is only active when it is actually included in a document.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding id="clock">
  <implementation>
   ({
    xblEnteredDocument: function () {
      this.timer = setInterval(update, 1000);
    },
    xblLeftDocument: function () {
      clearInterval(this.timer);
    },
    update: function () {
      this.shadowTree.getElementById('clock-value').textContent = new Date();
    },
   })
  </implementation>
  <template><div id="clock-value"></div></template>
 </binding>
</xbl>

5.2. The XBLImplementationList Interface

The xblImplementations attribute on all elements must return an instance of an XBLImplementationList object (the same object for the lifetime of the element), which is a live list of the implementation objects provided by the bindings for that bound element at any particular point in time.

interface XBLImplementationList {
  XBLImplementation item(in unsigned long index);
  readonly attribute unsigned long length;
};

The length attribute must return the number of implementation objects associated with the bound element, or zero if the element is not a bound element or has none of its bindings have implementations.

The item(n) method must return the nth implementation object associated with the bound element. If the index is not a number between zero and length-1 (inclusive), then the method must raise an INDEX_SIZE_ERR DOM exception. [DOM3CORE]

The list must be ordered such that the most derived binding is last, and the base binding has index zero.

In ECMAScript implementations, objects that implement the XBLImplementationList interface must also have a [[Get]] method that, when invoked with a property name that is a number, acts like the item() method would when invoked with that argument.

5.3. Accessing Binding Implementations

Script can access binding implementations directly using the xblImplementations member. In addition, in languages that support dynamic dispatch (such as ECMAScript), any attempts to access members of ElementXBL objects that do not correspond to methods or properties on the object itself but do correspond to members of one of the objects in the xblImplementations list must be forwarded to the last object in the xblImplementations list that is so matched.

5.4. ECMAScript Bindings

When a binding is attached, the user agent must follow the following steps to make the binding implementation available to scripts:

  1. If this is the first time the binding defined by that binding element is used since that binding document was loaded, and if that element contains an implementation element, then:

    1. The first implementation element child of the binding element must have its code compiled and run (see below).
    2. The return value of that script, if it is an object, must be forever associated with that binding element as that binding's implementation prototype object.

    Otherwise, if the binding element doesn't contain an implementation element, or if it does but it does not evaluate to an object, then an empty object must be created (by invoking the Object constructor in the global scope of the binding document), and the binding element's implementation prototype object must be forever set to that object.

    Any further changes to implementation elements will have no effect on the implementation prototype object of this particular binding.

  2. Next, the UA must create two new ECMAScript objects by invoking the Object constructor in the global scope of the binding document. These objects are the private object and the public object.

  3. The [[Prototype]] property of the private object must be set to the public object, and the [[Prototype]] property of the public object must be set to the binding's implementation prototype object.

  4. The private object must then have the following fields defined:

    public
    This field's value must be set to a reference to the public object.
    boundElement
    This field's value must be set to a reference of the node object that is the bound element.
    shadowTree
    This field's value must be initially set to null. Its value is changed during shadow content generation and destruction.
    baseBinding
    If the binding's extends attribute caused another binding to be attached to the bound element, then the baseBinding field's value must be set to a reference of that binding's implementation object, if it has one (if that is an ECMAScript implementation as well, then that is that binding's public object). Otherwise, it must be set to the value null.

Conceptually, the private and public objects together make the implementation object, but as far as the xblImplementations property's list is concerned, the public object is the one that is returned as the implementation object.

5.4.1. Compiling ECMAScript Bindings

When the user agent has to compile and run an XBL binding ECMAScript implementation, it must first obtain the script itself in the manner described in the section on loading and running scripts, and must then compile and execute the script using the binding document's global scope.

If the script evaluates to an object, then that is the implementation prototype object. Otherwise, there isn't one.

5.4.2. Invoking Methods on an ECMAScript Implementation Object

When function code of an implementation object implemented in ECMAScript is called, the user agent must set the this value to the private object associated with the public object on which the function was invoked.

6. Event Handlers

6.1. Event Forwarding

Whenever an event passes through a bound element, whether during the capture, target, bubble, or default phases, the user agent must also invoke any appropriate event listeners attached to the binding's first handlers element.

When events are forwarded in this manner, the event handlers attached to the handlers element must fire after any event handlers on the bound element itself in the capture phase, after the event has been retargeted to shadow nodes, if appropriate; and before any event handlers on the bound element itself in the target and bubble phases, before the event has been retargeted to the bound element, if appropriate. (See: event flow and targeting across shadow scopes.)

Event handlers must fire first on the most derived binding and then on its inherited binding, continuing all the way up the chains to the base binding. A derived handler then has a way of preventing the event from flowing to the handlers of the bindings it inherits from, by using the stopImmediatePropagation() method.

Event handlers may be attached to the handlers element using any method, including DOM3 Events' addEventListener() method and the handler XBL element. All event handlers registered on the first handlers element of the binding are considered, not just those attached using the handler element.

In the following example, the bound element is the hotspot element. When either it is clicked or the element inside it is clicked, an alert is generated containing the text "Hello World".

The bound document is:

<hotspot message="Hello World">
  <instruction> Activate this text. </instruction>
</hotspot>

The binding is:

<binding>
  <handlers>
    <handler event="click">
      alert(event.currentTarget.getAttribute('message'));
    </handler>
  </handlers>
</binding>

Note that the event object passed to the handlers's handlers is the same as would have been passed to event handlers registered directly on the bound element. This is why currentTarget in this example points to the bound element.

6.2. Registering Event Handlers with the handler Element

Whenever the event or phase attributes of an XBL handler element change, or whenever a handler element's parent changes, an event listener must be registered on the element's parent element, if it has one; and if an event listener had previously been registered for that handler element, it must be removed.

In terms of the DOM3 Events addEventListenerNS() method, the arguments used when registering the new event listener must be set as follows:

namespaceURI
Always null in this version of XBL.
type
The literal value of the event attribute, or the empty string if the attribute is missing.
listener
An object implementing the EventListener interface that invokes the handler element as described below.
useCapture
True if the phase attribute is present and has the literal value capture, otherwise false.
evtGroup
Always null in this version of XBL. (Event listeners registered with handler elements are registered in the default event group.)

Thus, the event attribute specifies the event type, and the phase attribute the listener type. If the event attribute is missing or its value is the empty string, it is in error. If the phase attribute is present but has a value other than the literal strings capture, target, bubble, or default-action, it is in error. (However, their being in error does not affect the processing model described above.)

When a handler element is invoked by the object passed to the addEventListenerNS() method, the user agent must check that the event in question was forwarded to a handlers element from a bound element, and that that handlers element is the parent node of the handler element.

If that isn't the case, then the invocation must do nothing.

Otherwise, if that condition is met, then the UA must check any relevant filters specified on the handler element. If any of them fail to match the event, then the invocation must not do anything else. (The filter attributes are defined in the next few sections.)

Otherwise, if all the filters match, then the user agent must execute the contents of the handler element, treating it as being in the language specified by the script-type attribute. (See: loading and running scripts, event handlers implemented in ECMAScript.) The script must be run in the context of the binding document (and not, e.g., in the bound document's context).

The propagate attribute specifies whether, after processing all listeners at the current node, the event is allowed to continue on its path (either in the capture or the bubble phase). The possible values are stop and continue (the default). If stop is specified, then after the event handler has been fired, the event's stopPropagation() method must be called.

The default-action attribute specifies whether, after processing of all listeners for the event, the default action for the event (if any) should be performed or not. For instance, in XHTML the default action for a mouse click on an html:a element or one of its descendants is to traverse the link. The possible values are cancel and perform (the default). If cancel is specified, then after the event handler has been fired, the event's preventDefault() method must be called.

The trusted attribute is a filter that, if set to the value true, matches only events whose trusted attribute is true. Otherwise, if it has another value or if it is not specified, any event matches this filter. This filter can be used regardless of the type of the event.

The phase attribute is a filter that matches only events that are in the phase it specifies. If the attribute has the value capture, it must only match events whose eventPhase attribute has the value CAPTURING_PHASE (1). If the attribute has the value target, it must only match events whose eventPhase attribute has the value AT_TARGET (2). If the attribute has the value default-action, it must only match events whose eventPhase attribute has the value 0x78626C44 (2019716164). This is the value used in the default phase. If it is specified and has another value, it must only match events whose eventPhase attribute has the value BUBBLE_PHASE (3). If it is not specified, any event matches this filter. This filter can be used regardless of the type of the event.

In addition to the trusted and phase filters, event-specific filters may be used, as described in the following sections. Only filters appropriate to the given event type may be used; all other filter attributes, if specified, are in error and UAs must ignore them.

6.3. Mouse Event Handler Filters

For events that use or derive from the MouseEvent interface, three event-specific filter attributes may be used. [DOM3EVENTS]

The filters are:

button
A list of values, at least one of which has to match the button attribute on the event object for the XBL event handler to fire. If the attribute is not specified, then any value of the button attribute on the event object must be considered a match. If the value is specified, it must be a space-separated list of values, each of which must be one or more digits in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). Each string must be interpreted as a base ten integer and then compared to the value of the button attribute on the event object. If none of the values match the button attribute, then the event handler must not be executed.
click-count
A list of values, at least one of which has to match the detail attribute on the event object for the XBL event handler to fire. If the attribute is not specified, then any value of the detail attribute on the event object must be considered a match. If the value is specified, it must be a space-separated list of values, each of which must be one or more digits in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). Each string must be interpreted as a base ten integer and then compared to the value of the detail attribute on the event object. If none of the values match the detail attribute, then the event handler must not be executed. Note that this is checked for any event that uses the MouseEvent interface, not just those for which detail is defined. Authors should take care to not specify this attribute with, for example, mouseover events, since in that context detail is undefined.
modifiers
See modifiers.

6.4. Key Event Handler Filters

For events that use or derive from the KeyboardEvent interface, three event-specific filter attributes may be used. [DOM3EVENTS]

The filters are:

key
The key identifier. If specified, the value must be an exact literal match of the keyIdentifier attribute of the event object. For example, Enter. If this filter is specified but the modifiers attribute is not, the user agent must act as if the modifiers attribute had been set with the value "none". If specified, the value of this attribute must be a valid value of the keyIdentifier attribute.
key-location
If specified, this attribute's value must be a space-separated list of values from the four literal (case-sensitive) keywords standard, left, right, and numpad (with no duplicates), which map to the DOM values 0x00, 0x01, 0x02, or 0x03 respectively. If specified, the event object's keyLocation attribute must have a value equal to the numeric value of one of the specified keywords. Unknown and duplicate values are in error and UAs must ignore them (although without dropping any correct values).
modifiers
See modifiers.

6.5. Text Input Event Handler Filters

For events that use or derive from the TextEvent interface, one event-specific filter attribute may be used. [DOM3EVENTS]

The filter is:

text
The text data to match. If specified, the value must be an exact literal match of the data attribute of the event object. The value of the attribute may be any string.

6.6. Mutation Event Handler Filters

For events that use or derive from the MutationEvent interface, four event-specific filter attributes may be used. [DOM3EVENTS]

The filters are:

prev-value
If specified, the value must be an exact literal match of the prevValue attribute of the event object. The value of the attribute may be any string.
new-value
If specified, the value must be an exact literal match of the newValue attribute of the event object. The value of the attribute may be any string.
attr-name
If specified, the value must be an exact literal match of the attrName attribute of the event object. The value of the attribute may be any string.
attr-change
If specified, this attribute's value must be a space-separated list of values from the three literal (case-sensitive) keywords modification, addition, removal (with no duplicates), which map to the DOM values 0x00, 0x01, or 0x02 respectively. If specified, the event object's attrChange attribute must have a value equal to the numeric value of one of the specified keywords. Unknown and duplicate values are in error and the UA must ignore them, although without causing correct values to be dropped.

There are currently no attributes specifically designed to be used with events that use the MutationEventName interface.

6.7. Modifiers

The modifiers attribute specifies a filter dependent on which keyboard accelerator keys ("modifiers") are set.

The attribute is a space-separated list of values.

To process this filter, the user agent must first invoke the getModifierState() method of the event for all the modifiers the UA supports, noting the return value for each modifier. The user agent must then walk through all the values in the modifiers attribute, as described in the list below. The filter matches if all the modifiers that returned true are accounted for, and none of the values made the filter fail.

The getModifierState() method, and the modifiers that go with it, are defined in DOM3 Events. [DOM3EVENTS]

By default, only the CapsLock, NumLock, and Scroll modifiers are accounted for. Values on the attribute cause other modifiers to be accounted for.

Before comparing the modifiers to the attribute values, the user agent must convert all the modifiers to lowercase.

User agents must recognize the accel keyword as a synonym for the modifier that is the primary accelerator key on the platform (on Windows, this would typically be control, on Mac it would typically be meta).

User agents must also recognize the access keyword as a synonym for the primary shortcut mnemonic key on the platform (on Windows, this would typically be alt).

The attribute values must be handled as follows:

any
If the keyword any is specified, then all the modifiers are accounted for.
none
The keyword none makes the filter fail if any modifiers returned true, except for the CapsLock, NumLock, and Scroll modifiers, which are ignored for the purposes of this keyword.
+modifier
The modifier modifier is accounted for. If the given modifier does not correspond to the lowercase version of one of the modifiers supported by the UA, or if the getModifierState() method did not actually return true for the corresponding modifier, then it makes the filter fail.
-modifier
If the getModifierState() method returned true for the modifier corresponding to modifier, then it makes the filter fail.
modifier?
The modifier modifier is accounted for. If the getModifierState() method did not actually return true for the modifier corresponding to modifier, the value is ignored.
Anything else ("modifier")
Treated the same as +modifier.

A modifier can be listed multiple times, though this is not particularly useful.

Here are some examples of what this means:

modifiers not specified
The modifiers are ignored, unless the key attribute is specified, in which case the event handler is only invoked if no modifiers are pressed.
modifiers=""
modifiers="none"
The event handler is only invoked if no modifiers are pressed.
modifiers="any"
The modifiers are ignored.
modifiers="alt control"
The filter matches if both alt and control were pressed, and no others.
modifiers="alt control?"
The filter matches if alt was pressed, and no others, except maybe control.
modifiers="any -control"
The filter matches if the control key was not pressed, regardless of the state of other modifiers.
modifiers="Alt"
Never matches, since the user agent must compare the given values to lowercase modifier names.
modifiers="accel -capslock"
Matches when the platform's accelerator key is pressed, but only if the caps lock key is not active.
modifiers="alt alt alt"
Same as just listing the alt modifier once: the filter matches if only the alt modifier is pressed.
modifiers="+alt -accel"
Matches when the platform's accelerator key is pressed, but the alt modifier is not pressed. If the platform's accelerator key is in fact the alt key, this filter can never match.

6.8. Event Flow and Targeting Across Shadow Scopes

DOM events can fire on shadow targets just as they can on explicit targets. As long as the event flows within the same shadow tree scope, it is no different from the behavior outlined in the DOM Events specification.

Events must flow through the final transformed content model (the final flattened tree).

Whenever events originating from a shadow tree flow from a shadow element in that shadow tree to the bound element, one of two actions occurs. Either the event is retargeted so that the bound element becomes the target, or the event is stopped and flow proceeds to the next phase. Whenever an event is retargeted, the event is cloned, with the clone's target field set to the bound element.

The action taken (retarget vs. stop) is specific to the event type. In general, UI events must be retargeted and mutation events must be stopped. Exceptions to the rule are noted below. The goal of this retargeting or stopping is to stop outer shadow scopes from being exposed to nodes from inner shadow scopes, and to stop outer shadow scopes from getting apparently meaningless events that only make sense in the context of inner shadow scopes.

During the capture phase, the rules are exactly reversed. The first node to see the event is the node after which bubbling stops. The target node, when the event is passing through a node at a higher shadow scope than the event target, is always the bound element in whose shadow content the event target lies.

When the event is fired for the bound element's event handlers, it does so in the target phase. The capture phase listeners are not fired for the bound element.

The timing of event retargeting is such that when the event is forwarded to the handlers element, the bound element sees the relevant shadow tree node as the target, rather than the bound element as the target. (See: event forwarding.)

Events bubble into deeper scopes; for example, an event fired on a bound element's explicit child bubbles into the element containing the content element the element was assigned to. This does not cause any event retargeting to take place, either when entering the deeper scope or when leaving it, since such an event does not actually originate in that shadow tree.

Any method invocations on any clones of the event object must also be forwarded to the original event and all the clones, so that attempts to stop propagation and cancel the default action affect the event regardless of how many scopes it has crossed.

Bound document:

<root xmlns="">
 <bound/>
</root>

Binding template applied to the bound element:

  ...
  <xbl:template>
   <shadow xmlns="">
    <target/>
   </shadow>
  </xbl:template>
  ...

If someone clicks the "target" element, the click event is dispatched as follows:

  1. The capture listeners on root. Capture phase, target is bound.
  2. The capture listeners on bound. Capture phase, target is bound.
  3. The capture listeners on the binding's handlers. Capture phase, target is target.
  4. The capture listeners on shadow. Capture phase, target is target.
  5. The bubbling listeners on target. Target phase, target is target.
  6. The bubbling listeners on shadow. Bubbling phase, target is target.
  7. The bubbling listeners on the binding's handlers. Bubbling phase, target is target.
  8. The bubbling listeners on bound. Target phase, target is bound.
  9. The bubbling listeners on root. Bubbling phase, target is bound.
  10. The default action listeners on the binding's handlers. Default phase, target is target.
  11. The UA's default action listeners for target. Default phase, target is target.

6.9. The Default Phase

If an event bubbles through or is targeted at one or more bound elements, and the event is not canceled (after the capture, target, and bubble phases have all completed, its defaultPrevented attribute is still false), then the event's eventPhase attribute must be set to the value 0x78626C44 (2019716164), and then the event must be forwarded to the relevant handlers elements of all the bound elements the event bubbled through or was targeted at in those bubble and target phases, in reverse tree order (starting from the target node and walking the tree towards the Document node), with currentTarget set to the relevant bound element each time. If the event is canceled (that is, if the defaultPrevented attribute becomes true) while being forwarded to one of these bound elements, subsequent bound elements must not receive the event.

If the event has a UA default action, it must only perform it if the defaultPrevented attribute is still false after it has been so forwarded.

The stopPropagation() method must have no effect during this "default" phase.

6.10. The focus, DOMFocusIn, blur, and DOMFocusOut Events

If shadow content underneath a focusable bound element loses focus and shadow content also underneath the bound element takes focus, then both focus change events must be stopped. As far as the bound element is concerned, it retains focus throughout the two events. (Other specifications may go into more detail as to how to determine if an element can be focused.)

The 'nav-index' property defined in the CSS UI module [CSS3UI] can be used to specify the tab order for focusable elements. This property can be specified on shadow content. Each shadow scope has a unique tab order. The 'nav-index' values used in one shadow scope are ignored by other shadow scopes. The tab order is resolved in the shadow tree first to produce a list of elements in the tab order. This list is substituted in place of the bound element in the bound element's tree tab order.

As an example, consider the HTML file upload control. It is a focusable element that in turn is made up of two focusable shadow elements: a text field and a button. Tab indices can be specified on the text field and the button to indicate the order in which the components of the file control should be accessed when tabbing.

When the user tabs such that the file control should become focused, the user agent determines if any shadow content should also become focused, using the tab order specified by the shadow content elements. It then generates a focus event on the text field inside the file control. As this event flows across shadow scopes, it is retargeted to be a focus event on the file control itself.

Focus events should also be stopped if the bound element is already focused. For example, if the user has already focused the text field within an HTML file upload control, then the file upload control is now also focused. If the user then focuses the button inside the file upload control, the focus event generated for the button is stopped before it reaches the file control, since the file control is already focused.

Because content in multiple shadow scopes can be focused, the CSS :focus pseudo-element is hierarchical in the presence of XBL, with up to one element in each shadow scope matching the pseudo-class. Style rules can be written with the assumption that they will match (in the above example) both the file control and the element focused inside the file control. In other words, an arbitrary chain of elements can be in the :focus state at the same time.

Further specifications may describe in more detail the interaction of arbitrary chains of elements that can be in the :focus state at the same time.

6.11. The mouseover and mouseout Events

Mouseover and mouseout events must be retargeted if the pointing device genuinely moves onto (enters) or is moved away (exits) the bound element (in addition to entering or exiting some shadow content). If, however, the user has simply moved the pointing device from one element in the shadow tree to another element in the same shadow tree, without entering or exiting the bound element itself, then the event must be stopped.

For example, if the user enters the HTML file upload control from the left, a mouseover event is generated for the shadow text field. Because this event also constitutes a mouseover of the file control itself, the event is retargeted when it flows across shadow scopes. If the user then moves the mouse from the text field to the button, a mouseout is generated for the text field, followed by a mouseover of the button.

Since neither of these events constitutes a mouseover or mouseout of the file control itself, the events are not allowed to flow to the file control. If the user continues moving to the right and leaves the button, then the mouseout generated will be retargeted, since the file control will also have been exited.

6.12. Event Handlers Implemented in ECMAScript

When a script of a handler element implemented in ECMAScript is executed the user agent must set the this value to the private object part of the implementation object of the binding with which the handler element is associated. The script must be executed as a function body with one argument, called event, which is a reference to the Event object representing the event. The script must be compiled and executed each time it is accessed, so that any dynamic changes to the event handler code in the binding document take effect.

7. DOM Interfaces

XBL introduces a few XBL-specific interfaces.

7.1. The DocumentXBL Interface

The DocumentXBL interface contains methods for loading and obtaining binding documents. The interface is implemented by DOM documents that support having their elements bound by XBL.

IDL Definition
interface DocumentXBL {
  readonly attribute NamedNodeMap bindingDocuments;
  Document loadBindingDocument(in DOMString documentURI);
};
Attributes
bindingDocuments of type NamedNodeMap, readonly
The bindingDocuments attribute must return a NamedNodeMap of all the binding documents loaded by the document. Documents are referenced using their URIs as the node names, with null namespaces. The NamedNodeMap must be live, and must raise NO_MODIFICATION_ALLOWED_ERR on any attempts at modification or deletion.
Methods
loadBindingDocument
The loadBindingDocument method must synchronously load the specified binding document (unless it has already been loaded), and any bindings defined by that document must be applied to matching elements in the document that corresponds to this DocumentXBL object. The method must then return the binding document's Document object. (See: binding attachment and detachment.) If the load succeeded, it is also added to the bindingDocuments attribute. If the load fails, this method must return null.
Parameters
documentURI of type DOMString
The URI of a binding document.
Return Value
Document
The return value of loadBindingDocument() is the Document object of the binding document that was loaded, or null if the load failed.
No Exceptions

7.2. The ElementXBL Interface

The ElementXBL interface contains methods for adding or removing bindings from an element. The interface is implemented by all Element nodes (regardless of whether they are currently involved with any XBL processing) and may be obtained using binding-specific casting methods on an Element interface.

IDL Definition
interface ElementXBL {
  readonly attribute XBLImplementationList xblImplementations;
  void addBinding(in DOMString bindingURI);
  void removeBinding(in DOMString bindingURI);
  boolean hasBinding(in DOMString bindingURI);
};
Attributes
xblImplementations of type XBLImplementationList, readonly
See binding implementations.
Methods
addBinding
The addBinding method must attach the specified binding (and any bindings that the binding inherits from) to the element. This call is not necessarily synchronous. The binding may not be attached yet when the call completes.
Parameters
bindingURI of type DOMString
A URI that specifies the location of a specific binding to attach.
No Return Value
Exceptions
HIERARCHY_REQUEST_ERR
This exception must be raised if the node is not an element.
removeBinding
The removeBinding method must detach the specified binding (and any bindings that the binding inherits from explicitly using the extends attribute) from the element. This method can only detach bindings that were attached using addBinding. If the binding in question is not attached to this element (or was attached through another attachment mechanism), or if the node is not an element, then the method must do nothing.
Parameters
bindingURI of type DOMString
A URI that specifies the location of a specific binding to detach.
No Return Value
No Exceptions
hasBinding

The hasBinding method must check the bindings applied to the element and compares each binding's URI with the parameter passed. If any of the bindings matches the specified URI, then the method must return true, otherwise it must return false. This can be used to check if an element has been bound to a particular binding in in order to ensure that the expected methods and attributes are available.

For example widgets may walk up their ancestors looking for an element that has been bound to a form-container binding in order to locate their scope (so that radio buttons may properly be mutually exclusive, or so that a submit button can properly submit a form).

Parameters
bindingURI of type DOMString
A URI that specifies the location of a specific binding for which to look.
Returns
boolean
true if any of the bindings match the parameter, false otherwise.
No Exceptions

7.2.1. Scoping and Access Using the DOM

In effect the shadow content exists in its own insulated pocket within the document, its shadow scope. Bound elements have no knowledge of their shadow children in terms of DOM Core [DOM3CORE]. The shadow content is not accessible via the childNodes list for the bound element, nor is it accessible using firstChild/nextSibling to iterate over the children of the bound element.

DOM methods that can be invoked on elements (e.g., getElementsByTagName()) will only see nodes that are in the same shadow scope. Methods invoked on the document (e.g., getElementById) only see nodes that are not in shadow trees.

On shadow content nodes, ownerDocument always points to the document from which the nodes were cloned.

Elements in different shadow scopes may have clashing IDs. IDs need only be unique within each shadow scope.

Elements that are the root of a shadow tree (the cloned template elements) cannot be inserted into a document. Any attempt to do so must raise a HIERARCHY_REQUEST_ERR.

Manipulating the DOM of a shadow content tree must directly affect the content under the bound element. content elements may be moved about or even removed altogether, xbl:attr attributes may be attached and modified, etc, and all these changes must be immediately reflected in the DOM and the final flattened tree.

Changes to namespace prefix definitions in the shadow tree that affect QNames used in xbl:attr attributes may have their effects applied immediately but this is not required.

Because each bound element gets its own copy of the cloned template, changes to a bound element's shadow content only affect that bound element. Other bindings are unaffected.

If an element is added to the DOM dynamically, its shadow scope is that of its parent element. Adding an element as a child of a bound element causes that element to be assigned to an appropriate content element (if there is one — if there is not, the element does not appear anywhere in the final flattened tree).

7.3. The XBLContentElement Interface

The XBLContentElement interface is implemented by content elements in the XBL namespace (regardless of whether they are in error or not).

IDL Definition
interface XBLContentElement : Element {
  readonly attribute NodeList xblChildNodes;
  void setInsertionPoint(in Node child);
};
Attributes
xblChildNodes of type NodeList, readonly

The xblChildNodes attribute must return a NodeList containing a live list of all the nodes that are currently assigned to the content element.

A node can be assigned to multiple content elements simultaneously, in the case of bound elements inside shadow trees.

Exception: if the content element is not in a shadow tree, then this attribute must return null.

Methods
setInsertionPoint

The setInsertionPoint method perform the following steps.

  1. Let e be the bound element for which the user agent generated the shadow tree in which the given content element finds itself. If there is no such bound element (e.g. the content element was created by the author using createElementNS()), then the user agent must abort these steps and do nothing.
  2. Let child be the node that was given as an argument to the method.
  3. The user agent must then check that the parent of child is in fact e. If it is not, then the user agent must abort these steps and do nothing.
  4. The user agent must then check that either the content element has no includes attribute, or that child matches the selector given in the content element's includes attribute. If the attribute is present but the element does not match the selector it specifies (or if the selector is not syntactically correct), then the user agent must abort these steps and do nothing.
  5. Finally, the user agent must assign child to the content element, instead of whatever previous content element it was assigned to, if any.

See processing content elements.

Exception: if the content element is not in a shadow tree, then this method must raise an INVALID_STATE_ERR exception.

The order of nodes assigned to a content element is always be the same as the relative order of those nodes in the original core DOM.

Parameters
child of type Node
The child of the bound element to assign to this content element.
No Return Value
No Exceptions

The following example implements a tabbed interface as a binding. It creates a list of buttons to enable the user to access each of the sections that the tab box contains, and then uses setInsertionPoint() to make the selected tab panel appear.

<xbl xmlns="http://www.w3.org/ns/xbl">
 <template>
  <div id="tabs"/>
  <div class="panel"><content id="current" locked="true"/></div>
  <div class="hidden"><content id="not-current"/></div>
 </template>
 <implementation>
  ({
    set current(section) {
      if (this._current)
        this.shadowTree.getElementById('not-current').setInsertionPoint(this._current);
      this._current = section;
      if (this._current)
        this.shadowTree.getElementById('current').setInsertionPoint(this._current);
    },
    get current() {
      return this._current;
    },
    xblBindingAttached: function() {
      this.updateTabs();
      this.current = this.boundElement.getElementsByTagName('section')[0];
    },
    clearTabs: function() {
      with (this.shadowTree.getElementById('tabs'))
        while (hasChildNodes())
          removeChild(firstChild);
    },
    addTabFor: function(section) {
      var tab = document.createElementNS('http://www.w3.org/ns/xbl', 'div');
      tab.appendChild(document.createTextNode(section.getAttribute('title')););
      tab.addEventListener('click', function (_this) { return function (event) {
        var tabs = this.shadowTree.getElementByTagID('tabs').getElementsByTagName('div');
        for (var i = 0; i &lt; tabs.length; ++i)
          tabs[i].setAttribute('class', '');
        _this.current = section;
        event.target.setAttribute('class', 'selected');
        event.preventDefault();
      } }(this), false);
      this.shadowTree.getElementById('tabs').appendChild(tab);
    },
    updateTabs: function() {
      this.clearTabs();
      var sections = this.boundElement.getElementsByTagName('section');
      for (var i = 0; i &lt; sections.length; ++i)
        this.addTabFor(sections[i]);
    },
  })
 </implementation>
 <resources>
  <style>
   #tabs > div { /* style for tabs */ }
   #tabs > div.selected { /* style for selected tab */ }
   .panel { /* style for panel */ }
   .hidden { display: none; }
  </style>
 </resources>
</xbl>

This binding could be applied to any element that has section elements as children, each section element having its title given in its title attribute.

The binding implemented above doesn't dynamically update when the DOM is changed, a full implementation would probably want to listen to mutation events to catch attribute changes and insertions and removals of the panels.

7.4. The XBLTemplateElement Interface

The XBLTemplateElement interface is implemented by template elements that are in the XBL namespace (regardless of whether they are in error or not).

IDL Definition
interface XBLTemplateElement : Element {
  Element getElementById(in DOMString elementId);
};
Attributes
No Attributes
Methods
getElementById

This method is modeled after the method of the same name defined by [DOM3CORE] on the Document interface.

This method must return an Element that has an ID attribute with the given value, and that is a descendant of the template element on which it is invoked. If more than one such element exists, which one is returned is undefined. If no such element exists, this returns null.

Attributes with the name "ID" or "id" are not of type ID unless so defined. For example, attributes with the name "id" on elements that are from the XHTML, MathML and XBL namespaces are defined to be of type ID by their respective specifications.

Parameters
elementId of type DOMString
The unique id value for an element.
Returns
Element
The matching element or null if there is none.
No Exceptions

7.5. The EventXBL Interface

Objects that implement the Event interface must also implement the EventXBL interface. [DOM3EVENTS]

IDL Definition
interface EventXBL {
  readonly attribute boolean trusted;
};

The trusted attribute must return true if the user agent dispatched the event (e.g. in response to user action), and false otherwise (e.g. if an author script dispatched a synthetic event). Events fired by the user agent in response to untrusted events must themselves be untrusted.

8. Resources

8.1. Loading External Resources

8.1.1. Binding Documents

Several features in XBL allow binding documents to be loaded.

When the specification says that a binding document must be loaded unless it has already been loaded, then references to the same binding document (even if they are somewhat indirect, for example via HTTP redirects) must result in the same Document instance being reused, or shared.

To determine if two binding documents are the same, their final base URIs (after all redirects) are compared.

A binding document A contains a binding element that refers to a second binding document X. A new DOM Document instance is created to represent that instance and the relevant bindings are used.

Now assume RX is a resource that redirects to resource X using the HTTP 301 redirection mechanism. A second binding element in the binding document A refers to resource RX. When that resource is being loaded, the redirect to X would be discovered, and therefore instead of creating a new Document, the existing one is reused.

Such sharing of binding documents must be limited to binding documents loaded by a document, its binding documents, its scripts, and its style sheets. Nested documents and images do not share binding documents with each other or with their container document.

For example, if a document uses a binding document, and its style sheets use that binding document, the same binding document instance will be used for both cases. However, if that document contains an iframe whose document uses the same binding document, a new instance will be used: the binding document instance from the outer document is not reused.

Binding documents that are currently loading count as binding documents that are already loaded for the purposes of this reuse mechanism.

8.1.2. External Resources

When the specification simply says that the external resource must be loaded, without giving any caveats regarding multiple accesses of the same resource, then each reference must instantiate a new unique copy of the document.

For example, two style elements whose src attributes point to the same style sheet must create two different Stylesheet instances, such that mutating one does not affect the other.

Several XBL attributes are defined to contain URIs. All URIs may be relative. For relative URIs, the rules given in [XMLBASE] must be used to resolve the value to an absolute URI.

8.2. Loading and Running Scripts

Scripts in XBL may be found in script, implementation, and handler elements, or in resources that those elements point to.

In the case of script and implementation elements, if a src attribute is present then the contents of the element must be ignored (even if fetching the specified URI fails).

The rules for parsing the scripts are the same for all three elements, but depend on the scripting language specified by the author.

For non-XML languages, if the content is inline, UAs must concatenate all the textual contents of text and CDATA child nodes, and must ignore any other, non-text nodes (such as elements and comments) along with all their children. All descendant elements must be processed, though, according to their semantics, before the XBL script block itself is executed.

For example, in an XHTML-aware and ECMAScript-capable user agent, the following ridiculous code would cause the alerts to appear in the order One, Two, Three, and would set the test property in the binding document's global script scope to the string "undefinedABC":

<xbl xmlns="http://www.w3.org/ns/xbl">
 <!-- WARNING: THIS EXAMPLE IS NON-CONFORMING -->
 <script>
  alert('Two');
  test += "B";
  <script xmlns="http://www.w3.org/1999/xhtml">
   alert('One');
   test += "A";
  </script>
  alert('Three');
  test += "C";
 </script>
</xbl>

Authors must not ever consider doing this. The above is invalid.

For XML-based scripting languages, handling of unknown elements and other unexpected nodes must be defined by that language.

If the content is not inline, then when the element is evaluated, the resource specified by the src attribute must be fetched. For script elements, while an external script is being fetched, any pending binding attachments from the same binding document must block, as must the evaluation of any further script blocks. For implementation elements, while the external script is being fetched, the attachment of that binding must block. If the file's Content-Type (or equivalent for non-HTTP protocols), if any, is not of the type specified on the xbl element, then the script must be ignored. Otherwise, the contents of that file must be used directly, as specified by the relevant language specification.

8.2.1. XForms Actions

This section is only normative for implementations that support XForms.

It is theoretically possible to use XForms Actions as the scripting language in XBL [XFORMS]. The MIME type that indicates this scripting language is tentatively defined to be application/x-xforms-actions+xml. XBL elements have the following semantics when used with XForms Actions:

script elements
These are exactly equivalent to xforms:action elements that trigger immediately upon being added to the document.
handler elements
These are exactly equivalent to xforms:action elements that trigger when the appropriate event on the bound element is detected.
implementation elements
Since XForms Actions cannot declare new interfaces, implementation elements when the script language is set to application/x-xforms-actions+xml are in error and the UA must ignore them, by treating implementation elements like xforms:action elements that are not bound to any event.

8.2.2. Scripting Model

Each document that runs script (including bound documents and binding documents) has a DocumentWindow object, a Window object, a global script scope, and a security context. In ECMAScript, the global script scope and the Window object are one and the same.

This above paragraph is a vague description of the Web's de-facto scripting model. This specification depends on that model, but it hasn't yet been specified in detail. This specification will be updated when a suitable description is available.

Script must always be executed in the context of the global script scope of the document specified by the script's element's ownerDocument DOM attribute. This implies that scripts from different bindings in the same binding document bound to different elements in the same bound document share the same scripting scope. If the bindings were defined in the document itself, then the scope is the same scope as for that document.

A binding document must inherit the security context of the document to which it is bound, not the security context of the domain from which it was fetched.

Scripting and security contexts are (or will be) described in the HTML5 specification. [HTML5]

In binding documents, the location and history properties of the Window object, and the location and cookie properties of the DocumentWindow object, must return null, and any methods that are defined in terms of the browsing context's session history must do nothing. [HTML5]

User agents should implement a security mechanism such as the proposed <?access-control?> PI to prevent unauthorized cross-domain access. [ACCESSCONTROL]

8.3. Loading Style Sheets

XBL style elements describe the style sheets that apply to bindings.

If a style element's src attribute is present, the contents of the element must be ignored (even if fetching the specified URI failed). Otherwise, it is the element's contents that give the style sheet.

Wherever the style is found, the rules for parsing it are the same, but depend on the language specified by the author.

For non-XML styling languages, if the content is inline, UAs must concatenate all the textual contents of text and CDATA child nodes, and the UA must ignore any other, non-text nodes (such as elements and comments) along with all their children. All descendant elements must be processed, though, according to their semantics, before the XBL style block itself is parsed. A style element labeled as containing a style sheet in a non-XML language yet containing element nodes is in error.

For example, in an XHTML-aware and ECMAScript-capable user agent, the rather dubious code below would result in a binding that enclosed the bound element's children in a green box, not a red one:

<xbl xmlns="http://www.w3.org/ns/xbl">
 <binding>
  <template>
   <div>
    <content/>
   </div>
  </template>
  <resources>
   <style id="test">
    div { background: red; }
    <script xmlns="http://www.w3.org/1999/xhtml">
     document.getElementById('test').firstChild.data = "div { background: green; }";
    </script>
    <p xmlns="http://www.w3.org/1999/xhtml">
     div { border: red solid; }
     This will either be ignored by the XBL user agent, or will cause
     it to abort all processing altogether, as this text node is not a
     child of the style element.
    </p>
   </style>
  </resources>
 </binding>
</xbl>

For XML-based styling languages, handling of unknown elements and other unexpected nodes must be defined by that language.

If the content was in another resource, and the Content-Type (or equivalent for non-HTTP protocols), if any, was of the type specified on the xbl element (or implied by its absence), then the contents of that file must be used directly, as specified by the relevant language specification. Otherwise, the style element doesn't provide any styling. The src attribute must only be examined once all of the element's children have been processed (if any).

8.4. Interpretation of URIs to XBL bindings

XBL attachment mechanisms use a URI to specify which binding to attach to the designated element.

For example:

my|foo {
   -xbl-binding: url("http://www.example.org/bindings.xml#fooBinding");
}

This section defines how these URIs, which are used in the argument to the addBinding() method, and in the value of the '-xbl-binding' property, are to be interpreted.

The URI specifies a particular binding document (an XBL document or non-XBL document containing one or more XBL subtrees). The user agent must fetch this resource (unless it has already been loaded).

If the URI contains a fragment identifier, then it must be processed as described in the relevant MIME type definition. The element targeted by the fragment identifier must be a binding element within an XBL subtree in the specified document, and that element must be a direct child of an xbl element that does not itself have an xbl element as an ancestor; if these conditions are not met then the URI is in error.

For example, if the binding document is sent as application/xhtml+xml, and the fragment identifier matches a binding element's id attribute, then that is the binding that is attached.

If there is no fragment identifier and the URI points to an XBL document (not a non-XBL document) then the first binding element in the binding document that is a child of the root xbl element is selected. Otherwise, the URI does not point to a correct binding and is in error.

When an attachment mechanism uses a URI that is in error (as per the last two paragraphs), then the user agent must act as if the attachment mechanism had not specified that binding.

Otherwise, the specified binding is attached to the element, as described for the relevant attachment mechanism.

9. Summaries of Elements, Attributes, and Events

9.1. Elements and Attributes

This section is non-normative.

Element Attributes Content Model
xbl
binding
implementation
  • Script
template
content
inherited
div
handlers
handler
  • Script
resources
style
  • Style
prefetch
script
  • Script

9.2. Events

This section is non-normative.

Event Name Interface Target when fired by UA Bubbles? Cancelable? Default Action
xbl-bound Event Bound element ✓ Bubbles None
xbl-bindings-are-ready Event Bound document's root element ✓ Bubbles None

Acknowledgments

David Hyatt developed XBL 1.0 and provided guidance for the development of XBL 2.0.

The editor would like to thank Alex Danilo, Alex Vincent, Anne van Kesteren, Axel Hecht, Antoine Quint, Benjamin Smedberg, Bjoern Hoehrmann, Boris Zbarsky, Brendan Eich, Cameron McCormack, Chris Lilley, Christophe Jolif, Cyril Concolato, Darryl Fuller, Dean Jackson, Jon Ferraiolo, Jonas Sicking, Karl Dubost, L. David Baron, Lachlan Hunt, Liam Quin, Marcos Caceres, Mark Baker, Micah Dubinko, Mihai Sucan, Mikko Pohja, Peter Sorotokin, Robin Berjon, Ruud Steltenpool, Sean Hogan, Simon Pieters, Steve K. Speicher, Steve Zilles, Tim Rowley, and Tom Pike for their contributions to this specification.

References

All references are normative unless prefixed by the mark "(Informative)".

[ACCESSCONTROL]
(Informative) Authorizing Read Access to XML Content Using the <?access-control?> Processing Instruction 1.0, M. Oshry, B. Porter, R. Auburn. W3C, June 2005. The latest version of this specification is available at http://www.w3.org/TR/access-control/
[CSS21]
CSS 2.1 Specification, B. Bos, T. Çelik, I. Hickson, H. Lie. W3C, September 2003. The latest version of the CSS 2.1 specification is available at http://www.w3.org/TR/CSS21/
[CSS3UI]
CSS3 Basic User Interface Module, T. Çelik. W3C, May 2004. The latest version of the CSS3 UI module is available at http://www.w3.org/TR/css3-ui/
[DOM2VIEWS]
Document Object Model (DOM) Level 2 Views Specification, A. Le Hors, L. Cable. W3C, November 2000. The latest version of the DOM Level 2 Views specification is available at http://www.w3.org/TR/DOM-Level-2-Views/
[DOM3CORE]
Document Object Model (DOM) Level 3 Core Specification, A. Le Hors, P. Le Hégaret, L. Wood, G. Nicol, J. Robie, M. Champion, S. Byrne. W3C, November 2003. The latest version of the DOM Level 3 Core specification is available at http://www.w3.org/TR/DOM-Level-3-Core/
[DOM3EVENTS]
Document Object Model (DOM) Level 3 Events Specification, P. Le Hégaret, T. Pixley. W3C, November 2003. (Note: Despite its non-normative status on the W3C Recommendation track, this specification should be considered normative for the purposes of conformance.) The latest version of the DOM Level 3 Events specification is available at http://www.w3.org/TR/DOM-Level-3-Events/
[ECMA262]
ECMAScript Language Specification, Third Edition. ECMA, December 1999. This version of the ECMAScript Language is available at http://www.ecma-international.org/publications/standards/Ecma-262.htm
(Informative) ECMAScript Language Specification, Fourth Edition (Incomplete Draft Proposal). ECMA, January 2006. This version of the ECMAScript Language is available at http://developer.mozilla.org/es4/spec/spec.html
[HTC]
(Informative) HTML Components, C. Wilson. Microsoft, September 1998. The HTML Components submission is available at http://www.w3.org/TR/1998/NOTE-HTMLComponents-19981023
[HTML5]
(Informative) Web Applications 1.0, I. Hickson. WHATWG, work in progress. The latest version of the HTML5 proposal is at http://whatwg.org/specs/web-apps/current-work/
[MQ]
Media Queries, H. Lie, T. Çelik, D Glazman. W3C, July 2002. The latest version of Media Queries is available at http://www.w3.org/TR/css3-mediaqueries/
[RFC2045]
Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies, N. Freed, N. Borenstein. IETF, November 1996. RFC 2045 is available at http://www.ietf.org/rfc/rfc2045
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997. RFC 2119 is available at http://www.ietf.org/rfc/rfc2119.txt
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter. IETF, January 2005. RFC 3986 is available at http://www.ietf.org/rfc/rfc3986
[RFC3987]
Internationalized Resource Identifiers (IRIs), M. Dürst, M. Suignard. IETF, January 2005. RFC 3987 is available at http://www.ietf.org/rfc/rfc3987
[SELECTORS]
Selectors, D. Glazman, T. Çelik, I. Hickson. W3C, November 2001. The latest version of the Selectors specification is available at http://www.w3.org/TR/css3-selectors/
[UNICODE]
The Unicode Standard, Version 5.0.0, The Unicode Consortium. Boston, MA, Addison-Wesley, November 2006. ISBN 0-321-48091-0. The latest version of the Unicode specification is available at http://www.unicode.org/versions/
[XBL10]
(Informative) XML Binding Language, D. Hyatt. Mozilla, February 2001. The XBL submission is available at http://www.w3.org/TR/2001/NOTE-xbl-20010223/
(Informative) XML Binding Language, D. Hyatt. Mozilla, November 2000 (and subsequently edited by other contributors). The XBL 1.0 specification is available at http://www.mozilla.org/projects/xbl/xbl.html
[XFORMS]
(Informative) XForms 1.0, M. Dubinko, L. Klotz, R. Merrick, T. Raman. W3C, October 2003. The latest version of the XForms specification is available at http://www.w3.org/TR/xforms/
[XML]
Extensible Markup Language (XML) 1.0 (Third Edition), T. Bray, J. Paoli, C. Sperberg-McQueen, E. Maler, F. Yergeau. W3C, Feburary 2004. The latest version of the XML specification is available at http://www.w3.org/TR/REC-xml/
[XMLBASE]
XML Base, J. Marsh. W3C, June 2001. The latest version of the XML Base specification is available at http://www.w3.org/TR/xmlbase/
[XMLEVENTS]
XML Events, S. McCarron, S. Pemberton, T. Raman. W3C, October 2003. The latest version of the XML Events specification is available at http://www.w3.org/TR/xml-events/
[XMLNS]
Namespaces in XML, T. Bray, D. Hollander, A. Layman. W3C, January 1999. The latest version of the Namespaces in XML specification is available at http://www.w3.org/TR/REC-xml-names/
[XMLSSPI]
Associating Style Sheets with XML documents, J. Clark. W3C, June 1999. The latest version of the Associating Style Sheets with XML documents specification is available at http://www.w3.org/TR/xml-stylesheet/