blob: 471cc9b8dee9d018920994052755675b5a5b5536 (
plain) (
blame)
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
57
58
59
60
61
|
// handles dynamic reCAPTCHA loading
const loadHandler = "onRecaptchaLoad";
const script = `https://www.google.com/recaptcha/api.js?onload=${loadHandler}`;
// @ts-ignore
type gRecaptchaInstance = any;
export default class ReCaptchaLoader {
/**
* asynchronously injects reCAPTCHA and resolves once fully loaded
*
* @return {Promise<gRecaptchaInstance>} the grecaptcha inferface
*/
static load (): Promise<gRecaptchaInstance> {
return new Promise((resolve, reject) => {
if (Reflect.has(self, "grecaptcha")) {
// we already have it loaded: reset it
this.instance.reset();
return resolve(this.instance);
}
let el: HTMLScriptElement|null = document.querySelector(`script[src="${script}"]`);
if (el) {
// already loading: don't attempt another load
return;
} else {
el = document.createElement("script");
el.type = "text/javascript";
el.async = true;
el.src = script;
}
// create a load handler:
Reflect.set(self, loadHandler, () => {
resolve(this.instance);
Reflect.deleteProperty(self, loadHandler);
});
// attach the handlers:
el.addEventListener("error", reject);
el.addEventListener("abort", reject);
// no listener for "load": we rely on reCAPTCHA to self-report loading
// inject the tag and begin loading
document.head.appendChild(el);
});
}
/**
* checks whether reCAPTCHA is ready to use
*/
static get isReady (): boolean {
return Reflect.has(self, "grecaptcha");
}
static get instance (): gRecaptchaInstance {
return this.isReady ? Reflect.get(self, "grecaptcha"): null;
}
}
|