Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@bpierre
Created February 23, 2014 17:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bpierre/9174771 to your computer and use it in GitHub Desktop.
Save bpierre/9174771 to your computer and use it in GitHub Desktop.
Mini location.hash system + mini routing system (useful with PhoneGap)
/*
* Mini location.hash update system
*
* Usage:
*
* var createHash = require('./hash');
* var hash = createHash('!/', function(value) {
* // Value updated
* });
*
* // Updates the location.hash value and triggers the update
* hash.value = 'foo';
*
*/
module.exports = function createHash(prefix, update) {
if (!update) update = function(){};
var hash = {};
var _value = getHash(prefix);
Object.defineProperty(hash, 'value', {
enumerable: false,
get: function() {
return _value;
},
set: function(value) {
if (value === _value) return;
_value = setHash(prefix, value);
update(_value);
}
});
hashChange(prefix, function(value) {
hash.value = getHash(prefix);
});
update(_value);
return hash;
};
function getHash(prefix) {
return window.location.hash.slice(prefix.length + 1);
}
function setHash(prefix, value) {
window.location.hash = '#' + prefix + value;
return value;
}
function hashChange(prefix, cb) {
window.addEventListener('hashchange', cb);
}
/*
* Mini routing system
*
* Usage:
*
* var createRouting = require('./routing');
*
* var paths = [
*
* // Match '', 'search', 'search/<anything>'
* [ 'search', /^(?:search(?:\/(.+))?)?$/ ],
*
* // Match 'page2'
* [ 'page2', /^page2$/ ]
*
* ];
*
* var routing = createRouting(paths, function(route) {
* console.log(route);
* });
*
* routing('search'); // { 'name': 'search', params: [] }
* routing('search/test'); // { 'name': 'search', params: ['test'] }
*
* With hash.js:
*
* var createHash = require('./hash');
* var hash = createHash('!/', routing);
*
* // Updates the location.hash value and triggers the update
* hash.value = 'foo';
*
*/
module.exports = function createRouting(paths, cb) {
return function updatePath(value) {
cb(validPath(paths, value));
};
}
function matches(re, path) {
var matches = re.exec(path);
if (matches === null) return null;
return matches.slice(1).map(function(val) {
if (typeof val === 'undefined') return null;
return val;
});
}
function validPath(paths, value) {
// Remove any trailing slash
value = value.trim().replace(/\/+$/, '');
for (var i=0, l = paths.length, params; i < l; i++) {
// Valid path found
if (params = matches(paths[i][1], value) !== null) {
return {
name: paths[i][0],
params: params
};
}
}
return { name: null, params: [] };
};
@bpierre
Copy link
Author

bpierre commented Mar 6, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment