From 31d7c3bd71fdab3fef1b4615ecb8124fe6c165bd Mon Sep 17 00:00:00 2001 From: Michal Materowski Date: Fri, 15 Apr 2022 19:38:50 +0200 Subject: [PATCH] feat(common): add getState method to LocationStrategy interface (#45648) Adds getState to LocationStrategy interface as it suppose to be the place to control all window.location interactions. BREAKING CHANGE: Adds new required class member that any implementors of the LocationStrategy will need to satisfy. Location does not depend on PlatformLocation anymore. PR Close #45648 --- goldens/public-api/common/index.md | 8 ++++- .../src/location/hash_location_strategy.ts | 4 +++ packages/common/src/location/location.ts | 32 ++++++++----------- .../common/src/location/location_strategy.ts | 7 +++- packages/common/testing/src/location_mock.ts | 6 ++-- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/goldens/public-api/common/index.md b/goldens/public-api/common/index.md index 5c0a4e95592..acaba4ab30f 100644 --- a/goldens/public-api/common/index.md +++ b/goldens/public-api/common/index.md @@ -210,6 +210,8 @@ export class HashLocationStrategy extends LocationStrategy implements OnDestroy // (undocumented) getBaseHref(): string; // (undocumented) + getState(): unknown; + // (undocumented) historyGo(relativePosition?: number): void; // (undocumented) ngOnDestroy(): void; @@ -309,7 +311,7 @@ export class KeyValuePipe implements PipeTransform { // @public class Location_2 implements OnDestroy { - constructor(platformStrategy: LocationStrategy, platformLocation: PlatformLocation); + constructor(locationStrategy: LocationStrategy); back(): void; forward(): void; getState(): unknown; @@ -360,6 +362,8 @@ export abstract class LocationStrategy { // (undocumented) abstract getBaseHref(): string; // (undocumented) + abstract getState(): unknown; + // (undocumented) historyGo?(relativePosition: number): void; // (undocumented) abstract onPopState(fn: LocationChangeListener): void; @@ -636,6 +640,8 @@ export class PathLocationStrategy extends LocationStrategy implements OnDestroy // (undocumented) getBaseHref(): string; // (undocumented) + getState(): unknown; + // (undocumented) historyGo(relativePosition?: number): void; // (undocumented) ngOnDestroy(): void; diff --git a/packages/common/src/location/hash_location_strategy.ts b/packages/common/src/location/hash_location_strategy.ts index 1c16af2bd54..b352eebc02c 100644 --- a/packages/common/src/location/hash_location_strategy.ts +++ b/packages/common/src/location/hash_location_strategy.ts @@ -100,6 +100,10 @@ export class HashLocationStrategy extends LocationStrategy implements OnDestroy this._platformLocation.back(); } + override getState(): unknown { + return this._platformLocation.getState(); + } + override historyGo(relativePosition: number = 0): void { this._platformLocation.historyGo?.(relativePosition); } diff --git a/packages/common/src/location/location.ts b/packages/common/src/location/location.ts index 1c765627314..f603960ccd6 100644 --- a/packages/common/src/location/location.ts +++ b/packages/common/src/location/location.ts @@ -10,7 +10,6 @@ import {EventEmitter, Injectable, OnDestroy, ɵɵinject} from '@angular/core'; import {SubscriptionLike} from 'rxjs'; import {LocationStrategy} from './location_strategy'; -import {PlatformLocation} from './platform_location'; import {joinWithSlash, normalizeQueryParams, stripTrailingSlash} from './util'; /** @publicApi */ @@ -60,20 +59,17 @@ export class Location implements OnDestroy { /** @internal */ _baseHref: string; /** @internal */ - _platformStrategy: LocationStrategy; - /** @internal */ - _platformLocation: PlatformLocation; + _locationStrategy: LocationStrategy; /** @internal */ _urlChangeListeners: ((url: string, state: unknown) => void)[] = []; /** @internal */ _urlChangeSubscription: SubscriptionLike|null = null; - constructor(platformStrategy: LocationStrategy, platformLocation: PlatformLocation) { - this._platformStrategy = platformStrategy; - const browserBaseHref = this._platformStrategy.getBaseHref(); - this._platformLocation = platformLocation; + constructor(locationStrategy: LocationStrategy) { + this._locationStrategy = locationStrategy; + const browserBaseHref = this._locationStrategy.getBaseHref(); this._baseHref = stripTrailingSlash(_stripIndexHtml(browserBaseHref)); - this._platformStrategy.onPopState((ev) => { + this._locationStrategy.onPopState((ev) => { this._subject.emit({ 'url': this.path(true), 'pop': true, @@ -99,7 +95,7 @@ export class Location implements OnDestroy { // TODO: vsavkin. Remove the boolean flag and always include hash once the deprecated router is // removed. path(includeHash: boolean = false): string { - return this.normalize(this._platformStrategy.path(includeHash)); + return this.normalize(this._locationStrategy.path(includeHash)); } /** @@ -107,7 +103,7 @@ export class Location implements OnDestroy { * @returns The current value of the `history.state` object. */ getState(): unknown { - return this._platformLocation.getState(); + return this._locationStrategy.getState(); } /** @@ -148,7 +144,7 @@ export class Location implements OnDestroy { if (url && url[0] !== '/') { url = '/' + url; } - return this._platformStrategy.prepareExternalUrl(url); + return this._locationStrategy.prepareExternalUrl(url); } // TODO: rename this method to pushState @@ -162,7 +158,7 @@ export class Location implements OnDestroy { * */ go(path: string, query: string = '', state: any = null): void { - this._platformStrategy.pushState(state, '', path, query); + this._locationStrategy.pushState(state, '', path, query); this._notifyUrlChangeListeners( this.prepareExternalUrl(path + normalizeQueryParams(query)), state); } @@ -176,7 +172,7 @@ export class Location implements OnDestroy { * @param state Location history state. */ replaceState(path: string, query: string = '', state: any = null): void { - this._platformStrategy.replaceState(state, '', path, query); + this._locationStrategy.replaceState(state, '', path, query); this._notifyUrlChangeListeners( this.prepareExternalUrl(path + normalizeQueryParams(query)), state); } @@ -185,14 +181,14 @@ export class Location implements OnDestroy { * Navigates forward in the platform's history. */ forward(): void { - this._platformStrategy.forward(); + this._locationStrategy.forward(); } /** * Navigates back in the platform's history. */ back(): void { - this._platformStrategy.back(); + this._locationStrategy.back(); } /** @@ -208,7 +204,7 @@ export class Location implements OnDestroy { * @see https://developer.mozilla.org/en-US/docs/Web/API/History_API#Moving_to_a_specific_point_in_history */ historyGo(relativePosition: number = 0): void { - this._platformStrategy.historyGo?.(relativePosition); + this._locationStrategy.historyGo?.(relativePosition); } /** @@ -295,7 +291,7 @@ export class Location implements OnDestroy { } export function createLocation() { - return new Location(ɵɵinject(LocationStrategy as any), ɵɵinject(PlatformLocation as any)); + return new Location(ɵɵinject(LocationStrategy as any)); } function _stripBaseHref(baseHref: string, url: string): string { diff --git a/packages/common/src/location/location_strategy.ts b/packages/common/src/location/location_strategy.ts index 43597911efe..96d155676da 100644 --- a/packages/common/src/location/location_strategy.ts +++ b/packages/common/src/location/location_strategy.ts @@ -34,6 +34,7 @@ import {joinWithSlash, normalizeQueryParams} from './util'; export abstract class LocationStrategy { abstract path(includeHash?: boolean): string; abstract prepareExternalUrl(internal: string): string; + abstract getState(): unknown; abstract pushState(state: any, title: string, url: string, queryParams: string): void; abstract replaceState(state: any, title: string, url: string, queryParams: string): void; abstract forward(): void; @@ -45,7 +46,7 @@ export abstract class LocationStrategy { abstract getBaseHref(): string; } -export function provideLocationStrategy(platformLocation: PlatformLocation) { +export function provideLocationStrategy() { // See #23917 const location = ɵɵinject(DOCUMENT).location; return new PathLocationStrategy( @@ -176,6 +177,10 @@ export class PathLocationStrategy extends LocationStrategy implements OnDestroy this._platformLocation.back(); } + override getState(): unknown { + return this._platformLocation.getState(); + } + override historyGo(relativePosition: number = 0): void { this._platformLocation.historyGo?.(relativePosition); } diff --git a/packages/common/testing/src/location_mock.ts b/packages/common/testing/src/location_mock.ts index e53025b9a54..d609392202f 100644 --- a/packages/common/testing/src/location_mock.ts +++ b/packages/common/testing/src/location_mock.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Location, LocationStrategy, PlatformLocation} from '@angular/common'; +import {Location, LocationStrategy} from '@angular/common'; import {EventEmitter, Injectable} from '@angular/core'; import {SubscriptionLike} from 'rxjs'; @@ -27,9 +27,7 @@ export class SpyLocation implements Location { /** @internal */ _baseHref: string = ''; /** @internal */ - _platformStrategy: LocationStrategy = null!; - /** @internal */ - _platformLocation: PlatformLocation = null!; + _locationStrategy: LocationStrategy = null!; /** @internal */ _urlChangeListeners: ((url: string, state: unknown) => void)[] = []; /** @internal */