-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Copy pathurlRouter.js
120 lines (102 loc) · 3.76 KB
/
urlRouter.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
110
111
112
113
114
115
116
117
118
119
120
$UrlRouterProvider.$inject = ['$urlMatcherFactoryProvider'];
function $UrlRouterProvider( $urlMatcherFactory) {
var rules = [],
otherwise = null;
// Returns a string that is a prefix of all strings matching the RegExp
function regExpPrefix(re) {
var prefix = /^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(re.source);
return (prefix != null) ? prefix[1].replace(/\\(.)/g, "$1") : '';
}
// Interpolates matched values into a String.replace()-style pattern
function interpolate(pattern, match) {
return pattern.replace(/\$(\$|\d{1,2})/, function (m, what) {
return match[what === '$' ? 0 : Number(what)];
});
}
this.rule =
function (rule) {
if (!isFunction(rule)) throw new Error("'rule' must be a function");
rules.push(rule);
return this;
};
this.otherwise =
function (rule) {
if (isString(rule)) {
var redirect = rule;
rule = function () { return redirect; };
}
else if (!isFunction(rule)) throw new Error("'rule' must be a function");
otherwise = rule;
return this;
};
function handleIfMatch($injector, handler, match) {
if (!match) return false;
var result = $injector.invoke(handler, handler, { $match: match });
return isDefined(result) ? result : true;
}
this.when =
function (what, handler) {
var rule, redirect;
if (isString(what))
what = $urlMatcherFactory.compile(what);
if ($urlMatcherFactory.isMatcher(what)) {
if (isString(handler)) {
redirect = $urlMatcherFactory.compile(handler);
handler = ['$match', function ($match) { return redirect.format($match); }];
}
else if (!isFunction(handler) && !isArray(handler))
throw new Error("invalid 'handler' in when()");
rule = function ($injector, $location) {
return handleIfMatch($injector, handler, what.exec($location.path(), $location.search()));
};
rule.prefix = isString(what.prefix) ? what.prefix : '';
}
else if (what instanceof RegExp) {
if (isString(handler)) {
redirect = handler;
handler = ['$match', function ($match) { return interpolate(redirect, $match); }];
}
else if (!isFunction(handler) && !isArray(handler))
throw new Error("invalid 'handler' in when()");
if (what.global || what.sticky)
throw new Error("when() RegExp must not be global or sticky");
rule = function ($injector, $location) {
return handleIfMatch($injector, handler, what.exec($location.path()));
};
rule.prefix = regExpPrefix(what);
}
else
throw new Error("invalid 'what' in when()");
return this.rule(rule);
};
//clears the rules and clears "otherwise" if it is defined
function clearAll() {
rules = [];
otherwise = null;
}
this.clearAll = function() {clearAll(); return this;};
this.$get =
[ '$location', '$rootScope', '$injector',
function ($location, $rootScope, $injector) {
// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
function update() {
var n=rules.length, i, handled;
for (i=0; i<n; i++) {
handled = rules[i]($injector, $location);
if (handled) {
if (isString(handled)) $location.replace().url(handled);
break;
}
}
if (!handled && otherwise) {
handled = otherwise($injector, $location);
if (handled) {
if (isString(handled)) $location.replace().url(handled);
}
}
}
$rootScope.$on('$locationChangeSuccess', update);
return {};
}];
}
angular.module('ui.router').provider('$urlRouter', $UrlRouterProvider);