src/dom/implementation.js in envjs-0.3.7 vs src/dom/implementation.js in envjs-0.3.8
- old
+ new
@@ -35,11 +35,11 @@
return new DOMDocumentType();
},
createDocument : function(nsuri, qname, doctype){
//TODO - this currently returns an empty doc
//but needs to handle the args
- return new Document(this, null);
+ return new DOMDocument(this, null);
},
createHTMLDocument : function(title){
// N.B. explict window on purpose ...
var doc = new HTMLDocument(this, window, "");
var html = doc.createElement("html"); doc.appendChild(html);
@@ -123,471 +123,9 @@
return msg;
}
});
-
-/**
-* Defined 'globally' to this scope. Remember everything is wrapped in a closure so this doesnt show up
-* in the outer most global scope.
-*/
-
-/**
- * process SAX events
- *
- * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
- *
- * @param impl : DOMImplementation
- * @param doc : DOMDocument - the Document to contain the parsed XML string
- * @param p : XMLP - the SAX Parser
- *
- * @return : DOMDocument
- */
-
-function __parseLoop__(impl, doc, p, isWindowDocument) {
- var iEvt, iNode, iAttr, strName;
- var iNodeParent = doc;
-
- var el_close_count = 0;
-
- var entitiesList = new Array();
- var textNodesList = new Array();
-
- // if namespaceAware, add default namespace
- if (impl.namespaceAware) {
- var iNS = doc.createNamespace(""); // add the default-default namespace
- iNS.value = "http://www.w3.org/2000/xmlns/";
- doc._namespaces.setNamedItem(iNS);
- }
-
- // loop until SAX parser stops emitting events
- var q = 0;
- while(true) {
- // get next event
- iEvt = p.next();
-
- if (iEvt == XMLP._ELM_B) { // Begin-Element Event
- var pName = p.getName(); // get the Element name
- pName = trim(pName, true, true); // strip spaces from Element name
- if(pName.toLowerCase() == 'script')
- p.replaceEntities = false;
-
- if (!impl.namespaceAware) {
- iNode = doc.createElement(p.getName()); // create the Element
- // add attributes to Element
- for(var i = 0; i < p.getAttributeCount(); i++) {
- strName = p.getAttributeName(i); // get Attribute name
- iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
-
- if(!iAttr) {
- iAttr = doc.createAttribute(strName); // otherwise create it
- }
-
- iAttr.value = p.getAttributeValue(i); // set Attribute value
- iNode.setAttributeNode(iAttr); // attach Attribute to Element
- }
- }
- else { // Namespace Aware
- // create element (with empty namespaceURI,
- // resolve after namespace 'attributes' have been parsed)
- iNode = doc.createElementNS("", p.getName());
-
- // duplicate ParentNode's Namespace definitions
- iNode._namespaces = __cloneNamedNodes__(iNodeParent._namespaces, iNode, true);
-
- // add attributes to Element
- for(var i = 0; i < p.getAttributeCount(); i++) {
- strName = p.getAttributeName(i); // get Attribute name
-
- // if attribute is a namespace declaration
- if (__isNamespaceDeclaration__(strName)) {
- // parse Namespace Declaration
- var namespaceDec = __parseNSName__(strName);
-
- if (strName != "xmlns") {
- iNS = doc.createNamespace(strName); // define namespace
- }
- else {
- iNS = doc.createNamespace(""); // redefine default namespace
- }
- iNS.value = p.getAttributeValue(i); // set value = namespaceURI
-
- iNode._namespaces.setNamedItem(iNS); // attach namespace to namespace collection
- }
- else { // otherwise, it is a normal attribute
- iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
-
- if(!iAttr) {
- iAttr = doc.createAttributeNS("", strName); // otherwise create it
- }
-
- iAttr.value = p.getAttributeValue(i); // set Attribute value
- iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
-
- if (__isIdDeclaration__(strName)) {
- iNode.id = p.getAttributeValue(i); // cache ID for getElementById()
- }
- }
- }
-
- // resolve namespaceURIs for this Element
- if (iNode._namespaces.getNamedItem(iNode.prefix)) {
- iNode.namespaceURI = iNode._namespaces.getNamedItem(iNode.prefix).value;
- } else {
- iNode.namespaceURI = iNodeParent.namespaceURI;
- }
-
- // for this Element's attributes
- for (var i = 0; i < iNode.attributes.length; i++) {
- if (iNode.attributes.item(i).prefix != "") { // attributes do not have a default namespace
- if (iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix)) {
- iNode.attributes.item(i).namespaceURI = iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix).value;
- }
- }
- }
-
- // We didn't know the NS of the node when we created it, which means we created a default DOM object.
- // Now that we know the NS, if there is one, we clone this node so that it'll get created under
- // with the right constructor. This makes things like SVG work. Might be nice not to create twice as
- // as many nodes, but that's painfully given the complexity of namespaces.
- if(iNode.namespaceURI != ""){
- iNode = iNode.cloneNode();
- }
- }
-
- // if this is the Root Element
- if (iNodeParent.nodeType == DOMNode.DOCUMENT_NODE) {
- iNodeParent._documentElement = iNode; // register this Element as the Document.documentElement
- }
-
- iNodeParent.appendChild(iNode); // attach Element to parentNode
- iNodeParent = iNode; // descend one level of the DOM Tree
- }
-
- else if(iEvt == XMLP._ELM_E) { // End-Element Event
- iNodeParent = iNodeParent.parentNode; // ascend one level of the DOM Tree
- }
-
- else if(iEvt == XMLP._ELM_EMP) { // Empty Element Event
- pName = p.getName(); // get the Element name
- pName = trim(pName, true, true); // strip spaces from Element name
-
- if (!impl.namespaceAware) {
- iNode = doc.createElement(pName); // create the Element
-
- // add attributes to Element
- for(var i = 0; i < p.getAttributeCount(); i++) {
- strName = p.getAttributeName(i); // get Attribute name
- iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
-
- if(!iAttr) {
- iAttr = doc.createAttribute(strName); // otherwise create it
- }
-
- iAttr.value = p.getAttributeValue(i); // set Attribute value
- iNode.setAttributeNode(iAttr); // attach Attribute to Element
- }
- }
- else { // Namespace Aware
- // create element (with empty namespaceURI,
- // resolve after namespace 'attributes' have been parsed)
- iNode = doc.createElementNS("", p.getName());
-
- // duplicate ParentNode's Namespace definitions
- iNode._namespaces = __cloneNamedNodes__(iNodeParent._namespaces, iNode);
-
- // add attributes to Element
- for(var i = 0; i < p.getAttributeCount(); i++) {
- strName = p.getAttributeName(i); // get Attribute name
-
- // if attribute is a namespace declaration
- if (__isNamespaceDeclaration__(strName)) {
- // parse Namespace Declaration
- var namespaceDec = __parseNSName__(strName);
-
- if (strName != "xmlns") {
- iNS = doc.createNamespace(strName); // define namespace
- }
- else {
- iNS = doc.createNamespace(""); // redefine default namespace
- }
- iNS.value = p.getAttributeValue(i); // set value = namespaceURI
-
- iNode._namespaces.setNamedItem(iNS); // attach namespace to namespace collection
- }
- else { // otherwise, it is a normal attribute
- iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
-
- if(!iAttr) {
- iAttr = doc.createAttributeNS("", strName); // otherwise create it
- }
-
- iAttr.value = p.getAttributeValue(i); // set Attribute value
- iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
-
- if (__isIdDeclaration__(strName)) {
- iNode.id = p.getAttributeValue(i); // cache ID for getElementById()
- }
- }
- }
-
- // resolve namespaceURIs for this Element
- if (iNode._namespaces.getNamedItem(iNode.prefix)) {
- iNode.namespaceURI = iNode._namespaces.getNamedItem(iNode.prefix).value;
- }
-
- // for this Element's attributes
- for (var i = 0; i < iNode.attributes.length; i++) {
- if (iNode.attributes.item(i).prefix != "") { // attributes do not have a default namespace
- if (iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix)) {
- iNode.attributes.item(i).namespaceURI = iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix).value;
- }
- }
- }
- }
-
- // if this is the Root Element
- if (iNodeParent.nodeType == DOMNode.DOCUMENT_NODE) {
- iNodeParent._documentElement = iNode; // register this Element as the Document.documentElement
- }
-
- iNodeParent.appendChild(iNode); // attach Element to parentNode
- }
- else if(iEvt == XMLP._TEXT || iEvt == XMLP._ENTITY) { // TextNode and entity Events
- // get Text content
- var pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
-
- if (!impl.preserveWhiteSpace ) {
- if (trim(pContent, true, true) == "") {
- pContent = ""; //this will cause us not to create the text node below
- }
- }
-
- if (pContent.length > 0) { // ignore empty TextNodes
- var textNode = doc.createTextNode(pContent);
- iNodeParent.appendChild(textNode); // attach TextNode to parentNode
-
- //the sax parser breaks up text nodes when it finds an entity. For
- //example hello<there will fire a text, an entity and another text
- //this sucks for the dom parser because it looks to us in this logic
- //as three text nodes. I fix this by keeping track of the entity nodes
- //and when we're done parsing, calling normalize on their parent to
- //turn the multiple text nodes into one, which is what DOM users expect
- //the code to do this is at the bottom of this function
- if (iEvt == XMLP._ENTITY) {
- entitiesList[entitiesList.length] = textNode;
- }
- else {
- //I can't properly decide how to handle preserve whitespace
- //until the siblings of the text node are built due to
- //the entitiy handling described above. I don't know that this
- //will be all of the text node or not, so trimming is not appropriate
- //at this time. Keep a list of all the text nodes for now
- //and we'll process the preserve whitespace stuff at a later time.
- textNodesList[textNodesList.length] = textNode;
- }
- }
- }
- else if(iEvt == XMLP._PI) { // ProcessingInstruction Event
- // attach ProcessingInstruction to parentNode
- iNodeParent.appendChild(doc.createProcessingInstruction(p.getName(), p.getContent().substring(p.getContentBegin(), p.getContentEnd())));
- }
- else if(iEvt == XMLP._CDATA) { // CDATA Event
- // get CDATA data
- pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
-
- if (!impl.preserveWhiteSpace) {
- pContent = trim(pContent, true, true); // trim whitespace
- pContent.replace(/ +/g, ' '); // collapse multiple spaces to 1 space
- }
-
- if (pContent.length > 0) { // ignore empty CDATANodes
- iNodeParent.appendChild(doc.createCDATASection(pContent)); // attach CDATA to parentNode
- }
- }
- else if(iEvt == XMLP._COMMENT) { // Comment Event
- // get COMMENT data
- var pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
-
- if (!impl.preserveWhiteSpace) {
- pContent = trim(pContent, true, true); // trim whitespace
- pContent.replace(/ +/g, ' '); // collapse multiple spaces to 1 space
- }
-
- if (pContent.length > 0) { // ignore empty CommentNodes
- iNodeParent.appendChild(doc.createComment(pContent)); // attach Comment to parentNode
- }
- }
- else if(iEvt == XMLP._DTD) { // ignore DTD events
- }
- else if(iEvt == XMLP._ERROR) {
- $error("Fatal Error: " + p.getContent() +
- "\nLine: " + p.getLineNumber() +
- "\nColumn: " + p.getColumnNumber() + "\n");
- throw(new DOMException(DOMException.SYNTAX_ERR));
- }
- else if(iEvt == XMLP._NONE) { // no more events
- //steven woods notes that unclosed tags are rejected elsewhere and this check
- //breaks a table patching routine
- //if (iNodeParent == doc) { // confirm that we have recursed back up to root
- // break;
- //}
- //else {
- // throw(new DOMException(DOMException.SYNTAX_ERR)); // one or more Tags were not closed properly
- //}
- break;
-
- }
- }
-
- //normalize any entities in the DOM to a single textNode
- for (var i = 0; i < entitiesList.length; i++) {
- var entity = entitiesList[i];
- //its possible (if for example two entities were in the
- //same domnode, that the normalize on the first entitiy
- //will remove the parent for the second. Only do normalize
- //if I can find a parent node
- var parentNode = entity.parentNode;
- if (parentNode) {
- parentNode.normalize();
-
- //now do whitespace (if necessary)
- //it was not done for text nodes that have entities
- if(!impl.preserveWhiteSpace) {
- var children = parentNode.childNodes;
- for ( var j = 0; j < children.length; j++) {
- var child = children.item(j);
- if (child.nodeType == DOMNode.TEXT_NODE) {
- var childData = child.data;
- childData.replace(/\s/g, ' ');
- child.data = childData;
- }
- }
- }
- }
- }
-
- //do the preserve whitespace processing on the rest of the text nodes
- //It's possible (due to the processing above) that the node will have been
- //removed from the tree. Only do whitespace checking if parentNode is not null.
- //This may duplicate the whitespace processing for some nodes that had entities in them
- //but there's no way around that
- if (!impl.preserveWhiteSpace) {
- for (var i = 0; i < textNodesList.length; i++) {
- var node = textNodesList[i];
- if (node.parentNode != null) {
- var nodeData = node.data;
- nodeData.replace(/\s/g, ' ');
- node.data = nodeData;
- }
- }
-
- }
-};
-
-
-/**
- * @method DOMImplementation._isNamespaceDeclaration - Return true, if attributeName is a namespace declaration
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param attributeName : string - the attribute name
- * @return : boolean
- */
-function __isNamespaceDeclaration__(attributeName) {
- // test if attributeName is 'xmlns'
- return (attributeName.indexOf('xmlns') > -1);
-};
-
-/**
- * @method DOMImplementation._isIdDeclaration - Return true, if attributeName is an id declaration
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param attributeName : string - the attribute name
- * @return : boolean
- */
-function __isIdDeclaration__(attributeName) {
- // test if attributeName is 'id' (case insensitive)
- return attributeName?(attributeName.toLowerCase() == 'id'):false;
-};
-
-/**
- * @method DOMImplementation._isValidName - Return true,
- * if name contains no invalid characters
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param name : string - the candidate name
- * @return : boolean
- */
-function __isValidName__(name) {
- // test if name contains only valid characters
- return name.match(re_validName);
-};
-var re_validName = /^[a-zA-Z_:][a-zA-Z0-9\.\-_:]*$/;
-
-/**
- * @method DOMImplementation._isValidString - Return true, if string does not contain any illegal chars
- * All of the characters 0 through 31 and character 127 are nonprinting control characters.
- * With the exception of characters 09, 10, and 13, (Ox09, Ox0A, and Ox0D)
- * Note: different from _isValidName in that ValidStrings may contain spaces
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param name : string - the candidate string
- * @return : boolean
- */
-function __isValidString__(name) {
- // test that string does not contains invalid characters
- return (name.search(re_invalidStringChars) < 0);
-};
-var re_invalidStringChars = /\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F/;
-
-/**
- * @method DOMImplementation._parseNSName - parse the namespace name.
- * if there is no colon, the
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param qualifiedName : string - The qualified name
- * @return : NSName - [
- .prefix : string - The prefix part of the qname
- .namespaceName : string - The namespaceURI part of the qname
- ]
- */
-function __parseNSName__(qualifiedName) {
- var resultNSName = new Object();
-
- resultNSName.prefix = qualifiedName; // unless the qname has a namespaceName, the prefix is the entire String
- resultNSName.namespaceName = "";
-
- // split on ':'
- var delimPos = qualifiedName.indexOf(':');
- if (delimPos > -1) {
- // get prefix
- resultNSName.prefix = qualifiedName.substring(0, delimPos);
- // get namespaceName
- resultNSName.namespaceName = qualifiedName.substring(delimPos +1, qualifiedName.length);
- }
- return resultNSName;
-};
-
-/**
- * @method DOMImplementation._parseQName - parse the qualified name
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param qualifiedName : string - The qualified name
- * @return : QName
- */
-function __parseQName__(qualifiedName) {
- var resultQName = new Object();
-
- resultQName.localName = qualifiedName; // unless the qname has a prefix, the local name is the entire String
- resultQName.prefix = "";
-
- // split on ':'
- var delimPos = qualifiedName.indexOf(':');
-
- if (delimPos > -1) {
- // get prefix
- resultQName.prefix = qualifiedName.substring(0, delimPos);
-
- // get localName
- resultQName.localName = qualifiedName.substring(delimPos +1, qualifiedName.length);
- }
-
- return resultQName;
-};
if(false){
$debug("Initializing document.implementation");
var $implementation = new DOMImplementation();
// $implementation.namespaceAware = false;