-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash-router.js
98 lines (98 loc) · 3.5 KB
/
hash-router.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
var HashRouterLib = function(w, isModule) {
var reference = "HashRouter";
var HashRouter = function (routes, autoResolve) {
autoResolve = typeof autoResolve !== 'undefined' ? autoResolve : true;
this.routes = [];
if (typeof routes === 'object') {
for (var route in routes) {
this.add(route, routes[route]);
}
} else if (Array.isArray(routes)) {
this.routes = routes;
}
window.onhashchange = this.hashChanged.bind(this);
if (this.routes.length && autoResolve) {
this.resolve();
}
};
HashRouter.prototype = {
add: function (route, handler) {
if (typeof route === 'string') {
route = encodeURI(route);
} else if (typeof route === 'function') {
handler = route;
route = '';
}
this.routes.push({route: route, handler: handler});
return this;
},
matchAnyRoute: function (route) {
return route === '*';
},
matchRootRoute: function (url, route) {
return (url === '' || url === '#/') && (route === '' || route === '/');
},
isRootRoute: function (route) {
return route === '' || route === '/';
},
extractParamsFromMatch: function (match, paramNames) {
if (!match || paramNames.length === 0) return null;
return match
.slice(1, match.length)
.reduce(function (params, value, index) {
params = params || {};
params[paramNames[index]] = decodeURIComponent(value);
return params;
}, null);
},
check: function (url) {
var i, match, route, paramNames = [], params = [], regexp, $this = this;
url = url || window.location.hash;
for (i = 0; i < this.routes.length; i++) {
route = this.routes[i].route;
if (this.matchAnyRoute(route) || this.matchRootRoute(url, route)) {
this.routes[i].handler(params, $this);
return this;
}
if (this.isRootRoute(route)) {
continue;
}
paramNames = [];
regexp = new RegExp(
route.replace(/([:*])(\w+)/g, function (full, dots, name) {
paramNames.push(name);
return '([^\/]+)';
}).replace(/\*/g, '(?:.*)') + '(?:\/$|$)', '');
match = url.replace(/^\/+/, '/').match(regexp);
if (match) {
params = this.extractParamsFromMatch(match, paramNames);
if (typeof this.routes[i].handler === 'function') {
this.routes[i].handler(params, $this);
}
return this;
}
}
return this;
},
resolve: function () {
this.check(window.location.hash);
},
hashChanged: function (ev) {
this.resolve();
},
navigate: function (path) {
window.location.hash = path;
return this;
}
};
if (isModule){
return HashRouter;
} else {
w[reference] = HashRouter;
}
};
if (typeof module === 'undefined'){
HashRouterLib(window);
} else {
module.exports = HashRouterLib(window, true);
}