/** * @license * Copyright Google Inc. 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 */ import {Route} from './config'; import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state'; /** * Identifies the call or event that triggered a navigation. * * * 'imperative': Triggered by `router.navigateByUrl()` or `router.navigate()`. * * 'popstate' : Triggered by a `popstate` event. * * 'hashchange'-: Triggered by a `hashchange` event. * * @publicApi */ export type NavigationTrigger = 'imperative'|'popstate'|'hashchange'; /** * Base for events the router goes through, as opposed to events tied to a specific * route. Fired one time for any given navigation. * * @usageNotes * * ```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` * @publicApi */ export class RouterEvent { constructor( /** A unique ID that the router assigns to every router navigation. */ public id: number, /** The URL that is the destination for this navigation. */ public url: string) {} } /** * An event triggered when a navigation starts. * * @publicApi */ export class NavigationStart extends RouterEvent { /** * Identifies the call or event that triggered the navigation. * An `imperative` trigger is a call to `router.navigateByUrl()` or `router.navigate()`. * */ navigationTrigger?: 'imperative'|'popstate'|'hashchange'; /** * The navigation state that was previously supplied to the `pushState` call, * when the navigation is triggered by a `popstate` event. Otherwise null. * * The state object is defined by `NavigationExtras`, and contains any * developer-defined state value, as well as a unique ID that * the router assigns to every router transition/navigation. * * From the perspective of the router, the router never "goes back". * When the user clicks on the back button in the browser, * a new navigation ID is created. * * Use the ID in this previous-state object to differentiate between a newly created * state and one returned to by a `popstate` event, so that you can restore some * remembered state, such as scroll position. * */ restoredState?: {[k: string]: any, navigationId: number}|null; constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ navigationTrigger: 'imperative'|'popstate'|'hashchange' = 'imperative', /** @docsNotRequired */ restoredState: {[k: string]: any, navigationId: number}|null = null) { super(id, url); this.navigationTrigger = navigationTrigger; this.restoredState = restoredState; } /** @docsNotRequired */ toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; } } /** * An event triggered when a navigation ends successfully. * * @publicApi */ export class NavigationEnd extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string) { super(id, url); } /** @docsNotRequired */ toString(): string { return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}')`; } } /** * An event triggered when a navigation is canceled, directly or indirectly. * * This can happen when a [route guard](guide/router#milestone-5-route-guards) * returns `false` or initiates a redirect by returning a `UrlTree`. * * @publicApi */ export class NavigationCancel extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public reason: string) { super(id, url); } /** @docsNotRequired */ toString(): string { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; } } /** * An event triggered when a navigation fails due to an unexpected error. * * @publicApi */ export class NavigationError extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public error: any) { super(id, url); } /** @docsNotRequired */ toString(): string { return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`; } } /** *An event triggered when routes are recognized. * * @publicApi */ export class RoutesRecognized extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string, /** @docsNotRequired */ public state: RouterStateSnapshot) { super(id, url); } /** @docsNotRequired */ toString(): string { return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}', state: ${this.state})`; } } /** * An event triggered at the start of the Guard phase of routing. * * @publicApi */ export class GuardsCheckStart extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string, /** @docsNotRequired */ public state: RouterStateSnapshot) { super(id, url); } toString(): string { return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}', state: ${this.state})`; } } /** * An event triggered at the end of the Guard phase of routing. * * @publicApi */ export class GuardsCheckEnd extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string, /** @docsNotRequired */ public state: RouterStateSnapshot, /** @docsNotRequired */ public shouldActivate: boolean) { super(id, url); } toString(): string { return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`; } } /** * 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. * * @publicApi */ export class ResolveStart extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string, /** @docsNotRequired */ public state: RouterStateSnapshot) { super(id, url); } toString(): string { return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}', state: ${this.state})`; } } /** * An event triggered at the end of the Resolve phase of routing. * @see `ResolveStart`. * * @publicApi */ export class ResolveEnd extends RouterEvent { constructor( /** @docsNotRequired */ id: number, /** @docsNotRequired */ url: string, /** @docsNotRequired */ public urlAfterRedirects: string, /** @docsNotRequired */ public state: RouterStateSnapshot) { super(id, url); } toString(): string { return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${ this.urlAfterRedirects}', state: ${this.state})`; } } /** * An event triggered before lazy loading a route configuration. * * @publicApi */ export class RouteConfigLoadStart { constructor( /** @docsNotRequired */ public route: Route) {} toString(): string { return `RouteConfigLoadStart(path: ${this.route.path})`; } } /** * An event triggered when a route has been lazy loaded. * * @publicApi */ export class RouteConfigLoadEnd { constructor( /** @docsNotRequired */ public route: Route) {} toString(): string { return `RouteConfigLoadEnd(path: ${this.route.path})`; } } /** * An event triggered at the start of the child-activation * part of the Resolve phase of routing. * @see `ChildActivationEnd` * @see `ResolveStart` * * @publicApi */ export class ChildActivationStart { constructor( /** @docsNotRequired */ public snapshot: ActivatedRouteSnapshot) {} toString(): string { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ChildActivationStart(path: '${path}')`; } } /** * An event triggered at the end of the child-activation part * of the Resolve phase of routing. * @see `ChildActivationStart` * @see `ResolveStart` * * @publicApi */ export class ChildActivationEnd { constructor( /** @docsNotRequired */ public snapshot: ActivatedRouteSnapshot) {} toString(): string { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ChildActivationEnd(path: '${path}')`; } } /** * An event triggered at the start of the activation part * of the Resolve phase of routing. * @see ActivationEnd` * @see `ResolveStart` * * @publicApi */ export class ActivationStart { constructor( /** @docsNotRequired */ public snapshot: ActivatedRouteSnapshot) {} toString(): string { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ActivationStart(path: '${path}')`; } } /** * An event triggered at the end of the activation part * of the Resolve phase of routing. * @see `ActivationStart` * @see `ResolveStart` * * @publicApi */ export class ActivationEnd { constructor( /** @docsNotRequired */ public snapshot: ActivatedRouteSnapshot) {} toString(): string { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ActivationEnd(path: '${path}')`; } } /** * An event triggered by scrolling. * * @publicApi */ export class Scroll { constructor( /** @docsNotRequired */ readonly routerEvent: NavigationEnd, /** @docsNotRequired */ readonly position: [number, number]|null, /** @docsNotRequired */ readonly anchor: string|null) {} toString(): string { const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null; return `Scroll(anchor: '${this.anchor}', position: '${pos}')`; } } /** * Router events that allow you to track the lifecycle of the router. * * The sequence of router events is as follows: * * - `NavigationStart`, * - `RouteConfigLoadStart`, * - `RouteConfigLoadEnd`, * - `RoutesRecognized`, * - `GuardsCheckStart`, * - `ChildActivationStart`, * - `ActivationStart`, * - `GuardsCheckEnd`, * - `ResolveStart`, * - `ResolveEnd`, * - `ActivationEnd` * - `ChildActivationEnd` * - `NavigationEnd`, * - `NavigationCancel`, * - `NavigationError` * - `Scroll` * * @publicApi */ export type Event = RouterEvent|RouteConfigLoadStart|RouteConfigLoadEnd|ChildActivationStart| ChildActivationEnd|ActivationStart|ActivationEnd|Scroll;