XUL Tutorial - 10.3 - XBL Attribute Inheritance
Previous Contents Reference Next

XUL Tutorial - 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, a scroll bar can be used as follows:

XUL:

<scrollbar curpos="5" maxpos="100" increment="1" pageincrement="5">

XBL:

<binding id="scrollbarBinding">
  <content>
    <xul:scrollbarbutton type="decrement"/>
    <xul:slider flex="1"/>
    <xul:scrollbarbutton type="increment"/>
  </content>
</binding>

However, what happens to the attributes that were placed on the scrollbar such as curpos? We really want these attributes to be moved over to the slider. The inherits attribute can be used for this. It should be placed on the element that inherits attributes, in this case the slider. Its value should be set to a comma-separated list of attribute names that are to be inherited:

<xul:slider flex="1" inherits="curpos,maxpos,increment,pageincrement"/>

When the content is generated, the slider grabs the inherited attributes from the scrollbar. In addition, changing the value of the attribute on the scrollbar will update the slider also. You can add the inherits attribute to as many elements as you wish, to inherit any number of attributes.

In addition to having the attribute inherited, you can specify the attribute on the inner element also. This will set the default value if the attribute is not present. For example:

<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 value="OK" xbl:inherits="value"/>
  </xbl:content>
</xbl:binding>

This button will inherit its value attribute from the outer element. However, if no value is present, it will be given a default value of OK.

Note that the namespace needs to explicitly specified as XBL, because the inherits attribute is from XBL, and doesn't make any sense on a XUL element. (Actually, currently Mozilla doesn't care what namespace it is).

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 button (a button with a text description beside it) out of a text and a button element, the text widget will need to inherit its text from the value attribute and so will the button. 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="labeledbutton" title="Click this button:" value="OK"/>

CSS:

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

XBL:

<binding id="labeledbutton">
  <content>
    <xul:text inherits="value=title"/>
    <xul:button inherits="value"/>
  </content>
</binding>
Note that syntax has recently changed to use an equals sign instead of a colon and the order has switched around.

The button inherits the value attribute directly. To set the value on the text widget, we need to use a different attribute name and map it to the value. The inherits attribute on the text element here grabs the title attribute from the labeledbutton and maps it to the value attribute of the text 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" crop="right"/>

CSS:

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

XBL:

<binding id="okcancel">
  <content>
    <xul:button inherits="value=oktitle,crop"/>
    <xul:button inherits="value=canceltitle"/>
  </content>
</binding>

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

<box class="okcancel" oktitle="OK" canceltitle="Cancel" crop="right">
  <button value="OK" crop="right"/>
  <button value="Cancel"/>
<okcancel>

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.


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

XUL Tutorial - 10.3 - XBL Attribute Inheritance
Previous Contents Reference Next