Skip to content

Commit

Permalink
feat(common): Add BrowserPlatformLocation to the public API (#48488)
Browse files Browse the repository at this point in the history
`PlatformLocation` is already part of the public API so developers can
create their own. This means that developers would already be able to
access the existing `BrowserPlatformLocation` at runtime by injecting
it. The motivation for adding `BrowserPlatformLocation` to the public
API is because of those facts, but driven more by the fact that we are
looking to include `MockPlatformLocation` by default in TestBed.
Developers would need a way to revert back to the current behavior for
some tests that rely directly on browser interaction.

PR Close #48488
  • Loading branch information
atscott authored and thePunderWoman committed Dec 14, 2022
1 parent 4ab3ed3 commit fe50813
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 20 deletions.
42 changes: 42 additions & 0 deletions goldens/public-api/common/index.md
Expand Up @@ -50,6 +50,48 @@ export class AsyncPipe implements OnDestroy, PipeTransform {
static ɵpipe: i0.ɵɵPipeDeclaration<AsyncPipe, "async", true>;
}

// @public
export class BrowserPlatformLocation extends PlatformLocation {
constructor(_doc: any);
// (undocumented)
back(): void;
// (undocumented)
forward(): void;
// (undocumented)
getBaseHrefFromDOM(): string;
// (undocumented)
getState(): unknown;
// (undocumented)
get hash(): string;
// (undocumented)
historyGo(relativePosition?: number): void;
// (undocumented)
get hostname(): string;
// (undocumented)
get href(): string;
// (undocumented)
onHashChange(fn: LocationChangeListener): VoidFunction;
// (undocumented)
onPopState(fn: LocationChangeListener): VoidFunction;
// (undocumented)
get pathname(): string;
set pathname(newPath: string);
// (undocumented)
get port(): string;
// (undocumented)
get protocol(): string;
// (undocumented)
pushState(state: any, title: string, url: string): void;
// (undocumented)
replaceState(state: any, title: string, url: string): void;
// (undocumented)
get search(): string;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<BrowserPlatformLocation, never>;
// (undocumented)
static ɵprov: i0.ɵɵInjectableDeclaration<BrowserPlatformLocation>;
}

// @public
export class CommonModule {
// (undocumented)
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/location/index.ts
Expand Up @@ -9,4 +9,4 @@
export {HashLocationStrategy} from './hash_location_strategy';
export {Location, PopStateEvent} from './location';
export {APP_BASE_HREF, LocationStrategy, PathLocationStrategy} from './location_strategy';
export {LOCATION_INITIALIZED, LocationChangeEvent, LocationChangeListener, PlatformLocation} from './platform_location';
export {BrowserPlatformLocation, LOCATION_INITIALIZED, LocationChangeEvent, LocationChangeListener, PlatformLocation} from './platform_location';
35 changes: 16 additions & 19 deletions packages/common/src/location/platform_location.ts
Expand Up @@ -7,6 +7,7 @@
*/

import {Inject, Injectable, InjectionToken, ɵɵinject} from '@angular/core';

import {getDOM} from '../dom_adapter';
import {DOCUMENT} from '../dom_tokens';

Expand Down Expand Up @@ -106,25 +107,21 @@ export interface LocationChangeListener {
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
* This class should not be used directly by an application developer. Instead, use
* {@link Location}.
*
* @publicApi
*/
@Injectable({
providedIn: 'platform',
// See #23917
useFactory: createBrowserPlatformLocation,
})
export class BrowserPlatformLocation extends PlatformLocation {
public readonly location!: Location;
private _history!: History;
private _location: Location;
private _history: History;

constructor(@Inject(DOCUMENT) private _doc: any) {
super();
this._init();
}

// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
/** @internal */
_init() {
(this as {location: Location}).location = window.location;
this._location = window.location;
this._history = window.history;
}

Expand All @@ -145,43 +142,43 @@ export class BrowserPlatformLocation extends PlatformLocation {
}

override get href(): string {
return this.location.href;
return this._location.href;
}
override get protocol(): string {
return this.location.protocol;
return this._location.protocol;
}
override get hostname(): string {
return this.location.hostname;
return this._location.hostname;
}
override get port(): string {
return this.location.port;
return this._location.port;
}
override get pathname(): string {
return this.location.pathname;
return this._location.pathname;
}
override get search(): string {
return this.location.search;
return this._location.search;
}
override get hash(): string {
return this.location.hash;
return this._location.hash;
}
override set pathname(newPath: string) {
this.location.pathname = newPath;
this._location.pathname = newPath;
}

override pushState(state: any, title: string, url: string): void {
if (supportsState()) {
this._history.pushState(state, title, url);
} else {
this.location.hash = url;
this._location.hash = url;
}
}

override replaceState(state: any, title: string, url: string): void {
if (supportsState()) {
this._history.replaceState(state, title, url);
} else {
this.location.hash = url;
this._location.hash = url;
}
}

Expand Down

0 comments on commit fe50813

Please sign in to comment.