topical media & game development
professional-ria-03-xmlw3cdom.js / js
// =========================================================================
//
// xmlw3cdom.js - a W3C compliant DOM parser for XML for <SCRIPT>
//
// version 3.1
//
// =========================================================================
//
// Copyright (C) 2002, 2003, 2004 Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// visit the XML for <SCRIPT> home page at xmljs.sourceforge.net
//
// Contains text (used within comments to methods) from the
// XML Path Language (XPath) Version 1.0 W3C Recommendation
// Copyright � 16 November 1999 World Wide Web Consortium,
// (Massachusetts Institute of Technology,
// European Research Consortium for Informatics and Mathematics, Keio University).
// All Rights Reserved.
// (see: http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/)
/**
* @function addClass - add new className to classCollection
*
*
author: Jon van Noort (jon@webarcana.com.au)
*
*
parameter: classCollectionStr : string - list of existing class names
* (separated and top and tailed with '|'s)
*
parameter: newClass : string - new class name to add
*
*
returns: : string - the new classCollection, with new className appended,
* (separated and top and tailed with '|'s)
*/
function addClass(classCollectionStr, newClass) {
if (classCollectionStr) {
if (classCollectionStr.indexOf("|"+ newClass +"|") < 0) {
classCollectionStr += newClass + "|";
}
}
else {
classCollectionStr = "|"+ newClass + "|";
}
return classCollectionStr;
}
@class DOMException - raised when an operation is impossible to perform
author: Jon van Noort (jon@webarcana.com.au)
parameter: code : int - the exception code (one of the DOMException constants)
DOMException = function(code) {
this._class = addClass(this._class, "DOMException");
this.code = code;
};
// DOMException constants
// Introduced in DOM Level 1:
DOMException.INDEX_SIZE_ERR = 1;
DOMException.DOMSTRING_SIZE_ERR = 2;
DOMException.HIERARCHY_REQUEST_ERR = 3;
DOMException.WRONG_DOCUMENT_ERR = 4;
DOMException.INVALID_CHARACTER_ERR = 5;
DOMException.NO_DATA_ALLOWED_ERR = 6;
DOMException.NO_MODIFICATION_ALLOWED_ERR = 7;
DOMException.NOT_FOUND_ERR = 8;
DOMException.NOT_SUPPORTED_ERR = 9;
DOMException.INUSE_ATTRIBUTE_ERR = 10;
// Introduced in DOM Level 2:
DOMException.INVALID_STATE_ERR = 11;
DOMException.SYNTAX_ERR = 12;
DOMException.INVALID_MODIFICATION_ERR = 13;
DOMException.NAMESPACE_ERR = 14;
DOMException.INVALID_ACCESS_ERR = 15;
@class DOMImplementation - provides a number of methods for performing operations
that are independent of any particular instance of the document object model.
author: Jon van Noort (jon@webarcana.com.au)
DOMImplementation = function() {
this._class = addClass(this._class, "DOMImplementation");
this._p = null;
this.preserveWhiteSpace = false; // by default, ignore whitespace
this.namespaceAware = true; // by default, handle namespaces
this.errorChecking = true; // by default, test for exceptions
};
@method DOMImplementation.escapeString - escape special characters
author: Jon van Noort (jon@webarcana.com.au)
parameter: str : string - The string to be escaped
returns: : string - The escaped string
DOMImplementation.prototype.escapeString = function DOMNode__escapeString(str) {
//the sax processor already has this function. Just wrap it
return __escapeString(str);
};
@method DOMImplementation.unescapeString - unescape special characters
author: Jon van Noort (jon@webarcana.com.au)
parameter: str : string - The string to be unescaped
returns: : string - The unescaped string
DOMImplementation.prototype.unescapeString = function DOMNode__unescapeString(str) {
//the sax processor already has this function. Just wrap it
return __unescapeString(str);
};
@method DOMImplementation.hasFeature - Test if the DOM implementation implements a specific feature
author: Jon van Noort (jon@webarcana.com.au)
parameter: feature : string - The package name of the feature to test. the legal only values are "XML" and "CORE" (case-insensitive).
parameter: version : string - This is the version number of the package name to test. In Level 1, this is the string "1.0".
returns: : boolean
DOMImplementation.prototype.hasFeature = function DOMImplementation_hasFeature(feature, version) {
var ret = false;
if (feature.toLowerCase() == "xml") {
ret = (!version || (version == "1.0") || (version == "2.0"));
}
else if (feature.toLowerCase() == "core") {
ret = (!version || (version == "2.0"));
}
return ret;
};
@method DOMImplementation.loadXML - parse XML string
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: xmlStr : string - the XML string
returns: : DOMDocument
DOMImplementation.prototype.loadXML = function DOMImplementation_loadXML(xmlStr) {
// create SAX Parser
var parser;
try {
parser = new XMLP(xmlStr);
}
catch (e) {
alert("Error Creating the SAX Parser. Did you include xmlsax.js or tinyxmlsax.js in your web page?\nThe SAX parser is needed to populate XML for <SCRIPT>'s W3C DOM Parser with data.");
}
// create DOM Document
var doc = new DOMDocument(this);
// populate Document with Parsed Nodes
this._parseLoop(doc, parser);
// set parseComplete flag, (Some validation Rules are relaxed if this is false)
doc._parseComplete = true;
return doc;
};
@method DOMImplementation.translateErrCode - convert DOMException Code
to human readable error message;
author: Jon van Noort (jon@webarcana.com.au)
parameter: code : int - the DOMException code
returns: : string - the human readbale error message
DOMImplementation.prototype.translateErrCode = function DOMImplementation_translateErrCode(code) {
var msg = "";
switch (code) {
case DOMException.INDEX_SIZE_ERR : // 1
msg = "INDEX_SIZE_ERR: Index out of bounds";
break;
case DOMException.DOMSTRING_SIZE_ERR : // 2
msg = "DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a DOMString";
break;
case DOMException.HIERARCHY_REQUEST_ERR : // 3
msg = "HIERARCHY_REQUEST_ERR: The Node can not be inserted at this location";
break;
case DOMException.WRONG_DOCUMENT_ERR : // 4
msg = "WRONG_DOCUMENT_ERR: The source and the destination Documents are not the same";
break;
case DOMException.INVALID_CHARACTER_ERR : // 5
msg = "INVALID_CHARACTER_ERR: The string contains an invalid character";
break;
case DOMException.NO_DATA_ALLOWED_ERR : // 6
msg = "NO_DATA_ALLOWED_ERR: This Node / NodeList does not support data";
break;
case DOMException.NO_MODIFICATION_ALLOWED_ERR : // 7
msg = "NO_MODIFICATION_ALLOWED_ERR: This object cannot be modified";
break;
case DOMException.NOT_FOUND_ERR : // 8
msg = "NOT_FOUND_ERR: The item cannot be found";
break;
case DOMException.NOT_SUPPORTED_ERR : // 9
msg = "NOT_SUPPORTED_ERR: This implementation does not support function";
break;
case DOMException.INUSE_ATTRIBUTE_ERR : // 10
msg = "INUSE_ATTRIBUTE_ERR: The Attribute has already been assigned to another Element";
break;
// Introduced in DOM Level 2:
case DOMException.INVALID_STATE_ERR : // 11
msg = "INVALID_STATE_ERR: The object is no longer usable";
break;
case DOMException.SYNTAX_ERR : // 12
msg = "SYNTAX_ERR: Syntax error";
break;
case DOMException.INVALID_MODIFICATION_ERR : // 13
msg = "INVALID_MODIFICATION_ERR: Cannot change the type of the object";
break;
case DOMException.NAMESPACE_ERR : // 14
msg = "NAMESPACE_ERR: The namespace declaration is incorrect";
break;
case DOMException.INVALID_ACCESS_ERR : // 15
msg = "INVALID_ACCESS_ERR: The object does not support this function";
break;
default :
msg = "UNKNOWN: Unknown Exception Code ("+ code +")";
}
return msg;
}
@method DOMImplementation._parseLoop - process SAX events
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: doc : DOMDocument - the Document to contain the parsed XML string
parameter: p : XMLP - the SAX Parser
returns: : DOMDocument
DOMImplementation.prototype._parseLoop = function DOMImplementation__parseLoop(doc, p) {
var iEvt, iNode, iAttr, strName;
iNodeParent = doc;
var el_close_count = 0;
var entitiesList = new Array();
var textNodesList = new Array();
// if namespaceAware, add default namespace
if (this.namespaceAware) {
var iNS = doc.createNamespace(""); // add the default-default namespace
iNS.setValue("http://www.w3.org/2000/xmlns/");
doc._namespaces.setNamedItem(iNS);
}
// loop until SAX parser stops emitting events
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 (!this.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.setValue(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 = iNodeParent._namespaces._cloneNodes(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 (this._isNamespaceDeclaration(strName)) {
// parse Namespace Declaration
var namespaceDec = this._parseNSName(strName);
if (strName != "xmlns") {
iNS = doc.createNamespace(strName); // define namespace
}
else {
iNS = doc.createNamespace(""); // redefine default namespace
}
iNS.setValue(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.setValue(p.getAttributeValue(i)); // set Attribute value
iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
if (this._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
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 (!this.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.setValue(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 = iNodeParent._namespaces._cloneNodes(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 (this._isNamespaceDeclaration(strName)) {
// parse Namespace Declaration
var namespaceDec = this._parseNSName(strName);
if (strName != "xmlns") {
iNS = doc.createNamespace(strName); // define namespace
}
else {
iNS = doc.createNamespace(""); // redefine default namespace
}
iNS.setValue(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.setValue(p.getAttributeValue(i)); // set Attribute value
iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
if (this._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 (!this.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 (!this.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 (!this.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) {
throw(new DOMException(DOMException.SYNTAX_ERR));
// alert("Fatal Error: " + p.getContent() + "\nLine: " + p.getLineNumber() + "\nColumn: " + p.getColumnNumber() + "\n");
// break;
}
else if(iEvt == XMLP._NONE) { // no more events
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
}
}
}
//normalize any entities in the DOM to a single textNode
var intCount = entitiesList.length;
for (intLoop = 0; intLoop < intCount; intLoop++) {
var entity = entitiesList[intLoop];
//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.getParentNode();
if (parentNode) {
parentNode.normalize();
//now do whitespace (if necessary)
//it was not done for text nodes that have entities
if(!this.preserveWhiteSpace) {
var children = parentNode.getChildNodes();
var intCount2 = children.getLength();
for ( intLoop2 = 0; intLoop2 < intCount2; intLoop2++) {
var child = children.item(intLoop2);
if (child.getNodeType() == DOMNode.TEXT_NODE) {
var childData = child.getData();
childData = trim(childData, true, true);
childData.replace(/ +/g, ' ');
child.setData(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 (!this.preserveWhiteSpace) {
var intCount = textNodesList.length;
for (intLoop = 0; intLoop < intCount; intLoop++) {
var node = textNodesList[intLoop];
if (node.getParentNode() != null) {
var nodeData = node.getData();
nodeData = trim(nodeData, true, true);
nodeData.replace(/ +/g, ' ');
node.setData(nodeData);
}
}
}
};
@method DOMImplementation._isNamespaceDeclaration - Return true, if attributeName is a namespace declaration
author: Jon van Noort (jon@webarcana.com.au)
parameter: attributeName : string - the attribute name
returns: : boolean
DOMImplementation.prototype._isNamespaceDeclaration = function DOMImplementation__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)
parameter: attributeName : string - the attribute name
returns: : boolean
DOMImplementation.prototype._isIdDeclaration = function DOMImplementation__isIdDeclaration(attributeName) {
// test if attributeName is 'id' (case insensitive)
return (attributeName.toLowerCase() == 'id');
}
@method DOMImplementation._isValidName - Return true,
if name contains no invalid characters
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - the candidate name
returns: : boolean
DOMImplementation.prototype._isValidName = function DOMImplementation__isValidName(name) {
// test if name contains only valid characters
return name.match(re_validName);
}
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)
parameter: name : string - the candidate string
returns: : boolean
DOMImplementation.prototype._isValidString = function DOMImplementation__isValidString(name) {
// test that string does not contains invalid characters
return (name.search(re_invalidStringChars) < 0);
}
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)
parameter: qualifiedName : string - The qualified name
returns: : NSName - [
.prefix : string - The prefix part of the qname
.namespaceName : string - The namespaceURI part of the qname
]
DOMImplementation.prototype._parseNSName = function DOMImplementation__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 ':'
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)
parameter: qualifiedName : string - The qualified name
returns: : QName
DOMImplementation.prototype._parseQName = function DOMImplementation__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 ':'
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;
}
@class DOMNodeList - provides the abstraction of an ordered collection of nodes
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - the ownerDocument
parameter: parentNode : DOMNode - the node that the DOMNodeList is attached to (or null)
DOMNodeList = function(ownerDocument, parentNode) {
this._class = addClass(this._class, "DOMNodeList");
this._nodes = new Array();
this.length = 0;
this.parentNode = parentNode;
this.ownerDocument = ownerDocument;
this._readonly = false;
};
@method DOMNodeList.getLength - Java style gettor for .length
author: Jon van Noort (jon@webarcana.com.au)
returns: : int
DOMNodeList.prototype.getLength = function DOMNodeList_getLength() {
return this.length;
};
@method DOMNodeList.item - Returns the indexth item in the collection.
If index is greater than or equal to the number of nodes in the list, this returns null.
author: Jon van Noort (jon@webarcana.com.au)
parameter: index : int - Index into the collection.
returns: : DOMNode - The node at the indexth position in the NodeList, or null if that is not a valid index
DOMNodeList.prototype.item = function DOMNodeList_item(index) {
var ret = null;
if ((index >= 0) && (index < this._nodes.length)) { // bounds check
ret = this._nodes[index]; // return selected Node
}
return ret; // if the index is out of bounds, default value null is returned
};
@method DOMNodeList._findItemIndex - find the item index of the node with the specified internal id
author: Jon van Noort (jon@webarcana.com.au)
parameter: id : int - unique internal id
returns: : int
DOMNodeList.prototype._findItemIndex = function DOMNodeList__findItemIndex(id) {
var ret = -1;
// test that id is valid
if (id > -1) {
for (var i=0; i<this._nodes.length; i++) {
// compare id to each node's _id
if (this._nodes[i]._id == id) { // found it!
ret = i;
break;
}
}
}
return ret; // if node is not found, default value -1 is returned
};
@method DOMNodeList._insertBefore - insert the specified Node into the NodeList before the specified index
Used by DOMNode.insertBefore(). Note: DOMNode.insertBefore() is responsible for Node Pointer surgery
DOMNodeList._insertBefore() simply modifies the internal data structure (Array).
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - the Node to be inserted
parameter: refChildIndex : int - the array index to insert the Node before
DOMNodeList.prototype._insertBefore = function DOMNodeList__insertBefore(newChild, refChildIndex) {
if ((refChildIndex >= 0) && (refChildIndex < this._nodes.length)) { // bounds check
// get array containing children prior to refChild
var tmpArr = new Array();
tmpArr = this._nodes.slice(0, refChildIndex);
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
// append the children of DocumentFragment
tmpArr = tmpArr.concat(newChild.childNodes._nodes);
}
else {
// append the newChild
tmpArr[tmpArr.length] = newChild;
}
// append the remaining original children (including refChild)
this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex));
this.length = this._nodes.length; // update length
}
};
@method DOMNodeList._replaceChild - replace the specified Node in the NodeList at the specified index
Used by DOMNode.replaceChild(). Note: DOMNode.replaceChild() is responsible for Node Pointer surgery
DOMNodeList._replaceChild() simply modifies the internal data structure (Array).
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - the Node to be inserted
parameter: refChildIndex : int - the array index to hold the Node
DOMNodeList.prototype._replaceChild = function DOMNodeList__replaceChild(newChild, refChildIndex) {
var ret = null;
if ((refChildIndex >= 0) && (refChildIndex < this._nodes.length)) { // bounds check
ret = this._nodes[refChildIndex]; // preserve old child for return
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
// get array containing children prior to refChild
var tmpArr = new Array();
tmpArr = this._nodes.slice(0, refChildIndex);
// append the children of DocumentFragment
tmpArr = tmpArr.concat(newChild.childNodes._nodes);
// append the remaining original children (not including refChild)
this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex + 1));
}
else {
// simply replace node in array (links between Nodes are made at higher level)
this._nodes[refChildIndex] = newChild;
}
}
return ret; // return replaced node
};
@method DOMNodeList._removeChild - remove the specified Node in the NodeList at the specified index
Used by DOMNode.removeChild(). Note: DOMNode.removeChild() is responsible for Node Pointer surgery
DOMNodeList._replaceChild() simply modifies the internal data structure (Array).
author: Jon van Noort (jon@webarcana.com.au)
parameter: refChildIndex : int - the array index holding the Node to be removed
DOMNodeList.prototype._removeChild = function DOMNodeList__removeChild(refChildIndex) {
var ret = null;
if (refChildIndex > -1) { // found it!
ret = this._nodes[refChildIndex]; // return removed node
// rebuild array without removed child
var tmpArr = new Array();
tmpArr = this._nodes.slice(0, refChildIndex);
this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex +1));
this.length = this._nodes.length; // update length
}
return ret; // return removed node
};
@method DOMNodeList._appendChild - append the specified Node to the NodeList
Used by DOMNode.appendChild(). Note: DOMNode.appendChild() is responsible for Node Pointer surgery
DOMNodeList._appendChild() simply modifies the internal data structure (Array).
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - the Node to be inserted
DOMNodeList.prototype._appendChild = function DOMNodeList__appendChild(newChild) {
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
// append the children of DocumentFragment
this._nodes = this._nodes.concat(newChild.childNodes._nodes);
}
else {
// simply add node to array (links between Nodes are made at higher level)
this._nodes[this._nodes.length] = newChild;
}
this.length = this._nodes.length; // update length
};
@method DOMNodeList._cloneNodes - Returns a NodeList containing clones of the Nodes in this NodeList
author: Jon van Noort (jon@webarcana.com.au)
parameter: deep : boolean - If true, recursively clone the subtree under each of the nodes;
if false, clone only the nodes themselves (and their attributes, if it is an Element).
parameter: parentNode : DOMNode - the new parent of the cloned NodeList
returns: : DOMNodeList - NodeList containing clones of the Nodes in this NodeList
DOMNodeList.prototype._cloneNodes = function DOMNodeList__cloneNodes(deep, parentNode) {
var cloneNodeList = new DOMNodeList(this.ownerDocument, parentNode);
// create list containing clones of each child
for (var i=0; i < this._nodes.length; i++) {
cloneNodeList._appendChild(this._nodes[i].cloneNode(deep));
}
return cloneNodeList;
};
@method DOMNodeList.toString - Serialize this NodeList into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMNodeList.prototype.toString = function DOMNodeList_toString() {
var ret = "";
// create string containing the concatenation of the string values of each child
for (var i=0; i < this.length; i++) {
ret += this._nodes[i].toString();
}
return ret;
};
@class DOMNamedNodeMap - used to represent collections of nodes that can be accessed by name
typically a set of Element attributes
@extends DOMNodeList - note W3C spec says that this is not the case,
but we need an item() method identicle to DOMNodeList's, so why not?
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - the ownerDocument
parameter: parentNode : DOMNode - the node that the DOMNamedNodeMap is attached to (or null)
DOMNamedNodeMap = function(ownerDocument, parentNode) {
this._class = addClass(this._class, "DOMNamedNodeMap");
this.DOMNodeList = DOMNodeList;
this.DOMNodeList(ownerDocument, parentNode);
};
DOMNamedNodeMap.prototype = new DOMNodeList;
@method DOMNamedNodeMap.getNamedItem - Retrieves a node specified by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - Name of a node to retrieve
returns: : DOMNode
DOMNamedNodeMap.prototype.getNamedItem = function DOMNamedNodeMap_getNamedItem(name) {
var ret = null;
// test that Named Node exists
var itemIndex = this._findNamedItemIndex(name);
if (itemIndex > -1) { // found it!
ret = this._nodes[itemIndex]; // return NamedNode
}
return ret; // if node is not found, default value null is returned
};
@method DOMNamedNodeMap.setNamedItem - Adds a node using its nodeName attribute
author: Jon van Noort (jon@webarcana.com.au)
parameter: arg : DOMNode - A node to store in a named node map.
The node will later be accessible using the value of the nodeName attribute of the node.
If a node with that name is already present in the map, it is replaced by the new one.
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
@throws : DOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
The DOM user must explicitly clone Attr nodes to re-use them in other elements.
returns: : DOMNode - If the new Node replaces an existing node with the same name the previously existing Node is returned,
otherwise null is returned
DOMNamedNodeMap.prototype.setNamedItem = function DOMNamedNodeMap_setNamedItem(arg) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if arg was not created by this Document
if (this.ownerDocument != arg.ownerDocument) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
// throw Exception if DOMNamedNodeMap is readonly
if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if arg is already an attribute of another Element object
if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
}
}
// get item index
var itemIndex = this._findNamedItemIndex(arg.name);
var ret = null;
if (itemIndex > -1) { // found it!
ret = this._nodes[itemIndex]; // use existing Attribute
// throw Exception if DOMAttr is readonly
if (this.ownerDocument.implementation.errorChecking && ret._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
else {
this._nodes[itemIndex] = arg; // over-write existing NamedNode
}
}
else {
this._nodes[this.length] = arg; // add new NamedNode
}
this.length = this._nodes.length; // update length
arg.ownerElement = this.parentNode; // update ownerElement
return ret; // return old node or null
};
@method DOMNamedNodeMap.removeNamedItem - Removes a node specified by name.
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of a node to remove
@throws : DOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
returns: : DOMNode - The node removed from the map or null if no node with such a name exists.
DOMNamedNodeMap.prototype.removeNamedItem = function DOMNamedNodeMap_removeNamedItem(name) {
var ret = null;
// test for exceptions
// throw Exception if DOMNamedNodeMap is readonly
if (this.ownerDocument.implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// get item index
var itemIndex = this._findNamedItemIndex(name);
// throw Exception if there is no node named name in this map
if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
// get Node
var oldNode = this._nodes[itemIndex];
// throw Exception if Node is readonly
if (this.ownerDocument.implementation.errorChecking && oldNode._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// return removed node
return this._removeChild(itemIndex);
};
@method DOMNamedNodeMap.getNamedItemNS - Retrieves a node specified by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : DOMNode
DOMNamedNodeMap.prototype.getNamedItemNS = function DOMNamedNodeMap_getNamedItemNS(namespaceURI, localName) {
var ret = null;
// test that Named Node exists
var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
if (itemIndex > -1) { // found it!
ret = this._nodes[itemIndex]; // return NamedNode
}
return ret; // if node is not found, default value null is returned
};
@method DOMNamedNodeMap.setNamedItemNS - Adds a node using
author: Jon van Noort (jon@webarcana.com.au)
parameter: arg : string - A node to store in a named node map.
The node will later be accessible using the value of the nodeName attribute of the node.
If a node with that name is already present in the map, it is replaced by the new one.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
The DOM user must explicitly clone Attr nodes to re-use them in other elements.
returns: : DOMNode - If the new Node replaces an existing node with the same name the previously existing Node is returned,
otherwise null is returned
DOMNamedNodeMap.prototype.setNamedItemNS = function DOMNamedNodeMap_setNamedItemNS(arg) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if DOMNamedNodeMap is readonly
if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if arg was not created by this Document
if (this.ownerDocument != arg.ownerDocument) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
// throw Exception if arg is already an attribute of another Element object
if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
}
}
// get item index
var itemIndex = this._findNamedItemNSIndex(arg.namespaceURI, arg.localName);
var ret = null;
if (itemIndex > -1) { // found it!
ret = this._nodes[itemIndex]; // use existing Attribute
// throw Exception if DOMAttr is readonly
if (this.ownerDocument.implementation.errorChecking && ret._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
else {
this._nodes[itemIndex] = arg; // over-write existing NamedNode
}
}
else {
this._nodes[this.length] = arg; // add new NamedNode
}
this.length = this._nodes.length; // update length
arg.ownerElement = this.parentNode;
return ret; // return old node or null
};
@method DOMNamedNodeMap.removeNamedItemNS - Removes a node specified by name.
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
@throws : DOMException - NOT_FOUND_ERR: Raised if there is no node with the specified namespaceURI and localName in this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
returns: : DOMNode - The node removed from the map or null if no node with such a name exists.
DOMNamedNodeMap.prototype.removeNamedItemNS = function DOMNamedNodeMap_removeNamedItemNS(namespaceURI, localName) {
var ret = null;
// test for exceptions
// throw Exception if DOMNamedNodeMap is readonly
if (this.ownerDocument.implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// get item index
var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
// throw Exception if there is no matching node in this map
if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
// get Node
var oldNode = this._nodes[itemIndex];
// throw Exception if Node is readonly
if (this.ownerDocument.implementation.errorChecking && oldNode._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
return this._removeChild(itemIndex); // return removed node
};
@method DOMNamedNodeMap._findNamedItemIndex - find the item index of the node with the specified name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - the name of the required node
returns: : int
DOMNamedNodeMap.prototype._findNamedItemIndex = function DOMNamedNodeMap__findNamedItemIndex(name) {
var ret = -1;
// loop through all nodes
for (var i=0; i<this._nodes.length; i++) {
// compare name to each node's nodeName
if (this._nodes[i].name == name) { // found it!
ret = i;
break;
}
}
return ret; // if node is not found, default value -1 is returned
};
@method DOMNamedNodeMap._findNamedItemNSIndex - find the item index of the node with the specified namespaceURI and localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : int
DOMNamedNodeMap.prototype._findNamedItemNSIndex = function DOMNamedNodeMap__findNamedItemNSIndex(namespaceURI, localName) {
var ret = -1;
// test that localName is not null
if (localName) {
// loop through all nodes
for (var i=0; i<this._nodes.length; i++) {
// compare name to each node's namespaceURI and localName
if ((this._nodes[i].namespaceURI == namespaceURI) && (this._nodes[i].localName == localName)) {
ret = i; // found it!
break;
}
}
}
return ret; // if node is not found, default value -1 is returned
};
@method DOMNamedNodeMap._hasAttribute - Returns true if specified node exists
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - the name of the required node
returns: : boolean
DOMNamedNodeMap.prototype._hasAttribute = function DOMNamedNodeMap__hasAttribute(name) {
var ret = false;
// test that Named Node exists
var itemIndex = this._findNamedItemIndex(name);
if (itemIndex > -1) { // found it!
ret = true; // return true
}
return ret; // if node is not found, default value false is returned
}
@method DOMNamedNodeMap._hasAttributeNS - Returns true if specified node exists
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : boolean
DOMNamedNodeMap.prototype._hasAttributeNS = function DOMNamedNodeMap__hasAttributeNS(namespaceURI, localName) {
var ret = false;
// test that Named Node exists
var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
if (itemIndex > -1) { // found it!
ret = true; // return true
}
return ret; // if node is not found, default value false is returned
}
@method DOMNamedNodeMap._cloneNodes - Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap
author: Jon van Noort (jon@webarcana.com.au)
parameter: parentNode : DOMNode - the new parent of the cloned NodeList
returns: : DOMNamedNodeMap - NamedNodeMap containing clones of the Nodes in this DOMNamedNodeMap
DOMNamedNodeMap.prototype._cloneNodes = function DOMNamedNodeMap__cloneNodes(parentNode) {
var cloneNamedNodeMap = new DOMNamedNodeMap(this.ownerDocument, parentNode);
// create list containing clones of all children
for (var i=0; i < this._nodes.length; i++) {
cloneNamedNodeMap._appendChild(this._nodes[i].cloneNode(false));
}
return cloneNamedNodeMap;
};
@method DOMNamedNodeMap.toString - Serialize this NodeMap into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMNamedNodeMap.prototype.toString = function DOMNamedNodeMap_toString() {
var ret = "";
// create string containing concatenation of all (but last) Attribute string values (separated by spaces)
for (var i=0; i < this.length -1; i++) {
ret += this._nodes[i].toString() +" ";
}
// add last Attribute to string (without trailing space)
if (this.length > 0) {
ret += this._nodes[this.length -1].toString();
}
return ret;
};
@class DOMNamespaceNodeMap - used to represent collections of namespace nodes that can be accessed by name
typically a set of Element attributes
@extends DOMNamedNodeMap
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - the ownerDocument
parameter: parentNode : DOMNode - the node that the DOMNamespaceNodeMap is attached to (or null)
DOMNamespaceNodeMap = function(ownerDocument, parentNode) {
this._class = addClass(this._class, "DOMNamespaceNodeMap");
this.DOMNamedNodeMap = DOMNamedNodeMap;
this.DOMNamedNodeMap(ownerDocument, parentNode);
};
DOMNamespaceNodeMap.prototype = new DOMNamedNodeMap;
@method DOMNamespaceNodeMap._findNamedItemIndex - find the item index of the node with the specified localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: localName : string - the localName of the required node
returns: : int
DOMNamespaceNodeMap.prototype._findNamedItemIndex = function DOMNamespaceNodeMap__findNamedItemIndex(localName) {
var ret = -1;
// loop through all nodes
for (var i=0; i<this._nodes.length; i++) {
// compare name to each node's nodeName
if (this._nodes[i].localName == localName) { // found it!
ret = i;
break;
}
}
return ret; // if node is not found, default value -1 is returned
};
@method DOMNamespaceNodeMap._cloneNodes - Returns a NamespaceNodeMap containing clones of the Nodes in this NamespaceNodeMap
author: Jon van Noort (jon@webarcana.com.au)
parameter: parentNode : DOMNode - the new parent of the cloned NodeList
returns: : DOMNamespaceNodeMap - NamespaceNodeMap containing clones of the Nodes in this NamespaceNodeMap
DOMNamespaceNodeMap.prototype._cloneNodes = function DOMNamespaceNodeMap__cloneNodes(parentNode) {
var cloneNamespaceNodeMap = new DOMNamespaceNodeMap(this.ownerDocument, parentNode);
// create list containing clones of all children
for (var i=0; i < this._nodes.length; i++) {
cloneNamespaceNodeMap._appendChild(this._nodes[i].cloneNode(false));
}
return cloneNamespaceNodeMap;
};
@method DOMNamespaceNodeMap.toString - Serialize this NamespaceNodeMap into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMNamespaceNodeMap.prototype.toString = function DOMNamespaceNodeMap_toString() {
var ret = "";
// identify namespaces declared local to this Element (ie, not inherited)
for (var ind = 0; ind < this._nodes.length; ind++) {
// if namespace declaration does not exist in the containing node's, parentNode's namespaces
var ns = null;
try {
var ns = this.parentNode.parentNode._namespaces.getNamedItem(this._nodes[ind].localName);
}
catch (e) {
//breaking to prevent default namespace being inserted into return value
break;
}
if (!(ns && (""+ ns.nodeValue == ""+ this._nodes[ind].nodeValue))) {
// display the namespace declaration
ret += this._nodes[ind].toString() +" ";
}
}
return ret;
};
@class DOMNode - The Node interface is the primary datatype for the entire Document Object Model.
It represents a single node in the document tree.
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMNode = function(ownerDocument) {
this._class = addClass(this._class, "DOMNode");
if (ownerDocument) {
this._id = ownerDocument._genId(); // generate unique internal id
}
this.namespaceURI = ""; // The namespace URI of this node (Level 2)
this.prefix = ""; // The namespace prefix of this node (Level 2)
this.localName = ""; // The localName of this node (Level 2)
this.nodeName = ""; // The name of this node
this.nodeValue = ""; // The value of this node
this.nodeType = 0; // A code representing the type of the underlying object
// The parent of this node. All nodes, except Document, DocumentFragment, and Attr may have a parent.
// However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is null
this.parentNode = null;
// A NodeList that contains all children of this node. If there are no children, this is a NodeList containing no nodes.
// The content of the returned NodeList is "live" in the sense that, for instance, changes to the children of the node object
// that it was created from are immediately reflected in the nodes returned by the NodeList accessors;
// it is not a static snapshot of the content of the node. This is true for every NodeList, including the ones returned by the getElementsByTagName method.
this.childNodes = new DOMNodeList(ownerDocument, this);
this.firstChild = null; // The first child of this node. If there is no such node, this is null
this.lastChild = null; // The last child of this node. If there is no such node, this is null.
this.previousSibling = null; // The node immediately preceding this node. If there is no such node, this is null.
this.nextSibling = null; // The node immediately following this node. If there is no such node, this is null.
this.attributes = new DOMNamedNodeMap(ownerDocument, this); // A NamedNodeMap containing the attributes of this node (if it is an Element) or null otherwise.
this.ownerDocument = ownerDocument; // The Document object associated with this node
this._namespaces = new DOMNamespaceNodeMap(ownerDocument, this); // The namespaces in scope for this node
this._readonly = false;
};
// nodeType constants
DOMNode.ELEMENT_NODE = 1;
DOMNode.ATTRIBUTE_NODE = 2;
DOMNode.TEXT_NODE = 3;
DOMNode.CDATA_SECTION_NODE = 4;
DOMNode.ENTITY_REFERENCE_NODE = 5;
DOMNode.ENTITY_NODE = 6;
DOMNode.PROCESSING_INSTRUCTION_NODE = 7;
DOMNode.COMMENT_NODE = 8;
DOMNode.DOCUMENT_NODE = 9;
DOMNode.DOCUMENT_TYPE_NODE = 10;
DOMNode.DOCUMENT_FRAGMENT_NODE = 11;
DOMNode.NOTATION_NODE = 12;
DOMNode.NAMESPACE_NODE = 13;
@method DOMNode.hasAttributes
author: Jon van Noort (jon@webarcana.com.au) & David Joham (djoham@yahoo.com)
returns: : boolean
DOMNode.prototype.hasAttributes = function DOMNode_hasAttributes() {
if (this.attributes.length == 0) {
return false;
}
else {
return true;
}
};
@method DOMNode.getNodeName - Java style gettor for .nodeName
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMNode.prototype.getNodeName = function DOMNode_getNodeName() {
return this.nodeName;
};
@method DOMNode.getNodeValue - Java style gettor for .NodeValue
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMNode.prototype.getNodeValue = function DOMNode_getNodeValue() {
return this.nodeValue;
};
@method DOMNode.setNodeValue - Java style settor for .NodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: nodeValue : string - unique internal id
DOMNode.prototype.setNodeValue = function DOMNode_setNodeValue(nodeValue) {
// throw Exception if DOMNode is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
this.nodeValue = nodeValue;
};
@method DOMNode.getNodeType - Java style gettor for .nodeType
author: Jon van Noort (jon@webarcana.com.au)
returns: : int
DOMNode.prototype.getNodeType = function DOMNode_getNodeType() {
return this.nodeType;
};
@method DOMNode.getParentNode - Java style gettor for .parentNode
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNode
DOMNode.prototype.getParentNode = function DOMNode_getParentNode() {
return this.parentNode;
};
@method DOMNode.getChildNodes - Java style gettor for .childNodes
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNodeList
DOMNode.prototype.getChildNodes = function DOMNode_getChildNodes() {
return this.childNodes;
};
@method DOMNode.getFirstChild - Java style gettor for .firstChild
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNode
DOMNode.prototype.getFirstChild = function DOMNode_getFirstChild() {
return this.firstChild;
};
@method DOMNode.getLastChild - Java style gettor for .lastChild
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNode
DOMNode.prototype.getLastChild = function DOMNode_getLastChild() {
return this.lastChild;
};
@method DOMNode.getPreviousSibling - Java style gettor for .previousSibling
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNode
DOMNode.prototype.getPreviousSibling = function DOMNode_getPreviousSibling() {
return this.previousSibling;
};
@method DOMNode.getNextSibling - Java style gettor for .nextSibling
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNode
DOMNode.prototype.getNextSibling = function DOMNode_getNextSibling() {
return this.nextSibling;
};
@method DOMNode.getAttributes - Java style gettor for .attributes
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMNamedNodeList
DOMNode.prototype.getAttributes = function DOMNode_getAttributes() {
return this.attributes;
};
@method DOMNode.getOwnerDocument - Java style gettor for .ownerDocument
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMDocument
DOMNode.prototype.getOwnerDocument = function DOMNode_getOwnerDocument() {
return this.ownerDocument;
};
@method DOMNode.getNamespaceURI - Java style gettor for .namespaceURI
author: Jon van Noort (jon@webarcana.com.au)
returns: : String
DOMNode.prototype.getNamespaceURI = function DOMNode_getNamespaceURI() {
return this.namespaceURI;
};
@method DOMNode.getPrefix - Java style gettor for .prefix
author: Jon van Noort (jon@webarcana.com.au)
returns: : String
DOMNode.prototype.getPrefix = function DOMNode_getPrefix() {
return this.prefix;
};
@method DOMNode.setPrefix - Java style settor for .prefix
author: Jon van Noort (jon@webarcana.com.au)
parameter: prefix : String
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
@throws : DOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
DOMNode.prototype.setPrefix = function DOMNode_setPrefix(prefix) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if DOMNode is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if the prefix string contains an illegal character
if (!this.ownerDocument.implementation._isValidName(prefix)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
// throw Exception if the Namespace is invalid;
// if the specified prefix is malformed,
// if the namespaceURI of this node is null,
// if the specified prefix is "xml" and the namespaceURI of this node is
// different from "http://www.w3.org/XML/1998/namespace",
if (!this.ownerDocument._isValidNamespace(this.namespaceURI, prefix +":"+ this.localName)) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
// throw Exception if we are trying to make the attribute look like a namespace declaration;
// if this node is an attribute and the specified prefix is "xmlns"
// and the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/",
if ((prefix == "xmlns") && (this.namespaceURI != "http://www.w3.org/2000/xmlns/")) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
// throw Exception if we are trying to make the attribute look like a default namespace declaration;
// if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces].
if ((prefix == "") && (this.localName == "xmlns")) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
}
// update prefix
this.prefix = prefix;
// update nodeName (QName)
if (this.prefix != "") {
this.nodeName = this.prefix +":"+ this.localName;
}
else {
this.nodeName = this.localName; // no prefix, therefore nodeName is simply localName
}
};
@method DOMNode.getLocalName - Java style gettor for .localName
author: Jon van Noort (jon@webarcana.com.au)
returns: : String
DOMNode.prototype.getLocalName = function DOMNode_getLocalName() {
return this.localName;
};
@method DOMNode.insertBefore - Inserts the node newChild before the existing child node refChild.
If refChild is null, insert newChild at the end of the list of children.
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - The node to insert.
parameter: refChild : DOMNode - The reference node, i.e., the node before which the new node must be inserted
@throws : DOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
@throws : DOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
returns: : DOMNode - The node being inserted.
DOMNode.prototype.insertBefore = function DOMNode_insertBefore(newChild, refChild) {
var prevNode;
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if DOMNode is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if newChild was not created by this Document
if (this.ownerDocument != newChild.ownerDocument) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
// throw Exception if the node is an ancestor
if (this._isAncestor(newChild)) {
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
}
}
if (refChild) { // if refChild is specified, insert before it
// find index of refChild
var itemIndex = this.childNodes._findItemIndex(refChild._id);
// throw Exception if there is no child node with this id
if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
// if the newChild is already in the tree,
var newChildParent = newChild.parentNode;
if (newChildParent) {
// remove it
newChildParent.removeChild(newChild);
}
// insert newChild into childNodes
this.childNodes._insertBefore(newChild, this.childNodes._findItemIndex(refChild._id));
// do node pointer surgery
prevNode = refChild.previousSibling;
// handle DocumentFragment
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
if (newChild.childNodes._nodes.length > 0) {
// set the parentNode of DocumentFragment's children
for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
newChild.childNodes._nodes[ind].parentNode = this;
}
// link refChild to last child of DocumentFragment
refChild.previousSibling = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
}
}
else {
newChild.parentNode = this; // set the parentNode of the newChild
refChild.previousSibling = newChild; // link refChild to newChild
}
}
else { // otherwise, append to end
prevNode = this.lastChild;
this.appendChild(newChild);
}
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
// do node pointer surgery for DocumentFragment
if (newChild.childNodes._nodes.length > 0) {
if (prevNode) {
prevNode.nextSibling = newChild.childNodes._nodes[0];
}
else { // this is the first child in the list
this.firstChild = newChild.childNodes._nodes[0];
}
newChild.childNodes._nodes[0].previousSibling = prevNode;
newChild.childNodes._nodes[newChild.childNodes._nodes.length-1].nextSibling = refChild;
}
}
else {
// do node pointer surgery for newChild
if (prevNode) {
prevNode.nextSibling = newChild;
}
else { // this is the first child in the list
this.firstChild = newChild;
}
newChild.previousSibling = prevNode;
newChild.nextSibling = refChild;
}
return newChild;
};
@method DOMNode.replaceChild - Replaces the child node oldChild with newChild in the list of children,
and returns the oldChild node.
If the newChild is already in the tree, it is first removed.
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - The node to insert.
parameter: oldChild : DOMNode - The node being replaced in the list.
@throws : DOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
@throws : DOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
returns: : DOMNode - The node that was replaced
DOMNode.prototype.replaceChild = function DOMNode_replaceChild(newChild, oldChild) {
var ret = null;
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if DOMNode is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if newChild was not created by this Document
if (this.ownerDocument != newChild.ownerDocument) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
// throw Exception if the node is an ancestor
if (this._isAncestor(newChild)) {
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
}
}
// get index of oldChild
var index = this.childNodes._findItemIndex(oldChild._id);
// throw Exception if there is no child node with this id
if (this.ownerDocument.implementation.errorChecking && (index < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
// if the newChild is already in the tree,
var newChildParent = newChild.parentNode;
if (newChildParent) {
// remove it
newChildParent.removeChild(newChild);
}
// add newChild to childNodes
ret = this.childNodes._replaceChild(newChild, index);
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
// do node pointer surgery for Document Fragment
if (newChild.childNodes._nodes.length > 0) {
for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
newChild.childNodes._nodes[ind].parentNode = this;
}
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = newChild.childNodes._nodes[0];
}
else {
this.firstChild = newChild.childNodes._nodes[0];
}
if (oldChild.nextSibling) {
oldChild.nextSibling.previousSibling = newChild;
}
else {
this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
}
newChild.childNodes._nodes[0].previousSibling = oldChild.previousSibling;
newChild.childNodes._nodes[newChild.childNodes._nodes.length-1].nextSibling = oldChild.nextSibling;
}
}
else {
// do node pointer surgery for newChild
newChild.parentNode = this;
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = newChild;
}
else {
this.firstChild = newChild;
}
if (oldChild.nextSibling) {
oldChild.nextSibling.previousSibling = newChild;
}
else {
this.lastChild = newChild;
}
newChild.previousSibling = oldChild.previousSibling;
newChild.nextSibling = oldChild.nextSibling;
}
return ret;
};
@method DOMNode.removeChild - Removes the child node indicated by oldChild from the list of children, and returns it.
author: Jon van Noort (jon@webarcana.com.au)
parameter: oldChild : DOMNode - The node being removed.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
@throws : DOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
returns: : DOMNode - The node being removed.
DOMNode.prototype.removeChild = function DOMNode_removeChild(oldChild) {
// throw Exception if DOMNamedNodeMap is readonly
if (this.ownerDocument.implementation.errorChecking && (this._readonly || oldChild._readonly)) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// get index of oldChild
var itemIndex = this.childNodes._findItemIndex(oldChild._id);
// throw Exception if there is no child node with this id
if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
// remove oldChild from childNodes
this.childNodes._removeChild(itemIndex);
// do node pointer surgery
oldChild.parentNode = null;
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = oldChild.nextSibling;
}
else {
this.firstChild = oldChild.nextSibling;
}
if (oldChild.nextSibling) {
oldChild.nextSibling.previousSibling = oldChild.previousSibling;
}
else {
this.lastChild = oldChild.previousSibling;
}
oldChild.previousSibling = null;
oldChild.nextSibling = null;
return oldChild;
};
@method DOMNode.appendChild - Adds the node newChild to the end of the list of children of this node.
If the newChild is already in the tree, it is first removed.
author: Jon van Noort (jon@webarcana.com.au)
parameter: newChild : DOMNode - The node to add
@throws : DOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
returns: : DOMNode - The node added
DOMNode.prototype.appendChild = function DOMNode_appendChild(newChild) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if arg was not created by this Document
if (this.ownerDocument != newChild.ownerDocument) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
// throw Exception if the node is an ancestor
if (this._isAncestor(newChild)) {
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
}
}
// if the newChild is already in the tree,
var newChildParent = newChild.parentNode;
if (newChildParent) {
// remove it
newChildParent.removeChild(newChild);
}
// add newChild to childNodes
this.childNodes._appendChild(newChild);
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
// do node pointer surgery for DocumentFragment
if (newChild.childNodes._nodes.length > 0) {
for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
newChild.childNodes._nodes[ind].parentNode = this;
}
if (this.lastChild) {
this.lastChild.nextSibling = newChild.childNodes._nodes[0];
newChild.childNodes._nodes[0].previousSibling = this.lastChild;
this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
}
else {
this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
this.firstChild = newChild.childNodes._nodes[0];
}
}
}
else {
// do node pointer surgery for newChild
newChild.parentNode = this;
if (this.lastChild) {
this.lastChild.nextSibling = newChild;
newChild.previousSibling = this.lastChild;
this.lastChild = newChild;
}
else {
this.lastChild = newChild;
this.firstChild = newChild;
}
}
return newChild;
};
@method DOMNode.hasChildNodes - This is a convenience method to allow easy determination of whether a node has any children.
author: Jon van Noort (jon@webarcana.com.au)
returns: : boolean - true if the node has any children, false if the node has no children
DOMNode.prototype.hasChildNodes = function DOMNode_hasChildNodes() {
return (this.childNodes.length > 0);
};
@method DOMNode.cloneNode - Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes.
The duplicate node has no parent (parentNode returns null.).
author: Jon van Noort (jon@webarcana.com.au)
parameter: deep : boolean - If true, recursively clone the subtree under the specified node;
if false, clone only the node itself (and its attributes, if it is an Element).
returns: : DOMNode
DOMNode.prototype.cloneNode = function DOMNode_cloneNode(deep) {
// use importNode to clone this Node
//do not throw any exceptions
try {
return this.ownerDocument.importNode(this, deep);
}
catch (e) {
//there shouldn't be any exceptions, but if there are, return null
return null;
}
};
@method DOMNode.normalize - Puts all Text nodes in the full depth of the sub-tree underneath this Element into a "normal" form
where only markup (e.g., tags, comments, processing instructions, CDATA sections, and entity references) separates Text nodes,
i.e., there are no adjacent Text nodes.
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
DOMNode.prototype.normalize = function DOMNode_normalize() {
var inode;
var nodesToRemove = new DOMNodeList();
if (this.nodeType == DOMNode.ELEMENT_NODE || this.nodeType == DOMNode.DOCUMENT_NODE) {
var adjacentTextNode = null;
// loop through all childNodes
for(var i = 0; i < this.childNodes.length; i++) {
inode = this.childNodes.item(i);
if (inode.nodeType == DOMNode.TEXT_NODE) { // this node is a text node
if (inode.length < 1) { // this text node is empty
nodesToRemove._appendChild(inode); // add this node to the list of nodes to be remove
}
else {
if (adjacentTextNode) { // if previous node was also text
adjacentTextNode.appendData(inode.data); // merge the data in adjacent text nodes
nodesToRemove._appendChild(inode); // add this node to the list of nodes to be removed
}
else {
adjacentTextNode = inode; // remember this node for next cycle
}
}
}
else {
adjacentTextNode = null; // (soon to be) previous node is not a text node
inode.normalize(); // normalise non Text childNodes
}
}
// remove redundant Text Nodes
for(var i = 0; i < nodesToRemove.length; i++) {
inode = nodesToRemove.item(i);
inode.parentNode.removeChild(inode);
}
}
};
@method DOMNode.isSupported - Test if the DOM implementation implements a specific feature
author: Jon van Noort (jon@webarcana.com.au)
parameter: feature : string - The package name of the feature to test. the legal only values are "XML" and "CORE" (case-insensitive).
parameter: version : string - This is the version number of the package name to test. In Level 1, this is the string "1.0".
returns: : boolean
DOMNode.prototype.isSupported = function DOMNode_isSupported(feature, version) {
// use Implementation.hasFeature to determin if this feature is supported
return this.ownerDocument.implementation.hasFeature(feature, version);
}
@method DOMNode.getElementsByTagName - Returns a NodeList of all the Elements with a given tag name
in the order in which they would be encountered in a preorder traversal of the Document tree.
author: Jon van Noort (jon@webarcana.com.au)
parameter: tagname : string - The name of the tag to match on. The special value "*" matches all tags
returns: : DOMNodeList
DOMNode.prototype.getElementsByTagName = function DOMNode_getElementsByTagName(tagname) {
// delegate to _getElementsByTagNameRecursive
return this._getElementsByTagNameRecursive(tagname, new DOMNodeList(this.ownerDocument));
};
@method DOMNode._getElementsByTagNameRecursive - implements getElementsByTagName()
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: tagname : string - The name of the tag to match on. The special value "*" matches all tags
parameter: nodeList : DOMNodeList - The accumulating list of matching nodes
returns: : DOMNodeList
DOMNode.prototype._getElementsByTagNameRecursive = function DOMNode__getElementsByTagNameRecursive(tagname, nodeList) {
if (this.nodeType == DOMNode.ELEMENT_NODE || this.nodeType == DOMNode.DOCUMENT_NODE) {
if((this.nodeName == tagname) || (tagname == "*")) {
nodeList._appendChild(this); // add matching node to nodeList
}
// recurse childNodes
for(var i = 0; i < this.childNodes.length; i++) {
nodeList = this.childNodes.item(i)._getElementsByTagNameRecursive(tagname, nodeList);
}
}
return nodeList;
};
@method DOMNode.getXML - Returns the String XML of the node and all of its children
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string - XML String of the XML of the node and all of its children
DOMNode.prototype.getXML = function DOMNode_getXML() {
return this.toString();
}
@method DOMNode.getElementsByTagNameNS - Returns a NodeList of all the Elements with a given namespaceURI and localName
in the order in which they would be encountered in a preorder traversal of the Document tree.
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : DOMNodeList
DOMNode.prototype.getElementsByTagNameNS = function DOMNode_getElementsByTagNameNS(namespaceURI, localName) {
// delegate to _getElementsByTagNameNSRecursive
return this._getElementsByTagNameNSRecursive(namespaceURI, localName, new DOMNodeList(this.ownerDocument));
};
@method DOMNode._getElementsByTagNameNSRecursive - implements getElementsByTagName()
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
parameter: nodeList : DOMNodeList - The accumulating list of matching nodes
returns: : DOMNodeList
DOMNode.prototype._getElementsByTagNameNSRecursive = function DOMNode__getElementsByTagNameNSRecursive(namespaceURI, localName, nodeList) {
if (this.nodeType == DOMNode.ELEMENT_NODE || this.nodeType == DOMNode.DOCUMENT_NODE) {
if (((this.namespaceURI == namespaceURI) || (namespaceURI == "*")) && ((this.localName == localName) || (localName == "*"))) {
nodeList._appendChild(this); // add matching node to nodeList
}
// recurse childNodes
for(var i = 0; i < this.childNodes.length; i++) {
nodeList = this.childNodes.item(i)._getElementsByTagNameNSRecursive(namespaceURI, localName, nodeList);
}
}
return nodeList;
};
@method DOMNode._isAncestor - returns true if node is ancestor of this
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: node : DOMNode - The candidate ancestor node
returns: : boolean
DOMNode.prototype._isAncestor = function DOMNode__isAncestor(node) {
// if this node matches, return true,
// otherwise recurse up (if there is a parentNode)
return ((this == node) || ((this.parentNode) && (this.parentNode._isAncestor(node))));
}
@method DOMNode.importNode - Imports a node from another document to this document.
The returned node has no parent; (parentNode is null).
author: Jon van Noort (jon@webarcana.com.au)
parameter: importedNode : Node - The Node to be imported
parameter: deep : boolean - If true, recursively clone the subtree under the specified node;
if false, clone only the node itself (and its attributes, if it is an Element).
returns: : DOMNode
DOMNode.prototype.importNode = function DOMNode_importNode(importedNode, deep) {
var importNode;
//there is no need to perform namespace checks since everything has already gone through them
//in order to have gotten into the DOM in the first place. The following line
//turns namespace checking off in ._isValidNamespace
this.getOwnerDocument()._performingImportNodeOperation = true;
try {
if (importedNode.nodeType == DOMNode.ELEMENT_NODE) {
if (!this.ownerDocument.implementation.namespaceAware) {
// create a local Element (with the name of the importedNode)
importNode = this.ownerDocument.createElement(importedNode.tagName);
// create attributes matching those of the importedNode
for(var i = 0; i < importedNode.attributes.length; i++) {
importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
}
}
else {
// create a local Element (with the name & namespaceURI of the importedNode)
importNode = this.ownerDocument.createElementNS(importedNode.namespaceURI, importedNode.nodeName);
// create attributes matching those of the importedNode
for(var i = 0; i < importedNode.attributes.length; i++) {
importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI, importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
}
// create namespace definitions matching those of the importedNode
for(var i = 0; i < importedNode._namespaces.length; i++) {
importNode._namespaces._nodes[i] = this.ownerDocument.createNamespace(importedNode._namespaces.item(i).localName);
importNode._namespaces._nodes[i].setValue(importedNode._namespaces.item(i).value);
}
}
}
else if (importedNode.nodeType == DOMNode.ATTRIBUTE_NODE) {
if (!this.ownerDocument.implementation.namespaceAware) {
// create a local Attribute (with the name of the importedAttribute)
importNode = this.ownerDocument.createAttribute(importedNode.name);
}
else {
// create a local Attribute (with the name & namespaceURI of the importedAttribute)
importNode = this.ownerDocument.createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
// create namespace definitions matching those of the importedAttribute
for(var i = 0; i < importedNode._namespaces.length; i++) {
importNode._namespaces._nodes[i] = this.ownerDocument.createNamespace(importedNode._namespaces.item(i).localName);
importNode._namespaces._nodes[i].setValue(importedNode._namespaces.item(i).value);
}
}
// set the value of the local Attribute to match that of the importedAttribute
importNode.setValue(importedNode.value);
}
else if (importedNode.nodeType == DOMNode.DOCUMENT_FRAGMENT) {
// create a local DocumentFragment
importNode = this.ownerDocument.createDocumentFragment();
}
else if (importedNode.nodeType == DOMNode.NAMESPACE_NODE) {
// create a local NamespaceNode (with the same name & value as the importedNode)
importNode = this.ownerDocument.createNamespace(importedNode.nodeName);
importNode.setValue(importedNode.value);
}
else if (importedNode.nodeType == DOMNode.TEXT_NODE) {
// create a local TextNode (with the same data as the importedNode)
importNode = this.ownerDocument.createTextNode(importedNode.data);
}
else if (importedNode.nodeType == DOMNode.CDATA_SECTION_NODE) {
// create a local CDATANode (with the same data as the importedNode)
importNode = this.ownerDocument.createCDATASection(importedNode.data);
}
else if (importedNode.nodeType == DOMNode.PROCESSING_INSTRUCTION_NODE) {
// create a local ProcessingInstruction (with the same target & data as the importedNode)
importNode = this.ownerDocument.createProcessingInstruction(importedNode.target, importedNode.data);
}
else if (importedNode.nodeType == DOMNode.COMMENT_NODE) {
// create a local Comment (with the same data as the importedNode)
importNode = this.ownerDocument.createComment(importedNode.data);
}
else { // throw Exception if nodeType is not supported
throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
}
if (deep) { // recurse childNodes
for(var i = 0; i < importedNode.childNodes.length; i++) {
importNode.appendChild(this.ownerDocument.importNode(importedNode.childNodes.item(i), true));
}
}
//reset _performingImportNodeOperation
this.getOwnerDocument()._performingImportNodeOperation = false;
return importNode;
}
catch (eAny) {
//reset _performingImportNodeOperation
this.getOwnerDocument()._performingImportNodeOperation = false;
//re-throw the exception
throw eAny;
}//djotemp
};
@method DOMNode.escapeString - escape special characters
author: Jon van Noort (jon@webarcana.com.au)
parameter: str : string - The string to be escaped
returns: : string - The escaped string
DOMNode.prototype.__escapeString = function DOMNode__escapeString(str) {
//the sax processor already has this function. Just wrap it
return __escapeString(str);
};
@method DOMNode.unescapeString - unescape special characters
author: Jon van Noort (jon@webarcana.com.au)
parameter: str : string - The string to be unescaped
returns: : string - The unescaped string
DOMNode.prototype.__unescapeString = function DOMNode__unescapeString(str) {
//the sax processor already has this function. Just wrap it
return __unescapeString(str);
};
@class DOMDocument - The Document interface represents the entire HTML or XML document.
Conceptually, it is the root of the document tree, and provides the primary access to the document's data.
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: implementation : DOMImplementation - the creator Implementation
DOMDocument = function(implementation) {
this._class = addClass(this._class, "DOMDocument");
this.DOMNode = DOMNode;
this.DOMNode(this);
this.doctype = null; // The Document Type Declaration (see DocumentType) associated with this document
this.implementation = implementation; // The DOMImplementation object that handles this document.
this.documentElement = null; // This is a convenience attribute that allows direct access to the child node that is the root element of the document
this.all = new Array(); // The list of all Elements
this.nodeName = "#document";
this.nodeType = DOMNode.DOCUMENT_NODE;
this._id = 0;
this._lastId = 0;
this._parseComplete = false; // initially false, set to true by parser
this.ownerDocument = this;
this._performingImportNodeOperation = false;
};
DOMDocument.prototype = new DOMNode;
@method DOMDocument.getDoctype - Java style gettor for .doctype
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMDocument
DOMDocument.prototype.getDoctype = function DOMDocument_getDoctype() {
return this.doctype;
};
@method DOMDocument.getImplementation - Java style gettor for .implementation
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMImplementation
DOMDocument.prototype.getImplementation = function DOMDocument_implementation() {
return this.implementation;
};
@method DOMDocument.getDocumentElement - Java style gettor for .documentElement
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMDocumentElement
DOMDocument.prototype.getDocumentElement = function DOMDocument_getDocumentElement() {
return this.documentElement;
};
@method DOMDocument.createElement - Creates an element of the type specified.
Note that the instance returned implements the Element interface,
so attributes can be specified directly on the returned object.
author: Jon van Noort (jon@webarcana.com.au)
parameter: tagName : string - The name of the element type to instantiate.
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
returns: : DOMElement - The new Element object.
DOMDocument.prototype.createElement = function DOMDocument_createElement(tagName) {
// throw Exception if the tagName string contains an illegal character
if (this.ownerDocument.implementation.errorChecking && (!this.ownerDocument.implementation._isValidName(tagName))) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
// create DOMElement specifying 'this' as ownerDocument
var node = new DOMElement(this);
// assign values to properties (and aliases)
node.tagName = tagName;
node.nodeName = tagName;
// add Element to 'all' collection
this.all[this.all.length] = node;
return node;
};
@method DOMDocument.createDocumentFragment - CCreates an empty DocumentFragment object.
author: Jon van Noort (jon@webarcana.com.au)
returns: : DOMDocumentFragment - The new DocumentFragment object
DOMDocument.prototype.createDocumentFragment = function DOMDocument_createDocumentFragment() {
// create DOMDocumentFragment specifying 'this' as ownerDocument
var node = new DOMDocumentFragment(this);
return node;
};
@method DOMDocument.createTextNode - Creates a Text node given the specified string.
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - The data for the node.
returns: : DOMText - The new Text object.
DOMDocument.prototype.createTextNode = function DOMDocument_createTextNode(data) {
// create DOMText specifying 'this' as ownerDocument
var node = new DOMText(this);
// assign values to properties (and aliases)
node.data = data;
node.nodeValue = data;
// set initial length
node.length = data.length;
return node;
};
@method DOMDocument.createComment - Creates a Text node given the specified string.
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - The data for the node.
returns: : DOMComment - The new Comment object.
DOMDocument.prototype.createComment = function DOMDocument_createComment(data) {
// create DOMComment specifying 'this' as ownerDocument
var node = new DOMComment(this);
// assign values to properties (and aliases)
node.data = data;
node.nodeValue = data;
// set initial length
node.length = data.length;
return node;
};
@method DOMDocument.createCDATASection - Creates a CDATASection node whose value is the specified string.
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - The data for the node.
returns: : DOMCDATASection - The new CDATASection object.
DOMDocument.prototype.createCDATASection = function DOMDocument_createCDATASection(data) {
// create DOMCDATASection specifying 'this' as ownerDocument
var node = new DOMCDATASection(this);
// assign values to properties (and aliases)
node.data = data;
node.nodeValue = data;
// set initial length
node.length = data.length;
return node;
};
@method DOMDocument.createProcessingInstruction - Creates a ProcessingInstruction node given the specified target and data strings.
author: Jon van Noort (jon@webarcana.com.au)
parameter: target : string - The target part of the processing instruction.
parameter: data : string - The data for the node.
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
returns: : DOMProcessingInstruction - The new ProcessingInstruction object.
DOMDocument.prototype.createProcessingInstruction = function DOMDocument_createProcessingInstruction(target, data) {
// throw Exception if the target string contains an illegal character
if (this.ownerDocument.implementation.errorChecking && (!this.implementation._isValidName(target))) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
// create DOMProcessingInstruction specifying 'this' as ownerDocument
var node = new DOMProcessingInstruction(this);
// assign values to properties (and aliases)
node.target = target;
node.nodeName = target;
node.data = data;
node.nodeValue = data;
// set initial length
node.length = data.length;
return node;
};
@method DOMDocument.createAttribute - Creates an Attr of the given name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of the attribute.
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
returns: : DOMAttr - The new Attr object.
DOMDocument.prototype.createAttribute = function DOMDocument_createAttribute(name) {
// throw Exception if the name string contains an illegal character
if (this.ownerDocument.implementation.errorChecking && (!this.ownerDocument.implementation._isValidName(name))) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
// create DOMAttr specifying 'this' as ownerDocument
var node = new DOMAttr(this);
// assign values to properties (and aliases)
node.name = name;
node.nodeName = name;
return node;
};
@method DOMDocument.createElementNS - Creates an element of the type specified,
within the specified namespace.
Note that the instance returned implements the Element interface,
so attributes can be specified directly on the returned object.
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - The namespace URI of the element.
parameter: qualifiedName : string - The qualified name of the element type to instantiate.
@throws : DOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
returns: : DOMElement - The new Element object.
DOMDocument.prototype.createElementNS = function DOMDocument_createElementNS(namespaceURI, qualifiedName) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if the Namespace is invalid
if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName)) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
// throw Exception if the qualifiedName string contains an illegal character
if (!this.ownerDocument.implementation._isValidName(qualifiedName)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
// create DOMElement specifying 'this' as ownerDocument
var node = new DOMElement(this);
var qname = this.implementation._parseQName(qualifiedName);
// assign values to properties (and aliases)
node.nodeName = qualifiedName;
node.namespaceURI = namespaceURI;
node.prefix = qname.prefix;
node.localName = qname.localName;
node.tagName = qualifiedName;
// add Element to 'all' collection
this.all[this.all.length] = node;
return node;
};
@method DOMDocument.createAttributeNS - Creates an Attr of the given name
within the specified namespace.
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - The namespace URI of the attribute.
parameter: qualifiedName : string - The qualified name of the attribute.
@throws : DOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
returns: : DOMAttr - The new Attr object.
DOMDocument.prototype.createAttributeNS = function DOMDocument_createAttributeNS(namespaceURI, qualifiedName) {
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if the Namespace is invalid
if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName, true)) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
// throw Exception if the qualifiedName string contains an illegal character
if (!this.ownerDocument.implementation._isValidName(qualifiedName)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
// create DOMAttr specifying 'this' as ownerDocument
var node = new DOMAttr(this);
var qname = this.implementation._parseQName(qualifiedName);
// assign values to properties (and aliases)
node.nodeName = qualifiedName
node.namespaceURI = namespaceURI
node.prefix = qname.prefix;
node.localName = qname.localName;
node.name = qualifiedName
node.nodeValue = "";
return node;
};
@method DOMDocument.createNamespace - Creates an Namespace of the given name
author: Jon van Noort (jon@webarcana.com.au)
parameter: qualifiedName : string - The qualified name of the attribute.
returns: : DOMNamespace - The new Namespace object.
DOMDocument.prototype.createNamespace = function DOMDocument_createNamespace(qualifiedName) {
// create DOMNamespace specifying 'this' as ownerDocument
var node = new DOMNamespace(this);
var qname = this.implementation._parseQName(qualifiedName);
// assign values to properties (and aliases)
node.nodeName = qualifiedName
node.prefix = qname.prefix;
node.localName = qname.localName;
node.name = qualifiedName
node.nodeValue = "";
return node;
};
@method DOMDocument.getElementById - Return the Element whose ID is given by elementId
author: Jon van Noort (jon@webarcana.com.au)
parameter: elementId : string - The unique ID of the Element
returns: : DOMElement - The requested DOMElement
DOMDocument.prototype.getElementById = function DOMDocument_getElementById(elementId) {
// return this._ids[elementId];
retNode = null;
// loop through all Elements in the 'all' collection
for (var i=0; i < this.all.length; i++) {
var node = this.all[i];
// if id matches & node is alive (ie, connected (in)directly to the documentElement)
if ((node.id == elementId) && (node._isAncestor(node.ownerDocument.documentElement))) {
retNode = node;
break;
}
}
return retNode;
};
@method DOMDocument._genId - generate a unique internal id
author: Jon van Noort (jon@webarcana.com.au)
returns: : string - The unique (serial) id
DOMDocument.prototype._genId = function DOMDocument__genId() {
this._lastId += 1; // increment lastId (to generate unique id)
return this._lastId;
};
@method DOMDocument._isValidNamespace - test if Namespace is valid
ie, not valid if;
the qualifiedName is malformed, or
the qualifiedName has a prefix and the namespaceURI is null, or
the qualifiedName has a prefix that is "xml" and the namespaceURI is
different from "http://www.w3.org/XML/1998/namespace" [Namespaces].
author: Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
parameter: namespaceURI : string - the namespace URI
parameter: qualifiedName : string - the QName
@Param isAttribute : boolean - true, if the requesting node is an Attr
returns: : boolean
DOMDocument.prototype._isValidNamespace = function DOMDocument__isValidNamespace(namespaceURI, qualifiedName, isAttribute) {
if (this._performingImportNodeOperation == true) {
//we're doing an importNode operation (or a cloneNode) - in both cases, there
//is no need to perform any namespace checking since the nodes have to have been valid
//to have gotten into the DOM in the first place
return true;
}
var valid = true;
// parse QName
var qName = this.implementation._parseQName(qualifiedName);
//only check for namespaces if we're finished parsing
if (this._parseComplete == true) {
// if the qualifiedName is malformed
if (qName.localName.indexOf(":") > -1 ){
valid = false;
}
if ((valid) && (!isAttribute)) {
// if the namespaceURI is not null
if (!namespaceURI) {
valid = false;
}
}
// if the qualifiedName has a prefix
if ((valid) && (qName.prefix == "")) {
valid = false;
}
}
// if the qualifiedName has a prefix that is "xml" and the namespaceURI is
// different from "http://www.w3.org/XML/1998/namespace" [Namespaces].
if ((valid) && (qName.prefix == "xml") && (namespaceURI != "http://www.w3.org/XML/1998/namespace")) {
valid = false;
}
return valid;
}
@method DOMDocument.toString - Serialize the document into an XML string
author: David Joham (djoham@yahoo.com)
returns: : string
DOMDocument.prototype.toString = function DOMDocument_toString() {
return "" + this.childNodes;
} // end function getXML
@class DOMElement - By far the vast majority of objects (apart from text) that authors encounter
when traversing a document are Element nodes.
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMElement = function(ownerDocument) {
this._class = addClass(this._class, "DOMElement");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
this.tagName = ""; // The name of the element.
this.id = ""; // the ID of the element
this.nodeType = DOMNode.ELEMENT_NODE;
};
DOMElement.prototype = new DOMNode;
@method DOMElement.getTagName - Java style gettor for .TagName
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMElement.prototype.getTagName = function DOMElement_getTagName() {
return this.tagName;
};
@method DOMElement.getAttribute - Retrieves an attribute value by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of the attribute to retrieve
returns: : string - The Attr value as a string, or the empty string if that attribute does not have a specified value.
DOMElement.prototype.getAttribute = function DOMElement_getAttribute(name) {
var ret = "";
// if attribute exists, use it
var attr = this.attributes.getNamedItem(name);
if (attr) {
ret = attr.value;
}
return ret; // if Attribute exists, return its value, otherwise, return ""
};
@method DOMElement.setAttribute - Retrieves an attribute value by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of the attribute to create or alter
parameter: value : string - Value to set in string form
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attribute is readonly.
DOMElement.prototype.setAttribute = function DOMElement_setAttribute(name, value) {
// if attribute exists, use it
var attr = this.attributes.getNamedItem(name);
if (!attr) {
attr = this.ownerDocument.createAttribute(name); // otherwise create it
}
var value = new String(value);
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if Attribute is readonly
if (attr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if the value string contains an illegal character
if (!this.ownerDocument.implementation._isValidString(value)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
if (this.ownerDocument.implementation._isIdDeclaration(name)) {
this.id = value; // cache ID for getElementById()
}
// assign values to properties (and aliases)
attr.value = value;
attr.nodeValue = value;
// update .specified
if (value.length > 0) {
attr.specified = true;
}
else {
attr.specified = false;
}
// add/replace Attribute in NamedNodeMap
this.attributes.setNamedItem(attr);
};
@method DOMElement.removeAttribute - Removes an attribute by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of the attribute to remove
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
DOMElement.prototype.removeAttribute = function DOMElement_removeAttribute(name) {
// delegate to DOMNamedNodeMap.removeNamedItem
return this.attributes.removeNamedItem(name);
};
@method DOMElement.getAttributeNode - Retrieves an Attr node by name
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - The name of the attribute to remove
returns: : DOMAttr - The Attr node with the specified attribute name or null if there is no such attribute.
DOMElement.prototype.getAttributeNode = function DOMElement_getAttributeNode(name) {
// delegate to DOMNamedNodeMap.getNamedItem
return this.attributes.getNamedItem(name);
};
@method DOMElement.setAttributeNode - Adds a new attribute
If an attribute with that name is already present in the element, it is replaced by the new one
author: Jon van Noort (jon@webarcana.com.au)
parameter: newAttr : DOMAttr - The attribute node to be attached
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Element is readonly.
@throws : DOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
returns: : DOMAttr - If the newAttr attribute replaces an existing attribute with the same name,
the previously existing Attr node is returned, otherwise null is returned.
DOMElement.prototype.setAttributeNode = function DOMElement_setAttributeNode(newAttr) {
// if this Attribute is an ID
if (this.ownerDocument.implementation._isIdDeclaration(newAttr.name)) {
this.id = newAttr.value; // cache ID for getElementById()
}
// delegate to DOMNamedNodeMap.setNamedItem
return this.attributes.setNamedItem(newAttr);
};
@method DOMElement.removeAttributeNode - Removes the specified attribute
author: Jon van Noort (jon@webarcana.com.au)
parameter: oldAttr : DOMAttr - The Attr node to remove from the attribute list
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Element is readonly.
@throws : DOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
returns: : DOMAttr - The Attr node that was removed.
DOMElement.prototype.removeAttributeNode = function DOMElement_removeAttributeNode(oldAttr) {
// throw Exception if Attribute is readonly
if (this.ownerDocument.implementation.errorChecking && oldAttr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// get item index
var itemIndex = this.attributes._findItemIndex(oldAttr._id);
// throw Exception if node does not exist in this map
if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
return this.attributes._removeChild(itemIndex);
};
@method DOMElement.getAttributeNS - Retrieves an attribute value by namespaceURI and localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : string - The Attr value as a string, or the empty string if that attribute does not have a specified value.
DOMElement.prototype.getAttributeNS = function DOMElement_getAttributeNS(namespaceURI, localName) {
var ret = "";
// delegate to DOMNAmedNodeMap.getNamedItemNS
var attr = this.attributes.getNamedItemNS(namespaceURI, localName);
if (attr) {
ret = attr.value;
}
return ret; // if Attribute exists, return its value, otherwise return ""
};
@method DOMElement.setAttributeNS - Sets an attribute value by namespaceURI and localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: qualifiedName : string - the qualified name of the required node
parameter: value : string - Value to set in string form
@throws : DOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
@throws : DOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
DOMElement.prototype.setAttributeNS = function DOMElement_setAttributeNS(namespaceURI, qualifiedName, value) {
// call DOMNamedNodeMap.getNamedItem
var attr = this.attributes.getNamedItem(namespaceURI, qualifiedName);
if (!attr) { // if Attribute exists, use it
// otherwise create it
attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
}
var value = new String(value);
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if Attribute is readonly
if (attr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if the Namespace is invalid
if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName)) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
// throw Exception if the value string contains an illegal character
if (!this.ownerDocument.implementation._isValidString(value)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
// if this Attribute is an ID
if (this.ownerDocument.implementation._isIdDeclaration(name)) {
this.id = value; // cache ID for getElementById()
}
// assign values to properties (and aliases)
attr.value = value;
attr.nodeValue = value;
// update .specified
if (value.length > 0) {
attr.specified = true;
}
else {
attr.specified = false;
}
// delegate to DOMNamedNodeMap.setNamedItem
this.attributes.setNamedItemNS(attr);
};
@method DOMElement.removeAttributeNS - Removes an attribute by namespaceURI and localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
returns: : DOMAttr
DOMElement.prototype.removeAttributeNS = function DOMElement_removeAttributeNS(namespaceURI, localName) {
// delegate to DOMNamedNodeMap.removeNamedItemNS
return this.attributes.removeNamedItemNS(namespaceURI, localName);
};
@method DOMElement.getAttributeNodeNS - Retrieves an Attr node by namespaceURI and localName
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : DOMAttr - The Attr node with the specified attribute name or null if there is no such attribute.
DOMElement.prototype.getAttributeNodeNS = function DOMElement_getAttributeNodeNS(namespaceURI, localName) {
// delegate to DOMNamedNodeMap.getNamedItemNS
return this.attributes.getNamedItemNS(namespaceURI, localName);
};
@method DOMElement.setAttributeNodeNS - Adds a new attribute
If an attribute with that name is already present in the element, it is replaced by the new one
author: Jon van Noort (jon@webarcana.com.au)
parameter: newAttr : DOMAttr - the attribute node to be attached
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
@throws : DOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
@throws : DOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
The DOM user must explicitly clone Attr nodes to re-use them in other elements.
returns: : DOMAttr - If the newAttr attribute replaces an existing attribute with the same name,
the previously existing Attr node is returned, otherwise null is returned.
DOMElement.prototype.setAttributeNodeNS = function DOMElement_setAttributeNodeNS(newAttr) {
// if this Attribute is an ID
if ((newAttr.prefix == "") && this.ownerDocument.implementation._isIdDeclaration(newAttr.name)) {
this.id = newAttr.value; // cache ID for getElementById()
}
// delegate to DOMNamedNodeMap.setNamedItemNS
return this.attributes.setNamedItemNS(newAttr);
};
@method DOMElement.hasAttribute - Returns true if specified node exists
author: Jon van Noort (jon@webarcana.com.au)
parameter: name : string - the name of the required node
returns: : boolean
DOMElement.prototype.hasAttribute = function DOMElement_hasAttribute(name) {
// delegate to DOMNamedNodeMap._hasAttribute
return this.attributes._hasAttribute(name);
}
@method DOMElement.hasAttributeNS - Returns true if specified node exists
author: Jon van Noort (jon@webarcana.com.au)
parameter: namespaceURI : string - the namespace URI of the required node
parameter: localName : string - the local name of the required node
returns: : boolean
DOMElement.prototype.hasAttributeNS = function DOMElement_hasAttributeNS(namespaceURI, localName) {
// delegate to DOMNamedNodeMap._hasAttributeNS
return this.attributes._hasAttributeNS(namespaceURI, localName);
}
@method DOMElement.toString - Serialize this Element and its children into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMElement.prototype.toString = function DOMElement_toString() {
var ret = "";
// serialize namespace declarations
var ns = this._namespaces.toString();
if (ns.length > 0) ns = " "+ ns;
// serialize Attribute declarations
var attrs = this.attributes.toString();
if (attrs.length > 0) attrs = " "+ attrs;
// serialize this Element
ret += "<" + this.nodeName + ns + attrs +">";
ret += this.childNodes.toString();;
ret += "</" + this.nodeName+">";
return ret;
}
@class DOMAttr - The Attr interface represents an attribute in an Element object
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMAttr = function(ownerDocument) {
this._class = addClass(this._class, "DOMAttr");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
this.name = ""; // the name of this attribute
// If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
// Note that the implementation is in charge of this attribute, not the user.
// If the user changes the value of the attribute (even if it ends up having the same value as the default value)
// then the specified flag is automatically flipped to true
// (I wish! You will need to use setValue to 'automatically' update specified)
this.specified = false;
this.value = ""; // the value of the attribute is returned as a string
this.nodeType = DOMNode.ATTRIBUTE_NODE;
this.ownerElement = null; // set when Attr is added to NamedNodeMap
// disable childNodes
this.childNodes = null;
this.attributes = null;
};
DOMAttr.prototype = new DOMNode;
@method DOMAttr.getName - Java style gettor for .name
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMAttr.prototype.getName = function DOMAttr_getName() {
return this.nodeName;
};
@method DOMAttr.getSpecified - Java style gettor for .specified
author: Jon van Noort (jon@webarcana.com.au)
returns: : boolean
DOMAttr.prototype.getSpecified = function DOMAttr_getSpecified() {
return this.specified;
};
@method DOMAttr.getValue - Java style gettor for .value
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMAttr.prototype.getValue = function DOMAttr_getValue() {
return this.nodeValue;
};
@method DOMAttr.setValue - Java style settor for .value
alias for DOMAttr.setNodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: value : string - the new attribute value
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
DOMAttr.prototype.setValue = function DOMAttr_setValue(value) {
// throw Exception if Attribute is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// delegate to setNodeValue
this.setNodeValue(value);
};
@method DOMAttr.setNodeValue - Java style settor for .nodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: value : string - the new attribute value
DOMAttr.prototype.setNodeValue = function DOMAttr_setNodeValue(value) {
this.nodeValue = new String(value);
this.value = this.nodeValue;
this.specified = (this.value.length > 0);
};
@method DOMAttr.toString - Serialize this Attr into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMAttr.prototype.toString = function DOMAttr_toString() {
var ret = "";
// serialize Attribute
ret += this.nodeName +"=\""+ this.__escapeString(this.nodeValue) +"\"";
return ret;
}
DOMAttr.prototype.getOwnerElement = function() {
return this.ownerElement;
}
@class DOMNamespace - The Namespace interface represents an namespace in an Element object
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMNamespace = function(ownerDocument) {
this._class = addClass(this._class, "DOMNamespace");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
this.name = ""; // the name of this attribute
// If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
// Note that the implementation is in charge of this attribute, not the user.
// If the user changes the value of the attribute (even if it ends up having the same value as the default value)
// then the specified flag is automatically flipped to true
// (I wish! You will need to use _setValue to 'automatically' update specified)
this.specified = false;
this.value = ""; // the value of the attribute is returned as a string
this.nodeType = DOMNode.NAMESPACE_NODE;
};
DOMNamespace.prototype = new DOMNode;
@method DOMNamespace.getValue - Java style gettor for .value
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMNamespace.prototype.getValue = function DOMNamespace_getValue() {
return this.nodeValue;
};
@method DOMNamespace.setValue - utility function to set value (rather than direct assignment to .value)
author: Jon van Noort (jon@webarcana.com.au)
parameter: value : string - the new namespace value
DOMNamespace.prototype.setValue = function DOMNamespace_setValue(value) {
// assign values to properties (and aliases)
this.nodeValue = new String(value);
this.value = this.nodeValue;
};
@method DOMNamespace.toString - Serialize this Attr into an XML string
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMNamespace.prototype.toString = function DOMNamespace_toString() {
var ret = "";
// serialize Namespace Declaration
if (this.nodeName != "") {
ret += this.nodeName +"=\""+ this.__escapeString(this.nodeValue) +"\"";
}
else { // handle default namespace
ret += "xmlns=\""+ this.__escapeString(this.nodeValue) +"\"";
}
return ret;
}
@class DOMCharacterData - parent abstract class for DOMText and DOMComment
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMCharacterData = function(ownerDocument) {
this._class = addClass(this._class, "DOMCharacterData");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
this.data = "";
this.length = 0;
};
DOMCharacterData.prototype = new DOMNode;
@method DOMCharacterData.getData - Java style gettor for .data
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMCharacterData.prototype.getData = function DOMCharacterData_getData() {
return this.nodeValue;
};
@method DOMCharacterData.setData - Java style settor for .data
alias for DOMCharacterData.setNodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - the character data
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
DOMCharacterData.prototype.setData = function DOMCharacterData_setData(data) {
// delegate to setNodeValue
this.setNodeValue(data);
};
@method DOMCharacterData.setNodeValue - Java style settor for .nodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - the node value
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
DOMCharacterData.prototype.setNodeValue = function DOMCharacterData_setNodeValue(data) {
// throw Exception if Attribute is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// assign values to properties (and aliases)
this.nodeValue = new String(data);
this.data = this.nodeValue;
// update length
this.length = this.nodeValue.length;
};
@method DOMCharacterData.getLength - Java style gettor for .length
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMCharacterData.prototype.getLength = function DOMCharacterData_getLength() {
return this.nodeValue.length;
};
@method DOMCharacterData.substringData - Extracts a range of data from the node
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - Start offset of substring to extract
parameter: count : int - The number of characters to extract
@throws : DOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
returns: : string - The specified substring.
If the sum of offset and count exceeds the length, then all characters to the end of the data are returned.
DOMCharacterData.prototype.substringData = function DOMCharacterData_substringData(offset, count) {
var ret = null;
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
// or the count is negative
if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
// if count is not specified
if (!count) {
ret = this.data.substring(offset); // default to 'end of string'
}
else {
ret = this.data.substring(offset, offset + count);
}
}
return ret;
};
@method DOMCharacterData.appendData - Append the string to the end of the character data of the node.
Upon success, data provides access to the concatenation of data and the DOMString specified.
author: Jon van Noort (jon@webarcana.com.au)
parameter: arg : string - The string to append
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
DOMCharacterData.prototype.appendData = function DOMCharacterData_appendData(arg) {
// throw Exception if DOMCharacterData is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// append data
this.setData(""+ this.data + arg);
};
@method DOMCharacterData.insertData - Insert a string at the specified character offset.
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - The character offset at which to insert
parameter: arg : string - The string to insert
@throws : DOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
or if the specified count is negative.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
DOMCharacterData.prototype.insertData = function DOMCharacterData_insertData(offset, arg) {
// throw Exception if DOMCharacterData is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
// insert data
this.setData(this.data.substring(0, offset).concat(arg, this.data.substring(offset)));
}
else {
// throw Exception if offset is negative or greater than the data length,
if (this.ownerDocument.implementation.errorChecking && (offset != 0)) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
// set data
this.setData(arg);
}
};
@method DOMCharacterData.deleteData - Remove a range of characters from the node.
Upon success, data and length reflect the change
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - The offset from which to remove characters
parameter: count : int - The number of characters to delete.
If the sum of offset and count exceeds length then all characters from offset to the end of the data are deleted
@throws : DOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
or if the specified count is negative.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
DOMCharacterData.prototype.deleteData = function DOMCharacterData_deleteData(offset, count) {
// throw Exception if DOMCharacterData is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
// delete data
if(!count || (offset + count) > this.data.length) {
this.setData(this.data.substring(0, offset));
}
else {
this.setData(this.data.substring(0, offset).concat(this.data.substring(offset + count)));
}
}
};
@method DOMCharacterData.replaceData - Replace the characters starting at the specified character offset with the specified string
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - The offset from which to start replacing
parameter: count : int - The number of characters to replace.
If the sum of offset and count exceeds length, then all characters to the end of the data are replaced
parameter: arg : string - The string with which the range must be replaced
@throws : DOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
or if the specified count is negative.
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
DOMCharacterData.prototype.replaceData = function DOMCharacterData_replaceData(offset, count, arg) {
// throw Exception if DOMCharacterData is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
// replace data
this.setData(this.data.substring(0, offset).concat(arg, this.data.substring(offset + count)));
}
else {
// set data
this.setData(arg);
}
};
@class DOMText - The Text interface represents the textual content (termed character data in XML) of an Element or Attr.
If there is no markup inside an element's content, the text is contained in a single object implementing the Text interface
that is the only child of the element. If there is markup, it is parsed into a list of elements and Text nodes that form the
list of children of the element.
@extends DOMCharacterData
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMText = function(ownerDocument) {
this._class = addClass(this._class, "DOMText");
this.DOMCharacterData = DOMCharacterData;
this.DOMCharacterData(ownerDocument);
this.nodeName = "#text";
this.nodeType = DOMNode.TEXT_NODE;
};
DOMText.prototype = new DOMCharacterData;
@method DOMText.splitText - Breaks this Text node into two Text nodes at the specified offset,
keeping both in the tree as siblings. This node then only contains all the content up to the offset point.
And a new Text node, which is inserted as the next sibling of this node, contains all the content at and after the offset point.
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - The offset at which to split, starting from 0.
@throws : DOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
@throws : DOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Text is readonly.
returns: : DOMText - The new Text node
DOMText.prototype.splitText = function DOMText_splitText(offset) {
var data, inode;
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if offset is negative or greater than the data length,
if ((offset < 0) || (offset > this.data.length)) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
}
if (this.parentNode) {
// get remaining string (after offset)
data = this.substringData(offset);
// create new TextNode with remaining string
inode = this.ownerDocument.createTextNode(data);
// attach new TextNode
if (this.nextSibling) {
this.parentNode.insertBefore(inode, this.nextSibling);
}
else {
this.parentNode.appendChild(inode);
}
// remove remaining string from original TextNode
this.deleteData(offset);
}
return inode;
};
@method DOMText.toString - Serialize this Text into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMText.prototype.toString = function DOMText_toString() {
return this.__escapeString(""+ this.nodeValue);
}
@class DOMCDATASection - CDATA sections are used to escape blocks of text containing characters that would otherwise be regarded as markup.
The only delimiter that is recognized in a CDATA section is the "\]\]\>" string that ends the CDATA section
@extends DOMCharacterData
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMCDATASection = function(ownerDocument) {
this._class = addClass(this._class, "DOMCDATASection");
this.DOMCharacterData = DOMCharacterData;
this.DOMCharacterData(ownerDocument);
this.nodeName = "#cdata-section";
this.nodeType = DOMNode.CDATA_SECTION_NODE;
};
DOMCDATASection.prototype = new DOMCharacterData;
@method DOMCDATASection.splitText - Breaks this CDATASection node into two CDATASection nodes at the specified offset,
keeping both in the tree as siblings. This node then only contains all the content up to the offset point.
And a new CDATASection node, which is inserted as the next sibling of this node, contains all the content at and after the offset point.
author: Jon van Noort (jon@webarcana.com.au)
parameter: offset : int - The offset at which to split, starting from 0.
returns: : DOMCDATASection - The new CDATASection node
DOMCDATASection.prototype.splitText = function DOMCDATASection_splitText(offset) {
var data, inode;
// test for exceptions
if (this.ownerDocument.implementation.errorChecking) {
// throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// throw Exception if offset is negative or greater than the data length,
if ((offset < 0) || (offset > this.data.length)) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
}
if(this.parentNode) {
// get remaining string (after offset)
data = this.substringData(offset);
// create new CDATANode with remaining string
inode = this.ownerDocument.createCDATASection(data);
// attach new CDATANode
if (this.nextSibling) {
this.parentNode.insertBefore(inode, this.nextSibling);
}
else {
this.parentNode.appendChild(inode);
}
// remove remaining string from original CDATANode
this.deleteData(offset);
}
return inode;
};
@method DOMCDATASection.toString - Serialize this CDATASection into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMCDATASection.prototype.toString = function DOMCDATASection_toString() {
var ret = "";
//do NOT unescape the nodeValue string in CDATA sections!
ret += "<![CDATA[" + this.nodeValue + "\]\]\>";
return ret;
}
@class DOMComment - This represents the content of a comment, i.e., all the characters between the starting '<!--' and ending '-->'
@extends DOMCharacterData
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMComment = function(ownerDocument) {
this._class = addClass(this._class, "DOMComment");
this.DOMCharacterData = DOMCharacterData;
this.DOMCharacterData(ownerDocument);
this.nodeName = "#comment";
this.nodeType = DOMNode.COMMENT_NODE;
};
DOMComment.prototype = new DOMCharacterData;
@method DOMComment.toString - Serialize this Comment into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMComment.prototype.toString = function DOMComment_toString() {
var ret = "";
ret += "<!--" + this.nodeValue + "-->";
return ret;
}
@class DOMProcessingInstruction - The ProcessingInstruction interface represents a "processing instruction",
used in XML as a way to keep processor-specific information in the text of the document
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMProcessingInstruction = function(ownerDocument) {
this._class = addClass(this._class, "DOMProcessingInstruction");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
// The target of this processing instruction.
// XML defines this as being the first token following the markup that begins the processing instruction.
this.target = "";
// The content of this processing instruction.
// This is from the first non white space character after the target to the character immediately preceding the ?>
this.data = "";
this.nodeType = DOMNode.PROCESSING_INSTRUCTION_NODE;
};
DOMProcessingInstruction.prototype = new DOMNode;
@method DOMProcessingInstruction.getTarget - Java style gettor for .target
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMProcessingInstruction.prototype.getTarget = function DOMProcessingInstruction_getTarget() {
return this.nodeName;
};
@method DOMProcessingInstruction.getData - Java style gettor for .data
author: Jon van Noort (jon@webarcana.com.au)
returns: : string
DOMProcessingInstruction.prototype.getData = function DOMProcessingInstruction_getData() {
return this.nodeValue;
};
@method DOMProcessingInstruction.setData - Java style settor for .data
alias for DOMProcessingInstruction.setNodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - The new data of this processing instruction.
DOMProcessingInstruction.prototype.setData = function DOMProcessingInstruction_setData(data) {
// delegate to setNodeValue
this.setNodeValue(data);
};
@method DOMProcessingInstruction.setNodeValue - Java style settor for .nodeValue
author: Jon van Noort (jon@webarcana.com.au)
parameter: data : string - The new data of this processing instruction.
DOMProcessingInstruction.prototype.setNodeValue = function DOMProcessingInstruction_setNodeValue(data) {
// throw Exception if DOMNode is readonly
if (this.ownerDocument.implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// assign values to properties (and aliases)
this.nodeValue = new String(data);
this.data = this.nodeValue;
};
@method DOMProcessingInstruction.toString - Serialize this ProcessingInstruction into an XML string
author: Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
returns: : string
DOMProcessingInstruction.prototype.toString = function DOMProcessingInstruction_toString() {
var ret = "";
ret += "<?" + this.nodeName +" "+ this.nodeValue + " ?>";
return ret;
}
@class DOMDocumentFragment - DocumentFragment is a "lightweight" or "minimal" Document object.
@extends DOMNode
author: Jon van Noort (jon@webarcana.com.au)
parameter: ownerDocument : DOMDocument - The Document object associated with this node.
DOMDocumentFragment = function(ownerDocument) {
this._class = addClass(this._class, "DOMDocumentFragment");
this.DOMNode = DOMNode;
this.DOMNode(ownerDocument);
this.nodeName = "#document-fragment";
this.nodeType = DOMNode.DOCUMENT_FRAGMENT_NODE;
};
DOMDocumentFragment.prototype = new DOMNode;
@method DOMDocumentFragment.toString - Serialize this DocumentFragment into an XML string
author: David Joham (djoham@yahoo.com)
returns: : string
DOMDocumentFragment.prototype.toString = function DOMDocumentFragment_toString() {
var xml = "";
var intCount = this.getChildNodes().getLength();
// create string concatenating the serialized ChildNodes
for (intLoop = 0; intLoop < intCount; intLoop++) {
xml += this.getChildNodes().item(intLoop).toString();
}
return xml;
}
////////////////////
// NOT IMPLEMENTED //
////////////////////
DOMDocumentType = function() { alert("DOMDocumentType.constructor(): Not Implemented" ); };
DOMEntity = function() { alert("DOMEntity.constructor(): Not Implemented" ); };
DOMEntityReference = function() { alert("DOMEntityReference.constructor(): Not Implemented"); };
DOMNotation = function() { alert("DOMNotation.constructor(): Not Implemented" ); };
Strings = new Object()
Strings.WHITESPACE = " \t\n\r";
Strings.QUOTES = "\"'";
Strings.isEmpty = function Strings_isEmpty(strD) {
return (strD == null) || (strD.length == 0);
};
Strings.indexOfNonWhitespace = function Strings_indexOfNonWhitespace(strD, iB, iE) {
if(Strings.isEmpty(strD)) return -1;
iB = iB || 0;
iE = iE || strD.length;
for(var i = iB; i < iE; i++)
if(Strings.WHITESPACE.indexOf(strD.charAt(i)) == -1) {
return i;
}
return -1;
};
Strings.lastIndexOfNonWhitespace = function Strings_lastIndexOfNonWhitespace(strD, iB, iE) {
if(Strings.isEmpty(strD)) return -1;
iB = iB || 0;
iE = iE || strD.length;
for(var i = iE - 1; i >= iB; i--)
if(Strings.WHITESPACE.indexOf(strD.charAt(i)) == -1)
return i;
return -1;
};
Strings.indexOfWhitespace = function Strings_indexOfWhitespace(strD, iB, iE) {
if(Strings.isEmpty(strD)) return -1;
iB = iB || 0;
iE = iE || strD.length;
for(var i = iB; i < iE; i++)
if(Strings.WHITESPACE.indexOf(strD.charAt(i)) != -1)
return i;
return -1;
};
Strings.replace = function Strings_replace(strD, iB, iE, strF, strR) {
if(Strings.isEmpty(strD)) return "";
iB = iB || 0;
iE = iE || strD.length;
return strD.substring(iB, iE).split(strF).join(strR);
};
Strings.getLineNumber = function Strings_getLineNumber(strD, iP) {
if(Strings.isEmpty(strD)) return -1;
iP = iP || strD.length;
return strD.substring(0, iP).split("\n").length
};
Strings.getColumnNumber = function Strings_getColumnNumber(strD, iP) {
if(Strings.isEmpty(strD)) return -1;
iP = iP || strD.length;
var arrD = strD.substring(0, iP).split("\n");
var strLine = arrD[arrD.length - 1];
arrD.length--;
var iLinePos = arrD.join("\n").length;
return iP - iLinePos;
};
StringBuffer = function() {this._a=new Array();};
StringBuffer.prototype.append = function StringBuffer_append(d){this._a[this._a.length]=d;};
StringBuffer.prototype.toString = function StringBuffer_toString(){return this._a.join("");};
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.