|
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
-
Predefined Entities. The following are predefined
entities and shall not be redefined in any XUL:
Entity Name/Reference |
Name |
Symbol |
Value |
< |
less than |
< |
"&#60;" |
> |
greater than |
> |
">" |
& |
ampersand |
& |
"&#38;" |
' |
apostrophe |
' |
"'" |
" |
quote |
" |
""" |
We also define the entity for EURO SIGN as follows.
<!ENTITY euro "€" >
-
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:
-
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:
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!
-
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.
-
Modify your makefile (config) to 'install' navigator.dtd into chrome/navigator/locale/en-US/.
-
Manually add the locale provider to your package in the chrome registry. ...
... en-US
-
Optionally, take out the base entry since they REALLY shall not be there.
-
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
|