aboutsummaryrefslogtreecommitdiff
path: root/generator/node_modules/xmlbuilder/lib/XMLNode.js
diff options
context:
space:
mode:
Diffstat (limited to 'generator/node_modules/xmlbuilder/lib/XMLNode.js')
-rw-r--r--generator/node_modules/xmlbuilder/lib/XMLNode.js999
1 files changed, 999 insertions, 0 deletions
diff --git a/generator/node_modules/xmlbuilder/lib/XMLNode.js b/generator/node_modules/xmlbuilder/lib/XMLNode.js
new file mode 100644
index 0000000..0ade97b
--- /dev/null
+++ b/generator/node_modules/xmlbuilder/lib/XMLNode.js
@@ -0,0 +1,999 @@
+// Generated by CoffeeScript 2.4.1
+(function() {
+ var DocumentPosition, NodeType, XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLDummy, XMLElement, XMLNamedNodeMap, XMLNode, XMLNodeList, XMLProcessingInstruction, XMLRaw, XMLText, getValue, isEmpty, isFunction, isObject,
+ hasProp = {}.hasOwnProperty,
+ splice = [].splice;
+
+ ({isObject, isFunction, isEmpty, getValue} = require('./Utility'));
+
+ XMLElement = null;
+
+ XMLCData = null;
+
+ XMLComment = null;
+
+ XMLDeclaration = null;
+
+ XMLDocType = null;
+
+ XMLRaw = null;
+
+ XMLText = null;
+
+ XMLProcessingInstruction = null;
+
+ XMLDummy = null;
+
+ NodeType = null;
+
+ XMLNodeList = null;
+
+ XMLNamedNodeMap = null;
+
+ DocumentPosition = null;
+
+ // Represents a generic XMl element
+ module.exports = XMLNode = (function() {
+ class XMLNode {
+ // Initializes a new instance of `XMLNode`
+
+ // `parent` the parent node
+ constructor(parent1) {
+ this.parent = parent1;
+ if (this.parent) {
+ this.options = this.parent.options;
+ this.stringify = this.parent.stringify;
+ }
+ this.value = null;
+ this.children = [];
+ this.baseURI = null;
+ // first execution, load dependencies that are otherwise
+ // circular (so we can't load them at the top)
+ if (!XMLElement) {
+ XMLElement = require('./XMLElement');
+ XMLCData = require('./XMLCData');
+ XMLComment = require('./XMLComment');
+ XMLDeclaration = require('./XMLDeclaration');
+ XMLDocType = require('./XMLDocType');
+ XMLRaw = require('./XMLRaw');
+ XMLText = require('./XMLText');
+ XMLProcessingInstruction = require('./XMLProcessingInstruction');
+ XMLDummy = require('./XMLDummy');
+ NodeType = require('./NodeType');
+ XMLNodeList = require('./XMLNodeList');
+ XMLNamedNodeMap = require('./XMLNamedNodeMap');
+ DocumentPosition = require('./DocumentPosition');
+ }
+ }
+
+
+ // Sets the parent node of this node and its children recursively
+
+ // `parent` the parent node
+ setParent(parent) {
+ var child, j, len, ref1, results;
+ this.parent = parent;
+ if (parent) {
+ this.options = parent.options;
+ this.stringify = parent.stringify;
+ }
+ ref1 = this.children;
+ results = [];
+ for (j = 0, len = ref1.length; j < len; j++) {
+ child = ref1[j];
+ results.push(child.setParent(this));
+ }
+ return results;
+ }
+
+ // Creates a child element node
+
+ // `name` node name or an object describing the XML tree
+ // `attributes` an object containing name/value pairs of attributes
+ // `text` element text
+ element(name, attributes, text) {
+ var childNode, item, j, k, key, lastChild, len, len1, val;
+ lastChild = null;
+ if (attributes === null && (text == null)) {
+ [attributes, text] = [{}, null];
+ }
+ if (attributes == null) {
+ attributes = {};
+ }
+ attributes = getValue(attributes);
+ // swap argument order: text <-> attributes
+ if (!isObject(attributes)) {
+ [text, attributes] = [attributes, text];
+ }
+ if (name != null) {
+ name = getValue(name);
+ }
+ // expand if array
+ if (Array.isArray(name)) {
+ for (j = 0, len = name.length; j < len; j++) {
+ item = name[j];
+ lastChild = this.element(item);
+ }
+ // evaluate if function
+ } else if (isFunction(name)) {
+ lastChild = this.element(name.apply());
+ // expand if object
+ } else if (isObject(name)) {
+ for (key in name) {
+ if (!hasProp.call(name, key)) continue;
+ val = name[key];
+ if (isFunction(val)) {
+ // evaluate if function
+ val = val.apply();
+ }
+ // assign attributes
+ if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) {
+ lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val);
+ // skip empty arrays
+ } else if (!this.options.separateArrayItems && Array.isArray(val) && isEmpty(val)) {
+ lastChild = this.dummy();
+ // empty objects produce one node
+ } else if (isObject(val) && isEmpty(val)) {
+ lastChild = this.element(key);
+ // skip null and undefined nodes
+ } else if (!this.options.keepNullNodes && (val == null)) {
+ lastChild = this.dummy();
+
+ // expand list by creating child nodes
+ } else if (!this.options.separateArrayItems && Array.isArray(val)) {
+ for (k = 0, len1 = val.length; k < len1; k++) {
+ item = val[k];
+ childNode = {};
+ childNode[key] = item;
+ lastChild = this.element(childNode);
+ }
+
+ // expand child nodes under parent
+ } else if (isObject(val)) {
+ // if the key is #text expand child nodes under this node to support mixed content
+ if (!this.options.ignoreDecorators && this.stringify.convertTextKey && key.indexOf(this.stringify.convertTextKey) === 0) {
+ lastChild = this.element(val);
+ } else {
+ lastChild = this.element(key);
+ lastChild.element(val);
+ }
+ } else {
+
+ // text node
+ lastChild = this.element(key, val);
+ }
+ }
+ // skip null nodes
+ } else if (!this.options.keepNullNodes && text === null) {
+ lastChild = this.dummy();
+ } else {
+ // text node
+ if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) {
+ lastChild = this.text(text);
+ // cdata node
+ } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) {
+ lastChild = this.cdata(text);
+ // comment node
+ } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) {
+ lastChild = this.comment(text);
+ // raw text node
+ } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) {
+ lastChild = this.raw(text);
+ // processing instruction
+ } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && name.indexOf(this.stringify.convertPIKey) === 0) {
+ lastChild = this.instruction(name.substr(this.stringify.convertPIKey.length), text);
+ } else {
+ // element node
+ lastChild = this.node(name, attributes, text);
+ }
+ }
+ if (lastChild == null) {
+ throw new Error("Could not create any elements with: " + name + ". " + this.debugInfo());
+ }
+ return lastChild;
+ }
+
+ // Creates a child element node before the current node
+
+ // `name` node name or an object describing the XML tree
+ // `attributes` an object containing name/value pairs of attributes
+ // `text` element text
+ insertBefore(name, attributes, text) {
+ var child, i, newChild, refChild, removed;
+ // DOM level 1
+ // insertBefore(newChild, refChild) inserts the child node newChild before refChild
+ if (name != null ? name.type : void 0) {
+ newChild = name;
+ refChild = attributes;
+ newChild.setParent(this);
+ if (refChild) {
+ // temporarily remove children starting *with* refChild
+ i = children.indexOf(refChild);
+ removed = children.splice(i);
+
+ // add the new child
+ children.push(newChild);
+
+ // add back removed children after new child
+ Array.prototype.push.apply(children, removed);
+ } else {
+ children.push(newChild);
+ }
+ return newChild;
+ } else {
+ if (this.isRoot) {
+ throw new Error("Cannot insert elements at root level. " + this.debugInfo(name));
+ }
+
+ // temporarily remove children starting *with* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i);
+
+ // add the new child
+ child = this.parent.element(name, attributes, text);
+
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return child;
+ }
+ }
+
+ // Creates a child element node after the current node
+
+ // `name` node name or an object describing the XML tree
+ // `attributes` an object containing name/value pairs of attributes
+ // `text` element text
+ insertAfter(name, attributes, text) {
+ var child, i, removed;
+ if (this.isRoot) {
+ throw new Error("Cannot insert elements at root level. " + this.debugInfo(name));
+ }
+
+ // temporarily remove children starting *after* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i + 1);
+
+ // add the new child
+ child = this.parent.element(name, attributes, text);
+
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return child;
+ }
+
+ // Deletes a child element node
+
+ remove() {
+ var i, ref1;
+ if (this.isRoot) {
+ throw new Error("Cannot remove the root element. " + this.debugInfo());
+ }
+ i = this.parent.children.indexOf(this);
+ splice.apply(this.parent.children, [i, i - i + 1].concat(ref1 = [])), ref1;
+ return this.parent;
+ }
+
+ // Creates a node
+
+ // `name` name of the node
+ // `attributes` an object containing name/value pairs of attributes
+ // `text` element text
+ node(name, attributes, text) {
+ var child;
+ if (name != null) {
+ name = getValue(name);
+ }
+ attributes || (attributes = {});
+ attributes = getValue(attributes);
+ // swap argument order: text <-> attributes
+ if (!isObject(attributes)) {
+ [text, attributes] = [attributes, text];
+ }
+ child = new XMLElement(this, name, attributes);
+ if (text != null) {
+ child.text(text);
+ }
+ this.children.push(child);
+ return child;
+ }
+
+ // Creates a text node
+
+ // `value` element text
+ text(value) {
+ var child;
+ if (isObject(value)) {
+ this.element(value);
+ }
+ child = new XMLText(this, value);
+ this.children.push(child);
+ return this;
+ }
+
+ // Creates a CDATA node
+
+ // `value` element text without CDATA delimiters
+ cdata(value) {
+ var child;
+ child = new XMLCData(this, value);
+ this.children.push(child);
+ return this;
+ }
+
+ // Creates a comment node
+
+ // `value` comment text
+ comment(value) {
+ var child;
+ child = new XMLComment(this, value);
+ this.children.push(child);
+ return this;
+ }
+
+ // Creates a comment node before the current node
+
+ // `value` comment text
+ commentBefore(value) {
+ var child, i, removed;
+ // temporarily remove children starting *with* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i);
+ // add the new child
+ child = this.parent.comment(value);
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return this;
+ }
+
+ // Creates a comment node after the current node
+
+ // `value` comment text
+ commentAfter(value) {
+ var child, i, removed;
+ // temporarily remove children starting *after* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i + 1);
+ // add the new child
+ child = this.parent.comment(value);
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return this;
+ }
+
+ // Adds unescaped raw text
+
+ // `value` text
+ raw(value) {
+ var child;
+ child = new XMLRaw(this, value);
+ this.children.push(child);
+ return this;
+ }
+
+ // Adds a dummy node
+ dummy() {
+ var child;
+ child = new XMLDummy(this);
+ // Normally when a new node is created it is added to the child node collection.
+ // However, dummy nodes are never added to the XML tree. They are created while
+ // converting JS objects to XML nodes in order not to break the recursive function
+ // chain. They can be thought of as invisible nodes. They can be traversed through
+ // by using prev(), next(), up(), etc. functions but they do not exists in the tree.
+
+ // @children.push child
+ return child;
+ }
+
+ // Adds a processing instruction
+
+ // `target` instruction target
+ // `value` instruction value
+ instruction(target, value) {
+ var insTarget, insValue, instruction, j, len;
+ if (target != null) {
+ target = getValue(target);
+ }
+ if (value != null) {
+ value = getValue(value);
+ }
+ if (Array.isArray(target)) { // expand if array
+ for (j = 0, len = target.length; j < len; j++) {
+ insTarget = target[j];
+ this.instruction(insTarget);
+ }
+ } else if (isObject(target)) { // expand if object
+ for (insTarget in target) {
+ if (!hasProp.call(target, insTarget)) continue;
+ insValue = target[insTarget];
+ this.instruction(insTarget, insValue);
+ }
+ } else {
+ if (isFunction(value)) {
+ value = value.apply();
+ }
+ instruction = new XMLProcessingInstruction(this, target, value);
+ this.children.push(instruction);
+ }
+ return this;
+ }
+
+ // Creates a processing instruction node before the current node
+
+ // `target` instruction target
+ // `value` instruction value
+ instructionBefore(target, value) {
+ var child, i, removed;
+ // temporarily remove children starting *with* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i);
+ // add the new child
+ child = this.parent.instruction(target, value);
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return this;
+ }
+
+ // Creates a processing instruction node after the current node
+
+ // `target` instruction target
+ // `value` instruction value
+ instructionAfter(target, value) {
+ var child, i, removed;
+ // temporarily remove children starting *after* this
+ i = this.parent.children.indexOf(this);
+ removed = this.parent.children.splice(i + 1);
+ // add the new child
+ child = this.parent.instruction(target, value);
+ // add back removed children after new child
+ Array.prototype.push.apply(this.parent.children, removed);
+ return this;
+ }
+
+ // Creates the xml declaration
+
+ // `version` A version number string, e.g. 1.0
+ // `encoding` Encoding declaration, e.g. UTF-8
+ // `standalone` standalone document declaration: true or false
+ declaration(version, encoding, standalone) {
+ var doc, xmldec;
+ doc = this.document();
+ xmldec = new XMLDeclaration(doc, version, encoding, standalone);
+ // Replace XML declaration if exists, otherwise insert at top
+ if (doc.children.length === 0) {
+ doc.children.unshift(xmldec);
+ } else if (doc.children[0].type === NodeType.Declaration) {
+ doc.children[0] = xmldec;
+ } else {
+ doc.children.unshift(xmldec);
+ }
+ return doc.root() || doc;
+ }
+
+ // Creates the document type declaration
+
+ // `pubID` the public identifier of the external subset
+ // `sysID` the system identifier of the external subset
+ dtd(pubID, sysID) {
+ var child, doc, doctype, i, j, k, len, len1, ref1, ref2;
+ doc = this.document();
+ doctype = new XMLDocType(doc, pubID, sysID);
+ ref1 = doc.children;
+ // Replace DTD if exists
+ for (i = j = 0, len = ref1.length; j < len; i = ++j) {
+ child = ref1[i];
+ if (child.type === NodeType.DocType) {
+ doc.children[i] = doctype;
+ return doctype;
+ }
+ }
+ ref2 = doc.children;
+ // insert before root node if the root node exists
+ for (i = k = 0, len1 = ref2.length; k < len1; i = ++k) {
+ child = ref2[i];
+ if (child.isRoot) {
+ doc.children.splice(i, 0, doctype);
+ return doctype;
+ }
+ }
+ // otherwise append to end
+ doc.children.push(doctype);
+ return doctype;
+ }
+
+ // Gets the parent node
+ up() {
+ if (this.isRoot) {
+ throw new Error("The root node has no parent. Use doc() if you need to get the document object.");
+ }
+ return this.parent;
+ }
+
+ // Gets the root node
+ root() {
+ var node;
+ node = this;
+ while (node) {
+ if (node.type === NodeType.Document) {
+ return node.rootObject;
+ } else if (node.isRoot) {
+ return node;
+ } else {
+ node = node.parent;
+ }
+ }
+ }
+
+ // Gets the node representing the XML document
+ document() {
+ var node;
+ node = this;
+ while (node) {
+ if (node.type === NodeType.Document) {
+ return node;
+ } else {
+ node = node.parent;
+ }
+ }
+ }
+
+ // Ends the document and converts string
+ end(options) {
+ return this.document().end(options);
+ }
+
+ // Gets the previous node
+ prev() {
+ var i;
+ i = this.parent.children.indexOf(this);
+ if (i < 1) {
+ throw new Error("Already at the first node. " + this.debugInfo());
+ }
+ return this.parent.children[i - 1];
+ }
+
+ // Gets the next node
+ next() {
+ var i;
+ i = this.parent.children.indexOf(this);
+ if (i === -1 || i === this.parent.children.length - 1) {
+ throw new Error("Already at the last node. " + this.debugInfo());
+ }
+ return this.parent.children[i + 1];
+ }
+
+ // Imports cloned root from another XML document
+
+ // `doc` the XML document to insert nodes from
+ importDocument(doc) {
+ var child, clonedRoot, j, len, ref1;
+ clonedRoot = doc.root().clone();
+ clonedRoot.parent = this;
+ clonedRoot.isRoot = false;
+ this.children.push(clonedRoot);
+ // set properties if imported element becomes the root node
+ if (this.type === NodeType.Document) {
+ clonedRoot.isRoot = true;
+ clonedRoot.documentObject = this;
+ this.rootObject = clonedRoot;
+ // set dtd name
+ if (this.children) {
+ ref1 = this.children;
+ for (j = 0, len = ref1.length; j < len; j++) {
+ child = ref1[j];
+ if (child.type === NodeType.DocType) {
+ child.name = clonedRoot.name;
+ break;
+ }
+ }
+ }
+ }
+ return this;
+ }
+
+
+ // Returns debug string for this node
+ debugInfo(name) {
+ var ref1, ref2;
+ name = name || this.name;
+ if ((name == null) && !((ref1 = this.parent) != null ? ref1.name : void 0)) {
+ return "";
+ } else if (name == null) {
+ return "parent: <" + this.parent.name + ">";
+ } else if (!((ref2 = this.parent) != null ? ref2.name : void 0)) {
+ return "node: <" + name + ">";
+ } else {
+ return "node: <" + name + ">, parent: <" + this.parent.name + ">";
+ }
+ }
+
+ // Aliases
+ ele(name, attributes, text) {
+ return this.element(name, attributes, text);
+ }
+
+ nod(name, attributes, text) {
+ return this.node(name, attributes, text);
+ }
+
+ txt(value) {
+ return this.text(value);
+ }
+
+ dat(value) {
+ return this.cdata(value);
+ }
+
+ com(value) {
+ return this.comment(value);
+ }
+
+ ins(target, value) {
+ return this.instruction(target, value);
+ }
+
+ doc() {
+ return this.document();
+ }
+
+ dec(version, encoding, standalone) {
+ return this.declaration(version, encoding, standalone);
+ }
+
+ e(name, attributes, text) {
+ return this.element(name, attributes, text);
+ }
+
+ n(name, attributes, text) {
+ return this.node(name, attributes, text);
+ }
+
+ t(value) {
+ return this.text(value);
+ }
+
+ d(value) {
+ return this.cdata(value);
+ }
+
+ c(value) {
+ return this.comment(value);
+ }
+
+ r(value) {
+ return this.raw(value);
+ }
+
+ i(target, value) {
+ return this.instruction(target, value);
+ }
+
+ u() {
+ return this.up();
+ }
+
+ // can be deprecated in a future release
+ importXMLBuilder(doc) {
+ return this.importDocument(doc);
+ }
+
+ // Adds or modifies an attribute.
+
+ // `name` attribute name
+ // `value` attribute value
+ attribute(name, value) {
+ throw new Error("attribute() applies to element nodes only.");
+ }
+
+ att(name, value) {
+ return this.attribute(name, value);
+ }
+
+ a(name, value) {
+ return this.attribute(name, value);
+ }
+
+ // Removes an attribute
+
+ // `name` attribute name
+ removeAttribute(name) {
+ throw new Error("attribute() applies to element nodes only.");
+ }
+
+ // DOM level 1 functions to be implemented later
+ replaceChild(newChild, oldChild) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ removeChild(oldChild) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ appendChild(newChild) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ hasChildNodes() {
+ return this.children.length !== 0;
+ }
+
+ cloneNode(deep) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ normalize() {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ // DOM level 2
+ isSupported(feature, version) {
+ return true;
+ }
+
+ hasAttributes() {
+ return this.attribs.length !== 0;
+ }
+
+ // DOM level 3 functions to be implemented later
+ compareDocumentPosition(other) {
+ var ref, res;
+ ref = this;
+ if (ref === other) {
+ return 0;
+ } else if (this.document() !== other.document()) {
+ res = DocumentPosition.Disconnected | DocumentPosition.ImplementationSpecific;
+ if (Math.random() < 0.5) {
+ res |= DocumentPosition.Preceding;
+ } else {
+ res |= DocumentPosition.Following;
+ }
+ return res;
+ } else if (ref.isAncestor(other)) {
+ return DocumentPosition.Contains | DocumentPosition.Preceding;
+ } else if (ref.isDescendant(other)) {
+ return DocumentPosition.Contains | DocumentPosition.Following;
+ } else if (ref.isPreceding(other)) {
+ return DocumentPosition.Preceding;
+ } else {
+ return DocumentPosition.Following;
+ }
+ }
+
+ isSameNode(other) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ lookupPrefix(namespaceURI) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ isDefaultNamespace(namespaceURI) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ lookupNamespaceURI(prefix) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ isEqualNode(node) {
+ var i, j, ref1;
+ if (node.nodeType !== this.nodeType) {
+ return false;
+ }
+ if (node.children.length !== this.children.length) {
+ return false;
+ }
+ for (i = j = 0, ref1 = this.children.length - 1; (0 <= ref1 ? j <= ref1 : j >= ref1); i = 0 <= ref1 ? ++j : --j) {
+ if (!this.children[i].isEqualNode(node.children[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ getFeature(feature, version) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ setUserData(key, data, handler) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ getUserData(key) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+
+ // Returns true if other is an inclusive descendant of node,
+ // and false otherwise.
+ contains(other) {
+ if (!other) {
+ return false;
+ }
+ return other === this || this.isDescendant(other);
+ }
+
+ // An object A is called a descendant of an object B, if either A is
+ // a child of B or A is a child of an object C that is a descendant of B.
+ isDescendant(node) {
+ var child, isDescendantChild, j, len, ref1;
+ ref1 = this.children;
+ for (j = 0, len = ref1.length; j < len; j++) {
+ child = ref1[j];
+ if (node === child) {
+ return true;
+ }
+ isDescendantChild = child.isDescendant(node);
+ if (isDescendantChild) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // An object A is called an ancestor of an object B if and only if
+ // B is a descendant of A.
+ isAncestor(node) {
+ return node.isDescendant(this);
+ }
+
+ // An object A is preceding an object B if A and B are in the
+ // same tree and A comes before B in tree order.
+ isPreceding(node) {
+ var nodePos, thisPos;
+ nodePos = this.treePosition(node);
+ thisPos = this.treePosition(this);
+ if (nodePos === -1 || thisPos === -1) {
+ return false;
+ } else {
+ return nodePos < thisPos;
+ }
+ }
+
+ // An object A is folllowing an object B if A and B are in the
+ // same tree and A comes after B in tree order.
+ isFollowing(node) {
+ var nodePos, thisPos;
+ nodePos = this.treePosition(node);
+ thisPos = this.treePosition(this);
+ if (nodePos === -1 || thisPos === -1) {
+ return false;
+ } else {
+ return nodePos > thisPos;
+ }
+ }
+
+ // Returns the preorder position of the given node in the tree, or -1
+ // if the node is not in the tree.
+ treePosition(node) {
+ var found, pos;
+ pos = 0;
+ found = false;
+ this.foreachTreeNode(this.document(), function(childNode) {
+ pos++;
+ if (!found && childNode === node) {
+ return found = true;
+ }
+ });
+ if (found) {
+ return pos;
+ } else {
+ return -1;
+ }
+ }
+
+
+ // Depth-first preorder traversal through the XML tree
+ foreachTreeNode(node, func) {
+ var child, j, len, ref1, res;
+ node || (node = this.document());
+ ref1 = node.children;
+ for (j = 0, len = ref1.length; j < len; j++) {
+ child = ref1[j];
+ if (res = func(child)) {
+ return res;
+ } else {
+ res = this.foreachTreeNode(child, func);
+ if (res) {
+ return res;
+ }
+ }
+ }
+ }
+
+ };
+
+ // DOM level 1
+ Object.defineProperty(XMLNode.prototype, 'nodeName', {
+ get: function() {
+ return this.name;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'nodeType', {
+ get: function() {
+ return this.type;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'nodeValue', {
+ get: function() {
+ return this.value;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'parentNode', {
+ get: function() {
+ return this.parent;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'childNodes', {
+ get: function() {
+ if (!this.childNodeList || !this.childNodeList.nodes) {
+ this.childNodeList = new XMLNodeList(this.children);
+ }
+ return this.childNodeList;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'firstChild', {
+ get: function() {
+ return this.children[0] || null;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'lastChild', {
+ get: function() {
+ return this.children[this.children.length - 1] || null;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'previousSibling', {
+ get: function() {
+ var i;
+ i = this.parent.children.indexOf(this);
+ return this.parent.children[i - 1] || null;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'nextSibling', {
+ get: function() {
+ var i;
+ i = this.parent.children.indexOf(this);
+ return this.parent.children[i + 1] || null;
+ }
+ });
+
+ Object.defineProperty(XMLNode.prototype, 'ownerDocument', {
+ get: function() {
+ return this.document() || null;
+ }
+ });
+
+ // DOM level 3
+ Object.defineProperty(XMLNode.prototype, 'textContent', {
+ get: function() {
+ var child, j, len, ref1, str;
+ if (this.nodeType === NodeType.Element || this.nodeType === NodeType.DocumentFragment) {
+ str = '';
+ ref1 = this.children;
+ for (j = 0, len = ref1.length; j < len; j++) {
+ child = ref1[j];
+ if (child.textContent) {
+ str += child.textContent;
+ }
+ }
+ return str;
+ } else {
+ return null;
+ }
+ },
+ set: function(value) {
+ throw new Error("This DOM method is not implemented." + this.debugInfo());
+ }
+ });
+
+ return XMLNode;
+
+ }).call(this);
+
+}).call(this);