Merge remote-tracking branch 'origin/rewrite' into rewrite
Conflicts: docs/route.md
This commit is contained in:
commit
55f0dfa4dd
16 changed files with 546 additions and 392 deletions
|
|
@ -2,38 +2,56 @@
|
|||
|
||||
var Vnode = require("../render/vnode")
|
||||
var coreRouter = require("../router/router")
|
||||
var autoredraw = require("../api/autoredraw")
|
||||
|
||||
module.exports = function($window, renderer, pubsub) {
|
||||
module.exports = function($window, mount) {
|
||||
var router = coreRouter($window)
|
||||
var currentResolve, currentComponent, currentRender, currentArgs, currentPath
|
||||
|
||||
var RouteComponent = {view: function() {
|
||||
return currentRender(Vnode(currentComponent, null, currentArgs, undefined, undefined, undefined))
|
||||
}}
|
||||
function defaultRender(vnode) {
|
||||
return vnode
|
||||
}
|
||||
var route = function(root, defaultRoute, routes) {
|
||||
var current = {path: null, component: "div", resolver: null}, currentResolutionIdentifier = null
|
||||
var replay = router.defineRoutes(routes, function(payload, args, path, route) {
|
||||
var resolutionIdentifier = currentResolutionIdentifier = {}
|
||||
function resolve(component) {
|
||||
if (resolutionIdentifier !== currentResolutionIdentifier) return
|
||||
resolutionIdentifier = null
|
||||
current.path = path, current.component = component
|
||||
renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined)))
|
||||
currentComponent = "div"
|
||||
currentRender = defaultRender
|
||||
currentArgs = null
|
||||
|
||||
mount(root, RouteComponent)
|
||||
|
||||
router.defineRoutes(routes, function(payload, args, path) {
|
||||
var isResolver = typeof payload.view !== "function"
|
||||
var render = defaultRender
|
||||
|
||||
var resolve = currentResolve = function (component) {
|
||||
if (resolve !== currentResolve) return
|
||||
currentResolve = null
|
||||
|
||||
currentComponent = component != null ? component : isResolver ? "div" : payload
|
||||
currentRender = render
|
||||
currentArgs = args
|
||||
currentPath = path
|
||||
|
||||
root.redraw(true)
|
||||
}
|
||||
if (typeof payload.view !== "function") {
|
||||
if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode}
|
||||
if (typeof payload.onmatch !== "function") payload.onmatch = function() {resolve(current.component)}
|
||||
if (path !== current.path) payload.onmatch(Vnode(payload, null, args, undefined, undefined, undefined), resolve)
|
||||
else resolve(current.component)
|
||||
var onmatch = function() {
|
||||
resolve()
|
||||
}
|
||||
else {
|
||||
renderer.render(root, Vnode(payload, null, args, undefined, undefined, undefined))
|
||||
if (isResolver) {
|
||||
if (typeof payload.render === "function") render = payload.render.bind(payload)
|
||||
if (typeof payload.onmatch === "function") onmatch = payload.onmatch
|
||||
}
|
||||
|
||||
onmatch.call(payload, resolve, args, path)
|
||||
}, function() {
|
||||
router.setPath(defaultRoute, null, {replace: true})
|
||||
})
|
||||
autoredraw(root, renderer, pubsub, replay)
|
||||
}
|
||||
route.link = router.link
|
||||
route.prefix = router.setPrefix
|
||||
route.set = router.setPath
|
||||
route.get = router.getPath
|
||||
|
||||
route.get = function() {return currentPath}
|
||||
|
||||
return route
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@ o.spec("mount", function() {
|
|||
render = coreRenderer($window).render
|
||||
})
|
||||
|
||||
o("throws on invalid `root` DOM node", function() {
|
||||
var threw = false
|
||||
try {
|
||||
mount(null, {view: function() {}})
|
||||
} catch (e) {
|
||||
threw = true
|
||||
}
|
||||
o(threw).equals(true)
|
||||
})
|
||||
|
||||
o("renders into `root`", function() {
|
||||
mount(root, {
|
||||
view : function() {
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ var m = require("../../render/hyperscript")
|
|||
var coreRenderer = require("../../render/render")
|
||||
var apiPubSub = require("../../api/pubsub")
|
||||
var apiRouter = require("../../api/router")
|
||||
var apiMounter = require("../../api/mount")
|
||||
|
||||
o.spec("route", function() {
|
||||
void [{protocol: "http:", hostname: "localhost"}, {protocol: "file:", hostname: "/"}].forEach(function(env) {
|
||||
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, redraw, route
|
||||
var $window, root, redraw, mount, route
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = browserMock(env)
|
||||
|
|
@ -22,11 +23,22 @@ o.spec("route", function() {
|
|||
root = $window.document.body
|
||||
|
||||
redraw = apiPubSub()
|
||||
route = apiRouter($window, coreRenderer($window), redraw)
|
||||
mount = apiMounter(coreRenderer($window), redraw)
|
||||
route = apiRouter($window, mount)
|
||||
route.prefix(prefix)
|
||||
})
|
||||
|
||||
o("renders into `root`", function(done) {
|
||||
o("throws on invalid `root` DOM node", function() {
|
||||
var threw = false
|
||||
try {
|
||||
route(null, '/', {'/':{view: function() {}}})
|
||||
} catch (e) {
|
||||
threw = true
|
||||
}
|
||||
o(threw).equals(true)
|
||||
})
|
||||
|
||||
o("renders into `root`", function() {
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
|
|
@ -36,11 +48,21 @@ o.spec("route", function() {
|
|||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
})
|
||||
|
||||
o("routed mount points can redraw synchronoulsy (#1275)", function() {
|
||||
var view = o.spy()
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {"/":{view:view}})
|
||||
|
||||
o(view.callCount).equals(1)
|
||||
|
||||
redraw.publish(true)
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
|
||||
})
|
||||
|
||||
o("default route doesn't break back button", function(done) {
|
||||
|
|
@ -55,11 +77,11 @@ o.spec("route", function() {
|
|||
|
||||
setTimeout(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
|
||||
$window.history.back()
|
||||
|
||||
|
||||
o($window.location.pathname).equals("/")
|
||||
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
|
@ -77,12 +99,12 @@ o.spec("route", function() {
|
|||
|
||||
function init(vnode) {
|
||||
o(vnode.attrs.foo).equals(undefined)
|
||||
|
||||
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
o("redraws when render function is executed", function(done) {
|
||||
o("redraws when render function is executed", function() {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
|
||||
|
|
@ -98,18 +120,11 @@ o.spec("route", function() {
|
|||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(oninit.callCount).equals(1)
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
redraw.publish(true)
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("redraws on events", function(done) {
|
||||
|
|
@ -133,23 +148,21 @@ o.spec("route", function() {
|
|||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o(oninit.callCount).equals(1)
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
o(onclick.callCount).equals(1)
|
||||
o(onclick.this).equals(root.firstChild)
|
||||
o(onclick.args[0].type).equals("click")
|
||||
o(onclick.args[0].target).equals(root.firstChild)
|
||||
o(onclick.callCount).equals(1)
|
||||
o(onclick.this).equals(root.firstChild)
|
||||
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)
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
done()
|
||||
}, FRAME_BUDGET * 2)
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
|
|
@ -175,21 +188,19 @@ o.spec("route", function() {
|
|||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o(oninit.callCount).equals(1)
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
// Wrapped to ensure no redraw fired
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(0)
|
||||
// Wrapped to ensure no redraw fired
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(0)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("changes location on route.link", function(done) {
|
||||
o("changes location on route.link", function() {
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
|
@ -211,20 +222,16 @@ o.spec("route", function() {
|
|||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : ""))
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : ""))
|
||||
|
||||
root.firstChild.dispatchEvent(e)
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
|
||||
done()
|
||||
})
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
})
|
||||
|
||||
o("accepts RouteResolver", function(done) {
|
||||
|
||||
o("accepts RouteResolver", function() {
|
||||
var matchCount = 0
|
||||
var renderCount = 0
|
||||
var Component = {
|
||||
|
|
@ -232,107 +239,93 @@ o.spec("route", function() {
|
|||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
|
||||
$window.location.href = prefix + "/abc"
|
||||
route(root, "/abc", {
|
||||
"/:id" : {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve, args, requestedPath) {
|
||||
matchCount++
|
||||
|
||||
o(vnode.attrs.id).equals("abc")
|
||||
o(route.get()).equals("/abc")
|
||||
|
||||
|
||||
o(args.id).equals("abc")
|
||||
o(requestedPath).equals("/abc")
|
||||
|
||||
resolve(Component)
|
||||
},
|
||||
render: function(vnode) {
|
||||
renderCount++
|
||||
|
||||
|
||||
o(vnode.attrs.id).equals("abc")
|
||||
|
||||
|
||||
return vnode
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
})
|
||||
|
||||
o("accepts RouteResolver without `render` method as payload", function(done) {
|
||||
|
||||
o("accepts RouteResolver without `render` method as payload", function() {
|
||||
var matchCount = 0
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
|
||||
$window.location.href = prefix + "/abc"
|
||||
route(root, "/abc", {
|
||||
"/:id" : {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve, args, requestedPath) {
|
||||
matchCount++
|
||||
|
||||
o(vnode.attrs.id).equals("abc")
|
||||
o(route.get()).equals("/abc")
|
||||
|
||||
|
||||
o(args.id).equals("abc")
|
||||
o(requestedPath).equals("/abc")
|
||||
|
||||
resolve(Component)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(matchCount).equals(1)
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
|
||||
o(matchCount).equals(1)
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
})
|
||||
|
||||
o("accepts RouteResolver without `onmatch` method as payload", function(done) {
|
||||
|
||||
o("accepts RouteResolver without `onmatch` method as payload", function() {
|
||||
var renderCount = 0
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
|
||||
$window.location.href = prefix + "/abc"
|
||||
route(root, "/abc", {
|
||||
"/:id" : {
|
||||
render: function(vnode) {
|
||||
renderCount++
|
||||
|
||||
|
||||
o(vnode.attrs.id).equals("abc")
|
||||
|
||||
|
||||
return m(Component)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
})
|
||||
|
||||
o("RouteResolver `render` does not have component semantics", function(done, timeout) {
|
||||
timeout(60)
|
||||
|
||||
|
||||
o("RouteResolver `render` does not have component semantics", function(done) {
|
||||
var renderCount = 0
|
||||
var A = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
render: function(vnode) {
|
||||
|
|
@ -345,22 +338,20 @@ o.spec("route", function() {
|
|||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
var dom = root.firstChild
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
route.set("/b")
|
||||
|
||||
setTimeout(function() {
|
||||
var dom = root.firstChild
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
route.set("/b")
|
||||
|
||||
setTimeout(function() {
|
||||
o(root.firstChild).equals(dom)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
o(root.firstChild).equals(dom)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("calls onmatch and view correct number of times", function(done) {
|
||||
o("calls onmatch and view correct number of times", function() {
|
||||
var matchCount = 0
|
||||
var renderCount = 0
|
||||
var Component = {
|
||||
|
|
@ -368,11 +359,11 @@ o.spec("route", function() {
|
|||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
matchCount++
|
||||
resolve(Component)
|
||||
},
|
||||
|
|
@ -383,69 +374,63 @@ o.spec("route", function() {
|
|||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
|
||||
setTimeout(function() {
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
redraw.publish(true)
|
||||
|
||||
o(matchCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
})
|
||||
|
||||
|
||||
o("onmatch can redirect to another route", function(done) {
|
||||
var redirected = false
|
||||
var redirected = false
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
onmatch: function() {
|
||||
route.set("/b")
|
||||
}
|
||||
},
|
||||
"/b" : {
|
||||
view: function(vnode){
|
||||
redirected = true
|
||||
}
|
||||
}
|
||||
})
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
onmatch: function() {
|
||||
route.set("/b")
|
||||
}
|
||||
},
|
||||
"/b" : {
|
||||
view: function(vnode){
|
||||
redirected = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(redirected).equals(true)
|
||||
setTimeout(function() {
|
||||
o(redirected).equals(true)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("onmatch can redirect to another route that has RouteResolver", function(done) {
|
||||
var redirected = false
|
||||
var redirected = false
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
onmatch: function() {
|
||||
route.set("/b")
|
||||
}
|
||||
},
|
||||
"/b" : {
|
||||
render: function(vnode){
|
||||
redirected = true
|
||||
}
|
||||
}
|
||||
})
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
onmatch: function() {
|
||||
route.set("/b")
|
||||
}
|
||||
},
|
||||
"/b" : {
|
||||
render: function(vnode){
|
||||
redirected = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(redirected).equals(true)
|
||||
setTimeout(function() {
|
||||
o(redirected).equals(true)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("onmatch resolution callback resolves at most once", function(done) {
|
||||
var resolveCount = 0
|
||||
var resolvedComponent
|
||||
|
|
@ -456,7 +441,7 @@ o.spec("route", function() {
|
|||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
resolve(A)
|
||||
resolve(B)
|
||||
callAsync(function() {resolve(C)})
|
||||
|
|
@ -474,15 +459,114 @@ o.spec("route", function() {
|
|||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("calling route.set invalidates pending onmatch resolution", function(done, timeout) {
|
||||
timeout(100)
|
||||
|
||||
var resolved
|
||||
|
||||
o("the previous view redraws while onmatch resolution is pending (#1268)", function(done) {
|
||||
var view = o.spy()
|
||||
var onmatch = o.spy()
|
||||
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, "/", {
|
||||
"/a": {view: view},
|
||||
"/b": {onmatch: onmatch}
|
||||
})
|
||||
|
||||
o(view.callCount).equals(1)
|
||||
o(onmatch.callCount).equals(0)
|
||||
|
||||
route.set("/b")
|
||||
|
||||
setTimeout(function(){
|
||||
o(view.callCount).equals(1)
|
||||
o(onmatch.callCount).equals(1)
|
||||
|
||||
redraw.publish(true)
|
||||
|
||||
o(view.callCount).equals(2)
|
||||
o(onmatch.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("m.route.set(m.route.get()) re-runs the resolution logic (#1180)", function(done){
|
||||
var onmatch = o.spy(function(resolve){resolve()})
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, '/', {
|
||||
"/":{
|
||||
onmatch: onmatch,
|
||||
render: function(){return m("div")}
|
||||
}
|
||||
})
|
||||
|
||||
o(onmatch.callCount).equals(1)
|
||||
|
||||
route.set(route.get())
|
||||
|
||||
setTimeout(function() {
|
||||
o(onmatch.callCount).equals(2)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("m.route.get() returns the last fully resolved route (#1276)", function(done){
|
||||
$window.location.href = prefix + "/"
|
||||
|
||||
route(root, "/", {
|
||||
"/": {view: function(){}},
|
||||
"/2": {onmatch: function(){}}
|
||||
})
|
||||
|
||||
|
||||
o(route.get()).equals("/")
|
||||
|
||||
route.set("/2")
|
||||
|
||||
setTimeout(function(){
|
||||
o(route.get()).equals("/")
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("routing with RouteResolver works more than once (#1286)", function(done, timeout){
|
||||
timeout(FRAME_BUDGET * 3)
|
||||
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, '/a', {
|
||||
'/a': {
|
||||
render: function() {
|
||||
return m("a", "a")
|
||||
}
|
||||
},
|
||||
'/b': {
|
||||
render: function() {
|
||||
return m("b", "b")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
route.set('/b')
|
||||
|
||||
setTimeout(function(){
|
||||
route.set('/a')
|
||||
|
||||
setTimeout(function(){
|
||||
o(root.firstChild.nodeName).equals("A")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("calling route.set invalidates pending onmatch resolution", function(done, timeout) {
|
||||
timeout(50)
|
||||
|
||||
var resolved
|
||||
$window.location.href = prefix + "/a"
|
||||
route(root, "/a", {
|
||||
"/a": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
setTimeout(resolve, 20)
|
||||
},
|
||||
render: function(vnode) {resolved = "a"}
|
||||
|
|
@ -491,15 +575,14 @@ o.spec("route", function() {
|
|||
view: function() {resolved = "b"}
|
||||
}
|
||||
})
|
||||
setTimeout(function() {
|
||||
route.set("/b")
|
||||
|
||||
setTimeout(function() {
|
||||
o(resolved).equals("b")
|
||||
|
||||
done()
|
||||
}, 30)
|
||||
}, FRAME_BUDGET)
|
||||
route.set("/b")
|
||||
|
||||
setTimeout(function() {
|
||||
o(resolved).equals("b")
|
||||
|
||||
done()
|
||||
}, 30)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
- [API](#api)
|
||||
- [Static members](#static-members)
|
||||
- [route.set](#route-set)
|
||||
- [route.get](#route-get)
|
||||
- [route.prefix](#route-prefix)
|
||||
- [route.link](#route-link)
|
||||
- [route.set](#routeset)
|
||||
- [route.get](#routeget)
|
||||
- [route.prefix](#routeprefix)
|
||||
- [route.link](#routelink)
|
||||
- [RouteResolver](#routeresolver)
|
||||
- [routeResolver.onmatch](#routeresolver-onmatch)
|
||||
- [routeResolver.render](#routeresolver-render)
|
||||
- [routeResolver.onmatch](#routeresolveronmatch)
|
||||
- [routeResolver.render](#routeresolverrender)
|
||||
- [How it works](#how-it-works)
|
||||
- [Typical usage](#typical-usage)
|
||||
- [Navigating to different routes](#navigating-to-different-routes)
|
||||
|
|
@ -52,13 +52,13 @@ Argument | Type | Required | Description
|
|||
|
||||
##### route.get
|
||||
|
||||
Returns the current routing path, without the prefix.
|
||||
Returns the last fully resolved routing path, without the prefix. It may differ from the path displayed in the location bar while an asynchronous route is [pending resolution](#code-splitting).
|
||||
|
||||
`path = m.route.get()`
|
||||
|
||||
Argument | Type | Required | Description
|
||||
----------------- | --------- | -------- | ---
|
||||
**returns** | String | | Returns the current path
|
||||
**returns** | String | | Returns the last fully resolved path
|
||||
|
||||
##### route.prefix
|
||||
|
||||
|
|
@ -94,14 +94,12 @@ This method also allows you to asynchronously define what component will be rend
|
|||
|
||||
`routeResolver.onmatch(vnode, resolve)`
|
||||
|
||||
Argument | Type | Description
|
||||
------------------- | --------------------- | ---
|
||||
`vnode` | `Vnode` | A [vnode](vnodes.md) whose attributes object contains routing parameters. If the routeResolver does not have a `resolve` method, the vnode's `tag` field defaults to a `div`
|
||||
`vnode.attrs` | `Object` | The [routing parameters](#routing-parameters)
|
||||
`vnode.attrs.path` | `String` | The current router path, including interpolated routing parameter values, but without the prefix. Same value as `m.route.get()`
|
||||
`vnode.attrs.route` | `String` | The matched route
|
||||
`resolve` | `Function(Component)` | Call this function with a component as the first argument to use it as the route's component
|
||||
**returns** | | Returns `undefined`
|
||||
Argument | Type | Description
|
||||
--------------- | --------------------- | ---
|
||||
`resolve` | `Function(Component)` | Call this function with a component as the first argument to use it as the route's component
|
||||
`args` | `Object` | The [routing parameters](#routing-parameters)
|
||||
`requestedPath` | `String` | The router path requested by the last routing action, including interpolated routing parameter values, but without the prefix. When `onmatch` is called, the resolution for this path is not complete and `m.route.get()` still returns the previous path.
|
||||
**returns** | | Returns `undefined`
|
||||
|
||||
##### routeResolver.render
|
||||
|
||||
|
|
@ -113,8 +111,6 @@ Argument | Type | Description
|
|||
------------------- | --------------- | -----------
|
||||
`vnode` | `Object` | A [vnode](vnodes.md) whose attributes object contains routing parameters. If the routeResolver does not have a `resolve` method, the vnode's `tag` field defaults to a `div`
|
||||
`vnode.attrs` | `Object` | A [vnode](vnodes.md) whose attributes object contains routing parameters. If the routeResolver does not have a `resolve` method, the vnode defaults to a `div`
|
||||
`vnode.attrs.path` | `String` | The current router path, including interpolated routing parameter values, but without the prefix. Same value as `m.route.get()`
|
||||
`vnode.attrs.route` | `String` | The matched route
|
||||
**returns** | `Vnode` | Returns a vnode
|
||||
|
||||
---
|
||||
|
|
@ -271,7 +267,7 @@ Instead of mapping a component to a route, you can specify a RouteResolver objec
|
|||
```javascript
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve, args, requestedPath) {
|
||||
resolve(Home)
|
||||
},
|
||||
render: function(vnode) {
|
||||
|
|
@ -351,7 +347,7 @@ var Login = {
|
|||
|
||||
m.route(document.body, "/secret", {
|
||||
"/secret": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
if (isLoggedIn) resolve(Home)
|
||||
else m.route.set("/login")
|
||||
},
|
||||
|
|
@ -399,7 +395,7 @@ function load(file, done) {
|
|||
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
load("Home.js", resolve)
|
||||
},
|
||||
},
|
||||
|
|
@ -413,7 +409,7 @@ Fortunately, there are a number of tools that facilitate the task of bundling mo
|
|||
```javascript
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
onmatch: function(vnode, resolve) {
|
||||
onmatch: function(resolve) {
|
||||
// using Webpack async code splitting
|
||||
require(['./Home.js'], resolve)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ m.route(element, '/', {
|
|||
|
||||
## `m.route` mode
|
||||
|
||||
`m.route.mode` was replaced by `m.route.prefix(prefix)` where `prefix` can be `#`, `?`, `` (for "pathname" mode). The new API also supports hashbang (`#!`), which is the default, and it supports non-root pathnames and arbitrary mode variations such as querybang (`?!`)
|
||||
`m.route.mode` was replaced by `m.route.prefix(prefix)` where `prefix` can be `#`, `?`, or an empty string (for "pathname" mode). The new API also supports hashbang (`#!`), which is the default, and it supports non-root pathnames and arbitrary mode variations such as querybang (`?!`)
|
||||
|
||||
## `m.route()` and anchor tags
|
||||
|
||||
|
|
|
|||
2
index.js
2
index.js
|
|
@ -10,8 +10,8 @@ var Stream = require("./stream")
|
|||
|
||||
requestService.setCompletionCallback(redrawService.publish)
|
||||
|
||||
m.route = require("./route")
|
||||
m.mount = require("./mount")
|
||||
m.route = require("./route")
|
||||
m.withAttr = require("./util/withAttr")
|
||||
m.prop = Stream
|
||||
m.render = renderService.render
|
||||
|
|
|
|||
196
mithril.js
196
mithril.js
|
|
@ -573,6 +573,7 @@ var renderService = function($window) {
|
|||
Object.keys(source).forEach(function(k){target[k] = source[k]})
|
||||
}
|
||||
function render(dom, vnodes) {
|
||||
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
|
||||
var hooks = []
|
||||
var active = $doc.activeElement
|
||||
// First time rendering into a node clears it out
|
||||
|
|
@ -967,6 +968,56 @@ var parseQueryString = function(string) {
|
|||
return data
|
||||
}
|
||||
requestService.setCompletionCallback(redrawService.publish)
|
||||
var throttle = function(callback) {
|
||||
//60fps translates to 16.6ms, round it down since setTimeout requires int
|
||||
var time = 16
|
||||
var last = 0, pending = null
|
||||
var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
|
||||
return function(synchronous) {
|
||||
var now = Date.now()
|
||||
if (synchronous === true || last === 0 || now - last >= time) {
|
||||
last = now
|
||||
callback()
|
||||
}
|
||||
else if (pending === null) {
|
||||
pending = timeout(function() {
|
||||
pending = null
|
||||
callback()
|
||||
last = Date.now()
|
||||
}, time - (now - last))
|
||||
}
|
||||
}
|
||||
}
|
||||
var autoredraw = function(root, renderer, pubsub, callback) {
|
||||
var run = throttle(callback)
|
||||
if (renderer != null) {
|
||||
renderer.setEventCallback(function(e) {
|
||||
if (e.redraw !== false) pubsub.publish()
|
||||
})
|
||||
}
|
||||
if (pubsub != null) {
|
||||
if (root.redraw) pubsub.unsubscribe(root.redraw)
|
||||
pubsub.subscribe(run)
|
||||
}
|
||||
return root.redraw = run
|
||||
}
|
||||
m.mount = function(renderer, pubsub) {
|
||||
return function(root, component) {
|
||||
if (component === null) {
|
||||
renderer.render(root, [])
|
||||
pubsub.unsubscribe(root.redraw)
|
||||
delete root.redraw
|
||||
return
|
||||
}
|
||||
var run = autoredraw(root, renderer, pubsub, function() {
|
||||
renderer.render(
|
||||
root,
|
||||
Vnode(component, undefined, undefined, undefined, undefined, undefined)
|
||||
)
|
||||
})
|
||||
run()
|
||||
}
|
||||
}(renderService, redrawService)
|
||||
var coreRouter = function($window) {
|
||||
var supportsPushState = typeof $window.history.pushState === "function"
|
||||
var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
|
|
@ -977,6 +1028,16 @@ var coreRouter = function($window) {
|
|||
if (fragment === "pathname" && data[0] !== "/") data = "/" + data
|
||||
return data
|
||||
}
|
||||
var asyncId
|
||||
function debounceAsync(f) {
|
||||
return function() {
|
||||
if (asyncId != null) return
|
||||
asyncId = callAsync(function() {
|
||||
asyncId = null
|
||||
f()
|
||||
})
|
||||
}
|
||||
}
|
||||
function parsePath(path, queryData, hashData) {
|
||||
var queryIndex = path.indexOf("?")
|
||||
var hashIndex = path.indexOf("#")
|
||||
|
|
@ -1022,7 +1083,7 @@ var coreRouter = function($window) {
|
|||
else $window.location.href = prefix + path
|
||||
}
|
||||
function defineRoutes(routes, resolve, reject) {
|
||||
if (supportsPushState) $window.onpopstate = resolveRoute
|
||||
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
|
||||
else if (prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
|
||||
resolveRoute()
|
||||
|
||||
|
|
@ -1031,23 +1092,21 @@ var coreRouter = function($window) {
|
|||
var params = {}
|
||||
var pathname = parsePath(path, params, params)
|
||||
|
||||
callAsync(function() {
|
||||
for (var route in routes) {
|
||||
var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$")
|
||||
if (matcher.test(pathname)) {
|
||||
pathname.replace(matcher, function() {
|
||||
var keys = route.match(/:[^\/]+/g) || []
|
||||
var values = [].slice.call(arguments, 1, -2)
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
|
||||
}
|
||||
resolve(routes[route], params, path, route)
|
||||
})
|
||||
return
|
||||
}
|
||||
for (var route in routes) {
|
||||
var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$")
|
||||
if (matcher.test(pathname)) {
|
||||
pathname.replace(matcher, function() {
|
||||
var keys = route.match(/:[^\/]+/g) || []
|
||||
var values = [].slice.call(arguments, 1, -2)
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
|
||||
}
|
||||
resolve(routes[route], params, path, route)
|
||||
})
|
||||
return
|
||||
}
|
||||
reject(path, params)
|
||||
})
|
||||
}
|
||||
reject(path, params)
|
||||
}
|
||||
return resolveRoute
|
||||
}
|
||||
|
|
@ -1061,89 +1120,52 @@ var coreRouter = function($window) {
|
|||
}
|
||||
return {setPrefix: setPrefix, getPath: getPath, setPath: setPath, defineRoutes: defineRoutes, link: link}
|
||||
}
|
||||
var throttle = function(callback) {
|
||||
//60fps translates to 16.6ms, round it down since setTimeout requires int
|
||||
var time = 16
|
||||
var last = 0, pending = null
|
||||
var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
|
||||
return function(synchronous) {
|
||||
var now = Date.now()
|
||||
if (synchronous === true || last === 0 || now - last >= time) {
|
||||
last = now
|
||||
callback()
|
||||
}
|
||||
else if (pending === null) {
|
||||
pending = timeout(function() {
|
||||
pending = null
|
||||
callback()
|
||||
last = Date.now()
|
||||
}, time - (now - last))
|
||||
}
|
||||
}
|
||||
}
|
||||
var autoredraw = function(root, renderer, pubsub, callback) {
|
||||
var run = throttle(callback)
|
||||
if (renderer != null) {
|
||||
renderer.setEventCallback(function(e) {
|
||||
if (e.redraw !== false) pubsub.publish()
|
||||
})
|
||||
}
|
||||
if (pubsub != null) {
|
||||
if (root.redraw) pubsub.unsubscribe(root.redraw)
|
||||
pubsub.subscribe(run)
|
||||
}
|
||||
return root.redraw = run
|
||||
}
|
||||
m.route = function($window, renderer, pubsub) {
|
||||
m.route = function($window, mount1) {
|
||||
var router = coreRouter($window)
|
||||
var globalId, currentComponent, currentRender, currentArgs, currentPath
|
||||
var RouteComponent = {view: function() {
|
||||
return currentRender(Vnode(currentComponent, null, currentArgs, undefined, undefined, undefined))
|
||||
}}
|
||||
function defaultRender(vnode) {
|
||||
return vnode
|
||||
}
|
||||
var route = function(root, defaultRoute, routes) {
|
||||
var current = {path: null, component: "div", resolver: null}, currentResolutionIdentifier = null
|
||||
var replay = router.defineRoutes(routes, function(payload, args, path, route) {
|
||||
var resolutionIdentifier = currentResolutionIdentifier = {}
|
||||
function resolve(component) {
|
||||
if (resolutionIdentifier !== currentResolutionIdentifier) return
|
||||
resolutionIdentifier = null
|
||||
current.path = path, current.component = component
|
||||
renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined)))
|
||||
currentComponent = "div"
|
||||
currentRender = defaultRender
|
||||
currentArgs = null
|
||||
mount1(root, RouteComponent)
|
||||
router.defineRoutes(routes, function(payload, args, path) {
|
||||
var resolutionIdentifier = globalId = {}
|
||||
var isResolver = typeof payload.view !== "function"
|
||||
var render = defaultRender
|
||||
function resolve (component) {
|
||||
if (resolutionIdentifier !== globalId) return
|
||||
globalId = null
|
||||
currentComponent = component != null ? component : isResolver ? "div" : payload
|
||||
currentRender = render
|
||||
currentArgs = args
|
||||
currentPath = path
|
||||
root.redraw(true)
|
||||
}
|
||||
if (typeof payload.view !== "function") {
|
||||
if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode}
|
||||
if (typeof payload.onmatch !== "function") payload.onmatch = function() {resolve(current.component)}
|
||||
if (path !== current.path) payload.onmatch(Vnode(payload, null, args, undefined, undefined, undefined), resolve)
|
||||
else resolve(current.component)
|
||||
var onmatch = function() {
|
||||
resolve()
|
||||
}
|
||||
else {
|
||||
renderer.render(root, Vnode(payload, null, args, undefined, undefined, undefined))
|
||||
if (isResolver) {
|
||||
if (typeof payload.render === "function") render = payload.render.bind(payload)
|
||||
if (typeof payload.onmatch === "function") onmatch = payload.onmatch
|
||||
}
|
||||
|
||||
onmatch.call(payload, resolve, args, path)
|
||||
}, function() {
|
||||
router.setPath(defaultRoute, null, {replace: true})
|
||||
})
|
||||
autoredraw(root, renderer, pubsub, replay)
|
||||
}
|
||||
route.link = router.link
|
||||
route.prefix = router.setPrefix
|
||||
route.set = router.setPath
|
||||
route.get = router.getPath
|
||||
|
||||
route.get = function() {return currentPath}
|
||||
return route
|
||||
}(window, renderService, redrawService)
|
||||
m.mount = function(renderer, pubsub) {
|
||||
return function(root, component) {
|
||||
if (component === null) {
|
||||
renderer.render(root, [])
|
||||
pubsub.unsubscribe(root.redraw)
|
||||
delete root.redraw
|
||||
return
|
||||
}
|
||||
var run = autoredraw(root, renderer, pubsub, function() {
|
||||
renderer.render(
|
||||
root,
|
||||
Vnode(component, undefined, undefined, undefined, undefined, undefined)
|
||||
)
|
||||
})
|
||||
run()
|
||||
}
|
||||
}(renderService, redrawService)
|
||||
}(window, m.mount)
|
||||
m.withAttr = function(attrName, callback, context) {
|
||||
return function(e) {
|
||||
return callback.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))
|
||||
|
|
|
|||
83
mithril.min.js
vendored
83
mithril.min.js
vendored
|
|
@ -1,41 +1,42 @@
|
|||
new function(){function u(d,e,p,g,k,m){return{tag:d,key:e,attrs:p,children:g,text:k,dom:m,domSize:void 0,state:{},events:void 0,instance:void 0,skip:!1}}function x(d){if(null==d||"string"!==typeof d&&null==d.view)throw Error("The selector must be either a string or a component.");if("string"===typeof d&&void 0===H[d]){for(var e,p,g=[],k={};e=P.exec(d);){var m=e[1],n=e[2];""===m&&""!==n?p=n:"#"===m?k.id=n:"."===m?g.push(n):"["===e[3][0]&&((m=e[6])&&(m=m.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),
|
||||
k[e[4]]=m||!0)}0<g.length&&(k.className=g.join(" "));H[d]=function(d,c){var e=!1,g,h,m=d.className||d["class"],n;for(n in k)d[n]=k[n];void 0!==m&&(void 0!==d["class"]&&(d["class"]=void 0,d.className=m),void 0!==k.className&&(d.className=k.className+" "+m));for(n in d)if("key"!==n){e=!0;break}c instanceof Array&&1==c.length&&null!=c[0]&&"#"===c[0].tag?h=c[0].children:g=c;return u(p||"div",d.key,e?d:void 0,g,h,void 0)}}var l;null!=arguments[1]&&("object"!==typeof arguments[1]||void 0!==arguments[1].tag||
|
||||
arguments[1]instanceof Array)?g=1:(l=arguments[1],g=2);if(arguments.length===g+1)e=arguments[g]instanceof Array?arguments[g]:[arguments[g]];else for(e=[];g<arguments.length;g++)e.push(arguments[g]);return"string"===typeof d?H[d](l||{},u.normalizeChildren(e)):u(d,l&&l.key,l||{},u.normalizeChildren(e),void 0,void 0)}u.normalize=function(d){return d instanceof Array?u("[",void 0,void 0,u.normalizeChildren(d),void 0,void 0):null!=d&&"object"!==typeof d?u("#",void 0,void 0,d,void 0,void 0):d};u.normalizeChildren=
|
||||
function(d){for(var e=0;e<d.length;e++)d[e]=u.normalize(d[e]);return d};var P=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,H={};x.trust=function(d){return u("<",void 0,void 0,d,void 0,void 0)};x.fragment=function(d,e){return u("[",d.key,d,u.normalizeChildren(e),void 0,void 0)};var F=function(d){function e(b,a,f,c,d,e,q){for(;f<c;f++){var r=a[f];null!=r&&t(b,p(r,d,q),e)}}function p(b,a,f){var c=b.tag;null!=b.attrs&&J(b.attrs,b,a);if("string"===typeof c)switch(c){case "#":return b.dom=
|
||||
y.createTextNode(b.children);case "<":return g(b);case "[":var d=y.createDocumentFragment();null!=b.children&&(c=b.children,e(d,c,0,c.length,a,null,f));b.dom=d.firstChild;b.domSize=d.childNodes.length;return d;default:var t=b.tag;switch(b.tag){case "svg":f="http://www.w3.org/2000/svg";break;case "math":f="http://www.w3.org/1998/Math/MathML"}var q=(c=b.attrs)&&c.is,t=f?q?y.createElementNS(f,t,{is:q}):y.createElementNS(f,t):q?y.createElement(t,{is:q}):y.createElement(t);b.dom=t;if(null!=c)for(d in q=
|
||||
f,c)v(b,d,null,c[d],q);null!=b.text&&(""!==b.text?t.textContent=b.text:b.children=[u("#",void 0,void 0,b.text,void 0,void 0)]);null!=b.children&&(d=b.children,e(t,d,0,d.length,a,null,f),a=b.attrs,"select"===b.tag&&null!=a&&("value"in a&&v(b,"value",null,a.value,void 0),"selectedIndex"in a&&v(b,"selectedIndex",null,a.selectedIndex,void 0)));return t}else{b.state||(b.state={});K(b.state,b.tag);J(b.tag,b,a);b.instance=u.normalize(b.tag.view.call(b.state,b));if(null!=b.instance){if(b.instance===b)throw Error("A view cannot return the vnode it received as arguments");
|
||||
a=p(b.instance,a,f);b.dom=b.instance.dom;b.domSize=null!=b.dom?b.instance.domSize:0;b=a}else b.domSize=0,b=D;return b}}function g(b){var a={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(b.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",a=y.createElement(a);a.innerHTML=b.children;b.dom=a.firstChild;b.domSize=a.childNodes.length;b=y.createDocumentFragment();for(var f;f=a.firstChild;)b.appendChild(f);return b}function k(b,a,f,d,
|
||||
h,g){if(a!==f&&(null!=a||null!=f))if(null==a)e(b,f,0,f.length,d,h,void 0);else if(null==f)c(b,a,0,a.length,f);else{var q;a:{if(null!=a.pool&&Math.abs(a.pool.length-f.length)<=Math.abs(a.length-f.length)&&(q=f[0]&&f[0].children&&f[0].children.length||0,Math.abs((a.pool[0]&&a.pool[0].children&&a.pool[0].children.length||0)-q)<=Math.abs((a[0]&&a[0].children&&a[0].children.length||0)-q))){q=!0;break a}q=!1}q&&(a=a.concat(a.pool));if(a.length===f.length&&null!=f[0]&&null==f[0].key)for(var r=0;r<a.length;r++)a[r]===
|
||||
f[r]||null==a[r]&&null==f[r]||(null==a[r]?t(b,p(f[r],d,g),l(a,r+1,h)):null==f[r]?c(b,a,r,r+1,f):m(b,a[r],f[r],d,l(a,r+1,h),q,g),q&&a[r].tag===f[r].tag&&t(b,n(a[r]),l(a,r+1,h)));else{for(var B=r=0,k=a.length-1,z=f.length-1,A;k>=r&&z>=B;){var v=a[r],w=f[B];if(v===w)r++,B++;else if(null!=v&&null!=w&&v.key===w.key)r++,B++,m(b,v,w,d,l(a,r,h),q,g),q&&v.tag===w.tag&&t(b,n(v),h);else if(v=a[k],v===w)k--,B++;else if(null!=v&&null!=w&&v.key===w.key)m(b,v,w,d,l(a,k+1,h),q,g),B<z&&t(b,n(v),l(a,r,h)),k--,B++;
|
||||
else break}for(;k>=r&&z>=B;){v=a[k];w=f[z];if(v===w)k--;else if(null!=v&&null!=w&&v.key===w.key)m(b,v,w,d,l(a,k+1,h),q,g),q&&v.tag===w.tag&&t(b,n(v),h),null!=v.dom&&(h=v.dom),k--;else{if(!A){A=a;var v=k,u={},y;for(y=0;y<v;y++){var C=A[y];null!=C&&(C=C.key,null!=C&&(u[C]=y))}A=u}null!=w&&(v=A[w.key],null!=v?(u=a[v],m(b,u,w,d,l(a,k+1,h),q,g),t(b,n(u),h),a[v].skip=!0,null!=u.dom&&(h=u.dom)):(w=p(w,d,void 0),t(b,w,h),h=w))}z--;if(z<B)break}e(b,f,B,z+1,d,h,g);c(b,a,r,k+1,f)}}}function m(b,a,f,c,d,e,q){var r=
|
||||
a.tag;if(r===f.tag){f.state=a.state;f.events=a.events;var h;var z;null!=f.attrs&&"function"===typeof f.attrs.onbeforeupdate&&(h=f.attrs.onbeforeupdate.call(f.state,f,a));"string"!==typeof f.tag&&"function"===typeof f.tag.onbeforeupdate&&(z=f.tag.onbeforeupdate.call(f.state,f,a));void 0===h&&void 0===z||h||z?h=!1:(f.dom=a.dom,f.domSize=a.domSize,f.instance=a.instance,h=!0);if(!h)if(null!=f.attrs&&x(f.attrs,f,c,e),"string"===typeof r)switch(r){case "#":a.children.toString()!==f.children.toString()&&
|
||||
(a.dom.nodeValue=f.children);f.dom=a.dom;break;case "<":a.children!==f.children?(n(a),t(b,g(f),d)):(f.dom=a.dom,f.domSize=a.domSize);break;case "[":k(b,a.children,f.children,c,d,q);a=0;c=f.children;f.dom=null;if(null!=c){for(var l=0;l<c.length;l++)b=c[l],null!=b&&null!=b.dom&&(null==f.dom&&(f.dom=b.dom),a+=b.domSize||1);1!==a&&(f.domSize=a)}break;default:b=q;d=f.dom=a.dom;switch(f.tag){case "svg":b="http://www.w3.org/2000/svg";break;case "math":b="http://www.w3.org/1998/Math/MathML"}"textarea"===
|
||||
f.tag&&(null==f.attrs&&(f.attrs={}),null!=f.text&&(f.attrs.value=f.text));e=a.attrs;q=f.attrs;r=b;if(null!=q)for(l in q)v(f,l,e&&e[l],q[l],r);if(null!=e)for(l in e)null!=q&&l in q||("o"!==l[0]||"n"!==l[1]||w(l)?"key"!==l&&f.dom.removeAttribute(l):C(f,l,void 0));null!=a.text&&null!=f.text&&""!==f.text?a.text.toString()!==f.text.toString()&&(a.dom.firstChild.nodeValue=f.text):(null!=a.text&&(a.children=[u("#",void 0,void 0,a.text,void 0,a.dom.firstChild)]),null!=f.text&&(f.children=[u("#",void 0,void 0,
|
||||
f.text,void 0,void 0)]),k(d,a.children,f.children,c,null,b))}else f.instance=u.normalize(f.tag.view.call(f.state,f)),x(f.tag,f,c,e),null!=f.instance?(null==a.instance?t(b,p(f.instance,c,q),d):m(b,a.instance,f.instance,c,d,e,q),f.dom=f.instance.dom,f.domSize=f.instance.domSize):null!=a.instance?(A(b,a.instance,null),f.dom=void 0,f.domSize=0):(f.dom=a.dom,f.domSize=a.domSize)}else A(b,a,null),t(b,p(f,c,void 0),d)}function n(b){var a=b.domSize;if(null!=a||null==b.dom){var f=y.createDocumentFragment();
|
||||
if(0<a){for(b=b.dom;--a;)f.appendChild(b.nextSibling);f.insertBefore(b,f.firstChild)}return f}return b.dom}function l(b,a,f){for(;a<b.length;a++)if(null!=b[a]&&null!=b[a].dom)return b[a].dom;return f}function t(b,a,f){f&&f.parentNode?b.insertBefore(a,f):b.appendChild(a)}function c(b,a,f,c,d){for(;f<c;f++){var e=a[f];null!=e&&(e.skip?e.skip=!1:A(b,e,d))}}function z(b){var a=!1;return function(){a||(a=!0,b())}}function A(b,a,f){function c(){if(++e===d&&(h(a),a.dom)){var q=a.domSize||1;if(1<q)for(var r=
|
||||
a.dom;--q;)b.removeChild(r.nextSibling);null!=a.dom.parentNode&&b.removeChild(a.dom);if(q=null!=f&&null==a.domSize)q=a.attrs,q=!(null!=q&&(q.oncreate||q.onupdate||q.onbeforeremove||q.onremove));q&&"string"===typeof a.tag&&(f.pool?f.pool.push(a):f.pool=[a])}}var d=1,e=0;a.attrs&&a.attrs.onbeforeremove&&(d++,a.attrs.onbeforeremove.call(a.state,a,z(c)));"string"!==typeof a.tag&&a.tag.onbeforeremove&&(d++,a.tag.onbeforeremove.call(a.state,a,z(c)));c()}function h(b){b.attrs&&b.attrs.onremove&&b.attrs.onremove.call(b.state,
|
||||
b);"string"!==typeof b.tag&&b.tag.onremove&&b.tag.onremove.call(b.state,b);if(null!=b.instance)h(b.instance);else if(b=b.children,b instanceof Array)for(var a=0;a<b.length;a++){var f=b[a];null!=f&&h(f)}}function v(b,a,f,c,d){var e=b.dom;if("key"!==a&&(f!==c||"value"===a||"checked"===a||"selectedIndex"===a||"selected"===a&&b.dom===y.activeElement||"object"===typeof c)&&"undefined"!==typeof c&&!w(a)){var q=a.indexOf(":");if(-1<q&&"xlink"===a.substr(0,q))e.setAttributeNS("http://www.w3.org/1999/xlink",
|
||||
a.slice(q+1),c);else if("o"===a[0]&&"n"===a[1]&&"function"===typeof c)C(b,a,c);else if("style"===a)if(b=f,b===c&&(e.style.cssText="",b=null),null==c)e.style.cssText="";else if("string"===typeof c)e.style.cssText=c;else{"string"===typeof b&&(e.style.cssText="");for(var r in c)e.style[r]=c[r];if(null!=b&&"string"!==typeof b)for(r in b)r in c||(e.style[r]="")}else if(a in e&&"href"!==a&&"list"!==a&&"form"!==a&&void 0===d){if("input"!==b.tag||"value"!==a||b.dom.value!==c||b.dom!==y.activeElement)e[a]=
|
||||
c}else"boolean"===typeof c?c?e.setAttribute(a,""):e.removeAttribute(a):e.setAttribute("className"===a?"class":a,c)}}function w(b){return"oninit"===b||"oncreate"===b||"onupdate"===b||"onremove"===b||"onbeforeremove"===b||"onbeforeupdate"===b}function C(b,a,c){var d=b.dom,e=function(a){var b=c.call(d,a);"function"===typeof I&&I.call(d,a);return b};if(a in d)d[a]=e;else{var h=a.slice(2);void 0===b.events&&(b.events={});null!=b.events[a]&&d.removeEventListener(h,b.events[a],!1);"function"===typeof c&&
|
||||
(b.events[a]=e,d.addEventListener(h,b.events[a],!1))}}function J(b,a,c){"function"===typeof b.oninit&&b.oninit.call(a.state,a);"function"===typeof b.oncreate&&c.push(b.oncreate.bind(a.state,a))}function x(b,a,c,d){d?J(b,a,c):"function"===typeof b.onupdate&&c.push(b.onupdate.bind(a.state,a))}function K(b,a){Object.keys(a).forEach(function(c){b[c]=a[c]})}var y=d.document,D=y.createDocumentFragment(),I;return{render:function(b,a){var c=[],d=y.activeElement;null==b.vnodes&&(b.textContent="");a instanceof
|
||||
Array||(a=[a]);k(b,b.vnodes,u.normalizeChildren(a),c,null,void 0);b.vnodes=a;for(var e=0;e<c.length;e++)c[e]();y.activeElement!==d&&d.focus()},setEventCallback:function(b){return I=b}}}(window),N=function(d){function e(){function a(){0<arguments.length&&arguments[0]!==E&&g(a,arguments[0],void 0);return a._state.value}p(a,arguments);0<arguments.length&&arguments[0]!==E&&g(a,arguments[0],void 0);return a}function p(a,b){a.constructor=e;a._state={id:H++,value:void 0,error:void 0,state:0,derive:void 0,
|
||||
recover:void 0,deps:{},parents:[],errorStream:void 0,endStream:void 0};a.map=D;a.ap=K;a.of=e;a.valueOf=y;a.toJSON=G;a.toString=y;a.run=z;a["catch"]=A;Object.defineProperties(a,{error:{get:function(){if(!a._state.errorStream){var b=function(){0<arguments.length&&arguments[0]!==E&&g(a,void 0,arguments[0]);return a._state.error};p(b,[]);w(b,[a],F,F);a._state.errorStream=b}return a._state.errorStream}},end:{get:function(){if(!a._state.endStream){var b=e();b.map(function(c){!0===c&&(x(a),x(b));return c});
|
||||
a._state.endStream=b}return a._state.endStream}}})}function g(a,b,c){k(a,b,c);for(var d in a._state.deps)n(a._state.deps[d],!1);a._state.changed=!1;for(var f in a._state.deps)a._state.deps[f]._state.changed=!1}function k(a,b,c){c=t(b,c);if(void 0!==c&&"function"===typeof a._state.recover){if(!l(a,m,!0))return}else m(a,b,c);a._state.changed=!0;2!==a._state.state&&(a._state.state=1)}function m(a,b,c){a._state.value=b;a._state.error=c}function n(a,c){var d=a._state.parents;0<d.length&&d.filter(I).length===
|
||||
d.length&&(c||0<d.filter(b).length)&&(d=d.filter(f),0<d.length?k(a,void 0,d[0]._state.error):l(a,k,!1))}function l(a,b,d){try{var f=d?a._state.recover():a._state.derive();if(f===E)return!1;b(a,f,void 0)}catch(e){b(a,void 0,null!=e.__error?e.__error:e),null==e.__error&&c(a,e)}return!0}function t(a,b){null!=a&&a.constructor===e&&(b=void 0!==a._state.error?a._state.error:t(a._state.value,a._state.error));return b}function c(a,b){0===Object.keys(a._state.deps).length&&setTimeout(function(){0===Object.keys(a._state.deps).length&&
|
||||
d(b)},0)}function z(a){var b=e(),c=this;return w(b,[c],function(){return v(b,a(c()))},void 0)}function A(a){var b=e(),c=this;return w(b,[c],function(){return c._state.value},function(){return v(b,a(c._state.error))})}function h(a,c){return w(e(),c,function(){var d=c.filter(f);if(0<d.length)throw{__error:d[0]._state.error};return a.apply(this,c.concat([c.filter(b)]))},void 0)}function v(a,b){if(null!=b&&b.constructor===e){var c=b,d=function(){k(a,c._state.value,c._state.error);for(var b in a._state.deps)n(a._state.deps[b],
|
||||
!1)};c.map(d)["catch"](function(a){d();throw{__error:a};});if(0===c._state.state)return E;if(c._state.error)throw{__error:c._state.error};b=c._state.value}return b}function w(b,c,d,f){var e=b._state;e.derive=d;e.recover=f;e.parents=c.filter(a);u(b,e.parents);n(b,!0);return b}function u(a,b){for(var c=0;c<b.length;c++)b[c]._state.deps[a._state.id]=a,u(a,b[c]._state.parents)}function x(a){for(var b=0;b<a._state.parents.length;b++)delete a._state.parents[b]._state.deps[a._state.id];for(var c in a._state.deps){var b=
|
||||
a._state.deps[c],d=b._state.parents.indexOf(a);-1<d&&b._state.parents.splice(d,1)}a._state.state=2;a._state.deps={}}function D(a){return h(function(b){return a(b())},[this])}function K(a){return h(function(a,b){return a()(b())},[this,a])}function y(){return this._state.value}function G(){return null!=this._state.value&&"function"===typeof this._state.value.toJSON?this._state.value.toJSON():this._state.value}function I(a){return 1===a._state.state}function b(a){return a._state.changed}function a(a){return 2!==
|
||||
a._state.state}function f(a){return a._state.error}var H=0,F=function(){},E={};e.merge=function(a){return h(function(){return a.map(function(a){return a()})},a)};e.combine=h;e.reject=function(a){var b=e();b.error(a);return b};e.HALT=E;return e}(console.log.bind(console)),D=function(d){function e(d,g){if(g instanceof Array)for(var n=0;n<g.length;n++)e(d+"["+n+"]",g[n]);else if("[object Object]"===Object.prototype.toString.call(g))for(n in g)e(d+"["+n+"]",g[n]);else p.push(encodeURIComponent(d)+(null!=
|
||||
g&&""!==g?"="+encodeURIComponent(g):""))}if("[object Object]"!==Object.prototype.toString.call(d))return"";var p=[],g;for(g in d)e(g,d[g]);return p.join("&")},L=function(d,e){function p(c,d){if(null==d)return c;for(var e=c.match(/:[^\/]+/gi)||[],h=0;h<e.length;h++){var g=e[h].slice(1);null!=d[g]&&(c=c.replace(e[h],d[g]),delete d[g])}return c}function g(c,d){var e=D(d);if(""!==e){var h=0>c.indexOf("?")?"?":"&";c+=h+e}return c}function k(c){try{return""!==c?JSON.parse(c):null}catch(d){throw Error(c);
|
||||
}}function m(c){return c.responseText}function n(c,d){if("function"===typeof c)if(d instanceof Array)for(var e=0;e<d.length;e++)d[e]=new c(d[e]);else return new c(d);return d}var l=0,t;return{request:function(c){var l=e();void 0!==c.initialValue&&l(c.initialValue);var A="boolean"===typeof c.useBody?c.useBody:"GET"!==c.method&&"TRACE"!==c.method;"function"!==typeof c.serialize&&(c.serialize="undefined"!==typeof FormData&&c.data instanceof FormData?function(c){return c}:JSON.stringify);"function"!==
|
||||
typeof c.deserialize&&(c.deserialize=k);"function"!==typeof c.extract&&(c.extract=m);c.url=p(c.url,c.data);A?c.data=c.serialize(c.data):c.url=g(c.url,c.data);var h=new d.XMLHttpRequest;h.open(c.method,c.url,"boolean"===typeof c.async?c.async:!0,"string"===typeof c.user?c.user:void 0,"string"===typeof c.password?c.password:void 0);c.serialize===JSON.stringify&&A&&h.setRequestHeader("Content-Type","application/json; charset=utf-8");c.deserialize===k&&h.setRequestHeader("Accept","application/json, text/*");
|
||||
"function"===typeof c.config&&(h=c.config(h,c)||h);h.onreadystatechange=function(){if(4===h.readyState){try{var d=c.extract!==m?c.extract(h,c):c.deserialize(c.extract(h,c));if(200<=h.status&&300>h.status)l(n(c.type,d));else{var e=Error(h.responseText),g;for(g in d)e[g]=d[g];l.error(e)}}catch(k){l.error(k)}"function"===typeof t&&t()}};A?h.send(c.data):h.send();return l},jsonp:function(c){var k=e();void 0!==c.initialValue&&k(c.initialValue);var m=c.callbackName||"_mithril_"+Math.round(1E16*Math.random())+
|
||||
"_"+l++,h=d.document.createElement("script");d[m]=function(e){h.parentNode.removeChild(h);k(n(c.type,e));"function"===typeof t&&t();delete d[m]};h.onerror=function(){h.parentNode.removeChild(h);k.error(Error("JSONP request failed"));"function"===typeof t&&t();delete d[m]};null==c.data&&(c.data={});c.url=p(c.url,c.data);c.data[c.callbackKey||"callback"]=m;h.src=g(c.url,c.data);d.document.documentElement.appendChild(h);return k},setCompletionCallback:function(c){t=c}}}(window,N),G=function(){var d=
|
||||
[];return{subscribe:d.push.bind(d),unsubscribe:function(e){e=d.indexOf(e);-1<e&&d.splice(e,1)},publish:function(){for(var e=0;e<d.length;e++)d[e].apply(this,arguments)}}}(),M=function(d){if(""===d||null==d)return{};"?"===d.charAt(0)&&(d=d.slice(1));d=d.split("&");for(var e={},p={},g=0;g<d.length;g++){var k=d[g].split("="),m=decodeURIComponent(k[0]),k=2===k.length?decodeURIComponent(k[1]):"",n=Number(k);""!==k&&!isNaN(n)||"NaN"===k?k=n:"true"===k?k=!0:"false"===k?k=!1:(n=new Date(k),isNaN(n.getTime())||
|
||||
(k=n));var n=m.split(/\]\[?|\[/),l=e;-1<m.indexOf("[")&&n.pop();for(var t=0;t<n.length;t++){var m=n[t],c=n[t+1],c=""==c||!isNaN(parseInt(c,10)),z=t===n.length-1;""===m&&(m=n.slice(0,t).join(),null==p[m]&&(p[m]=0),m=p[m]++);null==l[m]&&(l[m]=z?k:c?[]:{});l=l[m]}}return e};L.setCompletionCallback(G.publish);var Q=function(d){function e(e){var c=d.location[e].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===e&&"/"!==c[0]&&(c="/"+c);return c}function p(d,c,e){var g=d.indexOf("?"),h=
|
||||
d.indexOf("#"),k=-1<g?g:-1<h?h:d.length;if(-1<g){var g=M(d.slice(g+1,-1<h?h:d.length)),l;for(l in g)c[l]=g[l]}if(-1<h)for(l in c=M(d.slice(h+1)),c)e[l]=c[l];return d.slice(0,k)}function g(){switch(l.charAt(0)){case "#":return e("hash").slice(l.length);case "?":return e("search").slice(l.length)+e("hash");default:return e("pathname").slice(l.length)+e("search")+e("hash")}}function k(e,c,g){var k={},h={};e=p(e,k,h);if(null!=c){for(var n in c)k[n]=c[n];e=e.replace(/:([^\/]+)/g,function(d,e){delete k[e];
|
||||
return c[e]})}(n=D(k))&&(e+="?"+n);(h=D(h))&&(e+="#"+h);m?(g&&g.replace?d.history.replaceState(null,null,l+e):d.history.pushState(null,null,l+e),d.onpopstate()):d.location.href=l+e}var m="function"===typeof d.history.pushState,n="function"===typeof setImmediate?setImmediate:setTimeout,l="#!";return{setPrefix:function(d){l=d},getPath:g,setPath:k,defineRoutes:function(e,c,k){function u(){var d=g(),l={},m=p(d,l,l);n(function(){for(var g in e){var n=new RegExp("^"+g.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,
|
||||
"([^\\/]+)")+"/?$");if(n.test(m)){m.replace(n,function(){for(var k=g.match(/:[^\/]+/g)||[],n=[].slice.call(arguments,1,-2),m=0;m<k.length;m++)l[k[m].replace(/:|\./g,"")]=decodeURIComponent(n[m]);c(e[g],l,d,g)});return}}k(d,l)})}m?d.onpopstate=u:"#"===l.charAt(0)&&(d.onhashchange=u);u();return u},link:function(d){d.dom.setAttribute("href",l+d.attrs.href);d.dom.onclick=function(c){c.preventDefault();c.redraw=!1;k(d.attrs.href,void 0,void 0)}}}},R=function(d){var e=0,p=null,g="function"===typeof requestAnimationFrame?
|
||||
requestAnimationFrame:setTimeout;return function(k){var m=Date.now();!0===k||0===e||16<=m-e?(e=m,d()):null===p&&(p=g(function(){p=null;d();e=Date.now()},16-(m-e)))}},O=function(d,e,p,g){g=R(g);null!=e&&e.setEventCallback(function(d){!1!==d.redraw&&p.publish()});null!=p&&(d.redraw&&p.unsubscribe(d.redraw),p.subscribe(g));return d.redraw=g};x.route=function(d,e,p){var g=Q(d);d=function(d,m,n){var l=null,t="div",c=null;n=g.defineRoutes(n,function(g,m,h,n){function p(n){x===c&&(x=null,l=h,t=n,e.render(d,
|
||||
g.render(u(n,null,m,void 0,void 0,void 0))))}var x=c={};if("function"!==typeof g.view)if("function"!==typeof g.render&&(g.render=function(c){return c}),"function"!==typeof g.onmatch&&(g.onmatch=function(){p(t)}),h!==l)g.onmatch(u(g,null,m,void 0,void 0,void 0),p);else p(t);else e.render(d,u(g,null,m,void 0,void 0,void 0))},function(){g.setPath(m,null,{replace:!0})});O(d,e,p,n)};d.link=g.link;d.prefix=g.setPrefix;d.set=g.setPath;d.get=g.getPath;return d}(window,F,G);x.mount=function(d,e){return function(p,
|
||||
g){null===g?(d.render(p,[]),e.unsubscribe(p.redraw),delete p.redraw):O(p,d,e,function(){d.render(p,u(g,void 0,void 0,void 0,void 0,void 0))})()}}(F,G);x.withAttr=function(d,e,p){return function(g){return e.call(p||this,d in g.currentTarget?g.currentTarget[d]:g.currentTarget.getAttribute(d))}};x.prop=N;x.render=F.render;x.redraw=G.publish;x.request=L.request;x.jsonp=L.jsonp;x.parseQueryString=M;x.buildQueryString=D;x.version="1.0.0";"undefined"!==typeof module?module.exports=x:window.m=x};
|
||||
new function(){function x(b,f,n,h,k,l){return{tag:b,key:f,attrs:n,children:h,text:k,dom:l,domSize:void 0,state:{},events:void 0,instance:void 0,skip:!1}}function y(b){if(null==b||"string"!==typeof b&&null==b.view)throw Error("The selector must be either a string or a component.");if("string"===typeof b&&void 0===F[b]){for(var f,n,h=[],k={};f=P.exec(b);){var l=f[1],m=f[2];""===l&&""!==m?n=m:"#"===l?k.id=m:"."===l?h.push(m):"["===f[3][0]&&((l=f[6])&&(l=l.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),
|
||||
k[f[4]]=l||!0)}0<h.length&&(k.className=h.join(" "));F[b]=function(b,d){var f=!1,l,h,m=b.className||b["class"],r;for(r in k)b[r]=k[r];void 0!==m&&(void 0!==b["class"]&&(b["class"]=void 0,b.className=m),void 0!==k.className&&(b.className=k.className+" "+m));for(r in b)if("key"!==r){f=!0;break}d instanceof Array&&1==d.length&&null!=d[0]&&"#"===d[0].tag?h=d[0].children:l=d;return x(n||"div",b.key,f?b:void 0,l,h,void 0)}}var w;null!=arguments[1]&&("object"!==typeof arguments[1]||void 0!==arguments[1].tag||
|
||||
arguments[1]instanceof Array)?h=1:(w=arguments[1],h=2);if(arguments.length===h+1)f=arguments[h]instanceof Array?arguments[h]:[arguments[h]];else for(f=[];h<arguments.length;h++)f.push(arguments[h]);return"string"===typeof b?F[b](w||{},x.normalizeChildren(f)):x(b,w&&w.key,w||{},x.normalizeChildren(f),void 0,void 0)}x.normalize=function(b){return b instanceof Array?x("[",void 0,void 0,x.normalizeChildren(b),void 0,void 0):null!=b&&"object"!==typeof b?x("#",void 0,void 0,b,void 0,void 0):b};x.normalizeChildren=
|
||||
function(b){for(var f=0;f<b.length;f++)b[f]=x.normalize(b[f]);return b};var P=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,F={};y.trust=function(b){return x("<",void 0,void 0,b,void 0,void 0)};y.fragment=function(b,f){return x("[",b.key,b,x.normalizeChildren(f),void 0,void 0)};var N=function(b){function f(c,a,e,d,b,f,p){for(;e<d;e++){var v=a[e];null!=v&&q(c,n(v,b,p),f)}}function n(c,a,e){var d=c.tag;null!=c.attrs&&D(c.attrs,c,a);if("string"===typeof d)switch(d){case "#":return c.dom=
|
||||
z.createTextNode(c.children);case "<":return h(c);case "[":var b=z.createDocumentFragment();null!=c.children&&(d=c.children,f(b,d,0,d.length,a,null,e));c.dom=b.firstChild;c.domSize=b.childNodes.length;return b;default:var g=c.tag;switch(c.tag){case "svg":e="http://www.w3.org/2000/svg";break;case "math":e="http://www.w3.org/1998/Math/MathML"}var p=(d=c.attrs)&&d.is,g=e?p?z.createElementNS(e,g,{is:p}):z.createElementNS(e,g):p?z.createElement(g,{is:p}):z.createElement(g);c.dom=g;if(null!=d)for(b in p=
|
||||
e,d)u(c,b,null,d[b],p);null!=c.text&&(""!==c.text?g.textContent=c.text:c.children=[x("#",void 0,void 0,c.text,void 0,void 0)]);null!=c.children&&(b=c.children,f(g,b,0,b.length,a,null,e),a=c.attrs,"select"===c.tag&&null!=a&&("value"in a&&u(c,"value",null,a.value,void 0),"selectedIndex"in a&&u(c,"selectedIndex",null,a.selectedIndex,void 0)));return g}else{c.state||(c.state={});Q(c.state,c.tag);D(c.tag,c,a);c.instance=x.normalize(c.tag.view.call(c.state,c));if(null!=c.instance){if(c.instance===c)throw Error("A view cannot return the vnode it received as arguments");
|
||||
a=n(c.instance,a,e);c.dom=c.instance.dom;c.domSize=null!=c.dom?c.instance.domSize:0;c=a}else c.domSize=0,c=J;return c}}function h(c){var a={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(c.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",a=z.createElement(a);a.innerHTML=c.children;c.dom=a.firstChild;c.domSize=a.childNodes.length;c=z.createDocumentFragment();for(var e;e=a.firstChild;)c.appendChild(e);return c}function k(c,a,e,b,
|
||||
g,h){if(a!==e&&(null!=a||null!=e))if(null==a)f(c,e,0,e.length,b,g,void 0);else if(null==e)d(c,a,0,a.length,e);else{var p;a:{if(null!=a.pool&&Math.abs(a.pool.length-e.length)<=Math.abs(a.length-e.length)&&(p=e[0]&&e[0].children&&e[0].children.length||0,Math.abs((a.pool[0]&&a.pool[0].children&&a.pool[0].children.length||0)-p)<=Math.abs((a[0]&&a[0].children&&a[0].children.length||0)-p))){p=!0;break a}p=!1}p&&(a=a.concat(a.pool));if(a.length===e.length&&null!=e[0]&&null==e[0].key)for(var v=0;v<a.length;v++)a[v]===
|
||||
e[v]||null==a[v]&&null==e[v]||(null==a[v]?q(c,n(e[v],b,h),w(a,v+1,g)):null==e[v]?d(c,a,v,v+1,e):l(c,a[v],e[v],b,w(a,v+1,g),p,h),p&&a[v].tag===e[v].tag&&q(c,m(a[v]),w(a,v+1,g)));else{for(var E=v=0,k=a.length-1,A=e.length-1,t;k>=v&&A>=E;){var r=a[v],u=e[E];if(r===u)v++,E++;else if(null!=r&&null!=u&&r.key===u.key)v++,E++,l(c,r,u,b,w(a,v,g),p,h),p&&r.tag===u.tag&&q(c,m(r),g);else if(r=a[k],r===u)k--,E++;else if(null!=r&&null!=u&&r.key===u.key)l(c,r,u,b,w(a,k+1,g),p,h),E<A&&q(c,m(r),w(a,v,g)),k--,E++;
|
||||
else break}for(;k>=v&&A>=E;){r=a[k];u=e[A];if(r===u)k--;else if(null!=r&&null!=u&&r.key===u.key)l(c,r,u,b,w(a,k+1,g),p,h),p&&r.tag===u.tag&&q(c,m(r),g),null!=r.dom&&(g=r.dom),k--;else{if(!t){t=a;var r=k,C={},z;for(z=0;z<r;z++){var D=t[z];null!=D&&(D=D.key,null!=D&&(C[D]=z))}t=C}null!=u&&(r=t[u.key],null!=r?(C=a[r],l(c,C,u,b,w(a,k+1,g),p,h),q(c,m(C),g),a[r].skip=!0,null!=C.dom&&(g=C.dom)):(u=n(u,b,void 0),q(c,u,g),g=u))}A--;if(A<E)break}f(c,e,E,A+1,b,g,h);d(c,a,v,k+1,e)}}}function l(c,a,e,b,d,g,p){var v=
|
||||
a.tag;if(v===e.tag){e.state=a.state;e.events=a.events;var f;var t;null!=e.attrs&&"function"===typeof e.attrs.onbeforeupdate&&(f=e.attrs.onbeforeupdate.call(e.state,e,a));"string"!==typeof e.tag&&"function"===typeof e.tag.onbeforeupdate&&(t=e.tag.onbeforeupdate.call(e.state,e,a));void 0===f&&void 0===t||f||t?f=!1:(e.dom=a.dom,e.domSize=a.domSize,e.instance=a.instance,f=!0);if(!f)if(null!=e.attrs&&y(e.attrs,e,b,g),"string"===typeof v)switch(v){case "#":a.children.toString()!==e.children.toString()&&
|
||||
(a.dom.nodeValue=e.children);e.dom=a.dom;break;case "<":a.children!==e.children?(m(a),q(c,h(e),d)):(e.dom=a.dom,e.domSize=a.domSize);break;case "[":k(c,a.children,e.children,b,d,p);a=0;b=e.children;e.dom=null;if(null!=b){for(var B=0;B<b.length;B++)c=b[B],null!=c&&null!=c.dom&&(null==e.dom&&(e.dom=c.dom),a+=c.domSize||1);1!==a&&(e.domSize=a)}break;default:c=p;d=e.dom=a.dom;switch(e.tag){case "svg":c="http://www.w3.org/2000/svg";break;case "math":c="http://www.w3.org/1998/Math/MathML"}"textarea"===
|
||||
e.tag&&(null==e.attrs&&(e.attrs={}),null!=e.text&&(e.attrs.value=e.text));g=a.attrs;p=e.attrs;v=c;if(null!=p)for(B in p)u(e,B,g&&g[B],p[B],v);if(null!=g)for(B in g)null!=p&&B in p||("o"!==B[0]||"n"!==B[1]||r(B)?"key"!==B&&e.dom.removeAttribute(B):C(e,B,void 0));null!=a.text&&null!=e.text&&""!==e.text?a.text.toString()!==e.text.toString()&&(a.dom.firstChild.nodeValue=e.text):(null!=a.text&&(a.children=[x("#",void 0,void 0,a.text,void 0,a.dom.firstChild)]),null!=e.text&&(e.children=[x("#",void 0,void 0,
|
||||
e.text,void 0,void 0)]),k(d,a.children,e.children,b,null,c))}else e.instance=x.normalize(e.tag.view.call(e.state,e)),y(e.tag,e,b,g),null!=e.instance?(null==a.instance?q(c,n(e.instance,b,p),d):l(c,a.instance,e.instance,b,d,g,p),e.dom=e.instance.dom,e.domSize=e.instance.domSize):null!=a.instance?(A(c,a.instance,null),e.dom=void 0,e.domSize=0):(e.dom=a.dom,e.domSize=a.domSize)}else A(c,a,null),q(c,n(e,b,void 0),d)}function m(c){var a=c.domSize;if(null!=a||null==c.dom){var e=z.createDocumentFragment();
|
||||
if(0<a){for(c=c.dom;--a;)e.appendChild(c.nextSibling);e.insertBefore(c,e.firstChild)}return e}return c.dom}function w(c,a,e){for(;a<c.length;a++)if(null!=c[a]&&null!=c[a].dom)return c[a].dom;return e}function q(c,a,e){e&&e.parentNode?c.insertBefore(a,e):c.appendChild(a)}function d(c,a,e,b,d){for(;e<b;e++){var g=a[e];null!=g&&(g.skip?g.skip=!1:A(c,g,d))}}function g(c){var a=!1;return function(){a||(a=!0,c())}}function A(c,a,e){function b(){if(++f===d&&(t(a),a.dom)){var p=a.domSize||1;if(1<p)for(var g=
|
||||
a.dom;--p;)c.removeChild(g.nextSibling);null!=a.dom.parentNode&&c.removeChild(a.dom);if(p=null!=e&&null==a.domSize)p=a.attrs,p=!(null!=p&&(p.oncreate||p.onupdate||p.onbeforeremove||p.onremove));p&&"string"===typeof a.tag&&(e.pool?e.pool.push(a):e.pool=[a])}}var d=1,f=0;a.attrs&&a.attrs.onbeforeremove&&(d++,a.attrs.onbeforeremove.call(a.state,a,g(b)));"string"!==typeof a.tag&&a.tag.onbeforeremove&&(d++,a.tag.onbeforeremove.call(a.state,a,g(b)));b()}function t(c){c.attrs&&c.attrs.onremove&&c.attrs.onremove.call(c.state,
|
||||
c);"string"!==typeof c.tag&&c.tag.onremove&&c.tag.onremove.call(c.state,c);if(null!=c.instance)t(c.instance);else if(c=c.children,c instanceof Array)for(var a=0;a<c.length;a++){var e=c[a];null!=e&&t(e)}}function u(c,a,e,b,d){var g=c.dom;if("key"!==a&&(e!==b||"value"===a||"checked"===a||"selectedIndex"===a||"selected"===a&&c.dom===z.activeElement||"object"===typeof b)&&"undefined"!==typeof b&&!r(a)){var p=a.indexOf(":");if(-1<p&&"xlink"===a.substr(0,p))g.setAttributeNS("http://www.w3.org/1999/xlink",
|
||||
a.slice(p+1),b);else if("o"===a[0]&&"n"===a[1]&&"function"===typeof b)C(c,a,b);else if("style"===a)if(c=e,c===b&&(g.style.cssText="",c=null),null==b)g.style.cssText="";else if("string"===typeof b)g.style.cssText=b;else{"string"===typeof c&&(g.style.cssText="");for(var v in b)g.style[v]=b[v];if(null!=c&&"string"!==typeof c)for(v in c)v in b||(g.style[v]="")}else if(a in g&&"href"!==a&&"list"!==a&&"form"!==a&&void 0===d){if("input"!==c.tag||"value"!==a||c.dom.value!==b||c.dom!==z.activeElement)g[a]=
|
||||
b}else"boolean"===typeof b?b?g.setAttribute(a,""):g.removeAttribute(a):g.setAttribute("className"===a?"class":a,b)}}function r(c){return"oninit"===c||"oncreate"===c||"onupdate"===c||"onremove"===c||"onbeforeremove"===c||"onbeforeupdate"===c}function C(c,a,b){var d=c.dom,g=function(a){var c=b.call(d,a);"function"===typeof I&&I.call(d,a);return c};if(a in d)d[a]=g;else{var f=a.slice(2);void 0===c.events&&(c.events={});null!=c.events[a]&&d.removeEventListener(f,c.events[a],!1);"function"===typeof b&&
|
||||
(c.events[a]=g,d.addEventListener(f,c.events[a],!1))}}function D(c,a,b){"function"===typeof c.oninit&&c.oninit.call(a.state,a);"function"===typeof c.oncreate&&b.push(c.oncreate.bind(a.state,a))}function y(c,a,b,d){d?D(c,a,b):"function"===typeof c.onupdate&&b.push(c.onupdate.bind(a.state,a))}function Q(c,a){Object.keys(a).forEach(function(b){c[b]=a[b]})}var z=b.document,J=z.createDocumentFragment(),I;return{render:function(c,a){if(!c)throw Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");
|
||||
var b=[],d=z.activeElement;null==c.vnodes&&(c.textContent="");a instanceof Array||(a=[a]);k(c,c.vnodes,x.normalizeChildren(a),b,null,void 0);c.vnodes=a;for(var g=0;g<b.length;g++)b[g]();z.activeElement!==d&&d.focus()},setEventCallback:function(c){return I=c}}}(window),O=function(b){function f(){function a(){0<arguments.length&&arguments[0]!==G&&h(a,arguments[0],void 0);return a._state.value}n(a,arguments);0<arguments.length&&arguments[0]!==G&&h(a,arguments[0],void 0);return a}function n(a,c){a.constructor=
|
||||
f;a._state={id:H++,value:void 0,error:void 0,state:0,derive:void 0,recover:void 0,deps:{},parents:[],errorStream:void 0,endStream:void 0};a.map=x;a.ap=y;a.of=f;a.valueOf=z;a.toJSON=J;a.toString=z;a.run=g;a["catch"]=A;Object.defineProperties(a,{error:{get:function(){if(!a._state.errorStream){var c=function(){0<arguments.length&&arguments[0]!==G&&h(a,void 0,arguments[0]);return a._state.error};n(c,[]);r(c,[a],F,F);a._state.errorStream=c}return a._state.errorStream}},end:{get:function(){if(!a._state.endStream){var c=
|
||||
f();c.map(function(b){!0===b&&(D(a),D(c));return b});a._state.endStream=c}return a._state.endStream}}})}function h(a,c,b){k(a,c,b);for(var d in a._state.deps)m(a._state.deps[d],!1);a._state.changed=!1;for(var e in a._state.deps)a._state.deps[e]._state.changed=!1}function k(a,c,b){b=q(c,b);if(void 0!==b&&"function"===typeof a._state.recover){if(!w(a,l,!0))return}else l(a,c,b);a._state.changed=!0;2!==a._state.state&&(a._state.state=1)}function l(a,c,b){a._state.value=c;a._state.error=b}function m(a,
|
||||
b){var d=a._state.parents;0<d.length&&d.filter(I).length===d.length&&(b||0<d.filter(c).length)&&(d=d.filter(e),0<d.length?k(a,void 0,d[0]._state.error):w(a,k,!1))}function w(a,c,b){try{var e=b?a._state.recover():a._state.derive();if(e===G)return!1;c(a,e,void 0)}catch(g){c(a,void 0,null!=g.__error?g.__error:g),null==g.__error&&d(a,g)}return!0}function q(a,c){null!=a&&a.constructor===f&&(c=void 0!==a._state.error?a._state.error:q(a._state.value,a._state.error));return c}function d(a,c){0===Object.keys(a._state.deps).length&&
|
||||
setTimeout(function(){0===Object.keys(a._state.deps).length&&b(c)},0)}function g(a){var c=f(),b=this;return r(c,[b],function(){return u(c,a(b()))},void 0)}function A(a){var c=f(),b=this;return r(c,[b],function(){return b._state.value},function(){return u(c,a(b._state.error))})}function t(a,b){return r(f(),b,function(){var d=b.filter(e);if(0<d.length)throw{__error:d[0]._state.error};return a.apply(this,b.concat([b.filter(c)]))},void 0)}function u(a,c){if(null!=c&&c.constructor===f){var b=c,d=function(){k(a,
|
||||
b._state.value,b._state.error);for(var c in a._state.deps)m(a._state.deps[c],!1)};b.map(d)["catch"](function(a){d();throw{__error:a};});if(0===b._state.state)return G;if(b._state.error)throw{__error:b._state.error};c=b._state.value}return c}function r(c,b,d,e){var g=c._state;g.derive=d;g.recover=e;g.parents=b.filter(a);C(c,g.parents);m(c,!0);return c}function C(a,c){for(var b=0;b<c.length;b++)c[b]._state.deps[a._state.id]=a,C(a,c[b]._state.parents)}function D(a){for(var c=0;c<a._state.parents.length;c++)delete a._state.parents[c]._state.deps[a._state.id];
|
||||
for(var b in a._state.deps){var c=a._state.deps[b],d=c._state.parents.indexOf(a);-1<d&&c._state.parents.splice(d,1)}a._state.state=2;a._state.deps={}}function x(a){return t(function(c){return a(c())},[this])}function y(a){return t(function(a,c){return a()(c())},[this,a])}function z(){return this._state.value}function J(){return null!=this._state.value&&"function"===typeof this._state.value.toJSON?this._state.value.toJSON():this._state.value}function I(a){return 1===a._state.state}function c(a){return a._state.changed}
|
||||
function a(a){return 2!==a._state.state}function e(a){return a._state.error}var H=0,F=function(){},G={};f.merge=function(a){return t(function(){return a.map(function(a){return a()})},a)};f.combine=t;f.reject=function(a){var c=f();c.error(a);return c};f.HALT=G;return f}(console.log.bind(console)),H=function(b){function f(b,h){if(h instanceof Array)for(var m=0;m<h.length;m++)f(b+"["+m+"]",h[m]);else if("[object Object]"===Object.prototype.toString.call(h))for(m in h)f(b+"["+m+"]",h[m]);else n.push(encodeURIComponent(b)+
|
||||
(null!=h&&""!==h?"="+encodeURIComponent(h):""))}if("[object Object]"!==Object.prototype.toString.call(b))return"";var n=[],h;for(h in b)f(h,b[h]);return n.join("&")},K=function(b,f){function n(b,g){if(null==g)return b;for(var f=b.match(/:[^\/]+/gi)||[],h=0;h<f.length;h++){var k=f[h].slice(1);null!=g[k]&&(b=b.replace(f[h],g[k]),delete g[k])}return b}function h(b,g){var f=H(g);if(""!==f){var h=0>b.indexOf("?")?"?":"&";b+=h+f}return b}function k(b){try{return""!==b?JSON.parse(b):null}catch(g){throw Error(b);
|
||||
}}function l(b){return b.responseText}function m(b,g){if("function"===typeof b)if(g instanceof Array)for(var f=0;f<g.length;f++)g[f]=new b(g[f]);else return new b(g);return g}var w=0,q;return{request:function(d){var g=f();void 0!==d.initialValue&&g(d.initialValue);var A="boolean"===typeof d.useBody?d.useBody:"GET"!==d.method&&"TRACE"!==d.method;"function"!==typeof d.serialize&&(d.serialize="undefined"!==typeof FormData&&d.data instanceof FormData?function(b){return b}:JSON.stringify);"function"!==
|
||||
typeof d.deserialize&&(d.deserialize=k);"function"!==typeof d.extract&&(d.extract=l);d.url=n(d.url,d.data);A?d.data=d.serialize(d.data):d.url=h(d.url,d.data);var t=new b.XMLHttpRequest;t.open(d.method,d.url,"boolean"===typeof d.async?d.async:!0,"string"===typeof d.user?d.user:void 0,"string"===typeof d.password?d.password:void 0);d.serialize===JSON.stringify&&A&&t.setRequestHeader("Content-Type","application/json; charset=utf-8");d.deserialize===k&&t.setRequestHeader("Accept","application/json, text/*");
|
||||
"function"===typeof d.config&&(t=d.config(t,d)||t);t.onreadystatechange=function(){if(4===t.readyState){try{var b=d.extract!==l?d.extract(t,d):d.deserialize(d.extract(t,d));if(200<=t.status&&300>t.status)g(m(d.type,b));else{var f=Error(t.responseText),h;for(h in b)f[h]=b[h];g.error(f)}}catch(k){g.error(k)}"function"===typeof q&&q()}};A?t.send(d.data):t.send();return g},jsonp:function(d){var g=f();void 0!==d.initialValue&&g(d.initialValue);var k=d.callbackName||"_mithril_"+Math.round(1E16*Math.random())+
|
||||
"_"+w++,t=b.document.createElement("script");b[k]=function(f){t.parentNode.removeChild(t);g(m(d.type,f));"function"===typeof q&&q();delete b[k]};t.onerror=function(){t.parentNode.removeChild(t);g.error(Error("JSONP request failed"));"function"===typeof q&&q();delete b[k]};null==d.data&&(d.data={});d.url=n(d.url,d.data);d.data[d.callbackKey||"callback"]=k;t.src=h(d.url,d.data);b.document.documentElement.appendChild(t);return g},setCompletionCallback:function(b){q=b}}}(window,O),L=function(){var b=
|
||||
[];return{subscribe:b.push.bind(b),unsubscribe:function(f){f=b.indexOf(f);-1<f&&b.splice(f,1)},publish:function(){for(var f=0;f<b.length;f++)b[f].apply(this,arguments)}}}(),M=function(b){if(""===b||null==b)return{};"?"===b.charAt(0)&&(b=b.slice(1));b=b.split("&");for(var f={},n={},h=0;h<b.length;h++){var k=b[h].split("="),l=decodeURIComponent(k[0]),k=2===k.length?decodeURIComponent(k[1]):"",m=Number(k);""!==k&&!isNaN(m)||"NaN"===k?k=m:"true"===k?k=!0:"false"===k?k=!1:(m=new Date(k),isNaN(m.getTime())||
|
||||
(k=m));var m=l.split(/\]\[?|\[/),w=f;-1<l.indexOf("[")&&m.pop();for(var q=0;q<m.length;q++){var l=m[q],d=m[q+1],d=""==d||!isNaN(parseInt(d,10)),g=q===m.length-1;""===l&&(l=m.slice(0,q).join(),null==n[l]&&(n[l]=0),l=n[l]++);null==w[l]&&(w[l]=g?k:d?[]:{});w=w[l]}}return f};K.setCompletionCallback(L.publish);var R=function(b){var f=0,n=null,h="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(k){var l=Date.now();!0===k||0===f||16<=l-f?(f=l,b()):null===n&&(n=h(function(){n=
|
||||
null;b();f=Date.now()},16-(l-f)))}},S=function(b,f,n,h){h=R(h);null!=f&&f.setEventCallback(function(b){!1!==b.redraw&&n.publish()});null!=n&&(b.redraw&&n.unsubscribe(b.redraw),n.subscribe(h));return b.redraw=h};y.mount=function(b,f){return function(n,h){null===h?(b.render(n,[]),f.unsubscribe(n.redraw),delete n.redraw):S(n,b,f,function(){b.render(n,x(h,void 0,void 0,void 0,void 0,void 0))})()}}(N,L);var T=function(b){function f(g){var d=b.location[g].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);
|
||||
"pathname"===g&&"/"!==d[0]&&(d="/"+d);return d}function n(b){return function(){null==d&&(d=w(function(){d=null;b()}))}}function h(b,d,f){var h=b.indexOf("?"),k=b.indexOf("#"),m=-1<h?h:-1<k?k:b.length;if(-1<h){var h=M(b.slice(h+1,-1<k?k:b.length)),l;for(l in h)d[l]=h[l]}if(-1<k)for(l in d=M(b.slice(k+1)),d)f[l]=d[l];return b.slice(0,m)}function k(){switch(q.charAt(0)){case "#":return f("hash").slice(q.length);case "?":return f("search").slice(q.length)+f("hash");default:return f("pathname").slice(q.length)+
|
||||
f("search")+f("hash")}}function l(d,f,k){var l={},r={};d=h(d,l,r);if(null!=f){for(var n in f)l[n]=f[n];d=d.replace(/:([^\/]+)/g,function(b,d){delete l[d];return f[d]})}(n=H(l))&&(d+="?"+n);(r=H(r))&&(d+="#"+r);m?(k&&k.replace?b.history.replaceState(null,null,q+d):b.history.pushState(null,null,q+d),b.onpopstate()):b.location.href=q+d}var m="function"===typeof b.history.pushState,w="function"===typeof setImmediate?setImmediate:setTimeout,q="#!",d;return{setPrefix:function(b){q=b},getPath:k,setPath:l,
|
||||
defineRoutes:function(d,f,l){function u(){var b=k(),m={},n=h(b,m,m),q;for(q in d){var u=new RegExp("^"+q.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(u.test(n)){n.replace(u,function(){for(var h=q.match(/:[^\/]+/g)||[],k=[].slice.call(arguments,1,-2),l=0;l<h.length;l++)m[h[l].replace(/:|\./g,"")]=decodeURIComponent(k[l]);f(d[q],m,b,q)});return}}l(b,m)}m?b.onpopstate=n(u):"#"===q.charAt(0)&&(b.onhashchange=u);u();return u},link:function(b){b.dom.setAttribute("href",q+
|
||||
b.attrs.href);b.dom.onclick=function(d){d.preventDefault();d.redraw=!1;l(b.attrs.href,void 0,void 0)}}}};y.route=function(b,f){function n(b){return b}var h=T(b),k,l,m,w,q,d={view:function(){return m(x(l,null,w,void 0,void 0,void 0))}},g=function(b,g,u){l="div";m=n;w=null;f(b,d);h.defineRoutes(u,function(d,f,g){function h(c){t===k&&(k=null,l=null!=c?c:u?"div":d,m=x,w=f,q=g,b.redraw(!0))}var t=k={},u="function"!==typeof d.view,x=n,y=function(){h()};u&&("function"===typeof d.render&&(x=d.render.bind(d)),
|
||||
"function"===typeof d.onmatch&&(y=d.onmatch));y.call(d,h,f,g)},function(){h.setPath(g,null,{replace:!0})})};g.link=h.link;g.prefix=h.setPrefix;g.set=h.setPath;g.get=function(){return q};return g}(window,y.mount);y.withAttr=function(b,f,n){return function(h){return f.call(n||this,b in h.currentTarget?h.currentTarget[b]:h.currentTarget.getAttribute(b))}};y.prop=O;y.render=N.render;y.redraw=L.publish;y.request=K.request;y.jsonp=K.jsonp;y.parseQueryString=M;y.buildQueryString=H;y.version="1.0.0";"undefined"!==
|
||||
typeof module?module.exports=y:window.m=y};
|
||||
|
|
@ -27,6 +27,11 @@ module.exports = new function init() {
|
|||
|
||||
if (fn) return fn.apply(this, arguments)
|
||||
}
|
||||
if (fn)
|
||||
Object.defineProperties(spy, {
|
||||
length: {value: fn.length},
|
||||
name: {value: fn.name}
|
||||
})
|
||||
spy.args = []
|
||||
spy.callCount = 0
|
||||
return spy
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ o.spec("ospec", function() {
|
|||
|
||||
var output = spy.call(state, {children: children})
|
||||
|
||||
o(spy.length).equals(1)
|
||||
o(spy.name).equals("view")
|
||||
o(spy.callCount).equals(1)
|
||||
o(spy.args.length).equals(1)
|
||||
o(spy.args[0]).deepEquals({children: children})
|
||||
|
|
|
|||
|
|
@ -516,6 +516,7 @@ module.exports = function($window) {
|
|||
}
|
||||
|
||||
function render(dom, vnodes) {
|
||||
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
|
||||
var hooks = []
|
||||
var active = $doc.activeElement
|
||||
|
||||
|
|
|
|||
|
|
@ -21,4 +21,13 @@ o.spec("render", function() {
|
|||
|
||||
o(root.childNodes.length).equals(0)
|
||||
})
|
||||
o("throws on invalid root node", function(){
|
||||
var threw = false
|
||||
try {
|
||||
render(null, [])
|
||||
} catch (e) {
|
||||
threw = true
|
||||
}
|
||||
o(threw).equals(true)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
5
route.js
5
route.js
|
|
@ -1,4 +1,3 @@
|
|||
var renderService = require("./render")
|
||||
var redrawService = require("./redraw")
|
||||
var mount = require("./mount")
|
||||
|
||||
module.exports = require("./api/router")(window, renderService, redrawService)
|
||||
module.exports = require("./api/router")(window, mount)
|
||||
|
|
@ -16,6 +16,18 @@ module.exports = function($window) {
|
|||
return data
|
||||
}
|
||||
|
||||
var asyncId
|
||||
function debounceAsync(f) {
|
||||
return function() {
|
||||
if (asyncId != null) return
|
||||
asyncId = callAsync(function() {
|
||||
asyncId = null
|
||||
f()
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function parsePath(path, queryData, hashData) {
|
||||
var queryIndex = path.indexOf("?")
|
||||
var hashIndex = path.indexOf("#")
|
||||
|
|
@ -67,7 +79,7 @@ module.exports = function($window) {
|
|||
}
|
||||
|
||||
function defineRoutes(routes, resolve, reject) {
|
||||
if (supportsPushState) $window.onpopstate = resolveRoute
|
||||
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
|
||||
else if (prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
|
||||
resolveRoute()
|
||||
|
||||
|
|
@ -76,25 +88,23 @@ module.exports = function($window) {
|
|||
var params = {}
|
||||
var pathname = parsePath(path, params, params)
|
||||
|
||||
callAsync(function() {
|
||||
for (var route in routes) {
|
||||
var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$")
|
||||
for (var route in routes) {
|
||||
var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$")
|
||||
|
||||
if (matcher.test(pathname)) {
|
||||
pathname.replace(matcher, function() {
|
||||
var keys = route.match(/:[^\/]+/g) || []
|
||||
var values = [].slice.call(arguments, 1, -2)
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
|
||||
}
|
||||
resolve(routes[route], params, path, route)
|
||||
})
|
||||
return
|
||||
}
|
||||
if (matcher.test(pathname)) {
|
||||
pathname.replace(matcher, function() {
|
||||
var keys = route.match(/:[^\/]+/g) || []
|
||||
var values = [].slice.call(arguments, 1, -2)
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
|
||||
}
|
||||
resolve(routes[route], params, path, route)
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
reject(path, params)
|
||||
})
|
||||
reject(path, params)
|
||||
}
|
||||
return resolveRoute
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,18 +285,14 @@ o.spec("Router.defineRoutes", function() {
|
|||
})
|
||||
})
|
||||
|
||||
o("replays", function(done) {
|
||||
o("replays", function() {
|
||||
$window.location.href = prefix + "/test"
|
||||
var replay = router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
replay()
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(2)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
o(onRouteChange.callCount).equals(2)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -164,9 +164,11 @@ o.spec("api", function() {
|
|||
|
||||
setTimeout(function() {
|
||||
m.route.set("/b")
|
||||
o(m.route.get()).equals("/b")
|
||||
setTimeout(function() {
|
||||
o(m.route.get()).equals("/b")
|
||||
|
||||
done()
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue