Dennis’s Weblog

Thunderbird Add-on Design(XUL and XML)

Posted on: October 14, 2008

XUL (XML User Interface Language) is Mozilla’s XML-based language that lets you build feature-rich cross platform applications that can run connected or disconnected from the Internet. These applications are easily customized with alternative text, graphics and layout so they can be readily branded or localized for various markets. Web developers already familiar with Dynamic HTML (DHTML) will learn XUL quickly and can start building applications right away.

In my opinion, XUL is just like HTML,  We can use this language to customize our software view. And use Javascript to assign functions to our program.

When you want to learn how to develop thunderbird Add-on, you should know what is DTD.

For Example:

<?xml-stylesheet href=”chrome://messenger/skin/addressbook/addressbook.css” type=”text/css”?>

In XUL, developers use chrome:// to Locate the root path. In the Chrome folder, messenger is the main file that we need to modify. It contains some jar files. When thunderbird start, it read the XUL files in these Jar to generate it’s view instead of generating at compile time. So what we need to do is to modify these Jar to customize our program.

These Jar file is just a simple zip file that contain some special manifest according to Thunderbird program.  We can simple Unzip it into a folder and then let the Thunderbird to directly read from the folder instead of from Jar, this will simplify our development.

Just like HTML, in XUL we can use some kind of CSS to beautify our program.
<!DOCTYPE window [
<!ENTITY % abMainWindowDTD SYSTEM “chrome://messenger/locale/addressbook/abMainWindow.dtd” >
<!ENTITY % brandDTD SYSTEM “chrome://branding/locale/brand.dtd” >
]>use these external files to verify our file. it’s DTD. Entity is a kind of reference, you can just replace the Entity name with the external file.

<window xmlns=””(XML namespace)
    persist=”width height screenX screenY sizemode”

In this window element, we can assign some attributes, Which is for calling from Javascript. For example “windowtype”
function toAddressBook()
  toOpenWindowByType(“mail:addressbook”, “chrome://messenger/content/addressbook/addressbook.xul”);
Here in javascript it can call the addressbook.
And onload is some kind of EventHandler, it just likes Javascript. If you want to know more details on this topic , refer to it’s website.

function toOpenWindowByType( inType, uri )
 var windowManager = Components.classes[‘;1’].getService();

 var windowManagerInterface = windowManager.QueryInterface(nsIWindowMediator);

 var topWindow = windowManagerInterface.getMostRecentWindow( inType );
 if ( topWindow )
 else, “_blank”, “chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar”);

It is also some kind of Javascript, you just need to refer to it’s website and use this objects.

And the functions In Messenger/mailcore, Messenger can action like a global function, In your add on program XUL file can directly refer to it without designating path or other thing.

By the way, when we write our add-on, it evently will be merge to main program’s XUL file according to XML regulate(match the same element and merge). It seem to use Install object , you can refer to the website.
if (!(‘extensions’ in window))//simply use in to judge whether there are extension element in window. And then it can define a new field for the object .
    window.extensions = new Array();

if (!(‘mook’ in window.extensions))
    window.extensions.mook = new Array();

if (!(‘minimizetotray’ in window.extensions.mook))
    window.extensions.mook.minimizetotray = use the method we can assign some functions to the array.
        // this is a stub only
        throw Components.results.NS_ERROR_ABORT;

.trayCallback =
function ( aEvent, aParam, aKeyMask, aMouseX, aMouseY ) {
    // note that |this| is the function itself         In Javascript we can use object-oritented, google!




<!ENTITY  cmd.totray.label        “最小化至系统栏”>
<!ENTITY  cmd.totray.accesskey    “小”>
<!ENTITY  cmd.totray.key          “最”>
<!ENTITY  cmd.totray.modifier     “accel,shift”>

<!– tray popup –>
<!ENTITY  cmd.restore.label       “还原窗口”>
<!ENTITY  cmd.restore.accesskey   “R”>
<!ENTITY  cmd.newwindow.label     “新建窗口”>
<!ENTITY  cmd.newwindow.accesskey “O”>
<!ENTITY  cmd.downloads.label     “查看下载项”>
<!ENTITY  cmd.downloads.accesskey “V”>
<!ENTITY  cmd.close.label         “关闭窗口”>
<!ENTITY  cmd.close.accesskey     “C”>
<!ENTITY  cmd.quit.label          “退出快速启动”>
<!ENTITY  cmd.quit.accesskey      “E”>
<!ENTITY  cmd.cancel.label        “Cancel”>

<!DOCTYPE overlay [
<!ENTITY % extensionDTD SYSTEM “chrome://minimizetotray/locale/browser.dtd”>
In XUL, it use this code snippet to refer to the DTD.

  <menupopup id=”menu_FilePopup”>
      accesskey=”&cmd.totray.accesskey;”  Here it refer to the DTD, and Program will replace this reference with the string in the DTD.

So this is Entity, it is a kind of reference.   Format:   & entity_name  ;
      key=”extensions.mook.minimizetotray.key.menuitem”//this kind action just like a namespace. It assing a key attribute to the menuitem.
      oncommand=”window.extensions.mook.minimizetotray.minimizeWindow();”//Call the method defined before.


Conclusion: XUL is just like Html, and use Javascript to give the program functions. Use CSS to beautify your program.

At the same time we should know what is DTD, and how to use it. About XML, we should know how to read element/node or trverse them.






Build a Thunderbird add-on:


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: