source: trip-planner-front/node_modules/@angular/common/fesm2015/upgrade.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 34.8 KB
Line 
1/**
2 * @license Angular v12.2.9
3 * (c) 2010-2021 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { ReplaySubject } from 'rxjs';
8import { Location, PlatformLocation, LocationStrategy, APP_BASE_HREF, CommonModule, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
9import { InjectionToken, Inject, Optional, NgModule } from '@angular/core';
10import { UpgradeModule } from '@angular/upgrade/static';
11
12/**
13 * @license
14 * Copyright Google LLC All Rights Reserved.
15 *
16 * Use of this source code is governed by an MIT-style license that can be
17 * found in the LICENSE file at https://angular.io/license
18 */
19function stripPrefix(val, prefix) {
20 return val.startsWith(prefix) ? val.substring(prefix.length) : val;
21}
22function deepEqual(a, b) {
23 if (a === b) {
24 return true;
25 }
26 else if (!a || !b) {
27 return false;
28 }
29 else {
30 try {
31 if ((a.prototype !== b.prototype) || (Array.isArray(a) && Array.isArray(b))) {
32 return false;
33 }
34 return JSON.stringify(a) === JSON.stringify(b);
35 }
36 catch (e) {
37 return false;
38 }
39 }
40}
41function isAnchor(el) {
42 return el.href !== undefined;
43}
44function isPromise(obj) {
45 // allow any Promise/A+ compliant thenable.
46 // It's up to the caller to ensure that obj.then conforms to the spec
47 return !!obj && typeof obj.then === 'function';
48}
49
50/**
51 * @license
52 * Copyright Google LLC All Rights Reserved.
53 *
54 * Use of this source code is governed by an MIT-style license that can be
55 * found in the LICENSE file at https://angular.io/license
56 */
57const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
58const DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
59const IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
60const DEFAULT_PORTS = {
61 'http:': 80,
62 'https:': 443,
63 'ftp:': 21
64};
65/**
66 * Location service that provides a drop-in replacement for the $location service
67 * provided in AngularJS.
68 *
69 * @see [Using the Angular Unified Location Service](guide/upgrade#using-the-unified-angular-location-service)
70 *
71 * @publicApi
72 */
73class $locationShim {
74 constructor($injector, location, platformLocation, urlCodec, locationStrategy) {
75 this.location = location;
76 this.platformLocation = platformLocation;
77 this.urlCodec = urlCodec;
78 this.locationStrategy = locationStrategy;
79 this.initalizing = true;
80 this.updateBrowser = false;
81 this.$$absUrl = '';
82 this.$$url = '';
83 this.$$host = '';
84 this.$$replace = false;
85 this.$$path = '';
86 this.$$search = '';
87 this.$$hash = '';
88 this.$$changeListeners = [];
89 this.cachedState = null;
90 this.urlChanges = new ReplaySubject(1);
91 this.lastBrowserUrl = '';
92 // This variable should be used *only* inside the cacheState function.
93 this.lastCachedState = null;
94 const initialUrl = this.browserUrl();
95 let parsedUrl = this.urlCodec.parse(initialUrl);
96 if (typeof parsedUrl === 'string') {
97 throw 'Invalid URL';
98 }
99 this.$$protocol = parsedUrl.protocol;
100 this.$$host = parsedUrl.hostname;
101 this.$$port = parseInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
102 this.$$parseLinkUrl(initialUrl, initialUrl);
103 this.cacheState();
104 this.$$state = this.browserState();
105 this.location.onUrlChange((newUrl, newState) => {
106 this.urlChanges.next({ newUrl, newState });
107 });
108 if (isPromise($injector)) {
109 $injector.then($i => this.initialize($i));
110 }
111 else {
112 this.initialize($injector);
113 }
114 }
115 initialize($injector) {
116 const $rootScope = $injector.get('$rootScope');
117 const $rootElement = $injector.get('$rootElement');
118 $rootElement.on('click', (event) => {
119 if (event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 ||
120 event.button === 2) {
121 return;
122 }
123 let elm = event.target;
124 // traverse the DOM up to find first A tag
125 while (elm && elm.nodeName.toLowerCase() !== 'a') {
126 // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
127 if (elm === $rootElement[0] || !(elm = elm.parentNode)) {
128 return;
129 }
130 }
131 if (!isAnchor(elm)) {
132 return;
133 }
134 const absHref = elm.href;
135 const relHref = elm.getAttribute('href');
136 // Ignore when url is started with javascript: or mailto:
137 if (IGNORE_URI_REGEXP.test(absHref)) {
138 return;
139 }
140 if (absHref && !elm.getAttribute('target') && !event.isDefaultPrevented()) {
141 if (this.$$parseLinkUrl(absHref, relHref)) {
142 // We do a preventDefault for all urls that are part of the AngularJS application,
143 // in html5mode and also without, so that we are able to abort navigation without
144 // getting double entries in the location history.
145 event.preventDefault();
146 // update location manually
147 if (this.absUrl() !== this.browserUrl()) {
148 $rootScope.$apply();
149 }
150 }
151 }
152 });
153 this.urlChanges.subscribe(({ newUrl, newState }) => {
154 const oldUrl = this.absUrl();
155 const oldState = this.$$state;
156 this.$$parse(newUrl);
157 newUrl = this.absUrl();
158 this.$$state = newState;
159 const defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, newState, oldState)
160 .defaultPrevented;
161 // if the location was changed by a `$locationChangeStart` handler then stop
162 // processing this location change
163 if (this.absUrl() !== newUrl)
164 return;
165 // If default was prevented, set back to old state. This is the state that was locally
166 // cached in the $location service.
167 if (defaultPrevented) {
168 this.$$parse(oldUrl);
169 this.state(oldState);
170 this.setBrowserUrlWithFallback(oldUrl, false, oldState);
171 this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
172 }
173 else {
174 this.initalizing = false;
175 $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, newState, oldState);
176 this.resetBrowserUpdate();
177 }
178 if (!$rootScope.$$phase) {
179 $rootScope.$digest();
180 }
181 });
182 // update browser
183 $rootScope.$watch(() => {
184 if (this.initalizing || this.updateBrowser) {
185 this.updateBrowser = false;
186 const oldUrl = this.browserUrl();
187 const newUrl = this.absUrl();
188 const oldState = this.browserState();
189 let currentReplace = this.$$replace;
190 const urlOrStateChanged = !this.urlCodec.areEqual(oldUrl, newUrl) || oldState !== this.$$state;
191 // Fire location changes one time to on initialization. This must be done on the
192 // next tick (thus inside $evalAsync()) in order for listeners to be registered
193 // before the event fires. Mimicing behavior from $locationWatch:
194 // https://github.com/angular/angular.js/blob/master/src/ng/location.js#L983
195 if (this.initalizing || urlOrStateChanged) {
196 this.initalizing = false;
197 $rootScope.$evalAsync(() => {
198 // Get the new URL again since it could have changed due to async update
199 const newUrl = this.absUrl();
200 const defaultPrevented = $rootScope
201 .$broadcast('$locationChangeStart', newUrl, oldUrl, this.$$state, oldState)
202 .defaultPrevented;
203 // if the location was changed by a `$locationChangeStart` handler then stop
204 // processing this location change
205 if (this.absUrl() !== newUrl)
206 return;
207 if (defaultPrevented) {
208 this.$$parse(oldUrl);
209 this.$$state = oldState;
210 }
211 else {
212 // This block doesn't run when initalizing because it's going to perform the update to
213 // the URL which shouldn't be needed when initalizing.
214 if (urlOrStateChanged) {
215 this.setBrowserUrlWithFallback(newUrl, currentReplace, oldState === this.$$state ? null : this.$$state);
216 this.$$replace = false;
217 }
218 $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, this.$$state, oldState);
219 if (urlOrStateChanged) {
220 this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
221 }
222 }
223 });
224 }
225 }
226 this.$$replace = false;
227 });
228 }
229 resetBrowserUpdate() {
230 this.$$replace = false;
231 this.$$state = this.browserState();
232 this.updateBrowser = false;
233 this.lastBrowserUrl = this.browserUrl();
234 }
235 browserUrl(url, replace, state) {
236 // In modern browsers `history.state` is `null` by default; treating it separately
237 // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
238 // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
239 if (typeof state === 'undefined') {
240 state = null;
241 }
242 // setter
243 if (url) {
244 let sameState = this.lastHistoryState === state;
245 // Normalize the inputted URL
246 url = this.urlCodec.parse(url).href;
247 // Don't change anything if previous and current URLs and states match.
248 if (this.lastBrowserUrl === url && sameState) {
249 return this;
250 }
251 this.lastBrowserUrl = url;
252 this.lastHistoryState = state;
253 // Remove server base from URL as the Angular APIs for updating URL require
254 // it to be the path+.
255 url = this.stripBaseUrl(this.getServerBase(), url) || url;
256 // Set the URL
257 if (replace) {
258 this.locationStrategy.replaceState(state, '', url, '');
259 }
260 else {
261 this.locationStrategy.pushState(state, '', url, '');
262 }
263 this.cacheState();
264 return this;
265 // getter
266 }
267 else {
268 return this.platformLocation.href;
269 }
270 }
271 cacheState() {
272 // This should be the only place in $browser where `history.state` is read.
273 this.cachedState = this.platformLocation.getState();
274 if (typeof this.cachedState === 'undefined') {
275 this.cachedState = null;
276 }
277 // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
278 if (deepEqual(this.cachedState, this.lastCachedState)) {
279 this.cachedState = this.lastCachedState;
280 }
281 this.lastCachedState = this.cachedState;
282 this.lastHistoryState = this.cachedState;
283 }
284 /**
285 * This function emulates the $browser.state() function from AngularJS. It will cause
286 * history.state to be cached unless changed with deep equality check.
287 */
288 browserState() {
289 return this.cachedState;
290 }
291 stripBaseUrl(base, url) {
292 if (url.startsWith(base)) {
293 return url.substr(base.length);
294 }
295 return undefined;
296 }
297 getServerBase() {
298 const { protocol, hostname, port } = this.platformLocation;
299 const baseHref = this.locationStrategy.getBaseHref();
300 let url = `${protocol}//${hostname}${port ? ':' + port : ''}${baseHref || '/'}`;
301 return url.endsWith('/') ? url : url + '/';
302 }
303 parseAppUrl(url) {
304 if (DOUBLE_SLASH_REGEX.test(url)) {
305 throw new Error(`Bad Path - URL cannot start with double slashes: ${url}`);
306 }
307 let prefixed = (url.charAt(0) !== '/');
308 if (prefixed) {
309 url = '/' + url;
310 }
311 let match = this.urlCodec.parse(url, this.getServerBase());
312 if (typeof match === 'string') {
313 throw new Error(`Bad URL - Cannot parse URL: ${url}`);
314 }
315 let path = prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname;
316 this.$$path = this.urlCodec.decodePath(path);
317 this.$$search = this.urlCodec.decodeSearch(match.search);
318 this.$$hash = this.urlCodec.decodeHash(match.hash);
319 // make sure path starts with '/';
320 if (this.$$path && this.$$path.charAt(0) !== '/') {
321 this.$$path = '/' + this.$$path;
322 }
323 }
324 /**
325 * Registers listeners for URL changes. This API is used to catch updates performed by the
326 * AngularJS framework. These changes are a subset of the `$locationChangeStart` and
327 * `$locationChangeSuccess` events which fire when AngularJS updates its internally-referenced
328 * version of the browser URL.
329 *
330 * It's possible for `$locationChange` events to happen, but for the browser URL
331 * (window.location) to remain unchanged. This `onChange` callback will fire only when AngularJS
332 * actually updates the browser URL (window.location).
333 *
334 * @param fn The callback function that is triggered for the listener when the URL changes.
335 * @param err The callback function that is triggered when an error occurs.
336 */
337 onChange(fn, err = (e) => { }) {
338 this.$$changeListeners.push([fn, err]);
339 }
340 /** @internal */
341 $$notifyChangeListeners(url = '', state, oldUrl = '', oldState) {
342 this.$$changeListeners.forEach(([fn, err]) => {
343 try {
344 fn(url, state, oldUrl, oldState);
345 }
346 catch (e) {
347 err(e);
348 }
349 });
350 }
351 /**
352 * Parses the provided URL, and sets the current URL to the parsed result.
353 *
354 * @param url The URL string.
355 */
356 $$parse(url) {
357 let pathUrl;
358 if (url.startsWith('/')) {
359 pathUrl = url;
360 }
361 else {
362 // Remove protocol & hostname if URL starts with it
363 pathUrl = this.stripBaseUrl(this.getServerBase(), url);
364 }
365 if (typeof pathUrl === 'undefined') {
366 throw new Error(`Invalid url "${url}", missing path prefix "${this.getServerBase()}".`);
367 }
368 this.parseAppUrl(pathUrl);
369 if (!this.$$path) {
370 this.$$path = '/';
371 }
372 this.composeUrls();
373 }
374 /**
375 * Parses the provided URL and its relative URL.
376 *
377 * @param url The full URL string.
378 * @param relHref A URL string relative to the full URL string.
379 */
380 $$parseLinkUrl(url, relHref) {
381 // When relHref is passed, it should be a hash and is handled separately
382 if (relHref && relHref[0] === '#') {
383 this.hash(relHref.slice(1));
384 return true;
385 }
386 let rewrittenUrl;
387 let appUrl = this.stripBaseUrl(this.getServerBase(), url);
388 if (typeof appUrl !== 'undefined') {
389 rewrittenUrl = this.getServerBase() + appUrl;
390 }
391 else if (this.getServerBase() === url + '/') {
392 rewrittenUrl = this.getServerBase();
393 }
394 // Set the URL
395 if (rewrittenUrl) {
396 this.$$parse(rewrittenUrl);
397 }
398 return !!rewrittenUrl;
399 }
400 setBrowserUrlWithFallback(url, replace, state) {
401 const oldUrl = this.url();
402 const oldState = this.$$state;
403 try {
404 this.browserUrl(url, replace, state);
405 // Make sure $location.state() returns referentially identical (not just deeply equal)
406 // state object; this makes possible quick checking if the state changed in the digest
407 // loop. Checking deep equality would be too expensive.
408 this.$$state = this.browserState();
409 }
410 catch (e) {
411 // Restore old values if pushState fails
412 this.url(oldUrl);
413 this.$$state = oldState;
414 throw e;
415 }
416 }
417 composeUrls() {
418 this.$$url = this.urlCodec.normalize(this.$$path, this.$$search, this.$$hash);
419 this.$$absUrl = this.getServerBase() + this.$$url.substr(1); // remove '/' from front of URL
420 this.updateBrowser = true;
421 }
422 /**
423 * Retrieves the full URL representation with all segments encoded according to
424 * rules specified in
425 * [RFC 3986](https://tools.ietf.org/html/rfc3986).
426 *
427 *
428 * ```js
429 * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
430 * let absUrl = $location.absUrl();
431 * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
432 * ```
433 */
434 absUrl() {
435 return this.$$absUrl;
436 }
437 url(url) {
438 if (typeof url === 'string') {
439 if (!url.length) {
440 url = '/';
441 }
442 const match = PATH_MATCH.exec(url);
443 if (!match)
444 return this;
445 if (match[1] || url === '')
446 this.path(this.urlCodec.decodePath(match[1]));
447 if (match[2] || match[1] || url === '')
448 this.search(match[3] || '');
449 this.hash(match[5] || '');
450 // Chainable method
451 return this;
452 }
453 return this.$$url;
454 }
455 /**
456 * Retrieves the protocol of the current URL.
457 *
458 * ```js
459 * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
460 * let protocol = $location.protocol();
461 * // => "http"
462 * ```
463 */
464 protocol() {
465 return this.$$protocol;
466 }
467 /**
468 * Retrieves the protocol of the current URL.
469 *
470 * In contrast to the non-AngularJS version `location.host` which returns `hostname:port`, this
471 * returns the `hostname` portion only.
472 *
473 *
474 * ```js
475 * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
476 * let host = $location.host();
477 * // => "example.com"
478 *
479 * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
480 * host = $location.host();
481 * // => "example.com"
482 * host = location.host;
483 * // => "example.com:8080"
484 * ```
485 */
486 host() {
487 return this.$$host;
488 }
489 /**
490 * Retrieves the port of the current URL.
491 *
492 * ```js
493 * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
494 * let port = $location.port();
495 * // => 80
496 * ```
497 */
498 port() {
499 return this.$$port;
500 }
501 path(path) {
502 if (typeof path === 'undefined') {
503 return this.$$path;
504 }
505 // null path converts to empty string. Prepend with "/" if needed.
506 path = path !== null ? path.toString() : '';
507 path = path.charAt(0) === '/' ? path : '/' + path;
508 this.$$path = path;
509 this.composeUrls();
510 return this;
511 }
512 search(search, paramValue) {
513 switch (arguments.length) {
514 case 0:
515 return this.$$search;
516 case 1:
517 if (typeof search === 'string' || typeof search === 'number') {
518 this.$$search = this.urlCodec.decodeSearch(search.toString());
519 }
520 else if (typeof search === 'object' && search !== null) {
521 // Copy the object so it's never mutated
522 search = Object.assign({}, search);
523 // remove object undefined or null properties
524 for (const key in search) {
525 if (search[key] == null)
526 delete search[key];
527 }
528 this.$$search = search;
529 }
530 else {
531 throw new Error('LocationProvider.search(): First argument must be a string or an object.');
532 }
533 break;
534 default:
535 if (typeof search === 'string') {
536 const currentSearch = this.search();
537 if (typeof paramValue === 'undefined' || paramValue === null) {
538 delete currentSearch[search];
539 return this.search(currentSearch);
540 }
541 else {
542 currentSearch[search] = paramValue;
543 return this.search(currentSearch);
544 }
545 }
546 }
547 this.composeUrls();
548 return this;
549 }
550 hash(hash) {
551 if (typeof hash === 'undefined') {
552 return this.$$hash;
553 }
554 this.$$hash = hash !== null ? hash.toString() : '';
555 this.composeUrls();
556 return this;
557 }
558 /**
559 * Changes to `$location` during the current `$digest` will replace the current
560 * history record, instead of adding a new one.
561 */
562 replace() {
563 this.$$replace = true;
564 return this;
565 }
566 state(state) {
567 if (typeof state === 'undefined') {
568 return this.$$state;
569 }
570 this.$$state = state;
571 return this;
572 }
573}
574/**
575 * The factory function used to create an instance of the `$locationShim` in Angular,
576 * and provides an API-compatiable `$locationProvider` for AngularJS.
577 *
578 * @publicApi
579 */
580class $locationShimProvider {
581 constructor(ngUpgrade, location, platformLocation, urlCodec, locationStrategy) {
582 this.ngUpgrade = ngUpgrade;
583 this.location = location;
584 this.platformLocation = platformLocation;
585 this.urlCodec = urlCodec;
586 this.locationStrategy = locationStrategy;
587 }
588 /**
589 * Factory method that returns an instance of the $locationShim
590 */
591 $get() {
592 return new $locationShim(this.ngUpgrade.$injector, this.location, this.platformLocation, this.urlCodec, this.locationStrategy);
593 }
594 /**
595 * Stub method used to keep API compatible with AngularJS. This setting is configured through
596 * the LocationUpgradeModule's `config` method in your Angular app.
597 */
598 hashPrefix(prefix) {
599 throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
600 }
601 /**
602 * Stub method used to keep API compatible with AngularJS. This setting is configured through
603 * the LocationUpgradeModule's `config` method in your Angular app.
604 */
605 html5Mode(mode) {
606 throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
607 }
608}
609
610/**
611 * @license
612 * Copyright Google LLC All Rights Reserved.
613 *
614 * Use of this source code is governed by an MIT-style license that can be
615 * found in the LICENSE file at https://angular.io/license
616 */
617/**
618 * A codec for encoding and decoding URL parts.
619 *
620 * @publicApi
621 **/
622class UrlCodec {
623}
624/**
625 * A `UrlCodec` that uses logic from AngularJS to serialize and parse URLs
626 * and URL parameters.
627 *
628 * @publicApi
629 */
630class AngularJSUrlCodec {
631 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L15
632 encodePath(path) {
633 const segments = path.split('/');
634 let i = segments.length;
635 while (i--) {
636 // decode forward slashes to prevent them from being double encoded
637 segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, '/'));
638 }
639 path = segments.join('/');
640 return _stripIndexHtml((path && path[0] !== '/' && '/' || '') + path);
641 }
642 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L42
643 encodeSearch(search) {
644 if (typeof search === 'string') {
645 search = parseKeyValue(search);
646 }
647 search = toKeyValue(search);
648 return search ? '?' + search : '';
649 }
650 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L44
651 encodeHash(hash) {
652 hash = encodeUriSegment(hash);
653 return hash ? '#' + hash : '';
654 }
655 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L27
656 decodePath(path, html5Mode = true) {
657 const segments = path.split('/');
658 let i = segments.length;
659 while (i--) {
660 segments[i] = decodeURIComponent(segments[i]);
661 if (html5Mode) {
662 // encode forward slashes to prevent them from being mistaken for path separators
663 segments[i] = segments[i].replace(/\//g, '%2F');
664 }
665 }
666 return segments.join('/');
667 }
668 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L72
669 decodeSearch(search) {
670 return parseKeyValue(search);
671 }
672 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L73
673 decodeHash(hash) {
674 hash = decodeURIComponent(hash);
675 return hash[0] === '#' ? hash.substring(1) : hash;
676 }
677 normalize(pathOrHref, search, hash, baseUrl) {
678 if (arguments.length === 1) {
679 const parsed = this.parse(pathOrHref, baseUrl);
680 if (typeof parsed === 'string') {
681 return parsed;
682 }
683 const serverUrl = `${parsed.protocol}://${parsed.hostname}${parsed.port ? ':' + parsed.port : ''}`;
684 return this.normalize(this.decodePath(parsed.pathname), this.decodeSearch(parsed.search), this.decodeHash(parsed.hash), serverUrl);
685 }
686 else {
687 const encPath = this.encodePath(pathOrHref);
688 const encSearch = search && this.encodeSearch(search) || '';
689 const encHash = hash && this.encodeHash(hash) || '';
690 let joinedPath = (baseUrl || '') + encPath;
691 if (!joinedPath.length || joinedPath[0] !== '/') {
692 joinedPath = '/' + joinedPath;
693 }
694 return joinedPath + encSearch + encHash;
695 }
696 }
697 areEqual(valA, valB) {
698 return this.normalize(valA) === this.normalize(valB);
699 }
700 // https://github.com/angular/angular.js/blob/864c7f0/src/ng/urlUtils.js#L60
701 parse(url, base) {
702 try {
703 // Safari 12 throws an error when the URL constructor is called with an undefined base.
704 const parsed = !base ? new URL(url) : new URL(url, base);
705 return {
706 href: parsed.href,
707 protocol: parsed.protocol ? parsed.protocol.replace(/:$/, '') : '',
708 host: parsed.host,
709 search: parsed.search ? parsed.search.replace(/^\?/, '') : '',
710 hash: parsed.hash ? parsed.hash.replace(/^#/, '') : '',
711 hostname: parsed.hostname,
712 port: parsed.port,
713 pathname: (parsed.pathname.charAt(0) === '/') ? parsed.pathname : '/' + parsed.pathname
714 };
715 }
716 catch (e) {
717 throw new Error(`Invalid URL (${url}) with base (${base})`);
718 }
719 }
720}
721function _stripIndexHtml(url) {
722 return url.replace(/\/index.html$/, '');
723}
724/**
725 * Tries to decode the URI component without throwing an exception.
726 *
727 * @param str value potential URI component to check.
728 * @returns the decoded URI if it can be decoded or else `undefined`.
729 */
730function tryDecodeURIComponent(value) {
731 try {
732 return decodeURIComponent(value);
733 }
734 catch (e) {
735 // Ignore any invalid uri component.
736 return undefined;
737 }
738}
739/**
740 * Parses an escaped url query string into key-value pairs. Logic taken from
741 * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1382
742 */
743function parseKeyValue(keyValue) {
744 const obj = {};
745 (keyValue || '').split('&').forEach((keyValue) => {
746 let splitPoint, key, val;
747 if (keyValue) {
748 key = keyValue = keyValue.replace(/\+/g, '%20');
749 splitPoint = keyValue.indexOf('=');
750 if (splitPoint !== -1) {
751 key = keyValue.substring(0, splitPoint);
752 val = keyValue.substring(splitPoint + 1);
753 }
754 key = tryDecodeURIComponent(key);
755 if (typeof key !== 'undefined') {
756 val = typeof val !== 'undefined' ? tryDecodeURIComponent(val) : true;
757 if (!obj.hasOwnProperty(key)) {
758 obj[key] = val;
759 }
760 else if (Array.isArray(obj[key])) {
761 obj[key].push(val);
762 }
763 else {
764 obj[key] = [obj[key], val];
765 }
766 }
767 }
768 });
769 return obj;
770}
771/**
772 * Serializes into key-value pairs. Logic taken from
773 * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1409
774 */
775function toKeyValue(obj) {
776 const parts = [];
777 for (const key in obj) {
778 let value = obj[key];
779 if (Array.isArray(value)) {
780 value.forEach((arrayValue) => {
781 parts.push(encodeUriQuery(key, true) +
782 (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
783 });
784 }
785 else {
786 parts.push(encodeUriQuery(key, true) +
787 (value === true ? '' : '=' + encodeUriQuery(value, true)));
788 }
789 }
790 return parts.length ? parts.join('&') : '';
791}
792/**
793 * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
794 * https://tools.ietf.org/html/rfc3986 with regards to the character set (pchar) allowed in path
795 * segments:
796 * segment = *pchar
797 * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
798 * pct-encoded = "%" HEXDIG HEXDIG
799 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
800 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
801 * / "*" / "+" / "," / ";" / "="
802 *
803 * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1437
804 */
805function encodeUriSegment(val) {
806 return encodeUriQuery(val, true).replace(/%26/g, '&').replace(/%3D/gi, '=').replace(/%2B/gi, '+');
807}
808/**
809 * This method is intended for encoding *key* or *value* parts of query component. We need a custom
810 * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
811 * encoded per https://tools.ietf.org/html/rfc3986:
812 * query = *( pchar / "/" / "?" )
813 * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
814 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
815 * pct-encoded = "%" HEXDIG HEXDIG
816 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
817 * / "*" / "+" / "," / ";" / "="
818 *
819 * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1456
820 */
821function encodeUriQuery(val, pctEncodeSpaces = false) {
822 return encodeURIComponent(val)
823 .replace(/%40/g, '@')
824 .replace(/%3A/gi, ':')
825 .replace(/%24/g, '$')
826 .replace(/%2C/gi, ',')
827 .replace(/%3B/gi, ';')
828 .replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
829}
830
831/**
832 * @license
833 * Copyright Google LLC All Rights Reserved.
834 *
835 * Use of this source code is governed by an MIT-style license that can be
836 * found in the LICENSE file at https://angular.io/license
837 */
838/**
839 * A provider token used to configure the location upgrade module.
840 *
841 * @publicApi
842 */
843const LOCATION_UPGRADE_CONFIGURATION = new InjectionToken('LOCATION_UPGRADE_CONFIGURATION');
844const APP_BASE_HREF_RESOLVED = new InjectionToken('APP_BASE_HREF_RESOLVED');
845/**
846 * `NgModule` used for providing and configuring Angular's Unified Location Service for upgrading.
847 *
848 * @see [Using the Unified Angular Location Service](guide/upgrade#using-the-unified-angular-location-service)
849 *
850 * @publicApi
851 */
852class LocationUpgradeModule {
853 static config(config) {
854 return {
855 ngModule: LocationUpgradeModule,
856 providers: [
857 Location,
858 {
859 provide: $locationShim,
860 useFactory: provide$location,
861 deps: [UpgradeModule, Location, PlatformLocation, UrlCodec, LocationStrategy]
862 },
863 { provide: LOCATION_UPGRADE_CONFIGURATION, useValue: config ? config : {} },
864 { provide: UrlCodec, useFactory: provideUrlCodec, deps: [LOCATION_UPGRADE_CONFIGURATION] },
865 {
866 provide: APP_BASE_HREF_RESOLVED,
867 useFactory: provideAppBaseHref,
868 deps: [LOCATION_UPGRADE_CONFIGURATION, [new Inject(APP_BASE_HREF), new Optional()]]
869 },
870 {
871 provide: LocationStrategy,
872 useFactory: provideLocationStrategy,
873 deps: [
874 PlatformLocation,
875 APP_BASE_HREF_RESOLVED,
876 LOCATION_UPGRADE_CONFIGURATION,
877 ]
878 },
879 ],
880 };
881 }
882}
883LocationUpgradeModule.decorators = [
884 { type: NgModule, args: [{ imports: [CommonModule] },] }
885];
886function provideAppBaseHref(config, appBaseHref) {
887 if (config && config.appBaseHref != null) {
888 return config.appBaseHref;
889 }
890 else if (appBaseHref != null) {
891 return appBaseHref;
892 }
893 return '';
894}
895function provideUrlCodec(config) {
896 const codec = config && config.urlCodec || AngularJSUrlCodec;
897 return new codec();
898}
899function provideLocationStrategy(platformLocation, baseHref, options = {}) {
900 return options.useHash ? new HashLocationStrategy(platformLocation, baseHref) :
901 new PathLocationStrategy(platformLocation, baseHref);
902}
903function provide$location(ngUpgrade, location, platformLocation, urlCodec, locationStrategy) {
904 const $locationProvider = new $locationShimProvider(ngUpgrade, location, platformLocation, urlCodec, locationStrategy);
905 return $locationProvider.$get();
906}
907
908/**
909 * @license
910 * Copyright Google LLC All Rights Reserved.
911 *
912 * Use of this source code is governed by an MIT-style license that can be
913 * found in the LICENSE file at https://angular.io/license
914 */
915
916/**
917 * @license
918 * Copyright Google LLC All Rights Reserved.
919 *
920 * Use of this source code is governed by an MIT-style license that can be
921 * found in the LICENSE file at https://angular.io/license
922 */
923// This file only reexports content of the `src` folder. Keep it that way.
924
925/**
926 * @license
927 * Copyright Google LLC All Rights Reserved.
928 *
929 * Use of this source code is governed by an MIT-style license that can be
930 * found in the LICENSE file at https://angular.io/license
931 */
932
933/**
934 * Generated bundle index. Do not edit.
935 */
936
937export { $locationShim, $locationShimProvider, AngularJSUrlCodec, LOCATION_UPGRADE_CONFIGURATION, LocationUpgradeModule, UrlCodec, provideAppBaseHref as ɵangular_packages_common_upgrade_upgrade_a, provideUrlCodec as ɵangular_packages_common_upgrade_upgrade_b, provideLocationStrategy as ɵangular_packages_common_upgrade_upgrade_c, provide$location as ɵangular_packages_common_upgrade_upgrade_d };
938//# sourceMappingURL=upgrade.js.map
Note: See TracBrowser for help on using the repository browser.