-
Notifications
You must be signed in to change notification settings - Fork 9
/
script.ts
56 lines (52 loc) · 1.96 KB
/
script.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import {setAttr} from './attr';
export interface LoadScriptAttributes {
crossorigin?: boolean | 'anonymous' | 'use-credentials' | '';
integrity?: string;
referrerpolicy?: ReferrerPolicy;
}
/**
* Creates new script element with specified attributes
* Note: as the script will be added dynamically, it will be treated as async by the browser
*/
const createScript = (id: string, src: string, attrs: LoadScriptAttributes): HTMLScriptElement => {
const script = document.createElement('script');
script.id = id;
script.src = src;
Object.entries(attrs).forEach(([name, value]) => setAttr(script, name, value));
return script;
};
/**
* Common function that loads script async
* @param id - unique script id that is used as a marker to prevent future load
* @param src - script src (url) to load
* @param attrs - additional attributes to set on the script tag
*/
export function loadScript(id: string, src: string, attrs: LoadScriptAttributes = {}): Promise<Event> {
return new Promise((resolve, reject) => {
const script: HTMLScriptElement =
(document.getElementById(id) || createScript(id, src, attrs)) as HTMLScriptElement;
const state = script.getAttribute('state');
switch (state) {
case 'success': resolve(new Event('load')); break;
case 'error': reject(new Event('error')); break;
default:
script.addEventListener('load', (e: Event) => {
script.setAttribute('state', 'success');
resolve(e);
});
script.addEventListener('error', (e: Event) => {
script.setAttribute('state', 'error');
reject(e);
});
}
if (!script.parentNode) {
const firstScriptTag =
document.querySelector('script') || document.querySelector('head title');
if (firstScriptTag && firstScriptTag.parentNode) {
firstScriptTag.parentNode.insertBefore(script, firstScriptTag);
} else {
reject('Page document structure is incorrect');
}
}
});
}