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
This commit is contained in:
Michal Materowski
2022-04-15 19:38:50 +02:00
committed by Andrew Scott
parent 50004c143b
commit 31d7c3bd71
5 changed files with 33 additions and 24 deletions
+7 -1
View File
@@ -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;
@@ -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);
}
+14 -18
View File
@@ -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 {
@@ -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);
}
+2 -4
View File
@@ -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 */