[mv3] Reflect no-filtering mode on the toolbar icon

Related issue:
https://github.com/uBlockOrigin/uBOL-home/issues/198
This commit is contained in:
Raymond Hill 2025-04-24 19:32:40 -04:00
parent 83d62b9aca
commit 203b2235aa
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
12 changed files with 202 additions and 56 deletions

View file

@ -40,7 +40,9 @@
"activeTab",
"declarativeNetRequest",
"scripting",
"storage"
"storage",
"tabs",
"webNavigation"
],
"short_name": "uBO Lite",
"storage": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,120 @@
/*******************************************************************************
uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
Copyright (C) 2022-present Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
import { browser } from './ext.js';
import { getFilteringModeDetails } from './mode-manager.js';
/******************************************************************************/
let reverseMode = false;
/******************************************************************************/
function toggleToolbarIcon(tabId) {
if ( reverseMode ) {
enableToolbarIcon(tabId);
} else {
disableToolbarIcon(tabId);
}
}
function disableToolbarIcon(tabId) {
const details = {
path: {
'16': '/img/icon_16_off.png',
'32': '/img/icon_32_off.png',
'64': '/img/icon_64_off.png',
'128': '/img/icon_128_off.png',
}
};
if ( tabId !== undefined ) {
details.tabId = tabId;
}
browser.action.setIcon(details);
}
function enableToolbarIcon(tabId) {
const details = {
path: {
'16': '/img/icon_16.png',
'32': '/img/icon_32.png',
'64': '/img/icon_64.png',
'128': '/img/icon_128.png',
}
};
if ( tabId !== undefined ) {
details.tabId = tabId;
}
browser.action.setIcon(details);
}
/******************************************************************************/
function toolbarIconListener(details) {
if ( details.frameId !== 0 ) { return; }
toggleToolbarIcon(details.tabId);
}
/******************************************************************************/
// https://github.com/uBlockOrigin/uBOL-home/issues/198
// Ensure the toolbar icon reflects the no-filtering mode of "trusted sites"
export async function syncToolbarIcon(wakeup) {
const { webNavigation } = browser;
if ( typeof webNavigation !== 'object' ) { return; }
webNavigation.onCommitted.removeListener(toolbarIconListener);
const { none, basic, optimal, complete } = await getFilteringModeDetails();
const reverseModeAfter = none.delete('all-urls');
const toToggle = reverseModeAfter ?
new Set([ ...basic, ...optimal, ...complete ])
: none;
if ( reverseModeAfter !== reverseMode ) {
if ( reverseModeAfter ) {
disableToolbarIcon();
} else {
enableToolbarIcon();
}
reverseMode = reverseModeAfter;
}
if ( toToggle.size === 0 ) { return; }
webNavigation.onCommitted.addListener(toolbarIconListener, {
url: Array.from(toToggle).map(a => ({
originAndPathMatches: `^https?://(.+\\.)?${a}/`
})),
});
if ( wakeup === undefined ) { return; }
// If waking up, update icon for existing tabs
const tabs = await browser.tabs.query({
url: Array.from(toToggle).map(a => `*://*.${a}/*`)
}).catch(( ) => ([]));
for ( const tab of tabs ) {
toggleToolbarIcon(tab.id);
}
}

View file

@ -21,6 +21,7 @@
import {
MODE_BASIC,
MODE_NONE,
MODE_OPTIMAL,
getDefaultFilteringMode,
getFilteringMode,
@ -38,6 +39,7 @@ import {
import {
broadcastMessage,
gotoURL,
hasBroadHostPermissions,
hostnamesFromMatches,
} from './utils.js';
@ -46,7 +48,6 @@ import {
browser,
localRead, localRemove, localWrite,
runtime,
windows,
} from './ext.js';
import {
@ -76,6 +77,7 @@ import {
import { dnr } from './ext-compat.js';
import { registerInjectables } from './scripting-manager.js';
import { syncToolbarIcon } from './action.js';
/******************************************************************************/
@ -133,36 +135,6 @@ async function onPermissionsAdded(permissions) {
/******************************************************************************/
async function gotoURL(url, type) {
const pageURL = new URL(url, runtime.getURL('/'));
const tabs = await browser.tabs.query({
url: pageURL.href,
windowType: type !== 'popup' ? 'normal' : 'popup'
});
if ( Array.isArray(tabs) && tabs.length !== 0 ) {
const { windowId, id } = tabs[0];
return Promise.all([
browser.windows.update(windowId, { focused: true }),
browser.tabs.update(id, { active: true }),
]);
}
if ( type === 'popup' ) {
return windows.create({
type: 'popup',
url: pageURL.href,
});
}
return browser.tabs.create({
active: true,
url: pageURL.href,
});
}
/******************************************************************************/
function onMessage(request, sender, callback) {
// Does not require trusted origin.
@ -340,12 +312,18 @@ function onMessage(request, sender, callback) {
break;
case 'setFilteringMode': {
getFilteringMode(request.hostname).then(actualLevel => {
if ( request.level === actualLevel ) { return actualLevel; }
let trustedSitesChanged = false;
getFilteringMode(request.hostname).then(beforeLevel => {
if ( request.level === beforeLevel ) { return beforeLevel; }
trustedSitesChanged = beforeLevel === MODE_NONE;
return setFilteringMode(request.hostname, request.level);
}).then(actualLevel => {
}).then(afterLevel => {
registerInjectables();
callback(actualLevel);
trustedSitesChanged ||= afterLevel === MODE_NONE;
if ( trustedSitesChanged ) {
syncToolbarIcon();
}
callback(afterLevel);
});
return true;
}
@ -378,6 +356,7 @@ function onMessage(request, sender, callback) {
case 'setTrustedSites':
setTrustedSites(request.hostnames).then(( ) => {
registerInjectables();
syncToolbarIcon(true);
return Promise.all([
getDefaultFilteringMode(),
getTrustedSites(),
@ -404,7 +383,7 @@ function onMessage(request, sender, callback) {
return true;
case 'showMatchedRules':
windows.create({
browser.windows.create({
type: 'popup',
url: `/matched-rules.html?tab=${request.tabId}`,
});
@ -436,7 +415,7 @@ function onCommand(command, tab) {
/******************************************************************************/
async function launch() {
async function startSession() {
const currentVersion = getCurrentVersion();
const isNewVersion = currentVersion !== rulesetConfig.version;
@ -499,9 +478,10 @@ async function start() {
await loadRulesetConfig();
if ( process.wakeupRun === false ) {
await launch();
await startSession();
}
syncToolbarIcon(process.wakeupRun);
toggleDeveloperMode(rulesetConfig.developerMode);
}

View file

@ -26,7 +26,6 @@ import { webext } from './ext-compat.js';
export const browser = webext;
export const i18n = browser.i18n;
export const runtime = browser.runtime;
export const windows = browser.windows;
/******************************************************************************/

View file

@ -334,13 +334,18 @@ export async function getTrustedSites() {
}
export async function setTrustedSites(hostnames) {
const filteringModes = await getFilteringModeDetails();
const [
filteringModes,
hasOmnipotence,
] = await Promise.all([
getFilteringModeDetails(),
hasBroadHostPermissions(),
]);
const { none } = filteringModes;
const hnSet = new Set(hostnames);
let modified = false;
// Set default mode to Basic when removing No-filtering as default mode
if ( none.has('all-urls') && hnSet.has('all-urls') === false ) {
applyFilteringMode(filteringModes, 'all-urls', MODE_BASIC);
applyFilteringMode(filteringModes, 'all-urls', hasOmnipotence ? MODE_OPTIMAL : MODE_BASIC);
modified = true;
}
for ( const hn of none ) {
@ -389,16 +394,18 @@ export async function syncWithBrowserPermissions() {
const afterMode = await getDefaultFilteringMode();
if ( afterMode > MODE_BASIC ) { return afterMode !== beforeMode; }
const filteringModes = await getFilteringModeDetails();
const { optimal, complete } = filteringModes;
for ( const hn of optimal ) {
if ( allowedHostnames.has(hn) ) { continue; }
optimal.delete(hn);
modified = true;
}
for ( const hn of complete ) {
if ( allowedHostnames.has(hn) ) { continue; }
complete.delete(hn);
modified = true;
if ( allowedHostnames.has('all-urls') === false ) {
const { optimal, complete } = filteringModes;
for ( const hn of optimal ) {
if ( allowedHostnames.has(hn) ) { continue; }
optimal.delete(hn);
modified = true;
}
for ( const hn of complete ) {
if ( allowedHostnames.has(hn) ) { continue; }
complete.delete(hn);
modified = true;
}
}
await writeFilteringModeDetails(filteringModes);
return modified;

View file

@ -19,7 +19,10 @@
Home: https://github.com/gorhill/uBlock
*/
import { browser } from './ext.js';
import {
browser,
runtime,
} from './ext.js';
/******************************************************************************/
@ -149,6 +152,36 @@ async function hasBroadHostPermissions() {
/******************************************************************************/
async function gotoURL(url, type) {
const pageURL = new URL(url, runtime.getURL('/'));
const tabs = await browser.tabs.query({
url: pageURL.href,
windowType: type !== 'popup' ? 'normal' : 'popup'
});
if ( Array.isArray(tabs) && tabs.length !== 0 ) {
const { windowId, id } = tabs[0];
return Promise.all([
browser.windows.update(windowId, { focused: true }),
browser.tabs.update(id, { active: true }),
]);
}
if ( type === 'popup' ) {
return browser.windows.create({
type: 'popup',
url: pageURL.href,
});
}
return browser.tabs.create({
active: true,
url: pageURL.href,
});
}
/******************************************************************************/
export {
broadcastMessage,
parsedURLromOrigin,
@ -161,4 +194,5 @@ export {
matchesFromHostnames,
hostnamesFromMatches,
hasBroadHostPermissions,
gotoURL,
};

View file

@ -52,7 +52,9 @@
"activeTab",
"declarativeNetRequest",
"scripting",
"storage"
"storage",
"tabs",
"webNavigation"
],
"short_name": "uBO Lite",
"version": "1.0",

View file

@ -39,7 +39,9 @@
"declarativeNetRequest",
"declarativeNetRequestWithHostAccess",
"scripting",
"storage"
"storage",
"tabs",
"webNavigation"
],
"short_name": "uBO Lite",
"version": "1.0",