From afc2cca49d6c972dcaa2ab039fd517172edb3073 Mon Sep 17 00:00:00 2001 From: Simon Jenner Date: Wed, 12 Apr 2023 00:59:20 +0100 Subject: [PATCH] Get rid of blocking behaviour, unify Chrome and Firefox processors, update readme --- README.md | 2 +- manifest.firefox.json | 4 +-- src/background/chrome.ts | 33 ----------------- src/background/firefox.ts | 43 ----------------------- src/background/main.ts | 29 ++++++--------- src/background/{shared.ts => requests.ts} | 37 +++++++++++++++++-- 6 files changed, 46 insertions(+), 102 deletions(-) delete mode 100644 src/background/chrome.ts delete mode 100644 src/background/firefox.ts rename src/background/{shared.ts => requests.ts} (70%) diff --git a/README.md b/README.md index 1123742..3bf2ea4 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ If you want to import bangs from DuckDuckGo, see [this page](./ddg/README.md). ## How the extension works -CBS uses the `WebRequestBlocking` API to intercept requests to the supported search engines, and if a bang is found, redirects the user to the chosen URL with the query inserted. +CBS uses the `webRequest.onBeforeRequest` event listener to listen for requests to the supported search engines, and if a bang is found, sends the user to the chosen URL with the query inserted, using the `tabs.update` API. ## Development diff --git a/manifest.firefox.json b/manifest.firefox.json index a2f0d9c..ab9d1a4 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,7 +1,5 @@ { - "permissions": [ - "webRequestBlocking" - ], + "permissions": [], "host_permissions": [], "background": { "scripts": [ diff --git a/src/background/chrome.ts b/src/background/chrome.ts deleted file mode 100644 index 3c419ea..0000000 --- a/src/background/chrome.ts +++ /dev/null @@ -1,33 +0,0 @@ -import browser, { WebRequest } from 'webextension-polyfill'; - -import { getIgnoredDomains } from './ignoreddomains'; -import { getRedirects, shouldReject } from './shared'; - -export default async function processRequest( - r: WebRequest.OnBeforeRequestDetailsType, -): Promise { - if (r.type !== 'main_frame') { - return Promise.resolve(); - } - - if (shouldReject(await getIgnoredDomains(), r.url)) { - return Promise.resolve(); - } - - // From the current URL, get the redirections (if any) to apply. - const redirections = await getRedirects(r.url, r); - - if (redirections.length === 0) { - return Promise.resolve(); - } - - // Open all URLs (except the first) in new tabs - for (let i = 1; i < redirections.length; i += 1) { - browser.tabs.create({ url: redirections[i] }); - } - - // Finally send the current tab to the first in the array. - browser.tabs.update(r.tabId, { url: redirections[0] }); - - return Promise.resolve(); -} diff --git a/src/background/firefox.ts b/src/background/firefox.ts deleted file mode 100644 index 4e6bc39..0000000 --- a/src/background/firefox.ts +++ /dev/null @@ -1,43 +0,0 @@ -import browser, { WebRequest } from 'webextension-polyfill'; - -import { getIgnoredDomains } from './ignoreddomains'; -import { getRedirects, shouldReject } from './shared'; - -export default async function processRequest( - r: WebRequest.OnBeforeRequestDetailsType, -): Promise { - if (r.type !== 'main_frame') { - return Promise.resolve({}); - } - - if (shouldReject(await getIgnoredDomains(), r.url)) { - return Promise.resolve({}); - } - - // From the current URL, get the redirections (if any) to apply. - const redirections = await getRedirects(r.url, r); - - if (redirections.length === 0) { - return Promise.resolve({}); - } - - // Open all URLs (except the first) in new tabs - for (let i = 1; i < redirections.length; i += 1) { - browser.tabs.create({ url: redirections[i] }); - } - - // Finally redirect the current tab to the first in the array. - // TODO: Is this better than tabs.update? Maybe unify Chrome and FF a bit more. - let res: WebRequest.BlockingResponse; - - if (r.method === 'GET') { - res = { redirectUrl: redirections[0] }; - } else { - // If we're handling a POST request, we need to tell the tab where to go, - // as redirecting the POST would not change the tabs location. - browser.tabs.update(r.tabId, { url: redirections[0] }); - res = { cancel: true }; - } - - return Promise.resolve(res); -} diff --git a/src/background/main.ts b/src/background/main.ts index 4c98a5a..2db955e 100644 --- a/src/background/main.ts +++ b/src/background/main.ts @@ -3,8 +3,7 @@ import browser from 'webextension-polyfill'; import { dev, currentBrowser, version, hash, hostPermissions, } from '../lib/esbuilddefinitions'; -import chromeProcessRequest from './chrome'; -import firefoxProcessRequest from './firefox'; +import processRequest from './requests'; import { Settings } from '../lib/settings'; import * as legacy from './legacy'; import * as storage from '../lib/storage'; @@ -67,23 +66,15 @@ function main(): void { } }); - if (currentBrowser === 'chrome') { - browser.webRequest.onBeforeRequest.addListener( - (r) => { - // Type defs don't like an async non-blocking handler. - chromeProcessRequest(r); - }, - { urls: hostPermissions }, - // The requestBody spec is required for handling POST situations. - ['requestBody'], - ); - } else { - browser.webRequest.onBeforeRequest.addListener( - firefoxProcessRequest, - { urls: hostPermissions }, - ['requestBody', 'blocking'], - ); - } + browser.webRequest.onBeforeRequest.addListener( + (r) => { + // Type defs don't like an async non-blocking handler. + processRequest(r); + }, + { urls: hostPermissions }, + // The requestBody opt is required for handling POST situations. + ['requestBody'], + ); } main(); diff --git a/src/background/shared.ts b/src/background/requests.ts similarity index 70% rename from src/background/shared.ts rename to src/background/requests.ts index 5aca4ef..fd66e37 100644 --- a/src/background/shared.ts +++ b/src/background/requests.ts @@ -1,10 +1,12 @@ -import { WebRequest } from 'webextension-polyfill'; +import browser, { WebRequest } from 'webextension-polyfill'; import { getBangsLookup } from './lookup'; +import { getIgnoredDomains } from './ignoreddomains'; const possibleQueryParams = ['q', 'query', 'eingabe']; -export function shouldReject(blacklist: Readonly, url: string): boolean { +// Should this URL be rejected provided the given blacklist? +function shouldReject(blacklist: Readonly, url: string): boolean { if (blacklist.includes(new URL(url).hostname)) { return true; } @@ -25,7 +27,7 @@ function constructRedirect(redirectUrl: string, queryText: string): string { * @param request (Optional) The request details object from a WebRequestBlocking event. * @returns A list of redirections to issue. */ -export async function getRedirects( +async function getRedirects( reqUrl: string, request: WebRequest.OnBeforeRequestDetailsType | undefined = undefined, ): Promise { @@ -84,3 +86,32 @@ export async function getRedirects( return Promise.resolve(redirects); } + +export default async function processRequest( + r: WebRequest.OnBeforeRequestDetailsType, +): Promise { + if (r.type !== 'main_frame') { + return Promise.resolve(); + } + + if (shouldReject(await getIgnoredDomains(), r.url)) { + return Promise.resolve(); + } + + // From the current URL, get the redirections (if any) to apply. + const redirections = await getRedirects(r.url, r); + + if (redirections.length === 0) { + return Promise.resolve(); + } + + // Open all URLs (except the first) in new tabs + for (let i = 1; i < redirections.length; i += 1) { + browser.tabs.create({ url: redirections[i] }); + } + + // Finally send the current tab to the first in the array. + browser.tabs.update(r.tabId, { url: redirections[0] }); + + return Promise.resolve(); +}