[Pkg-javascript-commits] [ltx] 392/469: Various changes
Jonas Smedegaard
dr at jones.dk
Wed Aug 31 13:03:30 UTC 2016
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository ltx.
commit f70e712290aa41b3c31fc0c275a8682240bd2f14
Author: Sonny Piers <sonny at fastmail.net>
Date: Thu Sep 10 01:59:16 2015 +0200
Various changes
---
.gitignore | 5 +-
.npmignore | 10 +
Gruntfile.js | 2 +-
benchmark.js | 27 +
benchmark/.gitignore | 1 -
benchmark/benchmark.js | 146 --
benchmark/build.js | 16 -
benchmark/index.html | 8 -
index.js | 3 -
lib/{dom-element.js => DOMElement.js} | 3 +-
lib/{element.js => Element.js} | 30 +-
lib/Parser.js | 72 +
lib/escape.js | 17 +
lib/index-browserify.js | 9 -
lib/index.js | 24 +-
lib/parse.js | 98 +-
lib/{sax/sax_easysax.js => parsers/easysax.js} | 0
lib/parsers/index.js | 11 +
lib/{sax/sax_ltx.js => parsers/ltx.js} | 0
lib/{sax/sax_expat.js => parsers/node-expat.js} | 0
lib/{sax/sax_node-xml.js => parsers/node-xml.js} | 0
lib/{sax/sax_saxjs.js => parsers/sax.js} | 0
ltx-browser.js | 1884 ----------------------
package.json | 6 +-
test/dom-element-test.js | 8 +-
test/element-test.js | 2 +-
test/parse-test.js | 13 +-
test/unicode-test.js | 2 +-
28 files changed, 179 insertions(+), 2218 deletions(-)
diff --git a/.gitignore b/.gitignore
index 93f1361..a430685 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
-node_modules
-npm-debug.log
+node_modules/
+
+ltx.js
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..ea77ae3
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,10 @@
+test/
+
+.editorconfig
+.gitignore
+.jshintrc
+.npmignore
+.travis.yml
+benchmark.js
+CONTRIBUTING.md
+Gruntfile.js
diff --git a/Gruntfile.js b/Gruntfile.js
index e354ed5..d840764 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -13,7 +13,7 @@ module.exports = function(grunt) {
browserify: {
dist: {
files: {
- 'ltx-browser.js': ['./lib/index-browserify.js']
+ 'ltx.js': ['./lib/index.js']
},
options: {
debug: grunt.cli.options.debug
diff --git a/benchmark.js b/benchmark.js
new file mode 100644
index 0000000..75df1da
--- /dev/null
+++ b/benchmark.js
@@ -0,0 +1,27 @@
+'use strict'
+
+var benchmark = require('benchmark')
+var ltx = require('./lib/index')
+var parsers = require('./lib/parsers')
+
+var XML = [
+ '<message to="foo at bar" from="bar at to" type="chat" id="foobar">',
+ '<body>Where there is love there is life.</body>',
+ '</message>'
+].join('')
+
+var suite = new benchmark.Suite('parse')
+
+parsers.forEach(function(Parser) {
+ suite.add(Parser.name, function() {
+ ltx.parse(XML, {Parser: Parser})
+ })
+})
+
+suite.on('cycle', function(event) {
+ console.log(event.target.toString())
+})
+.on('complete', function() {
+ console.log('Fastest is ' + this.filter('fastest').pluck('name'))
+})
+.run({'async': true})
diff --git a/benchmark/.gitignore b/benchmark/.gitignore
deleted file mode 100644
index 012a3cd..0000000
--- a/benchmark/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-index.js
diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js
deleted file mode 100644
index 46fc8a7..0000000
--- a/benchmark/benchmark.js
+++ /dev/null
@@ -1,146 +0,0 @@
-'use strict';
-
-if (process.title === 'browser') {
- var ltx = require("ltx")
- var strophe = require('Strophe.js')
- var requestAnimationFrame = require('request-animation-frame').requestAnimationFrame
-} else {
- var path = "../lib/index"
- var ltx = require(path)
-}
-var util = require('util')
-
-function now() {
- return new Date().getTime()
-}
-
-function Test() {
- this.timings = {}
-}
-Test.prototype = {
- record: function(name, fun) {
- var t1 = now()
- var res = fun()
- var t2 = now()
-
- if (!this.timings.hasOwnProperty(name))
- this.timings[name] = { i: 0, t: 0 }
- this.timings[name].i++
- this.timings[name].t += t2 - t1
- },
-
- report: function() {
- if (process.title === 'browser') {
- var s = []
- var html = "<div style='float: left min-width: 25em'><h2>" + this.name + "</h2><dl>"
- for(var k in this.timings) {
- var t = this.timings[k].t / this.timings[k].i
- html += "<dt>" + k + "</dt><dd class='" + k + "'>" + t + " ms </dd>"
- }
- html += "</dl></div>\n"
- return html
- } else {
- var s = this.name + "\t"
- for(k in this.timings) {
- var t = this.timings[k].t / this.timings[k].i
- s += k + ": " + t + " ms\t"
- }
- return s
- }
- }
-}
-
-function LtxTest(saxParser) {
- Test.call(this)
- this.saxParser = saxParser
- this.name = "LTX/" + saxParser.name
-}
-util.inherits(LtxTest, Test)
-
-LtxTest.prototype.parse = function(s) {
- return ltx.parse(s, this.saxParser)
-}
-
-LtxTest.prototype.serialize = function(el) {
- return el.toString()
-}
-
-LtxTest.prototype.traverse = function(node) {
- while(node.children && node.children[0])
- node = node.children[0]
-}
-
-function StropheTest() {
- Test.call(this)
-
- this.serialize = Strophe.serialize
-}
-util.inherits(StropheTest, Test)
-
-StropheTest.prototype.name = "Strophe.js"
-
-StropheTest.prototype.parse = function(s) {
- return Strophe.xmlHtmlNode(s).firstChild
-}
-
-StropheTest.prototype.traverse = function(node) {
- while(node.firstChild)
- node = node.firstChild
-}
-
-var tests = ltx.availableSaxParsers.map(function(saxParser) {
- return new LtxTest(saxParser)
-})
-if (process.title === 'browser')
- tests.push(new StropheTest())
-var messages = [
- "<message/>",
- "<message foo='bar'/>",
- "<message foo='bar'><foo/><bar>fnord<baz/>fnord</bar></message>"
-]
-messages[3] = "<message>"
-for(var i = 0; i < 10; i++) {
- messages[3] += "fnord fnord fnord<foo bar='baz'>"
-}
-for(var i = 0; i < 10; i++) {
- messages[3] += "</foo>fnordfnordfnordfnord<quux foo='bar'/>"
-}
-messages[3] += "</message>"
-
-var iteration = 0
-function runTests() {
- iteration++
- tests.forEach(function(test) {
- for(var j = 0; j < messages.length; j++) {
- var parsed, serialized
- test.record('parse' + j, function() {
- parsed = test.parse(messages[j])
- })
- test.record('serialize' + j, function() {
- serialized = test.serialize(parsed)
- })
- test.record('traverse' + j, function() {
- test.traverse(parsed)
- })
- }
- })
-
- if (process.title === 'browser') {
- document.body.innerHTML = "<style>.parse0, .parse1, .parse2, .parse3 { color: red; } .serialize1, .serialize2, .serialize3, .serialize4 { color: blue; }</style>\n" +
- "<h1>Iteration " + iteration + "<h1>\n"
- tests.forEach(function(test) {
- document.body.innerHTML += test.report() + "<br>"
- })
- requestAnimationFrame(runTests)
- } else {
- console.log("Iteration " + iteration)
- tests.forEach(function(test) {
- console.log(test.report())
- })
- process.nextTick(runTests)
- }
-}
-
-setTimeout(function() {
- runTests()
-}, 1000)
diff --git a/benchmark/build.js b/benchmark/build.js
deleted file mode 100644
index 2aac8be..0000000
--- a/benchmark/build.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-
-var browserify = require('browserify');
-var path = require('path');
-var b = browserify({
- debug: true
-});
-var root = path.join(__dirname, "..");
-b.require("./lib/index-browserify.js",
- { root: root, basedir: root });
-b.alias("ltx", "./lib/index-browserify.js");
-b.addEntry('benchmark.js');
-
-var fs = require('fs');
-
-fs.writeFileSync('index.js', b.bundle());
diff --git a/benchmark/index.html b/benchmark/index.html
deleted file mode 100644
index 481935a..0000000
--- a/benchmark/index.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <script src="index.js"></script>
- </head>
- <body>
- </body>
-</html>
diff --git a/index.js b/index.js
deleted file mode 100644
index b01e345..0000000
--- a/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'use strict';
-
-module.exports = require('./lib/index.js')
diff --git a/lib/dom-element.js b/lib/DOMElement.js
similarity index 98%
rename from lib/dom-element.js
rename to lib/DOMElement.js
index f50d1be..099bb1f 100644
--- a/lib/dom-element.js
+++ b/lib/DOMElement.js
@@ -1,7 +1,7 @@
'use strict';
var util = require('util')
- , Element = require('./element').Element
+ , Element = require('./Element')
function DOMElement(name, attrs) {
Element.call(this, name, attrs)
@@ -118,5 +118,4 @@ DOMElement.createElement = function(name, attrs /*, child1, child2, ...*/) {
return el
}
-
module.exports = DOMElement
diff --git a/lib/element.js b/lib/Element.js
similarity index 94%
rename from lib/element.js
rename to lib/Element.js
index c72b22a..e2dcf1c 100644
--- a/lib/element.js
+++ b/lib/Element.js
@@ -1,5 +1,9 @@
'use strict';
+var escape = require('./escape')
+var escapeXML = escape.escapeXML
+var escapeXMLText = escape.escapeXMLText
+
/**
* This cheap replica of DOM/Builder puts me to shame :-)
*
@@ -338,9 +342,9 @@ Element.prototype._addChildren = function(writer) {
if (child.write) {
child.write(writer)
} else if (typeof child === 'string') {
- writer(escapeXmlText(child))
+ writer(escapeXMLText(child))
} else if (child.toString) {
- writer(escapeXmlText(child.toString(10)))
+ writer(escapeXMLText(child.toString(10)))
}
}
}
@@ -361,7 +365,7 @@ Element.prototype.write = function(writer) {
if (typeof v !== 'string') {
v = v.toString(10)
}
- writer(escapeXml(v))
+ writer(escapeXML(v))
writer('"')
}
}
@@ -383,22 +387,4 @@ Element.createElement = function(name, attrs /*, child1, child2, ...*/) {
return el
}
-
-function escapeXml(s) {
- return s.
- replace(/\&/g, '&').
- replace(/</g, '<').
- replace(/>/g, '>').
- replace(/"/g, '"').
- replace(/"/g, ''')
-}
-
-function escapeXmlText(s) {
- return s.
- replace(/\&/g, '&').
- replace(/</g, '<').
- replace(/>/g, '>')
-}
-
-exports.Element = Element
-exports.escapeXml = escapeXml
+module.exports = Element
diff --git a/lib/Parser.js b/lib/Parser.js
new file mode 100644
index 0000000..0f03038
--- /dev/null
+++ b/lib/Parser.js
@@ -0,0 +1,72 @@
+'use strict';
+
+var EventEmitter = require('events').EventEmitter
+var inherits = require('util').inherits
+var Element = require('./Element')
+var LtxParser = require('./parsers/ltx')
+
+var Parser = function(options) {
+ EventEmitter.call(this)
+
+ var ParserInterface = this.Parser = (options && options.Parser) || LtxParser
+ var ElementInterface = this.Element = (options && options.Element) || Element
+
+ if (!ParserInterface) {
+ throw new Error('No SAX parser available')
+ }
+ this.parser = new ParserInterface()
+
+ var el
+ , self = this
+ this.parser.on('startElement', function(name, attrs) {
+ var child = new ElementInterface(name, attrs)
+ if (!el) {
+ el = child
+ } else {
+ el = el.cnode(child)
+ }
+ })
+ this.parser.on('endElement', function(name) {
+ /* jshint -W035 */
+ if (!el) {
+ /* Err */
+ } else if (name === el.name) {
+ if (el.parent) {
+ el = el.parent
+ } else if (!self.tree) {
+ self.tree = el
+ el = undefined
+ }
+ }
+ /* jshint +W035 */
+ })
+ this.parser.on('text', function(str) {
+ if (el) {
+ el.t(str)
+ }
+ })
+ this.parser.on('error', function(e) {
+ self.error = e
+ self.emit('error', e)
+ })
+}
+
+inherits(Parser, EventEmitter)
+
+Parser.prototype.write = function(data) {
+ this.parser.write(data)
+}
+
+Parser.prototype.end = function(data) {
+ this.parser.end(data)
+
+ if (!this.error) {
+ if (this.tree) {
+ this.emit('tree', this.tree)
+ } else {
+ this.emit('error', new Error('Incomplete document'))
+ }
+ }
+}
+
+module.exports = Parser
diff --git a/lib/escape.js b/lib/escape.js
new file mode 100644
index 0000000..7479fc0
--- /dev/null
+++ b/lib/escape.js
@@ -0,0 +1,17 @@
+'use strict';
+
+module.exports.escapeXML = function escapeXML(s) {
+ return s.
+ replace(/\&/g, '&').
+ replace(/</g, '<').
+ replace(/>/g, '>').
+ replace(/"/g, '"').
+ replace(/"/g, ''')
+}
+
+module.exports.escapeXMLText = function escapeXMLText(s) {
+ return s.
+ replace(/\&/g, '&').
+ replace(/</g, '<').
+ replace(/>/g, '>')
+}
diff --git a/lib/index-browserify.js b/lib/index-browserify.js
deleted file mode 100644
index 223ebf4..0000000
--- a/lib/index-browserify.js
+++ /dev/null
@@ -1,9 +0,0 @@
-'use strict';
-
-/* Cause browserify to bundle SAX parsers: */
-var parse = require('./parse')
-
-parse.availableSaxParsers.push(parse.bestSaxParser = require('./sax/sax_ltx'))
-
-/* SHIM */
-module.exports = require('./index')
diff --git a/lib/index.js b/lib/index.js
index 1536cc2..4134cdb 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,14 +1,15 @@
'use strict';
var parse = require('./parse')
-var element = require('./element')
-var Element = element.Element
-var DOMElement = require('./dom-element')
+var Parser = require('./Parser')
+var escape = require('./escape')
+var Element = require('./Element')
+var DOMElement = require('./DOMElement')
/**
* The only (relevant) data structure
*/
-exports.Element = DOMElement
+exports.Element = Element
exports.createElement = Element.createElement
exports.DOMElement = DOMElement
@@ -17,16 +18,11 @@ exports.createDOMElement = DOMElement.createElement
/**
* Helper
*/
-exports.escapeXml = element.escapeXml
+exports.escapeXML = escape.escapeXML
+exports.escapeXMLText = escape.escapeXMLText
/**
- * DOM parser interface
+ * parser interface
*/
-exports.parse = parse.parse
-exports.Parser = parse.Parser
-
-/**
- * SAX parser interface
- */
-exports.availableSaxParsers = parse.availableSaxParsers
-exports.bestSaxParser = parse.bestSaxParser
+exports.Parser = Parser
+exports.parse = parse
diff --git a/lib/parse.js b/lib/parse.js
index aa6ee21..3722dd6 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -1,101 +1,9 @@
'use strict';
-var events = require('events')
- , util = require('util')
- , DOMElement = require('./dom-element')
+var Parser = require('./Parser')
-
-exports.availableSaxParsers = []
-exports.bestSaxParser = null
-
-var saxParsers = [
- './sax/sax_expat.js',
- './sax/sax_ltx.js',
- /*'./sax_easysax.js', './sax_node-xml.js',*/
- './sax/sax_saxjs.js'
-]
-
-saxParsers.forEach(function(modName) {
- var mod
- try {
- mod = require(modName)
- } catch (e) {
- /* Silently missing libraries drop for debug:
- console.error(e.stack || e)
- */
- }
- if (mod) {
- exports.availableSaxParsers.push(mod)
- if (!exports.bestSaxParser) {
- exports.bestSaxParser = mod
- }
- }
-})
-
-exports.Parser = function(saxParser) {
- events.EventEmitter.call(this)
- var self = this
-
- var ParserMod = saxParser || exports.bestSaxParser
- if (!ParserMod) {
- throw new Error('No SAX parser available')
- }
- this.parser = new ParserMod()
-
- var el
- this.parser.addListener('startElement', function(name, attrs) {
- var child = new DOMElement(name, attrs)
- if (!el) {
- el = child
- } else {
- el = el.cnode(child)
- }
- })
- this.parser.addListener('endElement', function(name) {
- /* jshint -W035 */
- if (!el) {
- /* Err */
- } else if (name === el.name) {
- if (el.parent) {
- el = el.parent
- } else if (!self.tree) {
- self.tree = el
- el = undefined
- }
- }
- /* jshint +W035 */
- })
- this.parser.addListener('text', function(str) {
- if (el) {
- el.t(str)
- }
- })
- this.parser.addListener('error', function(e) {
- self.error = e
- self.emit('error', e)
- })
-}
-
-util.inherits(exports.Parser, events.EventEmitter)
-
-exports.Parser.prototype.write = function(data) {
- this.parser.write(data)
-}
-
-exports.Parser.prototype.end = function(data) {
- this.parser.end(data)
-
- if (!this.error) {
- if (this.tree) {
- this.emit('tree', this.tree)
- } else {
- this.emit('error', new Error('Incomplete document'))
- }
- }
-}
-
-exports.parse = function(data, saxParser) {
- var p = new exports.Parser(saxParser)
+module.exports = function parse(data, options) {
+ var p = new Parser(options)
var result = null
, error = null
diff --git a/lib/sax/sax_easysax.js b/lib/parsers/easysax.js
similarity index 100%
rename from lib/sax/sax_easysax.js
rename to lib/parsers/easysax.js
diff --git a/lib/parsers/index.js b/lib/parsers/index.js
new file mode 100644
index 0000000..e1c9ef8
--- /dev/null
+++ b/lib/parsers/index.js
@@ -0,0 +1,11 @@
+'use strict';
+
+module.exports = [
+ // 'easysax',
+ 'ltx',
+ 'node-expat',
+ 'node-xml',
+ 'sax'
+].map(function(name) {
+ return require('./' + name)
+})
diff --git a/lib/sax/sax_ltx.js b/lib/parsers/ltx.js
similarity index 100%
rename from lib/sax/sax_ltx.js
rename to lib/parsers/ltx.js
diff --git a/lib/sax/sax_expat.js b/lib/parsers/node-expat.js
similarity index 100%
rename from lib/sax/sax_expat.js
rename to lib/parsers/node-expat.js
diff --git a/lib/sax/sax_node-xml.js b/lib/parsers/node-xml.js
similarity index 100%
rename from lib/sax/sax_node-xml.js
rename to lib/parsers/node-xml.js
diff --git a/lib/sax/sax_saxjs.js b/lib/parsers/sax.js
similarity index 100%
rename from lib/sax/sax_saxjs.js
rename to lib/parsers/sax.js
diff --git a/ltx-browser.js b/ltx-browser.js
deleted file mode 100644
index 2677c6e..0000000
--- a/ltx-browser.js
+++ /dev/null
@@ -1,1884 +0,0 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-'use strict';
-
-var util = require('util')
- , Element = require('./element').Element
-
-function DOMElement(name, attrs) {
- Element.call(this, name, attrs)
-
- this.nodeType = 1
- this.nodeName = this.localName
-}
-
-util.inherits(DOMElement, Element)
-
-DOMElement.prototype._getElement = function(name, attrs) {
- var element = new DOMElement(name, attrs)
- return element
-}
-
-Object.defineProperty(DOMElement.prototype, 'localName', {
- get: function () {
- return this.getName()
- }
-})
-
-Object.defineProperty(DOMElement.prototype, 'namespaceURI', {
- get: function () {
- return this.getNS()
- }
-})
-
-Object.defineProperty(DOMElement.prototype, 'parentNode', {
- get: function () {
- return this.parent
- }
-})
-
-Object.defineProperty(DOMElement.prototype, 'childNodes', {
- get: function () {
- return this.children
- }
-})
-
-Object.defineProperty(DOMElement.prototype, 'textContent', {
- get: function () {
- return this.getText()
- },
- set: function (value) {
- this.children.push(value)
- }
-})
-
-DOMElement.prototype.getElementsByTagName = function (name) {
- return this.getChildren(name)
-}
-
-DOMElement.prototype.getAttribute = function (name) {
- return this.getAttr(name)
-}
-
-DOMElement.prototype.setAttribute = function (name, value) {
- this.attr(name, value)
-}
-
-DOMElement.prototype.getAttributeNS = function (ns, name) {
- if (ns === 'http://www.w3.org/XML/1998/namespace') {
- return this.getAttr(['xml', name].join(':'))
- }
- return this.getAttr(name, ns)
-}
-
-DOMElement.prototype.setAttributeNS = function (ns, name, value) {
- var prefix
- if (ns === 'http://www.w3.org/XML/1998/namespace') {
- prefix = 'xml'
- } else {
- var nss = this.getXmlns()
- prefix = nss[ns] || ''
- }
- if (prefix) {
- this.attr([prefix, name].join(':'), value)
- }
-}
-
-DOMElement.prototype.removeAttribute = function (name) {
- this.attr(name, null)
-}
-
-DOMElement.prototype.removeAttributeNS = function (ns, name) {
- var prefix
- if (ns === 'http://www.w3.org/XML/1998/namespace') {
- prefix = 'xml'
- } else {
- var nss = this.getXmlns()
- prefix = nss[ns] || ''
- }
- if (prefix) {
- this.attr([prefix, name].join(':'), null)
- }
-}
-
-DOMElement.prototype.appendChild = function (el) {
- this.cnode(el)
-}
-
-DOMElement.prototype.removeChild = function (el) {
- this.remove(el)
-}
-
-DOMElement.createElement = function(name, attrs /*, child1, child2, ...*/) {
- var el = new DOMElement(name, attrs)
-
- var children = Array.prototype.slice.call(arguments, 2)
-
- children.forEach(function(child) {
- el.appendChild(child)
- })
- return el
-}
-
-
-module.exports = DOMElement
-
-},{"./element":2,"util":11}],2:[function(require,module,exports){
-'use strict';
-
-/**
- * This cheap replica of DOM/Builder puts me to shame :-)
- *
- * Attributes are in the element.attrs object. Children is a list of
- * either other Elements or Strings for text content.
- **/
-function Element(name, attrs) {
- this.name = name
- this.parent = null
- this.children = []
- this.setAttrs(attrs)
-}
-
-/*** Accessors ***/
-
-/**
- * if (element.is('message', 'jabber:client')) ...
- **/
-Element.prototype.is = function(name, xmlns) {
- return (this.getName() === name) &&
- (!xmlns || (this.getNS() === xmlns))
-}
-
-/* without prefix */
-Element.prototype.getName = function() {
- if (this.name.indexOf(':') >= 0) {
- return this.name.substr(this.name.indexOf(':') + 1)
- } else {
- return this.name
- }
-}
-
-/**
- * retrieves the namespace of the current element, upwards recursively
- **/
-Element.prototype.getNS = function() {
- if (this.name.indexOf(':') >= 0) {
- var prefix = this.name.substr(0, this.name.indexOf(':'))
- return this.findNS(prefix)
- }
- return this.findNS()
-}
-
-/**
- * find the namespace to the given prefix, upwards recursively
- **/
-Element.prototype.findNS = function(prefix) {
- if (!prefix) {
- /* default namespace */
- if (this.attrs.xmlns) {
- return this.attrs.xmlns
- } else if (this.parent) {
- return this.parent.findNS()
- }
- } else {
- /* prefixed namespace */
- var attr = 'xmlns:' + prefix
- if (this.attrs[attr]) {
- return this.attrs[attr]
- } else if (this.parent) {
- return this.parent.findNS(prefix)
- }
- }
-}
-
-/**
- * Recursiverly gets all xmlns defined, in the form of {url:prefix}
- **/
-Element.prototype.getXmlns = function() {
- var namespaces = {}
-
- if (this.parent) {
- namespaces = this.parent.getXmlns()
- }
-
- for (var attr in this.attrs) {
- var m = attr.match('xmlns:?(.*)')
- if (this.attrs.hasOwnProperty(attr) && m) {
- namespaces[this.attrs[attr]] = m[1]
- }
- }
- return namespaces
-}
-
-Element.prototype.setAttrs = function(attrs) {
- this.attrs = {}
-
- if (typeof attrs === 'string')
- this.attrs.xmlns = attrs
- else if (attrs) {
- Object.keys(attrs).forEach(function(key) {
- this.attrs[key] = attrs[key]
- }, this)
- }
-}
-
-/**
- * xmlns can be null, returns the matching attribute.
- **/
-Element.prototype.getAttr = function(name, xmlns) {
- if (!xmlns) {
- return this.attrs[name]
- }
-
- var namespaces = this.getXmlns()
-
- if (!namespaces[xmlns]) {
- return null
- }
-
- return this.attrs[[namespaces[xmlns], name].join(':')]
-}
-
-/**
- * xmlns can be null
- **/
-Element.prototype.getChild = function(name, xmlns) {
- return this.getChildren(name, xmlns)[0]
-}
-
-/**
- * xmlns can be null
- **/
-Element.prototype.getChildren = function(name, xmlns) {
- var result = []
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- if (child.getName &&
- (child.getName() === name) &&
- (!xmlns || (child.getNS() === xmlns)))
- result.push(child)
- }
- return result
-}
-
-/**
- * xmlns and recursive can be null
- **/
-Element.prototype.getChildByAttr = function(attr, val, xmlns, recursive) {
- return this.getChildrenByAttr(attr, val, xmlns, recursive)[0]
-}
-
-/**
- * xmlns and recursive can be null
- **/
-Element.prototype.getChildrenByAttr = function(attr, val, xmlns, recursive) {
- var result = []
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- if (child.attrs &&
- (child.attrs[attr] === val) &&
- (!xmlns || (child.getNS() === xmlns)))
- result.push(child)
- if (recursive && child.getChildrenByAttr) {
- result.push(child.getChildrenByAttr(attr, val, xmlns, true))
- }
- }
- if (recursive) {
- result = [].concat.apply([], result)
- }
- return result
-}
-
-Element.prototype.getChildrenByFilter = function(filter, recursive) {
- var result = []
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- if (filter(child))
- result.push(child)
- if (recursive && child.getChildrenByFilter){
- result.push(child.getChildrenByFilter(filter, true))
- }
- }
- if (recursive) {
- result = [].concat.apply([], result)
- }
- return result
-}
-
-Element.prototype.getText = function() {
- var text = ''
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- if ((typeof child === 'string') || (typeof child === 'number')) {
- text += child
- }
- }
- return text
-}
-
-Element.prototype.getChildText = function(name, xmlns) {
- var child = this.getChild(name, xmlns)
- return child ? child.getText() : null
-}
-
-/**
- * Return all direct descendents that are Elements.
- * This differs from `getChildren` in that it will exclude text nodes,
- * processing instructions, etc.
- */
-Element.prototype.getChildElements = function() {
- return this.getChildrenByFilter(function(child) {
- return child instanceof Element
- })
-}
-
-/*** Builder ***/
-
-/** returns uppermost parent */
-Element.prototype.root = function() {
- if (this.parent) {
- return this.parent.root()
- }
- return this
-}
-Element.prototype.tree = Element.prototype.root
-
-/** just parent or itself */
-Element.prototype.up = function() {
- if (this.parent) {
- return this.parent
- }
- return this
-}
-
-Element.prototype._getElement = function(name, attrs) {
- var element = new Element(name, attrs)
- return element
-}
-
-/** create child node and return it */
-Element.prototype.c = function(name, attrs) {
- return this.cnode(this._getElement(name, attrs))
-}
-
-Element.prototype.cnode = function(child) {
- this.children.push(child)
- if (typeof child === 'object') {
- child.parent = this
- }
- return child
-}
-
-/** add text node and return element */
-Element.prototype.t = function(text) {
- this.children.push(text)
- return this
-}
-
-/*** Manipulation ***/
-
-/**
- * Either:
- * el.remove(childEl)
- * el.remove('author', 'urn:...')
- */
-Element.prototype.remove = function(el, xmlns) {
- var filter
- if (typeof el === 'string') {
- /* 1st parameter is tag name */
- filter = function(child) {
- return !(child.is &&
- child.is(el, xmlns))
- }
- } else {
- /* 1st parameter is element */
- filter = function(child) {
- return child !== el
- }
- }
-
- this.children = this.children.filter(filter)
-
- return this
-}
-
-/**
- * To use in case you want the same XML data for separate uses.
- * Please refrain from this practise unless you know what you are
- * doing. Building XML with ltx is easy!
- */
-Element.prototype.clone = function() {
- var clone = this._getElement(this.name, this.attrs)
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- clone.cnode(child.clone ? child.clone() : child)
- }
- return clone
-}
-
-Element.prototype.text = function(val) {
- if (val && this.children.length === 1) {
- this.children[0] = val
- return this
- }
- return this.getText()
-}
-
-Element.prototype.attr = function(attr, val) {
- if (((typeof val !== 'undefined') || (val === null))) {
- if (!this.attrs) {
- this.attrs = {}
- }
- this.attrs[attr] = val
- return this
- }
- return this.attrs[attr]
-}
-
-/*** Serialization ***/
-
-Element.prototype.toString = function() {
- var s = ''
- this.write(function(c) {
- s += c
- })
- return s
-}
-
-Element.prototype.toJSON = function() {
- return {
- name: this.name,
- attrs: this.attrs,
- children: this.children.map(function(child) {
- return child && child.toJSON ? child.toJSON() : child
- })
- }
-}
-
-Element.prototype._addChildren = function(writer) {
- writer('>')
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i]
- /* Skip null/undefined */
- if (child || (child === 0)) {
- if (child.write) {
- child.write(writer)
- } else if (typeof child === 'string') {
- writer(escapeXmlText(child))
- } else if (child.toString) {
- writer(escapeXmlText(child.toString(10)))
- }
- }
- }
- writer('</')
- writer(this.name)
- writer('>')
-}
-
-Element.prototype.write = function(writer) {
- writer('<')
- writer(this.name)
- for (var k in this.attrs) {
- var v = this.attrs[k]
- if (v || (v === '') || (v === 0)) {
- writer(' ')
- writer(k)
- writer('="')
- if (typeof v !== 'string') {
- v = v.toString(10)
- }
- writer(escapeXml(v))
- writer('"')
- }
- }
- if (this.children.length === 0) {
- writer('/>')
- } else {
- this._addChildren(writer)
- }
-}
-
-Element.createElement = function(name, attrs /*, child1, child2, ...*/) {
- var el = new Element(name, attrs)
-
- var children = Array.prototype.slice.call(arguments, 2)
-
- children.forEach(function(child) {
- el.cnode(child)
- })
- return el
-}
-
-
-function escapeXml(s) {
- return s.
- replace(/\&/g, '&').
- replace(/</g, '<').
- replace(/>/g, '>').
- replace(/"/g, '"').
- replace(/"/g, ''')
-}
-
-function escapeXmlText(s) {
- return s.
- replace(/\&/g, '&').
- replace(/</g, '<').
- replace(/>/g, '>')
-}
-
-exports.Element = Element
-exports.escapeXml = escapeXml
-
-},{}],3:[function(require,module,exports){
-'use strict';
-
-/* Cause browserify to bundle SAX parsers: */
-var parse = require('./parse')
-
-parse.availableSaxParsers.push(parse.bestSaxParser = require('./sax/sax_ltx'))
-
-/* SHIM */
-module.exports = require('./index')
-
-},{"./index":4,"./parse":5,"./sax/sax_ltx":6}],4:[function(require,module,exports){
-'use strict';
-
-var parse = require('./parse')
-var element = require('./element')
-var Element = element.Element
-var DOMElement = require('./dom-element')
-
-/**
- * The only (relevant) data structure
- */
-exports.Element = DOMElement
-exports.createElement = Element.createElement
-
-exports.DOMElement = DOMElement
-exports.createDOMElement = DOMElement.createElement
-
-/**
- * Helper
- */
-exports.escapeXml = element.escapeXml
-
-/**
- * DOM parser interface
- */
-exports.parse = parse.parse
-exports.Parser = parse.Parser
-
-/**
- * SAX parser interface
- */
-exports.availableSaxParsers = parse.availableSaxParsers
-exports.bestSaxParser = parse.bestSaxParser
-
-},{"./dom-element":1,"./element":2,"./parse":5}],5:[function(require,module,exports){
-'use strict';
-
-var events = require('events')
- , util = require('util')
- , DOMElement = require('./dom-element')
-
-
-exports.availableSaxParsers = []
-exports.bestSaxParser = null
-
-var saxParsers = [
- './sax/sax_expat.js',
- './sax/sax_ltx.js',
- /*'./sax_easysax.js', './sax_node-xml.js',*/
- './sax/sax_saxjs.js'
-]
-
-saxParsers.forEach(function(modName) {
- var mod
- try {
- mod = require(modName)
- } catch (e) {
- /* Silently missing libraries drop for debug:
- console.error(e.stack || e)
- */
- }
- if (mod) {
- exports.availableSaxParsers.push(mod)
- if (!exports.bestSaxParser) {
- exports.bestSaxParser = mod
- }
- }
-})
-
-exports.Parser = function(saxParser) {
- events.EventEmitter.call(this)
- var self = this
-
- var ParserMod = saxParser || exports.bestSaxParser
- if (!ParserMod) {
- throw new Error('No SAX parser available')
- }
- this.parser = new ParserMod()
-
- var el
- this.parser.addListener('startElement', function(name, attrs) {
- var child = new DOMElement(name, attrs)
- if (!el) {
- el = child
- } else {
- el = el.cnode(child)
- }
- })
- this.parser.addListener('endElement', function(name) {
- /* jshint -W035 */
- if (!el) {
- /* Err */
- } else if (name === el.name) {
- if (el.parent) {
- el = el.parent
- } else if (!self.tree) {
- self.tree = el
- el = undefined
- }
- }
- /* jshint +W035 */
- })
- this.parser.addListener('text', function(str) {
- if (el) {
- el.t(str)
- }
- })
- this.parser.addListener('error', function(e) {
- self.error = e
- self.emit('error', e)
- })
-}
-
-util.inherits(exports.Parser, events.EventEmitter)
-
-exports.Parser.prototype.write = function(data) {
- this.parser.write(data)
-}
-
-exports.Parser.prototype.end = function(data) {
- this.parser.end(data)
-
- if (!this.error) {
- if (this.tree) {
- this.emit('tree', this.tree)
- } else {
- this.emit('error', new Error('Incomplete document'))
- }
- }
-}
-
-exports.parse = function(data, saxParser) {
- var p = new exports.Parser(saxParser)
- var result = null
- , error = null
-
- p.on('tree', function(tree) {
- result = tree
- })
- p.on('error', function(e) {
- error = e
- })
-
- p.write(data)
- p.end()
-
- if (error) {
- throw error
- } else {
- return result
- }
-}
-
-},{"./dom-element":1,"events":7,"util":11}],6:[function(require,module,exports){
-'use strict';
-
-var util = require('util')
- , events = require('events')
-
-var STATE_TEXT = 0,
- STATE_IGNORE_TAG = 1,
- STATE_TAG_NAME = 2,
- STATE_TAG = 3,
- STATE_ATTR_NAME = 4,
- STATE_ATTR_EQ = 5,
- STATE_ATTR_QUOT = 6,
- STATE_ATTR_VALUE = 7
-
-var SaxLtx = module.exports = function SaxLtx() {
- events.EventEmitter.call(this)
-
- var state = STATE_TEXT, remainder
- var tagName, attrs, endTag, selfClosing, attrQuote
- var recordStart = 0
- var attrName
-
- this._handleTagOpening = function(endTag, tagName, attrs) {
- if (!endTag) {
- this.emit('startElement', tagName, attrs)
- if (selfClosing) {
- this.emit('endElement', tagName)
- }
- } else {
- this.emit('endElement', tagName)
- }
- }
-
- this.write = function(data) {
- /* jshint -W071 */
- /* jshint -W074 */
- if (typeof data !== 'string') {
- data = data.toString()
- }
- var pos = 0
-
- /* Anything from previous write()? */
- if (remainder) {
- data = remainder + data
- pos += remainder.length
- remainder = null
- }
-
- function endRecording() {
- if (typeof recordStart === 'number') {
- var recorded = data.slice(recordStart, pos)
- recordStart = undefined
- return recorded
- }
- }
-
- for(; pos < data.length; pos++) {
- var c = data.charCodeAt(pos)
- //console.log("state", state, "c", c, data[pos])
- switch(state) {
- case STATE_TEXT:
- if (c === 60 /* < */) {
- var text = endRecording()
- if (text) {
- this.emit('text', unescapeXml(text))
- }
- state = STATE_TAG_NAME
- recordStart = pos + 1
- attrs = {}
- }
- break
- case STATE_TAG_NAME:
- if (c === 47 /* / */ && recordStart === pos) {
- recordStart = pos + 1
- endTag = true
- } else if (c === 33 /* ! */ || c === 63 /* ? */) {
- recordStart = undefined
- state = STATE_IGNORE_TAG
- } else if (c <= 32 || c === 47 /* / */ || c === 62 /* > */) {
- tagName = endRecording()
- pos--
- state = STATE_TAG
- }
- break
- case STATE_IGNORE_TAG:
- if (c === 62 /* > */) {
- state = STATE_TEXT
- }
- break
- case STATE_TAG:
- if (c === 62 /* > */) {
- this._handleTagOpening(endTag, tagName, attrs)
- tagName = undefined
- attrs = undefined
- endTag = undefined
- selfClosing = undefined
- state = STATE_TEXT
- recordStart = pos + 1
- } else if (c === 47 /* / */) {
- selfClosing = true
- } else if (c > 32) {
- recordStart = pos
- state = STATE_ATTR_NAME
- }
- break
- case STATE_ATTR_NAME:
- if (c <= 32 || c === 61 /* = */) {
- attrName = endRecording()
- pos--
- state = STATE_ATTR_EQ
- }
- break
- case STATE_ATTR_EQ:
- if (c === 61 /* = */) {
- state = STATE_ATTR_QUOT
- }
- break
- case STATE_ATTR_QUOT:
- if (c === 34 /* " */ || c === 39 /* ' */) {
- attrQuote = c
- state = STATE_ATTR_VALUE
- recordStart = pos + 1
- }
- break
- case STATE_ATTR_VALUE:
- if (c === attrQuote) {
- var value = unescapeXml(endRecording())
- attrs[attrName] = value
- attrName = undefined
- state = STATE_TAG
- }
- break
- }
- }
-
- if (typeof recordStart === 'number' &&
- recordStart <= data.length) {
-
- remainder = data.slice(recordStart)
- recordStart = 0
- }
- }
-
- /*var origEmit = this.emit
- this.emit = function() {
- console.log('ltx', arguments)
- origEmit.apply(this, arguments)
- }*/
-}
-util.inherits(SaxLtx, events.EventEmitter)
-
-
-SaxLtx.prototype.end = function(data) {
- if (data) {
- this.write(data)
- }
-
- /* Uh, yeah */
- this.write = function() {}
-}
-
-function unescapeXml(s) {
- return s.
- replace(/\&(amp|#38);/g, '&').
- replace(/\&(lt|#60);/g, '<').
- replace(/\&(gt|#62);/g, '>').
- replace(/\&(quot|#34);/g, '"').
- replace(/\&(apos|#39);/g, '\'').
- replace(/\&(nbsp|#160);/g, '\n')
-}
-
-},{"events":7,"util":11}],7:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
- this._events = this._events || {};
- this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
- this._maxListeners = n;
- return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
-
- if (!this._events)
- this._events = {};
-
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
- er = arguments[1];
- if (er instanceof Error) {
- throw er; // Unhandled 'error' event
- }
- throw TypeError('Uncaught, unspecified "error" event.');
- }
- }
-
- handler = this._events[type];
-
- if (isUndefined(handler))
- return false;
-
- if (isFunction(handler)) {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- len = arguments.length;
- args = new Array(len - 1);
- for (i = 1; i < len; i++)
- args[i - 1] = arguments[i];
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- len = arguments.length;
- args = new Array(len - 1);
- for (i = 1; i < len; i++)
- args[i - 1] = arguments[i];
-
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
- }
-
- return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
- var m;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events)
- this._events = {};
-
- // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(listener.listener) ?
- listener.listener : listener);
-
- if (!this._events[type])
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
-
- // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- var m;
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
- }
- }
- }
-
- return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
-
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
- }
- }
-
- g.listener = listener;
- this.on(type, g);
-
- return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events || !this._events[type])
- return this;
-
- list = this._events[type];
- length = list.length;
- position = -1;
-
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
- position = i;
- break;
- }
- }
-
- if (position < 0)
- return this;
-
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
-
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
- }
-
- return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
-
- if (!this._events)
- return this;
-
- // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
- return this;
- }
-
- // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
- }
-
- listeners = this._events[type];
-
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else {
- // LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
- }
- delete this._events[type];
-
- return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
- var ret;
- if (!this._events || !this._events[type])
- ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
- else
- ret = this._events[type].slice();
- return ret;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
- var ret;
- if (!emitter._events || !emitter._events[type])
- ret = 0;
- else if (isFunction(emitter._events[type]))
- ret = 1;
- else
- ret = emitter._events[type].length;
- return ret;
-};
-
-function isFunction(arg) {
- return typeof arg === 'function';
-}
-
-function isNumber(arg) {
- return typeof arg === 'number';
-}
-
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
- return arg === void 0;
-}
-
-},{}],8:[function(require,module,exports){
-if (typeof Object.create === 'function') {
- // implementation from standard node.js 'util' module
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- };
-} else {
- // old school shim for old browsers
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- var TempCtor = function () {}
- TempCtor.prototype = superCtor.prototype
- ctor.prototype = new TempCtor()
- ctor.prototype.constructor = ctor
- }
-}
-
-},{}],9:[function(require,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
-}
-
-function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = setTimeout(cleanUpNextTick);
- draining = true;
-
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- currentQueue[queueIndex].run();
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- clearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- setTimeout(drainQueue, 0);
- }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
- this.fun = fun;
- this.array = array;
-}
-Item.prototype.run = function () {
- this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-
-process.binding = function (name) {
- throw new Error('process.binding is not supported');
-};
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-},{}],10:[function(require,module,exports){
-module.exports = function isBuffer(arg) {
- return arg && typeof arg === 'object'
- && typeof arg.copy === 'function'
- && typeof arg.fill === 'function'
- && typeof arg.readUInt8 === 'function';
-}
-},{}],11:[function(require,module,exports){
-(function (process,global){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var formatRegExp = /%[sdj%]/g;
-exports.format = function(f) {
- if (!isString(f)) {
- var objects = [];
- for (var i = 0; i < arguments.length; i++) {
- objects.push(inspect(arguments[i]));
- }
- return objects.join(' ');
- }
-
- var i = 1;
- var args = arguments;
- var len = args.length;
- var str = String(f).replace(formatRegExp, function(x) {
- if (x === '%%') return '%';
- if (i >= len) return x;
- switch (x) {
- case '%s': return String(args[i++]);
- case '%d': return Number(args[i++]);
- case '%j':
- try {
- return JSON.stringify(args[i++]);
- } catch (_) {
- return '[Circular]';
- }
- default:
- return x;
- }
- });
- for (var x = args[i]; i < len; x = args[++i]) {
- if (isNull(x) || !isObject(x)) {
- str += ' ' + x;
- } else {
- str += ' ' + inspect(x);
- }
- }
- return str;
-};
-
-
-// Mark that a method should not be used.
-// Returns a modified function which warns once by default.
-// If --no-deprecation is set, then it is a no-op.
-exports.deprecate = function(fn, msg) {
- // Allow for deprecating things in the process of starting up.
- if (isUndefined(global.process)) {
- return function() {
- return exports.deprecate(fn, msg).apply(this, arguments);
- };
- }
-
- if (process.noDeprecation === true) {
- return fn;
- }
-
- var warned = false;
- function deprecated() {
- if (!warned) {
- if (process.throwDeprecation) {
- throw new Error(msg);
- } else if (process.traceDeprecation) {
- console.trace(msg);
- } else {
- console.error(msg);
- }
- warned = true;
- }
- return fn.apply(this, arguments);
- }
-
- return deprecated;
-};
-
-
-var debugs = {};
-var debugEnviron;
-exports.debuglog = function(set) {
- if (isUndefined(debugEnviron))
- debugEnviron = process.env.NODE_DEBUG || '';
- set = set.toUpperCase();
- if (!debugs[set]) {
- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
- var pid = process.pid;
- debugs[set] = function() {
- var msg = exports.format.apply(exports, arguments);
- console.error('%s %d: %s', set, pid, msg);
- };
- } else {
- debugs[set] = function() {};
- }
- }
- return debugs[set];
-};
-
-
-/**
- * Echos the value of a value. Trys to print the value out
- * in the best way possible given the different types.
- *
- * @param {Object} obj The object to print out.
- * @param {Object} opts Optional options object that alters the output.
- */
-/* legacy: obj, showHidden, depth, colors*/
-function inspect(obj, opts) {
- // default options
- var ctx = {
- seen: [],
- stylize: stylizeNoColor
- };
- // legacy...
- if (arguments.length >= 3) ctx.depth = arguments[2];
- if (arguments.length >= 4) ctx.colors = arguments[3];
- if (isBoolean(opts)) {
- // legacy...
- ctx.showHidden = opts;
- } else if (opts) {
- // got an "options" object
- exports._extend(ctx, opts);
- }
- // set default options
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
- if (isUndefined(ctx.depth)) ctx.depth = 2;
- if (isUndefined(ctx.colors)) ctx.colors = false;
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
- if (ctx.colors) ctx.stylize = stylizeWithColor;
- return formatValue(ctx, obj, ctx.depth);
-}
-exports.inspect = inspect;
-
-
-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
-inspect.colors = {
- 'bold' : [1, 22],
- 'italic' : [3, 23],
- 'underline' : [4, 24],
- 'inverse' : [7, 27],
- 'white' : [37, 39],
- 'grey' : [90, 39],
- 'black' : [30, 39],
- 'blue' : [34, 39],
- 'cyan' : [36, 39],
- 'green' : [32, 39],
- 'magenta' : [35, 39],
- 'red' : [31, 39],
- 'yellow' : [33, 39]
-};
-
-// Don't use 'blue' not visible on cmd.exe
-inspect.styles = {
- 'special': 'cyan',
- 'number': 'yellow',
- 'boolean': 'yellow',
- 'undefined': 'grey',
- 'null': 'bold',
- 'string': 'green',
- 'date': 'magenta',
- // "name": intentionally not styling
- 'regexp': 'red'
-};
-
-
-function stylizeWithColor(str, styleType) {
- var style = inspect.styles[styleType];
-
- if (style) {
- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
- '\u001b[' + inspect.colors[style][1] + 'm';
- } else {
- return str;
- }
-}
-
-
-function stylizeNoColor(str, styleType) {
- return str;
-}
-
-
-function arrayToHash(array) {
- var hash = {};
-
- array.forEach(function(val, idx) {
- hash[val] = true;
- });
-
- return hash;
-}
-
-
-function formatValue(ctx, value, recurseTimes) {
- // Provide a hook for user-specified inspect functions.
- // Check that value is an object with an inspect function on it
- if (ctx.customInspect &&
- value &&
- isFunction(value.inspect) &&
- // Filter out the util module, it's inspect function is special
- value.inspect !== exports.inspect &&
- // Also filter out any prototype objects using the circular check.
- !(value.constructor && value.constructor.prototype === value)) {
- var ret = value.inspect(recurseTimes, ctx);
- if (!isString(ret)) {
- ret = formatValue(ctx, ret, recurseTimes);
- }
- return ret;
- }
-
- // Primitive types cannot have properties
- var primitive = formatPrimitive(ctx, value);
- if (primitive) {
- return primitive;
- }
-
- // Look up the keys of the object.
- var keys = Object.keys(value);
- var visibleKeys = arrayToHash(keys);
-
- if (ctx.showHidden) {
- keys = Object.getOwnPropertyNames(value);
- }
-
- // IE doesn't make error fields non-enumerable
- // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
- if (isError(value)
- && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
- return formatError(value);
- }
-
- // Some type of object without properties can be shortcutted.
- if (keys.length === 0) {
- if (isFunction(value)) {
- var name = value.name ? ': ' + value.name : '';
- return ctx.stylize('[Function' + name + ']', 'special');
- }
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- }
- if (isDate(value)) {
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
- }
- if (isError(value)) {
- return formatError(value);
- }
- }
-
- var base = '', array = false, braces = ['{', '}'];
-
- // Make Array say that they are Array
- if (isArray(value)) {
- array = true;
- braces = ['[', ']'];
- }
-
- // Make functions say that they are functions
- if (isFunction(value)) {
- var n = value.name ? ': ' + value.name : '';
- base = ' [Function' + n + ']';
- }
-
- // Make RegExps say that they are RegExps
- if (isRegExp(value)) {
- base = ' ' + RegExp.prototype.toString.call(value);
- }
-
- // Make dates with properties first say the date
- if (isDate(value)) {
- base = ' ' + Date.prototype.toUTCString.call(value);
- }
-
- // Make error with message first say the error
- if (isError(value)) {
- base = ' ' + formatError(value);
- }
-
- if (keys.length === 0 && (!array || value.length == 0)) {
- return braces[0] + base + braces[1];
- }
-
- if (recurseTimes < 0) {
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- } else {
- return ctx.stylize('[Object]', 'special');
- }
- }
-
- ctx.seen.push(value);
-
- var output;
- if (array) {
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
- } else {
- output = keys.map(function(key) {
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
- });
- }
-
- ctx.seen.pop();
-
- return reduceToSingleString(output, base, braces);
-}
-
-
-function formatPrimitive(ctx, value) {
- if (isUndefined(value))
- return ctx.stylize('undefined', 'undefined');
- if (isString(value)) {
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
- .replace(/'/g, "\\'")
- .replace(/\\"/g, '"') + '\'';
- return ctx.stylize(simple, 'string');
- }
- if (isNumber(value))
- return ctx.stylize('' + value, 'number');
- if (isBoolean(value))
- return ctx.stylize('' + value, 'boolean');
- // For some reason typeof null is "object", so special case here.
- if (isNull(value))
- return ctx.stylize('null', 'null');
-}
-
-
-function formatError(value) {
- return '[' + Error.prototype.toString.call(value) + ']';
-}
-
-
-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
- var output = [];
- for (var i = 0, l = value.length; i < l; ++i) {
- if (hasOwnProperty(value, String(i))) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- String(i), true));
- } else {
- output.push('');
- }
- }
- keys.forEach(function(key) {
- if (!key.match(/^\d+$/)) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- key, true));
- }
- });
- return output;
-}
-
-
-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
- var name, str, desc;
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
- if (desc.get) {
- if (desc.set) {
- str = ctx.stylize('[Getter/Setter]', 'special');
- } else {
- str = ctx.stylize('[Getter]', 'special');
- }
- } else {
- if (desc.set) {
- str = ctx.stylize('[Setter]', 'special');
- }
- }
- if (!hasOwnProperty(visibleKeys, key)) {
- name = '[' + key + ']';
- }
- if (!str) {
- if (ctx.seen.indexOf(desc.value) < 0) {
- if (isNull(recurseTimes)) {
- str = formatValue(ctx, desc.value, null);
- } else {
- str = formatValue(ctx, desc.value, recurseTimes - 1);
- }
- if (str.indexOf('\n') > -1) {
- if (array) {
- str = str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n').substr(2);
- } else {
- str = '\n' + str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n');
- }
- }
- } else {
- str = ctx.stylize('[Circular]', 'special');
- }
- }
- if (isUndefined(name)) {
- if (array && key.match(/^\d+$/)) {
- return str;
- }
- name = JSON.stringify('' + key);
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
- name = name.substr(1, name.length - 2);
- name = ctx.stylize(name, 'name');
- } else {
- name = name.replace(/'/g, "\\'")
- .replace(/\\"/g, '"')
- .replace(/(^"|"$)/g, "'");
- name = ctx.stylize(name, 'string');
- }
- }
-
- return name + ': ' + str;
-}
-
-
-function reduceToSingleString(output, base, braces) {
- var numLinesEst = 0;
- var length = output.reduce(function(prev, cur) {
- numLinesEst++;
- if (cur.indexOf('\n') >= 0) numLinesEst++;
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
- }, 0);
-
- if (length > 60) {
- return braces[0] +
- (base === '' ? '' : base + '\n ') +
- ' ' +
- output.join(',\n ') +
- ' ' +
- braces[1];
- }
-
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
-}
-
-
-// NOTE: These type checking functions intentionally don't use `instanceof`
-// because it is fragile and can be easily faked with `Object.create()`.
-function isArray(ar) {
- return Array.isArray(ar);
-}
-exports.isArray = isArray;
-
-function isBoolean(arg) {
- return typeof arg === 'boolean';
-}
-exports.isBoolean = isBoolean;
-
-function isNull(arg) {
- return arg === null;
-}
-exports.isNull = isNull;
-
-function isNullOrUndefined(arg) {
- return arg == null;
-}
-exports.isNullOrUndefined = isNullOrUndefined;
-
-function isNumber(arg) {
- return typeof arg === 'number';
-}
-exports.isNumber = isNumber;
-
-function isString(arg) {
- return typeof arg === 'string';
-}
-exports.isString = isString;
-
-function isSymbol(arg) {
- return typeof arg === 'symbol';
-}
-exports.isSymbol = isSymbol;
-
-function isUndefined(arg) {
- return arg === void 0;
-}
-exports.isUndefined = isUndefined;
-
-function isRegExp(re) {
- return isObject(re) && objectToString(re) === '[object RegExp]';
-}
-exports.isRegExp = isRegExp;
-
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
-}
-exports.isObject = isObject;
-
-function isDate(d) {
- return isObject(d) && objectToString(d) === '[object Date]';
-}
-exports.isDate = isDate;
-
-function isError(e) {
- return isObject(e) &&
- (objectToString(e) === '[object Error]' || e instanceof Error);
-}
-exports.isError = isError;
-
-function isFunction(arg) {
- return typeof arg === 'function';
-}
-exports.isFunction = isFunction;
-
-function isPrimitive(arg) {
- return arg === null ||
- typeof arg === 'boolean' ||
- typeof arg === 'number' ||
- typeof arg === 'string' ||
- typeof arg === 'symbol' || // ES6 symbol
- typeof arg === 'undefined';
-}
-exports.isPrimitive = isPrimitive;
-
-exports.isBuffer = require('./support/isBuffer');
-
-function objectToString(o) {
- return Object.prototype.toString.call(o);
-}
-
-
-function pad(n) {
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
-}
-
-
-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec'];
-
-// 26 Feb 16:19:34
-function timestamp() {
- var d = new Date();
- var time = [pad(d.getHours()),
- pad(d.getMinutes()),
- pad(d.getSeconds())].join(':');
- return [d.getDate(), months[d.getMonth()], time].join(' ');
-}
-
-
-// log is just a thin wrapper to console.log that prepends a timestamp
-exports.log = function() {
- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
-};
-
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be rewritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- * prototype.
- * @param {function} superCtor Constructor function to inherit prototype from.
- */
-exports.inherits = require('inherits');
-
-exports._extend = function(origin, add) {
- // Don't do anything if add isn't an object
- if (!add || !isObject(add)) return origin;
-
- var keys = Object.keys(add);
- var i = keys.length;
- while (i--) {
- origin[keys[i]] = add[keys[i]];
- }
- return origin;
-};
-
-function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-}
-
-}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./support/isBuffer":10,"_process":9,"inherits":8}]},{},[3]);
diff --git a/package.json b/package.json
index 575437d..462a3d6 100644
--- a/package.json
+++ b/package.json
@@ -31,9 +31,7 @@
"license": "MIT",
"engine": "node",
"devDependencies": {
- "sax": "^1.1.1",
- "node-expat": "^2.3.10",
- "Strophe.js": "https://github.com/metajack/strophejs/tarball/master",
+ "benchmark": "^1.0.0",
"easysax": "^0.1.14",
"grunt": "^0.4.5",
"grunt-browserify": "^4.0.1",
@@ -41,9 +39,9 @@
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-jshint": "^0.11.3",
"grunt-vows": "^0.4.2",
+ "microtime": "^2.0.0",
"node-expat": "^2.3.9",
"node-xml": "^1.0.2",
- "request-animation-frame": "^0.1.1",
"sax": "^1.1.2",
"vows": "^0.8.1"
},
diff --git a/test/dom-element-test.js b/test/dom-element-test.js
index 59f8c6c..6ef4202 100644
--- a/test/dom-element-test.js
+++ b/test/dom-element-test.js
@@ -2,11 +2,12 @@
var vows = require('vows')
, assert = require('assert')
- , ltx = require('./../lib/index')
+ , ltx = require('../lib/index')
+ , parsers = require('../lib/parsers')
-ltx.availableSaxParsers.forEach(function(saxParser) {
+parsers.forEach(function(Parser) {
var parse = function(s) {
- return ltx.parse(s, saxParser)
+ return ltx.parse(s, {Parser: Parser, Element: ltx.DOMElement})
}
vows.describe('Parsing returns DOMElement\'s').addBatch({
'DOMElement': {
@@ -15,6 +16,7 @@ ltx.availableSaxParsers.forEach(function(saxParser) {
'<p>DOM</p></body></message>'
var el = parse(stanza)
+ assert(el.getChild('body') instanceof ltx.DOMElement)
assert.equal(el.getChild('body').constructor.name, 'DOMElement')
var body = el.getChild('body')
assert.isDefined(body.localName)
diff --git a/test/element-test.js b/test/element-test.js
index c895822..a5f4721 100644
--- a/test/element-test.js
+++ b/test/element-test.js
@@ -3,7 +3,7 @@
var vows = require('vows')
, assert = require('assert')
, ltx = require('../lib/index')
- , Element = require('../lib/element').Element
+ , Element = require('../lib/Element')
vows.describe('ltx').addBatch({
'new element': {
diff --git a/test/parse-test.js b/test/parse-test.js
index 80863b6..ff723c4 100644
--- a/test/parse-test.js
+++ b/test/parse-test.js
@@ -2,13 +2,14 @@
var vows = require('vows')
, assert = require('assert')
- , ltx = require('./../lib/index')
+ , ltx = require('../lib/index')
+ , parsers = require('../lib/parsers')
-ltx.availableSaxParsers.forEach(function(SaxParser) {
+parsers.forEach(function(Parser) {
var parse = function(s) {
- return ltx.parse(s, SaxParser)
+ return ltx.parse(s, {Parser: Parser})
}
- vows.describe('ltx with ' + SaxParser.name).addBatch({
+ vows.describe('ltx with ' + Parser.name).addBatch({
'DOM parsing': {
'simple document': function() {
var el = parse('<root/>')
@@ -69,7 +70,7 @@ ltx.availableSaxParsers.forEach(function(SaxParser) {
'SAX parsing': {
/* jshint -W071 */
'XMPP stream': function() {
- var parser = new SaxParser()
+ var parser = new Parser()
var events = []
parser.on('startElement', function(name, attrs) {
events.push({ start: name, attrs: attrs })
@@ -112,7 +113,7 @@ ltx.availableSaxParsers.forEach(function(SaxParser) {
assert.equal(events.length, 18)
},
'bug: partial attrs': function() {
- var parser = new SaxParser()
+ var parser = new Parser()
var events = []
parser.on('startElement', function(name, attrs) {
events.push({ start: name, attrs:attrs })
diff --git a/test/unicode-test.js b/test/unicode-test.js
index 3cca616..c5865d7 100644
--- a/test/unicode-test.js
+++ b/test/unicode-test.js
@@ -2,7 +2,7 @@
var vows = require('vows')
, assert = require('assert')
- , Element = require('../lib/element').Element
+ , Element = require('../lib/Element')
vows.describe('unicode').addBatch({
'unicode forming': {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/ltx.git
More information about the Pkg-javascript-commits
mailing list