-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathPostMessageIframeTransport.ts
66 lines (60 loc) · 2.21 KB
/
PostMessageIframeTransport.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
60
61
62
63
64
65
66
import { Transport } from "./Transport";
import { JSONRPCRequestData, IJSONRPCData, getNotifications } from "../Request";
class PostMessageIframeTransport extends Transport {
public uri: string;
public frame: undefined | null | Window;
public postMessageID: string;
public origin: string;
constructor(uri: string) {
super();
this.uri = uri;
this.origin = new URL(uri).origin;
this.postMessageID = `post-message-transport-${Math.random()}`;
}
public createWindow(uri: string): Promise<Window | null> {
return new Promise((resolve, reject) => {
let frame: Window | null;
const iframe = document.createElement("iframe");
iframe.setAttribute("id", this.postMessageID);
iframe.setAttribute("width", "0px");
iframe.setAttribute("height", "0px");
iframe.setAttribute("style", "visiblity:hidden;border:none;outline:none;");
iframe.addEventListener("load", () => {
resolve(frame);
});
iframe.setAttribute("src", uri);
window.document.body.appendChild(iframe);
frame = iframe.contentWindow;
});
}
private messageHandler = (ev: MessageEvent) => {
if (ev.origin === this.origin)
this.transportRequestManager.resolveResponse(JSON.stringify(ev.data));
}
public connect(): Promise<any> {
const urlRegex = /^(http|https):\/\/.*$/;
return new Promise(async (resolve, reject) => {
if (!urlRegex.test(this.uri)) {
reject(new Error("Bad URI"));
}
this.frame = await this.createWindow(this.uri);
window.addEventListener("message", this.messageHandler);
resolve();
});
}
public async sendData(data: JSONRPCRequestData, timeout: number | null = 5000): Promise<any> {
const prom = this.transportRequestManager.addRequest(data, null);
const notifications = getNotifications(data);
if (this.frame) {
this.frame.postMessage((data as IJSONRPCData).request, this.origin);
this.transportRequestManager.settlePendingRequest(notifications);
}
return prom;
}
public close(): void {
const el = document.getElementById(this.postMessageID);
el?.remove();
window.removeEventListener("message", this.messageHandler);
}
}
export default PostMessageIframeTransport;