Using XUL prefwindow and prefpanes

The combination of <prefwindow> and <prefpane>‘s provides Firefox addon developers with an effective mechanism for creating a preferences dialog. The best example of <prefwindow> usage is the Firefox options dialog.

This tech note will focus on getting all the elements of the <prefwindow> framework right as it is fairly easy to miss one small element, leaving you scratching your head. Below is a screenshot of the end result.

Setting up the <prefwindow>

The code below a minimal <prefwindow> page with two <prefpane>‘s. If only one <prefpane> is used, the navigation bar is not displayed. When two or more <prefpane>‘s are used, a navigation bar is added at the top of the page.

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

<prefwindow id="modifyheadersPreferences"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    style="width: 42em; min-height: 37.5em;">

    <prefpane id="paneProfiles" label="Profiles"
        src="chrome://modifyheaders/content/profiles.xul"/>
    <prefpane id="paneHeaders" label="Headers"
        src="chrome://modifyheaders/content/headers.xul"/>
</prefwindow>

For this example, the contents of each <prefpane> are contained in external files, but you can place content directly between <prefpane> start and end tags. No content should appear above between the opening <prefwindow> element and the <prefpane> elements. If any scripts or other content must be defined, place them after the last <prefpane>.

Defining <prefpane> panels

There are several rules for defining <prefpane>s in external files:

  1. The root tag must be an <overlay>.
  2. The id of the <prefpane> must match the id specified in the <prefwindow>
  3. A <preferences> element must be specified, even if it is empty

Here is an example for the <prefpane> with id="paneProfiles".

<?xml version="1.0"?>
<overlay id="modifyheaders-profiles-overlay"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <prefpane id="paneProfiles" label="Profiles">
        <preferences/>
        <vbox id="modifyheaders-profiles">
            <description>Edit Site Profiles</description>
        </vbox>
    </prefpane>
</overlay>

This markup is repeated for each <prefpane> you need to define. Only the id attribute must be unique.

Opening the <prefwindow> using javascript

This is the bit that caught me out. You have to be careful about which features are specified for the window. Typically for a XUL dialog, you would use:

window.openDialog("chrome://modifyheaders/content/dialog.xul", "modifyheadersDialog", "resizable,dialog,centerscreen,modal", this);

The third argument lists the features for the dialog. In this case: resizable, dialog, centerscreen, modal. For a <prefwindow>, you have to make sure the toolbar feature is specified. Resizeable can be ignored as it seems to have no affect on this type of window:

window.openDialog("chrome://modifyheaders/content/preferences.xul", "modifyheadersPreferences", "chrome,titlebar,toolbar,centerscreen,modal", this);

That about wraps it up. As you can see, it is straightforward enough. For further information, here are some further references from MDC:

This entry was posted in Firefox, Howto. Bookmark the permalink.