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
attribute has been placed directly on the label
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 button
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
grabs the textbox
flex
attribute from the searchbox and the
grabs the button
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 label
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
element. The next example demonstrates this.bindings
<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
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 label
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
and a label
element, the label will need to inherit its text from the textbox
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:value
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
inherits the textbox
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 value
inherits
attribute on the label grabs the title
attribute from the labeledtextbox and maps it to the
attribute of the value
element. The syntax label
<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
attribute of the first button. The label
canceltitle
attribute is mapped to the
attribute of the second button. The first button also inherits the label
attribute. The result is as follows:image
<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.
If you need to map an attribute to the text content of the node, use "xbl:text" as the inner attribute, eg:
<xul:description xbl:inherits="xbl:text=value"/>
In the next section, we look at adding properties, methods and events to a binding.