// Session-wide preload that runs every page-inject add-on's bridge script in // the isolated world of tabs whose URL matches the add-on's declared origin // patterns. Registered via session.defaultSession.setPreloads in main.js // alongside bcnr-preload.js. // // The decision of WHICH scripts apply is made in main against the sender's // committed URL, not against anything the page can influence. Each script // gets a `theseus` object scoped to its add-on id: // theseus.contextBridge — expose an API into the page's main world // theseus.invoke(msg, payload) — call the add-on's onMessage(msg) handler // theseus.origin — the page origin main will show the user // plus a `require` that only resolves "electron" so scripts written in the // ordinary preload idiom keep working. const { contextBridge, ipcRenderer } = require("electron"); let injections = []; try { injections = ipcRenderer.sendSync("addon-inject-scripts", location.href) || []; } catch {} for (const inj of injections) { const id = String(inj.id); const theseus = Object.freeze({ id, origin: inj.origin, contextBridge, invoke: (msg, payload) => ipcRenderer.invoke("addon-page-msg", id, String(msg), payload), }); const scopedRequire = (name) => { if (name === "electron") return { contextBridge }; throw new Error(`addon inject scripts may only require("electron") — got ${name}`); }; try { new Function("theseus", "require", inj.source)(theseus, scopedRequire); } catch (e) { console.warn(`[theseus] add-on "${id}" page-inject failed:`, e?.message || e); } }