- Remove appropriate route change subcriptions when a root is removed via `m.mount(root, null)`. - Don't pollute `onpopstate` and friends - use standard event listeners instead. - Simplify and streamline subscriptions, in preparation of adding a `remove` parameter to `m.mount`. - Change the redraw internals to redraw immediately, with ability to cancel via returning a sentinel. - Change `"bleeding-edge"` for `m.version` in `next` to instead just be the latest `m.version`. (If you're using `next`, you should know what you're in for.) - Update tests to be aware of these changes. (Some were failing for subtle reasons.) - Drive-by: remove some uses of `string.charAt(n)` and use `string[n]` instead.
58 lines
1.4 KiB
JavaScript
58 lines
1.4 KiB
JavaScript
"use strict"
|
|
|
|
var coreRenderer = require("../render/render")
|
|
|
|
function throttle(callback) {
|
|
var pending = null
|
|
return function() {
|
|
if (pending === null) {
|
|
pending = requestAnimationFrame(function() {
|
|
pending = null
|
|
callback()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = function($window, throttleMock) {
|
|
var renderService = coreRenderer($window)
|
|
var subscriptions = []
|
|
var rendering = false
|
|
|
|
function run(sub) {
|
|
var vnode = sub.c(sub)
|
|
if (vnode !== sub) renderService.render(sub.k, vnode)
|
|
}
|
|
function subscribe(key, callback, onremove) {
|
|
var sub = {k: key, c: callback, r: onremove}
|
|
unsubscribe(key)
|
|
subscriptions.push(sub)
|
|
var vnode = sub.c(sub)
|
|
if (vnode !== sub) renderService.render(sub.k, vnode)
|
|
}
|
|
function unsubscribe(key) {
|
|
for (var i = 0; i < subscriptions.length; i++) {
|
|
var sub = subscriptions[i]
|
|
if (sub.k === key) {
|
|
subscriptions.splice(i, 1)
|
|
renderService.render(sub.k, [])
|
|
if (typeof sub.r === "function") sub.r()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
function sync() {
|
|
if (rendering) throw new Error("Nested m.redraw.sync() call")
|
|
rendering = true
|
|
for (var i = 0; i < subscriptions.length; i++) {
|
|
try { run(subscriptions[i]) }
|
|
catch (e) { if (typeof console !== "undefined") console.error(e) }
|
|
}
|
|
rendering = false
|
|
}
|
|
|
|
var redraw = (throttleMock || throttle)(sync)
|
|
redraw.sync = sync
|
|
renderService.setRedraw(redraw)
|
|
return {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render}
|
|
}
|