They can be either the content of the element using the binding or anonymous content generated by the base binding.. If the element the binding is attached to contains children, the defa
Trang 1Chapter 7 Extending the UI with XBL- P4
7.4.4 Extra Binding Content and Insertion Points
All examples in the chapter have so far dealt with standard binding content rendering within a bound document The processes outlined in this section can, in one sense, be seen as abnormal because they allow ordering of the content to change based on insertion points defined in the binding This process is done with the XBL <children> element
7.4.4.1 Working with children of the bound element
Zero or more children can be contained in anonymous content These
children are marked up with the XBL-specific <children> tag They can
be either the content of the element using the binding or anonymous content generated by the base binding If the <children> tag contains its own elements, then it will be used as the default content If the element the
binding is attached to contains children, the default content will be ignored
The location of the <children> tags determines the content's insertion point Insertion points play an important role in the generation of content within a template because they affect how the content is displayed and accessed by the DOM
<binding id="my-binding">
<content>
<xul:vbox>
<children />
</xul:vbox>
Trang 2</content>
</binding>
This stripped-down binding has only a vertical box as its own content and looks to the children of the bound element for more content by using the
<children> element Here is the XUL content that uses the binding:
<mybinding id="myNewWidget" flex="1"
class="attached">
<label value="this is child 1" />
<label value="this is child 2" />
</mybinding>
When the binding is attached and the content is drawn, the insertion point for the two labels is inside the container vertical box inside the binding This scenario could be used when a binding is used multiple times Each time, it needs to be rendered differently with extra content that can be provided this way
7.4.4.2 Selective inclusion
Sometimes multiple siblings are located within a box in the XUL, but you want to use only some of them in the binding, such as when a user logs into
a system and content is displayed depending on its level of membership In these cases, you can be selective about which children should be included in the binding Example 7-5 shows how to use the includes attribute on the
<children> element
Example 7-5 Selective inclusion of child content in a binding
<binding id="my-binding">
Trang 3<content>
<xul:vbox class="insideBox">
<xul:description value="Top" />
<xul:box>
<children includes="image" />
</xul:box>
<xul:description value="Bottom" />
</xul:vbox>
</content>
</binding>
The children element in Example 7-5 essentially tells, "Of all the content contained in the bound element, insert only the image element at this
particular insertion point." Here is the XUL code that goes with this
example:
<mybinding id="myNewWidget" flex="1">
<image
src="http://www.mozdev.org/sharedimages/header.gif" />
<label value="a non includes element" />
</mybinding>
The image is the only child taken from the XUL content and the label is ignored
Trang 4If you have children that are not defined in the includes attribute, then the binding is discarded and not used If the bound element uses another element in addition to an image element, the binding is discarded and only the explicit content is used If the image element isn't used at all, the binding
is discarded
<mybinding id="myNewWidget" flex="1">
<image
src="http://www.mozdev.org/sharedimages/header.gif" />
<label value="an element" />
</mybinding>
This example renders the image and the label and discards the binding The anonymous content does not appear because the binding is discarded and only the explicit content is used
7.5 Inheritance
In XBL, inheritance is the process in which one object included in another object is allowed to use properties from that parent object These properties can be many things, depending on the implementation, ranging from
methods to attribute property values Inheritance is a concept familiar in programming languages, most notably object-oriented ones It's not
something alien to markup, however, and it is deployed effectively in XBL This section examines three forms of XBL inheritance: binding, attribute, and implementation As you will see, inheritance promotes self-contained (modular) and flexible bindings that permit shared content across and within XBL documents
Trang 57.5.1 Binding Inheritance
Binding inheritance occurs when one binding is linked to another binding or XUL element and uses some or all properties of it, whether they are content
or behavior A binding can inherit from another binding that exists in the same or different file In one way, this useful feature makes a binding like a class, with content and methods that can be used elsewhere Bindings
become modules, which prevents code duplication, makes maintenance easier, and gets slotted in and out of documents
Linkage or inheritance is enabled by the extends attribute on the
<binding> element This attribute contains the URL of the binding that you inherit from This URL is made up of the location and name of the file that contains the binding (the # symbol), and the id of the specific binding being used In this way, it is similar to the access method used in CSS
attachment
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
Example 7-6 Binding inheritance
<binding id="listbox-base">
<resources>
<stylesheet
src="chrome://global/skin/listbox.css"/>
Trang 6</resources>
</binding>
<binding id="listcell"
extends="chrome://global/content/bindings/listbox.x ml#listbox-base">
<content>
<children>
<xul:label class="listcell-label"
xbl:inherits="value=label,flex=flexlabel,crop,disab led"
flex="1" crop="right"/>
</children>
</content>
</binding>
<binding id="listcell-iconic"
extends="chrome://global/content/bindings/listbox.x ml#listcell">
<content>
<children>
Trang 7<xul:image class="listcell-icon"
xbl:inherits="src=image"/>
<xul:label class="listcell-label"
xbl:inherits="value=label,flex=flexlabel,crop,disab led"
flex="1" crop="right"/>
</children>
</content>
</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
Trang 8use 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
Example 7-7 Inheriting XUL widget characteristics using extends
<binding id="Widget1" extends="xul:vbox">
<content>
<xul:description value="Top" />
<children includes="image" />
<xul:description value="Bottom" />
</content>
</binding>
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
7.5.2 Attribute Inheritance
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
Example 7-8 XBL attribute inheritance
Trang 9<xul:box class="insideBox" xbl:inherits="orient, flex, align">
<xul:description value="Top" />
<xul:box>
<children includes="image" />
</xul:box>
<xul:description value="Bottom" />
</xul:box>
</xul:box>
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
Trang 10on 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">
7.5.3 Implementation Inheritance
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
Example 7-9 Inheritance of behavior between bindings
<binding id="Widget1" extends="test.xml#Widget2">
<content>
<xul:box class="insideBox">
<xul:description value="Top" />
<xul:box>
<children includes="image" />
Trang 11</xul:box>
<xul:description value="Bottom" />
</xul:box>
</content>
</binding>
<binding id="Widget2">
<implementation>
<constructor>
this.init( );
</constructor>
<method name="init">
<body>
<![CDATA[ dump("This is Widget2");]]>
</body>
</method>
</implementation>
</binding>
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
Trang 12In 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
7.6 Event Handling
Trang 13Event handlers are attributes that listen for events They intercept events
raised by certain user actions, such as button clicks When intercepted,
control is given to the application to carry out some functionality
Mouse and keyboard actions are included in these events XBL uses all events that are available on an element in XUL and calls them by their name, minus the on prefix Thus, for example, the onmouseclick event handler becomes mouseclick in XBL Refer to Appendix C for a full list of these events, which also describes the difference between XUL and XBL event handling
The <handler> element contains a single event Sets of individual
<handler> elements need to be included in a <handlers> element The event that sets off the action is contained in the event attribute
<handlers>
<handler event="mousedown"
action="dumpString('hello', 'there!')" />
</handlers>
This code uses the action attribute to point to script that is executed when the event is triggered The alternative way to set up the actions is to put the executable script between the handler tags, like you can with the XUL
<script> element If you use this "embedded" syntax, wrap your script in
a CDATA section so it gets interpreted and executed properly:
<handlers>
<handler event="mousedown">
<![CDATA[