You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by jm...@apache.org on 2007/03/02 23:47:35 UTC

svn commit: r514021 - in /incubator/xap/trunk/codebase/src/xap/xml/dom: Document.js XapElement.js

Author: jmargaris
Date: Fri Mar  2 15:47:34 2007
New Revision: 514021

URL: http://svn.apache.org/viewvc?view=rev&rev=514021
Log:
patched in changes from Michael M

Modified:
    incubator/xap/trunk/codebase/src/xap/xml/dom/Document.js
    incubator/xap/trunk/codebase/src/xap/xml/dom/XapElement.js

Modified: incubator/xap/trunk/codebase/src/xap/xml/dom/Document.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/xml/dom/Document.js?view=diff&rev=514021&r1=514020&r2=514021
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/xml/dom/Document.js (original)
+++ incubator/xap/trunk/codebase/src/xap/xml/dom/Document.js Fri Mar  2 15:47:34 2007
@@ -32,21 +32,16 @@
  * Conceptually, it is the root of the document tree, and provides the 
  * primary access to the document's data.
  *
- * @author ikaplansky
- * @author jmargaris
- * 
  * @see xap.xml.dom.XapElement
  */
  
  /** 
   * Creates a xap.xml.dom.Document instance.
   * @extends google.XDocument
-  * @class The xap.xml.dom.Document object represents an entire XML document. Conceptually, it
-  * is the root of the document tree, and provides the primary access to the
+  * @class The xap.xml.dom.Document object represents an entire XML document.
+  * Conceptually, it is the root of the document tree, and provides the primary access to the
   * document's data.
   *
-  * <br><br>
-  *
   * Listeners may be registered at the xap.xml.dom.Document level to hear changes
   * in the entire document.
   *
@@ -64,7 +59,8 @@
   * @param rootElement The root Element for the newly created document.
   */
 xap.xml.dom.Document = function( rootElement ) {
-	 google.XDocument.call(this);
+	
+	google.XDocument.call(this);
     this._rootElement = rootElement;
     
     this._structureChangeListeners = [];
@@ -72,21 +68,16 @@
     
     this._idToElementMap = {};
     this._prefixToNamespaceMap = {};
-}
+};
 
-xap.xml.dom.Document.prototype = new google.XDocument();
 
+xap.xml.dom.Document.prototype = new google.XDocument();
 
-//-----------------------------------------------------------------------
-// Constants.
-//-----------------------------------------------------------------------
 
 /** @private */
 xap.xml.dom.Document.XML_DECL_WITHOUT_ENC = "<?xml version=\"1.0\"?>";
 
-//-----------------------------------------------------------------------
-// xap.xml.dom.Document Interface.
-//-----------------------------------------------------------------------
+
 /**
  * Creates a new xap.xml.dom.XapElement with the specified name, prefix and namespace.
  * 
@@ -98,7 +89,7 @@
 	if( !localName ) {
     	throw new xap.xml.InvalidXmlException( 
     		xap.xml.InvalidXmlException.NULL_LOCALNAME_MSGID,
-    		new Array( "xap.xml.dom.Document.createElement" ));
+    		[ "xap.xml.dom.Document.createElement" ] );
     }
     
     //note we are passing in NO owner doc here! only is set when node actually
@@ -110,14 +101,16 @@
     e._setNamespaceUri( ns ? ns : "" );
     e._setPrefix( prefix );
     return e;        
-}
+};
+
 
 /**
+ *
  * @return The root xap.xml.dom.XapElement of this xap.xml.dom.Document
  */
 xap.xml.dom.Document.prototype.getRootElement = function() {
 	return this._rootElement;
-}
+};
 
 
 /**
@@ -126,7 +119,8 @@
  */
 xap.xml.dom.Document.prototype.addAttributeChangeListener = function( listener ) {
 	this._attributeChangeListeners.push( listener );
-}
+};
+
 
 /**
  * Removes the specified xap.xml.dom.events.AttributeChangeListener
@@ -134,7 +128,8 @@
  */
 xap.xml.dom.Document.prototype.removeAttributeChangeListener = function( listener ) {
 	return xap.util.ArrayHelper.removeElement(this._attributeChangeListeners, listener);
-}
+};
+
 
 /**
  * Adds a xap.xml.dom.events.StructureChangeListener to this xap.xml.dom.Document
@@ -142,7 +137,8 @@
  */
 xap.xml.dom.Document.prototype.addStructureChangeListener = function( listener ) {
 	this._structureChangeListeners.push( listener );
-}
+};
+
 
 /**
  * Removes the specified xap.xml.dom.events.StructureChangeListener from this xap.xml.dom.Document.
@@ -150,7 +146,8 @@
  */
 xap.xml.dom.Document.prototype.removeStructureChangeListener = function( listener ) {
 	return xap.util.ArrayHelper.removeElement(this._structureChangeListeners, listener);
-}
+};
+
 
 /**
  * Returns the xap.xml.dom.XapElement with the specified id attribute value. The xap.xml.dom.Document 
@@ -160,7 +157,8 @@
  */
 xap.xml.dom.Document.prototype.getElementById = function( id ) {
 	return this._idToElementMap[id];
-}
+};
+
 
 /**
  * Sets the root xap.xml.dom.XapElement on this xap.xml.dom.Document
@@ -184,12 +182,9 @@
 	
 	if ( root) {
 		var event = new xap.xml.dom.events.StructureChangeEvent( null, root );
-        
    
-		this._notifyListenersOfStructureChange
-			( this._structureChangeListeners, event, 'beforeChildAdded' );
+		this._notifyListenersOfStructureChange( this._structureChangeListeners, event, 'beforeChildAdded' );
       
-        
 		// Take the element from the event because they have the
 		// opportunity to change the element in the event.  It is safe to
 		// cast here because the event itself guarantees that root element
@@ -198,8 +193,7 @@
 		this._rootElement = event.getChange();
         
 		if ( this._rootElement.getParent() ) {
-			// remove the to-be root from its current parent and owner
-			// document.
+			// remove the to-be root from its current parent and owner document.
 			this._rootElement.getParent().removeChild( this._rootElement );
 		} 
         
@@ -216,14 +210,13 @@
 		
 		this._addDocumentFragmentToIdMapAndCheckForPrefixCollisions( this._rootElement );
         
-		this._notifyListenersOfStructureChange( 
-			this._structureChangeListeners, event, 'onChildAdded');
-        
+		this._notifyListenersOfStructureChange(this._structureChangeListeners, event, 'onChildAdded');
         
-	} else {
+ 	} else {
 		this._rootElement = null;
 	}
-}
+};
+
 
 /**
  * Returns an XML string representation of this xap.xml.dom.Document.
@@ -233,7 +226,8 @@
  */
 xap.xml.dom.Document.prototype.toXml = function( prettyPrint ) {
 	return this._toStringHelper( prettyPrint, true );
-}
+};
+
 
 /**
  * Returns an XML string representation of this xap.xml.dom.Document omitting all auto
@@ -244,134 +238,158 @@
  */
 xap.xml.dom.Document.prototype.toXmlWithoutAutoAssignedIds = function( prettyPrint ) {
 	return this._toStringHelper( prettyPrint, false );
-}
+};
+
 
 /**
  * @return The string representation of this xap.xml.dom.Document object.
  */
 xap.xml.dom.Document.prototype.toString = function() {
 	return this._toStringHelper( true, false );
-}
+};
 
-	
-//-----------------------------------------------------------------------
-// Private Methods
-//-----------------------------------------------------------------------
             
 /**
+ * Update fragment after adding to this Document
  * @private
+ * @param {XapElement} e Element to be added to this document
  */            
 xap.xml.dom.Document.prototype._addDocumentFragmentToIdMapAndCheckForPrefixCollisions = function( e ) {
+
 	e.ownerDocument = this;
 	this._addIdToElementMapping( e.getAttribute( "id" ), e );
 	this._checkPrefixForCollisionAndRegister( e );
 	e._notifyListenersOnAddedToDocument( this );
-	for( var i=0; i < e.childNodes.length; i++ ) {
+	
+	// update all children recursively
+	for( var i = 0; i < e.childNodes.length; i++ ) {
 		var o = e.childNodes[i];
 		if (o.nodeType==google.DOM_ELEMENT_NODE){
 			this._addDocumentFragmentToIdMapAndCheckForPrefixCollisions( o );
 		}
 	}
-}
+};
+
 
 /**
+ * Update fragment after removing from this Document
+ *
  * @private
+ * @param {XapElement} e Element to be removed from this document
  */            
 xap.xml.dom.Document.prototype._removeDocumentFragmentFromIdMap = function( e ) {
 	delete e.ownerDocument;
 	delete (this._idToElementMap[e.getAttribute( "id" )]);
 	e._notifyListenersOnRemovedFromDocument( this );
-	for( var i=0; i < e.childNodes.length; i++ ) {
+	
+	// update all children recursively
+	for( var i = 0; i < e.childNodes.length; i++ ) {
 		var o = e.childNodes[i];
 		if (o.nodeType==google.DOM_ELEMENT_NODE){
 			this._removeDocumentFragmentFromIdMap( o );
 		}
 	}
-}
+};
 
 
 /**
+ * Remove root Element (if any) fron this Document
+ *
  * @private
  */            
 xap.xml.dom.Document.prototype._removeExistingRoot = function() {
 	if ( this._rootElement ) {
 		var event = new xap.xml.dom.events.StructureChangeEvent( null, this._rootElement );
   
-		this._notifyListenersOfStructureChange
-			( this._structureChangeListeners, 'beforeChildRemoved' );
+		this._notifyListenersOfStructureChange( this._structureChangeListeners, 'beforeChildRemoved' );
         
 		this.removeChild(this._rootElement);
+		
 		this._removeDocumentFragmentFromIdMap( this._rootElement );
          
-      this._notifyListenersOfStructureChange
-          ( this._structureChangeListeners, event, 'onChildRemoved' );
-       
+      	this._notifyListenersOfStructureChange( this._structureChangeListeners, event, 'onChildRemoved' );
 	}
-}
+};
+
 
 /**
+ * Notifies all registered Listeners
+ *
  * @private
+ * @param listeners An array of registered listeneres
+ * @param event Change event object
+ * @param {String} method An onXXX event name
  */            
-xap.xml.dom.Document.prototype._notifyListenersOfStructureChange = function( v, e, method ) {
-	if ( v ) {
-		for ( var i = 0; i < v.length; i ++ ) {
-        	var listener = v[i];
+xap.xml.dom.Document.prototype._notifyListenersOfStructureChange = function( listeners, event, method ) {
+	if ( listeners ) {
+		for ( var i = 0; i < listeners.length; i ++ ) {
+        	var listener = listeners[i];
         	
         	//if the listener has that callback method, call it.
         	if (listener[method]){
-        		listener[method].call(listener,e);
+        		listener[method].call(listener, event);
         		
         		// Handle the case where the event causes the
             	// listener to remove itself.
-            	if ( v[i] != listener ) {
-            		i = i - 1;
-            	}
+            	if ( listeners[i] != listener ) { i = i - 1; }
         	}
-            
-        }
+        } // end for()
     }
-}
+};
+
 
 /**
+ * Adds an element to the id-element map
+ *
  * @private
+ * @param {String} id An Element's Id
+ * @param e An element object
  */            
-xap.xml.dom.Document.prototype._addIdToElementMapping = function( id, e ) { 
+xap.xml.dom.Document.prototype._addIdToElementMapping = function( id, element ) { 
 	if( this._idToElementMap[id] ) {
 		throw new xap.xml.InvalidXmlException(
 				xap.xml.InvalidXmlException.ID_CONFLICT_MSGID, 
-				[id, e.toXml(), this._idToElementMap[id].toXml()]);
+				[id, element.toXml(), this._idToElementMap[id].toXml()]);
 	}
-	this._idToElementMap[id] = e;
-}
+	this._idToElementMap[id] = element;
+};
+
 
 /**
+ * Registers a new NS prefix
+ *
  * @private
+ * @param element An element to check
+ * @throw xap.xml.InvalidXmlException
  */            
-xap.xml.dom.Document.prototype._checkPrefixForCollisionAndRegister = function( e ) { 
-    if( !e.getPrefix()) {
-        return;
-    }
-    if( this._prefixToNamespaceMap[e.getPrefix()]) {
-        var currentNs = this._prefixToNamespaceMap[e.getPrefix()];
-        var newNs = e.getNamespaceUri();
+xap.xml.dom.Document.prototype._checkPrefixForCollisionAndRegister = function( element ) { 
+    
+    if( !element.getPrefix()) { return; }
+    
+    if( this._prefixToNamespaceMap[element.getPrefix()]) {
+        var currentNs = this._prefixToNamespaceMap[element.getPrefix()];
+        var newNs = element.getNamespaceUri();
         if( currentNs != newNs ) {
             throw new xap.xml.InvalidXmlException(
                     xap.xml.InvalidXmlException.PREFIX_CONFLICT_MSGID, 
-                    new Array( e.getPrefix(),
-                    		   currentNs, 
-                               e.getPrefix(), 
-                               newNs ));
+                    [ element.getPrefix(), currentNs, element.getPrefix(), newNs ]);
         }
     } else {
-        this._prefixToNamespaceMap[e.getPrefix()] = e.getNamespaceUri();
+        this._prefixToNamespaceMap[element.getPrefix()] = element.getNamespaceUri();
     }
-}
+};
+
 
 /**
+ *
+ * Converts an XML fragmment to string
+ *
  * @private
+ * @param prettyPrint If we need to add new lines to the output
+ * @param withInternalIds If we need to output internal ids as well
  */            
 xap.xml.dom.Document.prototype._toStringHelper = function( prettyPrint, withInternalIds ) {
-	var elementOutput = "";
+	var elementOutput = '';
 	if( this._rootElement ) {
 		if( withInternalIds ) {
 			elementOutput = this._rootElement.toXml( prettyPrint );
@@ -381,11 +399,12 @@
 		}
 	}
     var sbuf = xap.xml.dom.Document.XML_DECL_WITHOUT_ENC;
-    if( prettyPrint ) {
-    	sbuf += "\n";
-    }
+    
+    if( prettyPrint ) { sbuf += '\n'; }
+    
     // append the toXml of the root element.s
     sbuf += elementOutput;
+	
 	return sbuf;
-}
+};
 

Modified: incubator/xap/trunk/codebase/src/xap/xml/dom/XapElement.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/xml/dom/XapElement.js?view=diff&rev=514021&r1=514020&r2=514021
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/xml/dom/XapElement.js (original)
+++ incubator/xap/trunk/codebase/src/xap/xml/dom/XapElement.js Fri Mar  2 15:47:34 2007
@@ -32,9 +32,6 @@
  * @fileoverview An DOM element node implementation that supports
  * notification of changes.
  *
- * @author ikaplansky
- * @author jmargaris
- * 
  */
  
  
@@ -56,9 +53,10 @@
  * @param id The id attribute to use for the new xap.xml.dom.XapElement
  * 
  */
-xap.xml.dom.XapElement = function(elementName, ownerDoc, parentEl, id ){
+xap.xml.dom.XapElement = function( elementName, ownerDoc, parentEl, id ) {
 	
-	google.XNode.call(this, google.DOM_ELEMENT_NODE, elementName, null, ownerDoc)
+	// params: nodeType, nodeName, nodeValue, ownerDocument
+	google.XNode.call(this, google.DOM_ELEMENT_NODE, elementName, null, ownerDoc);
 	this._namespaceUri = null;
 	this._prefix = null;
     
@@ -74,9 +72,9 @@
    		this.setAttribute( "id", id );
 	} 
 	else{
-		this.setAttribute( "id",xap.util.UidProvider.createId() );
+		this.setAttribute( "id", xap.util.UidProvider.createId() );
 	}
-}
+};
 
 xap.xml.dom.XapElement.prototype = new google.XNode();
 
@@ -84,11 +82,6 @@
 xap.xml.dom.XapElement.prototype.constructor = xap.xml.dom.XapElement ;
 
 
-
-//-----------------------------------------------------------------------
-// Private Constants.
-//-----------------------------------------------------------------------
-
 /** @private */
 xap.xml.dom.XapElement.CANNOT_SET_ID_ATTRIBUTE_WHEN_PART_OF_DOCUMENT = "cannotSetIdAttributeWhenPartOfOwnerDocument";
 
@@ -104,9 +97,6 @@
 /** @private */
 xap.xml.dom.XapElement.s_log = xap.log.Logger.getLogger( "xap.xml.dom.DocumentObjectModel" );
 
-//-----------------------------------------------------------------------
-// Public Class Methods.
-//-----------------------------------------------------------------------
 
 /**
  * Returns true if the ID was a system generated one rather than
@@ -114,36 +104,27 @@
  */
 xap.xml.dom.XapElement.isGeneratedId = function( id ) {
 	return ( id && id.indexOf( xap.util.UidProvider.XAP_ID_PREFIX, 0 ) != -1 );
-}
-
-
-
-//-----------------------------------------------------------------------
-// Private Class Methods.
-//-----------------------------------------------------------------------
+};
 
 
 /**  Appends this class' indentation string to a prexisting string:
- *   @param{int} indent The indentation level.
- *   @param{Swtring}sbuf The string to which to append the indentation.
+ *   @param {int} indent The indentation level.
+ *   @param {String} sbuf The string to which to append the indentation.
  *   @see xap.xml.dom.XapElement.INDENT
- * @private 
+ *   @private 
  **/
 xap.xml.dom.XapElement._writeIndent = function ( sbuf, indent ) {
 	for ( var i = 0; i < indent; i++ ) {
 		sbuf += xap.xml.dom.XapElement.INDENT;
 	}
-}
-
+};
 
 
-//-----------------------------------------------------------------------
-// Public Methods.
-//-----------------------------------------------------------------------
-
 /**
  * Returns the attribute interpreted as a url. That url will be properly
  * qualified based on information stored within this element and attribute.
+ * @param name {String} Attribute name
+ * @return //TODO why do we need it?
  */
 xap.xml.dom.XapElement.prototype.getAttributeAsUrl = function( name ) {
 	var att = null;
@@ -154,26 +135,25 @@
 	    }
 	}
 	
-	if (att==null){
+	if (att === null){
 		return null;
 	}
 	
 	var attValue = att.nodeValue;
 	
-	
 	var baseUrl = att.baseUrl;
 
-	baseUrl = baseUrl || this.baseUrl;
-	baseUrl = baseUrl || "";
+	baseUrl = baseUrl || this.baseUrl || "";
 	return (baseUrl + attValue);
-}
+};
 
 /**
  * Sets an attribute with the given name to the given value.
  * @param{String} name The name of the attribute to set
  * @param{String} value The value of the attribute to set
+ * @param{String} baseUrl The base URL of the attribute to set
  */
-xap.xml.dom.XapElement.prototype.setAttribute = function(name, value, baseUrl){
+xap.xml.dom.XapElement.prototype.setAttribute = function(name, value, baseUrl) {
 	
 	//NOTE this is tricky because NULL values are not ok but "" is ok...
 	//TODO clean this up and check for NULL/UNDEF better
@@ -183,70 +163,76 @@
 	//flag that indicates if we are setting the id att
 	if( "id" == name ) {
  		if ( doc ) {
- 			throw new xap.util.Exception
-      		( xap.util.ResourceDictionary.getMessage
-	    		( xap.xml.dom.XapElement.CANNOT_SET_ID_ATTRIBUTE_WHEN_PART_OF_DOCUMENT, 
+ 			throw new xap.util.Exception( xap.util.ResourceDictionary.getMessage(
+ 				xap.xml.dom.XapElement.CANNOT_SET_ID_ATTRIBUTE_WHEN_PART_OF_DOCUMENT, 
 	      		xap.xml.dom.XapElement.CLASSNAME ) );
 		}
 	}
     
-	var event = null;
-	var attributeChangeListenersExist = 
-	this._doAnyAttributeChangeListenersExist( doc );
-	if ( attributeChangeListenersExist ) {
-		event = new xap.xml.dom.events.AttributeChangeEvent( this, name, value );
+	if ( this._doAnyAttributeChangeListenersExist( doc ) ) {
+	
+		var event = new xap.xml.dom.events.AttributeChangeEvent( this, name, value );
 		this._fireAttributeChangeEvent( doc, event, 'beforeAttributeSet');
+
 		// Listeners have the opportunity to modify the value.
 		// Make sure we get the latest value out of the event.
 		value = event.getNewValue();
-		if ( value == null ) {
-		throw new xap.xml.dom.events.ChangeRejectedException
-			( xap.xml.dom.events.ChangeRejectedException.CHANGE_ATTRIBUTE_TO_NULL_MSGID, 
-			null, null, event );
+
+		if ( value === null ) {
+		throw new xap.xml.dom.events.ChangeRejectedException(
+			xap.xml.dom.events.ChangeRejectedException.CHANGE_ATTRIBUTE_TO_NULL_MSGID, null, null, event );
 		}
-    }
-    
-    if ( attributeChangeListenersExist ) {
-    	event.setNewValue( value );
-    }
-    
-	 google.XNode.prototype.setAttribute.call(this, name, value, baseUrl);
-	 
-	if ( attributeChangeListenersExist ) {
+
+		event.setNewValue( value );
+		
+		google.XNode.prototype.setAttribute.call(this, name, value, baseUrl);
+		
 		this._fireAttributeChangeEvent( doc, event, 'onAttributeSet');
-	}
-}
+		
+    } else {
+    	
+    	// just set the new value
+		google.XNode.prototype.setAttribute.call(this, name, value, baseUrl);
+    	
+    }// end if ( attributeChangeListenersExist )
+    
+	
+}; // end xap.xml.dom.XapElement.prototype.setAttribute
+
 
 /**
  * Removes the attribute with the given name.
  * @param {String} name The name of the attribute to remove.
  */
 xap.xml.dom.XapElement.prototype.removeAttribute = function(name) {
+
 	var doc = this.ownerDocument;
-	if (doc && name=="id"){
-  		throw "Can't change ID of element already in document";
+
+	if (doc && (name == "id") ){
+ 			throw new xap.util.Exception( xap.util.ResourceDictionary.getMessage(
+ 				xap.xml.dom.XapElement.CANNOT_SET_ID_ATTRIBUTE_WHEN_PART_OF_DOCUMENT, 
+	      		xap.xml.dom.XapElement.CLASSNAME ) );
   	}
 	
    var event = new xap.xml.dom.events.AttributeChangeEvent(this, name, null);
    
    this._fireAttributeChangeEvent( doc, event, 'beforeAttributeRemoved');
+   
    // Actually perform the removal:
    google.XNode.prototype.removeAttribute.call(this, name);
    
    this._fireAttributeChangeEvent( doc, event, 'onAttributeRemoved');
-       
+    
+	//IMPORTANT auto-assigning IDs should depend on the document type?
+	//for example data sources should have auto-assigned IDs?   
   	// We never allow elements not to have IDs - if the id attribute tries
 	// to be removed - remove it then reset it with one of our IDs
-	
-	//IMPORTANT does this really make sense? shouldn't this be conditional on
-	//the document type or something like that? Maybe when we add to a doc
-	//that expects IDs we should assign them then instead of here?
- 	if ( "id" ==  name  ) {
+ 	if ( name == "id" ) {
 		setAttribute( "id", xap.util.UidProvider.createId());
    }
-   
-   return name;
-}
+
+}; // end xap.xml.dom.XapElement.prototype.removeAttribute
+
 
 //TODO override replace child?
 
@@ -257,45 +243,50 @@
  */
 xap.xml.dom.XapElement.prototype.insertBefore = function(newNode, oldNode) {
 	return this._insertBefore( newNode, oldNode );
-}
+};
+
+
 /**
  * Appends the given child to this element.
  * 
- * @param {google.XNode} child The child text or element node to append.
+ * @param {google.XNode} newNode The new child text or element node to append.
  */
-xap.xml.dom.XapElement.prototype.appendChild = function(child){
-	return this._insertBefore( child );  
-}
+xap.xml.dom.XapElement.prototype.appendChild = function(newNode){
+	return this._insertBefore( newNode, null );  
+};
+
 
 /**
  * Inserts the new child newNode at the given index.
  * @param {google.XNode} newChild The new child to insert.
  * @param {int} index The index at which to insert the new child
+ * @return {google.XNode} newChild
  */
 xap.xml.dom.XapElement.prototype.insertChildAt = function(index, newChild) {
-	var nChildren = this.childNodes.length ;
+	
+	var nChildren = this.childNodes.length;
+	
 	if(index > nChildren){
 		var event = new xap.xml.dom.events.StructureChangeEvent(this, newChild, index);
 		throw new xap.xml.dom.events.ChangeRejectedException( 
 				xap.xml.dom.events.ChangeRejectedException.REJECTED_WITH_REASON_MSGID,
-		      	["Attempted to insert at invalid index: "+index+"; last child is at nChildren"], 
-		      	null, 
-		      	event 
-		      													);	
-	}
+		      	["Attempted to insert at invalid index: " + index + ", last child is at " + nChildren], 
+		      	null, event);	
+	}// end if()
+	
 	// reduce to known cases:
-	var result = null ;
+	var result = null;
+	
 	if( index == nChildren){
 		// At the end:
 		result = this.appendChild(newChild) ;
 	} else {
-		// This is a bit backwards, but at this
-		// point I'd rather not (e.g.) just copy
-		// most of the code from _insertBefore
 		result = this.insertBefore( newChild, this.childNodes[index] );
 	}
-	return result ;
-}
+	
+	return result;
+	
+}; // end xap.xml.dom.XapElement.prototype.insertChildAt
 
 
 
@@ -303,22 +294,13 @@
  * Removes the given child from this element.
  * 
  * @param {google.XNode} child The child text or element node to remove.
+ * @return {google.XNode} removed child node or null
  */
-xap.xml.dom.XapElement.prototype.removeChild = function(child){
-	var index = 0; //TODO fill in correctly
+xap.xml.dom.XapElement.prototype.removeChild = function(child) {
+
+	var index = xap.util.ArrayHelper.indexOf(this.childNodes, child);
 	
-	//TODO what if o is not a child?  
-	if(!child){
-//		throw new xap.util.Exception
-//                ( xap.util.ResourceDictionary.getMessage
-//                  ( CANNOT_REMOVE_NULL_CHILD, ElementImpl.class ) );
-//	    }
-//	    
-//	    int i = _children.indexOf(o);
-//	    if ( i == -1 ) {
-//	        return null;
-		return null;
-	}
+	if( (!child) || (index == -1) ) { return null; }
 	
 	var doc = this.ownerDocument;
 	var structureChangeListenerExists = this._doAnyStructureChangeListenersExist( doc );
@@ -332,7 +314,7 @@
 	}
 
 	//make the actual change
-	google.XNode.prototype.removeChild.call(this,child);   
+	google.XNode.prototype.removeChild.call(this, child);   
 
 	//if we are removing an element node we have to remove it from
 	//our ID map and clean up owner doc stuff
@@ -347,9 +329,11 @@
 		this._fireStructureChangeEvent( doc, event, 'onChildRemoved');
 	}
 	
-	//TODO child here could be changed by the before event?
 	return child;
-}
+
+};
+
+
 /**
  * 
  * For compatibility with existing code we don't consider
@@ -357,50 +341,49 @@
  * We need to clean this up at some point
  */
 xap.xml.dom.XapElement.prototype.getParent = function() {
-	if (!this.parentNode) return null;
-	if (this.parentNode.nodeType!=google.DOM_ELEMENT_NODE) return null;
+	if (!this.parentNode || (this.parentNode.nodeType != google.DOM_ELEMENT_NODE) ) {
+		return null;
+	}
+
     return this.parentNode;
-}
+};
+
 
 /**
  * Returns the element namespace prefix
  */
 xap.xml.dom.XapElement.prototype.getPrefix = function() {
     return this._prefix;
-}
+};
+
 
 /**
  * Returns the namespace uri for the element.
  */
 xap.xml.dom.XapElement.prototype.getNamespaceUri = function() {
     return this._namespaceUri;
-}
+};
+
 
 /**
- * TODO should we differentiate between local name
- * and nodeName? Technically we should but then xpath
- * needs to use localName instead of nodeName or 
- * something like that?
+ * Returns node name for the element
  */
 xap.xml.dom.XapElement.prototype.getLocalName = function() {
     return this.nodeName;
-}
+};
+
 
 /**
- * Returns an XML string representing this element
- * and all children.
+ * Returns an XML string representing this element and all children.
  * 
  * @param prettyPrint If true print this in human-readable form with spacing.
  */
 xap.xml.dom.XapElement.prototype.toXml = function ( prettyPrint ) {
 	var sbuf = "";
-	sbuf = this._toStringHelper( this,
-                    sbuf,
-                    0, 
-                    prettyPrint,
-                    true );
+	this._toStringHelper( this, sbuf, 0, prettyPrint, true );
 	return sbuf;
-}
+};
+
 
 /**
  * Returns an XML string representing this element
@@ -410,13 +393,9 @@
  */
 xap.xml.dom.XapElement.prototype.toXmlWithoutAutoAssignedIds = function( prettyPrint ) {
 	var sbuf = "";
-	sbuf = this._toStringHelper( this,
-                    sbuf,
-                    0,
-                    prettyPrint,
-                    false );
+	this._toStringHelper( this, sbuf, 0, prettyPrint, false );
 	return sbuf;
-}
+};
 
 
 /**
@@ -429,7 +408,8 @@
  */
 xap.xml.dom.XapElement.prototype.addAttributeChangeListener = function ( listener ) {
 	this._getAttributeChangeListeners().push( listener );
-}
+};
+
 
 /**
  * Removes an xap.xml.dom.events.AttributeChangeListener from the element.
@@ -440,7 +420,8 @@
  */
 xap.xml.dom.XapElement.prototype.removeAttributeChangeListener = function( listener ) {
 	xap.util.ArrayHelper.removeElement( this._getAttributeChangeListeners(), listener );
-}
+};
+
 
 /**
  * Adds a xap.xml.dom.events.StructureChangeListener to the element. This listener
@@ -452,7 +433,8 @@
  */
 xap.xml.dom.XapElement.prototype.addStructureChangeListener = function ( listener ) {
     this._getStructureChangeListeners().push( listener );
-}
+};
+
 
 /**
  * Removes a xap.xml.dom.events.StructureChangeListener from the element.
@@ -463,7 +445,8 @@
  */
 xap.xml.dom.XapElement.prototype.removeStructureChangeListener = function( listener ) {
 	xap.util.ArrayHelper.removeElement( this._getStructureChangeListeners(), listener );
-}
+};
+
 
 /**
  * Adds a xap.xml.dom.DocumentOwnershipListener to the element. This listener
@@ -475,7 +458,8 @@
  */
 xap.xml.dom.XapElement.prototype.addDocumentOwnershipListener = function( listener ) {
 	this._getDocumentOwnershipListeners().push( listener );
-}
+};
+
 
 /**
  * Removes a xap.xml.dom.DocumentOwnershipListener from the element. 
@@ -484,9 +468,9 @@
  * xap.xml.dom.DocumentOwnershipListener or implements the same methods.
  * 
  */
-xap.xml.dom.XapElement.prototype.removeDocumentOwnershipListener = function( listener) {
+xap.xml.dom.XapElement.prototype.removeDocumentOwnershipListener = function( listener ) {
 	xap.util.ArrayHelper.removeElement( this._getDocumentOwnershipListeners(), listener );
-}
+};
 
 
 /**
@@ -495,7 +479,8 @@
  */
 xap.xml.dom.XapElement.prototype.clone = function ( ) {
 	return this._cloneHelper( false );
-}
+};
+
 
 /**
  * Creates a deep clone of the element. This will not copy generated IDs.
@@ -503,11 +488,7 @@
  */
 xap.xml.dom.XapElement.prototype.deepClone = function( ) {
 	return this._cloneHelper( true );
-}
-
-//-----------------------------------------------------------------------
-// Private methods
-//-----------------------------------------------------------------------
+};
 
 
 /**
@@ -520,15 +501,17 @@
  */
 xap.xml.dom.XapElement.prototype._insertBefore = function(newNode, oldNode) {
 	
-	//TODO check newNode for null?
-	
 	var index = this.childNodes.length;
-	if (oldNode){		
+	
+	if (oldNode) {		
 		//TODO this is somewhat inneficient as the superclass
 		//insertBefore does this same lookup
 		index = xap.util.ArrayHelper.indexOf(this.childNodes, oldNode);
-		if (index==-1){
-			return null; //TODO exception?
+		if (index == -1){
+		throw new xap.xml.dom.events.ChangeRejectedException( 
+				xap.xml.dom.events.ChangeRejectedException.REJECTED_WITH_REASON_MSGID,
+		      	["Attempted to insert before at invalid node"], 
+		      	null, null);	
 		}
 	}
 	
@@ -545,8 +528,8 @@
 		// event, not the element passed to this method.
 		newNode = event.getChange();
 		if ( !newNode ) {
-			throw new xap.xml.dom.events.ChangeRejectedException
-                ( xap.xml.dom.events.ChangeRejectedException.CHANGE_CHILD_TO_NULL_MSGID,
+			throw new xap.xml.dom.events.ChangeRejectedException( 
+				xap.xml.dom.events.ChangeRejectedException.CHANGE_CHILD_TO_NULL_MSGID,
                   null, null, event );
 		}
 	}
@@ -579,20 +562,21 @@
     } 
    
    //if there was an old node we are doing an insert before
-   if (oldNode){
+   if (oldNode)  {
 		google.XNode.prototype.insertBefore.call(this,newNode, oldNode);
    }
-   
    //otherwise we are doing an append
-   else{
-   	google.XNode.prototype.appendChild.call(this,newNode);
+   else {
+   	google.XNode.prototype.appendChild.call(this, newNode);
    }
     
+    // send notification
 	if ( structureChangeListenersExist ) {
 		this._fireStructureChangeEvent( doc, event, 'onChildAdded');
 	}
+	
 	return newNode;    
-}
+};
 
 
 /**
@@ -604,7 +588,8 @@
  */
 xap.xml.dom.XapElement.prototype._setNamespaceUri = function( ns ) {
     this._namespaceUri = ns;
-}
+};
+
 
 /**
  * A simple accessor for the prefix.
@@ -615,9 +600,14 @@
  */
 xap.xml.dom.XapElement.prototype._setPrefix = function( prefix ) {
     this._prefix = prefix;
-}
+};
 
-/** @private */
+
+/** 
+ *	Sends 'onRemovedFromDocument' message to all Document Ownership Listeners
+ *
+ *	@private
+ */
 xap.xml.dom.XapElement.prototype._notifyListenersOnRemovedFromDocument = function( doc ) {
 
  	var listeners = this._getDocumentOwnershipListeners();
@@ -631,15 +621,19 @@
             i = i - 1;
           }
       } catch ( t ) {
-      	xap.xml.dom.XapElement.s_log.error
-                  ( xap.util.ResourceDictionary.getMessage
-                    ( xap.xml.dom.XapElement.DOC_OWNERSHIP_FAILURE, 
-                    xap.xml.dom.XapElement.CLASSNAME ), t );
+      	xap.xml.dom.XapElement.s_log.error( xap.util.ResourceDictionary.getMessage(
+      			xap.xml.dom.XapElement.DOC_OWNERSHIP_FAILURE, 
+                xap.xml.dom.XapElement.CLASSNAME ), t );
       }
 	}  
-}
+};
 
-/** @private */
+
+/** 
+ *	Sends 'onAddedToDocument' message to all Document Ownership Listeners
+ *
+ *	@private
+ */
 xap.xml.dom.XapElement.prototype._notifyListenersOnAddedToDocument = function( doc ) {
      var listeners = this._getDocumentOwnershipListeners();
      for ( var i = 0; i < listeners.length; i++ ) {
@@ -651,33 +645,31 @@
              if ( listeners[i] != listener ) {
              	i = i - 1;
              }
-         } catch ( t ) {
-         	xap.xml.dom.XapElement.s_log.error
-                     ( xap.util.ResourceDictionary.getMessage
-                       ( xap.xml.dom.XapElement.DOC_OWNERSHIP_FAILURE, 
-                         xap.xml.dom.XapElement.CLASSNAME ), t );
+         } catch ( e ) {
+         	xap.xml.dom.XapElement.s_log.error( xap.util.ResourceDictionary.getMessage(
+				xap.xml.dom.XapElement.DOC_OWNERSHIP_FAILURE, 
+				xap.xml.dom.XapElement.CLASSNAME ), e );
          }
      }
-}
+};
 
-//-----------------------------------------------------------------------
-// Private Methods.
-//-----------------------------------------------------------------------
 
 /** @private */
 xap.xml.dom.XapElement.prototype._getAttributeChangeListeners = function() {
 	return this._attributeChangeListeners;
-}
+};
+
 
 /** @private */
 xap.xml.dom.XapElement.prototype._getStructureChangeListeners = function() {
 	return this._structureChangeListeners;
-}
+};
+
 
 /** @private */
 xap.xml.dom.XapElement.prototype._getDocumentOwnershipListeners = function() {
 	return this._documentOwnershipListeners;
-}
+};
 
 
 /**
@@ -688,13 +680,10 @@
  * @param node the current node.
  * @param sbuf the resulting content
  * @param indent the indentation for this step
- * @param prettyPrint if true the resulting StringBuffer will contain 
- * pretty-printed XML
- * @param attributeEncodingChoice is one of the private constants on this 
- * class.
+ * @param prettyPrint if true the resulting StringBuffer will contain pretty-printed XML
+ * @param attributeEncodingChoice is one of the private constants on this class.
  */
-xap.xml.dom.XapElement.prototype._toStringHelper = function( node, sbuf, indent, prettyPrint,
-				   							 withInternalIds) {
+xap.xml.dom.XapElement.prototype._toStringHelper = function( node, sbuf, indent, prettyPrint, withInternalIds) {
 	if( node.nodeType == google.DOM_TEXT_NODE ) {
 		// if its a string, simply print it XML-encoded
         sbuf += xap.util.XmlUtils.encode( node.nodeValue );
@@ -707,8 +696,8 @@
         	    // any of the protocol handlers.
         	} else {
         		 //var child = node.getParent().getChildAt(index-1);
-        		 if ( index == 0 || 
-        		 	( node.getParent().childNodes[index-1].nodeType==google.DOM_ELEMENT_NODE)) {
+        		 if ( index === 0 || 
+        		 	( node.getParent().childNodes[index - 1].nodeType == google.DOM_ELEMENT_NODE)) {
         	    	sbuf += '\n';
         	    	xap.xml.dom.XapElement._writeIndent( sbuf, indent );
         		 }
@@ -726,19 +715,13 @@
 		// on this element.  This is to handle the case where the namespace
 		// is inherited, it should not be printed on every child element
 		var printNamespaceAtt = false;
-		if( node.getNamespaceUri() != null ) { //"" namespace URI is ok!
+		if( node.getNamespaceUri() !== null ) { //"" namespace URI is ok!
 			if( node.getParent() ) {
 			    var myNS = node.getNamespaceUri();
 			    var parentNS = node.getParent().getNamespaceUri();
-			    
 		    	// if this is the first element where this namespace
 		    	// appears then print it
-			    if( parentNS == null ) {
-			        printNamespaceAtt = true;
-			    }
-			    else if( myNS != parentNS ) {
-			        printNamespaceAtt = true;
-			    }
+			    if( parentNS === null || myNS != parentNS) { printNamespaceAtt = true; }
 			} else {
 				printNamespaceAtt = true;
 			}
@@ -747,19 +730,18 @@
 		//TODO what if this has a namespace URI and ALSO
 		//has an xmlns attribute? Will print twice
 
-		if( printNamespaceAtt == true ){
+		if( printNamespaceAtt === true ){
 		    sbuf += " ";
 		    // determine correct namespace attribute to use
 			if( node.getPrefix() ) {
 				sbuf += "xmlns:" + node.getPrefix();
-				
 			} else {
 				sbuf += "xmlns";
 			}
 			sbuf += "=\"" + xap.util.XmlUtils.encode(node.getNamespaceUri()) + "\"";
 		}
 		
-		for( var i=0; i<node.attributes.length; i++ ) {
+		for( var i = 0; i < node.attributes.length; i++ ) {
 		    var key = node.attributes[i].nodeName;
 		    var value = node.attributes[i].nodeValue;
 		    
@@ -776,14 +758,13 @@
 		}
 		
 		//add children if there are any
-		if ( node.childNodes.length == 0 ) {
+		if ( node.childNodes.length === 0 ) {
 			sbuf += "/>";
-		}
-		else {
+		} else {
 			sbuf += '>';
 			var elementHasTextNode = false;
-			for ( var i = 0; i < node.childNodes.length; i++ ) {
-				var child = node.childNodes[i];
+			for ( var j = 0; j < node.childNodes.length; j++ ) {
+				var child = node.childNodes[j];
 				if( child.nodeType == google.DOM_TEXT_NODE ) {
 					elementHasTextNode = true;
 				}
@@ -794,7 +775,7 @@
 							   withInternalIds);
 			}
 
-			if( prettyPrint && elementHasTextNode == false ) {
+			if( prettyPrint && (elementHasTextNode === false) ) {
 				// if this element had a text node it is not valid to
 				// write whitespace
 				sbuf += '\n';
@@ -809,33 +790,41 @@
 		}
     }
     return sbuf;
-}
+};
 
 
 /** 
+ * Notifies document's listenters (if there is one) and then its own listeners
+ *
  * @private 
+ * @param doc Containing document. Can be null.
+ * @param event Modification event
+ * @param methodName { String } onXXX handler name 
  */
 xap.xml.dom.XapElement.prototype._fireStructureChangeEvent = function( doc, event, methodName){
 	if (doc){
-		this._notifyListeners(doc._structureChangeListeners,
-			event, methodName);
+		this._notifyListeners(doc._structureChangeListeners, event, methodName);
 	}
 	
 	this._notifyListeners(this._getStructureChangeListeners(), event, methodName);	
-}
+};
 
 
 /** 
- * @private 
+ * Notifies document's listenters (if there is one) and then its own listeners
+ *
+ * @private
+ * @param doc Containing document. Can be null.
+ * @param event Modification event
+ * @param methodName { String } onXXX handler name 
  */
-xap.xml.dom.XapElement.prototype._fireAttributeChangeEvent = function( doc, event, methodName){
+xap.xml.dom.XapElement.prototype._fireAttributeChangeEvent = function( doc, event, methodName ) {
 	if (doc){
-		this._notifyListeners(doc._attributeChangeListeners,
-			event, methodName);
+		this._notifyListeners(doc._attributeChangeListeners, event, methodName);
 	}
 	
 	this._notifyListeners(this._getAttributeChangeListeners(), event, methodName);	
-}
+};
 
 
 
@@ -848,110 +837,116 @@
  * @throws xap.xml.dom.events.ChangeRejectedException
  */
 xap.xml.dom.XapElement.prototype._notifyListeners = function( listeners, event, methodName){
-	if (!listeners) return;
 	
-	for (var i =0; i<listeners.length; i++){
+	if (!listeners) { return; }
+	
+	for (var i = 0; i < listeners.length; i++){
 		var listener = listeners[i];
-		
 		if(listener[methodName]){
 			listener[methodName].call(listener, event);
-			
 			if ( listeners[i] != listener ) {
-			i = i - 1;
+				i = i - 1;
      		}
 		}
 	}
-}
-
+};
 
 
-/** 
+/**
+ *
+ *
  * @private 
  */
 xap.xml.dom.XapElement.prototype._doAnyAttributeChangeListenersExist = function( doc ) {
 	return ( (doc && doc._attributeChangeListeners.length>0) || 
 			(this._getAttributeChangeListeners().length > 0 ));
 
-}
+};
 
-/** @private */
+
+/** 
+ *
+ *
+ *	@private
+ */
 xap.xml.dom.XapElement.prototype._doAnyStructureChangeListenersExist = function( doc ) {
 	return ( (doc && doc._structureChangeListeners.length>0) || 
 			(this._getStructureChangeListeners().length > 0 ));
-}
+};
 
 
 /**
- * Needed for data.controller classes---Binding and ElementLocation 
+ * Needed for data.controller classes---Binding and ElementLocation
+ *
+ * @param child A child node to search for in this.childNodes
  * @return {int}
  */
-xap.xml.dom.XapElement.prototype.indexOfChild = function(aChild) {
-    return xap.util.ArrayHelper.indexOf(this.childNodes, aChild);
-}
+xap.xml.dom.XapElement.prototype.indexOfChild = function(child) {
+    return xap.util.ArrayHelper.indexOf(this.childNodes, child);
+};
+
+
 /**
  * Needed for Iterator 
  * @return {int}
  */
 xap.xml.dom.XapElement.prototype.getChildCount = function() {
-    return this.childNodes.length ;
-}
-
-
+    return this.childNodes.length;
+};
 
 
 /**
  * Needed for Iterator 
- * @return {int}
+ * @return Child node or null
  */
 xap.xml.dom.XapElement.prototype.getChildAt = function(anInt) {
-    return this.childNodes[anInt] ;
-}
+	if(anInt < this.childNodes.length) {
+    	return this.childNodes[anInt] ;
+    }
+    return null;
+};
 
 
 /**
  * This will return the first text node of this element.  If this element
  * has multiple text nodes ONLY the first text node is returned.
  * 
- * @param node{XNode}
+ * @param {XNode} node
  * @return {String} The first text node of the element.
  */
 xap.xml.dom.XapElement.getFirstTextChild = function(node) {
-	var result=null ;
-	var children = node.childNodes ;
-	for(var i=0; node.childNodes && i< children.length ; i++) {
+
+	var children = node.childNodes;
+
+	if(!children) { return null; }
+	
+	for(var i = 0; children.length ; i++) {
 		if(children[i].nodeType == google.DOM_TEXT_NODE ) {
-			result =  children[i] ;
-			break ;
+			return (children[i]);
 		}
 	}
-	return result ;
-}
-
-
-
-
+	return null;
+};
 
-//-----------------------------------------------------------------------
-// Array Helpers.
-//-----------------------------------------------------------------------
 
-
-/** 
- * @private 
+/**
+ *	Makes a deep clone of this node
+ *
+ * 	@private 
+ *	@return {xap.xml.dom.XapElement} New node
  */
 xap.xml.dom.XapElement.prototype._cloneHelper = function( deep ) {
+
 	var e = new xap.xml.dom.XapElement( this.nodeName );
 
 	e._setNamespaceUri( this._namespaceUri );
 	e._setPrefix( this._prefix );
    
    for (var i = 0; i<this.attributes.length; i++){
-	e.setAttribute(this.attributes[i].nodeName, this.attributes[i].nodeValue,this.attributes[i].baseUrl);
+		e.setAttribute(this.attributes[i].nodeName, this.attributes[i].nodeValue, this.attributes[i].baseUrl);
    } 
    
-   if (this.baseUrl){
-   	e.baseUrl = this.baseUrl;
-   }
+   if (this.baseUrl) { e.baseUrl = this.baseUrl; }
 
 	var id = e.getAttribute( "id" );
 	
@@ -959,51 +954,21 @@
 	if ( xap.xml.dom.XapElement.isGeneratedId( id ) ) {
 		e.setAttribute( "id", xap.util.UidProvider.createId());
 	}
-
     
-	if ( deep == false ) {
-		return e;
-	}
+	if ( deep === false ) {	return e; }
 
-	for ( var i = 0; i < this.childNodes.length; i++ ) {
-		var o = this.childNodes[i];
-		if (o.nodeType==google.DOM_ELEMENT_NODE){
-			var childCopy = o._cloneHelper( deep );
-			e.appendChild( childCopy );
+	for ( var j = 0; j < this.childNodes.length; j++ ) {
+		var o = this.childNodes[j];
+		if (o.nodeType == google.DOM_ELEMENT_NODE){
+			e.appendChild( o._cloneHelper( deep ) );
 		}
-		else if (o.nodeType==google.DOM_TEXT_NODE){
+		else if (o.nodeType == google.DOM_TEXT_NODE){
 			//TODO we should really use document.createTextNode here
 			//but do we always have a document to reference?
-			var childCopy = google.XNode.create(google.DOM_TEXT_NODE,null,o.nodeValue,null);
+			var childCopy = google.XNode.create(google.DOM_TEXT_NODE, null, o.nodeValue, null);
 			e.appendChild( childCopy );
 		}
 	}
 	return e;
-}
-
+};
 
-/** 
- * @private 
- */
-xap.xml.dom.XapElement.prototype._encodeEverythingButSingleTicks = function( s ) {
-    if ( !s ) { return ""; }
-	var buffer = new Array( s.length );
-	var c;
-	for ( var i = 0; i < s.length; i++ ) {
-		c = s.charAt(i);
-		if (c == '&') {
-			buffer[i] = "&amp;";
-        } else if (c == '<') {
-			buffer[i] = "&lt;";
-        } else if (c == '>') {
-			buffer[i] = "&gt;";
-      } else if (c == '\'') {
-			buffer[i] = "&apos;";
-        } else if (c == '\"') {
-			buffer[i] = "&quot;";
-        } else {
-			buffer[i] = c;
-        }
-	}
-	return buffer.join();
-}