[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