1 | window.addEventListener('message', e => {
|
2 | const {data} = e;
|
3 | if (data._strg) {
|
4 | if (data.type === 'init') {
|
5 | win = iframe.contentWindow;
|
6 |
|
7 | for (let i = 0; i < queue.length; i++) {
|
8 | win.postMessage(queue[i], '*');
|
9 | }
|
10 | queue.length = 0;
|
11 | } else if (data.type === 'response') {
|
12 | const {id} = data;
|
13 | const queue = queues[id];
|
14 | if (queue) {
|
15 | const {error, result} = data;
|
16 | queue(error, result);
|
17 | queues[id] = null;
|
18 | _cleanupQueues();
|
19 | }
|
20 | }
|
21 | }
|
22 | });
|
23 |
|
24 | const iframe = document.createElement('iframe');
|
25 | iframe.src = '/iframe.html';
|
26 | iframe.style.cssText = 'display: none;';
|
27 | document.body.appendChild(iframe);
|
28 |
|
29 | let win = null;
|
30 | const queue = [];
|
31 | let ids = 0;
|
32 | let queues = {};
|
33 | let numRemovedQueues = 0;
|
34 | const _cleanupQueues = () => {
|
35 | if (++numRemovedQueues >= 16) {
|
36 | const newQueues = {};
|
37 | for (const id in queues) {
|
38 | const entry = queues[id];
|
39 | if (entry !== null) {
|
40 | newQueues[id] = entry;
|
41 | }
|
42 | }
|
43 | queues = newQueues;
|
44 | numRemovedQueues = 0;
|
45 | }
|
46 | };
|
47 | iframe.addEventListener('error', err => {
|
48 | console.warn(err);
|
49 | });
|
50 |
|
51 | const _request = (method, args) => new Promise((accept, reject) => {
|
52 | const id = ids++;
|
53 | const e = {
|
54 | id,
|
55 | method,
|
56 | args,
|
57 | };
|
58 | if (win) {
|
59 | win.postMessage(e, '*');
|
60 | } else {
|
61 | queue.push(e);
|
62 | }
|
63 | queues[id] = (err, result) => {
|
64 | if (!err) {
|
65 | accept(result);
|
66 | } else {
|
67 | reject(err);
|
68 | }
|
69 | };
|
70 | });
|
71 |
|
72 | module.exports = {
|
73 | get: key => _request('get', {key}),
|
74 | set: (key, value) => _request('set', {key, value}),
|
75 | remove: key => _request('remove', {key}),
|
76 | };
|