initial commit (work in progress)
This commit is contained in:
parent
13fdb60f66
commit
559369016d
83 changed files with 10461 additions and 0 deletions
219
test-utils/domMock.js
Normal file
219
test-utils/domMock.js
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
"use strict"
|
||||
|
||||
module.exports = function() {
|
||||
function appendChild(child) {
|
||||
var ancestor = this
|
||||
while (ancestor !== child && ancestor !== null) ancestor = ancestor.parentNode
|
||||
if (ancestor === child) throw new Error("Node cannot be inserted at the specified point in the hierarchy")
|
||||
|
||||
if (child.nodeType == null) throw new Error("Argument is not a DOM element")
|
||||
|
||||
var index = this.childNodes.indexOf(child)
|
||||
if (index > -1) this.childNodes.splice(index, 1)
|
||||
if (child.nodeType === 11) {
|
||||
while (child.firstChild != null) this.appendChild(child.firstChild)
|
||||
child.childNodes = []
|
||||
}
|
||||
else {
|
||||
this.childNodes.push(child)
|
||||
if (child.parentNode != null && child.parentNode !== this) child.parentNode.removeChild(child)
|
||||
child.parentNode = this
|
||||
}
|
||||
}
|
||||
function removeChild(child) {
|
||||
var index = this.childNodes.indexOf(child)
|
||||
if (index > -1) {
|
||||
this.childNodes.splice(index, 1)
|
||||
child.parentNode = null
|
||||
}
|
||||
else throw new TypeError("Failed to execute 'removeChild'")
|
||||
}
|
||||
function insertBefore(child, reference) {
|
||||
var ancestor = this
|
||||
while (ancestor !== child && ancestor !== null) ancestor = ancestor.parentNode
|
||||
if (ancestor === child) throw new Error("Node cannot be inserted at the specified point in the hierarchy")
|
||||
|
||||
if (child.nodeType == null) throw new Error("Argument is not a DOM element")
|
||||
|
||||
var refIndex = this.childNodes.indexOf(reference)
|
||||
var index = this.childNodes.indexOf(child)
|
||||
if (reference !== null && refIndex < 0) throw new TypeError("Invalid argument")
|
||||
if (index > -1) this.childNodes.splice(index, 1)
|
||||
if (reference === null) this.appendChild(child)
|
||||
else {
|
||||
if (child.nodeType === 11) {
|
||||
this.childNodes.splice.apply(this.childNodes, [refIndex, 0].concat(child.childNodes))
|
||||
while (child.firstChild) {
|
||||
var subchild = child.firstChild
|
||||
child.removeChild(subchild)
|
||||
subchild.parentNode = this
|
||||
}
|
||||
child.childNodes = []
|
||||
}
|
||||
else {
|
||||
this.childNodes.splice(refIndex, 0, child)
|
||||
if (child.parentNode != null && child.parentNode !== this) child.parentNode.removeChild(child)
|
||||
child.parentNode = this
|
||||
}
|
||||
}
|
||||
}
|
||||
function setAttribute(name, value) {
|
||||
var nodeValue = String(value)
|
||||
this.attributes[name] = {
|
||||
namespaceURI: null,
|
||||
get nodeValue() {return nodeValue},
|
||||
set nodeValue(value) {nodeValue = String(value)},
|
||||
}
|
||||
}
|
||||
function setAttributeNS(ns, name, value) {
|
||||
this.setAttribute(name, value)
|
||||
this.attributes[name].namespaceURI = ns
|
||||
}
|
||||
function removeAttribute(name) {
|
||||
delete this.attributes[name]
|
||||
}
|
||||
var activeElement
|
||||
var $window = {
|
||||
document: {
|
||||
createElement: function(tag, is) {
|
||||
var style = {}
|
||||
var element = {
|
||||
nodeType: 1,
|
||||
nodeName: tag.toUpperCase(),
|
||||
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||
appendChild: appendChild,
|
||||
removeChild: removeChild,
|
||||
insertBefore: insertBefore,
|
||||
setAttribute: setAttribute,
|
||||
setAttributeNS: setAttributeNS,
|
||||
removeAttribute: removeAttribute,
|
||||
parentNode: null,
|
||||
childNodes: [],
|
||||
attributes: {},
|
||||
get firstChild() {
|
||||
return this.childNodes[0] || null
|
||||
},
|
||||
get nextSibling() {
|
||||
if (this.parentNode == null) return null
|
||||
var index = this.parentNode.childNodes.indexOf(this)
|
||||
if (index < 0) throw new TypeError("Parent's childNodes is out of sync")
|
||||
return this.parentNode.childNodes[index + 1] || null
|
||||
},
|
||||
set textContent(value) {
|
||||
this.childNodes = []
|
||||
if (value !== "") this.appendChild($window.document.createTextNode(value))
|
||||
},
|
||||
set innerHTML(value) {
|
||||
while (this.firstChild) this.removeChild(this.firstChild)
|
||||
|
||||
var stack = [this], depth = 0, voidElements = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]
|
||||
value.replace(/<([a-z0-9\-]+?)((?:\s+?[^=]+?=(?:"[^"]*?"|'[^']*?'|[^\s>]*))*?)(\s*\/)?>|<\/([a-z0-9\-]+?)>|([^<]+)/g, function(match, startTag, attrs, selfClosed, endTag, text) {
|
||||
if (startTag) {
|
||||
var element = $window.document.createElement(startTag)
|
||||
attrs.replace(/\s+?([^=]+?)=(?:"([^"]*?)"|'([^']*?)'|([^\s>]*))/g, function(match, key, doubleQuoted, singleQuoted, unquoted) {
|
||||
var keyParts = key.split(":")
|
||||
var name = keyParts.pop()
|
||||
var ns = keyParts[0]
|
||||
var value = doubleQuoted || singleQuoted || unquoted || ""
|
||||
if (ns != null) element.setAttributeNS(ns, name, value)
|
||||
else element.setAttribute(name, value)
|
||||
})
|
||||
stack[depth].appendChild(element)
|
||||
if (!selfClosed && voidElements.indexOf(startTag.toLowerCase()) < 0) stack[++depth] = element
|
||||
}
|
||||
else if (endTag) {
|
||||
depth--
|
||||
}
|
||||
else if (text) {
|
||||
stack[depth].appendChild($window.document.createTextNode(text)) // FIXME handle html entities
|
||||
}
|
||||
})
|
||||
},
|
||||
get style() {
|
||||
return style
|
||||
},
|
||||
set style(value) {
|
||||
if (typeof value === "string") {
|
||||
for (var key in style) style[key] = ""
|
||||
var rules = value.split(";")
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
var rule = rules[i]
|
||||
var colonIndex = rule.indexOf(":")
|
||||
if (colonIndex > -1) {
|
||||
var key = rule.slice(0, colonIndex).trim().replace(/-\D/g, function(match) {return match[1].toUpperCase()})
|
||||
var value = rule.slice(colonIndex + 1).trim()
|
||||
style[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
focus: function() {activeElement = this},
|
||||
dispatchEvent: function(e) {
|
||||
e.target = this
|
||||
if (typeof this["on" + e.type] === "function") this["on" + e.type](e)
|
||||
},
|
||||
}
|
||||
if (element.nodeName === "A") {
|
||||
var href
|
||||
Object.defineProperty(element, "href", {
|
||||
get: function() {return this.attributes["href"] === undefined ? "" : "[FIXME implement]"},
|
||||
set: function(value) {this.setAttribute("href", value)},
|
||||
enumerable: true,
|
||||
})
|
||||
}
|
||||
if (element.nodeName === "INPUT") {
|
||||
var checked
|
||||
Object.defineProperty(element, "checked", {
|
||||
get: function() {return checked === undefined ? this.attributes["checked"] !== undefined : checked},
|
||||
set: function(value) {checked = Boolean(value)},
|
||||
enumerable: true,
|
||||
})
|
||||
}
|
||||
return element
|
||||
},
|
||||
createElementNS: function(ns, tag, is) {
|
||||
var element = this.createElement(tag, is)
|
||||
element.nodeName = tag
|
||||
element.namespaceURI = ns
|
||||
return element
|
||||
},
|
||||
createTextNode: function(text) {
|
||||
var nodeValue = String(text)
|
||||
return {
|
||||
nodeType: 3,
|
||||
nodeName: "#text",
|
||||
parentNode: null,
|
||||
get nodeValue() {return nodeValue},
|
||||
set nodeValue(value) {nodeValue = String(value)},
|
||||
}
|
||||
},
|
||||
createDocumentFragment: function() {
|
||||
return {
|
||||
nodeType: 11,
|
||||
nodeName: "#document-fragment",
|
||||
appendChild: appendChild,
|
||||
insertBefore: insertBefore,
|
||||
removeChild: removeChild,
|
||||
parentNode: null,
|
||||
childNodes: [],
|
||||
get firstChild() {
|
||||
return this.childNodes[0] || null
|
||||
},
|
||||
}
|
||||
},
|
||||
createEvent: function() {
|
||||
return {
|
||||
initEvent: function(type) {this.type = type},
|
||||
}
|
||||
},
|
||||
get activeElement() {return activeElement},
|
||||
},
|
||||
}
|
||||
$window.document.documentElement = $window.document.createElement("html")
|
||||
$window.document.documentElement.appendChild($window.document.createElement("head"))
|
||||
$window.document.body = $window.document.createElement("body")
|
||||
$window.document.documentElement.appendChild($window.document.body)
|
||||
activeElement = $window.document.body
|
||||
|
||||
return $window
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue