A bundled add-on that answers cookie consent dialogs, rejecting all but the essentials by default (or accepting, if the user prefers the banner simply gone), so pages open without one. Built on DuckDuckGo's autoconsent (MPL-2.0): its rule bundle covers hundreds of consent managers, and a reject-button heuristic handles unknown banners in reject mode. The library runs through the page-inject slot in every http(s) frame's isolated world; the add-on hands each frame the user's settings and the rules, and counts what was handled per site for the panel, which also excludes a site with one click. build-inject.js assembles inject.js from the library in node_modules plus the glue, and copies the compact rules and licence into the add-on so a rule update can ship through the add-on channel. Host side: page-inject scripts get theseus.evalInPage for the few rules that need the page's own JavaScript (they already reach the page via contextBridge, so no new trust tier), and api.tabs is open to page-inject add-ons as well as request-filter ones.
39 lines
1.9 KiB
JavaScript
39 lines
1.9 KiB
JavaScript
// 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
|
|
// theseus.evalInPage(code) — run code in the page's main world, resolve
|
|
// its value (cookie-consent rules need it)
|
|
// plus a `require` that only resolves "electron" so scripts written in the
|
|
// ordinary preload idiom keep working.
|
|
const { contextBridge, ipcRenderer, webFrame } = require("electron");
|
|
|
|
let injections = [];
|
|
try { injections = ipcRenderer.sendSync("addon-inject-scripts", location.href) || []; }
|
|
catch (e) { console.warn("[theseus] add-on inject query failed:", e?.message || e); }
|
|
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),
|
|
evalInPage: (code) => webFrame.executeJavaScript(String(code)),
|
|
});
|
|
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);
|
|
}
|
|
}
|