diff --git a/packages/browser-extension/src/manifest.json b/packages/browser-extension/src/manifest.json index 72c0dab..c964baf 100644 --- a/packages/browser-extension/src/manifest.json +++ b/packages/browser-extension/src/manifest.json @@ -60,7 +60,7 @@ } ], "host_permissions": ["http://*/*", "https://*/*"], - "permissions": ["contextMenus", "declarativeNetRequest", "scripting", "storage"], + "permissions": ["contextMenus", "declarativeNetRequest", "scripting", "storage", "webRequest"], "web_accessible_resources": [ { "matches": ["http://*/*", "https://*/*"], diff --git a/packages/browser-extension/src/scripts/background.js b/packages/browser-extension/src/scripts/background.js index c94fbf9..49c4d04 100644 --- a/packages/browser-extension/src/scripts/background.js +++ b/packages/browser-extension/src/scripts/background.js @@ -233,3 +233,43 @@ browser.runtime.onInstalled.addListener(() => { browser.runtime.onStartup.addListener(() => { refreshData(); }); + +/** + * @description Listen to the moment before a request is made to apply the rules + */ +browser.webRequest.onBeforeRequest.addListener( + async (details) => { + const { tabId, type, url } = details; + + if (tabId > -1 && type === 'main_frame') { + const manifest = browser.runtime.getManifest(); + const excludeMatches = manifest.content_scripts[0].exclude_matches; + const excludePatterns = excludeMatches.map( + (match) => `^${match.replaceAll('*.', '*(.)?').replaceAll('*', '.*')}$` + ); + + if (excludePatterns.some((pattern) => new RegExp(pattern).test(url))) { + return; + } + + const hostname = url.split('.').slice(-3).join('.').replace('www.', ''); + const store = await storage.get(hostname); + const state = store[hostname] ?? { enabled: true }; + + if (state.enabled) { + const { data } = await storage.get('data'); + + if (data?.rules?.length) { + browser.declarativeNetRequest.updateSessionRules({ + addRules: data.rules.map((rule) => ({ + ...rule, + condition: { ...rule.condition, tabIds: [tabId] }, + })), + removeRuleIds: data.rules.map((rule) => rule.id), + }); + } + } + } + }, + { urls: [''] } +); diff --git a/packages/browser-extension/src/scripts/content.js b/packages/browser-extension/src/scripts/content.js index a80be05..fd48417 100644 --- a/packages/browser-extension/src/scripts/content.js +++ b/packages/browser-extension/src/scripts/content.js @@ -307,7 +307,9 @@ function filterNodeEarly(node, stopRecursion) { * @returns {void} */ function fix() { - const backdrops = tokens.backdrops.length ? [...document.querySelectorAll(tokens.backdrops)] : []; + const backdrops = tokens.backdrops?.length + ? [...document.querySelectorAll(tokens.backdrops)] + : []; const domains = skips.domains.map((x) => (x.split('.').length < 3 ? `*${x}` : x)); for (const backdrop of backdrops) { @@ -364,7 +366,9 @@ function fix() { * @returns {void} */ function restoreDOM() { - const backdrops = tokens.backdrops.length ? [...document.querySelectorAll(tokens.backdrops)] : []; + const backdrops = tokens.backdrops?.length + ? [...document.querySelectorAll(tokens.backdrops)] + : []; for (const backdrop of backdrops) { if (backdrop.children.length === 0 && backdrop.hasAttribute(dataAttributeName)) { @@ -431,10 +435,10 @@ async function setUp(params = {}) { if (state.enabled) { const data = await dispatch({ hostname, type: 'GET_DATA' }); - commonWords = data.commonWords ?? commonWords; - fixes = data.fixes ?? fixes; - skips = data.skips ?? skips; - tokens = data.tokens ?? tokens; + commonWords = data?.commonWords ?? commonWords; + fixes = data?.fixes ?? fixes; + skips = data?.skips ?? skips; + tokens = data?.tokens ?? tokens; if (count > 0) { dispatch({ type: 'SET_BADGE', value: `${count}` });