00001
00002 (function() {
00003 var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLProcessingInstruction, XMLRaw, XMLText, isEmpty, isFunction, isObject, ref,
00004 hasProp = {}.hasOwnProperty;
00005
00006 ref = require('./Utility'), isObject = ref.isObject, isFunction = ref.isFunction, isEmpty = ref.isEmpty;
00007
00008 XMLElement = null;
00009
00010 XMLCData = null;
00011
00012 XMLComment = null;
00013
00014 XMLDeclaration = null;
00015
00016 XMLDocType = null;
00017
00018 XMLRaw = null;
00019
00020 XMLText = null;
00021
00022 XMLProcessingInstruction = null;
00023
00024 module.exports = XMLNode = (function() {
00025 function XMLNode(parent) {
00026 this.parent = parent;
00027 if (this.parent) {
00028 this.options = this.parent.options;
00029 this.stringify = this.parent.stringify;
00030 }
00031 this.children = [];
00032 if (!XMLElement) {
00033 XMLElement = require('./XMLElement');
00034 XMLCData = require('./XMLCData');
00035 XMLComment = require('./XMLComment');
00036 XMLDeclaration = require('./XMLDeclaration');
00037 XMLDocType = require('./XMLDocType');
00038 XMLRaw = require('./XMLRaw');
00039 XMLText = require('./XMLText');
00040 XMLProcessingInstruction = require('./XMLProcessingInstruction');
00041 }
00042 }
00043
00044 XMLNode.prototype.element = function(name, attributes, text) {
00045 var childNode, item, j, k, key, lastChild, len, len1, ref1, val;
00046 lastChild = null;
00047 if (attributes == null) {
00048 attributes = {};
00049 }
00050 attributes = attributes.valueOf();
00051 if (!isObject(attributes)) {
00052 ref1 = [attributes, text], text = ref1[0], attributes = ref1[1];
00053 }
00054 if (name != null) {
00055 name = name.valueOf();
00056 }
00057 if (Array.isArray(name)) {
00058 for (j = 0, len = name.length; j < len; j++) {
00059 item = name[j];
00060 lastChild = this.element(item);
00061 }
00062 } else if (isFunction(name)) {
00063 lastChild = this.element(name.apply());
00064 } else if (isObject(name)) {
00065 for (key in name) {
00066 if (!hasProp.call(name, key)) continue;
00067 val = name[key];
00068 if (isFunction(val)) {
00069 val = val.apply();
00070 }
00071 if ((isObject(val)) && (isEmpty(val))) {
00072 val = null;
00073 }
00074 if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) {
00075 lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val);
00076 } else if (!this.options.separateArrayItems && Array.isArray(val)) {
00077 for (k = 0, len1 = val.length; k < len1; k++) {
00078 item = val[k];
00079 childNode = {};
00080 childNode[key] = item;
00081 lastChild = this.element(childNode);
00082 }
00083 } else if (isObject(val)) {
00084 lastChild = this.element(key);
00085 lastChild.element(val);
00086 } else {
00087 lastChild = this.element(key, val);
00088 }
00089 }
00090 } else {
00091 if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) {
00092 lastChild = this.text(text);
00093 } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) {
00094 lastChild = this.cdata(text);
00095 } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) {
00096 lastChild = this.comment(text);
00097 } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) {
00098 lastChild = this.raw(text);
00099 } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && name.indexOf(this.stringify.convertPIKey) === 0) {
00100 lastChild = this.instruction(name.substr(this.stringify.convertPIKey.length), text);
00101 } else {
00102 lastChild = this.node(name, attributes, text);
00103 }
00104 }
00105 if (lastChild == null) {
00106 throw new Error("Could not create any elements with: " + name);
00107 }
00108 return lastChild;
00109 };
00110
00111 XMLNode.prototype.insertBefore = function(name, attributes, text) {
00112 var child, i, removed;
00113 if (this.isRoot) {
00114 throw new Error("Cannot insert elements at root level");
00115 }
00116 i = this.parent.children.indexOf(this);
00117 removed = this.parent.children.splice(i);
00118 child = this.parent.element(name, attributes, text);
00119 Array.prototype.push.apply(this.parent.children, removed);
00120 return child;
00121 };
00122
00123 XMLNode.prototype.insertAfter = function(name, attributes, text) {
00124 var child, i, removed;
00125 if (this.isRoot) {
00126 throw new Error("Cannot insert elements at root level");
00127 }
00128 i = this.parent.children.indexOf(this);
00129 removed = this.parent.children.splice(i + 1);
00130 child = this.parent.element(name, attributes, text);
00131 Array.prototype.push.apply(this.parent.children, removed);
00132 return child;
00133 };
00134
00135 XMLNode.prototype.remove = function() {
00136 var i, ref1;
00137 if (this.isRoot) {
00138 throw new Error("Cannot remove the root element");
00139 }
00140 i = this.parent.children.indexOf(this);
00141 [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref1 = [])), ref1;
00142 return this.parent;
00143 };
00144
00145 XMLNode.prototype.node = function(name, attributes, text) {
00146 var child, ref1;
00147 if (name != null) {
00148 name = name.valueOf();
00149 }
00150 attributes || (attributes = {});
00151 attributes = attributes.valueOf();
00152 if (!isObject(attributes)) {
00153 ref1 = [attributes, text], text = ref1[0], attributes = ref1[1];
00154 }
00155 child = new XMLElement(this, name, attributes);
00156 if (text != null) {
00157 child.text(text);
00158 }
00159 this.children.push(child);
00160 return child;
00161 };
00162
00163 XMLNode.prototype.text = function(value) {
00164 var child;
00165 child = new XMLText(this, value);
00166 this.children.push(child);
00167 return this;
00168 };
00169
00170 XMLNode.prototype.cdata = function(value) {
00171 var child;
00172 child = new XMLCData(this, value);
00173 this.children.push(child);
00174 return this;
00175 };
00176
00177 XMLNode.prototype.comment = function(value) {
00178 var child;
00179 child = new XMLComment(this, value);
00180 this.children.push(child);
00181 return this;
00182 };
00183
00184 XMLNode.prototype.commentBefore = function(value) {
00185 var child, i, removed;
00186 i = this.parent.children.indexOf(this);
00187 removed = this.parent.children.splice(i);
00188 child = this.parent.comment(value);
00189 Array.prototype.push.apply(this.parent.children, removed);
00190 return this;
00191 };
00192
00193 XMLNode.prototype.commentAfter = function(value) {
00194 var child, i, removed;
00195 i = this.parent.children.indexOf(this);
00196 removed = this.parent.children.splice(i + 1);
00197 child = this.parent.comment(value);
00198 Array.prototype.push.apply(this.parent.children, removed);
00199 return this;
00200 };
00201
00202 XMLNode.prototype.raw = function(value) {
00203 var child;
00204 child = new XMLRaw(this, value);
00205 this.children.push(child);
00206 return this;
00207 };
00208
00209 XMLNode.prototype.instruction = function(target, value) {
00210 var insTarget, insValue, instruction, j, len;
00211 if (target != null) {
00212 target = target.valueOf();
00213 }
00214 if (value != null) {
00215 value = value.valueOf();
00216 }
00217 if (Array.isArray(target)) {
00218 for (j = 0, len = target.length; j < len; j++) {
00219 insTarget = target[j];
00220 this.instruction(insTarget);
00221 }
00222 } else if (isObject(target)) {
00223 for (insTarget in target) {
00224 if (!hasProp.call(target, insTarget)) continue;
00225 insValue = target[insTarget];
00226 this.instruction(insTarget, insValue);
00227 }
00228 } else {
00229 if (isFunction(value)) {
00230 value = value.apply();
00231 }
00232 instruction = new XMLProcessingInstruction(this, target, value);
00233 this.children.push(instruction);
00234 }
00235 return this;
00236 };
00237
00238 XMLNode.prototype.instructionBefore = function(target, value) {
00239 var child, i, removed;
00240 i = this.parent.children.indexOf(this);
00241 removed = this.parent.children.splice(i);
00242 child = this.parent.instruction(target, value);
00243 Array.prototype.push.apply(this.parent.children, removed);
00244 return this;
00245 };
00246
00247 XMLNode.prototype.instructionAfter = function(target, value) {
00248 var child, i, removed;
00249 i = this.parent.children.indexOf(this);
00250 removed = this.parent.children.splice(i + 1);
00251 child = this.parent.instruction(target, value);
00252 Array.prototype.push.apply(this.parent.children, removed);
00253 return this;
00254 };
00255
00256 XMLNode.prototype.declaration = function(version, encoding, standalone) {
00257 var doc, xmldec;
00258 doc = this.document();
00259 xmldec = new XMLDeclaration(doc, version, encoding, standalone);
00260 if (doc.children[0] instanceof XMLDeclaration) {
00261 doc.children[0] = xmldec;
00262 } else {
00263 doc.children.unshift(xmldec);
00264 }
00265 return doc.root() || doc;
00266 };
00267
00268 XMLNode.prototype.doctype = function(pubID, sysID) {
00269 var child, doc, doctype, i, j, k, len, len1, ref1, ref2;
00270 doc = this.document();
00271 doctype = new XMLDocType(doc, pubID, sysID);
00272 ref1 = doc.children;
00273 for (i = j = 0, len = ref1.length; j < len; i = ++j) {
00274 child = ref1[i];
00275 if (child instanceof XMLDocType) {
00276 doc.children[i] = doctype;
00277 return doctype;
00278 }
00279 }
00280 ref2 = doc.children;
00281 for (i = k = 0, len1 = ref2.length; k < len1; i = ++k) {
00282 child = ref2[i];
00283 if (child.isRoot) {
00284 doc.children.splice(i, 0, doctype);
00285 return doctype;
00286 }
00287 }
00288 doc.children.push(doctype);
00289 return doctype;
00290 };
00291
00292 XMLNode.prototype.up = function() {
00293 if (this.isRoot) {
00294 throw new Error("The root node has no parent. Use doc() if you need to get the document object.");
00295 }
00296 return this.parent;
00297 };
00298
00299 XMLNode.prototype.root = function() {
00300 var node;
00301 node = this;
00302 while (node) {
00303 if (node.isDocument) {
00304 return node.rootObject;
00305 } else if (node.isRoot) {
00306 return node;
00307 } else {
00308 node = node.parent;
00309 }
00310 }
00311 };
00312
00313 XMLNode.prototype.document = function() {
00314 var node;
00315 node = this;
00316 while (node) {
00317 if (node.isDocument) {
00318 return node;
00319 } else {
00320 node = node.parent;
00321 }
00322 }
00323 };
00324
00325 XMLNode.prototype.end = function(options) {
00326 return this.document().end(options);
00327 };
00328
00329 XMLNode.prototype.prev = function() {
00330 var i;
00331 i = this.parent.children.indexOf(this);
00332 if (i < 1) {
00333 throw new Error("Already at the first node");
00334 }
00335 return this.parent.children[i - 1];
00336 };
00337
00338 XMLNode.prototype.next = function() {
00339 var i;
00340 i = this.parent.children.indexOf(this);
00341 if (i === -1 || i === this.parent.children.length - 1) {
00342 throw new Error("Already at the last node");
00343 }
00344 return this.parent.children[i + 1];
00345 };
00346
00347 XMLNode.prototype.importDocument = function(doc) {
00348 var clonedRoot;
00349 clonedRoot = doc.root().clone();
00350 clonedRoot.parent = this;
00351 clonedRoot.isRoot = false;
00352 this.children.push(clonedRoot);
00353 return this;
00354 };
00355
00356 XMLNode.prototype.ele = function(name, attributes, text) {
00357 return this.element(name, attributes, text);
00358 };
00359
00360 XMLNode.prototype.nod = function(name, attributes, text) {
00361 return this.node(name, attributes, text);
00362 };
00363
00364 XMLNode.prototype.txt = function(value) {
00365 return this.text(value);
00366 };
00367
00368 XMLNode.prototype.dat = function(value) {
00369 return this.cdata(value);
00370 };
00371
00372 XMLNode.prototype.com = function(value) {
00373 return this.comment(value);
00374 };
00375
00376 XMLNode.prototype.ins = function(target, value) {
00377 return this.instruction(target, value);
00378 };
00379
00380 XMLNode.prototype.doc = function() {
00381 return this.document();
00382 };
00383
00384 XMLNode.prototype.dec = function(version, encoding, standalone) {
00385 return this.declaration(version, encoding, standalone);
00386 };
00387
00388 XMLNode.prototype.dtd = function(pubID, sysID) {
00389 return this.doctype(pubID, sysID);
00390 };
00391
00392 XMLNode.prototype.e = function(name, attributes, text) {
00393 return this.element(name, attributes, text);
00394 };
00395
00396 XMLNode.prototype.n = function(name, attributes, text) {
00397 return this.node(name, attributes, text);
00398 };
00399
00400 XMLNode.prototype.t = function(value) {
00401 return this.text(value);
00402 };
00403
00404 XMLNode.prototype.d = function(value) {
00405 return this.cdata(value);
00406 };
00407
00408 XMLNode.prototype.c = function(value) {
00409 return this.comment(value);
00410 };
00411
00412 XMLNode.prototype.r = function(value) {
00413 return this.raw(value);
00414 };
00415
00416 XMLNode.prototype.i = function(target, value) {
00417 return this.instruction(target, value);
00418 };
00419
00420 XMLNode.prototype.u = function() {
00421 return this.up();
00422 };
00423
00424 XMLNode.prototype.importXMLBuilder = function(doc) {
00425 return this.importDocument(doc);
00426 };
00427
00428 return XMLNode;
00429
00430 })();
00431
00432 }).call(this);