mirror of https://github.com/gorhill/uBlock.git
[mv3] Improve and cleanup options page
Additionally, ensure the options page stay in sync with the internal state of the extension.
This commit is contained in:
parent
554400f7bd
commit
a77c23c74f
|
@ -57,6 +57,7 @@ import {
|
||||||
} from './mode-manager.js';
|
} from './mode-manager.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
broadcastMessage,
|
||||||
ubolLog,
|
ubolLog,
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ import {
|
||||||
const rulesetConfig = {
|
const rulesetConfig = {
|
||||||
version: '',
|
version: '',
|
||||||
enabledRulesets: [ 'default' ],
|
enabledRulesets: [ 'default' ],
|
||||||
autoReload: 1,
|
autoReload: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const UBOL_ORIGIN = runtime.getURL('').replace(/\/$/, '');
|
const UBOL_ORIGIN = runtime.getURL('').replace(/\/$/, '');
|
||||||
|
@ -84,7 +85,7 @@ async function loadRulesetConfig() {
|
||||||
if ( data ) {
|
if ( data ) {
|
||||||
rulesetConfig.version = data.version;
|
rulesetConfig.version = data.version;
|
||||||
rulesetConfig.enabledRulesets = data.enabledRulesets;
|
rulesetConfig.enabledRulesets = data.enabledRulesets;
|
||||||
rulesetConfig.autoReload = data.autoReload;
|
rulesetConfig.autoReload = data.autoReload && true || false;
|
||||||
wakeupRun = true;
|
wakeupRun = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +93,7 @@ async function loadRulesetConfig() {
|
||||||
if ( data ) {
|
if ( data ) {
|
||||||
rulesetConfig.version = data.version;
|
rulesetConfig.version = data.version;
|
||||||
rulesetConfig.enabledRulesets = data.enabledRulesets;
|
rulesetConfig.enabledRulesets = data.enabledRulesets;
|
||||||
rulesetConfig.autoReload = data.autoReload;
|
rulesetConfig.autoReload = data.autoReload && true || false;
|
||||||
sessionWrite('rulesetConfig', rulesetConfig);
|
sessionWrite('rulesetConfig', rulesetConfig);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +176,7 @@ function onMessage(request, sender, callback) {
|
||||||
}).then(( ) => {
|
}).then(( ) => {
|
||||||
registerInjectables();
|
registerInjectables();
|
||||||
callback();
|
callback();
|
||||||
|
broadcastMessage({ enabledRulesets: rulesetConfig.enabledRulesets });
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +200,7 @@ function onMessage(request, sender, callback) {
|
||||||
enabledRulesets,
|
enabledRulesets,
|
||||||
maxNumberOfEnabledRulesets: dnr.MAX_NUMBER_OF_ENABLED_STATIC_RULESETS,
|
maxNumberOfEnabledRulesets: dnr.MAX_NUMBER_OF_ENABLED_STATIC_RULESETS,
|
||||||
rulesetDetails: Array.from(rulesetDetails.values()),
|
rulesetDetails: Array.from(rulesetDetails.values()),
|
||||||
autoReload: rulesetConfig.autoReload === 1,
|
autoReload: rulesetConfig.autoReload,
|
||||||
firstRun,
|
firstRun,
|
||||||
});
|
});
|
||||||
firstRun = false;
|
firstRun = false;
|
||||||
|
@ -207,9 +209,10 @@ function onMessage(request, sender, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'setAutoReload':
|
case 'setAutoReload':
|
||||||
rulesetConfig.autoReload = request.state ? 1 : 0;
|
rulesetConfig.autoReload = request.state && true || false;
|
||||||
saveRulesetConfig().then(( ) => {
|
saveRulesetConfig().then(( ) => {
|
||||||
callback();
|
callback();
|
||||||
|
broadcastMessage({ autoReload: rulesetConfig.autoReload });
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -222,7 +225,7 @@ function onMessage(request, sender, callback) {
|
||||||
]).then(results => {
|
]).then(results => {
|
||||||
callback({
|
callback({
|
||||||
level: results[0],
|
level: results[0],
|
||||||
autoReload: rulesetConfig.autoReload === 1,
|
autoReload: rulesetConfig.autoReload,
|
||||||
hasOmnipotence: results[1],
|
hasOmnipotence: results[1],
|
||||||
hasGreatPowers: results[2],
|
hasGreatPowers: results[2],
|
||||||
rulesetDetails: results[3],
|
rulesetDetails: results[3],
|
||||||
|
|
|
@ -34,6 +34,7 @@ import {
|
||||||
} from './ext.js';
|
} from './ext.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
broadcastMessage,
|
||||||
hostnamesFromMatches,
|
hostnamesFromMatches,
|
||||||
isDescendantHostnameOfIter,
|
isDescendantHostnameOfIter,
|
||||||
toBroaderHostname,
|
toBroaderHostname,
|
||||||
|
@ -271,6 +272,16 @@ async function writeFilteringModeDetails(afterDetails) {
|
||||||
localWrite('filteringModeDetails', data);
|
localWrite('filteringModeDetails', data);
|
||||||
sessionWrite('filteringModeDetails', data);
|
sessionWrite('filteringModeDetails', data);
|
||||||
readFilteringModeDetails.cache = unserializeModeDetails(data);
|
readFilteringModeDetails.cache = unserializeModeDetails(data);
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
getDefaultFilteringMode(),
|
||||||
|
getTrustedSites(),
|
||||||
|
]).then(results => {
|
||||||
|
broadcastMessage({
|
||||||
|
defaultFilteringMode: results[0],
|
||||||
|
trustedSites: Array.from(results[1]),
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -38,6 +38,10 @@ function renderNumber(value) {
|
||||||
return value.toLocaleString();
|
return value.toLocaleString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hashFromIterable(iter) {
|
||||||
|
return Array.from(iter).sort().join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
function rulesetStats(rulesetId) {
|
function rulesetStats(rulesetId) {
|
||||||
|
@ -55,7 +59,7 @@ function rulesetStats(rulesetId) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
function renderFilterLists(soft = false) {
|
function renderFilterLists() {
|
||||||
const { enabledRulesets, rulesetDetails } = cachedRulesetData;
|
const { enabledRulesets, rulesetDetails } = cachedRulesetData;
|
||||||
const listGroupTemplate = qs$('#templates .groupEntry');
|
const listGroupTemplate = qs$('#templates .groupEntry');
|
||||||
const listEntryTemplate = qs$('#templates .listEntry');
|
const listEntryTemplate = qs$('#templates .listEntry');
|
||||||
|
@ -68,9 +72,10 @@ function renderFilterLists(soft = false) {
|
||||||
}
|
}
|
||||||
const on = enabledRulesets.includes(ruleset.id);
|
const on = enabledRulesets.includes(ruleset.id);
|
||||||
dom.cl.toggle(li, 'checked', on);
|
dom.cl.toggle(li, 'checked', on);
|
||||||
|
dom.cl.toggle(li, 'unused', hideUnused && !on);
|
||||||
|
qs$(li, 'input[type="checkbox"]').checked = on;
|
||||||
if ( dom.attr(li, 'data-listkey') !== ruleset.id ) {
|
if ( dom.attr(li, 'data-listkey') !== ruleset.id ) {
|
||||||
dom.attr(li, 'data-listkey', ruleset.id);
|
dom.attr(li, 'data-listkey', ruleset.id);
|
||||||
qs$(li, 'input[type="checkbox"]').checked = on;
|
|
||||||
qs$(li, '.listname').append(i18n.patchUnicodeFlags(ruleset.name));
|
qs$(li, '.listname').append(i18n.patchUnicodeFlags(ruleset.name));
|
||||||
dom.cl.remove(li, 'toRemove');
|
dom.cl.remove(li, 'toRemove');
|
||||||
if ( ruleset.homeURL ) {
|
if ( ruleset.homeURL ) {
|
||||||
|
@ -85,12 +90,7 @@ function renderFilterLists(soft = false) {
|
||||||
} else {
|
} else {
|
||||||
dom.cl.remove(li, 'mustread');
|
dom.cl.remove(li, 'mustread');
|
||||||
}
|
}
|
||||||
dom.cl.toggle(li, 'isDefault', ruleset.isDefault === true);
|
dom.cl.toggle(li, 'isDefault', ruleset.id === 'default');
|
||||||
dom.cl.toggle(li, 'unused', hideUnused && !on);
|
|
||||||
}
|
|
||||||
// https://github.com/gorhill/uBlock/issues/1429
|
|
||||||
if ( soft !== true ) {
|
|
||||||
qs$(li, 'input[type="checkbox"]').checked = on;
|
|
||||||
}
|
}
|
||||||
const stats = rulesetStats(ruleset.id);
|
const stats = rulesetStats(ruleset.id);
|
||||||
li.title = listStatsTemplate
|
li.title = listStatsTemplate
|
||||||
|
@ -159,10 +159,6 @@ function renderFilterLists(soft = false) {
|
||||||
return liGroup;
|
return liGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Incremental rendering: this will allow us to easily discard unused
|
|
||||||
// DOM list entries.
|
|
||||||
dom.cl.add('#lists .listEntries .listEntry[data-listkey]', 'discard');
|
|
||||||
|
|
||||||
// Visually split the filter lists in groups
|
// Visually split the filter lists in groups
|
||||||
const ulLists = qs$('#lists');
|
const ulLists = qs$('#lists');
|
||||||
const groups = new Map([
|
const groups = new Map([
|
||||||
|
@ -203,25 +199,17 @@ function renderFilterLists(soft = false) {
|
||||||
ulLists.appendChild(liGroup);
|
ulLists.appendChild(liGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.remove('#lists .listEntries .listEntry.discard');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const renderWidgets = function() {
|
function renderWidgets() {
|
||||||
if ( cachedRulesetData.firstRun ) {
|
if ( cachedRulesetData.firstRun ) {
|
||||||
dom.cl.add(dom.body, 'firstRun');
|
dom.cl.add(dom.body, 'firstRun');
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultLevel = cachedRulesetData.defaultFilteringMode;
|
renderDefaultMode();
|
||||||
if ( defaultLevel !== 0 ) {
|
renderTrustedSites();
|
||||||
qs$(`.filteringModeCard input[type="radio"][value="${defaultLevel}"]`).checked = true;
|
|
||||||
} else {
|
|
||||||
dom.prop('.filteringModeCard input[type="radio"]', 'checked', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderTrustedSites(cachedRulesetData.trustedSites);
|
|
||||||
|
|
||||||
qs$('#autoReload input[type="checkbox"').checked = cachedRulesetData.autoReload;
|
qs$('#autoReload input[type="checkbox"').checked = cachedRulesetData.autoReload;
|
||||||
|
|
||||||
|
@ -245,7 +233,18 @@ const renderWidgets = function() {
|
||||||
dom.cl.toggle(dom.body, 'noMoreRuleset',
|
dom.cl.toggle(dom.body, 'noMoreRuleset',
|
||||||
rulesetCount === cachedRulesetData.maxNumberOfEnabledRulesets
|
rulesetCount === cachedRulesetData.maxNumberOfEnabledRulesets
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -278,7 +277,7 @@ async function onFilteringModeChange(ev) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
renderFilterLists(true);
|
renderFilterLists();
|
||||||
renderWidgets();
|
renderWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,11 +299,9 @@ dom.on('#autoReload input[type="checkbox"', 'change', ev => {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
let trustedSitesHash = '';
|
function renderTrustedSites() {
|
||||||
|
|
||||||
function renderTrustedSites(hostnames) {
|
|
||||||
const textarea = qs$('#trustedSites');
|
const textarea = qs$('#trustedSites');
|
||||||
trustedSitesHash = hostnames.sort().join('\n');
|
const hostnames = cachedRulesetData.trustedSites;
|
||||||
textarea.value = hostnames.map(hn => punycode.toUnicode(hn)).join('\n');
|
textarea.value = hostnames.map(hn => punycode.toUnicode(hn)).join('\n');
|
||||||
if ( textarea.value !== '' ) {
|
if ( textarea.value !== '' ) {
|
||||||
textarea.value += '\n';
|
textarea.value += '\n';
|
||||||
|
@ -312,8 +309,18 @@ function renderTrustedSites(hostnames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeTrustedSites() {
|
function changeTrustedSites() {
|
||||||
|
const hostnames = getStagedTrustedSites();
|
||||||
|
const hash = hashFromIterable(cachedRulesetData.trustedSites);
|
||||||
|
if ( hashFromIterable(hostnames) === hash ) { return; }
|
||||||
|
sendMessage({
|
||||||
|
what: 'setTrustedSites',
|
||||||
|
hostnames,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStagedTrustedSites() {
|
||||||
const textarea = qs$('#trustedSites');
|
const textarea = qs$('#trustedSites');
|
||||||
const hostnames = textarea.value.split(/\s/).map(hn => {
|
return textarea.value.split(/\s/).map(hn => {
|
||||||
try {
|
try {
|
||||||
return punycode.toASCII(
|
return punycode.toASCII(
|
||||||
(new URL(`https://${hn}/`)).hostname
|
(new URL(`https://${hn}/`)).hostname
|
||||||
|
@ -321,16 +328,7 @@ function changeTrustedSites() {
|
||||||
} catch(_) {
|
} catch(_) {
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}).filter(hn => hn !== '').sort();
|
}).filter(hn => hn !== '');
|
||||||
if ( hostnames.join('\n') === trustedSitesHash ) { return; }
|
|
||||||
sendMessage({
|
|
||||||
what: 'setTrustedSites',
|
|
||||||
hostnames,
|
|
||||||
}).then(response => {
|
|
||||||
cachedRulesetData.defaultFilteringMode = response.defaultFilteringMode;
|
|
||||||
cachedRulesetData.trustedSites = response.trustedSites;
|
|
||||||
renderWidgets();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.on('#trustedSites', 'blur', changeTrustedSites);
|
dom.on('#trustedSites', 'blur', changeTrustedSites);
|
||||||
|
@ -420,6 +418,57 @@ localRead('hideUnusedFilterLists').then(value => {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
const bc = new self.BroadcastChannel('uBOL');
|
||||||
|
|
||||||
|
bc.onmessage = ev => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( message.enabledRulesets !== undefined ) {
|
||||||
|
if ( hashFromIterable(message.enabledRulesets) !== hashFromIterable(local.enabledRulesets) ) {
|
||||||
|
local.enabledRulesets = message.enabledRulesets;
|
||||||
|
render = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( render === false ) { return; }
|
||||||
|
renderFilterLists();
|
||||||
|
renderWidgets();
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
what: 'getOptionsPageData',
|
what: 'getOptionsPageData',
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
|
|
|
@ -123,6 +123,13 @@ const hostnamesFromMatches = origins => {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
export const broadcastMessage = message => {
|
||||||
|
const bc = new self.BroadcastChannel('uBOL');
|
||||||
|
bc.postMessage(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
const ubolLog = (...args) => {
|
const ubolLog = (...args) => {
|
||||||
// Do not pollute dev console in stable release.
|
// Do not pollute dev console in stable release.
|
||||||
if ( browser.runtime.id === 'ddkjiahejlhfcafbddmgiahcphecmpfh' ) { return; }
|
if ( browser.runtime.id === 'ddkjiahejlhfcafbddmgiahcphecmpfh' ) { return; }
|
||||||
|
|
Loading…
Reference in New Issue