From d482020daaa56cb34d803a24817b584b6f846b68 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Mon, 9 Feb 2015 23:02:32 -0500 Subject: [PATCH] fix onunload preventdefault in non-curried modules --- mithril.js | 5 ++- tests/mithril-tests.js | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/mithril.js b/mithril.js index ab490134..5ca89f85 100644 --- a/mithril.js +++ b/mithril.js @@ -234,6 +234,7 @@ var m = (function app(window, undefined) { if (data.controller) { var module = data var controller = cached.controller || new (module.controller || function() {}) + if (controller.onunload) unloaders.push({controller: controller, handler: controller.onunload}) data = module.view(controller) if (!data.tag) throw new Error(module.view.toString() + "\n\nThis template must return a virtual element, not an array, string, etc.") } @@ -506,9 +507,7 @@ var m = (function app(window, undefined) { var FRAME_BUDGET = 16; //60 frames per second = 1 call per 16 ms function submodule(module, args) { var controller = function() { - var instance = module.controller.apply(this, args) || this - if (instance.onunload) unloaders.push({controller: instance, handler: instance.onunload}) - return instance + return module.controller.apply(this, args) || this } var view = function(ctrl) { if (arguments.length > 1) args = args.concat([].slice.call(arguments, 1)) diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 2427dcfd..0e4d21a7 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -350,6 +350,80 @@ function testMithril(mock) { return count === 1 }) + test(function() { + //calling preventDefault from component's onunload should prevent route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var module = { + controller: function() {}, + view: function() { + return m.module(sub) + } + } + var sub = { + controller: function(opts) { + controller = this + this.onunload = function(e) {if (testEnabled) e.preventDefault()} + }, + view: function() { + return m("div") + } + } + m.route(root, "/a", { + "/a": module, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) + test(function() { + //calling preventDefault from non-curried component's onunload should prevent route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var module = { + controller: function() {}, + view: function() { + return sub + } + } + var sub = { + controller: function(opts) { + controller = this + this.onunload = function(e) {if (testEnabled) e.preventDefault()} + }, + view: function() { + return m("div") + } + } + m.route(root, "/a", { + "/a": module, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) //m.withAttr test(function() {