Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active December 11, 2016 18:25
Show Gist options
  • Save barneycarroll/75319080d8fe9a85fa34a903fece4504 to your computer and use it in GitHub Desktop.
Save barneycarroll/75319080d8fe9a85fa34a903fece4504 to your computer and use it in GitHub Desktop.
A Mithril v1 route plugin for SPAs
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