Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mithril

Package Overview
Dependencies
Maintainers
1
Versions
160
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mithril - npm Package Compare versions

Comparing version 1.0.0-rc.5 to 1.0.0-rc.6

api/redraw.js

20

api/mount.js
"use strict"
var Vnode = require("../render/vnode")
var autoredraw = require("../api/autoredraw")
module.exports = function(renderer, pubsub) {
module.exports = function(redrawService) {
return function(root, component) {
if (component === null) {
renderer.render(root, [])
pubsub.unsubscribe(root.redraw)
delete root.redraw
redrawService.render(root, [])
redrawService.unsubscribe(root)
return

@@ -16,9 +14,9 @@ }

if (component.view == null) throw new Error("m.mount(element, component) expects a component, not a vnode")
var run = autoredraw(root, renderer, pubsub, function() {
renderer.render(root, Vnode(component, undefined, undefined, undefined, undefined, undefined))
})
run()
var run = function() {
redrawService.render(root, Vnode(component))
}
redrawService.subscribe(root, run)
redrawService.redraw()
}
}
"use strict"
var Vnode = require("../render/vnode")
var Promise = require("../promise/promise")
var coreRouter = require("../router/router")
module.exports = function($window, mount) {
var router = coreRouter($window)
var currentResolve, currentComponent, currentRender, currentArgs, currentPath
module.exports = function($window, redrawService) {
var routeService = coreRouter($window)
var RouteComponent = {view: function() {
return [currentRender(Vnode(currentComponent, null, currentArgs, undefined, undefined, undefined))]
}}
function defaultRender(vnode) {
return vnode
}
var identity = function(v) {return v}
var render, component, attrs, currentPath, updatePending = false
var route = function(root, defaultRoute, routes) {
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 (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined")
var update = function(routeResolver, comp, params, path) {
component = comp != null && typeof comp.view === "function" ? comp : "div", attrs = params, currentPath = path, updatePending = false
render = (routeResolver.render || identity).bind(routeResolver)
run()
}
var run = function() {
if (render != null) redrawService.render(root, render(Vnode(component, attrs.key, attrs)))
}
var bail = function() {
routeService.setPath(defaultRoute)
}
routeService.defineRoutes(routes, function(payload, params, path) {
if (payload.view) update({}, payload, params, path)
else {
if (payload.onmatch) {
updatePending = true
Promise.resolve(payload.onmatch(params, path)).then(function(resolved) {
if (updatePending) update(payload, resolved, params, path)
}, bail)
}
else update(payload, "div", params, path)
}
var onmatch = function() {
resolve()
}
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})
})
}, bail)
redrawService.subscribe(root, run)
}
route.link = router.link
route.prefix = router.setPrefix
route.set = router.setPath
route.set = function(path, data, options) {
if (updatePending) options = {replace: true}
updatePending = false
routeService.setPath(path, data, options)
}
route.get = function() {return currentPath}
route.prefix = function(prefix) {routeService.prefix = prefix}
route.link = function(vnode) {
vnode.dom.setAttribute("href", routeService.prefix + vnode.attrs.href)
vnode.dom.onclick = function(e) {
if (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return
e.preventDefault()
e.redraw = false
var href = this.getAttribute("href")
if (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length)
route.set(href, undefined, undefined)
}
}
return route
}

@@ -8,3 +8,3 @@ "use strict"

var coreRenderer = require("../../render/render")
var apiPubSub = require("../../api/pubsub")
var apiRedraw = require("../../api/redraw")
var apiMounter = require("../../api/mount")

@@ -14,3 +14,3 @@

var FRAME_BUDGET = Math.floor(1000 / 60)
var $window, root, redraw, mount, render
var $window, root, redrawService, mount, render

@@ -22,4 +22,4 @@ o.beforeEach(function() {

redraw = apiPubSub()
mount = apiMounter(coreRenderer($window), redraw)
redrawService = apiRedraw($window)
mount = apiMounter(redrawService)
render = coreRenderer($window).render

@@ -48,3 +48,3 @@ })

o("mounting null deletes `redraw` from `root`", function() {
o("mounting null unmounts", function() {
mount(root, {

@@ -56,7 +56,5 @@ view : function() {

o(typeof root.redraw).equals('function')
mount(root, null)
o(typeof root.redraw).equals('undefined')
o(root.childNodes.length).equals(0)
})

@@ -169,3 +167,3 @@

var onupdate = o.spy()
var oninit = o.spy()
var oninit = o.spy()
var e = $window.document.createEvent("MouseEvents")

@@ -206,4 +204,4 @@

return m("div", {
oninit : oninit,
onupdate : onupdate
oninit: oninit,
onupdate: onupdate
})

@@ -216,3 +214,3 @@ }

redraw.publish()
redrawService.redraw()

@@ -226,2 +224,24 @@ // Wrapped to give time for the rate-limited redraw to fire

})
o("throttles", function(done, timeout) {
timeout(200)
var i = 0
mount(root, {view: function() {i++}})
var before = i
redrawService.redraw()
redrawService.redraw()
redrawService.redraw()
redrawService.redraw()
var after = i
setTimeout(function(){
o(before).equals(1) // mounts synchronously
o(after).equals(1) // throttles rest
o(i).equals(2)
done()
},40)
})
})

@@ -8,6 +8,7 @@ "use strict"

var m = require("../../render/hyperscript")
var callAsync = require("../../test-utils/callAsync")
var coreRenderer = require("../../render/render")
var apiPubSub = require("../../api/pubsub")
var apiRedraw = require("../../api/redraw")
var apiRouter = require("../../api/router")
var apiMounter = require("../../api/mount")
var Promise = require("../../promise/promise")

@@ -19,3 +20,3 @@ o.spec("route", function() {

var FRAME_BUDGET = Math.floor(1000 / 60)
var $window, root, redraw, mount, route
var $window, root, redrawService, route

@@ -27,5 +28,4 @@ o.beforeEach(function() {

redraw = apiPubSub()
mount = apiMounter(coreRenderer($window), redraw)
route = apiRouter($window, mount)
redrawService = apiRedraw($window)
route = apiRouter($window, redrawService)
route.prefix(prefix)

@@ -65,3 +65,3 @@ })

redraw.publish(true)
redrawService.redraw()

@@ -82,3 +82,3 @@ o(view.callCount).equals(2)

setTimeout(function() {
callAsync(function() {
o(root.firstChild.nodeName).equals("DIV")

@@ -91,3 +91,3 @@

done()
}, FRAME_BUDGET)
})
})

@@ -131,3 +131,3 @@

redraw.publish(true)
redrawService.redraw()

@@ -139,4 +139,4 @@ o(onupdate.callCount).equals(1)

var onupdate = o.spy()
var oninit = o.spy()
var onclick = o.spy()
var oninit = o.spy()
var onclick = o.spy()
var e = $window.document.createEvent("MouseEvents")

@@ -169,7 +169,7 @@

// Wrapped to give time for the rate-limited redraw to fire
setTimeout(function() {
callAsync(function() {
o(onupdate.callCount).equals(1)
done()
}, FRAME_BUDGET * 2)
})
})

@@ -179,4 +179,4 @@

var onupdate = o.spy()
var oninit = o.spy()
var onclick = o.spy()
var oninit = o.spy()
var onclick = o.spy()
var e = $window.document.createEvent("MouseEvents")

@@ -206,7 +206,7 @@

// Wrapped to ensure no redraw fired
setTimeout(function() {
callAsync(function() {
o(onupdate.callCount).equals(0)
done()
}, FRAME_BUDGET)
})
})

@@ -245,3 +245,3 @@

o("accepts RouteResolver", function() {
o("accepts RouteResolver with onmatch that returns Component", function(done) {
var matchCount = 0

@@ -251,36 +251,202 @@ var renderCount = 0

view: function() {
return m("div")
return m("span")
}
}
var resolver = {
onmatch: function(args, requestedPath) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
o(this).equals(resolver)
return Component
},
render: function(vnode) {
renderCount++
o(vnode.attrs.id).equals("abc")
o(this).equals(resolver)
return vnode
},
}
$window.location.href = prefix + "/abc"
route(root, "/abc", {
"/:id" : {
onmatch: function(resolve, args, requestedPath) {
matchCount++
"/:id" : resolver
})
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
o(root.firstChild.nodeName).equals("SPAN")
done()
})
})
resolve(Component)
},
render: function(vnode) {
renderCount++
o("accepts RouteResolver with onmatch that returns Promise<Component>", function(done) {
var matchCount = 0
var renderCount = 0
var Component = {
view: function() {
return m("span")
}
}
o(vnode.attrs.id).equals("abc")
var resolver = {
onmatch: function(args, requestedPath) {
matchCount++
return vnode
},
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
o(this).equals(resolver)
return Promise.resolve(Component)
},
render: function(vnode) {
renderCount++
o(vnode.attrs.id).equals("abc")
o(this).equals(resolver)
return vnode
},
}
$window.location.href = prefix + "/abc"
route(root, "/abc", {
"/:id" : resolver
})
o(matchCount).equals(1)
o(renderCount).equals(1)
o(root.firstChild.nodeName).equals("DIV")
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
o(root.firstChild.nodeName).equals("SPAN")
done()
})
})
o("accepts RouteResolver without `render` method as payload", function() {
o("accepts RouteResolver with onmatch that returns Promise<undefined>", function(done) {
var matchCount = 0
var renderCount = 0
var Component = {
view: function() {
return m("span")
}
}
var resolver = {
onmatch: function(args, requestedPath) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
o(this).equals(resolver)
return Promise.resolve()
},
render: function(vnode) {
renderCount++
o(vnode.attrs.id).equals("abc")
o(this).equals(resolver)
return vnode
},
}
$window.location.href = prefix + "/abc"
route(root, "/abc", {
"/:id" : resolver
})
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
o(root.firstChild.nodeName).equals("DIV")
done()
})
})
o("accepts RouteResolver with onmatch that returns Promise<any>", function(done) {
var matchCount = 0
var renderCount = 0
var Component = {
view: function() {
return m("span")
}
}
var resolver = {
onmatch: function(args, requestedPath) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
o(this).equals(resolver)
return Promise.resolve([])
},
render: function(vnode) {
renderCount++
o(vnode.attrs.id).equals("abc")
o(this).equals(resolver)
return vnode
},
}
$window.location.href = prefix + "/abc"
route(root, "/abc", {
"/:id" : resolver
})
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
o(root.firstChild.nodeName).equals("DIV")
done()
})
})
o("accepts RouteResolver with onmatch that returns rejected Promise", function(done) {
var matchCount = 0
var renderCount = 0
var spy = o.spy()
var Component = {
view: function() {
return m("span")
}
}
var resolver = {
onmatch: function(args, requestedPath) {
matchCount++
return Promise.reject(new Error("error"))
},
render: function(vnode) {
renderCount++
return vnode
},
}
$window.location.href = prefix + "/test/1"
route(root, "/default", {
"/default" : {view: spy},
"/test/:id" : resolver
})
callAsync(function() {
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(0)
o(spy.callCount).equals(1)
done()
})
})
})
o("accepts RouteResolver without `render` method as payload", function(done) {
var matchCount = 0
var Component = {
view: function() {
return m("div")

@@ -293,3 +459,3 @@ }

"/:id" : {
onmatch: function(resolve, args, requestedPath) {
onmatch: function(args, requestedPath) {
matchCount++

@@ -300,3 +466,3 @@

resolve(Component)
return Component
},

@@ -306,14 +472,14 @@ },

o(matchCount).equals(1)
o(root.firstChild.nodeName).equals("DIV")
callAsync(function() {
o(matchCount).equals(1)
o(root.firstChild.nodeName).equals("DIV")
done()
})
})
o("changing `vnode.key` in `render` resets the component", function(done, timeout){
timeout(FRAME_BUDGET * 6)
var oninit = o.spy()
var Component = {
oninit: oninit,
view: function(){
view: function() {
return m("div")

@@ -328,10 +494,10 @@ }

})
setTimeout(function(){
callAsync(function() {
o(oninit.callCount).equals(1)
route.set('/def')
setTimeout(function(){
route.set("/def")
callAsync(function() {
o(oninit.callCount).equals(2)
done()
}, FRAME_BUDGET)
}, FRAME_BUDGET)
})
})
})

@@ -390,10 +556,10 @@

setTimeout(function() {
callAsync(function() {
o(root.firstChild).equals(dom)
done()
}, FRAME_BUDGET)
})
})
o("calls onmatch and view correct number of times", function() {
o("calls onmatch and view correct number of times", function(done) {
var matchCount = 0

@@ -410,5 +576,5 @@ var renderCount = 0

"/" : {
onmatch: function(resolve) {
onmatch: function() {
matchCount++
resolve(Component)
return Component
},

@@ -422,14 +588,54 @@ render: function(vnode) {

o(matchCount).equals(1)
o(renderCount).equals(1)
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
redraw.publish(true)
redrawService.redraw()
o(matchCount).equals(1)
o(renderCount).equals(2)
o(matchCount).equals(1)
o(renderCount).equals(2)
done()
})
})
o("calls onmatch and view correct number of times when not onmatch returns undefined", function(done) {
var matchCount = 0
var renderCount = 0
var Component = {
view: function() {
return m("div")
}
}
$window.location.href = prefix + "/"
route(root, "/", {
"/" : {
onmatch: function() {
matchCount++
},
render: function(vnode) {
renderCount++
return {tag: Component}
},
},
})
callAsync(function() {
o(matchCount).equals(1)
o(renderCount).equals(1)
redrawService.redraw()
o(matchCount).equals(1)
o(renderCount).equals(2)
done()
})
})
o("onmatch can redirect to another route", function(done) {
var redirected = false
var render = o.spy()
$window.location.href = prefix + "/a"

@@ -440,6 +646,7 @@ route(root, "/a", {

route.set("/b")
}
},
render: render
},
"/b" : {
view: function(vnode){
view: function() {
redirected = true

@@ -450,11 +657,14 @@ }

setTimeout(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
done()
}, FRAME_BUDGET)
})
})
o("onmatch can redirect to another route that has RouteResolver", function(done) {
o("onmatch can redirect to another route that has RouteResolver w/ only onmatch", function(done) {
var redirected = false
var render = o.spy()
var view = o.spy(function() {return m("div")})

@@ -466,3 +676,37 @@ $window.location.href = prefix + "/a"

route.set("/b")
},
render: render
},
"/b" : {
onmatch: function() {
redirected = true
return {view: view}
}
}
})
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
o(view.callCount).equals(1)
o(root.childNodes.length).equals(1)
o(root.firstChild.nodeName).equals("DIV")
done()
})
})
})
o("onmatch can redirect to another route that has RouteResolver w/ only render", function(done) {
var redirected = false
var render = o.spy()
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a" : {
onmatch: function() {
route.set("/b")
},
render: render
},

@@ -476,41 +720,215 @@ "/b" : {

setTimeout(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
done()
}, FRAME_BUDGET)
})
})
o("onmatch resolution callback resolves at most once", function(done) {
var resolveCount = 0
var resolvedComponent
var A = {view: function() {}}
var B = {view: function() {}}
var C = {view: function() {}}
o("onmatch can redirect to another route that has RouteResolver whose onmatch resolves asynchronously", function(done) {
var redirected = false
var render = o.spy()
var view = o.spy()
$window.location.href = prefix + "/"
route(root, "/", {
"/": {
onmatch: function(resolve) {
resolve(A)
resolve(B)
callAsync(function() {resolve(C)})
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a" : {
onmatch: function() {
route.set("/b")
},
render: render
},
"/b" : {
onmatch: function() {
redirected = true
return new Promise(function(fulfill){
callAsync(function(){
fulfill({view: view})
})
})
}
}
})
callAsync(function() {
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
o(view.callCount).equals(1)
done()
})
})
})
})
o("onmatch can redirect to another route asynchronously", function(done) {
var redirected = false
var render = o.spy()
var view = o.spy()
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a" : {
onmatch: function() {
callAsync(function() {route.set("/b")})
return new Promise(function() {})
},
render: render
},
"/b" : {
onmatch: function() {
redirected = true
return {view: view}
}
}
})
callAsync(function() {
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
o(view.callCount).equals(1)
done()
})
})
})
})
o("onmatch can redirect w/ window.history.back()", function(done) {
var render = o.spy()
var component = {view: o.spy()}
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a" : {
onmatch: function() {
return component
},
render: function(vnode) {
resolveCount++
resolvedComponent = vnode.tag
return vnode
}
},
"/b" : {
onmatch: function() {
$window.history.back()
return new Promise(function() {})
},
render: render
}
})
setTimeout(function() {
o(resolveCount).equals(1)
o(resolvedComponent).equals(A)
done()
}, FRAME_BUDGET)
callAsync(function() {
route.set('/b')
callAsync(function() {
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(component.view.callCount).equals(2)
done()
})
})
})
})
})
o("onmatch can redirect to a non-existent route that defaults to a RouteResolver w/ onmatch", function(done) {
var redirected = false
var render = o.spy()
$window.location.href = prefix + "/a"
route(root, "/b", {
"/a" : {
onmatch: function() {
route.set("/c")
},
render: render
},
"/b" : {
onmatch: function(vnode){
redirected = true
return {view: function() {}}
}
}
})
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
done()
})
})
})
o("onmatch can redirect to a non-existent route that defaults to a RouteResolver w/ render", function(done) {
var redirected = false
var render = o.spy()
$window.location.href = prefix + "/a"
route(root, "/b", {
"/a" : {
onmatch: function() {
route.set("/c")
},
render: render
},
"/b" : {
render: function(vnode){
redirected = true
}
}
})
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
done()
})
})
})
o("onmatch can redirect to a non-existent route that defaults to a component", function(done) {
var redirected = false
var render = o.spy()
$window.location.href = prefix + "/a"
route(root, "/b", {
"/a" : {
onmatch: function() {
route.set("/c")
},
render: render
},
"/b" : {
view: function(vnode){
redirected = true
}
}
})
callAsync(function() {
callAsync(function() {
o(render.callCount).equals(0)
o(redirected).equals(true)
done()
})
})
})
o("the previous view redraws while onmatch resolution is pending (#1268)", function(done) {
var view = o.spy()
var onmatch = o.spy()
var onmatch = o.spy(function() {
return new Promise(function() {})
})

@@ -528,7 +946,7 @@ $window.location.href = prefix + "/a"

setTimeout(function(){
callAsync(function() {
o(view.callCount).equals(1)
o(onmatch.callCount).equals(1)
redraw.publish(true)
redrawService.redraw()

@@ -539,25 +957,32 @@ o(view.callCount).equals(2)

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()})
var onmatch = o.spy()
var render = o.spy(function() {return m("div")})
$window.location.href = prefix + "/"
route(root, '/', {
"/":{
"/": {
onmatch: onmatch,
render: function(){return m("div")}
render: render
}
})
o(onmatch.callCount).equals(1)
callAsync(function() {
o(onmatch.callCount).equals(1)
o(render.callCount).equals(1)
route.set(route.get())
route.set(route.get())
setTimeout(function() {
o(onmatch.callCount).equals(2)
callAsync(function() {
callAsync(function() {
o(onmatch.callCount).equals(2)
o(render.callCount).equals(2)
done()
}, FRAME_BUDGET)
done()
})
})
})
})

@@ -569,4 +994,8 @@

route(root, "/", {
"/": {view: function(){}},
"/2": {onmatch: function(){}}
"/": {view: function() {}},
"/2": {
onmatch: function() {
return new Promise(function() {})
}
}
})

@@ -579,11 +1008,9 @@

setTimeout(function(){
callAsync(function() {
o(route.get()).equals("/")
done()
}, FRAME_BUDGET)
})
})
o("routing with RouteResolver works more than once", function(done, timeout) {
timeout(200)
o("routing with RouteResolver works more than once", function(done) {
$window.location.href = prefix + "/a"

@@ -605,16 +1032,52 @@ route(root, '/a', {

setTimeout(function(){
callAsync(function() {
route.set('/a')
setTimeout(function(){
callAsync(function() {
o(root.firstChild.nodeName).equals("A")
done()
}, FRAME_BUDGET)
}, FRAME_BUDGET)
})
})
})
o("calling route.set invalidates pending onmatch resolution", function(done, timeout) {
timeout(200)
o("calling route.set invalidates pending onmatch resolution", function(done) {
var rendered = false
var resolved
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a": {
onmatch: function() {
return new Promise(function(resolve) {
callAsync(function() {
callAsync(function() {
resolve({view: function() {}})
})
})
})
},
render: function(vnode) {
rendered = true
resolved = "a"
}
},
"/b": {
view: function() {
resolved = "b"
}
}
})
route.set("/b")
callAsync(function() {
o(rendered).equals(false)
o(resolved).equals("b")
done()
})
})
o("calling route.set invalidates pending onmatch resolution", function(done) {
var rendered = false
var resolved

@@ -624,9 +1087,20 @@ $window.location.href = prefix + "/a"

"/a": {
onmatch: function(resolve) {
setTimeout(resolve, 20)
onmatch: function() {
return new Promise(function(resolve) {
callAsync(function() {
callAsync(function() {
resolve({view: function() {rendered = true}})
})
})
})
},
render: function(vnode) {resolved = "a"}
render: function(vnode) {
rendered = true
resolved = "a"
}
},
"/b": {
view: function() {resolved = "b"}
view: function() {
resolved = "b"
}
}

@@ -637,8 +1111,93 @@ })

setTimeout(function() {
callAsync(function() {
o(rendered).equals(false)
o(resolved).equals("b")
callAsync(function() {
o(rendered).equals(false)
o(resolved).equals("b")
done()
})
})
})
o("route changes activate onbeforeremove", function(done) {
var spy = o.spy()
$window.location.href = prefix + "/a"
route(root, "/a", {
"/a": {
onbeforeremove: spy,
view: function() {}
},
"/b": {
view: function() {}
}
})
route.set("/b")
callAsync(function() {
o(spy.callCount).equals(1)
done()
}, 30)
})
})
o("asynchronous route.set in onmatch works", function(done) {
var rendered = false, resolved
route(root, "/a", {
"/a": {
onmatch: function() {
return Promise.resolve().then(function() {
route.set("/b")
})
},
render: function(vnode) {
rendered = true
resolved = "a"
}
},
"/b": {
view: function() {
resolved = "b"
}
},
})
callAsync(function() { // tick for popstate for /a
callAsync(function() { // tick for promise in onmatch
callAsync(function() { // tick for onpopstate for /b
o(rendered).equals(false)
o(resolved).equals("b")
done()
})
})
})
})
o("throttles", function(done, timeout) {
timeout(200)
var i = 0
$window.location.href = prefix + "/"
route(root, "/", {
"/": {view: function(v) {i++}}
})
var before = i
redrawService.redraw()
redrawService.redraw()
redrawService.redraw()
redrawService.redraw()
var after = i
setTimeout(function() {
o(before).equals(1) // routes synchronously
o(after).equals(2) // redraws synchronously
o(i).equals(3) // throttles rest
done()
}, FRAME_BUDGET * 2)
})
})

@@ -645,0 +1204,0 @@ })

@@ -18,2 +18,3 @@ "use strict"

var error
function run(input, output) {

@@ -35,4 +36,5 @@ try {

var dependency = resolve(filepath, filename)
var code = process(dependency, pre + (modules[dependency] == null ? exportCode(filename, dependency, def, variable, eq, rest, uuid) : def + variable + eq + modules[dependency]))
modules[dependency] = rest ? "_" + uuid : variable
var localUUID = uuid // global uuid can update from nested `process` call, ensure same id is used on declaration and consumption
var code = process(dependency, pre + (modules[dependency] == null ? exportCode(filename, dependency, def, variable, eq, rest, localUUID) : def + variable + eq + modules[dependency]))
modules[dependency] = rest ? "_" + localUUID : variable
uuid++

@@ -61,4 +63,7 @@ return code + rest

try {new Function(code)} catch (e) {
proc.exec("node " + filename, function(error) {
if (error !== null) console.log("\x1b[31m" + error.message)
proc.exec("node " + filepath, function(e) {
if (e !== null && e.message !== error) {
error = e.message
console.log("\x1b[31m" + e.message + "\x1b[0m")
}
})

@@ -117,3 +122,7 @@ }

if (!isFile(output) || code !== read(output)) fs.writeFileSync(output, code, "utf8")
if (!isFile(output) || code !== read(output)) {
//try {new Function(code); console.log("build completed at " + new Date())} catch (e) {}
error = null
fs.writeFileSync(output, code, "utf8")
}
}

@@ -120,0 +129,0 @@ catch (e) {

@@ -276,2 +276,26 @@ var o = require("../../ospec/ospec")

})
o("works if included multiple times", function() {
write("a.js", `module.exports = 123`)
write("b.js", `var a = require("./a").toString()\nmodule.exports = a`)
write("c.js", `var a = require("./a").toString()\nvar b = require("./b")`)
bundle(ns + "c.js", ns + "out.js")
o(read("out.js")).equals(`new function() {\nvar _0 = 123\nvar a = _0.toString()\nvar a0 = _0.toString()\nvar b = a0\n}`)
remove("a.js")
remove("b.js")
remove("c.js")
})
o("works if included multiple times reverse", function() {
write("a.js", `module.exports = 123`)
write("b.js", `var a = require("./a").toString()\nmodule.exports = a`)
write("c.js", `var b = require("./b")\nvar a = require("./a").toString()`)
bundle(ns + "c.js", ns + "out.js")
o(read("out.js")).equals(`new function() {\nvar _0 = 123\nvar a0 = _0.toString()\nvar b = a0\nvar a = _0.toString()\n}`)
remove("a.js")
remove("b.js")
remove("c.js")
})
o("reuses binding if possible", function() {

@@ -278,0 +302,0 @@ write("a.js", `var b = require("./b")\nvar c = require("./c")`)

@@ -7,3 +7,3 @@ "use strict"

requestService.setCompletionCallback(redrawService.publish)
requestService.setCompletionCallback(redrawService.redraw)

@@ -14,3 +14,3 @@ m.mount = require("./mount")

m.render = require("./render").render
m.redraw = redrawService.publish
m.redraw = redrawService.redraw
m.request = requestService.request

@@ -17,0 +17,0 @@ m.jsonp = requestService.jsonp

@@ -33,3 +33,4 @@ new function() {

if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
attributes[match[4]] = attrValue || true
if (match[4] === "class") classes.push(attrValue)
else attributes[match[4]] = attrValue || true
}

@@ -205,27 +206,34 @@ }

var callbackCount = 0
var count = 0
var oncompletion
function setCompletionCallback(callback) {oncompletion = callback}
function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()}
function finalize(promise0) {
var then0 = promise0.then
promise0.then = function() {
count++
var next = then0.apply(promise0, arguments)
next.then(complete, function(e) {
complete()
throw e
})
return finalize(next)
function finalizer() {
var count = 0
function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()}
return function finalize(promise0) {
var then0 = promise0.then
promise0.then = function() {
count++
var next = then0.apply(promise0, arguments)
next.then(complete, function(e) {
complete()
if (count === 0) throw e
})
return finalize(next)
}
return promise0
}
return promise0
}
function normalize(args, extra) {
if (typeof args === "string") {
var url = args
args = extra || {}
if (args.url == null) args.url = url
}
return args
}
function request(args, extra) {
return finalize(new Promise(function(resolve, reject) {
if (typeof args === "string") {
var url = args
args = extra || {}
if (args.url == null) args.url = url
}
var finalize = finalizer()
args = normalize(args, extra)
var promise0 = new Promise(function(resolve, reject) {
if (args.method == null) args.method = "GET"

@@ -248,2 +256,3 @@ args.method = args.method.toUpperCase()

}
if (args.withCredentials) xhr.withCredentials = args.withCredentials
if (typeof args.config === "function") xhr = args.config(xhr, args) || xhr

@@ -270,6 +279,10 @@ xhr.onreadystatechange = function() {

else xhr.send()
}))
})
return args.background === true ? promise0 : finalize(promise0)
}
function jsonp(args) {
return finalize(new Promise(function(resolve, reject) {
function jsonp(args, extra) {
var finalize = finalizer()
args = normalize(args, extra)
var promise0 = new Promise(function(resolve, reject) {
var callbackName = args.callbackName || "_mithril_" + Math.round(Math.random() * 1e16) + "_" + callbackCount++

@@ -292,3 +305,4 @@ var script = $window.document.createElement("script")

$window.document.documentElement.appendChild(script)
}))
})
return args.background === true? promise0 : finalize(promise0)
}

@@ -334,18 +348,3 @@ function interpolate(url, data) {

var requestService = _8(window, PromisePolyfill)
var _11 = function() {
var callbacks = []
function unsubscribe(callback) {
var index = callbacks.indexOf(callback)
if (index > -1) callbacks.splice(index, 1)
}
function publish() {
for (var i = 0; i < callbacks.length; i++) {
callbacks[i].apply(this, arguments)
}
}
return {subscribe: callbacks.push.bind(callbacks), unsubscribe: unsubscribe, publish: publish}
}
var redrawService = _11()
requestService.setCompletionCallback(redrawService.publish)
var _13 = function($window) {
var coreRenderer = function($window) {
var $doc = $window.document

@@ -463,14 +462,20 @@ var $emptyFragment = $doc.createDocumentFragment()

else {
var recycling = isRecyclable(old, vnodes)
if (recycling) old = old.concat(old.pool)
if (old.length === vnodes.length && vnodes[0] != null && vnodes[0].key == null) {
var isUnkeyed = false
for (var i = 0; i < vnodes.length; i++) {
if (vnodes[i] != null) {
isUnkeyed = vnodes[i].key == null
break
}
}
if (old.length === vnodes.length && isUnkeyed) {
for (var i = 0; i < old.length; i++) {
if (old[i] === vnodes[i] || old[i] == null && vnodes[i] == null) continue
if (old[i] === vnodes[i]) continue
else if (old[i] == null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling))
else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)
if (recycling && old[i].tag === vnodes[i].tag) insertNode(parent, toFragment(old[i]), getNextSibling(old, i + 1, nextSibling))
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns)
}
}
else {
var recycling = isRecyclable(old, vnodes)
if (recycling) old = old.concat(old.pool)
var oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map

@@ -480,3 +485,5 @@ while (oldEnd >= oldStart && end >= start) {

if (o === v && !recycling) oldStart++, start++
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldStart++
else if (v == null) start++
else if (o.key === v.key) {
oldStart++, start++

@@ -489,3 +496,5 @@ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns)

if (o === v && !recycling) oldEnd--, start++
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldEnd--
else if (v == null) start++
else if (o.key === v.key) {
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)

@@ -501,3 +510,5 @@ if (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))

if (o === v && !recycling) oldEnd--, end--
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldEnd--
else if (v == null) end--
else if (o.key === v.key) {
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)

@@ -647,4 +658,4 @@ if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)

if (vnode != null) {
var key1 = vnode.key
if (key1 != null) map[key1] = i
var key2 = vnode.key
if (key2 != null) map[key2] = i
}

@@ -683,3 +694,3 @@ }

}
else if (children != null || vnode.text != null) throw new Error("Child node of a contenteditable must be trusted")
else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
}

@@ -756,26 +767,30 @@ //remove

function setAttrs(vnode, attrs2, ns) {
for (var key1 in attrs2) {
setAttr(vnode, key1, null, attrs2[key1], ns)
for (var key2 in attrs2) {
setAttr(vnode, key2, null, attrs2[key2], ns)
}
}
function setAttr(vnode, key1, old, value, ns) {
function setAttr(vnode, key2, old, value, ns) {
var element = vnode.dom
if (key1 === "key" || (old === value && !isFormAttribute(vnode, key1)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key1)) return
var nsLastIndex = key1.indexOf(":")
if (nsLastIndex > -1 && key1.substr(0, nsLastIndex) === "xlink") {
element.setAttributeNS("http://www.w3.org/1999/xlink", key1.slice(nsLastIndex + 1), value)
if (key2 === "key" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key2)) return
var nsLastIndex = key2.indexOf(":")
if (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === "xlink") {
element.setAttributeNS("http://www.w3.org/1999/xlink", key2.slice(nsLastIndex + 1), value)
}
else if (key1[0] === "o" && key1[1] === "n" && typeof value === "function") updateEvent(vnode, key1, value)
else if (key1 === "style") updateStyle(element, old, value)
else if (key1 in element && !isAttribute(key1) && ns === undefined) {
else if (key2[0] === "o" && key2[1] === "n" && typeof value === "function") updateEvent(vnode, key2, value)
else if (key2 === "style") updateStyle(element, old, value)
else if (key2 in element && !isAttribute(key2) && ns === undefined) {
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
if (vnode.tag === "input" && key1 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
element[key1] = value
if (vnode.tag === "input" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && key2 === "value" && vnode.dom.value === value) return
element[key2] = value
}
else {
if (typeof value === "boolean") {
if (value) element.setAttribute(key1, "")
else element.removeAttribute(key1)
if (value) element.setAttribute(key2, "")
else element.removeAttribute(key2)
}
else element.setAttribute(key1 === "className" ? "class" : key1, value)
else element.setAttribute(key2 === "className" ? "class" : key2, value)
}

@@ -792,12 +807,12 @@ }

if (attrs2 != null) {
for (var key1 in attrs2) {
setAttr(vnode, key1, old && old[key1], attrs2[key1], ns)
for (var key2 in attrs2) {
setAttr(vnode, key2, old && old[key2], attrs2[key2], ns)
}
}
if (old != null) {
for (var key1 in old) {
if (attrs2 == null || !(key1 in attrs2)) {
if (key1 === "className") key1 = "class"
if (key1[0] === "o" && key1[1] === "n" && !isLifecycleMethod(key1)) updateEvent(vnode, key1, undefined)
else if (key1 !== "key") vnode.dom.removeAttribute(key1)
for (var key2 in old) {
if (attrs2 == null || !(key2 in attrs2)) {
if (key2 === "className") key2 = "class"
if (key2[0] === "o" && key2[1] === "n" && !isLifecycleMethod(key2)) updateEvent(vnode, key2, undefined)
else if (key2 !== "key") vnode.dom.removeAttribute(key2)
}

@@ -826,8 +841,8 @@ }

if (typeof old === "string") element.style.cssText = ""
for (var key1 in style) {
element.style[key1] = style[key1]
for (var key2 in style) {
element.style[key2] = style[key2]
}
if (old != null && typeof old !== "string") {
for (var key1 in old) {
if (!(key1 in style)) element.style[key1] = ""
for (var key2 in old) {
if (!(key2 in style)) element.style[key2] = ""
}

@@ -838,17 +853,18 @@ }

//event
function updateEvent(vnode, key1, value) {
function updateEvent(vnode, key2, value) {
var element = vnode.dom
var callback = function(e) {
var callback = typeof onevent !== "function" ? value : function(e) {
var result = value.call(element, e)
if (typeof onevent === "function") onevent.call(element, e)
onevent.call(element, e)
return result
}
if (key1 in element) element[key1] = typeof value === "function" ? callback : null
if (key2 in element) element[key2] = typeof value === "function" ? callback : null
else {
var eventName = key1.slice(2)
var eventName = key2.slice(2)
if (vnode.events === undefined) vnode.events = {}
if (vnode.events[key1] != null) element.removeEventListener(eventName, vnode.events[key1], false)
if (vnode.events[key2] === callback) return
if (vnode.events[key2] != null) element.removeEventListener(eventName, vnode.events[key2], false)
if (typeof value === "function") {
vnode.events[key1] = callback
element.addEventListener(eventName, vnode.events[key1], false)
vnode.events[key2] = callback
element.addEventListener(eventName, vnode.events[key2], false)
}

@@ -885,3 +901,3 @@ }

var active = $doc.activeElement
// First time rendering into a node clears it out
// First time0 rendering into a node clears it out
if (dom.vnodes == null) dom.textContent = ""

@@ -896,4 +912,3 @@ if (!(vnodes instanceof Array)) vnodes = [vnodes]

}
var renderService = _13(window)
var throttle = function(callback1) {
function throttle(callback) {
//60fps translates to 16.6ms, round it down since setTimeout requires int

@@ -903,7 +918,7 @@ var time = 16

var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
return function(synchronous) {
return function() {
var now = Date.now()
if (synchronous === true || last === 0 || now - last >= time) {
if (last === 0 || now - last >= time) {
last = now
callback1()
callback()
}

@@ -913,3 +928,3 @@ else if (pending === null) {

pending = null
callback1()
callback()
last = Date.now()

@@ -920,21 +935,31 @@ }, time - (now - last))

}
var autoredraw = function(root, renderer, pubsub, callback0) {
var run1 = throttle(callback0)
if (renderer != null) {
renderer.setEventCallback(function(e) {
if (e.redraw !== false) pubsub.publish()
})
var _11 = function($window) {
var renderService = coreRenderer($window)
renderService.setEventCallback(function(e) {
if (e.redraw !== false) redraw()
})
var callbacks = []
function subscribe(key1, callback) {
unsubscribe(key1)
callbacks.push(key1, throttle(callback))
}
if (pubsub != null) {
if (root.redraw) pubsub.unsubscribe(root.redraw)
pubsub.subscribe(run1)
function unsubscribe(key1) {
var index = callbacks.indexOf(key1)
if (index > -1) callbacks.splice(index, 2)
}
return root.redraw = run1
function redraw() {
for (var i = 1; i < callbacks.length; i += 2) {
callbacks[i]()
}
}
return {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render}
}
var _17 = function(renderer, pubsub) {
var redrawService = _11(window)
requestService.setCompletionCallback(redrawService.redraw)
var _16 = function(redrawService0) {
return function(root, component) {
if (component === null) {
renderer.render(root, [])
pubsub.unsubscribe(root.redraw)
delete root.redraw
redrawService0.render(root, [])
redrawService0.unsubscribe(root)
return

@@ -944,10 +969,12 @@ }

if (component.view == null) throw new Error("m.mount(element, component) expects a component, not a vnode")
var run0 = autoredraw(root, renderer, pubsub, function() {
renderer.render(root, Vnode(component, undefined, undefined, undefined, undefined, undefined))
})
run0()
var run0 = function() {
redrawService0.render(root, Vnode(component))
}
redrawService0.subscribe(root, run0)
redrawService0.redraw()
}
}
m.mount = _17(renderService, redrawService)
var mount = m.mount
m.mount = _16(redrawService)
var Promise = PromisePolyfill
var parseQueryString = function(string) {

@@ -959,9 +986,9 @@ if (string === "" || string == null) return {}

var entry = entries[i].split("=")
var key3 = decodeURIComponent(entry[0])
var key5 = decodeURIComponent(entry[0])
var value = entry.length === 2 ? decodeURIComponent(entry[1]) : ""
if (value === "true") value = true
else if (value === "false") value = false
var levels = key3.split(/\]\[?|\[/)
var levels = key5.split(/\]\[?|\[/)
var cursor = data0
if (key3.indexOf("[") > -1) levels.pop()
if (key5.indexOf("[") > -1) levels.pop()
for (var j = 0; j < levels.length; j++) {

@@ -972,5 +999,5 @@ var level = levels[j], nextLevel = levels[j + 1]

if (level === "") {
var key3 = levels.slice(0, j).join()
if (counters[key3] == null) counters[key3] = 0
level = counters[key3]++
var key5 = levels.slice(0, j).join()
if (counters[key5] == null) counters[key5] = 0
level = counters[key5]++
}

@@ -988,5 +1015,3 @@ if (cursor[level] == null) {

var callAsync0 = typeof setImmediate === "function" ? setImmediate : setTimeout
var prefix1 = "#!"
function setPrefix(value) {prefix1 = value}
function normalize(fragment0) {
function normalize1(fragment0) {
var data = $window.location[fragment0].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)

@@ -997,3 +1022,3 @@ if (fragment0 === "pathname" && data[0] !== "/") data = "/" + data

var asyncId
function debounceAsync(f) {
function debounceAsync(callback0) {
return function() {

@@ -1003,3 +1028,3 @@ if (asyncId != null) return

asyncId = null
f()
callback0()
})

@@ -1015,23 +1040,24 @@ }

var queryParams = parseQueryString(path.slice(queryIndex + 1, queryEnd))
for (var key2 in queryParams) queryData[key2] = queryParams[key2]
for (var key4 in queryParams) queryData[key4] = queryParams[key4]
}
if (hashIndex > -1) {
var hashParams = parseQueryString(path.slice(hashIndex + 1))
for (var key2 in hashParams) hashData[key2] = hashParams[key2]
for (var key4 in hashParams) hashData[key4] = hashParams[key4]
}
return path.slice(0, pathEnd)
}
function getPath() {
var type2 = prefix1.charAt(0)
var router = {prefix: "#!"}
router.getPath = function() {
var type2 = router.prefix.charAt(0)
switch (type2) {
case "#": return normalize("hash").slice(prefix1.length)
case "?": return normalize("search").slice(prefix1.length) + normalize("hash")
default: return normalize("pathname").slice(prefix1.length) + normalize("search") + normalize("hash")
case "#": return normalize1("hash").slice(router.prefix.length)
case "?": return normalize1("search").slice(router.prefix.length) + normalize1("hash")
default: return normalize1("pathname").slice(router.prefix.length) + normalize1("search") + normalize1("hash")
}
}
function setPath(path, data, options) {
router.setPath = function(path, data, options) {
var queryData = {}, hashData = {}
path = parsePath(path, queryData, hashData)
if (data != null) {
for (var key2 in data) queryData[key2] = data[key2]
for (var key4 in data) queryData[key4] = data[key4]
path = path.replace(/:([^\/]+)/g, function(match2, token) {

@@ -1047,15 +1073,11 @@ delete queryData[token]

if (supportsPushState) {
if (options && options.replace) $window.history.replaceState(null, null, prefix1 + path)
else $window.history.pushState(null, null, prefix1 + path)
if (options && options.replace) $window.history.replaceState(null, null, router.prefix + path)
else $window.history.pushState(null, null, router.prefix + path)
$window.onpopstate()
}
else $window.location.href = prefix1 + path
else $window.location.href = router.prefix + path
}
function defineRoutes(routes, resolve0, reject) {
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
else if (prefix1.charAt(0) === "#") $window.onhashchange = resolveRoute
resolveRoute()
router.defineRoutes = function(routes, resolve, reject) {
function resolveRoute() {
var path = getPath()
var path = router.getPath()
var params = {}

@@ -1073,3 +1095,3 @@ var pathname = parsePath(path, params, params)

}
resolve0(routes[route0], params, path, route0)
resolve(routes[route0], params, path, route0)
})

@@ -1081,7 +1103,51 @@ return

}
return resolveRoute
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
else if (router.prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
resolveRoute()
}
function link(vnode2) {
vnode2.dom.setAttribute("href", prefix1 + vnode2.attrs.href)
vnode2.dom.onclick = function(e) {
return router
}
var _20 = function($window, redrawService0) {
var routeService = coreRouter($window)
var identity = function(v) {return v}
var render1, component, attrs3, currentPath, updatePending = false
var route = function(root, defaultRoute, routes) {
if (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined")
var update = function(routeResolver, comp, params, path) {
component = comp != null && typeof comp.view === "function" ? comp : "div", attrs3 = params, currentPath = path, updatePending = false
render1 = (routeResolver.render || identity).bind(routeResolver)
run1()
}
var run1 = function() {
if (render1 != null) redrawService0.render(root, render1(Vnode(component, attrs3.key, attrs3)))
}
var bail = function() {
routeService.setPath(defaultRoute)
}
routeService.defineRoutes(routes, function(payload, params, path) {
if (payload.view) update({}, payload, params, path)
else {
if (payload.onmatch) {
updatePending = true
Promise.resolve(payload.onmatch(params, path)).then(function(resolved) {
if (updatePending) update(payload, resolved, params, path)
}, bail)
}
else update(payload, "div", params, path)
}
}, bail)
redrawService0.subscribe(root, run1)
}
route.set = function(path, data, options) {
if (updatePending) options = {replace: true}
updatePending = false
routeService.setPath(path, data, options)
}
route.get = function() {return currentPath}
route.prefix = function(prefix0) {routeService.prefix = prefix0}
route.link = function(vnode1) {
vnode1.dom.setAttribute("href", routeService.prefix + vnode1.attrs.href)
vnode1.dom.onclick = function(e) {
if (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return

@@ -1091,61 +1157,17 @@ e.preventDefault()

var href = this.getAttribute("href")
if (href.indexOf(prefix1) === 0) href = href.slice(prefix1.length)
setPath(href, undefined, undefined)
if (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length)
route.set(href, undefined, undefined)
}
}
return {setPrefix: setPrefix, getPath: getPath, setPath: setPath, defineRoutes: defineRoutes, link: link}
}
var _23 = function($window, mount0) {
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(vnode1) {
return vnode1
}
var route = function(root, defaultRoute, routes) {
currentComponent = "div"
currentRender = defaultRender
currentArgs = null
mount0(root, RouteComponent)
router.defineRoutes(routes, function(payload, args0, path) {
var isResolver = typeof payload.view !== "function"
var render1 = defaultRender
var resolve = currentResolve = function (component) {
if (resolve !== currentResolve) return
currentResolve = null
currentComponent = component != null ? component : isResolver ? "div" : payload
currentRender = render1
currentArgs = args0
currentPath = path
root.redraw(true)
}
var onmatch = function() {
resolve()
}
if (isResolver) {
if (typeof payload.render === "function") render1 = payload.render.bind(payload)
if (typeof payload.onmatch === "function") onmatch = payload.onmatch
}
onmatch.call(payload, resolve, args0, path)
}, function() {
router.setPath(defaultRoute, null, {replace: true})
})
}
route.link = router.link
route.prefix = router.setPrefix
route.set = router.setPath
route.get = function() {return currentPath}
return route
}
m.route = _23(window, mount)
m.withAttr = function(attrName, callback2, context) {
m.route = _20(window, redrawService)
m.withAttr = function(attrName, callback1, context) {
return function(e) {
return callback2.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))
return callback1.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))
}
}
m.render = renderService.render
m.redraw = redrawService.publish
var _28 = coreRenderer(window)
m.render = _28.render
m.redraw = redrawService.redraw
m.request = requestService.request

@@ -1155,5 +1177,5 @@ m.jsonp = requestService.jsonp

m.buildQueryString = buildQueryString
m.version = "1.0.0-rc.4"
m.version = "1.0.0-rc.6"
if (typeof module !== "undefined") module["exports"] = m
else window.m = m
}

@@ -1,40 +0,41 @@

new function(){function m(a,b,k,d,l,h){return{tag:a,key:b,attrs:k,children:d,text:l,dom:h,domSize:void 0,state:{},events:void 0,instance:void 0,skip:!1}}function t(a){if(null==a||"string"!==typeof a&&null==a.view)throw Error("The selector must be either a string or a component.");if("string"===typeof a&&void 0===G[a]){for(var b,k,d=[],l={};b=N.exec(a);){var h=b[1],u=b[2];""===h&&""!==u?k=u:"#"===h?l.id=u:"."===h?d.push(u):"["===b[3][0]&&((h=b[6])&&(h=h.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),
l[b[4]]=h||!0)}0<d.length&&(l.className=d.join(" "));G[a]=function(a,b){var d=!1,h,f,w=a.className||a["class"],p;for(p in l)a[p]=l[p];void 0!==w&&(void 0!==a["class"]&&(a["class"]=void 0,a.className=w),void 0!==l.className&&(a.className=l.className+" "+w));for(p in a)if("key"!==p){d=!0;break}b instanceof Array&&1==b.length&&null!=b[0]&&"#"===b[0].tag?f=b[0].children:h=b;return m(k||"div",a.key,d?a:void 0,h,f,void 0)}}var q;null!=arguments[1]&&("object"!==typeof arguments[1]||void 0!==arguments[1].tag||
arguments[1]instanceof Array)?d=1:(q=arguments[1],d=2);if(arguments.length===d+1)b=arguments[d]instanceof Array?arguments[d]:[arguments[d]];else for(b=[];d<arguments.length;d++)b.push(arguments[d]);return"string"===typeof a?G[a](q||{},m.normalizeChildren(b)):m(a,q&&q.key,q||{},m.normalizeChildren(b),void 0,void 0)}m.normalize=function(a){return a instanceof Array?m("[",void 0,void 0,m.normalizeChildren(a),void 0,void 0):null!=a&&"object"!==typeof a?m("#",void 0,void 0,a,void 0,void 0):a};m.normalizeChildren=
function(a){for(var b=0;b<a.length;b++)a[b]=m.normalize(a[b]);return a};var N=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,G={};t.trust=function(a){null==a&&(a="");return m("<",void 0,void 0,a,void 0,void 0)};t.fragment=function(a,b){return m("[",a.key,a,m.normalizeChildren(b),void 0,void 0)};var x=function(a){function b(a,b){return function w(p){var n;try{if(!b||null==p||"object"!==typeof p&&"function"!==typeof p||"function"!==typeof(n=p.then))m(function(){b||0!==
a.length||console.error("Possible unhandled promise rejection:",p);for(var d=0;d<a.length;d++)a[d](p);l.length=0;h.length=0;r.state=b;r.retry=function(){w(p)}});else{if(p===d)throw new TypeError("Promise can't be resolved w/ itself");k(n.bind(p))}}catch(E){q(E)}}}function k(a){function b(a){return function(b){0<f++||a(b)}}var f=0,d=b(q);try{a(b(u),d)}catch(p){d(p)}}if(!(this instanceof x))throw Error("Promise must be called with `new`");if("function"!==typeof a)throw new TypeError("executor must be a function");
var d=this,l=[],h=[],u=b(l,!0),q=b(h,!1),r=d._instance={resolvers:l,rejectors:h},m="function"===typeof setImmediate?setImmediate:setTimeout;k(a)};x.prototype.then=function(a,b){function k(a,b,k,n){b.push(function(b){if("function"!==typeof a)k(b);else try{l(a(b))}catch(f){h&&h(f)}});"function"===typeof d.retry&&n===d.state&&d.retry()}var d=this._instance,l,h,u=new x(function(a,b){l=a;h=b});k(a,d.resolvers,l,!0);k(b,d.rejectors,h,!1);return u};x.prototype["catch"]=function(a){return this.then(null,
a)};x.resolve=function(a){return a instanceof x?a:new x(function(b){b(a)})};x.reject=function(a){return new x(function(b,k){k(a)})};x.all=function(a){return new x(function(b,k){var d=a.length,l=0,h=[];if(0===a.length)b([]);else for(var u=0;u<a.length;u++)(function(u){function r(a){l++;h[u]=a;l===d&&b(h)}null==a[u]||"object"!==typeof a[u]&&"function"!==typeof a[u]||"function"!==typeof a[u].then?r(a[u]):a[u].then(r,k)})(u)})};x.race=function(a){return new x(function(b,k){for(var d=0;d<a.length;d++)a[d].then(b,
k)})};"undefined"===typeof Promise&&("undefined"!==typeof window?window.Promise=x:"undefined"!==typeof global&&(global.Promise=x));var C=function(a){function b(a,d){if(d instanceof Array)for(var h=0;h<d.length;h++)b(a+"["+h+"]",d[h]);else if("[object Object]"===Object.prototype.toString.call(d))for(h in d)b(a+"["+h+"]",d[h]);else k.push(encodeURIComponent(a)+(null!=d&&""!==d?"="+encodeURIComponent(d):""))}if("[object Object]"!==Object.prototype.toString.call(a))return"";var k=[],d;for(d in a)b(d,
a[d]);return k.join("&")},H=function(a,b){function k(){0===--n&&"function"===typeof v&&v()}function d(a){var f=a.then;a.then=function(){n++;var b=f.apply(a,arguments);b.then(k,function(a){k();throw a;});return d(b)};return a}function l(a,b){if(null==b)return a;for(var f=a.match(/:[^\/]+/gi)||[],d=0;d<f.length;d++){var h=f[d].slice(1);null!=b[h]&&(a=a.replace(f[d],b[h]),delete b[h])}return a}function h(a,b){var f=C(b);if(""!==f){var d=0>a.indexOf("?")?"?":"&";a+=d+f}return a}function u(a){try{return""!==
a?JSON.parse(a):null}catch(w){throw Error(a);}}function q(a){return a.responseText}function r(a,b){if("function"===typeof a)if(b instanceof Array)for(var d=0;d<b.length;d++)b[d]=new a(b[d]);else return new a(b);return b}var m=0,n=0,v;return{request:function(f,k){return d(new b(function(b,d){if("string"===typeof f){var n=f;f=k||{};null==f.url&&(f.url=n)}null==f.method&&(f.method="GET");f.method=f.method.toUpperCase();n="boolean"===typeof f.useBody?f.useBody:"GET"!==f.method&&"TRACE"!==f.method;"function"!==
typeof f.serialize&&(f.serialize="undefined"!==typeof FormData&&f.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==typeof f.deserialize&&(f.deserialize=u);"function"!==typeof f.extract&&(f.extract=q);f.url=l(f.url,f.data);n?f.data=f.serialize(f.data):f.url=h(f.url,f.data);var p=new a.XMLHttpRequest;p.open(f.method,f.url,"boolean"===typeof f.async?f.async:!0,"string"===typeof f.user?f.user:void 0,"string"===typeof f.password?f.password:void 0);f.serialize===JSON.stringify&&
n&&p.setRequestHeader("Content-Type","application/json; charset=utf-8");f.deserialize===u&&p.setRequestHeader("Accept","application/json, text/*");"function"===typeof f.config&&(p=f.config(p,f)||p);p.onreadystatechange=function(){if(4===p.readyState)try{var a=f.extract!==q?f.extract(p,f):f.deserialize(f.extract(p,f));if(200<=p.status&&300>p.status||304===p.status)b(r(f.type,a));else{var h=Error(p.responseText),k;for(k in a)h[k]=a[k];d(h)}}catch(F){d(F)}};n&&null!=f.data?p.send(f.data):p.send()}))},
jsonp:function(f){return d(new b(function(b,d){var p=f.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+m++,k=a.document.createElement("script");a[p]=function(d){k.parentNode.removeChild(k);b(r(f.type,d));delete a[p]};k.onerror=function(){k.parentNode.removeChild(k);d(Error("JSONP request failed"));delete a[p]};null==f.data&&(f.data={});f.url=l(f.url,f.data);f.data[f.callbackKey||"callback"]=p;k.src=h(f.url,f.data);a.document.documentElement.appendChild(k)}))},setCompletionCallback:function(a){v=
a}}}(window,"undefined"!==typeof Promise?Promise:x),I=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)}}}();H.setCompletionCallback(I.publish);var M=function(a){function b(c,g,a,b,d,f,h){for(;a<b;a++){var e=g[a];null!=e&&r(c,k(e,d,h),f)}}function k(c,g,a){var e=c.tag;null!=c.attrs&&t(c.attrs,c,g);if("string"===typeof e)switch(e){case "#":return c.dom=A.createTextNode(c.children);
case "<":return d(c);case "[":var f=A.createDocumentFragment();null!=c.children&&(e=c.children,b(f,e,0,e.length,g,null,a));c.dom=f.firstChild;c.domSize=f.childNodes.length;return f;default:var h=c.tag;switch(c.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}var n=(e=c.attrs)&&e.is,h=a?n?A.createElementNS(a,h,{is:n}):A.createElementNS(a,h):n?A.createElement(h,{is:n}):A.createElement(h);c.dom=h;if(null!=e)for(f in n=a,e)p(c,f,null,e[f],n);null!=
c.attrs&&null!=c.attrs.contenteditable?x(c):(null!=c.text&&(""!==c.text?h.textContent=c.text:c.children=[m("#",void 0,void 0,c.text,void 0,void 0)]),null!=c.children&&(f=c.children,b(h,f,0,f.length,g,null,a),g=c.attrs,"select"===c.tag&&null!=g&&("value"in g&&p(c,"value",null,g.value,void 0),"selectedIndex"in g&&p(c,"selectedIndex",null,g.selectedIndex,void 0))));return h}else{c.state||(c.state={});O(c.state,c.tag);f=c.tag.view;if(null!=f.reentrantLock)c=F;else if(f.reentrantLock=!0,t(c.tag,c,g),c.instance=
m.normalize(f.call(c.state,c)),f.reentrantLock=null,null!=c.instance){if(c.instance===c)throw Error("A view cannot return the vnode it received as arguments");g=k(c.instance,g,a);c.dom=c.instance.dom;c.domSize=null!=c.dom?c.instance.domSize:0;c=g}else c.domSize=0,c=F;return c}}function d(c){var g={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",g=A.createElement(g);g.innerHTML=
c.children;c.dom=g.firstChild;c.domSize=g.childNodes.length;c=A.createDocumentFragment();for(var a;a=g.firstChild;)c.appendChild(a);return c}function l(c,a,e,f,d,p){if(a!==e&&(null!=a||null!=e))if(null==a)b(c,e,0,e.length,f,d,void 0);else if(null==e)n(a,0,a.length,e);else{var g;a:{if(null!=a.pool&&Math.abs(a.pool.length-e.length)<=Math.abs(a.length-e.length)&&(g=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)-g)<=Math.abs((a[0]&&
a[0].children&&a[0].children.length||0)-g))){g=!0;break a}g=!1}g&&(a=a.concat(a.pool));if(a.length===e.length&&null!=e[0]&&null==e[0].key)for(var l=0;l<a.length;l++)a[l]===e[l]||null==a[l]&&null==e[l]||(null==a[l]?r(c,k(e[l],f,p),q(a,l+1,d)):null==e[l]?n(a,l,l+1,e):h(c,a[l],e[l],f,q(a,l+1,d),g,p),g&&a[l].tag===e[l].tag&&r(c,u(a[l]),q(a,l+1,d)));else{for(var z=l=0,v=a.length-1,B=e.length-1,w;v>=l&&B>=z;){var y=a[l],m=e[z];if(y!==m||g)if(null!=y&&null!=m&&y.key===m.key)l++,z++,h(c,y,m,f,q(a,l,d),g,
p),g&&y.tag===m.tag&&r(c,u(y),d);else if(y=a[v],y!==m||g)if(null!=y&&null!=m&&y.key===m.key)h(c,y,m,f,q(a,v+1,d),g,p),(g||z<B)&&r(c,u(y),q(a,l,d)),v--,z++;else break;else v--,z++;else l++,z++}for(;v>=l&&B>=z;){y=a[v];m=e[B];if(y!==m||g)if(null!=y&&null!=m&&y.key===m.key)h(c,y,m,f,q(a,v+1,d),g,p),g&&y.tag===m.tag&&r(c,u(y),d),null!=y.dom&&(d=y.dom),v--;else{if(!w){w=a;var y=v,D={},t;for(t=0;t<y;t++){var x=w[t];null!=x&&(x=x.key,null!=x&&(D[x]=t))}w=D}null!=m&&(y=w[m.key],null!=y?(D=a[y],h(c,D,m,f,
q(a,v+1,d),g,p),r(c,u(D),d),a[y].skip=!0,null!=D.dom&&(d=D.dom)):(m=k(m,f,void 0),r(c,m,d),d=m))}else v--;B--;if(B<z)break}b(c,e,z,B+1,f,d,p);n(a,l,v+1,e)}}}function h(a,g,e,b,n,v,w){var c=g.tag;if(c===e.tag){e.state=g.state;e.events=g.events;var z;var B;null!=e.attrs&&"function"===typeof e.attrs.onbeforeupdate&&(z=e.attrs.onbeforeupdate.call(e.state,e,g));"string"!==typeof e.tag&&"function"===typeof e.tag.onbeforeupdate&&(B=e.tag.onbeforeupdate.call(e.state,e,g));void 0===z&&void 0===B||z||B?z=!1:
(e.dom=g.dom,e.domSize=g.domSize,e.instance=g.instance,z=!0);if(!z)if(null!=e.attrs&&L(e.attrs,e,b,v),"string"===typeof c)switch(c){case "#":g.children.toString()!==e.children.toString()&&(g.dom.nodeValue=e.children);e.dom=g.dom;break;case "<":g.children!==e.children?(u(g),r(a,d(e),n)):(e.dom=g.dom,e.domSize=g.domSize);break;case "[":l(a,g.children,e.children,b,n,w);g=0;b=e.children;e.dom=null;if(null!=b){for(var q=0;q<b.length;q++)a=b[q],null!=a&&null!=a.dom&&(null==e.dom&&(e.dom=a.dom),g+=a.domSize||
1);1!==g&&(e.domSize=g)}break;default:a=w;n=e.dom=g.dom;switch(e.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===e.tag&&(null==e.attrs&&(e.attrs={}),null!=e.text&&(e.attrs.value=e.text,e.text=void 0));v=g.attrs;w=e.attrs;c=a;if(null!=w)for(q in w)p(e,q,v&&v[q],w[q],c);if(null!=v)for(q in v)null!=w&&q in w||("className"===q&&(q="class"),"o"!==q[0]||"n"!==q[1]||K(q)?"key"!==q&&e.dom.removeAttribute(q):E(e,q,void 0));null!=e.attrs&&
null!=e.attrs.contenteditable?x(e):null!=g.text&&null!=e.text&&""!==e.text?g.text.toString()!==e.text.toString()&&(g.dom.firstChild.nodeValue=e.text):(null!=g.text&&(g.children=[m("#",void 0,void 0,g.text,void 0,g.dom.firstChild)]),null!=e.text&&(e.children=[m("#",void 0,void 0,e.text,void 0,void 0)]),l(n,g.children,e.children,b,null,a))}else e.instance=m.normalize(e.tag.view.call(e.state,e)),L(e.tag,e,b,v),null!=e.instance?(null==g.instance?r(a,k(e.instance,b,w),n):h(a,g.instance,e.instance,b,n,
v,w),e.dom=e.instance.dom,e.domSize=e.instance.domSize):null!=g.instance?(f(g.instance,null),e.dom=void 0,e.domSize=0):(e.dom=g.dom,e.domSize=g.domSize)}else f(g,null),r(a,k(e,b,w),n)}function u(a){var c=a.domSize;if(null!=c||null==a.dom){var e=A.createDocumentFragment();if(0<c){for(a=a.dom;--c;)e.appendChild(a.nextSibling);e.insertBefore(a,e.firstChild)}return e}return a.dom}function q(a,g,e){for(;g<a.length;g++)if(null!=a[g]&&null!=a[g].dom)return a[g].dom;return e}function r(a,g,e){e&&e.parentNode?
a.insertBefore(g,e):a.appendChild(g)}function x(a){var c=a.children;if(null!=c&&1===c.length&&"<"===c[0].tag)c=c[0].children,a.dom.innerHTML!==c&&(a.dom.innerHTML=c);else if(null!=c||null!=a.text)throw Error("Child node of a contenteditable must be trusted");}function n(a,g,e,b){for(;g<e;g++){var c=a[g];null!=c&&(c.skip?c.skip=!1:f(c,b))}}function v(a){var c=!1;return function(){c||(c=!0,a())}}function f(a,g){function c(){if(++d===b&&(w(a),a.dom)){var c=a.domSize||1;if(1<c)for(var e=a.dom;--c;){var f=
e.nextSibling,h=f.parentNode;null!=h&&h.removeChild(f)}c=a.dom;e=c.parentNode;null!=e&&e.removeChild(c);if(c=null!=g&&null==a.domSize)c=a.attrs,c=!(null!=c&&(c.oncreate||c.onupdate||c.onbeforeremove||c.onremove));c&&"string"===typeof a.tag&&(g.pool?g.pool.push(a):g.pool=[a])}}var b=1,d=0;a.attrs&&a.attrs.onbeforeremove&&(b++,a.attrs.onbeforeremove.call(a.state,a,v(c)));"string"!==typeof a.tag&&a.tag.onbeforeremove&&(b++,a.tag.onbeforeremove.call(a.state,a,v(c)));c()}function w(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)w(a.instance);else if(a=a.children,a instanceof Array)for(var c=0;c<a.length;c++){var e=a[c];null!=e&&w(e)}}function p(a,g,e,b,d){var c=a.dom;if("key"!==g&&(e!==b||"value"===g||"checked"===g||"selectedIndex"===g||"selected"===g&&a.dom===A.activeElement||"object"===typeof b)&&"undefined"!==typeof b&&!K(g)){var f=g.indexOf(":");if(-1<f&&"xlink"===g.substr(0,f))c.setAttributeNS("http://www.w3.org/1999/xlink",
g.slice(f+1),b);else if("o"===g[0]&&"n"===g[1]&&"function"===typeof b)E(a,g,b);else if("style"===g)if(a=e,a===b&&(c.style.cssText="",a=null),null==b)c.style.cssText="";else if("string"===typeof b)c.style.cssText=b;else{"string"===typeof a&&(c.style.cssText="");for(var h in b)c.style[h]=b[h];if(null!=a&&"string"!==typeof a)for(h in a)h in b||(c.style[h]="")}else if(g in c&&"href"!==g&&"list"!==g&&"form"!==g&&"width"!==g&&"height"!==g&&void 0===d){if("input"!==a.tag||"value"!==g||a.dom.value!==b||a.dom!==
A.activeElement)c[g]=b}else"boolean"===typeof b?b?c.setAttribute(g,""):c.removeAttribute(g):c.setAttribute("className"===g?"class":g,b)}}function K(a){return"oninit"===a||"oncreate"===a||"onupdate"===a||"onremove"===a||"onbeforeremove"===a||"onbeforeupdate"===a}function E(a,b,e){var c=a.dom,g=function(a){var b=e.call(c,a);"function"===typeof C&&C.call(c,a);return b};if(b in c)c[b]="function"===typeof e?g:null;else{var d=b.slice(2);void 0===a.events&&(a.events={});null!=a.events[b]&&c.removeEventListener(d,
a.events[b],!1);"function"===typeof e&&(a.events[b]=g,c.addEventListener(d,a.events[b],!1))}}function t(a,b,e){"function"===typeof a.oninit&&a.oninit.call(b.state,b);"function"===typeof a.oncreate&&e.push(a.oncreate.bind(b.state,b))}function L(a,b,e,d){d?t(a,b,e):"function"===typeof a.onupdate&&e.push(a.onupdate.bind(b.state,b))}function O(a,b){Object.keys(b).forEach(function(c){a[c]=b[c]})}var A=a.document,F=A.createDocumentFragment(),C;return{render:function(a,b){if(!a)throw Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");
var c=[],d=A.activeElement;null==a.vnodes&&(a.textContent="");b instanceof Array||(b=[b]);l(a,a.vnodes,m.normalizeChildren(b),c,null,void 0);a.vnodes=b;for(var f=0;f<c.length;f++)c[f]();A.activeElement!==d&&d.focus()},setEventCallback:function(a){return C=a}}}(window),P=function(a){var b=0,k=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(l){var h=Date.now();!0===l||0===b||16<=h-b?(b=h,a()):null===k&&(k=d(function(){k=null;a();b=Date.now()},16-(h-
b)))}},Q=function(a,b,k,d){d=P(d);null!=b&&b.setEventCallback(function(a){!1!==a.redraw&&k.publish()});null!=k&&(a.redraw&&k.unsubscribe(a.redraw),k.subscribe(d));return a.redraw=d};t.mount=function(a,b){return function(k,d){if(null===d)a.render(k,[]),b.unsubscribe(k.redraw),delete k.redraw;else{if(null==d.view)throw Error("m.mount(element, component) expects a component, not a vnode");Q(k,a,b,function(){a.render(k,m(d,void 0,void 0,void 0,void 0,void 0))})()}}}(M,I);var J=function(a){if(""===a||
null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");for(var b={},k={},d=0;d<a.length;d++){var l=a[d].split("="),h=decodeURIComponent(l[0]),l=2===l.length?decodeURIComponent(l[1]):"";"true"===l?l=!0:"false"===l&&(l=!1);var m=h.split(/\]\[?|\[/),q=b;-1<h.indexOf("[")&&m.pop();for(var r=0;r<m.length;r++){var h=m[r],t=m[r+1],t=""==t||!isNaN(parseInt(t,10)),n=r===m.length-1;""===h&&(h=m.slice(0,r).join(),null==k[h]&&(k[h]=0),h=k[h]++);null==q[h]&&(q[h]=n?l:t?[]:{});q=q[h]}}return b},R=function(a){function b(b){var d=
a.location[b].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===b&&"/"!==d[0]&&(d="/"+d);return d}function k(a){return function(){null==t&&(t=q(function(){t=null;a()}))}}function d(a,b,d){var f=a.indexOf("?"),h=a.indexOf("#"),l=-1<f?f:-1<h?h:a.length;if(-1<f){var f=J(a.slice(f+1,-1<h?h:a.length)),k;for(k in f)b[k]=f[k]}if(-1<h)for(k in b=J(a.slice(h+1)),b)d[k]=b[k];return a.slice(0,l)}function l(){switch(r.charAt(0)){case "#":return b("hash").slice(r.length);case "?":return b("search").slice(r.length)+
b("hash");default:return b("pathname").slice(r.length)+b("search")+b("hash")}}function h(b,h,f){var k={},l={};b=d(b,k,l);if(null!=h){for(var n in h)k[n]=h[n];b=b.replace(/:([^\/]+)/g,function(a,b){delete k[b];return h[b]})}(n=C(k))&&(b+="?"+n);(l=C(l))&&(b+="#"+l);m?(f&&f.replace?a.history.replaceState(null,null,r+b):a.history.pushState(null,null,r+b),a.onpopstate()):a.location.href=r+b}var m="function"===typeof a.history.pushState,q="function"===typeof setImmediate?setImmediate:setTimeout,r="#!",
t;return{setPrefix:function(a){r=a},getPath:l,setPath:h,defineRoutes:function(b,h,f){function n(){var a=l(),k={},m=d(a,k,k),n;for(n in b){var q=new RegExp("^"+n.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(q.test(m)){m.replace(q,function(){for(var d=n.match(/:[^\/]+/g)||[],f=[].slice.call(arguments,1,-2),l=0;l<d.length;l++)k[d[l].replace(/:|\./g,"")]=decodeURIComponent(f[l]);h(b[n],k,a,n)});return}}f(a,k)}m?a.onpopstate=k(n):"#"===r.charAt(0)&&(a.onhashchange=n);n();
return n},link:function(a){a.dom.setAttribute("href",r+a.attrs.href);a.dom.onclick=function(a){a.ctrlKey||a.metaKey||a.shiftKey||2===a.which||(a.preventDefault(),a.redraw=!1,a=this.getAttribute("href"),0===a.indexOf(r)&&(a=a.slice(r.length)),h(a,void 0,void 0))}}}};t.route=function(a,b){function k(a){return a}var d=R(a),l,h,t,q,r,x={view:function(){return[t(m(h,null,q,void 0,void 0,void 0))]}},n=function(a,f,m){h="div";t=k;q=null;b(a,x);d.defineRoutes(m,function(b,d,f){var m="function"!==typeof b.view,
n=k,p=l=function(k){p===l&&(l=null,h=null!=k?k:m?"div":b,t=n,q=d,r=f,a.redraw(!0))},u=function(){p()};m&&("function"===typeof b.render&&(n=b.render.bind(b)),"function"===typeof b.onmatch&&(u=b.onmatch));u.call(b,p,d,f)},function(){d.setPath(f,null,{replace:!0})})};n.link=d.link;n.prefix=d.setPrefix;n.set=d.setPath;n.get=function(){return r};return n}(window,t.mount);t.withAttr=function(a,b,k){return function(d){return b.call(k||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};
t.render=M.render;t.redraw=I.publish;t.request=H.request;t.jsonp=H.jsonp;t.parseQueryString=J;t.buildQueryString=C;t.version="1.0.0-rc.4";"undefined"!==typeof module?module.exports=t:window.m=t};
new function(){function w(a,c,h,d,g,m){return{tag:a,key:c,attrs:h,children:d,text:g,dom:m,domSize:void 0,state:{},events:void 0,instance:void 0,skip:!1}}function z(a){if(null==a||"string"!==typeof a&&null==a.view)throw Error("The selector must be either a string or a component.");if("string"===typeof a&&void 0===K[a]){for(var c,h,d=[],g={};c=P.exec(a);){var m=c[1],l=c[2];""===m&&""!==l?h=l:"#"===m?g.id=l:"."===m?d.push(l):"["===c[3][0]&&((m=c[6])&&(m=m.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),
"class"===c[4]?d.push(m):g[c[4]]=m||!0)}0<d.length&&(g.className=d.join(" "));K[a]=function(a,c){var m=!1,b,p,d=a.className||a["class"],t;for(t in g)a[t]=g[t];void 0!==d&&(void 0!==a["class"]&&(a["class"]=void 0,a.className=d),void 0!==g.className&&(a.className=g.className+" "+d));for(t in a)if("key"!==t){m=!0;break}c instanceof Array&&1==c.length&&null!=c[0]&&"#"===c[0].tag?p=c[0].children:b=c;return w(h||"div",a.key,m?a:void 0,b,p,void 0)}}var n;null!=arguments[1]&&("object"!==typeof arguments[1]||
void 0!==arguments[1].tag||arguments[1]instanceof Array)?d=1:(n=arguments[1],d=2);if(arguments.length===d+1)c=arguments[d]instanceof Array?arguments[d]:[arguments[d]];else for(c=[];d<arguments.length;d++)c.push(arguments[d]);return"string"===typeof a?K[a](n||{},w.normalizeChildren(c)):w(a,n&&n.key,n||{},w.normalizeChildren(c),void 0,void 0)}function Q(a){var c=0,h=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(){var g=Date.now();0===c||16<=g-c?(c=
g,a()):null===h&&(h=d(function(){h=null;a();c=Date.now()},16-(g-c)))}}w.normalize=function(a){return a instanceof Array?w("[",void 0,void 0,w.normalizeChildren(a),void 0,void 0):null!=a&&"object"!==typeof a?w("#",void 0,void 0,a,void 0,void 0):a};w.normalizeChildren=function(a){for(var c=0;c<a.length;c++)a[c]=w.normalize(a[c]);return a};var P=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,K={};z.trust=function(a){null==a&&(a="");return w("<",void 0,void 0,a,void 0,
void 0)};z.fragment=function(a,c){return w("[",a.key,a,w.normalizeChildren(c),void 0,void 0)};var v=function(a){function c(a,b){return function C(c){var l;try{if(!b||null==c||"object"!==typeof c&&"function"!==typeof c||"function"!==typeof(l=c.then))k(function(){b||0!==a.length||console.error("Possible unhandled promise rejection:",c);for(var d=0;d<a.length;d++)a[d](c);g.length=0;m.length=0;p.state=b;p.retry=function(){C(c)}});else{if(c===d)throw new TypeError("Promise can't be resolved w/ itself");
h(l.bind(c))}}catch(G){n(G)}}}function h(a){function b(b){return function(a){0<c++||b(a)}}var c=0,d=b(n);try{a(b(l),d)}catch(t){d(t)}}if(!(this instanceof v))throw Error("Promise must be called with `new`");if("function"!==typeof a)throw new TypeError("executor must be a function");var d=this,g=[],m=[],l=c(g,!0),n=c(m,!1),p=d._instance={resolvers:g,rejectors:m},k="function"===typeof setImmediate?setImmediate:setTimeout;h(a)};v.prototype.then=function(a,c){function h(a,c,h,l){c.push(function(b){if("function"!==
typeof a)h(b);else try{g(a(b))}catch(D){m&&m(D)}});"function"===typeof d.retry&&l===d.state&&d.retry()}var d=this._instance,g,m,l=new v(function(a,c){g=a;m=c});h(a,d.resolvers,g,!0);h(c,d.rejectors,m,!1);return l};v.prototype["catch"]=function(a){return this.then(null,a)};v.resolve=function(a){return a instanceof v?a:new v(function(c){c(a)})};v.reject=function(a){return new v(function(c,h){h(a)})};v.all=function(a){return new v(function(c,h){var d=a.length,g=0,m=[];if(0===a.length)c([]);else for(var l=
0;l<a.length;l++)(function(l){function p(a){g++;m[l]=a;g===d&&c(m)}null==a[l]||"object"!==typeof a[l]&&"function"!==typeof a[l]||"function"!==typeof a[l].then?p(a[l]):a[l].then(p,h)})(l)})};v.race=function(a){return new v(function(c,h){for(var d=0;d<a.length;d++)a[d].then(c,h)})};"undefined"===typeof E&&("undefined"!==typeof window?window.Promise=v:"undefined"!==typeof global&&(global.Promise=v));var H="undefined"!==typeof E?E:v,I=function(a){function c(a,d){if(d instanceof Array)for(var g=0;g<d.length;g++)c(a+
"["+g+"]",d[g]);else if("[object Object]"===Object.prototype.toString.call(d))for(g in d)c(a+"["+g+"]",d[g]);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)c(d,a[d]);return h.join("&")},M=function(a,c){function h(){function b(){0===--a&&"function"===typeof r&&r()}var a=0;return function t(c){var d=c.then;c.then=function(){a++;var g=d.apply(c,arguments);g.then(b,function(c){b();
if(0===a)throw c;});return t(g)};return c}}function d(b,a){if("string"===typeof b){var c=b;b=a||{};null==b.url&&(b.url=c)}return b}function g(b,a){if(null==a)return b;for(var c=b.match(/:[^\/]+/gi)||[],d=0;d<c.length;d++){var g=c[d].slice(1);null!=a[g]&&(b=b.replace(c[d],a[g]),delete a[g])}return b}function m(a,c){var b=I(c);if(""!==b){var d=0>a.indexOf("?")?"?":"&";a+=d+b}return a}function l(a){try{return""!==a?JSON.parse(a):null}catch(D){throw Error(a);}}function n(a){return a.responseText}function p(a,
c){if("function"===typeof a)if(c instanceof Array)for(var b=0;b<c.length;b++)c[b]=new a(c[b]);else return new a(c);return c}var k=0,r;return{request:function(b,k){var r=h();b=d(b,k);var t=new c(function(c,d){null==b.method&&(b.method="GET");b.method=b.method.toUpperCase();var h="boolean"===typeof b.useBody?b.useBody:"GET"!==b.method&&"TRACE"!==b.method;"function"!==typeof b.serialize&&(b.serialize="undefined"!==typeof FormData&&b.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==
typeof b.deserialize&&(b.deserialize=l);"function"!==typeof b.extract&&(b.extract=n);b.url=g(b.url,b.data);h?b.data=b.serialize(b.data):b.url=m(b.url,b.data);var k=new a.XMLHttpRequest;k.open(b.method,b.url,"boolean"===typeof b.async?b.async:!0,"string"===typeof b.user?b.user:void 0,"string"===typeof b.password?b.password:void 0);b.serialize===JSON.stringify&&h&&k.setRequestHeader("Content-Type","application/json; charset=utf-8");b.deserialize===l&&k.setRequestHeader("Accept","application/json, text/*");
b.withCredentials&&(k.withCredentials=b.withCredentials);"function"===typeof b.config&&(k=b.config(k,b)||k);k.onreadystatechange=function(){if(4===k.readyState)try{var a=b.extract!==n?b.extract(k,b):b.deserialize(b.extract(k,b));if(200<=k.status&&300>k.status||304===k.status)c(p(b.type,a));else{var g=Error(k.responseText),h;for(h in a)g[h]=a[h];d(g)}}catch(F){d(F)}};h&&null!=b.data?k.send(b.data):k.send()});return!0===b.background?t:r(t)},jsonp:function(b,l){var n=h();b=d(b,l);var t=new c(function(c,
d){var h=b.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+k++,l=a.document.createElement("script");a[h]=function(d){l.parentNode.removeChild(l);c(p(b.type,d));delete a[h]};l.onerror=function(){l.parentNode.removeChild(l);d(Error("JSONP request failed"));delete a[h]};null==b.data&&(b.data={});b.url=g(b.url,b.data);b.data[b.callbackKey||"callback"]=h;l.src=m(b.url,b.data);a.document.documentElement.appendChild(l)});return!0===b.background?t:n(t)},setCompletionCallback:function(a){r=a}}}(window,
H),O=function(a){function c(e,f,a,b,c,d,g){for(;a<b;a++){var q=f[a];null!=q&&p(e,h(q,c,g),d)}}function h(e,f,a){var q=e.tag;null!=e.attrs&&L(e.attrs,e,f);if("string"===typeof q)switch(q){case "#":return e.dom=B.createTextNode(e.children);case "<":return d(e);case "[":var b=B.createDocumentFragment();null!=e.children&&(q=e.children,c(b,q,0,q.length,f,null,a));e.dom=b.firstChild;e.domSize=b.childNodes.length;return b;default:var g=e.tag;switch(e.tag){case "svg":a="http://www.w3.org/2000/svg";break;
case "math":a="http://www.w3.org/1998/Math/MathML"}var p=(q=e.attrs)&&q.is,g=a?p?B.createElementNS(a,g,{is:p}):B.createElementNS(a,g):p?B.createElement(g,{is:p}):B.createElement(g);e.dom=g;if(null!=q)for(b in p=a,q)t(e,b,null,q[b],p);null!=e.attrs&&null!=e.attrs.contenteditable?k(e):(null!=e.text&&(""!==e.text?g.textContent=e.text:e.children=[w("#",void 0,void 0,e.text,void 0,void 0)]),null!=e.children&&(b=e.children,c(g,b,0,b.length,f,null,a),f=e.attrs,"select"===e.tag&&null!=f&&("value"in f&&t(e,
"value",null,f.value,void 0),"selectedIndex"in f&&t(e,"selectedIndex",null,f.selectedIndex,void 0))));return g}else{e.state||(e.state={});R(e.state,e.tag);b=e.tag.view;if(null!=b.reentrantLock)e=E;else if(b.reentrantLock=!0,L(e.tag,e,f),e.instance=w.normalize(b.call(e.state,e)),b.reentrantLock=null,null!=e.instance){if(e.instance===e)throw Error("A view cannot return the vnode it received as arguments");f=h(e.instance,f,a);e.dom=e.instance.dom;e.domSize=null!=e.dom?e.instance.domSize:0;e=f}else e.domSize=
0,e=E;return e}}function d(e){var f={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(e.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",f=B.createElement(f);f.innerHTML=e.children;e.dom=f.firstChild;e.domSize=f.childNodes.length;e=B.createDocumentFragment();for(var a;a=f.firstChild;)e.appendChild(a);return e}function g(e,f,a,b,d,g){if(f!==a&&(null!=f||null!=a))if(null==f)c(e,a,0,a.length,b,d,void 0);else if(null==a)r(f,0,f.length,
a);else{for(var q=!1,k=0;k<a.length;k++)if(null!=a[k]){q=null==a[k].key;break}if(f.length===a.length&&q)for(k=0;k<f.length;k++)f[k]!==a[k]&&(null==f[k]?p(e,h(a[k],b,g),n(f,k+1,d)):null==a[k]?r(f,k,k+1,a):m(e,f[k],a[k],b,n(f,k+1,d),!1,g));else{a:{if(null!=f.pool&&Math.abs(f.pool.length-a.length)<=Math.abs(f.length-a.length)&&(q=a[0]&&a[0].children&&a[0].children.length||0,Math.abs((f.pool[0]&&f.pool[0].children&&f.pool[0].children.length||0)-q)<=Math.abs((f[0]&&f[0].children&&f[0].children.length||
0)-q))){q=!0;break a}q=!1}q&&(f=f.concat(f.pool));for(var A=k=0,y=f.length-1,t=a.length-1,D;y>=k&&t>=A;){var x=f[k],u=a[A];if(x!==u||q)if(null==x)k++;else if(null==u)A++;else if(x.key===u.key)k++,A++,m(e,x,u,b,n(f,k,d),q,g),q&&x.tag===u.tag&&p(e,l(x),d);else if(x=f[y],x!==u||q)if(null==x)y--;else if(null==u)A++;else if(x.key===u.key)m(e,x,u,b,n(f,y+1,d),q,g),(q||A<t)&&p(e,l(x),n(f,k,d)),y--,A++;else break;else y--,A++;else k++,A++}for(;y>=k&&t>=A;){x=f[y];u=a[t];if(x!==u||q)if(null==x)y--;else{if(null!=
u)if(x.key===u.key)m(e,x,u,b,n(f,y+1,d),q,g),q&&x.tag===u.tag&&p(e,l(x),d),null!=x.dom&&(d=x.dom),y--;else{if(!D){D=f;var x=y,C={},w;for(w=0;w<x;w++){var v=D[w];null!=v&&(v=v.key,null!=v&&(C[v]=w))}D=C}null!=u&&(x=D[u.key],null!=x?(C=f[x],m(e,C,u,b,n(f,y+1,d),q,g),p(e,l(C),d),f[x].skip=!0,null!=C.dom&&(d=C.dom)):(u=h(u,b,void 0),p(e,u,d),d=u))}t--}else y--,t--;if(t<A)break}c(e,a,A,t+1,b,d,g);r(f,k,y+1,a)}}}function m(a,f,b,c,u,y,n){var e=f.tag;if(e===b.tag){b.state=f.state;b.events=f.events;var q;
var A;null!=b.attrs&&"function"===typeof b.attrs.onbeforeupdate&&(q=b.attrs.onbeforeupdate.call(b.state,b,f));"string"!==typeof b.tag&&"function"===typeof b.tag.onbeforeupdate&&(A=b.tag.onbeforeupdate.call(b.state,b,f));void 0===q&&void 0===A||q||A?q=!1:(b.dom=f.dom,b.domSize=f.domSize,b.instance=f.instance,q=!0);if(!q)if(null!=b.attrs&&z(b.attrs,b,c,y),"string"===typeof e)switch(e){case "#":f.children.toString()!==b.children.toString()&&(f.dom.nodeValue=b.children);b.dom=f.dom;break;case "<":f.children!==
b.children?(l(f),p(a,d(b),u)):(b.dom=f.dom,b.domSize=f.domSize);break;case "[":g(a,f.children,b.children,c,u,n);f=0;c=b.children;b.dom=null;if(null!=c){for(var r=0;r<c.length;r++)a=c[r],null!=a&&null!=a.dom&&(null==b.dom&&(b.dom=a.dom),f+=a.domSize||1);1!==f&&(b.domSize=f)}break;default:a=n;u=b.dom=f.dom;switch(b.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===b.tag&&(null==b.attrs&&(b.attrs={}),null!=b.text&&(b.attrs.value=b.text,
b.text=void 0));y=f.attrs;n=b.attrs;e=a;if(null!=n)for(r in n)t(b,r,y&&y[r],n[r],e);if(null!=y)for(r in y)null!=n&&r in n||("className"===r&&(r="class"),"o"!==r[0]||"n"!==r[1]||v(r)?"key"!==r&&b.dom.removeAttribute(r):G(b,r,void 0));null!=b.attrs&&null!=b.attrs.contenteditable?k(b):null!=f.text&&null!=b.text&&""!==b.text?f.text.toString()!==b.text.toString()&&(f.dom.firstChild.nodeValue=b.text):(null!=f.text&&(f.children=[w("#",void 0,void 0,f.text,void 0,f.dom.firstChild)]),null!=b.text&&(b.children=
[w("#",void 0,void 0,b.text,void 0,void 0)]),g(u,f.children,b.children,c,null,a))}else b.instance=w.normalize(b.tag.view.call(b.state,b)),z(b.tag,b,c,y),null!=b.instance?(null==f.instance?p(a,h(b.instance,c,n),u):m(a,f.instance,b.instance,c,u,y,n),b.dom=b.instance.dom,b.domSize=b.instance.domSize):null!=f.instance?(D(f.instance,null),b.dom=void 0,b.domSize=0):(b.dom=f.dom,b.domSize=f.domSize)}else D(f,null),p(a,h(b,c,n),u)}function l(b){var a=b.domSize;if(null!=a||null==b.dom){var e=B.createDocumentFragment();
if(0<a){for(b=b.dom;--a;)e.appendChild(b.nextSibling);e.insertBefore(b,e.firstChild)}return e}return b.dom}function n(b,a,c){for(;a<b.length;a++)if(null!=b[a]&&null!=b[a].dom)return b[a].dom;return c}function p(b,a,c){c&&c.parentNode?b.insertBefore(a,c):b.appendChild(a)}function k(b){var a=b.children;if(null!=a&&1===a.length&&"<"===a[0].tag)a=a[0].children,b.dom.innerHTML!==a&&(b.dom.innerHTML=a);else if(null!=b.text||null!=a&&0!==a.length)throw Error("Child node of a contenteditable must be trusted");
}function r(b,a,c,d){for(;a<c;a++){var e=b[a];null!=e&&(e.skip?e.skip=!1:D(e,d))}}function b(b){var a=!1;return function(){a||(a=!0,b())}}function D(a,f){function e(){if(++d===c&&(C(a),a.dom)){var b=a.domSize||1;if(1<b)for(var e=a.dom;--b;){var g=e.nextSibling,k=g.parentNode;null!=k&&k.removeChild(g)}b=a.dom;e=b.parentNode;null!=e&&e.removeChild(b);if(b=null!=f&&null==a.domSize)b=a.attrs,b=!(null!=b&&(b.oncreate||b.onupdate||b.onbeforeremove||b.onremove));b&&"string"===typeof a.tag&&(f.pool?f.pool.push(a):
f.pool=[a])}}var c=1,d=0;a.attrs&&a.attrs.onbeforeremove&&(c++,a.attrs.onbeforeremove.call(a.state,a,b(e)));"string"!==typeof a.tag&&a.tag.onbeforeremove&&(c++,a.tag.onbeforeremove.call(a.state,a,b(e)));e()}function C(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)C(b.instance);else if(b=b.children,b instanceof Array)for(var a=0;a<b.length;a++){var e=b[a];null!=e&&C(e)}}function t(b,a,c,d,g){var e=
b.dom;if("key"!==a&&(c!==d||"value"===a||"checked"===a||"selectedIndex"===a||"selected"===a&&b.dom===B.activeElement||"object"===typeof d)&&"undefined"!==typeof d&&!v(a)){var f=a.indexOf(":");if(-1<f&&"xlink"===a.substr(0,f))e.setAttributeNS("http://www.w3.org/1999/xlink",a.slice(f+1),d);else if("o"===a[0]&&"n"===a[1]&&"function"===typeof d)G(b,a,d);else if("style"===a)if(b=c,b===d&&(e.style.cssText="",b=null),null==d)e.style.cssText="";else if("string"===typeof d)e.style.cssText=d;else{"string"===
typeof b&&(e.style.cssText="");for(var k in d)e.style[k]=d[k];if(null!=b&&"string"!==typeof b)for(k in b)k in d||(e.style[k]="")}else a in e&&"href"!==a&&"list"!==a&&"form"!==a&&"width"!==a&&"height"!==a&&void 0===g?"input"===b.tag&&"value"===a&&b.dom.value===d&&b.dom===B.activeElement||"select"===b.tag&&"value"===a&&b.dom.value===d&&b.dom===B.activeElement||"option"===b.tag&&"value"===a&&b.dom.value===d||(e[a]=d):"boolean"===typeof d?d?e.setAttribute(a,""):e.removeAttribute(a):e.setAttribute("className"===
a?"class":a,d)}}function v(b){return"oninit"===b||"oncreate"===b||"onupdate"===b||"onremove"===b||"onbeforeremove"===b||"onbeforeupdate"===b}function G(b,a,c){var d=b.dom,e="function"!==typeof F?c:function(b){var a=c.call(d,b);F.call(d,b);return a};if(a in d)d[a]="function"===typeof c?e:null;else{var f=a.slice(2);void 0===b.events&&(b.events={});b.events[a]!==e&&(null!=b.events[a]&&d.removeEventListener(f,b.events[a],!1),"function"===typeof c&&(b.events[a]=e,d.addEventListener(f,b.events[a],!1)))}}
function L(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 z(b,a,c,d){d?L(b,a,c):"function"===typeof b.onupdate&&c.push(b.onupdate.bind(a.state,a))}function R(b,a){Object.keys(a).forEach(function(c){b[c]=a[c]})}var B=a.document,E=B.createDocumentFragment(),F;return{render:function(b,a){if(!b)throw Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var c=[],d=B.activeElement;
null==b.vnodes&&(b.textContent="");a instanceof Array||(a=[a]);g(b,b.vnodes,w.normalizeChildren(a),c,null,void 0);b.vnodes=a;for(var e=0;e<c.length;e++)c[e]();B.activeElement!==d&&d.focus()},setEventCallback:function(b){return F=b}}},J=function(a){function c(a){a=d.indexOf(a);-1<a&&d.splice(a,2)}function h(){for(var a=1;a<d.length;a+=2)d[a]()}a=O(a);a.setEventCallback(function(a){!1!==a.redraw&&h()});var d=[];return{subscribe:function(a,h){c(a);d.push(a,Q(h))},unsubscribe:c,redraw:h,render:a.render}}(window);
M.setCompletionCallback(J.redraw);z.mount=function(a){return function(c,h){if(null===h)a.render(c,[]),a.unsubscribe(c);else{if(null==h.view)throw Error("m.mount(element, component) expects a component, not a vnode");a.subscribe(c,function(){a.render(c,w(h))});a.redraw()}}}(J);var E=H,N=function(a){if(""===a||null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");for(var c={},h={},d=0;d<a.length;d++){var g=a[d].split("="),m=decodeURIComponent(g[0]),g=2===g.length?decodeURIComponent(g[1]):
"";"true"===g?g=!0:"false"===g&&(g=!1);var l=m.split(/\]\[?|\[/),n=c;-1<m.indexOf("[")&&l.pop();for(var p=0;p<l.length;p++){var m=l[p],k=l[p+1],k=""==k||!isNaN(parseInt(k,10)),r=p===l.length-1;""===m&&(m=l.slice(0,p).join(),null==h[m]&&(h[m]=0),m=h[m]++);null==n[m]&&(n[m]=r?g:k?[]:{});n=n[m]}}return c},S=function(a){function c(c){var d=a.location[c].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===c&&"/"!==d[0]&&(d="/"+d);return d}function h(a){return function(){null==l&&(l=m(function(){l=
null;a()}))}}function d(a,c,d){var b=a.indexOf("?"),g=a.indexOf("#"),k=-1<b?b:-1<g?g:a.length;if(-1<b){var b=N(a.slice(b+1,-1<g?g:a.length)),h;for(h in b)c[h]=b[h]}if(-1<g)for(h in c=N(a.slice(g+1)),c)d[h]=c[h];return a.slice(0,k)}var g="function"===typeof a.history.pushState,m="function"===typeof setImmediate?setImmediate:setTimeout,l,n={prefix:"#!",getPath:function(){switch(n.prefix.charAt(0)){case "#":return c("hash").slice(n.prefix.length);case "?":return c("search").slice(n.prefix.length)+c("hash");
default:return c("pathname").slice(n.prefix.length)+c("search")+c("hash")}},setPath:function(c,k,h){var b={},l={};c=d(c,b,l);if(null!=k){for(var m in k)b[m]=k[m];c=c.replace(/:([^\/]+)/g,function(a,c){delete b[c];return k[c]})}(m=I(b))&&(c+="?"+m);(l=I(l))&&(c+="#"+l);g?(h&&h.replace?a.history.replaceState(null,null,n.prefix+c):a.history.pushState(null,null,n.prefix+c),a.onpopstate()):a.location.href=n.prefix+c},defineRoutes:function(c,k,l){function b(){var a=n.getPath(),b={},g=d(a,b,b),h;for(h in c){var m=
new RegExp("^"+h.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(m.test(g)){g.replace(m,function(){for(var d=h.match(/:[^\/]+/g)||[],g=[].slice.call(arguments,1,-2),l=0;l<d.length;l++)b[d[l].replace(/:|\./g,"")]=decodeURIComponent(g[l]);k(c[h],b,a,h)});return}}l(a,b)}g?a.onpopstate=h(b):"#"===n.prefix.charAt(0)&&(a.onhashchange=b);b()}};return n};z.route=function(a,c){var h=S(a),d=function(a){return a},g,m,l,n,p=!1,k=function(a,b,k){if(null==a)throw Error("Ensure the DOM element that was passed to `m.route` is not undefined");
var r=function(a,b,c,h){m=null!=b&&"function"===typeof b.view?b:"div";l=c;n=h;p=!1;g=(a.render||d).bind(a);t()},t=function(){null!=g&&c.render(a,g(w(m,l.key,l)))},v=function(){h.setPath(b)};h.defineRoutes(k,function(a,b,c){a.view?r({},a,b,c):a.onmatch?(p=!0,E.resolve(a.onmatch(b,c)).then(function(d){p&&r(a,d,b,c)},v)):r(a,"div",b,c)},v);c.subscribe(a,t)};k.set=function(a,b,c){p&&(c={replace:!0});p=!1;h.setPath(a,b,c)};k.get=function(){return n};k.prefix=function(a){h.prefix=a};k.link=function(a){a.dom.setAttribute("href",
h.prefix+a.attrs.href);a.dom.onclick=function(a){a.ctrlKey||a.metaKey||a.shiftKey||2===a.which||(a.preventDefault(),a.redraw=!1,a=this.getAttribute("href"),0===a.indexOf(h.prefix)&&(a=a.slice(h.prefix.length)),k.set(a,void 0,void 0))}};return k}(window,J);z.withAttr=function(a,c,h){return function(d){return c.call(h||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};H=O(window);z.render=H.render;z.redraw=J.redraw;z.request=M.request;z.jsonp=M.jsonp;z.parseQueryString=
N;z.buildQueryString=I;z.version="1.0.0-rc.6";"undefined"!==typeof module?module.exports=z:window.m=z};

@@ -1,4 +0,3 @@

var renderService = require("./render")
var redrawService = require("./redraw")
module.exports = require("./api/mount")(renderService, redrawService)
module.exports = require("./api/mount")(redrawService)

@@ -205,3 +205,6 @@ "use strict"

}
console.log(results.length + " assertions completed in " + Math.round(new Date - start) + "ms")
console.log(
results.length + " assertions completed in " + Math.round(new Date - start) + "ms, " +
"of which " + results.filter(function(result){return result.error}).length + " failed"
)
if (hasProcess && status === 1) process.exit(1)

@@ -208,0 +211,0 @@ }

{
"name": "ospec",
"version": "1.2.0",
"version": "1.2.1",
"description": "Noiseless testing framework",

@@ -5,0 +5,0 @@ "main": "ospec.js",

@@ -7,3 +7,3 @@ # ospec

Version: 1.2
Version: 1.2.1
License: MIT

@@ -10,0 +10,0 @@

{
"name": "mithril",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"description": "A framework for building brilliant applications",

@@ -15,2 +15,3 @@ "author": "Leo Horie",

"lintdocs": "node docs/lint",
"gendocs": "node docs/generate",
"lint": "eslint .",

@@ -22,3 +23,4 @@ "test": "node ospec/bin/ospec",

"eslint": "^2.10.2",
"istanbul": "^0.4.3"
"istanbul": "^0.4.3",
"marked": "^0.3.6"
},

@@ -25,0 +27,0 @@ "publishConfig": {

@@ -406,2 +406,23 @@ "use strict"

})
o("triggers all branched rejection handlers upon rejection", function(done) {
var promise = Promise.reject()
var then = o.spy()
var catch1 = o.spy()
var catch2 = o.spy()
var catch3 = o.spy()
promise.catch(catch1)
promise.then(then, catch2)
promise.then(then).catch(catch3)
callAsync(function() {
callAsync(function() {
o(catch1.callCount).equals(1)
o(then.callCount).equals(0)
o(catch2.callCount).equals(1)
o(catch3.callCount).equals(1)
done()
})
})
})
o("does not absorb resolved promise via static rejector", function(done) {

@@ -408,0 +429,0 @@ var promise = Promise.reject(Promise.resolve(1))

# Mithril.js - A framework for building brilliant applications
[Installation](docs/installation.md) | [API](docs/api.md) | [Examples](docs/examples.md) | [Migration Guide](docs/v1.x-migration.md)
[Installation](docs/installation.md) | [API](docs/api.md) | [Examples](docs/examples.md) | [Changelog/Migration Guide](docs/change-log.md)
Note: This branch is the upcoming version 1.0. It's a rewrite from the ground up and it's not backwards compatible with [Mithril 0.2.x](http://mithril.js.org). You can find preliminary [documentation here](docs) and [migration guide here](docs/v1.x-migration.md)
Note: This branch is the upcoming version 1.0. It's a rewrite from the ground up and it's not backwards compatible with [Mithril 0.2.x](http://mithril.js.org). You can find preliminary [documentation here](docs) and [migration guide here](docs/change-log.md)

@@ -37,4 +37,4 @@ This rewrite aims to fix longstanding API design issues, significantly improve performance, and clean up the codebase.

Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at <!-- size -->7.37 KB<!-- /size --> min+gzip
Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at <!-- size -->7.47 KB<!-- /size --> min+gzip
In addition, Mithril is now completely modular: you can import only the modules that you need and easily integrate 3rd party modules if you wish to use a different library for routing, ajax, and even rendering

@@ -1,1 +0,1 @@

module.exports = require("./api/pubsub")()
module.exports = require("./api/redraw")(window)

@@ -22,3 +22,4 @@ "use strict"

if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
attributes[match[4]] = attrValue || true
if (match[4] === "class") classes.push(attrValue)
else attributes[match[4]] = attrValue || true
}

@@ -25,0 +26,0 @@ }

@@ -127,15 +127,21 @@ "use strict"

else {
var recycling = isRecyclable(old, vnodes)
if (recycling) old = old.concat(old.pool)
if (old.length === vnodes.length && vnodes[0] != null && vnodes[0].key == null) {
var isUnkeyed = false
for (var i = 0; i < vnodes.length; i++) {
if (vnodes[i] != null) {
isUnkeyed = vnodes[i].key == null
break
}
}
if (old.length === vnodes.length && isUnkeyed) {
for (var i = 0; i < old.length; i++) {
if (old[i] === vnodes[i] || old[i] == null && vnodes[i] == null) continue
if (old[i] === vnodes[i]) continue
else if (old[i] == null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling))
else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)
if (recycling && old[i].tag === vnodes[i].tag) insertNode(parent, toFragment(old[i]), getNextSibling(old, i + 1, nextSibling))
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns)
}
}
else {
var recycling = isRecyclable(old, vnodes)
if (recycling) old = old.concat(old.pool)
var oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map

@@ -145,3 +151,5 @@ while (oldEnd >= oldStart && end >= start) {

if (o === v && !recycling) oldStart++, start++
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldStart++
else if (v == null) start++
else if (o.key === v.key) {
oldStart++, start++

@@ -154,3 +162,5 @@ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns)

if (o === v && !recycling) oldEnd--, start++
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldEnd--
else if (v == null) start++
else if (o.key === v.key) {
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)

@@ -166,3 +176,5 @@ if (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))

if (o === v && !recycling) oldEnd--, end--
else if (o != null && v != null && o.key === v.key) {
else if (o == null) oldEnd--
else if (v == null) end--
else if (o.key === v.key) {
updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)

@@ -349,3 +361,3 @@ if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)

}
else if (children != null || vnode.text != null) throw new Error("Child node of a contenteditable must be trusted")
else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
}

@@ -440,2 +452,6 @@

if (vnode.tag === "input" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && key === "value" && vnode.dom.value === value) return
element[key] = value

@@ -508,5 +524,5 @@ }

var element = vnode.dom
var callback = function(e) {
var callback = typeof onevent !== "function" ? value : function(e) {
var result = value.call(element, e)
if (typeof onevent === "function") onevent.call(element, e)
onevent.call(element, e)
return result

@@ -518,2 +534,3 @@ }

if (vnode.events === undefined) vnode.events = {}
if (vnode.events[key] === callback) return
if (vnode.events[key] != null) element.removeEventListener(eventName, vnode.events[key], false)

@@ -520,0 +537,0 @@ if (typeof value === "function") {

@@ -82,5 +82,5 @@ "use strict"

var canvas = {tag: "canvas", attrs: {width: "100%"}}
render(root, canvas)
o(canvas.dom.attributes["width"].nodeValue).equals("100%")

@@ -99,2 +99,56 @@ o(canvas.dom.width).equals(100)

})
o.spec("contenteditable throws on untrusted children", function() {
o("including text nodes", function() {
var div = {tag: "div", attrs: {contenteditable: true}, text: ''}
var succeeded = false
try {
render(root, div)
succeeded = true
}
catch(e){}
o(succeeded).equals(false)
})
o("including elements", function() {
var div = {tag: "div", attrs: {contenteditable: true}, children: [{tag: "script", attrs: {src: "http://evil.com"}}]}
var succeeded = false
try {
render(root, div)
succeeded = true
}
catch(e){}
o(succeeded).equals(false)
})
o("tolerating empty children", function() {
var div = {tag: "div", attrs: {contenteditable: true}, children: []}
var succeeded = false
try {
render(root, div)
succeeded = true
}
catch(e){}
o(succeeded).equals(true)
})
o("tolerating trusted content", function() {
var div = {tag: "div", attrs: {contenteditable: true}, children: [{tag: "<", children: "<a></a>"}]}
var succeeded = false
try {
render(root, div)
succeeded = true
}
catch(e){}
o(succeeded).equals(true)
})
})
})

@@ -187,2 +187,7 @@ var o = require("../../ospec/ospec")

})
o("handles 'class' as a verbose attribute declaration", function() {
var vnode = m("[class=a]")
o(vnode.attrs.className).equals("a")
})
o("handles merging classes w/ class property", function() {

@@ -189,0 +194,0 @@ var vnode = m(".a", {class: "b"})

@@ -718,2 +718,18 @@ "use strict"

})
o("change type, position and length", function() {
var vnodes = {tag: "div", children: [
undefined,
{tag: "#", children: "a"}
]}
var updated = {tag: "div", children: [
{tag: "[", children: [{tag: "#", children: "b"}]},
undefined,
undefined
]}
render(root, vnodes)
render(root, updated)
o(root.firstChild.childNodes.length).equals(1)
})
o("removes then recreates then reverses children", function() {

@@ -867,2 +883,40 @@ var vnodes = [{tag: "a", key: 1, children: [{tag: "i", key: 3}, {tag: "s", key: 4}]}, {tag: "b", key: 2}]

})
o("null stays in place", function() {
var create = o.spy()
var update = o.spy()
var remove = o.spy()
var vnodes = [{tag: "div"}, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
var temp = [null, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
var updated = [{tag: "div"}, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
render(root, vnodes)
var before = vnodes[1].dom
render(root, temp)
render(root, updated)
var after = updated[1].dom
o(before).equals(after)
o(create.callCount).equals(1)
o(update.callCount).equals(2)
o(remove.callCount).equals(0)
})
o("null stays in place if not first", function() {
var create = o.spy()
var update = o.spy()
var remove = o.spy()
var vnodes = [{tag: "b"}, {tag: "div"}, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
var temp = [{tag: "b"}, null, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
var updated = [{tag: "b"}, {tag: "div"}, {tag: "a", attrs: {oncreate: create, onupdate: update, onremove: remove}}]
render(root, vnodes)
var before = vnodes[2].dom
render(root, temp)
render(root, updated)
var after = updated[2].dom
o(before).equals(after)
o(create.callCount).equals(1)
o(update.callCount).equals(2)
o(remove.callCount).equals(0)
})
})

@@ -8,29 +8,36 @@ "use strict"

var count = 0
var oncompletion
function setCompletionCallback(callback) {oncompletion = callback}
function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()}
function finalizer() {
var count = 0
function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()}
function finalize(promise) {
var then = promise.then
promise.then = function() {
count++
var next = then.apply(promise, arguments)
next.then(complete, function(e) {
complete()
throw e
})
return finalize(next)
return function finalize(promise) {
var then = promise.then
promise.then = function() {
count++
var next = then.apply(promise, arguments)
next.then(complete, function(e) {
complete()
if (count === 0) throw e
})
return finalize(next)
}
return promise
}
return promise
}
function normalize(args, extra) {
if (typeof args === "string") {
var url = args
args = extra || {}
if (args.url == null) args.url = url
}
return args
}
function request(args, extra) {
return finalize(new Promise(function(resolve, reject) {
if (typeof args === "string") {
var url = args
args = extra || {}
if (args.url == null) args.url = url
}
var finalize = finalizer()
args = normalize(args, extra)
var promise = new Promise(function(resolve, reject) {
if (args.method == null) args.method = "GET"

@@ -58,2 +65,3 @@ args.method = args.method.toUpperCase()

}
if (args.withCredentials) xhr.withCredentials = args.withCredentials

@@ -83,7 +91,11 @@ if (typeof args.config === "function") xhr = args.config(xhr, args) || xhr

else xhr.send()
}))
})
return args.background === true ? promise : finalize(promise)
}
function jsonp(args) {
return finalize(new Promise(function(resolve, reject) {
function jsonp(args, extra) {
var finalize = finalizer()
args = normalize(args, extra)
var promise = new Promise(function(resolve, reject) {
var callbackName = args.callbackName || "_mithril_" + Math.round(Math.random() * 1e16) + "_" + callbackCount++

@@ -106,3 +118,4 @@ var script = $window.document.createElement("script")

$window.document.documentElement.appendChild(script)
}))
})
return args.background === true? promise : finalize(promise)
}

@@ -109,0 +122,0 @@

@@ -10,6 +10,9 @@ "use strict"

o.spec("jsonp", function() {
var mock, jsonp, spy
var mock, jsonp, spy, complete
o.beforeEach(function() {
mock = xhrMock()
jsonp = new Request(mock, Promise).jsonp
var requestService = Request(mock, Promise)
jsonp = requestService.jsonp
complete = o.spy()
requestService.setCompletionCallback(complete)
})

@@ -28,2 +31,16 @@

})
o("first argument can be a string aliasing url property", function(done){
var s = new Date
mock.$defineRoutes({
"GET /item": function(request) {
var queryData = parseQueryString(request.query)
return {status: 200, responseText: queryData["callback"] + "(" + JSON.stringify({a: 1}) + ")"}
}
})
jsonp("/item").then(function(data) {
o(data).deepEquals({a: 1})
}).then(function() {
done()
})
})
o("works w/ other querystring params", function(done) {

@@ -52,2 +69,60 @@ mock.$defineRoutes({

})
o("works w/ custom callbackKey", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
var queryData = parseQueryString(request.query)
return {status: 200, responseText: queryData["cb"] + "(" + JSON.stringify({a: 2}) + ")"}
}
})
jsonp({url: "/item", callbackKey: "cb"}).then(function(data) {
o(data).deepEquals({a: 2})
}).then(done)
})
o("requests don't block each other", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
var queryData = parseQueryString(request.query)
return {status: 200, responseText: queryData["callback"] + "([])"}
}
})
jsonp("/item").then(function() {
return jsonp("/item")
})
jsonp("/item").then(function() {
return jsonp("/item")
})
setTimeout(function() {
o(complete.callCount).equals(4)
done()
}, 20)
})
o("requests trigger finally once with a chained then", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
var queryData = parseQueryString(request.query)
return {status: 200, responseText: queryData["callback"] + "([])"}
}
})
var promise = jsonp("/item")
promise.then(function() {}).then(function() {})
promise.then(function() {}).then(function() {})
setTimeout(function() {
o(complete.callCount).equals(1)
done()
}, 20)
})
o("requests does not trigger finally when background: true", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
var queryData = parseQueryString(request.query)
return {status: 200, responseText: queryData["callback"] + "([])"}
}
})
var promise = jsonp("/item", {background: true}).then(function() {})
setTimeout(function() {
o(complete.callCount).equals(0)
done()
}, 20)
})
o("handles error", function(done) {

@@ -54,0 +129,0 @@ jsonp({url: "/item", callbackKey: "cb"}).catch(function(e) {

"use strict"
var o = require("../../ospec/ospec")
var callAsync = require("../../test-utils/callAsync")
var xhrMock = require("../../test-utils/xhrMock")

@@ -9,6 +10,9 @@ var Request = require("../../request/request")

o.spec("xhr", function() {
var mock, xhr
var mock, xhr, complete
o.beforeEach(function() {
mock = xhrMock()
xhr = new Request(mock, Promise).request
var requestService = Request(mock, Promise)
xhr = requestService.request
complete = o.spy()
requestService.setCompletionCallback(complete)
})

@@ -299,2 +303,46 @@

})
o("requests don't block each other", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
return {status: 200, responseText: "[]"}
}
})
xhr("/item").then(function() {
return xhr("/item")
})
xhr("/item").then(function() {
return xhr("/item")
})
setTimeout(function() {
o(complete.callCount).equals(4)
done()
}, 20)
})
o("requests trigger finally once with a chained then", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
return {status: 200, responseText: "[]"}
}
})
var promise = xhr("/item")
promise.then(function() {}).then(function() {})
promise.then(function() {}).then(function() {})
setTimeout(function() {
o(complete.callCount).equals(1)
done()
}, 20)
})
o("requests does not trigger finally when background: true", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
return {status: 200, responseText: "[]"}
}
})
var promise = xhr("/item", {background: true}).then(function() {})
setTimeout(function() {
o(complete.callCount).equals(0)
done()
}, 20)
})
})

@@ -335,3 +383,29 @@ o.spec("failure", function() {

})
o("triggers all branched catches upon rejection", function(done) {
mock.$defineRoutes({
"GET /item": function(request) {
return {status: 500, responseText: "error"}
}
})
var request = xhr({method: "GET", url: "/item"})
var then = o.spy()
var catch1 = o.spy()
var catch2 = o.spy()
var catch3 = o.spy()
request.catch(catch1)
request.then(then, catch2)
request.then(then).catch(catch3)
callAsync(function() {
callAsync(function() {
o(catch1.callCount).equals(1)
o(then.callCount).equals(0)
o(catch2.callCount).equals(1)
o(catch3.callCount).equals(1)
done()
})
})
})
})
})

@@ -1,3 +0,3 @@

var mount = require("./mount")
var redrawService = require("./redraw")
module.exports = require("./api/router")(window, mount)
module.exports = require("./api/router")(window, redrawService)

@@ -10,5 +10,2 @@ "use strict"

var prefix = "#!"
function setPrefix(value) {prefix = value}
function normalize(fragment) {

@@ -21,3 +18,3 @@ var data = $window.location[fragment].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)

var asyncId
function debounceAsync(f) {
function debounceAsync(callback) {
return function() {

@@ -27,5 +24,4 @@ if (asyncId != null) return

asyncId = null
f()
callback()
})
}

@@ -50,12 +46,12 @@ }

function getPath() {
var type = prefix.charAt(0)
var router = {prefix: "#!"}
router.getPath = function() {
var type = router.prefix.charAt(0)
switch (type) {
case "#": return normalize("hash").slice(prefix.length)
case "?": return normalize("search").slice(prefix.length) + normalize("hash")
default: return normalize("pathname").slice(prefix.length) + normalize("search") + normalize("hash")
case "#": return normalize("hash").slice(router.prefix.length)
case "?": return normalize("search").slice(router.prefix.length) + normalize("hash")
default: return normalize("pathname").slice(router.prefix.length) + normalize("search") + normalize("hash")
}
}
function setPath(path, data, options) {
router.setPath = function(path, data, options) {
var queryData = {}, hashData = {}

@@ -78,16 +74,11 @@ path = parsePath(path, queryData, hashData)

if (supportsPushState) {
if (options && options.replace) $window.history.replaceState(null, null, prefix + path)
else $window.history.pushState(null, null, prefix + path)
if (options && options.replace) $window.history.replaceState(null, null, router.prefix + path)
else $window.history.pushState(null, null, router.prefix + path)
$window.onpopstate()
}
else $window.location.href = prefix + path
else $window.location.href = router.prefix + path
}
function defineRoutes(routes, resolve, reject) {
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
else if (prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
resolveRoute()
router.defineRoutes = function(routes, resolve, reject) {
function resolveRoute() {
var path = getPath()
var path = router.getPath()
var params = {}

@@ -114,18 +105,9 @@ var pathname = parsePath(path, params, params)

}
return resolveRoute
if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
else if (router.prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
resolveRoute()
}
function link(vnode) {
vnode.dom.setAttribute("href", prefix + vnode.attrs.href)
vnode.dom.onclick = function(e) {
if (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return
e.preventDefault()
e.redraw = false
var href = this.getAttribute("href")
if (href.indexOf(prefix) === 0) href = href.slice(prefix.length)
setPath(href, undefined, undefined)
}
}
return {setPrefix: setPrefix, getPath: getPath, setPath: setPath, defineRoutes: defineRoutes, link: link}
return router
}

@@ -17,3 +17,3 @@ "use strict"

router = new Router($window)
router.setPrefix(prefix)
router.prefix = prefix
onRouteChange = o.spy()

@@ -77,3 +77,3 @@ onFail = o.spy()

router = new Router($window)
router.setPrefix(prefix)
router.prefix = prefix

@@ -289,12 +289,2 @@ router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)

})
o("replays", function() {
$window.location.href = prefix + "/test"
var replay = router.defineRoutes({"/test": {data: 1}}, onRouteChange, onFail)
replay()
o(onRouteChange.callCount).equals(2)
o(onRouteChange.args).deepEquals([{data: 1}, {}, "/test", "/test"])
o(onFail.callCount).equals(0)
})
})

@@ -301,0 +291,0 @@ })

@@ -16,3 +16,3 @@ "use strict"

router = new Router($window)
router.setPrefix(prefix)
router.prefix = prefix
onRouteChange = o.spy()

@@ -19,0 +19,0 @@ onFail = o.spy()

@@ -17,3 +17,3 @@ "use strict"

router = new Router($window)
router.setPrefix(prefix)
router.prefix = prefix
onRouteChange = o.spy()

@@ -92,3 +92,3 @@ onFail = o.spy()

router = new Router($window)
router.setPrefix(prefix)
router.prefix = prefix

@@ -95,0 +95,0 @@ router.defineRoutes({"/test": {data: 1}, "/other/:a/:b...": {data: 2}}, onRouteChange, onFail)

@@ -47,3 +47,3 @@ "use strict"

var state = stream._state, parents = state.parents
if (parents.length > 0 && parents.filter(active).length === parents.length && (mustSync || parents.filter(changed).length > 0)) {
if (parents.length > 0 && parents.every(active) && (mustSync || parents.some(changed))) {
var value = stream._state.derive()

@@ -60,3 +60,3 @@ if (value === HALT) return false

function combine(fn, streams) {
if (streams.length > streams.filter(valid).length) throw new Error("Ensure that each item passed to m.prop.combine/m.prop.merge is a stream")
if (!streams.every(valid)) throw new Error("Ensure that each item passed to m.prop.combine/m.prop.merge is a stream")
return initDependency(createStream(), streams, function() {

@@ -63,0 +63,0 @@ return fn.apply(this, streams.concat([streams.filter(changed)]))

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc