1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.BaseUrlRule = exports.UrlRuleFactory = void 0;
|
4 | var urlMatcher_1 = require("./urlMatcher");
|
5 | var predicates_1 = require("../common/predicates");
|
6 | var common_1 = require("../common/common");
|
7 | var hof_1 = require("../common/hof");
|
8 | var stateObject_1 = require("../state/stateObject");
|
9 | /**
|
10 | * Creates a [[UrlRule]]
|
11 | *
|
12 | * Creates a [[UrlRule]] from a:
|
13 | *
|
14 | * - `string`
|
15 | * - [[UrlMatcher]]
|
16 | * - `RegExp`
|
17 | * - [[StateObject]]
|
18 | */
|
19 | var UrlRuleFactory = /** @class */ (function () {
|
20 | function UrlRuleFactory(router) {
|
21 | this.router = router;
|
22 | }
|
23 | UrlRuleFactory.prototype.compile = function (str) {
|
24 | return this.router.urlMatcherFactory.compile(str);
|
25 | };
|
26 | UrlRuleFactory.prototype.create = function (what, handler) {
|
27 | var _this = this;
|
28 | var isState = stateObject_1.StateObject.isState, isStateDeclaration = stateObject_1.StateObject.isStateDeclaration;
|
29 | var makeRule = hof_1.pattern([
|
30 | [predicates_1.isString, function (_what) { return makeRule(_this.compile(_what)); }],
|
31 | [hof_1.is(urlMatcher_1.UrlMatcher), function (_what) { return _this.fromUrlMatcher(_what, handler); }],
|
32 | [hof_1.or(isState, isStateDeclaration), function (_what) { return _this.fromState(_what, _this.router); }],
|
33 | [hof_1.is(RegExp), function (_what) { return _this.fromRegExp(_what, handler); }],
|
34 | [predicates_1.isFunction, function (_what) { return new BaseUrlRule(_what, handler); }],
|
35 | ]);
|
36 | var rule = makeRule(what);
|
37 | if (!rule)
|
38 | throw new Error("invalid 'what' in when()");
|
39 | return rule;
|
40 | };
|
41 | /**
|
42 | * A UrlRule which matches based on a UrlMatcher
|
43 | *
|
44 | * The `handler` may be either a `string`, a [[UrlRuleHandlerFn]] or another [[UrlMatcher]]
|
45 | *
|
46 | * ## Handler as a function
|
47 | *
|
48 | * If `handler` is a function, the function is invoked with:
|
49 | *
|
50 | * - matched parameter values ([[RawParams]] from [[UrlMatcher.exec]])
|
51 | * - url: the current Url ([[UrlParts]])
|
52 | * - router: the router object ([[UIRouter]])
|
53 | *
|
54 | * #### Example:
|
55 | * ```js
|
56 | * var urlMatcher = $umf.compile("/foo/:fooId/:barId");
|
57 | * var rule = factory.fromUrlMatcher(urlMatcher, match => "/home/" + match.fooId + "/" + match.barId);
|
58 | * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }
|
59 | * var result = rule.handler(match); // '/home/123/456'
|
60 | * ```
|
61 | *
|
62 | * ## Handler as UrlMatcher
|
63 | *
|
64 | * If `handler` is a UrlMatcher, the handler matcher is used to create the new url.
|
65 | * The `handler` UrlMatcher is formatted using the matched param from the first matcher.
|
66 | * The url is replaced with the result.
|
67 | *
|
68 | * #### Example:
|
69 | * ```js
|
70 | * var urlMatcher = $umf.compile("/foo/:fooId/:barId");
|
71 | * var handler = $umf.compile("/home/:fooId/:barId");
|
72 | * var rule = factory.fromUrlMatcher(urlMatcher, handler);
|
73 | * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }
|
74 | * var result = rule.handler(match); // '/home/123/456'
|
75 | * ```
|
76 | */
|
77 | UrlRuleFactory.prototype.fromUrlMatcher = function (urlMatcher, handler) {
|
78 | var _handler = handler;
|
79 | if (predicates_1.isString(handler))
|
80 | handler = this.router.urlMatcherFactory.compile(handler);
|
81 | if (hof_1.is(urlMatcher_1.UrlMatcher)(handler))
|
82 | _handler = function (match) { return handler.format(match); };
|
83 | function matchUrlParamters(url) {
|
84 | var params = urlMatcher.exec(url.path, url.search, url.hash);
|
85 | return urlMatcher.validates(params) && params;
|
86 | }
|
87 | // Prioritize URLs, lowest to highest:
|
88 | // - Some optional URL parameters, but none matched
|
89 | // - No optional parameters in URL
|
90 | // - Some optional parameters, some matched
|
91 | // - Some optional parameters, all matched
|
92 | function matchPriority(params) {
|
93 | var optional = urlMatcher.parameters().filter(function (param) { return param.isOptional; });
|
94 | if (!optional.length)
|
95 | return 0.000001;
|
96 | var matched = optional.filter(function (param) { return params[param.id]; });
|
97 | return matched.length / optional.length;
|
98 | }
|
99 | var details = { urlMatcher: urlMatcher, matchPriority: matchPriority, type: 'URLMATCHER' };
|
100 | return common_1.extend(new BaseUrlRule(matchUrlParamters, _handler), details);
|
101 | };
|
102 | /**
|
103 | * A UrlRule which matches a state by its url
|
104 | *
|
105 | * #### Example:
|
106 | * ```js
|
107 | * var rule = factory.fromState($state.get('foo'), router);
|
108 | * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }
|
109 | * var result = rule.handler(match);
|
110 | * // Starts a transition to 'foo' with params: { fooId: '123', barId: '456' }
|
111 | * ```
|
112 | */
|
113 | UrlRuleFactory.prototype.fromState = function (stateOrDecl, router) {
|
114 | var state = stateObject_1.StateObject.isStateDeclaration(stateOrDecl) ? stateOrDecl.$$state() : stateOrDecl;
|
115 | /**
|
116 | * Handles match by transitioning to matched state
|
117 | *
|
118 | * First checks if the router should start a new transition.
|
119 | * A new transition is not required if the current state's URL
|
120 | * and the new URL are already identical
|
121 | */
|
122 | var handler = function (match) {
|
123 | var $state = router.stateService;
|
124 | var globals = router.globals;
|
125 | if ($state.href(state, match) !== $state.href(globals.current, globals.params)) {
|
126 | $state.transitionTo(state, match, { inherit: true, source: 'url' });
|
127 | }
|
128 | };
|
129 | var details = { state: state, type: 'STATE' };
|
130 | return common_1.extend(this.fromUrlMatcher(state.url, handler), details);
|
131 | };
|
132 | /**
|
133 | * A UrlRule which matches based on a regular expression
|
134 | *
|
135 | * The `handler` may be either a [[UrlRuleHandlerFn]] or a string.
|
136 | *
|
137 | * ## Handler as a function
|
138 | *
|
139 | * If `handler` is a function, the function is invoked with:
|
140 | *
|
141 | * - regexp match array (from `regexp`)
|
142 | * - url: the current Url ([[UrlParts]])
|
143 | * - router: the router object ([[UIRouter]])
|
144 | *
|
145 | * #### Example:
|
146 | * ```js
|
147 | * var rule = factory.fromRegExp(/^\/foo\/(bar|baz)$/, match => "/home/" + match[1])
|
148 | * var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]
|
149 | * var result = rule.handler(match); // '/home/bar'
|
150 | * ```
|
151 | *
|
152 | * ## Handler as string
|
153 | *
|
154 | * If `handler` is a string, the url is *replaced by the string* when the Rule is invoked.
|
155 | * The string is first interpolated using `string.replace()` style pattern.
|
156 | *
|
157 | * #### Example:
|
158 | * ```js
|
159 | * var rule = factory.fromRegExp(/^\/foo\/(bar|baz)$/, "/home/$1")
|
160 | * var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]
|
161 | * var result = rule.handler(match); // '/home/bar'
|
162 | * ```
|
163 | */
|
164 | UrlRuleFactory.prototype.fromRegExp = function (regexp, handler) {
|
165 | if (regexp.global || regexp.sticky)
|
166 | throw new Error('Rule RegExp must not be global or sticky');
|
167 | /**
|
168 | * If handler is a string, the url will be replaced by the string.
|
169 | * If the string has any String.replace() style variables in it (like `$2`),
|
170 | * they will be replaced by the captures from [[match]]
|
171 | */
|
172 | var redirectUrlTo = function (match) {
|
173 | // Interpolates matched values into $1 $2, etc using a String.replace()-style pattern
|
174 | return handler.replace(/\$(\$|\d{1,2})/, function (m, what) { return match[what === '$' ? 0 : Number(what)]; });
|
175 | };
|
176 | var _handler = predicates_1.isString(handler) ? redirectUrlTo : handler;
|
177 | var matchParamsFromRegexp = function (url) { return regexp.exec(url.path); };
|
178 | var details = { regexp: regexp, type: 'REGEXP' };
|
179 | return common_1.extend(new BaseUrlRule(matchParamsFromRegexp, _handler), details);
|
180 | };
|
181 | UrlRuleFactory.isUrlRule = function (obj) { return obj && ['type', 'match', 'handler'].every(function (key) { return predicates_1.isDefined(obj[key]); }); };
|
182 | return UrlRuleFactory;
|
183 | }());
|
184 | exports.UrlRuleFactory = UrlRuleFactory;
|
185 | /**
|
186 | * A base rule which calls `match`
|
187 | *
|
188 | * The value from the `match` function is passed through to the `handler`.
|
189 | * @internal
|
190 | */
|
191 | var BaseUrlRule = /** @class */ (function () {
|
192 | function BaseUrlRule(match, handler) {
|
193 | var _this = this;
|
194 | this.match = match;
|
195 | this.type = 'RAW';
|
196 | this.matchPriority = function (match) { return 0 - _this.$id; };
|
197 | this.handler = handler || common_1.identity;
|
198 | }
|
199 | return BaseUrlRule;
|
200 | }());
|
201 | exports.BaseUrlRule = BaseUrlRule;
|
202 | //# sourceMappingURL=urlRule.js.map |
\ | No newline at end of file |