-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathinitialize.ts
75 lines (63 loc) · 2.41 KB
/
initialize.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
import { ConnectMessage, KnownSDK } from './types'
import connect, { Channel } from './channel'
export default function createInitializer(
currentWindow: Window,
apiCreator: (channel: Channel, data: ConnectMessage, window: Window) => KnownSDK
) {
const connectDeferred = createDeferred()
connectDeferred.promise.then(([channel]: [Channel]) => {
const { document } = currentWindow
document.addEventListener('focus', () => channel.send('setActive', true), true)
document.addEventListener('blur', () => channel.send('setActive', false), true)
})
// We need to connect right away so we can record incoming
// messages before `init` is called.
connect(currentWindow, (...args) => connectDeferred.resolve(args))
return function init(
initCb: (sdk: KnownSDK, customSdk: any) => any,
{
makeCustomApi,
supressIframeWarning,
}: { makeCustomApi?: Function; supressIframeWarning?: boolean } = {
supressIframeWarning: false,
}
) {
if (!supressIframeWarning && currentWindow.self === currentWindow.top) {
console.error(`Cannot use ui-extension-sdk outside of Contenful:
In order for the ui-extension-sdk to function correctly, your app needs to be run in an iframe in the Contentful Web App.
Learn more about local development with the ui-extension-sdk here:
https://www.contentful.com/developers/docs/extensibility/ui-extensions/faq/#how-can-i-use-the-ui-extension-sdk-locally`)
}
connectDeferred.promise.then(
([channel, params, messageQueue]: [Channel, ConnectMessage, unknown[]]) => {
const api = apiCreator(channel, params, currentWindow)
let customApi
if (typeof makeCustomApi === 'function') {
customApi = makeCustomApi(channel, params)
}
// Handle pending incoming messages.
// APIs are created before so handlers are already
// registered on the channel.
messageQueue.forEach((m) => {
// TODO Expose private handleMessage method
;(channel as any)._handleMessage(m)
})
// Hand over control to the developer.
initCb(api, customApi)
}
)
}
}
function createDeferred<T = any>() {
const deferred: {
promise: Promise<T>
resolve: (value: T | PromiseLike<T>) => void
} = {
promise: null as any,
resolve: null as any,
}
deferred.promise = new Promise<T>((resolve) => {
deferred.resolve = resolve
})
return deferred
}