mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Reflect no-filtering mode on the toolbar icon
Related issue: https://github.com/uBlockOrigin/uBOL-home/issues/198
This commit is contained in:
parent
83d62b9aca
commit
203b2235aa
12 changed files with 202 additions and 56 deletions
|
|
@ -40,7 +40,9 @@
|
|||
"activeTab",
|
||||
"declarativeNetRequest",
|
||||
"scripting",
|
||||
"storage"
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation"
|
||||
],
|
||||
"short_name": "uBO Lite",
|
||||
"storage": {
|
||||
|
|
|
|||
BIN
platform/mv3/extension/img/icon_128_off.png
Normal file
BIN
platform/mv3/extension/img/icon_128_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
platform/mv3/extension/img/icon_16_off.png
Normal file
BIN
platform/mv3/extension/img/icon_16_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 446 B |
BIN
platform/mv3/extension/img/icon_32_off.png
Normal file
BIN
platform/mv3/extension/img/icon_32_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 802 B |
BIN
platform/mv3/extension/img/icon_64_off.png
Normal file
BIN
platform/mv3/extension/img/icon_64_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
120
platform/mv3/extension/js/action.js
Normal file
120
platform/mv3/extension/js/action.js
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@
|
|||
"activeTab",
|
||||
"declarativeNetRequest",
|
||||
"scripting",
|
||||
"storage"
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation"
|
||||
],
|
||||
"short_name": "uBO Lite",
|
||||
"version": "1.0",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
"declarativeNetRequest",
|
||||
"declarativeNetRequestWithHostAccess",
|
||||
"scripting",
|
||||
"storage"
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation"
|
||||
],
|
||||
"short_name": "uBO Lite",
|
||||
"version": "1.0",
|
||||
|
|
|
|||
Loading…
Reference in a new issue