From 0b5800d09a0d23e3bda0f1cb363c40db2178457c Mon Sep 17 00:00:00 2001 From: Pierre-Yves Gerardy Date: Tue, 16 Aug 2016 22:48:58 +0200 Subject: [PATCH] Make `onbeforeremove` `done()` handlers more robust. --- render/render.js | 67 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/render/render.js b/render/render.js index f0fad6a1..40874142 100644 --- a/render/render.js +++ b/render/render.js @@ -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,41 +327,48 @@ 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() } - if (vnode.attrs && vnode.attrs.onbeforeremove) { - expected++ - vnode.attrs.onbeforeremove.call(vnode.state, vnode, callback) - } - if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) { - expected++ - vnode.tag.onbeforeremove.call(vnode.state, vnode, callback) - } - if (expected > 0) return } - - onremove(vnode) - if (vnode.dom) { - var count = vnode.domSize || 1 - if (count > 1) { - var dom = vnode.dom - while (--count) { - parent.removeChild(dom.nextSibling) + } + function removeNode(parent, vnode, context) { + var expected = 1, called = 0 + if (vnode.attrs && vnode.attrs.onbeforeremove) { + expected++ + 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, once(continuation)) + } + continuation() + function continuation() { + if (++called === expected) { + 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 && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string") { //TODO test custom elements + if (!context.pool) context.pool = [vnode] + else context.pool.push(vnode) + } } } - if (vnode.dom.parentNode != null) parent.removeChild(vnode.dom) - if (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string") { //TODO test custom elements - if (!context.pool) context.pool = [vnode] - else context.pool.push(vnode) - } } } function onremove(vnode) {