Skip to content

Instantly share code, notes, and snippets.

@sukima
Forked from yorickvP/gist:2725801
Last active December 10, 2015 05:38
Show Gist options
  • Save sukima/4388940 to your computer and use it in GitHub Desktop.
Save sukima/4388940 to your computer and use it in GitHub Desktop.
A simple router class in JavaScript using callbacks (not events)
/**
* # Simple Router
* A JavaScript router class.
*
* #### Examples
* var appRouter, func,
* Router = require("Router");
*
* appRouter = new Router();
* appRouter.get("/", indexMethod);
* appRouter.post("/save", saveMethod);
* appRouter.get(/foo/, fooMethod);
*
* func = appRouter.getRoute("get", "/");
* func();
* func = appRouter.getRoute("get", "/123/foobar/");
* func();
*/
(function() {
var get_routes, Router;
/**
* ### get_routes()
* **Private** function to find all the routes accosiated with a specific
* route method.
*
* #### Arguments
* - context: _object_ - the context that stores the routes variable (ex. the `this` keyword)
* - method: _string_ - the routing method (ex. 'get', 'post')
*/
get_routes = function(context, method) {
return context.routes[method] || (context.routes[method] = []);
};
/**
* ## Router class
*/
Router = (function() {
function Router() {
this.routes = {
get: [],
post: []
};
}
/**
* ### getRoute()
* Returns a route for a specific method and url
*
* #### Arguments
* - method: _string_ - the HTTP method (ex. 'get', 'post')
* - url: _string_ - the URL in question (ex. 'http://example.com/')
*/
Router.prototype.getRoute = function(method, url) {
var r, rl, i, route, match;
r = get_routes(this, method);
for (i = 0, rl = r.length; i < rl; i++) {
route = r[i];
if (route.type === "string") {
if (route.url === url) {
return [url, route.callback];
}
}
else if (route.type === "regexp") {
if (match = route.url.exec(url)) {
return [match, route.callback];
}
}
else {
throw TypeError("unknown routing url type");
}
}
return null;
};
/**
* ### set()
* Set a route. The URL in question can be a string or Regexp.
* Retuns itself so chaning can be used.
*
* #### Arguments
* - method: _string_ - the HTTP method (ex. 'get', 'post')
* - url: _string, regexp_ - the URL for the route
* - callback: _function_ - the function to use for this route
*/
Router.prototype.set = function(method, url, callback) {
get_routes(this, method).push({
url: url,
callback: callback,
type: Object.prototype.toString.call(url).slice(8,1).toLowerCase()
});
return this;
};
/**
* ### get()
* Adds a route for the 'get' and 'head' methods with the URL in question
*
* #### Arguments
* - url: _string, regexp_ - the URL in question
* - callback: _function_ - the function to use for this route
*/
Router.prototype.get = function(url, callback) {
this.set('get', url, callback);
this.set('head', url, callback);
return this;
};
/**
* ### post()
* Adds a route for the 'post' method with the URL in question
*
* #### Arguments
* - url: _string, regexp_ - the URL in question
* - callback: _function_ - the function to use for this route
*/
Router.prototype.post = function(url, callback) {
this.set('post', url, callback);
return this;
};
return Router;
})();
// Check that we can export as a module.
// If not attach to the window object.
if (module != null) {
module.exports = Router;
}
else {
window.Router = Router;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment