src/route.js

URI routing via hashtag Client side routes will be in routes.all

var route = {

Private

Current route ( Client only )

current : "",

Private

Initial / default route

initial : null,

Private

Reused regex object

reg : new RegExp(),

Private

Routing listeners

routes : {},

Public method method

Determines which HTTP method to use

Parameters:

  • arg must be a String.
    (HTTP method)

Returns a [type]
(HTTP method to utilize)

method : function ( arg ) { return regex.route_methods.test( arg ) ? arg.toLowerCase() : "all"; },

Public method del

Deletes a route

Parameters:

  • name must be a String.
    (Route name)

  • verb must be a String.
    (HTTP method)

Returns a Mixed
(True or undefined)

del : function ( name, verb, host ) { host = host || "all"; verb = route.method( verb ); var error = ( name === "error" ); if ( ( error && verb !== "all" ) || ( !error && route.routes[host][verb].hasOwnProperty( name ) ) ) { if ( route.initial === name ) { route.initial = null; } return ( delete route.routes[host][verb][name] ); } else { throw new Error( label.error.invalidArguments ); } },

Public method hash

Getter / setter for the hashbang

Parameters:

  • arg must be a String.
    (Route to set)

Returns a String
(Current route)

hash : function ( arg ) { var output = ""; if ( !server ) { if ( arg === undefined ) { output = document.location.hash.replace( regex.hash_bang, "" ); } else { output = arg.replace( regex.hash_bang, "" ); document.location.hash = "!" + output; } } return output; },

Public method hostname

Creates a hostname entry in the routes table

Parameters:

  • arg must be a String.
    (Hostname to route)

Returns an Object
(Routes for hostname)

hostname : function ( arg ) { if ( !route.routes.hasOwnProperty( arg ) ) { route.routes[arg] = { all : {}, "delete" : {}, get : {}, post : {}, put : {} }; } return route.routes[arg]; },

Public method init

Initializes the routing by loading the initial OR the first route registered

Returns an Undefined
(undefined)

init : function () { var val = document.location.hash; string.isEmpty( val ) ? route.hash( route.initial !== null ? route.initial : array.cast( route.routes.all.all, true ).remove( "error" )[0] ) : route.load( val ); },

Public method list

Lists all routes

Parameters:

  • verb must be a String.
    (HTTP method)

Returns a Mixed
(Hash of routes if host not specified, else an Array of routes for a method)

list : function ( verb, host ) { host = host || "all"; var result; if ( !server ) { result = array.cast( route.routes.all.all, true ); } else if ( verb !== undefined ) { result = array.cast( route.routes[route.routes[host] ? host : "all" ][route.method( verb )], true ); } else { result = {}; if ( route.routes.hasOwnProperty( host ) ) { utility.iterate( route.routes[host], function ( v, k ) { result[k] = []; utility.iterate( v, function ( fn, r ) { result[k].push( r ); }); }); } } return result; },

Public method load

Loads the hash into the view

Parameters:

  • name must be a String.
    (Route to load)

  • req must be a String.
    ([Optional] HTTP request ( node ))

  • res must be an Object.
    ([Optional] HTTP response ( node ))

  • host must be a String.
    ([Optional] Hostname to query)

Returns a Mixed
(True or undefined)

load : function ( name, req, res, host ) { req = req || "all"; host = host || "all"; var active = "", path = "", result = true, found = false, verb = route.method( req.method || req ), crawl, find;

Not a GET, but assuming the route is smart enough to strip the entity body

if ( regex.route_nget.test( verb ) ) { verb = "get"; }

Public, private, local scope

name = name.replace( /^\#\!?|\?.*|\#.*/g, "" ); if ( !server ) { route.current = name; }

Private method crawl

Crawls the hostnames, sets active & path

Parameters:

  • host must be a String.
    (Hostname)

  • verb must be a String.
    (HTTP method)

  • name must be a String.
    (Route)

Returns an Undefined
(undefined)

crawl = function ( host, verb, name ) { if ( route.routes[host][verb][name] !== undefined ) { active = name; path = verb; } else if ( verb !== "all" && route.routes[host].all[name] !== undefined ) { active = name; path = "all"; } else { utility.iterate( route.routes[host][verb], function ( v, k ) { return find( k, verb, name ); }); if ( string.isEmpty( active ) && verb !== "all" ) { utility.iterate( route.routes[host].all, function ( v, k ) { return find( k, "all", name ); }); } } };

Private method find

Finds a match, sets active & path

Parameters:

  • pattern must be a String.
    (Route)

  • method must be a String.
    (HTTP method)

  • arg must be a String.
    (URL)

Returns an Undefined
(undefined)

find = function ( pattern, method, arg ) { if ( utility.compile( route.reg, "^" + pattern + "$" ) && route.reg.test( arg ) ) { active = pattern; path = method; return false; } }; if ( host !== "all" && !route.routes.hasOwnProperty( host ) ) { array.each( array.cast( route.routes, true ), function ( i ) { var regex = new RegExp( i.replace(/^\*/g, ".*") ); if ( regex.test( host ) ) { host = i; found = true; return false; } }); if ( !found ) { host = "all"; } } crawl( host, verb, name ); if ( string.isEmpty( active ) ) { if ( host !== "all" ) { host = "all"; crawl( host, verb, name ); } if ( string.isEmpty( active ) ) { active = "error"; path = "all"; result = false; } } route.routes[host][path][active]( req || active, res ); return result; },

Public method reset

Resets the routes

Returns an Undefined
(undefined)

reset : function () { route.routes = { all : { all : { error : function () { if ( !server ) { if ( string.isEmpty( route.hash() ) ) { return history.go( -1 ); } else { utility.error( label.error.invalidRoute ); if ( route.initial !== null ) { route.hash( route.initial ); } } } else { throw new Error( label.error.invalidRoute ); } } }, "delete" : {}, get : {}, put : {}, post : {} } }; },

Public method server

Creates a Server with URI routing

Parameters:

  • arg must be an Object.
    (Server options)

  • fn must be a Function.
    (Error handler)

  • ssl must be a Boolean.
    (Determines if HTTPS server is created)

Returns an Object
(Server)

server : function ( args, fn, ssl ) { var maxConnections = 25, handler, err, obj; if ( !server ) { throw new Error( label.error.notSupported ); } args = args || {}; ssl = ( ssl === true || args.port === 443 );

Private method handler

Request handler

Parameters:

  • req must be an Object.
    (HTTP(S) Request Object)

  • res must be an Object.
    (HTTP(S) Response Object)

Returns an Undefined
(undefined)

handler = function ( req, res ) { var parsed = url.parse( req.url ), hostname = req.headers.host.replace( regex.header_replace, "" ); route.load( parsed.pathname, req, res, hostname ); };

Private method err

Error handler

Parameters:

  • e must be an Object.
    (Error)

Returns an Undefined
(undefined)

err = function ( e ) { utility.error( e, [args, fn, ssl] ); if ( typeof fn === "function" ) { fn( e ); } };

Enabling routing, in case it's not explicitly enabled prior to route.server()

route.enabled = true;

Server parameters

args.host = args.host || undefined; args.port = args.port || 8000;

Creating server

if ( !ssl ) {

For proxy behavior

http.globalAgent.maxConnections = args.maxConnections || maxConnections; obj = http.createServer( handler ).on( "error", err ).listen( args.port, args.host ); if ( obj.maxConnections ) { obj.maxConnections = args.maxConnections || maxConnections; } } else {

For proxy behavior

https.globalAgent.maxConnections = args.maxConnections; obj = https.createServer( args, handler ).on( "error", err).listen( args.port ); if ( obj.maxConnections ) { obj.maxConnections = args.maxConnections || maxConnections; } } return obj; },

Public method set

Sets a route for a URI

Parameters:

  • name must be a String.
    (Regex pattern for the route)

  • fn must be a Function.
    (Route listener)

  • verb must be a String.
    (HTTP method the route is for ( default is GET ))

Returns a Mixed
(True or undefined)

set : function ( name, fn, verb, host ) { host = server ? ( host || "all" ) : "all"; verb = server ? route.method( verb ) : "all"; if ( typeof name !== "string" || string.isEmpty( name ) || typeof fn !== "function") { throw new Error( label.error.invalidArguments ); } route.hostname( host )[verb][name] = fn; return true; } };