2014-06-24 00:42:43 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
|
2016-03-07 15:55:04 +01:00
|
|
|
uBlock Origin - a browser extension to block requests.
|
2018-07-19 00:00:55 +02:00
|
|
|
Copyright (C) 2014-present Raymond Hill
|
2014-06-24 00:42:43 +02:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
|
|
|
|
|
|
Home: https://github.com/gorhill/uBlock
|
|
|
|
*/
|
|
|
|
|
2014-10-17 21:44:19 +02:00
|
|
|
/******************************************************************************/
|
2014-11-16 14:09:28 +01:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2016-08-06 18:05:01 +02:00
|
|
|
'use strict';
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/710
|
|
|
|
// Listeners have a name and a "privileged" status.
|
|
|
|
// The nameless default handler is always deemed "privileged".
|
|
|
|
// Messages from privileged ports must never relayed to listeners
|
|
|
|
// which are not privileged.
|
2014-11-16 15:49:55 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
/******************************************************************************/
|
2014-11-16 15:49:55 +01:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Default handler
|
|
|
|
// priviledged
|
2015-06-07 00:31:38 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
|
|
|
|
|
|
|
const µb = µBlock;
|
2015-06-07 00:31:38 +02:00
|
|
|
|
2019-05-18 20:20:05 +02:00
|
|
|
const getDomainNames = function(targets) {
|
|
|
|
const µburi = µb.URI;
|
2019-05-19 23:00:49 +02:00
|
|
|
return targets.map(target => {
|
|
|
|
if ( typeof target !== 'string' ) { return ''; }
|
|
|
|
return target.indexOf('/') !== -1
|
2019-05-18 20:20:05 +02:00
|
|
|
? µburi.domainFromURI(target) || ''
|
2019-05-19 23:00:49 +02:00
|
|
|
: µburi.domainFromHostname(target) || target;
|
|
|
|
});
|
2015-06-07 00:31:38 +02:00
|
|
|
};
|
|
|
|
|
2019-01-08 13:37:50 +01:00
|
|
|
const onMessage = function(request, sender, callback) {
|
2014-11-16 15:49:55 +01:00
|
|
|
// Async
|
2014-10-17 21:44:19 +02:00
|
|
|
switch ( request.what ) {
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'getAssetContent':
|
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/417
|
2019-05-24 01:29:59 +02:00
|
|
|
µb.assets.get(
|
|
|
|
request.url,
|
2019-09-15 13:58:28 +02:00
|
|
|
{ dontCache: true, needSourceURL: true }
|
|
|
|
).then(result => {
|
|
|
|
callback(result);
|
|
|
|
});
|
2015-04-25 13:28:35 +02:00
|
|
|
return;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-06-13 17:21:55 +02:00
|
|
|
case 'listsFromNetFilter':
|
|
|
|
µb.staticFilteringReverseLookup.fromNetFilter(
|
|
|
|
request.compiledFilter,
|
|
|
|
request.rawFilter,
|
|
|
|
callback
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'listsFromCosmeticFilter':
|
2018-07-22 16:47:02 +02:00
|
|
|
µb.staticFilteringReverseLookup.fromCosmeticFilter(request, callback);
|
2015-06-11 18:12:23 +02:00
|
|
|
return;
|
|
|
|
|
2015-06-26 06:08:41 +02:00
|
|
|
case 'reloadAllFilters':
|
2019-09-18 14:34:55 +02:00
|
|
|
µb.loadFilterLists().then(( ) => { callback(); });
|
2015-06-26 06:08:41 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
case 'scriptlet':
|
|
|
|
µb.scriptlets.inject(request.tabId, request.scriptlet, callback);
|
|
|
|
return;
|
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
default:
|
|
|
|
break;
|
2014-11-16 15:49:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
|
|
|
var response;
|
|
|
|
|
|
|
|
switch ( request.what ) {
|
2017-01-22 22:05:16 +01:00
|
|
|
case 'applyFilterListSelection':
|
|
|
|
response = µb.applyFilterListSelection(request);
|
2015-04-25 13:28:35 +02:00
|
|
|
break;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-06-07 00:31:38 +02:00
|
|
|
case 'createUserFilter':
|
2019-09-01 18:43:12 +02:00
|
|
|
µb.createUserFilters(request);
|
2015-06-07 00:31:38 +02:00
|
|
|
break;
|
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'forceUpdateAssets':
|
2017-01-18 19:17:47 +01:00
|
|
|
µb.scheduleAssetUpdater(0);
|
2017-12-30 23:38:07 +01:00
|
|
|
µb.assets.updateStart({
|
|
|
|
delay: µb.hiddenSettings.manualUpdateAssetFetchPeriod
|
|
|
|
});
|
2015-04-25 13:28:35 +02:00
|
|
|
break;
|
2014-12-01 17:25:33 +01:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'getAppData':
|
2018-05-17 18:45:57 +02:00
|
|
|
response = {
|
2019-09-21 18:06:57 +02:00
|
|
|
name: browser.runtime.getManifest().name,
|
2018-05-17 18:45:57 +02:00
|
|
|
version: vAPI.app.version
|
|
|
|
};
|
2015-04-25 13:28:35 +02:00
|
|
|
break;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-06-07 00:31:38 +02:00
|
|
|
case 'getDomainNames':
|
|
|
|
response = getDomainNames(request.targets);
|
|
|
|
break;
|
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'getWhitelist':
|
2018-03-12 13:28:07 +01:00
|
|
|
response = {
|
2019-05-18 20:20:05 +02:00
|
|
|
whitelist: µb.arrayFromWhitelist(µb.netWhitelist),
|
|
|
|
whitelistDefault: µb.netWhitelistDefault,
|
2018-03-12 13:28:07 +01:00
|
|
|
reBadHostname: µb.reWhitelistBadHostname.source,
|
|
|
|
reHostnameExtractor: µb.reWhitelistHostnameExtractor.source
|
|
|
|
};
|
2016-03-06 16:51:06 +01:00
|
|
|
break;
|
|
|
|
|
2015-05-25 00:50:09 +02:00
|
|
|
case 'launchElementPicker':
|
|
|
|
// Launched from some auxiliary pages, clear context menu coords.
|
2019-09-18 18:17:45 +02:00
|
|
|
µb.epickerArgs.mouse = false;
|
2017-05-27 17:51:24 +02:00
|
|
|
µb.elementPickerExec(request.tabId, request.targetURL, request.zap);
|
2015-05-25 00:50:09 +02:00
|
|
|
break;
|
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'gotoURL':
|
2016-09-16 23:41:17 +02:00
|
|
|
µb.openNewTab(request.details);
|
2015-04-25 13:28:35 +02:00
|
|
|
break;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'reloadTab':
|
|
|
|
if ( vAPI.isBehindTheSceneTabId(request.tabId) === false ) {
|
2018-01-07 23:53:33 +01:00
|
|
|
vAPI.tabs.reload(request.tabId, request.bypassCache === true);
|
2015-04-25 13:28:35 +02:00
|
|
|
if ( request.select && vAPI.tabs.select ) {
|
|
|
|
vAPI.tabs.select(request.tabId);
|
2015-01-20 00:42:58 +01:00
|
|
|
}
|
2015-04-25 13:28:35 +02:00
|
|
|
}
|
|
|
|
break;
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'setWhitelist':
|
|
|
|
µb.netWhitelist = µb.whitelistFromString(request.whitelist);
|
|
|
|
µb.saveWhitelist();
|
|
|
|
break;
|
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'toggleHostnameSwitch':
|
|
|
|
µb.toggleHostnameSwitch(request);
|
|
|
|
break;
|
2015-03-27 18:00:55 +01:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'userSettings':
|
|
|
|
response = µb.changeUserSettings(request.name, request.value);
|
|
|
|
break;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2014-10-17 21:44:19 +02:00
|
|
|
}
|
2014-11-16 15:49:55 +01:00
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
|
|
|
vAPI.messaging.setup(onMessage);
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2014-09-14 22:20:40 +02:00
|
|
|
/******************************************************************************/
|
2014-06-24 00:42:43 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// popupPanel
|
|
|
|
// privileged
|
2014-09-28 18:05:46 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const µb = µBlock;
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const getHostnameDict = function(hostnameToCountMap) {
|
|
|
|
const r = Object.create(null);
|
|
|
|
const domainFromHostname = µb.URI.domainFromHostname;
|
2017-05-19 16:12:55 +02:00
|
|
|
// Note: destructuring assignment not supported before Chromium 49.
|
2019-09-01 18:43:12 +02:00
|
|
|
for ( const [ hostname, hnCounts ] of hostnameToCountMap ) {
|
2017-05-19 16:12:55 +02:00
|
|
|
if ( r[hostname] !== undefined ) { continue; }
|
2019-09-01 18:43:12 +02:00
|
|
|
const domain = domainFromHostname(hostname) || hostname;
|
|
|
|
const dnCounts = hostnameToCountMap.get(domain) || 0;
|
|
|
|
let blockCount = dnCounts & 0xFFFF;
|
|
|
|
let allowCount = dnCounts >>> 16 & 0xFFFF;
|
2016-10-08 16:15:31 +02:00
|
|
|
if ( r[domain] === undefined ) {
|
2019-09-01 18:43:12 +02:00
|
|
|
r[domain] = {
|
2015-02-17 03:15:09 +01:00
|
|
|
domain: domain,
|
|
|
|
blockCount: blockCount,
|
|
|
|
allowCount: allowCount,
|
2016-02-22 21:54:07 +01:00
|
|
|
totalBlockCount: blockCount,
|
|
|
|
totalAllowCount: allowCount
|
2015-02-17 03:15:09 +01:00
|
|
|
};
|
|
|
|
}
|
2019-09-01 18:43:12 +02:00
|
|
|
const domainEntry = r[domain];
|
|
|
|
blockCount = hnCounts & 0xFFFF;
|
|
|
|
allowCount = hnCounts >>> 16 & 0xFFFF;
|
2016-10-08 16:15:31 +02:00
|
|
|
domainEntry.totalBlockCount += blockCount;
|
|
|
|
domainEntry.totalAllowCount += allowCount;
|
2017-05-19 16:12:55 +02:00
|
|
|
if ( hostname === domain ) { continue; }
|
2014-12-30 22:36:29 +01:00
|
|
|
r[hostname] = {
|
|
|
|
domain: domain,
|
2015-02-17 03:15:09 +01:00
|
|
|
blockCount: blockCount,
|
2015-08-18 17:44:24 +02:00
|
|
|
allowCount: allowCount,
|
|
|
|
totalBlockCount: 0,
|
|
|
|
totalAllowCount: 0
|
2014-12-30 22:36:29 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const getFirewallRules = function(srcHostname, desHostnames) {
|
2014-12-28 16:07:43 +01:00
|
|
|
var r = {};
|
2015-05-21 20:15:17 +02:00
|
|
|
var df = µb.sessionFirewall;
|
2017-05-12 16:35:11 +02:00
|
|
|
r['/ * *'] = df.lookupRuleData('*', '*', '*');
|
|
|
|
r['/ * image'] = df.lookupRuleData('*', '*', 'image');
|
|
|
|
r['/ * 3p'] = df.lookupRuleData('*', '*', '3p');
|
|
|
|
r['/ * inline-script'] = df.lookupRuleData('*', '*', 'inline-script');
|
|
|
|
r['/ * 1p-script'] = df.lookupRuleData('*', '*', '1p-script');
|
|
|
|
r['/ * 3p-script'] = df.lookupRuleData('*', '*', '3p-script');
|
|
|
|
r['/ * 3p-frame'] = df.lookupRuleData('*', '*', '3p-frame');
|
2019-09-01 18:43:12 +02:00
|
|
|
if ( typeof srcHostname !== 'string' ) { return r; }
|
2014-12-30 22:36:29 +01:00
|
|
|
|
2017-05-12 16:35:11 +02:00
|
|
|
r['. * *'] = df.lookupRuleData(srcHostname, '*', '*');
|
|
|
|
r['. * image'] = df.lookupRuleData(srcHostname, '*', 'image');
|
|
|
|
r['. * 3p'] = df.lookupRuleData(srcHostname, '*', '3p');
|
2019-09-01 18:43:12 +02:00
|
|
|
r['. * inline-script'] = df.lookupRuleData(srcHostname,
|
|
|
|
'*',
|
|
|
|
'inline-script'
|
|
|
|
);
|
2017-05-12 16:35:11 +02:00
|
|
|
r['. * 1p-script'] = df.lookupRuleData(srcHostname, '*', '1p-script');
|
|
|
|
r['. * 3p-script'] = df.lookupRuleData(srcHostname, '*', '3p-script');
|
|
|
|
r['. * 3p-frame'] = df.lookupRuleData(srcHostname, '*', '3p-frame');
|
2014-12-30 22:36:29 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
for ( const desHostname in desHostnames ) {
|
|
|
|
r[`/ ${desHostname} *`] = df.lookupRuleData(
|
|
|
|
'*',
|
|
|
|
desHostname,
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
r[`. ${desHostname} *`] = df.lookupRuleData(
|
|
|
|
srcHostname,
|
|
|
|
desHostname,
|
|
|
|
'*'
|
|
|
|
);
|
2014-12-30 22:36:29 +01:00
|
|
|
}
|
2014-12-28 16:07:43 +01:00
|
|
|
return r;
|
2014-10-06 20:02:44 +02:00
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const popupDataFromTabId = function(tabId, tabTitle) {
|
|
|
|
const tabContext = µb.tabContextManager.mustLookup(tabId);
|
|
|
|
const rootHostname = tabContext.rootHostname;
|
|
|
|
const r = {
|
2015-01-06 17:44:06 +01:00
|
|
|
advancedUserEnabled: µb.userSettings.advancedUserEnabled,
|
2014-12-01 17:25:33 +01:00
|
|
|
appName: vAPI.app.name,
|
|
|
|
appVersion: vAPI.app.version,
|
2015-04-22 16:46:10 +02:00
|
|
|
colorBlindFriendly: µb.userSettings.colorBlindFriendly,
|
2015-01-06 17:44:06 +01:00
|
|
|
cosmeticFilteringSwitch: false,
|
|
|
|
dfEnabled: µb.userSettings.dynamicFilteringEnabled,
|
2015-02-17 03:15:09 +01:00
|
|
|
firewallPaneMinimized: µb.userSettings.firewallPaneMinimized,
|
2014-06-24 00:42:43 +02:00
|
|
|
globalAllowedRequestCount: µb.localSettings.allowedRequestCount,
|
2015-01-06 17:44:06 +01:00
|
|
|
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
2016-11-06 22:27:21 +01:00
|
|
|
fontSize: µb.hiddenSettings.popupFontSize,
|
2015-01-06 17:44:06 +01:00
|
|
|
netFilteringSwitch: false,
|
2015-04-09 00:46:08 +02:00
|
|
|
rawURL: tabContext.rawURL,
|
|
|
|
pageURL: tabContext.normalURL,
|
2016-01-17 19:30:43 +01:00
|
|
|
pageHostname: rootHostname,
|
2015-04-09 00:46:08 +02:00
|
|
|
pageDomain: tabContext.rootDomain,
|
2014-06-24 00:42:43 +02:00
|
|
|
pageAllowedRequestCount: 0,
|
2015-01-06 17:44:06 +01:00
|
|
|
pageBlockedRequestCount: 0,
|
2016-01-04 16:48:28 +01:00
|
|
|
popupBlockedCount: 0,
|
2015-03-02 19:49:34 +01:00
|
|
|
tabId: tabId,
|
2015-12-13 06:33:53 +01:00
|
|
|
tabTitle: tabTitle,
|
|
|
|
tooltipsDisabled: µb.userSettings.tooltipsDisabled
|
2014-06-24 00:42:43 +02:00
|
|
|
};
|
2015-04-09 00:46:08 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const pageStore = µb.pageStoreFromTabId(tabId);
|
2014-06-24 00:42:43 +02:00
|
|
|
if ( pageStore ) {
|
2016-10-29 17:15:04 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/2105
|
2019-09-01 18:43:12 +02:00
|
|
|
// Be sure to always include the current page's hostname -- it
|
|
|
|
// might not be present when the page itself is pulled from the
|
|
|
|
// browser's short-term memory cache. This needs to be done
|
|
|
|
// before calling getHostnameDict().
|
2016-10-29 17:15:04 +02:00
|
|
|
if (
|
|
|
|
pageStore.hostnameToCountMap.has(rootHostname) === false &&
|
|
|
|
µb.URI.isNetworkURI(tabContext.rawURL)
|
|
|
|
) {
|
|
|
|
pageStore.hostnameToCountMap.set(rootHostname, 0);
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
r.pageBlockedRequestCount = pageStore.perLoadBlockedRequestCount;
|
|
|
|
r.pageAllowedRequestCount = pageStore.perLoadAllowedRequestCount;
|
2014-08-02 17:40:27 +02:00
|
|
|
r.netFilteringSwitch = pageStore.getNetFilteringSwitch();
|
2014-12-30 22:36:29 +01:00
|
|
|
r.hostnameDict = getHostnameDict(pageStore.hostnameToCountMap);
|
2015-01-10 17:23:28 +01:00
|
|
|
r.contentLastModified = pageStore.contentLastModified;
|
2016-01-17 19:30:43 +01:00
|
|
|
r.firewallRules = getFirewallRules(rootHostname, r.hostnameDict);
|
2018-09-07 16:52:10 +02:00
|
|
|
r.canElementPicker = µb.URI.isNetworkURI(r.rawURL);
|
2019-09-01 18:43:12 +02:00
|
|
|
r.noPopups = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-popups',
|
|
|
|
rootHostname
|
|
|
|
);
|
2016-01-04 16:48:28 +01:00
|
|
|
r.popupBlockedCount = pageStore.popupBlockedCount;
|
2019-09-01 18:43:12 +02:00
|
|
|
r.noCosmeticFiltering = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-cosmetic-filtering',
|
|
|
|
rootHostname
|
|
|
|
);
|
|
|
|
r.noLargeMedia = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-large-media',
|
|
|
|
rootHostname
|
|
|
|
);
|
2016-01-17 19:30:43 +01:00
|
|
|
r.largeMediaCount = pageStore.largeMediaCount;
|
2019-09-01 18:43:12 +02:00
|
|
|
r.noRemoteFonts = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-remote-fonts',
|
|
|
|
rootHostname
|
|
|
|
);
|
2016-01-17 19:30:43 +01:00
|
|
|
r.remoteFontCount = pageStore.remoteFontCount;
|
2019-09-01 18:43:12 +02:00
|
|
|
r.noScripting = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-scripting',
|
|
|
|
rootHostname
|
|
|
|
);
|
2014-12-30 22:36:29 +01:00
|
|
|
} else {
|
|
|
|
r.hostnameDict = {};
|
2015-02-11 06:26:45 +01:00
|
|
|
r.firewallRules = getFirewallRules();
|
|
|
|
}
|
2018-09-03 20:06:49 +02:00
|
|
|
|
|
|
|
r.matrixIsDirty = µb.sessionFirewall.hasSameRules(
|
2015-04-09 00:46:08 +02:00
|
|
|
µb.permanentFirewall,
|
2016-01-17 19:30:43 +01:00
|
|
|
rootHostname,
|
2015-04-09 00:46:08 +02:00
|
|
|
r.hostnameDict
|
2018-09-03 20:06:49 +02:00
|
|
|
) === false;
|
|
|
|
if ( r.matrixIsDirty === false ) {
|
|
|
|
r.matrixIsDirty = µb.sessionSwitches.hasSameRules(
|
|
|
|
µb.permanentSwitches,
|
|
|
|
rootHostname
|
|
|
|
) === false;
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
return r;
|
|
|
|
};
|
|
|
|
|
2019-09-16 15:45:17 +02:00
|
|
|
const popupDataFromRequest = async function(request) {
|
2015-05-18 16:39:20 +02:00
|
|
|
if ( request.tabId ) {
|
2019-09-16 15:45:17 +02:00
|
|
|
return popupDataFromTabId(request.tabId, '');
|
2015-01-20 00:42:58 +01:00
|
|
|
}
|
2015-01-21 17:13:32 +01:00
|
|
|
|
2015-05-18 16:39:20 +02:00
|
|
|
// Still no target tab id? Use currently selected tab.
|
2019-09-16 15:45:17 +02:00
|
|
|
const tab = await vAPI.tabs.getCurrent();
|
|
|
|
let tabId = '';
|
|
|
|
let tabTitle = '';
|
|
|
|
if ( tab instanceof Object ) {
|
|
|
|
tabId = tab.id;
|
|
|
|
tabTitle = tab.title || '';
|
|
|
|
}
|
|
|
|
return popupDataFromTabId(tabId, tabTitle);
|
2015-01-20 00:42:58 +01:00
|
|
|
};
|
|
|
|
|
2019-09-17 21:15:01 +02:00
|
|
|
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 };
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const onMessage = function(request, sender, callback) {
|
|
|
|
let pageStore;
|
2016-08-06 18:05:01 +02:00
|
|
|
|
2014-06-24 00:42:43 +02:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
2019-09-17 21:15:01 +02:00
|
|
|
case 'getPopupLazyData':
|
|
|
|
getDOMStats(request.tabId).then(results => {
|
|
|
|
callback(results);
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
|
2015-04-24 14:36:19 +02:00
|
|
|
case 'getPopupData':
|
2019-09-16 15:45:17 +02:00
|
|
|
popupDataFromRequest(request).then(popupData => {
|
|
|
|
callback(popupData);
|
|
|
|
});
|
2015-04-24 14:36:19 +02:00
|
|
|
return;
|
2014-10-17 21:44:19 +02:00
|
|
|
|
2015-04-24 14:36:19 +02:00
|
|
|
default:
|
|
|
|
break;
|
2014-06-24 00:42:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
2019-09-01 18:43:12 +02:00
|
|
|
let response;
|
2014-06-24 00:42:43 +02:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2015-04-24 14:36:19 +02:00
|
|
|
case 'hasPopupContentChanged':
|
|
|
|
pageStore = µb.pageStoreFromTabId(request.tabId);
|
|
|
|
var lastModified = pageStore ? pageStore.contentLastModified : 0;
|
|
|
|
response = lastModified !== request.contentLastModified;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'revertFirewallRules':
|
|
|
|
µb.sessionFirewall.copyRules(
|
|
|
|
µb.permanentFirewall,
|
|
|
|
request.srcHostname,
|
|
|
|
request.desHostnames
|
|
|
|
);
|
2018-09-03 20:06:49 +02:00
|
|
|
µb.sessionSwitches.copyRules(
|
|
|
|
µb.permanentSwitches,
|
|
|
|
request.srcHostname
|
|
|
|
);
|
2015-05-09 14:25:05 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/188
|
2018-09-03 20:06:49 +02:00
|
|
|
µb.cosmeticFilteringEngine.removeFromSelectorCache(
|
|
|
|
request.srcHostname,
|
|
|
|
'net'
|
|
|
|
);
|
2019-08-10 16:57:24 +02:00
|
|
|
µb.updateToolbarIcon(request.tabId, 0b100);
|
2015-05-18 16:39:20 +02:00
|
|
|
response = popupDataFromTabId(request.tabId);
|
2015-04-24 14:36:19 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'saveFirewallRules':
|
2018-09-03 20:06:49 +02:00
|
|
|
if (
|
|
|
|
µb.permanentFirewall.copyRules(
|
|
|
|
µb.sessionFirewall,
|
|
|
|
request.srcHostname,
|
|
|
|
request.desHostnames
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
µb.savePermanentFirewallRules();
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
µb.permanentSwitches.copyRules(
|
|
|
|
µb.sessionSwitches,
|
|
|
|
request.srcHostname
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
µb.saveHostnameSwitches();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'toggleHostnameSwitch':
|
|
|
|
µb.toggleHostnameSwitch(request);
|
|
|
|
response = popupDataFromTabId(request.tabId);
|
2015-04-24 14:36:19 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'toggleFirewallRule':
|
|
|
|
µb.toggleFirewallRule(request);
|
2015-05-18 16:39:20 +02:00
|
|
|
response = popupDataFromTabId(request.tabId);
|
2015-04-24 14:36:19 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'toggleNetFiltering':
|
|
|
|
pageStore = µb.pageStoreFromTabId(request.tabId);
|
|
|
|
if ( pageStore ) {
|
2019-09-01 18:43:12 +02:00
|
|
|
pageStore.toggleNetFilteringSwitch(
|
|
|
|
request.url,
|
|
|
|
request.scope,
|
|
|
|
request.state
|
|
|
|
);
|
2019-08-10 16:57:24 +02:00
|
|
|
µb.updateToolbarIcon(request.tabId, 0b111);
|
2015-04-24 14:36:19 +02:00
|
|
|
}
|
|
|
|
break;
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2015-04-24 14:36:19 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2014-06-24 00:42:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'popupPanel',
|
|
|
|
listener: onMessage,
|
|
|
|
privileged: true,
|
|
|
|
});
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2014-09-14 22:20:40 +02:00
|
|
|
/******************************************************************************/
|
2014-06-24 00:42:43 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// contentscript
|
|
|
|
// unprivileged
|
2014-06-27 23:06:42 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2014-06-27 23:06:42 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const µb = µBlock;
|
2014-09-28 18:05:46 +02:00
|
|
|
|
2019-09-21 17:30:38 +02:00
|
|
|
const retrieveContentScriptParameters = function(senderDetails, request) {
|
|
|
|
const { url, tabId, frameId } = senderDetails;
|
|
|
|
if ( url === undefined || tabId === undefined || frameId === undefined ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( request.url !== url ) { return; }
|
|
|
|
const pageStore = µb.pageStoreFromTabId(tabId);
|
|
|
|
if ( pageStore === null || pageStore.getNetFilteringSwitch() === false ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const noCosmeticFiltering = pageStore.noCosmeticFiltering === true;
|
|
|
|
|
|
|
|
const response = {
|
|
|
|
collapseBlocked: µb.userSettings.collapseBlocked,
|
|
|
|
noCosmeticFiltering,
|
|
|
|
noGenericCosmeticFiltering: noCosmeticFiltering,
|
|
|
|
noSpecificCosmeticFiltering: noCosmeticFiltering,
|
|
|
|
};
|
|
|
|
|
|
|
|
// https://github.com/uBlockOrigin/uAssets/issues/5704
|
|
|
|
// `generichide` must be evaluated in the frame context.
|
|
|
|
if ( noCosmeticFiltering === false ) {
|
|
|
|
const genericHide =
|
|
|
|
µb.staticNetFilteringEngine.matchStringElementHide(
|
|
|
|
'generic',
|
|
|
|
request.url
|
|
|
|
);
|
|
|
|
response.noGenericCosmeticFiltering = genericHide === 2;
|
|
|
|
if ( genericHide !== 0 && µb.logger.enabled ) {
|
|
|
|
µBlock.filteringContext
|
|
|
|
.duplicate()
|
|
|
|
.fromTabId(tabId)
|
|
|
|
.setURL(request.url)
|
|
|
|
.setRealm('network')
|
|
|
|
.setType('generichide')
|
|
|
|
.setFilter(µb.staticNetFilteringEngine.toLogData())
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
request.tabId = tabId;
|
|
|
|
request.frameId = frameId;
|
|
|
|
request.hostname = µb.URI.hostnameFromURI(request.url);
|
|
|
|
request.domain = µb.URI.domainFromHostname(request.hostname);
|
|
|
|
request.entity = µb.URI.entityFromDomain(request.domain);
|
|
|
|
|
|
|
|
// https://www.reddit.com/r/uBlockOrigin/comments/d6vxzj/
|
|
|
|
// Add support for `specifichide`.
|
|
|
|
if ( noCosmeticFiltering === false ) {
|
|
|
|
const specificHide =
|
|
|
|
µb.staticNetFilteringEngine.matchStringElementHide(
|
|
|
|
'specific',
|
|
|
|
request.url
|
|
|
|
);
|
|
|
|
response.noSpecificCosmeticFiltering = specificHide === 2;
|
|
|
|
if ( specificHide !== 0 && µb.logger.enabled ) {
|
|
|
|
µBlock.filteringContext
|
|
|
|
.duplicate()
|
|
|
|
.fromTabId(tabId)
|
|
|
|
.setURL(request.url)
|
|
|
|
.setRealm('network')
|
|
|
|
.setType('specifichide')
|
|
|
|
.setFilter(µb.staticNetFilteringEngine.toLogData())
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cosmetic filtering can be effectively disabled when both specific and
|
|
|
|
// generic cosmetic filtering are disabled.
|
|
|
|
if (
|
|
|
|
noCosmeticFiltering === false &&
|
|
|
|
response.noGenericCosmeticFiltering &&
|
|
|
|
response.noSpecificCosmeticFiltering
|
|
|
|
) {
|
|
|
|
response.noCosmeticFiltering = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
response.specificCosmeticFilters =
|
|
|
|
µb.cosmeticFilteringEngine.retrieveSpecificSelectors(request, response);
|
|
|
|
|
|
|
|
if ( µb.canInjectScriptletsNow === false ) {
|
|
|
|
response.scriptlets = µb.scriptletFilteringEngine.retrieve(request);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( µb.logger.enabled && response.noCosmeticFiltering !== true ) {
|
|
|
|
µb.logCosmeticFilters(tabId, frameId);
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const onMessage = function(request, sender, callback) {
|
2014-06-27 23:06:42 +02:00
|
|
|
// Async
|
2015-04-25 13:28:35 +02:00
|
|
|
switch ( request.what ) {
|
|
|
|
default:
|
|
|
|
break;
|
2014-06-27 23:06:42 +02:00
|
|
|
}
|
|
|
|
|
2019-09-21 17:30:38 +02:00
|
|
|
const senderDetails = µb.getMessageSenderDetails(sender);
|
|
|
|
const pageStore = µb.pageStoreFromTabId(senderDetails.tabId);
|
|
|
|
|
2014-06-27 23:06:42 +02:00
|
|
|
// Sync
|
2019-09-21 17:30:38 +02:00
|
|
|
let response;
|
2014-06-27 23:06:42 +02:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
switch ( request.what ) {
|
2019-09-01 18:43:12 +02:00
|
|
|
case 'cosmeticFiltersInjected':
|
|
|
|
µb.cosmeticFilteringEngine.addToSelectorCache(request);
|
|
|
|
break;
|
|
|
|
|
2017-08-03 16:18:05 +02:00
|
|
|
case 'getCollapsibleBlockedRequests':
|
|
|
|
response = {
|
|
|
|
id: request.id,
|
|
|
|
hash: request.hash,
|
2017-10-21 19:43:46 +02:00
|
|
|
netSelectorCacheCountMax:
|
2019-09-21 17:30:38 +02:00
|
|
|
µb.cosmeticFilteringEngine.netSelectorCacheCountMax,
|
2017-08-03 16:18:05 +02:00
|
|
|
};
|
|
|
|
if (
|
|
|
|
µb.userSettings.collapseBlocked &&
|
2019-09-21 17:30:38 +02:00
|
|
|
pageStore && pageStore.getNetFilteringSwitch()
|
2017-08-03 16:18:05 +02:00
|
|
|
) {
|
|
|
|
pageStore.getBlockedResources(request, response);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-09-18 18:17:45 +02:00
|
|
|
case 'maybeGoodPopup':
|
2019-09-21 17:30:38 +02:00
|
|
|
µb.maybeGoodPopup.tabId = senderDetails.tabId;
|
2019-09-18 18:17:45 +02:00
|
|
|
µb.maybeGoodPopup.url = request.url;
|
2019-09-01 18:43:12 +02:00
|
|
|
break;
|
|
|
|
|
2018-09-01 00:47:02 +02:00
|
|
|
case 'shouldRenderNoscriptTags':
|
|
|
|
if ( pageStore === null ) { break; }
|
2019-09-21 17:30:38 +02:00
|
|
|
const fctxt = µb.filteringContext.fromTabId(senderDetails.tabId);
|
2018-12-13 18:30:54 +01:00
|
|
|
if ( pageStore.filterScripting(fctxt, undefined) ) {
|
2019-09-21 17:30:38 +02:00
|
|
|
vAPI.tabs.executeScript(senderDetails.tabId, {
|
2019-09-16 22:17:48 +02:00
|
|
|
file: '/js/scriptlets/noscript-spoof.js',
|
2019-09-21 17:30:38 +02:00
|
|
|
frameId: senderDetails.frameId,
|
|
|
|
runAt: 'document_end',
|
2019-09-16 22:17:48 +02:00
|
|
|
});
|
2018-09-01 00:47:02 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-08-12 14:55:35 +02:00
|
|
|
case 'retrieveContentScriptParameters':
|
2019-09-21 17:30:38 +02:00
|
|
|
response = retrieveContentScriptParameters(senderDetails, request);
|
2016-03-06 16:51:06 +01:00
|
|
|
break;
|
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
case 'retrieveGenericCosmeticSelectors':
|
2019-09-21 17:30:38 +02:00
|
|
|
request.tabId = senderDetails.tabId;
|
|
|
|
request.frameId = senderDetails.frameId;
|
2019-06-03 12:37:39 +02:00
|
|
|
response = {
|
2019-09-21 17:30:38 +02:00
|
|
|
result: µb.cosmeticFilteringEngine.retrieveGenericSelectors(request),
|
2019-06-03 12:37:39 +02:00
|
|
|
};
|
2015-04-25 13:28:35 +02:00
|
|
|
break;
|
2014-06-27 23:06:42 +02:00
|
|
|
|
2015-04-25 13:28:35 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2014-10-20 13:26:02 +02:00
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2014-10-20 13:26:02 +02:00
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'contentscript',
|
|
|
|
listener: onMessage,
|
|
|
|
});
|
2014-10-20 13:26:02 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-10-20 13:26:02 +02:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// elementPicker
|
|
|
|
// unprivileged
|
2014-10-20 13:26:02 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2014-09-28 18:05:46 +02:00
|
|
|
|
2019-01-08 13:37:50 +01:00
|
|
|
const onMessage = function(request, sender, callback) {
|
|
|
|
const µb = µBlock;
|
2014-10-20 13:26:02 +02:00
|
|
|
|
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'elementPickerArguments':
|
2019-01-08 13:37:50 +01:00
|
|
|
const xhr = new XMLHttpRequest();
|
2015-05-19 19:59:53 +02:00
|
|
|
xhr.open('GET', 'epicker.html', true);
|
|
|
|
xhr.overrideMimeType('text/html;charset=utf-8');
|
|
|
|
xhr.responseType = 'text';
|
|
|
|
xhr.onload = function() {
|
|
|
|
this.onload = null;
|
|
|
|
var i18n = {
|
|
|
|
bidi_dir: document.body.getAttribute('dir'),
|
|
|
|
create: vAPI.i18n('pickerCreate'),
|
|
|
|
pick: vAPI.i18n('pickerPick'),
|
|
|
|
quit: vAPI.i18n('pickerQuit'),
|
2016-04-16 17:20:01 +02:00
|
|
|
preview: vAPI.i18n('pickerPreview'),
|
2015-05-19 19:59:53 +02:00
|
|
|
netFilters: vAPI.i18n('pickerNetFilters'),
|
|
|
|
cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
|
|
|
|
cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
|
|
|
|
};
|
2019-01-08 13:37:50 +01:00
|
|
|
const reStrings = /\{\{(\w+)\}\}/g;
|
|
|
|
const replacer = function(a0, string) {
|
2015-05-19 19:59:53 +02:00
|
|
|
return i18n[string];
|
2014-07-13 02:32:44 +02:00
|
|
|
};
|
2015-03-20 16:39:20 +01:00
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
callback({
|
|
|
|
frameContent: this.responseText.replace(reStrings, replacer),
|
2019-09-18 18:17:45 +02:00
|
|
|
target: µb.epickerArgs.target,
|
|
|
|
mouse: µb.epickerArgs.mouse,
|
|
|
|
zap: µb.epickerArgs.zap,
|
|
|
|
eprom: µb.epickerArgs.eprom,
|
2015-05-19 19:59:53 +02:00
|
|
|
});
|
|
|
|
|
2019-09-18 18:17:45 +02:00
|
|
|
µb.epickerArgs.target = '';
|
2015-05-19 19:59:53 +02:00
|
|
|
};
|
|
|
|
xhr.send();
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2015-02-08 19:34:28 +01:00
|
|
|
}
|
2014-07-13 02:32:44 +02:00
|
|
|
|
2015-02-08 19:34:28 +01:00
|
|
|
// Sync
|
2019-01-08 13:37:50 +01:00
|
|
|
let response;
|
2015-02-08 19:34:28 +01:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2019-09-02 14:43:49 +02:00
|
|
|
case 'compileCosmeticFilterSelector':
|
|
|
|
response = µb.staticExtFilteringEngine.compileSelector(
|
|
|
|
request.selector
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/3497
|
|
|
|
// This needs to be removed once issue is fixed.
|
|
|
|
case 'createUserFilter':
|
|
|
|
µb.createUserFilters(request);
|
|
|
|
break;
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'elementPickerEprom':
|
2019-09-18 18:17:45 +02:00
|
|
|
µb.epickerArgs.eprom = request;
|
2015-05-19 19:59:53 +02:00
|
|
|
break;
|
2015-03-20 16:39:20 +01:00
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2014-07-13 02:32:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'elementPicker',
|
|
|
|
listener: onMessage,
|
|
|
|
});
|
2014-09-28 18:05:46 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2014-09-14 22:20:40 +02:00
|
|
|
/******************************************************************************/
|
2014-06-24 00:42:43 +02:00
|
|
|
/******************************************************************************/
|
2015-08-11 21:29:14 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// cloudWidget
|
|
|
|
// privileged
|
2015-08-11 21:29:14 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2015-08-11 21:29:14 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
const onMessage = function(request, sender, callback) {
|
2016-10-16 19:04:31 +02:00
|
|
|
// Cloud storage support is optional.
|
2016-10-19 16:20:26 +02:00
|
|
|
if ( µBlock.cloudStorageSupported !== true ) {
|
2016-10-16 19:04:31 +02:00
|
|
|
callback();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-11 21:29:14 +02:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
|
|
|
case 'cloudGetOptions':
|
|
|
|
vAPI.cloud.getOptions(function(options) {
|
2016-10-16 19:04:31 +02:00
|
|
|
options.enabled = µBlock.userSettings.cloudStorageEnabled === true;
|
2015-08-11 21:29:14 +02:00
|
|
|
callback(options);
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'cloudSetOptions':
|
|
|
|
vAPI.cloud.setOptions(request.options, callback);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'cloudPull':
|
2019-09-18 14:34:55 +02:00
|
|
|
return vAPI.cloud.pull(request.datakey).then(result => {
|
|
|
|
callback(result);
|
|
|
|
});
|
2015-08-11 21:29:14 +02:00
|
|
|
|
|
|
|
case 'cloudPush':
|
2019-09-18 14:34:55 +02:00
|
|
|
return vAPI.cloud.push(request.datakey, request.data).then(result => {
|
|
|
|
callback(result);
|
|
|
|
});
|
2015-08-11 21:29:14 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
2019-09-01 18:43:12 +02:00
|
|
|
let response;
|
2015-08-11 21:29:14 +02:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
|
|
|
// For when cloud storage is disabled.
|
|
|
|
case 'cloudPull':
|
|
|
|
// fallthrough
|
|
|
|
case 'cloudPush':
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'cloudWidget',
|
|
|
|
listener: onMessage,
|
|
|
|
privileged: true,
|
|
|
|
});
|
2014-12-31 23:26:17 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-12-31 23:26:17 +01:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// dashboard
|
|
|
|
// privileged
|
2014-07-17 16:52:43 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2014-07-17 16:52:43 +02:00
|
|
|
|
2018-11-02 20:18:50 +01:00
|
|
|
const µb = µBlock;
|
2014-09-28 18:05:46 +02:00
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
// Settings
|
2019-09-15 13:58:28 +02:00
|
|
|
const getLocalData = async function() {
|
|
|
|
const data = Object.assign({}, µb.restoreBackupSettings);
|
|
|
|
data.storageUsed = await µb.getBytesInUse();
|
2019-09-17 21:15:01 +02:00
|
|
|
data.cloudStorageSupported = µb.cloudStorageSupported;
|
|
|
|
data.privacySettingsSupported = µb.privacySettingsSupported;
|
2019-09-15 13:58:28 +02:00
|
|
|
return data;
|
2015-03-07 05:36:09 +01:00
|
|
|
};
|
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
const backupUserData = async function() {
|
2019-09-17 21:15:01 +02:00
|
|
|
const userFilters = await µb.loadUserFilters();
|
2019-09-15 13:58:28 +02:00
|
|
|
|
2019-06-25 17:57:14 +02:00
|
|
|
const userData = {
|
2015-04-16 18:14:43 +02:00
|
|
|
timeStamp: Date.now(),
|
|
|
|
version: vAPI.app.version,
|
|
|
|
userSettings: µb.userSettings,
|
2017-01-26 16:17:38 +01:00
|
|
|
selectedFilterLists: µb.selectedFilterLists,
|
2018-02-21 19:29:36 +01:00
|
|
|
hiddenSettings: µb.hiddenSettings,
|
2019-06-25 17:57:14 +02:00
|
|
|
whitelist: µb.arrayFromWhitelist(µb.netWhitelist),
|
|
|
|
// String representation eventually to be deprecated
|
2015-04-16 18:14:43 +02:00
|
|
|
netWhitelist: µb.stringFromWhitelist(µb.netWhitelist),
|
|
|
|
dynamicFilteringString: µb.permanentFirewall.toString(),
|
2015-05-21 20:15:17 +02:00
|
|
|
urlFilteringString: µb.permanentURLFiltering.toString(),
|
2018-09-03 20:06:49 +02:00
|
|
|
hostnameSwitchesString: µb.permanentSwitches.toString(),
|
2019-09-15 13:58:28 +02:00
|
|
|
userFilters: userFilters.content,
|
2017-01-26 16:17:38 +01:00
|
|
|
};
|
2015-04-16 18:14:43 +02:00
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
const filename = vAPI.i18n('aboutBackupFilename')
|
|
|
|
.replace('{{datetime}}', µb.dateNowToSensibleString())
|
|
|
|
.replace(/ +/g, '_');
|
|
|
|
µb.restoreBackupSettings.lastBackupFile = filename;
|
|
|
|
µb.restoreBackupSettings.lastBackupTime = Date.now();
|
|
|
|
vAPI.storage.set(µb.restoreBackupSettings);
|
2015-03-07 05:36:09 +01:00
|
|
|
|
2019-09-17 21:15:01 +02:00
|
|
|
const localData = await getLocalData();
|
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
return { localData, userData };
|
2014-10-07 14:59:35 +02:00
|
|
|
};
|
|
|
|
|
2019-09-15 15:36:50 +02:00
|
|
|
const restoreUserData = async function(request) {
|
2019-03-28 14:17:47 +01:00
|
|
|
const userData = request.userData;
|
2014-10-11 22:44:56 +02:00
|
|
|
|
2015-04-07 03:26:05 +02:00
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/1102
|
2019-09-15 15:36:50 +02:00
|
|
|
// Ensure all currently cached assets are flushed from storage AND memory.
|
2015-03-27 14:50:31 +01:00
|
|
|
µb.assets.rmrf();
|
|
|
|
|
2014-10-07 16:46:10 +02:00
|
|
|
// If we are going to restore all, might as well wipe out clean local
|
2019-09-15 15:36:50 +02:00
|
|
|
// storages
|
2018-02-21 19:29:36 +01:00
|
|
|
vAPI.localStorage.removeItem('immediateHiddenSettings');
|
2019-09-15 15:36:50 +02:00
|
|
|
await Promise.all([
|
|
|
|
µb.cacheStorage.clear(),
|
|
|
|
vAPI.storage.clear(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Restore block stats
|
|
|
|
µBlock.saveLocalSettings();
|
|
|
|
|
|
|
|
// Restore user data
|
|
|
|
vAPI.storage.set(userData.userSettings);
|
|
|
|
let hiddenSettings = userData.hiddenSettings;
|
|
|
|
if ( hiddenSettings instanceof Object === false ) {
|
|
|
|
hiddenSettings = µBlock.hiddenSettingsFromString(
|
|
|
|
userData.hiddenSettingsString || ''
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// Whitelist directives can be represented as an array or as a
|
|
|
|
// (eventually to be deprecated) string.
|
|
|
|
let whitelist = userData.whitelist;
|
|
|
|
if (
|
|
|
|
Array.isArray(whitelist) === false &&
|
|
|
|
typeof userData.netWhitelist === 'string' &&
|
|
|
|
userData.netWhitelist !== ''
|
|
|
|
) {
|
|
|
|
whitelist = userData.netWhitelist.split('\n');
|
|
|
|
}
|
|
|
|
vAPI.storage.set({
|
|
|
|
hiddenSettings: hiddenSettings,
|
|
|
|
netWhitelist: whitelist || [],
|
|
|
|
dynamicFilteringString: userData.dynamicFilteringString || '',
|
|
|
|
urlFilteringString: userData.urlFilteringString || '',
|
|
|
|
hostnameSwitchesString: userData.hostnameSwitchesString || '',
|
|
|
|
lastRestoreFile: request.file || '',
|
|
|
|
lastRestoreTime: Date.now(),
|
|
|
|
lastBackupFile: '',
|
|
|
|
lastBackupTime: 0
|
|
|
|
});
|
|
|
|
µb.saveUserFilters(userData.userFilters);
|
|
|
|
if ( Array.isArray(userData.selectedFilterLists) ) {
|
|
|
|
await µb.saveSelectedFilterLists(userData.selectedFilterLists);
|
|
|
|
}
|
|
|
|
|
|
|
|
vAPI.app.restart();
|
2014-10-07 14:59:35 +02:00
|
|
|
};
|
|
|
|
|
2018-07-24 15:17:18 +02:00
|
|
|
// Remove all stored data but keep global counts, people can become
|
|
|
|
// quite attached to numbers
|
2019-09-15 13:58:28 +02:00
|
|
|
const resetUserData = async function() {
|
2018-02-21 19:29:36 +01:00
|
|
|
vAPI.localStorage.removeItem('immediateHiddenSettings');
|
2019-09-15 13:58:28 +02:00
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
µb.cacheStorage.clear(),
|
|
|
|
vAPI.storage.clear(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
await µb.saveLocalSettings();
|
|
|
|
|
|
|
|
vAPI.app.restart();
|
2014-10-07 14:59:35 +02:00
|
|
|
};
|
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
// 3rd-party filters
|
2019-05-20 00:31:12 +02:00
|
|
|
const prepListEntries = function(entries) {
|
|
|
|
const µburi = µb.URI;
|
|
|
|
for ( const k in entries ) {
|
2017-01-18 19:17:47 +01:00
|
|
|
if ( entries.hasOwnProperty(k) === false ) { continue; }
|
2019-05-20 00:31:12 +02:00
|
|
|
const entry = entries[k];
|
2016-03-06 16:51:06 +01:00
|
|
|
if ( typeof entry.supportURL === 'string' && entry.supportURL !== '' ) {
|
|
|
|
entry.supportName = µburi.hostnameFromURI(entry.supportURL);
|
|
|
|
} else if ( typeof entry.homeURL === 'string' && entry.homeURL !== '' ) {
|
2019-05-20 00:31:12 +02:00
|
|
|
const hn = µburi.hostnameFromURI(entry.homeURL);
|
|
|
|
entry.supportURL = `http://${hn}/`;
|
2016-03-06 16:51:06 +01:00
|
|
|
entry.supportName = µburi.domainFromHostname(hn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
const getLists = async function(callback) {
|
2019-05-20 00:31:12 +02:00
|
|
|
const r = {
|
2016-03-06 16:51:06 +01:00
|
|
|
autoUpdate: µb.userSettings.autoUpdate,
|
|
|
|
available: null,
|
|
|
|
cache: null,
|
|
|
|
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
|
2017-01-18 19:17:47 +01:00
|
|
|
current: µb.availableFilterLists,
|
2017-01-22 22:05:16 +01:00
|
|
|
externalLists: µb.userSettings.externalLists,
|
2016-08-13 22:42:58 +02:00
|
|
|
ignoreGenericCosmeticFilters: µb.userSettings.ignoreGenericCosmeticFilters,
|
2019-05-20 00:31:12 +02:00
|
|
|
isUpdating: µb.assets.isUpdating(),
|
2016-03-06 16:51:06 +01:00
|
|
|
netFilterCount: µb.staticNetFilteringEngine.getFilterCount(),
|
2017-01-22 22:05:16 +01:00
|
|
|
parseCosmeticFilters: µb.userSettings.parseAllABPHideFilters,
|
2017-12-14 22:42:54 +01:00
|
|
|
userFiltersPath: µb.userFiltersPath
|
2016-03-06 16:51:06 +01:00
|
|
|
};
|
2019-09-15 13:58:28 +02:00
|
|
|
const [ lists, metadata ] = await Promise.all([
|
|
|
|
µb.getAvailableLists(),
|
|
|
|
µb.assets.metadata(),
|
|
|
|
]);
|
|
|
|
r.available = lists;
|
|
|
|
prepListEntries(r.available);
|
|
|
|
r.cache = metadata;
|
|
|
|
prepListEntries(r.cache);
|
|
|
|
callback(r);
|
2016-03-06 16:51:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// My rules
|
2019-05-20 00:31:12 +02:00
|
|
|
const getRules = function() {
|
2016-03-06 16:51:06 +01:00
|
|
|
return {
|
2018-09-03 20:06:49 +02:00
|
|
|
permanentRules:
|
|
|
|
µb.permanentFirewall.toArray().concat(
|
|
|
|
µb.permanentSwitches.toArray(),
|
|
|
|
µb.permanentURLFiltering.toArray()
|
|
|
|
),
|
|
|
|
sessionRules:
|
|
|
|
µb.sessionFirewall.toArray().concat(
|
|
|
|
µb.sessionSwitches.toArray(),
|
|
|
|
µb.sessionURLFiltering.toArray()
|
|
|
|
)
|
2016-03-06 16:51:06 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-05-20 00:31:12 +02:00
|
|
|
const modifyRuleset = function(details) {
|
2018-09-03 20:06:49 +02:00
|
|
|
let swRuleset, hnRuleset, urlRuleset;
|
2018-03-11 15:59:39 +01:00
|
|
|
if ( details.permanent ) {
|
2018-09-03 20:06:49 +02:00
|
|
|
swRuleset = µb.permanentSwitches;
|
2018-03-11 15:59:39 +01:00
|
|
|
hnRuleset = µb.permanentFirewall;
|
|
|
|
urlRuleset = µb.permanentURLFiltering;
|
|
|
|
} else {
|
2018-09-03 20:06:49 +02:00
|
|
|
swRuleset = µb.sessionSwitches;
|
2018-03-11 15:59:39 +01:00
|
|
|
hnRuleset = µb.sessionFirewall;
|
|
|
|
urlRuleset = µb.sessionURLFiltering;
|
|
|
|
}
|
2018-09-03 20:06:49 +02:00
|
|
|
let toRemove = new Set(details.toRemove.trim().split(/\s*[\n\r]+\s*/));
|
|
|
|
for ( let rule of toRemove ) {
|
2018-03-11 15:59:39 +01:00
|
|
|
if ( rule === '' ) { continue; }
|
2018-09-03 20:06:49 +02:00
|
|
|
let parts = rule.split(/\s+/);
|
|
|
|
if ( hnRuleset.removeFromRuleParts(parts) === false ) {
|
|
|
|
if ( swRuleset.removeFromRuleParts(parts) === false ) {
|
|
|
|
urlRuleset.removeFromRuleParts(parts);
|
|
|
|
}
|
|
|
|
}
|
2018-03-11 15:59:39 +01:00
|
|
|
}
|
2018-09-03 20:06:49 +02:00
|
|
|
let toAdd = new Set(details.toAdd.trim().split(/\s*[\n\r]+\s*/));
|
|
|
|
for ( let rule of toAdd ) {
|
2018-03-11 15:59:39 +01:00
|
|
|
if ( rule === '' ) { continue; }
|
2018-09-03 20:06:49 +02:00
|
|
|
let parts = rule.split(/\s+/);
|
|
|
|
if ( hnRuleset.addFromRuleParts(parts) === false ) {
|
|
|
|
if ( swRuleset.addFromRuleParts(parts) === false ) {
|
|
|
|
urlRuleset.addFromRuleParts(parts);
|
|
|
|
}
|
|
|
|
}
|
2018-03-11 15:59:39 +01:00
|
|
|
}
|
|
|
|
if ( details.permanent ) {
|
2018-09-03 20:06:49 +02:00
|
|
|
if ( swRuleset.changed ) {
|
|
|
|
µb.saveHostnameSwitches();
|
|
|
|
swRuleset.changed = false;
|
|
|
|
}
|
2018-03-11 15:59:39 +01:00
|
|
|
if ( hnRuleset.changed ) {
|
|
|
|
µb.savePermanentFirewallRules();
|
|
|
|
hnRuleset.changed = false;
|
2016-03-06 16:51:06 +01:00
|
|
|
}
|
2018-03-11 15:59:39 +01:00
|
|
|
if ( urlRuleset.changed ) {
|
|
|
|
µb.savePermanentURLFilteringRules();
|
|
|
|
urlRuleset.changed = false;
|
2016-03-06 16:51:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-07-19 00:00:55 +02:00
|
|
|
// Shortcuts pane
|
2019-05-20 00:31:12 +02:00
|
|
|
const getShortcuts = function(callback) {
|
2018-07-20 19:52:14 +02:00
|
|
|
if ( µb.canUseShortcuts === false ) {
|
|
|
|
return callback([]);
|
2018-07-19 00:00:55 +02:00
|
|
|
}
|
2018-07-20 19:52:14 +02:00
|
|
|
|
|
|
|
vAPI.commands.getAll(commands => {
|
|
|
|
let response = [];
|
|
|
|
for ( let command of commands ) {
|
|
|
|
let desc = command.description;
|
|
|
|
let match = /^__MSG_(.+?)__$/.exec(desc);
|
|
|
|
if ( match !== null ) {
|
|
|
|
desc = vAPI.i18n(match[1]);
|
|
|
|
}
|
|
|
|
if ( desc === '' ) { continue; }
|
|
|
|
command.description = desc;
|
|
|
|
response.push(command);
|
|
|
|
}
|
|
|
|
callback(response);
|
|
|
|
});
|
2018-07-19 00:00:55 +02:00
|
|
|
};
|
|
|
|
|
2019-05-20 00:31:12 +02:00
|
|
|
const setShortcut = function(details) {
|
2018-07-20 19:52:14 +02:00
|
|
|
if ( µb.canUpdateShortcuts === false ) { return; }
|
2018-07-19 00:00:55 +02:00
|
|
|
if ( details.shortcut === undefined ) {
|
|
|
|
vAPI.commands.reset(details.name);
|
|
|
|
µb.commandShortcuts.delete(details.name);
|
|
|
|
} else {
|
|
|
|
vAPI.commands.update({ name: details.name, shortcut: details.shortcut });
|
|
|
|
µb.commandShortcuts.set(details.name, details.shortcut);
|
|
|
|
}
|
|
|
|
vAPI.storage.set({ commandShortcuts: Array.from(µb.commandShortcuts) });
|
|
|
|
};
|
|
|
|
|
2019-05-20 00:31:12 +02:00
|
|
|
const onMessage = function(request, sender, callback) {
|
2014-06-24 00:42:43 +02:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'backupUserData':
|
2019-09-15 13:58:28 +02:00
|
|
|
return backupUserData().then(data => {
|
|
|
|
callback(data);
|
|
|
|
});
|
2015-03-07 05:36:09 +01:00
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'getLists':
|
|
|
|
return getLists(callback);
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'getLocalData':
|
2019-09-15 13:58:28 +02:00
|
|
|
return getLocalData().then(localData => {
|
|
|
|
callback(localData);
|
|
|
|
});
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2018-07-19 00:00:55 +02:00
|
|
|
case 'getShortcuts':
|
|
|
|
return getShortcuts(callback);
|
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'readUserFilters':
|
2019-09-15 13:58:28 +02:00
|
|
|
return µb.loadUserFilters().then(result => {
|
|
|
|
callback(result);
|
|
|
|
});
|
2016-03-06 16:51:06 +01:00
|
|
|
|
|
|
|
case 'writeUserFilters':
|
2019-09-15 13:58:28 +02:00
|
|
|
return µb.saveUserFilters(request.content).then(result => {
|
|
|
|
callback(result);
|
|
|
|
});
|
2016-03-06 16:51:06 +01:00
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
break;
|
2014-06-24 00:42:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
2019-09-15 13:58:28 +02:00
|
|
|
let response;
|
2014-06-24 00:42:43 +02:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2018-07-19 00:00:55 +02:00
|
|
|
case 'canUpdateShortcuts':
|
2018-07-20 19:52:14 +02:00
|
|
|
response = µb.canUpdateShortcuts;
|
2018-07-19 00:00:55 +02:00
|
|
|
break;
|
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'getRules':
|
|
|
|
response = getRules();
|
|
|
|
break;
|
|
|
|
|
2018-03-11 15:59:39 +01:00
|
|
|
case 'modifyRuleset':
|
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/772
|
|
|
|
µb.cosmeticFilteringEngine.removeFromSelectorCache('*');
|
|
|
|
modifyRuleset(request);
|
|
|
|
response = getRules();
|
|
|
|
break;
|
|
|
|
|
2017-01-18 19:17:47 +01:00
|
|
|
case 'purgeAllCaches':
|
|
|
|
if ( request.hard ) {
|
|
|
|
µb.assets.remove(/./);
|
|
|
|
} else {
|
2017-01-23 15:35:05 +01:00
|
|
|
µb.assets.purge(/./, 'public_suffix_list.dat');
|
2017-01-18 19:17:47 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-03-06 16:51:06 +01:00
|
|
|
case 'purgeCache':
|
2017-01-18 19:17:47 +01:00
|
|
|
µb.assets.purge(request.assetKey);
|
|
|
|
µb.assets.remove('compiled/' + request.assetKey);
|
2016-03-06 16:51:06 +01:00
|
|
|
break;
|
|
|
|
|
2016-11-03 16:20:47 +01:00
|
|
|
case 'readHiddenSettings':
|
|
|
|
response = µb.stringFromHiddenSettings();
|
|
|
|
break;
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'restoreUserData':
|
|
|
|
restoreUserData(request);
|
|
|
|
break;
|
2014-10-07 14:59:35 +02:00
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'resetUserData':
|
|
|
|
resetUserData();
|
|
|
|
break;
|
2016-03-06 16:51:06 +01:00
|
|
|
|
2018-07-19 00:00:55 +02:00
|
|
|
case 'setShortcut':
|
|
|
|
setShortcut(request);
|
|
|
|
break;
|
|
|
|
|
2016-11-03 16:20:47 +01:00
|
|
|
case 'writeHiddenSettings':
|
2018-03-19 15:25:03 +01:00
|
|
|
µb.changeHiddenSettings(µb.hiddenSettingsFromString(request.content));
|
2016-11-03 16:20:47 +01:00
|
|
|
break;
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2014-06-24 00:42:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'dashboard',
|
|
|
|
listener: onMessage,
|
|
|
|
privileged: true,
|
|
|
|
});
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2015-01-06 14:01:15 +01:00
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// loggerUI
|
|
|
|
// privileged
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2018-12-14 17:01:21 +01:00
|
|
|
const µb = µBlock;
|
|
|
|
const extensionOriginURL = vAPI.getURL('');
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2019-09-16 15:45:17 +02:00
|
|
|
const getLoggerData = async function(details, activeTabId, callback) {
|
2018-12-14 17:01:21 +01:00
|
|
|
const response = {
|
2018-01-09 14:08:17 +01:00
|
|
|
colorBlind: µb.userSettings.colorBlindFriendly,
|
2018-05-27 14:31:17 +02:00
|
|
|
entries: µb.logger.readAll(details.ownerId),
|
2018-01-09 14:08:17 +01:00
|
|
|
maxEntries: µb.userSettings.requestLogMaxEntries,
|
|
|
|
activeTabId: activeTabId,
|
2018-12-17 19:54:17 +01:00
|
|
|
tabIdsToken: µb.pageStoresToken,
|
|
|
|
tooltips: µb.userSettings.tooltipsDisabled === false
|
2018-05-27 14:31:17 +02:00
|
|
|
};
|
|
|
|
if ( µb.pageStoresToken !== details.tabIdsToken ) {
|
2018-12-14 17:01:21 +01:00
|
|
|
const tabIds = new Map();
|
|
|
|
for ( const entry of µb.pageStores ) {
|
|
|
|
const pageStore = entry[1];
|
2018-05-27 14:31:17 +02:00
|
|
|
if ( pageStore.rawURL.startsWith(extensionOriginURL) ) { continue; }
|
|
|
|
tabIds.set(entry[0], pageStore.title);
|
|
|
|
}
|
|
|
|
response.tabIds = Array.from(tabIds);
|
|
|
|
}
|
|
|
|
if ( activeTabId ) {
|
2018-12-14 17:01:21 +01:00
|
|
|
const pageStore = µb.pageStoreFromTabId(activeTabId);
|
2018-05-27 14:31:17 +02:00
|
|
|
if (
|
|
|
|
pageStore === null ||
|
|
|
|
pageStore.rawURL.startsWith(extensionOriginURL)
|
|
|
|
) {
|
|
|
|
response.activeTabId = undefined;
|
|
|
|
}
|
|
|
|
}
|
2019-09-16 15:45:17 +02:00
|
|
|
if ( details.popupLoggerBoxChanged && vAPI.windows instanceof Object ) {
|
|
|
|
const tabs = await vAPI.tabs.query({
|
|
|
|
url: vAPI.getURL('/logger-ui.html?popup=1')
|
|
|
|
});
|
|
|
|
if ( tabs.length !== 0 ) {
|
|
|
|
const win = await vAPI.windows.get(tabs[0].windowId);
|
|
|
|
if ( win === null ) { return; }
|
|
|
|
vAPI.localStorage.setItem('popupLoggerBox', JSON.stringify({
|
|
|
|
left: win.left,
|
|
|
|
top: win.top,
|
|
|
|
width: win.width,
|
|
|
|
height: win.height,
|
|
|
|
}));
|
|
|
|
}
|
2018-12-14 17:01:21 +01:00
|
|
|
}
|
2018-05-27 14:31:17 +02:00
|
|
|
callback(response);
|
2018-01-09 14:08:17 +01:00
|
|
|
};
|
|
|
|
|
2018-12-14 17:01:21 +01:00
|
|
|
const getURLFilteringData = function(details) {
|
|
|
|
const colors = {};
|
|
|
|
const response = {
|
2015-05-21 20:15:17 +02:00
|
|
|
dirty: false,
|
|
|
|
colors: colors
|
|
|
|
};
|
2018-12-14 17:01:21 +01:00
|
|
|
const suf = µb.sessionURLFiltering;
|
|
|
|
const puf = µb.permanentURLFiltering;
|
|
|
|
const urls = details.urls;
|
|
|
|
const context = details.context;
|
|
|
|
const type = details.type;
|
|
|
|
for ( const url of urls ) {
|
|
|
|
const colorEntry = colors[url] = { r: 0, own: false };
|
2015-05-21 20:15:17 +02:00
|
|
|
if ( suf.evaluateZ(context, url, type).r !== 0 ) {
|
|
|
|
colorEntry.r = suf.r;
|
2018-12-14 17:01:21 +01:00
|
|
|
colorEntry.own = suf.r !== 0 &&
|
|
|
|
suf.context === context &&
|
|
|
|
suf.url === url &&
|
|
|
|
suf.type === type;
|
2015-05-21 20:15:17 +02:00
|
|
|
}
|
2018-12-14 17:01:21 +01:00
|
|
|
if ( response.dirty ) { continue; }
|
2015-05-21 20:15:17 +02:00
|
|
|
puf.evaluateZ(context, url, type);
|
2018-12-14 17:01:21 +01:00
|
|
|
response.dirty = colorEntry.own !== (
|
|
|
|
puf.r !== 0 &&
|
|
|
|
puf.context === context &&
|
|
|
|
puf.url === url &&
|
|
|
|
puf.type === type
|
|
|
|
);
|
2015-05-21 20:15:17 +02:00
|
|
|
}
|
|
|
|
return response;
|
|
|
|
};
|
|
|
|
|
2018-12-14 17:01:21 +01:00
|
|
|
const onMessage = function(request, sender, callback) {
|
2015-01-06 14:01:15 +01:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'readAll':
|
2018-01-08 20:29:39 +01:00
|
|
|
if (
|
|
|
|
µb.logger.ownerId !== undefined &&
|
|
|
|
µb.logger.ownerId !== request.ownerId
|
|
|
|
) {
|
2019-09-16 15:45:17 +02:00
|
|
|
return callback({ unavailable: true });
|
2018-01-08 20:29:39 +01:00
|
|
|
}
|
2019-09-16 15:45:17 +02:00
|
|
|
vAPI.tabs.getCurrent().then(tab => {
|
2018-05-27 14:31:17 +02:00
|
|
|
getLoggerData(request, tab && tab.id, callback);
|
2018-01-09 14:08:17 +01:00
|
|
|
});
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
2015-05-19 19:59:53 +02:00
|
|
|
break;
|
2018-01-09 14:08:17 +01:00
|
|
|
}
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2018-01-09 14:08:17 +01:00
|
|
|
// Sync
|
2018-12-14 17:01:21 +01:00
|
|
|
let response;
|
2018-01-09 14:08:17 +01:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2018-01-08 20:29:39 +01:00
|
|
|
case 'releaseView':
|
|
|
|
if ( request.ownerId === µb.logger.ownerId ) {
|
|
|
|
µb.logger.ownerId = undefined;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-05-21 20:15:17 +02:00
|
|
|
case 'saveURLFilteringRules':
|
2015-05-22 14:05:55 +02:00
|
|
|
response = µb.permanentURLFiltering.copyRules(
|
|
|
|
µb.sessionURLFiltering,
|
|
|
|
request.context,
|
|
|
|
request.urls,
|
|
|
|
request.type
|
|
|
|
);
|
|
|
|
if ( response ) {
|
2015-05-21 20:15:17 +02:00
|
|
|
µb.savePermanentURLFilteringRules();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'setURLFilteringRule':
|
|
|
|
µb.toggleURLFilteringRule(request);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'getURLFilteringData':
|
|
|
|
response = getURLFilteringData(request);
|
|
|
|
break;
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2015-01-06 14:01:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'loggerUI',
|
|
|
|
listener: onMessage,
|
|
|
|
privileged: true,
|
|
|
|
});
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2014-06-24 00:42:43 +02:00
|
|
|
/******************************************************************************/
|
2015-03-09 17:57:52 +01:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// documentBlocked
|
|
|
|
// privileged
|
2015-03-26 00:28:22 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2015-03-26 00:28:22 +01:00
|
|
|
|
2019-05-22 00:56:59 +02:00
|
|
|
const onMessage = function(request, sender, callback) {
|
|
|
|
const tabId = sender && sender.tab ? sender.tab.id : 0;
|
|
|
|
|
2015-03-26 00:28:22 +01:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
break;
|
2015-03-26 00:28:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
2018-10-29 13:56:51 +01:00
|
|
|
let response;
|
2015-03-26 00:28:22 +01:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2019-05-22 00:56:59 +02:00
|
|
|
case 'closeThisTab':
|
|
|
|
vAPI.tabs.remove(tabId);
|
|
|
|
break;
|
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
case 'temporarilyWhitelistDocument':
|
2018-10-29 13:56:51 +01:00
|
|
|
µBlock.webRequest.strictBlockBypass(request.hostname);
|
2015-05-19 19:59:53 +02:00
|
|
|
break;
|
2015-03-26 00:28:22 +01:00
|
|
|
|
2015-05-19 19:59:53 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
2015-03-26 00:28:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'documentBlocked',
|
|
|
|
listener: onMessage,
|
|
|
|
privileged: true,
|
|
|
|
});
|
2015-03-26 00:28:22 +01:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2015-03-09 17:57:52 +01:00
|
|
|
|
|
|
|
/******************************************************************************/
|
2015-05-25 00:50:09 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// Channel:
|
|
|
|
// scriptlets
|
|
|
|
// unprivileged
|
2015-05-25 00:50:09 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2015-05-25 00:50:09 +02:00
|
|
|
|
2018-12-21 20:16:17 +01:00
|
|
|
const µb = µBlock;
|
2015-05-25 00:50:09 +02:00
|
|
|
|
2018-12-13 18:30:54 +01:00
|
|
|
const logCosmeticFilters = function(tabId, details) {
|
|
|
|
if ( µb.logger.enabled === false ) { return; }
|
|
|
|
|
|
|
|
const filter = { source: 'cosmetic', raw: '' };
|
|
|
|
const fctxt = µb.filteringContext.duplicate();
|
|
|
|
fctxt.fromTabId(tabId)
|
|
|
|
.setRealm('cosmetic')
|
|
|
|
.setType('dom')
|
|
|
|
.setURL(details.frameURL)
|
|
|
|
.setDocOriginFromURL(details.frameURL)
|
|
|
|
.setFilter(filter);
|
|
|
|
for ( const selector of details.matchedSelectors.sort() ) {
|
2019-05-16 19:44:49 +02:00
|
|
|
filter.raw = selector;
|
2018-12-13 18:30:54 +01:00
|
|
|
fctxt.toLogger();
|
2015-05-25 00:50:09 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-11 16:40:34 +02:00
|
|
|
const logCSPViolations = function(pageStore, request) {
|
|
|
|
if ( µb.logger.enabled === false || pageStore === null ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( request.violations.length === 0 ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fctxt = µb.filteringContext.duplicate();
|
|
|
|
fctxt.fromTabId(pageStore.tabId)
|
|
|
|
.setRealm('network')
|
|
|
|
.setDocOriginFromURL(request.docURL)
|
|
|
|
.setURL(request.docURL);
|
|
|
|
|
|
|
|
let cspData = pageStore.extraData.get('cspData');
|
|
|
|
if ( cspData === undefined ) {
|
|
|
|
cspData = new Map();
|
|
|
|
|
|
|
|
const policies = [];
|
|
|
|
const logData = [];
|
|
|
|
µb.staticNetFilteringEngine.matchAndFetchData(
|
|
|
|
'csp',
|
|
|
|
request.docURL,
|
|
|
|
policies,
|
|
|
|
logData
|
|
|
|
);
|
|
|
|
for ( let i = 0; i < policies.length; i++ ) {
|
|
|
|
cspData.set(policies[i], logData[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fctxt.type = 'inline-script';
|
|
|
|
fctxt.filter = undefined;
|
|
|
|
if ( pageStore.filterRequest(fctxt) === 1 ) {
|
|
|
|
cspData.set(µb.cspNoInlineScript, fctxt.filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
fctxt.type = 'script';
|
|
|
|
fctxt.filter = undefined;
|
|
|
|
if ( pageStore.filterScripting(fctxt, true) === 1 ) {
|
|
|
|
cspData.set(µb.cspNoScripting, fctxt.filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
fctxt.type = 'inline-font';
|
|
|
|
fctxt.filter = undefined;
|
|
|
|
if ( pageStore.filterRequest(fctxt) === 1 ) {
|
|
|
|
cspData.set(µb.cspNoInlineFont, fctxt.filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cspData.size === 0 ) { return false; }
|
|
|
|
|
|
|
|
pageStore.extraData.set('cspData', cspData);
|
|
|
|
}
|
|
|
|
|
|
|
|
const typeMap = logCSPViolations.policyDirectiveToTypeMap;
|
|
|
|
for ( const json of request.violations ) {
|
|
|
|
const violation = JSON.parse(json);
|
|
|
|
let type = typeMap.get(violation.directive);
|
|
|
|
if ( type === undefined ) { continue; }
|
|
|
|
const logData = cspData.get(violation.policy);
|
|
|
|
if ( logData === undefined ) { continue; }
|
|
|
|
if ( /^[\w.+-]+:\/\//.test(violation.url) === false ) {
|
|
|
|
violation.url = request.docURL;
|
|
|
|
if ( type === 'script' ) { type = 'inline-script'; }
|
|
|
|
else if ( type === 'font' ) { type = 'inline-font'; }
|
|
|
|
}
|
|
|
|
fctxt.setURL(violation.url)
|
|
|
|
.setType(type)
|
|
|
|
.setFilter(logData)
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
logCSPViolations.policyDirectiveToTypeMap = new Map([
|
|
|
|
[ 'img-src', 'image' ],
|
|
|
|
[ 'connect-src', 'xmlhttprequest' ],
|
|
|
|
[ 'font-src', 'font' ],
|
|
|
|
[ 'frame-src', 'sub_frame' ],
|
|
|
|
[ 'media-src', 'media' ],
|
|
|
|
[ 'object-src', 'object' ],
|
|
|
|
[ 'script-src', 'script' ],
|
|
|
|
[ 'script-src-attr', 'script' ],
|
|
|
|
[ 'script-src-elem', 'script' ],
|
|
|
|
[ 'style-src', 'stylesheet' ],
|
|
|
|
[ 'style-src-attr', 'stylesheet' ],
|
|
|
|
[ 'style-src-elem', 'stylesheet' ],
|
|
|
|
]);
|
|
|
|
|
|
|
|
const onMessage = function(request, sender, callback) {
|
2018-12-21 20:16:17 +01:00
|
|
|
const tabId = sender && sender.tab ? sender.tab.id : 0;
|
|
|
|
const pageStore = µb.pageStoreFromTabId(tabId);
|
2015-06-26 06:08:41 +02:00
|
|
|
|
2015-05-25 00:50:09 +02:00
|
|
|
// Async
|
|
|
|
switch ( request.what ) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sync
|
2019-05-11 16:40:34 +02:00
|
|
|
let response;
|
2015-05-25 00:50:09 +02:00
|
|
|
|
|
|
|
switch ( request.what ) {
|
2019-09-01 18:43:12 +02:00
|
|
|
case 'applyFilterListSelection':
|
|
|
|
response = µb.applyFilterListSelection(request);
|
|
|
|
break;
|
|
|
|
|
2018-12-21 20:16:17 +01:00
|
|
|
case 'inlinescriptFound':
|
|
|
|
if ( µb.logger.enabled && pageStore !== null ) {
|
|
|
|
const fctxt = µb.filteringContext.duplicate();
|
|
|
|
fctxt.fromTabId(tabId)
|
|
|
|
.setType('inline-script')
|
|
|
|
.setURL(request.docURL)
|
|
|
|
.setDocOriginFromURL(request.docURL);
|
|
|
|
if ( pageStore.filterRequest(fctxt) === 0 ) {
|
2019-01-12 22:36:20 +01:00
|
|
|
fctxt.setRealm('network').toLogger();
|
2018-12-21 20:16:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-05-25 00:50:09 +02:00
|
|
|
case 'logCosmeticFilteringData':
|
|
|
|
logCosmeticFilters(tabId, request);
|
|
|
|
break;
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
case 'reloadAllFilters':
|
|
|
|
µb.loadFilterLists();
|
|
|
|
return;
|
|
|
|
|
2019-05-11 16:40:34 +02:00
|
|
|
case 'securityPolicyViolation':
|
|
|
|
response = logCSPViolations(pageStore, request);
|
|
|
|
break;
|
|
|
|
|
2016-01-17 19:30:43 +01:00
|
|
|
case 'temporarilyAllowLargeMediaElement':
|
|
|
|
if ( pageStore !== null ) {
|
|
|
|
pageStore.allowLargeMediaElementsUntil = Date.now() + 2000;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'subscriberData':
|
|
|
|
response = {
|
2017-01-22 22:05:16 +01:00
|
|
|
confirmStr: vAPI.i18n('subscriberConfirm')
|
2016-01-17 19:30:43 +01:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
|
2015-05-25 00:50:09 +02:00
|
|
|
default:
|
|
|
|
return vAPI.messaging.UNHANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(response);
|
|
|
|
};
|
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
vAPI.messaging.listen({
|
|
|
|
name: 'scriptlets',
|
|
|
|
listener: onMessage,
|
|
|
|
});
|
2015-05-25 00:50:09 +02:00
|
|
|
|
2019-09-01 18:43:12 +02:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|
2015-05-25 00:50:09 +02:00
|
|
|
|
2015-06-26 06:08:41 +02:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|