Tour of XAP Source Code

Getting Started

This tour assumes you are familiar with the architecture overview on the XAP web page

Codebase Layout

XAP code is located in the codebase/src folder of SVN. That in turn has three entries:

Namespace Handlers and Page Processing

Namespace handlers are a key component of the XAP architecture. A namespace handler is a piece of code that recognizes a certain namespace and does some processing based on those tags. When a XAL page is processed the following steps take place:

These namespace handlers include:

In addition there are namespaces that provide data support, initial creation of the UI without the need for xmodify, etc.

Instantiating and Modifying the UI

XAP maintains a client-side UI document, which is an XML document that is similar to the HTML document saved by a web browser. Whenever this XML UI document is modified those modifications result in on-screen changes.

XML Structure Events

The XML documents used by XAP fire events to listeners when changes are made to elements within the document. Whenever a child is added or removed, or an attribute is changed, interested listeners will receive notifcation that the change took place.

Plugin Tag Mapping Files

The default tag mapping file is located in taghandling/plugin.xml. This file specifies how XML tags in the UI namespace map to classes that implement those tags.

UI Creation Workflow

An instance of taghandling/PluginDocumentHandler.js listens to the XML UI document events. Whenever a new tag is added to the UI document (using the DOM APIs or through the use of xmodify)this class will instantiate a bridge class based on the contents of the plugin.xml file. This bridge class is then responsible for modifying the HTML document to make appropriate onscreen changes.

Bridge Classes and Peer Objects

A bridge class is a class that connects an XML element to the HTML onscreen representation, typically though a peer class.

Consider the case of <window>. When the user adds a <window> tag to the XML document they expect a window to appear onscreen. The Dojo widget library offers a window implementation we can use. What is needed is a translation layer that can inspect the <window> tag and configure a Dojo window widget based on that tag.

A bridge class serves as this translation layer, and has two primary responsibilities:

In this case consider a <textField> tag. If the user uses the DOM API to change the text attribute of the tag, we expect the onscreen text to change. In addition if the user types into the text field and hits enter we expect the text attribute of the XML element to reflect the new text, and we might also expect some event to fire informing us that the editing is finished.

Translating XML Changes to Peer Modifications

A typical bridge class listens for changes on the XML element it is responsible for, using the change notification events described previously. When an attribute on an XML element is changed dynamically the bridge class is notified and makes the appropriate calls to update the widget.

Responding to Widget Events

Just as a bridge class listens for XML events, it also listens for events on the underlying widget. When events occur on that widget the bridge class writes back into the XML element if needed, and fires events as well. How the bridge listens to the widget events depends on the widget itself. Standard dojo widgets can have listeners to specific methods added via dojo.event.connect()

Bridge Base Classes

There are a number of base classes to make bridge development easier.

TextFieldBridge - An Example Dojo Widget Bridge

bridges/dojo/TextFieldBridge.js is a good example of a medium complexity bridge class. It does the following:

Supporting common attributes comes for free by extending DojoWidgetBridge. Supporting new attributes is a two step process:

You can see that in the TextFieldBridge setTextAttribute() takes the argument, which is the new value of the text attribute, and passes it to a function on the widget itself that does the work. setMaxLengthAttribute() also calls a function on the widget but does some extra work to truncate the existing text if it is currently too long.

Supporting events is done in TextFieldBridge by using dojo.event.connect() to listen for keyup, textchange and mouseout on the underlying widget. When the underlying widget receives a keyup the onTextChange() method in TextFieldBridge is called. This method checks to make sure the text has actually changed and if so updates the text in the XML DOM using writeBackAttribute() and fires an event using fireEvent(), two methods provided by the base class.

xap/CodeTour (last edited 2009-09-20 23:05:44 by localhost)