Index: lib/requestBlocker.js |
=================================================================== |
rename from webrequest.js |
rename to lib/requestBlocker.js |
--- a/webrequest.js |
+++ b/lib/requestBlocker.js |
@@ -15,41 +15,28 @@ |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
-var FilterNotifier = require("filterNotifier").FilterNotifier; |
-var RegExpFilter = require("filterClasses").RegExpFilter; |
-var platform = require("info").platform; |
-var devtools = require("devtools"); |
+/** @module requestBlocker */ |
-ext.webRequest.getIndistinguishableTypes().forEach(function(types) |
+"use strict"; |
+ |
+let {RegExpFilter, BlockingFilter} = require("filterClasses"); |
+let {defaultMatcher} = require("matcher"); |
+let {FilterNotifier} = require("filterNotifier"); |
+let {Prefs} = require("prefs"); |
+let {checkWhitelisted, getKey} = require("whitelisting"); |
+let {stringifyURL, extractHostFromFrame, isThirdParty} = require("url"); |
+let {port} = require("messaging"); |
+let devtools = require("devtools"); |
+ |
+ext.webRequest.getIndistinguishableTypes().forEach(types => |
{ |
- for (var i = 1; i < types.length; i++) |
+ for (let i = 1; i < types.length; i++) |
RegExpFilter.typeMap[types[i]] = RegExpFilter.typeMap[types[0]]; |
}); |
-FilterNotifier.addListener(function(action, arg) |
-{ |
- switch (action) |
- { |
- case "filter.added": |
- case "filter.removed": |
- case "filter.disabled": |
- // Only request blocking/whitelisting filters have |
- // an effect on the webRequest handler behavior. |
- if (!(arg instanceof RegExpFilter)) |
- break; |
- case "subscription.added": |
- case "subscription.removed": |
- case "subscription.disabled": |
- case "subscription.updated": |
- case "load": |
- ext.webRequest.handlerBehaviorChanged(); |
- break; |
- } |
-}); |
- |
function onBeforeRequestAsync(page, url, type, docDomain, |
- thirdParty, key, specificOnly, |
- filter) |
+ thirdParty, sitekey, |
+ specificOnly, filter) |
{ |
if (filter) |
FilterNotifier.triggerListeners("filter.hitCount", filter, 0, 0, page); |
@@ -57,64 +44,125 @@ |
if (devtools) |
devtools.logRequest( |
page, url, type, docDomain, |
- thirdParty, key, specificOnly, |
- filter |
+ thirdParty, sitekey, |
+ specificOnly, filter |
); |
} |
-function onBeforeRequest(url, type, page, frame) |
+ext.webRequest.onBeforeRequest.addListener((url, type, page, frame) => |
{ |
if (checkWhitelisted(page, frame)) |
return true; |
- var urlString = stringifyURL(url); |
- var docDomain = extractHostFromFrame(frame); |
- var thirdParty = isThirdParty(url, docDomain); |
- var key = getKey(page, frame); |
+ let urlString = stringifyURL(url); |
+ let docDomain = extractHostFromFrame(frame); |
+ let thirdParty = isThirdParty(url, docDomain); |
+ let sitekey = getKey(page, frame); |
- var specificOnly = !!checkWhitelisted( |
+ let specificOnly = !!checkWhitelisted( |
page, frame, RegExpFilter.typeMap.GENERICBLOCK |
); |
- var filter = defaultMatcher.matchesAny( |
+ let filter = defaultMatcher.matchesAny( |
urlString, RegExpFilter.typeMap[type], |
- docDomain, thirdParty, key, specificOnly |
+ docDomain, thirdParty, sitekey, specificOnly |
); |
setTimeout(onBeforeRequestAsync, 0, page, urlString, |
type, docDomain, |
- thirdParty, key, |
+ thirdParty, sitekey, |
specificOnly, filter); |
return !(filter instanceof BlockingFilter); |
-} |
+}); |
-ext.webRequest.onBeforeRequest.addListener(onBeforeRequest); |
+port.on("filters.collapse", (message, sender) => |
+{ |
+ if (checkWhitelisted(sender.page, sender.frame)) |
+ return false; |
-if (platform == "chromium") |
-{ |
- function onHeadersReceived(details) |
+ let typeMask = RegExpFilter.typeMap[message.mediatype]; |
+ let documentHost = extractHostFromFrame(sender.frame); |
+ let sitekey = getKey(sender.page, sender.frame); |
+ let blocked = false; |
+ |
+ let specificOnly = checkWhitelisted( |
+ sender.page, sender.frame, |
+ RegExpFilter.typeMap.GENERICBLOCK |
+ ); |
+ |
+ for (let url of message.urls) |
{ |
- var page = new ext.Page({id: details.tabId}); |
- var frame = ext.getFrame(details.tabId, details.frameId); |
+ let urlObj = new URL(url, message.baseURL); |
+ let filter = defaultMatcher.matchesAny( |
+ stringifyURL(urlObj), |
+ typeMask, documentHost, |
+ isThirdParty(urlObj, documentHost), |
+ sitekey, specificOnly |
+ ); |
- if (!frame || frame.url.href != details.url) |
- return; |
- |
- for (var i = 0; i < details.responseHeaders.length; i++) |
+ if (filter instanceof BlockingFilter) |
{ |
- var header = details.responseHeaders[i]; |
- if (header.name.toLowerCase() == "x-adblock-key" && header.value) |
- processKey(header.value, page, frame); |
+ if (filter.collapse != null) |
+ return filter.collapse; |
+ blocked = true; |
} |
} |
- chrome.webRequest.onHeadersReceived.addListener( |
- onHeadersReceived, |
+ return blocked && Prefs.hidePlaceholders; |
+}); |
+ |
+let ignoreFilterNotifications = false; |
+FilterNotifier.addListener((action, arg) => |
+{ |
+ // Avoid triggering filters.behaviorChanged multiple times |
+ // when multiple filter hanges happen at the same time. |
+ if (ignoreFilterNotifications) |
+ return; |
+ |
+ if (action != "load") |
+ { |
+ let parts = action.split("."); |
+ let [category, event] = parts; |
+ if (category == "subscription") |
{ |
- urls: ["http://*/*", "https://*/*"], |
- types: ["main_frame", "sub_frame"] |
- }, |
- ["responseHeaders"] |
- ); |
-} |
+ if (event != "added" && |
+ event != "removed" && |
+ event != "updated" && |
+ event != "disabled") |
+ return; |
+ |
+ // Ignore empty subscriptions. This includes subscriptions |
+ // that have just been added, but not downloaded yet. |
+ if (arg.filters.length == 0) |
+ return; |
+ } |
+ else if (category == "filter") |
+ { |
+ if (event != "added" && |
+ event != "removed" && |
+ event != "disabled") |
+ return; |
+ |
+ // Ignore all types of filters but request filters, |
+ // only these have an effect on the handler behavior. |
+ if (!(arg instanceof RegExpFilter)) |
+ return; |
+ } |
+ else |
+ return; |
+ |
+ // Ignore disabled subscriptions and filters, unless they just got |
+ // disabled, otherwise they have no effect on the handler behavior. |
+ if (arg.disabled && event != "disabled") |
+ return; |
+ } |
+ |
+ ignoreFilterNotifications = true; |
+ setTimeout(() => |
+ { |
+ ignoreFilterNotifications = false; |
+ ext.webRequest.handlerBehaviorChanged(); |
+ FilterNotifier.triggerListeners("filter.behaviorChanged"); |
+ }); |
+}); |