Created
April 20, 2016 20:53
-
-
Save daniellizik/3a1bbdeb915a46097aa5e9116c58172e to your computer and use it in GitHub Desktop.
hash router
This file contains hidden or 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
(function(name, global, factory) { | |
//amd | |
if (typeof global.define === 'function' && global.define.amd) | |
global.define([], function() { return factory; }); | |
//common js | |
else if (typeof global.module === 'object' && global.module.exports) { | |
global.module.exports = factory; | |
//browser | |
else if (global.window) | |
global[name] = factory; | |
})('hashRouter', this, (function(utils) { | |
var util = utils(), | |
$ = util.$, | |
ui = util.ui; | |
/** | |
* @factory simpleHashRouter | |
* | |
* config params | |
* @param attr {string} - name of html5 data attribute to look for, similar to ui-router's <ui-view> directive | |
* @param otherwise {string} = base route if app is started with no hash route specified | |
* | |
* @returns this {object} - context of factory | |
* @property routes {object} - object literal containing all hash routes as they are registered with the .hash method | |
* @property config {object} - config object passed to factory | |
* @property hash {function} - main method used to instantiate new routes | |
* @property here {string} - the current hash | |
*/ | |
return function(config) { | |
var self = { | |
routes: {}, | |
config: config, | |
hash: hash, | |
here: '' | |
}; | |
watch(self); | |
otherwise(self); | |
return self; | |
} | |
/** | |
* @method simpleHashRouter.hash | |
* | |
* config params | |
* @param policy {function} - synchronous function must return true for route to render | |
* @param resolve {function} - promise to run before route is rendered | |
* @param after {function} - function to run after route has been rendered | |
* @param name {string} - name of the route, must be specified in html with configurable attribute | |
*/ | |
function hash(config) { | |
var self = this; | |
var instance = routeFactory.call(self, config); | |
if (!this.routes.hasOwnProperty(instance.hash)) | |
self.routes[instance.hash] = instance; | |
return self; | |
} | |
function routeFactory(config) { | |
return { | |
hash: '#' + config.name, | |
name: config.name, | |
after: config.after || function() {}, | |
policy: config.policy || function() { return true; }, | |
resolve: config.resolve || function() { return Promise.resolve(); } | |
} | |
} | |
function watch(self) { | |
var urls = {}, route; | |
window.addEventListener('hashchange', function(e) { | |
loc = location.hash; | |
//update main factory instance | |
self.here = loc; | |
if (self.routes.hasOwnProperty(loc)) { | |
route = self.routes[loc]; | |
view.call(self, route) | |
route.after.call(self, route) | |
} | |
}); | |
} | |
function otherwise(self) { | |
if (!self.here || self.here === '') | |
location.hash = self.config.otherwise; | |
} | |
function view(route) { | |
var self = this, | |
attr = self.config.attr, | |
uiview = ui(attr, self.here.slice(1)); | |
for (p in self.routes) { | |
if (p !== self.here) | |
ui(attr, p.slice(1)).style.display = 'none'; | |
//resolve, after | |
else { | |
if (route.policy() === true) { | |
route.resolve().then(function() { | |
route.after(); | |
uiview.style.display = 'block'; | |
}); | |
} | |
} | |
} | |
} | |
})( | |
function utils() { | |
//crappy jquery | |
function $(s) { | |
var list = document.querySelectorAll(s); | |
if (list.length === 1) | |
return document.querySelector(s); | |
else | |
return Array.prototype.slice.call(list); | |
} | |
//finds the uiview easily | |
function ui(attr, val) { | |
var selector ='[' + attr + '="' + val + '"]'; | |
return $(selector); | |
} | |
return { | |
$: $, | |
ui: ui | |
}; | |
} | |
)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment