initial commit (work in progress)
This commit is contained in:
parent
13fdb60f66
commit
559369016d
83 changed files with 10461 additions and 0 deletions
75
render/hyperscript.js
Normal file
75
render/hyperscript.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"use strict"
|
||||
|
||||
var normalizeChildren = require("../render/normalizeChildren")
|
||||
|
||||
var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:\s*=\s*("|'|)(.*?)\2)?\]/
|
||||
var selectorCache = {}
|
||||
function hyperscript(selector) {
|
||||
if (selectorCache[selector] === undefined) {
|
||||
var match, tag, id, classes = [], attributes = {}
|
||||
while (match = selectorParser.exec(selector)) {
|
||||
var type = match[1], value = match[2]
|
||||
if (type === "" && value !== "") tag = value
|
||||
else if (type === "#") attributes.id = value
|
||||
else if (type === ".") classes.push(value)
|
||||
else if (match[3][0] === "[") {
|
||||
var pair = attrParser.exec(match[3])
|
||||
attributes[pair[1]] = pair[3] || true
|
||||
}
|
||||
}
|
||||
if (classes.length > 0) attributes.className = classes.join(" ")
|
||||
selectorCache[selector] = function(attrs, children) {
|
||||
var hasAttrs = false, childList, text
|
||||
var className = attrs.className || attrs.class
|
||||
for (var key in attributes) attrs[key] = attributes[key]
|
||||
if (className !== undefined) {
|
||||
if (attrs.class !== undefined) {
|
||||
attrs.class = undefined
|
||||
attrs.className = className
|
||||
}
|
||||
if (attributes.className !== undefined) attrs.className = attributes.className + " " + className
|
||||
}
|
||||
for (var key in attrs) {
|
||||
if (key !== "key") {
|
||||
hasAttrs = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (children instanceof Array && children.length == 1 && children[0] != null && children[0].tag === "#") text = children[0].children
|
||||
else childList = children
|
||||
return namespace({tag: tag || "div", key: attrs.key, attrs: hasAttrs ? attrs : undefined, children: childList, text: text})
|
||||
}
|
||||
}
|
||||
var attrs, children, childrenIndex
|
||||
if (arguments[1] == null || typeof arguments[1] === "object" && arguments[1].tag === undefined && !(arguments[1] instanceof Array)) {
|
||||
attrs = arguments[1]
|
||||
childrenIndex = 2
|
||||
}
|
||||
else childrenIndex = 1
|
||||
if (arguments.length === childrenIndex + 1) {
|
||||
children = arguments[childrenIndex] instanceof Array ? arguments[childrenIndex] : [arguments[childrenIndex]]
|
||||
}
|
||||
else {
|
||||
children = []
|
||||
for (var i = childrenIndex; i < arguments.length; i++) children.push(arguments[i])
|
||||
}
|
||||
|
||||
return selectorCache[selector](attrs || {}, normalizeChildren(children))
|
||||
}
|
||||
|
||||
function namespace(vnode) {
|
||||
switch (vnode.tag) {
|
||||
case "svg": changeNS("http://www.w3.org/2000/svg", vnode); break
|
||||
case "math": changeNS("http://www.w3.org/1998/Math/MathML", vnode); break
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
|
||||
function changeNS(ns, vnode) {
|
||||
vnode.ns = ns
|
||||
if (vnode.children != null) {
|
||||
for (var i = 0; i < vnode.children.length; i++) changeNS(ns, vnode.children[i])
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = hyperscript
|
||||
7
render/normalizeChildren.js
Normal file
7
render/normalizeChildren.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = function normalizeChildren(children) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
if (children[i] instanceof Array) children[i] = {tag: "[", key: undefined, attrs: undefined, children: normalizeChildren(children[i]), text: undefined}
|
||||
else if (children[i] != null && typeof children[i] !== "object") children[i] = {tag: "#", key: undefined, attrs: undefined, children: children[i], text: undefined}
|
||||
}
|
||||
return children
|
||||
}
|
||||
382
render/render.js
Normal file
382
render/render.js
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
"use strict"
|
||||
|
||||
var normalizeChildren = require("../render/normalizeChildren")
|
||||
|
||||
module.exports = function($window, onevent) {
|
||||
var $doc = $window.document
|
||||
|
||||
//create
|
||||
function createNodes(parent, vnodes, start, end, hooks, nextSibling) {
|
||||
for (var i = start; i < end; i++) {
|
||||
var vnode = vnodes[i]
|
||||
if (vnode != null) {
|
||||
insertNode(parent, createNode(vnode, hooks), nextSibling)
|
||||
}
|
||||
}
|
||||
}
|
||||
function createNode(vnode, hooks) {
|
||||
var tag = vnode.tag
|
||||
if (vnode.attrs && vnode.attrs.oncreate) {
|
||||
hooks.push(vnode.attrs.oncreate.bind(vnode, vnode))
|
||||
}
|
||||
switch (tag) {
|
||||
case "#": return createText(vnode)
|
||||
case "<": return createHTML(vnode)
|
||||
case "[": return createFragment(vnode, hooks)
|
||||
default: return createElement(vnode, hooks)
|
||||
}
|
||||
}
|
||||
function createText(vnode) {
|
||||
return vnode.dom = $doc.createTextNode(vnode.children)
|
||||
}
|
||||
function createHTML(vnode) {
|
||||
var match = vnode.children.match(/^\s*?<(\w+)/im) || []
|
||||
var parent = {caption: "table", thead: "table", tbody: "table", tfoot: "table", tr: "tbody", th: "tr", td: "tr", colgroup: "table", col: "colgroup"}[match[1]] || "div"
|
||||
var temp = $doc.createElement(parent)
|
||||
|
||||
temp.innerHTML = vnode.children
|
||||
vnode.dom = temp.firstChild
|
||||
vnode.domSize = temp.childNodes.length
|
||||
var fragment = $doc.createDocumentFragment()
|
||||
var child
|
||||
while (child = temp.firstChild) {
|
||||
fragment.appendChild(child)
|
||||
}
|
||||
return fragment
|
||||
}
|
||||
function createFragment(vnode, hooks) {
|
||||
var fragment = $doc.createDocumentFragment()
|
||||
if (vnode.children != null) {
|
||||
var children = vnode.children
|
||||
createNodes(fragment, children, 0, children.length, hooks, null)
|
||||
}
|
||||
vnode.dom = fragment.firstChild
|
||||
vnode.domSize = fragment.childNodes.length
|
||||
return fragment
|
||||
}
|
||||
function createElement(vnode, hooks) {
|
||||
var tag = vnode.tag
|
||||
var ns = vnode.ns
|
||||
|
||||
var attrs = vnode.attrs
|
||||
var is = attrs && attrs.is
|
||||
|
||||
var element = ns ?
|
||||
is ? $doc.createElementNS(ns, tag, is) : $doc.createElementNS(ns, tag) :
|
||||
is ? $doc.createElement(tag, is) : $doc.createElement(tag)
|
||||
vnode.dom = element
|
||||
|
||||
if (attrs != null) {
|
||||
setAttrs(vnode, attrs)
|
||||
}
|
||||
|
||||
if (vnode.text != null) {
|
||||
if (vnode.text !== "") element.textContent = vnode.text
|
||||
else vnode.children = [{tag: "#", children: vnode.text}]
|
||||
}
|
||||
|
||||
if (vnode.children != null) {
|
||||
var children = vnode.children
|
||||
createNodes(element, children, 0, children.length, hooks, null)
|
||||
}
|
||||
return element
|
||||
}
|
||||
|
||||
//update
|
||||
function updateNodes(parent, old, vnodes, hooks, nextSibling) {
|
||||
if (old == null && vnodes == null) return
|
||||
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling)
|
||||
else if (vnodes == null) removeNodes(parent, old, 0, old.length, vnodes)
|
||||
else {
|
||||
var recycling = isRecyclable(old, vnodes)
|
||||
if (recycling) old = old.concat(old.pool)
|
||||
|
||||
var oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map
|
||||
while (oldEnd >= oldStart && end >= start) {
|
||||
var o = old[oldStart], v = vnodes[start]
|
||||
if (o === v) oldStart++, start++
|
||||
else if (o != null && v != null && o.key === v.key) {
|
||||
oldStart++, start++
|
||||
updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling)
|
||||
if (recycling) insertNode(parent, toFragment(v), nextSibling)
|
||||
}
|
||||
else {
|
||||
var o = old[oldEnd]
|
||||
if (o === v) oldEnd--, start++
|
||||
else if (o != null && v != null && o.key === v.key) {
|
||||
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling)
|
||||
insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))
|
||||
oldEnd--, start++
|
||||
}
|
||||
else break
|
||||
}
|
||||
}
|
||||
while (oldEnd >= oldStart && end >= start) {
|
||||
var o = old[oldEnd], v = vnodes[end]
|
||||
if (o === v) oldEnd--, end--
|
||||
else if (o != null && v != null && o.key === v.key) {
|
||||
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling)
|
||||
if (recycling) insertNode(parent, toFragment(v), nextSibling)
|
||||
nextSibling = o.dom
|
||||
oldEnd--, end--
|
||||
}
|
||||
else {
|
||||
if (!map) map = getKeyMap(old, oldEnd)
|
||||
if (v != null) {
|
||||
var oldIndex = map[v.key]
|
||||
if (oldIndex != null) {
|
||||
var movable = old[oldIndex]
|
||||
updateNode(parent, movable, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling)
|
||||
insertNode(parent, toFragment(movable), nextSibling)
|
||||
old[oldIndex].skip = true
|
||||
nextSibling = movable.dom
|
||||
}
|
||||
else {
|
||||
var dom = createNode(v, hooks)
|
||||
insertNode(parent, dom, nextSibling)
|
||||
nextSibling = dom
|
||||
}
|
||||
}
|
||||
end--
|
||||
}
|
||||
if (end < start) break
|
||||
}
|
||||
createNodes(parent, vnodes, start, end + 1, hooks, nextSibling)
|
||||
removeNodes(parent, old, oldStart, oldEnd + 1, vnodes)
|
||||
}
|
||||
}
|
||||
function updateNode(parent, old, vnode, hooks, nextSibling, recycling) {
|
||||
var oldTag = old.tag, tag = vnode.tag
|
||||
if (oldTag === tag) {
|
||||
if (recycling) {
|
||||
if (vnode.attrs && vnode.attrs.oncreate) hooks.push(vnode.attrs.oncreate.bind(vnode, vnode))
|
||||
}
|
||||
else if (vnode.attrs && vnode.attrs.onupdate) hooks.push(vnode.attrs.onupdate.bind(vnode, vnode))
|
||||
switch (oldTag) {
|
||||
case "#": updateText(old, vnode); break
|
||||
case "<": updateHTML(parent, old, vnode, nextSibling); break
|
||||
case "[": updateFragment(parent, old, vnode, hooks, nextSibling); break
|
||||
default: updateElement(old, vnode, hooks)
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeNode(parent, old, null, false)
|
||||
insertNode(parent, createNode(vnode, hooks), nextSibling)
|
||||
}
|
||||
}
|
||||
function updateText(old, vnode) {
|
||||
if (old.children.toString() !== vnode.children.toString()) {
|
||||
old.dom.nodeValue = vnode.children
|
||||
}
|
||||
vnode.dom = old.dom
|
||||
}
|
||||
function updateHTML(parent, old, vnode, nextSibling) {
|
||||
if (old.children !== vnode.children) {
|
||||
toFragment(old)
|
||||
insertNode(parent, createHTML(vnode), nextSibling)
|
||||
}
|
||||
else vnode.dom = old.dom
|
||||
}
|
||||
function updateFragment(parent, old, vnode, hooks, nextSibling) {
|
||||
updateNodes(parent, old.children, vnode.children, hooks, nextSibling)
|
||||
var domSize = 0, children = vnode.children
|
||||
vnode.dom = null
|
||||
if (children != null) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i]
|
||||
if (child != null) {
|
||||
if (vnode.dom == null) vnode.dom = child.dom
|
||||
domSize += child.domSize || 1
|
||||
}
|
||||
}
|
||||
if (domSize != 1) vnode.domSize = domSize
|
||||
}
|
||||
}
|
||||
function updateElement(old, vnode, hooks) {
|
||||
var element = vnode.dom = old.dom
|
||||
updateAttrs(vnode, old.attrs, vnode.attrs)
|
||||
if (old.text != null && vnode.text != null && vnode.text !== "") {
|
||||
if (old.text.toString() !== vnode.text.toString()) old.dom.firstChild.nodeValue = vnode.text
|
||||
}
|
||||
else {
|
||||
if (old.text != null) old.children = [{tag: "#", children: old.text, dom: old.dom.firstChild}]
|
||||
if (vnode.text != null) vnode.children = [{tag: "#", children: vnode.text}]
|
||||
updateNodes(element, old.children, vnode.children, hooks, null)
|
||||
}
|
||||
}
|
||||
function isRecyclable(old, vnodes) {
|
||||
if (old.pool != null && Math.abs(old.pool.length - vnodes.length) <= Math.abs(old.length - vnodes.length)) {
|
||||
var oldChildrenLength = old[0] && old[0].children && old[0].children.length || 0
|
||||
var poolChildrenLength = old.pool[0] && old.pool[0].children && old.pool[0].children.length || 0
|
||||
var vnodesChildrenLength = vnodes[0] && vnodes[0].children && vnodes[0].children.length || 0
|
||||
if (Math.abs(poolChildrenLength - vnodesChildrenLength) <= Math.abs(oldChildrenLength - vnodesChildrenLength)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
function getKeyMap(vnodes, end) {
|
||||
var map = {}, i = 0
|
||||
for (var i = 0; i < end; i++) {
|
||||
var vnode = vnodes[i]
|
||||
if (vnode != null) {
|
||||
var key = vnode.key
|
||||
if (key != null) map[key] = i
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
function toFragment(vnode) {
|
||||
var count = vnode.domSize
|
||||
if (count != null) {
|
||||
var fragment = $doc.createDocumentFragment()
|
||||
if (count > 0) {
|
||||
var dom = vnode.dom
|
||||
while (--count) fragment.appendChild(dom.nextSibling)
|
||||
fragment.insertBefore(dom, fragment.firstChild)
|
||||
}
|
||||
return fragment
|
||||
}
|
||||
else return vnode.dom
|
||||
}
|
||||
function getNextSibling(vnodes, i, nextSibling) {
|
||||
for (; i < vnodes.length; i++) {
|
||||
if (vnodes[i] != null) return vnodes[i].dom
|
||||
}
|
||||
return nextSibling
|
||||
}
|
||||
|
||||
function insertNode(parent, dom, nextSibling) {
|
||||
if (nextSibling && nextSibling.parentNode) parent.insertBefore(dom, nextSibling)
|
||||
else parent.appendChild(dom)
|
||||
}
|
||||
|
||||
//remove
|
||||
function removeNodes(parent, vnodes, start, end, context) {
|
||||
for (var i = start; i < end; i++) {
|
||||
var vnode = vnodes[i]
|
||||
if (vnode != null) {
|
||||
if (vnode.skip) vnode.skip = undefined
|
||||
else removeNode(parent, vnode, context, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
function removeNode(parent, vnode, context, deferred) {
|
||||
if (vnode.attrs && vnode.attrs.onbeforeremove && deferred === false) {
|
||||
vnode.attrs.onbeforeremove.call(vnode, vnode, function() {removeNode(parent, vnode, context, true)})
|
||||
return
|
||||
}
|
||||
|
||||
onremove(vnode)
|
||||
if (vnode.dom) {
|
||||
var count = vnode.domSize || 1
|
||||
if (count > 1) {
|
||||
var dom = vnode.dom
|
||||
while (--count) {
|
||||
parent.removeChild(dom.nextSibling)
|
||||
}
|
||||
}
|
||||
if (vnode.dom.parentNode != null) parent.removeChild(vnode.dom)
|
||||
if (context != null && vnode.domSize == null) { //TODO test custom elements
|
||||
if (!context.pool) context.pool = [vnode]
|
||||
else context.pool.push(vnode)
|
||||
}
|
||||
}
|
||||
}
|
||||
function onremove(vnode) {
|
||||
if (vnode.attrs && vnode.attrs.onremove) vnode.attrs.onremove.call(vnode, vnode)
|
||||
|
||||
var children = vnode.children
|
||||
if (children) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i]
|
||||
if (child != null) onremove(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//attrs
|
||||
function setAttrs(vnode, attrs) {
|
||||
for (var key in attrs) {
|
||||
setAttr(vnode, key, null, attrs[key])
|
||||
}
|
||||
}
|
||||
function setAttr(vnode, key, old, value) {
|
||||
//TODO test input undo history
|
||||
var element = vnode.dom
|
||||
if (key === "key" || old === value || typeof value === "undefined" || isLifecycleMethod(key)) return
|
||||
var nsLastIndex = key.indexOf(":")
|
||||
if (nsLastIndex > -1 && key.substr(0, nsLastIndex) === "xlink") {
|
||||
element.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(nsLastIndex + 1), value)
|
||||
}
|
||||
else if (key[0] === "o" && key[1] === "n" && typeof value === "function") {
|
||||
element[key] = function(e) {
|
||||
var result = value.call(element, e)
|
||||
if (typeof onevent === "function") onevent.call(element, e)
|
||||
return result
|
||||
}
|
||||
}
|
||||
else if (key === "style") updateStyle(element, old, value)
|
||||
else if (key in element && !isAttribute(key) && vnode.ns === undefined) element[key] = value
|
||||
else {
|
||||
if (typeof value === "boolean") {
|
||||
if (value) element.setAttribute(key, "")
|
||||
else element.removeAttribute(key)
|
||||
}
|
||||
else element.setAttribute(key, value)
|
||||
}
|
||||
}
|
||||
function updateAttrs(vnode, old, attrs) {
|
||||
if (attrs != null) {
|
||||
for (var key in attrs) {
|
||||
setAttr(vnode, key, old[key], attrs[key])
|
||||
}
|
||||
}
|
||||
if (old != null) {
|
||||
for (var key in old) {
|
||||
if (attrs == null || !(key in attrs)) {
|
||||
if (key !== "key") vnode.dom.removeAttribute(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function isLifecycleMethod(attr) {
|
||||
return attr === "oncreate" || attr === "onupdate" || attr === "onremove" || attr === "onbeforeremove"
|
||||
}
|
||||
function isAttribute(attr) {
|
||||
return attr === "href" || attr === "list" || attr === "form"// || attr === "type" || attr === "width" || attr === "height"
|
||||
}
|
||||
|
||||
//style
|
||||
function updateStyle(element, old, style) {
|
||||
if (style == null) element.style = ""
|
||||
else if (typeof style === "string") element.style = style
|
||||
else {
|
||||
if (typeof old === "string") element.style = ""
|
||||
for (var key in style) {
|
||||
element.style[key] = style[key]
|
||||
}
|
||||
if (old != null && typeof old !== "string") {
|
||||
for (var key in old) {
|
||||
if (!(key in style)) element.style[key] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render(dom, vnodes) {
|
||||
//if (dom.lastRedraw + 16 > performance.now() && vnodes.length > 0) return
|
||||
//dom.lastRedraw = performance.now()
|
||||
var hooks = []
|
||||
var active = $doc.activeElement
|
||||
if (!dom.vnodes) dom.vnodes = []
|
||||
|
||||
if (!(vnodes instanceof Array)) vnodes = [vnodes]
|
||||
updateNodes(dom, dom.vnodes, normalizeChildren(vnodes), hooks, null)
|
||||
for (var i = 0; i < hooks.length; i++) hooks[i]()
|
||||
dom.vnodes = vnodes
|
||||
if ($doc.activeElement !== active) active.focus()
|
||||
}
|
||||
|
||||
return {render: render}
|
||||
}
|
||||
37
render/tests/index.html
Normal file
37
render/tests/index.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script src="../../module/module.js"></script>
|
||||
<script src="../../ospec/ospec.js"></script>
|
||||
<script src="../../test-utils/callAsync.js"></script>
|
||||
<script src="../../test-utils/domMock.js"></script>
|
||||
|
||||
<script src="../../render/normalizeChildren.js"></script>
|
||||
<script src="../../render/hyperscript.js"></script>
|
||||
<script src="../../render/render.js"></script>
|
||||
<script src="test-hyperscript.js"></script>
|
||||
<script src="test-createText.js"></script>
|
||||
<script src="test-createHTML.js"></script>
|
||||
<script src="test-createFragment.js"></script>
|
||||
<script src="test-createElement.js"></script>
|
||||
<script src="test-createNodes.js"></script>
|
||||
<script src="test-updateText.js"></script>
|
||||
<script src="test-updateHTML.js"></script>
|
||||
<script src="test-updateFragment.js"></script>
|
||||
<script src="test-updateElement.js"></script>
|
||||
<script src="test-updateNodes.js"></script>
|
||||
<script src="test-oncreate.js"></script>
|
||||
<script src="test-onupdate.js"></script>
|
||||
<script src="test-onremove.js"></script>
|
||||
<script src="test-onbeforeremove.js"></script>
|
||||
<script src="test-attributes.js"></script>
|
||||
<script src="test-event.js"></script>
|
||||
<script src="test-input.js"></script>
|
||||
<script src="test-textContent.js"></script>
|
||||
|
||||
<script>require("../../ospec/ospec").run()</script>
|
||||
</body>
|
||||
</html>
|
||||
79
render/tests/test-attributes.js
Normal file
79
render/tests/test-attributes.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("attributes", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.body
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o.spec("input readonly", function() {
|
||||
o("when input readonly is true, attribute is present", function() {
|
||||
var a = {tag: "input", attrs: {readonly: true}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.attributes["readonly"].nodeValue).equals("")
|
||||
})
|
||||
o("when input readonly is false, attribute is not present", function() {
|
||||
var a = {tag: "input", attrs: {readonly: false}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.attributes["readonly"]).equals(undefined)
|
||||
})
|
||||
})
|
||||
o.spec("input checked", function() {
|
||||
o("when input checked is true, attribute is not present", function() {
|
||||
var a = {tag: "input", attrs: {checked: true}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.checked).equals(true)
|
||||
o(a.dom.attributes["checked"]).equals(undefined)
|
||||
})
|
||||
o("when input checked is false, attribute is not present", function() {
|
||||
var a = {tag: "input", attrs: {checked: false}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.checked).equals(false)
|
||||
o(a.dom.attributes["checked"]).equals(undefined)
|
||||
})
|
||||
o("after input checked is changed by 3rd party, it can still be changed by render", function() {
|
||||
var a = {tag: "input", attrs: {checked: false}}
|
||||
var b = {tag: "input", attrs: {checked: true}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
a.dom.checked = true //setting the javascript property makes the value no longer track the state of the attribute
|
||||
a.dom.checked = false
|
||||
|
||||
render(root, [b])
|
||||
|
||||
o(a.dom.checked).equals(true)
|
||||
o(a.dom.attributes["checked"]).equals(undefined)
|
||||
})
|
||||
})
|
||||
o.spec("link href", function() {
|
||||
o("when link href is true, attribute is present", function() {
|
||||
var a = {tag: "a", attrs: {href: true}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.attributes["href"]).notEquals(undefined)
|
||||
})
|
||||
o("when link href is false, attribute is not present", function() {
|
||||
var a = {tag: "a", attrs: {href: false}}
|
||||
|
||||
render(root, [a])
|
||||
|
||||
o(a.dom.attributes["href"]).equals(undefined)
|
||||
})
|
||||
})
|
||||
})
|
||||
82
render/tests/test-createElement.js
Normal file
82
render/tests/test-createElement.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("createElement", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("creates element", function() {
|
||||
var vnode = {tag: "div"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("DIV")
|
||||
})
|
||||
o("creates attr", function() {
|
||||
var vnode = {tag: "div", attrs: {id: "a", title: "b"}}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("DIV")
|
||||
o(vnode.dom.attributes["id"].nodeValue).equals("a")
|
||||
o(vnode.dom.attributes["title"].nodeValue).equals("b")
|
||||
})
|
||||
o("creates style", function() {
|
||||
var vnode = {tag: "div", attrs: {style: {backgroundColor: "red"}}}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("DIV")
|
||||
o(vnode.dom.style.backgroundColor).equals("red")
|
||||
})
|
||||
o("creates children", function() {
|
||||
var vnode = {tag: "div", children: [{tag: "a"}, {tag: "b"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("DIV")
|
||||
o(vnode.dom.childNodes.length).equals(2)
|
||||
o(vnode.dom.childNodes[0].nodeName).equals("A")
|
||||
o(vnode.dom.childNodes[1].nodeName).equals("B")
|
||||
})
|
||||
o("creates attrs and children", function() {
|
||||
var vnode = {tag: "div", attrs: {id: "a", title: "b"}, children: [{tag: "a"}, {tag: "b"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("DIV")
|
||||
o(vnode.dom.attributes["id"].nodeValue).equals("a")
|
||||
o(vnode.dom.attributes["title"].nodeValue).equals("b")
|
||||
o(vnode.dom.childNodes.length).equals(2)
|
||||
o(vnode.dom.childNodes[0].nodeName).equals("A")
|
||||
o(vnode.dom.childNodes[1].nodeName).equals("B")
|
||||
})
|
||||
o("creates svg", function() {
|
||||
var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", children: [{tag: "a", ns: "http://www.w3.org/2000/svg", attrs: {"xlink:href": "javascript:;"}}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("svg")
|
||||
o(vnode.dom.namespaceURI).equals("http://www.w3.org/2000/svg")
|
||||
o(vnode.dom.firstChild.nodeName).equals("a")
|
||||
o(vnode.dom.firstChild.namespaceURI).equals("http://www.w3.org/2000/svg")
|
||||
o(vnode.dom.firstChild.attributes["href"].nodeValue).equals("javascript:;")
|
||||
o(vnode.dom.firstChild.attributes["href"].namespaceURI).equals("http://www.w3.org/1999/xlink")
|
||||
})
|
||||
o("sets attributes correctly for svg", function() {
|
||||
var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", attrs: {viewBox: "0 0 100 100"}}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.attributes["viewBox"].nodeValue).equals("0 0 100 100")
|
||||
})
|
||||
o("creates mathml", function() {
|
||||
var vnode = {tag: "math", ns: "http://www.w3.org/1998/Math/MathML", children: [{tag: "mrow", ns: "http://www.w3.org/1998/Math/MathML"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("math")
|
||||
o(vnode.dom.namespaceURI).equals("http://www.w3.org/1998/Math/MathML")
|
||||
o(vnode.dom.firstChild.nodeName).equals("mrow")
|
||||
o(vnode.dom.firstChild.namespaceURI).equals("http://www.w3.org/1998/Math/MathML")
|
||||
})
|
||||
})
|
||||
50
render/tests/test-createFragment.js
Normal file
50
render/tests/test-createFragment.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("createFragment", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("creates fragment", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "a"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("A")
|
||||
})
|
||||
o("handles empty fragment", function() {
|
||||
var vnode = {tag: "[", children: []}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom).equals(null)
|
||||
o(vnode.domSize).equals(0)
|
||||
})
|
||||
o("handles childless fragment", function() {
|
||||
var vnode = {tag: "["}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom).equals(null)
|
||||
o(vnode.domSize).equals(0)
|
||||
})
|
||||
o("handles multiple children", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "a"}, {tag: "b"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.domSize).equals(2)
|
||||
o(vnode.dom.nodeName).equals("A")
|
||||
o(vnode.dom.nextSibling.nodeName).equals("B")
|
||||
})
|
||||
o("handles td", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "td"}]}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom).notEquals(null)
|
||||
o(vnode.dom.nodeName).equals("TD")
|
||||
})
|
||||
})
|
||||
54
render/tests/test-createHTML.js
Normal file
54
render/tests/test-createHTML.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("createHTML", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("creates HTML", function() {
|
||||
var vnode = {tag: "<", children: "<a></a>"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("A")
|
||||
})
|
||||
o("creates text HTML", function() {
|
||||
var vnode = {tag: "<", children: "a"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeValue).equals("a")
|
||||
})
|
||||
o("handles empty HTML", function() {
|
||||
var vnode = {tag: "<", children: ""}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom).equals(null)
|
||||
o(vnode.domSize).equals(0)
|
||||
})
|
||||
o("handles multiple children", function() {
|
||||
var vnode = {tag: "<", children: "<a></a><b></b>"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.domSize).equals(2)
|
||||
o(vnode.dom.nodeName).equals("A")
|
||||
o(vnode.dom.nextSibling.nodeName).equals("B")
|
||||
})
|
||||
o("handles valid html tags", function() {
|
||||
//FIXME body,head,html,frame,frameset are not supported
|
||||
//FIXME keygen is broken in Firefox
|
||||
var tags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", /*"body",*/ "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", /*"frame", "frameset",*/ "h1", "h2", "h3", "h4", "h5", "h6", /*"head",*/ "header", "hr", /*"html",*/ "i", "iframe", "img", "input", "ins", "kbd", /*"keygen", */"label", "legend", "li", "link", "main", "map", "mark", "menu", "menuitem", "meta", "meter", "nav", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]
|
||||
|
||||
tags.forEach(function(tag) {
|
||||
var vnode = {tag: "<", children: "<" + tag + " />"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals(tag.toUpperCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
62
render/tests/test-createNodes.js
Normal file
62
render/tests/test-createNodes.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("createNodes", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("creates nodes", function() {
|
||||
var vnodes = [
|
||||
{tag: "a"},
|
||||
{tag: "#", children: "b"},
|
||||
{tag: "<", children: "c"},
|
||||
{tag: "[", children: [{tag: "#", children: "d"}]},
|
||||
]
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(root.childNodes[0].nodeName).equals("A")
|
||||
o(root.childNodes[1].nodeValue).equals("b")
|
||||
o(root.childNodes[2].nodeValue).equals("c")
|
||||
o(root.childNodes[3].nodeValue).equals("d")
|
||||
})
|
||||
o("ignores null", function() {
|
||||
var vnodes = [
|
||||
{tag: "a"},
|
||||
{tag: "#", children: "b"},
|
||||
null,
|
||||
{tag: "<", children: "c"},
|
||||
{tag: "[", children: [{tag: "#", children: "d"}]},
|
||||
]
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(root.childNodes[0].nodeName).equals("A")
|
||||
o(root.childNodes[1].nodeValue).equals("b")
|
||||
o(root.childNodes[2].nodeValue).equals("c")
|
||||
o(root.childNodes[3].nodeValue).equals("d")
|
||||
})
|
||||
o("ignores undefined", function() {
|
||||
var vnodes = [
|
||||
{tag: "a"},
|
||||
{tag: "#", children: "b"},
|
||||
undefined,
|
||||
{tag: "<", children: "c"},
|
||||
{tag: "[", children: [{tag: "#", children: "d"}]},
|
||||
]
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(root.childNodes[0].nodeName).equals("A")
|
||||
o(root.childNodes[1].nodeValue).equals("b")
|
||||
o(root.childNodes[2].nodeValue).equals("c")
|
||||
o(root.childNodes[3].nodeValue).equals("d")
|
||||
})
|
||||
})
|
||||
71
render/tests/test-createText.js
Normal file
71
render/tests/test-createText.js
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("createText", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("creates string", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("a")
|
||||
})
|
||||
o("creates falsy string", function() {
|
||||
var vnode = {tag: "#", children: ""}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("")
|
||||
})
|
||||
o("creates number", function() {
|
||||
var vnode = {tag: "#", children: 1}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("1")
|
||||
})
|
||||
o("creates falsy number", function() {
|
||||
var vnode = {tag: "#", children: 0}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("0")
|
||||
})
|
||||
o("creates boolean", function() {
|
||||
var vnode = {tag: "#", children: true}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("true")
|
||||
})
|
||||
o("creates falsy boolean", function() {
|
||||
var vnode = {tag: "#", children: false}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("false")
|
||||
})
|
||||
o("creates spaces", function() {
|
||||
var vnode = {tag: "#", children: " "}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals(" ")
|
||||
})
|
||||
o("ignores html", function() {
|
||||
var vnode = {tag: "#", children: "<a></a>™"}
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.nodeName).equals("#text")
|
||||
o(vnode.dom.nodeValue).equals("<a></a>™")
|
||||
})
|
||||
})
|
||||
34
render/tests/test-event.js
Normal file
34
render/tests/test-event.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("event", function() {
|
||||
var $window, root, onevent, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.body
|
||||
onevent = o.spy()
|
||||
render = vdom($window, onevent).render
|
||||
})
|
||||
|
||||
o("handles onclick", function() {
|
||||
var spy = o.spy()
|
||||
var div = {tag: "div", attrs: {onclick: spy}}
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
render(root, [div])
|
||||
div.dom.dispatchEvent(e)
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
o(spy.this).equals(div.dom)
|
||||
o(spy.args[0].type).equals("click")
|
||||
o(spy.args[0].target).equals(div.dom)
|
||||
o(onevent.callCount).equals(1)
|
||||
o(onevent.this).equals(div.dom)
|
||||
o(onevent.args[0].type).equals("click")
|
||||
o(onevent.args[0].target).equals(div.dom)
|
||||
})
|
||||
})
|
||||
379
render/tests/test-hyperscript.js
Normal file
379
render/tests/test-hyperscript.js
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
var o = require("../../ospec/ospec")
|
||||
var m = require("../../render/hyperscript")
|
||||
|
||||
o.spec("hyperscript", function() {
|
||||
o.spec("selector", function() {
|
||||
o("handles tag in selector", function() {
|
||||
var vnode = m("a")
|
||||
|
||||
o(vnode.tag).equals("a")
|
||||
})
|
||||
o("handles class in selector", function() {
|
||||
var vnode = m(".a")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.className).equals("a")
|
||||
})
|
||||
o("handles many classes in selector", function() {
|
||||
var vnode = m(".a.b.c")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.className).equals("a b c")
|
||||
})
|
||||
o("handles id in selector", function() {
|
||||
var vnode = m("#a")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.id).equals("a")
|
||||
})
|
||||
o("handles attr in selector", function() {
|
||||
var vnode = m("[a=b]")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
})
|
||||
o("handles many attrs in selector", function() {
|
||||
var vnode = m("[a=b][c=d]")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.attrs.c).equals("d")
|
||||
})
|
||||
o("handles attr w/ spaces in selector", function() {
|
||||
var vnode = m("[a = b]")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
})
|
||||
o("handles attr w/ quotes in selector", function() {
|
||||
var vnode = m("[a='b']")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
})
|
||||
o("handles attr w/ quotes and spaces in selector", function() {
|
||||
var vnode = m("[a = 'b']")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
})
|
||||
o("handles many attr w/ quotes and spaces in selector", function() {
|
||||
var vnode = m("[a = 'b'][c = 'd']")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.attrs.c).equals("d")
|
||||
})
|
||||
o("handles tag, class, attrs in selector", function() {
|
||||
var vnode = m("a.b[c = 'd']")
|
||||
|
||||
o(vnode.tag).equals("a")
|
||||
o(vnode.attrs.className).equals("b")
|
||||
o(vnode.attrs.c).equals("d")
|
||||
})
|
||||
o("handles tag, mixed classes, attrs in selector", function() {
|
||||
var vnode = m("a.b[c = 'd'].e[f = 'g']")
|
||||
|
||||
o(vnode.tag).equals("a")
|
||||
o(vnode.attrs.className).equals("b e")
|
||||
o(vnode.attrs.c).equals("d")
|
||||
o(vnode.attrs.f).equals("g")
|
||||
})
|
||||
o("handles attr without value", function() {
|
||||
var vnode = m("[a]")
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals(true)
|
||||
})
|
||||
})
|
||||
o.spec("attrs", function() {
|
||||
o("handles string attr", function() {
|
||||
var vnode = m("div", {a: "b"})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
})
|
||||
o("handles falsy string attr", function() {
|
||||
var vnode = m("div", {a: ""})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("")
|
||||
})
|
||||
o("handles number attr", function() {
|
||||
var vnode = m("div", {a: 1})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals(1)
|
||||
})
|
||||
o("handles falsy number attr", function() {
|
||||
var vnode = m("div", {a: 0})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals(0)
|
||||
})
|
||||
o("handles boolean attr", function() {
|
||||
var vnode = m("div", {a: true})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals(true)
|
||||
})
|
||||
o("handles falsy boolean attr", function() {
|
||||
var vnode = m("div", {a: false})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals(false)
|
||||
})
|
||||
o("handles many attrs", function() {
|
||||
var vnode = m("div", {a: "b", c: "d"})
|
||||
|
||||
o(vnode.tag).equals("div")
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.attrs.c).equals("d")
|
||||
})
|
||||
o("handles merging classes w/ class property", function() {
|
||||
var vnode = m(".a", {class: "b"})
|
||||
|
||||
o(vnode.attrs.className).equals("a b")
|
||||
})
|
||||
o("handles merging classes w/ className property", function() {
|
||||
var vnode = m(".a", {className: "b"})
|
||||
|
||||
o(vnode.attrs.className).equals("a b")
|
||||
})
|
||||
})
|
||||
o.spec("children", function() {
|
||||
o("handles string single child", function() {
|
||||
var vnode = m("div", {}, ["a"])
|
||||
|
||||
o(vnode.text).equals("a")
|
||||
})
|
||||
o("handles falsy string single child", function() {
|
||||
var vnode = m("div", {}, [""])
|
||||
|
||||
o(vnode.text).equals("")
|
||||
})
|
||||
o("handles number single child", function() {
|
||||
var vnode = m("div", {}, [1])
|
||||
|
||||
o(vnode.text).equals(1)
|
||||
})
|
||||
o("handles falsy number single child", function() {
|
||||
var vnode = m("div", {}, [0])
|
||||
|
||||
o(vnode.text).equals(0)
|
||||
})
|
||||
o("handles boolean single child", function() {
|
||||
var vnode = m("div", {}, [true])
|
||||
|
||||
o(vnode.text).equals(true)
|
||||
})
|
||||
o("handles falsy boolean single child", function() {
|
||||
var vnode = m("div", {}, [false])
|
||||
|
||||
o(vnode.text).equals(false)
|
||||
})
|
||||
o("handles null single child", function() {
|
||||
var vnode = m("div", {}, [null])
|
||||
|
||||
o(vnode.children[0]).equals(null)
|
||||
})
|
||||
o("handles undefined single child", function() {
|
||||
var vnode = m("div", {}, [undefined])
|
||||
|
||||
o(vnode.children[0]).equals(undefined)
|
||||
})
|
||||
o("handles multiple string children", function() {
|
||||
var vnode = m("div", {}, ["", "a"])
|
||||
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals("")
|
||||
o(vnode.children[1].tag).equals("#")
|
||||
o(vnode.children[1].children).equals("a")
|
||||
})
|
||||
o("handles multiple number children", function() {
|
||||
var vnode = m("div", {}, [0, 1])
|
||||
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals(0)
|
||||
o(vnode.children[1].tag).equals("#")
|
||||
o(vnode.children[1].children).equals(1)
|
||||
})
|
||||
o("handles multiple boolean children", function() {
|
||||
var vnode = m("div", {}, [false, true])
|
||||
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals(false)
|
||||
o(vnode.children[1].tag).equals("#")
|
||||
o(vnode.children[1].children).equals(true)
|
||||
})
|
||||
o("handles multiple null/undefined child", function() {
|
||||
var vnode = m("div", {}, [null, undefined])
|
||||
|
||||
o(vnode.children[0]).equals(null)
|
||||
o(vnode.children[1]).equals(undefined)
|
||||
})
|
||||
})
|
||||
o.spec("permutations", function() {
|
||||
o("handles null attr and children", function() {
|
||||
var vnode = m("div", null, [m("a"), m("b")])
|
||||
|
||||
o(vnode.children.length).equals(2)
|
||||
o(vnode.children[0].tag).equals("a")
|
||||
o(vnode.children[1].tag).equals("b")
|
||||
})
|
||||
o("handles null attr and child unwrapped", function() {
|
||||
var vnode = m("div", null, m("a"))
|
||||
|
||||
o(vnode.children.length).equals(1)
|
||||
o(vnode.children[0].tag).equals("a")
|
||||
})
|
||||
o("handles null attr and children unwrapped", function() {
|
||||
var vnode = m("div", null, m("a"), m("b"))
|
||||
|
||||
o(vnode.children.length).equals(2)
|
||||
o(vnode.children[0].tag).equals("a")
|
||||
o(vnode.children[1].tag).equals("b")
|
||||
})
|
||||
o("handles attr and children", function() {
|
||||
var vnode = m("div", {a: "b"}, [m("i"), m("s")])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
o(vnode.children[1].tag).equals("s")
|
||||
})
|
||||
o("handles attr and child unwrapped", function() {
|
||||
var vnode = m("div", {a: "b"}, m("i"))
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
})
|
||||
o("handles attr and children unwrapped", function() {
|
||||
var vnode = m("div", {a: "b"}, m("i"), m("s"))
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
o(vnode.children[1].tag).equals("s")
|
||||
})
|
||||
o("handles attr and text children", function() {
|
||||
var vnode = m("div", {a: "b"}, ["c", "d"])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals("c")
|
||||
o(vnode.children[1].tag).equals("#")
|
||||
o(vnode.children[1].children).equals("d")
|
||||
})
|
||||
o("handles attr and single string text child", function() {
|
||||
var vnode = m("div", {a: "b"}, ["c"])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals("c")
|
||||
})
|
||||
o("handles attr and single falsy string text child", function() {
|
||||
var vnode = m("div", {a: "b"}, [""])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals("")
|
||||
})
|
||||
o("handles attr and single number text child", function() {
|
||||
var vnode = m("div", {a: "b"}, [1])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals(1)
|
||||
})
|
||||
o("handles attr and single falsy number text child", function() {
|
||||
var vnode = m("div", {a: "b"}, [0])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals(0)
|
||||
})
|
||||
o("handles attr and single boolean text child", function() {
|
||||
var vnode = m("div", {a: "b"}, [true])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals(true)
|
||||
})
|
||||
o("handles attr and single falsy boolean text child", function() {
|
||||
var vnode = m("div", {a: "b"}, [false])
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals(false)
|
||||
})
|
||||
o("handles attr and single text child unwrapped", function() {
|
||||
var vnode = m("div", {a: "b"}, "c")
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.text).equals("c")
|
||||
})
|
||||
o("handles attr and text children unwrapped", function() {
|
||||
var vnode = m("div", {a: "b"}, "c", "d")
|
||||
|
||||
o(vnode.attrs.a).equals("b")
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals("c")
|
||||
o(vnode.children[1].tag).equals("#")
|
||||
o(vnode.children[1].children).equals("d")
|
||||
})
|
||||
o("handles children without attr", function() {
|
||||
var vnode = m("div", [m("i"), m("s")])
|
||||
|
||||
o(vnode.attrs).equals(undefined)
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
o(vnode.children[1].tag).equals("s")
|
||||
})
|
||||
o("handles child without attr unwrapped", function() {
|
||||
var vnode = m("div", m("i"))
|
||||
|
||||
o(vnode.attrs).equals(undefined)
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
})
|
||||
o("handles children without attr unwrapped", function() {
|
||||
var vnode = m("div", m("i"), m("s"))
|
||||
|
||||
o(vnode.attrs).equals(undefined)
|
||||
o(vnode.children[0].tag).equals("i")
|
||||
o(vnode.children[1].tag).equals("s")
|
||||
})
|
||||
o("handles fragment children without attr unwrapped", function() {
|
||||
var vnode = m("div", [m("i")], [m("s")])
|
||||
|
||||
o(vnode.children[0].tag).equals("[")
|
||||
o(vnode.children[0].children[0].tag).equals("i")
|
||||
o(vnode.children[1].tag).equals("[")
|
||||
o(vnode.children[1].children[0].tag).equals("s")
|
||||
})
|
||||
o("handles children with nested array", function() {
|
||||
var vnode = m("div", [[m("i"), m("s")]])
|
||||
|
||||
o(vnode.children[0].tag).equals("[")
|
||||
o(vnode.children[0].children[0].tag).equals("i")
|
||||
o(vnode.children[0].children[1].tag).equals("s")
|
||||
})
|
||||
o("handles children with deeply nested array", function() {
|
||||
var vnode = m("div", [[[m("i"), m("s")]]])
|
||||
|
||||
o(vnode.children[0].tag).equals("[")
|
||||
o(vnode.children[0].children[0].tag).equals("[")
|
||||
o(vnode.children[0].children[0].children[0].tag).equals("i")
|
||||
o(vnode.children[0].children[0].children[1].tag).equals("s")
|
||||
})
|
||||
})
|
||||
o.spec("namespaced", function() {
|
||||
o("handles svg ns", function() {
|
||||
var vnode = m("svg", m("g"))
|
||||
|
||||
o(vnode.tag).equals("svg")
|
||||
o(vnode.ns).equals("http://www.w3.org/2000/svg")
|
||||
o(vnode.children[0].tag).equals("g")
|
||||
o(vnode.children[0].ns).equals("http://www.w3.org/2000/svg")
|
||||
})
|
||||
o("handles mathml ns", function() {
|
||||
var vnode = m("math", m("mrow"))
|
||||
|
||||
o(vnode.tag).equals("math")
|
||||
o(vnode.ns).equals("http://www.w3.org/1998/Math/MathML")
|
||||
o(vnode.children[0].tag).equals("mrow")
|
||||
o(vnode.children[0].ns).equals("http://www.w3.org/1998/Math/MathML")
|
||||
})
|
||||
})
|
||||
})
|
||||
26
render/tests/test-input.js
Normal file
26
render/tests/test-input.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("input", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.body
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("maintains focus after move", function() {
|
||||
var input = {tag: "input", key: 1}
|
||||
var a = {tag: "a", key: 2}
|
||||
var b = {tag: "b", key: 3}
|
||||
|
||||
render(root, [input, a, b])
|
||||
input.dom.focus()
|
||||
render(root, [a, input, b])
|
||||
|
||||
o($window.document.activeElement).equals(input.dom)
|
||||
})
|
||||
})
|
||||
159
render/tests/test-onbeforeremove.js
Normal file
159
render/tests/test-onbeforeremove.js
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("onbeforeremove", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("does not call onbeforeremove when creating", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onbeforeremove: create}}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
})
|
||||
o("does not call onbeforeremove when updating", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onbeforeremove: create}}
|
||||
var updated = {tag: "div", attrs: {onbeforeremove: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("calls onbeforeremove when removing element", function(done) {
|
||||
var vnode = {tag: "div", attrs: {onbeforeremove: remove}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
function remove(node, complete) {
|
||||
o(node).equals(vnode)
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(vnode.dom)
|
||||
|
||||
callAsync(function() {
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
complete()
|
||||
|
||||
o(root.childNodes.length).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
o("calls onbeforeremove when removing text", function(done) {
|
||||
var vnode = {tag: "#", attrs: {onbeforeremove: remove}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
function remove(node, complete) {
|
||||
o(node).equals(vnode)
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(vnode.dom)
|
||||
|
||||
callAsync(function() {
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
complete()
|
||||
|
||||
o(root.childNodes.length).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
o("calls onbeforeremove when removing fragment", function(done) {
|
||||
var vnode = {tag: "[", attrs: {onbeforeremove: remove}, children: [{tag: "div"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
function remove(node, complete) {
|
||||
o(node).equals(vnode)
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(vnode.dom)
|
||||
|
||||
callAsync(function() {
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
complete()
|
||||
|
||||
o(root.childNodes.length).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
o("calls onbeforeremove when removing html", function(done) {
|
||||
var vnode = {tag: "<", attrs: {onbeforeremove: remove}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
function remove(node, complete) {
|
||||
o(node).equals(vnode)
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(vnode.dom)
|
||||
|
||||
callAsync(function() {
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
complete()
|
||||
|
||||
o(root.childNodes.length).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
o("calls remove after onbeforeremove resolves", function(done) {
|
||||
var spy = o.spy()
|
||||
var vnode = {tag: "<", attrs: {onbeforeremove: remove, onremove: spy}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
function remove(node, complete) {
|
||||
o(node).equals(vnode)
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(vnode.dom)
|
||||
|
||||
callAsync(function() {
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(spy.callCount).equals(0)
|
||||
|
||||
complete()
|
||||
|
||||
o(root.childNodes.length).equals(0)
|
||||
o(spy.callCount).equals(1)
|
||||
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
o("does not set onbeforeremove as an event handler", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onbeforeremove: remove}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.onbeforeremove).equals(undefined)
|
||||
o(vnode.dom.attributes["onbeforeremove"]).equals(undefined)
|
||||
})
|
||||
})
|
||||
216
render/tests/test-oncreate.js
Normal file
216
render/tests/test-oncreate.js
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("oncreate", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("calls oncreate when creating element", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: callback}}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oncreate when creating text", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "#", attrs: {oncreate: callback}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oncreate when creating fragment", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "[", attrs: {oncreate: callback}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oncreate when creating html", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "<", attrs: {oncreate: callback}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oncreate when replacing keyed", function() {
|
||||
var createDiv = o.spy()
|
||||
var createA = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oncreate: createDiv}}
|
||||
var updated = {tag: "a", key: 1, attrs: {oncreate: createA}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(createDiv.callCount).equals(1)
|
||||
o(createDiv.this).equals(vnode)
|
||||
o(createDiv.args[0]).equals(vnode)
|
||||
o(createA.callCount).equals(1)
|
||||
o(createA.this).equals(updated)
|
||||
o(createA.args[0]).equals(updated)
|
||||
})
|
||||
o("does not call oncreate when noop", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: create}}
|
||||
var updated = {tag: "div", attrs: {oncreate: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call oncreate when updating attr", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: create}}
|
||||
var updated = {tag: "div", attrs: {oncreate: update, id: "a"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call oncreate when updating children", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: create}, children: [{tag: "a"}]}
|
||||
var updated = {tag: "div", attrs: {oncreate: update}, children: [{tag: "b"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call oncreate when updating keyed", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oncreate: create}}
|
||||
var otherVnode = {tag: "a", key: 2}
|
||||
var updated = {tag: "div", key: 1, attrs: {oncreate: update}}
|
||||
var otherUpdated = {tag: "a", key: 2}
|
||||
|
||||
render(root, [vnode, otherVnode])
|
||||
render(root, [otherUpdated, updated])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call oncreate when removing", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: create}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oncreate when recycling", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oncreate: create}}
|
||||
var updated = {tag: "div", key: 1, attrs: {oncreate: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
render(root, [updated])
|
||||
|
||||
o(vnode.dom).equals(updated.dom)
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls oncreate at the same step as onupdate", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}, children: []}
|
||||
var updated = {tag: "div", attrs: {onupdate: update}, children: [{tag: "a", attrs: {oncreate: callback}}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(updated.children[0])
|
||||
o(callback.args[0]).equals(updated.children[0])
|
||||
})
|
||||
o("calls oncreate after full DOM creation", function() {
|
||||
var created = false
|
||||
var vnode = {tag: "div", children: [
|
||||
{tag: "a", attrs: {oncreate: create}, children: [
|
||||
{tag: "b"}
|
||||
]}
|
||||
]}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
function create(vnode) {
|
||||
created = true
|
||||
|
||||
o(vnode.dom.parentNode).notEquals(null)
|
||||
o(vnode.dom.childNodes.length).equals(1)
|
||||
}
|
||||
o(created).equals(true)
|
||||
})
|
||||
o("does not set oncreate as an event handler", function() {
|
||||
var create = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oncreate: create}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.oncreate).equals(undefined)
|
||||
o(vnode.dom.attributes["oncreate"]).equals(undefined)
|
||||
})
|
||||
o("calls oncreate on recycle", function() {
|
||||
var create = o.spy()
|
||||
var vnodes = [{tag: "div", key: 1, attrs: {oncreate: create}}]
|
||||
var temp = []
|
||||
var updated = [{tag: "div", key: 1, attrs: {oncreate: create}}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(create.callCount).equals(2)
|
||||
})
|
||||
})
|
||||
103
render/tests/test-onremove.js
Normal file
103
render/tests/test-onremove.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("onremove", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("does not call onremove when creating", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onremove: create}}
|
||||
var updated = {tag: "div", attrs: {onremove: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
})
|
||||
o("does not call onremove when updating", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onremove: create}}
|
||||
var updated = {tag: "div", attrs: {onremove: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("calls onremove when removing element", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onremove: remove}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(remove.callCount).equals(1)
|
||||
o(remove.this).equals(vnode)
|
||||
o(remove.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls onremove when removing text", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "#", attrs: {onremove: remove}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(remove.callCount).equals(1)
|
||||
o(remove.this).equals(vnode)
|
||||
o(remove.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls onremove when removing fragment", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "[", attrs: {onremove: remove}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(remove.callCount).equals(1)
|
||||
o(remove.this).equals(vnode)
|
||||
o(remove.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls onremove when removing html", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "<", attrs: {onremove: remove}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(remove.callCount).equals(1)
|
||||
o(remove.this).equals(vnode)
|
||||
o(remove.args[0]).equals(vnode)
|
||||
})
|
||||
o("does not set onremove as an event handler", function() {
|
||||
var remove = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onremove: remove}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.onremove).equals(undefined)
|
||||
o(vnode.dom.attributes["onremove"]).equals(undefined)
|
||||
})
|
||||
o("calls onremove on recycle", function() {
|
||||
var remove = o.spy()
|
||||
var vnodes = [{tag: "div", key: 1}]
|
||||
var temp = [{tag: "div", key: 2, attrs: {onremove: remove}}]
|
||||
var updated = [{tag: "div", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(remove.callCount).equals(1)
|
||||
})
|
||||
})
|
||||
192
render/tests/test-onupdate.js
Normal file
192
render/tests/test-onupdate.js
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("onupdate", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("does not call onupdate when creating element", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}}
|
||||
var updated = {tag: "div", attrs: {onupdate: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("does not call onupdate when removing element", function() {
|
||||
var create = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
})
|
||||
o("does not call onupdate when replacing keyed element", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {onupdate: create}}
|
||||
var updated = {tag: "a", key: 1, attrs: {onupdate: update}}
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call onupdate when recycling", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {onupdate: create}}
|
||||
var updated = {tag: "div", key: 1, attrs: {onupdate: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
render(root, [updated])
|
||||
|
||||
o(vnode.dom).equals(updated.dom)
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(0)
|
||||
})
|
||||
o("does not call old onupdate when removing the onupdate property in new vnode", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "a", attrs: {onupdate: create}}
|
||||
var updated = {tag: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
})
|
||||
o("calls onupdate when noop", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}}
|
||||
var updated = {tag: "div", attrs: {onupdate: update}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate when updating attr", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}}
|
||||
var updated = {tag: "div", attrs: {onupdate: update, id: "a"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate when updating children", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: create}, children: [{tag: "a"}]}
|
||||
var updated = {tag: "div", attrs: {onupdate: update}, children: [{tag: "b"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate when updating text", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "#", attrs: {onupdate: create}, children: "a"}
|
||||
var updated = {tag: "#", attrs: {onupdate: update}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate when updating fragment", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "[", attrs: {onupdate: create}, children: []}
|
||||
var updated = {tag: "[", attrs: {onupdate: update}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate when updating html", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "<", attrs: {onupdate: create}, children: "a"}
|
||||
var updated = {tag: "<", attrs: {onupdate: update}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(create.callCount).equals(0)
|
||||
o(update.callCount).equals(1)
|
||||
o(update.this).equals(updated)
|
||||
o(update.args[0]).equals(updated)
|
||||
})
|
||||
o("calls onupdate after full DOM update", function() {
|
||||
var called = false
|
||||
var vnode = {tag: "div", attrs: {id: "1"}, children: [
|
||||
{tag: "a", attrs: {id: "2"}, children: [
|
||||
{tag: "b", attrs: {id: "3"}}
|
||||
]}
|
||||
]}
|
||||
var updated = {tag: "div", attrs: {id: "11"}, children: [
|
||||
{tag: "a", attrs: {onupdate: update, id: "22"}, children: [
|
||||
{tag: "b", attrs: {id: "33"}}
|
||||
]}
|
||||
]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
function update(vnode) {
|
||||
called = true
|
||||
|
||||
o(vnode.dom.parentNode.attributes["id"].nodeValue).equals("11")
|
||||
o(vnode.dom.attributes["id"].nodeValue).equals("22")
|
||||
o(vnode.dom.childNodes[0].attributes["id"].nodeValue).equals("33")
|
||||
}
|
||||
o(called).equals(true)
|
||||
})
|
||||
o("does not set onupdate as an event handler", function() {
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {onupdate: update}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.onupdate).equals(undefined)
|
||||
o(vnode.dom.attributes["onupdate"]).equals(undefined)
|
||||
})
|
||||
})
|
||||
0
render/tests/test-style.js
Normal file
0
render/tests/test-style.js
Normal file
200
render/tests/test-textContent.js
Normal file
200
render/tests/test-textContent.js
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("textContent", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("ignores null", function() {
|
||||
var vnodes = [{tag: "a", text: null}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(0)
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("ignores undefined", function() {
|
||||
var vnodes = [{tag: "a", text: undefined}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(0)
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates string", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("a")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates falsy string", function() {
|
||||
var vnodes = [{tag: "a", text: ""}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates number", function() {
|
||||
var vnodes = [{tag: "a", text: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("1")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates falsy number", function() {
|
||||
var vnodes = [{tag: "a", text: 0}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("0")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates boolean", function() {
|
||||
var vnodes = [{tag: "a", text: true}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("true")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("creates falsy boolean", function() {
|
||||
var vnodes = [{tag: "a", text: false}]
|
||||
|
||||
render(root, vnodes)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("false")
|
||||
o(vnodes[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to string", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: "b"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("b")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to falsy string", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: ""}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to number", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("1")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to falsy number", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: 0}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("0")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to boolean", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: true}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("true")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates to falsy boolean", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a", text: false}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("false")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates with typecasting", function() {
|
||||
var vnodes = [{tag: "a", text: "1"}]
|
||||
var updated = [{tag: "a", text: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("1")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates from without text to with text", function() {
|
||||
var vnodes = [{tag: "a"}]
|
||||
var updated = [{tag: "a", text: "b"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes[0].nodeValue).equals("b")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("updates from with text to without text", function() {
|
||||
var vnodes = [{tag: "a", text: "a"}]
|
||||
var updated = [{tag: "a"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(vnodes[0].dom.childNodes.length).equals(0)
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
})
|
||||
152
render/tests/test-updateElement.js
Normal file
152
render/tests/test-updateElement.js
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("updateElement", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("updates attr", function() {
|
||||
var vnode = {tag: "a", attrs: {id: "b"}}
|
||||
var updated = {tag: "a", attrs: {id: "c"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.attributes["id"].nodeValue).equals("c")
|
||||
})
|
||||
o("adds attr", function() {
|
||||
var vnode = {tag: "a", attrs: {id: "b"}}
|
||||
var updated = {tag: "a", attrs: {id: "c", title: "d"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.attributes["title"].nodeValue).equals("d")
|
||||
})
|
||||
o("removes attr", function() {
|
||||
var vnode = {tag: "a", attrs: {id: "b", title: "d"}}
|
||||
var updated = {tag: "a", attrs: {id: "c"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o("title" in updated.dom.attributes).equals(false)
|
||||
})
|
||||
o("creates style object", function() {
|
||||
var vnode = {tag: "a", attrs: {}}
|
||||
var updated = {tag: "a", attrs: {style: {backgroundColor: "green"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("creates style string", function() {
|
||||
var vnode = {tag: "a", attrs: {}}
|
||||
var updated = {tag: "a", attrs: {style: "background-color:green"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("updates style from object to object", function() {
|
||||
var vnode = {tag: "a", attrs: {style: {backgroundColor: "red"}}}
|
||||
var updated = {tag: "a", attrs: {style: {backgroundColor: "green"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("updates style from object to string", function() {
|
||||
var vnode = {tag: "a", attrs: {style: {backgroundColor: "red"}}}
|
||||
var updated = {tag: "a", attrs: {style: "background-color:green;"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("updates style from string to object", function() {
|
||||
var vnode = {tag: "a", attrs: {style: "background-color:red;"}}
|
||||
var updated = {tag: "a", attrs: {style: {backgroundColor: "green"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("updates style from string to string", function() {
|
||||
var vnode = {tag: "a", attrs: {style: "background-color:red;"}}
|
||||
var updated = {tag: "a", attrs: {style: "background-color:green;"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("green")
|
||||
})
|
||||
o("removes style from object to object", function() {
|
||||
var vnode = {tag: "a", attrs: {style: {backgroundColor: "red", border: "1px solid red"}}}
|
||||
var updated = {tag: "a", attrs: {style: {backgroundColor: "red"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("red")
|
||||
o(updated.dom.style.border).equals("")
|
||||
})
|
||||
o("removes style from string to object", function() {
|
||||
var vnode = {tag: "a", attrs: {style: "background-color:red;border:1px solid red"}}
|
||||
var updated = {tag: "a", attrs: {style: {backgroundColor: "red"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("red")
|
||||
o(updated.dom.style.border).notEquals("1px solid red")
|
||||
})
|
||||
o("removes style from object to string", function() {
|
||||
var vnode = {tag: "a", attrs: {style: {backgroundColor: "red", border: "1px solid red"}}}
|
||||
var updated = {tag: "a", attrs: {style: "background-color:red"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("red")
|
||||
o(updated.dom.style.border).equals("")
|
||||
})
|
||||
o("removes style from string to string", function() {
|
||||
var vnode = {tag: "a", attrs: {style: "background-color:red;border:1px solid red"}}
|
||||
var updated = {tag: "a", attrs: {style: "background-color:red"}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom.style.backgroundColor).equals("red")
|
||||
o(updated.dom.style.border).equals("")
|
||||
})
|
||||
o("replaces el", function() {
|
||||
var vnode = {tag: "a"}
|
||||
var updated = {tag: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeName).equals("B")
|
||||
})
|
||||
})
|
||||
69
render/tests/test-updateFragment.js
Normal file
69
render/tests/test-updateFragment.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("updateFragment", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("updates fragment", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "a"}]}
|
||||
var updated = {tag: "[", children: [{tag: "b"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeName).equals("B")
|
||||
})
|
||||
o("adds els", function() {
|
||||
var vnode = {tag: "[", children: []}
|
||||
var updated = {tag: "[", children: [{tag: "a"}, {tag: "b"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.domSize).equals(2)
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(root.childNodes[0].nodeName).equals("A")
|
||||
o(root.childNodes[1].nodeName).equals("B")
|
||||
})
|
||||
o("removes els", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "a"}, {tag: "b"}]}
|
||||
var updated = {tag: "[", children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(null)
|
||||
o(updated.domSize).equals(0)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
o("updates from childless fragment", function() {
|
||||
var vnode = {tag: "["}
|
||||
var updated = {tag: "[", children: [{tag: "a"}]}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeName).equals("A")
|
||||
})
|
||||
o("updates to childless fragment", function() {
|
||||
var vnode = {tag: "[", children: [{tag: "a"}]}
|
||||
var updated = {tag: "["}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(null)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
})
|
||||
49
render/tests/test-updateHTML.js
Normal file
49
render/tests/test-updateHTML.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("updateHTML", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("updates html", function() {
|
||||
var vnode = {tag: "<", children: "a"}
|
||||
var updated = {tag: "<", children: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("b")
|
||||
})
|
||||
o("adds html", function() {
|
||||
var vnode = {tag: "<", children: ""}
|
||||
var updated = {tag: "<", children: "<a></a><b></b>"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.domSize).equals(2)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(root.childNodes[0].nodeName).equals("A")
|
||||
o(root.childNodes[1].nodeName).equals("B")
|
||||
})
|
||||
o("removes html", function() {
|
||||
var vnode = {tag: "<", children: "<a></a><b></b>"}
|
||||
var updated = {tag: "<", children: ""}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(null)
|
||||
o(updated.domSize).equals(0)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
})
|
||||
789
render/tests/test-updateNodes.js
Normal file
789
render/tests/test-updateNodes.js
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("updateNodes", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("handles el noop", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("handles el noop without key", function() {
|
||||
var vnodes = [{tag: "a"}, {tag: "b"}]
|
||||
var updated = [{tag: "a"}, {tag: "b"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("handles text noop", function() {
|
||||
var vnodes = [{tag: "#", children: "a"}]
|
||||
var updated = [{tag: "#", children: "a"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeValue).equals("a")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("handles text noop w/ type casting", function() {
|
||||
var vnodes = [{tag: "#", children: 1}]
|
||||
var updated = [{tag: "#", children: "1"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeValue).equals("1")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("handles falsy text noop w/ type casting", function() {
|
||||
var vnodes = [{tag: "#", children: 0}]
|
||||
var updated = [{tag: "#", children: "0"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeValue).equals("0")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("handles html noop", function() {
|
||||
var vnodes = [{tag: "<", children: "a"}]
|
||||
var updated = [{tag: "<", children: "a"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeValue).equals("a")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("handles fragment noop", function() {
|
||||
var vnodes = [{tag: "[", children: [{tag: "a"}]}]
|
||||
var updated = [{tag: "[", children: [{tag: "a"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("handles fragment noop w/ text child", function() {
|
||||
var vnodes = [{tag: "[", children: [{tag: "#", children: "a"}]}]
|
||||
var updated = [{tag: "[", children: [{tag: "#", children: "a"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeValue).equals("a")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("reverses els w/ even count", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
var updated = [{tag: "s", key: 4}, {tag: "i", key: 3}, {tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("B")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
o(updated[3].dom.nodeName).equals("A")
|
||||
o(updated[3].dom).equals(root.childNodes[3])
|
||||
})
|
||||
o("reverses els w/ odd count", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}]
|
||||
var updated = [{tag: "i", key: 3}, {tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("A")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("creates el at start", function() {
|
||||
var vnodes = [{tag: "a", key: 1}]
|
||||
var updated = [{tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("B")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("creates el at end", function() {
|
||||
var vnodes = [{tag: "a", key: 1}]
|
||||
var updated = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("creates el in middle", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "a", key: 1}, {tag: "i", key: 3}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("B")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("creates el while reversing", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("B")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("A")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("deletes el at start", function() {
|
||||
var vnodes = [{tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
var updated = [{tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("deletes el at end", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("deletes el at middle", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "i", key: 3}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("deletes el while reversing", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "i", key: 3}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("B")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("creates, deletes, reverses els at same time", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "i", key: 3}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "b", key: 2}, {tag: "a", key: 1}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("B")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("S")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("adds to empty array followed by el", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: []}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "a"}]}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].children[0].dom.nodeName).equals("A")
|
||||
o(updated[0].children[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("reverses followed by el", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: [{tag: "a", key: 2}, {tag: "b", key: 3}]}, {tag: "i", key: 4}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "b", key: 3}, {tag: "a", key: 2}]}, {tag: "i", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].children[0].dom.nodeName).equals("B")
|
||||
o(updated[0].children[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].children[1].dom.nodeName).equals("A")
|
||||
o(updated[0].children[1].dom).equals(root.childNodes[1])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("updates empty array to html with same key", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: []}]
|
||||
var updated = [{tag: "<", key: 1, children: "<a></a><b></b>"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates empty html to array with same key", function() {
|
||||
var vnodes = [{tag: "<", key: 1, children: ""}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "a"}, {tag: "b"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates empty array to html without key", function() {
|
||||
var vnodes = [{tag: "[", children: []}]
|
||||
var updated = [{tag: "<", children: "<a></a><b></b>"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates empty html to array without key", function() {
|
||||
var vnodes = [{tag: "<", children: ""}]
|
||||
var updated = [{tag: "[", children: [{tag: "a"}, {tag: "b"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates array to html with same key", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: [{tag: "a"}, {tag: "b"}]}]
|
||||
var updated = [{tag: "<", key: 1, children: "<i></i><s></s>"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("S")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates html to array with same key", function() {
|
||||
var vnodes = [{tag: "<", key: 1, children: "<a></a><b></b>"}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "i"}, {tag: "s"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("S")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates array to html without key", function() {
|
||||
var vnodes = [{tag: "[", children: [{tag: "a"}, {tag: "b"}]}]
|
||||
var updated = [{tag: "<", children: "<i></i><s></s>"}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("S")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates html to array without key", function() {
|
||||
var vnodes = [{tag: "<", children: "<a></a><b></b>"}]
|
||||
var updated = [{tag: "[", children: [{tag: "i"}, {tag: "s"}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("S")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
})
|
||||
o("updates empty array to html with same key followed by el", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: []}, {tag: "i", key: 2}]
|
||||
var updated = [{tag: "<", key: 1, children: "<a></a><b></b>"}, {tag: "i", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("updates empty html to array with same key followed by el", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: []}, {tag: "i", key: 2}]
|
||||
var updated = [{tag: "<", key: 1, children: "<a></a><b></b>"}, {tag: "i", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("populates array followed by null then el", function() {
|
||||
var vnodes = [{tag: "[", key: 1, children: []}, null, {tag: "i", key: 2}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "a"}, {tag: "b"}]}, null, {tag: "i", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("I")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("populates childless array followed by el", function() {
|
||||
var vnodes = [{tag: "[", key: 1}, {tag: "i", key: 2}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "a"}, {tag: "b"}]}, {tag: "i", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("populates childless array followed by null then el", function() {
|
||||
var vnodes = [{tag: "[", key: 1}, null, {tag: "i", key: 2}]
|
||||
var updated = [{tag: "[", key: 1, children: [{tag: "a"}, {tag: "b"}]}, null, {tag: "i", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[0].domSize).equals(2)
|
||||
o(updated[0].dom.nextSibling.nodeName).equals("B")
|
||||
o(updated[0].dom.nextSibling).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("I")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("moves from end to start", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
var updated = [{tag: "s", key: 4}, {tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("B")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
o(updated[3].dom.nodeName).equals("I")
|
||||
o(updated[3].dom).equals(root.childNodes[3])
|
||||
})
|
||||
o("moves from start to end", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
var updated = [{tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(updated[0].dom.nodeName).equals("B")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("S")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
o(updated[3].dom.nodeName).equals("A")
|
||||
o(updated[3].dom).equals(root.childNodes[3])
|
||||
})
|
||||
o("removes then recreate", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("I")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
o(updated[3].dom.nodeName).equals("S")
|
||||
o(updated[3].dom).equals(root.childNodes[3])
|
||||
})
|
||||
o("removes then recreate reversed", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
var temp = []
|
||||
var updated = [{tag: "s", key: 4}, {tag: "i", key: 3}, {tag: "b", key: 2}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(4)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("B")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
o(updated[3].dom.nodeName).equals("A")
|
||||
o(updated[3].dom).equals(root.childNodes[3])
|
||||
})
|
||||
o("removes then recreate smaller", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("removes then recreate bigger", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("I")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("removes then create different", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("S")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("removes then create different smaller", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "i", key: 3}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
})
|
||||
o("removes then create different bigger", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "i", key: 3}, {tag: "s", key: 4}, {tag: "div", key: 5}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("I")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("S")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("DIV")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("removes then create mixed", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("S")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("removes then create mixed reversed", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "s", key: 4}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("removes then create mixed smaller", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("S")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("removes then create mixed smaller reversed", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}]
|
||||
var temp = []
|
||||
var updated = [{tag: "s", key: 4}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("A")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
})
|
||||
o("removes then create mixed bigger", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1}, {tag: "i", key: 3}, {tag: "s", key: 4}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("S")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("removes then create mixed bigger reversed", function() {
|
||||
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "s", key: 4}, {tag: "i", key: 3}, {tag: "a", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(3)
|
||||
o(updated[0].dom.nodeName).equals("S")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("I")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[2].dom.nodeName).equals("A")
|
||||
o(updated[2].dom).equals(root.childNodes[2])
|
||||
})
|
||||
o("removes then recreates then reverses children", function() {
|
||||
var vnodes = [{tag: "a", key: 1, children: [{tag: "i", key: 3}, {tag: "s", key: 4}]}, {tag: "b", key: 2}]
|
||||
var temp1 = []
|
||||
var temp2 = [{tag: "a", key: 1, children: [{tag: "i", key: 3}, {tag: "s", key: 4}]}, {tag: "b", key: 2}]
|
||||
var updated = [{tag: "a", key: 1, children: [{tag: "s", key: 4}, {tag: "i", key: 3}]}, {tag: "b", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp1)
|
||||
render(root, temp2)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(updated[0].dom.nodeName).equals("A")
|
||||
o(updated[0].dom).equals(root.childNodes[0])
|
||||
o(updated[1].dom.nodeName).equals("B")
|
||||
o(updated[1].dom).equals(root.childNodes[1])
|
||||
o(updated[0].dom.childNodes.length).equals(2)
|
||||
o(updated[0].dom.childNodes[0].nodeName).equals("S")
|
||||
o(updated[0].dom.childNodes[1].nodeName).equals("I")
|
||||
})
|
||||
o("removes then recreates nested", function() {
|
||||
var vnodes = [{tag: "a", key: 1, children: [{tag: "a", key: 3, children: [{tag: "a", key: 5}]}, {tag: "a", key: 4, children: [{tag: "a", key: 5}]}]}, {tag: "a", key: 2}]
|
||||
var temp = []
|
||||
var updated = [{tag: "a", key: 1, children: [{tag: "a", key: 3, children: [{tag: "a", key: 5}]}, {tag: "a", key: 4, children: [{tag: "a", key: 5}]}]}, {tag: "a", key: 2}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(root.childNodes[0].childNodes.length).equals(2)
|
||||
o(root.childNodes[0].childNodes[0].childNodes.length).equals(1)
|
||||
o(root.childNodes[0].childNodes[1].childNodes.length).equals(1)
|
||||
o(root.childNodes[1].childNodes.length).equals(0)
|
||||
})
|
||||
o("recycles", function() {
|
||||
var vnodes = [{tag: "div", key: 1}]
|
||||
var temp = []
|
||||
var updated = [{tag: "div", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(vnodes[0].dom).equals(updated[0].dom)
|
||||
o(updated[0].dom.nodeName).equals("DIV")
|
||||
})
|
||||
o("recycles when toggling", function() {
|
||||
var vnodes = [{tag: "div", key: 1}]
|
||||
var temp = [{tag: "div"}]
|
||||
var updated = [{tag: "div", key: 1}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(vnodes[0].dom).equals(updated[0].dom)
|
||||
o(updated[0].dom.nodeName).equals("DIV")
|
||||
})
|
||||
o("recycles deep", function() {
|
||||
var vnodes = [{tag: "div", children: [{tag: "a", key: 1}]}]
|
||||
var temp = [{tag: "div"}]
|
||||
var updated = [{tag: "div", children: [{tag: "a", key: 1}]}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(vnodes[0].dom.firstChild).equals(updated[0].dom.firstChild)
|
||||
o(updated[0].dom.firstChild.nodeName).equals("A")
|
||||
})
|
||||
})
|
||||
114
render/tests/test-updateText.js
Normal file
114
render/tests/test-updateText.js
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("updateText", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("updates to string", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("b")
|
||||
})
|
||||
o("updates to falsy string", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: ""}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("")
|
||||
})
|
||||
o("updates from falsy string", function() {
|
||||
var vnode = {tag: "#", children: ""}
|
||||
var updated = {tag: "#", children: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("b")
|
||||
})
|
||||
o("updates to number", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: 1}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("1")
|
||||
})
|
||||
o("updates to falsy number", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: 0}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("0")
|
||||
})
|
||||
o("updates from falsy number", function() {
|
||||
var vnode = {tag: "#", children: 0}
|
||||
var updated = {tag: "#", children: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("b")
|
||||
})
|
||||
o("updates to boolean", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: true}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("true")
|
||||
})
|
||||
o("updates to falsy boolean", function() {
|
||||
var vnode = {tag: "#", children: "a"}
|
||||
var updated = {tag: "#", children: false}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("false")
|
||||
})
|
||||
o("updates from falsy boolean", function() {
|
||||
var vnode = {tag: "#", children: false}
|
||||
var updated = {tag: "#", children: "b"}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [updated])
|
||||
|
||||
o(updated.dom).equals(vnode.dom)
|
||||
o(updated.dom).equals(root.firstChild)
|
||||
o(updated.dom.nodeValue).equals("b")
|
||||
})
|
||||
})
|
||||
3
render/trust.js
Normal file
3
render/trust.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function(html) {
|
||||
return {tag: "<", key: undefined, attrs: undefined, children: html, text: undefined}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue