| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|  | 3  * Copyright (C) 2006-present eyeo GmbH | 
|  | 4  * | 
|  | 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 | 
|  | 7  * published by the Free Software Foundation. | 
|  | 8  * | 
|  | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
|  | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 12  * GNU General Public License for more details. | 
|  | 13  * | 
|  | 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/>. | 
|  | 16  */ | 
|  | 17 | 
|  | 18 /** @module hitLogger */ | 
|  | 19 | 
|  | 20 "use strict"; | 
|  | 21 | 
|  | 22 const {desc} = require("coreUtils"); | 
|  | 23 const {extractHostFromFrame} = require("url"); | 
|  | 24 const {EventEmitter} = require("events"); | 
|  | 25 const {FilterStorage} = require("filterStorage"); | 
|  | 26 const {port} = require("messaging"); | 
|  | 27 const {RegExpFilter, ElemHideFilter} = require("filterClasses"); | 
|  | 28 | 
|  | 29 const nonRequestTypes = ["DOCUMENT", "ELEMHIDE", "GENERICBLOCK", "GENERICHIDE"]; | 
|  | 30 | 
|  | 31 let HitLogger = exports.HitLogger = Object.create(new EventEmitter(), desc({ | 
|  | 32   off(tabId, listener) | 
|  | 33   { | 
|  | 34     this.__proto__.off(tabId, listener); | 
|  | 35 | 
|  | 36     // EventEmitter leaves an empty array once the last listener for an event | 
|  | 37     // is removed. Usually that's fine, but in this case we need _listeners.size | 
|  | 38     // and _listeners.has to be accurate. | 
|  | 39     let listeners = this._listeners.get(tabId); | 
|  | 40     if (listeners && listeners.length == 0) | 
|  | 41       this._listeners.delete(tabId); | 
|  | 42   } | 
|  | 43 })); | 
|  | 44 | 
|  | 45 /** | 
|  | 46  * Logs a request for a page if there's something (e.g. devtools panel) | 
|  | 47  * listening. | 
|  | 48  * | 
|  | 49  * @param {number}   tabId         The page the request occured on or -1 if | 
|  | 50  *                                 the request isn't associated with a page | 
|  | 51  * @param {string}   url           The URL of the request | 
|  | 52  * @param {string}   type          The request type | 
|  | 53  * @param {string}   docDomain     The IDN-decoded hostname of the document | 
|  | 54  * @param {boolean}  thirdParty    Whether the origin of the request and | 
|  | 55  *                                 document differs | 
|  | 56  * @param {?string}  sitekey       The active sitekey if there is any | 
|  | 57  * @param {?boolean} specificOnly  Whether generic filters should be ignored | 
|  | 58  * @param {?BlockingFilter} filter The matched filter or null if there is no | 
|  | 59  *                                 match | 
|  | 60  */ | 
|  | 61 exports.logRequest = function(tabId, url, type, docDomain, thirdParty, sitekey, | 
|  | 62                               specificOnly, filter) | 
|  | 63 { | 
|  | 64   if (HitLogger._listeners.size == 0) | 
|  | 65     return; | 
|  | 66 | 
|  | 67   let request = {url, type, docDomain, thirdParty, sitekey, specificOnly, | 
|  | 68                  tabId}; | 
|  | 69   for (let loggerTabId of HitLogger._listeners.keys()) | 
|  | 70     if (tabId == -1 || tabId == loggerTabId) | 
|  | 71       HitLogger.emit(tabId, request, filter); | 
|  | 72 }; | 
|  | 73 | 
|  | 74 /** | 
|  | 75  * Logs active element hiding filters for a page if there's something's | 
|  | 76  * (e.g. devtools panel) listening. | 
|  | 77  * | 
|  | 78  * @param {int}      tabId      The page the elements were hidden on | 
|  | 79  * @param {string[]} selectors  The selectors of applied ElemHideFilters | 
|  | 80  * @param {string[]} filters    The text of applied ElemHideEmulationFilters | 
|  | 81  * @param {string}   docDomain  The IDN-decoded hostname of the document | 
|  | 82  */ | 
|  | 83 exports.logHiddenElements = function(tabId, selectors, filters, docDomain) | 
|  | 84 { | 
|  | 85   if (HitLogger._listeners.has(tabId)) | 
|  | 86   { | 
|  | 87     for (let subscription of FilterStorage.subscriptions) | 
|  | 88     { | 
|  | 89       if (subscription.disabled) | 
|  | 90         continue; | 
|  | 91 | 
|  | 92       for (let filter of subscription.filters) | 
|  | 93       { | 
|  | 94         // We only know the exact filter in case of element hiding emulation. | 
|  | 95         // For regular element hiding filters, the content script only knows | 
|  | 96         // the selector, so we have to find a filter that has an identical | 
|  | 97         // selector and is active on the domain the match was reported from. | 
|  | 98         let isActiveElemHideFilter = filter instanceof ElemHideFilter && | 
|  | 99                                      selectors.includes(filter.selector) && | 
|  | 100                                      filter.isActiveOnDomain(docDomain); | 
|  | 101 | 
|  | 102         if (isActiveElemHideFilter || filters.includes(filter.text)) | 
|  | 103           HitLogger.emit(tabId, {type: "ELEMHIDE", docDomain, tabId}, filter); | 
|  | 104       } | 
|  | 105     } | 
|  | 106   } | 
|  | 107 }; | 
|  | 108 | 
|  | 109 /** | 
|  | 110  * Logs a whitelisting filter, that disables (some kind of) blocking | 
|  | 111  * for a particular document if a devtools panel or similiar is listening. | 
|  | 112  * | 
|  | 113  * @param {number}       tabId     The page the whitelisting is active on | 
|  | 114  * @param {string}       url       The url of the whitelisted document | 
|  | 115  * @param {number}       typeMask  The bit mask of whitelisting types checked | 
|  | 116  *                                 for | 
|  | 117  * @param {string}       docDomain The IDN-decoded hostname of the parent | 
|  | 118  *                                 document | 
|  | 119  * @param {WhitelistFilter} filter The matched whitelisting filter | 
|  | 120  */ | 
|  | 121 exports.logWhitelistedDocument = function(tabId, url, typeMask, docDomain, | 
|  | 122                                           filter) | 
|  | 123 { | 
|  | 124   if (HitLogger._listeners.has(tabId)) | 
|  | 125   { | 
|  | 126     for (let type of nonRequestTypes) | 
|  | 127     { | 
|  | 128       if (typeMask & filter.contentType & RegExpFilter.typeMap[type]) | 
|  | 129         HitLogger.emit(tabId, {type, url, docDomain, tabId}, filter); | 
|  | 130     } | 
|  | 131   } | 
|  | 132 }; | 
|  | 133 | 
|  | 134 /** | 
|  | 135  * Checks whether anything (e.g. devtools panel) is listening for a page's hits. | 
|  | 136  */ | 
|  | 137 exports.hasListener = function(tabId) | 
|  | 138 { | 
|  | 139   return HitLogger._listeners.has(tabId); | 
|  | 140 }; | 
|  | 141 | 
|  | 142 port.on("hitLogger.traceElemHide", (message, sender) => | 
|  | 143 { | 
|  | 144   exports.logHiddenElements( | 
|  | 145     sender.page.id, message.selectors, message.filters, | 
|  | 146     extractHostFromFrame(sender.frame) | 
|  | 147   ); | 
|  | 148 }); | 
| OLD | NEW | 
|---|