From c649869624553864c6ac0620dac6f22ad6ddf578 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:42:46 -0600 Subject: [PATCH] fix(mv3): :wastebasket: Removing unnecessary refreshes. Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> --- add-on/src/lib/dnslink.js | 2 + .../lib/redirect-handler/blockOrObserve.ts | 73 ++++++++++++------- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/add-on/src/lib/dnslink.js b/add-on/src/lib/dnslink.js index fbda761af..d339dd1d0 100644 --- a/add-on/src/lib/dnslink.js +++ b/add-on/src/lib/dnslink.js @@ -8,6 +8,7 @@ import IsIpfs from 'is-ipfs' import LRU from 'lru-cache' import { offlinePeerCount } from './state.js' import { ipfsContentPath, sameGateway, pathAtHttpGateway } from './ipfs-path.js' +import { notifyDnslinkResolved } from './redirect-handler/blockOrObserve.js' const log = debug('ipfs-companion:dnslink') log.error = debug('ipfs-companion:dnslink:error') @@ -74,6 +75,7 @@ export default function createDnslinkResolver (getState) { if (dnslink) { // TODO: set TTL as maxAge: setDnslink(fqdn, dnslink, maxAge) dnslinkResolver.setDnslink(fqdn, dnslink) + notifyDnslinkResolved(fqdn) log(`found dnslink: '${fqdn}' -> '${dnslink}'`) } else { dnslinkResolver.setDnslink(fqdn, false) diff --git a/add-on/src/lib/redirect-handler/blockOrObserve.ts b/add-on/src/lib/redirect-handler/blockOrObserve.ts index dcb31d107..2a192dd17 100644 --- a/add-on/src/lib/redirect-handler/blockOrObserve.ts +++ b/add-on/src/lib/redirect-handler/blockOrObserve.ts @@ -7,6 +7,14 @@ import { CompanionState } from '../../types/companion.js' const log = debug('ipfs-companion:redirect-handler:blockOrObserve') log.error = debug('ipfs-companion:redirect-handler:blockOrObserve:error') +// We need to check if the browser supports the declarativeNetRequest API. +// TODO: replace with check for `Blocking` in `chrome.webRequest.OnBeforeRequestOptions` +// which is currently a bug https://bugs.chromium.org/p/chromium/issues/detail?id=1427952 +export const supportsBlock = !(browser.declarativeNetRequest?.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES === 5000) +export const GLOBAL_STATE_CHANGE = 'GLOBAL_STATE_CHANGE' +export const GLOBAL_STATE_OPTION_CHANGE = 'GLOBAL_STATE_OPTION_CHANGE' +export const DNSLINK_RESOLVED = 'DNSLINK_RESOLVED' + interface regexFilterMap { id: number regexSubstitution: string @@ -17,17 +25,12 @@ interface redirectHandlerInput { redirectUrl: string } +type validMsgToSelfTypes = typeof GLOBAL_STATE_CHANGE | typeof GLOBAL_STATE_OPTION_CHANGE | typeof DNSLINK_RESOLVED interface messageToSelf { - type: typeof GLOBAL_STATE_CHANGE | typeof GLOBAL_STATE_OPTION_CHANGE + type: validMsgToSelfTypes + value?: string } -// We need to check if the browser supports the declarativeNetRequest API. -// TODO: replace with check for `Blocking` in `chrome.webRequest.OnBeforeRequestOptions` -// which is currently a bug https://bugs.chromium.org/p/chromium/issues/detail?id=1427952 -export const supportsBlock = !(browser.declarativeNetRequest?.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES === 5000) -export const GLOBAL_STATE_CHANGE = 'GLOBAL_STATE_CHANGE' -export const GLOBAL_STATE_OPTION_CHANGE = 'GLOBAL_STATE_OPTION_CHANGE' - /** * Notify self about state change. * @returns void @@ -44,15 +47,24 @@ export async function notifyOptionChange (): Promise { return await sendMessageToSelf(GLOBAL_STATE_OPTION_CHANGE) } +/** + * Notify self about dnslink resolved. + * @returns void + * @param value - dnslink value + */ +export async function notifyDnslinkResolved (value: string): Promise { + return await sendMessageToSelf(DNSLINK_RESOLVED, value) +} + /** * Sends message to self to notify about change. * * @param msg */ -async function sendMessageToSelf (msg: typeof GLOBAL_STATE_CHANGE | typeof GLOBAL_STATE_OPTION_CHANGE): Promise { +async function sendMessageToSelf (msg: validMsgToSelfTypes, value: string = ''): Promise { // this check ensures we don't send messages to ourselves if blocking mode is enabled. if (!supportsBlock) { - const message: messageToSelf = { type: msg } + const message: messageToSelf = { type: msg, value } await browser.runtime.sendMessage(message) } } @@ -175,14 +187,10 @@ export async function cleanupRules (resetInMemory: boolean = false): Promise Promise): void { - browser.runtime.onMessage.addListener(async ({ type }: messageToSelf): Promise => { - if (type === GLOBAL_STATE_CHANGE) { - await handlerFn() - } - if (type === GLOBAL_STATE_OPTION_CHANGE) { - await cleanupRules(true) - await handlerFn() +function setupListeners (handlerFnMap: Record Promise>): void { + browser.runtime.onMessage.addListener(async ({ type, value }: messageToSelf): Promise => { + if (type in handlerFnMap) { + await handlerFnMap[type](value as string) } }) } @@ -192,7 +200,8 @@ function setupListeners (handlerFn: () => Promise): void { * * @param {CompanionState} state */ -async function reconcileRulesAndRemoveOld (state: CompanionState): Promise { +async function reconcileRulesAndRemoveOld (getState: () => CompanionState): Promise { + const state = getState() const rules = await browser.declarativeNetRequest.getDynamicRules() const addRules: browser.DeclarativeNetRequest.Rule[] = [] const removeRuleIds: number[] = [] @@ -226,6 +235,13 @@ async function reconcileRulesAndRemoveOld (state: CompanionState): Promise } } + if (rules.length >= browser.declarativeNetRequest.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES - 1) { + // we need to make space for new rules. + // this logic can be improved by removing the oldest rules. + // for now we just remove all the rules. + await cleanupRules(true) + } + // make sure that the default rules are added. for (const { originUrl, redirectUrl } of DEFAULT_LOCAL_RULES) { const { port } = new URL(state.gwURLString) @@ -347,14 +363,21 @@ export function addRuleToDynamicRuleSetGenerator ( removeRuleIds } ) - - // refresh the tab to apply the new rule. - const tabs = await browser.tabs.query({ url: `${originUrl}*` }) - await Promise.all(tabs.map(async tab => await browser.tabs.reload(tab.id))) } - setupListeners(async (): Promise => await reconcileRulesAndRemoveOld(getState())) + setupListeners({ + [GLOBAL_STATE_CHANGE]: async (): Promise => await reconcileRulesAndRemoveOld(getState), + [GLOBAL_STATE_OPTION_CHANGE]: async (): Promise => { + await cleanupRules(true) + await reconcileRulesAndRemoveOld(getState) + }, + [DNSLINK_RESOLVED]: async (value: string): Promise => { + // refresh the tab to apply the new rule. + const tabs = await browser.tabs.query({ url: `${value}*` }) + await Promise.all(tabs.map(async tab => await browser.tabs.reload(tab.id))) + } + }) // call to reconcile rules and remove old ones. - await reconcileRulesAndRemoveOld(state) + await reconcileRulesAndRemoveOld(getState) } }