uBlock/src/js/messaging.js

1585 lines
46 KiB
JavaScript
Raw Normal View History

2014-06-24 00:42:43 +02:00
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
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
*/
/******************************************************************************/
/******************************************************************************/
2016-08-06 18:05:01 +02:00
'use strict';
// 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.
/******************************************************************************/
/******************************************************************************/
// Default handler
// priviledged
{
// >>>>> start of local scope
const µb = µBlock;
const getDomainNames = function(targets) {
const µburi = µb.URI;
return targets.map(target => {
if ( typeof target !== 'string' ) { return ''; }
return target.indexOf('/') !== -1
? µburi.domainFromURI(target) || ''
: µburi.domainFromHostname(target) || target;
});
};
const onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
case 'getAssetContent':
// https://github.com/chrisaljoudi/uBlock/issues/417
µb.assets.get(
request.url,
{ dontCache: true, needSourceURL: true },
callback
);
return;
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);
return;
2015-06-26 06:08:41 +02:00
case 'reloadAllFilters':
µb.loadFilterLists();
2015-06-26 06:08:41 +02:00
return;
case 'scriptlet':
µb.scriptlets.inject(request.tabId, request.scriptlet, callback);
return;
default:
break;
}
// Sync
var response;
switch ( request.what ) {
2017-01-22 22:05:16 +01:00
case 'applyFilterListSelection':
response = µb.applyFilterListSelection(request);
break;
case 'compileCosmeticFilterSelector':
response = µb.staticExtFilteringEngine.compileSelector(
request.selector
);
break;
2015-03-11 04:46:18 +01:00
case 'createUserFilter':
µb.createUserFilters(request);
break;
case 'forceUpdateAssets':
µb.scheduleAssetUpdater(0);
2017-12-30 23:38:07 +01:00
µb.assets.updateStart({
delay: µb.hiddenSettings.manualUpdateAssetFetchPeriod
});
break;
2014-12-01 17:25:33 +01:00
case 'getAppData':
2018-05-17 18:45:57 +02:00
response = {
name: chrome.runtime.getManifest().name,
version: vAPI.app.version
};
break;
case 'getDomainNames':
response = getDomainNames(request.targets);
break;
2016-03-06 16:51:06 +01:00
case 'getWhitelist':
response = {
whitelist: µb.arrayFromWhitelist(µb.netWhitelist),
whitelistDefault: µb.netWhitelistDefault,
reBadHostname: µb.reWhitelistBadHostname.source,
reHostnameExtractor: µb.reWhitelistHostnameExtractor.source
};
2016-03-06 16:51:06 +01:00
break;
case 'launchElementPicker':
// Launched from some auxiliary pages, clear context menu coords.
2017-09-06 01:49:48 +02:00
µb.mouseEventRegister.x = µb.mouseEventRegister.y = -1;
2017-05-27 17:51:24 +02:00
µb.elementPickerExec(request.tabId, request.targetURL, request.zap);
break;
case 'gotoURL':
2016-09-16 23:41:17 +02:00
µb.openNewTab(request.details);
break;
case 'reloadTab':
if ( vAPI.isBehindTheSceneTabId(request.tabId) === false ) {
2018-01-07 23:53:33 +01:00
vAPI.tabs.reload(request.tabId, request.bypassCache === true);
if ( request.select && vAPI.tabs.select ) {
vAPI.tabs.select(request.tabId);
}
}
break;
2016-03-06 16:51:06 +01:00
case 'setWhitelist':
µb.netWhitelist = µb.whitelistFromString(request.whitelist);
µb.saveWhitelist();
break;
case 'toggleHostnameSwitch':
µb.toggleHostnameSwitch(request);
break;
2015-03-27 18:00:55 +01:00
case 'userSettings':
response = µb.changeUserSettings(request.name, request.value);
break;
default:
return vAPI.messaging.UNHANDLED;
}
callback(response);
};
vAPI.messaging.setup(onMessage);
// <<<<< end of local scope
}
2014-09-14 22:20:40 +02:00
/******************************************************************************/
2014-06-24 00:42:43 +02:00
/******************************************************************************/
// Channel:
// popupPanel
// privileged
2014-09-28 18:05:46 +02:00
{
// >>>>> start of local scope
2014-06-24 00:42:43 +02:00
const µb = µBlock;
2014-06-24 00:42:43 +02:00
const getHostnameDict = function(hostnameToCountMap) {
const r = Object.create(null);
const domainFromHostname = µb.URI.domainFromHostname;
// Note: destructuring assignment not supported before Chromium 49.
for ( const [ hostname, hnCounts ] of hostnameToCountMap ) {
if ( r[hostname] !== undefined ) { continue; }
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 ) {
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
};
}
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;
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,
allowCount: allowCount,
totalBlockCount: 0,
totalAllowCount: 0
2014-12-30 22:36:29 +01:00
};
}
return r;
};
const getFirewallRules = function(srcHostname, desHostnames) {
var r = {};
2015-05-21 20:15:17 +02:00
var df = µb.sessionFirewall;
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');
if ( typeof srcHostname !== 'string' ) { return r; }
2014-12-30 22:36:29 +01:00
r['. * *'] = df.lookupRuleData(srcHostname, '*', '*');
r['. * image'] = df.lookupRuleData(srcHostname, '*', 'image');
r['. * 3p'] = df.lookupRuleData(srcHostname, '*', '3p');
r['. * inline-script'] = df.lookupRuleData(srcHostname,
'*',
'inline-script'
);
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
for ( const desHostname in desHostnames ) {
r[`/ ${desHostname} *`] = df.lookupRuleData(
'*',
desHostname,
'*'
);
r[`. ${desHostname} *`] = df.lookupRuleData(
srcHostname,
desHostname,
'*'
);
2014-12-30 22:36:29 +01:00
}
return r;
2014-10-06 20:02:44 +02:00
};
const popupDataFromTabId = function(tabId, tabTitle) {
const tabContext = µb.tabContextManager.mustLookup(tabId);
const rootHostname = tabContext.rootHostname;
const r = {
advancedUserEnabled: µb.userSettings.advancedUserEnabled,
2014-12-01 17:25:33 +01:00
appName: vAPI.app.name,
appVersion: vAPI.app.version,
colorBlindFriendly: µb.userSettings.colorBlindFriendly,
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,
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
fontSize: µb.hiddenSettings.popupFontSize,
netFilteringSwitch: false,
2015-04-09 00:46:08 +02:00
rawURL: tabContext.rawURL,
pageURL: tabContext.normalURL,
pageHostname: rootHostname,
2015-04-09 00:46:08 +02:00
pageDomain: tabContext.rootDomain,
2014-06-24 00:42:43 +02:00
pageAllowedRequestCount: 0,
pageBlockedRequestCount: 0,
2016-01-04 16:48:28 +01:00
popupBlockedCount: 0,
2015-03-02 19:49:34 +01:00
tabId: tabId,
tabTitle: tabTitle,
tooltipsDisabled: µb.userSettings.tooltipsDisabled
2014-06-24 00:42:43 +02:00
};
2015-04-09 00:46:08 +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
// 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;
r.firewallRules = getFirewallRules(rootHostname, r.hostnameDict);
2018-09-07 16:52:10 +02:00
r.canElementPicker = µb.URI.isNetworkURI(r.rawURL);
r.noPopups = µb.sessionSwitches.evaluateZ(
'no-popups',
rootHostname
);
2016-01-04 16:48:28 +01:00
r.popupBlockedCount = pageStore.popupBlockedCount;
r.noCosmeticFiltering = µb.sessionSwitches.evaluateZ(
'no-cosmetic-filtering',
rootHostname
);
r.noLargeMedia = µb.sessionSwitches.evaluateZ(
'no-large-media',
rootHostname
);
r.largeMediaCount = pageStore.largeMediaCount;
r.noRemoteFonts = µb.sessionSwitches.evaluateZ(
'no-remote-fonts',
rootHostname
);
r.remoteFontCount = pageStore.remoteFontCount;
r.noScripting = µb.sessionSwitches.evaluateZ(
'no-scripting',
rootHostname
);
2014-12-30 22:36:29 +01:00
} else {
r.hostnameDict = {};
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,
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;
};
const popupDataFromRequest = function(request, callback) {
2015-05-18 16:39:20 +02:00
if ( request.tabId ) {
callback(popupDataFromTabId(request.tabId, ''));
return;
}
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.
vAPI.tabs.get(null, function(tab) {
var tabId = '';
var tabTitle = '';
if ( tab ) {
tabId = tab.id;
tabTitle = tab.title || '';
}
callback(popupDataFromTabId(tabId, tabTitle));
});
};
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 ) {
2015-04-24 14:36:19 +02:00
case 'getPopupData':
2015-05-18 16:39:20 +02:00
popupDataFromRequest(request, callback);
2015-04-24 14:36:19 +02:00
return;
2015-04-24 14:36:19 +02:00
default:
break;
2014-06-24 00:42:43 +02:00
}
// Sync
let response;
2014-06-24 00:42:43 +02:00
switch ( request.what ) {
case 'getPopupLazyData':
pageStore = µb.pageStoreFromTabId(request.tabId);
if ( pageStore !== null ) {
pageStore.hiddenElementCount = 0;
pageStore.scriptCount = 0;
vAPI.tabs.injectScript(request.tabId, {
allFrames: true,
file: '/js/scriptlets/dom-survey.js',
runAt: 'document_end'
});
}
break;
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'
);
µ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 ) {
pageStore.toggleNetFilteringSwitch(
request.url,
request.scope,
request.state
);
µ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);
};
vAPI.messaging.listen({
name: 'popupPanel',
listener: onMessage,
privileged: true,
});
2014-06-24 00:42:43 +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
/******************************************************************************/
// Channel:
// contentscript
// unprivileged
2014-06-27 23:06:42 +02:00
{
// >>>>> start of local scope
2014-06-27 23:06:42 +02:00
const µb = µBlock;
2014-09-28 18:05:46 +02:00
const onMessage = function(request, sender, callback) {
2014-06-27 23:06:42 +02:00
// Async
switch ( request.what ) {
default:
break;
2014-06-27 23:06:42 +02:00
}
// Sync
let response,
2017-12-17 14:09:47 +01:00
tabId, frameId,
pageStore = null;
2017-10-21 19:43:46 +02:00
2014-06-27 23:06:42 +02:00
if ( sender && sender.tab ) {
2017-10-21 19:43:46 +02:00
tabId = sender.tab.id;
2017-12-17 14:09:47 +01:00
frameId = sender.frameId;
2017-10-21 19:43:46 +02:00
pageStore = µb.pageStoreFromTabId(tabId);
2014-06-27 23:06:42 +02:00
}
switch ( request.what ) {
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:
µb.cosmeticFilteringEngine.netSelectorCacheCountMax
2017-08-03 16:18:05 +02:00
};
if (
µb.userSettings.collapseBlocked &&
pageStore &&
pageStore.getNetFilteringSwitch()
) {
pageStore.getBlockedResources(request, response);
}
break;
case 'mouseClick':
µb.mouseEventRegister.tabId = tabId;
µb.mouseEventRegister.x = request.x;
µb.mouseEventRegister.y = request.y;
µb.mouseEventRegister.url = request.url;
break;
case 'shouldRenderNoscriptTags':
if ( pageStore === null ) { break; }
const fctxt = µb.filteringContext.fromTabId(tabId);
if ( pageStore.filterScripting(fctxt, undefined) ) {
vAPI.tabs.injectScript(
tabId,
{
file: '/js/scriptlets/noscript-spoof.js',
frameId: frameId,
runAt: 'document_end'
}
);
}
break;
case 'retrieveContentScriptParameters':
if (
pageStore === null ||
pageStore.getNetFilteringSwitch() === false ||
!request.url
) {
break;
}
const noCosmeticFiltering = pageStore.noCosmeticFiltering === true;
response = {
collapseBlocked: µb.userSettings.collapseBlocked,
noCosmeticFiltering,
noGenericCosmeticFiltering: noCosmeticFiltering,
};
// https://github.com/uBlockOrigin/uAssets/issues/5704
// `generichide` must be evaluated in the frame context.
if ( noCosmeticFiltering === false ) {
const genericHide =
µb.staticNetFilteringEngine.matchStringGenericHide(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);
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);
2016-03-06 16:51:06 +01:00
}
break;
case 'retrieveGenericCosmeticSelectors':
request.tabId = tabId;
request.frameId = frameId;
response = {
result: µb.cosmeticFilteringEngine.retrieveGenericSelectors(request)
};
break;
2014-06-27 23:06:42 +02:00
default:
return vAPI.messaging.UNHANDLED;
}
2014-06-24 00:42:43 +02:00
callback(response);
};
vAPI.messaging.listen({
name: 'contentscript',
listener: onMessage,
});
// <<<<< end of local scope
}
/******************************************************************************/
/******************************************************************************/
// Channel:
// elementPicker
// unprivileged
{
// >>>>> start of local scope
2014-09-28 18:05:46 +02:00
const onMessage = function(request, sender, callback) {
const µb = µBlock;
// Async
switch ( request.what ) {
2015-05-19 19:59:53 +02:00
case 'elementPickerArguments':
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'),
preview: vAPI.i18n('pickerPreview'),
2015-05-19 19:59:53 +02:00
netFilters: vAPI.i18n('pickerNetFilters'),
cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
};
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-05-19 19:59:53 +02:00
callback({
frameContent: this.responseText.replace(reStrings, replacer),
target: µb.epickerTarget,
2017-09-06 01:49:48 +02:00
clientX: µb.mouseEventRegister.x,
clientY: µb.mouseEventRegister.y,
2017-05-27 17:51:24 +02:00
zap: µb.epickerZap,
2015-05-19 19:59:53 +02:00
eprom: µb.epickerEprom
});
µb.epickerTarget = '';
2017-09-06 01:49:48 +02:00
µb.mouseEventRegister.x = µb.mouseEventRegister.y = -1;
2015-05-19 19:59:53 +02:00
};
xhr.send();
return;
default:
break;
}
2014-07-13 02:32:44 +02:00
// Sync
let response;
switch ( request.what ) {
// 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':
µb.epickerEprom = request;
break;
2015-05-19 19:59:53 +02:00
default:
return vAPI.messaging.UNHANDLED;
2014-07-13 02:32:44 +02:00
}
callback(response);
};
vAPI.messaging.listen({
name: 'elementPicker',
listener: onMessage,
});
2014-09-28 18:05:46 +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
// Channel:
// cloudWidget
// privileged
2015-08-11 21:29:14 +02:00
{
// >>>>> start of local scope
2015-08-11 21:29:14 +02:00
const onMessage = function(request, sender, callback) {
// Cloud storage support is optional.
if ( µBlock.cloudStorageSupported !== true ) {
callback();
return;
}
2015-08-11 21:29:14 +02:00
// Async
switch ( request.what ) {
case 'cloudGetOptions':
vAPI.cloud.getOptions(function(options) {
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':
return vAPI.cloud.pull(request.datakey, callback);
case 'cloudPush':
return vAPI.cloud.push(request.datakey, request.data, callback);
default:
break;
}
// Sync
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);
};
vAPI.messaging.listen({
name: 'cloudWidget',
listener: onMessage,
privileged: true,
});
// <<<<< end of local scope
}
/******************************************************************************/
/******************************************************************************/
// Channel:
// dashboard
// privileged
2014-07-17 16:52:43 +02:00
{
// >>>>> start of local scope
2014-07-17 16:52:43 +02:00
const µb = µBlock;
2014-09-28 18:05:46 +02:00
2016-03-06 16:51:06 +01:00
// Settings
const getLocalData = function(callback) {
const onStorageInfoReady = function(bytesInUse) {
const o = µb.restoreBackupSettings;
2014-10-07 14:59:35 +02:00
callback({
2015-03-07 05:36:09 +01:00
storageUsed: bytesInUse,
lastRestoreFile: o.lastRestoreFile,
lastRestoreTime: o.lastRestoreTime,
lastBackupFile: o.lastBackupFile,
lastBackupTime: o.lastBackupTime,
cloudStorageSupported: µb.cloudStorageSupported,
privacySettingsSupported: µb.privacySettingsSupported
2014-10-07 14:59:35 +02:00
});
};
2015-03-07 05:36:09 +01:00
µb.getBytesInUse(onStorageInfoReady);
};
const backupUserData = function(callback) {
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,
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(),
2017-12-14 22:42:54 +01:00
userFilters: ''
2017-01-26 16:17:38 +01:00
};
2015-04-16 18:14:43 +02:00
const onUserFiltersReady = function(details) {
2017-01-26 16:17:38 +01:00
userData.userFilters = details.content;
const filename = vAPI.i18n('aboutBackupFilename')
2016-10-13 19:25:57 +02:00
.replace('{{datetime}}', µb.dateNowToSensibleString())
2015-03-07 05:36:09 +01:00
.replace(/ +/g, '_');
µb.restoreBackupSettings.lastBackupFile = filename;
µb.restoreBackupSettings.lastBackupTime = Date.now();
2015-04-10 15:52:16 +02:00
vAPI.storage.set(µb.restoreBackupSettings);
2017-04-04 22:45:50 +02:00
getLocalData(function(localData) {
callback({ localData: localData, userData: userData });
});
2015-03-07 05:36:09 +01:00
};
2016-02-17 15:28:20 +01:00
µb.assets.get(µb.userFiltersPath, onUserFiltersReady);
2014-10-07 14:59:35 +02:00
};
const restoreUserData = function(request) {
const userData = request.userData;
2014-10-11 22:44:56 +02:00
const restart = function() {
vAPI.app.restart();
};
let countdown = 2;
const onAllRemoved = function() {
countdown -= 1;
if ( countdown !== 0 ) { return; }
2015-11-29 23:06:58 +01:00
µBlock.saveLocalSettings();
vAPI.storage.set(userData.userSettings);
let hiddenSettings = userData.hiddenSettings;
2018-02-21 19:29:36 +01:00
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');
}
2015-04-10 15:52:16 +02:00
vAPI.storage.set({
2018-02-21 19:29:36 +01:00
hiddenSettings: hiddenSettings,
netWhitelist: whitelist || [],
dynamicFilteringString: userData.dynamicFilteringString || '',
urlFilteringString: userData.urlFilteringString || '',
hostnameSwitchesString: userData.hostnameSwitchesString || '',
2015-03-07 05:36:09 +01:00
lastRestoreFile: request.file || '',
lastRestoreTime: Date.now(),
lastBackupFile: '',
lastBackupTime: 0
});
µb.assets.put(µb.userFiltersPath, userData.userFilters);
if ( Array.isArray(userData.selectedFilterLists) ) {
2017-12-14 22:42:54 +01:00
µb.saveSelectedFilterLists(userData.selectedFilterLists, restart);
} else {
restart();
}
2014-10-11 22:44:56 +02:00
};
2015-04-07 03:26:05 +02:00
// https://github.com/chrisaljoudi/uBlock/issues/1102
2015-03-27 14:50:31 +01:00
// Ensure all currently cached assets are flushed from storage AND memory.
µ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
// storage
µb.cacheStorage.clear().then(( ) => { onAllRemoved(); });
2015-04-10 08:17:12 +02:00
vAPI.storage.clear(onAllRemoved);
2018-02-21 19:29:36 +01:00
vAPI.localStorage.removeItem('immediateHiddenSettings');
2014-10-07 14:59:35 +02:00
};
// Remove all stored data but keep global counts, people can become
// quite attached to numbers
const resetUserData = function() {
let count = 3;
const countdown = ( ) => {
count -= 1;
if ( count === 0 ) {
vAPI.app.restart();
}
};
µb.cacheStorage.clear().then(( ) => countdown()); // 1
vAPI.storage.clear(countdown); // 2
µb.saveLocalSettings(countdown); // 3
2018-02-21 19:29:36 +01:00
vAPI.localStorage.removeItem('immediateHiddenSettings');
2014-10-07 14:59:35 +02:00
};
2016-03-06 16:51:06 +01:00
// 3rd-party filters
const prepListEntries = function(entries) {
const µburi = µb.URI;
for ( const k in entries ) {
if ( entries.hasOwnProperty(k) === false ) { continue; }
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 !== '' ) {
const hn = µburi.hostnameFromURI(entry.homeURL);
entry.supportURL = `http://${hn}/`;
2016-03-06 16:51:06 +01:00
entry.supportName = µburi.domainFromHostname(hn);
}
}
};
const getLists = function(callback) {
const r = {
2016-03-06 16:51:06 +01:00
autoUpdate: µb.userSettings.autoUpdate,
available: null,
cache: null,
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
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,
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
};
const onMetadataReady = function(entries) {
2016-03-06 16:51:06 +01:00
r.cache = entries;
prepListEntries(r.cache);
callback(r);
};
const onLists = function(lists) {
2016-03-06 16:51:06 +01:00
r.available = lists;
prepListEntries(r.available);
µb.assets.metadata(onMetadataReady);
};
µb.getAvailableLists(onLists);
};
// My rules
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
};
};
const modifyRuleset = function(details) {
2018-09-03 20:06:49 +02:00
let swRuleset, hnRuleset, urlRuleset;
if ( details.permanent ) {
2018-09-03 20:06:49 +02:00
swRuleset = µb.permanentSwitches;
hnRuleset = µb.permanentFirewall;
urlRuleset = µb.permanentURLFiltering;
} else {
2018-09-03 20:06:49 +02:00
swRuleset = µb.sessionSwitches;
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 ) {
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-09-03 20:06:49 +02:00
let toAdd = new Set(details.toAdd.trim().split(/\s*[\n\r]+\s*/));
for ( let rule of toAdd ) {
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);
}
}
}
if ( details.permanent ) {
2018-09-03 20:06:49 +02:00
if ( swRuleset.changed ) {
µb.saveHostnameSwitches();
swRuleset.changed = false;
}
if ( hnRuleset.changed ) {
µb.savePermanentFirewallRules();
hnRuleset.changed = false;
2016-03-06 16:51:06 +01:00
}
if ( urlRuleset.changed ) {
µb.savePermanentURLFilteringRules();
urlRuleset.changed = false;
2016-03-06 16:51:06 +01:00
}
}
};
// Shortcuts pane
const getShortcuts = function(callback) {
if ( µb.canUseShortcuts === false ) {
return callback([]);
}
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);
});
};
const setShortcut = function(details) {
if ( µb.canUpdateShortcuts === false ) { return; }
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) });
};
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':
return backupUserData(callback);
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':
return getLocalData(callback);
2014-06-24 00:42:43 +02:00
case 'getShortcuts':
return getShortcuts(callback);
2016-03-06 16:51:06 +01:00
case 'readUserFilters':
return µb.loadUserFilters(callback);
case 'writeUserFilters':
return µb.saveUserFilters(request.content, callback);
2015-05-19 19:59:53 +02:00
default:
break;
2014-06-24 00:42:43 +02:00
}
// Sync
var response;
switch ( request.what ) {
case 'canUpdateShortcuts':
response = µb.canUpdateShortcuts;
break;
2016-03-06 16:51:06 +01:00
case 'getRules':
response = getRules();
break;
case 'modifyRuleset':
// https://github.com/chrisaljoudi/uBlock/issues/772
µb.cosmeticFilteringEngine.removeFromSelectorCache('*');
modifyRuleset(request);
response = getRules();
break;
case 'purgeAllCaches':
if ( request.hard ) {
µb.assets.remove(/./);
} else {
µb.assets.purge(/./, 'public_suffix_list.dat');
}
break;
2016-03-06 16:51:06 +01:00
case 'purgeCache':
µb.assets.purge(request.assetKey);
µb.assets.remove('compiled/' + request.assetKey);
2016-03-06 16:51:06 +01:00
break;
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
case 'setShortcut':
setShortcut(request);
break;
case 'writeHiddenSettings':
µb.changeHiddenSettings(µb.hiddenSettingsFromString(request.content));
break;
2015-05-19 19:59:53 +02:00
default:
return vAPI.messaging.UNHANDLED;
2014-06-24 00:42:43 +02:00
}
callback(response);
};
vAPI.messaging.listen({
name: 'dashboard',
listener: onMessage,
privileged: true,
});
2014-06-24 00:42:43 +02:00
// <<<<< end of local scope
}
2014-06-24 00:42:43 +02:00
/******************************************************************************/
/******************************************************************************/
// Channel:
// loggerUI
// privileged
{
// >>>>> start of local scope
const µb = µBlock;
const extensionOriginURL = vAPI.getURL('');
const getLoggerData = function(details, activeTabId, callback) {
const response = {
colorBlind: µb.userSettings.colorBlindFriendly,
entries: µb.logger.readAll(details.ownerId),
maxEntries: µb.userSettings.requestLogMaxEntries,
activeTabId: activeTabId,
tabIdsToken: µb.pageStoresToken,
tooltips: µb.userSettings.tooltipsDisabled === false
};
if ( µb.pageStoresToken !== details.tabIdsToken ) {
const tabIds = new Map();
for ( const entry of µb.pageStores ) {
const pageStore = entry[1];
if ( pageStore.rawURL.startsWith(extensionOriginURL) ) { continue; }
tabIds.set(entry[0], pageStore.title);
}
response.tabIds = Array.from(tabIds);
}
if ( activeTabId ) {
const pageStore = µb.pageStoreFromTabId(activeTabId);
if (
pageStore === null ||
pageStore.rawURL.startsWith(extensionOriginURL)
) {
response.activeTabId = undefined;
}
}
if ( details.popupLoggerBoxChanged && browser.windows instanceof Object ) {
browser.tabs.query(
{ url: vAPI.getURL('/logger-ui.html?popup=1') },
tabs => {
if ( Array.isArray(tabs) === false ) { return; }
if ( tabs.length === 0 ) { return; }
browser.windows.get(tabs[0].windowId, win => {
if ( win instanceof Object === false ) { return; }
vAPI.localStorage.setItem(
'popupLoggerBox',
JSON.stringify({
left: win.left,
top: win.top,
width: win.width,
height: win.height,
})
);
});
}
);
}
callback(response);
};
const getURLFilteringData = function(details) {
const colors = {};
const response = {
2015-05-21 20:15:17 +02:00
dirty: false,
colors: colors
};
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;
colorEntry.own = suf.r !== 0 &&
suf.context === context &&
suf.url === url &&
suf.type === type;
2015-05-21 20:15:17 +02:00
}
if ( response.dirty ) { continue; }
2015-05-21 20:15:17 +02:00
puf.evaluateZ(context, url, type);
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;
};
const onMessage = function(request, sender, callback) {
// 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
) {
callback({ unavailable: true });
return;
2018-01-08 20:29:39 +01:00
}
vAPI.tabs.get(null, function(tab) {
getLoggerData(request, tab && tab.id, callback);
});
return;
default:
2015-05-19 19:59:53 +02:00
break;
}
// Sync
let response;
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;
}
callback(response);
};
vAPI.messaging.listen({
name: 'loggerUI',
listener: onMessage,
privileged: true,
});
// <<<<< end of local scope
}
2014-06-24 00:42:43 +02:00
/******************************************************************************/
2015-03-09 17:57:52 +01:00
/******************************************************************************/
// Channel:
// documentBlocked
// privileged
2015-03-26 00:28:22 +01:00
{
// >>>>> start of local scope
2015-03-26 00:28:22 +01: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
let response;
2015-03-26 00:28:22 +01:00
switch ( request.what ) {
case 'closeThisTab':
vAPI.tabs.remove(tabId);
break;
2015-05-19 19:59:53 +02:00
case 'temporarilyWhitelistDocument':
µ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);
};
vAPI.messaging.listen({
name: 'documentBlocked',
listener: onMessage,
privileged: true,
});
2015-03-26 00:28:22 +01:00
// <<<<< end of local scope
}
2015-03-09 17:57:52 +01:00
/******************************************************************************/
/******************************************************************************/
// Channel:
// scriptlets
// unprivileged
{
// >>>>> start of local scope
const µb = µBlock;
const broadcastTimers = new Map();
2016-08-06 18:05:01 +02:00
const domSurveyFinalReport = function(tabId) {
broadcastTimers.delete(tabId + '-domSurveyReport');
2016-08-06 18:05:01 +02:00
const pageStore = µb.pageStoreFromTabId(tabId);
if ( pageStore === null ) { return; }
2016-08-06 18:05:01 +02:00
vAPI.messaging.broadcast({
what: 'domSurveyFinalReport',
2016-08-06 18:05:01 +02:00
tabId: tabId,
affectedElementCount: pageStore.hiddenElementCount,
scriptCount: pageStore.scriptCount,
2016-08-06 18:05:01 +02: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() ) {
filter.raw = selector;
fctxt.toLogger();
}
};
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) {
const tabId = sender && sender.tab ? sender.tab.id : 0;
const pageStore = µb.pageStoreFromTabId(tabId);
2015-06-26 06:08:41 +02:00
// Async
switch ( request.what ) {
default:
break;
}
// Sync
let response;
switch ( request.what ) {
case 'applyFilterListSelection':
response = µb.applyFilterListSelection(request);
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
));
2016-08-06 18:05:01 +02:00
}
}
break;
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 ) {
fctxt.setRealm('network').toLogger();
}
}
break;
case 'logCosmeticFilteringData':
logCosmeticFilters(tabId, request);
break;
case 'reloadAllFilters':
µb.loadFilterLists();
return;
case 'securityPolicyViolation':
response = logCSPViolations(pageStore, request);
break;
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')
};
break;
default:
return vAPI.messaging.UNHANDLED;
}
callback(response);
};
vAPI.messaging.listen({
name: 'scriptlets',
listener: onMessage,
});
// <<<<< end of local scope
}
2015-06-26 06:08:41 +02:00
/******************************************************************************/
/******************************************************************************/