uBlock/js/messaging-handlers.js

725 lines
20 KiB
JavaScript
Raw Normal View History

2014-06-23 16:42:43 -06:00
/*******************************************************************************
µBlock - a Chromium browser extension to block requests.
Copyright (C) 2014 Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
2014-08-02 09:40:27 -06:00
/* global chrome, µBlock, YaMD5 */
2014-06-23 16:42:43 -06:00
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
/******************************************************************************/
2014-09-28 10:05:46 -06:00
// popup.js
2014-06-23 16:42:43 -06:00
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
var µb = µBlock;
2014-06-23 16:42:43 -06:00
/******************************************************************************/
2014-10-06 12:02:44 -06:00
var getDynamicFilterResults = function(scope) {
return [
µb.netFilteringEngine.matchDynamicFilters(scope, 'inline-script', true),
µb.netFilteringEngine.matchDynamicFilters(scope, 'script', true),
µb.netFilteringEngine.matchDynamicFilters(scope, 'script', false),
µb.netFilteringEngine.matchDynamicFilters(scope, 'sub_frame', true),
µb.netFilteringEngine.matchDynamicFilters(scope, 'sub_frame', false)
];
};
/******************************************************************************/
2014-07-02 10:02:29 -06:00
var getStats = function(request) {
2014-06-23 16:42:43 -06:00
var r = {
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
globalAllowedRequestCount: µb.localSettings.allowedRequestCount,
tabId: request.tabId,
pageURL: '',
pageBlockedRequestCount: 0,
pageAllowedRequestCount: 0,
netFilteringSwitch: false,
2014-07-02 10:02:29 -06:00
cosmeticFilteringSwitch: false,
2014-10-06 12:02:44 -06:00
logRequests: µb.userSettings.logRequests,
dynamicFilteringEnabled: µb.userSettings.dynamicFilteringEnabled,
dynamicFilterResults: {
'/': getDynamicFilterResults('*')
}
2014-06-23 16:42:43 -06:00
};
var pageStore = µb.pageStoreFromTabId(request.tabId);
if ( pageStore ) {
r.pageURL = pageStore.pageURL;
r.pageHostname = pageStore.pageHostname;
r.pageBlockedRequestCount = pageStore.perLoadBlockedRequestCount;
r.pageAllowedRequestCount = pageStore.perLoadAllowedRequestCount;
2014-08-02 09:40:27 -06:00
r.netFilteringSwitch = pageStore.getNetFilteringSwitch();
2014-10-06 12:02:44 -06:00
r.dynamicFilterResults['.'] = getDynamicFilterResults(r.pageHostname);
2014-06-23 16:42:43 -06:00
}
return r;
};
/******************************************************************************/
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
2014-10-06 12:02:44 -06:00
case 'gotoPick':
// Picker launched from popup: clear context menu args
µb.contextMenuClientX = -1;
µb.contextMenuClientY = -1;
µb.elementPickerExec(request.tabId);
break;
2014-06-23 16:42:43 -06:00
case 'stats':
response = getStats(request);
break;
case 'toggleNetFiltering':
2014-09-28 10:05:46 -06:00
µb.toggleNetFilteringSwitch(
2014-08-02 09:40:27 -06:00
request.url,
request.scope,
2014-06-23 16:42:43 -06:00
request.state
);
2014-09-28 10:05:46 -06:00
µb.updateBadgeAsync(request.tabId);
2014-06-23 16:42:43 -06:00
break;
2014-10-06 12:02:44 -06:00
case 'toggleDynamicFilter':
µb.toggleDynamicFilter(request);
response = { '/': getDynamicFilterResults('*') };
if ( request.pageHostname ) {
response['.'] = getDynamicFilterResults(request.pageHostname);
}
2014-07-12 18:32:44 -06:00
break;
2014-06-23 16:42:43 -06:00
default:
2014-09-28 10:05:46 -06:00
return µb.messaging.defaultHandler(request, sender, callback);
2014-06-23 16:42:43 -06:00
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('popup.js', onMessage);
/******************************************************************************/
2014-06-23 16:42:43 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
/******************************************************************************/
2014-06-27 15:06:42 -06:00
// contentscript-start.js
2014-06-23 16:42:43 -06:00
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-08-02 09:40:27 -06:00
var µb = µBlock;
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
2014-06-23 17:23:36 -06:00
var pageStore;
if ( sender && sender.tab ) {
2014-08-02 09:40:27 -06:00
pageStore = µb.pageStoreFromTabId(sender.tab.id);
2014-06-23 17:23:36 -06:00
}
2014-06-23 16:42:43 -06:00
switch ( request.what ) {
case 'retrieveDomainCosmeticSelectors':
2014-08-02 09:40:27 -06:00
if ( pageStore && pageStore.getNetFilteringSwitch() ) {
2014-09-08 15:46:58 -06:00
response = µb.cosmeticFilteringEngine.retrieveDomainSelectors(request);
2014-08-02 09:40:27 -06:00
}
2014-06-23 16:42:43 -06:00
break;
2014-06-27 15:06:42 -06:00
default:
2014-08-02 09:40:27 -06:00
return µb.messaging.defaultHandler(request, sender, callback);
2014-06-27 15:06:42 -06:00
}
callback(response);
};
2014-08-02 09:40:27 -06:00
µb.messaging.listen('contentscript-start.js', onMessage);
2014-06-27 15:06:42 -06:00
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-06-27 15:06:42 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-27 15:06:42 -06:00
/******************************************************************************/
// contentscript-end.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-08-02 09:40:27 -06:00
var µb = µBlock;
2014-09-14 14:20:40 -06:00
/******************************************************************************/
var tagNameToRequestTypeMap = {
'embed': 'object',
'iframe': 'sub_frame',
'img': 'image',
'object': 'object'
};
/******************************************************************************/
// Evaluate many requests
var filterRequests = function(pageStore, details) {
details.pageDomain = µb.URI.domainFromHostname(details.pageHostname);
details.rootHostname = pageStore.rootHostname;
details.rootDomain = pageStore.rootDomain;
2014-09-14 14:20:40 -06:00
var inRequests = details.requests;
var outRequests = [];
var request, result;
var i = inRequests.length;
while ( i-- ) {
request = inRequests[i];
if ( tagNameToRequestTypeMap.hasOwnProperty(request.tagName) === false ) {
continue;
}
result = pageStore.filterRequest(
details,
tagNameToRequestTypeMap[request.tagName],
request.url
);
if ( pageStore.boolFromResult(result) ) {
outRequests.push(request);
}
}
return {
collapse: µb.userSettings.collapseBlocked,
requests: outRequests
};
};
/******************************************************************************/
// Evaluate a single request
var filterRequest = function(pageStore, details) {
if ( tagNameToRequestTypeMap.hasOwnProperty(details.tagName) === false ) {
return;
}
details.pageDomain = µb.URI.domainFromHostname(details.pageHostname);
details.rootHostname = pageStore.rootHostname;
details.rootDomain = pageStore.rootDomain;
2014-09-14 14:20:40 -06:00
var result = pageStore.filterRequest(
details,
tagNameToRequestTypeMap[details.tagName],
details.requestURL
);
if ( pageStore.boolFromResult(result) ) {
return { collapse: µb.userSettings.collapseBlocked };
}
};
/******************************************************************************/
var onMessage = function(details, sender, callback) {
2014-06-27 15:06:42 -06:00
// Async
2014-09-14 14:20:40 -06:00
switch ( details.what ) {
2014-06-27 15:06:42 -06:00
default:
break;
}
// Sync
var response;
var pageStore;
if ( sender && sender.tab ) {
2014-08-02 09:40:27 -06:00
pageStore = µb.pageStoreFromTabId(sender.tab.id);
2014-06-27 15:06:42 -06:00
}
2014-09-14 14:20:40 -06:00
switch ( details.what ) {
2014-06-23 16:42:43 -06:00
case 'retrieveGenericCosmeticSelectors':
2014-08-02 09:40:27 -06:00
if ( pageStore && pageStore.getNetFilteringSwitch() ) {
2014-09-14 14:20:40 -06:00
response = µb.cosmeticFilteringEngine.retrieveGenericSelectors(details);
2014-08-02 09:40:27 -06:00
}
2014-06-23 16:42:43 -06:00
break;
case 'injectedSelectors':
2014-09-14 14:20:40 -06:00
µb.cosmeticFilteringEngine.addToSelectorCache(details);
2014-06-27 15:06:42 -06:00
break;
2014-09-14 14:20:40 -06:00
// Evaluate many requests
case 'filterRequests':
if ( pageStore && pageStore.getNetFilteringSwitch() ) {
response = filterRequests(pageStore, details);
}
2014-08-15 08:34:13 -06:00
break;
2014-09-14 14:20:40 -06:00
// Evaluate a single request
case 'filterRequest':
if ( pageStore && pageStore.getNetFilteringSwitch() ) {
response = filterRequest(pageStore, details);
}
2014-06-29 10:38:18 -06:00
break;
2014-06-23 16:42:43 -06:00
default:
2014-09-14 14:20:40 -06:00
return µb.messaging.defaultHandler(details, sender, callback);
2014-06-23 16:42:43 -06:00
}
callback(response);
};
2014-08-02 09:40:27 -06:00
µb.messaging.listen('contentscript-end.js', onMessage);
2014-07-12 18:32:44 -06:00
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-07-12 18:32:44 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-07-12 18:32:44 -06:00
/******************************************************************************/
// element-picker.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
var µb = µBlock;
/******************************************************************************/
2014-07-12 18:32:44 -06:00
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
2014-09-28 10:05:46 -06:00
case 'elementPickerArguments':
2014-07-12 18:32:44 -06:00
response = {
2014-09-28 10:05:46 -06:00
i18n: {
create: chrome.i18n.getMessage('pickerCreate'),
pick: chrome.i18n.getMessage('pickerPick'),
quit: chrome.i18n.getMessage('pickerQuit'),
netFilters: chrome.i18n.getMessage('pickerNetFilters'),
cosmeticFilters: chrome.i18n.getMessage('pickerCosmeticFilters'),
cosmeticFiltersHint: chrome.i18n.getMessage('pickerCosmeticFiltersHint')
},
2014-09-28 12:38:17 -06:00
target: µb.contextMenuTarget,
clientX: µb.contextMenuClientX,
clientY: µb.contextMenuClientY
2014-07-12 18:32:44 -06:00
};
2014-09-28 12:38:17 -06:00
µb.contextMenuTarget = '';
µb.contextMenuClientX = -1;
µb.contextMenuClientY = -1;
2014-07-12 18:32:44 -06:00
break;
case 'createUserFilter':
2014-09-28 10:05:46 -06:00
µb.appendUserFilters(request.filters);
2014-07-12 18:32:44 -06:00
break;
default:
2014-09-28 10:05:46 -06:00
return µb.messaging.defaultHandler(request, sender, callback);
2014-07-12 18:32:44 -06:00
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('element-picker.js', onMessage);
/******************************************************************************/
2014-06-23 16:42:43 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
/******************************************************************************/
// 3p-filters.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
var µb = µBlock;
/******************************************************************************/
2014-07-25 14:12:20 -06:00
var getLists = function(callback) {
2014-07-26 14:10:20 -06:00
var r = {
available: null,
current: µb.remoteBlacklists,
cosmetic: µb.userSettings.parseAllABPHideFilters,
2014-09-08 15:46:58 -06:00
netFilterCount: µb.netFilteringEngine.getFilterCount(),
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
autoUpdate: µb.userSettings.autoUpdate,
2014-08-20 08:26:57 -06:00
userFiltersPath: µb.userFiltersPath,
2014-07-26 14:10:20 -06:00
cache: null
};
var onMetadataReady = function(entries) {
2014-07-26 14:10:20 -06:00
r.cache = entries;
2014-09-08 17:45:22 -06:00
callback(r);
2014-07-26 14:10:20 -06:00
};
var onLists = function(lists) {
r.available = lists;
2014-09-08 17:45:22 -06:00
µb.assets.metadata(onMetadataReady);
2014-07-25 14:12:20 -06:00
};
2014-07-26 14:10:20 -06:00
µb.getAvailableLists(onLists);
2014-07-25 14:12:20 -06:00
};
/******************************************************************************/
2014-06-23 16:42:43 -06:00
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
2014-07-25 14:12:20 -06:00
case 'getLists':
return getLists(callback);
2014-09-08 17:45:22 -06:00
case 'purgeAllCaches':
return µb.assets.purgeAll(callback);
2014-06-23 16:42:43 -06:00
case 'writeUserUbiquitousBlockRules':
return µb.assets.put(µb.userFiltersPath, request.content, callback);
default:
break;
}
// Sync
var response;
switch ( request.what ) {
2014-07-26 14:10:20 -06:00
case 'purgeCache':
µb.assets.purge(request.path);
break;
2014-06-23 16:42:43 -06:00
default:
return µb.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('3p-filters.js', onMessage);
/******************************************************************************/
2014-06-23 16:42:43 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
/******************************************************************************/
// 1p-filters.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
2014-09-28 10:05:46 -06:00
var µb = µBlock;
/******************************************************************************/
var onMessage = function(request, sender, callback) {
2014-06-23 16:42:43 -06:00
// Async
switch ( request.what ) {
case 'readUserFilters':
return µb.assets.get(µb.userFiltersPath, callback);
case 'writeUserFilters':
return µb.assets.put(µb.userFiltersPath, request.content, callback);
default:
break;
}
// Sync
var response;
switch ( request.what ) {
default:
return µb.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('1p-filters.js', onMessage);
/******************************************************************************/
2014-06-23 16:42:43 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
/******************************************************************************/
2014-07-17 08:52:43 -06:00
// whitelist.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-07-17 08:52:43 -06:00
2014-09-28 10:05:46 -06:00
var µb = µBlock;
/******************************************************************************/
var onMessage = function(request, sender, callback) {
2014-07-17 08:52:43 -06:00
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
case 'getWhitelist':
2014-08-02 09:40:27 -06:00
response = µb.stringFromWhitelist(µb.netWhitelist);
2014-07-17 08:52:43 -06:00
break;
case 'setWhitelist':
2014-08-02 09:40:27 -06:00
µb.netWhitelist = µb.whitelistFromString(request.whitelist);
2014-07-17 08:52:43 -06:00
µb.saveWhitelist();
break;
default:
return µb.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('whitelist.js', onMessage);
/******************************************************************************/
2014-07-17 08:52:43 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-07-17 08:52:43 -06:00
/******************************************************************************/
2014-07-02 10:02:29 -06:00
// stats.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
var µb = µBlock;
/******************************************************************************/
2014-07-02 10:02:29 -06:00
var getPageDetails = function(µb, tabId) {
var r = {
2014-07-06 17:14:32 -06:00
blockedRequests: [],
allowedRequests: [],
2014-07-02 10:02:29 -06:00
hash: ''
};
var pageStore = µb.pageStores[tabId];
if ( !pageStore ) {
return r;
}
2014-09-14 14:20:40 -06:00
var prepareRequests = function(wantBlocked, hasher) {
2014-08-27 12:01:38 -06:00
var µburi = µb.URI;
2014-09-14 14:20:40 -06:00
var dict = pageStore.netFilteringCache.fetchAll();
2014-07-06 17:14:32 -06:00
var r = [];
2014-10-02 14:45:26 -06:00
var details, hostname, domain;
2014-09-14 14:20:40 -06:00
for ( var url in dict ) {
if ( dict.hasOwnProperty(url) === false ) {
2014-07-06 17:14:32 -06:00
continue;
}
2014-10-02 14:45:26 -06:00
details = dict[url];
if ( wantBlocked !== pageStore.boolFromResult(details.result) ) {
2014-09-14 14:20:40 -06:00
continue;
2014-08-27 12:01:38 -06:00
}
2014-09-14 14:20:40 -06:00
hasher.appendStr(url);
2014-10-02 14:45:26 -06:00
hasher.appendStr(details.result);
2014-09-14 14:20:40 -06:00
hostname = µburi.hostnameFromURI(url);
domain = µburi.domainFromHostname(hostname) || hostname;
2014-07-06 17:14:32 -06:00
r.push({
2014-09-14 14:20:40 -06:00
url: url,
2014-10-02 14:45:26 -06:00
domain: domain,
reason: details.result,
type: details.type,
flags: details.flags
2014-07-06 17:14:32 -06:00
});
2014-07-02 10:02:29 -06:00
}
2014-07-06 17:14:32 -06:00
return r;
2014-07-06 19:52:16 -06:00
};
2014-07-06 17:14:32 -06:00
var hasher = new YaMD5();
2014-09-14 14:20:40 -06:00
if ( µb.userSettings.logRequests ) {
r.blockedRequests = prepareRequests(true, hasher);
r.allowedRequests = prepareRequests(false, hasher);
2014-07-02 10:02:29 -06:00
}
r.hash = hasher.end();
return r;
};
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-07-02 10:02:29 -06:00
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
case 'getPageSelectors':
response = Object.keys(µb.pageStores);
break;
case 'getPageDetails':
response = getPageDetails(µb, request.tabId);
break;
default:
return µb.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('stats.js', onMessage);
/******************************************************************************/
2014-07-02 10:02:29 -06:00
})();
2014-09-14 14:20:40 -06:00
/******************************************************************************/
2014-07-02 10:02:29 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
// about.js
(function() {
2014-09-28 10:05:46 -06:00
/******************************************************************************/
2014-06-23 16:42:43 -06:00
2014-09-28 10:05:46 -06:00
var µb = µBlock;
/******************************************************************************/
2014-10-07 06:59:35 -06:00
var getUserData = function(callback) {
var onUserFiltersReady = function(details) {
callback({
'timeStamp': Date.now(),
'version': µb.manifest.version,
'userSettings': µb.userSettings,
'filterLists': µb.remoteBlacklists,
'netWhitelist': µb.stringFromWhitelist(µb.netWhitelist),
'userFilters': details.content
});
};
µb.assets.get('assets/user/filters.txt', onUserFiltersReady);
};
/******************************************************************************/
var restoreUserData = function(userData) {
2014-10-11 14:44:56 -06:00
var countdown = 5;
var onCountdown = function() {
countdown -= 1;
if ( countdown === 0 ) {
µb.XAL.restart();
}
};
var onAllRemoved = function() {
// Be sure to adjust `countdown` if adding/removing anything below
µBlock.saveLocalSettings(onCountdown);
µb.XAL.keyvalSetMany(userData.userSettings, onCountdown);
µb.XAL.keyvalSetOne('remoteBlacklists', userData.filterLists, onCountdown);
µb.XAL.keyvalSetOne('netWhitelist', userData.netWhitelist, onCountdown);
µb.assets.put('assets/user/filters.txt', userData.userFilters, onCountdown);
};
2014-10-07 08:46:10 -06:00
// If we are going to restore all, might as well wipe out clean local
// storage
2014-10-11 14:44:56 -06:00
µb.XAL.keyvalRemoveAll(onAllRemoved);
2014-10-07 06:59:35 -06:00
};
/******************************************************************************/
var resetUserData = function() {
2014-10-07 08:46:10 -06:00
µb.XAL.keyvalRemoveAll();
2014-10-07 06:59:35 -06:00
// Keep global counts, people can become quite attached to numbers
2014-10-07 08:46:10 -06:00
µBlock.saveLocalSettings();
µb.XAL.restart();
2014-10-07 06:59:35 -06:00
};
/******************************************************************************/
2014-09-28 10:05:46 -06:00
var onMessage = function(request, sender, callback) {
2014-06-23 16:42:43 -06:00
// Async
switch ( request.what ) {
2014-10-07 06:59:35 -06:00
case 'getUserData':
return getUserData(callback);
2014-06-23 16:42:43 -06:00
default:
break;
}
// Sync
var response;
switch ( request.what ) {
2014-10-07 06:59:35 -06:00
case 'restoreUserData':
restoreUserData(request.userData);
break;
case 'resetUserData':
resetUserData();
break;
2014-06-23 16:42:43 -06:00
default:
return µb.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
2014-09-28 10:05:46 -06:00
µb.messaging.listen('about.js', onMessage);
/******************************************************************************/
2014-06-23 16:42:43 -06:00
})();
// https://www.youtube.com/watch?v=3_WcygKJP1k
2014-06-23 16:42:43 -06:00
/******************************************************************************/