Skip to content

Commit fe50813

Browse files
atscottthePunderWoman
authored andcommitted
feat(common): Add BrowserPlatformLocation to the public API (#48488)
`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
1 parent 4ab3ed3 commit fe50813

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

goldens/public-api/common/index.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,48 @@ export class AsyncPipe implements OnDestroy, PipeTransform {
5050
static ɵpipe: i0.ɵɵPipeDeclaration<AsyncPipe, "async", true>;
5151
}
5252

53+
// @public
54+
export class BrowserPlatformLocation extends PlatformLocation {
55+
constructor(_doc: any);
56+
// (undocumented)
57+
back(): void;
58+
// (undocumented)
59+
forward(): void;
60+
// (undocumented)
61+
getBaseHrefFromDOM(): string;
62+
// (undocumented)
63+
getState(): unknown;
64+
// (undocumented)
65+
get hash(): string;
66+
// (undocumented)
67+
historyGo(relativePosition?: number): void;
68+
// (undocumented)
69+
get hostname(): string;
70+
// (undocumented)
71+
get href(): string;
72+
// (undocumented)
73+
onHashChange(fn: LocationChangeListener): VoidFunction;
74+
// (undocumented)
75+
onPopState(fn: LocationChangeListener): VoidFunction;
76+
// (undocumented)
77+
get pathname(): string;
78+
set pathname(newPath: string);
79+
// (undocumented)
80+
get port(): string;
81+
// (undocumented)
82+
get protocol(): string;
83+
// (undocumented)
84+
pushState(state: any, title: string, url: string): void;
85+
// (undocumented)
86+
replaceState(state: any, title: string, url: string): void;
87+
// (undocumented)
88+
get search(): string;
89+
// (undocumented)
90+
static ɵfac: i0.ɵɵFactoryDeclaration<BrowserPlatformLocation, never>;
91+
// (undocumented)
92+
static ɵprov: i0.ɵɵInjectableDeclaration<BrowserPlatformLocation>;
93+
}
94+
5395
// @public
5496
export class CommonModule {
5597
// (undocumented)

packages/common/src/location/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
export {HashLocationStrategy} from './hash_location_strategy';
1010
export {Location, PopStateEvent} from './location';
1111
export {APP_BASE_HREF, LocationStrategy, PathLocationStrategy} from './location_strategy';
12-
export {LOCATION_INITIALIZED, LocationChangeEvent, LocationChangeListener, PlatformLocation} from './platform_location';
12+
export {BrowserPlatformLocation, LOCATION_INITIALIZED, LocationChangeEvent, LocationChangeListener, PlatformLocation} from './platform_location';

packages/common/src/location/platform_location.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {Inject, Injectable, InjectionToken, ɵɵinject} from '@angular/core';
10+
1011
import {getDOM} from '../dom_adapter';
1112
import {DOCUMENT} from '../dom_tokens';
1213

@@ -106,25 +107,21 @@ export interface LocationChangeListener {
106107
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
107108
* This class should not be used directly by an application developer. Instead, use
108109
* {@link Location}.
110+
*
111+
* @publicApi
109112
*/
110113
@Injectable({
111114
providedIn: 'platform',
112115
// See #23917
113116
useFactory: createBrowserPlatformLocation,
114117
})
115118
export class BrowserPlatformLocation extends PlatformLocation {
116-
public readonly location!: Location;
117-
private _history!: History;
119+
private _location: Location;
120+
private _history: History;
118121

119122
constructor(@Inject(DOCUMENT) private _doc: any) {
120123
super();
121-
this._init();
122-
}
123-
124-
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
125-
/** @internal */
126-
_init() {
127-
(this as {location: Location}).location = window.location;
124+
this._location = window.location;
128125
this._history = window.history;
129126
}
130127

@@ -145,43 +142,43 @@ export class BrowserPlatformLocation extends PlatformLocation {
145142
}
146143

147144
override get href(): string {
148-
return this.location.href;
145+
return this._location.href;
149146
}
150147
override get protocol(): string {
151-
return this.location.protocol;
148+
return this._location.protocol;
152149
}
153150
override get hostname(): string {
154-
return this.location.hostname;
151+
return this._location.hostname;
155152
}
156153
override get port(): string {
157-
return this.location.port;
154+
return this._location.port;
158155
}
159156
override get pathname(): string {
160-
return this.location.pathname;
157+
return this._location.pathname;
161158
}
162159
override get search(): string {
163-
return this.location.search;
160+
return this._location.search;
164161
}
165162
override get hash(): string {
166-
return this.location.hash;
163+
return this._location.hash;
167164
}
168165
override set pathname(newPath: string) {
169-
this.location.pathname = newPath;
166+
this._location.pathname = newPath;
170167
}
171168

172169
override pushState(state: any, title: string, url: string): void {
173170
if (supportsState()) {
174171
this._history.pushState(state, title, url);
175172
} else {
176-
this.location.hash = url;
173+
this._location.hash = url;
177174
}
178175
}
179176

180177
override replaceState(state: any, title: string, url: string): void {
181178
if (supportsState()) {
182179
this._history.replaceState(state, title, url);
183180
} else {
184-
this.location.hash = url;
181+
this._location.hash = url;
185182
}
186183
}
187184

0 commit comments

Comments
 (0)