3 var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject,
4 hasProp = {}.hasOwnProperty;
6 isObject = require(
'lodash/isObject');
8 isFunction = require(
'lodash/isFunction');
10 isEmpty = require(
'lodash/isEmpty');
18 XMLDeclaration = null;
26 module.exports = XMLNode = (
function() {
27 function XMLNode(parent) {
29 this.options = this.parent.options;
30 this.stringify = this.parent.stringify;
31 if (XMLElement === null) {
32 XMLElement = require(
'./XMLElement');
33 XMLCData = require(
'./XMLCData');
34 XMLComment = require(
'./XMLComment');
35 XMLDeclaration = require(
'./XMLDeclaration');
36 XMLDocType = require(
'./XMLDocType');
37 XMLRaw = require(
'./XMLRaw');
38 XMLText = require(
'./XMLText');
42 XMLNode.prototype.element =
function(name, attributes, text) {
43 var childNode, item, j, k, key, lastChild, len, len1, ref, val;
45 if (attributes == null) {
48 attributes = attributes.valueOf();
49 if (!isObject(attributes)) {
50 ref = [attributes, text], text = ref[0], attributes = ref[1];
53 name = name.valueOf();
55 if (Array.isArray(name)) {
56 for (j = 0, len = name.length; j < len; j++) {
58 lastChild = this.element(item);
60 }
else if (isFunction(name)) {
61 lastChild = this.element(name.apply());
62 }
else if (isObject(name)) {
64 if (!hasProp.call(name, key))
continue;
66 if (isFunction(val)) {
69 if ((isObject(val)) && (isEmpty(val))) {
72 if (!this.options.ignoreDecorators &&
this.stringify.convertAttKey && key.indexOf(
this.stringify.convertAttKey) === 0) {
73 lastChild = this.attribute(key.substr(
this.stringify.convertAttKey.length), val);
74 }
else if (!this.options.ignoreDecorators &&
this.stringify.convertPIKey && key.indexOf(
this.stringify.convertPIKey) === 0) {
75 lastChild = this.instruction(key.substr(
this.stringify.convertPIKey.length), val);
76 }
else if (!this.options.separateArrayItems && Array.isArray(val)) {
77 for (k = 0, len1 = val.length; k < len1; k++) {
80 childNode[key] = item;
81 lastChild = this.element(childNode);
83 }
else if (isObject(val)) {
84 lastChild = this.element(key);
85 lastChild.element(val);
87 lastChild = this.element(key, val);
91 if (!this.options.ignoreDecorators &&
this.stringify.convertTextKey && name.indexOf(
this.stringify.convertTextKey) === 0) {
92 lastChild = this.text(text);
93 }
else if (!this.options.ignoreDecorators &&
this.stringify.convertCDataKey && name.indexOf(
this.stringify.convertCDataKey) === 0) {
94 lastChild = this.cdata(text);
95 }
else if (!this.options.ignoreDecorators &&
this.stringify.convertCommentKey && name.indexOf(
this.stringify.convertCommentKey) === 0) {
96 lastChild = this.comment(text);
97 }
else if (!this.options.ignoreDecorators &&
this.stringify.convertRawKey && name.indexOf(
this.stringify.convertRawKey) === 0) {
98 lastChild = this.raw(text);
100 lastChild = this.node(name, attributes, text);
103 if (lastChild == null) {
104 throw new Error(
"Could not create any elements with: " + name);
109 XMLNode.prototype.insertBefore =
function(name, attributes, text) {
110 var child, i, removed;
112 throw new Error(
"Cannot insert elements at root level");
114 i = this.parent.children.indexOf(
this);
115 removed = this.parent.children.splice(i);
116 child = this.parent.element(name, attributes, text);
117 Array.prototype.push.apply(this.parent.children, removed);
121 XMLNode.prototype.insertAfter =
function(name, attributes, text) {
122 var child, i, removed;
124 throw new Error(
"Cannot insert elements at root level");
126 i = this.parent.children.indexOf(
this);
127 removed = this.parent.children.splice(i + 1);
128 child = this.parent.element(name, attributes, text);
129 Array.prototype.push.apply(this.parent.children, removed);
133 XMLNode.prototype.remove =
function() {
136 throw new Error(
"Cannot remove the root element");
138 i = this.parent.children.indexOf(
this);
139 [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref;
143 XMLNode.prototype.node =
function(name, attributes, text) {
146 name = name.valueOf();
148 if (attributes == null) {
151 attributes = attributes.valueOf();
152 if (!isObject(attributes)) {
153 ref = [attributes, text], text = ref[0], attributes = ref[1];
155 child =
new XMLElement(
this, name, attributes);
159 this.children.push(child);
163 XMLNode.prototype.text =
function(value) {
165 child =
new XMLText(
this, value);
166 this.children.push(child);
170 XMLNode.prototype.cdata =
function(value) {
172 child =
new XMLCData(
this, value);
173 this.children.push(child);
177 XMLNode.prototype.comment =
function(value) {
179 child =
new XMLComment(
this, value);
180 this.children.push(child);
184 XMLNode.prototype.raw =
function(value) {
186 child =
new XMLRaw(
this, value);
187 this.children.push(child);
191 XMLNode.prototype.declaration =
function(version, encoding, standalone) {
193 doc = this.document();
194 xmldec =
new XMLDeclaration(doc, version, encoding, standalone);
199 XMLNode.prototype.doctype =
function(pubID, sysID) {
201 doc = this.document();
202 doctype =
new XMLDocType(doc, pubID, sysID);
203 doc.doctype = doctype;
207 XMLNode.prototype.up =
function() {
209 throw new Error(
"The root node has no parent. Use doc() if you need to get the document object.");
214 XMLNode.prototype.root =
function() {
220 while (!child.isRoot) {
221 child = child.parent;
226 XMLNode.prototype.document =
function() {
227 return this.root().documentObject;
230 XMLNode.prototype.end =
function(options) {
231 return this.document().toString(options);
234 XMLNode.prototype.prev =
function() {
237 throw new Error(
"Root node has no siblings");
239 i = this.parent.children.indexOf(
this);
241 throw new Error(
"Already at the first node");
243 return this.parent.children[i - 1];
246 XMLNode.prototype.next =
function() {
249 throw new Error(
"Root node has no siblings");
251 i = this.parent.children.indexOf(
this);
252 if (i === -1 || i === this.parent.children.length - 1) {
253 throw new Error(
"Already at the last node");
255 return this.parent.children[i + 1];
258 XMLNode.prototype.importXMLBuilder =
function(xmlbuilder) {
260 clonedRoot = xmlbuilder.root().clone();
261 clonedRoot.parent =
this;
262 clonedRoot.isRoot =
false;
263 this.children.push(clonedRoot);
267 XMLNode.prototype.ele =
function(name, attributes, text) {
268 return this.element(name, attributes, text);
271 XMLNode.prototype.nod =
function(name, attributes, text) {
272 return this.node(name, attributes, text);
275 XMLNode.prototype.txt =
function(value) {
276 return this.text(value);
279 XMLNode.prototype.dat =
function(value) {
280 return this.cdata(value);
283 XMLNode.prototype.com =
function(value) {
284 return this.comment(value);
287 XMLNode.prototype.doc =
function() {
288 return this.document();
291 XMLNode.prototype.dec =
function(version, encoding, standalone) {
292 return this.declaration(version, encoding, standalone);
295 XMLNode.prototype.dtd =
function(pubID, sysID) {
296 return this.doctype(pubID, sysID);
299 XMLNode.prototype.e =
function(name, attributes, text) {
300 return this.element(name, attributes, text);
303 XMLNode.prototype.n =
function(name, attributes, text) {
304 return this.node(name, attributes, text);
307 XMLNode.prototype.t =
function(value) {
308 return this.text(value);
311 XMLNode.prototype.d =
function(value) {
312 return this.cdata(value);
315 XMLNode.prototype.c =
function(value) {
316 return this.comment(value);
319 XMLNode.prototype.r =
function(value) {
320 return this.raw(value);
323 XMLNode.prototype.u =
function() {