XBL Attribute Inheritance

In this section we'll see how attributes can be inherited.

Inherited Attributes

XBL allows us to build composite widgets while hiding their actual implementation. However, with the features mentioned so far, the anonymous content is always created in the same way. It would be useful to add attributes to the bound elements that modify the inner elements. For example:

XUL:

<searchbox/>

XBL:

<binding id="searchBinding">
  <content>
    <xul:textbox/>
    <xul:button label="Search"/>
  </content>
</binding>

In the example, the label attribute has been placed directly on the button element. The problem with this is that the label would be the same every time the binding was used. In this case, it would be preferable if the attribute could be specified on the searchbox instead. XBL provides an inherits attribute which can be used to inherit attributes from the bound element. It should be placed on the element that should inherit an attribute from the outer element, in this case the button. Its value should be set to a comma-separated list of attribute names that are to be inherited.

<xul:textbox xbl:inherits="flex"/>
<xul:button xbl:inherits="label"/>

When the content is generated, the textbox grabs the flex attribute from the searchbox and the button grabs the label attribute from the searchbox. This allows both the flexibility of the textbox and the label of the button to be different for each use of the binding. In addition, changing the value of the attributes on the searchbox with a script will update the textbox and button also. You can add the inherits attribute to as many elements as you wish, to inherit any number of attributes.

Note how the inherits attribute has been placed in the XBL namespace, by prefixing it with 'xbl:'. The namespace should be declared somewhere earlier, usually on the bindings element. The next example demonstrates this.

<bindings xmlns:xbl="http://www.mozilla.org/xbl"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<xbl:binding id="buttonBinding">
  <xbl:content>
    <xul:button label="OK" xbl:inherits="label"/>
  </xbl:content>
</xbl:binding>

In this example, the button inherits the label attribute, but this attribute is also given a value directly in the XBL. This technique is used to set the default value if the attribute is not present. This button will inherit its label attribute from the outer element. However, if no label is present, it will be given a default value of OK.

There may be times where two generated elements need to inherit from an attribute that has the same name. For example, to create a labeled textbox (a textbox with a text description beside it) out of a label and a textbox element, the label will need to inherit its text from the value attribute and the textbox will also need to inherit its default value from the value attribute as well. To solve this, we will need to use a different attribute and map it to the same one. The following demonstrates this:

XUL:

<box class="labeledtextbox" title="Enter some text:" value="OK"/>

CSS:

box.labeledtextbox {
    -moz-binding: url('chrome://example/skin/example.xml#labeledtextbox');
}

XBL:

<binding id="labeledtextbox">
  <content>
    <xul:label xbl:inherits="value=title"/>
    <xul:textbox xbl:inherits="value"/>
  </content>
</binding>

The textbox inherits the value attribute directly. To set the value attribute on the label, we need to use a different attribute name and map it to the value. The inherits attribute on the label grabs the title attribute from the labeledtextbox and maps it to the value attribute of the label element. The syntax <inner attribute>=<outer attribute> is used to map one attribute to another. Here is another example:

XUL:

<box class="okcancel" oktitle="OK" canceltitle="Cancel" image="happy.png"/>

CSS:

box.okcancel {
    -moz-binding: url('chrome://example/skin/example.xml#okcancel');
}

XBL:

<binding id="okcancel">
  <content>
    <xul:button xbl:inherits="label=oktitle,image"/>
    <xul:button xbl:inherits="label=canceltitle"/>
  </content>
</binding>

The value of the oktitle attribute is mapped to the label attribute of the first button. The canceltitle attribute is mapped to the label attribute of the second button. The first button also inherits the image attribute. The result is as follows:

<box class="okcancel" oktitle="OK" canceltitle="Cancel" image="happy.png">
  <button label="OK" image="happy.png"/>
  <button label="Cancel"/>
</box>

Note that the attributes are duplicated on the inner (anonymous) content. Changing the attributes on the box with the okcancel class will automatically change the values on the buttons. You may also have noticed that we just made up our own attribute names. This is valid in XUL.


(Next) In the next section, we look at adding properties, methods and events to a binding.


Copyright (C) 1999 - 2004 XulPlanet.com