Make m.redraw() strictly asynchronous
This commit is contained in:
parent
38956e119b
commit
b004c20f0c
11 changed files with 281 additions and 111 deletions
|
|
@ -16,6 +16,6 @@ module.exports = function(redrawService) {
|
|||
redrawService.render(root, Vnode(component))
|
||||
}
|
||||
redrawService.subscribe(root, run)
|
||||
redrawService.redraw()
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,26 +4,23 @@ var coreRenderer = require("../render/render")
|
|||
|
||||
function throttle(callback) {
|
||||
//60fps translates to 16.6ms, round it down since setTimeout requires int
|
||||
var time = 16
|
||||
var delay = 16
|
||||
var last = 0, pending = null
|
||||
var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
|
||||
return function() {
|
||||
var now = Date.now()
|
||||
if (last === 0 || now - last >= time) {
|
||||
last = now
|
||||
callback()
|
||||
}
|
||||
else if (pending === null) {
|
||||
var elapsed = Date.now() - last
|
||||
if (pending === null) {
|
||||
pending = timeout(function() {
|
||||
pending = null
|
||||
callback()
|
||||
last = Date.now()
|
||||
}, time - (now - last))
|
||||
}, delay - elapsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function($window) {
|
||||
module.exports = function($window, throttleMock) {
|
||||
var _throttle = throttleMock || throttle
|
||||
var renderService = coreRenderer($window)
|
||||
renderService.setEventCallback(function(e) {
|
||||
if (e.redraw !== false) redraw()
|
||||
|
|
@ -32,7 +29,7 @@ module.exports = function($window) {
|
|||
var callbacks = []
|
||||
function subscribe(key, callback) {
|
||||
unsubscribe(key)
|
||||
callbacks.push(key, throttle(callback))
|
||||
callbacks.push(key, _throttle(callback))
|
||||
}
|
||||
function unsubscribe(key) {
|
||||
var index = callbacks.indexOf(key)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,14 @@ module.exports = function($window, redrawService) {
|
|||
var render, component, attrs, currentPath, lastUpdate
|
||||
var route = function(root, defaultRoute, routes) {
|
||||
if (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined")
|
||||
var run = function() {
|
||||
function run() {
|
||||
if (render != null) redrawService.render(root, render(Vnode(component, attrs.key, attrs)))
|
||||
}
|
||||
var redraw = function() {
|
||||
run()
|
||||
redraw = redrawService.redraw
|
||||
}
|
||||
redrawService.subscribe(root, run)
|
||||
var bail = function(path) {
|
||||
if (path !== defaultRoute) routeService.setPath(defaultRoute, null, {replace: true})
|
||||
else throw new Error("Could not resolve default route " + defaultRoute)
|
||||
|
|
@ -24,7 +29,7 @@ module.exports = function($window, redrawService) {
|
|||
component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
|
||||
attrs = params, currentPath = path, lastUpdate = null
|
||||
render = (routeResolver.render || identity).bind(routeResolver)
|
||||
run()
|
||||
redraw()
|
||||
}
|
||||
if (payload.view || typeof payload === "function") update({}, payload)
|
||||
else {
|
||||
|
|
@ -36,7 +41,6 @@ module.exports = function($window, redrawService) {
|
|||
else update(payload, "div")
|
||||
}
|
||||
}, bail)
|
||||
redrawService.subscribe(root, run)
|
||||
}
|
||||
route.set = function(path, data, options) {
|
||||
if (lastUpdate != null) options = {replace: true}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
var o = require("../../ospec/ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
||||
var m = require("../../render/hyperscript")
|
||||
var coreRenderer = require("../../render/render")
|
||||
|
|
@ -11,18 +12,22 @@ var apiMounter = require("../../api/mount")
|
|||
|
||||
o.spec("mount", function() {
|
||||
var FRAME_BUDGET = Math.floor(1000 / 60)
|
||||
var $window, root, redrawService, mount, render
|
||||
var $window, root, redrawService, mount, render, throttleMock
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
throttleMock = throttleMocker()
|
||||
|
||||
root = $window.document.body
|
||||
|
||||
redrawService = apiRedraw($window)
|
||||
redrawService = apiRedraw($window, throttleMock.throttle)
|
||||
mount = apiMounter(redrawService)
|
||||
render = coreRenderer($window).render
|
||||
})
|
||||
|
||||
o.afterEach(function() {
|
||||
o(throttleMock.queueLength()).equals(0)
|
||||
})
|
||||
|
||||
o("throws on invalid component", function() {
|
||||
var threw = false
|
||||
try {
|
||||
|
|
@ -69,7 +74,7 @@ o.spec("mount", function() {
|
|||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
|
||||
o("redraws on events", function(done) {
|
||||
o("redraws on events", function() {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
|
|
@ -97,17 +102,12 @@ o.spec("mount", function() {
|
|||
o(onclick.args[0].type).equals("click")
|
||||
o(onclick.args[0].target).equals(root.firstChild)
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
throttleMock.fire()
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("redraws several mount points on events", function(done, timeout) {
|
||||
timeout(60)
|
||||
|
||||
o("redraws several mount points on events", function() {
|
||||
var onupdate0 = o.spy()
|
||||
var oninit0 = o.spy()
|
||||
var onclick0 = o.spy()
|
||||
|
|
@ -154,26 +154,26 @@ o.spec("mount", function() {
|
|||
o(onclick0.callCount).equals(1)
|
||||
o(onclick0.this).equals(root.childNodes[0].firstChild)
|
||||
|
||||
setTimeout(function() {
|
||||
o(onupdate0.callCount).equals(1)
|
||||
o(onupdate1.callCount).equals(1)
|
||||
throttleMock.fire()
|
||||
|
||||
root.childNodes[1].firstChild.dispatchEvent(e)
|
||||
o(onclick1.callCount).equals(1)
|
||||
o(onclick1.this).equals(root.childNodes[1].firstChild)
|
||||
o(onupdate0.callCount).equals(1)
|
||||
o(onupdate1.callCount).equals(1)
|
||||
|
||||
setTimeout(function() {
|
||||
o(onupdate0.callCount).equals(2)
|
||||
o(onupdate1.callCount).equals(2)
|
||||
root.childNodes[1].firstChild.dispatchEvent(e)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
}, FRAME_BUDGET)
|
||||
o(onclick1.callCount).equals(1)
|
||||
o(onclick1.this).equals(root.childNodes[1].firstChild)
|
||||
|
||||
throttleMock.fire()
|
||||
|
||||
o(onupdate0.callCount).equals(2)
|
||||
o(onupdate1.callCount).equals(2)
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
var onupdate = o.spy()
|
||||
o("event handlers can skip redraw", function() {
|
||||
var onupdate = o.spy(function(){
|
||||
throw new Error("This shouldn't have been called")
|
||||
})
|
||||
var oninit = o.spy()
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
|
|
@ -195,15 +195,12 @@ o.spec("mount", function() {
|
|||
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
// Wrapped to ensure no redraw fired
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(0)
|
||||
throttleMock.fire()
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
o(onupdate.callCount).equals(0)
|
||||
})
|
||||
|
||||
o("redraws when the render function is run", function(done) {
|
||||
o("redraws when the render function is run", function() {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
|
||||
|
|
@ -221,17 +218,12 @@ o.spec("mount", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
throttleMock.fire()
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("throttles", function(done, timeout) {
|
||||
timeout(200)
|
||||
|
||||
o("throttles", function() {
|
||||
var i = 0
|
||||
mount(root, createComponent({view: function() {i++}}))
|
||||
var before = i
|
||||
|
|
@ -243,12 +235,11 @@ o.spec("mount", function() {
|
|||
|
||||
var after = i
|
||||
|
||||
setTimeout(function(){
|
||||
o(before).equals(1) // mounts synchronously
|
||||
o(after).equals(1) // throttles rest
|
||||
o(i).equals(2)
|
||||
done()
|
||||
},40)
|
||||
throttleMock.fire()
|
||||
|
||||
o(before).equals(1) // mounts synchronously
|
||||
o(after).equals(1) // throttles rest
|
||||
o(i).equals(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
var o = require("../../ospec/ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
var apiRedraw = require("../../api/redraw")
|
||||
|
||||
o.spec("redrawService", function() {
|
||||
|
|
@ -17,25 +18,39 @@ o.spec("redrawService", function() {
|
|||
redrawService.redraw()
|
||||
})
|
||||
|
||||
o("honours throttleMock", function() {
|
||||
var throttleMock = throttleMocker()
|
||||
redrawService = apiRedraw(domMock(), throttleMock.throttle)
|
||||
var spy = o.spy()
|
||||
|
||||
redrawService.subscribe(root, spy)
|
||||
|
||||
o(spy.callCount).equals(0)
|
||||
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy.callCount).equals(0)
|
||||
|
||||
throttleMock.fire()
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("should run a single renderer entry", function(done) {
|
||||
var spy = o.spy()
|
||||
|
||||
redrawService.subscribe(root, spy)
|
||||
|
||||
o(spy.callCount).equals(0)
|
||||
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
|
||||
redrawService.redraw()
|
||||
redrawService.redraw()
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
o(spy.callCount).equals(0)
|
||||
setTimeout(function() {
|
||||
o(spy.callCount).equals(2)
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, 20)
|
||||
})
|
||||
|
|
@ -54,27 +69,29 @@ o.spec("redrawService", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy1.callCount).equals(1)
|
||||
o(spy2.callCount).equals(1)
|
||||
o(spy3.callCount).equals(1)
|
||||
o(spy1.callCount).equals(0)
|
||||
o(spy2.callCount).equals(0)
|
||||
o(spy3.callCount).equals(0)
|
||||
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy1.callCount).equals(1)
|
||||
o(spy2.callCount).equals(1)
|
||||
o(spy3.callCount).equals(1)
|
||||
o(spy1.callCount).equals(0)
|
||||
o(spy2.callCount).equals(0)
|
||||
o(spy3.callCount).equals(0)
|
||||
|
||||
setTimeout(function() {
|
||||
o(spy1.callCount).equals(2)
|
||||
o(spy2.callCount).equals(2)
|
||||
o(spy3.callCount).equals(2)
|
||||
|
||||
o(spy1.callCount).equals(1)
|
||||
o(spy2.callCount).equals(1)
|
||||
o(spy3.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, 20)
|
||||
})
|
||||
|
||||
o("should stop running after unsubscribe", function() {
|
||||
var spy = o.spy()
|
||||
o("should stop running after unsubscribe", function(done) {
|
||||
var spy = o.spy(function() {
|
||||
throw new Error("This shouldn't have been called")
|
||||
})
|
||||
|
||||
redrawService.subscribe(root, spy)
|
||||
redrawService.unsubscribe(root, spy)
|
||||
|
|
@ -82,9 +99,14 @@ o.spec("redrawService", function() {
|
|||
redrawService.redraw()
|
||||
|
||||
o(spy.callCount).equals(0)
|
||||
setTimeout(function() {
|
||||
o(spy.callCount).equals(0)
|
||||
|
||||
done()
|
||||
}, 20)
|
||||
})
|
||||
|
||||
o("does nothing on invalid unsubscribe", function() {
|
||||
o("does nothing on invalid unsubscribe", function(done) {
|
||||
var spy = o.spy()
|
||||
|
||||
redrawService.subscribe(root, spy)
|
||||
|
|
@ -92,6 +114,10 @@ o.spec("redrawService", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
o(spy.callCount).equals(1)
|
||||
setTimeout(function() {
|
||||
o(spy.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, 20)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
var o = require("../../ospec/ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var browserMock = require("../../test-utils/browserMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
||||
var m = require("../../render/hyperscript")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
|
|
@ -15,18 +16,23 @@ o.spec("route", function() {
|
|||
void ["#", "?", "", "#!", "?!", "/foo"].forEach(function(prefix) {
|
||||
o.spec("using prefix `" + prefix + "` starting on " + env.protocol + "//" + env.hostname, function() {
|
||||
var FRAME_BUDGET = Math.floor(1000 / 60)
|
||||
var $window, root, redrawService, route
|
||||
var $window, root, redrawService, route, throttleMock
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = browserMock(env)
|
||||
throttleMock = throttleMocker()
|
||||
|
||||
root = $window.document.body
|
||||
|
||||
redrawService = apiRedraw($window)
|
||||
redrawService = apiRedraw($window, throttleMock.throttle)
|
||||
route = apiRouter($window, redrawService)
|
||||
route.prefix(prefix)
|
||||
})
|
||||
|
||||
o.afterEach(function() {
|
||||
o(throttleMock.queueLength()).equals(0)
|
||||
})
|
||||
|
||||
o("throws on invalid `root` DOM node", function() {
|
||||
var threw = false
|
||||
try {
|
||||
|
|
@ -50,7 +56,7 @@ o.spec("route", function() {
|
|||
o(root.firstChild.nodeName).equals("DIV")
|
||||
})
|
||||
|
||||
o("routed mount points can redraw synchronously (POJO component)", function() {
|
||||
o("routed mount points only redraw asynchronously (POJO component)", function() {
|
||||
var view = o.spy()
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
|
|
@ -60,11 +66,14 @@ o.spec("route", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
o(view.callCount).equals(1)
|
||||
|
||||
throttleMock.fire()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
})
|
||||
|
||||
o("routed mount points can redraw synchronously (constructible component)", function() {
|
||||
o("routed mount points only redraw asynchronously (constructible component)", function() {
|
||||
var view = o.spy()
|
||||
|
||||
var Cmp = function(){}
|
||||
|
|
@ -77,11 +86,14 @@ o.spec("route", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
o(view.callCount).equals(1)
|
||||
|
||||
throttleMock.fire()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
})
|
||||
|
||||
o("routed mount points can redraw synchronously (closure component)", function() {
|
||||
o("routed mount points only redraw asynchronously (closure component)", function() {
|
||||
var view = o.spy()
|
||||
|
||||
function Cmp() {return {view: view}}
|
||||
|
|
@ -93,8 +105,11 @@ o.spec("route", function() {
|
|||
|
||||
redrawService.redraw()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
o(view.callCount).equals(1)
|
||||
|
||||
throttleMock.fire()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
})
|
||||
|
||||
o("default route doesn't break back button", function(done) {
|
||||
|
|
@ -160,11 +175,12 @@ o.spec("route", function() {
|
|||
o(oninit.callCount).equals(1)
|
||||
|
||||
redrawService.redraw()
|
||||
throttleMock.fire()
|
||||
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("redraws on events", function(done) {
|
||||
o("redraws on events", function() {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
|
|
@ -194,12 +210,9 @@ o.spec("route", function() {
|
|||
o(onclick.args[0].type).equals("click")
|
||||
o(onclick.args[0].target).equals(root.firstChild)
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
callAsync(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
})
|
||||
throttleMock.fire()
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
|
|
@ -500,7 +513,10 @@ o.spec("route", function() {
|
|||
o(oninit.callCount).equals(1)
|
||||
route.set("/def")
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(oninit.callCount).equals(2)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
|
@ -536,23 +552,28 @@ o.spec("route", function() {
|
|||
route(root, "/a", {
|
||||
"/a" : {
|
||||
render: function() {
|
||||
return m("div")
|
||||
return m("div", m('p'))
|
||||
},
|
||||
},
|
||||
"/b" : {
|
||||
render: function() {
|
||||
return m("div")
|
||||
return m("div", m('a'))
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
var dom = root.firstChild
|
||||
var child = dom.firstChild
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
route.set("/b")
|
||||
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(root.firstChild).equals(dom)
|
||||
o(root.firstChild.firstChild).notEquals(child)
|
||||
|
||||
done()
|
||||
})
|
||||
|
|
@ -586,6 +607,7 @@ o.spec("route", function() {
|
|||
o(renderCount).equals(1)
|
||||
|
||||
redrawService.redraw()
|
||||
throttleMock.fire()
|
||||
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
|
|
@ -621,6 +643,7 @@ o.spec("route", function() {
|
|||
o(renderCount).equals(1)
|
||||
|
||||
redrawService.redraw()
|
||||
throttleMock.fire()
|
||||
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
|
|
@ -815,10 +838,14 @@ o.spec("route", function() {
|
|||
})
|
||||
|
||||
callAsync(function() {
|
||||
route.set("/b")
|
||||
throttleMock.fire()
|
||||
|
||||
route.set('/b')
|
||||
callAsync(function() {
|
||||
callAsync(function() {
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(render.callCount).equals(0)
|
||||
o(component.view.callCount).equals(2)
|
||||
|
||||
|
|
@ -939,6 +966,7 @@ o.spec("route", function() {
|
|||
o(onmatch.callCount).equals(1)
|
||||
|
||||
redrawService.redraw()
|
||||
throttleMock.fire()
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
o(onmatch.callCount).equals(1)
|
||||
|
|
@ -1017,6 +1045,8 @@ o.spec("route", function() {
|
|||
})
|
||||
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(onmatch.callCount).equals(1)
|
||||
o(render.callCount).equals(1)
|
||||
|
||||
|
|
@ -1024,6 +1054,8 @@ o.spec("route", function() {
|
|||
|
||||
callAsync(function() {
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(onmatch.callCount).equals(2)
|
||||
o(render.callCount).equals(2)
|
||||
|
||||
|
|
@ -1074,9 +1106,15 @@ o.spec("route", function() {
|
|||
route.set("/b")
|
||||
|
||||
callAsync(function() {
|
||||
route.set("/a")
|
||||
throttleMock.fire()
|
||||
|
||||
o(root.firstChild.nodeName).equals("B")
|
||||
|
||||
route.set('/a')
|
||||
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(root.firstChild.nodeName).equals("A")
|
||||
|
||||
done()
|
||||
|
|
@ -1141,7 +1179,9 @@ o.spec("route", function() {
|
|||
|
||||
route.set("/b")
|
||||
|
||||
// setting the route is asynchronous
|
||||
callAsync(function() {
|
||||
throttleMock.fire()
|
||||
o(spy.callCount).equals(1)
|
||||
|
||||
done()
|
||||
|
|
@ -1181,9 +1221,7 @@ o.spec("route", function() {
|
|||
})
|
||||
})
|
||||
|
||||
o("throttles", function(done, timeout) {
|
||||
timeout(200)
|
||||
|
||||
o("throttles", function() {
|
||||
var i = 0
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
|
|
@ -1197,12 +1235,11 @@ o.spec("route", function() {
|
|||
redrawService.redraw()
|
||||
var after = i
|
||||
|
||||
setTimeout(function() {
|
||||
o(before).equals(1) // routes synchronously
|
||||
o(after).equals(2) // redraws synchronously
|
||||
o(i).equals(3) // throttles rest
|
||||
done()
|
||||
}, FRAME_BUDGET * 2)
|
||||
throttleMock.fire()
|
||||
|
||||
o(before).equals(1) // routes synchronously
|
||||
o(after).equals(1) // redraws asynchronously
|
||||
o(i).equals(2)
|
||||
})
|
||||
|
||||
o("m.route.param is available outside of route handlers", function(done) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue