parser.js 13 KB

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