Last active
January 17, 2018 23:25
-
-
Save dead-claudia/29d044e1d112a0bf70706a6cdd8149d4 to your computer and use it in GitHub Desktop.
Attempt to implement the RouteResolver API out of core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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