diff options
author | vnugent <public@vaughnnugent.com> | 2023-11-19 14:54:18 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-11-19 14:54:18 -0500 |
commit | 43429314c0989b423e116be3e9f222eba5b636c3 (patch) | |
tree | 78d394b1a995fa137fc542050e730ee76b423561 /extension/src/webext-bridge/internal/post-message.ts | |
parent | bc7b86a242673d7831f6105d000995d9f4d63e09 (diff) |
include webext-bridge modified source
Diffstat (limited to 'extension/src/webext-bridge/internal/post-message.ts')
-rw-r--r-- | extension/src/webext-bridge/internal/post-message.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/extension/src/webext-bridge/internal/post-message.ts b/extension/src/webext-bridge/internal/post-message.ts new file mode 100644 index 0000000..9db4424 --- /dev/null +++ b/extension/src/webext-bridge/internal/post-message.ts @@ -0,0 +1,52 @@ +import type { InternalMessage } from '../types' +import { getMessagePort } from './message-port' + +export interface EndpointWontRespondError { + type: 'error' + transactionID: string +} + +export const usePostMessaging = (thisContext: 'window' | 'content-script') => { + let allocatedNamespace: string + let messagingEnabled = false + let onMessageCallback: ( + msg: InternalMessage | EndpointWontRespondError + ) => void + let portP: Promise<MessagePort> + + return { + enable: () => (messagingEnabled = true), + onMessage: (cb: typeof onMessageCallback) => (onMessageCallback = cb), + postMessage: async(msg: InternalMessage | EndpointWontRespondError) => { + if (thisContext !== 'content-script' && thisContext !== 'window') + throw new Error('Endpoint does not use postMessage') + + if (!messagingEnabled) + throw new Error('Communication with window has not been allowed') + + ensureNamespaceSet(allocatedNamespace) + + return (await portP).postMessage(msg) + }, + setNamespace: (nsps: string) => { + if (allocatedNamespace) + throw new Error('Namespace once set cannot be changed') + + allocatedNamespace = nsps + portP = getMessagePort(thisContext, nsps, ({ data }) => + onMessageCallback?.(data), + ) + }, + } +} + +function ensureNamespaceSet(namespace: string) { + if (typeof namespace !== 'string' || namespace.trim().length === 0) { + throw new Error( + 'webext-bridge uses window.postMessage to talk with other "window"(s) for message routing' + + 'which is global/conflicting operation in case there are other scripts using webext-bridge. ' + + 'Call Bridge#setNamespace(nsps) to isolate your app. Example: setNamespace(\'com.facebook.react-devtools\'). ' + + 'Make sure to use same namespace across all your scripts whereever window.postMessage is likely to be used`', + ) + } +} |