Skip to content

Commit 2a86d90

Browse files
authored
feat: allow setting script id (#60)
1 parent 1c41fad commit 2a86d90

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/index.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
import { Loader, LoaderOptions } from ".";
1818

19+
afterEach(() => {
20+
document.getElementsByTagName('html')[0].innerHTML = '';
21+
});
22+
1923
test.each([
2024
[{}, "https://maps.googleapis.com/maps/api/js?callback=__googleMapsCallback"],
2125
[
@@ -52,13 +56,29 @@ test("setScript adds a script to head with correct attributes", () => {
5256

5357
const script = document.head.childNodes[0] as HTMLScriptElement;
5458

59+
expect(script.id).toEqual(loader.id);
5560
expect(script.src).toEqual(loader.createUrl());
5661
expect(script.defer).toBeTruthy();
5762
expect(script.async).toBeTruthy();
5863
expect(script.onerror).toBeTruthy();
5964
expect(script.type).toEqual("text/javascript");
6065
});
6166

67+
test("setScript does not add second script with same id", () => {
68+
new Loader({ apiKey: "foo", id: "bar" })['setScript']();
69+
new Loader({ apiKey: "foo", id: "bar" })['setScript']();
70+
71+
expect(document.head.childNodes.length).toBe(1);
72+
});
73+
74+
test("setScript adds a script with id", () => {
75+
const loader = new Loader({ apiKey: "foo", id: "bar" });
76+
loader["setScript"]();
77+
78+
const script = document.head.childNodes[0] as HTMLScriptElement;
79+
expect(script.id).toEqual(loader.id);
80+
});
81+
6282
test("load should return a promise that resolves even if called twice", () => {
6383
const loader = new Loader({ apiKey: "foo" });
6484

src/index.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ declare global {
2323
}
2424
}
2525

26-
type Libraries = ("drawing" | "geometry" | "localContext" | "places" | "visualization")[];
26+
type Libraries = (
27+
| "drawing"
28+
| "geometry"
29+
| "localContext"
30+
| "places"
31+
| "visualization"
32+
)[];
2733

2834
/**
2935
* The Google Maps JavaScript API
@@ -65,6 +71,10 @@ export interface LoaderOptions {
6571
* receive your default channel.
6672
*/
6773
version?: string;
74+
/**
75+
* The id of the script tag. Before adding a new script, the Loader will check for an existing one.
76+
*/
77+
id?: string;
6878
/**
6979
* When loading the Maps JavaScript API via the URL you may optionally load
7080
* additional libraries through use of the libraries URL parameter. Libraries
@@ -164,6 +174,10 @@ export class Loader {
164174
* See [[LoaderOptions.apiKey]]
165175
*/
166176
apiKey: string;
177+
/**
178+
* See [[LoaderOptions.id]]
179+
*/
180+
id: string;
167181
/**
168182
* See [[LoaderOptions.libraries]]
169183
*/
@@ -205,6 +219,7 @@ export class Loader {
205219
*/
206220
constructor({
207221
apiKey,
222+
id = "__googleMapsScriptId",
208223
libraries = [],
209224
language,
210225
region,
@@ -214,6 +229,7 @@ export class Loader {
214229
}: LoaderOptions) {
215230
this.version = version;
216231
this.apiKey = apiKey;
232+
this.id = id;
217233
this.libraries = libraries;
218234
this.language = language;
219235
this.region = region;
@@ -293,9 +309,14 @@ export class Loader {
293309
* Set the script on document.
294310
*/
295311
private setScript(): void {
312+
if (this.id && document.getElementById(this.id)) {
313+
this.callback();
314+
return;
315+
}
316+
296317
const url = this.createUrl();
297318
const script = document.createElement("script");
298-
319+
script.id = this.id;
299320
script.type = "text/javascript";
300321
script.src = url;
301322
script.onerror = this.loadErrorCallback.bind(this);

0 commit comments

Comments
 (0)