An Introduction to XUL Part 5

Learn about XUL, a subset of XML used to describe user interfaces, that helps you to make rich user interfaces with nothing more complicated than a text editor. In the fifth part of this series you will receive an introduction to XPCOM, the object model used by XUL, and take a close look at a basic example of the combination of Mozilla components and interfaces that make up the abstraction layer.

All applications need a way or warning users that something is about to happen, or that something has happened. If you’re working in a word-processing application and you try to exit the application without saving your work, you’ll get a message advising that you’ll lose your data if you don’t save it, and are given the opportunity of canceling the action in order to save the file. Computers and software in particular can be frustrating enough as it is from time to time, without this added layer of program safety. Luckily, XUL is able to provide this same safety net, with the inclusion in its syntax of dialog boxes. Of course, you’ll need more than just the code that draws the box on the screen to make dialog boxes a barrier between yourself and application misery, but initially, we’ll look at the code needed to render them.

The dialog element is used in place of the window element:

<dialog id=”mydialog”
  xmlns=”http://www.mozilla.org/keymaster/gatekeeper/
  there.is.only.xul” buttons=”accept,cancel”>

<dialogheader title=”Warning”/>

<description>The action you have selected will render your
  computer completely inoperable.  Do you wish to continue?
  </description>

</dialog>

As you can see, the XUL namespace still needs to be included. For scripting purposes, the id attribute is also recommended. The dialogheader is used to give the dialog box a separate heading, into which a title and description can be placed. The title is styled automatically to be bold and colored and gives an indication as to the function of the dialog box, whether this be information, a warning, or just a few words of wisdom. 

Dialogs need to be opened using a chrome URL from within Mozilla, which means that in order for Mozilla to know about them, an RDF file needs to contain references to them. Save the above file in the content directory used for the wizard example and update the existing contents.rdf file with the following bag and description:

RDF:Bag about=”urn:mozilla:package:root”>
    <RDF:li RDF:resource=”urn:mozilla:package:mydialog2″/>
</RDF:Bag>

<RDF:Description about=”urn:mozilla:package:mydialog2″
          chrome:displayName=”myDialog2″
          chrome:author=”Dan”
          chrome:name=”mydialog2″
          chrome:extension=”false”/>

As before, this will not be recognized by Mozilla until the existing chrome.rdf file has been deleted and regenerated in the Mozilla chrome directory. Now open the dialog using the normal chrome syntax (chrome://filename/content/). The dialog should open, and will have the header, the message and the specified buttons. 

Click one of the buttons to test that they will actually do something, and once again, Mozilla quits abruptly. You’ll also notice that instead of being a separate dialog box, Mozilla has opened it as if it were a window. Both of these things are caused by not calling the dialog from another file, which we can fix easily enough by creating a window that calls the dialog.  Create the following file and save it in your chrome folder:


<?xml version=”1.0″?>
<window
  id=”button”
  title=”Dialog test”
  xmlns=”http://www.mozilla.org/keymaster/gatekeeper/
 
there.is.only.xul”>

<script>
  function openD() {
    window.open(“chrome://mybutton/content/mydialog2.xul”,
    “chrome”, “dialog”);
  }

</script> 

<button id=”button1″ label=”Napalm my C: drive!”
  onclick=”openD();”/>

</window>

For this to work properly, it will need to be added to the RDF file and opened with a chrome URL in the normal way. As you can see, you simply add a click event to the button, which calls the function residing within the script tags. This function contains a simple method with some parameters specifying the full chrome URL of the window to open, that it is a chrome file and that it is a dialog. 

When the button file is opened with a chrome URL from Mozilla, you can click the button, and your dialog box will appear in a window of its own. Clicking the ok or cancel buttons (which both do exactly the same thing, as we haven’t scripted these) will close the dialog, but Mozilla itself will remain open. You could do the same thing for the wizard example to prevent Mozilla from closing, and also to give it its own window.

{mospagebreak title=Buttons, JavaScript, and XPCOM}

XUL does not give you as many different built-in buttons as other, more powerful programming languages such as Visual Basic or C, but you have to remember that XUL is just a mark-up language. Other buttons you can use are the help and disclosure buttons, which can be used by adding them to the comma delimited list in the dialog tag. Unlike the ok and cancel buttons, these will not do anything without adding scripts for them, but there are built-in methods (ondialoghelp and ondialogdisclosure) that will let you do this easily.

JavaScript is able to perform many of the processes that lie behind an application and is used to add behavior to menus, buttons and other elements. Unfortunately, there are many things an application will need to do that are beyond the reach of JavaScript, such as working with local files. To give XUL the power that it clearly has (after all, both Mozilla and Firefox are written entirely in XUL and these are world-class browser applications), Mozilla provides an object model that allows you to implement instances of existing components of Mozilla. These components are themselves composed of interfaces that contain specific sets of functionality, which allow you to do the kind of advanced things that applications need to do in order to function.

Programmers that have used .NET, for example, to inherit the functionality of pre-existing classes will feel right at home here. The object model used by Mozilla is XPCOM, which stands for cross platform component object model. In order to open and save files, for example, you will need to create an instance of a component that is able to access the required functions by implementing the correct interface, which will form the basis of the next example and will draw upon some of the elements we have already worked with.

You should only need a basic window to test the functionality of the file interface needed to produce an open file dialog. The window won’t actually open or save any files because this requires more components and interfaces and is beyond the scope of this article, but the code will demonstrate how to create a standard dialog box that people can use to select files for opening. The following window, which will need to be described by a contents.rdf and accessed through Mozilla should be enough:

<?xml version=”1.0″?>
<window
  id=”myApp”
  title=”Opening and Saving Files” width=”500″ height=”300″
  xmlns=”http://www.mozilla.org/keymaster/gatekeeper/
    there.is.only.xul”>

<menubar id=”mainmenu” grippyhidden=”true”>
  <menu id=”file” label=”File” accesskey=”f”>
    <menupopup id=”filepop”>
      <menuitem label=”Open” accesskey=”o” />
      <menuitem label=”Save” accesskey=”s”/>
      <menuseparator/>
      <menuitem label=”Exit” accesskey=”e”
        oncommand=”window.close();”/>
    </menupopup>
  </menu>
</menubar>

</window>

This will create a basic window with a basic menu in it. There are just three items in the menu, open, save and exit. There is almost no additional code required to close the window; just a simple JavaScript method that closes the current window. The oncommand event is used because we have specified accesskeys for the menu and items, which means that a user could select the exit menu item with the mouse or with the keyboard.

{mospagebreak title=The nsIFilePicker interface}

The code needed to open the dialog box that you use to select which file to open is implemented using the nsIFilePicker interface. The file open dialog will be opened when the Open button on the menu is selected, so it will need to go into a function, which will be called when the Open button is selected. Add anoncommand=”openDialog();”call to the open menu element. JavaScript would normally go into a file of its own, but for this example it can sit in the XUL file. Add the opening script tag and begin the function:

<script>
  function openDialog() {

The first line of the code inside the function sets a variable to hold the filePicker interface:

  var nsIFilePicker = Components.interfaces.nsIFilePicker;

You then set a second variable to hold the component and request an instance of the interface:

  var fileChooser =                                  

Components.classes["@mozilla.org/
  filepicker;1"].createInstance(nsIFilePicker);

Next you set a variable that initializes the open file dialog, and pass it parameters that specify its type, its title and its mode:

   fileChooser.init(window, “Select a File to open”,
nsIFilePicker.modeOpen);

Finally, you create a variable that calls the show() method of the open file dialog, which is what displays the box on screen:

var fileBox = fileChooser.show();

Don’t forget to add the closing curly brace to signify the end of the function. The code required to create the Save As dialog box is extremely similar. Create the following function and note that the only differences are the title and mode of the initialization variable:

function saveDialog() {
  var nsIFilePicker = Components.interfaces.nsIFilePicker;
  var fileChooser =
    Components.classes["@mozilla.org/
    filepicker;1"].createInstance(nsIFilePicker);
 
fileChooser.init(window, “Select a Location to save”,
    nsIFilePicker.modeSave);
  var fileBox = fileChooser.show();

Close off the script tag and save the file as opensave.xul in the same location as the rdf file describing it. Open the file from inside Mozilla using its chrome url and you should get your simple menu bar and simple menu. Selecting the Open will open the Select a File to open dialog box, and selecting Save will open the Select a Location to save dialog box.  The functionality to actually open or save files requires far more code and won’t be discussed here. Once you’re done, choose close on your menu and Mozilla should exit.

{mospagebreak title=The keyset element}

One final thing you can use in the example is the keyset element. The keyset element is used to specify a key combination that someone using the application can press to select menuitems without having to navigate the menus. The keyset element contains its children, individual key elements that define the keyboard shortcuts. The key elements need an id attribute which ties in with an attribute used on the menuitem they are a shortcut for, a modifiers attribute which specifies which special key should be pressed, a key attribute which specifies the keyboard key used in conjunction with the special key, and an event that calls whichever function they should be associated with. For this example, you can use the following keyset:

<keyset>
  <key id=”openKey” modifiers=”control” key=”O”
    oncommand=”openDialog();”/>
  <key id=”saveKey” modifiers=”control” key=”S”
    oncommand=”saveDialog();”/>
  <key id=”exitKey” modifiers=”control” key=”E”
    oncommand=”window,close();”/>
</keyset>

You’ll need to associate each of the keys to their respective menuitems, so add a key=”openKey” attribute to the open menuitem, a key=”saveKey” attribute to the save menuitem and a key=”exitKey” attribute to the exit menuitem. Now save the file and access it again via Mozilla, and press Ctrl + o to bring up the open dialog. If you expand the menu yourself, you’ll see that Mozilla has added explanatory text to the relevant menuitems to advise of the keyboard shortcuts that can be used.

This article has given an introduction to the object model used by XUL and has provided a basic example of the combination of Mozilla components and interfaces that make up the abstraction layer.  There is far, far more you can do using a combination of JavaScript and the XPCOM elements, anything in fact that any full-fledged application programming language can achieve.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye