File:  [mozdev] / books / www / chapters / ch03.html
Revision 1.21: download - view: text, annotated - select for diffs - revision graph
Fri Apr 4 16:27:40 2003 UTC (16 years, 7 months ago) by cdn
Branches: MAIN
CVS tags: HEAD
ahem

    1:     <link rel="prev" href="http://books.mozdev.org/chapters/ch02.html" />
    2:     <link rel="next" href="http://books.mozdev.org/chapters/ch04.html" />
    3: 
    4:     <style type="text/css">
    5:       div.c11 {font-weight: bold; text-align: center}
    6:       div.c10 {text-align: center}
    7:     </style>
    8: 
    9:     <h2>Chapter 3</h2>
   10:     <h1><a name="77084"></a> XUL Elements and Features</h1>
   11:     <p>The XML-based User-interface Language (XUL) includes all of
   12:     the basic widgets you need to build application user
   13:     interfaces. These interfaces include tabs, text areas, buttons,
   14:     and menus, as well as handy interfaces you may not have thought
   15:     you needed, such as the <tt>&lt;stack&gt;</tt> widget or
   16:     <tt>&lt;colorpicker&gt;</tt>.</p>
   17:     <p><a href="ch02.html#77048">Chapter 2</a> introduced some of
   18:     the XUL elements that make up a window and basic applications.
   19:     This chapter examines XUL elements and features in more detail,
   20:     describing the rationale behind them, their look and behavior,
   21:     and common usage. Though not comprehensive, the chapter
   22:     provides more than enough information about XUL to get you
   23:     started on building your own Mozilla applications, particularly
   24:     when used in conjunction with the XUL reference in <a href=
   25:     "appc.html#77003">Appendix C</a>.</p>
   26:     <p>The elements described here, such as menus, buttons, trees,
   27:     and boxes, are needed in almost any type of application, and
   28:     most of the examples are generic, so you can plug them into any
   29:     application or customize them to your needs. We've packed a lot
   30:     information in this chapter and it be a useful reference as you
   31:     begin to develop your applications.</p>
   32:     <h2><a name="77085"></a> The XUL Document Object</h2>
   33:     <p>At the core of a XUL file 
   34:     <!--INDEX XUL document object;objects:XUL document object -->
   35:     is the <tt>document</tt> object. As in HTML, <tt>document</tt>
   36:     is an object that represents the XUL document itself-the
   37:     content as opposed to the window that surrounds it. The
   38:     <tt>document</tt> provides methods for getting individual
   39:     elements, manipulating the structure of the document, or
   40:     updating style rules.</p>
   41:     <p>A <tt>document</tt> object provides 
   42:     <!--INDEX getElementById( ) method;methods:getElementById( ) -->
   43:     <!--INDEX getElementsByTagName( ) 
   44:     method;methods:getElementByTagName( ) --> 
   45:     <!--INDEX createElement( ) method;methods:createElement( ) --> 
   46:     <!--INDEX createTextNode( ) method;methods:createTextNode( ) -->
   47:     methods such as <tt>getElementById</tt>,
   48:     <tt>getElementsByTagName</tt>, <tt>createElement</tt>, and
   49:     <tt>createTextNode</tt> for DOM querying and manipulation of
   50:     the actual document. Further details about the DOM are
   51:     available in <a href="ch05.html#44523">Chapter 5</a>.</p>
   52:     <p>Other types of <tt>document</tt> objects include the width
   53:     and height of the window, a <tt>popupNode</tt> property that
   54:     accesses the elements currently displaying a pop up (a XUL
   55:     widget that attaches to another widget and appears above it
   56:     holding some content), a <tt>tooltipNode</tt> property that
   57:     accesses the element currently displaying a tooltip, and a
   58:     <tt>documentElement</tt> property that accesses the body of the
   59:     document:</p>
   60: <pre>
   61: var docEl = document.documentElement;
   62: var secondLevelNodes = new Array( );
   63: for (var I=0; I&lt;docEl.childNodes.length;I++)  {
   64: secondLevelNodes[I] = docEl.childNodes[I];
   65: }
   66: </pre>
   67:     <p>This example creates an array of all the second-level nodes
   68:     in relation to the document, and could be extended to walk to
   69:     the whole tree. Using nodes in the structural representation of
   70:     the document to get to other nodes in this way allows you to
   71:     quickly access and change any part of a document with
   72:     script.</p>
   73:     <p>The <tt>document</tt> object is global only for the
   74:     particular scope that you are working in, so every window,
   75:     dialog, and page has its own <tt>document</tt> object. To
   76:     access it, just use the <tt>document</tt>. prefix followed by
   77:     the name of the property you want to access:</p>
   78: <pre>
   79: var title = document.getElementById("bookTitle");
   80: </pre>
   81:     <p>It is possible to access <tt>document</tt> outside the
   82:     current scope-for example, the window that opened another one
   83:     using <tt>window.opener</tt>:</p>
   84: <pre>
   85: var title = window.opener.document.getElementById("bookTitle");
   86: </pre>
   87:     <h3><a name="77086"></a> XUL Parsing and the Document Object
   88:     Model</h3>
   89:     <p>Mozilla runs XUL documents 
   90:     <!--INDEX DOM (Document Object Model):XUL parsing and;XUL (XML-based User-interface Language):parsing, DOM and;parsing:XUL, DOM and -->
   91:     through the Expat XML parser to check that they are
   92:     well-formed. Expat is an XML parser library, written in C, that
   93:     was integrated into Mozilla at the early stages of the code
   94:     rewrite when the source was made open.</p>
   95:     <p>During parsing, a content model based on the Document Object
   96:     Model (DOM) is built, allowing access to the content in a way
   97:     that facilitates dynamic manipulation. Once the XML tags are in
   98:     the correct namespaces, Mozilla parses the document a second
   99:     time to ensure that XUL tags themselves are valid. If this
  100:     fails, or if the document does not conform to the syntax rules,
  101:     an error appears in your window so you can address the
  102:     problem.</p>
  103:     <p>The parsing process builds an internal tree structure that
  104:     can be used as a handle for querying, modifying, and copying
  105:     documents the structure represents. <a href=
  106:     "ch05.html#44523">Chapter 5</a> describes in more detail the
  107:     relationship between JavaScript (the main scripting engine used
  108:     in Mozilla) and the DOM, and it goes further with examples of
  109:     commonly used methods for querying and modifying a XUL
  110:     document. To view that internal tree, you can use a tool called
  111:     the DOM Inspector, which is a Mozilla application that lets you
  112:     view and manipulate the document object model of any XUL file
  113:     or web page. For more information about the DOM Inspector, see
  114:     <a href="appb.html#78077">Appendix B</a>.</p>
  115:     <h2><a name="77087"></a> Application Windows</h2>
  116:     <p><tt>&lt;window&gt;</tt> is just one of the 
  117:     <!--INDEX STARTRANGE==XUL (XML-based User-interface Language):application windows;application windows:XUL;windows:XUL:application windows -->
  118:     possible root elements of a XUL document, the others being
  119:     <tt>&lt;overlay&gt;</tt>, <tt>&lt;dialog&gt;</tt>,
  120:     <tt>&lt;page&gt;</tt>, and <tt>&lt;wizard&gt;</tt>. Overlays
  121:     play an especially important role in managing and modularizing 
  122:     <!--INDEX overlay element, XUL --> 
  123:     <!--INDEX dialog element, XUL --> 
  124:     <!--INDEX page element, XUL --> 
  125:     <!--INDEX wizard element, XUL --> the code in your XUL
  126:     application, so the section <a href="#77141">"Overlays</a>,"
  127:     later in this chapter, is dedicated to them.</p>
  128:     <p>The remaining root elements all have the XUL namespace and
  129:     XUL window attributes and properties. All have a XUL
  130:     <tt>document</tt> object. Yet, added features exist for each.
  131:     Which element you choose for the XUL document depends on the
  132:     purpose of the window. A <tt>&lt;window&gt;</tt> is typically
  133:     top-level, a <tt>&lt;dialog&gt;</tt> is secondary, appearing
  134:     above another window, a <tt>&lt;page&gt;</tt> is a document
  135:     that appears in a frame, and a <tt>&lt;wizard&gt;</tt> stores a
  136:     set of subsections for loading one at a time through a
  137:     step-by-step process.</p>
  138:     <h3><a name="77088"></a> Dialogs</h3>
  139:     <p>Dialogs usually carry out specific functions 
  140:     <!--INDEX dialogs, application windows (XUL);application windows:XUL:dialogs;XUL (XML-based User-interface Language):application windows:dialogs -->
  141:     like displaying a message or getting information from the user.
  142:     The <tt>&lt;dialog&gt;</tt> element was created relatively late
  143:     in the XUL toolkit development cycle to cater for some special
  144:     needs of dialog windows, including their position relative to
  145:     other windows (particularly the main application window) and
  146:     the existence of buttons for accepting or rejecting a
  147:     particular operation. A dialog in XUL appears in <a href=
  148:     "#77034">Example 3-1</a>.</p>
  149:     <p><i>Example 3-1: <a name="77034"></a></i> <i>XUL
  150:     dialog</i></p>
  151: <pre>
  152:  &lt;dialog id="turboDialog" buttons="accept" buttonpack="center"
  153:          xmlns="<a href=
  154: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  155:          title="Empty the Cache"
  156:          onunload="SetTurboPref( );"&gt;
  157: </pre>
  158:     <p>As you can see, the dialog includes the XUL namespace and
  159:     the <tt>id</tt> and <tt>title</tt> attributes. However, some
  160:     attributes, such as <tt>buttons</tt> and <tt>buttonpack</tt>,
  161:     don't appear in a regular window context.</p>
  162:     <p>Dialogs commonly require <!--INDEX buttons:dialogs, XUL -->
  163:     the user to take some action or make a choice, so the button
  164:     attributes are provided for this purpose. In addition to
  165:     <tt>buttons</tt> and <tt>buttonpack</tt>, there are special
  166:     event handlers on the dialog element-<tt>ondialogaccept</tt>,
  167:     <tt>ondialogcancel</tt>, and <tt>ondialoghelp-</tt>that
  168:     correspond to the buttons typically displayed and can execute
  169:     code in response to user input. As with <tt>onunload</tt>, you
  170:     can place a function in the <tt>ondialogaccept</tt> event
  171:     handler that executes when the user clicks the OK button:</p>
  172: <pre>
  173: &lt;dialog id="flush" buttons="accept" buttonpack="center"
  174: xmlns="<a href=
  175: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  176: title="&amp;exitWarningTitle.label;"
  177: ondialogaccept="doCacheFlush( );"&gt;
  178: </pre>
  179:     <h3><a name="77089"></a> Pages</h3>
  180:     <p>The <tt>&lt;page&gt;</tt> element is 
  181:     <!--INDEX page element, XUL --> designed specifically for
  182:     documents that are loaded in a frame of a higher-level
  183:     document. They are not top-level windows themselves. In
  184:     Mozilla, the <tt>page</tt> element is used often in the
  185:     preferences dialog to represent the various preference
  186:     panels.</p>
  187:     <p>As with the dialog in <a href="#77034">Example 3-1</a>, the
  188:     <tt>&lt;page&gt;</tt> element in <a href="#77036">Example
  189:     3-2</a> includes the familiar namespace attribute
  190:     (<tt>xmlns</tt>) and load handler (<tt>onload</tt>). The
  191:     <tt>headertitle</tt> attribute is also used for the top of the
  192:     page, which itself gets loaded into another window that has its
  193:     own title.</p>
  194:     <p><i>Example 3-2: <a name="77036"></a></i> <i>XUL page</i></p>
  195: <pre>
  196:  &lt;page xmlns="<a href=
  197: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  198:        onload="parent.initPanel('chrome://communicator/content/pref/pref-fonts.xul');"
  199:        headertitle="&amp;lHeader;"&gt;
  200: </pre>
  201:     <p>An application of the <tt>
  202:     <!--INDEX preferences, page element --> page</tt> element in
  203:     Mozilla is in the global preferences for the whole suite of
  204:     Mozilla applications. <a href="#77002">Figure 3-1</a> shows the
  205:     layout of this preferences panel. In <a href="#77036">Example
  206:     3-2</a>, the entity in the header title,
  207:     <tt>&amp;lHeader;</tt>, resolves to "Languages" and be
  208:     displayed above the individual preference panel page.</p>
  209:     <p>The main preferences window is a XUL dialog, and the content
  210:     is split in two. On the left is a tree from an overlay that
  211:     contains the preference topics, and on the right is a XUL
  212:     <tt>page</tt> loaded into an <tt>&lt;iframe&gt;</tt>.</p>
  213: <pre>
  214: &lt;iframe id="panelFrame" name="panelFrame" style="width:0px" flex="1"/&gt;
  215: </pre>
  216:     <div class="c10">
  217:       <img src="foo.gif">
  218:     </div>
  219:     <p><i>Figure 3-1: <a name="77002"></a></i> <i>Preferences panel
  220:     loaded as a page</i></p>
  221:     <p>As shown in <a href="#77002">Figure 3-1</a>, selecting one
  222:     of the topics in the left panel changes the page that is loaded
  223:     into the frame. Although the changeover requires quite a bit of
  224:     scripting in practice, at a basic level, it is just a case of
  225:     changing the <tt>src</tt> attribute on the frame:</p>
  226: <pre>
  227: document.getElementById("panelFrame").setAttribute("src", "chrome://communicator/content/pref/pref-navigator.xul" );
  228: </pre>
  229:     <h3><a name="77090"></a> Wizards</h3>
  230:     <p>This type of window 
  231:     <!--INDEX application windows:wizards;wizards, application windows -->
  232:     is designed for a very specific type of functionality-to walk
  233:     the user through a step-by-step process, with each step
  234:     represented by a different screen. Using one <tt>window</tt>
  235:     after another can create inconsistencies, including different
  236:     sizes and performance issues. These can be especially bad when
  237:     you try to create an interface that guides the user through a
  238:     new process, such as setting up an account of some kind. Thus,
  239:     the <tt>wizard</tt> element was adapted from the wizard
  240:     paradigm now common in some native toolkits. <a href=
  241:     "#77038">Example 3-3</a> shows how Mozilla handles wizard
  242:     dialogs.</p>
  243:     <p><i>Example 3-3: <a name="77038"></a></i> <i>A XUL
  244:     wizard</i></p>
  245: <pre>
  246:  &lt;wizard id="NewAccount" title="Account Set-up"
  247:      onwizardcancel="return Cancel( );"
  248:      onwizardfinish="return Finish( );"
  249:      onload="onLoad( );"
  250:      width="44em" height="30em"
  251:      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  252:      xmlns:nc="http://home.netscape.com/NC-rdf#"&gt;
  253:    &lt;wizardpage id="wPage1" pageid="page-1" label="New Account"
  254:        onpageshow="return acctNamePageInit( );"
  255:        onpageadvanced="nextPage(this)"&gt;
  256:      &lt;vbox flex="1"&gt;
  257:        &lt;description&gt;Welcome and enjoy the wizardry&lt;/description&gt;
  258:        &lt;image src="page1.png"/&gt;
  259:      &lt;/vbox&gt;
  260:    &lt;/wizardpage&gt;
  261:    &lt;wizardpage id="wPage2"/&gt;
  262:    &lt;wizardpage id="wPage3"/&gt;
  263:  &lt;/wizard&gt;
  264: </pre>
  265:     <p>A <tt>wizardpage</tt> is similar to a <tt>page</tt> because
  266:     it has a surrounding window into which it is loaded. The
  267:     difference, as shown in <a href="#77038">Example 3-3</a>, is
  268:     that in the wizard, the pages exist as a set within the 
  269:     <!--INDEX wizard element, XUL --> window-level
  270:     <tt>&lt;wizard&gt;</tt> element. Order wizardpages in the
  271:     sequence you want them to appear on the screen. When the user
  272:     accepts one page, the next one is loaded. In <a href=
  273:     "#77038">Example 3-3</a>, the content of the first page is text
  274:     and an image, and the other pages define only <tt>id</tt>
  275:     attributes (though this is exactly how you might set them up if
  276:     their actual content were overlaid into this wizard at
  277:     runtime). You can use the wizard code in <a href=
  278:     "#77038">Example 3-3</a> by including the <tt>&lt;?xml</tt>
  279:     <tt>version="1.0"?&gt;</tt> preamble at the top, adding
  280:     <tt>label</tt> attributes to pages two and three, and seeing
  281:     the pages advance as you click the buttons that guide the
  282:     wizard process when 
  283:     <!--INDEX ENDRANGE==XUL (XML-based User-interface Language):application windows;application windows:XUL;windows:XUL:application windows -->
  284:     you load the XUL file into the browser.</p>
  285:     <h2><a name="77091"></a> Application Widgets</h2>
  286:     <p>Like most applications, 
  287:     <!--INDEX STARTRANGE==XUL (XML-based User-interface Language):application widgets;widgets:XUL;application widgets, XUL -->
  288:     yours may rely on menus and toolbars as part of the basic user
  289:     interface. Menus and toolbars are common, multipurpose widgets
  290:     that are familiar to most users. Menus often appear as part of
  291:     a menu bar that organizes all of the capabilities of the
  292:     program, or they can be single menus for presenting a simple
  293:     list of choices. Buttons provide quick access to the most
  294:     commonly used tasks and help get information back from the
  295:     user. Beyond these basics, however, XUL provides widgets for
  296:     creating almost any kind of interface (and the flexibility of
  297:     Mozilla's presentation layer means you can make even the most
  298:     prosaic menus look any way you want).</p>
  299:     <h3><a name="77092"></a> The Toolbox</h3>
  300:     <p>As your applications grow 
  301:     <!--INDEX toolbox;toolbar;toolbargrippy --> in complexity and
  302:     provide more services to the user, the toolbox can be a good
  303:     way to organize menus, toolbars, and other widgets. A
  304:     <tt>&lt;toolbox&gt;</tt> is a special container for holding one
  305:     or more toolbars and/or menu bars. A Mozilla toolbar implements
  306:     a <tt>toolbargrippy</tt> and a box that contains children. The
  307:     <tt>toolbargrippy</tt> is a bar on the lefthand side used for
  308:     collapsing and expanding the bar. This useful method allows
  309:     users to control the space that is available to them
  310:     onscreen.</p>
  311:     <h4><a name="77093"></a> Toolbars</h4>
  312:     <p>The <tt>&lt;toolbar&gt;</tt> element shown 
  313:     <!--INDEX toolbars;toolbar element, XUL --> in <a href=
  314:     "#77040">Example 3-4</a> contains buttons used to carry out
  315:     various application functions. Buttons are the most common
  316:     children of a toolbar, but they are by no means the only
  317:     widgets or content you can put in there.</p>
  318:     <p><i>Example 3-4: <a name="77040"></a></i> <i>Toolbar with
  319:     buttons and spacing</i></p>
  320: <pre>
  321:  &lt;toolbox&gt;
  322:    &lt;toolbar id="fixed-toolbar" class="toolbar-primary"
  323:        tbautostretch="always" persist="collapsed"&gt;
  324:      &lt;toolbarbutton id="newfileBtn" label="New" oncommand="doNew( );" /&gt;
  325:      &lt;toolbarseparator /&gt;
  326:      &lt;toolbarbutton id="openfileBtn" label="Open" oncommand="doOpen( );" /&gt;
  327:      &lt;/td&gt;&lt;spacer flex="1" /&gt;
  328:    &lt;/toolbar&gt;
  329:  &lt;/toolbox&gt;
  330: </pre>
  331:     <p>To apply spacing between elements, 
  332:     <!--INDEX elements:XUL, spacing;XUL (XML-based User-interface Language):elements:spacing -->
  333:     <!--INDEX spacer element, XUL --> the <tt>&lt;spacer&gt;</tt>
  334:     element can be used. In <a href="#77040">Example 3-4</a>, all
  335:     space that remains after the buttons are drawn goes
  336:     <i>after</i> the buttons because the spacer there is flexible
  337:     and the buttons are not. Space added elsewhere with other
  338:     <tt>&lt;spacer&gt;</tt> elements is determined by ratio of the
  339:     <tt>flex</tt> values on the elements competing for layout
  340:     space. Extending the toolbar in <a href="#77040">Example
  341:     3-4</a>, you can add a print button on the far right:</p>
  342: <pre>
  343: &lt;toolbarbutton id="newfileBtn" label="New" oncommand="doNew( );" /&gt;
  344: &lt;toolbarseparator /&gt;
  345: &lt;toolbarbutton id="openfileBtn" label="Open" oncommand="doOpen( );" /&gt;
  346: &lt;spacer flex="1" /&gt;
  347: &lt;toolbarbutton id="printBtn" label="Print" oncommand="doPrint( );" /&gt;
  348: </pre>
  349:     <p>The <tt>&lt;toolbarseparator&gt;</tt> element does not
  350:     create additional spacing between the first two
  351:     <tt>toolbarbuttons</tt>, but there is space between them and
  352:     the print button, which is pushed to the far right because the
  353:     <tt>flex</tt> attribute of the spacer in between is set to
  354:     1.</p>
  355:     <h4><a name="77094"></a> Menu bar</h4>
  356:     <p>Among the other most common 
  357:     <!--INDEX menu bar;menubar element, XUL --> nested elements
  358:     within a toolbox is a XUL <tt>&lt;menubar&gt;</tt>.
  359:     <tt>&lt;menubar&gt;</tt> is a container much like the toolbar
  360:     that has one or more menus as its children.</p>
  361: <pre>
  362: &lt;menubar id="fixed-menubar"&gt;
  363: &lt;menu label="Quantity" /&gt;
  364: &lt;menu label="Color" /&gt;
  365: &lt;/menubar&gt;
  366: </pre>
  367:     <blockquote>
  368:       <div class="c11">
  369:         WARNING
  370:       </div>
  371:       <p>There is one caveat in <tt>menubar</tt> behavior that you
  372:       should be aware of. On the Mac OS, application menu bars
  373:       appear at the top of the screen. If you have any nonmenu
  374:       elements contained in your menu bar widget, they are ignored
  375:       because the OS does not know how to display them there.</p>
  376:     </blockquote>
  377:     <p>As <a href="#77042">Example 3-5</a> illustrates, it's easy
  378:     to build up a simple application menu and get the intrinsic
  379:     look and collapsibility of a menu bar with a few simple lines
  380:     of code:</p>
  381:     <p><i>Example 3-5: <a name="77042"></a></i> <i>Application menu
  382:     bar</i></p>
  383: <pre>
  384:  &lt;?xml version="1.0"?&gt;
  385:  &lt;window
  386:     xmlns="<a href=
  387: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
  388:  &lt;menubar id="appbar"&gt;
  389:    &lt;menu label="File"&gt;
  390:       &lt;menupopup&gt;
  391:         &lt;menuitem label="New"/&gt;
  392:         &lt;menuitem label="Open"/&gt;
  393:       &lt;/menupopup&gt;
  394:    &lt;/menu&gt;
  395:    &lt;menu label="Edit" /&gt;
  396:  &lt;/menubar&gt;
  397:  &lt;/window&gt;
  398: </pre>
  399:     <p>The complete XUL file in <a href="#77042">Example 3-5</a>
  400:     produces the menu bar in <a href="#77004">Figure 3-2</a>.</p>
  401:     <div class="c10">
  402:       <img src="foo.gif">
  403:     </div>
  404:     <p><i>Figure 3-2: <a name="77004"></a></i> <i>Application menu
  405:     bar</i></p>
  406:     <h3><a name="77095"></a> Selection Lists</h3>
  407:     <p>There are a number of ways to 
  408:     <!--INDEX lists;selection lists --> create lists in Mozilla.
  409:     This section provides three alternative ways of presenting the
  410:     same choices to the user. The options are illustrated in <a
  411:     href="#77006">Figure 3-3</a>. The one thing these three
  412:     selection list widgets-<i>menus</i>, <i>pop ups</i>, and
  413:     <i>menu lists-</i>have in common is they all use menu items to
  414:     display individual choices:</p>
  415: <pre>
  416: &lt;menuitem label="Tachinidae"   oncommand="changeF(1)"/&gt;
  417: &lt;menuitem label="Tanyderidae"   oncommand="changeF(2)"/&gt;
  418: &lt;menuitem label="Tipulidae"   oncommand="changeF(3)"/&gt;
  419: &lt;menuitem label="Syrphidae"   oncommand="changeF(4)"/&gt;
  420: &lt;menuitem label="Tephritidae"   oncommand="changeF(5)"/&gt;
  421: </pre>
  422:     <p>When you wrap the <tt>menuitem</tt> elements above in a
  423:     menu, a menu list, and a pop-up window, you see the variations
  424:     in <a href="#77006">Figure 3-3</a>.</p>
  425:     <div class="c10">
  426:       <img src="foo.gif">
  427:     </div>
  428:     <p><i>Figure 3-3: <a name="77006"></a></i> <i>Visual comparison
  429:     of menu widgets</i></p>
  430:     <h4><a name="77096"></a> Menus</h4>
  431:     <p>Menus are much more flexible 
  432:     <!--INDEX lists:menus;selection lists:menus;menus --> than they
  433:     first appear to be. They can appear anywhere in the UI, for one
  434:     thing, and needn't be stuck at the top of the window. They can
  435:     be in buttons, trees, or just out on their own. <a href=
  436:     "#77044">Example 3-6</a> shows the basic structure of a
  437:     menu.</p>
  438:     <p><i>Example 3-6: <a name="77044"></a></i> <i>A sample
  439:     menu</i></p>
  440: <pre>
  441:  &lt;menu label="Quantity"&gt;
  442:    &lt;menupopup&gt;
  443:      &lt;!-- menuitems here --&gt;
  444:    &lt;/menupopup&gt;
  445:  &lt;/menu&gt;
  446: </pre>
  447:     <p>There is a rigid ordering of nesting in a menu. A menu
  448:     contains a <tt>&lt;menupopup&gt;</tt>, which in turn contains
  449:     one or more menu items. Optionally, you can segregate groups of
  450:     menu items by using a <tt>&lt;menuseparator&gt;</tt> in the pop
  451:     up, which draws a thin line between items.</p>
  452:     <h4><a name="77097"></a> Pop ups</h4>
  453:     <p>The pop up manifests as either 
  454:     <!--INDEX lists:pop ups;selection lists:pop ups;pop ups;menupopup element, XUL -->
  455:     a <tt>&lt;menupopup&gt;</tt> or a <tt>&lt;popup&gt;</tt>
  456:     element. The latter can be used in a number of different ways,
  457:     but <a href="#77046">Example 3-7</a> focuses on its common use
  458:     in context menus.</p>
  459:     <p><i>Example 3-7: <a name="77046"></a></i> <i>Context menu
  460:     using pop up</i></p>
  461: <pre>
  462:  &lt;popup id="FlyContext"
  463:      onpopupshowing="return doThis( );"
  464:      onpopuphiding=" return doThat( );"&gt;
  465:    &lt;!-- menuitems here --&gt;
  466:  &lt;/popup&gt;
  467: </pre>
  468:     <p>A couple of extra steps are needed to prepare a context pop
  469:     up for activation. First, you must attach the <tt>popup</tt>
  470:     element to a widget in the UI by using the <tt>id</tt> of the
  471:     pop up that must correspond to the <tt>context</tt> of the
  472:     widget:</p>
  473: <pre>
  474: &lt;toolbar id="main-toolbar" context="FlyContext" /&gt;
  475: </pre>
  476:     <p>When the toolbar is clicked, the pop up that corresponds to
  477:     that value appears. You can have some script execute when you
  478:     show and/or hide the pop up by using the
  479:     <tt>onpopupshowing</tt> and <tt>onpopuphiding</tt> methods, as
  480:     when you show and hide items in a dynamic menu.</p>
  481:     <p>The second step includes the pop up in a set of pop ups,
  482:     enclosed in a <tt>&lt;popupset&gt;</tt> element. Though not
  483:     strictly necessary as a container for pop ups, the pop-up set
  484:     helps organize the free-floating<a name="b314"></a><a href=
  485:     "#314">[*]</a> pop-up windows in your application and makes it
  486:     easy to overlay them or overlay into them as the situation
  487:     requires.</p>
  488:     <h4><a name="77098"></a> Menu lists</h4>
  489:     <p>Another manifestation of the pop 
  490:     <!--INDEX lists:menu lists;selection lists:menu lists;menu lists;menulist element, XUL -->
  491:     up is in the use of menu lists. A menu list is a choice of
  492:     options presented to solicit a single choice, usually in the
  493:     form of a drop-down menu, for which XUL provides the
  494:     <tt>&lt;menulist&gt;</tt> element. <a href="#77048">Example
  495:     3-8</a> presents a straightforward menu list with a selection
  496:     of items to choose from. As in the other pop-up examples,
  497:     selecting an item executes the code defined in the
  498:     <tt>oncommand</tt> event handler for that item (e.g.,
  499:     <tt>changeF(1)</tt> for the menu item "Tachinidae").</p>
  500:     <p><i>Example 3-8: <a name="77048"></a></i> <i>XUL menu
  501:     list</i></p>
  502: <pre>
  503:  &lt;menulist id="FlyInput"&gt;
  504:    &lt;menupopup&gt;
  505:      &lt;!-- menuitems here --&gt;
  506:    &lt;/menupopup&gt;
  507:  &lt;/menulist&gt;
  508: </pre>
  509:     <p>The <tt>menulist</tt> widget provides functionality beyond
  510:     that of a regular menu. The menu list can be made editable when
  511:     the user should be allowed to enter a value not represented in
  512:     the menu items. In this case, the <tt>menulist</tt> element
  513:     definition in <a href="#77048">Example 3-8</a> would change to
  514:     something such as:</p>
  515: <pre>
  516: &lt;menulist id="FlyInput" editable="true"
  517: oninput="onInputFly( );"
  518: onchange="onChangeFly( );"&gt;
  519: </pre>
  520:     <p>A <tt>true</tt> value on the <tt>editable</tt> attribute
  521:     allows input in the list. Input can be validated immediately by
  522:     using the <tt>oninput</tt> attribute. The addition of the
  523:     <tt>onchange</tt> attribute can be used to carry out an extra 
  524:     <!--INDEX ENDRANGE==XUL (XML-based User-interface Language):application widgets;widgets:XUL;application widgets, XUL -->
  525:     script when a new selection is made.</p>
  526:     <h2><a name="77099"></a> Tabular and Hierarchical
  527:     Information</h2>
  528:     <p>Many options exist to display hierarchical 
  529:     <!--INDEX STARTRANGE==tabular information;hierarchical information -->
  530:     information in your user interface. The most common are
  531:     tree-like and table-like structures, both of which are
  532:     represented by elements in Mozilla's XPFE toolkit. In this
  533:     section, we look at list boxes, trees, and grids. With the
  534:     exception of the tree, these elements are not limited in regard
  535:     to the content they can contain. Currently, the tree only holds
  536:     text and image content and grids are designed for holding the
  537:     more diverse content as shown in upcoming examples.</p>
  538:     <h3><a name="77100"></a> List Boxes</h3>
  539:     <p><tt>&lt;listbox&gt;</tt> is used to display 
  540:     <!--INDEX tabular information:list boxes;list boxes;listbox element, XUL -->
  541:     tabular data. <a href="#77050">Example 3-9</a> shows a
  542:     <tt>listbox</tt> widget with all the basic features, including
  543:     the definition of the number of columns (<tt>listcol</tt>), the
  544:     <tt>listbox</tt> header (<tt>listhead</tt>), and a list item
  545:     (<tt>listitem</tt>).</p>
  546:     <p><i>Example 3-9: <a name="77050"></a></i> <i>Listbox
  547:     widget</i></p>
  548: <pre>
  549:  &lt;listbox rows="5" class="list" id="FlyTree" onselect="SelectFly( )"&gt;
  550:    &lt;listcols&gt;
  551:      &lt;listcol flex="1"/&gt;
  552:      &lt;splitter class="tree-splitter"/&gt;
  553:      &lt;listcol flex="1"/&gt;
  554:    &lt;/listcols&gt;
  555:    &lt;listhead&gt;
  556:      &lt;listheader label="Name" /&gt;
  557:      &lt;listheader label="Type" /&gt;
  558:    &lt;/listhead&gt;
  559:    &lt;listitem id="type-d"&gt;
  560:      &lt;listcell label="Syrphidae" /&gt;
  561:      &lt;listcell label="flower" /&gt;
  562:    &lt;/listitem&gt;
  563:    &lt;!-- More Items --&gt;
  564:  &lt;/listbox&gt;
  565: </pre>
  566:     <p>The first thing of note in the markup in <a href=
  567:     "#77050">Example 3-9</a> is the rules for the nesting of
  568:     elements within a <tt>listbox</tt> structure. The number of
  569:     columns needs to be set, each with a <tt>&lt;listcol&gt;</tt>
  570:     element, and all have to be wrapped in a
  571:     <tt>&lt;listcols&gt;</tt> set. <a href="#77050">Example 3-9</a>
  572:     has two columns. They are separated by a draggable
  573:     <tt>grippy</tt> item, which also acts as a column separator in
  574:     the header row. The cells for those columns are contained in a
  575:     <tt>&lt;listitem&gt;</tt> grouping. The header is optional and
  576:     has the same structure as a list item. Once you've put a
  577:     hierarchy like this in place, you can put the content you want
  578:     into the tabular structure.</p>
  579:     <blockquote>
  580:       <div class="c11">
  581:         NOTE
  582:       </div>
  583:       <p>The <tt>listbox</tt> does not support multilevel/nested
  584:       rows. Also note that the class attribute example above is
  585:       what gives the tree much of its particular appearance.
  586:       Listboxes and trees often use class-based style rules for
  587:       their appearance and positioning (e.g., the column splitter
  588:       in <a href="#77050">Example 3-9</a>).</p>
  589:     </blockquote>
  590:     <p><a href="#77050">Example 3-9</a> creates the listbox in <a
  591:     href="#77008">Figure 3-4</a>.</p>
  592:     <div class="c10">
  593:       <img src="foo.gif">
  594:     </div>
  595:     <p><i>Figure 3-4: <a name="77008"></a></i> <i>Listbox</i></p>
  596:     <h3><a name="77101"></a> High Performance Trees</h3>
  597:     <p>The <tt>&lt;listbox&gt;</tt> widget is 
  598:     <!--INDEX trees;tree element, XUL --> suitable only for certain
  599:     kinds of content. For better scalability and multilevel
  600:     capabilities, the <tt>&lt;tree&gt;</tt> was created.
  601:     <tt>&lt;tree&gt;</tt> is an advanced tree widget that was
  602:     originally designed for <!--INDEX Mail/News component --> the
  603:     Mail/News component in Mozilla. In its first incarnation, it
  604:     was called the outliner widget.</p>
  605:     <p>The tree is designed for high performance in large lists,
  606:     such as newsgroups, message folders, and other applications
  607:     where the volume of data is expected to be high. The tree
  608:     widget has a simpler, more lightweight layout, but it is more
  609:     difficult to use, requiring the addition of special "views" in
  610:     order to display data.</p>
  611:     <h4><a name="77102"></a> Tree features</h4>
  612:     <p>The implementation of the tree widget is unique 
  613:     <!--INDEX trees:features --> in the XUL universe in that it
  614:     displays its content only when it comes into view, which makes
  615:     it very efficient for long lists of data. <a href=
  616:     "#77026">Table 3-1</a> lists some of the main features of the
  617:     tree.</p>
  618:     <p><i>Table 3-1: <a name="77026"></a></i> <i>Main features of
  619:     the tree</i></p>
  620:     <table width="100%" border="1">
  621:       <tr>
  622:         <td><b>Row features</b></td>
  623:         <td><b>Column features</b></td>
  624:         <td><b>Visual features</b></td>
  625:       </tr>
  626:       <tr>
  627:         <td>Plain or hierarchical rows</td>
  628:         <td>Multicolumn</td>
  629:         <td>Each cell can display an image preceding text</td>
  630:       </tr>
  631:       <tr>
  632:         <td>Multiselection based on selection ranges</td>
  633:         <td>Resizing using mouse dragging</td>
  634:         <td>Look of each element (row, cell, image, etc.) is
  635:         defined in CSS</td>
  636:       </tr>
  637:       <tr>
  638:         <td>Drag and drop, either on a row or in between rows</td>
  639:         <td>Column hiding using pop-up menu in top-right
  640:         corner</td>
  641:         <td>Appearance of the drop feedback during drag-and-drop
  642:         can be styled</td>
  643:       </tr>
  644:     </table>
  645:     <p>Even with this rich set of features, however, a
  646:     <tt>tree</tt> can display only text and image content. The
  647:     <tt>listbox</tt> is more flexible in the type of content that
  648:     appears in its cells.</p>
  649:     <h4><a name="77103"></a> Tree views</h4>
  650:     <p>In the tree widget, a <i>view</i> is a model for the 
  651:     <!--INDEX trees:views --> <!--INDEX views, tree views -->
  652:     population and display of data. The view is a flexible feature
  653:     of the tree that can handle everything from simple data in a
  654:     content view to more dynamic data from a custom view or an RDF
  655:     datasource (builder view). <a href="#77028">Table 3-2</a> shows
  656:     the main features of each, using general categories of
  657:     datasource, speed, and type of usage.</p>
  658:     <p><i>Table 3-2: <a name="77028"></a></i> <i>Tree views</i></p>
  659:     <table>
  660:       <tr>
  661:         <td>Reordering using drag-and-drop</td>
  662:         <td>Spring loaded containers that open after hovering over
  663:         a closed container for a second</td>
  664:         <td>Sorting by clicking on a column header; custom views
  665:         can implement their own sorting</td>
  666:       </tr>
  667:       <tr>
  668:         <td><b>Content view</b></td>
  669:         <td><b>Builder view</b></td>
  670:         <td><b>Custom view</b></td>
  671:       </tr>
  672:       <tr>
  673:         <td>Rows are built from a content model.</td>
  674:         <td>Rows are built from an RDF datasource.</td>
  675:         <td>Consumer provides its own tree view
  676:         implementation.</td>
  677:       </tr>
  678:       <tr>
  679:         <td>Fast but not as memory efficient (bigger
  680:         footprint).</td>
  681:         <td>Still fast and efficient.</td>
  682:         <td>The fastest and most efficient way.</td>
  683:       </tr>
  684:       <tr>
  685:         <td>Suitable for small trees; easiest to use.</td>
  686:         <td>Relatively easy to use.</td>
  687:         <td>Most difficult to implement.</td>
  688:       </tr>
  689:     </table>
  690:     <p>As already mentioned, the <tt>tree</tt> is used in the
  691:     Mail/News thread pane, but there are plenty of other places to
  692:     look for it in Mozilla. Custom views and tree widgets are
  693:     implemented for the Address Book results, JS Debugger, DOM
  694:     Inspector, Bookmarks, and for autocomplete. You can see builder
  695:     views in History and a content view implementation in
  696:     Preferences.</p>
  697:     <h4><a name="77104"></a> The tree content model</h4>
  698:     <p>The content in a tree is 
  699:     <!--INDEX trees:content model;content model, trees;treecols element, XUL -->
  700:     defined <!--INDEX treecol element, XUL --> with
  701:     <tt>&lt;tree&gt;</tt>, <tt>&lt;treecols&gt;</tt>,
  702:     <tt>&lt;treecol&gt;</tt>, and <tt>&lt;treechildren&gt;</tt>
  703:     tags. <a href="#77052">Example 3-10</a> shows a basic column
  704:     number definition (two in this instance) and a
  705:     <tt>treechildren</tt> placeholder that defines the tree body.
  706:     Example 3-10<a name="77052"></a> <i>Tree base model</i></p>
  707: <pre>
  708:  &lt;tree id="tree" flex="1"&gt;
  709:    &lt;treecols&gt;
  710:      &lt;treecol id="Col1" label="Col1" flex="1"/&gt;
  711:      &lt;treecol id="Col2" label="Col1" flex="1"/&gt;
  712:    &lt;/treecols&gt;
  713:    &lt;treechildren/&gt;
  714:  &lt;/tree&gt;
  715: </pre>
  716:     <p>As in the <tt>listbox</tt>, a well-defined hierarchy of
  717:     elements has to be observed. This hierarchy is part of the
  718:     content model for a tree. The organization of content within a
  719:     tree enforced by the specific tree elements is listed
  720:     below.</p>
  721:     <blockquote>
  722:       <div class="c11">
  723:         NOTE
  724:       </div>
  725:       <p>Unlike <tt>listbox</tt>, nested children are possible for
  726:       multilevel trees. An example of nested children appears later
  727:       in this chapter in <a href="#77054">Example 3-11</a>.</p>
  728:     </blockquote>
  729:     <dl>
  730:       <dt>&lt;treeitem&gt;</dt>
  731:       <dd>This element contains a 
  732:       <!--INDEX treeitem element, XUL --> single top-level row and
  733:       all its descendants. The <tt>container</tt> attribute is used
  734:       to mark this row as a container and is optional. The
  735:       <tt>open</tt> attribute is used for expanded containers.</dd>
  736:       <dt>&lt;treerow&gt;</dt>
  737:       <dd>The row is contained in the <tt>
  738:       <!--INDEX treeitem element, XUL --> &lt;treeitem&gt;</tt>
  739:       element. You may optionally set the <tt>properties</tt>
  740:       attribute on the <tt>&lt;treerow&gt;</tt> to a
  741:       whitespace-separated list of properties.</dd>
  742:       <dt>&lt;treeseparator&gt;</dt>
  743:       <dd>A special element used to draw 
  744:       <!--INDEX treerow element, XUL --> a horizontal separating
  745:       line. The <tt>properties</tt> attribute is used to compute
  746:       the properties that apply to the separator.</dd>
  747:       <dt>&lt;treecell&gt;</dt>
  748:       <dd>The <tt><!--INDEX treecell element, XUL -->
  749:       &lt;treecell&gt;</tt> element must appear within the
  750:       <tt>&lt;treerow&gt;</tt> element. It specifies the text and
  751:       properties that apply for a cell. The <tt>label</tt>
  752:       attribute is used to set the text for the cell. The optional
  753:       <tt>properties</tt> attribute is used to compute the
  754:       properties that apply to the cell. The <tt>ref</tt> attribute
  755:       correlates a cell within an <tt>&lt;treerow&gt;</tt> to the
  756:       column in the <tt>tree</tt> and is optional.</dd>
  757:     </dl>
  758:     <p>Tying the concepts presented in this section together allows
  759:     us to present <a href="#77054">Example 3-11</a>, which shows a
  760:     multilevel <tt>tree</tt> with two columns and two top-level
  761:     rows. Example 3-11<a name="77054"></a> <i>Multilevel tree
  762:     content view</i></p>
  763: <pre>
  764:  &lt;tree id="tree" hidecolumnpicker="true" flex="1"&gt;
  765:    &lt;treecols&gt;
  766:      &lt;treecol id="type" label="Type" flex="1" primary="true"/&gt;
  767:      &lt;treecol id="method" label="Method" flex="1"/&gt;
  768:    &lt;/treecols&gt;
  769:    &lt;/td&gt;&lt;treechildren&gt;
  770:      &lt;treeitem&gt;
  771:        &lt;treerow&gt;
  772:          &lt;treecell label="Bike"/&gt;
  773:          &lt;treecell label="Bicycle"/&gt;
  774:        &lt;/treerow&gt;
  775:      &lt;/treeitem&gt;
  776:      &lt;treeitem container="true" open="true"&gt;
  777:        &lt;treerow&gt;
  778:          &lt;treecell label="Fly"/&gt;
  779:          &lt;treecell label="Wings"/&gt;
  780:        &lt;/treerow&gt;
  781:        &lt;/td&gt;&lt;treechildren&gt;  &lt;!-- Second level row --&gt;
  782:          &lt;treeitem&gt;
  783:            &lt;treerow&gt;
  784:              &lt;treecell label="Glide"/&gt;
  785:              &lt;treecell label="Hand-Glider"/&gt;
  786:            &lt;/treerow&gt;
  787:          &lt;/treeitem&gt;
  788:        &lt;/treechildren&gt;
  789:      &lt;/treeitem&gt;
  790:    &lt;/treechildren&gt;
  791:  &lt;/tree&gt;
  792: </pre>
  793:     <p>To create a new sublevel, create another <tt>
  794:     <!--INDEX treechildren element, XUL -->
  795:     &lt;treechildren&gt;</tt> element; inside of it, place a
  796:     <tt>&lt;treeitem&gt;</tt>, which, in turn, contains one or more
  797:     rows and cells. <a href="#77010">Figure 3-5</a> illustrates the
  798:     result of this hierarchy.</p>
  799:     <div class="c10">
  800:       <img src="foo.gif">
  801:     </div>
  802:     <p><i>Figure 3-5: <a name="77010"></a></i> <i>Multilevel tree
  803:     hierarchy</i></p>
  804:     <h4><a name="77105"></a> Using trees in XUL templates</h4>
  805:     <p>XUL templates are special built-in structures 
  806:     <!--INDEX XUL (XML-based User-interface Language):templates, trees in;templates:XUL templates:trees in;trees:XUL templates -->
  807:     that allow dynamic updating of XUL elements and that are often
  808:     used with trees and list boxes. Templates harness the power of
  809:     the Resource Description Framework (RDF) to 
  810:     <!--INDEX RDF (Resource Description Framework) --> pull data
  811:     from external datasources and dynamically create or update
  812:     content in the UI. The following code extract shows the basic
  813:     structure of a XUL template for displaying the browser history
  814:     in Mozilla:</p>
  815: <pre>
  816: &lt;template&gt;
  817: &lt;rule&gt;
  818: &lt;treechildren&gt;
  819: &lt;treeitem uri="rdf:*" rdf:type="rdf:<a href=
  820: "http://www.w3.org/1999/02/22-rdf-syntax">http://www.w3.org/1999/02/22-rdf-syntax</a>-            ns#type"&gt;
  821: &lt;treerow&gt;
  822: &lt;treecell label="rdf:<a href=
  823: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#Name"/&gt;
  824: &lt;treecell label="rdf:<a href=
  825: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#URL"/&gt;
  826: &lt;treecell label="rdf:<a href=
  827: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#Date"/&gt;
  828: &lt;!-- further cells --&gt;
  829: &lt;/treerow&gt;
  830: &lt;/treeitem&gt;
  831: &lt;/treechildren&gt;
  832: &lt;/rule&gt;
  833: &lt;/template&gt;
  834: </pre>
  835:     <p>For each entry or row in the browser history, the template
  836:     extracts information from the datasource and renders it in a
  837:     <tt>treecell</tt>. It then updates it each time a page is
  838:     visited. For a more detailed discussion, refer to <a href=
  839:     "ch09.html#97291">Chapter 9</a>.</p>
  840:     <h4><a name="77106"></a> Custom tree views</h4>
  841:     <p>Custom views extend upon the static presentation 
  842:     <!--INDEX trees:views:custom;views, tree views:custom --> of
  843:     data in a tree with more flexibility, different ways to present
  844:     the same data, and interfaces for defining behavior related to
  845:     content. The functions include intercepting a <tt>treeitem</tt>
  846:     selection and carrying out some functionality, populating or
  847:     getting values from the tree, and returning the number of rows
  848:     currently in the tree.</p>
  849:     <p>The first thing you have to do to build a custom view is
  850:     instantiate your <tt>tree</tt> and then associate a
  851:     <tt>view</tt> object with it, commonly known as a view.</p>
  852: <pre>
  853: document.getElementById('main-tree').treeBoxObject.view=mainView;
  854: </pre>
  855:     <p>In this example, the view that is exposed in the
  856:     <tt>nsITreeView</tt> XPCOM object is essentially the lifeline
  857:     for the tree, supplying the data that populates the view. The
  858:     view is assigned to the code object that contains all the
  859:     functions available to it and your implementation of what you
  860:     need to do when they are activated.</p>
  861:     <p>Here is a large subset of the functions available to the
  862:     view object:</p>
  863:     <p>setTree(tree)</p>
  864:     <dl>
  865:       <dd>Called during initialization and used to connect the tree
  866:       view to the front end. This connection ensures that the
  867:       correct tree is associated with the view.</dd>
  868:       <dt>getCellText (row,column)</dt>
  869:       <dd>Returns the text of a particular cell, or an empty string
  870:       if there's just an image in it.</dd>
  871:       <dt>rowCount</dt>
  872:       <dd>Set up the number of rows that you anticipate for your
  873:       tree.</dd>
  874:       <dt>cycleHeader(index)</dt>
  875:       <dd>Called when you click on the header of a particular
  876:       column.</dd>
  877:       <dt>toggleOpenState</dt>
  878:       <dd>Put code in here to be carried out when the view is
  879:       expanded and collapsed.</dd>
  880:       <dt>setCellText (row, colID, value)</dt>
  881:       <dd>Called when the contents of the cell have been
  882:       edited.</dd>
  883:       <dt>performAction (action)</dt>
  884:       <dd>An event from a set of commands can be invoked when you
  885:       carry out a certain action on the outliner. The tree invokes
  886:       this method when certain keys are pressed. For example, when
  887:       the ENTER key is pressed, <tt>performAction</tt> calls with
  888:       the "enter" string.</dd>
  889:       <dd>There are more local conveniences in the form of
  890:       <tt>PerformActionOnRow</tt> and
  891:       <tt>performActionOnCell</tt>.</dd>
  892:       <dt>selectionChanged</dt>
  893:       <dd>Should be hooked up to the <tt>onselect</tt> handler of
  894:       the <tt>&lt;tree&gt;</tt> element in the XUL content.</dd>
  895:     </dl>
  896:     <h3><a name="77107"></a> Grid</h3>
  897:     <p>A <tt>&lt;grid&gt;</tt> is another XUL table 
  898:     <!--INDEX grid element, XUL --> structure, designed 
  899:     <!--INDEX tabular information:grids --> to be more flexible
  900:     with the content it can hold than the other tabular widgets. <a
  901:     href="#77056">Example 3-12</a> shows a two-column grid that
  902:     holds text input boxes and labels for them. Example 3-12<a
  903:     name="77056"></a> <i>XUL grid</i></p>
  904: <pre>
  905:  &lt;grid&gt;
  906:    &lt;columns&gt;&lt;column flex="1"/&gt;&lt;column flex="2"/&gt;&lt;/columns&gt;
  907:    &lt;rows&gt;
  908:      &lt;row align="center"&gt;
  909:        &lt;label value="Title"/&gt;
  910:        &lt;textbox id="title-text" oninput="TextboxInput(this.id)"/&gt;
  911:      &lt;/row&gt;
  912:      &lt;row align="center"&gt;
  913:        &lt;label value="Author"/&gt;
  914:        &lt;textbox id="author-text" oninput=" TextboxInput(this.id)"/&gt;
  915:      &lt;/row&gt;
  916:      &lt;row align="center"&gt;
  917:        &lt;label value="About"/&gt;
  918:        &lt;textbox id="about-text" oninput=" TextboxInput(this.id)"/&gt;
  919:      &lt;/row&gt;
  920:    &lt;/rows&gt;
  921:  &lt;/grid&gt;
  922: </pre>
  923:     <p>In a grid, the number of columns needs to be defined and
  924:     placed in a <tt>&lt;columns&gt;</tt> set. In <a href=
  925:     "#77056">Example 3-12</a>, the first column holds the labels
  926:     and the second contains the text boxes. These two columns are
  927:     horizontal to each other and in rows for easy association. The
  928:     flex is greater on the second column, allowing more space for
  929:     the text input boxes. As with all examples in this chapter, you
  930:     can see <a href="#77056">Example 3-12</a> in action by adding
  931:     the XML processing instruction at the top and 
  932:     <!--INDEX ENDRANGE==tabular information;hierarchical information -->
  933:     surrounding the grid in a basic <tt>window</tt> root
  934:     element.</p>
  935:     <h2><a name="77108"></a> Words and Pictures</h2>
  936:     <p>The text widgets described here are used to label other
  937:     widgets, or simply to display messages or instructions to the
  938:     user in the interface and include a text input widget. Images
  939:     can be displayed with the main <tt>image</tt> element or in
  940:     various ways on other elements, such as buttons or menus.</p>
  941:     <h3><a name="77109"></a> Text Input</h3>
  942:     <p>The <tt>&lt;textbox&gt;</tt> element is a text input box not
  943:     <!--INDEX text widgets, input;input text;text:input text -->
  944:     unlike <!--INDEX textbox element, XUL --> the HTML
  945:     <tt>&lt;textarea&gt;</tt> element. The default
  946:     <tt>&lt;textbox&gt;</tt> element has a single line.</p>
  947: <pre>
  948: &lt;textbox id="singleFlyInput" /&gt;
  949: </pre>
  950:     <p>However, setting the <tt>multiline</tt> attribute makes it
  951:     into a larger text area.</p>
  952: <pre>
  953: &lt;textbox id="multiFlyInput" value="Fly Name" multiline="true" rows="4" /&gt;
  954: </pre>
  955:     <p>A multiline textbox defaults to three lines unless
  956:     constricted by a fixed size on a container or stretched out
  957:     with flex. To force the number of lines, use the <tt>rows</tt>
  958:     attribute. If you want to restrict the number of characters
  959:     inputted, set the <tt>size</tt> attribute to a numeric
  960:     value.</p>
  961: <pre>
  962: &lt;textbox id="holdtheFlyInput" cols="3" rows="2" /&gt;
  963: </pre>
  964:     <p>The initial value of an input widget is blank if no
  965:     <tt>value</tt> is specified. Setting the <tt>readonly</tt>
  966:     attribute to <tt>true</tt> or <tt>false</tt> can control
  967:     editing access.</p>
  968:     <h4><a name="77110"></a> Autocomplete</h4>
  969:     <p>Autocompletion is the process of 
  970:     <!--INDEX autocomplete, text input and;text:input text:autocomplete;input text:autocomplete -->
  971:     automatically finishing a user's input by offering possible
  972:     choices, or completions, when something is typed in. In
  973:     Mozilla, this mechanism is simply known as <i>autocomplete</i>,
  974:     and the textbox widget is used for this process in such places
  975:     as the browser URL bar and in the address area of the mail
  976:     compose window. <a href="#77058">Example 3-13</a> shows the
  977:     code from the Open Web Location dialog, which provides
  978:     autocompletion. Example 3-13<a name="77058"></a> <i>Text
  979:     autocomplete</i></p>
  980: <pre>
  981:  &lt;textbox id="dialog.input" flex="1" type="autocomplete"
  982:      searchSessions="history" timeout="50" maxrows="6"
  983:      disablehistory="false"
  984:      oninput="doEnabling( );"&gt;
  985:    &lt;menupopup id="ubhist-popup" class="autocomplete-history-popup"
  986:        popupalign="topleft" popupanchor="bottomleft"
  987:        onpopupshowing="createUBHistoryMenu(event.target);"
  988:        oncommand="useUBHistoryItem(event.target)"/&gt;
  989:  &lt;/textbox&gt;
  990: </pre>
  991:     <p>The first thing to note is the nested
  992:     <tt>&lt;menupopup&gt;</tt>. This pop up holds the choices in a
  993:     drop-down format. The relevant attribute in this example is
  994:     <tt>type</tt> on the <tt>&lt;textbox&gt;</tt>, which has a
  995:     value of <tt>autocomplete</tt>.</p>
  996:     <p><a href="#77012">Figure 3-6</a> shows the
  997:     <tt>autocomplete</tt> widget. As the user types the URL into
  998:     the textbox, auto completion kicks in and the values are
  999:     retrieved to show in the pop-up list, from which the user can
 1000:     then choose. When similar values are input regularly,
 1001:     <tt>autocomplete</tt> can be a great time-saving feature.</p>
 1002:     <div class="c10">
 1003:       <img src="foo.gif">
 1004:     </div>
 1005:     <p><i>Figure 3-6: <a name="77012"></a></i> <i>Autocomplete for
 1006:     Open Web Location</i></p>
 1007:     <h3><a name="77111"></a> Text Display</h3>
 1008:     <p>Three tags available in XUL handle 
 1009:     <!--INDEX text:displaying --> <!--INDEX display:text --> basic
 1010:     text display in the UI, and each has its own context for use.
 1011:     They include a <tt><!--INDEX caption element, XUL --> 
 1012:     <!--INDEX label element, XUL --> &lt;caption&gt;</tt>, a
 1013:     <tt>&lt;label&gt;</tt>, and a <tt>
 1014:     <!--INDEX description element, XUL --> &lt;description&gt;</tt>
 1015:     element.</p>
 1016:     <p>The <tt>caption</tt> is designed specifically for the text
 1017:     that appears inline in the border of a group box. You can
 1018:     control where the caption appears by putting the caption
 1019:     element above or below the other content in the group box:</p>
 1020: <pre>
 1021: &lt;groupbox id="textWidgetsBox"&gt;
 1022: &lt;caption id="textTitle" label="Text Widgets"/&gt;
 1023: &lt;!-- content here --&gt;
 1024: &lt;/groupbox&gt;
 1025: </pre>
 1026:     <p><tt>label</tt> is more flexible than <tt>caption</tt>
 1027:     because it isn't tied to a particular widget and can even be
 1028:     used as a standalone.</p>
 1029:     <p>For longer text, the <tt>&lt;description&gt;</tt> element is
 1030:     best. You can embed text in the description element and have it
 1031:     wrap to the maximum size of the containing element:</p>
 1032: <pre>
 1033: &lt;description&gt;
 1034: The mozdev.org site provides free project hosting for the Mozilla community. You are welcome to take a look at the more than 60 projects hosted on the site or to start your own development project.
 1035: &lt;/description&gt;
 1036: </pre>
 1037:     <p>Or you can use the <tt>value</tt> attribute when you're sure
 1038:     the text will not overflow. In this case,
 1039:     <tt>&lt;description&gt;</tt> is interchangeable with the
 1040:     <tt>&lt;label&gt;</tt> element for use in identifying other
 1041:     items in the UI:</p>
 1042: <pre>
 1043: &lt;description value="Start a project today." /&gt;
 1044: </pre>
 1045:     <h3><a name="77112"></a> Images</h3>
 1046:     <p>XUL supports the display of images in the native web 
 1047:     <!--INDEX images:displaying;display:images;XUL (XML-based User-interface Language):images 
 1048:     --> formats of JPEG, PNG, and GIF. Most images you will find in
 1049:     the Mozilla UI are GIF files, which retain the best quality
 1050:     when compressed. <a href="ch04.html#37942">Chapter 4</a>
 1051:     discusses theme issues 
 1052:     <!--INDEX JPEG files;PNG files;GIG files --> and considerations
 1053:     in more detail. The basic syntax for displaying an image
 1054:     is:</p>
 1055: <pre>
 1056: &lt;image src="myImage.png" /&gt;
 1057: </pre>
 1058:     <p>The <tt><!--INDEX image element, XUL --> &lt;image&gt;</tt>
 1059:     element is analogous to the HTML <tt>&lt;img&gt;</tt> element.
 1060:     The image to be displayed is directly associated with the
 1061:     element using the <tt>src</tt> attribute. You can also use
 1062:     <tt>list-style-image</tt>, which is a CSS2 property used to
 1063:     associate an image with an element. To do this, you need a
 1064:     style <i>selector-</i>in this case, the <tt>id</tt>.</p>
 1065: <pre>
 1066: &lt;image id="foo" /&gt;
 1067: </pre>
 1068:     <p>The style property takes a value of <tt>src</tt>, which has
 1069:     one parameter, the image, or a chrome or resource URL pointing
 1070:     to the image.</p>
 1071: <pre>
 1072: #foo  {
 1073: list-style-image: url("myImage.png");
 1074: }
 1075: </pre>
 1076:     <p><tt>src</tt> is good for single images and for convenience,
 1077:     but in general, using the CSS property is recommended because
 1078:     it follows the principal of separating functionality from
 1079:     presentation and it better fits into a theme-swapping
 1080:     architecture, as used in the Mozilla suite.</p>
 1081:     <blockquote>
 1082:       <div class="c11">
 1083:         NOTE
 1084:       </div>
 1085:       <p>Many in the open source community feel that PNG would have
 1086:       been a more natural choice for the project because it is a
 1087:       free format. Efforts to make this switch have been held up by
 1088:       a bug in gamma-corrected CSS color values and specified in
 1089:       both CSS1 and CSS2.</p>
 1090:     </blockquote>
 1091:     <h4><a name="77113"></a> Images in other XUL elements</h4>
 1092:     <p>Image display is 
 1093:     <!--INDEX list-style-image property (CSS);properties:list-style-image -->
 1094:     not the sole province of the <tt>image</tt> element. Using the
 1095:     <tt>list-style-image</tt> property, you can attach images to
 1096:     almost any element. For example, the <tt>tree</tt> widget has a
 1097:     couple of its own special associated CSS properties that allow
 1098:     you to define <tt>list-style-image</tt> values.
 1099:     <tt>-moz-tree-image</tt> defines images contained in a cell,
 1100:     and it takes input parameters that let you specify the
 1101:     <tt>id</tt> of the specific column and row to which the image
 1102:     should be applied:</p>
 1103: <pre>
 1104: treechildren:-moz-tree-image(col-id,row-id) {
 1105: list-style-image: url("chrome://xfly/skin/images/outliner.gif");
 1106: }
 1107: </pre>
 1108:     <p>Also, <tt>-moz-tree-twisty</tt> 
 1109:     <!--INDEX -moz-tree-twisty[moz-tree-twisty] --> allows you
 1110:     define an image for the <tt>twisty</tt> that is used to open
 1111:     and close a level in a tree.</p>
 1112: <pre>
 1113: treechildren:-moz-tree-twisty {
 1114: list-style-image: url("chrome://xfly/skin/images/twisty.gif");
 1115: }
 1116: </pre>
 1117:     <p>The example above uses a parameter of <tt>open</tt>, but if
 1118:     no parameter is specified, the default is closed, so you can
 1119:     have a different image for both states.</p>
 1120:     <p>The <tt>&lt;tab&gt;</tt> widget can also take a
 1121:     <tt>list-style-image</tt> property in CSS.</p>
 1122: <pre>
 1123: &lt;tab id="TabOne" class="tabbies" selected="1" label="Click Me!"  oncommand="SelectTab(1);" /&gt;
 1124: </pre>
 1125:     <p>In this case, the <tt>class</tt> attribute is used as a
 1126:     selector for associating the element with the style rule in
 1127:     which the image is referenced:</p>
 1128: <pre>
 1129: .tabbies {
 1130: list-style-image: url("chrome://xfly/skin/images/tab.gif");
 1131: }
 1132: </pre>
 1133:     <h2><a name="77114"></a> Form Controls</h2>
 1134:     <p>In the HTML world, the textbox 
 1135:     <!--INDEX STARTRANGE==form controls:XUL;XUL (XML-based User-interface Language):forms, controls;controls, forms:XUL -->
 1136:     is one of the most commonly used elements in a form control.
 1137:     While the XPFE toolkit has no concept of a form, it was
 1138:     originally designed to allow HTML in the UI when needed, but
 1139:     only on a limited scale. Although it's still possible to
 1140:     incorporate HTML when you use the correct namespace, the
 1141:     existence of XUL widgets such as the textbox, checkbox and
 1142:     radio group selector obviates the need for HTML elements.</p>
 1143:     <h3><a name="77115"></a> Radio</h3>
 1144:     <p>Radio groups are useful UI controls 
 1145:     <!--INDEX radio groups, XUL and;XUL (XML-based User-interface Language):radio groups -->
 1146:     that present the user with a choice of options in XUL. In HTML,
 1147:     radio choices are represented by the <tt>&lt;INPUT&gt;</tt>
 1148:     element with the <tt>type</tt> attribute set to the value of
 1149:     <tt>radio</tt>, all wrapped in a form element. <a href=
 1150:     "#77060">Example 3-14</a> shows how to make radio group choices
 1151:     in XUL. Example 3-14<a name="77060"></a> <i>A radio group
 1152:     choice of options</i></p>
 1153: <pre>
 1154:  &lt;radiogroup id="flyTypes" orient="vertical"&gt;
 1155:    &lt;radio id="tachina" group="flyTypes" label="Tachinidae"
 1156:      oncommand="chooseType(this);"/&gt;
 1157:    &lt;radio id="primitive-crane" group="flyTypes" label="Tanyderidae"
 1158:      oncommand="chooseType(this);"/&gt;
 1159:    &lt;radio id="crane" group="flyTypes" label="Tipulidae"
 1160:      oncommand="chooseType(this);"/&gt;
 1161:    &lt;radio id="flower" group="flyTypes" label="Syrphidae"
 1162:      oncommand="chooseType(this);"/&gt;
 1163:    &lt;radio id="fruit" group="flyTypes" label="Tephritidae"
 1164:      oncommand="chooseType(this);"/&gt;
 1165:  &lt;/radiogroup&gt;
 1166: </pre>
 1167:     <p>The options must be enclosed in the
 1168:     <tt>&lt;radiogroup&gt;</tt> element, and each one is
 1169:     represented by a <tt><!--INDEX radio element, XUL -->
 1170:     &lt;radio&gt;</tt> element. The important attributes are the
 1171:     <tt>id</tt> on the <tt>&lt;radiogroup&gt;</tt> and the
 1172:     <tt>group</tt> attribute on the <tt>&lt;radio&gt;</tt>
 1173:     elements. These attributes have to be identical to ensure that
 1174:     only one option at a time can be chosen. The <tt>this</tt>
 1175:     keyword in JavaScript lets you access the selected item in a
 1176:     straightforward way. In this case, it sends the node to the
 1177:     script every time an option is selected.</p>
 1178:     <h3><a name="77116"></a> Checkbox</h3>
 1179:     <p>A checkbox 
 1180:     <!--INDEX checkboxes;controls, forms:checkboxes;form controls:checkboxes;XUL (XML-based User-interface Language):checkboxes -->
 1181:     is a simpler widget that needn't be part of a selection group.
 1182:     It is often used to indicate if some functionality should be
 1183:     turned on or off, as shown in <a href="#77014">Figure
 1184:     3-7</a>.</p>
 1185: <pre>
 1186: &lt;checkbox id="closeWindow"
 1187: label="Close this window when download is complete"
 1188: checked="true" /&gt;
 1189: </pre>
 1190:     <div class="c10">
 1191:       <img src="foo.gif">
 1192:     </div>
 1193:     <p><i>Figure 3-7: <a name="77014"></a></i> <i>Checkbox
 1194:     widget</i></p>
 1195:     <p>Clicking on the box sets the <tt>checked</tt> attribute, for
 1196:     which the check indicates a positive value. You can set this
 1197:     attribute in script to give the checkbox an initial value.</p>
 1198:     <h3><a name="77117"></a> Buttons</h3>
 1199:     <p>A button is 
 1200:     <!--INDEX buttons;controls, forms:buttons;form controls:buttons;XUL (XML-based User-interface Language):buttons -->
 1201:     a multipurpose widget that commonly lives in toolbars and
 1202:     dialog boxes. The two button elements, <tt>
 1203:     <!--INDEX button element, XUL --> &lt;button&gt;</tt> and <tt>
 1204:     <!--INDEX toolbarbutton element, XUL -->
 1205:     &lt;toolbarbutton&gt;</tt>, are essentially the same. Often
 1206:     only the <tt>class</tt> attribute values distinguish the two.
 1207:     You can use a <tt>&lt;toolbarbutton&gt;</tt> outside a toolbar
 1208:     or use a <tt>&lt;button&gt;</tt> inside a toolbar, though in
 1209:     practice, the two usually stay in their respective domains.
 1210:     This flexibility has the nice effect of letting you get the
 1211:     buttons in a particular area by using the
 1212:     <tt>getElementsByTagName</tt> method with, for example, the tag
 1213:     name "button."</p>
 1214:     <p>A common form of the button contains text and an image, with
 1215:     image on the left and the text to the right by default.
 1216:     However, you may want to take advantage of some of the classes
 1217:     available in Mozilla to define a different orientation, or you
 1218:     can simply write your own style rules for your buttons.<a name=
 1219:     "b315"></a><a href="#315">[*]</a> The text that appears on the
 1220:     button is contained in the <tt>label</tt> attribute and shown
 1221:     in this example:</p>
 1222: <pre>
 1223: &lt;button id="newfileBtn"
 1224: tooltiptext="New File"
 1225: oncommand="doNew( )"
 1226: label="New"/&gt;
 1227: </pre>
 1228:     <p>You can associate the image with the button using the
 1229:     <tt>src</tt> attribute, but the more common way is to use the
 1230:     <tt>list-style-image</tt> style rule in CSS, as in the
 1231:     following snippet of code that uses the <tt>id</tt> style
 1232:     selector:</p>
 1233: <pre>
 1234: #newfileBtn
 1235: {
 1236: list-style-image:    url("chrome://editor/skin/images/newfile.gif");
 1237: }
 1238: </pre>
 1239:     <h4><a name="77118"></a> Button types</h4>
 1240:     <p>Mozilla provides more than 
 1241:     <!--INDEX buttons:types;controls, forms:buttons;form controls:buttons;XUL (XML-based User-interface Language):buttons:types -->
 1242:     the standard "click" and "go" buttons in its toolkit. <a href=
 1243:     "#77030">Table 3-3</a> describes the various button types in
 1244:     Mozilla.</p>
 1245:     <p><i>Table 3-3: <a name="77030"></a></i> <i>Button
 1246:     types</i></p>
 1247:     <table width="100%" border="1">
 1248:       <tr>
 1249:         <td><b>Type</b></td>
 1250:         <td><b>Usage</b></td>
 1251:         <td><b>Description</b></td>
 1252:       </tr>
 1253:       <tr>
 1254:         <td>Menu</td>
 1255:         <td>type= "menu"</td>
 1256:         <td>Menu integrated into the button with small arrow
 1257:         icon</td>
 1258:       </tr>
 1259:       <tr>
 1260:         <td>Dual Menu</td>
 1261:         <td>type= "menu-button"</td>
 1262:         <td>Menu appears distinct from the button, in separate
 1263:         clickable area</td>
 1264:       </tr>
 1265:       <tr>
 1266:         <td>Checkbox</td>
 1267:         <td>type= "checkbox"</td>
 1268:         <td>When selected, remains in a depressed state and toggles
 1269:         back to its natural state when selected again</td>
 1270:       </tr>
 1271:       <tr>
 1272:         <td>Radio</td>
 1273:         <td>type= "radio"</td>
 1274:         <td>Designed to be part of a group; only one button is
 1275:         selectable at a time</td>
 1276:       </tr>
 1277:       <tr>
 1278:         <td>Disclosure</td>
 1279:         <td>dlgtype= "disclosure"</td>
 1280:         <td>Shows/Hides a portion of a dialog window</td>
 1281:       </tr>
 1282:       <tr>
 1283:         <td>Default</td>
 1284:         <td>dlgtype= "accept"</td>
 1285:         <td>Performs the default action for a dialog</td>
 1286:       </tr>
 1287:       <tr>
 1288:         <td>Cancel</td>
 1289:         <td>dlgtype= "cancel"</td>
 1290:         <td>Closes the dialog and does not carry out the default
 1291:         action</td>
 1292:       </tr>
 1293:       <tr>
 1294:         <td>Help</td>
 1295:         <td>dlgtype= "help"</td>
 1296:         <td>Activates context-sensitive help</td>
 1297:       </tr>
 1298:     </table>
 1299:     <p>Taking one of the button types in <a href="#77030">Table
 1300:     3-3</a> as a mini-case study, you could use a button with the
 1301:     type <tt>menu-button</tt> to display more than one option at a
 1302:     time. The default orientation for this type of button is for
 1303:     the menu to be to the right of the button. Mozilla uses buttons
 1304:     of type <tt>menu-button</tt> for its back and forward buttons,
 1305:     in which the menu items hold previously visited pages. <a href=
 1306:     "#77016">Figure 3-8</a> shows the appearance of the browser's
 1307:     back button displaying the last several pages viewed.</p>
 1308:     <div class="c10">
 1309:       <img src="foo.gif">
 1310:     </div>
 1311:     <p><i>Figure 3-8: <a name="77016"></a></i> <i>menu-button for
 1312:     browser's back functionality</i></p>
 1313:     <p>Other possible uses include options for different variations
 1314:     of the same feature, such as a New button that displays New
 1315:     File, New Project, or New Template options. The button action
 1316:     is the default option and the <tt>menuitems</tt> contain the
 1317:     rest of the choices.</p>
 1318:     <h4><a name="77119"></a> Dialog buttons</h4>
 1319:     <p>The last four items in <a href="#77030">Table 3-3</a> are 
 1320:     <!--INDEX dialog buttons;buttons:dialog buttons;controls, forms:dialog buttons;form controls:dialog buttons;XUL (XML-based User-interface Language):dialog buttons -->
 1321:     button types that make most sense in, and were designed
 1322:     especially for, dialog windows. The easiest way to include them
 1323:     in dialogs is to use the <tt>buttons</tt> attribute on the <tt>
 1324:     <!--INDEX dialog element, XUL --> &lt;dialog&gt;</tt> element,
 1325:     which displays them automatically, as shown here:</p>
 1326: <pre>
 1327: &lt;dialog
 1328: xmlns="<a href=
 1329: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
 1330: buttons="accept,cancel,help"
 1331: buttonpack="center"
 1332: ondialogaccept="return onAccept( );"
 1333: ondialogcancel="return onCancel( );"
 1334: ondialoghelp="return doHelpButton( );"&gt;
 1335: </pre>
 1336:     <p>The functions activated when these buttons are clicked on
 1337:     are defined in the <tt>ondialogaccept</tt>,
 1338:     <tt>ondialogcancel</tt>, and <tt>ondialoghelp</tt> event
 1339:     handler attributes. These event handler shortcuts are best if
 1340:     you simply want to inherit the default button text (Ok, Cancel,
 1341:     and Help). In cases when you want your own text, or want some
 1342:     extra control over the scripting, you can define your own
 1343:     button with the <tt>dlgtype</tt> attribute:</p>
 1344: <pre>
 1345: &lt;button dlgtype="accept"
 1346: label="Go For It!"
 1347: oncommand="doExtraFunction( )"/&gt;
 1348: </pre>
 1349:     <p>The <tt>buttonpack</tt> attribute determines whether the
 1350:     buttons appear on the right, left, or center of the window. If
 1351:     no value is given, the default platform orientation takes
 1352:     effect. On Windows, the default is the right, and 
 1353:     <!--INDEX ENDRANGE==form controls:XUL;XUL (XML-based User-interface Language):forms, controls;controls, forms:XUL -->
 1354:     on Unix, it's the center.</p>
 1355:     <h2><a name="77120"></a> Widget Interaction</h2>
 1356:     <p>At a level above the use of widgets 
 1357:     <!--INDEX STARTRANGE==widgets:interactions;interacting with widgets -->
 1358:     for different, singular functions in the application interface,
 1359:     Mozilla provides tools for hooking things together and creating
 1360:     application logic that can make your interfaces work more
 1361:     consistently and handle more complex tasks. If you have
 1362:     different elements in your application that execute the same
 1363:     function, for example, the command and observer system is the
 1364:     ideal way to facilitate reuse. Or you can use command sets to
 1365:     define command sets and key sets that can be overlaid and made
 1366:     available in different parts of your application, similar to
 1367:     how the cut and paste commands and others are spread over the
 1368:     Mozilla user interface but defined in a centralized file.</p>
 1369:     <h3><a name="77121"></a> Broadcaster and Observers</h3>
 1370:     <p>Broadcasters and observers 
 1371:     <!--INDEX broadcasters;observers --> are a mechanism for making
 1372:     any number of elements aware of state and event information
 1373:     from a single, "broadcasting" element. That broadcasting
 1374:     element can be an actual <tt>
 1375:     <!--INDEX broadcaster element, XUL --> &lt;broadcaster&gt;</tt>
 1376:     or a regular element that broadcasts its state with special
 1377:     attributes. A common example of broadcasting is the disabling
 1378:     of a group of elements-a menu item and a separate button for
 1379:     viewing source, for example-when the source for a web page is
 1380:     not available.</p>
 1381:     <p>The state of a broadcaster has to be changed explicitly for
 1382:     its observers to be updated:</p>
 1383: <pre>
 1384: &lt;broadcasterset&gt;
 1385: &lt;broadcaster id="save_command" disabled="false"/&gt;
 1386: &lt;/broadcasterset&gt;
 1387: </pre>
 1388:     <p>Once a broadcaster is defined, a XUL file may define
 1389:     elements that observe the broadcast command:</p>
 1390: <pre>
 1391: &lt;button id="new" label="Save File" observes="save_command"/&gt;
 1392: &lt;key id="key_new" xulkey="true" key="s" observes="save_command" /&gt;
 1393: &lt;menuitem id="new_menuitem" label="New" observes="save_command"/&gt;
 1394: </pre>
 1395:     <p>Observing elements can also be more specific about the
 1396:     attribute they want to mimic. This is done by using the <tt>
 1397:     <!--INDEX observes element, XUL --> &lt;observes&gt;</tt>
 1398:     element:</p>
 1399: <pre>
 1400: &lt;menuitem id="new_menuitem" value="New" observes="open_new"/&gt;
 1401: &lt;observes element="open_new" attribute="disabled"/&gt;
 1402: &lt;/menu&gt;
 1403: </pre>
 1404:     <p>The <tt>element</tt> attribute associates the broadcaster
 1405:     and <tt>attribute</tt> tells the <tt>&lt;menuitem&gt;</tt>
 1406:     element to mimic the behavior of the broadcaster's
 1407:     <tt>"disabled"</tt> attribute.</p>
 1408:     <h3><a name="77122"></a> Commands</h3>
 1409:     <p>Any number of commands <!--INDEX commands --> can be
 1410:     contained in a <tt><!--INDEX commandset element, XUL -->
 1411:     &lt;commandset&gt;</tt>, and multiple sets can exist for
 1412:     different events in your application. It is also possible for
 1413:     sets to contain other command sets, mixed with commands or on
 1414:     their own. The idea is that there will be one base set that all
 1415:     other sets must inherit from; this base set can be defined in
 1416:     the top-level XUL file for your application. The following code
 1417:     has a command set that has its own commands and that pulls in a
 1418:     second set defined elsewhere (<tt>moreEditItems</tt>).</p>
 1419: <pre>
 1420: &lt;commandset id="EditItems"
 1421: oncommandupdate="updateCommandsetItems(this)"
 1422: commandupdater="true" events="select"&gt;
 1423: &lt;commandset id="moreEditItems" /&gt;
 1424: &lt;command id="cmd_cut" oncommand="goDoCommand('cmd_cut');"/&gt;
 1425: &lt;command id="cmd_copy" oncommand="goDoCommand('cmd_copy');"/&gt;
 1426: &lt;command id="cmd_delete" oncommand="goDoCommand('cmd_delete');"/&gt;
 1427: &lt;/commandset&gt;
 1428: </pre>
 1429:     <p>The command updater is the mechanism used to 
 1430:     <!--INDEX command updater --> 
 1431:     <!--INDEX events:command events, command updater and --> pass
 1432:     command events between widgets in the UI. When an event is
 1433:     carried out, the message filters through to the command sets.
 1434:     Thus in the example above, if the <tt>select</tt>
 1435:     <tt>event</tt> is activated, all UI elements in this
 1436:     <tt>commandset</tt> become active. For example, setting the
 1437:     <tt>disabled</tt> attribute on a command set for saving
 1438:     disables all functional elements depending on it-such as a menu
 1439:     item, a toolbar button, or a pop-up menu.</p>
 1440:     <p>There are a number of ways to trigger the command updater.
 1441:     First, associate a widget with a particular command by using
 1442:     the <tt>command</tt> attribute:</p>
 1443: <pre>
 1444: &lt;button id="cut-item" label="Cut" command="cmd_cut" enabled="true"/&gt;
 1445: </pre>
 1446:     <p>When this button is clicked, the command (<tt>cmd_cut</tt>)
 1447:     is located and carried out, firing the <tt>goDoCommand</tt>
 1448:     routine for that particular command.</p>
 1449:     <p>Alternatively, your application might have a select event
 1450:     for a text element or an image. When the select event is fired,
 1451:     the message filters through to the command set, which, in turn,
 1452:     updates (by using <tt>oncommandupdate</tt>) the
 1453:     widgets-associated button with the commands.</p>
 1454:     <p>The <!--INDEX keyset element, XUL -->
 1455:     &lt;<tt>keyset&gt;</tt> element is a 
 1456:     <!--INDEX key elements, containers;elements:key elements, containers;containers:key elements -->
 1457:     container for key elements. Key elements are used to execute
 1458:     commands from a keystroke combination. The keys Ctrl-Shift-s
 1459:     can be defined to execute a Save As command in your application
 1460:     (and that command can actually be defined in a <tt>command</tt>
 1461:     element):</p>
 1462: <pre>
 1463: &lt;key id="key_saveas" key="s" modifiers="control,shift" command="cmd_saveas"/&gt;
 1464: </pre>
 1465:     <p>The key element has various special attributes like
 1466:     <tt>key</tt>, which is used to set an identifier shortcut key,
 1467:     or the <tt>modifiers</tt> attribute to set the trigger key. For
 1468:     example, <tt>modifiers="accel</tt>" would be the Ctrl key on
 1469:     Windows and GTK Unix platforms and the command button on
 1470:     Macintosh.</p>
 1471:     <p><a href="#77062">Example 3-15</a> shows a simple window that
 1472:     <!--INDEX ENDRANGE==widgets:interactions;interacting with widgets -->
 1473:     you can load up that has all element sets: commands,
 1474:     broadcasters, and keys. Example 3-15<a name="77062"></a>
 1475:     <i>Shortcut keys with command observers</i></p>
 1476: <pre>
 1477:  &lt;?xml version="1.0"?&gt;
 1478:  &lt;window id="hello-goodbye"
 1479:      title="Hello Goodbye"
 1480:      xmlns:html="<a href=
 1481: "http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
 1482:      xmlns="<a href=
 1483: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
 1484:      style="min-width:100px;min-height:100px;background-color:white;"&gt;
 1485:    &lt;broadcasterset id="broadcasterset"&gt;
 1486:      &lt;broadcaster id="cmd_hello" oncommand="alert('Hello There!');"/&gt;
 1487:    &lt;/broadcasterset&gt;
 1488:    &lt;keyset id="keyset"&gt;
 1489:      &lt;key id="key_h" key="H" observes="cmd_hello" modifiers="accel,shift" /&gt;
 1490:      &lt;key id="key_g" key="G" command="cmd_goodbye" modifiers="accel,shift" /&gt;
 1491:    &lt;/keyset&gt;
 1492:    &lt;commandset id="commandset"&gt;
 1493:      &lt;command id="cmd_goodbye" oncommand="alert('Goodbye!');" /&gt;
 1494:    &lt;/commandset&gt;
 1495:    &lt;spacer flex="1"/&gt;
 1496:    &lt;label value="hello/goodbye"/&gt;
 1497:    &lt;textbox value="type ctl+shft+h"/&gt;
 1498:    &lt;textbox value="type ctl+shft+g"/&gt;
 1499:    &lt;spacer flex="1"/&gt;
 1500:  &lt;/window&gt;
 1501: </pre>
 1502:     <h2><a name="77123"></a> Content Panels</h2>
 1503:     <p>Content widgets allow you to 
 1504:     <!--INDEX STARTRANGE==control panels;content widgets, control panels -->
 1505:     load content into the UI for display. These
 1506:     widgets-<tt>browser</tt> and <tt>editor-</tt>provide a window
 1507:     into which you can load. In the standard browser, these
 1508:     documents can be written in HTML, XML, text, or other supported
 1509:     content types.</p>
 1510:     <h3><a name="77124"></a> Browser and IFrame</h3>
 1511:     <p>The <tt><!--INDEX browser element, XUL -->
 1512:     &lt;browser&gt;</tt> element displays online content and
 1513:     provides full browsing capabilities to your application, such
 1514:     as navigation features or maintaining a history.</p>
 1515: <pre>
 1516: &lt;browser id="content" type="content-primary" src="ch3.html"/&gt;
 1517: </pre>
 1518:     <p>The behind-the-scenes implementation for <tt>browser</tt>
 1519:     gives you access to certain interfaces that can be used in your
 1520:     scripts. These interfaces include:</p>
 1521:     <ul>
 1522:       <li>nsIDocShell</li>
 1523:       <li>nsIWebNavigation</li>
 1524:       <li>nsIMarkupDocumentViewer</li>
 1525:       <li>nsIContentViewerEdit</li>
 1526:       <li>nsIContentViewerFile</li>
 1527:       <li>nsIWebBrowserFind</li>
 1528:       <li>nsIDocumentCharsetInfo</li>
 1529:     </ul>
 1530:     <p>Without going into detail, these interfaces all provide
 1531:     sophisticated functionality for web browsing and other
 1532:     browser-like services, and are made available to JavaScript in
 1533:     the application interface. You can explore them further by
 1534:     looking at the interfaces themselves-at the IDL files of the
 1535:     same name in the Mozilla source tree.</p>
 1536:     <blockquote>
 1537:       <div class="c11">
 1538:         NOTE
 1539:       </div>
 1540:       <p>If you would like to learn more about these available
 1541:       interfaces, the best place to look is the source code. The
 1542:       two recommended files to start with are <i>browser.xml</i>,
 1543:       which shows how the interfaces are exposed, and
 1544:       <i>navigator.js</i>, which shows how they are used. Both
 1545:       files can be browsed on the online Mozilla Cross Reference,
 1546:       at <a href=
 1547:       "http://lxr.mozilla.org">http://lxr.mozilla.org</a>.</p>
 1548:     </blockquote>
 1549:     <p>An alternative to <tt>&lt;browser&gt;</tt> is the <tt>
 1550:     <!--INDEX iframe element, XUL --> &lt;iframe&gt;</tt>. It's
 1551:     similar to the browser widget in appearance, but better suited
 1552:     for simple or ephemeral content. It's often used as a preview
 1553:     window in HTML/XML editors and other WYSIWYG applications.
 1554:     iframes can also be good for dynamic document editing, as in
 1555:     the following example, in which the frame provides access to
 1556:     the document loaded as content. This can then be written
 1557:     to:</p>
 1558: <pre>
 1559: &lt;iframe id="simple-content" /&gt;
 1560: </pre>
 1561:     <p>The document's <tt>open( )</tt>, <tt>write( )</tt>, and
 1562:     <tt>close( )</tt> methods, which are standard in the JavaScript
 1563:     engine, are used to write to the document:</p>
 1564: <pre>
 1565: var doc = window.frames[1].document;
 1566: doc.open( );
 1567: doc.write("&lt;html&gt;&lt;body&gt;Come fly with me ...&lt;/body&gt;&lt;/html&gt;");
 1568: doc.close( );
 1569: </pre>
 1570:     <p>In this code snippet, you get a handle to the particular
 1571:     frame that you want by using <tt>window.frames</tt>, which
 1572:     returns an array of all frames contained in a document. There
 1573:     can be multiple frames in a document, which are indexed. Here
 1574:     it is assumed that we get the second (1 in a zero-based array)
 1575:     frame. The <tt>doc</tt> variable has a reference to the content
 1576:     area and uses the methods available on the <tt>document</tt>
 1577:     object to write content-in this case, HTML.</p>
 1578:     <p>Ideas for using content panels include:<a name="b316"></a><a
 1579:     href="#316">[*]</a></p>
 1580:     <ul>
 1581:       <li>Create HTML or XML help pages for your application and
 1582:       upload them in a ready-made help browser.</li>
 1583:       <li>Create a previewer: test your XML, HTML, or CSS layout
 1584:       and styling in Gecko--one of the most standards-compliant
 1585:       layout engines around.</li>
 1586:       <li>A slight variation of the previous use, you could use
 1587:       mini-versions inline in dialogs to load up examples that
 1588:       change depending on the selection of the user from a number
 1589:       of choices (a font previewer, for example).</li>
 1590:       <li>Pop ups contained in a window for display of web
 1591:       content.</li>
 1592:     </ul>
 1593:     <h3><a name="77125"></a> Editor</h3>
 1594:     <p>The <tt><!--INDEX editor element, XUL -->
 1595:     &lt;editor&gt;</tt> element loads editable content and can
 1596:     handle text or HTML editing. A good example of its usage is in
 1597:     Mozilla Composer, the HTML editor that comes bundled with
 1598:     Mozilla.</p>
 1599:     <p>The <tt>&lt;editor&gt;</tt> tag creates 
 1600:     <!--INDEX nsEditorBoxObject interface --> an instance of the
 1601:     <i>nsEditorBoxObject</i> interface when it's initialized. From
 1602:     that point, you can use JavaScript (via the
 1603:     <tt>element.editorShell</tt> property) to get to the
 1604:     <tt>editorShell</tt> methods for carrying out editing on the
 1605:     loaded document.</p>
 1606:     <p>The editor is also used in the various XUL and HTML text
 1607:     widgets in Mozilla, such as <tt>textbox</tt> and HTML forms,
 1608:     and for composing HTML messages in Mail and News. The text
 1609:     widgets differ from the full-blown <tt>editor</tt> because they
 1610:     act on a subtree of the document. Also, text widgets have
 1611:     limited text-editing services.</p>
 1612:     <p>Uses for the editor, both practical and speculative,
 1613:     include:</p>
 1614:     <ul>
 1615:       <li>Plain text editor</li>
 1616:       <li>Web forms editor</li>
 1617:       <li>An HTML-enabled bulletin board, a guestbook entry form,
 1618:       or a Wiki that is a web interface collaboration 
 1619:       <!--INDEX ENDRANGE==control panels;content widgets, control panels -->
 1620:       area for posting comments</li>
 1621:       <li>Instant Messaging</li>
 1622:     </ul>
 1623:     <blockquote>
 1624:       <hr>
 1625:       <b>Keeping Track in Multiframe Documents</b> 
 1626:       <p>The content contained in a <tt>&lt;browser&gt;</tt>,
 1627:       <tt>&lt;iframe&gt;</tt>, and <tt>&lt;editor&gt;</tt> is
 1628:       treated as a separate document. At times, you may want to
 1629:       access that specific content, so how do you keep track of
 1630:       different content?</p>
 1631:       <p>To return all the content frames in a document, you can
 1632:       use:</p>
 1633: <pre>
 1634: var contentAreas = content.frames;
 1635: </pre>
 1636:       There are two ways to access specific content in a script:
 1637:       through the index of the frame within the containing document
 1638:       or by using the <tt>id</tt> attribute. 
 1639:       <p>By index, starting at 0:</p>
 1640: <pre>
 1641: var content = window.frames[ 1 ];
 1642: </pre>
 1643:       By <tt>id</tt>: 
 1644: <pre>
 1645: var content = window.frames[ contentId ];
 1646: </pre>
 1647:       This code returns the second frame. 
 1648:       <p>To flag one as default, use the <tt>type</tt> attribute
 1649:       and give it a value.</p>
 1650: <pre>
 1651: &lt;iframe id="print-panel" type="content-primary" src="about:blank" flex="1""/&gt;
 1652: </pre>
 1653:       This code allows quick access to the default via the
 1654:       <tt>window.content</tt> property: 
 1655: <pre>
 1656: window.content.print( );
 1657: </pre>
 1658:       <hr>
 1659:     </blockquote>
 1660:     <h2><a name="77126"></a> The Box Model</h2>
 1661:     <p>The <i>box model</i> is the 
 1662:     <!--INDEX STARTRANGE==box model, XUL;XUL (XML-based User-interface Language):box model -->
 1663:     basic layout mechanism in XUL. Although it's possible to
 1664:     position your widgets in a window by using layout attributes of
 1665:     the <tt>window</tt> (a box-based container), using boxes allows
 1666:     you to arrange, nest, and position your widgets the way you
 1667:     want. The box model defines:</p>
 1668:     <ul>
 1669:       <li>How much space elements take up in relation to their
 1670:       siblings and containing elements</li>
 1671:       <li>The orientation of elements</li>
 1672:       <li>The relationship of elements to one another</li>
 1673:     </ul>
 1674:     <p>Space can be determined in a number of ways. You can
 1675:     constrain size by putting fixed sizes on windows or the widgets
 1676:     contained therein. Or you can let the natural sizes take effect
 1677:     and let the elements size themselves according to their
 1678:     content. Applying boxes to your layout uses space efficiently
 1679:     and optimizes the layout of your XUL windows and dialogs.</p>
 1680:     <h3><a name="77127"></a> Box Attributes</h3>
 1681:     <p>The XUL element <tt>&lt;box&gt;</tt> defines a 
 1682:     <!--INDEX boxes:attributes;attributes:boxes --> number 
 1683:     <!--INDEX box element, XUL --> of attributes and some implicit
 1684:     behavior for layout. Boxes can be oriented within other boxes
 1685:     to define the general layout of the UI. Some boxes stretch to
 1686:     fit the space available within the top-level window or their
 1687:     containing element; others take only as much space as needed to
 1688:     display their own children.</p>
 1689:     <p>Attributes on the box and its child elements determine the
 1690:     flexibility of the content contained within the box, the way
 1691:     that windows are resized, and the alignment of elements, as <a
 1692:     href="#77032">Table 3-4</a> describes.</p>
 1693:     <p><i>Table 3-4: <a name="77032"></a></i> <i>Common box
 1694:     attributes</i></p>
 1695:     <table width="100%" border="1">
 1696:       <tr>
 1697:         <td><b>Attribute</b></td>
 1698:         <td><b>Values</b></td>
 1699:         <td><b>Default value</b></td>
 1700:         <td><b>Description</b></td>
 1701:       </tr>
 1702:       <tr>
 1703:         <td>align</td>
 1704:         <td>start | end | center | baseline | stretch |
 1705:         inherit</td>
 1706:         <td>stretch</td>
 1707:         <td>Determines how the children are aligned in conjunction
 1708:         with the box's orientation</td>
 1709:       </tr>
 1710:       <tr>
 1711:         <td>flex</td>
 1712:         <td>&lt;number&gt; | inherit</td>
 1713:         <td>0.0</td>
 1714:         <td>Determines the flexibility of the contained elements,
 1715:         which depends on their particular flex values</td>
 1716:       </tr>
 1717:       <tr>
 1718:         <td>style</td>
 1719:         <td>CSS property and value</td>
 1720:         <td>N/A</td>
 1721:         <td>Applies CSS style settings to the box</td>
 1722:       </tr>
 1723:       <tr>
 1724:         <td>orient</td>
 1725:         <td>horizontal | vertical | inline-axis | block-axis |
 1726:         inherit</td>
 1727:         <td>inline-axis</td>
 1728:         <td>Determines the layout of the children of the box</td>
 1729:       </tr>
 1730:       <tr>
 1731:         <td>pack</td>
 1732:         <td>start | end | center | justify | inherit</td>
 1733:         <td>start</td>
 1734:         <td>Determines the use of remaining whitespace once all
 1735:         other objects are stretched to their full size</td>
 1736:       </tr>
 1737:       <tr>
 1738:         <td>direction</td>
 1739:         <td>normal | reverse | inherit</td>
 1740:         <td>normal</td>
 1741:         <td>Determines the direction of the children in the
 1742:         box</td>
 1743:       </tr>
 1744:       <tr>
 1745:         <td>ordinal-group</td>
 1746:         <td>&lt;integer&gt; | inherit</td>
 1747:         <td>1</td>
 1748:         <td>Controls the order in which widgets appear in a
 1749:         box</td>
 1750:       </tr>
 1751:     </table>
 1752:     <p>The attribute names in <a href="#77032">Table 3-4</a> (with
 1753:     the exception of <tt>style</tt>) are defined directly on the
 1754:     box. But there are also CSS versions of 
 1755:     <!--INDEX stylesheets:box attributes --> these properties that
 1756:     use the prefix <tt>box-</tt>. <tt>pack</tt> becomes <tt>box-pack</tt> when
 1757:     it's defined in CSS, for example. These properties are not part
 1758:     of the CSS specification, so you may need to go one step
 1759:     further and use the format <tt>-moz-box-pack</tt>. These
 1760:     special extensions to CSS are described in the section <a href=
 1761:     "ch04.html#77083">"Special Mozilla Extensions</a>" in <a href=
 1762:     "ch04.html#37942">Chapter 4</a>.</p>
 1763:     <p>The most commonly used attributes 
 1764:     <!--INDEX orient attribute, boxes;align attribute, boxes;pack attribute, boxes -->
 1765:     are <tt>orient</tt>, <tt>align</tt>, and <tt>pack</tt>. The
 1766:     orientation of the children of a box can be either vertical or
 1767:     horizontal. The default is horizontal for a plain
 1768:     <tt>&lt;box&gt;</tt>, but not for all box containers
 1769:     (<tt>&lt;groupbox&gt;</tt> is vertical). The
 1770:     <tt>&lt;vbox&gt;</tt> and <tt>&lt;hbox&gt;</tt> conveniences
 1771:     were created to bypass the use of this attribute and increase
 1772:     box layout efficiency in the rendering phase.</p>
 1773:     <p>Here is a look at how the pack and align properties can
 1774:     effect the layout of widgets. First, here is a bit of code with
 1775:     no constraints:</p>
 1776: <pre>
 1777: &lt;vbox style="width: 90px; height: 90px"&gt;
 1778: &lt;button label="Pack Me!" /&gt;
 1779: &lt;label value="This text is naturally aligned to the left" /&gt;
 1780: &lt;/vbox&gt;
 1781: </pre>
 1782:     <p>This XUL does not tell the button and text inside where to
 1783:     go, so they occupy the default positions shown in <a href=
 1784:     "#77018">Figure 3-9</a>.</p>
 1785:     <div class="c10">
 1786:       <img src="foo.gif">
 1787:     </div>
 1788:     <p><i>Figure 3-9: <a name="77018"></a></i> <i>Default box
 1789:     positioning</i></p>
 1790:     <p>Here is a changed <tt>box</tt> definition with the
 1791:     <tt>align</tt> and <tt>pack</tt> attributes set:</p>
 1792: <pre>
 1793: &lt;vbox style="width: 90px; height: 90px" align="right" pack="center"&gt;
 1794: </pre>
 1795:     <p>A noticeable visual difference can be seen in <a href=
 1796:     "#77020">Figure 3-10</a>.</p>
 1797:     <div class="c10">
 1798:       <img src="foo.gif">
 1799:     </div>
 1800:     Figure 3-10<a name="77020"></a> <i>Box packing and alignment
 1801:     effects</i> 
 1802:     <p>The <tt>align</tt> value moves the items to the right of the
 1803:     <tt>box</tt>, while simultaneously constraining the
 1804:     <tt>button</tt> to fit only the text <tt>label</tt>, making
 1805:     better use of space. <tt>pack</tt> centers both the items
 1806:     horizontally.</p>
 1807:     <h3><a name="77128"></a> Box-Like Containers</h3>
 1808:     <p>The basic XUL box is represented by 
 1809:     <!--INDEX box-like containers;containers:box-like containers -->
 1810:     the <tt><!--INDEX box element, XUL --> &lt;box&gt;</tt>, <tt>
 1811:     <!--INDEX vbox element, XUL --> &lt;vbox&gt;</tt>, and <tt>
 1812:     <!--INDEX hbox element, XUL --> &lt;hbox&gt;</tt> elements, but
 1813:     several more XUL elements are designed as box-like containers.
 1814:     They include:</p>
 1815:     <ul>
 1816:       <li>
 1817:       <!--INDEX radiogroup element, XUL -->&lt;radiogroup&gt;</li>
 1818:       <li>
 1819:       <!--INDEX scrollbox element, XUL -->&lt;scrollbox&gt;</li>
 1820:       <li><!--INDEX tabbox element, XUL -->&lt;tabbox&gt;</li>
 1821:       <li><!--INDEX groupbox element, XUL -->&lt;groupbox&gt;</li>
 1822:       <li><!--INDEX toolbox element, XUL -->&lt;toolbox&gt;</li>
 1823:       <li><!--INDEX stack element, XUL -->&lt;stack&gt;</li>
 1824:       <li><!--INDEX deck element, XUL -->&lt;deck&gt;</li>
 1825:       <li><!--INDEX listbox element, XUL -->&lt;listbox&gt;</li>
 1826:       <li><!--INDEX popup element, XUL -->&lt;popup&gt;</li>
 1827:       <li>
 1828:       <!--INDEX statusbar element, XUL -->&lt;statusbar&gt;</li>
 1829:     </ul>
 1830:     <p>Descriptions of the tabbed box and the group box follow.
 1831:     Additional information on other box widgets can be found in the
 1832:     XUL element reference in <a href="appc.html#72321">Appendix
 1833:     C</a>.</p>
 1834:     <h4><a name="77129"></a> Tab box</h4>
 1835:     <p>Tab <!--INDEX tab boxes;boxes:tab boxes --> boxes may
 1836:     contain only <tt><!--INDEX tabs element, XUL -->
 1837:     &lt;tabs&gt;</tt> and <tt><!--INDEX tabpanels element, XUL -->
 1838:     &lt;tabpanels&gt;</tt> elements, as shown in <a href=
 1839:     "#77064">Example 3-16</a>. Beyond this, there is no restriction
 1840:     on the content that can go into the panels themselves. For the
 1841:     panels to display content properly, there have to be the same
 1842:     number of children and tabs in the tab panels. Example 3-16<a
 1843:     name="77064"></a> <i>Tabbed panels</i></p>
 1844: <pre>
 1845:  &lt;tabbox orient="vertical" flex="1"&gt;
 1846:    &lt;tabs&gt;
 1847:      &lt;tab label="Fish" /&gt;
 1848:      &lt;tab label="Birds" /&gt;
 1849:      &lt;tab label="Coders" /&gt;
 1850:    &lt;/tabs&gt;
 1851:    &lt;tabpanels flex="1"&gt;
 1852:      &lt;button label="Swim"/&gt;
 1853:      &lt;button label="Fly"/&gt;
 1854:      &lt;button label="Hack"/&gt;
 1855:    &lt;/tabpanels&gt;
 1856:  &lt;/tabbox&gt;
 1857: </pre>
 1858:     <p><a href="#77064">Example 3-16</a> shows the main controls
 1859:     used to create a simple three-tab control with content elements
 1860:     on each panel. The tabs are associated with the appropriate
 1861:     panels by their order within the containing element.</p>
 1862:     <h4><a name="77130"></a> Status bar</h4>
 1863:     <p>A status bar is a <!--INDEX boxes:status bar;status bar -->
 1864:     horizontal box that appears on the bottom of the screen in many
 1865:     Mozilla applications, including the Mozilla browser itself. It
 1866:     can be used for the same purpose in your application if you
 1867:     need it. The <tt><!--INDEX statusbar element, XUL -->
 1868:     &lt;statusbar&gt;</tt> element typically contains icon images
 1869:     and text within one or more <tt>&lt;statusbarpanel&gt;</tt>
 1870:     elements:</p>
 1871: <pre>
 1872: &lt;statusbar id="ch3-bar" persist="collapsed"&gt;
 1873: &lt;statusbarpanel class="statusbarpanel-iconic" id="book-icon"/&gt;
 1874: &lt;statusbarpanel id="status-text" label="Thanks for reading chapter 3"
 1875: flex="1" crop="right"/&gt;
 1876: &lt;statusbarpanel class="statusbarpanel-iconic" id="book-icon-2"/&gt;
 1877: &lt;/statusbar&gt;
 1878: </pre>
 1879:     <p>As a box, the statusbar behaves like any other box widget.
 1880:     The panels constrain to their natural sizing and layout
 1881:     attributes such as flex situate all elements within. In this
 1882:     example, the icons appear to the left and right of the bar,
 1883:     while the flexed text panel takes up the remaining space.</p>
 1884:     <h3><a name="77131"></a> Additional Box Features</h3>
 1885:     <p>Boxes work in 
 1886:     <!--INDEX boxes:separator;separator element, XUL --> concert
 1887:     with a few other special elements, including the
 1888:     <tt>&lt;separator&gt;</tt> and <tt>&lt;spacer&gt;</tt>. These 
 1889:     <!--INDEX boxes:spacers;spacer element, XUL --> two elements
 1890:     create space between widgets in a box and can be horizontal or
 1891:     vertical depending on the orientation of the box. The separator
 1892:     is a visible divider and the spacer is invisible space. The
 1893:     default size for both of them is small, but they can be given
 1894:     <tt>flex</tt>, <tt>width</tt>, and <tt>height</tt> values like
 1895:     other elements. Used correctly, they can make all the
 1896:     difference in how your UI looks.</p>
 1897:     <h4><a name="77132"></a> Visibility</h4>
 1898:     <p>You can control 
 1899:     <!--INDEX boxes:visibility;visibility of boxes --> the
 1900:     visibility of a box by showing and hiding it in different
 1901:     circumstances-toggling the appearance of an advanced panel in a
 1902:     dialog, for example, or text that appears after a user selects
 1903:     something. One way to control visibility is to use the
 1904:     <tt>collapsed</tt> attribute to cede the space taken by the box
 1905:     to surrounding elements:</p>
 1906: <pre>
 1907: &lt;box flex="1" collapsed="true" /&gt;
 1908: </pre>
 1909:     <p>You can also set the CSS <tt>display</tt> property to
 1910:     <tt>none</tt>:</p>
 1911: <pre>
 1912: &lt;box flex="1" style="display: none;" /&gt;
 1913: </pre>
 1914:     <p>The document is rendered as though the element did not exist
 1915:     in the document tree. If you want the space to be maintained
 1916:     but the element to remain invisible, you can use the CSS
 1917:     <tt>visibility</tt> property:</p>
 1918: <pre>
 1919: &lt;box flex="1" style="visibility: hidden;" /&gt;
 1920: </pre>
 1921:     <p>Rendering the space but not the content avoids flicker and
 1922:     UI wobbles when content is being shown and hidden
 1923:     intermittently.</p>
 1924:     <h4><a name="77133"></a> Overflow</h4>
 1925:     <p>A value of <tt>scroll</tt> 
 1926:     <!--INDEX overflow, scrollbars;scrollbars, overflow --> or auto
 1927:     for the CSS <tt>overflow</tt> property ensures that a scrollbar
 1928:     appears and that the content can be accessed even when it can't
 1929:     be displayed. A value of <tt>hidden</tt> hides the content
 1930:     outside of the box. The content is not clipped if this value is
 1931:     set to <tt>visible</tt>, but it will be visible outside the
 1932:     box.</p>
 1933: <pre>
 1934: &lt;vbox flex="1" style="height:39px;overflow: auto;"&gt;
 1935: </pre>
 1936:     <p>This snippet constrains the height of the box but displays a
 1937:     scrollbar when the content exceeds the available space.</p>
 1938:     <h3><a name="77134"></a> Stacks and Decks</h3>
 1939:     <p>A variant and <!--INDEX stacks;decks --> special model of
 1940:     the <tt>box</tt> is available in the <tt>stack</tt> and
 1941:     <tt>deck</tt> elements. Both are boxes, but they lay their
 1942:     children out one on top of the other like a stack of crates or
 1943:     a deck of cards, rather than sequentially.</p>
 1944:     <p>A <tt>stack</tt> shows all its levels at once. If you have
 1945:     transparency or extra space on one level, you can see 
 1946:     <!--INDEX transparency, stacks and;stacks:transparency;levels:stacks and;stacks:levels and -->
 1947:     underneath. Stacks are useful when you want to add shadows in
 1948:     your content or if you want to create transparent layering
 1949:     effects. If you have a bird's eye view of XUL content, you can
 1950:     see the elements on each layer flowing into each other, like
 1951:     the text on top of an image in <a href="#77022">Figure
 1952:     3-11</a>.</p>
 1953: <pre>
 1954: &lt;stack&gt;
 1955: &lt;image src="logo5.gif"/&gt;
 1956: &lt;label value="BUZZ ..."
 1957: style="font-weight:bold; font-size: large" top="70px" left="140px"/&gt;
 1958: &lt;/stack&gt;
 1959: </pre>
 1960:     <div class="c10">
 1961:       <img src="foo.gif">
 1962:     </div>
 1963:     Figure 3-11<a name="77022"></a> <i>Text stacked on an image</i>
 1964:     
 1965:     <p>Decks show <!--INDEX levels:decks and;decks:levels and -->
 1966:     only one level at a time. In <a href="#77066">Example 3-17</a>,
 1967:     <i>logo3.gif</i> is foremost because the <tt>selectedIndex</tt>
 1968:     attribute on the deck is set to 2 in a zero-based index.
 1969:     Example 3-17<a name="77066"></a> <i>A deck with three image
 1970:     layers</i></p>
 1971: <pre>
 1972:  &lt;deck id="fly-deck" selectedIndex="2"&gt;
 1973:    &lt;image src="logo1.gif" /&gt;
 1974:    &lt;image src="logo2.gif" /&gt;
 1975:    &lt;image src="logo3.gif" /&gt;
 1976:  &lt;/deck&gt;
 1977: </pre>
 1978:     <p>As <a href="#77068">Example 3-18</a> shows, it is possible
 1979:     to switch pages using the DOM by changing the index on the
 1980:     deck. The <tt>setAttribute</tt> method changes the
 1981:     <tt>selectedIndex</tt> attribute of the deck <tt>element</tt>
 1982:     in script and can be executed, for example, when a user clicks
 1983:     a button or in other places in the interface. Example 3-18<a
 1984:     name="77068"></a> <i>Deck layer switching</i></p>
 1985: <pre>
 1986:  var deck = document.getElementById("fly-deck");
 1987:  var selected = deck.getAttribute("selectedIndex");
 1988:  if (!selected)
 1989:      selected = 0;
 1990:  if (selected &lt; 2)  {
 1991:      selected = parseInt(selected) + 1;
 1992:      deck.setAttribute("selectedIndex", selected);
 1993:  }
 1994:  else  {
 1995:      selected = 0;
 1996:      deck.setAttribute("selectedIndex", selected);
 1997:  }
 1998: </pre>
 1999:     <p>When applied to the deck in <a href="#77066">Example
 2000:     3-17</a>, the code in <a href="#77068">Example 3-18</a>
 2001:     continuously flips to the next image in the sequence and
 2002:     returns to the top of the deck when the last image is reached.
 2003:     In this case, there are only three images, so a maximum of 2 is
 2004:     put on the index check.</p>
 2005:     <h4><a name="77135"></a> Moveable content</h4>
 2006:     <p>At one point 
 2007:     <!--INDEX content:movable;movable content;XUL (XML-based User-interface Language):content, movable -->
 2008:     in XUL toolkit development, an <!--INDEX bulletinboard -->
 2009:     element called the <tt>bulletinboard</tt> allowed you to layer
 2010:     child elements one on top of another like its real-world
 2011:     namesake. You could change the coordinates of the child
 2012:     elements on the screen by using the <tt>top</tt> and
 2013:     <tt>left</tt> attributes. The order of the children in the XUL
 2014:     content determines the z-ordering on screen. As <tt>stack</tt>
 2015:     developed and took on much of this functionality,
 2016:     <tt>bulletinboard</tt> was officially deprecated and some of
 2017:     its properties were merged back into the <tt>stack</tt>
 2018:     element. As <a href="#77070">Example 3-19</a> demonstrates,
 2019:     this was a boon for the <tt>stack</tt> element, which can use
 2020:     coordinates to position children like its ancestor. The two
 2021:     boxes in the example are positioned at varying distances away
 2022:     from the stack's top left corner. Example 3-19<a name=
 2023:     "77070"></a> <i>Content positioning in a stack</i></p>
 2024: <pre>
 2025:  &lt;stack&gt;
 2026:   &lt;box id="box1" top="20px" left="40px"&gt;
 2027:    &lt;image src="logo1.gif" /&gt;
 2028:   &lt;/box&gt;
 2029:   &lt;box id="box2" top="40px" left="50px"&gt;
 2030:    &lt;image src="logo2.gif" /&gt;
 2031:   &lt;/box&gt;
 2032:  &lt;/stack&gt;
 2033: </pre>
 2034:     <p>You can position the two boxes, each containing an image, in
 2035:     any of the following ways:</p>
 2036:     <ul>
 2037:       <li>By placing the <tt>top</tt> and <tt>left</tt> attributes
 2038:       directly on the tags</li>
 2039:       <li>By setting them via stylesheets using the CSS properties
 2040:       <tt>top</tt> and left</li>
 2041:       <li>By using DOM calls in your script</li>
 2042:     </ul>
 2043:     <p>Here is some script used to switch the position of the boxes
 2044:     from one location to another by changing the <tt>top</tt> 
 2045:     <!--INDEX ENDRANGE==box model, XUL;XUL (XML-based User-interface Language):box model -->
 2046:     and <tt>left</tt> attributes:</p>
 2047: <pre>
 2048: Box1=document.getElementById("box1")
 2049: Box1.setAttribute("top","40px")
 2050: Box1.setAttribute("left","50px")
 2051: Box2=document.getElementById("box2")
 2052: Box2.setAttribute("top","20px")
 2053: Box2.setAttribute("left","40px")
 2054: </pre>
 2055:     <h2><a name="77136"></a> XUL Attributes</h2>
 2056:     <p>Each XUL element has an <tt>attributes</tt> property 
 2057:     <!--INDEX STARTRANGE==XUL (XML-based User-interface Language):attributes;attributes:XUL -->
 2058:     that contains an array of all its attributes. This section
 2059:     summarizes some of the general XUL attributes that developers
 2060:     find useful, including <tt>debug</tt>.</p>
 2061:     <h3><a name="77137"></a> Stretchiness</h3>
 2062:     <p>An object becomes flexible when 
 2063:     <!--INDEX flex attribute;attributes:XUL:flex --> 
 2064:     <!--INDEX objects:flexible --> the <tt>flex</tt> attribute is
 2065:     placed on the element. Flexible objects can shrink or grow as
 2066:     the box shrinks and grows. Whenever extra space is left over in
 2067:     a box, the flexible objects are expanded to fill that space.
 2068:     Flex is specified as a numerical value, and all flex is
 2069:     relative. For example, a child with a flex of 2 is twice as
 2070:     flexible as a child with a flex of 1, as <a href=
 2071:     "#77072">Example 3-20</a> shows. The <tt>flex</tt> attribute is
 2072:     invaluable for positioning elements in the box model. Example
 2073:     3-20<a name="77072"></a> <i>Flexible buttons</i></p>
 2074: <pre>
 2075:  &lt;?xml version="1.0"?&gt;
 2076:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
 2077:  &lt;window
 2078:     xmlns="<a href=
 2079: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
 2080:  &lt;box id="parent" style="margin: 50px;"&gt;
 2081:    &lt;button flex="2" label="flex2" /&gt;
 2082:    &lt;button flex="1" label="flex1" /&gt;
 2083:  &lt;/box&gt;
 2084:  &lt;/window&gt;
 2085: </pre>
 2086:     <h3><a name="77138"></a> Style</h3>
 2087:     <p>The <tt>style</tt> attribute allows you to 
 2088:     <!--INDEX style attribute;attributes:XUL:style attribute -->
 2089:     apply CSS style properties to your XUL element directly within
 2090:     the content. The attribute lets you access CSS properties
 2091:     (including <tt>width</tt>, <tt>height</tt>, <tt>min-width</tt>,
 2092:     <tt>min-height</tt>, <tt>max-width</tt>, and
 2093:     <tt>max-height</tt>), which give you more control over the size
 2094:     of your widget.</p>
 2095: <pre>
 2096: &lt;button style="height: 20px; background-color: blue;" /&gt;
 2097: </pre>
 2098:     <p>Don't use the <tt>style</tt> attribute too often, though,
 2099:     especially if you want to have more than one theme for your
 2100:     application. See the section <a href="ch04.html#77070">"Inline
 2101:     styles</a>" in <a href="ch04.html#37942">Chapter 4</a> for
 2102:     information about how this attribute can make your application
 2103:     less modular and, for some, a better way to apply style to your
 2104:     XUL documents.</p>
 2105:     <h3><a name="77139"></a> Persistence</h3>
 2106:     <p>The <tt>persist</tt> attribute preserves the 
 2107:     <!--INDEX persist attribute;attributes:XUL:persist attribute -->
 2108:     state and appearance of a widget on an attribute-by-attribute
 2109:     basis. This feature is useful for properties that change or are
 2110:     set by users during a session, such as window size and
 2111:     positioning, splitter state, and the visibility of certain
 2112:     elements.</p>
 2113: <pre>
 2114: &lt;splitter id="sidebar-splitter" collapse="before"
 2115: persist="state hidden" align="center" orient="vertical"&gt;
 2116: </pre>
 2117:     <p>When the state of the splitter changes-when a user handles
 2118:     the <tt>&lt;grippy&gt;</tt> and collapses the splitter, for
 2119:     example, and then quits-the <tt>persist</tt> attribute
 2120:     preserves the splitter state and its visibility for the next
 2121:     session.</p>
 2122:     <h3><a name="77140"></a> The debug Attribute</h3>
 2123:     <p>Many of XUL elements, particularly 
 2124:     <!--INDEX debug attribute;attributes:XUL:debug attribute -->
 2125:     container elements like box and toolbar, support the
 2126:     <tt>debug</tt> attribute as a useful tool for developers. If
 2127:     <tt>debug</tt> is set to <tt>true</tt>, extra borders are drawn
 2128:     around the element and all its children, with different color
 2129:     coding for each level. This setting can be used to check the
 2130:     orientation and the flexibility of elements. <tt>debug</tt>
 2131:     displays horizontal boxes with a blue border and vertical boxes
 2132:     with a red border, for example, making it easy to see subtle
 2133:     differences or layout bugs. The border above the element will
 2134:     be straight for nonflexible elements and 
 2135:     <!--INDEX ENDRANGE==XUL (XML-based User-interface Language):attributes;attributes:XUL -->
 2136:     grooved for flexible elements.</p>
 2137:     <h2><a name="77141"></a> Overlays</h2>
 2138:     <p>An overlay is a separate file in 
 2139:     <!--INDEX overlays;XUL (XML-based User-interface Language):overlays -->
 2140:     which additional XUL content can be defined and loaded at
 2141:     runtime. Overlays are often used to define things like menus
 2142:     that appear in different components or parts of the
 2143:     application.</p>
 2144:     <p>If you are creating a large application or a UI with many
 2145:     elements as a part of your design, the files can easily become
 2146:     large. The size in itself does not render it ineffective, but
 2147:     it does make the job of the developer a little difficult when
 2148:     tracking down and changing features. The best way to overcome
 2149:     this size problem is to use overlays. Another reason to use
 2150:     overlays is to extract information from a certain logical
 2151:     portion of the UI and contain it in a file of its own. This
 2152:     extraction and containment promotes modularization and
 2153:     reusability.</p>
 2154:     <h3><a name="77142"></a> How to Use Overlays</h3>
 2155:     <p>The following declaration is the principal method for
 2156:     including reusable content in a XUL window.</p>
 2157: <pre>
 2158: &lt;?xul-overlay href="chrome://global/content/globalOverlay.xul"?&gt;
 2159: </pre>
 2160:     <p>This declaration follows the same syntax as CSS processing
 2161:     instructions. Like other XML processing instructions, it uses a
 2162:     <tt>?</tt> at the beginning and end, just inside the braces.
 2163:     The <tt>href</tt> attribute points to the overlay and uses
 2164:     Mozilla's <i>chrome://</i> type URL.</p>
 2165:     <p>To insert content from an overlay, use 
 2166:     <!--INDEX overlays:inserting content from;content:overlay, inserting -->
 2167:     the same <tt>id</tt> of an element in the "base file" for a
 2168:     similar element in your overlay content, and the overlay will
 2169:     replace the base file at runtime (or be merged with it, as
 2170:     described later in this chapter in the <a href=
 2171:     "#77144">"Content Positioning</a>" section).</p>
 2172:     <p>When the base element is empty, it is replaced with the
 2173:     corresponding overlay element and any child subcontent. The
 2174:     following toolbar snippet shows a reference placed in a base
 2175:     file:</p>
 2176: <pre>
 2177: &lt;toolbar id="main-toolbar" /&gt;
 2178: </pre>
 2179:     <p>When an overlay is read with the content below, the previous
 2180:     line is replaced with that content:</p>
 2181: <pre>
 2182: &lt;toolbar id="main-menubar" persist="collapsed"&gt;
 2183: &lt;toolbarbutton id="new-button" label="New" observes="cmd_new"/&gt;
 2184: &lt;toolbarbutton id="open-button" label="Open" observes="cmd_open"/&gt;
 2185: &lt;toolbarbutton id="save-button" label="Save" observes="cmd_save"/&gt;
 2186: &lt;/toolbar&gt;
 2187: </pre>
 2188:     <p>Overlay files are XUL files with a <i>.xul</i> extension.
 2189:     The content within that file has to be contained in an
 2190:     <tt>&lt;overlay&gt;</tt> element, which is the root of the
 2191:     document. For example, the toolbar is a first level child of
 2192:     the root.</p>
 2193: <pre>
 2194: &lt;overlay id="xflyOverlay"&gt;
 2195: &lt;toolbar id="main-toolbar" /&gt;
 2196: &lt;!-- more overlay content --&gt;
 2197: &lt;/overlay&gt;
 2198: </pre>
 2199:     <blockquote>
 2200:       <div class="c11">
 2201:         WARNING
 2202:       </div>
 2203:       <p>Styles from overlays override styles from base XUL files,
 2204:       so be careful not to load master styles in an overlay.</p>
 2205:     </blockquote>
 2206:     <h4><a name="77143"></a> Dynamic loading</h4>
 2207:     <p>The usual method for loading 
 2208:     <!--INDEX loading:overlays, dynamic loading;overlays:loading, dynamic loading;dynamic loading, overlays -->
 2209:     overlays, as outlined previously, is to include the overlay
 2210:     processing instruction in your XUL file. The dynamic loading of
 2211:     content is more subtle, but just as effective. Mozilla has a
 2212:     registry of overlays, in the form of an RDF datasource that
 2213:     lives in the <i>chrome</i> directory. These overlays live in
 2214:     the tree in a directory called <i>overlayinfo</i> under the
 2215:     <i>chrome</i> root.<a name="b317"></a><a href="#317">[*]</a>
 2216:     When a new package or component is registered, the overlays
 2217:     that come with it are loaded automatically.</p>
 2218:     <p>Dynamic overlays are 
 2219:     <!--INDEX dynamic overlays;overlays:dynamic overlays -->
 2220:     commonly used to extend certain parts of the Mozilla
 2221:     application itself when new packages are installed that need
 2222:     access points, as do new language packages and themes, for
 2223:     instance. Certain menus in the UI, for example, are open for
 2224:     third-party authors to add items. Adding the name of your
 2225:     package to Mozilla's Tasks menu, for example, provides a
 2226:     convenient launching point and is handled with dynamic
 2227:     overlays. <a href="ch06.html#15291">Chapter 6</a> provides more
 2228:     information on this topic, in the section <a href=
 2229:     "ch06.html#77076">"Adding the xFly application to the Mozilla
 2230:     Tools menu</a>."</p>
 2231:     <h3><a name="77144"></a> Content Positioning</h3>
 2232:     <p>Content positioning is the order 
 2233:     <!--INDEX content:positioning;position:content positioning -->
 2234:     in which <!--INDEX widgets:position;position:widgets -->
 2235:     widgets appear in the UI. Usually content is laid out in the
 2236:     order elements are defined in the XUL file. However, there are
 2237:     a couple of ways to override this ordering in XUL.</p>
 2238:     <p>Continuing with the example of the overlaid toolbar in the
 2239:     previous section, it is possible for both the base definition
 2240:     and the overlaid definition to have children. In this instance,
 2241:     the content is merged, with the original content appearing
 2242:     before the overlaid content by default:</p>
 2243: <pre>
 2244: &lt;toolbar id="main-toolbar"&gt;
 2245: &lt;toolbarbutton id="print-button" label="Print" observes="cmd_print"/&gt;
 2246: &lt;/toolbar&gt;
 2247: </pre>
 2248:     <p>If the <tt>toolbarbutton</tt> above is in the base XUL, then
 2249:     the ordering of the buttons would be Print, New, Open, and
 2250:     Save. It is possible to change this ordering by using
 2251:     <tt>insertbefore</tt>, however, as shown in <a href=
 2252:     "#77074">Example 3-21</a>. Example 3-21<a name="77074"></a>
 2253:     <i>Positioning attributes</i></p>
 2254: <pre>
 2255:  &lt;toolbar id="main-toolbar" persist="collapsed"&gt;
 2256:    &lt;toolbarbutton id="new-button" label="New" observes="cmd_new"
 2257:        &lt;/td&gt;insertbefore="print-button"/&gt;
 2258:    &lt;toolbarbutton id="open-button" label="Open" observes="cmd_open"/&gt;
 2259:    &lt;/td&gt;&lt;toolbarbutton id="save-button" label="Save" observes="cmd_save"
 2260:        position="2"&lt;/td&gt;/&gt;
 2261:  &lt;/toolbar&gt;
 2262: </pre>
 2263:     <p>The <tt>insertbefore</tt> attribute is 
 2264:     <!--INDEX insertbefore attribute;attributes:XUL:insertbefore -->
 2265:     placed on one of the child items to signify that it should go
 2266:     before a sibling in the base file. <tt>insertbefore</tt> takes
 2267:     an element <tt>id</tt> as a value and says, in this case, that
 2268:     the New button should go before Print. Conversely, you can move
 2269:     an item after it by using the <tt>insertafter</tt> attribute.
 2270:     For more precision, you can use <tt>position</tt> to position
 2271:     an item absolutely in the sequence of siblings. In <a href=
 2272:     "#77074">Example 3-21</a>, the position attribute puts the Save
 2273:     button in the second position, so the final order is New, Save,
 2274:     Print, and Open.</p>
 2275:     <h2><a name="77145"></a> The Extras</h2>
 2276:     <p>Certain lesser-known elements and features are indispensable
 2277:     to the savvy XUL developer and can add that something extra to
 2278:     Mozilla applications, as shown here.</p>
 2279:     <h3><a name="77146"></a> Tooltips</h3>
 2280:     <p>Tooltips are visual pop ups <!--INDEX tooltips --> that
 2281:     appear when you place the cursor over a piece of the UI. The
 2282:     hovering behavior of a tooltip is useful for many things,
 2283:     including abbreviated help and the display of values that are
 2284:     otherwise obscured in the UI. In the Mozilla application, the
 2285:     most common places where they are used are on toolbar buttons
 2286:     and splitter grippies that divide panels in the window.</p>
 2287:     <p>To invoke a tooltip, add a <tt>
 2288:     <!--INDEX tooltiptext attribute;attributes:XUL:tooltiptext -->
 2289:     tooltiptext</tt> attribute to the widget that needs it:</p>
 2290: <pre>
 2291: &lt;button id="printButton" label="Print" tooltiptext="Print this page" /&gt;
 2292: </pre>
 2293:     <p>Defining this attribute is enough to ensure that the generic
 2294:     Mozilla tip box appears with the specified text when you place
 2295:     the cursor over the element.</p>
 2296:     <p>Tooltips are actually implemented 
 2297:     <!--INDEX bindings:XBL:tooltips and;XBL bindings, tooltips and -->
 2298:     as an XBL binding. Underneath, a tooltip is essentially a pop
 2299:     up with a <tt>description</tt> element within that holds text.
 2300:     You can also create your own tooltips.</p>
 2301:     <p>To create your own content and customized appearance for a
 2302:     tooltip:</p>
 2303:     <ol>
 2304:       <li>Create the content.</li>
 2305:       <li>Attach it to the pop-up element you will be using.</li>
 2306:       <li>Give the pop up a unique ID.</li>
 2307:     </ol>
 2308:     <p>The following snippet shows the kind of tooltip you can
 2309:     create and then reuse in your application code:</p>
 2310: <pre>
 2311: &lt;popupset id="aTooltipSet"&gt;
 2312: &lt;popup id="myTooltip"
 2313: class="tooltip"
 2314: onpopupshowing="return FillInTooltip(document.tooltipNode);" &gt;
 2315: &lt;description id="TOOLTIP-tooltipText"
 2316: class="my-tooltip-label" flex="1"/&gt;
 2317: &lt;/popup&gt;
 2318: &lt;/popupset&gt;
 2319: </pre>
 2320:     <p>Use your newly created widget by adding its <tt>id</tt>
 2321:     value to the <tt>tooltip</tt> attribute to the UI element that
 2322:     wants it:</p>
 2323: <pre>
 2324: &lt;treeitem id="FlyDescription" tooltip="myTooltip" tooltiptext="" /&gt;
 2325: </pre>
 2326:     <p>Note that this example assumes that the actual text will be
 2327:     applied dynamically to the <tt>tooltiptext</tt> attribute,
 2328:     which is initially empty. This is useful in many situations-for
 2329:     example, in tree cells that contain transient values.</p>
 2330:     <p>The advantage of creating your own tooltip is that you can
 2331:     apply your own styles to it, giving the text and background
 2332:     whatever font and colors you want. A variation of the
 2333:     <tt>tooltip</tt> attribute named <tt>contenttooltip</tt> is
 2334:     used for content panels.</p>
 2335:     <h3><a name="77147"></a> Progress Meter</h3>
 2336:     <p>Sometimes in your application you need 
 2337:     <!--INDEX progress meter;status bar/progress meter;downloading:progress meter;loading:progress meter -->
 2338:     to give the user feedback during a long operation. The classic
 2339:     example in the browser is the status bar that shows a visual
 2340:     representation of the time remaining when you load a big web
 2341:     page or download a file.</p>
 2342:     <p>Of these two activities, loading pages and downloading
 2343:     files, downloading uses the determined mode, meaning that the
 2344:     time to complete the operation is calculable. In this case, an
 2345:     algorithm is written based on the file size and the bandwidth
 2346:     values to formulate the time remaining. The second of three
 2347:     modes of a progress meter is the undetermined mode, in which
 2348:     the time for the operation to complete is unknown. Commonly
 2349:     called the "barber pole," the progress meter shows a spinning
 2350:     pole when in undetermined mode. The third mode is normal, which
 2351:     shows an empty bar. You can get/set the mode by using the
 2352:     <tt>mode</tt> attribute.</p>
 2353:     <p>Here is the XUL for a sample progress meter:</p>
 2354: <pre>
 2355: &lt;progressmeter id="progressTask" mode="normal" value="0" onclick="alert(`Task is in progress')"/&gt;
 2356: </pre>
 2357:     <p>Here is the accompanying script for activating the progress
 2358:     meter:</p>
 2359: <pre>
 2360: var meter = document.getElementById('progressTask');
 2361: meter.setAttribute('mode', 'undetermined');
 2362: sometask( );
 2363: meter.setAttribute('mode', 'determined');
 2364: meter.setAttribute('value', '100%');
 2365: </pre>
 2366:     <p>The mode is changed to undetermined just before carrying out
 2367:     the task, and is represented 
 2368:     <!--INDEX sometask( ) function, JavaScript;JavaScript:functions:sometask( );functions:JavaScript:sometask( ) -->
 2369:     by the function <tt>sometask( )</tt>. The JavaScript code is
 2370:     synchronous, so it will not hand back control until the
 2371:     operation is complete.</p>
 2372:     <h3><a name="77148"></a> Links</h3>
 2373:     <p>Mozilla is 
 2374:     <!--INDEX links;XUL (XML-based User-interface Language):links -->
 2375:     a web application, and many programs and operating systems
 2376:     (e.g., Windows XP) are moving toward full web integration.
 2377:     Linking is fundamental in application programming, so Mozilla
 2378:     provides a couple of ways to do it in your XUL document.</p>
 2379:     <h4><a name="77149"></a> Use of the &lt;html:a&gt; element</h4>
 2380:     <p>To use HTML in your XUL file, you must 
 2381:     <!--INDEX html\:a element --> define 
 2382:     <!--INDEX links:html\:a element and --> the 
 2383:     <!--INDEX XUL files:HTML in;HTML (Hypertext Markup Language):XUL files -->
 2384:     HTML namespace at the top of your document:</p>
 2385: <pre>
 2386: &lt;window id="MyOverlay"
 2387: xmlns:html="<a href=
 2388: "http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
 2389: xmlns="<a href=
 2390: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
 2391: </pre>
 2392:     <p>Then you can use the HTML elements just as you would in a
 2393:     regular web page, but with the addition of the namespace you
 2394:     declared:</p>
 2395: <pre>
 2396: &lt;vbox&gt;
 2397: &lt;html:a href="myOverlay.html"&gt;Go to Help page&lt;/html:a&gt;
 2398: &lt;/vbox&gt;
 2399: </pre>
 2400:     <p>When you use a page with code in your application, the user
 2401:     can click the link and open a Mozilla browser to the requested
 2402:     page or item.</p>
 2403:     <h4><a name="77150"></a> Simple XLinks</h4>
 2404:     <p>You <!--INDEX XLinks;links:XLinks --> can also tap into the
 2405:     more sophisticated XML capabilities in Mozilla by trying a
 2406:     simple XLink. Again, the correct namespace is required:</p>
 2407: <pre>
 2408: &lt;window xmlns:xlink=<a href=
 2409: "http://www.w3.org/1999/xlink">http://www.w3.org/1999/xlink</a> ...&gt;
 2410: </pre>
 2411:     <p>Then you define your link as follows:</p>
 2412: <pre>
 2413: &lt;xlink:link xlink:type="simple" xlink:href="c.xml"&gt;c.xml&lt;/xlink:link&gt;
 2414: </pre>
 2415:     <p>The element here is <tt>link</tt>, the <tt>type</tt> is
 2416:     simple, and the locator is <tt>href</tt>.</p>
 2417:     <h2><a name="77151"></a> Building the Application Shell</h2>
 2418:     <p>Now that the 
 2419:     <!--INDEX application shell, building;shells:application shell, building -->
 2420:     main XUL widgets and some crucial concepts like the box model
 2421:     have been described, you can bring things together and create
 2422:     an <i>application shell</i>, a user interface that isn't (yet)
 2423:     hooked up to application code, but which can be re-used for
 2424:     different applications.</p>
 2425:     <p>The XUL in <a href="#77076">Example 3-22</a> extends 
 2426:     <!--INDEX xFly:shell;shells:xFly application --> the 
 2427:     <!--INDEX APIs (Application 
 2428:     Programming Interfaces) Component Manager and:(see also xFly) -->
 2429:     xFly application work you've already done in <a href=
 2430:     "ch02.html#77048">Chapter 2</a>. It defines the interface for a
 2431:     viewer that will let you browse the examples in this book,
 2432:     giving xFly a measure of introspection. Examine the code
 2433:     closely in <a href="#77076">Example 3-22</a> to give yourself a
 2434:     feel for how the elements in the UI interact with each other to
 2435:     form something that is greater than the sum of its parts. Look
 2436:     particularly at how box elements are used such 
 2437:     <!--INDEX boxes:box elements --> as <tt>vbox</tt>,
 2438:     <tt>hbox</tt>, <tt>tabbox</tt>, and <tt>statusbar</tt>. Example
 2439:     3-22<a name="77076"></a> <i>xFly application main
 2440:     workspace</i></p>
 2441: <pre>
 2442:  &lt;?xml version="1.0"?&gt;
 2443:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
 2444:  &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css"?&gt;
 2445:  &lt;?xul-overlay href="chrome://xfly/content/xflyoverlay.xul"?&gt;
 2446:  &lt;!DOCTYPE window SYSTEM "chrome://xfly/locale/xfly.dtd"&gt;
 2447:  &lt;window title="&amp;window.title;"
 2448:    xmlns:html="<a href=
 2449: "http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
 2450:    xmlns="<a href=
 2451: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
 2452:    type="xfly:main"
 2453:    width="800"
 2454:    height="600"
 2455:    onload="onLoad( )"&gt;
 2456:  &lt;script type="application/x-javascript" src="chrome://xfly/content/xfly.js" /&gt;
 2457:  &lt;stringbundle id="bundle_xfly" src="chrome://xfly/locale/xfly.properties"/&gt;
 2458:  &lt;toolbox&gt;
 2459:    &lt;menubar id="appbar"&gt;
 2460:      &lt;menu label="xFly"&gt;
 2461:        &lt;menupopup&gt;
 2462:          &lt;menuitem label="Close" oncommand="exitxFly( )"/&gt;
 2463:        &lt;/menupopup&gt;
 2464:      &lt;/menu&gt;
 2465:      &lt;menu label="Examples"&gt;
 2466:        &lt;menupopup&gt;
 2467:          &lt;!-- items to go here --&gt;
 2468:        &lt;/menupopup&gt;
 2469:      &lt;/menu&gt;
 2470:      &lt;menu label="Help"&gt;
 2471:        &lt;menupopup&gt;
 2472:          &lt;menuitem label="About" oncommand="doAbout( )"/&gt;
 2473:        &lt;/menupopup&gt;
 2474:      &lt;/menu&gt;
 2475:    &lt;/menubar&gt;
 2476:  &lt;/toolbox&gt;
 2477:  &lt;hbox flex="1"&gt;
 2478:    &lt;vbox id="left-frame"&gt;
 2479:      &lt;tree id="example-tree" /&gt;
 2480:      &lt;hbox align="start"&gt;
 2481:        &lt;image src="chrome://xfly/skin/images/logo5.gif" /&gt;
 2482:      &lt;/hbox&gt;
 2483:    &lt;/vbox&gt;
 2484:    &lt;splitter collapse="before" resizeafter="grow" persist="state"&gt;
 2485:      &lt;grippy /&gt;
 2486:    &lt;/splitter&gt;
 2487:    &lt;tabbox id="raven-main-tabcontent" flex="1" orient="vertical"&gt;
 2488:      &lt;tabs orient="horizontal"&gt;
 2489:        &lt;tab id="tab-view" label="View Example"/&gt;
 2490:        &lt;tab id="tab-source" label="View Example Source"/&gt;
 2491:      &lt;/tabs&gt;
 2492:      &lt;tabpanels flex="1"&gt;
 2493:        &lt;iframe id="right-frame" name="right-frame"
 2494:        flex="3" src="chrome://xfly/content/examples/2-1.xul"/&gt;
 2495:        &lt;iframe id="right-frame-source" name="right-frame-source"
 2496:            flex="3" src="view-source:chrome://xfly/content/examples/2-1.xul"/&gt;
 2497:      &lt;/tabpanels&gt;
 2498:    &lt;/tabbox&gt;
 2499:  &lt;/hbox&gt;
 2500:  &lt;statusbar id="ch3-bar" persist="collapsed"&gt;
 2501:    &lt;statusbarpanel class="statusbarpanel-iconic" id="book-icon"/&gt;
 2502:    &lt;statusbarpanel id="status-text" label="Thanks for reading the book!"
 2503:        flex="4" crop="right"/&gt;
 2504:    &lt;statusbarpanel class="statusbarpanel-iconic" id="example-status" flex="1"/&gt;
 2505:  &lt;/statusbar&gt;
 2506:  &lt;/window&gt;
 2507: </pre>
 2508:     <p>The main application windows consists of a menu bar, two
 2509:     frames, and a status bar. The menus provide access to
 2510:     application-level functions like closing the window, or
 2511:     launching an "About" window. At the bottom of the window, the
 2512:     status bar displays the book icon and some status messages for
 2513:     the application. Between the menu bar and the status bar are
 2514:     the two main panels: a 
 2515:     <!--INDEX vertical boxes;vbox element, XUL --> vertical box
 2516:     (<tt>&lt;vbox&gt;</tt>) on the left that contains a tree for
 2517:     choosing examples with the xFly logo beneath it, and an <tt>
 2518:     <!--INDEX iframe element, XUL --> &lt;iframe&gt;</tt> into
 2519:     which the examples are loaded on the right. There are two tabs
 2520:     in the example pane, one for showing the example rendered and
 2521:     one for looking at the source.</p>
 2522:     <div class="c10">
 2523:       <img src="foo.gif">
 2524:     </div>
 2525:     Figure 3-12<a name="77024"></a> <i>xFly example viewing
 2526:     application</i> 
 2527:     <p>The code in <a href="#77076">Example 3-22</a> is not the
 2528:     final code for xFly, but it does show some important widgets
 2529:     used for the main layout of the application. But the layout in
 2530:     <a href="#77076">Example 3-22</a> (in which a
 2531:     <tt>&lt;toolbox&gt;</tt> holds the menus, a
 2532:     <tt>&lt;statusbar&gt;</tt> displays messages from the
 2533:     application, and the box model is used to layout the
 2534:     application display) is a very useful template for XUL
 2535:     applications.</p>
 2536:     <p>What remains to define is the tree structure that actually
 2537:     holds the various examples. In <a href="#77076">Example
 2538:     3-22</a>, the <tt>&lt;tree&gt;</tt> has an ID attribute that is
 2539:     meant to pick up content defined in an overlay. <a href=
 2540:     "#77078">Example 3-23</a> shows what such an overlay would look
 2541:     like, but if you'd rather, you can take the content of the
 2542:     <tt>&lt;tree id="example-tree</tt>"&gt; element in this
 2543:     example, define it as direct content of the
 2544:     <tt>&lt;tree&gt;</tt> in <a href="#77076">Example 3-22</a>, and
 2545:     end up with the application shell shown in <a href=
 2546:     "#77024">Figure 3-12</a>. See the section <a href=
 2547:     "#77141">"Overlays</a>" earlier in this chapter for more
 2548:     information about how to add content to your XUL using overlay
 2549:     files. Example 3-23<a name="77078"></a> <i>Example tree in the
 2550:     xFly application</i></p>
 2551: <pre>
 2552:  &lt;?xml version="1.0"?&gt;
 2553:  &lt;overlay id="xflyOverlay"
 2554:      xmlns:html="<a href=
 2555: "http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
 2556:      xmlns="<a href=
 2557: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
 2558:  &lt;tree id="example-tree" onselect="onExampleSelect( );" seltype="single"
 2559:      hidecolumnpicker="false"
 2560:      enableColumnDrag="true" flex="1"&gt;
 2561:    &lt;treecols&gt;
 2562:      &lt;treecol id="type" label="Title" flex="1" primary="true"
 2563:          persist="width ordinal hidden"/&gt;
 2564:      &lt;splitter class="tree-splitter"/&gt;
 2565:      &lt;treecol id="method" label="Example" flex="1"
 2566:          persist="width ordinal hidden"/&gt;
 2567:    &lt;/treecols&gt;
 2568:    &lt;treechildren&gt;
 2569:      &lt;treeitem container="true" open="true"&gt;
 2570:        &lt;treerow&gt;
 2571:          &lt;treecell label="Chapter 2"/&gt;
 2572:        &lt;/treerow&gt;
 2573:        &lt;treechildren&gt;  &lt;!-- Second level row --&gt;
 2574:          &lt;treeitem&gt;
 2575:            &lt;treerow&gt;
 2576:              &lt;treecell label="Hello xFly"
 2577:                  url="chrome://xfly/content/examples/2-1.xul"/&gt;
 2578:              &lt;treecell label="2-1"/&gt;
 2579:            &lt;/treerow&gt;
 2580:          &lt;/treeitem&gt;
 2581:        &lt;/treechildren&gt;
 2582:      &lt;/treeitem&gt;
 2583:      &lt;treeitem container="true" open="true"&gt;
 2584:        &lt;treerow&gt;
 2585:          &lt;treecell label="Chapter 3"/&gt;
 2586:        &lt;/treerow&gt;
 2587:        &lt;treechildren&gt;  &lt;!-- Second level row --&gt;
 2588:          &lt;treeitem&gt;
 2589:            &lt;treerow&gt;
 2590:              &lt;treecell label="Menu Bar"
 2591:                  url="chrome://xfly/content/examples/3-5.xul"/&gt;
 2592:              &lt;treecell label="3-5"/&gt;
 2593:            &lt;/treerow&gt;
 2594:          &lt;/treeitem&gt;
 2595:          &lt;treeitem&gt;
 2596:            &lt;treerow&gt;
 2597:              &lt;treecell label="Listbox"
 2598:                  url="chrome://xfly/content/examples/3-9.xul"/&gt;
 2599:              &lt;treecell label="3-9"/&gt;
 2600:            &lt;/treerow&gt;
 2601:          &lt;/treeitem&gt;
 2602:          &lt;treeitem&gt;
 2603:            &lt;treerow&gt;
 2604:              &lt;treecell label="Grid" url="chrome://xfly/content/examples/3-12.xul"/&gt;
 2605:              &lt;treecell label="3-12"/&gt;
 2606:            &lt;/treerow&gt;
 2607:          &lt;/treeitem&gt;
 2608:        &lt;/treechildren&gt;
 2609:      &lt;/treeitem&gt;
 2610:    &lt;/treechildren&gt;
 2611:  &lt;/tree&gt;
 2612:  &lt;/overlay&gt;
 2613: </pre>
 2614:     <hr>
 2615:     <hr>
 2616:     <a name="314"></a><a href="#b314">[Back]</a> <a name=
 2617:     "77080"></a> Free-floating because their location in the
 2618:     interface is not determined by their position in the XUL
 2619:     markup, as it usually is for items like menus and buttons. 
 2620:     <hr>
 2621:     <a name="315"></a><a href="#b315">[Back]</a> <a name=
 2622:     "77081"></a> Unfortunately, button skins and the <tt>class</tt>
 2623:     attributes that associate them with button widgets change too
 2624:     often to list here. Some classes like "toolbar-primary" tend to
 2625:     be reused often for buttons in Mozilla, but the best way to
 2626:     find and use classes is to consult the source code itself or to
 2627:     create your own. 
 2628:     <hr>
 2629:     <a name="316"></a><a href="#b316">[Back]</a> <a name=
 2630:     "77082"></a> Note that these examples are distinct from
 2631:     embedding the Gecko layout engine in your generic application.
 2632:     A separate toolkit and a set of APIs is available for doing
 2633:     this. 
 2634:     <hr>
 2635:     <a name="317"></a><a href="#b317">[Back]</a> <a name=
 2636:     "77083"></a> Chapter 9 has more information on RDF datasources.
 2637:     To delve deeper into the chrome layout and install issues, see
 2638:     Chapter 6. 
 2639:     <hr>
 2640:     <br>
 2641:     <br>
 2642:     File a <a href=
 2643:     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
 2644:     for chapter 3. 
 2645:     <?php $hide_text_control=1; $post_to_list=NO; $author='reviewers@mozdev.org'; // require(NOTES); ?>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>