aboutsummaryrefslogtreecommitdiff
path: root/node_modules/min-document
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/min-document')
-rw-r--r--node_modules/min-document/.jshintrc30
-rw-r--r--node_modules/min-document/.npmignore15
-rw-r--r--node_modules/min-document/.testem.json14
-rw-r--r--node_modules/min-document/.travis.yml6
-rw-r--r--node_modules/min-document/CONTRIBUTION.md48
-rw-r--r--node_modules/min-document/LICENCE19
-rw-r--r--node_modules/min-document/README.md43
-rw-r--r--node_modules/min-document/docs.mli156
-rw-r--r--node_modules/min-document/document.js72
-rw-r--r--node_modules/min-document/dom-comment.js19
-rw-r--r--node_modules/min-document/dom-element.js209
-rw-r--r--node_modules/min-document/dom-fragment.js28
-rw-r--r--node_modules/min-document/dom-text.js27
-rw-r--r--node_modules/min-document/event.js13
-rw-r--r--node_modules/min-document/event/add-event-listener.js17
-rw-r--r--node_modules/min-document/event/dispatch-event.js31
-rw-r--r--node_modules/min-document/event/remove-event-listener.js19
-rw-r--r--node_modules/min-document/index.js3
-rw-r--r--node_modules/min-document/package.json58
-rw-r--r--node_modules/min-document/serialize.js139
-rw-r--r--node_modules/min-document/test/cleanup.js13
-rw-r--r--node_modules/min-document/test/index.js14
-rw-r--r--node_modules/min-document/test/static/index.html11
-rw-r--r--node_modules/min-document/test/static/test-adapter.js49
-rw-r--r--node_modules/min-document/test/test-document.js564
-rw-r--r--node_modules/min-document/test/test-dom-comment.js20
-rw-r--r--node_modules/min-document/test/test-dom-element.js219
27 files changed, 1856 insertions, 0 deletions
diff --git a/node_modules/min-document/.jshintrc b/node_modules/min-document/.jshintrc
new file mode 100644
index 000000000..77887b5f0
--- /dev/null
+++ b/node_modules/min-document/.jshintrc
@@ -0,0 +1,30 @@
+{
+ "maxdepth": 4,
+ "maxstatements": 200,
+ "maxcomplexity": 12,
+ "maxlen": 80,
+ "maxparams": 5,
+
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "latedef": false,
+ "noarg": true,
+ "noempty": true,
+ "nonew": true,
+ "undef": true,
+ "unused": "vars",
+ "trailing": true,
+
+ "quotmark": true,
+ "expr": true,
+ "asi": true,
+
+ "browser": false,
+ "esnext": true,
+ "devel": false,
+ "node": false,
+ "nonstandard": false,
+
+ "predef": ["require", "module", "__dirname", "__filename"]
+}
diff --git a/node_modules/min-document/.npmignore b/node_modules/min-document/.npmignore
new file mode 100644
index 000000000..fd31f5ee6
--- /dev/null
+++ b/node_modules/min-document/.npmignore
@@ -0,0 +1,15 @@
+.DS_Store
+.monitor
+.*.swp
+.nodemonignore
+releases
+*.log
+*.err
+fleet.json
+public/browserify
+bin/*.json
+.bin
+build
+compile
+.lock-wscript
+node_modules
diff --git a/node_modules/min-document/.testem.json b/node_modules/min-document/.testem.json
new file mode 100644
index 000000000..41ab90e6a
--- /dev/null
+++ b/node_modules/min-document/.testem.json
@@ -0,0 +1,14 @@
+{
+ "launchers": {
+ "node": {
+ "command": "node ./test"
+ }
+ },
+ "src_files": [
+ "./**/*.js"
+ ],
+ "before_tests": "npm run build-test",
+ "on_exit": "rm test/static/bundle.js",
+ "test_page": "test/static/index.html",
+ "launch_in_dev": ["node", "phantomjs"]
+}
diff --git a/node_modules/min-document/.travis.yml b/node_modules/min-document/.travis.yml
new file mode 100644
index 000000000..52424f8d6
--- /dev/null
+++ b/node_modules/min-document/.travis.yml
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+ - 0.8
+ - 0.9
+ - 0.10
+script: node ./test/index.js
diff --git a/node_modules/min-document/CONTRIBUTION.md b/node_modules/min-document/CONTRIBUTION.md
new file mode 100644
index 000000000..4e78bdf74
--- /dev/null
+++ b/node_modules/min-document/CONTRIBUTION.md
@@ -0,0 +1,48 @@
+# This is an OPEN Open Source Project
+
+## What?
+
+Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
+
+## Rules
+
+There are a few basic ground-rules for contributors:
+
+ - No --force pushes or modifying the Git history in any way.
+ - Non-master branches ought to be used for ongoing work.
+ - External API changes and significant modifications ought to be subject to an internal pull-request to solicit feedback from other contributors.
+ - Internal pull-requests to solicit feedback are encouraged for any other non-trivial contribution but left to the discretion of the contributor.
+ - For significant changes wait a full 24 hours before merging so that active contributors who are distributed throughout the world have a chance to weigh in.
+ - Contributors should attempt to adhere to the prevailing code-style.
+Releases
+
+Declaring formal releases requires peer review.
+
+ - A reviewer of a pull request should recommend a new version number (patch, minor or major).
+ - Once your change is merged feel free to bump the version as recommended by the reviewer.
+ - A new version number should not be cut without peer review unless done by the project maintainer.
+
+## Want to contribute?
+
+Even though collaborators may contribute as they see fit, if you are not sure what to do, here's a suggested process:
+
+## Cutting a new version
+
+ - Get your branch merged on master
+ - Run `npm version major` or `npm version minor` or `npm version patch`
+ - `git push origin master --tags`
+ - If you are a project owner, then `npm publish`
+
+## If you want to have a bug fixed or a feature added:
+
+ - Check open issues for what you want.
+ - If there is an open issue, comment on it, otherwise open an issue describing your bug or feature with use cases.
+ - Discussion happens on the issue about how to solve your problem.
+ - You or a core contributor opens a pull request solving the issue with tests and documentation.
+ - The pull requests gets reviewed and then merged.
+ - A new release version get's cut.
+ - (Disclaimer: Your feature might get rejected.)
+
+### Changes to this arrangement
+
+This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
diff --git a/node_modules/min-document/LICENCE b/node_modules/min-document/LICENCE
new file mode 100644
index 000000000..72d356c12
--- /dev/null
+++ b/node_modules/min-document/LICENCE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Colingo.
+
+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.
diff --git a/node_modules/min-document/README.md b/node_modules/min-document/README.md
new file mode 100644
index 000000000..970b47d24
--- /dev/null
+++ b/node_modules/min-document/README.md
@@ -0,0 +1,43 @@
+# min-document
+
+[![build status][1]][2] [![dependency status][3]][4]
+
+<!-- [![browser support][5]][6] -->
+
+A minimal DOM implementation
+
+## Example
+
+```js
+var document = require("min-document")
+
+var div = document.createElement("div")
+div.className = "foo bar"
+
+var span = document.createElement("span")
+div.appendChild(span)
+span.textContent = "Hello!"
+
+/* <div class="foo bar">
+ <span>Hello!</span>
+ </div>
+*/
+var html = String(div)
+```
+
+## Installation
+
+`npm install min-document`
+
+## Contributors
+
+ - Raynos
+
+## MIT Licenced
+
+ [1]: https://secure.travis-ci.org/Raynos/min-document.png
+ [2]: https://travis-ci.org/Raynos/min-document
+ [3]: https://david-dm.org/Raynos/min-document.png
+ [4]: https://david-dm.org/Raynos/min-document
+ [5]: https://ci.testling.com/Raynos/min-document.png
+ [6]: https://ci.testling.com/Raynos/min-document
diff --git a/node_modules/min-document/docs.mli b/node_modules/min-document/docs.mli
new file mode 100644
index 000000000..ad17b4ae8
--- /dev/null
+++ b/node_modules/min-document/docs.mli
@@ -0,0 +1,156 @@
+type Comment := {
+ data: String,
+ length: Number,
+ nodeName: "#comment",
+ nodeType: 8,
+ nodeValue: String,
+ ownerDoucment: null | Document,
+
+ toString: (this: Comment) => String
+}
+
+type DOMText := {
+ data: String,
+ type: "DOMTextNode",
+ length: Number,
+ nodeType: 3,
+
+ toString: (this: DOMText) => String,
+ replaceChild: (
+ this: DOMText,
+ index: Number,
+ length: Number,
+ value: String
+ ) => void
+}
+
+type DOMNode := DOMText | DOMElement | DocumentFragment
+type DOMChild := DOMText | DOMElement
+
+type DOMElement := {
+ tagName: String,
+ className: String,
+ dataset: Object<String, Any>,
+ childNodes: Array<DOMChild>,
+ parentNode: null | DOMElement,
+ style: Object<String, String>,
+ type: "DOMElement",
+ nodeType: 1,
+ ownerDoucment: null | Document,
+ namespaceURI: null | String,
+
+ appendChild: (this: DOMElement, child: DOMChild) => DOMChild,
+ replaceChild:(
+ this: DOMElement,
+ elem: DOMChild,
+ needle: DOMChild
+ ) => DOMChild,
+ removeChild: (this: DOMElement, child: DOMChild) => DOMChild,
+ insertBefore: (
+ this: DOMElement,
+ elem: DOMChild,
+ needle: DOMChild | null | undefined
+ ) => DOMChild,
+ addEventListener: addEventListener,
+ dispatchEvent: dispatchEvent,
+ focus: () => void,
+ toString: (this: DOMElement) => String,
+ getElementsByClassName: (
+ this: DOMElement,
+ className: String
+ ) => Array<DOMElement>,
+ getElementsByTagName: (
+ this: DOMElement,
+ tagName: String
+ ) => Array<DOMElement>,
+}
+
+type DocumentFragment := {
+ childNodes: Array<DOMChild>,
+ parentNode: null | DOMElement,
+ type: "DocumentFragment",
+ nodeType: 11,
+ nodeName: "#document-fragment",
+ ownerDoucment: Document | null,
+
+ appendChild: (this: DocumentFragment, child: DOMChild),
+ replaceChild:
+ (this: DocumentFragment, elem: DOMChild, needle: DOMChild),
+ removeChild: (this: DocumentFragment, child: DOMChild),
+ toString: (this: DocumentFragment) => String
+}
+
+type Document := {
+ body: DOMElement,
+ childNodes: Array<DOMChild>,
+ documentElement: DOMElement,
+ nodeType: 9,
+
+ createComment: (this: Document, data: String) => Commment,
+ createTextNode: (this: Document, value: String) => DOMText,
+ createElement: (this: Document, tagName: String) => DOMElement,
+ createElementNS: (
+ this: Document,
+ namespace: String | null,
+ tagName: String
+ ) => DOMElement,
+ createDocumentFragment: (this: Document) => DocumentFragment,
+ createEvent: () => Event,
+ getElementById: (
+ this: Document,
+ id: String,
+ ) => null | DOMElement,
+ getElementsByClassName: (
+ this: Document,
+ className: String
+ ) => Array<DOMElement>,
+ getElementsByTagName: (
+ this: Document,
+ tagName: String
+ ) => Array<DOMElement>
+}
+
+type Event := {
+ type: String,
+ bubbles: Boolean,
+ cancelable: Boolean,
+
+ initEvent: (
+ this: Event,
+ type: String,
+ bubbles: Boolean,
+ cancelable: Boolean
+ ) => void
+}
+
+type addEventListener := (
+ this: DOMElement,
+ type: String,
+ listener: Listener
+) => void
+
+type dispatchEvent := (
+ this: DOMElement,
+ ev: Event
+)
+
+min-document/event/add-event-listener := addEventListener
+
+min-document/event/dispatch-event := dispatchEvent
+
+min-document/document := () => Document
+
+min-document/dom-element :=
+ (tagName: String, owner?: Document, namespace?: String | null) => DOMElement
+
+min-document/dom-fragment :=
+ (owner?: Document) => DocumentFragment
+
+min-document/dom-text :=
+ (value: String, owner?: Document) => DOMText
+
+min-document/event := () => Event
+
+min-document/serialize := (DOMElement) => String
+
+min-document := Document
diff --git a/node_modules/min-document/document.js b/node_modules/min-document/document.js
new file mode 100644
index 000000000..d929cbd54
--- /dev/null
+++ b/node_modules/min-document/document.js
@@ -0,0 +1,72 @@
+var domWalk = require("dom-walk")
+
+var Comment = require("./dom-comment.js")
+var DOMText = require("./dom-text.js")
+var DOMElement = require("./dom-element.js")
+var DocumentFragment = require("./dom-fragment.js")
+var Event = require("./event.js")
+var dispatchEvent = require("./event/dispatch-event.js")
+var addEventListener = require("./event/add-event-listener.js")
+var removeEventListener = require("./event/remove-event-listener.js")
+
+module.exports = Document;
+
+function Document() {
+ if (!(this instanceof Document)) {
+ return new Document();
+ }
+
+ this.head = this.createElement("head")
+ this.body = this.createElement("body")
+ this.documentElement = this.createElement("html")
+ this.documentElement.appendChild(this.head)
+ this.documentElement.appendChild(this.body)
+ this.childNodes = [this.documentElement]
+ this.nodeType = 9
+}
+
+var proto = Document.prototype;
+proto.createTextNode = function createTextNode(value) {
+ return new DOMText(value, this)
+}
+
+proto.createElementNS = function createElementNS(namespace, tagName) {
+ var ns = namespace === null ? null : String(namespace)
+ return new DOMElement(tagName, this, ns)
+}
+
+proto.createElement = function createElement(tagName) {
+ return new DOMElement(tagName, this)
+}
+
+proto.createDocumentFragment = function createDocumentFragment() {
+ return new DocumentFragment(this)
+}
+
+proto.createEvent = function createEvent(family) {
+ return new Event(family)
+}
+
+proto.createComment = function createComment(data) {
+ return new Comment(data, this)
+}
+
+proto.getElementById = function getElementById(id) {
+ id = String(id)
+
+ var result = domWalk(this.childNodes, function (node) {
+ if (String(node.id) === id) {
+ return node
+ }
+ })
+
+ return result || null
+}
+
+proto.getElementsByClassName = DOMElement.prototype.getElementsByClassName
+proto.getElementsByTagName = DOMElement.prototype.getElementsByTagName
+proto.contains = DOMElement.prototype.contains
+
+proto.removeEventListener = removeEventListener
+proto.addEventListener = addEventListener
+proto.dispatchEvent = dispatchEvent
diff --git a/node_modules/min-document/dom-comment.js b/node_modules/min-document/dom-comment.js
new file mode 100644
index 000000000..132ea373e
--- /dev/null
+++ b/node_modules/min-document/dom-comment.js
@@ -0,0 +1,19 @@
+module.exports = Comment
+
+function Comment(data, owner) {
+ if (!(this instanceof Comment)) {
+ return new Comment(data, owner)
+ }
+
+ this.data = data
+ this.nodeValue = data
+ this.length = data.length
+ this.ownerDocument = owner || null
+}
+
+Comment.prototype.nodeType = 8
+Comment.prototype.nodeName = "#comment"
+
+Comment.prototype.toString = function _Comment_toString() {
+ return "[object Comment]"
+}
diff --git a/node_modules/min-document/dom-element.js b/node_modules/min-document/dom-element.js
new file mode 100644
index 000000000..73ff10ecc
--- /dev/null
+++ b/node_modules/min-document/dom-element.js
@@ -0,0 +1,209 @@
+var domWalk = require("dom-walk")
+var dispatchEvent = require("./event/dispatch-event.js")
+var addEventListener = require("./event/add-event-listener.js")
+var removeEventListener = require("./event/remove-event-listener.js")
+var serializeNode = require("./serialize.js")
+
+var htmlns = "http://www.w3.org/1999/xhtml"
+
+module.exports = DOMElement
+
+function DOMElement(tagName, owner, namespace) {
+ if (!(this instanceof DOMElement)) {
+ return new DOMElement(tagName)
+ }
+
+ var ns = namespace === undefined ? htmlns : (namespace || null)
+
+ this.tagName = ns === htmlns ? String(tagName).toUpperCase() : tagName
+ this.nodeName = this.tagName
+ this.className = ""
+ this.dataset = {}
+ this.childNodes = []
+ this.parentNode = null
+ this.style = {}
+ this.ownerDocument = owner || null
+ this.namespaceURI = ns
+ this._attributes = {}
+
+ if (this.tagName === 'INPUT') {
+ this.type = 'text'
+ }
+}
+
+DOMElement.prototype.type = "DOMElement"
+DOMElement.prototype.nodeType = 1
+
+DOMElement.prototype.appendChild = function _Element_appendChild(child) {
+ if (child.parentNode) {
+ child.parentNode.removeChild(child)
+ }
+
+ this.childNodes.push(child)
+ child.parentNode = this
+
+ return child
+}
+
+DOMElement.prototype.replaceChild =
+ function _Element_replaceChild(elem, needle) {
+ // TODO: Throw NotFoundError if needle.parentNode !== this
+
+ if (elem.parentNode) {
+ elem.parentNode.removeChild(elem)
+ }
+
+ var index = this.childNodes.indexOf(needle)
+
+ needle.parentNode = null
+ this.childNodes[index] = elem
+ elem.parentNode = this
+
+ return needle
+ }
+
+DOMElement.prototype.removeChild = function _Element_removeChild(elem) {
+ // TODO: Throw NotFoundError if elem.parentNode !== this
+
+ var index = this.childNodes.indexOf(elem)
+ this.childNodes.splice(index, 1)
+
+ elem.parentNode = null
+ return elem
+}
+
+DOMElement.prototype.insertBefore =
+ function _Element_insertBefore(elem, needle) {
+ // TODO: Throw NotFoundError if referenceElement is a dom node
+ // and parentNode !== this
+
+ if (elem.parentNode) {
+ elem.parentNode.removeChild(elem)
+ }
+
+ var index = needle === null || needle === undefined ?
+ -1 :
+ this.childNodes.indexOf(needle)
+
+ if (index > -1) {
+ this.childNodes.splice(index, 0, elem)
+ } else {
+ this.childNodes.push(elem)
+ }
+
+ elem.parentNode = this
+ return elem
+ }
+
+DOMElement.prototype.setAttributeNS =
+ function _Element_setAttributeNS(namespace, name, value) {
+ var prefix = null
+ var localName = name
+ var colonPosition = name.indexOf(":")
+ if (colonPosition > -1) {
+ prefix = name.substr(0, colonPosition)
+ localName = name.substr(colonPosition + 1)
+ }
+ if (this.tagName === 'INPUT' && name === 'type') {
+ this.type = value;
+ }
+ else {
+ var attributes = this._attributes[namespace] || (this._attributes[namespace] = {})
+ attributes[localName] = {value: value, prefix: prefix}
+ }
+ }
+
+DOMElement.prototype.getAttributeNS =
+ function _Element_getAttributeNS(namespace, name) {
+ var attributes = this._attributes[namespace];
+ var value = attributes && attributes[name] && attributes[name].value
+ if (this.tagName === 'INPUT' && name === 'type') {
+ return this.type;
+ }
+ if (typeof value !== "string") {
+ return null
+ }
+ return value
+ }
+
+DOMElement.prototype.removeAttributeNS =
+ function _Element_removeAttributeNS(namespace, name) {
+ var attributes = this._attributes[namespace];
+ if (attributes) {
+ delete attributes[name]
+ }
+ }
+
+DOMElement.prototype.hasAttributeNS =
+ function _Element_hasAttributeNS(namespace, name) {
+ var attributes = this._attributes[namespace]
+ return !!attributes && name in attributes;
+ }
+
+DOMElement.prototype.setAttribute = function _Element_setAttribute(name, value) {
+ return this.setAttributeNS(null, name, value)
+}
+
+DOMElement.prototype.getAttribute = function _Element_getAttribute(name) {
+ return this.getAttributeNS(null, name)
+}
+
+DOMElement.prototype.removeAttribute = function _Element_removeAttribute(name) {
+ return this.removeAttributeNS(null, name)
+}
+
+DOMElement.prototype.hasAttribute = function _Element_hasAttribute(name) {
+ return this.hasAttributeNS(null, name)
+}
+
+DOMElement.prototype.removeEventListener = removeEventListener
+DOMElement.prototype.addEventListener = addEventListener
+DOMElement.prototype.dispatchEvent = dispatchEvent
+
+// Un-implemented
+DOMElement.prototype.focus = function _Element_focus() {
+ return void 0
+}
+
+DOMElement.prototype.toString = function _Element_toString() {
+ return serializeNode(this)
+}
+
+DOMElement.prototype.getElementsByClassName = function _Element_getElementsByClassName(classNames) {
+ var classes = classNames.split(" ");
+ var elems = []
+
+ domWalk(this, function (node) {
+ if (node.nodeType === 1) {
+ var nodeClassName = node.className || ""
+ var nodeClasses = nodeClassName.split(" ")
+
+ if (classes.every(function (item) {
+ return nodeClasses.indexOf(item) !== -1
+ })) {
+ elems.push(node)
+ }
+ }
+ })
+
+ return elems
+}
+
+DOMElement.prototype.getElementsByTagName = function _Element_getElementsByTagName(tagName) {
+ tagName = tagName.toLowerCase()
+ var elems = []
+
+ domWalk(this.childNodes, function (node) {
+ if (node.nodeType === 1 && (tagName === '*' || node.tagName.toLowerCase() === tagName)) {
+ elems.push(node)
+ }
+ })
+
+ return elems
+}
+
+DOMElement.prototype.contains = function _Element_contains(element) {
+ return domWalk(this, function (node) {
+ return element === node
+ }) || false
+}
diff --git a/node_modules/min-document/dom-fragment.js b/node_modules/min-document/dom-fragment.js
new file mode 100644
index 000000000..d4bac92ff
--- /dev/null
+++ b/node_modules/min-document/dom-fragment.js
@@ -0,0 +1,28 @@
+var DOMElement = require("./dom-element.js")
+
+module.exports = DocumentFragment
+
+function DocumentFragment(owner) {
+ if (!(this instanceof DocumentFragment)) {
+ return new DocumentFragment()
+ }
+
+ this.childNodes = []
+ this.parentNode = null
+ this.ownerDocument = owner || null
+}
+
+DocumentFragment.prototype.type = "DocumentFragment"
+DocumentFragment.prototype.nodeType = 11
+DocumentFragment.prototype.nodeName = "#document-fragment"
+
+DocumentFragment.prototype.appendChild = DOMElement.prototype.appendChild
+DocumentFragment.prototype.replaceChild = DOMElement.prototype.replaceChild
+DocumentFragment.prototype.removeChild = DOMElement.prototype.removeChild
+
+DocumentFragment.prototype.toString =
+ function _DocumentFragment_toString() {
+ return this.childNodes.map(function (node) {
+ return String(node)
+ }).join("")
+ }
diff --git a/node_modules/min-document/dom-text.js b/node_modules/min-document/dom-text.js
new file mode 100644
index 000000000..4a6c6b92a
--- /dev/null
+++ b/node_modules/min-document/dom-text.js
@@ -0,0 +1,27 @@
+module.exports = DOMText
+
+function DOMText(value, owner) {
+ if (!(this instanceof DOMText)) {
+ return new DOMText(value)
+ }
+
+ this.data = value || ""
+ this.length = this.data.length
+ this.ownerDocument = owner || null
+}
+
+DOMText.prototype.type = "DOMTextNode"
+DOMText.prototype.nodeType = 3
+DOMText.prototype.nodeName = "#text"
+
+DOMText.prototype.toString = function _Text_toString() {
+ return this.data
+}
+
+DOMText.prototype.replaceData = function replaceData(index, length, value) {
+ var current = this.data
+ var left = current.substring(0, index)
+ var right = current.substring(index + length, current.length)
+ this.data = left + value + right
+ this.length = this.data.length
+}
diff --git a/node_modules/min-document/event.js b/node_modules/min-document/event.js
new file mode 100644
index 000000000..0a989c3d7
--- /dev/null
+++ b/node_modules/min-document/event.js
@@ -0,0 +1,13 @@
+module.exports = Event
+
+function Event(family) {}
+
+Event.prototype.initEvent = function _Event_initEvent(type, bubbles, cancelable) {
+ this.type = type
+ this.bubbles = bubbles
+ this.cancelable = cancelable
+}
+
+Event.prototype.preventDefault = function _Event_preventDefault() {
+
+}
diff --git a/node_modules/min-document/event/add-event-listener.js b/node_modules/min-document/event/add-event-listener.js
new file mode 100644
index 000000000..022c7ef41
--- /dev/null
+++ b/node_modules/min-document/event/add-event-listener.js
@@ -0,0 +1,17 @@
+module.exports = addEventListener
+
+function addEventListener(type, listener) {
+ var elem = this
+
+ if (!elem.listeners) {
+ elem.listeners = {}
+ }
+
+ if (!elem.listeners[type]) {
+ elem.listeners[type] = []
+ }
+
+ if (elem.listeners[type].indexOf(listener) === -1) {
+ elem.listeners[type].push(listener)
+ }
+}
diff --git a/node_modules/min-document/event/dispatch-event.js b/node_modules/min-document/event/dispatch-event.js
new file mode 100644
index 000000000..8febc990d
--- /dev/null
+++ b/node_modules/min-document/event/dispatch-event.js
@@ -0,0 +1,31 @@
+module.exports = dispatchEvent
+
+function dispatchEvent(ev) {
+ var elem = this
+ var type = ev.type
+
+ if (!ev.target) {
+ ev.target = elem
+ }
+
+ if (!elem.listeners) {
+ elem.listeners = {}
+ }
+
+ var listeners = elem.listeners[type]
+
+ if (listeners) {
+ return listeners.forEach(function (listener) {
+ ev.currentTarget = elem
+ if (typeof listener === 'function') {
+ listener(ev)
+ } else {
+ listener.handleEvent(ev)
+ }
+ })
+ }
+
+ if (elem.parentNode) {
+ elem.parentNode.dispatchEvent(ev)
+ }
+}
diff --git a/node_modules/min-document/event/remove-event-listener.js b/node_modules/min-document/event/remove-event-listener.js
new file mode 100644
index 000000000..d96091bc3
--- /dev/null
+++ b/node_modules/min-document/event/remove-event-listener.js
@@ -0,0 +1,19 @@
+module.exports = removeEventListener
+
+function removeEventListener(type, listener) {
+ var elem = this
+
+ if (!elem.listeners) {
+ return
+ }
+
+ if (!elem.listeners[type]) {
+ return
+ }
+
+ var list = elem.listeners[type]
+ var index = list.indexOf(listener)
+ if (index !== -1) {
+ list.splice(index, 1)
+ }
+}
diff --git a/node_modules/min-document/index.js b/node_modules/min-document/index.js
new file mode 100644
index 000000000..0d97e8ef4
--- /dev/null
+++ b/node_modules/min-document/index.js
@@ -0,0 +1,3 @@
+var Document = require('./document.js');
+
+module.exports = new Document();
diff --git a/node_modules/min-document/package.json b/node_modules/min-document/package.json
new file mode 100644
index 000000000..807490209
--- /dev/null
+++ b/node_modules/min-document/package.json
@@ -0,0 +1,58 @@
+{
+ "name": "min-document",
+ "version": "2.19.0",
+ "description": "A minimal DOM implementation",
+ "keywords": [],
+ "author": "Raynos <raynos2@gmail.com>",
+ "repository": "git://github.com/Raynos/min-document.git",
+ "main": "index",
+ "homepage": "https://github.com/Raynos/min-document",
+ "contributors": [
+ {
+ "name": "Raynos"
+ }
+ ],
+ "bugs": {
+ "url": "https://github.com/Raynos/min-document/issues",
+ "email": "raynos2@gmail.com"
+ },
+ "dependencies": {
+ "dom-walk": "^0.1.0"
+ },
+ "devDependencies": {
+ "run-browser": "git://github.com/Raynos/run-browser",
+ "tap-dot": "^0.2.1",
+ "tap-spec": "^0.1.8",
+ "tape": "^2.12.3"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/Raynos/min-document/raw/master/LICENSE"
+ }
+ ],
+ "scripts": {
+ "test": "node ./test/index.js | tap-spec",
+ "dot": "node ./test/index.js | tap-dot",
+ "cover": "istanbul cover --report none --print detail ./test/index.js",
+ "view-cover": "istanbul report html && google-chrome ./coverage/index.html",
+ "browser": "run-browser test/index.js",
+ "phantom": "run-browser test/index.js -b | tap-spec"
+ },
+ "testling": {
+ "files": "test/index.js",
+ "browsers": [
+ "ie/8..latest",
+ "firefox/16..latest",
+ "firefox/nightly",
+ "chrome/22..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ }
+}
diff --git a/node_modules/min-document/serialize.js b/node_modules/min-document/serialize.js
new file mode 100644
index 000000000..4411d3c37
--- /dev/null
+++ b/node_modules/min-document/serialize.js
@@ -0,0 +1,139 @@
+module.exports = serializeNode
+
+var voidElements = ["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"];
+
+function serializeNode(node) {
+ switch (node.nodeType) {
+ case 3:
+ return escapeText(node.data)
+ case 8:
+ return "<!--" + node.data + "-->"
+ default:
+ return serializeElement(node)
+ }
+}
+
+function serializeElement(elem) {
+ var strings = []
+
+ var tagname = elem.tagName
+
+ if (elem.namespaceURI === "http://www.w3.org/1999/xhtml") {
+ tagname = tagname.toLowerCase()
+ }
+
+ strings.push("<" + tagname + properties(elem) + datasetify(elem))
+
+ if (voidElements.indexOf(tagname) > -1) {
+ strings.push(" />")
+ } else {
+ strings.push(">")
+
+ if (elem.childNodes.length) {
+ strings.push.apply(strings, elem.childNodes.map(serializeNode))
+ } else if (elem.textContent || elem.innerText) {
+ strings.push(escapeText(elem.textContent || elem.innerText))
+ } else if (elem.innerHTML) {
+ strings.push(elem.innerHTML)
+ }
+
+ strings.push("</" + tagname + ">")
+ }
+
+ return strings.join("")
+}
+
+function isProperty(elem, key) {
+ var type = typeof elem[key]
+
+ if (key === "style" && Object.keys(elem.style).length > 0) {
+ return true
+ }
+
+ return elem.hasOwnProperty(key) &&
+ (type === "string" || type === "boolean" || type === "number") &&
+ key !== "nodeName" && key !== "className" && key !== "tagName" &&
+ key !== "textContent" && key !== "innerText" && key !== "namespaceURI" && key !== "innerHTML"
+}
+
+function stylify(styles) {
+ if (typeof styles === 'string') return styles
+ var attr = ""
+ Object.keys(styles).forEach(function (key) {
+ var value = styles[key]
+ key = key.replace(/[A-Z]/g, function(c) {
+ return "-" + c.toLowerCase();
+ })
+ attr += key + ":" + value + ";"
+ })
+ return attr
+}
+
+function datasetify(elem) {
+ var ds = elem.dataset
+ var props = []
+
+ for (var key in ds) {
+ props.push({ name: "data-" + key, value: ds[key] })
+ }
+
+ return props.length ? stringify(props) : ""
+}
+
+function stringify(list) {
+ var attributes = []
+ list.forEach(function (tuple) {
+ var name = tuple.name
+ var value = tuple.value
+
+ if (name === "style") {
+ value = stylify(value)
+ }
+
+ attributes.push(name + "=" + "\"" + escapeAttributeValue(value) + "\"")
+ })
+
+ return attributes.length ? " " + attributes.join(" ") : ""
+}
+
+function properties(elem) {
+ var props = []
+ for (var key in elem) {
+ if (isProperty(elem, key)) {
+ props.push({ name: key, value: elem[key] })
+ }
+ }
+
+ for (var ns in elem._attributes) {
+ for (var attribute in elem._attributes[ns]) {
+ var prop = elem._attributes[ns][attribute]
+ var name = (prop.prefix ? prop.prefix + ":" : "") + attribute
+ props.push({ name: name, value: prop.value })
+ }
+ }
+
+ if (elem.className) {
+ props.push({ name: "class", value: elem.className })
+ }
+
+ return props.length ? stringify(props) : ""
+}
+
+function escapeText(s) {
+ var str = '';
+
+ if (typeof(s) === 'string') {
+ str = s;
+ } else if (s) {
+ str = s.toString();
+ }
+
+ return str
+ .replace(/&/g, "&amp;")
+ .replace(/</g, "&lt;")
+ .replace(/>/g, "&gt;")
+}
+
+function escapeAttributeValue(str) {
+ return escapeText(str).replace(/"/g, "&quot;")
+}
diff --git a/node_modules/min-document/test/cleanup.js b/node_modules/min-document/test/cleanup.js
new file mode 100644
index 000000000..d3ae66ab1
--- /dev/null
+++ b/node_modules/min-document/test/cleanup.js
@@ -0,0 +1,13 @@
+module.exports = Cleanup
+
+function Cleanup (document) {
+
+ return cleanup
+
+ function cleanup () {
+ var childNodes = document.body.childNodes
+ for (var i = 0; i < childNodes.length; i++) {
+ document.body.removeChild(childNodes[i])
+ }
+ }
+}
diff --git a/node_modules/min-document/test/index.js b/node_modules/min-document/test/index.js
new file mode 100644
index 000000000..14b736a14
--- /dev/null
+++ b/node_modules/min-document/test/index.js
@@ -0,0 +1,14 @@
+var testDocument = require("./test-document")
+var testDomElement = require("./test-dom-element")
+var testDomComment = require("./test-dom-comment")
+var document = require("../index")
+
+testDocument(document)
+testDomElement(document)
+testDomComment(document)
+
+if (typeof window !== "undefined" && window.document) {
+ testDocument(window.document)
+ testDomElement(window.document)
+ testDomComment(window.document)
+}
diff --git a/node_modules/min-document/test/static/index.html b/node_modules/min-document/test/static/index.html
new file mode 100644
index 000000000..60f6ef8b3
--- /dev/null
+++ b/node_modules/min-document/test/static/index.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+<head>
+ <title>TAPE Example</title>
+ <script src="/testem.js"></script>
+ <script src="test-adapter.js"></script>
+ <script src="bundle.js"></script>
+</head>
+<body>
+</body>
+</html>
diff --git a/node_modules/min-document/test/static/test-adapter.js b/node_modules/min-document/test/static/test-adapter.js
new file mode 100644
index 000000000..c5127925b
--- /dev/null
+++ b/node_modules/min-document/test/static/test-adapter.js
@@ -0,0 +1,49 @@
+(function () {
+ var Testem = window.Testem
+ var regex = /^((?:not )?ok) (\d+) (.+)$/
+
+ Testem.useCustomAdapter(tapAdapter)
+
+ function tapAdapter(socket){
+ var results = {
+ failed: 0
+ , passed: 0
+ , total: 0
+ , tests: []
+ }
+
+ socket.emit('tests-start')
+
+ Testem.handleConsoleMessage = function(msg){
+ var m = msg.match(regex)
+ if (m) {
+ var passed = m[1] === 'ok'
+ var test = {
+ passed: passed ? 1 : 0,
+ failed: passed ? 0 : 1,
+ total: 1,
+ id: m[2],
+ name: m[3],
+ items: []
+ }
+
+ if (passed) {
+ results.passed++
+ } else {
+ results.failed++
+ }
+
+ results.total++
+
+ socket.emit('test-result', test)
+ results.tests.push(test)
+ } else if (msg === '# ok' || msg.match(/^# tests \d+/)){
+ socket.emit('all-test-results', results)
+ }
+
+ // return false if you want to prevent the console message from
+ // going to the console
+ // return false
+ }
+ }
+}())
diff --git a/node_modules/min-document/test/test-document.js b/node_modules/min-document/test/test-document.js
new file mode 100644
index 000000000..282d9df7b
--- /dev/null
+++ b/node_modules/min-document/test/test-document.js
@@ -0,0 +1,564 @@
+var test = require("tape")
+
+module.exports = testDocument
+
+function testDocument(document) {
+ var cleanup = require('./cleanup')(document)
+ var Event = require('../event');
+
+ test("document is a Document", function (assert) {
+ assert.equal(typeof document.createTextNode, "function")
+ assert.equal(typeof document.createElement, "function")
+ assert.equal(typeof document.createDocumentFragment, "function")
+
+ assert.end()
+ })
+
+ test("document has a head property", function(assert) {
+ assert.equal(document.head.tagName, "HEAD")
+ assert.end()
+ })
+
+ test("document has nodeType 9", function (assert) {
+ assert.equal(document.nodeType, 9)
+ assert.end()
+ })
+
+ test("can do stuff", function (assert) {
+ var div = document.createElement("div")
+ div.className = "foo bar"
+
+ var span = document.createElement("span")
+ div.appendChild(span)
+ span.textContent = "Hello! <&>"
+
+ var html = String(div.outerHTML || div)
+
+ assert.equal(html, "<div class=\"foo bar\">" +
+ "<span>Hello! &lt;&amp;&gt;</span></div>")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can createDocumentFragment", function (assert) {
+ var frag = document.createDocumentFragment()
+
+ assert.equal(frag.nodeType, 11)
+
+ var h1 = document.createElement("h1")
+ var h2 = document.createElement("h2")
+
+ assert.equal(h1.nodeType, 1)
+ assert.equal(h1.nodeType, 1)
+
+ frag.appendChild(h1)
+ assert.equal(fragString(frag), "<h1></h1>")
+
+ frag.appendChild(h2)
+ assert.equal(fragString(frag), "<h1></h1><h2></h2>")
+
+ frag.removeChild(h1)
+ assert.equal(fragString(frag), "<h2></h2>")
+
+ frag.replaceChild(h1, h2)
+ assert.equal(fragString(frag), "<h1></h1>")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementById", function (assert) {
+
+ function append_div(id, parent) {
+ var div = document.createElement("div")
+ div.id = id
+ parent.appendChild(div)
+ return div
+ }
+
+ var div1 = append_div(1, document.body)
+ var div2 = append_div(2, document.body)
+ var div3 = append_div(3, document.body)
+
+ var div11 = append_div(11, div1)
+ var div12 = append_div(12, div1)
+ var div21 = append_div(21, div2)
+ var div22 = append_div(22, div2)
+ var div221 = append_div(221, div22)
+ var div222 = append_div(222, div22)
+
+ assert.equal(document.getElementById(1), div1)
+ assert.equal(document.getElementById("2"), div2)
+ assert.equal(document.getElementById(3), div3)
+ assert.equal(document.getElementById(11), div11)
+ assert.equal(document.getElementById(12), div12)
+ assert.equal(document.getElementById(21), div21)
+ assert.equal(document.getElementById(22), div22)
+ assert.equal(document.getElementById(221), div221)
+ assert.equal(document.getElementById(222), div222)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByClassName for a single class", function(assert) {
+ function append_div(className, parent) {
+ var div = document.createElement("div")
+ div.className = className
+ parent.appendChild(div)
+ return div
+ }
+
+ function assertSingleMatch(className, expectedElement) {
+ var result = document.getElementsByClassName(className)
+ assert.equal(result.length, 1)
+ assert.equal(result[0], expectedElement)
+ }
+
+ var divA = append_div("A", document.body)
+ var divB = append_div("B", document.body)
+ var divC = append_div("C", document.body)
+
+ var divA1 = append_div("A1", divA)
+ var divA2 = append_div("A2", divA)
+ var divB1 = append_div("B1", divB)
+ var divB2 = append_div("B2", divB)
+ var divB2a = append_div("B2a", divB2)
+ var divB2b = append_div("B2b", divB2)
+
+ assertSingleMatch("A", divA)
+ assertSingleMatch("B", divB)
+ assertSingleMatch("C", divC)
+ assertSingleMatch("A1", divA1)
+ assertSingleMatch("A2", divA2)
+ assertSingleMatch("B1", divB1)
+ assertSingleMatch("B2", divB2)
+ assertSingleMatch("B2a", divB2a)
+ assertSingleMatch("B2b", divB2b)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByClassName for many elements", function (assert) {
+ function h(className) {
+ var div = document.createElement("div")
+ div.className = className
+ return div
+ }
+
+ document.body.appendChild(h("multi-class-bar"))
+ document.body.appendChild(h("multi-class-bar"))
+
+ var elems = document.getElementsByClassName("multi-class-bar")
+ assert.equal(elems.length, 2)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByClassName for many classes", function(assert) {
+ function append_div(classNames, parent) {
+ var div = document.createElement("div")
+ div.className = classNames
+ parent.appendChild(div)
+ return div
+ }
+
+ function assertMatch(classNames, expectedElements) {
+ var result = document.getElementsByClassName(classNames)
+ assert.equal(result.length, expectedElements.length)
+ for (var i = 0; i < expectedElements.length; i++) {
+ assert.notEqual(expectedElements.indexOf(result[i]), -1)
+ }
+ }
+
+ var divXYZ = append_div("X Y Z", document.body)
+ var divYZ = append_div("Y Z", document.body)
+ var divZX = append_div("Z X", document.body)
+
+ var divX1X2 = append_div("X1 X2", divXYZ)
+ var divX1X2Y1 = append_div("X1 X2 Y1", divXYZ)
+
+
+ assertMatch("X", [divXYZ, divZX])
+ assertMatch("Y Z", [divXYZ, divYZ])
+ assertMatch("X Y Z", [divXYZ])
+ assertMatch("X1 X2", [divX1X2, divX1X2Y1])
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can create/manipulate textnodes", function (assert) {
+ var textnode = document.createTextNode("hello")
+
+ assert.equal(textnode.nodeType, 3)
+ assert.equal(textnode.data, "hello")
+ assert.equal(typeof textnode.replaceData, "function")
+
+ textnode.replaceData(0, 7, "nightly")
+ assert.equal(textnode.nodeType, 3)
+ assert.equal(textnode.data, "nightly")
+ assert.equal(typeof textnode.replaceData, "function")
+
+ textnode.replaceData(1, 1, "ou")
+ assert.equal(textnode.nodeType, 3)
+ assert.equal(textnode.data, "noughtly")
+
+ assert.end()
+ })
+
+ test("owner document is set", function (assert) {
+ var textnode = document.createTextNode("hello")
+ var domnode = document.createElement("div")
+ var fragment = document.createDocumentFragment()
+
+ assert.equal(textnode.ownerDocument, document)
+ assert.equal(domnode.ownerDocument, document)
+ assert.equal(fragment.ownerDocument, document)
+
+ assert.end()
+ })
+
+ test("Create namespaced nodes", function (assert) {
+ var svgURI = "http://www.w3.org/2000/svg"
+ var htmlURI = "http://www.w3.org/1999/xhtml"
+
+ var noNS = document.createElement("div")
+ var svgNS = document.createElementNS(svgURI, "svg")
+ var emptyNS = document.createElementNS("", "div")
+ var nullNS = document.createElementNS(null, "div")
+ var undefNS = document.createElementNS(undefined, "div")
+ var caseNS = document.createElementNS("Oops", "AbC")
+ var htmlNS = document.createElement("div")
+
+ assert.equal(noNS.tagName, "DIV")
+ assert.equal(noNS.namespaceURI, htmlURI)
+ assert.equal(elemString(noNS), "<div></div>")
+
+ assert.equal(svgNS.tagName, "svg")
+ assert.equal(svgNS.namespaceURI, svgURI)
+ assert.equal(elemString(svgNS), "<svg></svg>")
+
+ assert.equal(emptyNS.tagName, "div")
+ assert.equal(emptyNS.namespaceURI, null)
+ assert.equal(elemString(emptyNS), "<div></div>")
+
+ assert.equal(nullNS.tagName, "div")
+ assert.equal(nullNS.namespaceURI, null)
+ assert.equal(elemString(nullNS), "<div></div>")
+
+ assert.equal(undefNS.tagName, "div")
+ assert.equal(undefNS.namespaceURI, "undefined")
+ assert.equal(elemString(undefNS), "<div></div>")
+
+ assert.equal(caseNS.tagName, "AbC")
+ assert.equal(caseNS.namespaceURI, "Oops")
+ assert.equal(elemString(caseNS), "<AbC></AbC>")
+
+ assert.equal(htmlNS.tagName, "DIV")
+ assert.equal(htmlNS.namespaceURI, htmlURI)
+ assert.equal(elemString(htmlNS), "<div></div>")
+
+ assert.end()
+ })
+
+ test("Can insert before", function (assert) {
+ var rootNode = document.createElement("div")
+ var child = document.createElement("div")
+ var newElement = document.createElement("div")
+ rootNode.appendChild(child)
+ var el = rootNode.insertBefore(newElement, child)
+ assert.equal(el, newElement)
+ assert.equal(rootNode.childNodes.length, 2)
+ assert.equal(rootNode.childNodes[0], newElement)
+ assert.equal(rootNode.childNodes[1], child)
+ cleanup()
+ assert.end()
+ })
+
+ test("Insert before null appends to end", function (assert) {
+ var rootNode = document.createElement("div")
+ var child = document.createElement("div")
+ var newElement = document.createElement("div")
+ rootNode.appendChild(child)
+ var el = rootNode.insertBefore(newElement, null)
+ assert.equal(el, newElement)
+ assert.equal(rootNode.childNodes.length, 2)
+ assert.equal(rootNode.childNodes[0], child)
+ assert.equal(rootNode.childNodes[1], newElement)
+ cleanup()
+ assert.end()
+ })
+
+ test("Node insertions remove node from parent", function (assert) {
+ var parent = document.createElement("div")
+ var c1 = document.createElement("div")
+ var c2 = document.createElement("div")
+ var c3 = document.createElement("div")
+ parent.appendChild(c1)
+ parent.appendChild(c2)
+ parent.appendChild(c3)
+
+ var rootNode = document.createElement("div")
+
+ var node1 = rootNode.appendChild(c1)
+ assert.equal(node1, c1)
+ assert.equal(parent.childNodes.length, 2)
+ assert.equal(c1.parentNode, rootNode)
+
+ var node2 = rootNode.insertBefore(c2, c1)
+ assert.equal(node2, c2)
+ assert.equal(parent.childNodes.length, 1)
+ assert.equal(c2.parentNode, rootNode)
+
+ var node3 = rootNode.replaceChild(c3, c2)
+ assert.equal(node3, c2)
+ assert.equal(parent.childNodes.length, 0)
+ assert.equal(c3.parentNode, rootNode)
+ assert.equal(c2.parentNode, null)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("input has type=text by default", function (assert) {
+ var elem = document.createElement("input")
+ assert.equal(elem.getAttribute("type"), "text");
+ assert.equal(elemString(elem), "<input type=\"text\" />")
+ assert.end()
+ })
+
+ test("input type=text can be overridden", function (assert) {
+ var elem = document.createElement("input")
+ elem.setAttribute("type", "hidden")
+ assert.equal(elem.getAttribute("type"), "hidden");
+ assert.equal(elemString(elem), "<input type=\"hidden\" />")
+ assert.end()
+ })
+
+ test("can set and get attributes", function (assert) {
+ var elem = document.createElement("div")
+ assert.equal(elem.getAttribute("foo"), null)
+ assert.equal(elemString(elem), "<div></div>")
+ assert.notOk(elem.hasAttribute('foo'))
+
+ elem.setAttribute("foo", "bar")
+ assert.equal(elem.getAttribute("foo"), "bar")
+ assert.equal(elemString(elem), "<div foo=\"bar\"></div>")
+ assert.ok(elem.hasAttribute('foo'))
+
+ elem.removeAttribute("foo")
+ assert.equal(elem.getAttribute("foo"), null)
+ assert.equal(elemString(elem), "<div></div>")
+ assert.notOk(elem.hasAttribute('foo'))
+
+ assert.end()
+ })
+
+ test("can set and set style properties", function(assert) {
+ var elem = document.createElement("div")
+ assert.equal(elemString(elem), "<div></div>")
+
+ elem.style.color = "red";
+ assert.equal(elem.style.color, "red")
+ assert.equal(elemString(elem), "<div style=\"color:red;\"></div>")
+
+ elem.style.background = "blue";
+ assert.equal(elem.style.color, "red")
+ assert.equal(elem.style.background, "blue")
+ assert.equal(elemString(elem),
+ "<div style=\"color:red;background:blue;\"></div>")
+
+ assert.end()
+ })
+
+ test("can set and get namespaced attributes", function(assert) {
+ var elem = document.createElement("div")
+
+ var ns = "http://ns.com/my"
+ assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
+ elem.setAttributeNS(ns, "myns:myattr", "the value")
+ assert.equal(elem.getAttributeNS(ns, "myattr"), "the value")
+ assert.equal(elemString(elem), '<div myns:myattr="the value"></div>')
+ elem.removeAttributeNS(ns, "myattr")
+ assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
+
+ // Should work much like get/setAttribute when namespace is null.
+ assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
+ assert.equal(elem.getAttribute("foo"), null)
+ elem.setAttributeNS(null, "foo", "bar")
+ assert.equal(elem.getAttributeNS(null, "foo"), "bar")
+ assert.equal(elem.getAttribute("foo"), "bar")
+ elem.removeAttributeNS(null, "foo")
+ assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
+ assert.equal(elem.getAttribute("foo"), null)
+ assert.end()
+ })
+
+ test("can getElementsByTagName", function(assert) {
+ var parent = document.createElement("div")
+ var child1 = document.createElement("span")
+ var child2 = document.createElement("span")
+
+ child1.id = "foo"
+ child2.id = "bar"
+
+ child1.appendChild(child2)
+ parent.appendChild(child1)
+ document.body.appendChild(parent)
+
+ var elems = document.getElementsByTagName("SPAN")
+
+ assert.equal(elems.length, 2)
+ assert.equal(elems[0].id, "foo")
+ assert.equal(elems[1].id, "bar")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByTagName with *", function(assert) {
+ document.body.appendChild(document.createElement("div"))
+
+ var elems = document.getElementsByTagName("*")
+
+ assert.equal(elems.length, 4)
+ assert.equal(elems[0].tagName, "HTML")
+ assert.equal(elems[1].tagName, "HEAD")
+ assert.equal(elems[2].tagName, "BODY")
+ assert.equal(elems[3].tagName, "DIV")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("getElement* methods search outside the body", function(assert) {
+ var html = document.documentElement;
+ assert.equal(document.getElementsByTagName("html")[0], html)
+
+ html.id = "foo"
+ assert.equal(document.getElementById("foo"), html)
+
+ html.className = "bar"
+ assert.equal(document.getElementsByClassName("bar")[0], html)
+
+ // cleanup
+ html.id = ""
+ html.className = ""
+
+ cleanup()
+ assert.end()
+ })
+
+ test("getElement* methods can be passed to map()", function(assert) {
+ var e1 = document.createElement("div")
+ var e2 = document.createElement("span")
+
+ document.body.appendChild(e1)
+ document.body.appendChild(e2)
+
+ assert.deepEqual(
+ ["div", "span"].map(document.getElementsByTagName.bind(document)),
+ [[e1], [e2]]
+ )
+
+ e1.id = "1"
+ e2.id = "2"
+
+ assert.deepEqual(
+ ["1", "2"].map(document.getElementById.bind(document)),
+ [e1, e2]
+ )
+
+ e1.className = "foo"
+ e2.className = "bar"
+
+ assert.deepEqual(
+ ["foo", "bar"].map(document.getElementsByClassName.bind(document)),
+ [[e1], [e2]]
+ )
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can check if it contains an element", function(assert) {
+ var el = document.createElement("div")
+ document.body.appendChild(el)
+
+ assert.equals(document.contains(document.body), true)
+ assert.equals(document.contains(el), true)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can do events", function (assert) {
+ var x = 1
+ function incx() { x++ }
+
+ var ev = new Event();
+ ev.initEvent("click");
+ document.addEventListener("click", incx)
+ document.dispatchEvent(ev)
+
+ assert.equal(x, 2)
+
+ document.removeEventListener("click", incx)
+ document.dispatchEvent(ev)
+
+ assert.equal(x, 2)
+ assert.end()
+ })
+
+ function blankAttributeNS() {
+ // Most browsers conform to the latest version of the DOM spec,
+ // which requires `getAttributeNS` to return `null` when the attribute
+ // doesn't exist, but some browsers (including phantomjs) implement the
+ // old version of the spec and return an empty string instead, see:
+ // https://developer.mozilla.org/en-US/docs/Web/API/element.getAttributeNS#Return_value
+ var div = document.createElement("div")
+ var blank = div.getAttributeNS(null, "foo")
+ if (!(blank === null || blank === "")) {
+ throw "Expected blank attribute to be either null or empty string"
+ }
+ return blank;
+ }
+
+ function elemString(element) {
+ var html = String(element) || "[]"
+
+ if (html.charAt(0) === "[") {
+ html = element.outerHTML
+ if (!html && !element.parentNode) {
+ var div = document.createElement("div")
+ div.appendChild(element)
+ html = div.innerHTML
+ div.removeChild(element)
+ }
+ }
+
+ return html
+ }
+
+ function fragString(fragment) {
+ var html = String(fragment)
+
+
+ if (html === "[object DocumentFragment]") {
+ var innerHTML = []
+ for (var i = 0; i < fragment.childNodes.length; i++) {
+ var node = fragment.childNodes[i]
+ innerHTML.push(String(node.outerHTML || node))
+ }
+ html = innerHTML.join("")
+ }
+
+ return html
+ }
+}
+
+
diff --git a/node_modules/min-document/test/test-dom-comment.js b/node_modules/min-document/test/test-dom-comment.js
new file mode 100644
index 000000000..7ecf175eb
--- /dev/null
+++ b/node_modules/min-document/test/test-dom-comment.js
@@ -0,0 +1,20 @@
+var test = require("tape")
+
+module.exports = testDomComment
+
+function testDomComment(document) {
+ var cleanup = require('./cleanup')(document)
+
+ test("can createComment", function(assert) {
+ var comment = document.createComment("test")
+ assert.equal(comment.data, "test")
+ assert.equal(comment.length, 4)
+ assert.equal(comment.nodeName, "#comment")
+ assert.equal(comment.nodeType, 8)
+ assert.equal(comment.nodeValue, "test")
+ assert.equal(comment.ownerDocument, document)
+ assert.equal(comment.toString(), "[object Comment]")
+ cleanup()
+ assert.end()
+ })
+}
diff --git a/node_modules/min-document/test/test-dom-element.js b/node_modules/min-document/test/test-dom-element.js
new file mode 100644
index 000000000..b7f2baab6
--- /dev/null
+++ b/node_modules/min-document/test/test-dom-element.js
@@ -0,0 +1,219 @@
+var test = require("tape")
+
+module.exports = testDomElement
+
+function testDomElement(document) {
+
+ var cleanup = require('./cleanup')(document)
+
+ test("can getElementsByClassName", function(assert) {
+ function append_div(classNames, parent) {
+ var div = document.createElement("div")
+ div.className = classNames
+ parent.appendChild(div)
+ return div
+ }
+
+ function assertMatch(classNames, expectedElements, parent) {
+ var parent = parent || document
+ var result = parent.getElementsByClassName(classNames)
+ assert.equal(result.length, expectedElements.length)
+ for (var i = 0; i < expectedElements.length; i++) {
+ assert.notEqual(expectedElements.indexOf(result[i]), -1)
+ }
+ }
+
+ var divA = append_div("A", document.body)
+ var divB = append_div("B", document.body)
+ var divC = append_div("C", document.body)
+
+ var divA1 = append_div("A1", divA)
+ var divA2 = append_div("A2", divA)
+ var divB1 = append_div("B1", divB)
+ var divB2 = append_div("B2", divB)
+ var divB2a = append_div("B2a", divB2)
+ var divB2b = append_div("B2b", divB2)
+
+ assertMatch("A", [divA])
+ assertMatch("B", [divB])
+ assertMatch("C", [divC])
+ assertMatch("A1", [divA1])
+ assertMatch("A2", [divA2])
+ assertMatch("B1", [divB1])
+ assertMatch("B2", [divB2])
+ assertMatch("B2a", [divB2a])
+ assertMatch("B2b", [divB2b])
+
+ assertMatch("A1", [divA1], divA)
+ assertMatch("A2", [divA2], divA)
+ assertMatch("A1", [], divB)
+ assertMatch("A2", [], divC)
+ assertMatch("B1", [divB1], divB)
+ assertMatch("B2", [divB2], divB)
+ assertMatch("B2a", [divB2a], divB)
+ assertMatch("B2a", [divB2a], divB2)
+ assertMatch("B2b", [], divA)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("does not serialize innerText as an attribute", function(assert) {
+ var div = document.createElement("div")
+ div.innerText = "Test <&>"
+ assert.equal(div.toString(), "<div>Test &lt;&amp;&gt;</div>")
+ cleanup()
+ assert.end()
+ })
+
+ test("does not serialize innerHTML as an attribute", function(assert) {
+ var div = document.createElement("div")
+ div.innerHTML = "Test <img />"
+ assert.equal(div.toString(), "<div>Test <img /></div>")
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByTagName", function(assert) {
+ var parent = document.createElement("div")
+ var child1 = document.createElement("span")
+ var child2 = document.createElement("span")
+
+ child1.id = "foo"
+ child2.id = "bar"
+
+ child1.appendChild(child2)
+ parent.appendChild(child1)
+
+ var elems = parent.getElementsByTagName("SPAN")
+
+ assert.equal(elems.length, 2)
+ assert.equal(elems[0].id, "foo")
+ assert.equal(elems[1].id, "bar")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can getElementsByTagName with *", function(assert) {
+ var e1 = document.createElement("div")
+ var e2 = document.createElement("p")
+ var e3 = document.createElement("span")
+
+ e1.appendChild(e2)
+ e2.appendChild(e3)
+ // non-elements should be ignored
+ e3.appendChild(document.createTextNode('foo'))
+ e3.appendChild(document.createComment('bar'))
+
+ var elems = e1.getElementsByTagName("*")
+
+ assert.equal(elems.length, 2)
+ assert.equal(elems[0].tagName, "P")
+ assert.equal(elems[1].tagName, "SPAN")
+
+ cleanup()
+ assert.end()
+ })
+
+ test("getElement* methods can be passed to map()", function(assert) {
+ var container = document.createElement("div")
+ var e1 = document.createElement("div")
+ var e2 = document.createElement("span")
+ container.appendChild(e1)
+ container.appendChild(e2)
+
+ assert.deepEqual(
+ ["div", "span"].map(container.getElementsByTagName.bind(container)),
+ [[e1], [e2]]
+ )
+
+ e1.className = "foo"
+ e2.className = "bar"
+
+ assert.deepEqual(
+ ["foo", "bar"].map(container.getElementsByClassName.bind(container)),
+ [[e1], [e2]]
+ )
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can serialize comment nodes", function(assert) {
+ var div = document.createElement("div")
+ div.appendChild(document.createComment("test"))
+ assert.equal(div.toString(), "<div><!--test--></div>")
+ cleanup()
+ assert.end()
+ })
+
+ test("can serialize style property", function(assert) {
+ var div = document.createElement("div")
+ div.style.fontSize = "16px"
+ assert.equal(div.toString(), "<div style=\"font-size:16px;\"></div>")
+ cleanup();
+ assert.end()
+ })
+
+ test("can serialize style as a string", function(assert) {
+ var div = document.createElement("div")
+ div.setAttribute('style', 'display: none')
+ assert.equal(div.toString(), "<div style=\"display: none\"></div>")
+ cleanup()
+ assert.end()
+ })
+
+ test("can serialize text nodes", function(assert) {
+ var div = document.createElement("div")
+ div.appendChild(document.createTextNode('<test> "&'))
+ assert.equal(div.toString(), '<div>&lt;test&gt; "&amp;</div>')
+ cleanup()
+ assert.end()
+ })
+
+ test("escapes serialized attribute values", function(assert) {
+ var div = document.createElement("div")
+ div.setAttribute("data-foo", '<p>"&')
+ assert.equal(div.toString(), '<div data-foo="&lt;p&gt;&quot;&amp;"></div>')
+ cleanup()
+ assert.end()
+ })
+
+ test("can check if an element contains another", function(assert) {
+ var parent = document.createElement("div")
+ var sibling = document.createElement("div")
+ var child1 = document.createElement("div")
+ var child2 = document.createElement("div")
+
+ child1.appendChild(child2)
+ parent.appendChild(child1)
+
+ assert.equal(parent.contains(parent), true)
+ assert.equal(parent.contains(sibling), false)
+ assert.equal(parent.contains(child1), true)
+ assert.equal(parent.contains(child2), true)
+
+ cleanup()
+ assert.end()
+ })
+
+ test("can handle non string attribute values", function(assert) {
+ var div = document.createElement("div")
+ div.setAttribute("data-number", 100)
+ div.setAttribute("data-boolean", true)
+ div.setAttribute("data-null", null)
+ assert.equal(div.toString(), '<div data-number="100" data-boolean="true" data-null=""></div>')
+ cleanup()
+ assert.end()
+ })
+
+ test("can serialize textarea correctly", function(assert) {
+ var input = document.createElement("textarea")
+ input.setAttribute("name", "comment")
+ input.innerHTML = "user input here"
+ assert.equal(input.toString(), '<textarea name="comment">user input here</textarea>')
+ cleanup()
+ assert.end()
+ })
+}