diff --git a/docs/change-log.md b/docs/change-log.md index 454e2b8b..b4f5e5be 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -1,5 +1,14 @@ ## Change Log +[v0.1.18](/mithril/archive/v0.1.18) - maintenance + +### Bug Fixes: + +- routing now correctly clears diff cache [#148](https://github.com/lhorie/mithril.js/issues/148) +- fixed incorrect context unloading when reattaching a child to a new parent + +--- + [v0.1.17](/mithril/archive/v0.1.17) - maintenance ### News: diff --git a/mithril.js b/mithril.js index ba9fa9c2..22509d5e 100644 --- a/mithril.js +++ b/mithril.js @@ -123,7 +123,10 @@ Mithril = m = new function app(window) { } else if (dataType == "[object Object]") { - if (data.tag != cached.tag || Object.keys(data.attrs).join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) clear(cached.nodes, cached) + if (data.tag != cached.tag || Object.keys(data.attrs).join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) { + clear(cached.nodes) + if (cached.configContext && typeof cached.configContext.onunload == "function") cached.configContext.onunload() + } if (typeof data.tag != "string") return var node, isNew = cached.nodes.length === 0 @@ -238,7 +241,10 @@ Mithril = m = new function app(window) { } function unload(cached) { if (cached.configContext && typeof cached.configContext.onunload == "function") cached.configContext.onunload() - if (cached.children instanceof Array) for (var i = 0; i < cached.children.length; i++) unload(cached.children[i]) + if (cached.children) { + if (cached.children instanceof Array) for (var i = 0; i < cached.children.length; i++) unload(cached.children[i]) + else if (cached.children.tag) unload(cached.children) + } } function injectHTML(parentElement, index, data) { var nextSibling = parentElement.childNodes[index] diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 28666706..77f27497 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -603,6 +603,44 @@ function testMithril(mock) { ]) return unloaded == 0 }) + test(function() { + var root = mock.document.createElement("div") + var unloadedParent = 0 + var unloadedChild = 0 + var configParent = function(el, init, ctx) { + ctx.onunload = function() { + unloadedParent++ + } + } + var configChild = function(el, init, ctx) { + ctx.onunload = function() { + unloadedChild++ + } + } + var unloaded = 0 + m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) + m.render(root, m("main", {config: configParent}, m("a", {config: configChild}))) + return unloadedParent === 1 && unloadedChild === 0 + }) + test(function() { + var root = mock.document.createElement("div") + var unloadedParent = 0 + var unloadedChild = 0 + var configParent = function(el, init, ctx) { + ctx.onunload = function() { + unloadedParent++ + } + } + var configChild = function(el, init, ctx) { + ctx.onunload = function() { + unloadedChild++ + } + } + var unloaded = 0 + m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) + m.render(root, m("main", {config: configParent}, m("b", {config: configChild}))) + return unloadedParent === 1 && unloadedChild === 1 + }) //end m.render //m.redraw @@ -1161,10 +1199,40 @@ function testMithril(mock) { var foo = root.childNodes[0].childNodes[0].nodeValue; m.route("/bar") mock.performance.$elapse(50) //teardown - console.log(root.childNodes) var bar = root.childNodes[0].childNodes[0].nodeValue; return (foo === "foo" && bar === "bar") }) + test(function() { + mock.performance.$elapse(50) //setup + mock.location.search = "?" + + var root = mock.document.createElement("div") + var unloaded = 0 + var config = function(el, init, ctx) { + ctx.onunload = function() { + unloaded++ + } + } + m.route.mode = "search" + m.route(root, "/foo1", { + "/foo1": { + controller: function() {}, + view: function() { + return m("div", m("a", {config: config}, "foo")); + } + }, + "/bar1": { + controller: function() {}, + view: function() { + return m("main", m("a", {config: config}, "foo")); + } + }, + }) + mock.performance.$elapse(50) + m.route("/bar1") + mock.performance.$elapse(50) //teardown + return unloaded == 1 + }) //end m.route //m.prop