Bindings

This section is tested and adjusted for the current Firefox implementation. Please edit only if an actual behavior differs from the described one. Please do not edit only on the basis of another XBL specification.

<!ELEMENT bindings ( binding* ) >

Hierarchy:   root element
May contain: <binding>

The bindings element is the root element of any XBL document. It should usually declare XBL as the default namespace (unless an XBL namespace prefix is used) and it may additionally declare other namespace prefixes used in your binding.

bindings contains zero or more binding elements as children. Each binding child element defines a unique binding that can be attached to elements in other documents.

An element can have only one binding attached (explicitly or inherited) at one moment. From several bindings only the last in the sequence will be used (like with any CSS rule).

helloworld.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Hello world!</title>
<style type="text/css">
p {
 -moz-binding: url(hello.xml#default);
}
#p03 {
 -moz-binding: url(hello.xml#hello2);
}
</style>
</head>
<body>

  <p>Default content</p>
  <p>Default content</p>
  <p id="p03">Default content</p>

</body>
</html>

hello.xml:

<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
 xmlns:html="http://www.w3.org/1999/xhtml">
  <binding id="default">
    <content><html:b>Hello world! </html:b><children/></content>
  </binding>
  <binding id="hello2">
    <content><html:b>Hello from my binding! </html:b><children/></content>
  </binding>
</bindings>

You can view the result by opening helloworld.html in Firefox. hello.xml should reside in the same directory which contains helloworld.html.

Next: bindings > binding element.

Notes

<bindings xmlns="http://www.mozilla.org/xbl"
 xmlns:html = "http://www.w3.org/1999/xhtml"
 xmlns:xul  = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
 xmlns:svg  = "http://www.w3.org/2000/svg"
 xmlns:xlink= "http://www.w3.org/1999/xlink">

binding

<!ENTITY % binding-content "(resources?,content?,implementation?,handlers?)">
<!ELEMENT binding %binding-content;>
<!ATTLIST binding
   id                     ID             #REQUIRED
   extends                CDATA          #IMPLIED
   display                CDATA          #IMPLIED
   inheritstyle           true           #IMPLIED
>

The binding element describes a single XBL binding. A XBL binding can add anonymous content, fields, properties, methods, and event handlers to HTML/XML elements.

A single XBL binding can be attached to an element by using style sheets or by scripting. (See bug 83830 for <table> specifics).

CSS:

div {
 -moz-binding: url(myBinding.xml#default);
}

DOM:

elementReference.style.MozBinding = "url(myBinding.xml#default)";

In both cases above we are using binding with id="default" contained in file myBinding.xml

Starting with Firefox 3, you can also use a data: URL to embed the binding inline:

div {
  -moz-binding: url(data:text/xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cbindings%20id%3D%22xbltestBindings%22%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22%3E%0A%20%20%3Cbinding%20id%3D%22xbltest%22%3E%3Ccontent%3EPASS%3C/content%3E%3C/binding%3E%0A%3C/bindings%3E%0A);
}

Since data: URLs don't support fragment identifiers, the first binding found in the embedded XML is used instead. Keep in mind that the binding is still required to have an ID even though you're not referencing it. In addition, data: URLs are only supported from chrome code (in other words, from the application or an extension).

Note: The normal same-origin policy is used for web sites; they can only link to XBL files on the same domain, or within the chrome.

For clarity's sake, here's what the embedded XML in the previous example looks like:

<?xml version="1.0"?>
<bindings id="xbltestBindings" xmlns="http://www.mozilla.org/xbl">
  <binding id="xbltest"><content>PASS</content></binding>
</bindings>

Only CSS declarations provide an easy way to attach bindings to any set of elements. It also makes your binding partially functional if scripting is disabled. In the latter case all methods and handlers will be blocked, but the anonymous content and styling will be still used. Given that the CSS declarations should be always used - unless you need to add bindings at runtime to individual elements.

A binding element may contain a resources tag, a content tag, a implementation tag and a handlers tag.

 

content

<!ELEMENT content ANY>
<!ATTLIST content
   id               ID           #IMPLIED
>

A binding can specify new content that is placed inside the bound element. Although you can see this content on screen as if it was directly in the file, this content is anonymous and is hidden from the normal DOM. To access anonymous nodes on an XBL bound element, you can use the getAnonymousElementByAttribute and getAnonymousNodes functions. The only XBL element that can appear inside the content tag is the children tag. Attributes on the <content> element in the binding are set on the bound element.

children

<!ELEMENT children EMPTY>
<!ATTLIST children
   id               ID                           #IMPLIED
   includes         CDATA                        #IMPLIED
>

Specifies the location where any child elements of the bound element are placed in the generated content.

Normally, if the element bound to has its own content, the anonymous content is not generated. However, with a children element, you can merge the content from the HTML/XML element and the XBL content.

If the children tag contains content itself, that content will become the default content. If the element the binding is attached to contains content, the default content will be ignored. If the element does not contain content, the default content will be added.

implementation

<!ENTITY % implementation-content "(method|property)*">
<!ELEMENT implementation %implementation-content;>
<!ATTLIST implementation
   id               ID           #IMPLIED
   name             CDATA        #IMPLIED
   implements       CDATA        #IMPLIED
>

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

constructor

The code inside the constructor is called when a binding has just been attached to an element. So full access to anonymous nodes generated by the binding is already possible. The constructor tag must be placed inside the implementation tag.

Note: Prior to Firefox 3, the constructor could be called at a time when reflow of the document layout was locked down, so that attempting to get layout information from within the constructor could return out of date information. In Firefox 3 and later, the constructor is called when reflow can take place, which results in up-to-date information being returned. See bug 398404 for details.
Note:  All properties of the binding are "imported" as local variables in a constructor's scope. See bug 407314 for more details.

destructor

The code inside the destructor is called when a binding is being removed from an element. You can use this to unload resources to free memory. However the destructor is often not called when it should, see bug 230086. The destructor tag must be placed inside the implementation tag.

method

<!ENTITY % method-content "(parameter*,body?)">
<!ELEMENT method %method-content;>
<!ATTLIST method
   id               ID           #IMPLIED
   name             CDATA        #REQUIRED
   type             CDATA        #IMPLIED
>

The method element is used to describe a single method of a binding implementation.

Example

<method name="scrollTo">
  <parameter name="index"/>
  <body>
    this.setAttribute("scrollpos", index);
  </body>
</method>

parameter

<!ELEMENT parameter EMPTY>
<!ATTLIST parameter
   id               ID           #IMPLIED
   name             CDATA        #REQUIRED
>

The parameter element is used inside a method element. It represents a single parameter of a method.

body

<!ELEMENT body CDATA>
<!ATTLIST body
   id               ID           #IMPLIED
>

The body element represents the implementation of its corresponding method. Its contents are the script that is executed when the method is invoked.

field

<!ELEMENT field EMPTY>
<!ATTLIST field
   id               ID                  #IMPLIED
   name             CDATA               #REQUIRED
   readonly         (true|false)        #IMPLIED
>

A field is similar to a property, except that it should not have a getter or setter. It is useful as a simple holder for a value. The field element must have content which is code that determines the initial value of the field. The field tag must be inside the implementation tag.

Note: The readonly attribute did not work correctly on XBL fields until Gecko 2.0.
Note: In Firefox 3, fields are now evaluated the first time they're accessed instead of at binding attachment time. This shouldn't cause any problems in typical use cases, but there are cases in which this will impact the behavior of your code. See bug 372769 for details.

Here are some examples of cases in which the behavior of your code may change due to this change in Firefox 3:

  1. If you have two fields, one named A and one named B, and field A sets .B, the value of .B will depend on whether or not .A has already been accessed.
  2. If a proto is inserted into the proto chain after binding instantiation, doing so may affect field values (this wasn't the case in prior versions of Firefox).
  3. At binding attachment time, <field name="parentNode">this.parentNode</field> is undefined instead of the value of parentNode.
  4. A field no longer changes the value of a property set on the object itself (rather than a proto) before binding attachment.

property

<!ENTITY % property-content "(getter?,setter?)">
<!ELEMENT property %property-content;>
<!ATTLIST property
   id               ID                  #IMPLIED
   name             CDATA               #REQUIRED
   readonly         (true|false)        #IMPLIED
   onget            CDATA               #IMPLIED
   onset            CDATA               #IMPLIED
>

The property element represents a single property of an implementation. A property consists of a pair of getter/setter functions that can be defined using onget/onset attributes or getter/setter elements underneath the property element. Like methods, once the binding is attached, the property can be obtained directly from the bound element. The property tag must be inside the implementation tag.

getter

<!ELEMENT getter PCDATA>
<!ATTLIST getter
   id               ID                  #IMPLIED
>

The getter element contains script that gets executed when a specific property gets called. The getter tag must be inside the property tag.

setter

<!ELEMENT setter PCDATA>
<!ATTLIST setter
   id               ID                  #IMPLIED
>

The setter element contains script that gets executed when a specific property is being set. The setter tag must be inside the property tag.

handlers

<!ENTITY % handlers-content "handler*">
<!ELEMENT handlers %handlers-content;>
<!ATTLIST handlers
   id               ID                  #IMPLIED
>

The handlers element contains event handlers that can be attached to elements within the bound document. These handlers are installed when the binding is attached and removed when the binding is detached. The handlers tag must be inside the binding tag.

handler

<!ENTITY % handler-content "PCDATA">
<!ELEMENT handler %handler-content;>
<!ATTLIST handler
   id               ID                                  #IMPLIED
   event            NMREF                               #REQUIRED
   action           CDATA                               #IMPLIED
   phase            (capturing|bubbling|target)         #IMPLIED
   button           (1|2|3)                             #IMPLIED
   modifiers        CDATA                               #IMPLIED
   keycode          CDATA                               #IMPLIED
   key              CDATA                               #IMPLIED
   charcode         CDATA                               #IMPLIED
   clickcount       (1|2|3)                             #IMPLIED
   command          ID                                  #IMPLIED
   preventdefault   false|true                          #IMPLIED
>

The handler element describes a single event handler. This handler is attached to its target at the time the binding is attached and unhooked when the binding is detached from the bound element. The script inside the handler is executed when the event handler is matched. The handler tag must be inside the handlers tag.

resources

<!ENTITY % resources-content "(image?,stylesheet?)">
<!ELEMENT resources %resources-content;>
<!ATTLIST property
   id               ID                  #IMPLIED
>

Used for inclusion of image elements, to cache them for later use, and for inclusion of stylesheet elements. The resources tag must be used directly inside the binding tag.

stylesheet

<!ELEMENT stylesheet EMPTY>
<!ATTLIST stylesheet
   id               ID                  #IMPLIED
   src              URI                 #REQUIRED
>

The stylesheet element declares a style sheet used by the binding. The style rules in the style sheet will only be applied to the binding, not to other elements in the document. The stylesheet tag must be inside the resources tag.

image

<!ELEMENT image EMPTY>
<!ATTLIST image
   id               ID                  #IMPLIED
   src              URI                 #REQUIRED
>

Declares an image resource used by the binding. The image is loaded as soon as the binding is used. You can use this to preload a number of images for later use. The image tag must be inside the resources tag.