From 3541c7d2f01bb6e6da1871086e430ddabc3a31c8 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 7 Jul 2026 18:25:48 +0200 Subject: [PATCH] re-inject content script on 3XX redirects --- src/entrypoints/background/index.ts | 58 +++++++++++++++++------------ src/lib/settings.ts | 17 ++++++--- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/entrypoints/background/index.ts b/src/entrypoints/background/index.ts index 7fc4652..9d37ded 100644 --- a/src/entrypoints/background/index.ts +++ b/src/entrypoints/background/index.ts @@ -2,6 +2,30 @@ import { BackgroundMessageData, BackgroundMessageType } from '@/lib/communicatio import { getHost } from '@/lib/host'; import { HostSettings, UrlReferer } from '@/lib/settings'; +async function reInjectContentScript(domain: string) { + const contentScript: Browser.scripting.RegisteredContentScript = { + id: 'temporary-hosts', + js: ['content-scripts/content.js'], + matches: [`*://${domain}/*`], + persistAcrossSessions: false, + allFrames: true, + runAt: 'document_end' + }; + + const contentScripts = await browser.scripting.getRegisteredContentScripts({ ids: [contentScript.id] }); + if (contentScripts.length !== 0) { + const registeredContentScript = contentScripts[0]; + + // do not double register for same domain + if (registeredContentScript.matches!.indexOf(contentScript.matches![0]) !== -1) return; + + contentScript.matches!.push(...contentScripts[0].matches!); + await browser.scripting.updateContentScripts([contentScript]); + } else { + await browser.scripting.registerContentScripts([contentScript]); + } +} + export default defineBackground(() => { browser.runtime.onMessage.addListener(async (message, sender) => { const type = message.type as BackgroundMessageType; @@ -25,28 +49,7 @@ export default defineBackground(() => { if (import.meta.env.MANIFEST_VERSION === 3) break; data = data as BackgroundMessageData; - - const contentScript: Browser.scripting.RegisteredContentScript = { - id: 'temporary-hosts', - js: ['content-scripts/content.js'], - matches: [`*://${data.domain}/*`], - persistAcrossSessions: false, - allFrames: true, - runAt: 'document_end' - }; - - const contentScripts = await browser.scripting.getRegisteredContentScripts({ ids: [contentScript.id] }); - if (contentScripts.length !== 0) { - const registeredContentScript = contentScripts[0]; - - // do not double register for same domain - if (registeredContentScript.matches!.indexOf(contentScript.matches![0]) !== -1) break; - - contentScript.matches!.push(...contentScripts[0].matches!); - await browser.scripting.updateContentScripts([contentScript]); - } else { - await browser.scripting.registerContentScripts([contentScript]); - } + await reInjectContentScript(data.domain); break; } @@ -80,10 +83,17 @@ export default defineBackground(() => { browser.webRequest.onBeforeRedirect.addListener( async (details) => { - const host = await getHost(new URL(details.url).hostname); + const domain = new URL(details.url).host; + const host = await getHost(domain); if (!host) return; - await HostSettings.addTemporaryHostDomain(host.id, new URL(details.redirectUrl).hostname); + const newDomain = new URL(details.redirectUrl).host; + + await Promise.all([ + HostSettings.addTemporaryHostDomain(host.id, newDomain, { registerContentScript: false }), + // must be called manually, a message sent from a background script is only received on non-background pages + reInjectContentScript(newDomain) + ]); }, { urls: [''], types: ['main_frame', 'sub_frame'] } ); diff --git a/src/lib/settings.ts b/src/lib/settings.ts index 2496cc7..31e4501 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -39,12 +39,17 @@ export class HostSettings { /* tmp */ private static temporaryHostDomain = new Setting>('local:temporaryHostDomain', {}); - static addTemporaryHostDomain = async (hostId: HostId, domain: string) => { - // only has an effect with mv2 - const backgroundScriptInject = - import.meta.env.MANIFEST_VERSION === 2 - ? sendBackgroundMessage(BackgroundMessageType.RegisterContentScript, { domain: domain }) - : Promise.resolve(); + static addTemporaryHostDomain = async ( + hostId: HostId, + domain: string, + options = { + // only has an effect with mv2 + registerContentScript: import.meta.env.MANIFEST_VERSION === 2 + } + ) => { + const backgroundScriptInject = options.registerContentScript + ? sendBackgroundMessage(BackgroundMessageType.RegisterContentScript, { domain: domain }) + : Promise.resolve(); const temporaryHostDomainUpdate = this.temporaryHostDomain.update((val) => { val[domain] = hostId; return val;