Merge branch 'rewrite' of https://github.com/lhorie/mithril.js into call-async
This commit is contained in:
commit
2c3a0ebb3a
15 changed files with 802 additions and 717 deletions
|
|
@ -7,16 +7,16 @@ var autoredraw = require("../api/autoredraw")
|
|||
module.exports = function($window, renderer, pubsub) {
|
||||
var router = coreRouter($window)
|
||||
var route = function(root, defaultRoute, routes) {
|
||||
var current = {route: null, component: null}
|
||||
var current = {path: null, component: null}
|
||||
var replay = router.defineRoutes(routes, function(payload, args, path, route) {
|
||||
if (typeof payload.view !== "function") {
|
||||
if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode}
|
||||
var render = function(component) {
|
||||
current.route = route, current.component = component
|
||||
current.path = path, current.component = component
|
||||
renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined)))
|
||||
}
|
||||
if (typeof payload.resolve !== "function") payload.resolve = function() {render(current.component)}
|
||||
if (route !== current.route) payload.resolve(render, args, path, route)
|
||||
if (path !== current.path) payload.resolve(render, args, path, route)
|
||||
else render(current.component)
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,71 @@ o.spec("mount", function() {
|
|||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("redraws several mount points on events", function(done) {
|
||||
var onupdate0 = o.spy()
|
||||
var oninit0 = o.spy()
|
||||
var onclick0 = o.spy()
|
||||
var onupdate1 = o.spy()
|
||||
var oninit1 = o.spy()
|
||||
var onclick1 = o.spy()
|
||||
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
render(root, [
|
||||
m("#child0"),
|
||||
m("#child1")
|
||||
])
|
||||
|
||||
mount(root.childNodes[0], {
|
||||
view : function() {
|
||||
return m("div", {
|
||||
oninit : oninit0,
|
||||
onupdate : onupdate0,
|
||||
onclick : onclick0,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
o(oninit0.callCount).equals(1)
|
||||
o(onupdate0.callCount).equals(0)
|
||||
|
||||
mount(root.childNodes[1], {
|
||||
view : function() {
|
||||
return m("div", {
|
||||
oninit : oninit1,
|
||||
onupdate : onupdate1,
|
||||
onclick : onclick1,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
o(oninit1.callCount).equals(1)
|
||||
o(onupdate1.callCount).equals(0)
|
||||
|
||||
root.childNodes[0].firstChild.dispatchEvent(e)
|
||||
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)
|
||||
|
||||
root.childNodes[1].firstChild.dispatchEvent(e)
|
||||
o(onclick1.callCount).equals(1)
|
||||
o(onclick1.this).equals(root.childNodes[1].firstChild)
|
||||
|
||||
setTimeout(function() {
|
||||
o(onupdate0.callCount).equals(2)
|
||||
o(onupdate1.callCount).equals(2)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
}, FRAME_BUDGET)
|
||||
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
|
|
|
|||
|
|
@ -11,325 +11,327 @@ var apiPubSub = require("../../api/pubsub")
|
|||
var apiRouter = require("../../api/router")
|
||||
|
||||
o.spec("route", function() {
|
||||
void ["#", "?", "", "#!", "?!", "/foo"].forEach(function(prefix) {
|
||||
o.spec("using prefix `" + prefix + "`", function() {
|
||||
var FRAME_BUDGET = Math.floor(1000 / 60)
|
||||
var $window, root, redraw, route
|
||||
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
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = {}
|
||||
o.beforeEach(function() {
|
||||
$window = {}
|
||||
|
||||
var dom = domMock()
|
||||
for (var key in dom) $window[key] = dom[key]
|
||||
var dom = domMock()
|
||||
for (var key in dom) $window[key] = dom[key]
|
||||
|
||||
var loc = pushStateMock()
|
||||
for (var key in loc) $window[key] = loc[key]
|
||||
var loc = pushStateMock(env)
|
||||
for (var key in loc) $window[key] = loc[key]
|
||||
|
||||
root = $window.document.body
|
||||
root = $window.document.body
|
||||
|
||||
redraw = apiPubSub()
|
||||
route = apiRouter($window, coreRenderer($window), redraw)
|
||||
route.prefix(prefix)
|
||||
})
|
||||
redraw = apiPubSub()
|
||||
route = apiRouter($window, coreRenderer($window), redraw)
|
||||
route.prefix(prefix)
|
||||
})
|
||||
|
||||
o("renders into `root`", function(done) {
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div")
|
||||
o("renders into `root`", function(done) {
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("default route doesn't break back button", function(done) {
|
||||
$window.location.href = "http://google.com"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
$window.history.back()
|
||||
|
||||
o($window.location.pathname).equals("/")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("default route does not inherit params", function(done) {
|
||||
$window.location.href = "/invalid?foo=bar"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
oninit: init,
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function init(vnode) {
|
||||
o(vnode.attrs).deepEquals({})
|
||||
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
o("redraws when render function is executed", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("redraws on events", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate,
|
||||
onclick: onclick,
|
||||
})
|
||||
o("default route doesn't break back button", function(done) {
|
||||
$window.location.href = "http://google.com"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
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)
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate,
|
||||
onclick: function(e) {
|
||||
e.redraw = false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
// Wrapped to ensure no redraw fired
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(0)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
||||
o("changes location on route.link", function(done) {
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("a", {
|
||||
href: "/test",
|
||||
oncreate: route.link
|
||||
})
|
||||
}
|
||||
},
|
||||
"/test" : {
|
||||
view : function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
||||
o($window.location.href).equals("http://localhost" + slash + (prefix ? prefix + "/" : ""))
|
||||
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o($window.location.href).equals("http://localhost" + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {resolve(Component)},
|
||||
render: function(vnode) {return vnode},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object without `render` method as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {resolve(Component)},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object without `resolve` method as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
render: function() {return m(Component)},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("calls resolve and render correct number of times", function(done) {
|
||||
var resolveCount = 0
|
||||
var renderCount = 0
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {
|
||||
resolveCount++
|
||||
resolve(Component)
|
||||
},
|
||||
render: function(vnode) {
|
||||
renderCount++
|
||||
return vnode
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(resolveCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
o(resolveCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
$window.history.back()
|
||||
|
||||
o($window.location.pathname).equals("/")
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
|
||||
o("default route does not inherit params", function(done) {
|
||||
$window.location.href = "/invalid?foo=bar"
|
||||
route(root, "/a", {
|
||||
"/a" : {
|
||||
oninit: init,
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function init(vnode) {
|
||||
o(vnode.attrs).deepEquals({})
|
||||
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
o("redraws when render function is executed", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
||||
o("redraws on events", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate,
|
||||
onclick: onclick,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
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)
|
||||
|
||||
// Wrapped to give time for the rate-limited redraw to fire
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(1)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
||||
o("event handlers can skip redraw", function(done) {
|
||||
var onupdate = o.spy()
|
||||
var oninit = o.spy()
|
||||
var onclick = o.spy()
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("div", {
|
||||
oninit: oninit,
|
||||
onupdate: onupdate,
|
||||
onclick: function(e) {
|
||||
e.redraw = false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o(oninit.callCount).equals(1)
|
||||
|
||||
// Wrapped to ensure no redraw fired
|
||||
setTimeout(function() {
|
||||
o(onupdate.callCount).equals(0)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
|
||||
o("changes location on route.link", function(done) {
|
||||
var e = $window.document.createEvent("MouseEvents")
|
||||
|
||||
e.initEvent("click", true, true)
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
view: function() {
|
||||
return m("a", {
|
||||
href: "/test",
|
||||
oncreate: route.link
|
||||
})
|
||||
}
|
||||
},
|
||||
"/test" : {
|
||||
view : function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : ""))
|
||||
|
||||
root.firstChild.dispatchEvent(e)
|
||||
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {resolve(Component)},
|
||||
render: function(vnode) {return vnode},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object without `render` method as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {resolve(Component)},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("accepts object without `resolve` method as payload", function(done) {
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
render: function() {return m(Component)},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(root.firstChild.nodeName).equals("DIV")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("calls resolve and render correct number of times", function(done) {
|
||||
var resolveCount = 0
|
||||
var renderCount = 0
|
||||
var Component = {
|
||||
view: function() {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
$window.location.href = prefix + "/"
|
||||
route(root, "/", {
|
||||
"/" : {
|
||||
resolve: function(resolve) {
|
||||
resolveCount++
|
||||
resolve(Component)
|
||||
},
|
||||
render: function(vnode) {
|
||||
renderCount++
|
||||
return vnode
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(resolveCount).equals(1)
|
||||
o(renderCount).equals(1)
|
||||
|
||||
redraw.publish()
|
||||
|
||||
setTimeout(function() {
|
||||
o(resolveCount).equals(1)
|
||||
o(renderCount).equals(2)
|
||||
|
||||
done()
|
||||
}, FRAME_BUDGET)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
;(function() {
|
||||
window.m = require("./index")
|
||||
})()
|
||||
var m = require("./index")
|
||||
if (typeof module !== "undefined") module["exports"] = m
|
||||
else window.m = m
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
Argument | Type | Required | Description
|
||||
------------ | ------------------------------------------ | -------- | ---
|
||||
`selector` | `String|Object` | Yes | A CSS selector or a component
|
||||
`selector` | `String|Object` | Yes | A CSS selector or a [component](https://github.com/lhorie/mithril.js/blob/rewrite/docs/components.md)
|
||||
`attributes` | `Object` | No | HTML attributes or element properties
|
||||
`children` | `Array<Vnode>|String|Number|Boolean` | No | Child [vnodes](vnodes.md#structure). Can be written as [splat arguments](signatures.md#splats)
|
||||
**returns** | `Vnode` | | A [vnode](vnodes.md#structure)
|
||||
|
|
|
|||
13
mithril.js
13
mithril.js
|
|
@ -1,5 +1,4 @@
|
|||
new function() {
|
||||
"use strict"
|
||||
var guid = 0, noop = function() {}, HALT = {}
|
||||
function createStream() {
|
||||
function stream() {
|
||||
|
|
@ -944,7 +943,7 @@ var parseQueryString = function(string) {
|
|||
return data
|
||||
}
|
||||
var coreRouter = function($window) {
|
||||
var supportsPushState = typeof $window.history.pushState === "function" && $window.location.protocol !== "file:"
|
||||
var supportsPushState = typeof $window.history.pushState === "function"
|
||||
var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
var prefix = "#!"
|
||||
function setPrefix(value) {prefix = value}
|
||||
|
|
@ -1006,6 +1005,7 @@ var coreRouter = function($window) {
|
|||
var path = getPath()
|
||||
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, "([^\\/]+)") + "\/?$")
|
||||
|
|
@ -1072,16 +1072,16 @@ var autoredraw = function(root, renderer, pubsub, callback) {
|
|||
m.route = function($window, renderer, pubsub) {
|
||||
var router = coreRouter($window)
|
||||
var route = function(root, defaultRoute, routes) {
|
||||
var current = {route: null, component: null}
|
||||
var current = {path: null, component: null}
|
||||
var replay = router.defineRoutes(routes, function(payload, args, path, route) {
|
||||
if (typeof payload.view !== "function") {
|
||||
if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode}
|
||||
var render = function(component) {
|
||||
current.route = route, current.component = component
|
||||
current.path = path, current.component = component
|
||||
renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined)))
|
||||
}
|
||||
if (typeof payload.resolve !== "function") payload.resolve = function() {render(current.component)}
|
||||
if (route !== current.route) payload.resolve(render, args, path, route)
|
||||
if (path !== current.path) payload.resolve(render, args, path, route)
|
||||
else render(current.component)
|
||||
}
|
||||
else {
|
||||
|
|
@ -1125,6 +1125,7 @@ m.redraw = redrawService.publish
|
|||
m.request = requestService.xhr
|
||||
m.jsonp = requestService.jsonp
|
||||
m.version = "1.0.0"
|
||||
module.exports = m
|
||||
if (typeof module !== "undefined") module["exports"] = m
|
||||
else window.m = m
|
||||
|
||||
}
|
||||
38
mithril.min.js
vendored
38
mithril.min.js
vendored
|
|
@ -15,26 +15,26 @@ f)if(null==c)b(a,f,0,f.length,d,g,void 0);else if(null==f)v(a,c,0,c.length,f);el
|
|||
c[q]?n(a,h(f[q],d,B),e(c,q+1,g)):null==f[q]?v(a,c,q,q+1,f):k(a,c[q],f[q],d,e(c,q+1,g),p,B),p&&c[q].tag===f[q].tag&&n(a,m(c[q]),e(c,q+1,g))}else{for(var A=q=0,r=c.length-1,z=f.length-1,u;r>=q&&z>=A;){var t=c[q],w=f[A];if(t===w)q++,A++;else if(null!=t&&null!=w&&t.key===w.key)q++,A++,k(a,t,w,d,e(c,q,g),p,B),p&&t.tag===w.tag&&n(a,m(t),g);else if(t=c[r],t===w)r--,A++;else if(null!=t&&null!=w&&t.key===w.key)k(a,t,w,d,e(c,r+1,g),p,B),n(a,m(t),e(c,q,g)),r--,A++;else break}for(;r>=q&&z>=A;){t=c[r];w=f[z];
|
||||
if(t===w)r--;else if(null!=t&&null!=w&&t.key===w.key)k(a,t,w,d,e(c,r+1,g),p,B),p&&t.tag===w.tag&&n(a,m(t),g),null!=t.dom&&(g=t.dom),r--;else{if(!u){u=c;var t=r,l={},x;for(x=0;x<t;x++){var y=u[x];null!=y&&(y=y.key,null!=y&&(l[y]=x))}u=l}null!=w&&(t=u[w.key],null!=t?(l=c[t],k(a,l,w,d,e(c,r+1,g),p,B),n(a,m(l),g),c[t].skip=!0,null!=l.dom&&(g=l.dom)):(w=h(w,d,void 0),n(a,w,g),g=w))}z--;if(z<A)break}b(a,f,A,z+1,d,g,B);v(a,c,q,r+1,f)}}}function k(a,c,f,b,e,p,v){var q=c.tag;if(q===f.tag){f.state=c.state;
|
||||
f.events=c.events;var r;var z;null!=f.attrs&&"function"===typeof f.attrs.onbeforeupdate&&(r=f.attrs.onbeforeupdate.call(f.state,f,c));"string"!==typeof f.tag&&"function"===typeof f.tag.onbeforeupdate&&(z=f.tag.onbeforeupdate.call(f.state,f,c));void 0===r&&void 0===z||r||z?r=!1:(f.dom=c.dom,f.domSize=c.domSize,f.instance=c.instance,r=!0);if(!r)if(null!=f.attrs&&y(f.attrs,f,b,p),"string"===typeof q)switch(q){case "#":c.children.toString()!==f.children.toString()&&(c.dom.nodeValue=f.children);f.dom=
|
||||
c.dom;break;case "<":c.children!==f.children?(m(c),n(a,d(f),e)):f.dom=c.dom;break;case "[":g(a,c.children,f.children,b,e,v);c=0;b=f.children;f.dom=null;if(null!=b){for(var l=0;l<b.length;l++)a=b[l],null!=a&&null!=a.dom&&(null==f.dom&&(f.dom=a.dom),c+=a.domSize||1);1!==c&&(f.domSize=c)}break;default:a=v;e=f.dom=c.dom;switch(f.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===f.tag&&(null==f.attrs&&(f.attrs={}),null!=f.text&&(f.attrs.value=
|
||||
f.text));p=c.attrs;v=f.attrs;q=a;if(null!=v)for(l in v)A(f,l,p&&p[l],v[l],q);if(null!=p)for(l in p)null!=v&&l in v||"key"!==l&&f.dom.removeAttribute(l);null!=c.text&&null!=f.text&&""!==f.text?c.text.toString()!==f.text.toString()&&(c.dom.firstChild.nodeValue=f.text):(null!=c.text&&(c.children=[u("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=f.text&&(f.children=[u("#",void 0,void 0,f.text,void 0,void 0)]),g(e,c.children,f.children,b,null,a))}else f.instance=u.normalize(f.tag.view.call(f.state,
|
||||
f)),y(f.tag,f,b,p),null!=f.instance?(null==c.instance?n(a,h(f.instance,b,v),e):k(a,c.instance,f.instance,b,e,p,v),f.dom=f.instance.dom,f.domSize=f.instance.domSize):null!=c.instance?(B(a,c.instance,null,!1),f.dom=void 0,f.domSize=0):(f.dom=c.dom,f.domSize=c.domSize)}else B(a,c,null,!1),n(a,h(f,b,void 0),e)}function m(a){var c=a.domSize;if(null!=c||null==a.dom){var f=x.createDocumentFragment();if(0<c){for(a=a.dom;--c;)f.appendChild(a.nextSibling);f.insertBefore(a,f.firstChild)}return f}return a.dom}
|
||||
function e(a,c,f){for(;c<a.length;c++)if(null!=a[c]&&null!=a[c].dom)return a[c].dom;return f}function n(a,c,f){f&&f.parentNode?a.insertBefore(c,f):a.appendChild(c)}function v(a,c,f,b,e){for(;f<b;f++){var g=c[f];null!=g&&(g.skip?g.skip=void 0:B(a,g,e,!1))}}function B(a,c,f,b){if(!1===b){var e=0,g=0;b=function(){++g===e&&B(a,c,f,!0)};c.attrs&&c.attrs.onbeforeremove&&(e++,c.attrs.onbeforeremove.call(c.state,c,b));"string"!==typeof c.tag&&c.tag.onbeforeremove&&(e++,c.tag.onbeforeremove.call(c.state,c,
|
||||
b));if(0<e)return}p(c);if(c.dom){b=c.domSize||1;if(1<b)for(var d=c.dom;--b;)a.removeChild(d.nextSibling);null!=c.dom.parentNode&&a.removeChild(c.dom);null==f||null!=c.domSize||z(c.attrs)||"string"!==typeof c.tag||(f.pool?f.pool.push(c):f.pool=[c])}}function p(a){a.attrs&&a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&a.tag.onremove&&a.tag.onremove.call(a.state,a);if(null!=a.instance)p(a.instance);else if(a=a.children,a instanceof Array)for(var c=0;c<a.length;c++){var b=
|
||||
a[c];null!=b&&p(b)}}function A(a,c,b,e,g){var d=a.dom;if("key"!==c&&(b!==e||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===x.activeElement||"object"===typeof e)&&"undefined"!==typeof e&&"oninit"!==c&&"oncreate"!==c&&"onupdate"!==c&&"onremove"!==c&&"onbeforeremove"!==c&&"onbeforeupdate"!==c){var n=c.indexOf(":");if(-1<n&&"xlink"===c.substr(0,n))d.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(n+1),e);else if("o"===c[0]&&"n"===c[1]&&"function"===typeof e)r(a,c,e);else if("style"===
|
||||
c)if(a=b,a===e&&(d.style="",a=null),null==e)d.style="";else if("string"===typeof e)d.style=e;else{"string"===typeof a&&(d.style="");for(var h in e)d.style[h]=e[h];if(null!=a&&"string"!==typeof a)for(h in a)h in e||(d.style[h]="")}else if(c in d&&"href"!==c&&"list"!==c&&"form"!==c&&void 0===g){if("input"!==a.tag||"value"!==c||a.dom.value!==e||a.dom!==x.activeElement)d[c]=e}else"boolean"===typeof e?e?d.setAttribute(c,""):d.removeAttribute(c):d.setAttribute("className"===c?"class":c,e)}}function z(a){return null!=
|
||||
a&&(a.oncreate||a.onupdate||a.onbeforeremove||a.onremove)}function r(a,c,b){var e=a.dom,d=function(a){var c=b.call(e,a);"function"===typeof D&&D.call(e,a);return c};if(c in e)e[c]=d;else{var g=c.slice(2);void 0===a.events&&(a.events={});null!=a.events[c]&&e.removeEventListener(g,a.events[c],!1);a.events[c]=d;e.addEventListener(g,a.events[c],!1)}}function l(a,c,b){"function"===typeof a.oninit&&a.oninit.call(c.state,c);"function"===typeof a.oncreate&&b.push(a.oncreate.bind(c.state,c))}function y(a,
|
||||
c,b,e){e?l(a,c,b):"function"===typeof a.onupdate&&b.push(a.onupdate.bind(c.state,c))}function C(a){if(a instanceof Array){for(var c=[],b=0;b<a.length;b++)c[b]=a[b];return c}if("object"===typeof a){c={};for(b in a)c[b]=a[b];return c}return a}var x=a.document,ja=x.createDocumentFragment(),D;return{render:function(a,c){var b=[],e=x.activeElement;null==a.vnodes&&(a.vnodes=[]);c instanceof Array||(c=[c]);g(a,a.vnodes,u.normalizeChildren(c),b,null,void 0);a.vnodes=c;for(var d=0;d<b.length;d++)b[d]();x.activeElement!==
|
||||
e&&e.focus()},setEventCallback:function(a){return D=a}}}(window),L=function(a){function b(a,d){if(d instanceof Array)for(var m=0;m<d.length;m++)b(a+"["+m+"]",d[m]);else if("[object Object]"===Object.prototype.toString.call(d))for(m in d)b(a+"["+m+"]",d[m]);else h.push(encodeURIComponent(a)+(null!=d&&""!==d?"="+encodeURIComponent(d):""))}if("[object Object]"!==Object.prototype.toString.call(a))return"";var h=[],d;for(d in a)b(d,a[d]);return h.join("&")},M=function(a){function b(a,b){if(null==b)return a;
|
||||
for(var d=a.match(/:[^\/]+/gi)||[],g=0;g<d.length;g++){var h=d[g].slice(1);null!=b[h]&&(a=a.replace(d[g],b[h]),delete b[h])}return a}function h(a,b){var d=L(b);if(""!==d){var g=0>a.indexOf("?")?"?":"&";a+=g+d}return a}function d(a){try{return""!==a?JSON.parse(a):null}catch(b){throw Error(a);}}function g(a){return a.responseText}var k=0,m;return{xhr:function(e){var n=C.stream();void 0!==e.initialValue&&n(e.initialValue);var v="boolean"===typeof e.useBody?e.useBody:"GET"!==e.method&&"TRACE"!==e.method;
|
||||
"function"!==typeof e.serialize&&(e.serialize="undefined"!==typeof FormData&&e.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==typeof e.deserialize&&(e.deserialize=d);"function"!==typeof e.extract&&(e.extract=g);e.url=b(e.url,e.data);v?e.data=e.serialize(e.data):e.url=h(e.url,e.data);var k=new a.XMLHttpRequest;k.open(e.method,e.url,"boolean"===typeof e.async?e.async:!0,"string"===typeof e.user?e.user:void 0,"string"===typeof e.password?e.password:void 0);e.serialize===
|
||||
JSON.stringify&&v&&k.setRequestHeader("Content-Type","application/json; charset=utf-8");e.deserialize===d&&k.setRequestHeader("Accept","application/json, text/*");"function"===typeof e.config&&(k=e.config(k,e)||k);k.onreadystatechange=function(){if(4===k.readyState){try{var a=e.deserialize(e.extract(k,e));if(200<=k.status&&300>k.status){if("function"===typeof e.type)if(a instanceof Array)for(var b=0;b<a.length;b++)a[b]=new e.type(a[b]);else a=new e.type(a);n(a)}else{var b=Error(k.responseText),d;
|
||||
for(d in a)b[d]=a[d];n.error(b)}}catch(g){n.error(g)}"function"===typeof m&&m()}};v?k.send(e.data):k.send();return n},jsonp:function(e){var d=C.stream(),g=e.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+k++,l=a.document.createElement("script");a[g]=function(b){l.parentNode.removeChild(l);d(b);"function"===typeof m&&m();delete a[g]};l.onerror=function(){l.parentNode.removeChild(l);d.error(Error("JSONP request failed"));"function"===typeof m&&m();delete a[g]};null==e.data&&(e.data={});
|
||||
e.url=b(e.url,e.data);e.data[e.callbackKey||"callback"]=g;l.src=h(e.url,e.data);a.document.documentElement.appendChild(l);return d},setCompletionCallback:function(a){m=a}}}(window),H=function(){var a=[];return{subscribe:a.push.bind(a),unsubscribe:function(b){b=a.indexOf(b);-1<b&&a.splice(b,1)},publish:function(){for(var b=0;b<a.length;b++)a[b].apply(this,arguments)}}}();M.setCompletionCallback(H.publish);var Y=function(a){if(""===a||null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");
|
||||
c.dom;break;case "<":c.children!==f.children?(m(c),n(a,d(f),e)):(f.dom=c.dom,f.domSize=c.domSize);break;case "[":g(a,c.children,f.children,b,e,v);c=0;b=f.children;f.dom=null;if(null!=b){for(var l=0;l<b.length;l++)a=b[l],null!=a&&null!=a.dom&&(null==f.dom&&(f.dom=a.dom),c+=a.domSize||1);1!==c&&(f.domSize=c)}break;default:a=v;e=f.dom=c.dom;switch(f.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===f.tag&&(null==f.attrs&&(f.attrs={}),
|
||||
null!=f.text&&(f.attrs.value=f.text));p=c.attrs;v=f.attrs;q=a;if(null!=v)for(l in v)A(f,l,p&&p[l],v[l],q);if(null!=p)for(l in p)null!=v&&l in v||"key"!==l&&f.dom.removeAttribute(l);null!=c.text&&null!=f.text&&""!==f.text?c.text.toString()!==f.text.toString()&&(c.dom.firstChild.nodeValue=f.text):(null!=c.text&&(c.children=[u("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=f.text&&(f.children=[u("#",void 0,void 0,f.text,void 0,void 0)]),g(e,c.children,f.children,b,null,a))}else f.instance=
|
||||
u.normalize(f.tag.view.call(f.state,f)),y(f.tag,f,b,p),null!=f.instance?(null==c.instance?n(a,h(f.instance,b,v),e):k(a,c.instance,f.instance,b,e,p,v),f.dom=f.instance.dom,f.domSize=f.instance.domSize):null!=c.instance?(B(a,c.instance,null,!1),f.dom=void 0,f.domSize=0):(f.dom=c.dom,f.domSize=c.domSize)}else B(a,c,null,!1),n(a,h(f,b,void 0),e)}function m(a){var c=a.domSize;if(null!=c||null==a.dom){var f=x.createDocumentFragment();if(0<c){for(a=a.dom;--c;)f.appendChild(a.nextSibling);f.insertBefore(a,
|
||||
f.firstChild)}return f}return a.dom}function e(a,c,f){for(;c<a.length;c++)if(null!=a[c]&&null!=a[c].dom)return a[c].dom;return f}function n(a,c,f){f&&f.parentNode?a.insertBefore(c,f):a.appendChild(c)}function v(a,c,f,b,e){for(;f<b;f++){var g=c[f];null!=g&&(g.skip?g.skip=void 0:B(a,g,e,!1))}}function B(a,c,f,b){if(!1===b){var e=0,g=0;b=function(){++g===e&&B(a,c,f,!0)};c.attrs&&c.attrs.onbeforeremove&&(e++,c.attrs.onbeforeremove.call(c.state,c,b));"string"!==typeof c.tag&&c.tag.onbeforeremove&&(e++,
|
||||
c.tag.onbeforeremove.call(c.state,c,b));if(0<e)return}p(c);if(c.dom){b=c.domSize||1;if(1<b)for(var d=c.dom;--b;)a.removeChild(d.nextSibling);null!=c.dom.parentNode&&a.removeChild(c.dom);null==f||null!=c.domSize||z(c.attrs)||"string"!==typeof c.tag||(f.pool?f.pool.push(c):f.pool=[c])}}function p(a){a.attrs&&a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&a.tag.onremove&&a.tag.onremove.call(a.state,a);if(null!=a.instance)p(a.instance);else if(a=a.children,a instanceof Array)for(var c=
|
||||
0;c<a.length;c++){var b=a[c];null!=b&&p(b)}}function A(a,c,b,e,g){var d=a.dom;if("key"!==c&&(b!==e||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===x.activeElement||"object"===typeof e)&&"undefined"!==typeof e&&"oninit"!==c&&"oncreate"!==c&&"onupdate"!==c&&"onremove"!==c&&"onbeforeremove"!==c&&"onbeforeupdate"!==c){var n=c.indexOf(":");if(-1<n&&"xlink"===c.substr(0,n))d.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(n+1),e);else if("o"===c[0]&&"n"===c[1]&&"function"===
|
||||
typeof e)r(a,c,e);else if("style"===c)if(a=b,a===e&&(d.style="",a=null),null==e)d.style="";else if("string"===typeof e)d.style=e;else{"string"===typeof a&&(d.style="");for(var h in e)d.style[h]=e[h];if(null!=a&&"string"!==typeof a)for(h in a)h in e||(d.style[h]="")}else if(c in d&&"href"!==c&&"list"!==c&&"form"!==c&&void 0===g){if("input"!==a.tag||"value"!==c||a.dom.value!==e||a.dom!==x.activeElement)d[c]=e}else"boolean"===typeof e?e?d.setAttribute(c,""):d.removeAttribute(c):d.setAttribute("className"===
|
||||
c?"class":c,e)}}function z(a){return null!=a&&(a.oncreate||a.onupdate||a.onbeforeremove||a.onremove)}function r(a,c,b){var e=a.dom,d=function(a){var c=b.call(e,a);"function"===typeof D&&D.call(e,a);return c};if(c in e)e[c]=d;else{var g=c.slice(2);void 0===a.events&&(a.events={});null!=a.events[c]&&e.removeEventListener(g,a.events[c],!1);a.events[c]=d;e.addEventListener(g,a.events[c],!1)}}function l(a,c,b){"function"===typeof a.oninit&&a.oninit.call(c.state,c);"function"===typeof a.oncreate&&b.push(a.oncreate.bind(c.state,
|
||||
c))}function y(a,c,b,e){e?l(a,c,b):"function"===typeof a.onupdate&&b.push(a.onupdate.bind(c.state,c))}function C(a){if(a instanceof Array){for(var c=[],b=0;b<a.length;b++)c[b]=a[b];return c}if("object"===typeof a){c={};for(b in a)c[b]=a[b];return c}return a}var x=a.document,ja=x.createDocumentFragment(),D;return{render:function(a,c){var b=[],e=x.activeElement;null==a.vnodes&&(a.vnodes=[]);c instanceof Array||(c=[c]);g(a,a.vnodes,u.normalizeChildren(c),b,null,void 0);a.vnodes=c;for(var d=0;d<b.length;d++)b[d]();
|
||||
x.activeElement!==e&&e.focus()},setEventCallback:function(a){return D=a}}}(window),L=function(a){function b(a,d){if(d instanceof Array)for(var m=0;m<d.length;m++)b(a+"["+m+"]",d[m]);else if("[object Object]"===Object.prototype.toString.call(d))for(m in d)b(a+"["+m+"]",d[m]);else h.push(encodeURIComponent(a)+(null!=d&&""!==d?"="+encodeURIComponent(d):""))}if("[object Object]"!==Object.prototype.toString.call(a))return"";var h=[],d;for(d in a)b(d,a[d]);return h.join("&")},M=function(a){function b(a,
|
||||
b){if(null==b)return a;for(var d=a.match(/:[^\/]+/gi)||[],g=0;g<d.length;g++){var h=d[g].slice(1);null!=b[h]&&(a=a.replace(d[g],b[h]),delete b[h])}return a}function h(a,b){var d=L(b);if(""!==d){var g=0>a.indexOf("?")?"?":"&";a+=g+d}return a}function d(a){try{return""!==a?JSON.parse(a):null}catch(b){throw Error(a);}}function g(a){return a.responseText}var k=0,m;return{xhr:function(e){var n=C.stream();void 0!==e.initialValue&&n(e.initialValue);var v="boolean"===typeof e.useBody?e.useBody:"GET"!==e.method&&
|
||||
"TRACE"!==e.method;"function"!==typeof e.serialize&&(e.serialize="undefined"!==typeof FormData&&e.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==typeof e.deserialize&&(e.deserialize=d);"function"!==typeof e.extract&&(e.extract=g);e.url=b(e.url,e.data);v?e.data=e.serialize(e.data):e.url=h(e.url,e.data);var k=new a.XMLHttpRequest;k.open(e.method,e.url,"boolean"===typeof e.async?e.async:!0,"string"===typeof e.user?e.user:void 0,"string"===typeof e.password?e.password:void 0);
|
||||
e.serialize===JSON.stringify&&v&&k.setRequestHeader("Content-Type","application/json; charset=utf-8");e.deserialize===d&&k.setRequestHeader("Accept","application/json, text/*");"function"===typeof e.config&&(k=e.config(k,e)||k);k.onreadystatechange=function(){if(4===k.readyState){try{var a=e.deserialize(e.extract(k,e));if(200<=k.status&&300>k.status){if("function"===typeof e.type)if(a instanceof Array)for(var b=0;b<a.length;b++)a[b]=new e.type(a[b]);else a=new e.type(a);n(a)}else{var b=Error(k.responseText),
|
||||
d;for(d in a)b[d]=a[d];n.error(b)}}catch(g){n.error(g)}"function"===typeof m&&m()}};v?k.send(e.data):k.send();return n},jsonp:function(e){var d=C.stream(),g=e.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+k++,l=a.document.createElement("script");a[g]=function(b){l.parentNode.removeChild(l);d(b);"function"===typeof m&&m();delete a[g]};l.onerror=function(){l.parentNode.removeChild(l);d.error(Error("JSONP request failed"));"function"===typeof m&&m();delete a[g]};null==e.data&&(e.data=
|
||||
{});e.url=b(e.url,e.data);e.data[e.callbackKey||"callback"]=g;l.src=h(e.url,e.data);a.document.documentElement.appendChild(l);return d},setCompletionCallback:function(a){m=a}}}(window),H=function(){var a=[];return{subscribe:a.push.bind(a),unsubscribe:function(b){b=a.indexOf(b);-1<b&&a.splice(b,1)},publish:function(){for(var b=0;b<a.length;b++)a[b].apply(this,arguments)}}}();M.setCompletionCallback(H.publish);var Y=function(a){if(""===a||null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");
|
||||
for(var b={},h={},d=0;d<a.length;d++){var g=a[d].split("="),k=decodeURIComponent(g[0]),g=2===g.length?decodeURIComponent(g[1]):"",m=Number(g);""!==g&&!isNaN(m)||"NaN"===g?g=m:"true"===g?g=!0:"false"===g?g=!1:(m=new Date(g),isNaN(m.getTime())||(g=m));var m=k.split(/\]\[?|\[/),e=b;-1<k.indexOf("[")&&m.pop();for(var n=0;n<m.length;n++){var k=m[n],v=m[n+1],v=""==v||!isNaN(parseInt(v,10)),l=n===m.length-1;""===k&&(k=m.slice(0,n).join(),null==h[k]&&(h[k]=0),k=h[k]++);null==e[k]&&(e[k]=l?g:v?[]:{});e=e[k]}}return b},
|
||||
ka=function(a){function b(b){var e=a.location[b].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===b&&"/"!==e[0]&&(e="/"+e);return e}function h(a,b,e){var d=a.indexOf("?"),g=a.indexOf("#"),h=-1<d?d:-1<g?g:a.length;if(-1<d){var d=Y(a.slice(d+1,-1<g?g:a.length)),k;for(k in d)b[k]=d[k]}if(-1<g)for(k in b=Y(a.slice(g+1)),b)e[k]=b[k];return a.slice(0,h)}function d(){switch(e.charAt(0)){case "#":return b("hash").slice(e.length);case "?":return b("search").slice(e.length)+b("hash");default:return b("pathname").slice(e.length)+
|
||||
b("search")+b("hash")}}function g(b,d,g){var m={},l={};b=h(b,m,l);if(null!=d){for(var z in d)m[z]=d[z];b=b.replace(/:([^\/]+)/g,function(a,b){delete m[b];return d[b]})}(z=L(m))&&(b+="?"+z);(l=L(l))&&(b+="#"+l);k?(g&&g.replace?a.history.replaceState(null,null,e+b):a.history.pushState(null,null,e+b),a.onpopstate()):a.location.href=e+b}var k="function"===typeof a.history.pushState&&"file:"!==a.location.protocol,m="function"===typeof setImmediate?setImmediate:setTimeout,e="#!";return{setPrefix:function(a){e=
|
||||
a},getPath:d,setPath:g,defineRoutes:function(b,g,l){function p(){var a=d(),e={},k=h(a,e,e);m(function(){for(var d in b){var h=new RegExp("^"+d.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(h.test(k)){k.replace(h,function(){for(var h=d.match(/:[^\/]+/g)||[],k=[].slice.call(arguments,1,-2),l=0;l<h.length;l++)e[h[l].replace(/:|\./g,"")]=decodeURIComponent(k[l]);g(b[d],e,a,d)});return}}l(a,e)})}k?a.onpopstate=p:"#"===e.charAt(0)&&(a.onhashchange=p);p();return p},link:function(a){a.dom.setAttribute("href",
|
||||
e+a.attrs.href);a.dom.onclick=function(b){b.preventDefault();b.redraw=!1;g(a.attrs.href,void 0,void 0)}}}},la=function(a){var b=0,h=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(g){var k=(new Date).getTime();!0===g||0===b||16<=k-b?(b=k,a()):null===h&&(h=d(function(){h=null;a();b=(new Date).getTime()},16-(k-b)))}},Z=function(a,b,h,d){d=la(d);null!=b&&b.setEventCallback(function(a){!1!==a.redraw&&h.publish()});null!=h&&(a.redraw&&h.unsubscribe(a.redraw),
|
||||
h.subscribe(d));return a.redraw=d};l.route=function(a,b,h){var d=ka(a);a=function(a,k,l){var e=null,n=null;l=d.defineRoutes(l,function(d,h,k,l){if("function"!==typeof d.view){"function"!==typeof d.render&&(d.render=function(a){return a});var m=function(k){e=l;n=k;b.render(a,d.render(u(k,null,h,void 0,void 0,void 0)))};"function"!==typeof d.resolve&&(d.resolve=function(){m(n)});l!==e?d.resolve(m,h,k,l):m(n)}else b.render(a,u(d,null,h,void 0,void 0,void 0))},function(){d.setPath(k,null,{replace:!0})});
|
||||
Z(a,b,h,l)};a.link=d.link;a.prefix=d.setPrefix;a.set=d.setPath;a.get=d.getPath;return a}(window,K,H);l.mount=function(a,b){return function(h,d){Z(h,a,b,function(){a.render(h,{tag:d})})()}}(K,H);l.trust=function(a){return u("<",void 0,void 0,a,void 0,void 0)};l.withAttr=function(a,b,h){return function(d){return b.call(h||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};l.prop=C.stream;l.prop.combine=C.combine;l.prop.reject=C.reject;l.prop.merge=C.merge;l.prop.HALT=C.HALT;
|
||||
l.render=K.render;l.redraw=H.publish;l.request=M.xhr;l.jsonp=M.jsonp;l.version="1.0.0";window.m=l})()};
|
||||
e+a.attrs.href);a.dom.onclick=function(b){b.preventDefault();b.redraw=!1;g(a.attrs.href,void 0,void 0)}}}},la=function(a){var b=0,h=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(g){var k=Date.now();!0===g||0===b||16<=k-b?(b=k,a()):null===h&&(h=d(function(){h=null;a();b=Date.now()},16-(k-b)))}},Z=function(a,b,h,d){d=la(d);null!=b&&b.setEventCallback(function(a){!1!==a.redraw&&h.publish()});null!=h&&(a.redraw&&h.unsubscribe(a.redraw),h.subscribe(d));
|
||||
return a.redraw=d};l.route=function(a,b,h){var d=ka(a);a=function(a,k,l){var e=null,n=null;l=d.defineRoutes(l,function(d,h,k,l){if("function"!==typeof d.view){"function"!==typeof d.render&&(d.render=function(a){return a});var m=function(l){e=k;n=l;b.render(a,d.render(u(l,null,h,void 0,void 0,void 0)))};"function"!==typeof d.resolve&&(d.resolve=function(){m(n)});k!==e?d.resolve(m,h,k,l):m(n)}else b.render(a,u(d,null,h,void 0,void 0,void 0))},function(){d.setPath(k,null,{replace:!0})});Z(a,b,h,l)};
|
||||
a.link=d.link;a.prefix=d.setPrefix;a.set=d.setPath;a.get=d.getPath;return a}(window,K,H);l.mount=function(a,b){return function(h,d){Z(h,a,b,function(){a.render(h,{tag:d})})()}}(K,H);l.trust=function(a){return u("<",void 0,void 0,a,void 0,void 0)};l.withAttr=function(a,b,h){return function(d){return b.call(h||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};l.prop=C.stream;l.prop.combine=C.combine;l.prop.reject=C.reject;l.prop.merge=C.merge;l.prop.HALT=C.HALT;l.render=
|
||||
K.render;l.redraw=H.publish;l.request=M.xhr;l.jsonp=M.jsonp;l.version="1.0.0";window.m=l})()};
|
||||
|
|
@ -6,10 +6,10 @@
|
|||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "node bundler/cli index.js -o mithril.js -w",
|
||||
"build": "npm run build-commonjs & npm run build-browser",
|
||||
"build-commonjs": "node bundler/cli index.js -o mithril.js",
|
||||
"build-browser": "node bundler/cli browser.js -o mithril.min.js -m",
|
||||
"dev": "node bundler/cli browser.js -o mithril.js -w",
|
||||
"build": "npm run build-browser & npm run build-min",
|
||||
"build-browser": "node bundler/cli browser.js -o mithril.js",
|
||||
"build-min": "node bundler/cli browser.js -o mithril.min.js -m",
|
||||
"lintdocs": "node bundler/lintdocs",
|
||||
"lint": "eslint .",
|
||||
"test": "node ospec/bin/ospec",
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ module.exports = function($window) {
|
|||
}
|
||||
}
|
||||
if (vnode.dom.parentNode != null) parent.removeChild(vnode.dom)
|
||||
if (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string" && vnode.tag !== "<") { //TODO test custom elements
|
||||
if (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string") { //TODO test custom elements
|
||||
if (!context.pool) context.pool = [vnode]
|
||||
else context.pool.push(vnode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ var buildQueryString = require("../querystring/build")
|
|||
var parseQueryString = require("../querystring/parse")
|
||||
|
||||
module.exports = function($window) {
|
||||
var supportsPushState = typeof $window.history.pushState === "function" && $window.location.protocol !== "file:"
|
||||
var supportsPushState = typeof $window.history.pushState === "function"
|
||||
var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
|
||||
var prefix = "#!"
|
||||
|
|
@ -75,7 +75,7 @@ module.exports = function($window) {
|
|||
var path = getPath()
|
||||
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, "([^\\/]+)") + "\/?$")
|
||||
|
|
|
|||
|
|
@ -6,295 +6,297 @@ var pushStateMock = require("../../test-utils/pushStateMock")
|
|||
var Router = require("../../router/router")
|
||||
|
||||
o.spec("Router.defineRoutes", function() {
|
||||
void ["#", "?", "", "#!", "?!", "/foo"].forEach(function(prefix) {
|
||||
o.spec("using prefix `" + prefix + "`", function() {
|
||||
var $window, router, onRouteChange, onFail
|
||||
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 $window, router, onRouteChange, onFail
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock()
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock(env)
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
|
||||
o("calls onRouteChange on init", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}}, onRouteChange, onFail)
|
||||
o("calls onRouteChange on init", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
|
||||
done()
|
||||
o("resolves to route", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("resolves to route", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
o("resolves to route w/ escaped unicode", function(done) {
|
||||
$window.location.href = prefix + "/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6"
|
||||
router.defineRoutes({"/ö": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {"ö": "ö"}, "/ö?ö=ö#ö=ö", "/ö"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("resolves to route w/ escaped unicode", function(done) {
|
||||
$window.location.href = prefix + "/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6"
|
||||
router.defineRoutes({"/ö": {data: 2}}, onRouteChange, onFail)
|
||||
o("resolves to route w/ unicode", function(done) {
|
||||
$window.location.href = prefix + "/ö?ö=ö#ö=ö"
|
||||
router.defineRoutes({"/ö": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {"ö": "ö"}, "/ö?ö=ö#ö=ö", "/ö"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {"ö": "ö"}, "/ö?ö=ö#ö=ö", "/ö"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("resolves to route w/ unicode", function(done) {
|
||||
$window.location.href = prefix + "/ö?ö=ö#ö=ö"
|
||||
router.defineRoutes({"/ö": {data: 2}}, onRouteChange, onFail)
|
||||
o("resolves to route on fallback mode", function(done) {
|
||||
$window.location.href = "file://" + prefix + "/test"
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {"ö": "ö"}, "/ö?ö=ö#ö=ö", "/ö"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("resolves to route on fallback mode", function(done) {
|
||||
$window.location.href = "file://" + prefix + "/test"
|
||||
o("handles parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x"
|
||||
router.defineRoutes({"/test/:a": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x"}, "/test/x", "/test/:a"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x"
|
||||
router.defineRoutes({"/test/:a": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles multi-parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x/y"
|
||||
router.defineRoutes({"/test/:a/:b": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x"}, "/test/x", "/test/:a"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x", b: "y"}, "/test/x/y", "/test/:a/:b"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles multi-parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x/y"
|
||||
router.defineRoutes({"/test/:a/:b": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles rest parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x/y"
|
||||
router.defineRoutes({"/test/:a...": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x", b: "y"}, "/test/x/y", "/test/:a/:b"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x/y"}, "/test/x/y", "/test/:a..."])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles rest parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test/x/y"
|
||||
router.defineRoutes({"/test/:a...": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles route with search", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b&c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "x/y"}, "/test/x/y", "/test/:a..."])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test?a=b&c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles route with search", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b&c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles route with hash", function(done) {
|
||||
$window.location.href = prefix + "/test#a=b&c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test?a=b&c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test#a=b&c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles route with hash", function(done) {
|
||||
$window.location.href = prefix + "/test#a=b&c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles route with search and hash", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b#c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test#a=b&c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test?a=b#c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles route with search and hash", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b#c=d"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
o("calls reject", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/other": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {a: "b", c: "d"}, "/test?a=b#c=d", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
o(onFail.args).deepEquals(["/test", {}])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("calls reject", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/other": {data: 1}}, onRouteChange, onFail)
|
||||
o("calls reject w/ search and hash", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b#c=d"
|
||||
router.defineRoutes({"/other": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
o(onFail.args).deepEquals(["/test", {}])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
o(onFail.args).deepEquals(["/test?a=b#c=d", {a: "b", c: "d"}])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("calls reject w/ search and hash", function(done) {
|
||||
$window.location.href = prefix + "/test?a=b#c=d"
|
||||
router.defineRoutes({"/other": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles out of order routes", function(done) {
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes({"/z/y/x": {data: 1}, "/:a...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
o(onFail.args).deepEquals(["/test?a=b#c=d", {a: "b", c: "d"}])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles out of order routes", function(done) {
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes({"/z/y/x": {data: 1}, "/:a...": {data: 2}}, onRouteChange, onFail)
|
||||
o("handles reverse out of order routes", function(done) {
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes({"/:a...": {data: 2}, "/z/y/x": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles reverse out of order routes", function(done) {
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes({"/:a...": {data: 2}, "/z/y/x": {data: 1}}, onRouteChange, onFail)
|
||||
o("handles dynamically added out of order routes", function(done) {
|
||||
var routes = {}
|
||||
routes["/z/y/x"] = {data: 1}
|
||||
routes["/:a..."] = {data: 2}
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles dynamically added out of order routes", function(done) {
|
||||
var routes = {}
|
||||
routes["/z/y/x"] = {data: 1}
|
||||
routes["/:a..."] = {data: 2}
|
||||
o("handles reversed dynamically added out of order routes", function(done) {
|
||||
var routes = {}
|
||||
routes["/:a..."] = {data: 2}
|
||||
routes["/z/y/x"] = {data: 1}
|
||||
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles reversed dynamically added out of order routes", function(done) {
|
||||
var routes = {}
|
||||
routes["/:a..."] = {data: 2}
|
||||
routes["/z/y/x"] = {data: 1}
|
||||
o("handles mixed out of order routes", function(done) {
|
||||
var routes = {"/z/y/x": {data: 1}}
|
||||
routes["/:a..."] = {data: 2}
|
||||
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles mixed out of order routes", function(done) {
|
||||
var routes = {"/z/y/x": {data: 1}}
|
||||
routes["/:a..."] = {data: 2}
|
||||
o("handles reverse mixed out of order routes", function(done) {
|
||||
var routes = {"/:a...": {data: 2}}
|
||||
routes["/z/y/x"] = {data: 12}
|
||||
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/z/y/x", "/z/y/x"])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles reverse mixed out of order routes", function(done) {
|
||||
var routes = {"/:a...": {data: 2}}
|
||||
routes["/z/y/x"] = {data: 12}
|
||||
o("handles non-ascii routes", function(done) {
|
||||
$window.location.href = prefix + "/ö"
|
||||
router.defineRoutes({"/ö": "aaa"}, onRouteChange, onFail)
|
||||
|
||||
$window.location.href = prefix + "/z/y/x"
|
||||
router.defineRoutes(routes, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
o(onRouteChange.args).deepEquals([{data: 2}, {a: "z/y/x"}, "/z/y/x", "/:a..."])
|
||||
|
||||
done()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
o("handles non-ascii routes", function(done) {
|
||||
$window.location.href = prefix + "/ö"
|
||||
router.defineRoutes({"/ö": "aaa"}, onRouteChange, onFail)
|
||||
o("replays", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
var replay = router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
replay()
|
||||
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
o("replays", function(done) {
|
||||
$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()
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(2)
|
||||
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
|
||||
o(onFail.callCount).equals(0)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,41 +5,43 @@ var pushStateMock = require("../../test-utils/pushStateMock")
|
|||
var Router = require("../../router/router")
|
||||
|
||||
o.spec("Router.getPath", function() {
|
||||
void ["#", "?", "", "#!", "?!", '/foo'].forEach(function(prefix) {
|
||||
o.spec("using prefix `" + prefix + "`", function() {
|
||||
var $window, router, onRouteChange, onFail
|
||||
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 $window, router, onRouteChange, onFail
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock()
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock(env)
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
|
||||
o("gets route", function() {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
o("gets route", function() {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
|
||||
|
||||
o(router.getPath()).equals("/test")
|
||||
})
|
||||
o("gets route w/ params", function() {
|
||||
$window.location.href = prefix + "/other/x/y/z?c=d#e=f"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o(router.getPath()).equals("/test")
|
||||
})
|
||||
o("gets route w/ params", function() {
|
||||
$window.location.href = prefix + "/other/x/y/z?c=d#e=f"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
})
|
||||
o("gets route w/ escaped unicode", function() {
|
||||
$window.location.href = prefix + "/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
})
|
||||
o("gets route w/ escaped unicode", function() {
|
||||
$window.location.href = prefix + "/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
})
|
||||
o("gets route w/ unicode", function() {
|
||||
$window.location.href = prefix + "/ö?ö=ö#ö=ö"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
})
|
||||
o("gets route w/ unicode", function() {
|
||||
$window.location.href = prefix + "/ö?ö=ö#ö=ö"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,150 +6,152 @@ var pushStateMock = require("../../test-utils/pushStateMock")
|
|||
var Router = require("../../router/router")
|
||||
|
||||
o.spec("Router.setPath", function() {
|
||||
void ["#", "?", "", "#!", "?!", "/foo"].forEach(function(prefix) {
|
||||
o.spec("using prefix `" + prefix + "`", function() {
|
||||
var $window, router, onRouteChange, onFail
|
||||
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 $window, router, onRouteChange, onFail
|
||||
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock()
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
o.beforeEach(function() {
|
||||
$window = pushStateMock(env)
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
onRouteChange = o.spy()
|
||||
onFail = o.spy()
|
||||
})
|
||||
|
||||
o("setPath calls onRouteChange asynchronously", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}, "/b": {data: 2}}, onRouteChange, onFail)
|
||||
o("setPath calls onRouteChange asynchronously", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}, "/b": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/b")
|
||||
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(2)
|
||||
router.setPath("/b")
|
||||
|
||||
o(onRouteChange.callCount).equals(1)
|
||||
callAsync(function() {
|
||||
o(onRouteChange.callCount).equals(2)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("setPath calls onFail asynchronously", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}, "/b": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/c")
|
||||
|
||||
o(onFail.callCount).equals(0)
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets route via API", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other/x/y/z?c=d#e=f")
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("setPath calls onFail asynchronously", function(done) {
|
||||
$window.location.href = prefix + "/a"
|
||||
router.defineRoutes({"/a": {data: 1}, "/b": {data: 2}}, onRouteChange, onFail)
|
||||
o("sets route w/ escaped unicode", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/c")
|
||||
|
||||
o(onFail.callCount).equals(0)
|
||||
callAsync(function() {
|
||||
o(onFail.callCount).equals(1)
|
||||
router.setPath("/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6")
|
||||
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets route via API", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o("sets route w/ unicode", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other/x/y/z?c=d#e=f")
|
||||
callAsync(function() {
|
||||
router.setPath("/ö?ö=ö#ö=ö")
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets route w/ escaped unicode", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/%C3%B6?%C3%B6=%C3%B6#%C3%B6=%C3%B6")
|
||||
o("sets route on fallback mode", function(done) {
|
||||
$window.location.href = "file://" + prefix + "/test"
|
||||
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
|
||||
done()
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other/x/y/z?c=d#e=f")
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets route w/ unicode", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/ö/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o("sets route via pushState/onpopstate", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/ö?ö=ö#ö=ö")
|
||||
callAsync(function() {
|
||||
$window.history.pushState(null, null, prefix + "/other/x/y/z?c=d#e=f")
|
||||
$window.onpopstate()
|
||||
|
||||
o(router.getPath()).equals("/ö?ö=ö#ö=ö")
|
||||
|
||||
done()
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
o("sets route on fallback mode", function(done) {
|
||||
$window.location.href = "file://" + prefix + "/test"
|
||||
callAsync(function() {
|
||||
router.setPath("/other/:a/:b", {a: "x", b: "y/z", c: "d", e: "f"})
|
||||
|
||||
router = new Router($window)
|
||||
router.setPrefix(prefix)
|
||||
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other/x/y/z?c=d#e=f")
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d&e=f")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets route via pushState/onpopstate", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o("replace:true works", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
$window.history.pushState(null, null, prefix + "/other/x/y/z?c=d#e=f")
|
||||
$window.onpopstate()
|
||||
callAsync(function() {
|
||||
router.setPath("/other", null, {replace: true})
|
||||
$window.history.back()
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d#e=f")
|
||||
|
||||
done()
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + "/")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
o("sets parameterized route", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)
|
||||
o("replace:false works", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other/:a/:b", {a: "x", b: "y/z", c: "d", e: "f"})
|
||||
callAsync(function() {
|
||||
router.setPath("/other", null, {replace: false})
|
||||
$window.history.back()
|
||||
|
||||
o(router.getPath()).equals("/other/x/y/z?c=d&e=f")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
o("replace:true works", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other": {data: 2}}, onRouteChange, onFail)
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other", null, {replace: true})
|
||||
$window.history.back()
|
||||
|
||||
o($window.location.href).equals("http://localhost/")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
o("replace:false works", function(done) {
|
||||
$window.location.href = prefix + "/test"
|
||||
router.defineRoutes({"/test": {data: 1}, "/other": {data: 2}}, onRouteChange, onFail)
|
||||
|
||||
callAsync(function() {
|
||||
router.setPath("/other", null, {replace: false})
|
||||
$window.history.back()
|
||||
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
||||
o($window.location.href).equals("http://localhost" + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
|
||||
done()
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + slash + (prefix ? prefix + "/" : "") + "test")
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
var parseURL = require("../test-utils/parseURL")
|
||||
|
||||
module.exports = function() {
|
||||
var protocol = "http:"
|
||||
var hostname = "localhost"
|
||||
module.exports = function(options) {
|
||||
if (options == null) options = {}
|
||||
|
||||
var protocol = options.protocol || "http:"
|
||||
var hostname = options.hostname || "localhost"
|
||||
var port = ""
|
||||
var pathname = "/"
|
||||
var search = ""
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ o.spec("stream", function() {
|
|||
Stream.stream("20"),
|
||||
Stream.stream({value: 30}),
|
||||
])
|
||||
|
||||
|
||||
o(all()).deepEquals([10, "20", {value: 30}])
|
||||
})
|
||||
o("remains pending until all streams are active", function() {
|
||||
|
|
@ -184,7 +184,7 @@ o.spec("stream", function() {
|
|||
Stream.stream("20"),
|
||||
straggler,
|
||||
])
|
||||
|
||||
|
||||
o(all()).equals(undefined)
|
||||
|
||||
straggler(30)
|
||||
|
|
@ -549,9 +549,18 @@ o.spec("stream", function() {
|
|||
var absorbed = Stream.stream()
|
||||
var mapped = stream.run(function(value) {return absorbed})
|
||||
|
||||
absorbed(2)
|
||||
// TODO: uncomment when fixed.
|
||||
// var depCallCount = 0
|
||||
// mapped.map(function (value) {
|
||||
// o(value).equals(200)
|
||||
// depCallCount += 1
|
||||
// })
|
||||
// o(depCallCount).equals(0)
|
||||
|
||||
o(mapped()).equals(2)
|
||||
absorbed(200)
|
||||
// o(depCallCount).equals(1)
|
||||
|
||||
o(mapped()).equals(200)
|
||||
})
|
||||
o("works when updating pending stream to errored state", function() {
|
||||
var stream = Stream.stream(undefined)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue