From ad303427bf0f40acfbd601c6b81e38d5f3a1aa76 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Sat, 7 Feb 2015 23:20:51 -0500 Subject: [PATCH] prevent infinite recursion in m.redraw --- mithril.js | 4 ++++ tests/mithril-tests.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/mithril.js b/mithril.js index 8a7e826e..7ba24288 100644 --- a/mithril.js +++ b/mithril.js @@ -548,7 +548,10 @@ var m = (function app(window, undefined) { return controllers[index] } }; + var redrawing = false m.redraw = function(force) { + if (redrawing) return + redrawing = true //lastRedrawId is a positive number if a second redraw is requested before the next animation frame //lastRedrawID is null if it's the first redraw and not an event handler if (lastRedrawId && force !== true) { @@ -563,6 +566,7 @@ var m = (function app(window, undefined) { redraw(); lastRedrawId = $requestAnimationFrame(function() {lastRedrawId = null}, FRAME_BUDGET) } + redrawing = false }; m.redraw.strategy = m.prop(); var blank = function() {return ""} diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 15e24a5b..2427dcfd 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -323,6 +323,33 @@ function testMithril(mock) { return unloaded === 3 }) + test(function() { + //calling m.redraw synchronously from controller constructor should not trigger extra redraws + mock.requestAnimationFrame.$resolve() + + var root = mock.document.createElement("div") + var count = 0 + var module = { + controller: function() {}, + view: function(ctrl) { + return m.module(sub) + } + } + var sub = { + controller: function(opts) { + m.redraw() + }, + view: function() { + count++ + return m("div") + } + } + m.module(root, module) + + mock.requestAnimationFrame.$resolve() + + return count === 1 + }) //m.withAttr test(function() { @@ -1123,6 +1150,7 @@ function testMithril(mock) { m.redraw() m.redraw() mock.requestAnimationFrame.$resolve() //teardown + return count === 3 }) test(function() {