You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
13 KiB
381 lines
13 KiB
// Generated by CoffeeScript 1.12.7 |
|
(function() { |
|
"use strict"; |
|
var bom, defaults, events, isEmpty, processItem, processors, sax, setImmediate, |
|
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, |
|
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; }, |
|
hasProp = {}.hasOwnProperty; |
|
|
|
sax = require('sax'); |
|
|
|
events = require('events'); |
|
|
|
bom = require('./bom'); |
|
|
|
processors = require('./processors'); |
|
|
|
setImmediate = require('timers').setImmediate; |
|
|
|
defaults = require('./defaults').defaults; |
|
|
|
isEmpty = function(thing) { |
|
return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0; |
|
}; |
|
|
|
processItem = function(processors, item, key) { |
|
var i, len, process; |
|
for (i = 0, len = processors.length; i < len; i++) { |
|
process = processors[i]; |
|
item = process(item, key); |
|
} |
|
return item; |
|
}; |
|
|
|
exports.Parser = (function(superClass) { |
|
extend(Parser, superClass); |
|
|
|
function Parser(opts) { |
|
this.parseStringPromise = bind(this.parseStringPromise, this); |
|
this.parseString = bind(this.parseString, this); |
|
this.reset = bind(this.reset, this); |
|
this.assignOrPush = bind(this.assignOrPush, this); |
|
this.processAsync = bind(this.processAsync, this); |
|
var key, ref, value; |
|
if (!(this instanceof exports.Parser)) { |
|
return new exports.Parser(opts); |
|
} |
|
this.options = {}; |
|
ref = defaults["0.2"]; |
|
for (key in ref) { |
|
if (!hasProp.call(ref, key)) continue; |
|
value = ref[key]; |
|
this.options[key] = value; |
|
} |
|
for (key in opts) { |
|
if (!hasProp.call(opts, key)) continue; |
|
value = opts[key]; |
|
this.options[key] = value; |
|
} |
|
if (this.options.xmlns) { |
|
this.options.xmlnskey = this.options.attrkey + "ns"; |
|
} |
|
if (this.options.normalizeTags) { |
|
if (!this.options.tagNameProcessors) { |
|
this.options.tagNameProcessors = []; |
|
} |
|
this.options.tagNameProcessors.unshift(processors.normalize); |
|
} |
|
this.reset(); |
|
} |
|
|
|
Parser.prototype.processAsync = function() { |
|
var chunk, err; |
|
try { |
|
if (this.remaining.length <= this.options.chunkSize) { |
|
chunk = this.remaining; |
|
this.remaining = ''; |
|
this.saxParser = this.saxParser.write(chunk); |
|
return this.saxParser.close(); |
|
} else { |
|
chunk = this.remaining.substr(0, this.options.chunkSize); |
|
this.remaining = this.remaining.substr(this.options.chunkSize, this.remaining.length); |
|
this.saxParser = this.saxParser.write(chunk); |
|
return setImmediate(this.processAsync); |
|
} |
|
} catch (error1) { |
|
err = error1; |
|
if (!this.saxParser.errThrown) { |
|
this.saxParser.errThrown = true; |
|
return this.emit(err); |
|
} |
|
} |
|
}; |
|
|
|
Parser.prototype.assignOrPush = function(obj, key, newValue) { |
|
if (!(key in obj)) { |
|
if (!this.options.explicitArray) { |
|
return obj[key] = newValue; |
|
} else { |
|
return obj[key] = [newValue]; |
|
} |
|
} else { |
|
if (!(obj[key] instanceof Array)) { |
|
obj[key] = [obj[key]]; |
|
} |
|
return obj[key].push(newValue); |
|
} |
|
}; |
|
|
|
Parser.prototype.reset = function() { |
|
var attrkey, charkey, ontext, stack; |
|
this.removeAllListeners(); |
|
this.saxParser = sax.parser(this.options.strict, { |
|
trim: false, |
|
normalize: false, |
|
xmlns: this.options.xmlns |
|
}); |
|
this.saxParser.errThrown = false; |
|
this.saxParser.onerror = (function(_this) { |
|
return function(error) { |
|
_this.saxParser.resume(); |
|
if (!_this.saxParser.errThrown) { |
|
_this.saxParser.errThrown = true; |
|
return _this.emit("error", error); |
|
} |
|
}; |
|
})(this); |
|
this.saxParser.onend = (function(_this) { |
|
return function() { |
|
if (!_this.saxParser.ended) { |
|
_this.saxParser.ended = true; |
|
return _this.emit("end", _this.resultObject); |
|
} |
|
}; |
|
})(this); |
|
this.saxParser.ended = false; |
|
this.EXPLICIT_CHARKEY = this.options.explicitCharkey; |
|
this.resultObject = null; |
|
stack = []; |
|
attrkey = this.options.attrkey; |
|
charkey = this.options.charkey; |
|
this.saxParser.onopentag = (function(_this) { |
|
return function(node) { |
|
var key, newValue, obj, processedKey, ref; |
|
obj = {}; |
|
obj[charkey] = ""; |
|
if (!_this.options.ignoreAttrs) { |
|
ref = node.attributes; |
|
for (key in ref) { |
|
if (!hasProp.call(ref, key)) continue; |
|
if (!(attrkey in obj) && !_this.options.mergeAttrs) { |
|
obj[attrkey] = {}; |
|
} |
|
newValue = _this.options.attrValueProcessors ? processItem(_this.options.attrValueProcessors, node.attributes[key], key) : node.attributes[key]; |
|
processedKey = _this.options.attrNameProcessors ? processItem(_this.options.attrNameProcessors, key) : key; |
|
if (_this.options.mergeAttrs) { |
|
_this.assignOrPush(obj, processedKey, newValue); |
|
} else { |
|
obj[attrkey][processedKey] = newValue; |
|
} |
|
} |
|
} |
|
obj["#name"] = _this.options.tagNameProcessors ? processItem(_this.options.tagNameProcessors, node.name) : node.name; |
|
if (_this.options.xmlns) { |
|
obj[_this.options.xmlnskey] = { |
|
uri: node.uri, |
|
local: node.local |
|
}; |
|
} |
|
return stack.push(obj); |
|
}; |
|
})(this); |
|
this.saxParser.onclosetag = (function(_this) { |
|
return function() { |
|
var cdata, emptyStr, key, node, nodeName, obj, objClone, old, s, xpath; |
|
obj = stack.pop(); |
|
nodeName = obj["#name"]; |
|
if (!_this.options.explicitChildren || !_this.options.preserveChildrenOrder) { |
|
delete obj["#name"]; |
|
} |
|
if (obj.cdata === true) { |
|
cdata = obj.cdata; |
|
delete obj.cdata; |
|
} |
|
s = stack[stack.length - 1]; |
|
if (obj[charkey].match(/^\s*$/) && !cdata) { |
|
emptyStr = obj[charkey]; |
|
delete obj[charkey]; |
|
} else { |
|
if (_this.options.trim) { |
|
obj[charkey] = obj[charkey].trim(); |
|
} |
|
if (_this.options.normalize) { |
|
obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim(); |
|
} |
|
obj[charkey] = _this.options.valueProcessors ? processItem(_this.options.valueProcessors, obj[charkey], nodeName) : obj[charkey]; |
|
if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) { |
|
obj = obj[charkey]; |
|
} |
|
} |
|
if (isEmpty(obj)) { |
|
obj = _this.options.emptyTag !== '' ? _this.options.emptyTag : emptyStr; |
|
} |
|
if (_this.options.validator != null) { |
|
xpath = "/" + ((function() { |
|
var i, len, results; |
|
results = []; |
|
for (i = 0, len = stack.length; i < len; i++) { |
|
node = stack[i]; |
|
results.push(node["#name"]); |
|
} |
|
return results; |
|
})()).concat(nodeName).join("/"); |
|
(function() { |
|
var err; |
|
try { |
|
return obj = _this.options.validator(xpath, s && s[nodeName], obj); |
|
} catch (error1) { |
|
err = error1; |
|
return _this.emit("error", err); |
|
} |
|
})(); |
|
} |
|
if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') { |
|
if (!_this.options.preserveChildrenOrder) { |
|
node = {}; |
|
if (_this.options.attrkey in obj) { |
|
node[_this.options.attrkey] = obj[_this.options.attrkey]; |
|
delete obj[_this.options.attrkey]; |
|
} |
|
if (!_this.options.charsAsChildren && _this.options.charkey in obj) { |
|
node[_this.options.charkey] = obj[_this.options.charkey]; |
|
delete obj[_this.options.charkey]; |
|
} |
|
if (Object.getOwnPropertyNames(obj).length > 0) { |
|
node[_this.options.childkey] = obj; |
|
} |
|
obj = node; |
|
} else if (s) { |
|
s[_this.options.childkey] = s[_this.options.childkey] || []; |
|
objClone = {}; |
|
for (key in obj) { |
|
if (!hasProp.call(obj, key)) continue; |
|
objClone[key] = obj[key]; |
|
} |
|
s[_this.options.childkey].push(objClone); |
|
delete obj["#name"]; |
|
if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) { |
|
obj = obj[charkey]; |
|
} |
|
} |
|
} |
|
if (stack.length > 0) { |
|
return _this.assignOrPush(s, nodeName, obj); |
|
} else { |
|
if (_this.options.explicitRoot) { |
|
old = obj; |
|
obj = {}; |
|
obj[nodeName] = old; |
|
} |
|
_this.resultObject = obj; |
|
_this.saxParser.ended = true; |
|
return _this.emit("end", _this.resultObject); |
|
} |
|
}; |
|
})(this); |
|
ontext = (function(_this) { |
|
return function(text) { |
|
var charChild, s; |
|
s = stack[stack.length - 1]; |
|
if (s) { |
|
s[charkey] += text; |
|
if (_this.options.explicitChildren && _this.options.preserveChildrenOrder && _this.options.charsAsChildren && (_this.options.includeWhiteChars || text.replace(/\\n/g, '').trim() !== '')) { |
|
s[_this.options.childkey] = s[_this.options.childkey] || []; |
|
charChild = { |
|
'#name': '__text__' |
|
}; |
|
charChild[charkey] = text; |
|
if (_this.options.normalize) { |
|
charChild[charkey] = charChild[charkey].replace(/\s{2,}/g, " ").trim(); |
|
} |
|
s[_this.options.childkey].push(charChild); |
|
} |
|
return s; |
|
} |
|
}; |
|
})(this); |
|
this.saxParser.ontext = ontext; |
|
return this.saxParser.oncdata = (function(_this) { |
|
return function(text) { |
|
var s; |
|
s = ontext(text); |
|
if (s) { |
|
return s.cdata = true; |
|
} |
|
}; |
|
})(this); |
|
}; |
|
|
|
Parser.prototype.parseString = function(str, cb) { |
|
var err; |
|
if ((cb != null) && typeof cb === "function") { |
|
this.on("end", function(result) { |
|
this.reset(); |
|
return cb(null, result); |
|
}); |
|
this.on("error", function(err) { |
|
this.reset(); |
|
return cb(err); |
|
}); |
|
} |
|
try { |
|
str = str.toString(); |
|
if (str.trim() === '') { |
|
this.emit("end", null); |
|
return true; |
|
} |
|
str = bom.stripBOM(str); |
|
if (this.options.async) { |
|
this.remaining = str; |
|
setImmediate(this.processAsync); |
|
return this.saxParser; |
|
} |
|
return this.saxParser.write(str).close(); |
|
} catch (error1) { |
|
err = error1; |
|
if (!(this.saxParser.errThrown || this.saxParser.ended)) { |
|
this.emit('error', err); |
|
return this.saxParser.errThrown = true; |
|
} else if (this.saxParser.ended) { |
|
throw err; |
|
} |
|
} |
|
}; |
|
|
|
Parser.prototype.parseStringPromise = function(str) { |
|
return new Promise((function(_this) { |
|
return function(resolve, reject) { |
|
return _this.parseString(str, function(err, value) { |
|
if (err) { |
|
return reject(err); |
|
} else { |
|
return resolve(value); |
|
} |
|
}); |
|
}; |
|
})(this)); |
|
}; |
|
|
|
return Parser; |
|
|
|
})(events); |
|
|
|
exports.parseString = function(str, a, b) { |
|
var cb, options, parser; |
|
if (b != null) { |
|
if (typeof b === 'function') { |
|
cb = b; |
|
} |
|
if (typeof a === 'object') { |
|
options = a; |
|
} |
|
} else { |
|
if (typeof a === 'function') { |
|
cb = a; |
|
} |
|
options = {}; |
|
} |
|
parser = new exports.Parser(options); |
|
return parser.parseString(str, cb); |
|
}; |
|
|
|
exports.parseStringPromise = function(str, a) { |
|
var options, parser; |
|
if (typeof a === 'object') { |
|
options = a; |
|
} |
|
parser = new exports.Parser(options); |
|
return parser.parseStringPromise(str); |
|
}; |
|
|
|
}).call(this);
|
|
|