From 7227cc546f5599ffef463a0754737d974389cdbf Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Tue, 12 Jul 2016 11:30:58 -0400 Subject: [PATCH] fix recycling when tag is different in unkeyed node --- mithril.js | 6 ++++-- render/render.js | 6 +++--- render/tests/test-updateNodes.js | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/mithril.js b/mithril.js index 4c9795e9..ee63e707 100644 --- a/mithril.js +++ b/mithril.js @@ -341,6 +341,7 @@ var renderService = function($window) { 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] @@ -348,7 +349,7 @@ var renderService = function($window) { else if (o != null && v != null && o.key === v.key) { oldStart++, start++ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns) - if (recycling) insertNode(parent, toFragment(o), nextSibling) + if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) } else { var o = old[oldEnd] @@ -366,7 +367,7 @@ var renderService = function($window) { 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, ns) - if (recycling) insertNode(parent, toFragment(o), nextSibling) + if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) nextSibling = o.dom oldEnd--, end-- } @@ -1065,6 +1066,7 @@ m.route = function($window, renderer, pubsub) { route.prefix = router.setPrefix route.set = router.setPath route.get = router.getPath + return route }(window, renderService, redrawService) m.mount = function(renderer, pubsub) { diff --git a/render/render.js b/render/render.js index afe4cb8c..52abd954 100644 --- a/render/render.js +++ b/render/render.js @@ -112,7 +112,7 @@ module.exports = function($window) { 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] @@ -120,7 +120,7 @@ module.exports = function($window) { else if (o != null && v != null && o.key === v.key) { oldStart++, start++ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns) - if (recycling) insertNode(parent, toFragment(o), nextSibling) + if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) } else { var o = old[oldEnd] @@ -138,7 +138,7 @@ module.exports = function($window) { 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, ns) - if (recycling) insertNode(parent, toFragment(o), nextSibling) + if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) nextSibling = o.dom oldEnd--, end-- } diff --git a/render/tests/test-updateNodes.js b/render/tests/test-updateNodes.js index da4b29d7..29ea9fe9 100644 --- a/render/tests/test-updateNodes.js +++ b/render/tests/test-updateNodes.js @@ -787,4 +787,30 @@ o.spec("updateNodes", function() { o(vnodes[0].dom.firstChild).equals(updated[0].dom.firstChild) o(updated[0].dom.firstChild.nodeName).equals("A") }) + o("mixed unkeyed tags are not broken by recycle", function() { + var vnodes = [{tag: "a"}, {tag: "b"}] + var temp = [{tag: "b"}] + var updated = [{tag: "a"}, {tag: "b"}] + + render(root, vnodes) + render(root, temp) + render(root, updated) + + o(root.childNodes.length).equals(2) + o(root.childNodes[0].nodeName).equals("A") + o(root.childNodes[1].nodeName).equals("B") + }) + o("mixed unkeyed vnode types are not broken by recycle", function() { + var vnodes = [{tag: "[", children: [{tag: "a"}]}, {tag: "b"}] + var temp = [{tag: "b"}] + var updated = [{tag: "[", children: [{tag: "a"}]}, {tag: "b"}] + + render(root, vnodes) + render(root, temp) + render(root, updated) + + o(root.childNodes.length).equals(2) + o(root.childNodes[0].nodeName).equals("A") + o(root.childNodes[1].nodeName).equals("B") + }) })