| 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"); |
| + }); |
| +}); |