File:  [mozdev] / books / www / chapters / ch02.html
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Mon Sep 23 15:23:31 2002 UTC (17 years, 9 months ago) by david
Branches: MAIN
CVS tags: HEAD
updating chapter links

    1: <HTML>
    2: <HEAD><TITLE>Chapter 2</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 2</H2>
    3: <H1><A NAME="77048"></A> Getting Started</H1>
    4: <P>To help you start creating applications as quickly as possible, this chapter presents two "Hello World" examples that demonstrate the beginning stages of Mozilla application development.
    5: <P>The first example is a simple XUL file that is loaded into the browser window. This example is then expanded on by adding additional features to the XUL file, such as imported stylesheets and JavaScript functions. The second "Hello World" example shows how to turn files like these into packages, which are the modular, bundled sets of files that fit together to make Mozilla applications or new modules for the Mozilla browser.
    6: <P>These examples provide a context for discussing the development of Mozilla applications. The first example focuses on creating and editing the basic file types, and the second focuses on the organization and distribution of applications on the Mozilla platform.
    7: <H2><A NAME="77049"></A> Simple XUL Example</H2>
    8: <P>Like all good "Hello World" applications,  <!--INDEX Hello World XUL example -->  <!--INDEX XUL (XML-based User-interface Language):Hello World example --> <A HREF="#77016">Example 2-1</A> shows one of the simplest possible examples of XUL. Although it is small, it demonstrates some important aspects of XUL programming, including the use of event handlers to add behavior and the use of a <TT>box</TT> to lay out elements properly within the window. This example also provides a context for discussing more general features of the language, such as the file format, the namespace, and some XUL programming conventions.
   10: <P><I>Example 2-1: <A NAME="77016"></A></I>
   11: <I>Hello xFly</I>
   12: <PRE> &lt;?xml version="1.0"?&gt;
   13:  &lt;!-- Sample XUL file --&gt;
   14:  &lt;window xmlns="<A HREF=""></A>"&gt;
   15:  &lt;box align="center"&gt;
   16:    &lt;button label="hello xFly" onclick="alert('Hello World');" /&gt;
   17:  &lt;/box&gt;
   18:  &lt;/window&gt;</PRE>
   20: <P>Use your text editor to save the code in <A HREF="#77016">Example 2-1</A> in a file called <I>hello.xul</I> and then load the file in Mozilla (you can do this by using File &gt; Open File from the browser window and browsing to where you saved the file). You should see a button in the upper-left corner of the browser window that brings up an alert box when clicked. <A HREF="#77002">Figure 2-1</A> shows an example of the alert pop-up window that appears.
   21: <P><CENTER><IMG SRC="foo.gif"></CENTER>
   22: <P><I>Figure 2-1: <A NAME="77002"></A></I>
   23: <I>The first Hello xFly example</I>
   25: <P>The next few sections describe this sample file in more detail. The covered topics include the file itself, the syntax of the markup, XUL namespaces, and the basic layout of a XUL file.
   26: <BLOCKQUOTE><HR><B>The xFly Examples</B>
   27: <P>The best way to understand the possible uses of the Mozilla framework is to look more closely at a number of various existing applications. This book highlights several Mozilla development projects, such as ChatZilla and JSLib, as examples of how some people have already started using Mozilla's XPFE technologies.
   28: <P>Along with these applications, you'll note the use of the name "xFly" in many examples in this chapter and elsewhere in this book. The xFly 
   29: examples are used throughout <A HREF="#77048">Chapter 2</A> to <A HREF="ch06.html#77063">Chapter 6</A> to show how to create and package a simple Mozilla application.
   30: <P>This simple application is useful because it provides a place to start exploring the new information that you will learn about in this book. As you read more about XUL, CSS, JavaScript, and the other parts of Mozilla's development framework, you can create and edit the xFly files to see how these technologies work in practice.<HR></BLOCKQUOTE>
   32: <H2><A NAME="77050"></A> Basic XUL Concepts</H2>
   33: <P>You have already seen many of XUL's basic features at work. When you load the example in the previous example, the browser identifies it as a XUL file, parses the data, creates a new window and draws the button widget, and executes the function you've defined when the button is clicked.
   34: <P>These activities are part of the basic and often transparent interaction between your application files and Mozilla. However, the format of your XUL files, their syntax and namespace, the XUL layout, and the windowing system are all basic to successful XUL programming.
   35: <H3><A NAME="77051"></A> The XUL File Format</H3>
   36: <P>A XUL file is a simple text file  <!--INDEX XUL files -->  <!--INDEX files:XUL files --> that contains proper XML syntax and has a <I>.xul</I> file extension. Mozilla expects to draw UI widgets when it encounters a file with a <I>.xul</I> extension or when it encounters the XUL namespace in other markup files that it recognizes, including HTML and XML.
   37: <P>The MIME type registered  <!--INDEX MIME type, XUL files -->  <!--INDEX XUL files:MIME type registered --> for XUL files is 
   38: <I>application/vnd.mozilla.xul+xml</I>. When editing and using XUL files locally, you shouldn't need to worry about setting this on your computer; however, sometimes you may need to set the MIME type, such as when you host XUL files on a server. <A HREF="ch12.html#51383">Chapter 12</A> provides additional information about how you can set the correct file type for your system.
   39: <H3><A NAME="77052"></A> Conventions</H3>
   40: <P>XUL has to follow certain  <!--INDEX XUL (XML-based User-interface Language):conventions -->  <!--INDEX conventions, XUL --> conventions (as does XHTML or any other XML-based file) in order to be valid. Mozilla generates an error when it encounters an invalid XUL file.
   41: <P>The first thing required in a XUL document is the XML declaration.
   42: <PRE>&lt;?xml version="1.0"?&gt;</PRE>
   43: <P>Any comments used to introduce  <!--INDEX comments:XUL -->  <!--INDEX XUL (XML-based User-interface Language):comments --> your file can begin on the line after the declaration. Comments in XUL follow the same format used in HTML and XML, delimited by <TT>&lt;!--</TT> and <TT>--&gt;</TT>.
   44: <P>All tag sets must be closed. Empty  <!--INDEX tags, XUL -->  <!--INDEX XUL (XML-based User-interface Language):tags --> tags are allowed for some elements, such as the <TT>&lt;label&gt;</TT> element, that are used without nested elements or content. Note that a trailing slash at the end of the tag is required to denote an empty element.
   45: <PRE>&lt;label value="Getting Started" /&gt;</PRE>
   46: <P>Another thing to remember is  <!--INDEX case-sensitivity, XUL -->  <!--INDEX XUL (XML-based User-interface Language):case-sensitivity --> that XUL is case-sensitive. Closing a XUL <TT>&lt;window&gt;</TT> tag with <TT>&lt;/Window&gt;</TT> renders it invalid.
   47: <P>These conventions ensure that the rendering engine can parse the XUL file successfully and display the elements defined there. Mozilla does not validate XML files, such as XUL, and it does not resolve externally parsed entities, but it does check for document well-formedness.
   48: <P>Following the XML specification, Mozilla ignores well-formed tags that it does not recognize, which can give your applications extra flexibility, particularly as you begin to use technologies such as XBL. But it can also make debugging a little more difficult, as when you create an element named <TT>&lt;botton&gt;</TT> and don't see why your XUL button doesn't have the typical borders or three-dimensional style.
   49: <P>A good practice to follow when creating XUL files is to use comments, copious whitespace, indentations (but not tabbed indentations where you can avoid them), and XUL widgets you are familiar with.
   50: <H3><A NAME="77053"></A> The XUL Namespace</H3>
   51: <P>Like other markup  <!--INDEX namespaces:XUL -->  <!--INDEX XUL (XML-based User-interface Language):namespace --> vocabularies, XUL uses a namespace declaration to define the particular elements that may be included in a valid file. <A HREF="#77018">Example 2-2</A> shows a sample of the required namespace declaration. The namespace is an attribute of the root <TT>window</TT> element. The lack of any suffix on the XML namespace declaration (i.e., <TT>xmlns:xul</TT>) indicates that XUL is the default namespace for this file.
   53: <P><I>Example 2-2: <A NAME="77018"></A></I>
   54: <I>The XUL namespace declaration</I>
   55: <PRE> &lt;window
   56:    xmlns="<A HREF=""></A>" /&gt;
   57:    &lt;description&gt;Illustrating the XUL namespace&lt;/description&gt;
   58:  &lt;/window&gt;</PRE>
   60: <P>If you want to include XUL content in documents that use other types of markup, you need to declare more than one namespace. Common namespace declarations for getting other language elements into your code include HTML and RDF, but you can invent your own as well. If you wanted to put the button from <A HREF="#77016">Example 2-1</A> into a vanilla XML file, for example, you could place it into an XML document by using the <TT>xmlns:xul</TT> attribute, as shown in <A HREF="#77020">Example 2-3</A>.
   62: <P><I>Example 2-3: <A NAME="77020"></A></I>
   63: <I>Mixed namespaces in an XML document</I>
   64: <PRE> &lt;flies:flies
   65:    xmlns:flies="<A HREF=""></A>#"
   66:    xmlns:html="<A HREF=""></A>"
   67:    xmlns:xul="<A HREF=""></A>"&gt;
   68:    &lt;flies:wings&gt;
   69:      &lt;xul:box align="center"&gt;
   70:        &lt;xul:button label="hello xFly" onclick="alert('hello.');" /&gt;
   71:      &lt;/xul:box&gt;
   72:      &lt;html:img src="wings.jpg" /&gt;
   73:    &lt;/flies:wings&gt;
   74:  &lt;/flies:flies&gt;</PRE>
   76: <P>This file has three types of content: XUL, HTML, and customized markup called <TT>flies</TT>. When you use mixed namespaces, you have to prefix the XUL elements with <TT>xul</TT>: to distinguish them from markup in other namespaces, as with the <TT>xul:box</TT> and <TT>xul:button</TT> shown in <A HREF="#77020">Example 2-3</A>.
   77: <H3><A NAME="77054"></A> Basic XUL Layout</H3>
   78: <P><A HREF="#77016">Example 2-1</A> features  <!--INDEX XUL (XML-based User-interface Language):elements --> some very common XUL elements. In this section, each element is dissected to show what it does and how it interacts with other elements. The <TT>&lt;window&gt;</TT> element is the root of individual primary XUL documents (in contrast to dialogs that pop up from  <!--INDEX dialog element, XUL --> windows, which can use <TT>&lt;dialog&gt;</TT> as the root, and XUL documents loaded within other XUL containers, which can use <TT>&lt;page&gt;</TT>).
   79: <P>As in HTML, the root element defines the document into which all elements are drawn, but in XUL, that document is a piece of an application interface and not a web page. We'll have more to say about the window and some of its features in the second example.
   80: <P>A <TT>&lt;box&gt;</TT> element that  <!--INDEX box element, XUL -->  <!--INDEX button element, XUL --> contains a <TT>&lt;button&gt;</TT> is inside the window in <A HREF="#77016">Example 2-1</A>. Although you can use attributes on the window element to lay out and position window children, it's never a bad idea to use the <TT>&lt;box&gt;</TT> as a container, particularly when you add new layout to your document, such as rows of buttons, grids, tabs, or other elements that need to be arranged precisely within the space of the window. The <TT>box</TT> is the basic element for layout in XUL.
   81: <P>The <TT>align</TT> attribute on the box specifies that the children do not stretch and center themselves in the middle of the available space. If the box was omitted and there were multiple children of the root window, they would be laid out vertically by default, one under the other. This setting can be overridden by adding the <TT>orient</TT> attribute to <TT>&lt;window&gt;</TT> and giving it a value of "horizontal."
   82: <H3><A NAME="77055"></A> Using XUL Windows</H3>
   83: <P>The foundation of an XPFE application is  <!--INDEX XUL (XML-based User-interface Language):windows -->  <!--INDEX windows:XUL --> a window. Each XUL document has to have at least one XUL <TT>&lt;window&gt;</TT> element, and it must be the root of the document-the surrounding, outermost element in the XML document, set apart from the XML declaration itself and other processing "preambles." A basic window with no content looks like this:
   84: <PRE>&lt;?xml version="1.0"?&gt;
   85: &lt;!DOCTYPE window&gt;
   86: &lt;window
   87: xmlns:html="<A HREF=""></A>"
   88: xmlns="<A HREF=""></A>"&gt;
   89: &lt;/window&gt;</PRE>
   90: <P>Commonly, an application has more than one window, with a number of dialogs and secondary windows. Each window is also  <!--INDEX window element, XUL --> contained within a <TT>&lt;window&gt;</TT> element (though recent additions to the XUL specification include the <TT>dialog</TT> and <TT>page</TT> elements, which are derived from <TT>window</TT> and can be used in its place as root elements in your XUL files).
   91: <P>As your application becomes more complex, you need a way to keep track of the windows and ensure that they can communicate with one another. In Mozilla, there is a way to do this by using  <!--INDEX toOpenWindowByType( ) function -->  <!--INDEX functions:toOpenWindowByType( ) --> the <TT>type</TT> attribute identifier, which allows you to use special window-opening functions like <TT>toOpenWindowByType( )</TT> to manage particular window types.
   93: <P>As with any existing Mozilla functions referred to in this book, you can look up <TT>toOpenWindowByType</TT> by using the LXR web-based source 
   94: code viewer, described in <A HREF="appa.html#90096">Appendix A</A> and available at <A HREF=""></A>.<P></BLOCKQUOTE>
   95: <H4><A NAME="77056"></A> Window features</H4>
   96: <P>An <TT>id</TT> attribute is present on  <!--INDEX XUL (XML-based User-interface Language):windows -->  <!--INDEX windows:XML --> the 
   97: <TT>&lt;window&gt;</TT> element. Using this  <!--INDEX window element, XUL:id attribute --> attribute is not necessary to run the windows system, but it is a good idea to give each window a unique identifier because it makes nodes easier to find from script (see the DOM method <TT>getElementByID</TT> in <A HREF="ch05.html#77037">Chapter 5</A> for information about how to get elements by identifier). This is how to set up an ID attribute:
   98: <PRE>&lt;window
   99: xmlns:html="<A HREF=""></A>"
  100: xmlns="<A HREF=""></A>"&gt;
  101: id="xflyMain"&gt;</PRE>
  102: <P>Load event handlers such as <TT>onload</TT> and <TT>onunload</TT> are useful and  <!--INDEX load event handlers, window element, XUL --> necessary if you want to add behavior to a window, pass input to it, or manipulate its content depending on context:
  103: <PRE>&lt;window
  104: xmlns:html="<A HREF=""></A>"
  105: xmlns="<A HREF=""></A>"
  106: id="xfly-main"
  107: onload="startUp( )"
  108: onunload="shutdown( )"
  109: onclose="onClose( )"&gt;</PRE>
  110: <P>When you load a XUL file that begins in this way, the event handler attributes <TT>onload</TT> and <TT>onunload</TT> carry out the functions listed as values (<TT>startUp( )</TT> and <TT>shutdown( )</TT>). In addition, Mozilla provides an <TT>onclose</TT> event handler that intercepts the upcoming window closure to carry out any extra processing you need. The close event is fired before the <TT>unload</TT> event, so you can stop the window from closing in the <TT>onclose</TT> event handler if necessary. To stop window closure, the close event must return <I>false</I>.
  111: <P>Additional handlers are available for dialog windows. They are listed and their use is outlined in the section <A 
  112: HREF="ch03.html#77087">"Application Windows</A>" in <A HREF="ch03.html#32764">Chapter 3</A>.
  113: <H4><A NAME="77057"></A> Window properties</H4>
  114: <P>The window declaration is  <!--INDEX windows:XUL:properties -->  <!--INDEX properties:windows, XUL -->  <!--INDEX XUL (XML-based User-interface Language):windows:properties --> expanding, but there is still plenty of room for more features. In addition to the <I>attributes-</I>the event handlers, the ID, and the namespace that appear within the <TT>&lt;window&gt;</TT> tag itself-a XUL window also has all of the properties of the DOM <TT>window</TT> object from HTML. These properties are listed below, along with additional properties for application specific tasks.
  115: <P><TABLE WIDTH=100% BORDER=1><TR><TD> Navigator</TD>	<TD> Document</TD>	<TD> window</TD>	<TD> Parent</TD></TR>
  116: <TR><TD> Top</TD>	<TD> Scrollbars</TD>	<TD> name</TD>	<TD> ScrollX</TD></TR>
  117: <TR><TD> ScrollY</TD>	<TD> ScrollTo</TD>	<TD> scrollBy</TD>	<TD> GetSelection</TD></TR>
  118: <TR><TD> ScrollByLines</TD>	<TD> ScrollByPages</TD>	<TD> Size</TD></TR>
  119: <TR><TD> ToContent</TD>	<TD> Dump</TD></TR>
  120: <TR><TD> SetTimeout</TD>	<TD> SetInterval</TD>	<TD> Clear</TD></TR>
  121: <TR><TD> Timeout</TD>	<TD> ClearInterval</TD></TR>
  122: <TR><TD> SetResizable</TD>	<TD> CaptureEvents</TD>	<TD> Release</TD></TR>
  123: <TR><TD> Events</TD>	<TD> RouteEvent</TD></TR>
  124: <TR><TD> Enable</TD></TR>
  125: <TR><TD> External</TD></TR>
  126: <TR><TD> Capture</TD>	<TD> DisableExternal</TD></TR>
  127: <TR><TD> Capture</TD>	<TD> prompt</TD>	<TD> Open</TD></TR>
  128: <TR><TD> OpenDialog</TD>	<TD> Frames</TD>	<TD> find</TD>	<TD> self</TD></TR>
  129: <TR><TD> Screen</TD>	<TD> History</TD>	<TD> content</TD>	<TD> Sidebar</TD></TR>
  130: <TR><TD> Menubar</TD>	<TD> Toolbar</TD>	<TD> Locationbar</TD>	<TD> Personalbar</TD></TR>
  131: <TR><TD> Statusbar</TD>	<TD> Directories</TD>	<TD> closed</TD>	<TD> Crypto</TD></TR>
  132: <TR><TD> pkcs11</TD>	<TD> Controllers</TD>	<TD> opener</TD>	<TD> Status</TD></TR>
  133: <TR><TD> defaultStatus</TD>	<TD> Location</TD>	<TD> innerWidth</TD>	<TD> InnerHeight</TD></TR>
  134: <TR><TD> outerWidth</TD>	<TD> OuterHeight</TD>	<TD> screenX</TD>	<TD> ScreenY</TD></TR>
  135: <TR><TD> pageXOffset</TD>	<TD> PageYOffset</TD>	<TD> length</TD>	<TD> FullScreen</TD></TR>
  136: <TR><TD> alert</TD>	<TD> Confirm</TD>	<TD> focus</TD>	<TD> Blur</TD></TR>
  137: <TR><TD> back</TD>	<TD> Forward</TD>	<TD> home</TD>	<TD> Stop</TD></TR>
  138: <TR><TD> print</TD>	<TD> MoveTo</TD>	<TD> moveBy</TD>	<TD> ResizeTo</TD></TR>
  139: <TR><TD> resizeBy</TD>	<TD> Scroll</TD>	<TD> close</TD>	<TD> UpdateCommands</TD></TR>
  140: <TR><TD> escape</TD>	<TD> Unescape</TD>	<TD> atob</TD>	<TD> Btoa</TD></TR>
  141: <TR><TD> AddEvent</TD></TR>
  142: <TR><TD> Listener</TD>	<TD> RemoveEvent</TD></TR>
  143: <TR><TD> Listener</TD>	<TD> Dispatch</TD></TR>
  144: <TR><TD> Event</TD>	<TD> GetComputed</TD></TR>
  145: <TR><TD> Style</TD></TR></TABLE><P>
  147: <P>Special properties of the XUL window object include:
  148: <DL><DT>window.content
  149: <DD>Using this property is a quick way  <!--INDEX window.content property, window object --> to access the content area of your window, if one 
  150: exists. This property is useful only if your window uses one of the content elements, namely <TT>&lt;iframe&gt;</TT>, <TT>&lt;browser&gt;</TT>, 
  151: and <TT>&lt;editor&gt;</TT>. Refer to the section <A HREF="ch03.html#77123">"Content Panels</A>" in <A HREF="ch03.html#32764">Chapter 3</A> for a more detailed discussion. The <TT>content</TT> property is linked only to the frame you have explicitly declared as the primary area.<P></DL>
  152: &lt;browser type="content-primary" ...&gt;
  153: <DL><DD>Subsequently, you can access and manipulate the content.<P></DL>
  154: window.content.focus( );
  155: <DL><DT>window.sizeToContent( )
  156: <DD>This property is used to ensure  <!--INDEX window.sizeToContent( ) property, window object --> intrinsic sizing, which is important in XUL application development, especially in dialog windows. Intrinsic sizing ensures that the window adapts and morphs to fit the content. This is preferable to constraining your window with a fixed width and height when the <TT>onload</TT> handler anticipates changeable content, depends on context, or takes input from another window. The colorpicker in the Mozilla Editor, for example, uses this function to make sure that the window displaying the chosen palette shrinks to fit that palette:<P></DL>
  157: function ChangePalette(palette)
  158: {
  159:   gDialog.ColorPicker.setAttribute("palettename", palette);
  160:   window.sizeToContent( );
  161: }
  162: <H4><A NAME="77058"></A> Interaction between windows</H4>
  163: <P>The <TT>nsIWindowMediator</TT> XPCOM component  <!--INDEX nsIWindowMediator, XPCOM -->  <!--INDEX XPCOM:nsIWindowMediator -->  <!--INDEX windows:XUL:nsIWindowMeditor -->  <!--INDEX XUL (XML-based User-interface Language):windows:nsIWindowMediator --> provides several routines for interacting with different windows. Though it's a little too early to discuss using a component like this in the Hello World examples, these routines include:
  164: <UL><P><LI>Getting the most recent window of a particular type<P>
  165: <P><LI>Enumerating all open windows<P>
  166: <P><LI>Registering and unregistering the window<P>
  167: <P><LI>Updating the window timestamp<P>
  168: <P><LI>Updating the window title<P>
  169: <P><LI>Setting the Z-order position<P></UL>
  170: <P><A HREF="ch08.html#78382">Chapter 8</A> provides full details of how to understand and use XPCOM components.
  171: <H4><A NAME="77059"></A> Window behavior</H4>
  172: <P>Mozilla supports the  <!--INDEX XUL (XML-based User-interface Language):windows:behaviors -->  <!--INDEX windows:XUL:behaviors -->  <!--INDEX function (JavaScript) -->  <!--INDEX -->  <!--INDEX --> standard <TT></TT> JavaScript function, which has its origins in the world of browser scripting and the launching of new browser windows. Mozilla extends the function to provide some features for application development. It also provides the <TT>window.openDialog</TT>  <!--INDEX window.openDialog function, JavaScript -->  <!--INDEX functions:JavaScript:window.OpenDialog -->  <!--INDEX JavaScript:functions:window.openDialog --> function for opening windows in the XPFE scripting environment. The latter function has become the more commonly used method to open a new XUL window, although the two are interchangeable.
  173: <P>The usage of <TT></TT> is:
  174: <PRE> (url, name, features);</PRE>
  175: <P><TT>window.openDialog</TT> extends this functionality with a new argument list passed to it, which is optional and can be any number of arguments as needed:
  176: <PRE>window.openDialog (url, type, features, argument1, argument2);</PRE>
  177: <P>Here is a list of some of the features of a XUL window opened using <TT>window.openDialog</TT>:
  178: <DL><DT>close
  179: <DD>The window can be created with or without a close widget.<P>
  180: <DT>chrome
  181: <DD>The new window has to  <!--INDEX chrome context, XUL windows -->  <!--INDEX XUL (XML-based User-interface Language):windows:chrome context -->  <!--INDEX windows:XUL:chrome context --> be treated as a window within the chrome context, rather than in the browser context. It gets its own top-level window. The window itself is the chrome URL passed to the function, and is not to be loaded in a browser window.<P>
  182: <DT>dependent
  183: <DD>The new window belongs  <!--INDEX dependence, XUL windows -->  <!--INDEX windows:XUL:dependence -->  <!--INDEX XUL (XML-based User-interface Language):windows:dependence --> to the calling window on operating systems that support this behavior. It "floats" on top of the opening window, and you can still access the parent window. It is minimized with its parent.<P>
  184: <DT>modal
  185: <DD>The window will be run  <!--INDEX modality, XUL windows -->  <!--INDEX XUL (XML-based User-interface Language):windows:modality -->  <!--INDEX windows:XUL:modality --> modally. Control is not given back to the parent window until this window has closed.<P>
  186: <DT>titlebar
  187: <DD>The window can be created  <!--INDEX windows:XUL:titlebars -->  <!--INDEX XUL (XML-based User-interface Language):windows:titlebar -->  <!--INDEX titlebars, XUL windows --> with or without a titlebar.<P>
  188: <DT>centerscreen
  189: <DD>Open the window centered  <!--INDEX centerscreen, windows (XUL) -->  <!--INDEX windows:XUL:centerscreen -->  <!--INDEX XUL (XML-based User-interface Language):windows:centerscreen --> on screen.<P></DL>
  190: <P>A comma delimits the features list and the entire list must be in quotes. The script that handles the new window accesses the arguments list:
  191: <PRE>window.openDialog("chrome://xfly/content/utils/prompt.xul"
  192: "XFLYndo_prompt",
  193: "chrome,dialog,modal",
  194: message);</PRE>
  195: <P>The window created in this example will be modal and use the message that was passed to it in the variable <I>message</I>. By default, Mozilla assumes that the <TT>chrome</TT> feature is on when you use either <TT></TT> or <TT>window.openDialog</TT> in a chrome environment, and creates a new window in the window hierarchy.
  196: <H2><A NAME="77060"></A> Making Mozilla Work for You</H2>
  197: <P>The second "Hello World" sample,  <!--INDEX Hello World XUL example:JavaScript and -->  <!--INDEX XUL (XML-based User-interface Language):Hello World example:JavaScript and --> shown in <A HREF="#77022">Example 2-4</A>, adds some important application features and begins to take advantage of the resources that Mozilla provides for you. This section goes over the ways you can import stylesheets and Mozilla scripts to make your XUL more sophisticated and modular. It also prepares you to make an actual application.
  198: <P>You can see this example in action by saving the code in <A HREF="#77022">Example 2-4</A> to a file, <I>hello2.xul</I>, and then launching Mozilla and selecting File &gt; Open File &gt; from the browser. This displays the example as content in the Mozilla browser, as shown in <A HREF="#77004">Figure 2-2</A>.
  200: <P><I>Example 2-4: <A NAME="77022"></A></I>
  201: <I>Sample XUL window</I>
  202: <PRE> &lt;?xml version="1.0"?&gt;
  203:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
  204:  &lt;!DOCTYPE window&gt;
  205:  &lt;window title="Hello xFly"
  206:    xmlns:html="<A HREF=""></A>"
  207:    xmlns="<A HREF=""></A>"
  208:    style="background-color: white;"
  209:    width="300"
  210:    height="215"
  211:    onload="centerWindowOnScreen( )"&gt;
  212:  &lt;script type="application/x-javascript"
  213:    src="chrome://global/content/dialogOverlay.js" /&gt;
  214:  &lt;vbox align="left"&gt;
  215:    &lt;label style="font-weight: bold;"
  216:        value="Hello, Welcome to the xFly" /&gt;
  217:    &lt;image src="<A HREF=""></A>" /&gt;
  218:    &lt;button label="hello xFly" oncommand="alert('Hello World');" /&gt;
  219:  &lt;/vbox&gt;
  220:  &lt;/window&gt;</PRE>
  222: <P>The difference between <A HREF="#77022">Example 2-4</A> and the first example is the addition of new elements, including the <TT>script</TT> element that brings in Mozilla JavaScript functions for use, additional box layout properties, inline style rules and processing instructions to import stylesheets, and the <TT>DOCTYPE</TT> declaration, which we describe later in this chapter in the section <A HREF="#77078">"The xFly DTD</A>."
  223: <P>These extras make your XUL file work more like an application by giving you access to services and features that already exist in Mozilla. They can also help you organize your own work into reusable parts, such as application stylesheets, widgets, and script libraries, as described later in this chapter in the section <A HREF="#77065">"Creating a Package</A>."
  224: <P><CENTER><IMG SRC="foo.gif"></CENTER>
  225: <P><I>Figure 2-2: <A NAME="77004"></A></I>
  226: <I>The second Hello xFly example loaded in the browser</I>
  228: <H3><A NAME="77061"></A> Importing Resources from Mozilla</H3>
  229: <P>The code in <A HREF="#77022">Example 2-4</A> uses scripts  <!--INDEX resources:importing from Mozilla -->  <!--INDEX importing:resources --> and styles that are already defined in Mozilla. As you'll see in examples in this book  <!--INDEX global.css stylesheet -->  <!--INDEX stylesheets:global.css --> and in the Mozilla source code, the <I>global.css</I> stylesheet is where many basic styles  <!--INDEX XUL widgets:styles;widgets:XUL:styles;styles:widgets, XUL --> are defined for XUL widgets. Most XUL widgets have some inherent style, as you can see in <A HREF="#77016">Example 2-1</A>, where the button has a button-like look without any explicit style rules or stylesheet imports.
  230: <P>As the XPFE has evolved, XUL widgets  <!--INDEX XUL widgets:XBL and;XBL (eXtensible Binding Language):XUL widgets and --> have used XBL internally to define some of these inherent looks and behaviors, which has taken some of the responsibility away from <I>global.css</I> and other CSS files. But this stylesheet still contains important rules for displaying basic XUL widgets. It's usually a good idea to import this main stylesheet into your application, as described here, and see what it gets you in terms of presentation. If you load <A HREF="#77022">Example 2-4</A> with and without the <I>global.css</I> line, you can see the way that the rules in the stylesheet provide styles for the widgets in the XUL.
  231: <P>Similarly, scripts like <I>globalOverlay.js</I>, <I>tasksOverlay.js</I>, and <I>dialogOverlay.js</I>, imported in <A HREF="#77022">Example 2-4</A>, provide basic functions you can use in your applications.
  232: <H4><A NAME="77062"></A> Loading stylesheets</H4>
  233: <P>In the second line of <A HREF="#77022">Example 2-4</A>, the stylesheet  <!--INDEX stylesheets:loading --> declaration uses a <I>chrome://</I> URL to refer to and load the <I>global.css</I> file. The style rules in that file give the button widget its "widgetness." You can use the stylesheet  <!--INDEX stylesheets:(see also CSS)[stylesheets:zz(see also CSS)] --> processing instruction to load Mozilla stylesheets like <I>global.css</I>, <I>navigator.css</I>,  <!--INDEX navigator.css stylesheet;toolbar.css stylesheet;stylesheets:navigator.css;stylesheets:toolbar.css --> and <I>toolbar.css</I>, or you can use it to load your own application stylesheet. In both cases, the <I>chrome://</I> URL allows you to refer to packaged files in a flexible way.
  234: <PRE>&lt;!--import the navigator.css stylesheet
  235: from the Mozilla navigator component--&gt;
  236: &lt;?xml-stylesheet href="chrome://navigator/skin" type="text/css"?&gt;
  237: &lt;!--import xfly.css stylesheet from the xFly package--&gt;
  238: &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css"?&gt;</PRE>
  239: <P>Also note the use of an inline style in <A HREF="#77022">Example 2-4</A>. The <TT>style</TT> property on the <TT>label</TT> widget gives you a place to define CSS rules directly on widgets. In this case, the label is given a bold font so that it shows up better in the window. You could also define this style rule in an external stylesheet and make that stylesheet part of the package for your application, as we do later in this chapter in the section <A HREF="#77075">"Separating the Files</A>."
  240: <H4><A NAME="77063"></A> Accessing script in XUL</H4>
  241: <P>To access a script in XUL, use the <TT>script</TT> element  <!--INDEX XUL (XML-based User-interface Language):scripts, access;scripts:XUL, access --> and a URL value for its <TT>src</TT> attribute:
  242: <PRE>&lt;script type="application/x-javascript"
  243: src="chrome://xfly/content/xfly.js" /&gt;</PRE>
  244: <P>The <TT>dialogOverlay.js</TT> script imported into  <!--INDEX dialogOverlay.js script;scripts:dialogOverlay.js --> your XUL file in <A HREF="#77022">Example 2-4</A> provides access to the <TT>CenterWindoOnScreen( )</TT> function. This  <!--INDEX CenterWindowOnScreen( ) function, JavaScript;functions:JavaScript:CenterWindowOnScreen( );JavaScript:functions:CenterWindowOnScreen( ) --> function is made available to your XUL file with the line:
  245: <PRE>&lt;script type="application/x-javascript"
  246: src="chrome://global/content/dialogOverlay.js" /&gt;</PRE>
  247: <P>All functions in <I>dialogOverlay.js</I> are imported into the scope of the XUL file and can be called directly, as <TT>CenterWindowOnScreen( )</TT> is in the <TT>onload</TT> event handler for the XUL window. Note that the functions contained in an imported JavaScript file are not broadcast in any particular way (though you can see them if you use the JavaScript Debugger). You may need to look around in the source code or see how other applications import files to find the functions you need, but the routines you want to use in your application code are probably already available in Mozilla.<A NAME="b260"></A><A HREF="#260">[*]</A>
  248: <H2><A NAME="77064"></A> Displaying XUL Files as Chrome</H2>
  249: <P><A HREF="#77004">Figure 2-2</A> shows the XUL file  <!--INDEX XUL files:displaying as chrome;chrome:XUL files, displaying --> in <A HREF="#77022">Example 2-4</A> loaded into the browser's main content area. The example features a <TT>label</TT> widget and an <TT>image</TT>, both situated within a <TT>vbox</TT> that lays them out properly in the available space. These widgets make up the chrome of your application, the Mozilla user interface that can refer to itself and its resources with the special <I>chrome://</I> URL.
  250: <P>This example is starting to show off some of the nice features of XPFE programming, but it still isn't an application yet. Among other things, you probably don't want your code to live inside the browser window forever. As it grows, you may also want to divide it into sensible parts-a XUL file, a separate stylesheet, and a script file, for example. The rest of this chapter explains how to organize and package the code in <A HREF="#77022">Example 2-4</A> and launch it as a standalone window by using the <TT>-chrome</TT> option when launching Mozilla.
  251: <P>Launching a XUL file by using the chrome switch requires that you register your application in the chrome registry so that Mozilla sees and recognizes it. The <A HREF="#77079">"Registering a Package</A>" section later in this chapter provides more information about the chrome environment and how to register this sample application.
  252: <P>Although this example hasn't been registered yet, we want to give you a preview of what it will look like when launched in a standalone window so you can compare it with how the same XUL file looks when loaded into the browser window. When you do launch the example by using the <TT>-chrome</TT> option (as described later in this chapter in the section <A HREF="#77080">"Launching the Application</A>"), you will see the window displayed in <A HREF="#77006">Figure 2-3</A>.
  253: <P><CENTER><IMG SRC="foo.gif"></CENTER>
  254: <P><I>Figure 2-3: <A NAME="77006"></A></I>
  255: <I>The second Hello xFly example launched in its own window</I>
  257: <P>Using the <TT>-chrome</TT> option tells Mozilla to display the specified file (in this case, the code from <A HREF="#77022">Example 2-4</A>) as a standalone application rather than as content within a browser window. The file itself is the same regardless of how it is loaded, but the results differ depending on what you tell Mozilla to do with the file.
  258: <P>Displaying a XUL file in its own chrome window makes it more independent and breaks the link to the browser content area that is present when you use the File &gt; Open File... method. Launching standalone windows, accompanied by the JavaScript <TT>window.openDialog</TT> function explained later in this chapter, opens up much more flexible window display options for your application.
  259: <H2><A NAME="77065"></A> Creating a Package</H2>
  260: <P>The previous two main sections  <!--INDEX chrome:package content;packages:chrome and --> introduced the concept of chrome and the prospect of creating standalone application windows. The next step is to make the example into an actual package-a modularized collection of files that can be installed in Mozilla as a new application.
  261: <P>In the earlier section <A HREF="#77060">"Making Mozilla Work for You</A>," you added features and complexity to your XUL file. In this section, you pull those features into separate files-a CSS file, JS file, and a DTD file-register these files together, and make them installable as a single package.
  262: <P>Only when you have packaged your work will your files have access to Mozilla files, such as CSS and scripts, be accessible from the special <I>chrome://</I> type URLs, be able to accept new themes, and be able  <!--INDEX packages:CSS and;packages:scripts and;packages:themes and;packages:XPCOM objects and -->  <!--INDEX stylesheets:packages and;scripts:packages and;themes:packages and;XPCOM:methods:JavaScript implementation --> to get to the XPCOM objects in which much of the application for Mozilla is defined.
  263: <P>Tools are available that help set up the files that form the basis of a new package. <A HREF="appb.html#78077">Appendix B</A> provides 
  264: information about XULKit, which is a collection of scripts that automates part of the package creation process. It is recommended that you try to set up your own package by hand first to understand how packages are put together before using the XULKit scripts.
  265: <H3><A NAME="77066"></A> Architecture of a Chrome Package</H3>
  266: <P>The architecture of the  <!--INDEX packages:architecture -->  <!--INDEX chrome:packages (see packages) --> Mozilla XPFE is component- or layer-based. One of the primary aims of the design was the separation of each different component of an application, namely content, functionality, and layout. This design results in greater modularization, making it easy to create and change a UI-to change skins for your application, for example, update the language in which the user interface is presented, or bring in new script elements.
  267: <P>When a package is modularized like it can be in Mozilla, design determinations can be left to the designer, language in the user interface can be left to writers, and the application framework itself can be handled by software developers (though the programmer handles all of these in many small- to medium-sized projects). The next several sections provide more detail about each component and its content and file types. The way basic packages fit components together can be the basis for your own application development.
  268: <P>A package is a group of directories and related files that make up a Mozilla application. A small, typical package may include a single XUL file, a script file (currently JavaScript, with implementations for Perl, Python, Ruby, and other languages being developed), and a CSS file. However, a single package might include dozens of these files, and may also include XBL files, Image File Types (PNG, JPG, GIF), DTD, HTML, and RDF files. Each has an important role to play in the application.
  269: <H3><A NAME="77067"></A> Package Components</H3>
  270: <P>As you will discover, each  <!--INDEX packages:components --> component in a package is independent. It is possible for your application to exist with just one or two of these components. Yet they all tie together when necessary to create a full featured application, and they are all at your disposal to take advantage of.
  271: <H4><A NAME="77068"></A> Chrome content</H4>
  272: <P>The content is  <!--INDEX packages:chrome content;chrome:package content;XUL data, packages;XBL data, packages;packages:XUL data;packages:XBL 
  273: data --> the XUL and XBL data, contained in one or more files. This content is pulled in at runtime from files, overlays, and bindings, for display in the window system. The cross-platform implementation ensures consistency in the native system, and fits into the "write once, run anywhere" model. The XUL defines a single set of UI elements for all platforms. The XUL parser is much less tolerant than many HTML parsers; in fact, it's completely intolerant. However, it needs to be because every element in XUL impacts others and affects the layout of the UI-especially in the context of the Box Model, which <A HREF="ch03.html#77084">Chapter 3</A> describes in detail.
  274: <P>The widget set consists of simple widgets that display by drawing themselves absolutely in their allotted space, and of more complex widgets that act as containers, draw on top of others, or  <!--INDEX packages:widget set;widgets:packages --> accept input. A <TT>&lt;label&gt;</TT> widget is an example of the former, while <TT>&lt;stack&gt;</TT> is of the latter, more complex group. If the parser does not find an element in the content files, it fails to load and returns an error. Errors vary by type. An XML syntax error, for example, displays in the window in place of the expected content. It gives you the file the error originated in, along with the line number and column number.
  275: <P>Built as a complementary  <!--INDEX XBL (eXtensible Binding Language):widget creation --> description language to XUL, XBL allows you to create your own widgets or add new behavior to existing XUL widgets. You may attach scripting and create (anonymous) content in a single binding or in many. With a little imagination, you can extend the content available to you infinitely by adding your own styling and behavior with XBL.
  276: <H4><A NAME="77069"></A> Chrome appearance</H4>
  277: <P>Loading up a XUL file with  <!--INDEX chrome:appearance, packages;packages:chrome content:appearance --> no styles attached  <!--INDEX styles:packages;packages:styles --> to the XUL elements will render the UI as a plain, disproportioned group of widgets. While plain text on a web page can be effective for simply relaying information, the situation is not analogous in user interfaces.
  278: <P>Mozilla user interfaces without style are not very usable. Even to achieve the traditional plain gray interface that so many applications use, you must use CSS to style the Mozilla front end, and subtle effects, such as color grades or 3D button effects, often make even the most basic interface look and work better.
  279: <P>Themes and the ability to customize  <!--INDEX themes:packages;packages:themes and --> the look of an application are becoming more prominent. Mozilla developers realized this prominence during the design phase of Mozilla, and it's reflected in the architecture: the appearance of the interface is almost entirely separate from the structural representation in the content.
  280: <H4><A NAME="77070"></A> Chrome behavior</H4>
  281: <P>Mozilla currently supports  <!--INDEX chrome:package content:behavior;packages:chrome content:behavior --> only JavaScript  <!--INDEX JavaScript:UI and --> as the bridge between the UI and the application code. JavaScript is the glue that binds the UI and the back end functionality, which is almost entirely written in C++.
  282: <P>Much of the infrastructure is in place for  <!--INDEX Python;Perl --> the support of other programming languages, however, and Python and Perl are currently being proposed as the next languages to fit into the framework. Currently, you will see JavaScript associated with XUL content via the following declaration:
  283: <PRE>&lt;script type="application/x-javascript" src="xfly.js" /&gt;</PRE>
  284: <P><TT>type</TT> replaces the now deprecated <TT>language</TT> attribute and expects a MIME type for its value. As Mozilla matures and support for other languages arrives, this value may become interchangeable-which fits in with the philosophy, common in open source projects, of there being More Than One Way To Do It. Note that the behavior component of a Mozilla application usually sits in the <I>content</I> subdirectory of a package, as described later in the section <A HREF="#77072">"Directory Structure</A>."
  285: <H4><A NAME="77071"></A> Chrome locale</H4>
  286: <P>Localization is  <!--INDEX packages:chrome content:locale;chrome:package content:locale --> the modification of software to meet the language of a location and the adaptation of resources, such as user interface and documentation, for that region. Widgets such as menu items, buttons, window titlebars, and alert dialogs commonly need to be localized. Beyond these widgets, there can be other localizable content in an application, from HTML pages to install packages.
  287: <P>The formats used by Mozilla are:
  288: <UL><P><LI>DTD (<I>.dtd</I>) files, which contain entities that host the strings to be included in your XUL content.<P>
  289: <P><LI>Property files (<I>.properties</I>), which contain string bundles that are accessed by dynamic content in JavaScript and C++ files or, theoretically, any language.<P>
  290: <P><LI>HTML files for certain pages installed with the application-e.g., About Mozilla.<P>
  291: <P><LI>RDF files.<P></UL>
  292: <H3><A NAME="77072"></A> Directory Structure</H3>
  293: <P>Files can be organized  <!--INDEX directories --> in many different ways. If your application is small-say a single window with a simple structure that needs to be available only in one language-then having all your files in one directory may be easier. As the size of an application goes over a certain threshold, however, logically grouping your files into subdirectories is a good practice to make the files more accessible.
  294: <P>Most applications use a directory structure that mirrors the package component descriptions described earlier: XUL and JavaScript  <!--INDEX directories:content;content directory --> in a <I>content</I> subdirectory, CSS and images in a <I>skin</I> subdirectory,  <!--INDEX skin directory;directories:skin --> and DTDs and other resources for localizing the interface in a <I>locale</I> subdirectory. <A HREF="#77008">Figure 2-4</A>  <!--INDEX locale directory;directories:locale --> shows this common grouping.
  295: <P><CENTER><IMG SRC="foo.gif"></CENTER>
  296: <P><I>Figure 2-4: <A NAME="77008"></A></I>
  297: <I>A sample package layout in the directory system</I>
  299: <P>These three different directories usually contain the following type of files:
  300: <DL><DT>content
  301: <DD>The <I>content</I> directory is  <!--INDEX XUL files:content directory;content directory:XUL files --> the home for the XUL files that contain the widgets to be drawn for you application. It is  <!--INDEX JavaScript:files, content directory --> common practice to also place files related to behavior, namely JavaScript files, in this directory.<P>
  302: <DT>locale
  303: <DD>This directory contains  <!--INDEX locale directory;directories:locale --> the files  <!--INDEX DTD:locale directory --> that contain localized strings for your package. Most files are DTD files that contain the entities referenced in XUL files. There is a subdirectory for each language, and the naming convention is <I>code-region</I>, such as <TT>en-US</TT>.<P>
  304: <DT>skin
  305: <DD>The term "skin" is an  <!--INDEX skin directory;directories:skin --> internal name  <!--INDEX stylesheets:skin directory --> for a theme. The <I>skin</I> directory contains all CSS files and images that contribute to the appearance of the windows. This is a good place to put the application images-in their own subdirectory.<P></DL>
  306: <H4><A NAME="77073"></A> The xFly application directory structure</H4>
  307: <P>The structure of the directories in which  <!--INDEX xFly package:directories --> an application is defined (whether those directories are in the filesystem or subdirectories in an archive such as a JAR file) is an important part of that application's design and relationship to Mozilla. Use the following steps to make your xFly package self-contained, registerable, and adaptable.
  308: <UL><P><LI>On your computer, go to the directory where you have installed Mozilla and create a new directory underneath the <I>chrome</I> directory called "<I>xfly</I>."<P></UL>
  309: <OL><P>All Mozilla applications live in the <I>chrome</I> directory.<P></OL>
  310: <UL><P><LI>Under that directory, create the three new directories, <I>content</I>, <I>locale</I>, and <I>skin</I>, as shown in <A HREF="#77010">Figure 2-5</A>.<P></UL>
  311: <P><CENTER><IMG SRC="foo.gif"></CENTER>
  312: <P><I>Figure 2-5: <A NAME="77010"></A></I>
  313: <I>xFly package directory structure</I>
  315: <H3><A NAME="77074"></A> Package Manifests</H3>
  316: <P>Now that you have created the  <!--INDEX packages:manifests;manifests:packages --> directories for your package, you must tell Mozilla about them. All Mozilla packages must include manifests that describe their contents and make it possible to register them with Mozilla. A manifest is an RDF file (or series of RDF files) that sits within the package and interacts with Mozilla's <I>chrome</I> directory. RDF files are XML files that describe data in a machine-readable form.
  317: <P>Each xFly package subdirectory needs its own manifest file. Mozilla uses these files (in each case, called <I>contents.rdf</I>) when registering the application. These files are listed in Examples <A HREF="#77024">2-5</A>, <A HREF="#77026">2-6</A>, and <A HREF="#77028">2-7</A>. Create these files in your xFly <I>content</I>, <I>skin</I>, and <I>locale</I> subdirectories, respectively.
  319: <P><I>Example 2-5: <A NAME="77024"></A></I>
  320: <I>chrome/xfly/content/contents.rdf file</I>
  321: <PRE> &lt;?xml version="1.0"?&gt;
  322:  &lt;RDF:RDF xmlns:RDF="<A HREF=""></A>#"
  323:           xmlns:chrome="<A HREF=""></A>#"&gt;
  324:    &lt;!-- list all the packages being supplied --&gt;
  325:    &lt;RDF:Seq about="urn:mozilla:package:root"&gt;
  326:      &lt;RDF:li resource="urn:mozilla:package:xfly"/&gt;
  327:    &lt;/RDF:Seq&gt;
  328:    &lt;!-- package information --&gt;
  329:    &lt;RDF:Description about="urn:mozilla:package:xfly"
  330:          chrome:displayName="xFly"
  331:          chrome:author=""
  332:          chrome:name="xfly"&gt;
  333:    &lt;/RDF:Description&gt;
  334:   >&lt;/RDF:RDF&gt;</PRE>
  336: <P>In the content manifest in <A HREF="#77024">Example 2-5</A>, note the <TT>chrome:name</TT>, <TT>chrome:author</TT>, and the other metadata that the manifest provides to Mozilla. This information can be used by others to identify what your application is and who wrote it. For example, the name, author, and short description information for each browser theme you have installed is viewable by going to Preferences and selecting Appearance  &gt;  Themes.
  337: <P>In <A HREF="#77026">Example 2-6</A>, which describes  <!--INDEX skins:xFly application;xFly:skins --> the skin for xFly only, note that new skin resources for the Classic theme are all that is supplied, as indicated in the <TT>RDF:Seq</TT>, which lists only <TT>classic</TT> as affected by this new package.
  339: <P><I>Example 2-6: <A NAME="77026"></A></I>
  340: <I>chrome/xfly/skin/contents.rdf file</I>
  341: <PRE> &lt;?xml version="1.0"?&gt;
  342:  &lt;RDF:RDF xmlns:RDF="<A HREF=""></A>#"
  343:           xmlns:chrome="<A HREF=""></A>#"&gt;
  344:    &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
  345:      &lt;RDF:li resource="urn:mozilla:skin:classic/1.0" /&gt;
  346:    &lt;/RDF:Seq&gt;
  347:    &lt;RDF:Description about="urn:mozilla:skin:classic/1.0"&gt;
  348:      &lt;chrome:packages&gt;
  349:        &lt;RDF:Seq about="urn:mozilla:skin:classic/1.0:packages"&gt;
  350:          &lt;RDF:li resource="urn:mozilla:skin:classic/1.0:xfly"/&gt;
  351:        &lt;/RDF:Seq&gt;
  352:      &lt;/chrome:packages&gt;
  353:    &lt;/RDF:Description&gt;
  354:  &lt;/RDF:RDF&gt;</PRE>
  356: <P>In <A HREF="#77028">Example 2-7</A>, which shows the third kind of manifest, for new locale information, the English language pack (<TT>en-US</TT>) is augmented with the localizable resources in the xFly package named there. The <TT>RDF:Seq</TT> structure  <!--INDEX RDF\:Seq structure, manifests --> in a manifest states, "to the package listed here (i.e., the <TT>en-US</TT> language pack), add the following."
  358: <P><I>Example 2-7: <A NAME="77028"></A></I>
  359: <I>chrome/xfly/locale/contents.rdf file</I>
  360: <PRE> &lt;?xml version="1.0"?&gt;
  361:  &lt;RDF:RDF xmlns:RDF="<A HREF=""></A>#"
  362:           xmlns:chrome="<A HREF=""></A>#"&gt;
  363:    &lt;RDF:Seq about="urn:mozilla:locale:root"&gt;
  364:      &lt;RDF:li resource="urn:mozilla:locale:en-US"/&gt;
  365:    &lt;/RDF:Seq&gt;
  366:    &lt;!-- locale information --&gt;
  367:    </TD>&lt;RDF:Description about="urn:mozilla:locale:en-US"
  368:          chrome:displayName="English(US)"
  369:          chrome:author=""
  370:          chrome:name="en-US"
  371:          chrome:previewURL="<A HREF=""></A>"&gt;
  372:      &lt;chrome:packages&gt;
  373:        &lt;RDF:Seq about="urn:mozilla:locale:en-US:packages"&gt;
  374:          </TD>&lt;RDF:li resource="urn:mozilla:locale:en-US:xfly"/&gt;
  375:        &lt;/RDF:Seq&gt;
  376:      &lt;/chrome:packages&gt;
  377:    &lt;/RDF:Description&gt;
  378:  &lt;/RDF:RDF&gt;</PRE>
  380: <P>Manifests are detailed in <A HREF="ch06.html#15291">Chapter 6</A>. For now, it's enough to see that each manifest describes the subdirectory in 
  381: which it is located, and that the contents of those subdirectories make up the package collectively.
  382: <P>The content describes the content of the xFly package, the XUL, and the JavaScript. The skin describes the theme of xFly, or the CSS and images used to lay out the XUL. The third part describes the locale, or the strings in the UI that can be localized or adapted for various languages or locales.
  383: <H3><A NAME="77075"></A> Separating the Files</H3>
  384: <P>Once you have a subdirectory structure set up  <!--INDEX packages:file separation;files:separating, packages;separating files, packages --> in accordance with the package component structure of your application, you can pull the pieces of your XUL file out into their own files and modularize your application. These separate files-the basic XUL file and separate CSS, JS, and DTD files-are registered as a single package and can then be launched as a standalone application.
  385: <P>Though the files contain the information you've already seen in the "Hello World" sample shown in <A HREF="#77022">Example 2-4</A>, their interaction demonstrates how packages can work together in Mozilla. Each step taken to separate the different components requires editing the base XUL file.
  386: <H4><A NAME="77076"></A> The xFly CSS file</H4>
  387: <P>The inline style rule  <!--INDEX xfly.css file;stylesheets:xfly.css file;packages:xfly.css file --> on the label widget can go almost unadulterated into a separate text file called <I>xfly.css</I>. Save the code in <A HREF="#77030">Example 2-8</A> in the <I>chrome/xfly/skin/</I> directory.
  389: <P><I>Example 2-8: <A NAME="77030"></A></I>
  390: <I>The contents of the xfly.css file</I>
  391: <PRE> #xlabel { font-weight: bold; }
  392:  window  { background-color: white; }</PRE>
  394: <P>Using style rules from an external file is different because you have to specify some way for the style rule to associate itself with the appropriate tags in the XUL file. CSS provides a rich collection of selectors, which bind style data to elements. In this case, where you have two separate elements that need to pick up rules, the <TT>id</TT> attribute on the XUL element is used to bind a unique element to an external style rule and the other style rule is bound by referring to the XUL element directly. <A HREF="#77030">Example 2-8</A> includes the selectors for the two elements, and <A HREF="#77032">Example 2-9</A> shows the updated XUL that uses <I>xfly.css</I>.
  396: <P><I>Example 2-9: <A NAME="77032"></A></I>
  397: <I>XUL using external style data</I>
  398: <PRE> &lt;?xml version="1.0"?&gt;
  399:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
  400:  &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css"?&gt;
  401:  &lt;!DOCTYPE window&gt;
  402:  &lt;window title="Hello xFly"
  403:    xmlns:html="<A HREF=""></A>"
  404:    xmlns="<A HREF=""></A>"
  405:    width="300"
  406:    height="215"
  407:    onload="centerWindowOnScreen( )"&gt;
  408:   &lt;script type="application/x-javascript"
  409:    src="chrome://global/content/dialogOverlay.js" /&gt;
  410:   &lt;vbox align="left" id="vb"</TD>&gt;
  411:    &lt;label id="xlabel"
  412:        value="Hello, Welcome to the xFly" /&gt;
  413:    &lt;image src="<A HREF=""></A>" /&gt;
  414:    &lt;button label="hello xFly" oncommand="alert('hello.');" /&gt;
  415:   &lt;/vbox&gt;
  416:  &lt;/window&gt;</PRE>
  418: <P>Note the extra stylesheet import statement at the top and the use of the new <TT>id</TT> attribute on the label. When you register the new files in your package with Mozilla, the <I>xfly</I> directory in that stylesheet processing instruction will point into your application directory structure (at the <I>skin</I> subdirectory, and at a file named after the directory itself, <I>xfly.css</I>). The label will pick up the style information in the file that was previously defined directly in its <TT>style</TT> attribute.
  419: <H4><A NAME="77077"></A> The xFly script file</H4>
  420: <P>The next step is to take  <!--INDEX xfly.js file;JavaScript:xfly.js file;packages:xfly.js file --> the scripting portion, as simple as it is, out of the XUL file and put it into an external JavaScript file. <A HREF="#77034">Example 2-10</A> shows a XUL file that gets a function for the button from an external script file, given here as <I>xfly.js</I>.
  422: Example 2-10<A NAME="77034"></A>
  423: <I>XUL using an external script</I>
  424: <PRE> &lt;?xml version="1.0"?&gt;
  425:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
  426:  &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css"?&gt;
  427:  &lt;!DOCTYPE window&gt;
  428:  &lt;window title="Hello xFly"
  429:    xmlns:html="<A HREF=""></A>"
  430:    xmlns="<A HREF=""></A>"
  431:    width="300"
  432:    height="215"
  433:    onload="centerWindowOnScreen( )"&gt;
  434:  &lt;script type="application/x-javascript"
  435:    src="chrome://global/content/dialogOverlay.js" /&gt;
  436:  </TD>&lt;script type="application/x-javascript"
  437:    src="chrome://xfly/content/xfly.js" /&gt;
  438:   &lt;vbox align="left" id="vb"&gt;
  439:    &lt;label id="xlabel"
  440:        value="Hello, Welcome to the xFly" /&gt;
  441:    &lt;image src="<A HREF=""></A>" /&gt;
  442:    &lt;button label="hello xFly" oncommand="greet( );" /&gt;
  443:   &lt;/vbox&gt;
  444:  &lt;/window&gt;</PRE>
  446: <P>Note that the function <TT>greet( )</TT> is used to name the action that is performed when the button is clicked. The <TT>greet( )</TT> function is now defined in the <I>xfly.js</I> file that the XUL file picks up with the script import statement:
  447: <PRE>&lt;script type="application/x-javascript"
  448: src="chrome://xfly/content/xfly.js" /&gt;</PRE>
  449: <P><A HREF="#77036">Example 2-11</A> contains all of the code needed for the <I>xfly.js</I> file.
  451: Example 2-11<A NAME="77036"></A>
  452: <I>The contents of the xfly.js file</I>
  453: <PRE> function greet( ) {
  454:    alert("Hello World");
  455:  }</PRE>
  457: <P>Save <I>xfly.js</I> in the <I>content</I> subdirectory of the xFly application (<I>chrome/xfly/content/</I>). The script import statement above uses the <I>chrome://</I> URL to locate scripts from directories that were registered with Mozilla.
  458: <H4><A NAME="77078"></A> The xFly DTD</H4>
  459: <P>The final step in a basic  <!--INDEX xfly.dtd file;DTD:xfly.dtd file --> application setup is to generalize parts of the interface that are written in a particular language, such as English. When you create a <I>locale</I> subdirectory for your package and place a DTD file that contains the English strings in the user interface, you can refer to and load that DTD just as you do with the CSS and script files.
  460: <P>For example, to localize the text of the label and button elements in the "hello xFly" example, you can use a special syntax to tell Mozilla to use an entity rather than a string. Because that entity is defined in <I>xfly.dtd</I> and located in the locale subdirectory, it can easily be swapped for an entity from a different language pack when the user switches languages in Mozilla.
  461: <P>Once again, the external file you create can be very simple. <A HREF="#77038">Example 2-12</A> contains the code needed for the <I>xfly.dtd</I> file, which you create and save in the <I>locale</I> subdirectory.
  463: Example 2-12<A NAME="77038"></A>
  464: <I>The contents of the xfly.dtd file</I>
  465: <PRE> &lt;!ENTITY label.val       "Hello, Welcome to the xFly " &gt;
  466:  &lt;!ENTITY btn.lbl         "hello xFly " &gt;</PRE>
  468: <P>The updated XUL file that uses this external DTD, then, appears in <A HREF="#77040">Example 2-13</A>. Once you have made the final changes in the XUL to refer to the external files you've created, save the code in <A HREF="#77040">Example 2-13</A> as <I>xfly.xul</I> in the <I>chrome/xfly/content/</I> directory.
  470: Example 2-13<A NAME="77040"></A>
  471: <I>XUL using an external DTD file</I>
  472: <PRE> &lt;?xml version="1.0"?&gt;
  473:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
  474:  &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css"?&gt;
  475:  &lt;!DOCTYPE window SYSTEM "chrome://xfly/locale/xfly.dtd" &gt;
  476:  &lt;window title="Hello xFly"
  477:    xmlns:html="<A HREF=""></A>"
  478:    xmlns="<A HREF=""></A>"
  479:    width="300"
  480:    height="215"
  481:    onload="centerWindowOnScreen( )"&gt;
  482:  &lt;script type="application/x-javascript"
  483:    src="chrome://global/content/dialogOverlay.js" /&gt;
  484:  &lt;script type="application/x-javascript"
  485:    src="chrome://xfly/content/xfly.js" /&gt;
  486:   &lt;vbox align="left" id="vb"&gt;
  487:    &lt;label id="xlabel"
  488:        value="&amp;label.val;"</TD> /&gt;
  489:    &lt;image src="<A HREF=""></A>" /&gt;
  490:    &lt;button label="&amp;btn.lbl;"</TD> oncommand="greet( );" /&gt;
  491:   &lt;/vbox&gt;
  492:  &lt;/window&gt;</PRE>
  494: <P>Like the CSS and script file imports, the updated <TT>DOCTYPE</TT> definition at the top of the file tells Mozilla to load additional entities as part of the xFly package. Those entities-the English strings that display in the user interface-are defined so they can be localized or internationalized without affecting the application's structure.
  495: <P>All three of these imports use the <I>chrome://</I> URL to refer to resources that are internal to the xFly package. These type of URLs can also refer to resources elsewhere in Mozilla, such as image resources, strings that have already been defined in entities, and functions from scripts such as <TT>centerWindowOnScreen( )</TT>.
  496: <P>When you finish setting things up in the package directories, you should have a structure that looks like the tree structure in <A HREF="#77042">Example 2-14</A>.
  498: Example 2-14<A NAME="77042"></A>
  499: <I>Tree structure of a completed sample xFly package</I>
  500: <PRE> chrome/
  501:         xfly/
  502:             content/
  503:                    xfly.xul
  504:                    xfly.js
  505:                    contents.rdf
  506:             locale/
  507:                    xfly.dtd
  508:                    contents.rdf
  509:             skin/
  510:                    xfly.css
  511:                    contents.rdf</PRE>
  513: <H3><A NAME="77079"></A> Registering a Package</H3>
  514: <P>Registering packages in Mozilla  <!--INDEX packages:registration;registration:packages --> can be confusing at first, so don't worry about understanding everything at this point. Later chapters provide more detailed information about packaging and registration, and you can always copy the examples given here to install your own application. In general, to make your package registerable, create manifests that describe your package in terms that Mozilla can understand.
  515: <P>Although it's customary to make registration a part of the installation process by using the XPInstall API and installation  <!--INDEX XPInstall:registration and;registration:XPInstall API --> scripts, you need a simple way to register the xFly application so you can see your work and test it as it develops. For this purpose, hacking the <I>installed-chrome.txt</I> file living  <!--INDEX installed-chrome.txt file --> in Mozilla's <I>chrome</I> directory will do.
  516: <P>The <I>installed-chrome.txt</I> file is a list of packages and package parts that Mozilla should find and register on start up. When you add entries to this file, you point to your package and tell Mozilla to register that package when it starts up.
  517: <P>Append the entries in <A HREF="#77044">Example 2-15</A> to the bottom of the <I>installed-chrome.txt</I> file in the main chrome directory.
  519: Example 2-15<A NAME="77044"></A>
  520: <I>Additions to the installed-chrome.txt file</I>
  521: <PRE>content,install,url,resource:/chrome/xfly/content/
  522: skin,install,url,resource:/chrome/xfly/skin/
  523: locale,install,url,resource:/chrome/xfly/locale/</PRE>
  525: <P>When Mozilla starts up, it looks for the package manifests, reads them, and registers the xFly package.
  526: <P>When others install your application and use it on their machines (but do not use the hack to <I>installed-chrome.txt</I>), you can provide 
  527: them with a JavaScript installation file that downloads and registers your package from a web page. See <A HREF="ch06.html#15291">Chapter 6</A> for more information about these installation files and the XPInstall technology they are based upon.
  528: <H2><A NAME="77080"></A> Launching the Application</H2>
  529: <P>Once your package is registered, you can use these startup options to access your package directly.<A NAME="77081"></A>
  530: <H4><A NAME="77082"></A> Windows launch</H4>
  531: <P>In the Mozilla install directory, launch xFly at  <!--INDEX xFly:Windows launch;Windows:xFly launch --> the command prompt with:
  532: <PRE>mozilla -chrome chrome://xfly/content/</PRE>
  533: <P>You can also launch xFly from a shortcut on your desktop by right-clicking on the existing Mozilla icon and selecting Properties. In the Target area of the Properties box, add the following text at the end of the line:
  534: <PRE>-chrome chrome://xfly/content/</PRE>
  535: <P><A HREF="#77012">Figure 2-6</A> shows what the new properties box should look like.
  536: <P><CENTER><IMG SRC="foo.gif"></CENTER>
  537: <P><I>Figure 2-6: <A NAME="77012"></A></I>
  538: <I>Modified shortcut properties</I>
  540: <H4><A NAME="77083"></A> Unix launch</H4>
  541: <P>In the Mozilla install directory, launch xFly  <!--INDEX xFly:Unix launch;Unix:xFly launch --> with:
  542: <PRE>./mozilla -chrome chrome://xfly/content/</PRE>
  543: <H4><A NAME="77084"></A> Macintosh launch</H4>
  544: <P>Start xFly by creating a text file on your desktop  <!--INDEX xFly:Macintosh launch;Macintosh:application launch --> with the following content:
  545: <PRE>-chrome chrome://xfly/content/</PRE>
  546: <P>You can either drag this text file onto your Mozilla icon to launch the application or set the text file's creator type to <TT>MOZZ</TT>. If you change the creator type, you should be able to double-click on the text file to launch Mozilla.
  547: <P>Once you register your application, you are free to continue developing it in the various component subdirectories and relaunching it as it progresses. You can add new XUL files in the <I>content</I> directory, for example, that are invoked from buttons using <TT>window.openDialog( )</TT> event handlers.
  548: <P>You can add new widgets to <I>xfly.xul</I>, add new styles to <I>xfly.css</I> that apply to the XUL, add new functions to <I>xfly.js</I>, or use existing functions in the Mozilla source code that you can find new ways to use in your own application.
  549: <P>The steps described in this chapter-creating a basic XUL file, adding features, displaying that XUL file as a standalone window, organizing the code into separate files and a package structure, and registering and launching that package-are the basic building blocks of all Mozilla applications. When you get a feel for what's going on here, you'll be able to quickly understand and use the topics described in the rest of the book.
  550: <HR>
  551: <HR><A NAME="260"></A><A HREF="#b260">[Back]</A>
  552: <A NAME="77047"></A>
  553: Unfortunately, no good reference exists for the
  554: functions defined in the various scripts files you can import. The
  555: functions and their locations within the files continue to change, so
  556: finding and using the right ones is sometimes a matter of luck,
  557: sometimes a matter of whom you know, and often a matter of testing,
  558: determination, and patience.
  559: <HR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
  560: <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR></BODY>
  561: </HTML>

FreeBSD-CVSweb <>