XRDOM (XML Rest Dom API)
From VNetWiki
Web Development > XRDOM (XML Rest Dom API)
XRDOM v1.0 draft 3. (Published January, 30 2011)
XRDOM is an experimental protocol which makes it possible to connect two remote DOM interfaces together.
Contents |
Purpose
The purpose of this protocol is to make it possible to create an interactive web based user interface which can be actively controlled by a web server using DOM operations. The web page implementing this interface is expected to provide the ability to transmit DOM events to the XRDOM access point using AJAX and then perform the DOM operations specified in the response.
The Request Format
Requests are processed by an XRDOM access point which accepts the request using a HTTP transport. For security reasons a confirming implementation SHOULD only accept the request data if it is received using the HTTP POST method. The encoding must use the mime application/x-www-form-urlencoded format.
The request data consists of a single encoded array named dispatchEvent which contains a list of XRDOM events encoded as associative arrays.
Each XRDOM event contains 4 named variables; targetId, eventInfo, handlerId and task.
- (string) targetId - The ID attribute of the element which is listening for the event
- (string) handlerId - This is an identifier used by the XRDOM access point to identify the object responsible for handling the event. An object of the provided name need not exist in the XRDOM access point as long as the XRDOM access point knows which handler should process the request for the provided handlerId.
- (string) task - This is an identifier used by the XRDOM access point to identify a method within the handler object which must be called to process the event. The method name provided is not required to exist within the XRDOM access point as long as the XRDOM access point knows which function or method to call to handle the event.
- (associative array) eventInfo - An associative array containing all of the non-null string, boolean, and numeric attributes of the event as defined in the W3C Document Object Model (DOM) Level 3 Events Specification for that event type. Interfaces are free to send additional attributes which a conforming XRDOM access point should ignore. Objects, functions, null values, and undefined values must be skipped. The XRDOM access point is not expected to maintain a complete image of the document which submitted the request.
- (associative array) formData (optional) - An associative array containing any form data which needs to be attached to the event. An implementation SHOULD fill formData with all form data from the node identified by targetId and all of the target nodes decendents as if the parent node of the target node was a form element.
Note 1: Boolean attributes in the eventInfo array should be encoded as a string value "true" or "false".
Note 2: The XRDOM access point is expected to know the difference between a boolean value of true and a string value of "true" based on the data type specified in the DOM 3 specification for that attribute. The same rule applies to numeric values, if the DOM 3 specification states the value is a string and a number is received, it should be treated as a string such as "123".
Below is how the encoded names should appear, using a portion of a HTML test form as an example.
<!-- ... --> <input type="hidden" name="dispatchEvent[0][targetId]" value="MyButtonId" /> <input type="hidden" name="dispatchEvent[0][handlerId]" value="XRDOMHandler" /> <input type="hidden" name="dispatchEvent[0][task]" value="xrdom_test" /> <input type="hidden" name="dispatchEvent[0][eventInfo][type]" value="click" /> <input type="hidden" name="dispatchEvent[0][eventInfo][ctrlKey]" value="false" /> <input type="hidden" name="dispatchEvent[0][eventInfo][screenX]" value="305" /> <!-- ... -->
The Response Format
The response must be sent as a valid XML file containing a single response element from the XRDOM namespace. The response also MUST use the HTTP Content-Type of text/xml .
XRDOM Namespace: http://standards.vnetpublishing.com/schemas/vwp/2011/01/DOMResponse
The namespace is defined by the schema located at http://standards.vnetpublishing.com/schemas/vwp/2011/01/DOMResponse/.
The response element can contain 3 elements.
- userdoc - Provides an identifier for the document held by the requester, also called the target document.
- data - Provides fragments which can be used in DOM operations. For the purpose of modifying HTML documents, fragments SHOULD contain a namespace declaration using the xmlns attribute. Many implementations will import the fragments directly into the target document. If the proper namespace is not assigned many features such as CSS may not apply correctly if the elements do not have the proper namespace. There are no namespace requirements on fragments, the only requirement is that the content is well formed XML.
- process - Contains the DOM operation requests
The userdoc element has a single attribute of id which identifies the document of the requester.
The data element can contain fragment elements which define XML fragments. Each fragment element has a single required attribute of id which identifies the fragment for request operations. The fragment element SHOULD contain namespace declarations to define the namespaces for the fragment content. This is done using attributes of xmlns or xmlns:(prefix) as defined in the XML Namespaces specification.
In the process element are a series of request elements which define the operations to be performed on the userdoc. Each request element contains 4 required attributes.
- func - Defines the operation type.
- id - Defines an identifier for the result of the operation.
- href - An internal URI refrence to the DOM object the operations is applied to. For fatal errors this should be a reference to the userdoc if one is defined otherwise it may contain an empty string.
- name - The name of the DOM attribute or function in the object identified by the href attribute which is being accessed. For a fatal error the name should be fatalerror.
There are 4 operation types, identified by the func attribute of a request element
- get - Get an attribute from a DOM object
- set - Set an attribute on a DOM object
- call - Call a method in a DOM object
- fatalerror - Report a fatal error and stop processing
Parameters are defined for a request using child param elements which MUST have a xsi:type attribute in the XRDOM namespace where the xsi prefix is defined in the http://www.w3.org/2001/XMLSchema-instance namespace. The XRDOM namespace establishes the following types.
- null - A null value, param tag may include an xsi:nil="true" attribute for additional clarification.
- boolean - A binary value of either true or false
- domstring - A string value
- integer - An integer value
- float - A floating point number
- link - An internal URI reference to the userdoc, a fragment, or the result of a request
Example response:
<?xml version="1.0" encoding="UTF-8"?>
<vdom:response
xmlns:vdom="http://standards.vnetpublishing.com/schemas/vwp/2011/01/DOMResponse"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://standards.vnetpublishing.com/schemas/vwp/2011/01/DOMResponse
http://standards.vnetpublishing.com/schemas/vwp/2011/01/DOMResponse/">
<vdom:userdoc id="a0" />
<vdom:data>
<vdom:fragment id="a1" xmlns="http://www.w3.org/1999/xhtml"><p>Example Fragment</p></vdom:fragment>
</vdom:data>
<vdom:process>
<vdom:request func="call" id="a2" name="getElementById" href="#a0">
<vdom:param xsi:type="vdom:domstring">elemid</vdom:param>
</vdom:request>
<vdom:request func="get" id="a3" name="nodeType" href="#a2" />
<vdom:request func="set" id="a4" name="nodeType" href="#a2">
<vdom:param xsi:type="vdom:link">#a3</vdom:param>
</vdom:request>
</vdom:process>
</vdom:response>
The above response can be accurately processed as the following Javascript commands.
var a0 = document;
var a1 = document.createDocumentFragment();
var tmpptr = xmlhttp.responseXML.getElementById('a1').firstChild;
while(tmpptr != null) {
a1.appendChild(document.importNode(tmpptr,true));
tmpptr = tmpptr.nextSibling
}
var a2 = a0.getElementById('elemid');
var a3 = a2.nodeType;
var a4 = a2.nodeType = a3;
Note the use of the var keyword. Identifiers are not persistent between requests. Currently internet explorer is not DOM 3 compliant and therefore you may need to implement your own document.importNode() function.
Change Log
January, 14 2011 XRDOM v1.0 draft 1.
First Release
January, 15 2011 XRDOM v1.0 draft 2.
Changed javascript code based on operational testing Added provision suggesting the use of a namespace on fragments Added encoding rules for boolean and numeric values Added additional types to the schema and specification Added definitions for the attributes of a request element
January, 30 2011 XRDOM v1.0 draft 3.
Added optional formData attribute to the request format
Related Links
XRDOM Test - View a basic demonstration of this technology
If you have any questions or comments please don't hesitate to post them in our Forums.
Notes
01/22/2011 - Operational Testing Results
1) While doing operational testing of this protocol there seems to be some limitations caused by the lack of flow control features. Many DOM operations require conditional loops for moving data around. As of now the linear nature of this protocol appears to be preferable and an adequate solution seems to be extending the DOM API. By adding the following method to the Node interface it is possible to avoid needing to add process flow control features to the protocol.
// Interface: Node // Description: This method removes all of the child nodes from the provided // hostNode and appends them to the current node, carrying with // them all of the child node decedents and attributes of decedent nodes. // The attributes of the current Node and of the hostNode are not affected. // // Returns: The current node which now has the child nodes from the hostNode Node takeChildNodes(Node hostNode);
The following Javascript code can be used in most Javascript implementations to achieve this feature. If Node prototyping is not supported than the generated alternative method document.moveChildNodes(destNode,hostNode) can be used.
if (typeof(Node) != 'undefined' &&
typeof(Node.prototype) != 'undefined' &&
!Node.prototype.takeChildNodes) {
Node.prototype.takeChildNodes = function(hostNode) {
while(hostNode.firstChild) {
this.appendChild(hostNode.removeChild(hostNode.firstChild));
}
return this;
};
}
if (!document.moveChildNodes) {
document.moveChildNodes = function(destNode,hostNode) {
while(hostNode.firstChild) {
destNode.appendChild(hostNode.removeChild(hostNode.firstChild));
}
return destNode;
};
}
01/25/2011 - Revision
After suggesting a recommendation of takeChildNodes() to W3C one participant suggested using the DOM Traversal Module (Range Model). Please see the related article Re: DOMCore takeChildNodes() method. As of now it appears that issue #1 reported on 01/22/2011 may be resolved using the DOM Traversal Module. More research will need to be done regarding the level of support for the module, but unless the W3C accepts the takeChildNodes() recommendation, the only way to reliably handle the noted issue will be using the DOM Traversal Module.
01/25/2011 - Operational Testing Results
Event bubbling causes multiple events to be sent in groups. If events are sent to the XRDOM access point immediately than one event, such as a mouse click, may lead to multiple XRDOM requests being sent. This causes responsiveness issues in the interface. To resolve this problem while waiting for an AJAX response all intermediate events should be buffered and sent when the processing of the previous AJAX response is complete. A delay should also be implemented to allow time for all bubbling events to be buffered before sending the request. The protocol allows for multiple events to be sent in a single request which should maintain efficiency in complex systems.
There may also be some issues related to fast firing events such as mousemove events. Operational testing on fast firing events still needs to be done.
Next: End