# XULMaker Project

## Design

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.

### View Objects

(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 view

View objects have the following common methods:

- `addElement(elementType)` - add an element of the element type
- `deleteElement()` - removes the "active" element.
- `update()`
  - updates view from XML DOM (design view) - (used by non-design document views instead of `addElement(elementType)` and `deleteElement()`)
- `selectElement(id)`
- `onChangeSelectionElement(event)`
- `onClick()`

### XULMaker Events

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:

- selection of the "active" element
- adding an element (not communicated to the attributes view)
- deleting an element (not communicated to the attributes view)
- adding an attribute (not communicated to the idtree or idlist view)
- deleting an attribute (not communicated to the idtree or idlist view)

##### Adding or Deleting Elements and Attributes

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

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.

### XML Schema

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:

- getElementList()
- getAttributeListByElement(anElement)
- getAttributeValues(anAttribute)

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.