forked from BackboneSubroute/backbone.subroute
-
Notifications
You must be signed in to change notification settings - Fork 3
/
backbone.subroute.js
109 lines (92 loc) · 4.39 KB
/
backbone.subroute.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// backbone-subroute.js v0.4.3
//
// Copyright (C) 2012 Dave Cadwallader, Model N, Inc.
// Distributed under the MIT License
//
// Documentation and full license available at:
// https://github.com/ModelN/backbone.subroute
(function(factory) {
if (typeof define === 'function' && define.amd) {
// Register as an AMD module if available...
define(['underscore', 'backbone'], factory);
} else if (typeof exports === 'object') {
// Next for Node.js, CommonJS, browserify...
factory(require('underscore'), require('backbone'));
} else {
// Browser globals for the unenlightened...
factory(_, Backbone);
}
}(function(_, Backbone) {
Backbone.SubRoute = Backbone.Router.extend({
constructor: function(prefix, options) {
// each subroute instance should have its own routes hash
this.routes = _.clone(this.routes) || {};
// Prefix is optional, set to empty string if not passed
this.prefix = prefix = prefix || "";
// SubRoute instances may be instantiated using a prefix with or without a trailing slash.
// If the prefix does *not* have a trailing slash, we need to insert a slash as a separator
// between the prefix and the sub-route path for each route that we register with Backbone.
this.separator = (prefix.slice(-1) === "/") ? "" : "/";
// if you want to match "books" and "books/" without creating separate routes, set this
// option to "true" and the sub-router will automatically create those routes for you.
this.createTrailingSlashRoutes = options && options.createTrailingSlashRoutes;
// Required to have Backbone set up routes
Backbone.Router.prototype.constructor.call(this, options);
// grab the full URL
var hash;
if (Backbone.history.fragment) {
hash = Backbone.history.getFragment();
} else {
hash = Backbone.history.getHash();
}
// Trigger the subroute immediately. this supports the case where
// a user directly navigates to a URL with a subroute on the first page load.
// Check every element, if one matches, break. Prevent multiple matches
_.every(this.routes, function(key, route) {
// Use the Backbone parser to turn route into regex for matching
if (hash.match(Backbone.Router.prototype._routeToRegExp(route))) {
Backbone.history.loadUrl(hash);
return false;
}
return true;
}, this);
if (this.postInitialize) {
this.postInitialize(options);
}
},
navigate: function(route, options) {
if (route.substr(0, 1) != '/' &&
route.indexOf(this.prefix.substr(0, this.prefix.length - 1)) !== 0) {
route = this.prefix +
(route ? this.separator : "") +
route;
}
Backbone.Router.prototype.navigate.call(this, route, options);
},
route: function(route, name, callback) {
// strip off any leading slashes in the sub-route path,
// since we already handle inserting them when needed.
if (route.substr(0) === "/") {
route = route.substr(1, route.length);
}
var _route = this.prefix;
if (route && route.length > 0) {
if (this.prefix.length > 0)
_route += this.separator;
_route += route;
}
if (this.createTrailingSlashRoutes) {
this.routes[_route + '/'] = name;
Backbone.Router.prototype.route.call(this, _route + '/', name, callback);
}
// remove the un-prefixed route from our routes hash
delete this.routes[route];
// add the prefixed-route. note that this routes hash is just provided
// for informational and debugging purposes and is not used by the actual routing code.
this.routes[_route] = name;
// delegate the creation of the properly-prefixed route to Backbone
return Backbone.Router.prototype.route.call(this, _route, name, callback);
}
});
return Backbone.SubRoute;
}));