1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-06 09:37:12 +02:00

Work toward modernizing code base: promisification

Swathes of code have been converted to use
Promises/async/await.

Related commits:
- 26235d80d0
- 0051f3b5c7
- eec53c0154
- 915687fddb
- 55cc0c6997
- e27328f931
This commit is contained in:
Raymond Hill 2019-09-17 15:15:01 -04:00
parent 26235d80d0
commit 3224d9b5cc
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
26 changed files with 883 additions and 1099 deletions

View File

@ -137,10 +137,10 @@ vAPI.messaging = {
// Response to specific message previously sent // Response to specific message previously sent
if ( details.auxProcessId ) { if ( details.auxProcessId ) {
const listener = this.pending.get(details.auxProcessId); const resolver = this.pending.get(details.auxProcessId);
if ( listener !== undefined ) { if ( resolver !== undefined ) {
this.pending.delete(details.auxProcessId); this.pending.delete(details.auxProcessId);
listener(details.msg); resolver(details.msg);
return; return;
} }
} }
@ -222,10 +222,8 @@ vAPI.messaging = {
if ( this.pending.size !== 0 ) { if ( this.pending.size !== 0 ) {
const pending = this.pending; const pending = this.pending;
this.pending = new Map(); this.pending = new Map();
for ( const callback of pending.values() ) { for ( const resolver of pending.values() ) {
if ( typeof callback === 'function' ) { resolver();
callback(null);
}
} }
} }
}, },
@ -264,7 +262,7 @@ vAPI.messaging = {
return this.port !== null ? this.port : this.createPort(); return this.port !== null ? this.port : this.createPort();
}, },
send: function(channelName, message, callback) { send: function(channelName, msg) {
// Too large a gap between the last request and the last response means // Too large a gap between the last request and the last response means
// the main process is no longer reachable: memory leaks and bad // the main process is no longer reachable: memory leaks and bad
// performance become a risk -- especially for long-lived, dynamic // performance become a risk -- especially for long-lived, dynamic
@ -274,19 +272,14 @@ vAPI.messaging = {
} }
const port = this.getPort(); const port = this.getPort();
if ( port === null ) { if ( port === null ) {
if ( typeof callback === 'function' ) { callback(); } return Promise.resolve();
return;
} }
let auxProcessId; const auxProcessId = this.auxProcessId++;
if ( callback ) { const promise = new Promise(resolve => {
auxProcessId = this.auxProcessId++; this.pending.set(auxProcessId, resolve);
this.pending.set(auxProcessId, callback);
}
port.postMessage({
channelName: channelName,
auxProcessId: auxProcessId,
msg: message
}); });
port.postMessage({ channelName, auxProcessId, msg });
return promise;
}, },
connectTo: function(from, to, handler) { connectTo: function(from, to, handler) {

View File

@ -38,8 +38,11 @@ vAPI.userStylesheet = {
vAPI.messaging.send('vapi', { vAPI.messaging.send('vapi', {
what: 'userCSS', what: 'userCSS',
add: Array.from(this.added), add: Array.from(this.added),
remove: Array.from(this.removed) remove: Array.from(this.removed),
}, callback); }).then(( ) => {
if ( callback instanceof Function === false ) { return; }
callback();
});
this.added.clear(); this.added.clear();
this.removed.clear(); this.removed.clear();
}, },

View File

@ -29,14 +29,13 @@
/******************************************************************************/ /******************************************************************************/
const messaging = vAPI.messaging;
const cmEditor = new CodeMirror( const cmEditor = new CodeMirror(
document.getElementById('userFilters'), document.getElementById('userFilters'),
{ {
autofocus: true, autofocus: true,
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
styleActiveLine: true styleActiveLine: true,
} }
); );
@ -72,9 +71,12 @@ const userFiltersChanged = function(changed) {
/******************************************************************************/ /******************************************************************************/
const renderUserFilters = function(first) { const renderUserFilters = async function(first) {
const onRead = function(details) { const details = await vAPI.messaging.send('dashboard', {
if ( details.error ) { return; } what: 'readUserFilters',
});
if ( details instanceof Object === false || details.error ) { return; }
let content = details.content.trim(); let content = details.content.trim();
cachedUserFilters = content; cachedUserFilters = content;
if ( content.length !== 0 ) { if ( content.length !== 0 ) {
@ -95,8 +97,6 @@ const renderUserFilters = function(first) {
} }
userFiltersChanged(false); userFiltersChanged(false);
}; };
messaging.send('dashboard', { what: 'readUserFilters' }, onRead);
};
/******************************************************************************/ /******************************************************************************/
@ -170,20 +170,18 @@ const exportUserFiltersToFile = function() {
/******************************************************************************/ /******************************************************************************/
const applyChanges = function() { const applyChanges = async function() {
messaging.send( const details = await vAPI.messaging.send('dashboard', {
'dashboard',
{
what: 'writeUserFilters', what: 'writeUserFilters',
content: cmEditor.getValue() content: cmEditor.getValue(),
}, });
details => { if ( details instanceof Object === false || details.error ) { return; }
if ( details.error ) { return; }
cachedUserFilters = details.content.trim(); cachedUserFilters = details.content.trim();
userFiltersChanged(false); userFiltersChanged(false);
messaging.send('dashboard', { what: 'reloadAllFilters' }); vAPI.messaging.send('dashboard', {
} what: 'reloadAllFilters',
); });
}; };
const revertChanges = function() { const revertChanges = function() {
@ -223,7 +221,7 @@ self.hasUnsavedData = function() {
uDom('#importUserFiltersFromFile').on('click', startImportFilePicker); uDom('#importUserFiltersFromFile').on('click', startImportFilePicker);
uDom('#importFilePicker').on('change', handleImportFilePicker); uDom('#importFilePicker').on('change', handleImportFilePicker);
uDom('#exportUserFiltersToFile').on('click', exportUserFiltersToFile); uDom('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
uDom('#userFiltersApply').on('click', applyChanges); uDom('#userFiltersApply').on('click', ( ) => { applyChanges(); });
uDom('#userFiltersRevert').on('click', revertChanges); uDom('#userFiltersRevert').on('click', revertChanges);
renderUserFilters(true); renderUserFilters(true);

View File

@ -306,7 +306,11 @@ const renderFilterLists = function(soft) {
renderWidgets(); renderWidgets();
}; };
messaging.send('dashboard', { what: 'getLists' }, onListsReceived); messaging.send('dashboard', {
what: 'getLists',
}).then(details => {
onListsReceived(details);
});
}; };
/******************************************************************************/ /******************************************************************************/
@ -402,7 +406,10 @@ const onPurgeClicked = function(ev) {
const listKey = liEntry.attr('data-listkey'); const listKey = liEntry.attr('data-listkey');
if ( !listKey ) { return; } if ( !listKey ) { return; }
messaging.send('dashboard', { what: 'purgeCache', assetKey: listKey }); messaging.send('dashboard', {
what: 'purgeCache',
assetKey: listKey,
});
// If the cached version is purged, the installed version must be assumed // If the cached version is purged, the installed version must be assumed
// to be obsolete. // to be obsolete.
@ -419,17 +426,17 @@ const onPurgeClicked = function(ev) {
/******************************************************************************/ /******************************************************************************/
const selectFilterLists = function(callback) { const selectFilterLists = async function() {
// Cosmetic filtering switch // Cosmetic filtering switch
messaging.send('dashboard', { messaging.send('dashboard', {
what: 'userSettings', what: 'userSettings',
name: 'parseAllABPHideFilters', name: 'parseAllABPHideFilters',
value: document.getElementById('parseCosmeticFilters').checked value: document.getElementById('parseCosmeticFilters').checked,
}); });
messaging.send('dashboard', { messaging.send('dashboard', {
what: 'userSettings', what: 'userSettings',
name: 'ignoreGenericCosmeticFilters', name: 'ignoreGenericCosmeticFilters',
value: document.getElementById('ignoreGenericCosmeticFilters').checked value: document.getElementById('ignoreGenericCosmeticFilters').checked,
}); });
// Filter lists to select // Filter lists to select
@ -454,67 +461,53 @@ const selectFilterLists = function(callback) {
externalListsElem.value = ''; externalListsElem.value = '';
uDom.nodeFromId('importLists').checked = false; uDom.nodeFromId('importLists').checked = false;
messaging.send( await messaging.send('dashboard', {
'dashboard',
{
what: 'applyFilterListSelection', what: 'applyFilterListSelection',
toSelect: toSelect, toSelect: toSelect,
toImport: toImport, toImport: toImport,
toRemove: toRemove toRemove: toRemove,
}, });
callback
);
filteringSettingsHash = hashFromCurrentFromSettings(); filteringSettingsHash = hashFromCurrentFromSettings();
}; };
/******************************************************************************/ /******************************************************************************/
const buttonApplyHandler = function() { const buttonApplyHandler = async function() {
uDom('#buttonApply').removeClass('enabled'); uDom('#buttonApply').removeClass('enabled');
selectFilterLists(( ) => { renderWidgets();
await selectFilterLists();
messaging.send('dashboard', { what: 'reloadAllFilters' }); messaging.send('dashboard', { what: 'reloadAllFilters' });
});
renderWidgets();
}; };
/******************************************************************************/ /******************************************************************************/
const buttonUpdateHandler = function() { const buttonUpdateHandler = async function() {
selectFilterLists(( ) => { await selectFilterLists();
document.body.classList.add('updating'); document.body.classList.add('updating');
renderWidgets();
messaging.send('dashboard', { what: 'forceUpdateAssets' }); messaging.send('dashboard', { what: 'forceUpdateAssets' });
renderWidgets();
});
renderWidgets();
}; };
/******************************************************************************/ /******************************************************************************/
const buttonPurgeAllHandler = function(ev) { const buttonPurgeAllHandler = async function(hard) {
uDom('#buttonPurgeAll').removeClass('enabled'); uDom('#buttonPurgeAll').removeClass('enabled');
messaging.send( await messaging.send('dashboard', {
'dashboard',
{
what: 'purgeAllCaches', what: 'purgeAllCaches',
hard: ev.ctrlKey && ev.shiftKey hard,
}, });
( ) => {
renderFilterLists(true); renderFilterLists(true);
}
);
}; };
/******************************************************************************/ /******************************************************************************/
const autoUpdateCheckboxChanged = function() { const autoUpdateCheckboxChanged = function() {
messaging.send( messaging.send('dashboard', {
'dashboard',
{
what: 'userSettings', what: 'userSettings',
name: 'autoUpdate', name: 'autoUpdate',
value: this.checked value: this.checked,
} });
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -675,9 +668,11 @@ self.hasUnsavedData = function() {
uDom('#autoUpdate').on('change', autoUpdateCheckboxChanged); uDom('#autoUpdate').on('change', autoUpdateCheckboxChanged);
uDom('#parseCosmeticFilters').on('change', onFilteringSettingsChanged); uDom('#parseCosmeticFilters').on('change', onFilteringSettingsChanged);
uDom('#ignoreGenericCosmeticFilters').on('change', onFilteringSettingsChanged); uDom('#ignoreGenericCosmeticFilters').on('change', onFilteringSettingsChanged);
uDom('#buttonApply').on('click', buttonApplyHandler); uDom('#buttonApply').on('click', ( ) => { buttonApplyHandler(); });
uDom('#buttonUpdate').on('click', buttonUpdateHandler); uDom('#buttonUpdate').on('click', ( ) => { buttonUpdateHandler(); });
uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler); uDom('#buttonPurgeAll').on('click', ev => {
buttonPurgeAllHandler(ev.ctrlKey && ev.shiftKey);
});
uDom('#lists').on('change', '.listEntry > input', onFilteringSettingsChanged); uDom('#lists').on('change', '.listEntry > input', onFilteringSettingsChanged);
uDom('#lists').on('click', '.listEntry > a.remove', onRemoveExternalList); uDom('#lists').on('click', '.listEntry > a.remove', onRemoveExternalList);
uDom('#lists').on('click', 'span.cache', onPurgeClicked); uDom('#lists').on('click', 'span.cache', onPurgeClicked);

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2016 Raymond Hill Copyright (C) 2014-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -25,12 +25,7 @@
/******************************************************************************/ /******************************************************************************/
(( ) => { (async ( ) => {
vAPI.messaging.send('dashboard', { what: 'getAppData' }, appData => {
uDom('#aboutNameVer').text(appData.name + ' v' + appData.version);
});
document.querySelector( document.querySelector(
'[href="logger-ui.html"]' '[href="logger-ui.html"]'
).addEventListener( ).addEventListener(
@ -38,4 +33,8 @@
self.uBlockDashboard.openOrSelectPage self.uBlockDashboard.openOrSelectPage
); );
const appData = await vAPI.messaging.send('dashboard', {
what: 'getAppData',
});
uDom('#aboutNameVer').text(appData.name + ' v' + appData.version);
})(); })();

View File

@ -25,12 +25,11 @@
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
// >>>> Start of private namespace // >>>> Start of private namespace
/******************************************************************************/ /******************************************************************************/
const messaging = vAPI.messaging;
const noopFunc = function(){}; const noopFunc = function(){};
let beforeHash = ''; let beforeHash = '';
@ -57,18 +56,19 @@ const hashFromAdvancedSettings = function(raw) {
// This is to give a visual hint that the content of user blacklist has changed. // This is to give a visual hint that the content of user blacklist has changed.
const advancedSettingsChanged = (function () { const advancedSettingsChanged = (( ) => {
let timer = null; let timer;
const handler = ( ) => { const handler = ( ) => {
timer = null; timer = undefined;
let changed = hashFromAdvancedSettings(cmEditor.getValue()) !== beforeHash; const changed =
hashFromAdvancedSettings(cmEditor.getValue()) !== beforeHash;
uDom.nodeFromId('advancedSettingsApply').disabled = !changed; uDom.nodeFromId('advancedSettingsApply').disabled = !changed;
CodeMirror.commands.save = changed ? applyChanges : noopFunc; CodeMirror.commands.save = changed ? applyChanges : noopFunc;
}; };
return function() { return function() {
if ( timer !== null ) { clearTimeout(timer); } if ( timer !== undefined ) { clearTimeout(timer); }
timer = vAPI.setTimeout(handler, 100); timer = vAPI.setTimeout(handler, 100);
}; };
})(); })();
@ -77,8 +77,11 @@ cmEditor.on('changes', advancedSettingsChanged);
/******************************************************************************/ /******************************************************************************/
const renderAdvancedSettings = function(first) { const renderAdvancedSettings = async function(first) {
const onRead = function(raw) { const raw = await vAPI.messaging.send('dashboard', {
what: 'readHiddenSettings',
});
beforeHash = hashFromAdvancedSettings(raw); beforeHash = hashFromAdvancedSettings(raw);
let pretty = [], let pretty = [],
whitespaces = ' ', whitespaces = ' ',
@ -99,20 +102,15 @@ const renderAdvancedSettings = function(first) {
advancedSettingsChanged(); advancedSettingsChanged();
cmEditor.focus(); cmEditor.focus();
}; };
messaging.send('dashboard', { what: 'readHiddenSettings' }, onRead);
};
/******************************************************************************/ /******************************************************************************/
const applyChanges = function() { const applyChanges = async function() {
messaging.send( await vAPI.messaging.send('dashboard', {
'dashboard',
{
what: 'writeHiddenSettings', what: 'writeHiddenSettings',
content: cmEditor.getValue() content: cmEditor.getValue(),
}, });
renderAdvancedSettings renderAdvancedSettings();
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -121,10 +119,9 @@ uDom.nodeFromId('advancedSettings').addEventListener(
'input', 'input',
advancedSettingsChanged advancedSettingsChanged
); );
uDom.nodeFromId('advancedSettingsApply').addEventListener( uDom.nodeFromId('advancedSettingsApply').addEventListener('click', ( ) => {
'click', applyChanges();
applyChanges });
);
renderAdvancedSettings(true); renderAdvancedSettings(true);

View File

@ -25,27 +25,11 @@
/******************************************************************************/ /******************************************************************************/
(( ) => { (async ( ) => {
const params = new URL(document.location).searchParams; const params = new URL(document.location).searchParams;
const assetKey = params.get('url'); const assetKey = params.get('url');
if ( assetKey === null ) { return; } if ( assetKey === null ) { return; }
vAPI.messaging.send(
'default',
{
what : 'getAssetContent',
url: assetKey,
},
details => {
cmEditor.setValue(details && details.content || '');
if ( details.sourceURL ) {
const a = document.querySelector('.cm-search-widget .sourceURL');
a.setAttribute('href', details.sourceURL);
a.setAttribute('title', details.sourceURL);
}
}
);
const cmEditor = new CodeMirror( const cmEditor = new CodeMirror(
document.getElementById('content'), document.getElementById('content'),
{ {
@ -58,4 +42,15 @@
); );
uBlockDashboard.patchCodeMirrorEditor(cmEditor); uBlockDashboard.patchCodeMirrorEditor(cmEditor);
const details = await vAPI.messaging.send('default', {
what : 'getAssetContent',
url: assetKey,
});
cmEditor.setValue(details && details.content || '');
if ( details.sourceURL ) {
const a = document.querySelector('.cm-search-widget .sourceURL');
a.setAttribute('href', details.sourceURL);
a.setAttribute('title', details.sourceURL);
}
})(); })();

View File

@ -21,11 +21,11 @@
/* global uDom */ /* global uDom */
'use strict';
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
'use strict';
/******************************************************************************/ /******************************************************************************/
@ -39,31 +39,27 @@ self.cloud = {
/******************************************************************************/ /******************************************************************************/
var widget = uDom.nodeFromId('cloudWidget'); const widget = uDom.nodeFromId('cloudWidget');
if ( widget === null ) { if ( widget === null ) { return; }
return;
}
self.cloud.datakey = widget.getAttribute('data-cloud-entry') || ''; self.cloud.datakey = widget.getAttribute('data-cloud-entry') || '';
if ( self.cloud.datakey === '' ) { if ( self.cloud.datakey === '' ) { return; }
return;
}
var messaging = vAPI.messaging;
/******************************************************************************/ /******************************************************************************/
var onCloudDataReceived = function(entry) { const fetchCloudData = async function() {
if ( entry instanceof Object === false ) { const entry = await vAPI.messaging.send('cloudWidget', {
return; what: 'cloudPull',
} datakey: self.cloud.datakey,
});
if ( entry instanceof Object === false ) { return; }
self.cloud.data = entry.data; self.cloud.data = entry.data;
uDom.nodeFromId('cloudPull').removeAttribute('disabled'); uDom.nodeFromId('cloudPull').removeAttribute('disabled');
uDom.nodeFromId('cloudPullAndMerge').removeAttribute('disabled'); uDom.nodeFromId('cloudPullAndMerge').removeAttribute('disabled');
var timeOptions = { const timeOptions = {
weekday: 'short', weekday: 'short',
year: 'numeric', year: 'numeric',
month: 'short', month: 'short',
@ -74,7 +70,7 @@ var onCloudDataReceived = function(entry) {
timeZoneName: 'short' timeZoneName: 'short'
}; };
var time = new Date(entry.tstamp); const time = new Date(entry.tstamp);
widget.querySelector('#cloudInfo').textContent = widget.querySelector('#cloudInfo').textContent =
entry.source + '\n' + entry.source + '\n' +
time.toLocaleString('fullwide', timeOptions); time.toLocaleString('fullwide', timeOptions);
@ -82,40 +78,21 @@ var onCloudDataReceived = function(entry) {
/******************************************************************************/ /******************************************************************************/
var fetchCloudData = function() { const pushData = async function() {
messaging.send( if ( typeof self.cloud.onPush !== 'function' ) { return; }
'cloudWidget',
{
what: 'cloudPull',
datakey: self.cloud.datakey
},
onCloudDataReceived
);
};
/******************************************************************************/ const error = await vAPI.messaging.send('cloudWidget', {
var pushData = function() {
if ( typeof self.cloud.onPush !== 'function' ) {
return;
}
messaging.send(
'cloudWidget',
{
what: 'cloudPush', what: 'cloudPush',
datakey: self.cloud.datakey, datakey: self.cloud.datakey,
data: self.cloud.onPush() data: self.cloud.onPush(),
}, });
function(error) { const failed = typeof error === 'string';
var failed = typeof error === 'string';
document.getElementById('cloudPush') document.getElementById('cloudPush')
.classList .classList
.toggle('error', failed); .toggle('error', failed);
document.querySelector('#cloudError') document.querySelector('#cloudError')
.textContent = failed ? error : ''; .textContent = failed ? error : '';
fetchCloudData(); fetchCloudData();
}
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -155,46 +132,34 @@ var closeOptions = function(ev) {
/******************************************************************************/ /******************************************************************************/
var submitOptions = function() { const submitOptions = async function() {
var onOptions = function(options) { uDom.nodeFromId('cloudOptions').classList.remove('show');
if ( options instanceof Object === false ) {
return;
}
self.cloud.options = options;
};
messaging.send( const options = await vAPI.messaging.send('cloudWidget', {
'cloudWidget',
{
what: 'cloudSetOptions', what: 'cloudSetOptions',
options: { options: {
deviceName: uDom.nodeFromId('cloudDeviceName').value deviceName: uDom.nodeFromId('cloudDeviceName').value
}
}, },
onOptions });
); if ( options instanceof Object ) {
uDom.nodeFromId('cloudOptions').classList.remove('show'); self.cloud.options = options;
}
}; };
/******************************************************************************/ /******************************************************************************/
var onInitialize = function(options) { const onInitialize = function(options) {
if ( typeof options !== 'object' || options === null ) { if ( options instanceof Object === false ) { return; }
return; if ( !options.enabled ) { return; }
}
if ( !options.enabled ) {
return;
}
self.cloud.options = options; self.cloud.options = options;
var xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('GET', 'cloud-ui.html', true); xhr.open('GET', 'cloud-ui.html', true);
xhr.overrideMimeType('text/html;charset=utf-8'); xhr.overrideMimeType('text/html;charset=utf-8');
xhr.responseType = 'text'; xhr.responseType = 'text';
xhr.onload = function() { xhr.onload = function() {
this.onload = null; this.onload = null;
var parser = new DOMParser(), const parser = new DOMParser(),
parsed = parser.parseFromString(this.responseText, 'text/html'), parsed = parser.parseFromString(this.responseText, 'text/html'),
fromParent = parsed.body; fromParent = parsed.body;
while ( fromParent.firstElementChild !== null ) { while ( fromParent.firstElementChild !== null ) {
@ -206,12 +171,12 @@ var onInitialize = function(options) {
vAPI.i18n.render(widget); vAPI.i18n.render(widget);
widget.classList.remove('hide'); widget.classList.remove('hide');
uDom('#cloudPush').on('click', pushData); uDom('#cloudPush').on('click', ( ) => { pushData(); });
uDom('#cloudPull').on('click', pullData); uDom('#cloudPull').on('click', pullData);
uDom('#cloudPullAndMerge').on('click', pullAndMergeData); uDom('#cloudPullAndMerge').on('click', pullAndMergeData);
uDom('#cloudCog').on('click', openOptions); uDom('#cloudCog').on('click', openOptions);
uDom('#cloudOptions').on('click', closeOptions); uDom('#cloudOptions').on('click', closeOptions);
uDom('#cloudOptionsSubmit').on('click', submitOptions); uDom('#cloudOptionsSubmit').on('click', ( ) => { submitOptions(); });
// Patch 2018-01-05: Must not assume this XHR will always be faster // Patch 2018-01-05: Must not assume this XHR will always be faster
// than messaging // than messaging
@ -220,10 +185,12 @@ var onInitialize = function(options) {
xhr.send(); xhr.send();
}; };
messaging.send('cloudWidget', { what: 'cloudGetOptions' }, onInitialize); vAPI.messaging.send('cloudWidget', {
what: 'cloudGetOptions',
}).then(options => {
onInitialize(options);
});
/******************************************************************************/ /******************************************************************************/
// https://www.youtube.com/watch?v=aQFp67VoiDA
})(); })();

View File

@ -207,19 +207,15 @@ vAPI.SafeAnimationFrame.prototype = {
let timer; let timer;
const send = function() { const send = function() {
vAPI.messaging.send( vAPI.messaging.send('scriptlets', {
'scriptlets',
{
what: 'securityPolicyViolation', what: 'securityPolicyViolation',
type: 'net', type: 'net',
docURL: document.location.href, docURL: document.location.href,
violations: Array.from(newEvents), violations: Array.from(newEvents),
}, }).then(response => {
response => {
if ( response === true ) { return; } if ( response === true ) { return; }
stop(); stop();
} });
);
for ( const event of newEvents ) { for ( const event of newEvents ) {
allEvents.add(event); allEvents.add(event);
} }
@ -230,7 +226,7 @@ vAPI.SafeAnimationFrame.prototype = {
if ( timer !== undefined ) { return; } if ( timer !== undefined ) { return; }
timer = self.requestIdleCallback( timer = self.requestIdleCallback(
( ) => { timer = undefined; send(); }, ( ) => { timer = undefined; send(); },
{ timeout: 2000 } { timeout: 2063 }
); );
}; };
@ -908,7 +904,8 @@ vAPI.domCollapser = (function() {
// https://github.com/chrisaljoudi/uBlock/issues/174 // https://github.com/chrisaljoudi/uBlock/issues/174
// Do not remove fragment from src URL // Do not remove fragment from src URL
const onProcessed = function(response) { const onProcessed = function(response) {
if ( !response ) { // This happens if uBO is disabled or restarted. // This happens if uBO is disabled or restarted.
if ( response instanceof Object === false ) {
toCollapse.clear(); toCollapse.clear();
return; return;
} }
@ -964,29 +961,27 @@ vAPI.domCollapser = (function() {
} }
if ( selectors.length !== 0 ) { if ( selectors.length !== 0 ) {
messaging.send( messaging.send('contentscript', {
'contentscript',
{
what: 'cosmeticFiltersInjected', what: 'cosmeticFiltersInjected',
type: 'net', type: 'net',
hostname: window.location.hostname, hostname: window.location.hostname,
selectors: selectors selectors,
} });
);
} }
}; };
const send = function() { const send = function() {
processTimer = undefined; processTimer = undefined;
toCollapse.set(resquestIdGenerator, toProcess); toCollapse.set(resquestIdGenerator, toProcess);
const msg = { messaging.send('contentscript', {
what: 'getCollapsibleBlockedRequests', what: 'getCollapsibleBlockedRequests',
id: resquestIdGenerator, id: resquestIdGenerator,
frameURL: window.location.href, frameURL: window.location.href,
resources: toFilter, resources: toFilter,
hash: cachedBlockedSetHash hash: cachedBlockedSetHash,
}; }).then(response => {
messaging.send('contentscript', msg, onProcessed); onProcessed(response);
});
toProcess = []; toProcess = [];
toFilter = []; toFilter = [];
resquestIdGenerator += 1; resquestIdGenerator += 1;
@ -1256,18 +1251,16 @@ vAPI.domSurveyor = (function() {
//console.info(`domSurveyor> Surveyed ${processed} nodes in ${(t1-t0).toFixed(2)} ms`); //console.info(`domSurveyor> Surveyed ${processed} nodes in ${(t1-t0).toFixed(2)} ms`);
// Phase 2: Ask main process to lookup relevant cosmetic filters. // Phase 2: Ask main process to lookup relevant cosmetic filters.
if ( ids.length !== 0 || classes.length !== 0 ) { if ( ids.length !== 0 || classes.length !== 0 ) {
messaging.send( messaging.send('contentscript', {
'contentscript',
{
what: 'retrieveGenericCosmeticSelectors', what: 'retrieveGenericCosmeticSelectors',
hostname: hostname, hostname,
ids: ids, ids,
classes: classes, classes,
exceptions: domFilterer.exceptions, exceptions: domFilterer.exceptions,
cost: surveyCost cost: surveyCost,
}, }).then(response => {
surveyPhase3 surveyPhase3(response);
); });
} else { } else {
surveyPhase3(null); surveyPhase3(null);
} }
@ -1408,10 +1401,9 @@ vAPI.bootstrap = (function() {
if ( window.location === null ) { return; } if ( window.location === null ) { return; }
if ( vAPI instanceof Object === false ) { return; } if ( vAPI instanceof Object === false ) { return; }
vAPI.messaging.send( vAPI.messaging.send('contentscript', {
'contentscript', what: 'shouldRenderNoscriptTags',
{ what: 'shouldRenderNoscriptTags' } });
);
if ( vAPI.domWatcher instanceof Object ) { if ( vAPI.domWatcher instanceof Object ) {
vAPI.domWatcher.start(); vAPI.domWatcher.start();
@ -1437,15 +1429,12 @@ vAPI.bootstrap = (function() {
while ( elem !== null && elem.localName !== 'a' ) { while ( elem !== null && elem.localName !== 'a' ) {
elem = elem.parentElement; elem = elem.parentElement;
} }
vAPI.messaging.send( vAPI.messaging.send('contentscript', {
'contentscript',
{
what: 'mouseClick', what: 'mouseClick',
x: ev.clientX, x: ev.clientX,
y: ev.clientY, y: ev.clientY,
url: elem !== null && ev.isTrusted !== false ? elem.href : '' url: elem !== null && ev.isTrusted !== false ? elem.href : '',
} });
);
}; };
document.addEventListener('mousedown', onMouseClick, true); document.addEventListener('mousedown', onMouseClick, true);
@ -1546,16 +1535,14 @@ vAPI.bootstrap = (function() {
}; };
return function() { return function() {
vAPI.messaging.send( vAPI.messaging.send('contentscript', {
'contentscript',
{
what: 'retrieveContentScriptParameters', what: 'retrieveContentScriptParameters',
url: window.location.href, url: window.location.href,
isRootFrame: window === window.top, isRootFrame: window === window.top,
charset: document.characterSet, charset: document.characterSet,
}, }).then(response => {
bootstrapPhase1 bootstrapPhase1(response);
); });
}; };
})(); })();

View File

@ -225,7 +225,10 @@ self.uBlockDashboard.openOrSelectPage = function(url, options = {}) {
url = ev.target.getAttribute('href'); url = ev.target.getAttribute('href');
} }
const details = Object.assign({ url, select: true, index: -1 }, options); const details = Object.assign({ url, select: true, index: -1 }, options);
vAPI.messaging.send('default', { what: 'gotoURL', details }); vAPI.messaging.send('default', {
what: 'gotoURL',
details,
});
if ( ev ) { if ( ev ) {
ev.preventDefault(); ev.preventDefault();
} }

View File

@ -115,7 +115,9 @@ const onTabClickHandler = function(ev) {
}; };
// https://github.com/uBlockOrigin/uBlock-issues/issues/106 // https://github.com/uBlockOrigin/uBlock-issues/issues/106
vAPI.messaging.send('dashboard', { what: 'canUpdateShortcuts' }, response => { vAPI.messaging.send('dashboard', {
what: 'canUpdateShortcuts',
}).then(response => {
document.body.classList.toggle('canUpdateShortcuts', response === true); document.body.classList.toggle('canUpdateShortcuts', response === true);
}); });

View File

@ -41,22 +41,21 @@ let details = {};
/******************************************************************************/ /******************************************************************************/
messaging.send( (async ( ) => {
'documentBlocked', const response = await messaging.send('documentBlocked', {
{
what: 'listsFromNetFilter', what: 'listsFromNetFilter',
compiledFilter: details.fc, compiledFilter: details.fc,
rawFilter: details.fs rawFilter: details.fs,
}, });
response => {
if ( response instanceof Object === false ) { return; } if ( response instanceof Object === false ) { return; }
let lists; let lists;
for ( const rawFilter in response ) { for ( const rawFilter in response ) {
if ( response.hasOwnProperty(rawFilter) === false ) { continue; } if ( response.hasOwnProperty(rawFilter) ) {
lists = response[rawFilter]; lists = response[rawFilter];
break; break;
} }
}
if ( Array.isArray(lists) === false || lists.length === 0 ) { return; } if ( Array.isArray(lists) === false || lists.length === 0 ) { return; }
@ -77,8 +76,7 @@ messaging.send(
parent.appendChild(elem); parent.appendChild(elem);
} }
uDom.nodeFromId('whyex').style.removeProperty('display'); uDom.nodeFromId('whyex').style.removeProperty('display');
} })();
);
/******************************************************************************/ /******************************************************************************/
@ -219,10 +217,9 @@ if ( window.history.length > 1 ) {
uDom('#bye').on( uDom('#bye').on(
'click', 'click',
( ) => { ( ) => {
messaging.send( messaging.send('documentBlocked', {
'documentBlocked', what: 'closeThisTab',
{ what: 'closeThisTab', } });
);
} }
); );
uDom('#back').css('display', 'none'); uDom('#back').css('display', 'none');
@ -240,30 +237,24 @@ const proceedToURL = function() {
window.location.replace(details.url); window.location.replace(details.url);
}; };
const proceedTemporary = function() { const proceedTemporary = async function() {
messaging.send( await messaging.send('documentBlocked', {
'documentBlocked',
{
what: 'temporarilyWhitelistDocument', what: 'temporarilyWhitelistDocument',
hostname: getTargetHostname() hostname: getTargetHostname(),
}, });
proceedToURL proceedToURL();
);
}; };
const proceedPermanent = function() { const proceedPermanent = async function() {
messaging.send( await messaging.send('documentBlocked', {
'documentBlocked',
{
what: 'toggleHostnameSwitch', what: 'toggleHostnameSwitch',
name: 'no-strict-blocking', name: 'no-strict-blocking',
hostname: getTargetHostname(), hostname: getTargetHostname(),
deep: true, deep: true,
state: true, state: true,
persist: true persist: true,
}, });
proceedToURL proceedToURL();
);
}; };
uDom('#proceedTemporary').attr('href', details.url).on('click', proceedTemporary); uDom('#proceedTemporary').attr('href', details.url).on('click', proceedTemporary);

View File

@ -29,8 +29,6 @@
/******************************************************************************/ /******************************************************************************/
const messaging = vAPI.messaging;
const mergeView = new CodeMirror.MergeView( const mergeView = new CodeMirror.MergeView(
document.querySelector('.codeMirrorMergeContainer'), document.querySelector('.codeMirrorMergeContainer'),
{ {
@ -105,7 +103,7 @@ let differ;
const updateOverlay = (function() { const updateOverlay = (function() {
let reFilter; let reFilter;
let mode = { const mode = {
token: function(stream) { token: function(stream) {
if ( reFilter !== undefined ) { if ( reFilter !== undefined ) {
reFilter.lastIndex = stream.pos; reFilter.lastIndex = stream.pos;
@ -190,8 +188,8 @@ const rulesToDoc = function(clearHistory) {
/******************************************************************************/ /******************************************************************************/
const filterRules = function(key) { const filterRules = function(key) {
const filter = uDom.nodeFromSelector('#ruleFilter input').value;
let rules = unfilteredRules[key].rules; let rules = unfilteredRules[key].rules;
let filter = uDom.nodeFromSelector('#ruleFilter input').value;
if ( filter !== '' ) { if ( filter !== '' ) {
rules = rules.slice(); rules = rules.slice();
let i = rules.length; let i = rules.length;
@ -235,17 +233,14 @@ const renderRules = (( ) => {
/******************************************************************************/ /******************************************************************************/
const applyDiff = function(permanent, toAdd, toRemove) { const applyDiff = async function(permanent, toAdd, toRemove) {
messaging.send( const details = await vAPI.messaging.send('dashboard', {
'dashboard',
{
what: 'modifyRuleset', what: 'modifyRuleset',
permanent: permanent, permanent: permanent,
toAdd: toAdd, toAdd: toAdd,
toRemove: toRemove toRemove: toRemove,
}, });
renderRules renderRules(details);
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -266,13 +261,13 @@ mergeView.options.revertChunk = function(
} }
if ( typeof fromStart.ch !== 'number' ) { fromStart.ch = 0; } if ( typeof fromStart.ch !== 'number' ) { fromStart.ch = 0; }
if ( fromEnd.ch !== 0 ) { fromEnd.line += 1; } if ( fromEnd.ch !== 0 ) { fromEnd.line += 1; }
let toAdd = from.getRange( const toAdd = from.getRange(
{ line: fromStart.line, ch: 0 }, { line: fromStart.line, ch: 0 },
{ line: fromEnd.line, ch: 0 } { line: fromEnd.line, ch: 0 }
); );
if ( typeof toStart.ch !== 'number' ) { toStart.ch = 0; } if ( typeof toStart.ch !== 'number' ) { toStart.ch = 0; }
if ( toEnd.ch !== 0 ) { toEnd.line += 1; } if ( toEnd.ch !== 0 ) { toEnd.line += 1; }
let toRemove = to.getRange( const toRemove = to.getRange(
{ line: toStart.line, ch: 0 }, { line: toStart.line, ch: 0 },
{ line: toEnd.line, ch: 0 } { line: toEnd.line, ch: 0 }
); );
@ -282,7 +277,7 @@ mergeView.options.revertChunk = function(
/******************************************************************************/ /******************************************************************************/
function handleImportFilePicker() { function handleImportFilePicker() {
let fileReaderOnLoadHandler = function() { const fileReaderOnLoadHandler = function() {
if ( typeof this.result !== 'string' || this.result === '' ) { return; } if ( typeof this.result !== 'string' || this.result === '' ) { return; }
// https://github.com/chrisaljoudi/uBlock/issues/757 // https://github.com/chrisaljoudi/uBlock/issues/757
// Support RequestPolicy rule syntax // Support RequestPolicy rule syntax
@ -295,10 +290,10 @@ function handleImportFilePicker() {
} }
applyDiff(false, result, ''); applyDiff(false, result, '');
}; };
let file = this.files[0]; const file = this.files[0];
if ( file === undefined || file.name === '' ) { return; } if ( file === undefined || file.name === '' ) { return; }
if ( file.type.indexOf('text') !== 0 ) { return; } if ( file.type.indexOf('text') !== 0 ) { return; }
let fr = new FileReader(); const fr = new FileReader();
fr.onload = fileReaderOnLoadHandler; fr.onload = fileReaderOnLoadHandler;
fr.readAsText(file); fr.readAsText(file);
} }
@ -306,7 +301,7 @@ function handleImportFilePicker() {
/******************************************************************************/ /******************************************************************************/
const startImportFilePicker = function() { const startImportFilePicker = function() {
let input = document.getElementById('importFilePicker'); const input = document.getElementById('importFilePicker');
// Reset to empty string, this will ensure an change event is properly // Reset to empty string, this will ensure an change event is properly
// triggered if the user pick a file, even if it is the same as the last // triggered if the user pick a file, even if it is the same as the last
// one picked. // one picked.
@ -317,7 +312,7 @@ const startImportFilePicker = function() {
/******************************************************************************/ /******************************************************************************/
function exportUserRulesToFile() { function exportUserRulesToFile() {
let filename = vAPI.i18n('rulesDefaultFileName') const filename = vAPI.i18n('rulesDefaultFileName')
.replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString()) .replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString())
.replace(/ +/g, '_'); .replace(/ +/g, '_');
vAPI.download({ vAPI.download({
@ -339,7 +334,7 @@ const onFilterChanged = (function() {
const process = function() { const process = function() {
timer = undefined; timer = undefined;
if ( mergeView.editor().isClean(cleanEditToken) === false ) { return; } if ( mergeView.editor().isClean(cleanEditToken) === false ) { return; }
let filter = uDom.nodeFromSelector('#ruleFilter input').value; const filter = uDom.nodeFromSelector('#ruleFilter input').value;
if ( filter === last ) { return; } if ( filter === last ) { return; }
last = filter; last = filter;
if ( overlay !== null ) { if ( overlay !== null ) {
@ -401,15 +396,15 @@ const onTextChanged = (( ) => {
/******************************************************************************/ /******************************************************************************/
const revertAllHandler = function() { const revertAllHandler = function() {
let toAdd = [], toRemove = []; const toAdd = [], toRemove = [];
let left = mergeView.leftOriginal(), const left = mergeView.leftOriginal();
edit = mergeView.editor(); const edit = mergeView.editor();
for ( let chunk of mergeView.leftChunks() ) { for ( const chunk of mergeView.leftChunks() ) {
let addedLines = left.getRange( const addedLines = left.getRange(
{ line: chunk.origFrom, ch: 0 }, { line: chunk.origFrom, ch: 0 },
{ line: chunk.origTo, ch: 0 } { line: chunk.origTo, ch: 0 }
); );
let removedLines = edit.getRange( const removedLines = edit.getRange(
{ line: chunk.editFrom, ch: 0 }, { line: chunk.editFrom, ch: 0 },
{ line: chunk.editTo, ch: 0 } { line: chunk.editTo, ch: 0 }
); );
@ -422,15 +417,15 @@ const revertAllHandler = function() {
/******************************************************************************/ /******************************************************************************/
const commitAllHandler = function() { const commitAllHandler = function() {
let toAdd = [], toRemove = []; const toAdd = [], toRemove = [];
let left = mergeView.leftOriginal(), const left = mergeView.leftOriginal();
edit = mergeView.editor(); const edit = mergeView.editor();
for ( let chunk of mergeView.leftChunks() ) { for ( const chunk of mergeView.leftChunks() ) {
let addedLines = edit.getRange( const addedLines = edit.getRange(
{ line: chunk.editFrom, ch: 0 }, { line: chunk.editFrom, ch: 0 },
{ line: chunk.editTo, ch: 0 } { line: chunk.editTo, ch: 0 }
); );
let removedLines = left.getRange( const removedLines = left.getRange(
{ line: chunk.origFrom, ch: 0 }, { line: chunk.origFrom, ch: 0 },
{ line: chunk.origTo, ch: 0 } { line: chunk.origTo, ch: 0 }
); );
@ -443,16 +438,16 @@ const commitAllHandler = function() {
/******************************************************************************/ /******************************************************************************/
const editSaveHandler = function() { const editSaveHandler = function() {
let editor = mergeView.editor(); const editor = mergeView.editor();
let editText = editor.getValue().trim(); const editText = editor.getValue().trim();
if ( editText === cleanEditText ) { if ( editText === cleanEditText ) {
onTextChanged(true); onTextChanged(true);
return; return;
} }
if ( differ === undefined ) { differ = new diff_match_patch(); } if ( differ === undefined ) { differ = new diff_match_patch(); }
let toAdd = [], toRemove = []; const toAdd = [], toRemove = [];
let diffs = differ.diff_main(cleanEditText, editText); const diffs = differ.diff_main(cleanEditText, editText);
for ( let diff of diffs ) { for ( const diff of diffs ) {
if ( diff[0] === 1 ) { if ( diff[0] === 1 ) {
toAdd.push(diff[1]); toAdd.push(diff[1]);
} else if ( diff[0] === -1 ) { } else if ( diff[0] === -1 ) {
@ -485,7 +480,11 @@ self.hasUnsavedData = function() {
/******************************************************************************/ /******************************************************************************/
messaging.send('dashboard', { what: 'getRules' }, renderRules); vAPI.messaging.send('dashboard', {
what: 'getRules',
}).then(details => {
renderRules(details);
});
// Handle user interaction // Handle user interaction
uDom('#importButton').on('click', startImportFilePicker); uDom('#importButton').on('click', startImportFilePicker);

View File

@ -25,7 +25,7 @@
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
/******************************************************************************/ /******************************************************************************/
@ -385,9 +385,15 @@ const startDialog = (function() {
ev.stopPropagation(); ev.stopPropagation();
if ( target.id === 'createCosmeticFilters' ) { if ( target.id === 'createCosmeticFilters' ) {
messaging.send('loggerUI', { what: 'createUserFilter', filters: textarea.value }); messaging.send('loggerUI', {
what: 'createUserFilter',
filters: textarea.value,
});
// Force a reload for the new cosmetic filter(s) to take effect // Force a reload for the new cosmetic filter(s) to take effect
messaging.send('loggerUI', { what: 'reloadTab', tabId: inspectedTabId }); messaging.send('loggerUI', {
what: 'reloadTab',
tabId: inspectedTabId,
});
return stop(); return stop();
} }
}; };
@ -561,8 +567,8 @@ const injectInspector = function() {
inspectedTabId = tabId; inspectedTabId = tabId;
messaging.send('loggerUI', { messaging.send('loggerUI', {
what: 'scriptlet', what: 'scriptlet',
tabId: tabId, tabId,
scriptlet: 'dom-inspector' scriptlet: 'dom-inspector',
}); });
}; };

View File

@ -25,7 +25,7 @@
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
/******************************************************************************/ /******************************************************************************/
@ -975,7 +975,7 @@ const onLogBufferRead = function(response) {
const readLogBuffer = (( ) => { const readLogBuffer = (( ) => {
let timer; let timer;
const readLogBufferNow = function() { const readLogBufferNow = async function() {
if ( logger.ownerId === undefined ) { return; } if ( logger.ownerId === undefined ) { return; }
const msg = { const msg = {
@ -1002,11 +1002,11 @@ const readLogBuffer = (( ) => {
msg.popupLoggerBoxChanged = true; msg.popupLoggerBoxChanged = true;
} }
vAPI.messaging.send('loggerUI', msg, response => { const response = await vAPI.messaging.send('loggerUI', msg);
timer = undefined; timer = undefined;
onLogBufferRead(response); onLogBufferRead(response);
readLogBufferLater(); readLogBufferLater();
});
}; };
const readLogBufferLater = function() { const readLogBufferLater = function() {
@ -1078,7 +1078,7 @@ const reloadTab = function(ev) {
messaging.send('loggerUI', { messaging.send('loggerUI', {
what: 'reloadTab', what: 'reloadTab',
tabId: tabId, tabId: tabId,
bypassCache: ev && (ev.ctrlKey || ev.metaKey || ev.shiftKey) bypassCache: ev && (ev.ctrlKey || ev.metaKey || ev.shiftKey),
}); });
}; };
@ -1144,17 +1144,14 @@ const reloadTab = function(ev) {
} }
}; };
const colorize = function() { const colorize = async function() {
messaging.send( const response = await messaging.send('loggerUI', {
'loggerUI',
{
what: 'getURLFilteringData', what: 'getURLFilteringData',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
urls: targetURLs, urls: targetURLs,
type: uglyTypeFromSelector('dynamic') type: uglyTypeFromSelector('dynamic'),
}, });
onColorsReady onColorsReady(response);
);
}; };
const parseStaticInputs = function() { const parseStaticInputs = function() {
@ -1228,16 +1225,13 @@ const reloadTab = function(ev) {
} }
createdStaticFilters[value] = true; createdStaticFilters[value] = true;
if ( value !== '' ) { if ( value !== '' ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'createUserFilter', what: 'createUserFilter',
autoComment: true, autoComment: true,
filters: value, filters: value,
origin: targetPageDomain, origin: targetPageDomain,
pageDomain: targetPageDomain, pageDomain: targetPageDomain,
} });
);
} }
updateWidgets(); updateWidgets();
ev.stopPropagation(); ev.stopPropagation();
@ -1246,16 +1240,14 @@ const reloadTab = function(ev) {
// Save url filtering rule(s) // Save url filtering rule(s)
if ( target.id === 'saveRules' ) { if ( target.id === 'saveRules' ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'saveURLFilteringRules', what: 'saveURLFilteringRules',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
urls: targetURLs, urls: targetURLs,
type: uglyTypeFromSelector('dynamic') type: uglyTypeFromSelector('dynamic'),
}, }).then(( ) => {
colorize colorize();
); });
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
@ -1264,100 +1256,86 @@ const reloadTab = function(ev) {
// Remove url filtering rule // Remove url filtering rule
if ( tcl.contains('action') ) { if ( tcl.contains('action') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'setURLFilteringRule', what: 'setURLFilteringRule',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
url: target.getAttribute('data-url'), url: target.getAttribute('data-url'),
type: uglyTypeFromSelector('dynamic'), type: uglyTypeFromSelector('dynamic'),
action: 0, action: 0,
persist: persist persist: persist,
}, }).then(( ) => {
colorize colorize();
); });
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
// add "allow" url filtering rule // add "allow" url filtering rule
if ( tcl.contains('allow') ) { if ( tcl.contains('allow') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'setURLFilteringRule', what: 'setURLFilteringRule',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
url: target.parentNode.getAttribute('data-url'), url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector('dynamic'), type: uglyTypeFromSelector('dynamic'),
action: 2, action: 2,
persist: persist persist: persist,
}, }).then(( ) => {
colorize colorize();
); });
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
// add "block" url filtering rule // add "block" url filtering rule
if ( tcl.contains('noop') ) { if ( tcl.contains('noop') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'setURLFilteringRule', what: 'setURLFilteringRule',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
url: target.parentNode.getAttribute('data-url'), url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector('dynamic'), type: uglyTypeFromSelector('dynamic'),
action: 3, action: 3,
persist: persist persist: persist,
}, }).then(( ) => {
colorize colorize();
); });
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
// add "block" url filtering rule // add "block" url filtering rule
if ( tcl.contains('block') ) { if ( tcl.contains('block') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'setURLFilteringRule', what: 'setURLFilteringRule',
context: selectValue('select.dynamic.origin'), context: selectValue('select.dynamic.origin'),
url: target.parentNode.getAttribute('data-url'), url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector('dynamic'), type: uglyTypeFromSelector('dynamic'),
action: 1, action: 1,
persist: persist persist: persist,
}, }).then(( ) => {
colorize colorize();
); });
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
// Force a reload of the tab // Force a reload of the tab
if ( tcl.contains('reload') ) { if ( tcl.contains('reload') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'reloadTab', what: 'reloadTab',
tabId: targetTabId tabId: targetTabId,
} });
);
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
// Hightlight corresponding element in target web page // Hightlight corresponding element in target web page
if ( tcl.contains('picker') ) { if ( tcl.contains('picker') ) {
messaging.send( messaging.send('loggerUI', {
'loggerUI',
{
what: 'launchElementPicker', what: 'launchElementPicker',
tabId: targetTabId, tabId: targetTabId,
targetURL: 'img\t' + targetURLs[0], targetURL: 'img\t' + targetURLs[0],
select: true select: true,
} });
);
ev.stopPropagation(); ev.stopPropagation();
return; return;
} }
@ -1450,7 +1428,7 @@ const reloadTab = function(ev) {
return urls; return urls;
}; };
const fillSummaryPaneFilterList = function(rows) { const fillSummaryPaneFilterList = async function(rows) {
const rawFilter = targetRow.children[1].textContent; const rawFilter = targetRow.children[1].textContent;
const compiledFilter = targetRow.getAttribute('data-filter'); const compiledFilter = targetRow.getAttribute('data-filter');
@ -1509,25 +1487,19 @@ const reloadTab = function(ev) {
}; };
if ( targetRow.classList.contains('networkRealm') ) { if ( targetRow.classList.contains('networkRealm') ) {
messaging.send( const response = await messaging.send('loggerUI', {
'loggerUI',
{
what: 'listsFromNetFilter', what: 'listsFromNetFilter',
compiledFilter: compiledFilter, compiledFilter: compiledFilter,
rawFilter: rawFilter rawFilter: rawFilter,
}, });
handleResponse handleResponse(response);
);
} else if ( targetRow.classList.contains('cosmeticRealm') ) { } else if ( targetRow.classList.contains('cosmeticRealm') ) {
messaging.send( const response = await messaging.send('loggerUI', {
'loggerUI',
{
what: 'listsFromCosmeticFilter', what: 'listsFromCosmeticFilter',
url: targetRow.children[6].textContent, url: targetRow.children[6].textContent,
rawFilter: rawFilter, rawFilter: rawFilter,
}, });
handleResponse handleResponse(response);
);
} }
}; };
@ -1789,7 +1761,7 @@ const reloadTab = function(ev) {
modalDialog.show(); modalDialog.show();
}; };
const toggleOn = function(ev) { const toggleOn = async function(ev) {
targetRow = ev.target.closest('.canDetails'); targetRow = ev.target.closest('.canDetails');
if ( targetRow === null ) { return; } if ( targetRow === null ) { return; }
ev.stopPropagation(); ev.stopPropagation();
@ -1800,24 +1772,21 @@ const reloadTab = function(ev) {
targetFrameHostname = targetRow.getAttribute('data-dochn') || ''; targetFrameHostname = targetRow.getAttribute('data-dochn') || '';
// We need the root domain names for best user experience. // We need the root domain names for best user experience.
messaging.send( const domains = await messaging.send('loggerUI', {
'loggerUI',
{
what: 'getDomainNames', what: 'getDomainNames',
targets: [ targets: [
targetURLs[0], targetURLs[0],
targetPageHostname, targetPageHostname,
targetFrameHostname targetFrameHostname
] ],
}, });
fillDialog fillDialog(domains);
);
}; };
uDom('#netInspector').on( uDom('#netInspector').on(
'click', 'click',
'.canDetails > span:nth-of-type(2),.canDetails > span:nth-of-type(3),.canDetails > span:nth-of-type(5)', '.canDetails > span:nth-of-type(2),.canDetails > span:nth-of-type(3),.canDetails > span:nth-of-type(5)',
toggleOn ev => { toggleOn(ev); }
); );
})(); })();
@ -2766,10 +2735,10 @@ const grabView = function() {
const releaseView = function() { const releaseView = function() {
if ( logger.ownerId === undefined ) { return; } if ( logger.ownerId === undefined ) { return; }
vAPI.messaging.send( vAPI.messaging.send('loggerUI', {
'loggerUI', what: 'releaseView',
{ what: 'releaseView', ownerId: logger.ownerId } ownerId: logger.ownerId,
); });
logger.ownerId = undefined; logger.ownerId = undefined;
}; };

View File

@ -362,11 +362,35 @@ const popupDataFromRequest = async function(request) {
return popupDataFromTabId(tabId, tabTitle); return popupDataFromTabId(tabId, tabTitle);
}; };
const getDOMStats = async function(tabId) {
const results = await vAPI.tabs.executeScript(tabId, {
allFrames: true,
file: '/js/scriptlets/dom-survey.js',
runAt: 'document_end',
});
let elementCount = 0;
let scriptCount = 0;
results.forEach(result => {
if ( result instanceof Object === false ) { return; }
elementCount += result.elementCount;
scriptCount += result.scriptCount;
});
return { elementCount, scriptCount };
};
const onMessage = function(request, sender, callback) { const onMessage = function(request, sender, callback) {
let pageStore; let pageStore;
// Async // Async
switch ( request.what ) { switch ( request.what ) {
case 'getPopupLazyData':
getDOMStats(request.tabId).then(results => {
callback(results);
});
return;
case 'getPopupData': case 'getPopupData':
popupDataFromRequest(request).then(popupData => { popupDataFromRequest(request).then(popupData => {
callback(popupData); callback(popupData);
@ -381,19 +405,6 @@ const onMessage = function(request, sender, callback) {
let response; let response;
switch ( request.what ) { switch ( request.what ) {
case 'getPopupLazyData':
pageStore = µb.pageStoreFromTabId(request.tabId);
if ( pageStore !== null ) {
pageStore.hiddenElementCount = 0;
pageStore.scriptCount = 0;
vAPI.tabs.executeScript(request.tabId, {
allFrames: true,
file: '/js/scriptlets/dom-survey.js',
runAt: 'document_end'
});
}
break;
case 'hasPopupContentChanged': case 'hasPopupContentChanged':
pageStore = µb.pageStoreFromTabId(request.tabId); pageStore = µb.pageStoreFromTabId(request.tabId);
var lastModified = pageStore ? pageStore.contentLastModified : 0; var lastModified = pageStore ? pageStore.contentLastModified : 0;
@ -792,14 +803,13 @@ const µb = µBlock;
const getLocalData = async function() { const getLocalData = async function() {
const data = Object.assign({}, µb.restoreBackupSettings); const data = Object.assign({}, µb.restoreBackupSettings);
data.storageUsed = await µb.getBytesInUse(); data.storageUsed = await µb.getBytesInUse();
data.cloudStorageSupported = µb.cloudStorageSupported;
data.privacySettingsSupported = µb.privacySettingsSupported;
return data; return data;
}; };
const backupUserData = async function() { const backupUserData = async function() {
const [ userFilters, localData ] = await Promise.all([ const userFilters = await µb.loadUserFilters();
µb.loadUserFilters(),
getLocalData(),
]);
const userData = { const userData = {
timeStamp: Date.now(), timeStamp: Date.now(),
@ -823,6 +833,8 @@ const backupUserData = async function() {
µb.restoreBackupSettings.lastBackupTime = Date.now(); µb.restoreBackupSettings.lastBackupTime = Date.now();
vAPI.storage.set(µb.restoreBackupSettings); vAPI.storage.set(µb.restoreBackupSettings);
const localData = await getLocalData();
return { localData, userData }; return { localData, userData };
}; };
@ -1348,21 +1360,6 @@ vAPI.messaging.listen({
// >>>>> start of local scope // >>>>> start of local scope
const µb = µBlock; const µb = µBlock;
const broadcastTimers = new Map();
const domSurveyFinalReport = function(tabId) {
broadcastTimers.delete(tabId + '-domSurveyReport');
const pageStore = µb.pageStoreFromTabId(tabId);
if ( pageStore === null ) { return; }
vAPI.messaging.broadcast({
what: 'domSurveyFinalReport',
tabId: tabId,
affectedElementCount: pageStore.hiddenElementCount,
scriptCount: pageStore.scriptCount,
});
};
const logCosmeticFilters = function(tabId, details) { const logCosmeticFilters = function(tabId, details) {
if ( µb.logger.enabled === false ) { return; } if ( µb.logger.enabled === false ) { return; }
@ -1488,24 +1485,6 @@ const onMessage = function(request, sender, callback) {
response = µb.applyFilterListSelection(request); response = µb.applyFilterListSelection(request);
break; break;
case 'domSurveyTransientReport':
if ( pageStore !== null ) {
if ( request.filteredElementCount ) {
pageStore.hiddenElementCount += request.filteredElementCount;
}
if ( request.scriptCount ) {
pageStore.scriptCount += request.scriptCount;
}
const broadcastKey = `${tabId}-domSurveyReport`;
if ( broadcastTimers.has(broadcastKey) === false ) {
broadcastTimers.set(broadcastKey, vAPI.setTimeout(
( ) => { domSurveyFinalReport(tabId); },
103
));
}
}
break;
case 'inlinescriptFound': case 'inlinescriptFound':
if ( µb.logger.enabled && pageStore !== null ) { if ( µb.logger.enabled && pageStore !== null ) {
const fctxt = µb.filteringContext.duplicate(); const fctxt = µb.filteringContext.duplicate();

View File

@ -257,9 +257,7 @@ const PageStore = class {
this.logData = undefined; this.logData = undefined;
this.perLoadBlockedRequestCount = 0; this.perLoadBlockedRequestCount = 0;
this.perLoadAllowedRequestCount = 0; this.perLoadAllowedRequestCount = 0;
this.hiddenElementCount = ''; // Empty string means "unknown"
this.remoteFontCount = 0; this.remoteFontCount = 0;
this.scriptCount = 0;
this.popupBlockedCount = 0; this.popupBlockedCount = 0;
this.largeMediaCount = 0; this.largeMediaCount = 0;
this.largeMediaTimer = null; this.largeMediaTimer = null;

View File

@ -668,49 +668,36 @@ let renderOnce = function() {
/******************************************************************************/ /******************************************************************************/
const renderPopupLazy = function() { const renderPopupLazy = async function() {
messaging.send( const result = await messaging.send('popupPanel', {
'popupPanel', what: 'getPopupLazyData',
{ what: 'getPopupLazyData', tabId: popupData.tabId } tabId: popupData.tabId,
); });
}; if ( result instanceof Object === false ) { return; }
const onPopupMessage = function(data) { let count = result.elementCount || 0;
if ( !data ) { return; }
if ( data.tabId !== popupData.tabId ) { return; }
switch ( data.what ) {
case 'domSurveyFinalReport':
let count = data.affectedElementCount || '';
uDom.nodeFromSelector('#no-cosmetic-filtering > span.fa-icon-badge') uDom.nodeFromSelector('#no-cosmetic-filtering > span.fa-icon-badge')
.textContent = typeof count === 'number' .textContent = count !== 0
? Math.min(count, 99).toLocaleString() ? Math.min(count, 99).toLocaleString()
: count; : '';
count = data.scriptCount || ''; count = result.scriptCount || 0;
uDom.nodeFromSelector('#no-scripting > span.fa-icon-badge') uDom.nodeFromSelector('#no-scripting > span.fa-icon-badge')
.textContent = typeof count === 'number' .textContent = count !== 0
? Math.min(count, 99).toLocaleString() ? Math.min(count, 99).toLocaleString()
: count; : '';
break;
}
}; };
messaging.addChannelListener('popup', onPopupMessage);
/******************************************************************************/ /******************************************************************************/
const toggleNetFilteringSwitch = function(ev) { const toggleNetFilteringSwitch = function(ev) {
if ( !popupData || !popupData.pageURL ) { return; } if ( !popupData || !popupData.pageURL ) { return; }
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'toggleNetFiltering', what: 'toggleNetFiltering',
url: popupData.pageURL, url: popupData.pageURL,
scope: ev.ctrlKey || ev.metaKey ? 'page' : '', scope: ev.ctrlKey || ev.metaKey ? 'page' : '',
state: !uDom('body').toggleClass('off').hasClass('off'), state: !uDom('body').toggleClass('off').hasClass('off'),
tabId: popupData.tabId tabId: popupData.tabId,
} });
);
renderTooltips('#switch'); renderTooltips('#switch');
hashFromPopupData(); hashFromPopupData();
}; };
@ -718,14 +705,11 @@ const toggleNetFilteringSwitch = function(ev) {
/******************************************************************************/ /******************************************************************************/
const gotoZap = function() { const gotoZap = function() {
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'launchElementPicker', what: 'launchElementPicker',
tabId: popupData.tabId, tabId: popupData.tabId,
zap: true zap: true,
} });
);
vAPI.closePopup(); vAPI.closePopup();
}; };
@ -733,13 +717,10 @@ const gotoZap = function() {
/******************************************************************************/ /******************************************************************************/
const gotoPick = function() { const gotoPick = function() {
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'launchElementPicker', what: 'launchElementPicker',
tabId: popupData.tabId tabId: popupData.tabId,
} });
);
vAPI.closePopup(); vAPI.closePopup();
}; };
@ -759,18 +740,15 @@ const gotoURL = function(ev) {
url += '+' + popupData.tabId; url += '+' + popupData.tabId;
} }
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'gotoURL', what: 'gotoURL',
details: { details: {
url: url, url: url,
select: true, select: true,
index: -1, index: -1,
shiftKey: ev.shiftKey shiftKey: ev.shiftKey
} },
} });
);
vAPI.closePopup(); vAPI.closePopup();
}; };
@ -780,14 +758,11 @@ const gotoURL = function(ev) {
const toggleFirewallPane = function() { const toggleFirewallPane = function() {
popupData.dfEnabled = !popupData.dfEnabled; popupData.dfEnabled = !popupData.dfEnabled;
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'userSettings', what: 'userSettings',
name: 'dynamicFilteringEnabled', name: 'dynamicFilteringEnabled',
value: popupData.dfEnabled value: popupData.dfEnabled,
} });
);
// https://github.com/chrisaljoudi/uBlock/issues/996 // https://github.com/chrisaljoudi/uBlock/issues/996
// Remember the last state of the firewall pane. This allows to // Remember the last state of the firewall pane. This allows to
@ -817,7 +792,7 @@ const mouseleaveCellHandler = function() {
/******************************************************************************/ /******************************************************************************/
const setFirewallRule = function(src, des, type, action, persist) { const setFirewallRule = async function(src, des, type, action, persist) {
// This can happen on pages where uBlock does not work // This can happen on pages where uBlock does not work
if ( if (
typeof popupData.pageHostname !== 'string' || typeof popupData.pageHostname !== 'string' ||
@ -826,9 +801,7 @@ const setFirewallRule = function(src, des, type, action, persist) {
return; return;
} }
messaging.send( const response = await messaging.send('popupPanel', {
'popupPanel',
{
what: 'toggleFirewallRule', what: 'toggleFirewallRule',
tabId: popupData.tabId, tabId: popupData.tabId,
pageHostname: popupData.pageHostname, pageHostname: popupData.pageHostname,
@ -836,14 +809,12 @@ const setFirewallRule = function(src, des, type, action, persist) {
desHostname: des, desHostname: des,
requestType: type, requestType: type,
action: action, action: action,
persist: persist persist: persist,
}, });
response => {
cachePopupData(response); cachePopupData(response);
updateAllFirewallCells(); updateAllFirewallCells();
hashFromPopupData(); hashFromPopupData();
}
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -889,15 +860,12 @@ const setFirewallRuleHandler = function(ev) {
/******************************************************************************/ /******************************************************************************/
const reloadTab = function(ev) { const reloadTab = function(ev) {
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'reloadTab', what: 'reloadTab',
tabId: popupData.tabId, tabId: popupData.tabId,
select: vAPI.webextFlavor.soup.has('mobile'), select: vAPI.webextFlavor.soup.has('mobile'),
bypassCache: ev.ctrlKey || ev.metaKey || ev.shiftKey bypassCache: ev.ctrlKey || ev.metaKey || ev.shiftKey,
} });
);
// Polling will take care of refreshing the popup content // Polling will take care of refreshing the popup content
// https://github.com/chrisaljoudi/uBlock/issues/748 // https://github.com/chrisaljoudi/uBlock/issues/748
@ -930,17 +898,14 @@ const toggleMinimize = function(ev) {
// Useful to take snapshots of the whole list of domains -- example: // Useful to take snapshots of the whole list of domains -- example:
// https://github.com/gorhill/uBlock/issues/736#issuecomment-178879944 // https://github.com/gorhill/uBlock/issues/736#issuecomment-178879944
if ( ev.shiftKey && ev.ctrlKey ) { if ( ev.shiftKey && ev.ctrlKey ) {
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'gotoURL', what: 'gotoURL',
details: { details: {
url: 'popup.html?tabId=' + popupData.tabId + '&responsive=1', url: 'popup.html?tabId=' + popupData.tabId + '&responsive=1',
select: true, select: true,
index: -1 index: -1
} },
} });
);
vAPI.closePopup(); vAPI.closePopup();
return; return;
} }
@ -948,76 +913,62 @@ const toggleMinimize = function(ev) {
popupData.firewallPaneMinimized = popupData.firewallPaneMinimized =
uDom.nodeFromId('firewallContainer').classList.toggle('minimized'); uDom.nodeFromId('firewallContainer').classList.toggle('minimized');
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'userSettings', what: 'userSettings',
name: 'firewallPaneMinimized', name: 'firewallPaneMinimized',
value: popupData.firewallPaneMinimized value: popupData.firewallPaneMinimized,
} });
);
positionRulesetTools(); positionRulesetTools();
}; };
/******************************************************************************/ /******************************************************************************/
const saveFirewallRules = function() { const saveFirewallRules = function() {
messaging.send( messaging.send('popupPanel', {
'popupPanel',
{
what: 'saveFirewallRules', what: 'saveFirewallRules',
srcHostname: popupData.pageHostname, srcHostname: popupData.pageHostname,
desHostnames: popupData.hostnameDict desHostnames: popupData.hostnameDict,
} });
);
uDom.nodeFromId('firewallContainer').classList.remove('dirty'); uDom.nodeFromId('firewallContainer').classList.remove('dirty');
}; };
/******************************************************************************/ /******************************************************************************/
const revertFirewallRules = function() { const revertFirewallRules = async function() {
messaging.send( uDom.nodeFromId('firewallContainer').classList.remove('dirty');
'popupPanel', const response = await messaging.send('popupPanel', {
{
what: 'revertFirewallRules', what: 'revertFirewallRules',
srcHostname: popupData.pageHostname, srcHostname: popupData.pageHostname,
desHostnames: popupData.hostnameDict, desHostnames: popupData.hostnameDict,
tabId: popupData.tabId tabId: popupData.tabId,
}, });
response => {
cachePopupData(response); cachePopupData(response);
updateAllFirewallCells(); updateAllFirewallCells();
updateHnSwitches(); updateHnSwitches();
hashFromPopupData(); hashFromPopupData();
}
);
uDom.nodeFromId('firewallContainer').classList.remove('dirty');
}; };
/******************************************************************************/ /******************************************************************************/
const toggleHostnameSwitch = function(ev) { const toggleHostnameSwitch = async function(ev) {
const target = ev.currentTarget; const target = ev.currentTarget;
const switchName = target.getAttribute('id'); const switchName = target.getAttribute('id');
if ( !switchName ) { return; } if ( !switchName ) { return; }
target.classList.toggle('on'); target.classList.toggle('on');
messaging.send( renderTooltips('#' + switchName);
'popupPanel',
{ const response = await messaging.send('popupPanel', {
what: 'toggleHostnameSwitch', what: 'toggleHostnameSwitch',
name: switchName, name: switchName,
hostname: popupData.pageHostname, hostname: popupData.pageHostname,
state: target.classList.contains('on'), state: target.classList.contains('on'),
tabId: popupData.tabId, tabId: popupData.tabId,
persist: popupData.dfEnabled === false || ev.ctrlKey || ev.metaKey persist: popupData.dfEnabled === false || ev.ctrlKey || ev.metaKey,
}, });
response => {
cachePopupData(response); cachePopupData(response);
updateAllFirewallCells(); updateAllFirewallCells();
hashFromPopupData(); hashFromPopupData();
}
);
renderTooltips('#' + switchName);
}; };
/******************************************************************************/ /******************************************************************************/
@ -1040,20 +991,17 @@ const toggleHostnameSwitch = function(ev) {
// on demand rather than forcing the main process to assume a client may need // on demand rather than forcing the main process to assume a client may need
// it and thus having to push it all the time unconditionally. // it and thus having to push it all the time unconditionally.
const pollForContentChange = (function() { const pollForContentChange = (( ) => {
let pollTimer; let pollTimer;
const pollCallback = function() { const pollCallback = async function() {
pollTimer = undefined; pollTimer = undefined;
messaging.send( const response = await messaging.send('popupPanel', {
'popupPanel',
{
what: 'hasPopupContentChanged', what: 'hasPopupContentChanged',
tabId: popupData.tabId, tabId: popupData.tabId,
contentLastModified: popupData.contentLastModified contentLastModified: popupData.contentLastModified,
}, });
queryCallback queryCallback(response);
);
}; };
const queryCallback = function(response) { const queryCallback = function(response) {
@ -1074,8 +1022,12 @@ const pollForContentChange = (function() {
/******************************************************************************/ /******************************************************************************/
const getPopupData = function(tabId) { const getPopupData = async function(tabId) {
const onDataReceived = function(response) { const response = await messaging.send('popupPanel', {
what: 'getPopupData',
tabId,
});
cachePopupData(response); cachePopupData(response);
renderOnce(); renderOnce();
renderPopup(); renderPopup();
@ -1083,12 +1035,6 @@ const getPopupData = function(tabId) {
hashFromPopupData(true); hashFromPopupData(true);
pollForContentChange(); pollForContentChange();
}; };
messaging.send(
'popupPanel',
{ what: 'getPopupData', tabId: tabId },
onDataReceived
);
};
/******************************************************************************/ /******************************************************************************/
@ -1151,9 +1097,9 @@ uDom('#switch').on('click', toggleNetFilteringSwitch);
uDom('#gotoZap').on('click', gotoZap); uDom('#gotoZap').on('click', gotoZap);
uDom('#gotoPick').on('click', gotoPick); uDom('#gotoPick').on('click', gotoPick);
uDom('h2').on('click', toggleFirewallPane); uDom('h2').on('click', toggleFirewallPane);
uDom('.hnSwitch').on('click', toggleHostnameSwitch); uDom('.hnSwitch').on('click', ev => { toggleHostnameSwitch(ev); });
uDom('#saveRules').on('click', saveFirewallRules); uDom('#saveRules').on('click', saveFirewallRules);
uDom('#revertRules').on('click', revertFirewallRules); uDom('#revertRules').on('click', ( ) => { revertFirewallRules(); });
uDom('[data-i18n="popupAnyRulePrompt"]').on('click', toggleMinimize); uDom('[data-i18n="popupAnyRulePrompt"]').on('click', toggleMinimize);
uDom('body').on('mouseenter', '[data-tip]', onShowTooltip) uDom('body').on('mouseenter', '[data-tip]', onShowTooltip)

View File

@ -195,15 +195,12 @@ const processTimer = new vAPI.SafeAnimationFrame(( ) => {
if ( toLog.length === 0 ) { return; } if ( toLog.length === 0 ) { return; }
vAPI.messaging.send( vAPI.messaging.send('scriptlets', {
'scriptlets',
{
what: 'logCosmeticFilteringData', what: 'logCosmeticFilteringData',
frameURL: window.location.href, frameURL: window.location.href,
frameHostname: window.location.hostname, frameHostname: window.location.hostname,
matchedSelectors: toLog, matchedSelectors: toLog,
} });
);
//console.timeEnd('dom logger/scanning for matches'); //console.timeEnd('dom logger/scanning for matches');
}); });

View File

@ -49,37 +49,15 @@
const scriptTags = document.querySelectorAll('script[src]'); const scriptTags = document.querySelectorAll('script[src]');
let filteredElementCount = 0; let elementCount = 0;
if ( vAPI.domFilterer ) { if ( vAPI.domFilterer ) {
filteredElementCount = vAPI.domFilterer.getFilteredElementCount(); elementCount = vAPI.domFilterer.getFilteredElementCount();
} }
vAPI.messaging.send( // IMPORTANT: This is returned to the injector, so this MUST be
'scriptlets', // the last statement.
{ return {
what: 'domSurveyTransientReport', elementCount,
filteredElementCount: filteredElementCount,
scriptCount: inlineScriptCount + scriptTags.length, scriptCount: inlineScriptCount + scriptTags.length,
} };
);
})(); })();
/*******************************************************************************
DO NOT:
- Remove the following code
- Add code beyond the following code
Reason:
- https://github.com/gorhill/uBlock/pull/3721
- uBO never uses the return value from injected content scripts
**/
void 0;

View File

@ -371,15 +371,12 @@ const netFilterFromUnion = function(toMergeURL, out) {
) { ) {
lastNetFilterHostname = parsedURL.host; lastNetFilterHostname = parsedURL.host;
lastNetFilterUnion = toMergeURL; lastNetFilterUnion = toMergeURL;
vAPI.messaging.send( vAPI.messaging.send('elementPicker', {
'elementPicker',
{
what: 'elementPickerEprom', what: 'elementPickerEprom',
lastNetFilterSession: lastNetFilterSession, lastNetFilterSession: lastNetFilterSession,
lastNetFilterHostname: lastNetFilterHostname, lastNetFilterHostname: lastNetFilterHostname,
lastNetFilterUnion: lastNetFilterUnion lastNetFilterUnion: lastNetFilterUnion,
} });
);
return; return;
} }
@ -398,15 +395,12 @@ const netFilterFromUnion = function(toMergeURL, out) {
lastNetFilterUnion = mergedURL; lastNetFilterUnion = mergedURL;
// Remember across element picker sessions // Remember across element picker sessions
vAPI.messaging.send( vAPI.messaging.send('elementPicker', {
'elementPicker',
{
what: 'elementPickerEprom', what: 'elementPickerEprom',
lastNetFilterSession: lastNetFilterSession, lastNetFilterSession: lastNetFilterSession,
lastNetFilterHostname: lastNetFilterHostname, lastNetFilterHostname: lastNetFilterHostname,
lastNetFilterUnion: lastNetFilterUnion lastNetFilterUnion: lastNetFilterUnion,
} });
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -854,7 +848,7 @@ const filterToDOMInterface = (( ) => {
applied = false, applied = false,
previewing = false; previewing = false;
const queryAll = function(filter, callback) { const queryAll = async function(filter, callback) {
filter = filter.trim(); filter = filter.trim();
if ( filter === lastFilter ) { if ( filter === lastFilter ) {
callback(lastResultset); callback(lastResultset);
@ -883,15 +877,13 @@ const filterToDOMInterface = (( ) => {
return; return;
} }
// Procedural cosmetic filter // Procedural cosmetic filter
vAPI.messaging.send( const response = await vAPI.messaging.send('elementPicker', {
'elementPicker', what: 'compileCosmeticFilterSelector',
{ what: 'compileCosmeticFilterSelector', selector: selector }, selector,
response => { });
lastResultset = fromCompiledCosmeticFilter(response); lastResultset = fromCompiledCosmeticFilter(response);
if ( previewing ) { apply(); } if ( previewing ) { apply(); }
callback(lastResultset); callback(lastResultset);
}
);
}; };
// https://github.com/gorhill/uBlock/issues/1629 // https://github.com/gorhill/uBlock/issues/1629
@ -1190,17 +1182,14 @@ const onDialogClicked = function(ev) {
filterToDOMInterface.preview(false); filterToDOMInterface.preview(false);
userFilterFromCandidate((filter = undefined, isCosmetic = false) => { userFilterFromCandidate((filter = undefined, isCosmetic = false) => {
if ( filter === undefined ) { return; } if ( filter === undefined ) { return; }
vAPI.messaging.send( vAPI.messaging.send('elementPicker', {
'elementPicker',
{
what: 'createUserFilter', what: 'createUserFilter',
autoComment: true, autoComment: true,
filters: filter, filters: filter,
origin: window.location.origin, origin: window.location.origin,
pageDomain: window.location.hostname, pageDomain: window.location.hostname,
killCache: isCosmetic === false, killCache: isCosmetic === false,
} });
);
filterToDOMInterface.preview(rawFilterFromTextarea(), true); filterToDOMInterface.preview(rawFilterFromTextarea(), true);
stopPicker(); stopPicker();
}); });
@ -1697,14 +1686,12 @@ const startPicker = function(details) {
/******************************************************************************/ /******************************************************************************/
const bootstrapPicker = function() { const bootstrapPicker = async function() {
pickerRoot.removeEventListener('load', bootstrapPicker);
vAPI.shutdown.add(stopPicker); vAPI.shutdown.add(stopPicker);
vAPI.messaging.send( const details = await vAPI.messaging.send('elementPicker', {
'elementPicker', what: 'elementPickerArguments',
{ what: 'elementPickerArguments' }, });
startPicker startPicker(details);
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -1762,7 +1749,11 @@ vAPI.userStylesheet.apply();
// https://github.com/gorhill/uBlock/issues/2060 // https://github.com/gorhill/uBlock/issues/2060
vAPI.domFilterer.excludeNode(pickerRoot); vAPI.domFilterer.excludeNode(pickerRoot);
pickerRoot.addEventListener('load', bootstrapPicker); pickerRoot.addEventListener(
'load',
( ) => { bootstrapPicker(); },
{ once: true }
);
document.documentElement.appendChild(pickerRoot); document.documentElement.appendChild(pickerRoot);
/******************************************************************************/ /******************************************************************************/

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2015-2018 Raymond Hill Copyright (C) 2015-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -19,11 +19,11 @@
Home: https://github.com/gorhill/uBlock Home: https://github.com/gorhill/uBlock
*/ */
'use strict';
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
'use strict';
/******************************************************************************/ /******************************************************************************/
@ -34,19 +34,18 @@ if ( typeof vAPI !== 'object' || vAPI.loadLargeMediaInteractive === true ) {
/******************************************************************************/ /******************************************************************************/
var largeMediaElementAttribute = 'data-' + vAPI.sessionId; const largeMediaElementAttribute = 'data-' + vAPI.sessionId;
var largeMediaElementSelector = const largeMediaElementSelector =
':root audio[' + largeMediaElementAttribute + '],\n' + ':root audio[' + largeMediaElementAttribute + '],\n' +
':root img[' + largeMediaElementAttribute + '],\n' + ':root img[' + largeMediaElementAttribute + '],\n' +
':root video[' + largeMediaElementAttribute + ']'; ':root video[' + largeMediaElementAttribute + ']';
/******************************************************************************/ /******************************************************************************/
var mediaNotLoaded = function(elem) { const mediaNotLoaded = function(elem) {
var src = elem.getAttribute('src') || ''; const src = elem.getAttribute('src') || '';
if ( src === '' ) { if ( src === '' ) { return false; }
return false;
}
switch ( elem.localName ) { switch ( elem.localName ) {
case 'audio': case 'audio':
case 'video': case 'video':
@ -55,7 +54,7 @@ var mediaNotLoaded = function(elem) {
if ( elem.naturalWidth !== 0 || elem.naturalHeight !== 0 ) { if ( elem.naturalWidth !== 0 || elem.naturalHeight !== 0 ) {
break; break;
} }
var style = window.getComputedStyle(elem); const style = window.getComputedStyle(elem);
// For some reason, style can be null with Pale Moon. // For some reason, style can be null with Pale Moon.
return style !== null ? return style !== null ?
style.getPropertyValue('display') !== 'none' : style.getPropertyValue('display') !== 'none' :
@ -74,7 +73,7 @@ var mediaNotLoaded = function(elem) {
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
var surveyMissingMediaElements = function() { const surveyMissingMediaElements = function() {
var largeMediaElementCount = 0; var largeMediaElementCount = 0;
var elems = document.querySelectorAll('audio,img,video'); var elems = document.querySelectorAll('audio,img,video');
var i = elems.length, elem; var i = elems.length, elem;
@ -95,7 +94,7 @@ if ( surveyMissingMediaElements() === 0 ) {
vAPI.loadLargeMediaInteractive = true; vAPI.loadLargeMediaInteractive = true;
// Insert custom style tag. // Insert custom style tag.
var styleTag = document.createElement('style'); let styleTag = document.createElement('style');
styleTag.setAttribute('type', 'text/css'); styleTag.setAttribute('type', 'text/css');
styleTag.textContent = [ styleTag.textContent = [
largeMediaElementSelector + ' {', largeMediaElementSelector + ' {',
@ -114,10 +113,10 @@ document.head.appendChild(styleTag);
/******************************************************************************/ /******************************************************************************/
var stayOrLeave = (function() { const stayOrLeave = (( ) => {
var timer = null; let timer = null;
var timeoutHandler = function(leaveNow) { const timeoutHandler = function(leaveNow) {
timer = null; timer = null;
if ( leaveNow !== true ) { if ( leaveNow !== true ) {
if ( if (
@ -151,15 +150,26 @@ var stayOrLeave = (function() {
/******************************************************************************/ /******************************************************************************/
var onMouseClick = function(ev) { const loadImage = async function(elem) {
if ( ev.button !== 0 ) { const src = elem.getAttribute('src');
return; elem.removeAttribute('src');
}
var elem = ev.target; await vAPI.messaging.send('scriptlets', {
if ( elem.matches(largeMediaElementSelector) === false ) { what: 'temporarilyAllowLargeMediaElement',
return; });
}
elem.setAttribute('src', src);
elem.removeAttribute(largeMediaElementAttribute);
stayOrLeave();
};
/******************************************************************************/
const onMouseClick = function(ev) {
if ( ev.button !== 0 ) { return; }
const elem = ev.target;
if ( elem.matches(largeMediaElementSelector) === false ) { return; }
if ( mediaNotLoaded(elem) === false ) { if ( mediaNotLoaded(elem) === false ) {
elem.removeAttribute(largeMediaElementAttribute); elem.removeAttribute(largeMediaElementAttribute);
@ -167,20 +177,7 @@ var onMouseClick = function(ev) {
return; return;
} }
var src = elem.getAttribute('src'); loadImage(elem);
elem.removeAttribute('src');
var onLargeMediaElementAllowed = function() {
elem.setAttribute('src', src);
elem.removeAttribute(largeMediaElementAttribute);
stayOrLeave();
};
vAPI.messaging.send(
'scriptlets',
{ what: 'temporarilyAllowLargeMediaElement' },
onLargeMediaElementAllowed
);
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
@ -190,8 +187,8 @@ document.addEventListener('click', onMouseClick, true);
/******************************************************************************/ /******************************************************************************/
var onLoad = function(ev) { const onLoad = function(ev) {
var elem = ev.target; const elem = ev.target;
if ( elem.hasAttribute(largeMediaElementAttribute) ) { if ( elem.hasAttribute(largeMediaElementAttribute) ) {
elem.removeAttribute(largeMediaElementAttribute); elem.removeAttribute(largeMediaElementAttribute);
stayOrLeave(); stayOrLeave();
@ -202,8 +199,8 @@ document.addEventListener('load', onLoad, true);
/******************************************************************************/ /******************************************************************************/
var onLoadError = function(ev) { const onLoadError = function(ev) {
var elem = ev.target; const elem = ev.target;
if ( mediaNotLoaded(elem) ) { if ( mediaNotLoaded(elem) ) {
elem.setAttribute(largeMediaElementAttribute, ''); elem.setAttribute(largeMediaElementAttribute, '');
} }

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2015-2018 Raymond Hill Copyright (C) 2015-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
/******************************************************************************/ /******************************************************************************/
@ -48,61 +48,57 @@ if ( typeof vAPI !== 'object' ) {
/******************************************************************************/ /******************************************************************************/
var onMaybeAbpLinkClicked = function(ev) { const processSubscription = async function(location, title) {
if ( ev.button !== 0 ) { const details = await vAPI.messaging.send('scriptlets', {
return; what: 'subscriberData',
} });
const confirmStr = details.confirmStr
.replace('{{url}}', location)
.replace('{{title}}', title);
if ( window.confirm(confirmStr) === false ) { return; }
await vAPI.messaging.send('scriptlets', {
what: 'applyFilterListSelection',
toImport: location,
});
vAPI.messaging.send('scriptlets', {
what: 'reloadAllFilters',
});
};
/******************************************************************************/
const onMaybeAbpLinkClicked = function(ev) {
if ( ev.button !== 0 ) { return; }
// This addresses https://github.com/easylist/EasyListHebrew/issues/89 // This addresses https://github.com/easylist/EasyListHebrew/issues/89
// Also, as per feedback to original fix: // Also, as per feedback to original fix:
// https://github.com/gorhill/uBlock/commit/99a3d9631047d33dc7a454296ab3dd0a1e91d6f1 // https://github.com/gorhill/uBlock/commit/99a3d9631047d33dc7a454296ab3dd0a1e91d6f1
var target = ev.target; const target = ev.target;
if ( if (
ev.isTrusted === false || ev.isTrusted === false ||
target instanceof HTMLAnchorElement === false target instanceof HTMLAnchorElement === false
) { ) {
return; return;
} }
var href = target.href || '';
if ( href === '' ) { const href = target.href || '';
return; if ( href === '' ) { return; }
}
var matches = /^(?:abp|ubo):\/*subscribe\/*\?location=([^&]+).*title=([^&]+)/.exec(href); let matches = /^(?:abp|ubo):\/*subscribe\/*\?location=([^&]+).*title=([^&]+)/.exec(href);
if ( matches === null ) { if ( matches === null ) {
matches = /^https?:\/\/.*?[&?]location=([^&]+).*?&title=([^&]+)/.exec(href); matches = /^https?:\/\/.*?[&?]location=([^&]+).*?&title=([^&]+)/.exec(href);
if ( matches === null ) { return; } if ( matches === null ) { return; }
} }
var location = decodeURIComponent(matches[1]); const location = decodeURIComponent(matches[1]);
var title = decodeURIComponent(matches[2]); const title = decodeURIComponent(matches[2]);
var messaging = vAPI.messaging;
processSubscription(location, title);
ev.stopPropagation(); ev.stopPropagation();
ev.preventDefault(); ev.preventDefault();
var onListsSelectionDone = function() {
messaging.send('scriptlets', { what: 'reloadAllFilters' });
};
var onSubscriberDataReady = function(details) {
var confirmStr = details.confirmStr
.replace('{{url}}', location)
.replace('{{title}}', title);
if ( !window.confirm(confirmStr) ) { return; }
messaging.send(
'scriptlets',
{
what: 'applyFilterListSelection',
toImport: location
},
onListsSelectionDone
);
};
messaging.send(
'scriptlets',
{ what: 'subscriberData' },
onSubscriberDataReady
);
}; };
/******************************************************************************/ /******************************************************************************/

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill Copyright (C) 2014-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -29,10 +29,6 @@
/******************************************************************************/ /******************************************************************************/
const messaging = vAPI.messaging;
/******************************************************************************/
const handleImportFilePicker = function() { const handleImportFilePicker = function() {
const file = this.files[0]; const file = this.files[0];
if ( file === undefined || file.name === '' ) { return; } if ( file === undefined || file.name === '' ) { return; }
@ -74,16 +70,12 @@ const handleImportFilePicker = function() {
const msg = vAPI.i18n('aboutRestoreDataConfirm') const msg = vAPI.i18n('aboutRestoreDataConfirm')
.replace('{{time}}', time.toLocaleString()); .replace('{{time}}', time.toLocaleString());
const proceed = window.confirm(msg); const proceed = window.confirm(msg);
if ( proceed ) { if ( proceed !== true ) { return; }
messaging.send( vAPI.messaging.send('dashboard', {
'dashboard',
{
what: 'restoreUserData', what: 'restoreUserData',
userData: userData, userData,
file: filename file: filename,
} });
);
}
}; };
const fr = new FileReader(); const fr = new FileReader();
@ -104,8 +96,10 @@ const startImportFilePicker = function() {
/******************************************************************************/ /******************************************************************************/
const exportToFile = function() { const exportToFile = async function() {
messaging.send('dashboard', { what: 'backupUserData' }, response => { const response = await vAPI.messaging.send('dashboard', {
what: 'backupUserData',
});
if ( if (
response instanceof Object === false || response instanceof Object === false ||
response.userData instanceof Object === false response.userData instanceof Object === false
@ -118,7 +112,6 @@ const exportToFile = function() {
'filename': response.localData.lastBackupFile 'filename': response.localData.lastBackupFile
}); });
onLocalDataReceived(response.localData); onLocalDataReceived(response.localData);
});
}; };
/******************************************************************************/ /******************************************************************************/
@ -175,9 +168,10 @@ const onLocalDataReceived = function(details) {
const resetUserData = function() { const resetUserData = function() {
const msg = vAPI.i18n('aboutResetDataConfirm'); const msg = vAPI.i18n('aboutResetDataConfirm');
const proceed = window.confirm(msg); const proceed = window.confirm(msg);
if ( proceed ) { if ( proceed !== true ) { return; }
messaging.send('dashboard', { what: 'resetUserData' }); vAPI.messaging.send('dashboard', {
} what: 'resetUserData',
});
}; };
/******************************************************************************/ /******************************************************************************/
@ -192,14 +186,11 @@ const synchronizeDOM = function() {
/******************************************************************************/ /******************************************************************************/
const changeUserSettings = function(name, value) { const changeUserSettings = function(name, value) {
messaging.send( vAPI.messaging.send('dashboard', {
'dashboard',
{
what: 'userSettings', what: 'userSettings',
name: name, name,
value: value value,
} });
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -253,7 +244,7 @@ const onUserSettingsReceived = function(details) {
.on('click', onPreventDefault); .on('click', onPreventDefault);
}); });
uDom('#export').on('click', exportToFile); uDom('#export').on('click', ( ) => { exportToFile(); });
uDom('#import').on('click', startImportFilePicker); uDom('#import').on('click', startImportFilePicker);
uDom('#reset').on('click', resetUserData); uDom('#reset').on('click', resetUserData);
uDom('#restoreFilePicker').on('change', handleImportFilePicker); uDom('#restoreFilePicker').on('change', handleImportFilePicker);
@ -263,8 +254,13 @@ const onUserSettingsReceived = function(details) {
/******************************************************************************/ /******************************************************************************/
messaging.send('dashboard', { what: 'userSettings' }, onUserSettingsReceived); Promise.all([
messaging.send('dashboard', { what: 'getLocalData' }, onLocalDataReceived); vAPI.messaging.send('dashboard', { what: 'userSettings' }),
vAPI.messaging.send('dashboard', { what: 'getLocalData' }),
]).then(results => {
onUserSettingsReceived(results[0]);
onLocalDataReceived(results[1]);
});
// https://github.com/uBlockOrigin/uBlock-issues/issues/591 // https://github.com/uBlockOrigin/uBlock-issues/issues/591
document.querySelector( document.querySelector(

View File

@ -21,14 +21,14 @@
'use strict'; 'use strict';
(function() { (( ) => {
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/commands#Shortcut_values // https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/commands#Shortcut_values
let validStatus0Keys = new Map([ const validStatus0Keys = new Map([
[ 'alt', 'Alt' ], [ 'alt', 'Alt' ],
[ 'control', 'Ctrl' ], [ 'control', 'Ctrl' ],
]); ]);
let validStatus1Keys = new Map([ const validStatus1Keys = new Map([
[ 'a', 'A' ], [ 'a', 'A' ],
[ 'b', 'B' ], [ 'b', 'B' ],
[ 'c', 'C' ], [ 'c', 'C' ],
@ -93,42 +93,43 @@
[ 'shift', 'Shift' ], [ 'shift', 'Shift' ],
]); ]);
let commandNameFromElement = function(elem) { const commandNameFromElement = function(elem) {
while ( elem !== null ) { while ( elem !== null ) {
let name = elem.getAttribute('data-name'); const name = elem.getAttribute('data-name');
if ( typeof name === 'string' && name !== '' ) { return name; } if ( typeof name === 'string' && name !== '' ) { return name; }
elem = elem.parentElement; elem = elem.parentElement;
} }
}; };
let captureShortcut = function(ev) { const captureShortcut = function(ev) {
let input = ev.target; const input = ev.target;
let name = commandNameFromElement(input); const name = commandNameFromElement(input);
if ( name === undefined ) { return; } if ( name === undefined ) { return; }
let before = input.value; const before = input.value;
let after = new Set(); const after = new Set();
let status = 0; let status = 0;
let updateCapturedShortcut = function() { const updateCapturedShortcut = function() {
return (input.value = Array.from(after).join('+')); return (input.value = Array.from(after).join('+'));
}; };
let blurHandler = function() { const blurHandler = function() {
input.removeEventListener('blur', blurHandler, true); input.removeEventListener('blur', blurHandler, true);
input.removeEventListener('keydown', keydownHandler, true); input.removeEventListener('keydown', keydownHandler, true);
input.removeEventListener('keyup', keyupHandler, true); input.removeEventListener('keyup', keyupHandler, true);
if ( status === 2 ) { if ( status === 2 ) {
vAPI.messaging.send( vAPI.messaging.send('dashboard', {
'dashboard', what: 'setShortcut',
{ what: 'setShortcut', name: name, shortcut: updateCapturedShortcut() } name,
); shortcut: updateCapturedShortcut(),
});
} else { } else {
input.value = before; input.value = before;
} }
}; };
let keydownHandler = function(ev) { const keydownHandler = function(ev) {
ev.preventDefault(); ev.preventDefault();
ev.stopImmediatePropagation(); ev.stopImmediatePropagation();
if ( ev.code === 'Escape' ) { if ( ev.code === 'Escape' ) {
@ -136,7 +137,7 @@
return; return;
} }
if ( status === 0 ) { if ( status === 0 ) {
let keyName = validStatus0Keys.get(ev.key.toLowerCase()); const keyName = validStatus0Keys.get(ev.key.toLowerCase());
if ( keyName !== undefined ) { if ( keyName !== undefined ) {
after.add(keyName); after.add(keyName);
updateCapturedShortcut(); updateCapturedShortcut();
@ -161,11 +162,11 @@
} }
}; };
let keyupHandler = function(ev) { const keyupHandler = function(ev) {
ev.preventDefault(); ev.preventDefault();
ev.stopImmediatePropagation(); ev.stopImmediatePropagation();
if ( status !== 1 ) { return; } if ( status !== 1 ) { return; }
let keyName = validStatus0Keys.get(ev.key.toLowerCase()); const keyName = validStatus0Keys.get(ev.key.toLowerCase());
if ( keyName !== undefined && after.has(keyName) ) { if ( keyName !== undefined && after.has(keyName) ) {
after.clear(); after.clear();
updateCapturedShortcut(); updateCapturedShortcut();
@ -185,29 +186,29 @@
input.addEventListener('keyup', keyupHandler, true); input.addEventListener('keyup', keyupHandler, true);
}; };
let resetShortcut = function(ev) { const resetShortcut = function(ev) {
let name = commandNameFromElement(ev.target); const name = commandNameFromElement(ev.target);
if ( name === undefined ) { return; } if ( name === undefined ) { return; }
let input = document.querySelector('[data-name="' + name + '"] input'); const input = document.querySelector('[data-name="' + name + '"] input');
if ( input === null ) { return; } if ( input === null ) { return; }
input.value = ''; input.value = '';
vAPI.messaging.send( vAPI.messaging.send('dashboard', {
'dashboard', what: 'setShortcut',
{ what: 'setShortcut', name: name } name,
); });
}; };
let onShortcutsReady = function(commands) { const onShortcutsReady = function(commands) {
if ( Array.isArray(commands) === false ) { return; } if ( Array.isArray(commands) === false ) { return; }
let template = document.querySelector('#templates .commandEntry'); const template = document.querySelector('#templates .commandEntry');
let tbody = document.querySelector('.commandEntries tbody'); const tbody = document.querySelector('.commandEntries tbody');
for ( let command of commands ) { for ( const command of commands ) {
if ( command.description === '' ) { continue; } if ( command.description === '' ) { continue; }
let tr = template.cloneNode(true); const tr = template.cloneNode(true);
tr.setAttribute('data-name', command.name); tr.setAttribute('data-name', command.name);
tr.querySelector('.commandDesc').textContent = command.description; tr.querySelector('.commandDesc').textContent = command.description;
let input = tr.querySelector('.commandShortcut input'); const input = tr.querySelector('.commandShortcut input');
input.setAttribute('data-name', command.name); input.setAttribute('data-name', command.name);
input.value = command.shortcut; input.value = command.shortcut;
input.addEventListener('focus', captureShortcut); input.addEventListener('focus', captureShortcut);
@ -216,6 +217,9 @@
} }
}; };
vAPI.messaging.send('dashboard', { what: 'getShortcuts' }, onShortcutsReady); vAPI.messaging.send('dashboard', {
what: 'getShortcuts',
}).then(commands => {
onShortcutsReady(commands);
});
})(); })();

View File

@ -114,8 +114,11 @@ cmEditor.on('changes', whitelistChanged);
/******************************************************************************/ /******************************************************************************/
const renderWhitelist = function() { const renderWhitelist = async function() {
const onRead = details => { const details = await messaging.send('dashboard', {
what: 'getWhitelist',
});
const first = reBadHostname === undefined; const first = reBadHostname === undefined;
if ( first ) { if ( first ) {
reBadHostname = new RegExp(details.reBadHostname); reBadHostname = new RegExp(details.reBadHostname);
@ -151,8 +154,6 @@ const renderWhitelist = function() {
cmEditor.clearHistory(); cmEditor.clearHistory();
} }
}; };
messaging.send('dashboard', { what: 'getWhitelist' }, onRead);
};
/******************************************************************************/ /******************************************************************************/
@ -201,16 +202,13 @@ const exportWhitelistToFile = function() {
/******************************************************************************/ /******************************************************************************/
const applyChanges = function() { const applyChanges = async function() {
cachedWhitelist = cmEditor.getValue().trim(); cachedWhitelist = cmEditor.getValue().trim();
messaging.send( await messaging.send('dashboard', {
'dashboard',
{
what: 'setWhitelist', what: 'setWhitelist',
whitelist: cachedWhitelist whitelist: cachedWhitelist,
}, });
renderWhitelist renderWhitelist();
);
}; };
const revertChanges = function() { const revertChanges = function() {
@ -247,7 +245,7 @@ self.hasUnsavedData = function() {
uDom('#importWhitelistFromFile').on('click', startImportFilePicker); uDom('#importWhitelistFromFile').on('click', startImportFilePicker);
uDom('#importFilePicker').on('change', handleImportFilePicker); uDom('#importFilePicker').on('change', handleImportFilePicker);
uDom('#exportWhitelistToFile').on('click', exportWhitelistToFile); uDom('#exportWhitelistToFile').on('click', exportWhitelistToFile);
uDom('#whitelistApply').on('click', applyChanges); uDom('#whitelistApply').on('click', ( ) => { applyChanges(); });
uDom('#whitelistRevert').on('click', revertChanges); uDom('#whitelistRevert').on('click', revertChanges);
renderWhitelist(); renderWhitelist();