PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/jxon/1.5.4/index.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 278 lines | 203 code | 31 blank | 44 comment | 93 complexity | b017dd438d1b914fc52402bdb95e9808 MD5 | raw file
  1. /*
  2. * JXON framework - Copyleft 2011 by Mozilla Developer Network
  3. *
  4. * Revision #1 - September 5, 2014
  5. *
  6. * https://developer.mozilla.org/en-US/docs/JXON
  7. *
  8. * This framework is released under the GNU Public License, version 3 or later.
  9. * http://www.gnu.org/licenses/gpl-3.0-standalone.html
  10. *
  11. * small modifications performed by the iD project:
  12. * https://github.com/openstreetmap/iD/commits/18aa33ba97b52cacf454e95c65d154000e052a1f/js/lib/jxon.js
  13. *
  14. * small modifications performed by user @bugreport0
  15. * https://github.com/tyrasd/JXON/pull/2/commits
  16. *
  17. * some additions and modifications by user @igord
  18. * https://github.com/tyrasd/JXON/pull/5/commits
  19. *
  20. * adapted for nodejs and npm by Martin Raifer <tyr.asd@gmail.com>
  21. */
  22. /*
  23. * Modifications:
  24. * - added config method that excepts objects with props:
  25. * - valueKey (default: keyValue)
  26. * - attrKey (default: keyAttributes)
  27. * - attrPrefix (default: @)
  28. * - lowerCaseTags (default: true)
  29. * - trueIsEmpty (default: true)
  30. * - autoDate (default: true)
  31. * - turning tag and attributes to lower case is optional
  32. * - optional turning boolean true to empty tag
  33. * - auto Date parsing is optional
  34. * - added parseXml method
  35. *
  36. */
  37. (function (root, factory) {
  38. if (typeof define === 'function' && define.amd) {
  39. // AMD. Register as an anonymous module.
  40. define(factory(window));
  41. } else if (typeof exports === 'object') {
  42. if (typeof window === 'object' && window.DOMImplementation) {
  43. // Browserify. hardcode usage of browser's own XMLDom implementation
  44. // see https://github.com/tyrasd/jxon/issues/18
  45. module.exports = factory(window);
  46. } else {
  47. // Node. Does not work with strict CommonJS, but
  48. // only CommonJS-like environments that support module.exports,
  49. // like Node.
  50. module.exports = factory(require('xmldom'));
  51. }
  52. } else {
  53. // Browser globals (root is window)
  54. root.JXON = factory(window);
  55. }
  56. }(this, function (xmlDom) {
  57. return new (function () {
  58. var
  59. sValProp = "keyValue",
  60. sAttrProp = "keyAttributes",
  61. sAttrsPref = "@",
  62. sLowCase = true,
  63. sEmptyTrue = true,
  64. sAutoDate = true,
  65. sIgnorePrefixed = false,
  66. sParseValues = true, /* you can customize these values */
  67. aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
  68. function parseText (sValue) {
  69. if (!sParseValues) return sValue;
  70. if (rIsNull.test(sValue)) { return null; }
  71. if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; }
  72. if (isFinite(sValue)) { return parseFloat(sValue); }
  73. if (sAutoDate && isFinite(Date.parse(sValue))) { return new Date(sValue); }
  74. return sValue;
  75. }
  76. function EmptyTree () { }
  77. EmptyTree.prototype.toString = function () { return "null"; };
  78. EmptyTree.prototype.valueOf = function () { return null; };
  79. function objectify (vValue) {
  80. return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
  81. }
  82. function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
  83. var
  84. nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
  85. bAttributes = oParentNode.nodeType === oParentNode.ELEMENT_NODE && oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
  86. var
  87. sProp, vContent, nLength = 0, sCollectedTxt = "",
  88. vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ (sEmptyTrue ? true : '');
  89. if (bChildren) {
  90. for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
  91. oNode = oParentNode.childNodes.item(nItem);
  92. if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */
  93. else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */
  94. else if (oNode.nodeType === 1 && !(sIgnorePrefixed && oNode.prefix)) { aCache.push(oNode); } /* nodeType is "Element" (1) */
  95. }
  96. }
  97. var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
  98. if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
  99. for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
  100. sProp = aCache[nElId].nodeName;
  101. if (sLowCase) sProp = sProp.toLowerCase();
  102. vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
  103. if (vResult.hasOwnProperty(sProp)) {
  104. if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
  105. vResult[sProp].push(vContent);
  106. } else {
  107. vResult[sProp] = vContent;
  108. nLength++;
  109. }
  110. }
  111. if (bAttributes) {
  112. var
  113. nAttrLen = oParentNode.attributes.length,
  114. sAPrefix = bNesteAttr ? "" : sAttrsPref, oAttrParent = bNesteAttr ? {} : vResult;
  115. for (var oAttrib, oAttribName, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
  116. oAttrib = oParentNode.attributes.item(nAttrib);
  117. oAttribName = oAttrib.name;
  118. if (sLowCase) oAttribName = oAttribName.toLowerCase();
  119. oAttrParent[sAPrefix + oAttribName] = parseText(oAttrib.value.trim());
  120. }
  121. if (bNesteAttr) {
  122. if (bFreeze) { Object.freeze(oAttrParent); }
  123. vResult[sAttrProp] = oAttrParent;
  124. nLength -= nAttrLen - 1;
  125. }
  126. }
  127. if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
  128. vResult[sValProp] = vBuiltVal;
  129. } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
  130. vResult = vBuiltVal;
  131. }
  132. if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
  133. aCache.length = nLevelStart;
  134. return vResult;
  135. }
  136. function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
  137. var vValue, oChild;
  138. if (oParentObj.constructor === String || oParentObj.constructor === Number || oParentObj.constructor === Boolean) {
  139. oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 or 1 */
  140. if (oParentObj === oParentObj.valueOf()) { return; }
  141. } else if (oParentObj.constructor === Date) {
  142. oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
  143. }
  144. for (var sName in oParentObj) {
  145. vValue = oParentObj[sName];
  146. if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
  147. // when it is _
  148. if (sName === sValProp) {
  149. if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
  150. } else if (sName === sAttrProp) { /* verbosity level is 3 */
  151. for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
  152. } else if (sName.charAt(0) === sAttrsPref && sName !== sAttrsPref+'xmlns') {
  153. oParentEl.setAttribute(sName.slice(1), vValue);
  154. } else if (vValue.constructor === Array) {
  155. for (var nItem = 0; nItem < vValue.length; nItem++) {
  156. oChild = oXMLDoc.createElementNS(vValue[nItem][sAttrsPref+'xmlns'] || oParentEl.namespaceURI, sName);
  157. loadObjTree(oXMLDoc, oChild, vValue[nItem]);
  158. oParentEl.appendChild(oChild);
  159. }
  160. } else {
  161. oChild = oXMLDoc.createElementNS((vValue || {})[sAttrsPref+'xmlns'] || oParentEl.namespaceURI, sName);
  162. if (vValue instanceof Object) {
  163. loadObjTree(oXMLDoc, oChild, vValue);
  164. } else if (vValue !== null && vValue !== true) {
  165. oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
  166. } else if (!sEmptyTrue && vValue === true) {
  167. oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
  168. }
  169. oParentEl.appendChild(oChild);
  170. }
  171. }
  172. }
  173. this.xmlToJs = this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
  174. var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
  175. return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
  176. };
  177. this.jsToXml = this.unbuild = function (oObjTree, sNamespaceURI /* optional */, sQualifiedName /* optional */, oDocumentType /* optional */) {
  178. var documentImplementation = xmlDom.document && xmlDom.document.implementation || new xmlDom.DOMImplementation();
  179. var oNewDoc = documentImplementation.createDocument(sNamespaceURI || null, sQualifiedName || "", oDocumentType || null);
  180. loadObjTree(oNewDoc, oNewDoc.documentElement || oNewDoc, oObjTree);
  181. return oNewDoc;
  182. };
  183. this.config = function(o) {
  184. if (typeof o === 'undefined') {
  185. return {
  186. valueKey: sValProp,
  187. attrKey: sAttrProp,
  188. attrPrefix: sAttrPref,
  189. lowerCaseTags: sLowCase,
  190. trueIsEmpty: sEmptyTrue,
  191. autoDate: sAutoDate,
  192. ignorePrefixNodes: sIgnorePrefixed,
  193. parseValues: sParseValues
  194. };
  195. }
  196. for (var k in o) {
  197. switch(k) {
  198. case 'valueKey':
  199. sValProp = o.valueKey;
  200. break;
  201. case 'attrKey':
  202. sAttrProp = o.attrKey;
  203. break;
  204. case 'attrPrefix':
  205. sAttrsPref = o.attrPrefix;
  206. break;
  207. case 'lowerCaseTags':
  208. sLowCase = o.lowerCaseTags;
  209. break;
  210. case 'trueIsEmpty':
  211. sEmptyTrue = o.trueIsEmpty;
  212. break;
  213. case 'autoDate':
  214. sAutoDate = o.autoDate;
  215. break;
  216. case 'ignorePrefixedNodes':
  217. sIgnorePrefixed = o.ignorePrefixedNodes;
  218. break;
  219. case 'parseValues':
  220. sParseValues = o.parseValues;
  221. break;
  222. default:
  223. break;
  224. }
  225. }
  226. };
  227. this.stringToXml = function(xmlStr) {
  228. return ( new xmlDom.DOMParser() ).parseFromString(xmlStr, 'application/xml');
  229. };
  230. this.xmlToString = function (xmlObj) {
  231. if (typeof xmlObj.xml !== "undefined") {
  232. return xmlObj.xml;
  233. } else {
  234. return (new xmlDom.XMLSerializer()).serializeToString(xmlObj);
  235. }
  236. };
  237. this.stringToJs = function(str) {
  238. var xmlObj = this.stringToXml(str);
  239. return this.xmlToJs(xmlObj);
  240. };
  241. this.jsToString = this.stringify = function(oObjTree, sNamespaceURI /* optional */, sQualifiedName /* optional */, oDocumentType /* optional */) {
  242. return this.xmlToString(
  243. this.jsToXml(oObjTree, sNamespaceURI, sQualifiedName, oDocumentType)
  244. );
  245. };
  246. })();
  247. }));