Make onbeforeremove done() handlers more robust.

This commit is contained in:
Pierre-Yves Gerardy 2016-08-16 22:48:58 +02:00
parent 0ddad54e88
commit 0b5800d09a

View file

@ -203,7 +203,7 @@ module.exports = function($window) {
else updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns)
}
else {
removeNode(parent, old, null, false)
removeNode(parent, old, null)
insertNode(parent, createNode(vnode, hooks, undefined), nextSibling)
}
}
@ -265,7 +265,7 @@ module.exports = function($window) {
vnode.domSize = vnode.instance.domSize
}
else if (old.instance != null) {
removeNode(parent, old.instance, null, false)
removeNode(parent, old.instance, null)
vnode.dom = undefined
vnode.domSize = 0
}
@ -327,27 +327,32 @@ module.exports = function($window) {
var vnode = vnodes[i]
if (vnode != null) {
if (vnode.skip) vnode.skip = false
else removeNode(parent, vnode, context, false)
else removeNode(parent, vnode, context)
}
}
}
function removeNode(parent, vnode, context, deferred) {
if (deferred === false) {
var expected = 0, called = 0
var callback = function() {
if (++called === expected) removeNode(parent, vnode, context, true)
function once(f) {
var called = false
return function() {
if (!called) {
called = true
f()
}
}
}
function removeNode(parent, vnode, context) {
var expected = 1, called = 0
if (vnode.attrs && vnode.attrs.onbeforeremove) {
expected++
vnode.attrs.onbeforeremove.call(vnode.state, vnode, callback)
vnode.attrs.onbeforeremove.call(vnode.state, vnode, once(continuation))
}
if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) {
expected++
vnode.tag.onbeforeremove.call(vnode.state, vnode, callback)
vnode.tag.onbeforeremove.call(vnode.state, vnode, once(continuation))
}
if (expected > 0) return
}
continuation()
function continuation() {
if (++called === expected) {
onremove(vnode)
if (vnode.dom) {
var count = vnode.domSize || 1
@ -364,6 +369,8 @@ module.exports = function($window) {
}
}
}
}
}
function onremove(vnode) {
if (vnode.attrs && vnode.attrs.onremove) vnode.attrs.onremove.call(vnode.state, vnode)
if (typeof vnode.tag !== "string" && vnode.tag.onremove) vnode.tag.onremove.call(vnode.state, vnode)