-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathotterdocs.ts
103 lines (75 loc) · 2.34 KB
/
otterdocs.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import { Router } from "vue-router";
enum OtterDocsEvents {
Ready = '/otter-docs/ready',
Navigate = '/otter-docs/navigate',
Inject = '/otter-docs/inject',
}
type OtterDocsEvent = ReadyEvent | NavigateEvent | InjectEvent;
interface ReadyEvent {
type: OtterDocsEvents.Ready;
}
interface NavigateEvent {
type: OtterDocsEvents.Navigate;
path: string;
}
interface InjectEvent {
type: OtterDocsEvents.Inject;
variables: Record<string, any>;
}
let iframeWindow: (Window | undefined) = undefined
export const initHost = (contentWindow: Window, router: Router) => {
iframeWindow = contentWindow
const isReady = new Promise<boolean>((resolve, reject) => {
window.addEventListener('message', listener(contentWindow, router, resolve));
subscribeToNavigationEvents(contentWindow, router);
});
return isReady
}
const listener = (contentWindow: Window, router: Router, onReady: (ready: boolean) => void) => {
return (event: MessageEvent<OtterDocsEvent>) => {
if (event.source === window) {
// ignore our own events
return
}
console.debug('listener revieved event: ', event)
switch (event.data?.type) {
case OtterDocsEvents.Ready:
handleReady(event.data, contentWindow, router.currentRoute.value.fullPath, onReady)
break;
default:
break;
}
}
}
const sendMessage = (contentWindow: (Window | undefined), event: OtterDocsEvent) => {
if (!contentWindow) {
console.debug('host application is not yet ready to send event: ', event)
return
}
contentWindow.postMessage(event, '*')
}
const handleReady = (event: ReadyEvent, contentWindow: Window, currentPath: string, onReady: (ready: boolean) => void) => {
console.debug('host application is ready')
onReady(true);
const data: NavigateEvent = {
type: OtterDocsEvents.Navigate,
path: currentPath
};
sendMessage(contentWindow, data);
}
const subscribeToNavigationEvents = (contentWindow: Window, router: Router) => {
router.afterEach((to) => {
const event: NavigateEvent = {
type: OtterDocsEvents.Navigate,
path: to.fullPath
};
sendMessage(contentWindow, event)
});
}
export const injectVariables = (variables: Record<string, any>) => {
const event: InjectEvent = {
type: OtterDocsEvents.Inject,
variables
};
sendMessage(iframeWindow, event);
}