/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, curly:true, browser:true, indent:2, maxerr:50 */ /*! front.js (c) 2011 Anders Ytterström front.js may be freely distributed under the MIT license. TODO: pushState support */ /* USAGE: A route is defined by a path (could be a simple string or a regexp) and a callback (a function). // static routes front("books", displayBooks); front("talks", displayTalks); front("comments", displayComments); // dynamic routes front(/book:[\d+]$/, displayBookDetail); front(/talk:[\d+]$/, displayTalkDetail); front(/comment:[\d]$/, displayCommentDetail); The frontcontroller should be executed when all dependencies are in place and the routes are configured. front.run(); // defaults to location.hash -> http://example.com front.run("book:12"); // goto book 12 -> http://example.com#!book:12 location.hash is altered everytime front.run is executed. */ (function (global) { "use strict"; var i, _regexps = [], _statics = []; function addRoute(path, callback) { if (typeof path !== "string") { // regexp _regexps.push([ path, callback ]); } else { _statics.push([ path, callback ]); } return true; } function dispatch(path) { // set path if (typeof path === "undefined") { path = location.hash || ""; path = path.replace(/^#/, '').replace(/^!/, ''); } // cleanup var action, args; // static routes lookup i = _statics.length; while (i--) { if (_statics[i][0] === path) { action = _statics[i][1]; break; } } // regexp routes lookup unless a static action was defined. if (typeof action !== "function") { i = _regexps.length; while (i--) { args = args = path.match(_regexps[i][0]); if (args) { action = _regexps[i][1]; break; } } } // execute action and update hash unless the action is still undefined if (typeof action === "function") { if (args instanceof Array) { args.shift(); if (args.length === 1) { args = args[0]; } } action(args); path = (path.length ? '#!': '') + path; if (location.hash !== path) { location.hash = path; } } return false; // for click events. } global.front = addRoute; global.front.run = dispatch; })(this);