Skip to content

Instantly share code, notes, and snippets.

@dead-claudia
Last active January 17, 2018 23:25
Show Gist options
  • Save dead-claudia/29d044e1d112a0bf70706a6cdd8149d4 to your computer and use it in GitHub Desktop.
Save dead-claudia/29d044e1d112a0bf70706a6cdd8149d4 to your computer and use it in GitHub Desktop.
Attempt to implement the RouteResolver API out of core
// This wraps the `m.route` API to implement route resolvers
//
// Note: this is all in pure ES5
//
// Assumed extensions:
// - `m.route.default()` - Get the default route
var route = (function () {
"use strict"
var changed = true
function route(elem, defaultRoute, routes) {
function onchange(vnode) {
if (!changed) return
changed = false
var matcher = routes[m.route.get()]
function set(comp) {
vnode.state.comp = comp || "div"
vnode.state.render = typeof matcher.render === "function"
}
function bail(e) {
m.route.set(m.route.default(), null, {replace: true})
throw e
}
try {
if (
matcher == null || typeof matcher !== "object" ||
typeof matcher.onmatch !== "function"
) {
vnode.state.comp = matcher
vnode.state.render = typeof matcher.render === "function"
} else {
var request = vnode.attrs.onmatch(vnode.attrs, m.route.get())
if (request == null || typeof request.then !== "function") {
set(request)
} else {
Promise.resolve(request).then(set, bail).then(m.redraw)
}
}
} catch (e) {
bail(e)
}
}
var RouteResolver = {
oninit: onchange,
onupdate: onchange,
view: function (vnode) {
if (vnode.state.comp == null) return []
if (!vnode.state.render) return m(vnode.state.comp, vnode.attrs)
return vnode.attrs.render(m(vnode.state.comp, vnode.attrs))
}
}
var wrapped = Object.create(null)
Object.keys(routes).forEach(function (route) {
wrapped[route] = RouteResolver
})
return m.route(elem, defaultRoute, wrapped)
}
Object.keys(m.route).forEach(function (key) {
route[key] = m.route[key]
})
route.set = function (route, params, opts) {
changed = true
return m.route.set(route, params, opts)
}
return route
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment