Binding Implementations

Introduction

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

The methods and properties of an implementation can be defined declaratively using method and property tags in XML, or an external implementation (e.g., a binary implementation) can be specified using the src attribute. When the src attribute is specified, any children of the implementation element are ignored.

Methods

Methods are defined using the method element. The name given on the tag using the name attribute is the name that can be used to invoke the method on the element. A method with parameters specifies those parameters and their names with parameter elements declared underneath the method element.

The implementation of the method is contained inside a body element. The parameters specified are bound to their names in the method body.

<method name="scrollToIndex">
  <parameter name="index"/>
  <body>
    <![CDATA[
      if (index < 0)
        return;
      ...
    ]]>
  </body>
</method>

Properties

Properties can also be defined on the bound element using property tags. There are two basic types of properties. The first type of property is a raw value that is set directly on the element itself. The second type of property is one that defines functions that are invoked when the property is either retrieved or set. These functions are called getters and setters in XBL.

For properties with raw values, an initial value can be specified as a child of the property tag. The script is evaluated at the time of binding attachment and the resulting value is stored on the element. It can be assumed that the anonymous content of the binding has been fully constructed, although the bindingattached event will not have fired. Property initialization always takes place after content generation but before the firing of a binding attachment event, since the bindingattached handler needs to be able to assume that all properties will be accessible on the binding.

Properties with getters and setters can define them using onget and onset attributes, or using the more verbose getter and setter elements. If both the attribute form and the element form are used to specify a getter or setter, then the element form is ignored.

A getter contains script whose return value is handed back when the property is requested. A setter contains a script that is invoked when a new value is assigned to the property. In script, the word val is used to represent the new value.

Properties can be designated as constant using the readonly attribute. When set to true, the property's value cannot be altered. If a property is readonly and a setter is defined, then the setter is ignored.

Properties also support a shorthand syntax for defining getters and setters that forward requests or assignments to an anonymous content element. The element attribute specifies the ID of anonymous content underneath the bound element that should be used when obtained the property or setting the property.

On the anonymous content element, the property can be obtained either from an attribute on the element or from a property on the element. The property attribute's value specifies the name of a property to use on the anonymous content element. The attribute attribute specifies the name of an attribute to use on the anonymous content element. If either of these attributes is specified on the property element, then any defined getters and setters are ignored. A raw initial value is also ignored. If both a property and attribute are specified, then the property takes precedence and the attribute is ignored.

Inheritance of Implementations

When two bindings in an inheritance chain both supply implementations, the derived binding's implementation inherits from the base binding's implementation. Method and property lookups are dynamic. Without disambiguating, if two bindings define the same method or property, then the most derived binding's method or property will be used.

Because bindings extend DOM elements, they can override any built-in methods or properties on the DOM element. For example, a binding could override the setAttribute method on Element or the retrieval of the value property for an HTMLInputElement.

The following is currently not implemented in Mozilla, it seems. See bug #373652 for some details.

Implementations can be named using a name attribute specified on the implementation element. When an implementation has a name, that name can be used to disambiguate the desired method or property.

Note: The following paragraphs suggest a syntax for how JavaScript might enable access to base class methods and properties. This is an open issue. Should we attempt to define a language-independent abstraction, or specify that it must be possible to access base bindings' methods and properties?

For example, given a binding with an implementation ColorPickerGrid that derives from an implementation ColorPicker where the two implementations both specify the setColor method, a caller could invoke ColorPicker's method with the following syntax:

... // myElement is a ColorPickerGrid
myElement.ColorPicker.setColor(); // Calls the ColorPicker method.
myElement.setColor(); // Calls the ColorPickerGrid method.
...

In addition to being able to specifically name a base class, the name baseBinding can be used to specify the method or property on the base binding without necessarily knowing what the base class is. This situation can occur when bindings implicitly inherit, e.g., through the use of addBinding.

myElement.baseBinding.setColor(); // Calls the ColorPicker method.