UNPKG

@angular/common

Version:

Angular - commonly needed directives and services

1 lines 65 kB
{"version":3,"file":"upgrade.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-2d99d9656325/bin/packages/common/upgrade/src/utils.ts","../../../../../darwin_arm64-fastbuild-ST-2d99d9656325/bin/packages/common/upgrade/src/location_shim.ts","../../../../../darwin_arm64-fastbuild-ST-2d99d9656325/bin/packages/common/upgrade/src/params.ts","../../../../../darwin_arm64-fastbuild-ST-2d99d9656325/bin/packages/common/upgrade/src/location_upgrade_module.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nexport function stripPrefix(val: string, prefix: string): string {\n return val.startsWith(prefix) ? val.substring(prefix.length) : val;\n}\n\nexport function deepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true;\n } else if (!a || !b) {\n return false;\n } else {\n try {\n if (a.prototype !== b.prototype || (Array.isArray(a) && Array.isArray(b))) {\n return false;\n }\n return JSON.stringify(a) === JSON.stringify(b);\n } catch (e) {\n return false;\n }\n }\n}\n\nexport function isAnchor(el: (Node & ParentNode) | Element | null): el is HTMLAnchorElement {\n return (<HTMLAnchorElement>el).href !== undefined;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {Location, LocationStrategy, PlatformLocation} from '../../index';\nimport {ɵisPromise as isPromise} from '@angular/core';\nimport {UpgradeModule} from '@angular/upgrade/static';\nimport {ReplaySubject} from 'rxjs';\n\nimport {UrlCodec} from './params';\nimport {deepEqual, isAnchor} from './utils';\n\nconst PATH_MATCH = /^([^?#]*)(\\?([^#]*))?(#(.*))?$/;\nconst DOUBLE_SLASH_REGEX = /^\\s*[\\\\/]{2,}/;\nconst IGNORE_URI_REGEXP = /^\\s*(javascript|mailto):/i;\nconst DEFAULT_PORTS: {[key: string]: number} = {\n 'http:': 80,\n 'https:': 443,\n 'ftp:': 21,\n};\n\n/**\n * Location service that provides a drop-in replacement for the $location service\n * provided in AngularJS.\n *\n * @see [Using the Angular Unified Location Service](guide/upgrade#using-the-unified-angular-location-service)\n *\n * @publicApi\n */\nexport class $locationShim {\n private initializing = true;\n private updateBrowser = false;\n private $$absUrl: string = '';\n private $$url: string = '';\n private $$protocol: string;\n private $$host: string = '';\n private $$port: number | null;\n private $$replace: boolean = false;\n private $$path: string = '';\n private $$search: any = '';\n private $$hash: string = '';\n private $$state: unknown;\n private $$changeListeners: [\n (\n url: string,\n state: unknown,\n oldUrl: string,\n oldState: unknown,\n err?: (e: Error) => void,\n ) => void,\n (e: Error) => void,\n ][] = [];\n\n private cachedState: unknown = null;\n\n private urlChanges = new ReplaySubject<{newUrl: string; newState: unknown}>(1);\n\n private readonly removeOnUrlChangeFn: VoidFunction;\n\n constructor(\n $injector: any,\n private location: Location,\n private platformLocation: PlatformLocation,\n private urlCodec: UrlCodec,\n private locationStrategy: LocationStrategy,\n ) {\n const initialUrl = this.browserUrl();\n\n let parsedUrl = this.urlCodec.parse(initialUrl);\n\n if (typeof parsedUrl === 'string') {\n throw 'Invalid URL';\n }\n\n this.$$protocol = parsedUrl.protocol;\n this.$$host = parsedUrl.hostname;\n this.$$port = parseInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;\n\n this.$$parseLinkUrl(initialUrl, initialUrl);\n this.cacheState();\n this.$$state = this.browserState();\n\n this.removeOnUrlChangeFn = this.location.onUrlChange((newUrl, newState) => {\n this.urlChanges.next({newUrl, newState});\n });\n\n if (isPromise($injector)) {\n $injector.then(($i) => this.initialize($i));\n } else {\n this.initialize($injector);\n }\n }\n\n private initialize($injector: any) {\n const $rootScope = $injector.get('$rootScope');\n const $rootElement = $injector.get('$rootElement');\n\n $rootElement.on('click', (event: any) => {\n if (\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n event.which === 2 ||\n event.button === 2\n ) {\n return;\n }\n\n let elm: (Node & ParentNode) | null = event.target;\n\n // traverse the DOM up to find first A tag\n while (elm && elm.nodeName.toLowerCase() !== 'a') {\n // ignore rewriting if no A tag (reached root element, or no parent - removed from document)\n if (elm === $rootElement[0] || !(elm = elm.parentNode)) {\n return;\n }\n }\n\n if (!isAnchor(elm)) {\n return;\n }\n\n const absHref = elm.href;\n const relHref = elm.getAttribute('href');\n\n // Ignore when url is started with javascript: or mailto:\n if (IGNORE_URI_REGEXP.test(absHref)) {\n return;\n }\n\n if (absHref && !elm.getAttribute('target') && !event.isDefaultPrevented()) {\n if (this.$$parseLinkUrl(absHref, relHref)) {\n // We do a preventDefault for all urls that are part of the AngularJS application,\n // in html5mode and also without, so that we are able to abort navigation without\n // getting double entries in the location history.\n event.preventDefault();\n // update location manually\n if (this.absUrl() !== this.browserUrl()) {\n $rootScope.$apply();\n }\n }\n }\n });\n\n this.urlChanges.subscribe(({newUrl, newState}) => {\n const oldUrl = this.absUrl();\n const oldState = this.$$state;\n this.$$parse(newUrl);\n newUrl = this.absUrl();\n this.$$state = newState;\n const defaultPrevented = $rootScope.$broadcast(\n '$locationChangeStart',\n newUrl,\n oldUrl,\n newState,\n oldState,\n ).defaultPrevented;\n\n // if the location was changed by a `$locationChangeStart` handler then stop\n // processing this location change\n if (this.absUrl() !== newUrl) return;\n\n // If default was prevented, set back to old state. This is the state that was locally\n // cached in the $location service.\n if (defaultPrevented) {\n this.$$parse(oldUrl);\n this.state(oldState);\n this.setBrowserUrlWithFallback(oldUrl, false, oldState);\n this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);\n } else {\n this.initializing = false;\n $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, newState, oldState);\n this.resetBrowserUpdate();\n }\n if (!$rootScope.$$phase) {\n $rootScope.$digest();\n }\n });\n\n // Synchronize the browser's URL and state with the application.\n // Note: There is no need to save the `$watch` return value (deregister listener)\n // into a variable because `$scope.$$watchers` is automatically cleaned up when\n // the root scope is destroyed.\n $rootScope.$watch(() => {\n if (this.initializing || this.updateBrowser) {\n this.updateBrowser = false;\n\n const oldUrl = this.browserUrl();\n const newUrl = this.absUrl();\n const oldState = this.browserState();\n let currentReplace = this.$$replace;\n\n const urlOrStateChanged =\n !this.urlCodec.areEqual(oldUrl, newUrl) || oldState !== this.$$state;\n\n // Fire location changes one time to on initialization. This must be done on the\n // next tick (thus inside $evalAsync()) in order for listeners to be registered\n // before the event fires. Mimicing behavior from $locationWatch:\n // https://github.com/angular/angular.js/blob/master/src/ng/location.js#L983\n if (this.initializing || urlOrStateChanged) {\n this.initializing = false;\n\n $rootScope.$evalAsync(() => {\n // Get the new URL again since it could have changed due to async update\n const newUrl = this.absUrl();\n const defaultPrevented = $rootScope.$broadcast(\n '$locationChangeStart',\n newUrl,\n oldUrl,\n this.$$state,\n oldState,\n ).defaultPrevented;\n\n // if the location was changed by a `$locationChangeStart` handler then stop\n // processing this location change\n if (this.absUrl() !== newUrl) return;\n\n if (defaultPrevented) {\n this.$$parse(oldUrl);\n this.$$state = oldState;\n } else {\n // This block doesn't run when initializing because it's going to perform the update\n // to the URL which shouldn't be needed when initializing.\n if (urlOrStateChanged) {\n this.setBrowserUrlWithFallback(\n newUrl,\n currentReplace,\n oldState === this.$$state ? null : this.$$state,\n );\n this.$$replace = false;\n }\n $rootScope.$broadcast(\n '$locationChangeSuccess',\n newUrl,\n oldUrl,\n this.$$state,\n oldState,\n );\n if (urlOrStateChanged) {\n this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);\n }\n }\n });\n }\n }\n this.$$replace = false;\n });\n\n $rootScope.$on('$destroy', () => {\n this.removeOnUrlChangeFn();\n // Complete the subject to release all active observers when the root\n // scope is destroyed. Before this change, we subscribed to the `urlChanges`\n // subject, and the subscriber captured `this`, leading to a memory leak\n // after the root scope was destroyed.\n this.urlChanges.complete();\n });\n }\n\n private resetBrowserUpdate() {\n this.$$replace = false;\n this.$$state = this.browserState();\n this.updateBrowser = false;\n this.lastBrowserUrl = this.browserUrl();\n }\n\n private lastHistoryState: unknown;\n private lastBrowserUrl: string = '';\n private browserUrl(): string;\n private browserUrl(url: string, replace?: boolean, state?: unknown): this;\n private browserUrl(url?: string, replace?: boolean, state?: unknown) {\n // In modern browsers `history.state` is `null` by default; treating it separately\n // from `undefined` would cause `$browser.url('/foo')` to change `history.state`\n // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.\n if (typeof state === 'undefined') {\n state = null;\n }\n\n // setter\n if (url) {\n let sameState = this.lastHistoryState === state;\n\n // Normalize the inputted URL\n url = this.urlCodec.parse(url).href;\n\n // Don't change anything if previous and current URLs and states match.\n if (this.lastBrowserUrl === url && sameState) {\n return this;\n }\n this.lastBrowserUrl = url;\n this.lastHistoryState = state;\n\n // Remove server base from URL as the Angular APIs for updating URL require\n // it to be the path+.\n url = this.stripBaseUrl(this.getServerBase(), url) || url;\n\n // Set the URL\n if (replace) {\n this.locationStrategy.replaceState(state, '', url, '');\n } else {\n this.locationStrategy.pushState(state, '', url, '');\n }\n\n this.cacheState();\n\n return this;\n // getter\n } else {\n return this.platformLocation.href;\n }\n }\n\n // This variable should be used *only* inside the cacheState function.\n private lastCachedState: unknown = null;\n private cacheState() {\n // This should be the only place in $browser where `history.state` is read.\n this.cachedState = this.platformLocation.getState();\n if (typeof this.cachedState === 'undefined') {\n this.cachedState = null;\n }\n\n // Prevent callbacks fo fire twice if both hashchange & popstate were fired.\n if (deepEqual(this.cachedState, this.lastCachedState)) {\n this.cachedState = this.lastCachedState;\n }\n\n this.lastCachedState = this.cachedState;\n this.lastHistoryState = this.cachedState;\n }\n\n /**\n * This function emulates the $browser.state() function from AngularJS. It will cause\n * history.state to be cached unless changed with deep equality check.\n */\n private browserState(): unknown {\n return this.cachedState;\n }\n\n private stripBaseUrl(base: string, url: string) {\n if (url.startsWith(base)) {\n return url.slice(base.length);\n }\n return undefined;\n }\n\n private getServerBase() {\n const {protocol, hostname, port} = this.platformLocation;\n const baseHref = this.locationStrategy.getBaseHref();\n let url = `${protocol}//${hostname}${port ? ':' + port : ''}${baseHref || '/'}`;\n return url.endsWith('/') ? url : url + '/';\n }\n\n private parseAppUrl(url: string) {\n if (DOUBLE_SLASH_REGEX.test(url)) {\n throw new Error(`Bad Path - URL cannot start with double slashes: ${url}`);\n }\n\n let prefixed = url.charAt(0) !== '/';\n if (prefixed) {\n url = '/' + url;\n }\n let match = this.urlCodec.parse(url, this.getServerBase());\n if (typeof match === 'string') {\n throw new Error(`Bad URL - Cannot parse URL: ${url}`);\n }\n let path =\n prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname;\n this.$$path = this.urlCodec.decodePath(path);\n this.$$search = this.urlCodec.decodeSearch(match.search);\n this.$$hash = this.urlCodec.decodeHash(match.hash);\n\n // make sure path starts with '/';\n if (this.$$path && this.$$path.charAt(0) !== '/') {\n this.$$path = '/' + this.$$path;\n }\n }\n\n /**\n * Registers listeners for URL changes. This API is used to catch updates performed by the\n * AngularJS framework. These changes are a subset of the `$locationChangeStart` and\n * `$locationChangeSuccess` events which fire when AngularJS updates its internally-referenced\n * version of the browser URL.\n *\n * It's possible for `$locationChange` events to happen, but for the browser URL\n * (window.location) to remain unchanged. This `onChange` callback will fire only when AngularJS\n * actually updates the browser URL (window.location).\n *\n * @param fn The callback function that is triggered for the listener when the URL changes.\n * @param err The callback function that is triggered when an error occurs.\n */\n onChange(\n fn: (url: string, state: unknown, oldUrl: string, oldState: unknown) => void,\n err: (e: Error) => void = (e: Error) => {},\n ) {\n this.$$changeListeners.push([fn, err]);\n }\n\n /** @internal */\n $$notifyChangeListeners(\n url: string = '',\n state: unknown,\n oldUrl: string = '',\n oldState: unknown,\n ) {\n this.$$changeListeners.forEach(([fn, err]) => {\n try {\n fn(url, state, oldUrl, oldState);\n } catch (e) {\n err(e as Error);\n }\n });\n }\n\n /**\n * Parses the provided URL, and sets the current URL to the parsed result.\n *\n * @param url The URL string.\n */\n $$parse(url: string) {\n let pathUrl: string | undefined;\n if (url.startsWith('/')) {\n pathUrl = url;\n } else {\n // Remove protocol & hostname if URL starts with it\n pathUrl = this.stripBaseUrl(this.getServerBase(), url);\n }\n if (typeof pathUrl === 'undefined') {\n throw new Error(`Invalid url \"${url}\", missing path prefix \"${this.getServerBase()}\".`);\n }\n\n this.parseAppUrl(pathUrl);\n\n this.$$path ||= '/';\n this.composeUrls();\n }\n\n /**\n * Parses the provided URL and its relative URL.\n *\n * @param url The full URL string.\n * @param relHref A URL string relative to the full URL string.\n */\n $$parseLinkUrl(url: string, relHref?: string | null): boolean {\n // When relHref is passed, it should be a hash and is handled separately\n if (relHref && relHref[0] === '#') {\n this.hash(relHref.slice(1));\n return true;\n }\n let rewrittenUrl;\n let appUrl = this.stripBaseUrl(this.getServerBase(), url);\n if (typeof appUrl !== 'undefined') {\n rewrittenUrl = this.getServerBase() + appUrl;\n } else if (this.getServerBase() === url + '/') {\n rewrittenUrl = this.getServerBase();\n }\n // Set the URL\n if (rewrittenUrl) {\n this.$$parse(rewrittenUrl);\n }\n return !!rewrittenUrl;\n }\n\n private setBrowserUrlWithFallback(url: string, replace: boolean, state: unknown) {\n const oldUrl = this.url();\n const oldState = this.$$state;\n try {\n this.browserUrl(url, replace, state);\n\n // Make sure $location.state() returns referentially identical (not just deeply equal)\n // state object; this makes possible quick checking if the state changed in the digest\n // loop. Checking deep equality would be too expensive.\n this.$$state = this.browserState();\n } catch (e) {\n // Restore old values if pushState fails\n this.url(oldUrl);\n this.$$state = oldState;\n\n throw e;\n }\n }\n\n private composeUrls() {\n this.$$url = this.urlCodec.normalize(this.$$path, this.$$search, this.$$hash);\n this.$$absUrl = this.getServerBase() + this.$$url.slice(1); // remove '/' from front of URL\n this.updateBrowser = true;\n }\n\n /**\n * Retrieves the full URL representation with all segments encoded according to\n * rules specified in\n * [RFC 3986](https://tools.ietf.org/html/rfc3986).\n *\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let absUrl = $location.absUrl();\n * // => \"http://example.com/#/some/path?foo=bar&baz=xoxo\"\n * ```\n */\n absUrl(): string {\n return this.$$absUrl;\n }\n\n /**\n * Retrieves the current URL, or sets a new URL. When setting a URL,\n * changes the path, search, and hash, and returns a reference to its own instance.\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let url = $location.url();\n * // => \"/some/path?foo=bar&baz=xoxo\"\n * ```\n */\n url(): string;\n url(url: string): this;\n url(url?: string): string | this {\n if (typeof url === 'string') {\n if (!url.length) {\n url = '/';\n }\n\n const match = PATH_MATCH.exec(url);\n if (!match) return this;\n if (match[1] || url === '') this.path(this.urlCodec.decodePath(match[1]));\n if (match[2] || match[1] || url === '') this.search(match[3] || '');\n this.hash(match[5] || '');\n\n // Chainable method\n return this;\n }\n\n return this.$$url;\n }\n\n /**\n * Retrieves the protocol of the current URL.\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let protocol = $location.protocol();\n * // => \"http\"\n * ```\n */\n protocol(): string {\n return this.$$protocol;\n }\n\n /**\n * Retrieves the protocol of the current URL.\n *\n * In contrast to the non-AngularJS version `location.host` which returns `hostname:port`, this\n * returns the `hostname` portion only.\n *\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let host = $location.host();\n * // => \"example.com\"\n *\n * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo\n * host = $location.host();\n * // => \"example.com\"\n * host = location.host;\n * // => \"example.com:8080\"\n * ```\n */\n host(): string {\n return this.$$host;\n }\n\n /**\n * Retrieves the port of the current URL.\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let port = $location.port();\n * // => 80\n * ```\n */\n port(): number | null {\n return this.$$port;\n }\n\n /**\n * Retrieves the path of the current URL, or changes the path and returns a reference to its own\n * instance.\n *\n * Paths should always begin with forward slash (/). This method adds the forward slash\n * if it is missing.\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let path = $location.path();\n * // => \"/some/path\"\n * ```\n */\n path(): string;\n path(path: string | number | null): this;\n path(path?: string | number | null): string | this {\n if (typeof path === 'undefined') {\n return this.$$path;\n }\n\n // null path converts to empty string. Prepend with \"/\" if needed.\n path = path !== null ? path.toString() : '';\n path = path.charAt(0) === '/' ? path : '/' + path;\n\n this.$$path = path;\n\n this.composeUrls();\n return this;\n }\n\n /**\n * Retrieves a map of the search parameters of the current URL, or changes a search\n * part and returns a reference to its own instance.\n *\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n * let searchObject = $location.search();\n * // => {foo: 'bar', baz: 'xoxo'}\n *\n * // set foo to 'yipee'\n * $location.search('foo', 'yipee');\n * // $location.search() => {foo: 'yipee', baz: 'xoxo'}\n * ```\n *\n * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or\n * hash object.\n *\n * When called with a single argument the method acts as a setter, setting the `search` component\n * of `$location` to the specified value.\n *\n * If the argument is a hash object containing an array of values, these values will be encoded\n * as duplicate search parameters in the URL.\n *\n * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number,\n * then `paramValue`\n * will override only a single search property.\n *\n * If `paramValue` is an array, it will override the property of the `search` component of\n * `$location` specified via the first argument.\n *\n * If `paramValue` is `null`, the property specified via the first argument will be deleted.\n *\n * If `paramValue` is `true`, the property specified via the first argument will be added with no\n * value nor trailing equal sign.\n *\n * @return {Object} The parsed `search` object of the current URL, or the changed `search` object.\n */\n search(): {[key: string]: unknown};\n search(search: string | number | {[key: string]: unknown}): this;\n search(\n search: string | number | {[key: string]: unknown},\n paramValue: null | undefined | string | number | boolean | string[],\n ): this;\n search(\n search?: string | number | {[key: string]: unknown},\n paramValue?: null | undefined | string | number | boolean | string[],\n ): {[key: string]: unknown} | this {\n switch (arguments.length) {\n case 0:\n return this.$$search;\n case 1:\n if (typeof search === 'string' || typeof search === 'number') {\n this.$$search = this.urlCodec.decodeSearch(search.toString());\n } else if (typeof search === 'object' && search !== null) {\n // Copy the object so it's never mutated\n search = {...search};\n // remove object undefined or null properties\n for (const key in search) {\n if (search[key] == null) delete search[key];\n }\n\n this.$$search = search;\n } else {\n throw new Error(\n 'LocationProvider.search(): First argument must be a string or an object.',\n );\n }\n break;\n default:\n if (typeof search === 'string') {\n const currentSearch = this.search();\n if (typeof paramValue === 'undefined' || paramValue === null) {\n delete currentSearch[search];\n return this.search(currentSearch);\n } else {\n currentSearch[search] = paramValue;\n return this.search(currentSearch);\n }\n }\n }\n this.composeUrls();\n return this;\n }\n\n /**\n * Retrieves the current hash fragment, or changes the hash fragment and returns a reference to\n * its own instance.\n *\n * ```js\n * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue\n * let hash = $location.hash();\n * // => \"hashValue\"\n * ```\n */\n hash(): string;\n hash(hash: string | number | null): this;\n hash(hash?: string | number | null): string | this {\n if (typeof hash === 'undefined') {\n return this.$$hash;\n }\n\n this.$$hash = hash !== null ? hash.toString() : '';\n\n this.composeUrls();\n return this;\n }\n\n /**\n * Changes to `$location` during the current `$digest` will replace the current\n * history record, instead of adding a new one.\n */\n replace(): this {\n this.$$replace = true;\n return this;\n }\n\n /**\n * Retrieves the history state object when called without any parameter.\n *\n * Change the history state object when called with one parameter and return `$location`.\n * The state object is later passed to `pushState` or `replaceState`.\n *\n * This method is supported only in HTML5 mode and only in browsers supporting\n * the HTML5 History API methods such as `pushState` and `replaceState`. If you need to support\n * older browsers (like Android < 4.0), don't use this method.\n *\n */\n state(): unknown;\n state(state: unknown): this;\n state(state?: unknown): unknown | this {\n if (typeof state === 'undefined') {\n return this.$$state;\n }\n\n this.$$state = state;\n return this;\n }\n}\n\n/**\n * The factory function used to create an instance of the `$locationShim` in Angular,\n * and provides an API-compatible `$locationProvider` for AngularJS.\n *\n * @publicApi\n */\nexport class $locationShimProvider {\n constructor(\n private ngUpgrade: UpgradeModule,\n private location: Location,\n private platformLocation: PlatformLocation,\n private urlCodec: UrlCodec,\n private locationStrategy: LocationStrategy,\n ) {}\n\n /**\n * Factory method that returns an instance of the $locationShim\n */\n $get() {\n return new $locationShim(\n this.ngUpgrade.$injector,\n this.location,\n this.platformLocation,\n this.urlCodec,\n this.locationStrategy,\n );\n }\n\n /**\n * Stub method used to keep API compatible with AngularJS. This setting is configured through\n * the LocationUpgradeModule's `config` method in your Angular app.\n */\n hashPrefix(prefix?: string) {\n throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');\n }\n\n /**\n * Stub method used to keep API compatible with AngularJS. This setting is configured through\n * the LocationUpgradeModule's `config` method in your Angular app.\n */\n html5Mode(mode?: any) {\n throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * A codec for encoding and decoding URL parts.\n *\n * @publicApi\n **/\nexport abstract class UrlCodec {\n /**\n * Encodes the path from the provided string\n *\n * @param path The path string\n */\n abstract encodePath(path: string): string;\n\n /**\n * Decodes the path from the provided string\n *\n * @param path The path string\n */\n abstract decodePath(path: string): string;\n\n /**\n * Encodes the search string from the provided string or object\n *\n * @param path The path string or object\n */\n abstract encodeSearch(search: string | {[k: string]: unknown}): string;\n\n /**\n * Decodes the search objects from the provided string\n *\n * @param path The path string\n */\n abstract decodeSearch(search: string): {[k: string]: unknown};\n\n /**\n * Encodes the hash from the provided string\n *\n * @param path The hash string\n */\n abstract encodeHash(hash: string): string;\n\n /**\n * Decodes the hash from the provided string\n *\n * @param path The hash string\n */\n abstract decodeHash(hash: string): string;\n\n /**\n * Normalizes the URL from the provided string\n *\n * @param path The URL string\n */\n abstract normalize(href: string): string;\n\n /**\n * Normalizes the URL from the provided string, search, hash, and base URL parameters\n *\n * @param path The URL path\n * @param search The search object\n * @param hash The has string\n * @param baseUrl The base URL for the URL\n */\n abstract normalize(\n path: string,\n search: {[k: string]: unknown},\n hash: string,\n baseUrl?: string,\n ): string;\n\n /**\n * Checks whether the two strings are equal\n * @param valA First string for comparison\n * @param valB Second string for comparison\n */\n abstract areEqual(valA: string, valB: string): boolean;\n\n /**\n * Parses the URL string based on the base URL\n *\n * @param url The full URL string\n * @param base The base for the URL\n */\n abstract parse(\n url: string,\n base?: string,\n ): {\n href: string;\n protocol: string;\n host: string;\n search: string;\n hash: string;\n hostname: string;\n port: string;\n pathname: string;\n };\n}\n\n/**\n * A `UrlCodec` that uses logic from AngularJS to serialize and parse URLs\n * and URL parameters.\n *\n * @publicApi\n */\nexport class AngularJSUrlCodec implements UrlCodec {\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L15\n encodePath(path: string): string {\n const segments = path.split('/');\n let i = segments.length;\n\n while (i--) {\n // decode forward slashes to prevent them from being double encoded\n segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, '/'));\n }\n\n path = segments.join('/');\n return _stripIndexHtml(((path && path[0] !== '/' && '/') || '') + path);\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L42\n encodeSearch(search: string | {[k: string]: unknown}): string {\n if (typeof search === 'string') {\n search = parseKeyValue(search);\n }\n\n search = toKeyValue(search);\n return search ? '?' + search : '';\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L44\n encodeHash(hash: string) {\n hash = encodeUriSegment(hash);\n return hash ? '#' + hash : '';\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L27\n decodePath(path: string, html5Mode = true): string {\n const segments = path.split('/');\n let i = segments.length;\n\n while (i--) {\n segments[i] = decodeURIComponent(segments[i]);\n if (html5Mode) {\n // encode forward slashes to prevent them from being mistaken for path separators\n segments[i] = segments[i].replace(/\\//g, '%2F');\n }\n }\n\n return segments.join('/');\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L72\n decodeSearch(search: string) {\n return parseKeyValue(search);\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L73\n decodeHash(hash: string) {\n hash = decodeURIComponent(hash);\n return hash[0] === '#' ? hash.substring(1) : hash;\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L149\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/location.js#L42\n normalize(href: string): string;\n normalize(path: string, search: {[k: string]: unknown}, hash: string, baseUrl?: string): string;\n normalize(\n pathOrHref: string,\n search?: {[k: string]: unknown},\n hash?: string,\n baseUrl?: string,\n ): string {\n if (arguments.length === 1) {\n const parsed = this.parse(pathOrHref, baseUrl);\n\n if (typeof parsed === 'string') {\n return parsed;\n }\n\n const serverUrl = `${parsed.protocol}://${parsed.hostname}${\n parsed.port ? ':' + parsed.port : ''\n }`;\n\n return this.normalize(\n this.decodePath(parsed.pathname),\n this.decodeSearch(parsed.search),\n this.decodeHash(parsed.hash),\n serverUrl,\n );\n } else {\n const encPath = this.encodePath(pathOrHref);\n const encSearch = (search && this.encodeSearch(search)) || '';\n const encHash = (hash && this.encodeHash(hash)) || '';\n\n let joinedPath = (baseUrl || '') + encPath;\n\n if (!joinedPath.length || joinedPath[0] !== '/') {\n joinedPath = '/' + joinedPath;\n }\n return joinedPath + encSearch + encHash;\n }\n }\n\n areEqual(valA: string, valB: string) {\n return this.normalize(valA) === this.normalize(valB);\n }\n\n // https://github.com/angular/angular.js/blob/864c7f0/src/ng/urlUtils.js#L60\n parse(url: string, base?: string) {\n try {\n // Safari 12 throws an error when the URL constructor is called with an undefined base.\n const parsed = !base ? new URL(url) : new URL(url, base);\n return {\n href: parsed.href,\n protocol: parsed.protocol ? parsed.protocol.replace(/:$/, '') : '',\n host: parsed.host,\n search: parsed.search ? parsed.search.replace(/^\\?/, '') : '',\n hash: parsed.hash ? parsed.hash.replace(/^#/, '') : '',\n hostname: parsed.hostname,\n port: parsed.port,\n pathname: parsed.pathname.charAt(0) === '/' ? parsed.pathname : '/' + parsed.pathname,\n };\n } catch (e) {\n throw new Error(`Invalid URL (${url}) with base (${base})`);\n }\n }\n}\n\nfunction _stripIndexHtml(url: string): string {\n return url.replace(/\\/index.html$/, '');\n}\n\n/**\n * Tries to decode the URI component without throwing an exception.\n *\n * @param str value potential URI component to check.\n * @returns the decoded URI if it can be decoded or else `undefined`.\n */\nfunction tryDecodeURIComponent(value: string): string | undefined {\n try {\n return decodeURIComponent(value);\n } catch (e) {\n // Ignore any invalid uri component.\n return undefined;\n }\n}\n\n/**\n * Parses an escaped url query string into key-value pairs. Logic taken from\n * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1382\n */\nfunction parseKeyValue(keyValue: string): {[k: string]: unknown} {\n const obj: {[k: string]: unknown} = {};\n (keyValue || '').split('&').forEach((keyValue) => {\n let splitPoint, key, val;\n if (keyValue) {\n key = keyValue = keyValue.replace(/\\+/g, '%20');\n splitPoint = keyValue.indexOf('=');\n if (splitPoint !== -1) {\n key = keyValue.substring(0, splitPoint);\n val = keyValue.substring(splitPoint + 1);\n }\n key = tryDecodeURIComponent(key);\n if (typeof key !== 'undefined') {\n val = typeof val !== 'undefined' ? tryDecodeURIComponent(val) : true;\n if (!obj.hasOwnProperty(key)) {\n obj[key] = val;\n } else if (Array.isArray(obj[key])) {\n (obj[key] as unknown[]).push(val);\n } else {\n obj[key] = [obj[key], val];\n }\n }\n }\n });\n return obj;\n}\n\n/**\n * Serializes into key-value pairs. Logic taken from\n * https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1409\n */\nfunction toKeyValue(obj: {[k: string]: unknown}) {\n const parts: unknown[] = [];\n for (const key in obj) {\n let value = obj[key];\n if (Array.isArray(value)) {\n value.forEach((arrayValue) => {\n parts.push(\n encodeUriQuery(key, true) +\n (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)),\n );\n });\n } else {\n parts.push(\n encodeUriQuery(key, true) +\n (value === true ? '' : '=' + encodeUriQuery(value as any, true)),\n );\n }\n }\n return parts.length ? parts.join('&') : '';\n}\n\n/**\n * We need our custom method because encodeURIComponent is too aggressive and doesn't follow\n * https://tools.ietf.org/html/rfc3986 with regards to the character set (pchar) allowed in path\n * segments:\n * segment = *pchar\n * pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n * pct-encoded = \"%\" HEXDIG HEXDIG\n * unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n * sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n * / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n *\n * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1437\n */\nfunction encodeUriSegment(val: string) {\n return encodeUriQuery(val, true).replace(/%26/g, '&').replace(/%3D/gi, '=').replace(/%2B/gi, '+');\n}\n\n/**\n * This method is intended for encoding *key* or *value* parts of query component. We need a custom\n * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be\n * encoded per https://tools.ietf.org/html/rfc3986:\n * query = *( pchar / \"/\" / \"?\" )\n * pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n * unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n * pct-encoded = \"%\" HEXDIG HEXDIG\n * sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n * / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n *\n * Logic from https://github.com/angular/angular.js/blob/864c7f0/src/Angular.js#L1456\n */\nfunction encodeUriQuery(val: string, pctEncodeSpaces: boolean = false) {\n return encodeURIComponent(val)\n .replace(/%40/g, '@')\n .replace(/%3A/gi, ':')\n .replace(/%24/g, '$')\n .replace(/%2C/gi, ',')\n .replace(/%3B/gi, ';')\n .replace(/%20/g, pctEncodeSpaces ? '%20' : '+');\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n APP_BASE_HREF,\n CommonModule,\n HashLocationStrategy,\n Location,\n LocationStrategy,\n PathLocationStrategy,\n PlatformLocation,\n} from '../../index';\nimport {Inject, InjectionToken, ModuleWithProviders, NgModule, Optional} from '@angular/core';\nimport {UpgradeModule} from '@angular/upgrade/static';\n\nimport {$locationShim, $locationShimProvider} from './location_shim';\nimport {AngularJSUrlCodec, UrlCodec} from './params';\n\n/**\n * Configuration options for LocationUpgrade.\n *\n * @publicApi\n */\nexport interface LocationUpgradeConfig {\n /**\n * Configures whether the location upgrade module should use the `HashLocationStrategy`\n * or the `PathLocationStrategy`\n */\n useHash?: boolean;\n /**\n * Configures the hash prefix used in the URL when using the `HashLocationStrategy`\n */\n hashPrefix?: string;\n /**\n * Configures the URL codec for encoding and decoding URLs. Default is the `AngularJSCodec`\n */\n urlCodec?: typeof UrlCodec;\n /**\n * Configures the base href when used in server-side rendered applications\n */\n serverBaseHref?: string;\n /**\n * Configures the base href when used in client-side rendered applications\n */\n appBaseHref?: string;\n}\n\n/**\n * A provider token used to configure the location upgrade module.\n *\n * @publicApi\n */\nexport const LOCATION_UPGRADE_CONFIGURATION = new InjectionToken<LocationUpgradeConfig>(\n ngDevMode ? 'LOCATION_UPGRADE_CONFIGURATION' : '',\n);\n\nconst APP_BASE_HREF_RESOLVED = new InjectionToken<string>(\n ngDevMode ? 'APP_BASE_HREF_RESOLVED' : '',\n);\n\n/**\n * `NgModule` used for providing and configuring Angular's Unified Location Service for upgrading.\n *\n * @see [Using the Unified Angular Location Service](https://angular.io/guide/upgrade#using-the-unified-angular-location-service)\n *\n * @publicApi\n */\n@NgModule({imports: [CommonModule]})\nexport class LocationUpgradeModule {\n static config(config?: LocationUpgradeConfig): ModuleWithProviders<LocationUpgradeModule> {\n return {\n ngModule: LocationUpgradeModule,\n providers: [\n Location,\n {\n provide: $locationShim,\n useFactory: provide$location,\n deps: [UpgradeModule, Location, PlatformLocation, UrlCodec, LocationStrategy],\n },\n {provide: LOCATION_UPGRADE_CONFIGURATION, useValue: config ? config : {}},\n {provide: UrlCodec, useFactory: provideUrlCodec, deps: [LOCATION_UPGRADE_CONFIGURATION]},\n {\n provide: APP_BASE_HREF_RESOLVED,\n useFactory: provideAppBaseHref,\n deps: [LOCATION_UPGRADE_CONFIGURATION, [new Inject(APP_BASE_HREF), new Optional()]],\n },\n {\n provide: LocationStrategy,\n useFactory: provideLocationStrategy,\n deps: [PlatformLocation, APP_BASE_HREF_RESOLVED, LOCATION_UPGRADE_CONFIGURATION],\n },\n ],\n };\n }\n}\n\nexport function provideAppBaseHref(config: LocationUpgradeConfig, appBaseHref?: string) {\n if (config && config.appBaseHref != null) {\n return config.appBaseHref;\n } else if (appBaseHref != null) {\n return appBaseHref;\n }\n return '';\n}\n\nexport function provideUrlCodec(config: LocationUpgradeConfig) {\n const codec = (config && config.urlCodec) || AngularJSUrlCodec;\n return new (codec as any)();\n}\n\nexport function provideLocationStrategy(\n platformLocation: PlatformLocation,\n baseHref: string,\n options: LocationUpgradeConfig = {},\n) {\n return options.useHash\n ? new HashLocationStrategy(platformLocation, baseHref)\n : new PathLocationStrategy(platformLocation, baseHref);\n}\n\nexport function provide$location(\n ngUpgrade: UpgradeModule,\n location: Location,\n platformLocation: PlatformLocation,\n urlCodec: UrlCodec,\n locationStrategy: LocationStrategy,\n) {\n const $locationProvider = new $locationShimProvider(\n ngUpgrade,\n location,\n platformLocation,\n urlCodec,\n locationStrategy,\n );\n\n return $locationProvider.$get();\n}\n"],"names":["isPromise"],"mappings":"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