1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.UrlService = void 0;
|
4 | var common_1 = require("../common");
|
5 | var urlRules_1 = require("./urlRules");
|
6 | var urlConfig_1 = require("./urlConfig");
|
7 | var state_1 = require("../state");
|
8 | /**
|
9 | * API for URL management
|
10 | */
|
11 | var UrlService = /** @class */ (function () {
|
12 | /** @internal */
|
13 | function UrlService(/** @internal */ router) {
|
14 | var _this = this;
|
15 | this.router = router;
|
16 | /** @internal */ this.interceptDeferred = false;
|
17 | /**
|
18 | * The nested [[UrlRules]] API for managing URL rules and rewrites
|
19 | *
|
20 | * See: [[UrlRules]] for details
|
21 | */
|
22 | this.rules = new urlRules_1.UrlRules(this.router);
|
23 | /**
|
24 | * The nested [[UrlConfig]] API to configure the URL and retrieve URL information
|
25 | *
|
26 | * See: [[UrlConfig]] for details
|
27 | */
|
28 | this.config = new urlConfig_1.UrlConfig(this.router);
|
29 | // Delegate these calls to the current LocationServices implementation
|
30 | /**
|
31 | * Gets the current url, or updates the url
|
32 | *
|
33 | * ### Getting the current URL
|
34 | *
|
35 | * When no arguments are passed, returns the current URL.
|
36 | * The URL is normalized using the internal [[path]]/[[search]]/[[hash]] values.
|
37 | *
|
38 | * For example, the URL may be stored in the hash ([[HashLocationServices]]) or
|
39 | * have a base HREF prepended ([[PushStateLocationServices]]).
|
40 | *
|
41 | * The raw URL in the browser might be:
|
42 | *
|
43 | * ```
|
44 | * http://mysite.com/somepath/index.html#/internal/path/123?param1=foo#anchor
|
45 | * ```
|
46 | *
|
47 | * or
|
48 | *
|
49 | * ```
|
50 | * http://mysite.com/basepath/internal/path/123?param1=foo#anchor
|
51 | * ```
|
52 | *
|
53 | * then this method returns:
|
54 | *
|
55 | * ```
|
56 | * /internal/path/123?param1=foo#anchor
|
57 | * ```
|
58 | *
|
59 | *
|
60 | * #### Example:
|
61 | * ```js
|
62 | * locationServices.url(); // "/some/path?query=value#anchor"
|
63 | * ```
|
64 | *
|
65 | * ### Updating the URL
|
66 | *
|
67 | * When `newurl` arguments is provided, changes the URL to reflect `newurl`
|
68 | *
|
69 | * #### Example:
|
70 | * ```js
|
71 | * locationServices.url("/some/path?query=value#anchor", true);
|
72 | * ```
|
73 | *
|
74 | * @param newurl The new value for the URL.
|
75 | * This url should reflect only the new internal [[path]], [[search]], and [[hash]] values.
|
76 | * It should not include the protocol, site, port, or base path of an absolute HREF.
|
77 | * @param replace When true, replaces the current history entry (instead of appending it) with this new url
|
78 | * @param state The history's state object, i.e., pushState (if the LocationServices implementation supports it)
|
79 | *
|
80 | * @return the url (after potentially being processed)
|
81 | */
|
82 | this.url = function (newurl, replace, state) {
|
83 | return _this.router.locationService.url(newurl, replace, state);
|
84 | };
|
85 | /**
|
86 | * Gets the path part of the current url
|
87 | *
|
88 | * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`
|
89 | *
|
90 | * @return the path portion of the url
|
91 | */
|
92 | this.path = function () { return _this.router.locationService.path(); };
|
93 | /**
|
94 | * Gets the search part of the current url as an object
|
95 | *
|
96 | * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`
|
97 | *
|
98 | * @return the search (query) portion of the url, as an object
|
99 | */
|
100 | this.search = function () { return _this.router.locationService.search(); };
|
101 | /**
|
102 | * Gets the hash part of the current url
|
103 | *
|
104 | * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`
|
105 | *
|
106 | * @return the hash (anchor) portion of the url
|
107 | */
|
108 | this.hash = function () { return _this.router.locationService.hash(); };
|
109 | /**
|
110 | * @internal
|
111 | *
|
112 | * Registers a low level url change handler
|
113 | *
|
114 | * Note: Because this is a low level handler, it's not recommended for general use.
|
115 | *
|
116 | * #### Example:
|
117 | * ```js
|
118 | * let deregisterFn = locationServices.onChange((evt) => console.log("url change", evt));
|
119 | * ```
|
120 | *
|
121 | * @param callback a function that will be called when the url is changing
|
122 | * @return a function that de-registers the callback
|
123 | */
|
124 | this.onChange = function (callback) { return _this.router.locationService.onChange(callback); };
|
125 | }
|
126 | /** @internal */
|
127 | UrlService.prototype.dispose = function () {
|
128 | this.listen(false);
|
129 | this.rules.dispose();
|
130 | };
|
131 | /**
|
132 | * Gets the current URL parts
|
133 | *
|
134 | * This method returns the different parts of the current URL (the [[path]], [[search]], and [[hash]]) as a [[UrlParts]] object.
|
135 | */
|
136 | UrlService.prototype.parts = function () {
|
137 | return { path: this.path(), search: this.search(), hash: this.hash() };
|
138 | };
|
139 | /**
|
140 | * Activates the best rule for the current URL
|
141 | *
|
142 | * Checks the current URL for a matching [[UrlRule]], then invokes that rule's handler.
|
143 | * This method is called internally any time the URL has changed.
|
144 | *
|
145 | * This effectively activates the state (or redirect, etc) which matches the current URL.
|
146 | *
|
147 | * #### Example:
|
148 | * ```js
|
149 | * urlService.deferIntercept();
|
150 | *
|
151 | * fetch('/states.json').then(resp => resp.json()).then(data => {
|
152 | * data.forEach(state => $stateRegistry.register(state));
|
153 | * urlService.listen();
|
154 | * // Find the matching URL and invoke the handler.
|
155 | * urlService.sync();
|
156 | * });
|
157 | * ```
|
158 | */
|
159 | UrlService.prototype.sync = function (evt) {
|
160 | if (evt && evt.defaultPrevented)
|
161 | return;
|
162 | var _a = this.router, urlService = _a.urlService, stateService = _a.stateService;
|
163 | var url = { path: urlService.path(), search: urlService.search(), hash: urlService.hash() };
|
164 | var best = this.match(url);
|
165 | var applyResult = common_1.pattern([
|
166 | [common_1.isString, function (newurl) { return urlService.url(newurl, true); }],
|
167 | [state_1.TargetState.isDef, function (def) { return stateService.go(def.state, def.params, def.options); }],
|
168 | [common_1.is(state_1.TargetState), function (target) { return stateService.go(target.state(), target.params(), target.options()); }],
|
169 | ]);
|
170 | applyResult(best && best.rule.handler(best.match, url, this.router));
|
171 | };
|
172 | /**
|
173 | * Starts or stops listening for URL changes
|
174 | *
|
175 | * Call this sometime after calling [[deferIntercept]] to start monitoring the url.
|
176 | * This causes UI-Router to start listening for changes to the URL, if it wasn't already listening.
|
177 | *
|
178 | * If called with `false`, UI-Router will stop listening (call listen(true) to start listening again).
|
179 | *
|
180 | * #### Example:
|
181 | * ```js
|
182 | * urlService.deferIntercept();
|
183 | *
|
184 | * fetch('/states.json').then(resp => resp.json()).then(data => {
|
185 | * data.forEach(state => $stateRegistry.register(state));
|
186 | * // Start responding to URL changes
|
187 | * urlService.listen();
|
188 | * urlService.sync();
|
189 | * });
|
190 | * ```
|
191 | *
|
192 | * @param enabled `true` or `false` to start or stop listening to URL changes
|
193 | */
|
194 | UrlService.prototype.listen = function (enabled) {
|
195 | var _this = this;
|
196 | if (enabled === false) {
|
197 | this._stopListeningFn && this._stopListeningFn();
|
198 | delete this._stopListeningFn;
|
199 | }
|
200 | else {
|
201 | return (this._stopListeningFn =
|
202 | this._stopListeningFn || this.router.urlService.onChange(function (evt) { return _this.sync(evt); }));
|
203 | }
|
204 | };
|
205 | /**
|
206 | * Disables monitoring of the URL.
|
207 | *
|
208 | * Call this method before UI-Router has bootstrapped.
|
209 | * It will stop UI-Router from performing the initial url sync.
|
210 | *
|
211 | * This can be useful to perform some asynchronous initialization before the router starts.
|
212 | * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.
|
213 | *
|
214 | * #### Example:
|
215 | * ```js
|
216 | * // Prevent UI-Router from automatically intercepting URL changes when it starts;
|
217 | * urlService.deferIntercept();
|
218 | *
|
219 | * fetch('/states.json').then(resp => resp.json()).then(data => {
|
220 | * data.forEach(state => $stateRegistry.register(state));
|
221 | * urlService.listen();
|
222 | * urlService.sync();
|
223 | * });
|
224 | * ```
|
225 | *
|
226 | * @param defer Indicates whether to defer location change interception.
|
227 | * Passing no parameter is equivalent to `true`.
|
228 | */
|
229 | UrlService.prototype.deferIntercept = function (defer) {
|
230 | if (defer === undefined)
|
231 | defer = true;
|
232 | this.interceptDeferred = defer;
|
233 | };
|
234 | /**
|
235 | * Matches a URL
|
236 | *
|
237 | * Given a URL (as a [[UrlParts]] object), check all rules and determine the best matching rule.
|
238 | * Return the result as a [[MatchResult]].
|
239 | */
|
240 | UrlService.prototype.match = function (url) {
|
241 | var _this = this;
|
242 | url = common_1.extend({ path: '', search: {}, hash: '' }, url);
|
243 | var rules = this.rules.rules();
|
244 | // Checks a single rule. Returns { rule: rule, match: match, weight: weight } if it matched, or undefined
|
245 | var checkRule = function (rule) {
|
246 | var match = rule.match(url, _this.router);
|
247 | return match && { match: match, rule: rule, weight: rule.matchPriority(match) };
|
248 | };
|
249 | // The rules are pre-sorted.
|
250 | // - Find the first matching rule.
|
251 | // - Find any other matching rule that sorted *exactly the same*, according to `.sort()`.
|
252 | // - Choose the rule with the highest match weight.
|
253 | var best;
|
254 | for (var i = 0; i < rules.length; i++) {
|
255 | // Stop when there is a 'best' rule and the next rule sorts differently than it.
|
256 | if (best && best.rule._group !== rules[i]._group)
|
257 | break;
|
258 | var current = checkRule(rules[i]);
|
259 | // Pick the best MatchResult
|
260 | best = !best || (current && current.weight > best.weight) ? current : best;
|
261 | }
|
262 | return best;
|
263 | };
|
264 | return UrlService;
|
265 | }());
|
266 | exports.UrlService = UrlService;
|
267 | //# sourceMappingURL=urlService.js.map |
\ | No newline at end of file |