JavaScript: advanced DOM testing

While surfing the Chrome source code I've found an interesting utility library for handling DOM Level 2 tests in XHTML. The author of this small library is the W3C, though no documentation nor commented description has been provided in the source. The Chrome team has further extended it by adding some code at the end of the file. There are a few comments here and there that should indicate the purpose of each component. After viewing the code, this resource looks more a collection of components than a complete library. However, there are some components that catch the eye for their usefulness. For example:

function EventMonitor() {
  this.atEvents = new Array();
  this.bubbledEvents = new Array();
  this.capturedEvents = new Array();
  this.allEvents = new Array();
}

EventMonitor.prototype.handleEvent = function(evt) {
    switch(evt.eventPhase) {
       case 1:
       monitor.capturedEvents[monitor.capturedEvents.length] = evt;
       break;
       
       case 2:
       monitor.atEvents[monitor.atEvents.length] = evt;
       break;

       case 3:
       monitor.bubbledEvents[monitor.bubbledEvents.length] = evt;
       break;
    }
    monitor.allEvents[monitor.allEvents.length] = evt;
}

This object, called EventMonitor, use the DOM Level 2 property eventPhase of the Event object to check what's the current state of an event during event phases. This should be the standard way to handle such situations, but, unfortunately, Internet Explorer 8 and lower doesn't support the above code, having a completely different event implementation.

Another object, called HTMLBuilder, features an interesting method to clone various node types:

HTMLBuilder.prototype.cloneNode = function(srcNode, doc) {
   var clone = null;
   switch(srcNode.nodeType) {
      //
      //  element
      case 1:
      clone = doc.createElementNS(srcNode.namespaceURI, srcNode.nodeName);
      var attrs = srcNode.attributes;
      for(var i = 0; i < attrs.length; i++) {
          var srcAttr = attrs.item(i);
          clone.setAttributeNS(srcAttr.namespaceURI, srcAttr.nodeName, srcAttr.nodeValue);
      }
      var srcChild = srcNode.firstChild;
      while(srcChild != null) {
         var cloneChild = this.cloneNode(srcChild, doc);
         if (cloneChild != null) {
             clone.appendChild(cloneChild);
         }
         srcChild = srcChild.nextSibling;
      }
      break;
      
      case 3:
      clone = doc.createTextNode(srcNode.nodeValue);
      break;
      
      case 4:
      clone = doc.createCDATASection(srcNode.nodeValue);
      break;
      
      case 5:
      clone = doc.createEntityReference(srcNode.nodeName);
      break;
                  
      case 7:
      clone = doc.createProcessingInstruction(srcNode.target, srcNode.data);
      break;
      
      case 8:
      clone = doc.createComment(srcNode.nodeValue);
      break;
   }
   return clone;
      
}

It simply clones element nodes, text nodes, CDATA section nodes, entity nodes, PIs nodes and comment nodes. This can be considered as the basic algorithm behind the DOM Level 2 method cloneNode(), which also accepts a Boolean flag indicating whether events should be cloned as well.

In short, this resource features some interesting things that should be further investigated and studied, especially if you want to get a clear idea of how DOM testing should be handled in a standard, W3C-compliant way.

Leave a Reply

Note: Only a member of this blog may post a comment.