Xbl Module construction
Making xbl widgets portable across xul applications
An xbl module is a self contained widget tree which contains xbl
bindings and methods, css bindings and basic style information, images and
icons, Overlays and js, documentation and working code examples. The widget
tree is implemented as a directory structure. Everthing here is already available
in the mozilla AOM. What is presented here is a method of use.
Introduction
The examples below use the xbutton xbl module as a reference. The principle
of how to make an xbl module portable is what is being documented. The xbutton
is the first xbl module that can be 'dropped in' to multiple xul applications
and is implemented in the XPTK toolkit and the kiosk browser. This method
relies heavily on css and how style rules get applied in mozilla as does xbl.
Under this scheme you can copy the xbutton module directory into your projects
/content directory and include the WidgetName.css in your applications main
stylesheet or in the top of your xul application or Overlay. Here is a snippet
from one of the kiosk browser chromes that is using the xbutton xbl module:
<?xml-stylesheet href="chrome://kiosk/skin" type="text/css"?>
<?xml-stylesheet href="chrome://kiosk/content/toolkit/xbutton/style/xbutton.css" type="text/css"?>
<?xml-stylesheet href="chrome://kiosk/content/toolkit/xbutton/style/button.css" type="text/css"?>
Above we have the style sheet calls, we're bringing in the kiosk.css, xbutton.css
that contains the button binding, button.css that is a copy of the mozilla
modern skin button and later in the xul document we use the widget binding
we just created:
<button label="" orient="horizontal"
src="chrome://kiosk/content/toolkit/xbutton/images/message-mail.png"
id="mailBtn"
onclick='window.openDialog("chrome://messenger/content/");'
tooltiptext="Messenger Mail">
</button>
I know that I have a button widget provided by the xbutton.css only because
the module developer said so in his documentation. The widget bindings are
defined in the WidgetName-bindings.css, so you also look there to see what
tags the module is providing. Documenting the widget is a must. A developer
should not have to read and understand your xbl code to use your widget.
Thats all that is needed to include the xbutton xbl widget in an xul
document. The documentation you provide tells the xul developer the name
of the xbl widget that your module is providing, in the case of xbutton it
is <button>. You must expect that your css rules will be overloaded
by the xul developer, as we will see later in this doc.
XBL modules should include usage documentation in their main directories
so if someone lifts a module for their project the documentation goes with
the module. Also include good working examples that demonstrate all attributes
of your widget. You are going to write good documentation, right?
Organization of Module
XBL modules should have a widget tree directory structure as in
any mozilla project:
- /WidgetName - includes xul demo and documentation.
- /xbl - includes the xml bindings document(s),i.e 'widget-name.xml'
- /style - includes the widgetName-bindings.css, WidgetName.css
and the basic widgetName.css
- /content - includes content such as Overlays
- /images - includes image icons used for widget
- /locale - includes sub-directories for locale stuff
/WidgetName directory
This is the root of your module. In this root you would have your WidgetName.xul
demonstrating the propper use of your widget.Also here is where you keep
your widget documentation in html format All paths used in your css and xbl
should be relative to this directory. A demonstration is the xbutton-bindings.css
which points to the /xbl directory from inside the /style directory:
/* **** xbutton-binding.css
Binding stylesheet for the extended button */
button {
-moz-binding: url("../xbl/xbutton.xml#button");
}
menu-button {
-moz-binding: url("../xbl/xbutton.xml#button");
}
/xbl directory
In the xbl directory you would have the xml document(s) containing the
bindings for the custom widget. All paths used should be relative to the widget
directory so that the widget is not tied to one directory or project. The
resource definition points to the style directory, as in:
<resources>
<stylesheet src="../style/button.css"/>
</resources>
which points to the ./style directory from inside the ./xbl directory.
The key to making you xbl widget portable is the use of relative paths.
/style diectory
In the style directory you would have a /WidgetName-bindings.css
that could be imported into an applications main stylesheet to obtain the
widgets bindings. Also in the style directory there should be a widget specific
WidgetName.css that imports the WidgetName-bindings.css and basic
widgetName.css. The widgetName.css contains the basic style rules for the
xbl widget, these should be enough to display your widget in the absence of
any other style rules for your xbl widget. Here is a css binding for the xbutton.xml
button:
- button {
- -moz-binding: url("chrome://xptk/content/modules/xbutton/xbl/xbutton.xml#button");
- }
This binding shows that the xbutton is being used from the XPTK chrome
directory but the path could point to where it's installed into your project,
as shown above. It should be noted that the standard, cannonical, place to
drop the widget directory in your project is the /content directory so the
chrome path would be chrome://myproject/content/xbutton/xbutton.xml.
Also note that in line 1 above the button could be xbutton
and you would have an <xbutton> widget to use in your app with all
the attributes of the xbutton.xml button. You could have <button> and
<xbutton> tags in the same application. Another method of obtaining
a binding, while not as clean but css2 syntax, is:
- button[module="xbutton"] {
- -moz-binding: url("chrome://xptk/content/modules/xbutton/xbl/xbutton.xml#button");
- }
In the xul document you would then do:
<button module="xbutton" label="xbutton" orient="horizontal"
src="chrome://xptk/content/modules/xbutton/images/message-mail.png"
color="darkred" bgcolor="#cccccc" />
Notice the attribute selector module="xbutton" in the css matches
the attribute definiton in the xul button definition. This method also lets
you have multiple button bindings.
/content directory
The content directory contains any xul Overlays that implement your widget(s).
Any javascript used by your widget or Overlay should be here. Also any stringbundles
needed by your widgets or Overlays will be here.
/images directory
The images directory contains any images or icons that are needed for
your widget.
/locale directory
The locale directory contains any locale information needed by your widget
or Overlay