Update: Add elem to parent before adding its children

This commit is contained in:
Gyandeep Singh 2017-02-07 20:55:53 -06:00
parent 23a1693c02
commit 390e1fe343
2 changed files with 29 additions and 23 deletions

View file

@ -14,30 +14,32 @@ module.exports = function($window) {
for (var i = start; i < end; i++) { for (var i = start; i < end; i++) {
var vnode = vnodes[i] var vnode = vnodes[i]
if (vnode != null) { if (vnode != null) {
insertNode(parent, createNode(vnode, hooks, ns), nextSibling) createNode(parent, vnode, hooks, ns, nextSibling)
} }
} }
} }
function createNode(vnode, hooks, ns) { function createNode(parent, vnode, hooks, ns, nextSibling) {
var tag = vnode.tag var tag = vnode.tag
if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks) if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
if (typeof tag === "string") { if (typeof tag === "string") {
switch (tag) { switch (tag) {
case "#": return createText(vnode) case "#": return createText(parent, vnode, nextSibling)
case "<": return createHTML(vnode) case "<": return createHTML(parent, vnode, nextSibling)
case "[": return createFragment(vnode, hooks, ns) case "[": return createFragment(parent, vnode, hooks, ns, nextSibling)
default: return createElement(vnode, hooks, ns) default: return createElement(parent, vnode, hooks, ns, nextSibling)
} }
} }
else return createComponent(vnode, hooks, ns) else return createComponent(parent, vnode, hooks, ns, nextSibling)
} }
function createText(vnode) { function createText(parent, vnode, nextSibling) {
return vnode.dom = $doc.createTextNode(vnode.children) vnode.dom = $doc.createTextNode(vnode.children)
insertNode(parent, vnode.dom, nextSibling)
return vnode.dom
} }
function createHTML(vnode) { function createHTML(parent, vnode, nextSibling) {
var match = vnode.children.match(/^\s*?<(\w+)/im) || [] 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 parent1 = {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) var temp = $doc.createElement(parent1)
temp.innerHTML = vnode.children temp.innerHTML = vnode.children
vnode.dom = temp.firstChild vnode.dom = temp.firstChild
@ -47,9 +49,10 @@ module.exports = function($window) {
while (child = temp.firstChild) { while (child = temp.firstChild) {
fragment.appendChild(child) fragment.appendChild(child)
} }
insertNode(parent, fragment, nextSibling)
return fragment return fragment
} }
function createFragment(vnode, hooks, ns) { function createFragment(parent, vnode, hooks, ns, nextSibling) {
var fragment = $doc.createDocumentFragment() var fragment = $doc.createDocumentFragment()
if (vnode.children != null) { if (vnode.children != null) {
var children = vnode.children var children = vnode.children
@ -57,9 +60,10 @@ module.exports = function($window) {
} }
vnode.dom = fragment.firstChild vnode.dom = fragment.firstChild
vnode.domSize = fragment.childNodes.length vnode.domSize = fragment.childNodes.length
insertNode(parent, fragment, nextSibling)
return fragment return fragment
} }
function createElement(vnode, hooks, ns) { function createElement(parent, vnode, hooks, ns, nextSibling) {
var tag = vnode.tag var tag = vnode.tag
switch (vnode.tag) { switch (vnode.tag) {
case "svg": ns = "http://www.w3.org/2000/svg"; break case "svg": ns = "http://www.w3.org/2000/svg"; break
@ -78,6 +82,8 @@ module.exports = function($window) {
setAttrs(vnode, attrs, ns) setAttrs(vnode, attrs, ns)
} }
insertNode(parent, element, nextSibling)
if (vnode.attrs != null && vnode.attrs.contenteditable != null) { if (vnode.attrs != null && vnode.attrs.contenteditable != null) {
setContentEditable(vnode) setContentEditable(vnode)
} }
@ -94,7 +100,7 @@ module.exports = function($window) {
} }
return element return element
} }
function createComponent(vnode, hooks, ns) { function createComponent(parent, vnode, hooks, ns, nextSibling) {
vnode.state = Object.create(vnode.tag) vnode.state = Object.create(vnode.tag)
var view = vnode.tag.view var view = vnode.tag.view
if (view.reentrantLock != null) return $emptyFragment if (view.reentrantLock != null) return $emptyFragment
@ -104,9 +110,10 @@ module.exports = function($window) {
view.reentrantLock = null view.reentrantLock = null
if (vnode.instance != null) { if (vnode.instance != null) {
if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as arguments") if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as arguments")
var element = createNode(vnode.instance, hooks, ns) var element = createNode(parent, vnode.instance, hooks, ns, nextSibling)
vnode.dom = vnode.instance.dom vnode.dom = vnode.instance.dom
vnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0 vnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0
insertNode(parent, element, nextSibling)
return element return element
} }
else { else {
@ -132,7 +139,7 @@ module.exports = function($window) {
if (isUnkeyed) { if (isUnkeyed) {
for (var i = 0; i < old.length; i++) { for (var i = 0; i < old.length; i++) {
if (old[i] === vnodes[i]) continue if (old[i] === vnodes[i]) continue
else if (old[i] == null && vnodes[i] != null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling)) else if (old[i] == null && vnodes[i] != null) createNode(parent, vnodes[i], hooks, ns, getNextSibling(old, i + 1, nextSibling))
else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes) else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns) else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns)
} }
@ -189,8 +196,7 @@ module.exports = function($window) {
if (movable.dom != null) nextSibling = movable.dom if (movable.dom != null) nextSibling = movable.dom
} }
else { else {
var dom = createNode(v, hooks, undefined) var dom = createNode(parent, v, hooks, undefined, nextSibling)
insertNode(parent, dom, nextSibling)
nextSibling = dom nextSibling = dom
} }
} }
@ -223,7 +229,7 @@ module.exports = function($window) {
} }
else { else {
removeNode(old, null) removeNode(old, null)
insertNode(parent, createNode(vnode, hooks, ns), nextSibling) createNode(parent, vnode, hooks, ns, nextSibling)
} }
} }
function updateText(old, vnode) { function updateText(old, vnode) {
@ -235,7 +241,7 @@ module.exports = function($window) {
function updateHTML(parent, old, vnode, nextSibling) { function updateHTML(parent, old, vnode, nextSibling) {
if (old.children !== vnode.children) { if (old.children !== vnode.children) {
toFragment(old) toFragment(old)
insertNode(parent, createHTML(vnode), nextSibling) createHTML(parent, vnode, nextSibling)
} }
else vnode.dom = old.dom, vnode.domSize = old.domSize else vnode.dom = old.dom, vnode.domSize = old.domSize
} }
@ -284,7 +290,7 @@ module.exports = function($window) {
vnode.instance = Vnode.normalize(vnode.tag.view.call(vnode.state, vnode)) vnode.instance = Vnode.normalize(vnode.tag.view.call(vnode.state, vnode))
updateLifecycle(vnode.tag, vnode, hooks, recycling) updateLifecycle(vnode.tag, vnode, hooks, recycling)
if (vnode.instance != null) { if (vnode.instance != null) {
if (old.instance == null) insertNode(parent, createNode(vnode.instance, hooks, ns), nextSibling) if (old.instance == null) createNode(parent, vnode.instance, hooks, ns, nextSibling)
else updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns) else updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns)
vnode.dom = vnode.instance.dom vnode.dom = vnode.instance.dom
vnode.domSize = vnode.instance.domSize vnode.domSize = vnode.instance.domSize

View file

@ -187,7 +187,7 @@ o.spec("oninit", function() {
called = true called = true
o(vnode.dom).equals(undefined) o(vnode.dom).equals(undefined)
o(root.childNodes.length).equals(0) o(root.childNodes.length).equals(1)
} }
o(called).equals(true) o(called).equals(true)
}) })