-
Notifications
You must be signed in to change notification settings - Fork 37
fix(messaging)!: Fix mix up messaging in window and custom event messengers #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d85bce9
3804af6
3fc7f14
57562f3
26e7989
b16bfae
c34fc95
e6fe4a6
7af1395
120cf82
29e7f06
557b529
b38748a
21c9dcd
f33a8b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export default defineUnlistedScript(async () => { | ||
console.log('[duckduckgo-injected.ts] Injected script loaded'); | ||
|
||
duckduckgoMessaging.onMessage('ping', event => { | ||
console.log('[duckduckgo-injected.ts] Received', event); | ||
return 'pong'; | ||
}); | ||
|
||
duckduckgoMessaging.onMessage('ping2', event => { | ||
console.log('[duckduckgo-injected.ts] Received2', event); | ||
return 'pong2'; | ||
}); | ||
|
||
duckduckgoMessaging.sendMessage('fromInjected', undefined).then(res => { | ||
console.log('[duckduckgo-injected.ts] Response:', res); | ||
}); | ||
|
||
const res2 = await duckduckgoMessaging.sendMessage('fromInjected2', undefined); | ||
console.log('[duckduckgo-injected.ts] Response2:', res2); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
export default defineContentScript({ | ||
matches: ['*://*.duckduckgo.com/*'], | ||
|
||
main(ctx) { | ||
console.log('[duckduckgo.content.ts] Content script loaded'); | ||
|
||
duckduckgoMessaging.onMessage('fromInjected', event => { | ||
console.log('[duckduckgo.content.ts] Received:', event); | ||
return 'hello injected'; | ||
}); | ||
|
||
duckduckgoMessaging.onMessage('fromInjected2', event => { | ||
console.log('[duckduckgo.content.ts] Received:', event); | ||
return 'hello injected2'; | ||
}); | ||
|
||
const script = document.createElement('script'); | ||
script.src = browser.runtime.getURL('/duckduckgo-injected.js'); | ||
script.onload = async () => { | ||
const res = await duckduckgoMessaging.sendMessage('ping', undefined); | ||
console.log('[duckduckgo.content.ts] Response:', res); | ||
|
||
const res2 = await duckduckgoMessaging.sendMessage('ping2', undefined); | ||
console.log('[duckduckgo.content.ts] Response2:', res2); | ||
}; | ||
document.head.appendChild(script); | ||
}, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,20 @@ | ||
export default defineUnlistedScript(() => { | ||
export default defineUnlistedScript(async () => { | ||
console.log('[google-injected.ts] Injected script loaded'); | ||
|
||
googleMessaging.onMessage('ping', event => { | ||
console.log('[google-injected.ts] revieved', event); | ||
console.log('[google-injected.ts] Received', event); | ||
return 'pong'; | ||
}); | ||
|
||
googleMessaging.onMessage('ping2', event => { | ||
console.log('[google-injected.ts] Received2', event); | ||
return 'pong2'; | ||
}); | ||
|
||
googleMessaging.sendMessage('fromInjected', undefined).then(res => { | ||
console.log('[google-injected.ts] Response:', res); | ||
}); | ||
|
||
const res2 = await googleMessaging.sendMessage('fromInjected2', undefined); | ||
console.log('[google-injected.ts] Response2:', res2); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { defineCustomEventMessaging } from '@webext-core/messaging/page'; | ||
|
||
export interface DuckduckgoMessagingProtocol { | ||
ping(): string; | ||
ping2(): string; | ||
fromInjected(): string; | ||
fromInjected2(): string; | ||
} | ||
|
||
export const duckduckgoMessaging = defineCustomEventMessaging<DuckduckgoMessagingProtocol>({ | ||
namespace: '@webext-core/messaging-demo/duckduckgo', | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { uid } from 'uid'; | ||
import { GenericMessenger, defineGenericMessanging } from './generic'; | ||
import { NamespaceMessagingConfig } from './types'; | ||
|
||
|
@@ -51,48 +52,67 @@ export type CustomEventMessenger<TProtocolMap extends Record<string, any>> = Gen | |
* websiteMessenger.onMessage("initInjectedScript", (...) => { | ||
* // ... | ||
* }) | ||
* | ||
* * @link Spec diagrams | ||
* https://mermaid.live/edit#pako:eNqVlG9v2jAQxr-KZamvGv7YyYBYVSTGWgmpwAs6VZqQJpMc1BOxM8fZoIjvPieBACUVLC8SO3ru7vc4l9viUEWAGU7hdwYyhG-CLzWPZxLZa67WaKCkAWka01CLxDzMdSsobkKmhtsAUuy2SPIY0oSHwNBCKbQrMyRcGxGKhEuDbAT5qSTiKVJyBGnKl_CJKgUZ5br8eaa0-yPaUP6C0EDUeoX5VBi4hKP_A0dvgqM3wvWlMm-gi-Nb15ybe4k25_oTNPcmNPcKWrm8uzvWRF_Ld2NlAKk_oA_FnCodQ4PJaPR9PBz0X4aTMXp6nrwW6NP-6BH1p-j58enlkNsCoXKVX9WnbATB_f6AWcHWMpsE2AwnQi7JDNeFNNb7fmFILKXSlu-vLILP1HnOUkv3uCdqDemlOAgaVRWWS2phqjoXluipJVJriX6wRE8s0auWSGWJXLdEjpZovSV6ZqlcHjtBoVDFcSZFyG0LrIQ85D9rCfqhJcbnYUIWHRGJxQK0HRbHBrPJsINj0DEXkR0z2zz5DNs_I4YZZnYZwYJnK5ND7qyUZ0ZNNzLEzOgMHKxVtnzDbMFXqd1lSWTr7WdU9db2P2ZbvMasQYjX9AnteaRN3HbP7XgO3mBG3U6z533p-W637bue5-4c_K6UTUGbpOtT36edLvXaLu06GCJhlB6Vc7EYj0WJH4U-p9r9Aynbsqc | ||
*/ | ||
export function defineCustomEventMessaging< | ||
TProtocolMap extends Record<string, any> = Record<string, any>, | ||
>(config: CustomEventMessagingConfig): CustomEventMessenger<TProtocolMap> { | ||
const namespace = config.namespace; | ||
const instanceId = uid(); | ||
|
||
const removeAdditionalListeners: Array<() => void> = []; | ||
|
||
const sendCustomMessage = (event: CustomEvent) => | ||
const sendCustomMessage = (requestEvent: CustomEvent) => | ||
new Promise(res => { | ||
const responseListener = (e: Event) => { | ||
const { detail } = e as CustomEvent; | ||
res(detail); | ||
if ( | ||
detail.namespace === namespace && | ||
detail.instanceId !== instanceId && | ||
detail.message.type === requestEvent.detail.message.type | ||
) { | ||
res(detail.response); | ||
} | ||
}; | ||
removeAdditionalListeners.push(() => | ||
window.removeEventListener(RESPONSE_EVENT, responseListener), | ||
); | ||
window.addEventListener(RESPONSE_EVENT, responseListener, { once: true }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, too, I don't understand why it has been |
||
window.dispatchEvent(event); | ||
window.addEventListener(RESPONSE_EVENT, responseListener); | ||
window.dispatchEvent(requestEvent); | ||
}); | ||
|
||
const messenger = defineGenericMessanging<TProtocolMap, CustomEventMessage, []>({ | ||
...config, | ||
|
||
sendMessage(message) { | ||
const event = new CustomEvent(REQUEST_EVENT, { detail: { message, namespace } }); | ||
return sendCustomMessage(event); | ||
const reqDetail = { message, namespace, instanceId }; | ||
const requestEvent = new CustomEvent(REQUEST_EVENT, { | ||
// @ts-expect-error not exist cloneInto types because implemented only in Firefox. | ||
detail: typeof cloneInto !== 'undefined' ? cloneInto(reqDetail, window) : reqDetail, | ||
Comment on lines
+90
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a problem with |
||
}); | ||
return sendCustomMessage(requestEvent); | ||
}, | ||
|
||
addRootListener(processMessage) { | ||
const listener = async (e: Event) => { | ||
const requestListener = async (e: Event) => { | ||
const { detail, ...event } = e as CustomEvent; | ||
if (detail.namespace !== namespace) return; | ||
if (detail.namespace !== namespace || detail.instanceId === instanceId) return; | ||
|
||
const message = { ...detail.message, event }; | ||
const response = await processMessage(message); | ||
|
||
const responseEvent = new CustomEvent(RESPONSE_EVENT, { detail: response }); | ||
const resDetail = { response, message, instanceId, namespace }; | ||
const responseEvent = new CustomEvent(RESPONSE_EVENT, { | ||
// @ts-expect-error not exist cloneInto types because implemented only in Firefox. | ||
detail: typeof cloneInto !== 'undefined' ? cloneInto(resDetail, window) : resDetail, | ||
}); | ||
window.dispatchEvent(responseEvent); | ||
}; | ||
|
||
window.addEventListener(REQUEST_EVENT, listener); | ||
return () => window.removeEventListener(REQUEST_EVENT, listener); | ||
window.addEventListener(REQUEST_EVENT, requestListener); | ||
return () => window.removeEventListener(REQUEST_EVENT, requestListener); | ||
}, | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a mistake that unlike windowMessage, customEventMessage has been unguarded so far? Is there a particular reason I don't know about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a bug, but could be related to how
window.postMessage
sends the message to all frames in the window.