Mozilla DevCenter    
 Published on Mozilla DevCenter (http://www.oreillynet.com/mozilla/)
 See this if you're having trouble printing code examples


Creating Applications with Mozilla

Remote Application Development with Mozilla

by Brian King, coauthor of Creating Applications with Mozilla and Myk Melez

Editor's Note: This article will explore the uses for remote XUL (loaded from a Web server), contrast its capabilities with those of local XUL (installed on a user's computer), explain how to deploy remote XUL, and give examples of existing applications. This will give you a firm grasp on the potential uses for remote XUL, its current limitations, and how to start using it to enhance your Web sites and applications.

Web sites and applications have traditionally used HTML to construct their user interfaces, but HTML has a limited set of features for building UIs. The language's basic form controls (text fields, drop-down menus, buttons), hyperlinks, and content-centric layout model are adequate for many Web interfaces, but they do not provide the same level of usability as GUI toolkits designed for building applications. HTML was designed for content, not interactivity.

XUL, on the other hand, was designed specifically for creating application interfaces. It was originally used to build the interface for Mozilla, a desktop application, but because Mozilla can load XUL files from a remote Web server, it can also be used to build Web applications and sites. XUL has a comprehensive widget set and an application-centric layout model well-suited to organizing UI widgets in application interfaces. These features make XUL an attractive alternative to HTML for building Web applications and adding interactivity to Web sites.

You might use remote XUL to provide a tabular report whose columns can be individually sorted, resized, and shown or hidden without repeatedly reloading the data from the server. You could use it to add sophisticated menu-based navigation to your Web site. Or you might write a game in XUL and distribute it via the Web. Remote XUL applications can be as simple as a single XUL file or span dozens of XUL, XBL, JavaScript, CSS, and RDF files.

Remote vs. Local: Similarities and Differences

Remote XUL is similar to local XUL in a number of key ways. In both cases the XUL files are identified by URLs, and Mozilla, when given such a URL, renders it identically regardless of where it is located. This means you can use Mozilla's -chrome command-line option to start both local and remote XUL applications in the same way:

./mozilla -chrome chrome://navigator/content/

(starts the Mozilla browser)

./mozilla -chrome http://bugzilla.mozilla.org/duplicates.xul

(starts a remote XUL application)

Related Reading

Creating Applications with Mozilla
By David Boswell, Brian King, Ian Oeschger, Pete Collins, Eric Murphy

A chrome:// URL is a Mozilla-specific protocol for files in Mozilla's chrome directory, which stores files related to the Mozilla application interface. You can also type these URLs into the location bar of the Mozilla browser. In both cases, the browser will load and render the application within its content pane. Loading an instance of the browser within another browser window isn't very useful, of course, but the point is that Mozilla treats these two very different XUL applications the same when loading and rendering them.

Remote XUL files also use URLs to identify JavaScript scripts, CSS stylesheets, XUL overlays, and XBL bindings just like local XUL files use them. Relative URLs in remote XUL files are resolved relative to the Web server root or the remote XUL file, just as they are in HTML files loaded from a Web server.

Local and remote XUL differ in key ways, however. In particular, Mozilla places security restrictions on remote XUL that it does not place on local XUL. These restrictions are the same ones it places on remote HTML applications. While local XUL has unlimited access to the user's machine, including the ability to read and write local files and access remote servers, remote XUL has no filesystem access and can only contact the server it was loaded from unless the XUL and JavaScript files are digitally signed and the user explicitly permits such access. Code that attempts to access restricted services without being signed will fail silently.

For development purposes, you can overcome this limitation by manually adding the following line to the prefs.js file in your Mozilla profile directory, which will enable scripts to gain access to the services without being signed:

user_pref("signed.applets.codebase_principal_support", true);

Make sure you edit the preferences file while Mozilla isn't running (or else it will overwrite your changes when you quit), and remember that when you deploy your XUL application you should sign it to ensure your users' security.

Mozilla also doesn't support loading DTD files remotely, so you can't use them to localize your Web application. You can, however, load a DTD by including it in the content of the XUL file itself, so you could use HTTP 1.1 content negotiation to serve different localized versions of your remote XUL file depending on the user's locale preferences.

Finally, local XUL has been used much longer and received much wider testing and deployment than remote XUL, which is a relative newcomer to the Mozilla and Web development scenes. Local XUL has been used to build and deploy major applications like the Mozilla suite itself, the Komodo IDE, and the Crocodile Maths educational application, while there are no known major deployed remote XUL applications. Remote XUL is thus less mature and more prone to bugs (of which the known ones are tracked in the Bugzilla meta-bug report).

Still, remote XUL is already a viable approach to building applications, and a good example of this is the mozdev.org games project, which hosts a number of games including Snake, Solitaire, and Xulmine. All games on the site can be installed on your local machine or loaded into your browser and run remotely with installation. In both cases the games have the same functionality.

Serving It Up

Serving XUL files remotely is almost as simple as putting them on a Web server and pointing your users to them. However, you have to make sure your Web server identifies the files as the appropriate MIME type, which for XUL files is application/vnd.mozilla.xul+xml. If your application uses RDF files, make sure those are identified as application/xml.

mozilla.org's duplicate bugs report is an example of a XUL file served remotely.

mozilla.org duplicates report
mozilla.org duplicates report

In addition to serving XUL files themselves, you can also insert fragments of XUL into HTML files. This could be useful, for example when providing XUL-based navigation for an HTML Web site. To use XUL this way, you must define it in an XBL file and then use CSS to bind the XBL file to the HTML file, thus inserting the XUL into the HTML document's DOM.

Here's an example of XUL in HTML, an experimental version of the mozilla.org home page with a new XUL-based navigation bar instead of the existing HTML-based sidebar.

mozilla.org web site w/XUL navigation bar
mozilla.org website w/XUL navigation bar

Note that you can't bind the XBL to an arbitrary element like you can with XBL in XUL. You must bind it to a regular HTML element like a SPAN or a DIV. The code that binds the XBL is as simple as the following line from that experimental home page:

<div style="-moz-binding: url('menu.xml#menu');"></div>

You should also be able to insert XUL directly into XHTML files, but a bug in Mozilla currently prevents this from working. See the bug report for the details.

Database Support

Databases, or more specifically interaction with databases, is what makes many Web applications tick. Work is underway on a feature that adds database support to Mozilla. This is still an experimental feature, not available in nightly or milestone builds yet, but it is being actively worked on, and there is an installable component available in the bug monitoring this feature. Database connectivity is not exclusive to remote applications, but this is an arena where it can thrive.

Why is this feature important? Web applications have traditionally been implemented with three tiers in which the middle tier is an application server that handles interactions between the client browser and the database server. Native database support makes it possible for a Mozilla-based application to eliminate the middle tier and communicate directly with the database server, reducing the complexity and cost of implementing such apps.

The caveat is that functions ordinarily performed by the application server, like authentication and authorization, must then be handled by the database server. But such functions are typically built into database servers anyway, since two-tier client-server applications with a database backend were common before three-tier Web applications became popular. Mozilla can truly come into its own as a remote application framework with database access APIs that are easily available for populating UI widgets with data.

Like much of the Mozilla codebase, database support is designed to be cross-platform. The initial implementation supports only PostgreSQL databases, but adding other SQL databases (MySQL, Oracle, Informix, Sybase, etc.) is on the agenda. There is no plan to support non-SQL database systems.

To see an example of the database support (also known as mozdb) in action, first make sure you have PostgreSQL libraries installed on your system. Some Linux distributions come with the PostgreSQL libraries installed by default, and Windows users can get them by downloading libpq.dll from the bug report and installing it into their system directory or another suitable location.

Next install mozdb by loading the latest available installer attached to the bug report. Installers are the attachments with a .xpi extension; as of this writing, the latest versions are the ones attached on December 14 for Windows and Linux.

Then restart Mozilla and configure a database alias in the Database support panel of the Mozilla global preferences.

Adding an alias
Adding an alias

Configure an alias to run against your own PostgreSQL server per the directions in the bug report, or use the following settings to access a publicly available server hosted by Eric Gentilini of the PostgreSQL community.

     Name: mozdbtest
     Type: pgsql
 Hostname: egentili.net1.nerim.net
     Port: 5432
 Database: mozdbtest

Finally, run the example application bundled with mozdb by loading it in Mozilla or running Mozilla with the -chrome command line option set to chrome://mozdb/content/test/test.xul. When prompted for a username and password, use mozdbdemo for both. You will see a page with three tabs for different kinds of examples, including the following example of a XUL menu list and tree populated with data from the database.

Database query results in XUL
Database query results in XUL

Here is a code example illustrating how to set up a database connection via the mozdb XPCOM service.

function init() {
  var service = Components.classes["@mozilla.org/mozdb/service;1"]
                .getService(Components.interfaces.mozIDbService);
  try {
    connection = service.getConnection("urn:aliases:test");
  }
  catch (ex) {
    alert(service.errorMessage);
  }
}

This code first accesses the mozIDbService service and then calls its getConnection method to initialize a connection to the database server. Once a connection is initialized, you can use it to run queries and then populate trees, menulists, and grids with their results by retrieving them as RDF data sources. Here is a code example of a database query that populates a XUL tree in this way:

var code = document.getElementById("asyncStateCode").value;
var query = "select name from states where code = '" + code + "'";
var request = connection.asyncExecuteQuery(query, null, observer);
...
var ds = result.QueryInterface(Components.interfaces.nsIRDFDataSource);
var tree = document.getElementById("statesTree");
tree.database.AddDataSource(ds);
tree.builder.rebuild();

For simple queries, for example those that retrieve only a single table, results are editable, and synchronization of edited data with the remote database is automatic. Queries and updates can be executed either synchronously or asynchronously. In addition to RDF, you can also retrieve data as JavaScript objects.

Exchanging Information

Many new Web technologies are emerging to support the growing area of Web services. Standards are still being developed, and technologies are jockeying for position, but SOAP and XML-RPC have already achieved some measure of success as protocols for communicating between Web services and client applications.

We won't cover those protocols in this article. The Mozilla SOAP API has already been covered in a previous article on the DevCenter and is documented online, while the XML-RPC API is documented online in several places available from its project page.

In addition to those protocols, Mozilla provides an XMLHttpRequest component for lightweight communication between client applications and remote HTTP servers. The component allows client apps to establish a connection to a server, send and receive data, construct DOM trees from XML data, and so on. It has a simple API, which is easy to use. The following code sample demonstrates using it to retrieve an XML document:

  var request = new XMLHttpRequest();
  request.open("GET", "http://www.example.com/document.xml", false);
  request.send(null);

  // request.responseText now contains the document as a string
  // request.responseXML contains the document as a DOM tree

XMLHttpRequest places no restrictions on the kind of XML data you can exchange. It doesn't even have to be valid XML, although it won't be able to parse the data into a DOM tree unless it is. You can still use invalid XML, e.g. an HTML file, in its unparsed state as a text string.

Although it isn't a remote application, the "tinderstatus" Mozilla extension described in the Creating a Mozilla Extension tutorial is a good example of how to use the XMLHttpRequest component to retrieve data from a remote server. It uses the component to fetch a remote file with information about the current state of the Mozilla source code.

XMLHttpRequest is part of the XMLExtras module, a set of Mozilla features for manipulating XML as data. The XMLExtras module is built by default and included in all releases and nightly builds of Mozilla, so it's available to any remote application that wants to take advantage of it.

Final Thoughts

Mozilla provides a variety of technologies for building remote XUL applications, from support for remote XUL itself to APIs for communication with remote Web, application, and database servers. These technologies together make Mozilla a robust platform for the next generation of Web sites, applications, and services.

For more information about developing remote XUL applications, including how to generate XUL using scripting languages like PHP and Perl, see chapter 12 of the book Creating Applications With Mozilla.

In our next article, we'll delve into the details of one or more remote XUL applications and show you how they work.

Brian King is an independent consultant who works with web and open source technologies.

Myk Melez has been working with Mozilla since 1999, when he started using the browser as a DHTML application platform.


Return to the Mozilla DevCenter.

Copyright © 2009 O'Reilly Media, Inc.