XUL documents are XML documents - XUL is an XML language. XULMaker processes XUL documents in one of two representations - as an XML text document, or as an XML DOM. The primary internal representation is an XML DOM. We interactively construct a XUL document by building and manipulating an XML DOM.
Mozilla supports DOM1, DOM2 and DOM3 according to www.w3.org standards. XULMaker uses primarily DOM1 to manipulate the XUL document but also uses DOM3 to use XPath methods to manipulate the XUL document (only in reading the XUL Schema.)
XULMaker uses Mozilla's XML Extras - the XMLSerializer and the DOMParser, to convert the XUL document from XML DOM to XML text and from XML text to XML DOM respectively. (These programs, as of XULMaker v0.40 - Dec2002, are still incomplete and don't do everything as specified and required for XULMaker. Similary, we haven't been able to get DOM3's XPath methods to work as specified.)
We use the jslib
library for all file IO.
(This has been difficult to get working properly. We use corrected
copies of the jslib
files instead of the chrome:
files where necessary.) Note that file IO requires security permissions.
This design currently allows for file IO when running XULMaker as a
chrome:
package. It will not allow file IO when launched
as a file from the browser - either as a remote application or as a local
application.
(Note: The term "view" as used here is a "view object" and is not the same as the term "view" as used to define "view frames" for floating views.)
XULMaker has a number of different views of the XUL document. A change in any one view needs to be immediately reflected in all other views. The views in XULMaker include the following view objects:
DesignDocument
- design view (XUL DOM)<textbox>
) - code view (XUL text). (<textbox>
could become TextDocument
)ExplorerTree
- idtree view (XUL <tree> element node tree)ExplorerList
- idlist view (XUL <grid> element node tree)AttributeInspector
- attributes viewView objects have the following common methods:
addElement(elementType)
- add an element of the element typedeleteElement()
- removes the "active" element.update()
addElement(elementType)
and deleteElement()
) selectElement(id)
onChangeSelectionElement(event)
onClick()
A change in any one view needs to be immediately reflected in all other views. XULMaker uses events and event listeners to communicate changes between these views. Events communicated include:
Adding/deleting elements and attributes starts from XULMaker's UI controller - menubar,
toolbar, key, etc. - UI keystroke and mouse action results in a command being broadcast.
(xulmaker.xul
and its associated XUL overlay files associates
<menuitem>
, <toolbarbutton>
, and <key>
elements with an <broadcast>
element using an observe
attribute.
<broadcast>
elements define the actual listening code with the oncommand
attribute.)
Each view has it's own addElement(id)
and removeElement(id)
methods.
Selection of the "active" element happens as follows. Note that there are two sides to this - the firing of a selection event and the listening to a selection event.
The firing of the selection event happens as follows. All selectable elements in all views
have an onclick
attribute assigned to an onClick()
method in the
respective view. (This onclick
attribute gets assigned when we create the element
in the addElement()
method.) A mouse click on an element in any of these views results
in a call to the onClick()
method for that view. The onClick()
method then fires a selection
event. The firing of the selection event is
accomplished by setting the selection
attribute of the
designated broadcast
element to the selected "active" element. (The designated
broadcast
element has an id
attribute equal to
xm:onChangeElementSelection
.)
In other words, views fire a selection event that carries with it the associated selected element id.
(The selection
attribute is assigned the selected element's id.)
The selection event gets broadcast to all of the other listening views.
The listening to the selection event is accomplished by using the <observe>
element. Each view is given an <observe>
element which identifies the view's
listener with the <observe>
element's onbroadcast
attribute.
This method is typically onChangeElementSelection(event)
. This method gets the
id of the new selection from the broadcast
element and then calls the view's
selectElement(id)
method to actually accomplish the selection of the "active"
element for that view.
The view firing the selection event should discard the event when it receives its own event
(it causes no harm but it is redundant to process it.) This can be done in the
onChangeElementSelection(event)
method.
We define an XMLSchema object. (We can make this generic to XML rather than specific to XUL.) The XMLSchema constructor is called during XULMaker initialization. During initialization we read the XUL Schema ("xul.xsd") and parse it into an XML DOM.
We access the XMLSchema using XPath expressions.
We define a XULSchema object derived from XMLSchema. The XULSchema object has the following methods:
These methods essentially use XPath expressions to access the XUL DOM.
We could create all the required information for XULMaker by having it call these methods during initialization and then storing the information in tables. We can then remove the XUL DOM and subsequently access the information in the tables.
The required tables are currently part of DesignDocument, they should be extracted to XULSchema and probably redesigned for efficiency
The value of this design is that changes to the XUL Specification could be reflected in the XUL Schema and then automatically be reflected in XULMaker without having to make any program changes to XULMaker. Elements and attributes may be deleted or added and automatically show up in listboxes where required.