From a56e13156f1fd34a5abfdc937e7c6d25e871d7d9 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 25 Apr 2025 11:25:50 -0400 Subject: [PATCH] [mv3] Add more managed policies "showBlockedCount": Boolean, to enable/disable the badge count on the toolbar icon. "strictBlockMode": Boolean. to enable/disable strict-blocking. Related issues/discussion: - https://github.com/uBlockOrigin/uBOL-home/discussions/35#discussioncomment-12567804 - https://github.com/uBlockOrigin/uBOL-home/issues/334 --- platform/mv3/extension/js/admin.js | 76 ++++++++++++++++++-- platform/mv3/extension/js/background.js | 4 ++ platform/mv3/extension/js/config.js | 2 +- platform/mv3/extension/js/ruleset-manager.js | 6 +- platform/mv3/extension/managed_storage.json | 22 ++++-- 5 files changed, 95 insertions(+), 15 deletions(-) diff --git a/platform/mv3/extension/js/admin.js b/platform/mv3/extension/js/admin.js index 759651617..865f37dda 100644 --- a/platform/mv3/extension/js/admin.js +++ b/platform/mv3/extension/js/admin.js @@ -28,6 +28,7 @@ import { import { enableRulesets, getRulesetDetails, + setStrictBlockMode, } from './ruleset-manager.js'; import { @@ -36,19 +37,74 @@ import { readFilteringModeDetails, } from './mode-manager.js'; +import { + rulesetConfig, + saveRulesetConfig, +} from './config.js'; + import { broadcastMessage } from './utils.js'; import { dnr } from './ext-compat.js'; import { registerInjectables } from './scripting-manager.js'; -import { rulesetConfig } from './config.js'; import { ubolLog } from './debug.js'; /******************************************************************************/ +export async function loadAdminConfig() { + const [ + showBlockedCount, + strictBlockMode, + ] = await Promise.all([ + adminReadEx('showBlockedCount'), + adminReadEx('strictBlockMode'), + ]); + applyAdminConfig({ showBlockedCount, strictBlockMode }); +} + +/******************************************************************************/ + +function applyAdminConfig(config, apply = false) { + const toApply = []; + for ( const [ key, val ] of Object.entries(config) ) { + if ( typeof val !== typeof rulesetConfig[key] ) { continue; } + if ( val === rulesetConfig[key] ) { continue; } + rulesetConfig[key] = val; + toApply.push(key); + } + if ( toApply.length === 0 ) { return; } + saveRulesetConfig(); + if ( apply !== true ) { return; } + while ( toApply.length !== 0 ) { + const key = toApply.pop(); + switch ( key ) { + case 'showBlockedCount': { + if ( typeof dnr.setExtensionActionOptions !== 'function' ) { break; } + const { showBlockedCount } = config; + dnr.setExtensionActionOptions({ + displayActionCountAsBadgeText: showBlockedCount, + }); + broadcastMessage({ showBlockedCount }); + break; + } + case 'strictBlockMode': { + const { strictBlockMode } = config; + setStrictBlockMode(strictBlockMode, true).then(( ) => { + broadcastMessage({ strictBlockMode }); + }); + break; + } + default: + break; + } + } +} + +/******************************************************************************/ + const adminSettings = { - keys: new Set(), + keys: new Map(), timer: undefined, - change(key) { - this.keys.add(key); + change(key, value) { + this.keys.set(key, value); if ( this.timer !== undefined ) { return; } this.timer = self.setTimeout(( ) => { this.timer = undefined; @@ -80,6 +136,16 @@ const adminSettings = { const trustedSites = await getTrustedSites(); broadcastMessage({ trustedSites: Array.from(trustedSites) }); } + if ( this.keys.has('showBlockedCount') ) { + ubolLog('admin setting "showBlockedCount" changed'); + const showBlockedCount = this.keys.get('showBlockedCount'); + applyAdminConfig({ showBlockedCount }, true); + } + if ( this.keys.has('strictBlockMode') ) { + ubolLog('admin setting "strictBlockMode" changed'); + const strictBlockMode = this.keys.get('strictBlockMode'); + applyAdminConfig({ strictBlockMode }, true); + } this.keys.clear(); } }; @@ -142,7 +208,7 @@ export async function adminReadEx(key) { localWrite(adminKey, { data: value }), ]); if ( JSON.stringify(value) === JSON.stringify(cacheValue) ) { return; } - adminSettings.change(key); + adminSettings.change(key, value); }); return cacheValue; } diff --git a/platform/mv3/extension/js/background.js b/platform/mv3/extension/js/background.js index 4668b467f..f97771dcf 100644 --- a/platform/mv3/extension/js/background.js +++ b/platform/mv3/extension/js/background.js @@ -35,6 +35,7 @@ import { import { adminReadEx, getAdminRulesets, + loadAdminConfig, } from './admin.js'; import { @@ -419,6 +420,9 @@ async function startSession() { const currentVersion = getCurrentVersion(); const isNewVersion = currentVersion !== rulesetConfig.version; + // Admin settings override user settings + await loadAdminConfig(); + // The default rulesets may have changed, find out new ruleset to enable, // obsolete ruleset to remove. if ( isNewVersion ) { diff --git a/platform/mv3/extension/js/config.js b/platform/mv3/extension/js/config.js index 0986f7339..f48533473 100644 --- a/platform/mv3/extension/js/config.js +++ b/platform/mv3/extension/js/config.js @@ -46,7 +46,7 @@ export const process = { export async function loadRulesetConfig() { const sessionData = await sessionRead('rulesetConfig'); if ( sessionData ) { - Object.assign(rulesetConfig, sessionData) + Object.assign(rulesetConfig, sessionData); process.wakeupRun = true; return; } diff --git a/platform/mv3/extension/js/ruleset-manager.js b/platform/mv3/extension/js/ruleset-manager.js index 79c299d1a..1b52ca4a5 100644 --- a/platform/mv3/extension/js/ruleset-manager.js +++ b/platform/mv3/extension/js/ruleset-manager.js @@ -386,9 +386,11 @@ async function excludeFromStrictBlock(hostname, permanent) { return updateSessionRules(); } -async function setStrictBlockMode(state) { +async function setStrictBlockMode(state, force = false) { const newState = Boolean(state); - if ( newState === rulesetConfig.strictBlockMode ) { return; } + if ( force === false ) { + if ( newState === rulesetConfig.strictBlockMode ) { return; } + } rulesetConfig.strictBlockMode = newState; const promises = [ saveRulesetConfig() ]; if ( newState === false ) { diff --git a/platform/mv3/extension/managed_storage.json b/platform/mv3/extension/managed_storage.json index a5ffd877e..85446f2e6 100644 --- a/platform/mv3/extension/managed_storage.json +++ b/platform/mv3/extension/managed_storage.json @@ -7,8 +7,9 @@ "description": "Can be one of \"none\", \"basic\", \"optimal\", \"complete\".", "type": "string" }, - "noFiltering": { - "title": "List of domains for which no filtering should occur", + "disabledFeatures": { + "title": "User interface features to disable", + "description": "A list of tokens, each of which correspond to a user interface feature to disable.", "type": "array", "items": { "type": "string" } }, @@ -16,17 +17,24 @@ "title": "Disable first run page", "type": "boolean" }, + "noFiltering": { + "title": "List of domains for which no filtering should occur", + "type": "array", + "items": { "type": "string" } + }, "rulesets": { "title": "Rulesets to add/remove", "description": "Prefix a ruleset id with '+' to add, or '-' to remove. Use '-*' to disable all non-default lists.", "type": "array", "items": { "type": "string" } }, - "disabledFeatures": { - "title": "User interface features to disable", - "description": "A list of tokens, each of which correspond to a user interface feature to disable.", - "type": "array", - "items": { "type": "string" } + "showBlockedCount": { + "title": "Enable/disable toolbar icon count badge", + "type": "boolean" + }, + "strictBlockMode": { + "title": "Enable/disable strict blocking", + "type": "boolean" } } }