Skip to content

Commit

Permalink
improved router to support the concept of sub-routers
Browse files Browse the repository at this point in the history
  • Loading branch information
kbjr committed May 20, 2014
1 parent 8450c7b commit 83a9212
Showing 1 changed file with 67 additions and 10 deletions.
77 changes: 67 additions & 10 deletions lib/cloak/router.js
Expand Up @@ -4,22 +4,34 @@ var History = require('history');
var AppObject = require('cloak/app-object');
var _ = require('cloak/underscore');

var defaults = {
autoStart: true,
isTopLevel: true
};

//
// Router class
//
var Router = module.exports = AppObject.extend({

routes: null,
_routes: [ ],
_opts: null,
_routes: null,
_subRouters: null,
_isOn: false,
_variablePattern: /:([^\/]+)/g,
_currentUrl: null,
_currentRoute: null,
_isAnchor: false,

init: function() {
init: function(opts) {
this._super();
this._routes = [ ];
this._opts = _.defaults(opts || { }, Router.defaults);

if (this._opts.isTopLevel) {
this.topLevel = this;
}

_.forEach(_.keys(this.routes),
_.bind(
Expand All @@ -29,23 +41,42 @@ var Router = module.exports = AppObject.extend({
this)
);

this._subRouters = [ ];

this.bind('handleAnchor');

// Listen for history.statechange events
this.bind('_onstatechange');
if (History.enabled) {
if (History.enabled && this._opts.autoStart) {
this.start();
}

// Call any given initialize method
if (typeof this.initialize === 'function') {
this.initialize.apply(this, arguments);
}
},

//
// Add another router's routes to this one
//
// @param {router} the router to use
// @return this
//
use: function(router) {
// If given a router constructor, create an instance
if (typeof router === 'function') {
router = new router({
autoStart: false,
isTopLevel: false
});
}

router.parent = this;
router.topLevel = this.topLevel;
this._subRouters.push(router);

// When we initialize a new router, we trigger a statechange event. This shouldn't
// cause any issues, though, as we ignore statechanges that have the same url as
// the current one
cloak.$win.trigger('statechange');
return this;
},

//
Expand All @@ -57,6 +88,11 @@ var Router = module.exports = AppObject.extend({
if (! this._isOn) {
this._isOn = true;
cloak.$win.on('statechange', this._onstatechange);

// When we start a router, we trigger a statechange event. This shouldn't
// cause any issues, though, as we ignore statechanges that have the same url as
// the current one
cloak.$win.trigger('statechange');
}
},

Expand Down Expand Up @@ -228,20 +264,41 @@ var Router = module.exports = AppObject.extend({
// If the currently tracked url is the one we're already on, emit an event and move on
if (state.hash === this._currentUrl) {
this.emit('reload', this._currentRoute.params, this._currentRoute.href, data);
return;
return true;
}

cloak.log('State Change: ' + state.hash);
if (this._opts.isTopLevel) {
cloak.log('State Change: ' + state.hash);
}

this._currentUrl = state.hash;
this._currentRoute = this._find(state.hash);

// Handle unrecognized routes
if (! this._currentRoute) {
return this.emit('notfound', state);
this.emit('notfound', state);
return this._deferToSubRouters();
}


this._currentRoute.func(this._currentRoute.params, this._currentRoute.href, data);
return true;
},

//
// Checks any listed sub-routers for a match
//
// @return void
//
_deferToSubRouters: function() {
return !! _.find(this._subRouters, function(subRouter) {
return subRouter._onstatechange();
});
}

});

//
// Expose the default config object
//
Router.defaults = defaults;

0 comments on commit 83a9212

Please sign in to comment.