The Mozilla
Organization
At A Glance
Feedback
Get Involved
Newsgroups
License Terms
Newsbot
Developer Docs
Roadmap
Projects
Ports
Module Owners
Hacking
Get the Source
Build It
Testing
Download
Report A Bug
Bugzilla
Bug Writing
Tools
View Source
Tree Status
New Checkins
Submit A Bug
FAQ
Search

XUL Coding Style Guidelines

by Tao Cheng< tao@netscape.com >

Document History

Introduction

XUL, pronounced as /zool/, stands for "XML-based User Interface Language", is a cross platform way of describing user interface. It could contain XUL specific element types for UI controls, HTML4 markups for content data, and even JavaScript for user event handling. To make XUL files easy to read and maintain, localization friendly, and portable across user agents, we need to have a set of coding style guidelines to ensure our objectives are achievable.

The author has collected a set of guidelines from various sources as listed in the References section. While some of the guidelines are recommended practices, the others are mandatory.

In the following sections, several issues will be discussed.

XML, XUL, HTML, and XHTML guidelines

The following are considered good coding style for XML/XUL documents. Disobeying them might not cause any parsing error for now, however, it might cause future maintenance headache.
  • Convert HTML files to XUL files. All UI descriptions written in HTML shall be converted into XUL. Currently, we do not have a clean way of localizing HTML files. XUL is our UI description language. In addition, there are certain XUL specific features, such as XUL fragments, which are supported in XUL content model only.
  • The XML declaration. All XML declaration shall contain the following information:
    • Version number. Version number indicates that this XML document conforms to a particular version of XML specification. It is provided as a means to allow the possibility of automatic version recognition, should it become necessary. Processors may signal an error if they receive documents labeled with versions they do not support [Prolog and Document Type Declaration ].
    • UTF-8 encoding. Wherever applicable, the recommended encoding of the content data and attribute values is UTF-8. [EncodingDecl ]. In Mozilla, when such information is not specified, UTF-8 is the default encoding of all XML, XUL, and RDF documents. Note that  since ASCII is a subset of UTF-8, ordinary ASCII entities do not strictly need an encoding declaration.
    • Style sheet. An XML file must have a style sheet associated with it, otherwise, it won't know how to display the document. Note that, as suggested below in "Configurable Chrome", chrome type URLs shall be used to reference the style sheet. For details, see the "XUL File Preamble" section of David Matejka's  XUL Language  spec.
  • Namespace. In XUL documents, namespace shall default to "xul" and be declared in the root element. Other namespace referenced shall be declared before use and preferably in the root element of the document. See the sample XUL declaration below for illustration.
  • Case sensitivity. Be aware that XML is case sensitive. In compliance with XHTML working draft, all element names and attribute names shall be in lower case.

  • Sample XUL declaration (stolen from XUL Language )

      <?xml version="1.0" encoding='UTF-8' ?>
      <?xml-stylesheet href="xul.css" type="text/css"?>
      <!DOCTYPE window>
      <window xmlns:html="http://www.w3.org/TR/REC-html40"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  • Configurable Chrome. Please refer to Configurable Chrome for details about the concept of Configurable Chrome and the usage of chrome registry.

  • Three XUL style guidelines are proposed:

    • All resource reference in XUL shall use the chrome type URLs instead of hardwired URLs.
    • Place all platform and language neutral files in content/ and skin/ directories.
    • Place all locale and platform sensitive files under their specific sub-directories such as "navigator/locale/en" and "navigator/platform/unix". Note that all languages and platforms are treated equally and stored in their respective sub-directories. Candidates of such files are platform-specific style sheets and language-specific DTD files.
    Why is it important to put language-specific files in locale-specific sub-directories? Because we want to be able to switch between languages on the same user machine. This is essential on UNIX and maybe on other Operating systems. It would also facilitate the implementation of downloadable chrome customized to a user's language and platform characteristics.

    Also note that the support of locale type chrome URLs is not in place, yet. You can start playing with content and skin URLs, though. The earlier we use the chrome URLs for XUL authoring, the sooner we can identify potential problems and fix them.

    A close view of the "Directory Structure" outlined in David Hyatt's Configurable Chrome spec.
    Directory Structure Outline:

    [Mozilla]

    [chrome]
    [navigator]
    [skin]
    [default] navigatorSkin.jar
    ... other files bundled with navigator
    ... ... other skins used by users for navigator ...
    [content]
    [default]
    navigatorContent.jar
    ... other files bundled with navigator ...
    [platform]
    [unix]
    [win]
    [mac]
    [locale]
    [en]
    [es]
    [fr]
    [ja]
    [ko]
    [zh]


    /*... ... ... subdirectories for other specific window types ... */


    [messenger] ...

  • JavaScript code shall be moved out of XUL. Therefore, in stead of puttinig them inline as

  •  
       <html:script>
           ...
           ...
           /* JavaScript code */
           ...
           ...

       </html:script>

    We move them into a foo.js file and declare its URI in the start tag like this
      <html:script src="foo.js" encoding="UTF-8" />
      (Refer to SCRIPT for the official  spec of this syntax)
    The advantages of this are
    • Legibility. The main purpose of the XUL is to describe the UI content. As style information shall be in style sheet, JavaScript code shall be in *.js as well to keep the main XUL file clean. In some XUL files, JavaScript code takes up 20-25% of the length of the file. Often times, we need to go to the very bottom of the file to find the UI descriptions.
    • Maintainability. By putting JavaScript code in external files, we can isolate the function declaration in a separate file. The developer does not need to touch the main XUL to change its runtime behavior.
    • Flexibility. Since the JavaScript code is in an external file, customization can be achieved by switching the JS file. With chrome registry, developers, content providers, or even the end users will be able to edit the registry table to use a customized JS code for their browser client.
  • DTD declaration. The following are extracted from XML Applications
    • Comment declaration shall be included copiously.

    • <!-- There's no such thing as too many comments. -->

    • Comment declarations describing the purpose of a DTD to be included at the start.
    • Each declaration is presented on a separate line. For example,
      •  
        <!ELEMENT e1 (...) >
        <!ELEMENT e1 (...) >
      rather than
         
        <!ELEMENT e1 (...) > <!ELEMENT e1 (...) >
    • Element declaration precedes any attribute list associated with it.
      •  
        <!ELEMENT e1 (...) >
        <!ATTLIST    e1 (...) >
      rather than
         
        <!ATTLIST    e1 (...) >
        <!ELEMENT e1 (...) >
  • Predefined Entities. The following are predefined entities and shall not be redefined in any XUL:
  • Entity Name/Reference Name Symbol Value
    &lt; less than < "&#38;#60;"
    &gt; greater than > "&#62;"
    &amp; ampersand & "&#38;#38;"
    &apos; apostrophe ' "&#39;"
    &quot; quote " "&#34;"

    We also define the entity for EURO SIGN as follows.

    <!ENTITY euro "&#x20AC;" >
  • Other guidelines mentioned in  XHTML Working Draft help you write HTML content in XML documents that are portable across conforming parsers.

Making XUL localizable -- mandatory

In the past, UI (display) related resource descriptions are stored in *.rc (for Windows client) or *.ad (for UNIX client) so that they can be localized for a specific language or culture. In the new world, Mozilla 5.0, this is not true any more. Most of the windows and dialogs in Mozilla will be described using XUL.

To make XUL stream/file localizable, several guidelines need to be adopted and followed to make the translation work easier and less error-prone.

What resources are localizable?

The rule of thumb is- "all resources that contribute to the appearance of the chrome are localizable". Let's take a close look at them.
  • Widget resources
    • All texts in the graphical user interface are localizable. Examples include menu label strings, dialog and windows title strings, tooltip strings, status text, etc.
    • URLs to localizable images. While some icon images in one culture are popularly used, they might not be appropriate in other cultures. We need the ability to customize them to fit local cultures. Note that it is the URL to the image that we will localize instead of the image data itself.
  • Content data. This includes both plain text and HTML tagged data.
  • Style information such as font, size, and color, may need to be localized. For example, while color white is the symbol of purity in one culture, it is a color of sorrow and sadness in another.
  • The geometric layout. We may (rarely we hope) need to modify the layout. For example, some English radio buttons are laid out horizontally, but their German version could make them too wide. Under such circumstance, we might want to arrange them vertically.

How to make them localizable?

In this section, recommendation of how to make XUL based user interface localizable/customizable is presented.

Widget resources -- text entities and their naming convention

To make a widget attribute localizable, its value string must be declared as the value of a text entity and referenced by its entity name.. See the example below for illustration. More information about the proposed solution of XUL localizability can be found here.

In addition, to increase the readability of the XUL file and make entity names self-explanatory, a hierarchical naming scheme is proposed:

The entities to substitute attribute values of a widget shall be named after the widget ID (or widget element names if no ID is assigned.)
For example, if a command button is named backCmd, then its label string resource shall be named as "backCmd.label" and defined as <!ENTITY backCmd.label "Back" > in the external DTD. The general form is
 
elementName.attributeName


See the example below for illustration.
 

Example: a browser.xul and its browser.dtd:
browser.xml
<button id="backCmd"
        img="&backCmd.img;" tooltip="&backCmd.tooltip;" status="&backCmd.status;">
       &backCmd.label; </button>

browser.dtd
<!ENTITY backCmd.label    "Back">
<!ENTITY backCmd.tooltip "Back to previous page">
<!ENTITY backCmd.status "Back to the previous page">
<!ENTITY backCmd.img     "chrome://navigator/skin/TB_Back.gif">

Moving entities to DTDs

If you used to declare entities within XUL files, here is a perl script to move them to external DTD files for you.

What you need to do is:

  1. Save the this perl script to move entities from the internal DTD block to an external DTD file. The script, ent2dtd.pl, works like this:

  2. Usage: ent2dtd.pl [-h] xulORrdf | directory

      ent2dtd.pl takes one or more filenames or directories as input. arguments. It moves entities in 'xulORrdf' into a DTD file in the same directory 'xulORrdf' resides.

      If 'xulORrdf' is a XUL file, the generated DTD file will be named 'xulORrdf.dtd'. If 'xulORrdf' is a RDF file, it will be named 'xulORrdf-rdf.dtd'. All original files are renamed as 'xulORrdf.org' and 'xulORrdf-rdf.org' respectively.

      ent2dtd.pl enters a given directory and its sub-directories to process all *.xul and *.rdf files encountered.

    Options:
      -h Print help (this message)
      -p package_name use package_name in composing the system id. the default is 'l10n'.
    Note:

    Please do not run the script on a processed file!

  3. Assuming the target XUL file is navigator.xul, the script will move all entities into navigator.dtd and assign "chrome://l10n/locale/navigator.dtd" as the system id to this DTD file. You will need to replace the "l10n" part to your package name.
  4. Modify your makefile (config) to 'install' navigator.dtd into chrome/navigator/locale/en-US/.
  5. Manually add the locale provider to your package in the chrome registry. ... ... en-US 
  6. Optionally, take out the base entry since they REALLY shall not be there.
  7. Test your changes and check them (including the *.dtd) in.

Content data

Content data, either in plain text or HTML/XML tagged, need to be declared as general entities in the external DTD and referenced in XUL stream.

In addition,  recommendation of grouping content data and HTML tagged data is provided below.

  • Content containing markups shall be separated from plain text data. Localizing plain text is much easier (and cheaper) than localizing markup tagged data. See the example for illustrations. See the example for illustrations.
  • Content text forming a complete sentence shall be declared in one single entity. We try to avoid placing markups in entity declaration; but the rule, "forming a complete sentence", takes precedence when there is a conflict. Translating broken sentences is not only painful but also error-prone. Here are examples of HTML tagged data which shall be declared as one entity:

  •  
    • A list item (as opposed to the whole list.)
    • A table cell (as opposed to the whole table.)
    • A paragraph (as opposed to the whole chapter).
    • And many others (such as framesets...).
       
      Example:

      A sample HTML tagged content data:

      <html:i>This document is modified but not saved. You will have choices about what to do with it:</html:i>
      <html:ul>
      <html:li>Save it and exit.</html:li>
      <html:li>Save it but do not exit.</html:li>
      <html:li>Exit without saving it</html:li>
      <html:li><html:b>Don't</html:b> exit.</html:li>
      </html:ul>

      Entities to be declared for the document:

      <!ENTITY prompt  "This document is modified but not saved. You will have choices about what to do with it:" >
      <!ENTITY saveNexit         "Save it and exit." >
      <!ENTITY saveNotExit     "Save it but do not exit." >
      <!ENTITY exit                      "Exit without saving it" >
      <!ENTITY dontExit             "<html:b>Don't</html:b> exit." >

      The XUL will be sent to the parser
      <html:i> &prompt; </html:i>
      <html:ul>
      <html:li>&saveNexit;</html:li>
      <html:li>&saveNotExit;</html:li>
      <html:li>&saveNotExit;</html:li>
      <html:li>&exit;</html:li>
      <html:li>&dontExit;</html:li>
      </html:ul>
       

    Note that we try to avoid including markups in entity values unless the markups are within a complete sentence. The rule of thumb is use your judgment.

Style information

Style information shall be described in style sheets such as Cascade Style Sheet, (CSS ), XSL (if supported in the future), etc... Any UI preferences in the XUL must be localizable. References to style sheets must be in chrome URLs.
 

Layout Geometry

Layout shall be described in stylesheet, currently, the Cascade style Sheet (CSS).
 

Localization Notes

Localization notes are the XUL writers' notes to the localizers/translators. They are placed above the actual entity string in the format:
<!-- LOCALIZATION NOTE  (entity.name): content -->
where the "entity.name" is the entity name (id) for the string (entity value) to be localized, and the content provides helpful hints to the localizers. For example:
<!-- LOCALIZATION NOTE  homeBtn.label : Do not translate the entity value "Home". -->
<!-- ENTITY homeBtn.label "Home" -->
 
Properties files are very similar, but use the pound sign instead of <!-- xxxxx-->:
# LOCALIZATION NOTE  entity name : content
We recognize that translation is a subset of localization even though we've consistently referred to our notes as "LOCALIZATION NOTE".

Files not to be localized?

Some files live in the tree but aren't really part of the build; they're just there as programming examples or a kind of source documentation. To prevent them from being localized, you may insert a line of comment following the XML declaration as follows.

    <?xml version="1.0" encoding='UTF-8' ?>
    <!-- DO NOT localize this file: [reason...] it isn't part of the build; -->

When translators see this line, they won't bother to look at the rest of the file.
 

References

Document History (obsolete)

Obsolete

  • (obsolete; ruled out) Using property files. UI developers will place localizable resources in a Java-like-property file. I18/L10n teams will provide a utility tool to parse the property file and generate a DTD file containing all the entity definition needed for the main XUL stream.
  • (obsolete; ruled out) browser.property

  • backCmd.label:Back
    backCmd.img:TB_Back.gif
    backCmd.tooltip:Back to previous page
    backCmd.status:Back to the previous page
Copyright © 1998-2000 The Mozilla Organization.
Last modified October 5, 1999.