Last active
December 11, 2016 18:25
-
-
Save barneycarroll/75319080d8fe9a85fa34a903fece4504 to your computer and use it in GitHub Desktop.
A Mithril v1 route plugin for SPAs
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
var rootProxies = [ [], [] ] | |
// We apply m.route to a proxy node outside of the document | |
// This function ensures any given root always returns the same | |
// proxy. | |
function getProxy( root ){ | |
var roots = rootProxies[ 0 ] | |
var proxies = rootProxies[ 1 ] | |
var index = roots.indexOf( root ) | |
var proxy | |
if( index >= 0 ){ | |
proxy = proxies[ index ] | |
} | |
else { | |
proxy = document.createElement( 'div' ) | |
roots.push( root ) | |
proxies.push( proxy ) | |
} | |
return proxy | |
} | |
function SPA( root, fallback, endpoints, view ){ | |
// Unique reference for vnodes to pass between route endpoints | |
// and the global view | |
var vnode | |
// One render function for the view, which binds the state to vnode | |
function render( vnode ){ | |
vnode.state = {} | |
return view( vnode ) | |
} | |
// Resolves with the first route match endpoint | |
new Promise( function( init ){ | |
// Create an onmatch function | |
function matchFactory( resolver ){ | |
return function onmatch( routeArgs ){ | |
// New state object | |
state = {} | |
// Pass vnode-like object to the route endpoint promise | |
var resolution = resolver( { | |
attrs : routeArgs, | |
state : state, | |
} ) | |
// Resolve our initialisation promise if we haven't already | |
resolution.then( init ) | |
// Pass the promise back to Mithril | |
return resolution | |
} | |
} | |
// Build a Mithril-comptabile routeMap from | |
// { path : promise } key : value paires | |
var routeMap = {} | |
for( var path in endpoints ) | |
if( endpoints.hasOwnProperty( path ) ) | |
routeMap[ path ] = { | |
onmatch : matchFactory( endpoints[ path ] ) | |
} | |
// Attach | |
m.route( getProxy( root ), fallback, routeMap ) | |
} ).then( function initialise(){ | |
m.mount( root, view ) | |
} ) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment