Although it is in the XBL 1.0 specification, Mozilla hasn't fully implemented type="inherits" on the children tag yet, so the best way to work with binding inheritance is to use the extends attribute. Example 7-6 shows a few bindings used in the implementation of the listbox cell in the Mozilla tree. It illustrates how extends is used to inherit from another binding.
In Example 7-6, listcell-iconic inherits listcell. In turn, listcell inherits list-box-base, which holds resources. The listcell binding is a cell with text only and the listcell-iconic binding has text and an image. Thus, the user has a choice of using a list cell binding with an icon or no icon. Yet both of these bindings have access to the stylesheet resource declared in the base binding. If listcell-iconic is used, the duplicate xul:label is ignored in the inherited binding and the stylesheet inherited from the base binding via the inherited binding is used. We've used this technique to illustrate how resources in multiple bindings are shared.
With binding extensions that use the extends attribute, you can also extend a XUL element as a model, using extensions as a proxy to mimic that XUL element. The element may not be included directly in the anonymous content, but its characteristics are still present on the bound element. If you use the XUL namespace xul: in the same way you use it for XUL content in a binding, you can inherit the XUL element properties as illustrated in Example 7-7.
In Example 7-7, the binding has all of the attributes and behavior of a XUL box. Because you extend a box element, the base widget <mybinding> is now a vertical box. The anonymous content is laid out according to the box model, and all attributes that are recognized on the bound element are applied to the box.
Also known as "attribute forwarding," attribute inheritance is a way for anonymous content to link to the attributes from the bound element. When the bound element attribute is changed, this modification filters down to the binding attribute list. The code in Example 7-8 shows anonymous content where multiple attributes are picked up by the xbl:inherits attribute, with each one separated by a comma.
The element that inherits the attributes can be anywhere in the chain of anonymous content. In this case, it is on the top-level box. It assumes the value given to these attributes in the bound element. Here is the XUL that uses the binding content from Example 7-8:
<mywidget orient="vertical" flex="1" align="center" />
The xul:box element inherits the attribute values vertical, 1, and middle, respectively, from the bound element (mywidget). The box in the anonymous content contains three children: two text (description) elements and an image contained in another box. The default orientation for a box is horizontal, but these child elements are now positioned vertically.
![]() | You may notice that the inherits attribute is preceded with the xbl: prefix, unlike other attributes in the XBL element set. Why is this unique? It guarantees that the effect is on the binding and not directly on the element that uses it. This ensures that the element can have an inherits attribute of its own if needed. This scenerio is unlikely and you might wonder why this rule does not apply to other attributes used on XBL elements. To achieve correct binding, the XBL namespace must be declared on an element at a higher level than the element using it, most commonly the <bindings> container, as explained earlier. Here is what the code will look like: <binding id="my-bindings" xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtsml" xmlns:xbl="http://www.mozilla.org/xbl"> |
The third type of inheritance, inheritance of behavior, is also achieved by using the extends attribute and is useful when you want to use methods or properties in another binding. Example 7-9 shows how one binding inherits implementation from another in the same file.
The Widget1 binding in Example 7-9 pulls in Widget2 using extends. Widget2 has implemented a constructor that dumps some text to output. When Widget1 is bound and it does not find any implementation to initiate, it looks to the inherited binding and, in this case, dumps "This is Widget2" to output.
In a bindings inheritance tree, more than one implementation could have a method with the same name. In this case, the most derived binding -- the one nested deepest in the inheritance chain -- is the one used. It is even possible for some common DOM functions used on the bound element outside of the anonymous content to find imitators when implementing the attached bindings.
<method name="getElementById">
<parameter name="id" />
<body>
<!-- implementation here -->
</body>
</method>
If you glance through the source code for the Mozilla chrome, you may notice that many of the standard XUL widgets used were extended by using XBL. The button is a good example.
On its own, the button can display text with the value attribute and an image with the src attribute. Usually, this is sufficient, and you can color the button and change the text font with CSS. But you may want to take advantage of inherent behaviors in other elements or inherit from other bindings. Mozilla buttons are a mix of <box>, <text>, and <image> elements, and they take on the characteristics of each.