parser.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. // Generated by CoffeeScript 1.12.7
  2. (function() {
  3. "use strict";
  4. var bom, defaults, events, isEmpty, isValidKey, processItem, processors, sax, setImmediate,
  5. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  6. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  7. hasProp = {}.hasOwnProperty;
  8. sax = require('sax');
  9. events = require('events');
  10. bom = require('./bom');
  11. processors = require('./processors');
  12. setImmediate = require('timers').setImmediate;
  13. defaults = require('./defaults').defaults;
  14. isEmpty = function(thing) {
  15. return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0;
  16. };
  17. isValidKey = function(key) {
  18. return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';
  19. };
  20. processItem = function(processors, item, key) {
  21. var i, len, process;
  22. for (i = 0, len = processors.length; i < len; i++) {
  23. process = processors[i];
  24. item = process(item, key);
  25. }
  26. return item;
  27. };
  28. exports.Parser = (function(superClass) {
  29. extend(Parser, superClass);
  30. function Parser(opts) {
  31. this.parseStringPromise = bind(this.parseStringPromise, this);
  32. this.parseString = bind(this.parseString, this);
  33. this.reset = bind(this.reset, this);
  34. this.assignOrPush = bind(this.assignOrPush, this);
  35. this.processAsync = bind(this.processAsync, this);
  36. var key, ref, value;
  37. if (!(this instanceof exports.Parser)) {
  38. return new exports.Parser(opts);
  39. }
  40. this.options = {};
  41. ref = defaults["0.2"];
  42. for (key in ref) {
  43. if (!hasProp.call(ref, key)) continue;
  44. value = ref[key];
  45. this.options[key] = value;
  46. }
  47. for (key in opts) {
  48. if (!hasProp.call(opts, key)) continue;
  49. value = opts[key];
  50. this.options[key] = value;
  51. }
  52. if (this.options.xmlns) {
  53. this.options.xmlnskey = this.options.attrkey + "ns";
  54. }
  55. if (this.options.normalizeTags) {
  56. if (!this.options.tagNameProcessors) {
  57. this.options.tagNameProcessors = [];
  58. }
  59. this.options.tagNameProcessors.unshift(processors.normalize);
  60. }
  61. this.reset();
  62. }
  63. Parser.prototype.processAsync = function() {
  64. var chunk, err;
  65. try {
  66. if (this.remaining.length <= this.options.chunkSize) {
  67. chunk = this.remaining;
  68. this.remaining = '';
  69. this.saxParser = this.saxParser.write(chunk);
  70. return this.saxParser.close();
  71. } else {
  72. chunk = this.remaining.substr(0, this.options.chunkSize);
  73. this.remaining = this.remaining.substr(this.options.chunkSize, this.remaining.length);
  74. this.saxParser = this.saxParser.write(chunk);
  75. return setImmediate(this.processAsync);
  76. }
  77. } catch (error1) {
  78. err = error1;
  79. if (!this.saxParser.errThrown) {
  80. this.saxParser.errThrown = true;
  81. return this.emit(err);
  82. }
  83. }
  84. };
  85. Parser.prototype.assignOrPush = function(obj, key, newValue) {
  86. if (!isValidKey(key)) {
  87. return;
  88. }
  89. if (!(key in obj)) {
  90. if (!this.options.explicitArray) {
  91. return obj[key] = newValue;
  92. } else {
  93. return obj[key] = [newValue];
  94. }
  95. } else {
  96. if (!(obj[key] instanceof Array)) {
  97. obj[key] = [obj[key]];
  98. }
  99. return obj[key].push(newValue);
  100. }
  101. };
  102. Parser.prototype.reset = function() {
  103. var attrkey, charkey, ontext, stack;
  104. this.removeAllListeners();
  105. this.saxParser = sax.parser(this.options.strict, {
  106. trim: false,
  107. normalize: false,
  108. xmlns: this.options.xmlns
  109. });
  110. this.saxParser.errThrown = false;
  111. this.saxParser.onerror = (function(_this) {
  112. return function(error) {
  113. _this.saxParser.resume();
  114. if (!_this.saxParser.errThrown) {
  115. _this.saxParser.errThrown = true;
  116. return _this.emit("error", error);
  117. }
  118. };
  119. })(this);
  120. this.saxParser.onend = (function(_this) {
  121. return function() {
  122. if (!_this.saxParser.ended) {
  123. _this.saxParser.ended = true;
  124. return _this.emit("end", _this.resultObject);
  125. }
  126. };
  127. })(this);
  128. this.saxParser.ended = false;
  129. this.EXPLICIT_CHARKEY = this.options.explicitCharkey;
  130. this.resultObject = null;
  131. stack = [];
  132. attrkey = this.options.attrkey;
  133. charkey = this.options.charkey;
  134. this.saxParser.onopentag = (function(_this) {
  135. return function(node) {
  136. var key, newValue, obj, processedKey, ref;
  137. obj = {};
  138. obj[charkey] = "";
  139. if (!_this.options.ignoreAttrs) {
  140. ref = node.attributes;
  141. for (key in ref) {
  142. if (!hasProp.call(ref, key)) continue;
  143. if (!(attrkey in obj) && !_this.options.mergeAttrs) {
  144. obj[attrkey] = {};
  145. }
  146. newValue = _this.options.attrValueProcessors ? processItem(_this.options.attrValueProcessors, node.attributes[key], key) : node.attributes[key];
  147. processedKey = _this.options.attrNameProcessors ? processItem(_this.options.attrNameProcessors, key) : key;
  148. if (isValidKey(processedKey)) {
  149. if (_this.options.mergeAttrs) {
  150. _this.assignOrPush(obj, processedKey, newValue);
  151. } else {
  152. obj[attrkey][processedKey] = newValue;
  153. }
  154. }
  155. }
  156. }
  157. obj["#name"] = _this.options.tagNameProcessors ? processItem(_this.options.tagNameProcessors, node.name) : node.name;
  158. if (_this.options.xmlns) {
  159. obj[_this.options.xmlnskey] = {
  160. uri: node.uri,
  161. local: node.local
  162. };
  163. }
  164. return stack.push(obj);
  165. };
  166. })(this);
  167. this.saxParser.onclosetag = (function(_this) {
  168. return function() {
  169. var cdata, emptyStr, key, node, nodeName, obj, objClone, old, s, xpath;
  170. obj = stack.pop();
  171. nodeName = obj["#name"];
  172. if (!_this.options.explicitChildren || !_this.options.preserveChildrenOrder) {
  173. delete obj["#name"];
  174. }
  175. if (obj.cdata === true) {
  176. cdata = obj.cdata;
  177. delete obj.cdata;
  178. }
  179. s = stack[stack.length - 1];
  180. if (obj[charkey].match(/^\s*$/) && !cdata) {
  181. emptyStr = obj[charkey];
  182. delete obj[charkey];
  183. } else {
  184. if (_this.options.trim) {
  185. obj[charkey] = obj[charkey].trim();
  186. }
  187. if (_this.options.normalize) {
  188. obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
  189. }
  190. obj[charkey] = _this.options.valueProcessors ? processItem(_this.options.valueProcessors, obj[charkey], nodeName) : obj[charkey];
  191. if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
  192. obj = obj[charkey];
  193. }
  194. }
  195. if (isEmpty(obj)) {
  196. if (typeof _this.options.emptyTag === 'function') {
  197. obj = _this.options.emptyTag();
  198. } else {
  199. obj = _this.options.emptyTag !== '' ? _this.options.emptyTag : emptyStr;
  200. }
  201. }
  202. if (_this.options.validator != null) {
  203. xpath = "/" + ((function() {
  204. var i, len, results;
  205. results = [];
  206. for (i = 0, len = stack.length; i < len; i++) {
  207. node = stack[i];
  208. results.push(node["#name"]);
  209. }
  210. return results;
  211. })()).concat(nodeName).join("/");
  212. (function() {
  213. var err;
  214. try {
  215. return obj = _this.options.validator(xpath, s && s[nodeName], obj);
  216. } catch (error1) {
  217. err = error1;
  218. return _this.emit("error", err);
  219. }
  220. })();
  221. }
  222. if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') {
  223. if (!_this.options.preserveChildrenOrder) {
  224. node = {};
  225. if (_this.options.attrkey in obj) {
  226. node[_this.options.attrkey] = obj[_this.options.attrkey];
  227. delete obj[_this.options.attrkey];
  228. }
  229. if (!_this.options.charsAsChildren && _this.options.charkey in obj) {
  230. node[_this.options.charkey] = obj[_this.options.charkey];
  231. delete obj[_this.options.charkey];
  232. }
  233. if (Object.getOwnPropertyNames(obj).length > 0) {
  234. node[_this.options.childkey] = obj;
  235. }
  236. obj = node;
  237. } else if (s) {
  238. s[_this.options.childkey] = s[_this.options.childkey] || [];
  239. objClone = {};
  240. for (key in obj) {
  241. if (!hasProp.call(obj, key)) continue;
  242. if (isValidKey(key)) {
  243. objClone[key] = obj[key];
  244. }
  245. }
  246. s[_this.options.childkey].push(objClone);
  247. delete obj["#name"];
  248. if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
  249. obj = obj[charkey];
  250. }
  251. }
  252. }
  253. if (stack.length > 0) {
  254. return _this.assignOrPush(s, nodeName, obj);
  255. } else {
  256. if (_this.options.explicitRoot) {
  257. old = obj;
  258. obj = {};
  259. obj[nodeName] = old;
  260. }
  261. _this.resultObject = obj;
  262. _this.saxParser.ended = true;
  263. return _this.emit("end", _this.resultObject);
  264. }
  265. };
  266. })(this);
  267. ontext = (function(_this) {
  268. return function(text) {
  269. var charChild, s;
  270. s = stack[stack.length - 1];
  271. if (s) {
  272. s[charkey] += text;
  273. if (_this.options.explicitChildren && _this.options.preserveChildrenOrder && _this.options.charsAsChildren && (_this.options.includeWhiteChars || text.replace(/\\n/g, '').trim() !== '')) {
  274. s[_this.options.childkey] = s[_this.options.childkey] || [];
  275. charChild = {
  276. '#name': '__text__'
  277. };
  278. charChild[charkey] = text;
  279. if (_this.options.normalize) {
  280. charChild[charkey] = charChild[charkey].replace(/\s{2,}/g, " ").trim();
  281. }
  282. s[_this.options.childkey].push(charChild);
  283. }
  284. return s;
  285. }
  286. };
  287. })(this);
  288. this.saxParser.ontext = ontext;
  289. return this.saxParser.oncdata = (function(_this) {
  290. return function(text) {
  291. var s;
  292. s = ontext(text);
  293. if (s) {
  294. return s.cdata = true;
  295. }
  296. };
  297. })(this);
  298. };
  299. Parser.prototype.parseString = function(str, cb) {
  300. var err;
  301. if ((cb != null) && typeof cb === "function") {
  302. this.on("end", function(result) {
  303. this.reset();
  304. return cb(null, result);
  305. });
  306. this.on("error", function(err) {
  307. this.reset();
  308. return cb(err);
  309. });
  310. }
  311. try {
  312. str = str.toString();
  313. if (str.trim() === '') {
  314. this.emit("end", null);
  315. return true;
  316. }
  317. str = bom.stripBOM(str);
  318. if (this.options.async) {
  319. this.remaining = str;
  320. setImmediate(this.processAsync);
  321. return this.saxParser;
  322. }
  323. return this.saxParser.write(str).close();
  324. } catch (error1) {
  325. err = error1;
  326. if (!(this.saxParser.errThrown || this.saxParser.ended)) {
  327. this.emit('error', err);
  328. return this.saxParser.errThrown = true;
  329. } else if (this.saxParser.ended) {
  330. throw err;
  331. }
  332. }
  333. };
  334. Parser.prototype.parseStringPromise = function(str) {
  335. return new Promise((function(_this) {
  336. return function(resolve, reject) {
  337. return _this.parseString(str, function(err, value) {
  338. if (err) {
  339. return reject(err);
  340. } else {
  341. return resolve(value);
  342. }
  343. });
  344. };
  345. })(this));
  346. };
  347. return Parser;
  348. })(events);
  349. exports.parseString = function(str, a, b) {
  350. var cb, options, parser;
  351. if (b != null) {
  352. if (typeof b === 'function') {
  353. cb = b;
  354. }
  355. if (typeof a === 'object') {
  356. options = a;
  357. }
  358. } else {
  359. if (typeof a === 'function') {
  360. cb = a;
  361. }
  362. options = {};
  363. }
  364. parser = new exports.Parser(options);
  365. return parser.parseString(str, cb);
  366. };
  367. exports.parseStringPromise = function(str, a) {
  368. var options, parser;
  369. if (typeof a === 'object') {
  370. options = a;
  371. }
  372. parser = new exports.Parser(options);
  373. return parser.parseStringPromise(str);
  374. };
  375. }).call(this);