"Hello World" XUL application with XULRunner

Today, I do spend some hours with the XULRunner -- a Mozilla runtime package which can be used to bootstrap XUL+XPCOM applications that are as rich as Firefox and Thunderbird. I will create a "Hello World" XUL application step by step, just to remind myself. I will be very glad if it is also helpful for you. :)
今天,闲暇无事,花了几个小时玩耍了一下 XULRunner -- 一个 Mozill 运行库,以及 XUL+XPCOM 应用程序的启动器,利用它可以构建 Firefox 和 Thunderbird 一样的应用程序。我用它写了一个简单的 "Hello World" XUL 应用程序,在这里我把程序创建的过程一步一步地记录下来,主要是对自己的学习做一个笔记。希望它也能对其他人有所帮助。

About XULRunner

XULRunner is a Mozilla runtime package that can be used to bootstrap XUL+XPCOM applications that are as rich as Firefox and Thunderbird. It will provide mechanisms for installing, upgrading, and uninstalling these applications. XULRunner will also provide libxul, a solution which allows the embedding of Mozilla technologies in other projects and products. [Ref: http://developer.mozilla.org/en/docs/XULRunner]
Main features
  • Networking
  • Gecko rendering engine
  • DOM editing and transaction support (no UI)
  • Cryptography
  • XBL (XBL2 planned)
  • XUL
  • SVG
  • XSLT
  • XML Extras (XMLHttpRequest, DOMParser, etc.)
  • Web Services (SOAP)
  • Auto-update support (not yet complete)
  • Type ahead find toolbar
  • History implementation (the places implementation in the 1.9 cycle)
  • Accessibility support
  • IPC services for communication between gecko-based apps (not yet complete)
  • Storage/sqlite interfaces (not yet turned on by default)


For current 1.8.0.x release, XULRunner only available in ZIP format, you can download it and unzip at any place you want.
Refer: http://developer.mozilla.org/en/docs/XULRunner:Deploying_XULRunner_1.8

Skeletons of a XUL Application

I name my "Hello World" application as HelloWorldApp or helloworldapp,

- app files ...
All the folders/files are necessary for a XUL application, "app files..." will be variant, it depends on your application itself.

Define the XUL application.ini

This is the application.ini of the helloworldapp:

; This field specifies your organization's name. This field is recommended,
; but optional.
; This field specifies your application's name. This field is required.
; This field specifies your application's version. This field is optional.
; This field specifies your application's build ID (timestamp).
; This field is required.
; This field specifies a compact copyright notice for your application. This
; field is optional.
Copyright=Copyright (c) 2004 Mozilla.org
; This ID is just an example. Every XUL app ought to have it's own unique ID.
; You can use the microsoft "guidgen" or "uuidgen" tools, or go on
; irc.mozilla.org and /msg botbot uuid. This field is optional.

; This field is required. It specifies the minimum Gecko version that this
; application requires.
; This field is optional. It specifies the maximum Gecko version that this
; application requires. It should be specified if your application uses
; unfrozen interfaces.

You must specify the [App] name. It will be used for XULRunner to find the relevant prefs.js .
App::name 必须要指定,因为它将影响 XULRunner 如何读取 prefs.js 。

Define the prefs.js (helloworldapp-prefs.js) / 定义应用程序的 Preferences.

After the application.ini is defined, it is necessary to have a -prefs.js under ${APP_ROOT}/defaults/preferences
Here is the helloworldapp-prefs.js
定义了 application.ini 之后, 下一步就是指定 -prefs.js , 在这里我们的 是 helloworldapp, 因此我们需要在 ${APP_ROOT}/defaults/preferences目录下面建一个 helloworldapp-prefs.js JavaScript 文件,文件的内容如下:
pref("toolkit.defaultChromeURI", "chrome://helloworldapp/content/helloworld.xul");
pref("general.useragent.extra.helloworldapp", "HelloWorld/0.1");
It define "toolkit.defaultChromeURI" to "chrome://helloworldapp/content/helloworld.xul" .
其中最主要的部分就是定义了,"toolkit.defaultChromeURI" , 它就是 XUL 程序的缺省启动页面。

Setting up chrome.manifest / 设定 chrome.manifest

This file performs the mapping between a chrome:// url and your application files:

这个文件主要用来实现 XUL 程序中使用的 chrome:// scheme 和你自己编写的应用程序文件的对应。

This is the chrome.manifest of "Hello World" application.

Hello World 程序的 chrome.manifest 文件的内容如下:

content helloworldapp file:helloworldapp/
This institution tells XULRunner to look at ${APP_ROOT}/chrome/hellowworldapp/ when it encounters a chrome://helloworldapp/content/ URI. The change of the application name and folder name will impact the URI looking up of XULRunner.
通过这个指令,我们告诉 XULRunner,当程序中 URI 为 chrome:://helloworldapp/content/ 的时候,就到 ${APP_ROOT}/chrome/hellowworldapp/ -- 应用程序的chrome目录下面的helloworldapp 目录下面去寻找相应的文件。 我们也可以相应的改变 上面的语句中的 application name 以及目录的名字,但是这个改变将影响 XULRunner 如何解释以 chrome:// 为类型的 URI 的定位。 进一步的内容可以参考 ITArt 同志的Blog http://itart.wordpress.com/2005/12/05/mozext-ch3/ 第3.6章。

Chromes / 全金属外壳

To make it easy for the development, we are using the plain folder/files for the chrome.
为了方便进行开发和调试,在这直接使用文件和目录来保存 chrome 文件。

Most XUL applications are distributed as a .jar file, rather than a subfolder of chrome/ with all the files scattered about. When you do want to deploy it as a jar:

  1. Zip up your /chrome/applicationName folder, put the applicationName.zip in the /chrome directory.
  2. Rename applicationName.zip to applicationName.jar
  3. Change the chrome.manifest to point to applicationName.jar:
    content applicationName jar:applicationName.jar!/
The "jar:" protocol tells XULRunner that this is a jar file. With "jar:filename.jar!/uri/folder/", XULRunner will look for the resource under the give folder "/uri/folder/" in the JAR file.
"jar:" 协议,用来通知 XULRunner 所需要要得资源文件都被包裹在 JAR 文件中。"jar:filename.jar!/uri/folder/" 为 XULRunner 指名相应的资源需要去 filename.jar 文件的 /uri/folder/ 目录下面寻找。

Build the GUI with XUL / 使用XUL来构建 GUI

In the perfs.js, the toolkit.defaultChromeURI was defined as "chrome://helloworldapp/content/helloworld.xul", it will be the default GUI of this Hello World application.
在 perfs.js 中, 我们将 toolkit.defaultChromeURI 定义为 "chrome://helloworldapp/content/helloworld.xul", 它就是我们这个Hello World 应用程序的缺省 GUI.

The XULRunner looks up the URI -- "chrome://helloworldapp/content/helloworld.xul" at the ${APP_ROOT}/chrome/helloworld/helloworld.xul . So helloworld.xul will be the main GUI file.
对于 URI -- "chrome://helloworldapp/content/helloworld.xul", XULRunner 将会翻译成 ${APP_ROOT}/chrome/helloworld/helloworld.xul 并且试图使用这个XUL文件作为主 GUI 文件。

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

id = "helloworldapp"
title = "Hello World!"
width = "300" height = "200"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<button label="Hello World" onclick="window.alert('Hello World!');"/>
This is a very simple XUL file which defined a frame window, and there is only a button on it. When the button is clicked, there will be a prompt alert. It just works like HTML.

Ready and Go / 预备跑

Ok, it is time to go. Open a Command Processor window, cd into the ${APP_ROOT}, assuming the ${APP_ROOT} is "HelloWorld", and it is located within the XULRunner's folder, for me, the XULRunner is installed at "e:\devel\xulrunner". We can launch the Hello World application in this way.
好了,该出发了! 请打开一个命令行窗口,并且进入 XULRunner的安装目录, 比如说 XULRunner 被安装在 e:\devel\xulrunner ,HelloWorld应用程序的目录就在 XULRunner的安装目录中。我们就可以按照下面的命令来运行 HelloWorld。
e:\devel\xulrunner>xulrunner.exe HelloWorld\application.ini 
in other words:
${XULRUNNER_HOME}\xulrunner.exe ${APP_ROOT}\application.ini
当然也可以使用上面的方法来运行,这里 ${XULRUNNER_HOME} 和 ${APP_ROOT} 应该被替换成她们实际的全路径名。

We got it, isn't it?

Have Fun~~~