123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894 |
- /**
- * @license Angular v16.2.9
- * (c) 2010-2022 Google LLC. https://angular.io/
- * License: MIT
- */
- import * as i0 from '@angular/core';
- import { ɵisPromise, InjectionToken, Inject, Optional, NgModule } from '@angular/core';
- import { ReplaySubject } from 'rxjs';
- import { Location, PlatformLocation, LocationStrategy, APP_BASE_HREF, CommonModule, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
- import { UpgradeModule } from '@angular/upgrade/static';
- function stripPrefix(val, prefix) {
- return val.startsWith(prefix) ? val.substring(prefix.length) : val;
- }
- function deepEqual(a, b) {
- if (a === b) {
- return true;
- }
- else if (!a || !b) {
- return false;
- }
- else {
- try {
- if ((a.prototype !== b.prototype) || (Array.isArray(a) && Array.isArray(b))) {
- return false;
- }
- return JSON.stringify(a) === JSON.stringify(b);
- }
- catch (e) {
- return false;
- }
- }
- }
- function isAnchor(el) {
- return el.href !== undefined;
- }
- const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
- const DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
- const IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
- const DEFAULT_PORTS = {
- 'http:': 80,
- 'https:': 443,
- 'ftp:': 21
- };
- /**
- * Location service that provides a drop-in replacement for the $location service
- * provided in AngularJS.
- *
- * @see [Using the Angular Unified Location Service](guide/upgrade#using-the-unified-angular-location-service)
- *
- * @publicApi
- */
- class $locationShim {
- constructor($injector, location, platformLocation, urlCodec, locationStrategy) {
- this.location = location;
- this.platformLocation = platformLocation;
- this.urlCodec = urlCodec;
- this.locationStrategy = locationStrategy;
- this.initializing = true;
- this.updateBrowser = false;
- this.$$absUrl = '';
- this.$$url = '';
- this.$$host = '';
- this.$$replace = false;
- this.$$path = '';
- this.$$search = '';
- this.$$hash = '';
- this.$$changeListeners = [];
- this.cachedState = null;
- this.urlChanges = new ReplaySubject(1);
- this.lastBrowserUrl = '';
- // This variable should be used *only* inside the cacheState function.
- this.lastCachedState = null;
- const initialUrl = this.browserUrl();
- let parsedUrl = this.urlCodec.parse(initialUrl);
- if (typeof parsedUrl === 'string') {
- throw 'Invalid URL';
- }
- this.$$protocol = parsedUrl.protocol;
- this.$$host = parsedUrl.hostname;
- this.$$port = parseInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
- this.$$parseLinkUrl(initialUrl, initialUrl);
- this.cacheState();
- this.$$state = this.browserState();
- this.location.onUrlChange((newUrl, newState) => {
- this.urlChanges.next({ newUrl, newState });
- });
- if (ɵisPromise($injector)) {
- $injector.then($i => this.initialize($i));
- }
- else {
- this.initialize($injector);
- }
- }
- initialize($injector) {
- const $rootScope = $injector.get('$rootScope');
- const $rootElement = $injector.get('$rootElement');
- $rootElement.on('click', (event) => {
- if (event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 ||
- event.button === 2) {
- return;
- }
- let elm = event.target;
- // traverse the DOM up to find first A tag
- while (elm && elm.nodeName.toLowerCase() !== 'a') {
- // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
- if (elm === $rootElement[0] || !(elm = elm.parentNode)) {
- return;
- }
- }
- if (!isAnchor(elm)) {
- return;
- }
- const absHref = elm.href;
- const relHref = elm.getAttribute('href');
- // Ignore when url is started with javascript: or mailto:
- if (IGNORE_URI_REGEXP.test(absHref)) {
- return;
- }
- if (absHref && !elm.getAttribute('target') && !event.isDefaultPrevented()) {
- if (this.$$parseLinkUrl(absHref, relHref)) {
- // We do a preventDefault for all urls that are part of the AngularJS application,
- // in html5mode and also without, so that we are able to abort navigation without
- // getting double entries in the location history.
- event.preventDefault();
- // update location manually
- if (this.absUrl() !== this.browserUrl()) {
- $rootScope.$apply();
- }
- }
- }
- });
- this.urlChanges.subscribe(({ newUrl, newState }) => {
- const oldUrl = this.absUrl();
- const oldState = this.$$state;
- this.$$parse(newUrl);
- newUrl = this.absUrl();
- this.$$state = newState;
- const defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, newState, oldState)
- .defaultPrevented;
- // if the location was changed by a `$locationChangeStart` handler then stop
- // processing this location change
- if (this.absUrl() !== newUrl)
- return;
- // If default was prevented, set back to old state. This is the state that was locally
- // cached in the $location service.
- if (defaultPrevented) {
- this.$$parse(oldUrl);
- this.state(oldState);
- this.setBrowserUrlWithFallback(oldUrl, false, oldState);
- this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
- }
- else {
- this.initializing = false;
- $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, newState, oldState);
- this.resetBrowserUpdate();
- }
- if (!$rootScope.$$phase) {
- $rootScope.$digest();
- }
- });
- // update browser
- $rootScope.$watch(() => {
- if (this.initializing || this.updateBrowser) {
- this.updateBrowser = false;
- const oldUrl = this.browserUrl();
- const newUrl = this.absUrl();
- const oldState = this.browserState();
- let currentReplace = this.$$replace;
- const urlOrStateChanged = !this.urlCodec.areEqual(oldUrl, newUrl) || oldState !== this.$$state;
- // Fire location changes one time to on initialization. This must be done on the
- // next tick (thus inside $evalAsync()) in order for listeners to be registered
- // before the event fires. Mimicing behavior from $locationWatch:
- // https://github.com/angular/angular.js/blob/master/src/ng/location.js#L983
- if (this.initializing || urlOrStateChanged) {
- this.initializing = false;
- $rootScope.$evalAsync(() => {
- // Get the new URL again since it could have changed due to async update
- const newUrl = this.absUrl();
- const defaultPrevented = $rootScope
- .$broadcast('$locationChangeStart', newUrl, oldUrl, this.$$state, oldState)
- .defaultPrevented;
- // if the location was changed by a `$locationChangeStart` handler then stop
- // processing this location change
- if (this.absUrl() !== newUrl)
- return;
- if (defaultPrevented) {
- this.$$parse(oldUrl);
- this.$$state = oldState;
- }
- else {
- // This block doesn't run when initializing because it's going to perform the update
- // to the URL which shouldn't be needed when initializing.
- if (urlOrStateChanged) {
- this.setBrowserUrlWithFallback(newUrl, currentReplace, oldState === this.$$state ? null : this.$$state);
- this.$$replace = false;
- }
- $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, this.$$state, oldState);
- if (urlOrStateChanged) {
- this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
- }
- }
- });
- }
- }
- this.$$replace = false;
- });
- }
- resetBrowserUpdate() {
- this.$$replace = false;
- this.$$state = this.browserState();
- this.updateBrowser = false;
- this.lastBrowserUrl = this.browserUrl();
- }
- browserUrl(url, replace, state) {
- // In modern browsers `history.state` is `null` by default; treating it separately
- // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
- // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
- if (typeof state === 'undefined') {
- state = null;
- }
- // setter
- if (url) {
- let sameState = this.lastHistoryState === state;
- // Normalize the inputted URL
- url = this.urlCodec.parse(url).href;
- // Don't change anything if previous and current URLs and states match.
- if (this.lastBrowserUrl === url && sameState) {
- return this;
- }
- this.lastBrowserUrl = url;
- this.lastHistoryState = state;
- // Remove server base from URL as the Angular APIs for updating URL require
- // it to be the path+.
- url = this.stripBaseUrl(this.getServerBase(), url) || url;
- // Set the URL
- if (replace) {
- this.locationStrategy.replaceState(state, '', url, '');
- }
- else {
- this.locationStrategy.pushState(state, '', url, '');
- }
- this.cacheState();
- return this;
- // getter
- }
- else {
- return this.platformLocation.href;
- }
- }
- cacheState() {
- // This should be the only place in $browser where `history.state` is read.
- this.cachedState = this.platformLocation.getState();
- if (typeof this.cachedState === 'undefined') {
- this.cachedState = null;
- }
- // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
- if (deepEqual(this.cachedState, this.lastCachedState)) {
- this.cachedState = this.lastCachedState;
- }
- this.lastCachedState = this.cachedState;
- this.lastHistoryState = this.cachedState;
- }
- /**
- * This function emulates the $browser.state() function from AngularJS. It will cause
- * history.state to be cached unless changed with deep equality check.
- */
- browserState() {
- return this.cachedState;
- }
- stripBaseUrl(base, url) {
- if (url.startsWith(base)) {
- return url.slice(base.length);
- }
- return undefined;
- }
- getServerBase() {
- const { protocol, hostname, port } = this.platformLocation;
- const baseHref = this.locationStrategy.getBaseHref();
- let url = `${protocol}//${hostname}${port ? ':' + port : ''}${baseHref || '/'}`;
- return url.endsWith('/') ? url : url + '/';
- }
- parseAppUrl(url) {
- if (DOUBLE_SLASH_REGEX.test(url)) {
- throw new Error(`Bad Path - URL cannot start with double slashes: ${url}`);
- }
- let prefixed = (url.charAt(0) !== '/');
- if (prefixed) {
- url = '/' + url;
- }
- let match = this.urlCodec.parse(url, this.getServerBase());
- if (typeof match === 'string') {
- throw new Error(`Bad URL - Cannot parse URL: ${url}`);
- }
- let path = prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname;
- this.$$path = this.urlCodec.decodePath(path);
- this.$$search = this.urlCodec.decodeSearch(match.search);
- this.$$hash = this.urlCodec.decodeHash(match.hash);
- // make sure path starts with '/';
- if (this.$$path && this.$$path.charAt(0) !== '/') {
- this.$$path = '/' + this.$$path;
- }
- }
- /**
- * Registers listeners for URL changes. This API is used to catch updates performed by the
- * AngularJS framework. These changes are a subset of the `$locationChangeStart` and
- * `$locationChangeSuccess` events which fire when AngularJS updates its internally-referenced
- * version of the browser URL.
- *
- * It's possible for `$locationChange` events to happen, but for the browser URL
- * (window.location) to remain unchanged. This `onChange` callback will fire only when AngularJS
- * actually updates the browser URL (window.location).
- *
- * @param fn The callback function that is triggered for the listener when the URL changes.
- * @param err The callback function that is triggered when an error occurs.
- */
- onChange(fn, err = (e) => { }) {
- this.$$changeListeners.push([fn, err]);
- }
- /** @internal */
- $$notifyChangeListeners(url = '', state, oldUrl = '', oldState) {
- this.$$changeListeners.forEach(([fn, err]) => {
- try {
- fn(url, state, oldUrl, oldState);
- }
- catch (e) {
- err(e);
- }
- });
- }
- /**
- * Parses the provided URL, and sets the current URL to the parsed result.
- *
- * @param url The URL string.
- */
- $$parse(url) {
- let pathUrl;
- if (url.startsWith('/')) {
- pathUrl = url;
- }
- else {
- // Remove protocol & hostname if URL starts with it
- pathUrl = this.stripBaseUrl(this.getServerBase(), url);
- }
- if (typeof pathUrl === 'undefined') {
- throw new Error(`Invalid url "${url}", missing path prefix "${this.getServerBase()}".`);
- }
- this.parseAppUrl(pathUrl);
- if (!this.$$path) {
- this.$$path = '/';
- }
- this.composeUrls();
- }
- /**
- * Parses the provided URL and its relative URL.
- *
- * @param url The full URL string.
- * @param relHref A URL string relative to the full URL string.
- */
- $$parseLinkUrl(url, relHref) {
- // When relHref is passed, it should be a hash and is handled separately
- if (relHref && relHref[0] === '#') {
- this.hash(relHref.slice(1));
- return true;
- }
- let rewrittenUrl;
- let appUrl = this.stripBaseUrl(this.getServerBase(), url);
- if (typeof appUrl !== 'undefined') {
- rewrittenUrl = this.getServerBase() + appUrl;
- }
- else if (this.getServerBase() === url + '/') {
- rewrittenUrl = this.getServerBase();
- }
- // Set the URL
- if (rewrittenUrl) {
- this.$$parse(rewrittenUrl);
- }
- return !!rewrittenUrl;
- }
- setBrowserUrlWithFallback(url, replace, state) {
- const oldUrl = this.url();
- const oldState = this.$$state;
- try {
- this.browserUrl(url, replace, state);
- // Make sure $location.state() returns referentially identical (not just deeply equal)
- // state object; this makes possible quick checking if the state changed in the digest
- // loop. Checking deep equality would be too expensive.
- this.$$state = this.browserState();
- }
- catch (e) {
- // Restore old values if pushState fails
- this.url(oldUrl);
- this.$$state = oldState;
- throw e;
- }
- }
- composeUrls() {
- this.$$url = this.urlCodec.normalize(this.$$path, this.$$search, this.$$hash);
- this.$$absUrl = this.getServerBase() + this.$$url.slice(1); // remove '/' from front of URL
- this.updateBrowser = true;
- }
- /**
- * Retrieves the full URL representation with all segments encoded according to
- * rules specified in
- * [RFC 3986](https://tools.ietf.org/html/rfc3986).
- *
- *
- * ```js
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
- * let absUrl = $location.absUrl();
- * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
- * ```
- */
- absUrl() {
- return this.$$absUrl;
- }
- url(url) {
- if (typeof url === 'string') {
- if (!url.length) {
- url = '/';
- }
- const match = PATH_MATCH.exec(url);
- if (!match)
- return this;
- if (match[1] || url === '')
- this.path(this.urlCodec.decodePath(match[1]));
- if (match[2] || match[1] || url === '')
- this.search(match[3] || '');
- this.hash(match[5] || '');
- // Chainable method
- return this;
- }
- return this.$$url;
- }
- /**
- * Retrieves the protocol of the current URL.
- *
- * ```js
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
- * let protocol = $location.protocol();
- * // => "http"
- * ```
- */
- protocol() {
- return this.$$protocol;
- }
- /**
- * Retrieves the protocol of the current URL.
- *
- * In contrast to the non-AngularJS version `location.host` which returns `hostname:port`, this
- * returns the `hostname` portion only.
- *
- *
- * ```js
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
- * let host = $location.host();
- * // => "example.com"
- *
- * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
- * host = $location.host();
- * // => "example.com"
- * host = location.host;
- * // => "example.com:8080"
- * ```
- */
- host() {
- return this.$$host;
- }
- /**
- * Retrieves the port of the current URL.
- *
- * ```js
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
- * let port = $location.port();
- * // => 80
- * ```
- */
- port() {
- return this.$$port;
- }
- path(path) {
- if (typeof path === 'undefined') {
- return this.$$path;
- }
- // null path converts to empty string. Prepend with "/" if needed.
- path = path !== null ? path.toString() : '';
- path = path.charAt(0) === '/' ? path : '/' + path;
- this.$$path = path;
- this.composeUrls();
- return this;
- }
- search(search, paramValue) {
- switch (arguments.length) {
- case 0:
- return this.$$search;
- case 1:
- if (typeof search === 'string' || typeof search === 'number') {
- this.$$search = this.urlCodec.decodeSearch(search.toString());
- }
- else if (typeof search === 'object' && search !== null) {
- // Copy the object so it's never mutated
- search = { ...search };
- // remove object undefined or null properties
- for (const key in search) {
- if (search[key] == null)
- delete search[key];
- }
- this.$$search = search;
- }
- else {
- throw new Error('LocationProvider.search(): First argument must be a string or an object.');
- }
- break;
- default:
- if (typeof search === 'string') {
- const currentSearch = this.search();
- if (typeof paramValue === 'undefined' || paramValue === null) {
- delete currentSearch[search];
- return this.search(currentSearch);
- }
- else {
- currentSearch[search] = paramValue;
- return this.search(currentSearch);
- }
- }
- }
- this.composeUrls();
- return this;
- }
- hash(hash) {
- if (typeof hash === 'undefined') {
- return this.$$hash;
- }
- this.$$hash = hash !== null ? hash.toString() : '';
- this.composeUrls();
- return this;
- }
- /**
- * Changes to `$location` during the current `$digest` will replace the current
- * history record, instead of adding a new one.
- */
- replace() {
- this.$$replace = true;
- return this;
- }
- state(state) {
- if (typeof state === 'undefined') {
- return this.$$state;
- }
- this.$$state = state;
- return this;
- }
- }
- /**
- * The factory function used to create an instance of the `$locationShim` in Angular,
- * and provides an API-compatible `$locationProvider` for AngularJS.
- *
- * @publicApi
- */
- class $locationShimProvider {
- constructor(ngUpgrade, location, platformLocation, urlCodec, locationStrategy) {
- this.ngUpgrade = ngUpgrade;
- this.location = location;
- this.platformLocation = platformLocation;
- this.urlCodec = urlCodec;
- this.locationStrategy = locationStrategy;
- }
- /**
- * Factory method that returns an instance of the $locationShim
- */
- $get() {
- return new $locationShim(this.ngUpgrade.$injector, this.location, this.platformLocation, this.urlCodec, this.locationStrategy);
- }
- /**
- * Stub method used to keep API compatible with AngularJS. This setting is configured through
- * the LocationUpgradeModule's `config` method in your Angular app.
- */
- hashPrefix(prefix) {
- throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
- }
- /**
- * Stub method used to keep API compatible with AngularJS. This setting is configured through
- * the LocationUpgradeModule's `config` method in your Angular app.
- */
- html5Mode(mode) {
- throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
- }
- }
- /**
- * A codec for encoding and decoding URL parts.
- *
- * @publicApi
- **/
- class UrlCodec {
- }
- /**
- * A `UrlCodec` that uses logic from AngularJS to serialize and parse URLs
- * and URL parameters.
- *
- * @publicApi
- */
- class AngularJSUrlCodec {
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L15
- encodePath(path) {
- const segments = path.split('/');
- let i = segments.length;
- while (i--) {
- // decode forward slashes to prevent them from being double encoded
- segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, '/'));
- }
- path = segments.join('/');
- return _stripIndexHtml((path && path[0] !== '/' && '/' || '') + path);
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L42
- encodeSearch(search) {
- if (typeof search === 'string') {
- search = parseKeyValue(search);
- }
- search = toKeyValue(search);
- return search ? '?' + search : '';
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L44
- encodeHash(hash) {
- hash = encodeUriSegment(hash);
- return hash ? '#' + hash : '';
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L27
- decodePath(path, html5Mode = true) {
- const segments = path.split('/');
- let i = segments.length;
- while (i--) {
- segments[i] = decodeURIComponent(segments[i]);
- if (html5Mode) {
- // encode forward slashes to prevent them from being mistaken for path separators
- segments[i] = segments[i].replace(/\//g, '%2F');
- }
- }
- return segments.join('/');
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L72
- decodeSearch(search) {
- return parseKeyValue(search);
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L73
- decodeHash(hash) {
- hash = decodeURIComponent(hash);
- return hash[0] === '#' ? hash.substring(1) : hash;
- }
- normalize(pathOrHref, search, hash, baseUrl) {
- if (arguments.length === 1) {
- const parsed = this.parse(pathOrHref, baseUrl);
- if (typeof parsed === 'string') {
- return parsed;
- }
- const serverUrl = `${parsed.protocol}://${parsed.hostname}${parsed.port ? ':' + parsed.port : ''}`;
- return this.normalize(this.decodePath(parsed.pathname), this.decodeSearch(parsed.search), this.decodeHash(parsed.hash), serverUrl);
- }
- else {
- const encPath = this.encodePath(pathOrHref);
- const encSearch = search && this.encodeSearch(search) || '';
- const encHash = hash && this.encodeHash(hash) || '';
- let joinedPath = (baseUrl || '') + encPath;
- if (!joinedPath.length || joinedPath[0] !== '/') {
- joinedPath = '/' + joinedPath;
- }
- return joinedPath + encSearch + encHash;
- }
- }
- areEqual(valA, valB) {
- return this.normalize(valA) === this.normalize(valB);
- }
- // https://github.com/angular/angular.js/blob/864c7f0/src/ng/urlUtils.js#L60
- parse(url, base) {
- try {
- // Safari 12 throws an error when the URL constructor is called with an undefined base.
- const parsed = !base ? new URL(url) : new URL(url, base);
- return {
- href: parsed.href,
- protocol: parsed.protocol ? parsed.protocol.replace(/:$/, '') : '',
- host: parsed.host,
- search: parsed.search ? parsed.search.replace(/^\?/, '') : '',
- hash: parsed.hash ? parsed.hash.replace(/^#/, '') : '',
- hostname: parsed.hostname,
- port: parsed.port,
- pathname: (parsed.pathname.charAt(0) === '/') ? parsed.pathname : '/' + parsed.pathname
- };
- }
- catch (e) {
- throw new Error(`Invalid URL (${url}) with base (${base})`);
- }
- }
- }
- function _stripIndexHtml(url) {
- return url.replace(/\/index.html$/, '');
- }
- /**
- * Tries to decode the URI component without throwing an exception.
- *
- * @param str value potential URI component to check.
- * @returns the decoded URI if it can be decoded or else `undefined`.
- */
- function tryDecodeURIComponent(value) {
- try {
- return decodeURIComponent(value);
- }
- catch (e) {
- // Ignore any invalid uri component.
- return undefined;
- }
- }
- /**
- * Parses an escaped url query string into key-value pairs. Logic taken from
- * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1382
- */
- function parseKeyValue(keyValue) {
- const obj = {};
- (keyValue || '').split('&').forEach((keyValue) => {
- let splitPoint, key, val;
- if (keyValue) {
- key = keyValue = keyValue.replace(/\+/g, '%20');
- splitPoint = keyValue.indexOf('=');
- if (splitPoint !== -1) {
- key = keyValue.substring(0, splitPoint);
- val = keyValue.substring(splitPoint + 1);
- }
- key = tryDecodeURIComponent(key);
- if (typeof key !== 'undefined') {
- val = typeof val !== 'undefined' ? tryDecodeURIComponent(val) : true;
- if (!obj.hasOwnProperty(key)) {
- obj[key] = val;
- }
- else if (Array.isArray(obj[key])) {
- obj[key].push(val);
- }
- else {
- obj[key] = [obj[key], val];
- }
- }
- }
- });
- return obj;
- }
- /**
- * Serializes into key-value pairs. Logic taken from
- * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1409
- */
- function toKeyValue(obj) {
- const parts = [];
- for (const key in obj) {
- let value = obj[key];
- if (Array.isArray(value)) {
- value.forEach((arrayValue) => {
- parts.push(encodeUriQuery(key, true) +
- (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
- });
- }
- else {
- parts.push(encodeUriQuery(key, true) +
- (value === true ? '' : '=' + encodeUriQuery(value, true)));
- }
- }
- return parts.length ? parts.join('&') : '';
- }
- /**
- * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
- * https://tools.ietf.org/html/rfc3986 with regards to the character set (pchar) allowed in path
- * segments:
- * segment = *pchar
- * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- * pct-encoded = "%" HEXDIG HEXDIG
- * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
- * / "*" / "+" / "," / ";" / "="
- *
- * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1437
- */
- function encodeUriSegment(val) {
- return encodeUriQuery(val, true).replace(/%26/g, '&').replace(/%3D/gi, '=').replace(/%2B/gi, '+');
- }
- /**
- * This method is intended for encoding *key* or *value* parts of query component. We need a custom
- * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
- * encoded per https://tools.ietf.org/html/rfc3986:
- * query = *( pchar / "/" / "?" )
- * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- * pct-encoded = "%" HEXDIG HEXDIG
- * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
- * / "*" / "+" / "," / ";" / "="
- *
- * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1456
- */
- function encodeUriQuery(val, pctEncodeSpaces = false) {
- return encodeURIComponent(val)
- .replace(/%40/g, '@')
- .replace(/%3A/gi, ':')
- .replace(/%24/g, '$')
- .replace(/%2C/gi, ',')
- .replace(/%3B/gi, ';')
- .replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
- }
- /**
- * A provider token used to configure the location upgrade module.
- *
- * @publicApi
- */
- const LOCATION_UPGRADE_CONFIGURATION = new InjectionToken('LOCATION_UPGRADE_CONFIGURATION');
- const APP_BASE_HREF_RESOLVED = new InjectionToken('APP_BASE_HREF_RESOLVED');
- /**
- * `NgModule` used for providing and configuring Angular's Unified Location Service for upgrading.
- *
- * @see [Using the Unified Angular Location Service](guide/upgrade#using-the-unified-angular-location-service)
- *
- * @publicApi
- */
- class LocationUpgradeModule {
- static config(config) {
- return {
- ngModule: LocationUpgradeModule,
- providers: [
- Location,
- {
- provide: $locationShim,
- useFactory: provide$location,
- deps: [UpgradeModule, Location, PlatformLocation, UrlCodec, LocationStrategy]
- },
- { provide: LOCATION_UPGRADE_CONFIGURATION, useValue: config ? config : {} },
- { provide: UrlCodec, useFactory: provideUrlCodec, deps: [LOCATION_UPGRADE_CONFIGURATION] },
- {
- provide: APP_BASE_HREF_RESOLVED,
- useFactory: provideAppBaseHref,
- deps: [LOCATION_UPGRADE_CONFIGURATION, [new Inject(APP_BASE_HREF), new Optional()]]
- },
- {
- provide: LocationStrategy,
- useFactory: provideLocationStrategy,
- deps: [
- PlatformLocation,
- APP_BASE_HREF_RESOLVED,
- LOCATION_UPGRADE_CONFIGURATION,
- ]
- },
- ],
- };
- }
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: LocationUpgradeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.9", ngImport: i0, type: LocationUpgradeModule, imports: [CommonModule] }); }
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: LocationUpgradeModule, imports: [CommonModule] }); }
- }
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: LocationUpgradeModule, decorators: [{
- type: NgModule,
- args: [{ imports: [CommonModule] }]
- }] });
- function provideAppBaseHref(config, appBaseHref) {
- if (config && config.appBaseHref != null) {
- return config.appBaseHref;
- }
- else if (appBaseHref != null) {
- return appBaseHref;
- }
- return '';
- }
- function provideUrlCodec(config) {
- const codec = config && config.urlCodec || AngularJSUrlCodec;
- return new codec();
- }
- function provideLocationStrategy(platformLocation, baseHref, options = {}) {
- return options.useHash ? new HashLocationStrategy(platformLocation, baseHref) :
- new PathLocationStrategy(platformLocation, baseHref);
- }
- function provide$location(ngUpgrade, location, platformLocation, urlCodec, locationStrategy) {
- const $locationProvider = new $locationShimProvider(ngUpgrade, location, platformLocation, urlCodec, locationStrategy);
- return $locationProvider.$get();
- }
- /**
- * @module
- * @description
- * Entry point for all public APIs of this package.
- */
- // This file only reexports content of the `src` folder. Keep it that way.
- // This file is not used to build this module. It is only used during editing
- /**
- * Generated bundle index. Do not edit.
- */
- export { $locationShim, $locationShimProvider, AngularJSUrlCodec, LOCATION_UPGRADE_CONFIGURATION, LocationUpgradeModule, UrlCodec };
- //# sourceMappingURL=upgrade.mjs.map
|