2022-09-13 15:44:24 -06:00
|
|
|
/*******************************************************************************
|
|
|
|
|
2023-12-04 10:10:34 -07:00
|
|
|
uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
|
2022-09-13 15:44:24 -06:00
|
|
|
Copyright (C) 2014-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
|
|
|
|
*/
|
|
|
|
|
2024-11-17 15:27:27 -07:00
|
|
|
import { browser, sendMessage } from './ext.js';
|
|
|
|
import { dom, qs$ } from './dom.js';
|
2023-11-28 19:13:44 -07:00
|
|
|
import punycode from './punycode.js';
|
2024-11-17 15:27:27 -07:00
|
|
|
import { renderFilterLists } from './filter-lists.js';
|
2022-09-13 15:44:24 -06:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
let cachedRulesetData = {};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2023-11-29 14:11:22 -07:00
|
|
|
function hashFromIterable(iter) {
|
|
|
|
return Array.from(iter).sort().join('\n');
|
|
|
|
}
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2023-11-29 14:11:22 -07:00
|
|
|
function renderWidgets() {
|
2022-10-10 10:28:24 -06:00
|
|
|
if ( cachedRulesetData.firstRun ) {
|
|
|
|
dom.cl.add(dom.body, 'firstRun');
|
|
|
|
}
|
2022-09-30 07:18:52 -06:00
|
|
|
|
2023-11-29 14:11:22 -07:00
|
|
|
renderDefaultMode();
|
|
|
|
renderTrustedSites();
|
2022-09-27 17:51:38 -06:00
|
|
|
|
2024-03-21 11:57:50 -06:00
|
|
|
qs$('#autoReload input[type="checkbox"]').checked = cachedRulesetData.autoReload;
|
|
|
|
|
|
|
|
{
|
|
|
|
const input = qs$('#showBlockedCount input[type="checkbox"]');
|
|
|
|
if ( cachedRulesetData.canShowBlockedCount ) {
|
|
|
|
input.checked = cachedRulesetData.showBlockedCount;
|
|
|
|
} else {
|
|
|
|
input.checked = false;
|
|
|
|
dom.attr(input, 'disabled', '');
|
|
|
|
}
|
|
|
|
}
|
2023-11-29 14:11:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
function renderDefaultMode() {
|
|
|
|
const defaultLevel = cachedRulesetData.defaultFilteringMode;
|
|
|
|
if ( defaultLevel !== 0 ) {
|
|
|
|
qs$(`.filteringModeCard input[type="radio"][value="${defaultLevel}"]`).checked = true;
|
|
|
|
} else {
|
|
|
|
dom.prop('.filteringModeCard input[type="radio"]', 'checked', false);
|
|
|
|
}
|
|
|
|
}
|
2022-09-13 15:44:24 -06:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-10-10 10:28:24 -06:00
|
|
|
async function onFilteringModeChange(ev) {
|
2022-09-27 17:51:38 -06:00
|
|
|
const input = ev.target;
|
2022-10-10 10:28:24 -06:00
|
|
|
const newLevel = parseInt(input.value, 10);
|
2022-09-27 18:19:59 -06:00
|
|
|
|
2022-10-10 10:28:24 -06:00
|
|
|
switch ( newLevel ) {
|
|
|
|
case 1: { // Revoke broad permissions
|
2023-06-13 09:40:41 -06:00
|
|
|
await browser.permissions.remove({
|
2022-09-27 18:19:59 -06:00
|
|
|
origins: [ '<all_urls>' ]
|
|
|
|
});
|
2023-06-13 09:40:41 -06:00
|
|
|
cachedRulesetData.defaultFilteringMode = 1;
|
2022-10-10 10:28:24 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
case 3: { // Request broad permissions
|
2023-06-13 09:40:41 -06:00
|
|
|
const granted = await browser.permissions.request({
|
2022-09-27 18:19:59 -06:00
|
|
|
origins: [ '<all_urls>' ]
|
2022-10-10 10:28:24 -06:00
|
|
|
});
|
2023-06-13 09:40:41 -06:00
|
|
|
if ( granted ) {
|
|
|
|
const actualLevel = await sendMessage({
|
|
|
|
what: 'setDefaultFilteringMode',
|
|
|
|
level: newLevel,
|
|
|
|
});
|
|
|
|
cachedRulesetData.defaultFilteringMode = actualLevel;
|
|
|
|
}
|
2022-10-10 10:28:24 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2024-11-17 15:27:27 -07:00
|
|
|
renderFilterLists(cachedRulesetData);
|
2022-09-29 17:51:33 -06:00
|
|
|
renderWidgets();
|
2022-09-27 17:51:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
dom.on(
|
2022-11-12 07:51:22 -07:00
|
|
|
'#defaultFilteringMode',
|
2022-09-27 17:51:38 -06:00
|
|
|
'change',
|
2022-10-10 10:28:24 -06:00
|
|
|
'.filteringModeCard input[type="radio"]',
|
|
|
|
ev => { onFilteringModeChange(ev); }
|
2022-09-27 17:51:38 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2024-03-21 11:57:50 -06:00
|
|
|
dom.on('#autoReload input[type="checkbox"]', 'change', ev => {
|
2022-10-10 10:28:24 -06:00
|
|
|
sendMessage({
|
|
|
|
what: 'setAutoReload',
|
|
|
|
state: ev.target.checked,
|
|
|
|
});
|
|
|
|
});
|
2022-09-13 15:44:24 -06:00
|
|
|
|
2024-03-21 11:57:50 -06:00
|
|
|
dom.on('#showBlockedCount input[type="checkbox"]', 'change', ev => {
|
|
|
|
sendMessage({
|
|
|
|
what: 'setShowBlockedCount',
|
|
|
|
state: ev.target.checked,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2023-11-29 14:11:22 -07:00
|
|
|
function renderTrustedSites() {
|
2023-11-28 19:13:44 -07:00
|
|
|
const textarea = qs$('#trustedSites');
|
2024-10-17 10:32:28 -06:00
|
|
|
const hostnames = cachedRulesetData.trustedSites || [];
|
2023-11-28 19:13:44 -07:00
|
|
|
textarea.value = hostnames.map(hn => punycode.toUnicode(hn)).join('\n');
|
|
|
|
if ( textarea.value !== '' ) {
|
|
|
|
textarea.value += '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function changeTrustedSites() {
|
2023-11-29 14:11:22 -07:00
|
|
|
const hostnames = getStagedTrustedSites();
|
2024-10-17 10:32:28 -06:00
|
|
|
const hash = hashFromIterable(cachedRulesetData.trustedSites || []);
|
2023-11-29 14:11:22 -07:00
|
|
|
if ( hashFromIterable(hostnames) === hash ) { return; }
|
|
|
|
sendMessage({
|
|
|
|
what: 'setTrustedSites',
|
|
|
|
hostnames,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function getStagedTrustedSites() {
|
2023-11-28 19:13:44 -07:00
|
|
|
const textarea = qs$('#trustedSites');
|
2023-11-29 14:11:22 -07:00
|
|
|
return textarea.value.split(/\s/).map(hn => {
|
2023-11-28 19:13:44 -07:00
|
|
|
try {
|
|
|
|
return punycode.toASCII(
|
|
|
|
(new URL(`https://${hn}/`)).hostname
|
|
|
|
);
|
|
|
|
} catch(_) {
|
|
|
|
}
|
|
|
|
return '';
|
2023-11-29 14:11:22 -07:00
|
|
|
}).filter(hn => hn !== '');
|
2023-11-28 19:13:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
dom.on('#trustedSites', 'blur', changeTrustedSites);
|
|
|
|
|
|
|
|
self.addEventListener('beforeunload', changeTrustedSites);
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2024-11-11 11:20:54 -07:00
|
|
|
function listen() {
|
|
|
|
const bc = new self.BroadcastChannel('uBOL');
|
|
|
|
bc.onmessage = listen.onmessage;
|
|
|
|
}
|
2023-11-29 14:11:22 -07:00
|
|
|
|
2024-11-11 11:20:54 -07:00
|
|
|
listen.onmessage = ev => {
|
2023-11-29 14:11:22 -07:00
|
|
|
const message = ev.data;
|
|
|
|
if ( message instanceof Object === false ) { return; }
|
|
|
|
const local = cachedRulesetData;
|
|
|
|
let render = false;
|
|
|
|
|
|
|
|
// Keep added sites which have not yet been committed
|
|
|
|
if ( message.trustedSites !== undefined ) {
|
|
|
|
if ( hashFromIterable(message.trustedSites) !== hashFromIterable(local.trustedSites) ) {
|
|
|
|
const current = new Set(local.trustedSites);
|
|
|
|
const staged = new Set(getStagedTrustedSites());
|
|
|
|
for ( const hn of staged ) {
|
|
|
|
if ( current.has(hn) === false ) { continue; }
|
|
|
|
staged.delete(hn);
|
|
|
|
}
|
|
|
|
const combined = Array.from(new Set([ ...message.trustedSites, ...staged ]));
|
|
|
|
local.trustedSites = combined;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( message.defaultFilteringMode !== undefined ) {
|
|
|
|
if ( message.defaultFilteringMode !== local.defaultFilteringMode ) {
|
|
|
|
local.defaultFilteringMode = message.defaultFilteringMode;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( message.autoReload !== undefined ) {
|
|
|
|
if ( message.autoReload !== local.autoReload ) {
|
|
|
|
local.autoReload = message.autoReload;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-21 11:57:50 -06:00
|
|
|
if ( message.showBlockedCount !== undefined ) {
|
|
|
|
if ( message.showBlockedCount !== local.showBlockedCount ) {
|
|
|
|
local.showBlockedCount = message.showBlockedCount;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-11 11:20:54 -07:00
|
|
|
if ( message.adminRulesets !== undefined ) {
|
|
|
|
if ( hashFromIterable(message.adminRulesets) !== hashFromIterable(local.adminRulesets) ) {
|
|
|
|
local.adminRulesets = message.adminRulesets;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-29 14:11:22 -07:00
|
|
|
if ( message.enabledRulesets !== undefined ) {
|
|
|
|
if ( hashFromIterable(message.enabledRulesets) !== hashFromIterable(local.enabledRulesets) ) {
|
|
|
|
local.enabledRulesets = message.enabledRulesets;
|
|
|
|
render = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( render === false ) { return; }
|
2024-11-17 15:27:27 -07:00
|
|
|
renderFilterLists(cachedRulesetData);
|
2023-11-29 14:11:22 -07:00
|
|
|
renderWidgets();
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
sendMessage({
|
2022-10-10 10:28:24 -06:00
|
|
|
what: 'getOptionsPageData',
|
2022-09-13 15:44:24 -06:00
|
|
|
}).then(data => {
|
|
|
|
if ( !data ) { return; }
|
|
|
|
cachedRulesetData = data;
|
|
|
|
try {
|
2024-11-17 15:27:27 -07:00
|
|
|
renderFilterLists(cachedRulesetData);
|
2023-11-28 19:13:44 -07:00
|
|
|
renderWidgets();
|
2022-09-13 15:44:24 -06:00
|
|
|
} catch(ex) {
|
|
|
|
}
|
2024-11-11 11:20:54 -07:00
|
|
|
listen();
|
2022-09-13 15:44:24 -06:00
|
|
|
}).catch(reason => {
|
|
|
|
console.trace(reason);
|
|
|
|
});
|
|
|
|
|
|
|
|
/******************************************************************************/
|