blob: 3e5a9f91bc1a9120de803766efb5eecc3d55b8b6 [file] [log] [blame]
Adrià Vilanova Martínezac2a5612022-12-27 21:51:40 +01001export const kDefaultTimeout = 10 * 1000; // 10 seconds
2
3// Main World OptionsWatcher client (used in scripts injected into the Main
4// World (MW) to get the options).
5export default class MWOptionsWatcherClient {
6 constructor(options, CSTarget, MWTarget, timeout) {
7 if (!CSTarget || !MWTarget)
8 throw new Error(
9 `[MWOptionsWatcherClient] CSTarget and MWTarget are compulsory.`);
10
11 this.CSTarget = CSTarget;
12 this.MWTarget = MWTarget;
13 this.timeout = timeout ?? kDefaultTimeout;
14 this.#setUp(options);
15 }
16
17 #setUp(options) {
18 this.#sendRequestWithoutCallback('setUp', {options});
19 }
20
21 async getOption(option) {
22 if (!option) return null;
23 return this.#sendRequest('getOption', {option});
24 }
25
26 async getOptions(options) {
27 if (!options || options?.length === 0) return [];
28 return this.#sendRequest('getOptions', {options});
29 }
30
31 async isEnabled(option) {
32 if (!option) return null;
33 return this.#sendRequest('isEnabled', {option});
34 }
35
36 async areEnabled(options) {
37 if (!options || options?.length === 0) return [];
38 return this.#sendRequest('areEnabled', {options});
39 }
40
41 #sendRequestWithoutCallback(action, request, uuid) {
42 if (!uuid) uuid = self.crypto.randomUUID();
43 const data = {
44 target: this.CSTarget,
45 uuid,
46 action,
47 request,
48 };
49 window.postMessage(data, '*');
50 }
51
52 #sendRequest(action, request) {
53 return new Promise((res, rej) => {
54 const uuid = self.crypto.randomUUID();
55
56 let timeoutId;
57 let listener = e => {
58 if (e.source !== window || e.data?.target !== this.MWTarget ||
59 e.data?.uuid !== uuid)
60 return;
61
62 window.removeEventListener('message', listener);
63 clearTimeout(timeoutId);
64 res(e.data?.response);
65 };
66 window.addEventListener('message', listener);
67
68 timeoutId = setTimeout(() => {
69 window.removeEventListener('message', listener);
70 rej(new Error('Timed out while waiting response.'));
71 }, this.timeout);
72
73 this.#sendRequestWithoutCallback(action, request, uuid);
74 });
75 }
76}