UNPKG

@angular/router

Version:
1,338 lines (1,330 loc) 288 kB
/** * @license Angular v11.0.9 * (c) 2010-2020 Google LLC. https://angular.io/ * License: MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common'), require('@angular/core'), require('rxjs'), require('rxjs/operators')) : typeof define === 'function' && define.amd ? define('@angular/router', ['exports', '@angular/common', '@angular/core', 'rxjs', 'rxjs/operators'], factory) : (global = global || self, factory((global.ng = global.ng || {}, global.ng.router = {}), global.ng.common, global.ng.core, global.rxjs, global.rxjs.operators)); }(this, (function (exports, common, core, rxjs, operators) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); }; } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function (o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); }) : (function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, exports) { for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } ; function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } ; var __setModuleDefault = Object.create ? (function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function (o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * Base for events the router goes through, as opposed to events tied to a specific * route. Fired one time for any given navigation. * * The following code shows how a class subscribes to router events. * * ```ts * class MyService { * constructor(public router: Router, logger: Logger) { * router.events.pipe( * filter((e: Event): e is RouterEvent => e instanceof RouterEvent) * ).subscribe((e: RouterEvent) => { * logger.log(e.id, e.url); * }); * } * } * ``` * * @see `Event` * @see [Router events summary](guide/router#router-events) * @publicApi */ var RouterEvent = /** @class */ (function () { function RouterEvent( /** A unique ID that the router assigns to every router navigation. */ id, /** The URL that is the destination for this navigation. */ url) { this.id = id; this.url = url; } return RouterEvent; }()); /** * An event triggered when a navigation starts. * * @publicApi */ var NavigationStart = /** @class */ (function (_super) { __extends(NavigationStart, _super); function NavigationStart( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ navigationTrigger, /** @docsNotRequired */ restoredState) { if (navigationTrigger === void 0) { navigationTrigger = 'imperative'; } if (restoredState === void 0) { restoredState = null; } var _this = _super.call(this, id, url) || this; _this.navigationTrigger = navigationTrigger; _this.restoredState = restoredState; return _this; } /** @docsNotRequired */ NavigationStart.prototype.toString = function () { return "NavigationStart(id: " + this.id + ", url: '" + this.url + "')"; }; return NavigationStart; }(RouterEvent)); /** * An event triggered when a navigation ends successfully. * * @see `NavigationStart` * @see `NavigationCancel` * @see `NavigationError` * * @publicApi */ var NavigationEnd = /** @class */ (function (_super) { __extends(NavigationEnd, _super); function NavigationEnd( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; return _this; } /** @docsNotRequired */ NavigationEnd.prototype.toString = function () { return "NavigationEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "')"; }; return NavigationEnd; }(RouterEvent)); /** * An event triggered when a navigation is canceled, directly or indirectly. * This can happen when a route guard * returns `false` or initiates a redirect by returning a `UrlTree`. * * @see `NavigationStart` * @see `NavigationEnd` * @see `NavigationError` * * @publicApi */ var NavigationCancel = /** @class */ (function (_super) { __extends(NavigationCancel, _super); function NavigationCancel( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ reason) { var _this = _super.call(this, id, url) || this; _this.reason = reason; return _this; } /** @docsNotRequired */ NavigationCancel.prototype.toString = function () { return "NavigationCancel(id: " + this.id + ", url: '" + this.url + "')"; }; return NavigationCancel; }(RouterEvent)); /** * An event triggered when a navigation fails due to an unexpected error. * * @see `NavigationStart` * @see `NavigationEnd` * @see `NavigationCancel` * * @publicApi */ var NavigationError = /** @class */ (function (_super) { __extends(NavigationError, _super); function NavigationError( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ error) { var _this = _super.call(this, id, url) || this; _this.error = error; return _this; } /** @docsNotRequired */ NavigationError.prototype.toString = function () { return "NavigationError(id: " + this.id + ", url: '" + this.url + "', error: " + this.error + ")"; }; return NavigationError; }(RouterEvent)); /** * An event triggered when routes are recognized. * * @publicApi */ var RoutesRecognized = /** @class */ (function (_super) { __extends(RoutesRecognized, _super); function RoutesRecognized( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects, /** @docsNotRequired */ state) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; _this.state = state; return _this; } /** @docsNotRequired */ RoutesRecognized.prototype.toString = function () { return "RoutesRecognized(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")"; }; return RoutesRecognized; }(RouterEvent)); /** * An event triggered at the start of the Guard phase of routing. * * @see `GuardsCheckEnd` * * @publicApi */ var GuardsCheckStart = /** @class */ (function (_super) { __extends(GuardsCheckStart, _super); function GuardsCheckStart( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects, /** @docsNotRequired */ state) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; _this.state = state; return _this; } GuardsCheckStart.prototype.toString = function () { return "GuardsCheckStart(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")"; }; return GuardsCheckStart; }(RouterEvent)); /** * An event triggered at the end of the Guard phase of routing. * * @see `GuardsCheckStart` * * @publicApi */ var GuardsCheckEnd = /** @class */ (function (_super) { __extends(GuardsCheckEnd, _super); function GuardsCheckEnd( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects, /** @docsNotRequired */ state, /** @docsNotRequired */ shouldActivate) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; _this.state = state; _this.shouldActivate = shouldActivate; return _this; } GuardsCheckEnd.prototype.toString = function () { return "GuardsCheckEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ", shouldActivate: " + this.shouldActivate + ")"; }; return GuardsCheckEnd; }(RouterEvent)); /** * An event triggered at the the start of the Resolve phase of routing. * * Runs in the "resolve" phase whether or not there is anything to resolve. * In future, may change to only run when there are things to be resolved. * * @see `ResolveEnd` * * @publicApi */ var ResolveStart = /** @class */ (function (_super) { __extends(ResolveStart, _super); function ResolveStart( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects, /** @docsNotRequired */ state) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; _this.state = state; return _this; } ResolveStart.prototype.toString = function () { return "ResolveStart(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")"; }; return ResolveStart; }(RouterEvent)); /** * An event triggered at the end of the Resolve phase of routing. * @see `ResolveStart`. * * @publicApi */ var ResolveEnd = /** @class */ (function (_super) { __extends(ResolveEnd, _super); function ResolveEnd( /** @docsNotRequired */ id, /** @docsNotRequired */ url, /** @docsNotRequired */ urlAfterRedirects, /** @docsNotRequired */ state) { var _this = _super.call(this, id, url) || this; _this.urlAfterRedirects = urlAfterRedirects; _this.state = state; return _this; } ResolveEnd.prototype.toString = function () { return "ResolveEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")"; }; return ResolveEnd; }(RouterEvent)); /** * An event triggered before lazy loading a route configuration. * * @see `RouteConfigLoadEnd` * * @publicApi */ var RouteConfigLoadStart = /** @class */ (function () { function RouteConfigLoadStart( /** @docsNotRequired */ route) { this.route = route; } RouteConfigLoadStart.prototype.toString = function () { return "RouteConfigLoadStart(path: " + this.route.path + ")"; }; return RouteConfigLoadStart; }()); /** * An event triggered when a route has been lazy loaded. * * @see `RouteConfigLoadStart` * * @publicApi */ var RouteConfigLoadEnd = /** @class */ (function () { function RouteConfigLoadEnd( /** @docsNotRequired */ route) { this.route = route; } RouteConfigLoadEnd.prototype.toString = function () { return "RouteConfigLoadEnd(path: " + this.route.path + ")"; }; return RouteConfigLoadEnd; }()); /** * An event triggered at the start of the child-activation * part of the Resolve phase of routing. * @see `ChildActivationEnd` * @see `ResolveStart` * * @publicApi */ var ChildActivationStart = /** @class */ (function () { function ChildActivationStart( /** @docsNotRequired */ snapshot) { this.snapshot = snapshot; } ChildActivationStart.prototype.toString = function () { var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return "ChildActivationStart(path: '" + path + "')"; }; return ChildActivationStart; }()); /** * An event triggered at the end of the child-activation part * of the Resolve phase of routing. * @see `ChildActivationStart` * @see `ResolveStart` * @publicApi */ var ChildActivationEnd = /** @class */ (function () { function ChildActivationEnd( /** @docsNotRequired */ snapshot) { this.snapshot = snapshot; } ChildActivationEnd.prototype.toString = function () { var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return "ChildActivationEnd(path: '" + path + "')"; }; return ChildActivationEnd; }()); /** * An event triggered at the start of the activation part * of the Resolve phase of routing. * @see `ActivationEnd` * @see `ResolveStart` * * @publicApi */ var ActivationStart = /** @class */ (function () { function ActivationStart( /** @docsNotRequired */ snapshot) { this.snapshot = snapshot; } ActivationStart.prototype.toString = function () { var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return "ActivationStart(path: '" + path + "')"; }; return ActivationStart; }()); /** * An event triggered at the end of the activation part * of the Resolve phase of routing. * @see `ActivationStart` * @see `ResolveStart` * * @publicApi */ var ActivationEnd = /** @class */ (function () { function ActivationEnd( /** @docsNotRequired */ snapshot) { this.snapshot = snapshot; } ActivationEnd.prototype.toString = function () { var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return "ActivationEnd(path: '" + path + "')"; }; return ActivationEnd; }()); /** * An event triggered by scrolling. * * @publicApi */ var Scroll = /** @class */ (function () { function Scroll( /** @docsNotRequired */ routerEvent, /** @docsNotRequired */ position, /** @docsNotRequired */ anchor) { this.routerEvent = routerEvent; this.position = position; this.anchor = anchor; } Scroll.prototype.toString = function () { var pos = this.position ? this.position[0] + ", " + this.position[1] : null; return "Scroll(anchor: '" + this.anchor + "', position: '" + pos + "')"; }; return Scroll; }()); /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * The primary routing outlet. * * @publicApi */ var PRIMARY_OUTLET = 'primary'; var ParamsAsMap = /** @class */ (function () { function ParamsAsMap(params) { this.params = params || {}; } ParamsAsMap.prototype.has = function (name) { return Object.prototype.hasOwnProperty.call(this.params, name); }; ParamsAsMap.prototype.get = function (name) { if (this.has(name)) { var v = this.params[name]; return Array.isArray(v) ? v[0] : v; } return null; }; ParamsAsMap.prototype.getAll = function (name) { if (this.has(name)) { var v = this.params[name]; return Array.isArray(v) ? v : [v]; } return []; }; Object.defineProperty(ParamsAsMap.prototype, "keys", { get: function () { return Object.keys(this.params); }, enumerable: false, configurable: true }); return ParamsAsMap; }()); /** * Converts a `Params` instance to a `ParamMap`. * @param params The instance to convert. * @returns The new map instance. * * @publicApi */ function convertToParamMap(params) { return new ParamsAsMap(params); } var NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError'; function navigationCancelingError(message) { var error = Error('NavigationCancelingError: ' + message); error[NAVIGATION_CANCELING_ERROR] = true; return error; } function isNavigationCancelingError(error) { return error && error[NAVIGATION_CANCELING_ERROR]; } // Matches the route configuration (`route`) against the actual URL (`segments`). function defaultUrlMatcher(segments, segmentGroup, route) { var parts = route.path.split('/'); if (parts.length > segments.length) { // The actual URL is shorter than the config, no match return null; } if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || parts.length < segments.length)) { // The config is longer than the actual URL but we are looking for a full match, return null return null; } var posParams = {}; // Check each config part against the actual URL for (var index = 0; index < parts.length; index++) { var part = parts[index]; var segment = segments[index]; var isParameter = part.startsWith(':'); if (isParameter) { posParams[part.substring(1)] = segment; } else if (part !== segment.path) { // The actual URL part does not match the config, no match return null; } } return { consumed: segments.slice(0, parts.length), posParams: posParams }; } function shallowEqualArrays(a, b) { if (a.length !== b.length) return false; for (var i = 0; i < a.length; ++i) { if (!shallowEqual(a[i], b[i])) return false; } return true; } function shallowEqual(a, b) { // Casting Object.keys return values to include `undefined` as there are some cases // in IE 11 where this can happen. Cannot provide a test because the behavior only // exists in certain circumstances in IE 11, therefore doing this cast ensures the // logic is correct for when this edge case is hit. var k1 = Object.keys(a); var k2 = Object.keys(b); if (!k1 || !k2 || k1.length != k2.length) { return false; } var key; for (var i = 0; i < k1.length; i++) { key = k1[i]; if (!equalArraysOrString(a[key], b[key])) { return false; } } return true; } /** * Test equality for arrays of strings or a string. */ function equalArraysOrString(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; var aSorted = __spread(a).sort(); var bSorted_1 = __spread(b).sort(); return aSorted.every(function (val, index) { return bSorted_1[index] === val; }); } else { return a === b; } } /** * Flattens single-level nested arrays. */ function flatten(arr) { return Array.prototype.concat.apply([], arr); } /** * Return the last element of an array. */ function last(a) { return a.length > 0 ? a[a.length - 1] : null; } /** * Verifys all booleans in an array are `true`. */ function and(bools) { return !bools.some(function (v) { return !v; }); } function forEach(map, callback) { for (var prop in map) { if (map.hasOwnProperty(prop)) { callback(map[prop], prop); } } } function wrapIntoObservable(value) { if (core.ɵisObservable(value)) { return value; } if (core.ɵisPromise(value)) { // Use `Promise.resolve()` to wrap promise-like instances. // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the // change detection. return rxjs.from(Promise.resolve(value)); } return rxjs.of(value); } /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ function createEmptyUrlTree() { return new UrlTree(new UrlSegmentGroup([], {}), {}, null); } function containsTree(container, containee, exact) { if (exact) { return equalQueryParams(container.queryParams, containee.queryParams) && equalSegmentGroups(container.root, containee.root); } return containsQueryParams(container.queryParams, containee.queryParams) && containsSegmentGroup(container.root, containee.root); } function equalQueryParams(container, containee) { // TODO: This does not handle array params correctly. return shallowEqual(container, containee); } function equalSegmentGroups(container, containee) { if (!equalPath(container.segments, containee.segments)) return false; if (container.numberOfChildren !== containee.numberOfChildren) return false; for (var c in containee.children) { if (!container.children[c]) return false; if (!equalSegmentGroups(container.children[c], containee.children[c])) return false; } return true; } function containsQueryParams(container, containee) { return Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every(function (key) { return equalArraysOrString(container[key], containee[key]); }); } function containsSegmentGroup(container, containee) { return containsSegmentGroupHelper(container, containee, containee.segments); } function containsSegmentGroupHelper(container, containee, containeePaths) { if (container.segments.length > containeePaths.length) { var current = container.segments.slice(0, containeePaths.length); if (!equalPath(current, containeePaths)) return false; if (containee.hasChildren()) return false; return true; } else if (container.segments.length === containeePaths.length) { if (!equalPath(container.segments, containeePaths)) return false; for (var c in containee.children) { if (!container.children[c]) return false; if (!containsSegmentGroup(container.children[c], containee.children[c])) return false; } return true; } else { var current = containeePaths.slice(0, container.segments.length); var next = containeePaths.slice(container.segments.length); if (!equalPath(container.segments, current)) return false; if (!container.children[PRIMARY_OUTLET]) return false; return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next); } } /** * @description * * Represents the parsed URL. * * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a * serialized tree. * UrlTree is a data structure that provides a lot of affordances in dealing with URLs * * @usageNotes * ### Example * * ``` * @Component({templateUrl:'template.html'}) * class MyComponent { * constructor(router: Router) { * const tree: UrlTree = * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment'); * const f = tree.fragment; // return 'fragment' * const q = tree.queryParams; // returns {debug: 'true'} * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET]; * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33' * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor' * g.children['support'].segments; // return 1 segment 'help' * } * } * ``` * * @publicApi */ var UrlTree = /** @class */ (function () { /** @internal */ function UrlTree( /** The root segment group of the URL tree */ root, /** The query params of the URL */ queryParams, /** The fragment of the URL */ fragment) { this.root = root; this.queryParams = queryParams; this.fragment = fragment; } Object.defineProperty(UrlTree.prototype, "queryParamMap", { get: function () { if (!this._queryParamMap) { this._queryParamMap = convertToParamMap(this.queryParams); } return this._queryParamMap; }, enumerable: false, configurable: true }); /** @docsNotRequired */ UrlTree.prototype.toString = function () { return DEFAULT_SERIALIZER.serialize(this); }; return UrlTree; }()); /** * @description * * Represents the parsed URL segment group. * * See `UrlTree` for more information. * * @publicApi */ var UrlSegmentGroup = /** @class */ (function () { function UrlSegmentGroup( /** The URL segments of this group. See `UrlSegment` for more information */ segments, /** The list of children of this group */ children) { var _this = this; this.segments = segments; this.children = children; /** The parent node in the url tree */ this.parent = null; forEach(children, function (v, k) { return v.parent = _this; }); } /** Whether the segment has child segments */ UrlSegmentGroup.prototype.hasChildren = function () { return this.numberOfChildren > 0; }; Object.defineProperty(UrlSegmentGroup.prototype, "numberOfChildren", { /** Number of child segments */ get: function () { return Object.keys(this.children).length; }, enumerable: false, configurable: true }); /** @docsNotRequired */ UrlSegmentGroup.prototype.toString = function () { return serializePaths(this); }; return UrlSegmentGroup; }()); /** * @description * * Represents a single URL segment. * * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix * parameters associated with the segment. * * @usageNotes * ### Example * * ``` * @Component({templateUrl:'template.html'}) * class MyComponent { * constructor(router: Router) { * const tree: UrlTree = router.parseUrl('/team;id=33'); * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET]; * const s: UrlSegment[] = g.segments; * s[0].path; // returns 'team' * s[0].parameters; // returns {id: 33} * } * } * ``` * * @publicApi */ var UrlSegment = /** @class */ (function () { function UrlSegment( /** The path part of a URL segment */ path, /** The matrix parameters associated with a segment */ parameters) { this.path = path; this.parameters = parameters; } Object.defineProperty(UrlSegment.prototype, "parameterMap", { get: function () { if (!this._parameterMap) { this._parameterMap = convertToParamMap(this.parameters); } return this._parameterMap; }, enumerable: false, configurable: true }); /** @docsNotRequired */ UrlSegment.prototype.toString = function () { return serializePath(this); }; return UrlSegment; }()); function equalSegments(as, bs) { return equalPath(as, bs) && as.every(function (a, i) { return shallowEqual(a.parameters, bs[i].parameters); }); } function equalPath(as, bs) { if (as.length !== bs.length) return false; return as.every(function (a, i) { return a.path === bs[i].path; }); } function mapChildrenIntoArray(segment, fn) { var res = []; forEach(segment.children, function (child, childOutlet) { if (childOutlet === PRIMARY_OUTLET) { res = res.concat(fn(child, childOutlet)); } }); forEach(segment.children, function (child, childOutlet) { if (childOutlet !== PRIMARY_OUTLET) { res = res.concat(fn(child, childOutlet)); } }); return res; } /** * @description * * Serializes and deserializes a URL string into a URL tree. * * The url serialization strategy is customizable. You can * make all URLs case insensitive by providing a custom UrlSerializer. * * See `DefaultUrlSerializer` for an example of a URL serializer. * * @publicApi */ var UrlSerializer = /** @class */ (function () { function UrlSerializer() { } return UrlSerializer; }()); /** * @description * * A default implementation of the `UrlSerializer`. * * Example URLs: * * ``` * /inbox/33(popup:compose) * /inbox/33;open=true/messages/44 * ``` * * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to * specify route specific parameters. * * @publicApi */ var DefaultUrlSerializer = /** @class */ (function () { function DefaultUrlSerializer() { } /** Parses a url into a `UrlTree` */ DefaultUrlSerializer.prototype.parse = function (url) { var p = new UrlParser(url); return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment()); }; /** Converts a `UrlTree` into a url */ DefaultUrlSerializer.prototype.serialize = function (tree) { var segment = "/" + serializeSegment(tree.root, true); var query = serializeQueryParams(tree.queryParams); var fragment = typeof tree.fragment === "string" ? "#" + encodeUriFragment(tree.fragment) : ''; return "" + segment + query + fragment; }; return DefaultUrlSerializer; }()); var DEFAULT_SERIALIZER = new DefaultUrlSerializer(); function serializePaths(segment) { return segment.segments.map(function (p) { return serializePath(p); }).join('/'); } function serializeSegment(segment, root) { if (!segment.hasChildren()) { return serializePaths(segment); } if (root) { var primary = segment.children[PRIMARY_OUTLET] ? serializeSegment(segment.children[PRIMARY_OUTLET], false) : ''; var children_1 = []; forEach(segment.children, function (v, k) { if (k !== PRIMARY_OUTLET) { children_1.push(k + ":" + serializeSegment(v, false)); } }); return children_1.length > 0 ? primary + "(" + children_1.join('//') + ")" : primary; } else { var children = mapChildrenIntoArray(segment, function (v, k) { if (k === PRIMARY_OUTLET) { return [serializeSegment(segment.children[PRIMARY_OUTLET], false)]; } return [k + ":" + serializeSegment(v, false)]; }); // use no parenthesis if the only child is a primary outlet route if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) { return serializePaths(segment) + "/" + children[0]; } return serializePaths(segment) + "/(" + children.join('//') + ")"; } } /** * Encodes a URI string with the default encoding. This function will only ever be called from * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't * have to be encoded per https://url.spec.whatwg.org. */ function encodeUriString(s) { return encodeURIComponent(s) .replace(/%40/g, '@') .replace(/%3A/gi, ':') .replace(/%24/g, '$') .replace(/%2C/gi, ','); } /** * This function should be used to encode both keys and values in a query string key/value. In * the following URL, you need to call encodeUriQuery on "k" and "v": * * http://www.site.org/html;mk=mv?k=v#f */ function encodeUriQuery(s) { return encodeUriString(s).replace(/%3B/gi, ';'); } /** * This function should be used to encode a URL fragment. In the following URL, you need to call * encodeUriFragment on "f": * * http://www.site.org/html;mk=mv?k=v#f */ function encodeUriFragment(s) { return encodeURI(s); } /** * This function should be run on any URI segment as well as the key and value in a key/value * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html", * "mk", and "mv": * * http://www.site.org/html;mk=mv?k=v#f */ function encodeUriSegment(s) { return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&'); } function decode(s) { return decodeURIComponent(s); } // Query keys/values should have the "+" replaced first, as "+" in a query string is " ". // decodeURIComponent function will not decode "+" as a space. function decodeQuery(s) { return decode(s.replace(/\+/g, '%20')); } function serializePath(path) { return "" + encodeUriSegment(path.path) + serializeMatrixParams(path.parameters); } function serializeMatrixParams(params) { return Object.keys(params) .map(function (key) { return ";" + encodeUriSegment(key) + "=" + encodeUriSegment(params[key]); }) .join(''); } function serializeQueryParams(params) { var strParams = Object.keys(params).map(function (name) { var value = params[name]; return Array.isArray(value) ? value.map(function (v) { return encodeUriQuery(name) + "=" + encodeUriQuery(v); }).join('&') : encodeUriQuery(name) + "=" + encodeUriQuery(value); }); return strParams.length ? "?" + strParams.join('&') : ''; } var SEGMENT_RE = /^[^\/()?;=#]+/; function matchSegments(str) { var match = str.match(SEGMENT_RE); return match ? match[0] : ''; } var QUERY_PARAM_RE = /^[^=?&#]+/; // Return the name of the query param at the start of the string or an empty string function matchQueryParams(str) { var match = str.match(QUERY_PARAM_RE); return match ? match[0] : ''; } var QUERY_PARAM_VALUE_RE = /^[^?&#]+/; // Return the value of the query param at the start of the string or an empty string function matchUrlQueryParamValue(str) { var match = str.match(QUERY_PARAM_VALUE_RE); return match ? match[0] : ''; } var UrlParser = /** @class */ (function () { function UrlParser(url