diff --git a/packages/wxt/src/utils/content-script-context.ts b/packages/wxt/src/utils/content-script-context.ts index 22d68d590..f92ee7e8a 100644 --- a/packages/wxt/src/utils/content-script-context.ts +++ b/packages/wxt/src/utils/content-script-context.ts @@ -39,27 +39,14 @@ import { createLocationWatcher } from './internal/location-watcher'; * ``` */ export class ContentScriptContext implements AbortController { - private static SCRIPT_STARTED_MESSAGE_TYPE = getUniqueEventName( - 'wxt:content-script-started', - ); - - private isTopFrame = window.self === window.top; private abortController: AbortController; private locationWatcher = createLocationWatcher(this); - private receivedMessageIds = new Set(); constructor( private readonly contentScriptName: string, public readonly options?: Omit, ) { this.abortController = new AbortController(); - - if (this.isTopFrame) { - this.listenForNewerScripts({ ignoreFirstEvent: true }); - this.stopOldScripts(); - } else { - this.listenForNewerScripts(); - } } get signal() { @@ -221,8 +208,19 @@ export class ContentScriptContext implements AbortController { if (this.isValid) this.locationWatcher.run(); } + const eventType = type.startsWith('wxt:') ? getUniqueEventName(type) : type + + target.addEventListener?.( + eventType, + () => this.isInvalid, // signals the abort controller when invalid + { + capture: true, + signal: this.signal, + }, + ); + target.addEventListener?.( - type.startsWith('wxt:') ? getUniqueEventName(type) : type, + eventType, handler, { ...options, @@ -241,46 +239,6 @@ export class ContentScriptContext implements AbortController { `Content script "${this.contentScriptName}" context invalidated`, ); } - - stopOldScripts() { - // Use postMessage so it get's sent to all the frames of the page. - window.postMessage( - { - type: ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE, - contentScriptName: this.contentScriptName, - messageId: Math.random().toString(36).slice(2), - }, - '*', - ); - } - - verifyScriptStartedEvent(event: MessageEvent) { - const isScriptStartedEvent = - event.data?.type === ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE; - const isSameContentScript = - event.data?.contentScriptName === this.contentScriptName; - const isNotDuplicate = !this.receivedMessageIds.has(event.data?.messageId); - return isScriptStartedEvent && isSameContentScript && isNotDuplicate; - } - - listenForNewerScripts(options?: { ignoreFirstEvent?: boolean }) { - let isFirst = true; - - const cb = (event: MessageEvent) => { - if (this.verifyScriptStartedEvent(event)) { - this.receivedMessageIds.add(event.data.messageId); - - const wasFirst = isFirst; - isFirst = false; - if (wasFirst && options?.ignoreFirstEvent) return; - - this.notifyInvalidated(); - } - }; - - addEventListener('message', cb); - this.onInvalidated(() => removeEventListener('message', cb)); - } } export interface WxtWindowEventMap extends WindowEventMap {