/
iframe-manager.ts
59 lines (49 loc) · 1.39 KB
/
iframe-manager.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
57
58
59
//
// Copyright 2023 DXOS.org
//
import { PublicKey } from '@dxos/keys';
import { createIFrame } from '@dxos/rpc-tunnel';
import { type MaybePromise } from '@dxos/util';
export class IFrameManager {
private _iframe?: HTMLIFrameElement;
private readonly _source: URL;
private readonly _onOpen?: () => MaybePromise<void>;
private readonly _onMessage?: (event: MessageEvent) => MaybePromise<void>;
constructor({
source,
onOpen,
onMessage,
}: {
source: URL;
onOpen?: () => MaybePromise<void>;
onMessage?: (event: MessageEvent) => MaybePromise<void>;
}) {
this._source = source;
this._onOpen = onOpen;
this._onMessage = onMessage;
this._messageHandler = this._messageHandler.bind(this);
}
get source() {
return this._source;
}
get iframe() {
return this._iframe;
}
async open() {
if (this._iframe) {
return;
}
window.addEventListener('message', this._messageHandler);
const iframeId = `__DXOS_CLIENT_${PublicKey.random().toHex()}__`;
this._iframe = createIFrame(this._source.toString(), iframeId, { allow: 'clipboard-read; clipboard-write' });
await this._onOpen?.();
}
async close() {
window.removeEventListener('message', this._messageHandler);
this._iframe?.remove();
this._iframe = undefined;
}
private async _messageHandler(event: MessageEvent) {
void this._onMessage?.(event);
}
}