From 1d2378e74eada69fbce27d7baba1df2fdc22dbcc Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 21 Feb 2025 08:23:27 -0500 Subject: [PATCH] [mv3] Workaround for permissions dialog preventing proper mode change This is a Chromium-specific issue. Related issue: https://github.com/uBlockOrigin/uBOL-home/issues/280 --- platform/mv3/extension/js/background.js | 43 ++++++++++++++++++++++--- platform/mv3/extension/js/popup.js | 10 ++++++ platform/mv3/make-rulesets.js | 10 +++--- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/platform/mv3/extension/js/background.js b/platform/mv3/extension/js/background.js index 9577eeea6..7874b3d01 100644 --- a/platform/mv3/extension/js/background.js +++ b/platform/mv3/extension/js/background.js @@ -45,6 +45,11 @@ import { getAdminRulesets, } from './admin.js'; +import { + broadcastMessage, + hostnamesFromMatches, +} from './utils.js'; + import { enableRulesets, excludeFromStrictBlock, @@ -70,7 +75,6 @@ import { saveRulesetConfig, } from './config.js'; -import { broadcastMessage } from './utils.js'; import { registerInjectables } from './scripting-manager.js'; /******************************************************************************/ @@ -79,6 +83,8 @@ const UBOL_ORIGIN = runtime.getURL('').replace(/\/$/, ''); const canShowBlockedCount = typeof dnr.setExtensionActionOptions === 'function'; +let pendingPermissionRequest; + /******************************************************************************/ function getCurrentVersion() { @@ -116,6 +122,30 @@ async function onPermissionsRemoved() { return true; } +// https://github.com/uBlockOrigin/uBOL-home/issues/280 +async function onPermissionsAdded(permissions) { + const details = pendingPermissionRequest; + pendingPermissionRequest = undefined; + if ( details === undefined ) { return; } + const defaultMode = await getDefaultFilteringMode(); + if ( defaultMode >= MODE_OPTIMAL ) { return; } + if ( Array.isArray(permissions.origins) === false ) { return; } + const hostnames = hostnamesFromMatches(permissions.origins); + if ( hostnames.includes(details.hostname) === false ) { return; } + const beforeLevel = await getFilteringMode(details.hostname); + if ( beforeLevel === details.afterLevel ) { return; } + const afterLevel = await setFilteringMode(details.hostname, details.afterLevel); + if ( afterLevel !== details.afterLevel ) { return; } + await registerInjectables(); + if ( rulesetConfig.autoReload ) { + self.setTimeout(( ) => { + browser.tabs.update(details.tabId, { + url: details.url, + }); + }, 437); + } +} + /******************************************************************************/ async function gotoURL(url, type) { @@ -312,6 +342,10 @@ function onMessage(request, sender, callback) { return true; } + case 'setPendingFilteringMode': + pendingPermissionRequest = request; + break; + case 'getDefaultFilteringMode': { getDefaultFilteringMode().then(level => { callback(level); @@ -434,10 +468,6 @@ async function start() { runtime.onMessage.addListener(onMessage); - browser.permissions.onRemoved.addListener( - ( ) => { onPermissionsRemoved(); } - ); - if ( process.firstRun ) { const enableOptimal = await hasOmnipotence(); if ( enableOptimal ) { @@ -463,6 +493,9 @@ async function start() { if ( process.wakeupRun === false ) { adminReadEx('disabledFeatures'); } + + browser.permissions.onRemoved.addListener(onPermissionsRemoved); + browser.permissions.onAdded.addListener(onPermissionsAdded); } // https://github.com/uBlockOrigin/uBOL-home/issues/199 diff --git a/platform/mv3/extension/js/popup.js b/platform/mv3/extension/js/popup.js index 761f82032..d0eefb1bb 100644 --- a/platform/mv3/extension/js/popup.js +++ b/platform/mv3/extension/js/popup.js @@ -74,6 +74,16 @@ async function commitFilteringMode() { const afterLevel = parseInt(modeSlider.dataset.level, 10); const beforeLevel = parseInt(modeSlider.dataset.levelBefore, 10); if ( afterLevel > 1 ) { + if ( beforeLevel <= 1 ) { + sendMessage({ + what: 'setPendingFilteringMode', + tabId: currentTab.id, + url: tabURL.href, + hostname: targetHostname, + beforeLevel, + afterLevel, + }); + } let granted = false; try { granted = await browser.permissions.request({ diff --git a/platform/mv3/make-rulesets.js b/platform/mv3/make-rulesets.js index 6df89f918..9279ea6fe 100644 --- a/platform/mv3/make-rulesets.js +++ b/platform/mv3/make-rulesets.js @@ -93,7 +93,7 @@ const uidint32 = (s) => { const stdOutput = []; -const log = (text, silent = false) => { +const log = (text, silent = true) => { stdOutput.push(text); if ( silent === false ) { console.log(text); @@ -166,7 +166,7 @@ const requiredRedirectResources = new Set(); // This will be used to sign our inserted `!#trusted on` directives const secret = createHash('sha256').update(randomBytes(16)).digest('hex').slice(0,16); -log(`Secret: ${secret}`); +log(`Secret: ${secret}`, false); /******************************************************************************/ @@ -245,7 +245,7 @@ async function fetchList(assetDetails) { return { url, content }; } } - log(`No valid content for ${details.name}`); + log(`No valid content for ${details.name}`, false); return { url, content: '' }; }) ); @@ -257,7 +257,7 @@ async function fetchList(assetDetails) { const text = parts.join('\n'); if ( text === '' ) { - log('No filterset found'); + log('No filterset found', false); } return text; } @@ -1308,7 +1308,7 @@ async function main() { const minutePart = Math.floor(now.getUTCMinutes()); version = `${yearPart}.${monthPart}.${dayPart}.${hourPart * 60 + minutePart}`; } - log(`Version: ${version}`); + log(`Version: ${version}`, false); // Get assets.json content const assets = await fs.readFile(