components, angular dbmon
This commit is contained in:
parent
ba378d3652
commit
3282ef3f77
30 changed files with 1270 additions and 248 deletions
|
|
@ -1,43 +1,51 @@
|
|||
"use strict"
|
||||
|
||||
var normalizeChildren = require("../render/normalizeChildren")
|
||||
var Node = require("../render/node")
|
||||
|
||||
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 (typeof selector === "string") {
|
||||
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 (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})
|
||||
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
|
||||
|
||||
var vnode = Node(tag || "div", attrs.key, hasAttrs ? attrs : undefined, childList, text, undefined)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
var attrs, children, childrenIndex
|
||||
|
|
@ -54,15 +62,8 @@ function hyperscript(selector) {
|
|||
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
|
||||
if (typeof selector === "string") return selectorCache[selector](attrs || {}, Node.normalizeChildren(children))
|
||||
return Node(selector, attrs && attrs.key, attrs, Node.normalizeChildren(children), undefined, undefined)
|
||||
}
|
||||
|
||||
function changeNS(ns, vnode) {
|
||||
|
|
|
|||
16
render/node.js
Normal file
16
render/node.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
function Node(tag, key, attrs, children, text, dom) {
|
||||
return {tag: tag, key: key, attrs: attrs, children: children, text: text, dom: dom, domSize: undefined, state: {}}
|
||||
}
|
||||
Node.normalize = function(node) {
|
||||
if (node instanceof Array) return Node("[", undefined, undefined, Node.normalizeChildren(node), undefined, undefined)
|
||||
else if (node != null && typeof node !== "object") return Node("#", undefined, undefined, node, undefined, undefined)
|
||||
return node
|
||||
}
|
||||
Node.normalizeChildren = function normalizeChildren(children) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
children[i] = Node.normalize(children[i])
|
||||
}
|
||||
return children
|
||||
}
|
||||
|
||||
module.exports = Node
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
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
|
||||
}
|
||||
104
render/render.js
104
render/render.js
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var normalizeChildren = require("../render/normalizeChildren")
|
||||
var Node = require("../render/node")
|
||||
|
||||
module.exports = function($window, onevent) {
|
||||
var $doc = $window.document
|
||||
|
|
@ -16,15 +16,19 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
function createNode(vnode, hooks) {
|
||||
var tag = vnode.tag
|
||||
if (vnode.attrs && vnode.attrs.oncreate) {
|
||||
hooks.push(vnode.attrs.oncreate.bind(vnode, vnode))
|
||||
if (vnode.attrs) {
|
||||
if (vnode.attrs.oninit) vnode.attrs.oninit.call(vnode, vnode)
|
||||
if (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)
|
||||
if (typeof tag === "string") {
|
||||
switch (tag) {
|
||||
case "#": return createText(vnode)
|
||||
case "<": return createHTML(vnode)
|
||||
case "[": return createFragment(vnode, hooks)
|
||||
default: return createElement(vnode, hooks)
|
||||
}
|
||||
}
|
||||
else return createComponent(vnode, hooks)
|
||||
}
|
||||
function createText(vnode) {
|
||||
return vnode.dom = $doc.createTextNode(vnode.children)
|
||||
|
|
@ -72,7 +76,7 @@ module.exports = function($window, onevent) {
|
|||
|
||||
if (vnode.text != null) {
|
||||
if (vnode.text !== "") element.textContent = vnode.text
|
||||
else vnode.children = [{tag: "#", children: vnode.text}]
|
||||
else vnode.children = [Node("#", undefined, undefined, vnode.text, undefined, undefined)]
|
||||
}
|
||||
|
||||
if (vnode.children != null) {
|
||||
|
|
@ -81,6 +85,14 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
return element
|
||||
}
|
||||
function createComponent(vnode, hooks) {
|
||||
vnode.instance = Node.normalize(vnode.tag.view(vnode))
|
||||
initLifecycle(vnode.tag, vnode, hooks)
|
||||
var element = createNode(vnode.instance, hooks)
|
||||
vnode.dom = vnode.instance.dom
|
||||
vnode.domSize = vnode.instance.domSize
|
||||
return element
|
||||
}
|
||||
|
||||
//update
|
||||
function updateNodes(parent, old, vnodes, hooks, nextSibling) {
|
||||
|
|
@ -98,7 +110,7 @@ module.exports = function($window, onevent) {
|
|||
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)
|
||||
if (recycling) insertNode(parent, toFragment(o), nextSibling)
|
||||
}
|
||||
else {
|
||||
var o = old[oldEnd]
|
||||
|
|
@ -116,7 +128,7 @@ module.exports = function($window, onevent) {
|
|||
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)
|
||||
if (recycling) insertNode(parent, toFragment(o), nextSibling)
|
||||
nextSibling = o.dom
|
||||
oldEnd--, end--
|
||||
}
|
||||
|
|
@ -148,16 +160,17 @@ module.exports = function($window, onevent) {
|
|||
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)
|
||||
vnode.state = old.state
|
||||
if (vnode.attrs != null) updateLifecycle(vnode.attrs, vnode, hooks, recycling)
|
||||
if (typeof oldTag === "string") {
|
||||
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 updateComponent(parent, old, vnode, hooks, nextSibling, recycling)
|
||||
}
|
||||
else {
|
||||
removeNode(parent, old, null, false)
|
||||
|
|
@ -189,7 +202,7 @@ module.exports = function($window, onevent) {
|
|||
domSize += child.domSize || 1
|
||||
}
|
||||
}
|
||||
if (domSize != 1) vnode.domSize = domSize
|
||||
if (domSize !== 1) vnode.domSize = domSize
|
||||
}
|
||||
}
|
||||
function updateElement(old, vnode, hooks) {
|
||||
|
|
@ -199,11 +212,18 @@ module.exports = function($window, onevent) {
|
|||
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}]
|
||||
if (old.text != null) old.children = [Node("#", undefined, undefined, old.text, undefined, old.dom.firstChild)]
|
||||
if (vnode.text != null) vnode.children = [Node("#", undefined, undefined, vnode.text, undefined, undefined)]
|
||||
updateNodes(element, old.children, vnode.children, hooks, null)
|
||||
}
|
||||
}
|
||||
function updateComponent(parent, old, vnode, hooks, nextSibling, recycling) {
|
||||
vnode.instance = Node.normalize(vnode.tag.view(vnode))
|
||||
updateLifecycle(vnode.tag, vnode, hooks, recycling)
|
||||
updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling)
|
||||
vnode.dom = vnode.instance.dom
|
||||
vnode.domSize = vnode.instance.domSize
|
||||
}
|
||||
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
|
||||
|
|
@ -262,9 +282,20 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
}
|
||||
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
|
||||
if (deferred === false) {
|
||||
var expected = 0, called = 0
|
||||
var callback = function() {
|
||||
if (++called === expected) removeNode(parent, vnode, context, true)
|
||||
}
|
||||
if (vnode.attrs && vnode.attrs.onbeforeremove) {
|
||||
expected++
|
||||
vnode.attrs.onbeforeremove.call(vnode, vnode, callback)
|
||||
}
|
||||
if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) {
|
||||
expected++
|
||||
vnode.tag.onbeforeremove.call(vnode, vnode, callback)
|
||||
}
|
||||
if (expected > 0) return
|
||||
}
|
||||
|
||||
onremove(vnode)
|
||||
|
|
@ -285,9 +316,10 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
function onremove(vnode) {
|
||||
if (vnode.attrs && vnode.attrs.onremove) vnode.attrs.onremove.call(vnode, vnode)
|
||||
if (typeof vnode.tag !== "string" && vnode.tag.onremove) vnode.tag.onremove.call(vnode, vnode)
|
||||
|
||||
var children = vnode.children
|
||||
if (children) {
|
||||
if (children instanceof Array) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i]
|
||||
if (child != null) onremove(child)
|
||||
|
|
@ -341,7 +373,7 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
}
|
||||
function isLifecycleMethod(attr) {
|
||||
return attr === "oncreate" || attr === "onupdate" || attr === "onremove" || attr === "onbeforeremove"
|
||||
return attr === "oninit" || attr === "oncreate" || attr === "onupdate" || attr === "onremove" || attr === "onbeforeremove"
|
||||
}
|
||||
function isAttribute(attr) {
|
||||
return attr === "href" || attr === "list" || attr === "form"// || attr === "type" || attr === "width" || attr === "height"
|
||||
|
|
@ -364,15 +396,23 @@ module.exports = function($window, onevent) {
|
|||
}
|
||||
}
|
||||
|
||||
//lifecycle
|
||||
function initLifecycle(source, vnode, hooks) {
|
||||
if (source.oninit != null) source.oninit.call(vnode, vnode)
|
||||
if (source.oncreate != null) hooks.push(source.oncreate.bind(vnode, vnode))
|
||||
}
|
||||
function updateLifecycle(source, vnode, hooks, recycling) {
|
||||
if (recycling) initLifecycle(source, vnode, hooks)
|
||||
else if (source.onupdate != null) hooks.push(source.onupdate.bind(vnode, vnode))
|
||||
}
|
||||
|
||||
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 (dom.vnodes == null) dom.vnodes = []
|
||||
|
||||
if (!(vnodes instanceof Array)) vnodes = [vnodes]
|
||||
updateNodes(dom, dom.vnodes, normalizeChildren(vnodes), hooks, null)
|
||||
updateNodes(dom, dom.vnodes, Node.normalizeChildren(vnodes), hooks, null)
|
||||
for (var i = 0; i < hooks.length; i++) hooks[i]()
|
||||
dom.vnodes = vnodes
|
||||
if ($doc.activeElement !== active) active.focus()
|
||||
|
|
|
|||
|
|
@ -9,10 +9,14 @@
|
|||
<script src="../../test-utils/callAsync.js"></script>
|
||||
<script src="../../test-utils/domMock.js"></script>
|
||||
|
||||
<script src="../../render/normalizeChildren.js"></script>
|
||||
<script src="../../render/node.js"></script>
|
||||
<script src="../../render/trust.js"></script>
|
||||
<script src="../../render/hyperscript.js"></script>
|
||||
<script src="../../render/render.js"></script>
|
||||
<script src="test-hyperscript.js"></script>
|
||||
<script src="test-trust.js"></script>
|
||||
<script src="test-normalize.js"></script>
|
||||
<script src="test-normalizeChildren.js"></script>
|
||||
<script src="test-createText.js"></script>
|
||||
<script src="test-createHTML.js"></script>
|
||||
<script src="test-createFragment.js"></script>
|
||||
|
|
@ -23,6 +27,7 @@
|
|||
<script src="test-updateFragment.js"></script>
|
||||
<script src="test-updateElement.js"></script>
|
||||
<script src="test-updateNodes.js"></script>
|
||||
<script src="test-oninit.js"></script>
|
||||
<script src="test-oncreate.js"></script>
|
||||
<script src="test-onupdate.js"></script>
|
||||
<script src="test-onremove.js"></script>
|
||||
|
|
@ -31,6 +36,7 @@
|
|||
<script src="test-event.js"></script>
|
||||
<script src="test-input.js"></script>
|
||||
<script src="test-textContent.js"></script>
|
||||
<script src="test-component.js"></script>
|
||||
|
||||
<script>require("../../ospec/ospec").run()</script>
|
||||
</body>
|
||||
|
|
|
|||
459
render/tests/test-component.js
Normal file
459
render/tests/test-component.js
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("component", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o.spec("basics", function() {
|
||||
o("works", function() {
|
||||
var component = {
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
var node = {tag: component}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("receives arguments", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return {tag: "div", attrs: vnode.attrs, text: vnode.text}
|
||||
}
|
||||
}
|
||||
var node = {tag: component, attrs: {id: "a"}, text: "b"}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("updates", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return {tag: "div", attrs: vnode.attrs, text: vnode.text}
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component, attrs: {id: "a"}, text: "b"}])
|
||||
render(root, [{tag: component, attrs: {id: "c"}, text: "d"}])
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("c")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("d")
|
||||
})
|
||||
o("removes", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return {tag: "div"}
|
||||
}
|
||||
}
|
||||
var div = {tag: "div", key: 2}
|
||||
render(root, [{tag: component, key: 1}, div])
|
||||
render(root, [{tag: "div", key: 2}])
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(div.dom)
|
||||
})
|
||||
})
|
||||
o.spec("return value", function() {
|
||||
o("can return fragments", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return [
|
||||
{tag: "label"},
|
||||
{tag: "input"},
|
||||
]
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(root.childNodes[0].nodeName).equals("LABEL")
|
||||
o(root.childNodes[1].nodeName).equals("INPUT")
|
||||
})
|
||||
o("can return string", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return "a"
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("a")
|
||||
})
|
||||
o("can return falsy string", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("")
|
||||
})
|
||||
o("can return number", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("1")
|
||||
})
|
||||
o("can return falsy number", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("0")
|
||||
})
|
||||
o("can return boolean", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("true")
|
||||
})
|
||||
o("can return falsy boolean", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("false")
|
||||
})
|
||||
o("can update when returning fragments", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return [
|
||||
{tag: "label"},
|
||||
{tag: "input"},
|
||||
]
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.childNodes.length).equals(2)
|
||||
o(root.childNodes[0].nodeName).equals("LABEL")
|
||||
o(root.childNodes[1].nodeName).equals("INPUT")
|
||||
})
|
||||
o("can update when returning primitive", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return "a"
|
||||
}
|
||||
}
|
||||
render(root, [{tag: component}])
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(root.firstChild.nodeType).equals(3)
|
||||
o(root.firstChild.nodeValue).equals("a")
|
||||
})
|
||||
o("can remove when returning fragments", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return [
|
||||
{tag: "label"},
|
||||
{tag: "input"},
|
||||
]
|
||||
}
|
||||
}
|
||||
var div = {tag: "div", key: 2}
|
||||
render(root, [{tag: component, key: 1}, div])
|
||||
|
||||
render(root, [{tag: "div", key: 2}])
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(div.dom)
|
||||
})
|
||||
o("can remove when returning primitive", function() {
|
||||
var component = {
|
||||
view: function(vnode) {
|
||||
return "a"
|
||||
}
|
||||
}
|
||||
var div = {tag: "div", key: 2}
|
||||
render(root, [{tag: component, key: 1}, div])
|
||||
|
||||
render(root, [{tag: "div", key: 2}])
|
||||
|
||||
o(root.childNodes.length).equals(1)
|
||||
o(root.firstChild).equals(div.dom)
|
||||
})
|
||||
})
|
||||
o.spec("lifecycle", function() {
|
||||
o("calls oninit", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
oninit: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.tag).equals(component)
|
||||
o(vnode.dom).equals(undefined)
|
||||
o(root.childNodes.length).equals(0)
|
||||
},
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
var node = {tag: component}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls oninit when returning fragment", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
oninit: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.tag).equals(component)
|
||||
o(vnode.dom).equals(undefined)
|
||||
o(root.childNodes.length).equals(0)
|
||||
},
|
||||
view: function() {
|
||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||
}
|
||||
}
|
||||
var node = {tag: component}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls oncreate", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
oncreate: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
var node = {tag: component}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls oncreate when returning fragment", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
oncreate: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||
}
|
||||
}
|
||||
var node = {tag: component}
|
||||
|
||||
render(root, [node])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls onupdate", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onupdate: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls onupdate when returning fragment", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onupdate: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
o(root.firstChild.attributes["id"].nodeValue).equals("a")
|
||||
o(root.firstChild.firstChild.nodeValue).equals("b")
|
||||
})
|
||||
o("calls onremove", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onremove: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
o("calls onremove when returning fragment", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onremove: function(vnode) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
},
|
||||
view: function() {
|
||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
o("calls onbeforeremove", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onbeforeremove: function(vnode, done) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
done()
|
||||
},
|
||||
view: function() {
|
||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
o("calls onbeforeremove when returning fragment", function() {
|
||||
var called = 0
|
||||
var component = {
|
||||
onbeforeremove: function(vnode, done) {
|
||||
called++
|
||||
|
||||
o(vnode.dom).notEquals(undefined)
|
||||
o(vnode.dom).equals(root.firstChild)
|
||||
o(root.childNodes.length).equals(1)
|
||||
|
||||
done()
|
||||
},
|
||||
view: function() {
|
||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||
}
|
||||
}
|
||||
|
||||
render(root, [{tag: component}])
|
||||
|
||||
o(called).equals(0)
|
||||
|
||||
render(root, [])
|
||||
|
||||
o(called).equals(1)
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -376,4 +376,20 @@ o.spec("hyperscript", function() {
|
|||
o(vnode.children[0].ns).equals("http://www.w3.org/1998/Math/MathML")
|
||||
})
|
||||
})
|
||||
o.spec("components", function() {
|
||||
o("works", function() {
|
||||
var component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
var vnode = m(component, {id: "a"}, "b")
|
||||
|
||||
o(vnode.tag).equals(component)
|
||||
o(vnode.attrs.id).equals("a")
|
||||
o(vnode.children.length).equals(1)
|
||||
o(vnode.children[0].tag).equals("#")
|
||||
o(vnode.children[0].children).equals("b")
|
||||
})
|
||||
})
|
||||
})
|
||||
58
render/tests/test-normalize.js
Normal file
58
render/tests/test-normalize.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var Node = require("../../render/node")
|
||||
|
||||
o.spec("normalize", function() {
|
||||
o("normalizes array into fragment", function() {
|
||||
var node = Node.normalize([])
|
||||
|
||||
o(node.tag).equals("[")
|
||||
o(node.children.length).equals(0)
|
||||
})
|
||||
o("normalizes nested array into fragment", function() {
|
||||
var node = Node.normalize([[]])
|
||||
|
||||
o(node.tag).equals("[")
|
||||
o(node.children.length).equals(1)
|
||||
o(node.children[0].tag).equals("[")
|
||||
o(node.children[0].children.length).equals(0)
|
||||
})
|
||||
o("normalizes string into text node", function() {
|
||||
var node = Node.normalize("a")
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals("a")
|
||||
})
|
||||
o("normalizes falsy string into text node", function() {
|
||||
var node = Node.normalize("")
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals("")
|
||||
})
|
||||
o("normalizes number into text node", function() {
|
||||
var node = Node.normalize(1)
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals(1)
|
||||
})
|
||||
o("normalizes falsy number into text node", function() {
|
||||
var node = Node.normalize(0)
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals(0)
|
||||
})
|
||||
o("normalizes boolean into text node", function() {
|
||||
var node = Node.normalize(true)
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals(true)
|
||||
})
|
||||
o("normalizes falsy boolean into text node", function() {
|
||||
var node = Node.normalize(false)
|
||||
|
||||
o(node.tag).equals("#")
|
||||
o(node.children).equals(false)
|
||||
})
|
||||
})
|
||||
|
||||
20
render/tests/test-normalizeChildren.js
Normal file
20
render/tests/test-normalizeChildren.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var Node = require("../../render/node")
|
||||
|
||||
o.spec("normalizeChildren", function() {
|
||||
o("normalizes arrays into fragments", function() {
|
||||
var children = Node.normalizeChildren([[]])
|
||||
|
||||
o(children[0].tag).equals("[")
|
||||
o(children[0].children.length).equals(0)
|
||||
})
|
||||
o("normalizes strings into text nodes", function() {
|
||||
var children = Node.normalizeChildren(["a"])
|
||||
|
||||
o(children[0].tag).equals("#")
|
||||
o(children[0].children).equals("a")
|
||||
})
|
||||
})
|
||||
|
||||
216
render/tests/test-oninit.js
Normal file
216
render/tests/test-oninit.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("oninit", function() {
|
||||
var $window, root, render
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.createElement("div")
|
||||
render = vdom($window).render
|
||||
})
|
||||
|
||||
o("calls oninit when creating element", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: callback}}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oninit when creating text", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "#", attrs: {oninit: callback}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oninit when creating fragment", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "[", attrs: {oninit: callback}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oninit when creating html", function() {
|
||||
var callback = o.spy()
|
||||
var vnode = {tag: "<", attrs: {oninit: callback}, children: "a"}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(callback.callCount).equals(1)
|
||||
o(callback.this).equals(vnode)
|
||||
o(callback.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oninit when replacing keyed", function() {
|
||||
var createDiv = o.spy()
|
||||
var createA = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oninit: createDiv}}
|
||||
var updated = {tag: "a", key: 1, attrs: {oninit: 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 oninit when noop", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: create}}
|
||||
var updated = {tag: "div", attrs: {oninit: 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 oninit when updating attr", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: create}}
|
||||
var updated = {tag: "div", attrs: {oninit: 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 oninit when updating children", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: create}, children: [{tag: "a"}]}
|
||||
var updated = {tag: "div", attrs: {oninit: 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 oninit when updating keyed", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oninit: create}}
|
||||
var otherVnode = {tag: "a", key: 2}
|
||||
var updated = {tag: "div", key: 1, attrs: {oninit: 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 oninit when removing", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: create}}
|
||||
|
||||
render(root, [vnode])
|
||||
render(root, [])
|
||||
|
||||
o(create.callCount).equals(1)
|
||||
o(create.this).equals(vnode)
|
||||
o(create.args[0]).equals(vnode)
|
||||
})
|
||||
o("calls oninit when recycling", function() {
|
||||
var create = o.spy()
|
||||
var update = o.spy()
|
||||
var vnode = {tag: "div", key: 1, attrs: {oninit: create}}
|
||||
var updated = {tag: "div", key: 1, attrs: {oninit: 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 oninit 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: {oninit: 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 oninit before full DOM creation", function() {
|
||||
var called = false
|
||||
var vnode = {tag: "div", children: [
|
||||
{tag: "a", attrs: {oninit: create}, children: [
|
||||
{tag: "b"}
|
||||
]}
|
||||
]}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
function create(vnode) {
|
||||
called = true
|
||||
|
||||
o(vnode.dom).equals(undefined)
|
||||
o(root.childNodes.length).equals(0)
|
||||
}
|
||||
o(called).equals(true)
|
||||
})
|
||||
o("does not set oninit as an event handler", function() {
|
||||
var create = o.spy()
|
||||
var vnode = {tag: "div", attrs: {oninit: create}, children: []}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.oninit).equals(undefined)
|
||||
o(vnode.dom.attributes["oninit"]).equals(undefined)
|
||||
})
|
||||
o("calls oninit on recycle", function() {
|
||||
var create = o.spy()
|
||||
var vnodes = [{tag: "div", key: 1, attrs: {oninit: create}}]
|
||||
var temp = []
|
||||
var updated = [{tag: "div", key: 1, attrs: {oninit: create}}]
|
||||
|
||||
render(root, vnodes)
|
||||
render(root, temp)
|
||||
render(root, updated)
|
||||
|
||||
o(create.callCount).equals(2)
|
||||
})
|
||||
})
|
||||
20
render/tests/test-trust.js
Normal file
20
render/tests/test-trust.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var trust = require("../../render/trust")
|
||||
|
||||
o.spec("trust", function() {
|
||||
o("works with html", function() {
|
||||
var vnode = trust("<a></a>")
|
||||
|
||||
o(vnode.tag).equals("<")
|
||||
o(vnode.children).equals("<a></a>")
|
||||
})
|
||||
o("works with text", function() {
|
||||
var vnode = trust("abc")
|
||||
|
||||
o(vnode.tag).equals("<")
|
||||
o(vnode.children).equals("abc")
|
||||
})
|
||||
})
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
"use strict"
|
||||
|
||||
var Node = require("../render/node")
|
||||
|
||||
module.exports = function(html) {
|
||||
return {tag: "<", key: undefined, attrs: undefined, children: html, text: undefined}
|
||||
return Node("<", undefined, undefined, html, undefined, undefined)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue