| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-present eyeo GmbH | 3  * Copyright (C) 2006-present eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 "use strict"; | 18 "use strict"; | 
| 19 | 19 | 
| 20 const {RegExpFilter, | 20 const {RegExpFilter, | 
| 21        WhitelistFilter, | 21        WhitelistFilter, | 
| 22        ElemHideFilter} = require("../adblockpluscore/lib/filterClasses"); | 22        ElemHideFilter} = require("../adblockpluscore/lib/filterClasses"); | 
| 23 const {SpecialSubscription} = | 23 const {SpecialSubscription} = | 
| 24   require("../adblockpluscore/lib/subscriptionClasses"); | 24   require("../adblockpluscore/lib/subscriptionClasses"); | 
| 25 const {FilterStorage} = require("../adblockpluscore/lib/filterStorage"); | 25 const {FilterStorage} = require("../adblockpluscore/lib/filterStorage"); | 
| 26 const {defaultMatcher} = require("../adblockpluscore/lib/matcher"); | 26 const {defaultMatcher} = require("../adblockpluscore/lib/matcher"); | 
| 27 const {FilterNotifier} = require("../adblockpluscore/lib/filterNotifier"); | 27 const {FilterNotifier} = require("../adblockpluscore/lib/filterNotifier"); | 
| 28 const {extractHostFromFrame} = require("./url"); | 28 const {extractHostFromFrame} = require("./url"); | 
| 29 const {port} = require("./messaging"); | 29 const {port} = require("./messaging"); | 
| 30 | 30 const {HitLogger, nonRequestTypes} = require("./hitLogger"); | 
| 31 const nonRequestTypes = ["DOCUMENT", "ELEMHIDE", |  | 
| 32                          "GENERICBLOCK", "GENERICHIDE", "CSP"]; |  | 
| 33 | 31 | 
| 34 let panels = new Map(); | 32 let panels = new Map(); | 
| 35 | 33 | 
| 36 function isActivePanel(panel) | 34 function isActivePanel(panel) | 
| 37 { | 35 { | 
| 38   return panel && !panel.reload && !panel.reloading; | 36   return panel && !panel.reload && !panel.reloading; | 
| 39 } | 37 } | 
| 40 | 38 | 
| 41 function getActivePanel(tabId) | 39 function getActivePanel(tabId) | 
| 42 { | 40 { | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 110   return defaultMatcher.matchesAny( | 108   return defaultMatcher.matchesAny( | 
| 111     request.url, | 109     request.url, | 
| 112     RegExpFilter.typeMap[request.type], | 110     RegExpFilter.typeMap[request.type], | 
| 113     request.docDomain, | 111     request.docDomain, | 
| 114     request.thirdParty, | 112     request.thirdParty, | 
| 115     request.sitekey, | 113     request.sitekey, | 
| 116     request.specificOnly | 114     request.specificOnly | 
| 117   ); | 115   ); | 
| 118 } | 116 } | 
| 119 | 117 | 
| 120 /** |  | 
| 121  * Logs a request to the devtools panel. |  | 
| 122  * |  | 
| 123  * @param {number[]} tabIds        The tabIds associated with the request |  | 
| 124  * @param {string}   url           The URL of the request |  | 
| 125  * @param {string}   type          The request type |  | 
| 126  * @param {string}   docDomain     The IDN-decoded hostname of the document |  | 
| 127  * @param {boolean}  thirdParty    Whether the origin of the request and |  | 
| 128  *                                 document differs |  | 
| 129  * @param {?string}  sitekey       The active sitekey if there is any |  | 
| 130  * @param {?boolean} specificOnly  Whether generic filters should be ignored |  | 
| 131  * @param {?BlockingFilter} filter The matched filter or null if there is no |  | 
| 132  *                                 match |  | 
| 133  */ |  | 
| 134 exports.logRequest = function(tabIds, url, type, docDomain, |  | 
| 135                               thirdParty, sitekey, |  | 
| 136                               specificOnly, filter) |  | 
| 137 { |  | 
| 138   for (let tabId of tabIds) |  | 
| 139   { |  | 
| 140     let panel = getActivePanel(tabId); |  | 
| 141     if (panel) |  | 
| 142     { |  | 
| 143       let request = {url, type, docDomain, thirdParty, sitekey, specificOnly}; |  | 
| 144       addRecord(panel, request, filter); |  | 
| 145     } |  | 
| 146   } |  | 
| 147 }; |  | 
| 148 |  | 
| 149 /** |  | 
| 150  * Logs active element hiding filters to the devtools panel. |  | 
| 151  * |  | 
| 152  * @param {number}   tabId      The ID of the tab, the elements were hidden in |  | 
| 153  * @param {string[]} selectors  The selectors of applied ElemHideFilters |  | 
| 154  * @param {string[]} filters    The text of applied ElemHideEmulationFilters |  | 
| 155  * @param {string}   docDomain  The IDN-decoded hostname of the document |  | 
| 156  */ |  | 
| 157 function logHiddenElements(tabId, selectors, filters, docDomain) |  | 
| 158 { |  | 
| 159   let panel = getActivePanel(tabId); |  | 
| 160   if (panel) |  | 
| 161   { |  | 
| 162     for (let subscription of FilterStorage.subscriptions) |  | 
| 163     { |  | 
| 164       if (subscription.disabled) |  | 
| 165         continue; |  | 
| 166 |  | 
| 167       for (let filter of subscription.filters) |  | 
| 168       { |  | 
| 169         // We only know the exact filter in case of element hiding emulation. |  | 
| 170         // For regular element hiding filters, the content script only knows |  | 
| 171         // the selector, so we have to find a filter that has an identical |  | 
| 172         // selector and is active on the domain the match was reported from. |  | 
| 173         let isActiveElemHideFilter = filter instanceof ElemHideFilter && |  | 
| 174                                      selectors.includes(filter.selector) && |  | 
| 175                                      filter.isActiveOnDomain(docDomain); |  | 
| 176 |  | 
| 177         if (isActiveElemHideFilter || filters.includes(filter.text)) |  | 
| 178           addRecord(panel, {type: "ELEMHIDE", docDomain}, filter); |  | 
| 179       } |  | 
| 180     } |  | 
| 181   } |  | 
| 182 } |  | 
| 183 |  | 
| 184 /** |  | 
| 185  * Logs a whitelisting filter, that disables (some kind of) |  | 
| 186  * blocking for a particular document, to the devtools panel. |  | 
| 187  * |  | 
| 188  * @param {number}       tabId     The tabId the whitelisting is active for |  | 
| 189  * @param {string}       url       The url of the whitelisted document |  | 
| 190  * @param {number}       typeMask  The bit mask of whitelisting types checked |  | 
| 191  *                                 for |  | 
| 192  * @param {string}       docDomain The IDN-decoded hostname of the parent |  | 
| 193  *                                 document |  | 
| 194  * @param {WhitelistFilter} filter The matched whitelisting filter |  | 
| 195  */ |  | 
| 196 exports.logWhitelistedDocument = function(tabId, url, typeMask, docDomain, |  | 
| 197                                           filter) |  | 
| 198 { |  | 
| 199   let panel = getActivePanel(tabId); |  | 
| 200   if (panel) |  | 
| 201   { |  | 
| 202     for (let type of nonRequestTypes) |  | 
| 203     { |  | 
| 204       if (typeMask & filter.contentType & RegExpFilter.typeMap[type]) |  | 
| 205         addRecord(panel, {url, type, docDomain}, filter); |  | 
| 206     } |  | 
| 207   } |  | 
| 208 }; |  | 
| 209 |  | 
| 210 /** |  | 
| 211  * Checks whether a tab is inspected by the devtools panel. |  | 
| 212  * |  | 
| 213  * @param {number} tabId |  | 
| 214  * @return {boolean} |  | 
| 215  */ |  | 
| 216 exports.hasPanel = function(tabId) |  | 
| 217 { |  | 
| 218   return panels.has(tabId); |  | 
| 219 }; |  | 
| 220 |  | 
| 221 function onBeforeRequest(details) | 118 function onBeforeRequest(details) | 
| 222 { | 119 { | 
| 223   let panel = panels.get(details.tabId); | 120   let panel = panels.get(details.tabId); | 
| 224 | 121 | 
| 225   // Clear the devtools panel and reload the inspected tab without caching | 122   // Clear the devtools panel and reload the inspected tab without caching | 
| 226   // when a new request is issued. However, make sure that we don't end up | 123   // when a new request is issued. However, make sure that we don't end up | 
| 227   // in an infinite recursion if we already triggered a reload. | 124   // in an infinite recursion if we already triggered a reload. | 
| 228   if (panel.reloading) | 125   if (panel.reloading) | 
| 229   { | 126   { | 
| 230     panel.reloading = false; | 127     panel.reloading = false; | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 335 } | 232 } | 
| 336 | 233 | 
| 337 browser.runtime.onConnect.addListener(newPort => | 234 browser.runtime.onConnect.addListener(newPort => | 
| 338 { | 235 { | 
| 339   let match = newPort.name.match(/^devtools-(\d+)$/); | 236   let match = newPort.name.match(/^devtools-(\d+)$/); | 
| 340   if (!match) | 237   if (!match) | 
| 341     return; | 238     return; | 
| 342 | 239 | 
| 343   let inspectedTabId = parseInt(match[1], 10); | 240   let inspectedTabId = parseInt(match[1], 10); | 
| 344   let localOnBeforeRequest = onBeforeRequest.bind(); | 241   let localOnBeforeRequest = onBeforeRequest.bind(); | 
|  | 242   let panel = {port: newPort, records: []}; | 
|  | 243   let hitListener = addRecord.bind(null, panel); | 
| 345 | 244 | 
| 346   browser.webRequest.onBeforeRequest.addListener( | 245   browser.webRequest.onBeforeRequest.addListener( | 
| 347     localOnBeforeRequest, | 246     localOnBeforeRequest, | 
| 348     { | 247     { | 
| 349       urls: ["http://*/*", "https://*/*"], | 248       urls: ["http://*/*", "https://*/*"], | 
| 350       types: ["main_frame"], | 249       types: ["main_frame"], | 
| 351       tabId: inspectedTabId | 250       tabId: inspectedTabId | 
| 352     } | 251     } | 
| 353   ); | 252   ); | 
| 354 | 253 | 
| 355   if (panels.size == 0) | 254   if (panels.size == 0) | 
| 356   { | 255   { | 
| 357     ext.pages.onLoading.addListener(onLoading); | 256     ext.pages.onLoading.addListener(onLoading); | 
| 358     FilterNotifier.on("filter.added", onFilterAdded); | 257     FilterNotifier.on("filter.added", onFilterAdded); | 
| 359     FilterNotifier.on("filter.removed", onFilterRemoved); | 258     FilterNotifier.on("filter.removed", onFilterRemoved); | 
| 360     FilterNotifier.on("subscription.added", onSubscriptionAdded); | 259     FilterNotifier.on("subscription.added", onSubscriptionAdded); | 
| 361   } | 260   } | 
| 362 | 261 | 
| 363   newPort.onDisconnect.addListener(() => | 262   newPort.onDisconnect.addListener(() => | 
| 364   { | 263   { | 
|  | 264     HitLogger.removeListener(inspectedTabId, hitListener); | 
| 365     panels.delete(inspectedTabId); | 265     panels.delete(inspectedTabId); | 
| 366     browser.webRequest.onBeforeRequest.removeListener(localOnBeforeRequest); | 266     browser.webRequest.onBeforeRequest.removeListener(localOnBeforeRequest); | 
| 367 | 267 | 
| 368     if (panels.size == 0) | 268     if (panels.size == 0) | 
| 369     { | 269     { | 
| 370       ext.pages.onLoading.removeListener(onLoading); | 270       ext.pages.onLoading.removeListener(onLoading); | 
| 371       FilterNotifier.off("filter.added", onFilterAdded); | 271       FilterNotifier.off("filter.added", onFilterAdded); | 
| 372       FilterNotifier.off("filter.removed", onFilterRemoved); | 272       FilterNotifier.off("filter.removed", onFilterRemoved); | 
| 373       FilterNotifier.off("subscription.added", onSubscriptionAdded); | 273       FilterNotifier.off("subscription.added", onSubscriptionAdded); | 
| 374     } | 274     } | 
| 375   }); | 275   }); | 
| 376 | 276 | 
| 377   panels.set(inspectedTabId, {port: newPort, records: []}); | 277   HitLogger.addListener(inspectedTabId, hitListener); | 
|  | 278   panels.set(inspectedTabId, panel); | 
| 378 }); | 279 }); | 
| 379 |  | 
| 380 port.on("devtools.traceElemHide", (message, sender) => |  | 
| 381 { |  | 
| 382   logHiddenElements( |  | 
| 383     sender.page.id, message.selectors, message.filters, |  | 
| 384     extractHostFromFrame(sender.frame) |  | 
| 385   ); |  | 
| 386 }); |  | 
| OLD | NEW | 
|---|