| 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-2017 eyeo GmbH |    3  * Copyright (C) 2006-2017 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 /* globals ElemHideEmulation, splitSelector */ | 
 |   19  | 
|   18 "use strict"; |   20 "use strict"; | 
|   19  |   21  | 
|   20 const typeMap = { |   22 // This variable is also used by our other content scripts. | 
|   21   "img": "IMAGE", |   23 let elemhide; | 
|   22   "input": "IMAGE", |   24  | 
|   23   "picture": "IMAGE", |   25 const typeMap = new Map([ | 
|   24   "audio": "MEDIA", |   26   ["img", "IMAGE"], | 
|   25   "video": "MEDIA", |   27   ["input", "IMAGE"], | 
|   26   "frame": "SUBDOCUMENT", |   28   ["picture", "IMAGE"], | 
|   27   "iframe": "SUBDOCUMENT", |   29   ["audio", "MEDIA"], | 
|   28   "object": "OBJECT", |   30   ["video", "MEDIA"], | 
|   29   "embed": "OBJECT" |   31   ["frame", "SUBDOCUMENT"], | 
|   30 }; |   32   ["iframe", "SUBDOCUMENT"], | 
 |   33   ["object", "OBJECT"], | 
 |   34   ["embed", "OBJECT"] | 
 |   35 ]); | 
|   31  |   36  | 
|   32 function getURLsFromObjectElement(element) |   37 function getURLsFromObjectElement(element) | 
|   33 { |   38 { | 
|   34   let url = element.getAttribute("data"); |   39   let url = element.getAttribute("data"); | 
|   35   if (url) |   40   if (url) | 
|   36     return [url]; |   41     return [url]; | 
|   37  |   42  | 
|   38   for (let child of element.children) |   43   for (let child of element.children) | 
|   39   { |   44   { | 
|   40     if (child.localName != "param") |   45     if (child.localName != "param") | 
|   41       continue; |   46       continue; | 
|   42  |   47  | 
|   43     let name = child.getAttribute("name"); |   48     let name = child.getAttribute("name"); | 
|   44     if (name != "movie"  && // Adobe Flash |   49     if (name != "movie" &&  // Adobe Flash | 
|   45         name != "source" && // Silverlight |   50         name != "source" && // Silverlight | 
|   46         name != "src"    && // Real Media + Quicktime |   51         name != "src" &&    // Real Media + Quicktime | 
|   47         name != "FileName") // Windows Media |   52         name != "FileName") // Windows Media | 
|   48       continue; |   53       continue; | 
|   49  |   54  | 
|   50     let value = child.getAttribute("value"); |   55     let value = child.getAttribute("value"); | 
|   51     if (!value) |   56     if (!value) | 
|   52       continue; |   57       continue; | 
|   53  |   58  | 
|   54     return [value]; |   59     return [value]; | 
|   55   } |   60   } | 
|   56  |   61  | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|   77   return urls; |   82   return urls; | 
|   78 } |   83 } | 
|   79  |   84  | 
|   80 function getURLsFromMediaElement(element) |   85 function getURLsFromMediaElement(element) | 
|   81 { |   86 { | 
|   82   let urls = getURLsFromAttributes(element); |   87   let urls = getURLsFromAttributes(element); | 
|   83  |   88  | 
|   84   for (let child of element.children) |   89   for (let child of element.children) | 
|   85   { |   90   { | 
|   86     if (child.localName == "source" || child.localName == "track") |   91     if (child.localName == "source" || child.localName == "track") | 
|   87       urls.push.apply(urls, getURLsFromAttributes(child)); |   92       urls.push(...getURLsFromAttributes(child)); | 
|   88   } |   93   } | 
|   89  |   94  | 
|   90   if (element.poster) |   95   if (element.poster) | 
|   91     urls.push(element.poster); |   96     urls.push(element.poster); | 
|   92  |   97  | 
|   93   return urls; |   98   return urls; | 
|   94 } |   99 } | 
|   95  |  100  | 
|   96 function getURLsFromElement(element) |  101 function getURLsFromElement(element) | 
|   97 { |  102 { | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  117   { |  122   { | 
|  118     if (/^(?!https?:)[\w-]+:/i.test(urls[i])) |  123     if (/^(?!https?:)[\w-]+:/i.test(urls[i])) | 
|  119       urls.splice(i--, 1); |  124       urls.splice(i--, 1); | 
|  120   } |  125   } | 
|  121  |  126  | 
|  122   return urls; |  127   return urls; | 
|  123 } |  128 } | 
|  124  |  129  | 
|  125 function checkCollapse(element) |  130 function checkCollapse(element) | 
|  126 { |  131 { | 
|  127   let mediatype = typeMap[element.localName]; |  132   let mediatype = typeMap.get(element.localName); | 
|  128   if (!mediatype) |  133   if (!mediatype) | 
|  129     return; |  134     return; | 
|  130  |  135  | 
|  131   let urls = getURLsFromElement(element); |  136   let urls = getURLsFromElement(element); | 
|  132   if (urls.length == 0) |  137   if (urls.length == 0) | 
|  133     return; |  138     return; | 
|  134  |  139  | 
|  135   ext.backgroundPage.sendMessage( |  140   ext.backgroundPage.sendMessage( | 
|  136     { |  141     { | 
|  137       type: "filters.collapse", |  142       type: "filters.collapse", | 
|  138       urls: urls, |  143       urls, | 
|  139       mediatype: mediatype, |  144       mediatype, | 
|  140       baseURL: document.location.href |  145       baseURL: document.location.href | 
|  141     }, |  146     }, | 
|  142  |  147  | 
|  143     collapse => |  148     collapse => | 
|  144     { |  149     { | 
|  145       function collapseElement() |  150       function collapseElement() | 
|  146       { |  151       { | 
|  147         let propertyName = "display"; |  152         let propertyName = "display"; | 
|  148         let propertyValue = "none"; |  153         let propertyValue = "none"; | 
|  149         if (element.localName == "frame") |  154         if (element.localName == "frame") | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  172   ); |  177   ); | 
|  173 } |  178 } | 
|  174  |  179  | 
|  175 function checkSitekey() |  180 function checkSitekey() | 
|  176 { |  181 { | 
|  177   let attr = document.documentElement.getAttribute("data-adblockkey"); |  182   let attr = document.documentElement.getAttribute("data-adblockkey"); | 
|  178   if (attr) |  183   if (attr) | 
|  179     ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr}); |  184     ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr}); | 
|  180 } |  185 } | 
|  181  |  186  | 
|  182 function getContentDocument(element) |  | 
|  183 { |  | 
|  184   try |  | 
|  185   { |  | 
|  186     return element.contentDocument; |  | 
|  187   } |  | 
|  188   catch (e) |  | 
|  189   { |  | 
|  190     return null; |  | 
|  191   } |  | 
|  192 } |  | 
|  193  |  | 
|  194 function ElementHidingTracer() |  187 function ElementHidingTracer() | 
|  195 { |  188 { | 
|  196   this.selectors = []; |  189   this.selectors = []; | 
|  197   this.filters = []; |  190   this.filters = []; | 
|  198  |  191  | 
|  199   this.changedNodes = []; |  192   this.changedNodes = []; | 
|  200   this.timeout = null; |  193   this.timeout = null; | 
|  201  |  194  | 
|  202   this.observer = new MutationObserver(this.observe.bind(this)); |  195   this.observer = new MutationObserver(this.observe.bind(this)); | 
|  203   this.trace = this.trace.bind(this); |  196   this.trace = this.trace.bind(this); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  235           if (getComputedStyle(element).display == "none") |  228           if (getComputedStyle(element).display == "none") | 
|  236           { |  229           { | 
|  237             matchedSelectors.push(filters[i].replace(/^.*?##/, "")); |  230             matchedSelectors.push(filters[i].replace(/^.*?##/, "")); | 
|  238             break nodes; |  231             break nodes; | 
|  239           } |  232           } | 
|  240         } |  233         } | 
|  241       } |  234       } | 
|  242     } |  235     } | 
|  243  |  236  | 
|  244     if (matchedSelectors.length > 0) |  237     if (matchedSelectors.length > 0) | 
 |  238     { | 
|  245       ext.backgroundPage.sendMessage({ |  239       ext.backgroundPage.sendMessage({ | 
|  246         type: "devtools.traceElemHide", |  240         type: "devtools.traceElemHide", | 
|  247         selectors: matchedSelectors |  241         selectors: matchedSelectors | 
|  248       }); |  242       }); | 
 |  243     } | 
|  249   }, |  244   }, | 
|  250  |  245  | 
|  251   onTimeout() |  246   onTimeout() | 
|  252   { |  247   { | 
|  253     this.checkNodes(this.changedNodes, this.selectors, this.filters); |  248     this.checkNodes(this.changedNodes, this.selectors, this.filters); | 
|  254     this.changedNodes = []; |  249     this.changedNodes = []; | 
|  255     this.timeout = null; |  250     this.timeout = null; | 
|  256   }, |  251   }, | 
|  257  |  252  | 
|  258   observe(mutations) |  253   observe(mutations) | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  342   document.documentElement.removeChild(script); |  337   document.documentElement.removeChild(script); | 
|  343 } |  338 } | 
|  344  |  339  | 
|  345 // Before Chrome 58 the webRequest API didn't allow us to intercept |  340 // Before Chrome 58 the webRequest API didn't allow us to intercept | 
|  346 // WebSockets[1], and therefore some ad networks are misusing them as a way to |  341 // WebSockets[1], and therefore some ad networks are misusing them as a way to | 
|  347 // serve adverts and circumvent us. As a workaround we wrap WebSocket, |  342 // serve adverts and circumvent us. As a workaround we wrap WebSocket, | 
|  348 // preventing blocked WebSocket connections from being opened. |  343 // preventing blocked WebSocket connections from being opened. | 
|  349 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 |  344 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 | 
|  350 function wrapWebSocket() |  345 function wrapWebSocket() | 
|  351 { |  346 { | 
|  352   let eventName = "abpws-" + Math.random().toString(36).substr(2); |  347   let randomEventName = "abpws-" + Math.random().toString(36).substr(2); | 
|  353  |  348  | 
|  354   document.addEventListener(eventName, event => |  349   document.addEventListener(randomEventName, event => | 
|  355   { |  350   { | 
|  356     ext.backgroundPage.sendMessage({ |  351     ext.backgroundPage.sendMessage({ | 
|  357       type: "request.websocket", |  352       type: "request.websocket", | 
|  358       url: event.detail.url |  353       url: event.detail.url | 
|  359     }, block => |  354     }, block => | 
|  360     { |  355     { | 
|  361       document.dispatchEvent( |  356       document.dispatchEvent(new CustomEvent( | 
|  362         new CustomEvent(eventName + "-" + event.detail.url, {detail: block}) |  357         randomEventName + "-" + event.detail.url, {detail: block} | 
|  363       ); |  358       )); | 
|  364     }); |  359     }); | 
|  365   }); |  360   }); | 
|  366  |  361  | 
|  367   runInPageContext(eventName => |  362   runInPageContext(eventName => | 
|  368   { |  363   { | 
|  369     // As far as possible we must track everything we use that could be |  364     // As far as possible we must track everything we use that could be | 
|  370     // sabotaged by the website later in order to circumvent us. |  365     // sabotaged by the website later in order to circumvent us. | 
|  371     let RealWebSocket = WebSocket; |  366     let RealWebSocket = WebSocket; | 
|  372     let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.cl
     ose); |  367     let RealCustomEvent = window.CustomEvent; | 
 |  368     let closeWebSocket = Function.prototype.call.bind( | 
 |  369       RealWebSocket.prototype.close | 
 |  370     ); | 
|  373     let addEventListener = document.addEventListener.bind(document); |  371     let addEventListener = document.addEventListener.bind(document); | 
|  374     let removeEventListener = document.removeEventListener.bind(document); |  372     let removeEventListener = document.removeEventListener.bind(document); | 
|  375     let dispatchEvent = document.dispatchEvent.bind(document); |  373     let dispatchEvent = document.dispatchEvent.bind(document); | 
|  376     let CustomEvent = window.CustomEvent; |  | 
|  377  |  374  | 
|  378     function checkRequest(url, callback) |  375     function checkRequest(url, callback) | 
|  379     { |  376     { | 
|  380       let incomingEventName = eventName + "-" + url; |  377       let incomingEventName = eventName + "-" + url; | 
|  381       function listener(event) |  378       function listener(event) | 
|  382       { |  379       { | 
|  383         callback(event.detail); |  380         callback(event.detail); | 
|  384         removeEventListener(incomingEventName, listener); |  381         removeEventListener(incomingEventName, listener); | 
|  385       } |  382       } | 
|  386       addEventListener(incomingEventName, listener); |  383       addEventListener(incomingEventName, listener); | 
|  387  |  384  | 
|  388       dispatchEvent(new CustomEvent(eventName, { |  385       dispatchEvent(new RealCustomEvent(eventName, {detail: {url}})); | 
|  389         detail: {url: url} |  | 
|  390       })); |  | 
|  391     } |  386     } | 
|  392  |  387  | 
|  393     function WrappedWebSocket(url) |  388     function WrappedWebSocket(url, ...args) | 
|  394     { |  389     { | 
|  395       // Throw correct exceptions if the constructor is used improperly. |  390       // Throw correct exceptions if the constructor is used improperly. | 
|  396       if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); |  391       if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); | 
|  397       if (arguments.length < 1) return new RealWebSocket(); |  392       if (arguments.length < 1) return new RealWebSocket(); | 
|  398  |  393  | 
|  399       let websocket; |  394       let websocket = new RealWebSocket(url, ...args); | 
|  400       if (arguments.length == 1) |  | 
|  401         websocket = new RealWebSocket(url); |  | 
|  402       else |  | 
|  403         websocket = new RealWebSocket(url, arguments[1]); |  | 
|  404  |  395  | 
|  405       checkRequest(websocket.url, blocked => |  396       checkRequest(websocket.url, blocked => | 
|  406       { |  397       { | 
|  407         if (blocked) |  398         if (blocked) | 
|  408           closeWebSocket(websocket); |  399           closeWebSocket(websocket); | 
|  409       }); |  400       }); | 
|  410  |  401  | 
|  411       return websocket; |  402       return websocket; | 
|  412     } |  403     } | 
|  413     WrappedWebSocket.prototype = RealWebSocket.prototype; |  404     WrappedWebSocket.prototype = RealWebSocket.prototype; | 
|  414     WebSocket = WrappedWebSocket.bind(); |  405     window.WebSocket = WrappedWebSocket.bind(); | 
|  415     Object.defineProperties(WebSocket, { |  406     Object.defineProperties(WebSocket, { | 
|  416       CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true}, |  407       CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true}, | 
|  417       OPEN: {value: RealWebSocket.OPEN, enumerable: true}, |  408       OPEN: {value: RealWebSocket.OPEN, enumerable: true}, | 
|  418       CLOSING: {value: RealWebSocket.CLOSING, enumerable: true}, |  409       CLOSING: {value: RealWebSocket.CLOSING, enumerable: true}, | 
|  419       CLOSED: {value: RealWebSocket.CLOSED, enumerable: true}, |  410       CLOSED: {value: RealWebSocket.CLOSED, enumerable: true}, | 
|  420       prototype: {value: RealWebSocket.prototype} |  411       prototype: {value: RealWebSocket.prototype} | 
|  421     }); |  412     }); | 
|  422  |  413  | 
|  423     RealWebSocket.prototype.constructor = WebSocket; |  414     RealWebSocket.prototype.constructor = WebSocket; | 
|  424   }, eventName); |  415   }, randomEventName); | 
|  425 } |  416 } | 
|  426  |  417  | 
|  427 function ElemHide() |  418 function ElemHide() | 
|  428 { |  419 { | 
|  429   this.shadow = this.createShadowTree(); |  420   this.shadow = this.createShadowTree(); | 
|  430   this.style = null; |  421   this.style = null; | 
|  431   this.tracer = null; |  422   this.tracer = null; | 
|  432  |  423  | 
|  433   this.elemHideEmulation = new ElemHideEmulation( |  424   this.elemHideEmulation = new ElemHideEmulation( | 
|  434     window, |  425     window, | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  467     shadow.appendChild(document.createElement("shadow")); |  458     shadow.appendChild(document.createElement("shadow")); | 
|  468  |  459  | 
|  469     // Stop the website from messing with our shadow root (#4191, #4298). |  460     // Stop the website from messing with our shadow root (#4191, #4298). | 
|  470     if ("shadowRoot" in Element.prototype) |  461     if ("shadowRoot" in Element.prototype) | 
|  471     { |  462     { | 
|  472       runInPageContext(() => |  463       runInPageContext(() => | 
|  473       { |  464       { | 
|  474         let ourShadowRoot = document.documentElement.shadowRoot; |  465         let ourShadowRoot = document.documentElement.shadowRoot; | 
|  475         if (!ourShadowRoot) |  466         if (!ourShadowRoot) | 
|  476           return; |  467           return; | 
|  477         let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoo
     t"); |  468         let desc = Object.getOwnPropertyDescriptor(Element.prototype, | 
 |  469                                                    "shadowRoot"); | 
|  478         let shadowRoot = Function.prototype.call.bind(desc.get); |  470         let shadowRoot = Function.prototype.call.bind(desc.get); | 
|  479  |  471  | 
|  480         Object.defineProperty(Element.prototype, "shadowRoot", { |  472         Object.defineProperty(Element.prototype, "shadowRoot", { | 
|  481           configurable: true, enumerable: true, get() |  473           configurable: true, enumerable: true, get() | 
|  482           { |  474           { | 
|  483             let shadow = shadowRoot(this); |  475             let thisShadow = shadowRoot(this); | 
|  484             return shadow == ourShadowRoot ? null : shadow; |  476             return thisShadow == ourShadowRoot ? null : thisShadow; | 
|  485           } |  477           } | 
|  486         }); |  478         }); | 
|  487       }, null); |  479       }, null); | 
|  488     } |  480     } | 
|  489  |  481  | 
|  490     return shadow; |  482     return shadow; | 
|  491   }, |  483   }, | 
|  492  |  484  | 
|  493   addSelectors(selectors, filters) |  485   addSelectors(selectors, filters) | 
|  494   { |  486   { | 
|  495     if (selectors.length == 0) |  487     if (selectors.length == 0) | 
|  496       return; |  488       return; | 
|  497  |  489  | 
|  498     if (!this.style) |  490     if (!this.style) | 
|  499     { |  491     { | 
|  500       // Create <style> element lazily, only if we add styles. Add it to |  492       // Create <style> element lazily, only if we add styles. Add it to | 
|  501       // the shadow DOM if possible. Otherwise fallback to the <head> or |  493       // the shadow DOM if possible. Otherwise fallback to the <head> or | 
|  502       // <html> element. If we have injected a style element before that |  494       // <html> element. If we have injected a style element before that | 
|  503       // has been removed (the sheet property is null), create a new one. |  495       // has been removed (the sheet property is null), create a new one. | 
|  504       this.style = document.createElement("style"); |  496       this.style = document.createElement("style"); | 
|  505       (this.shadow || document.head |  497       (this.shadow || document.head || | 
|  506                    || document.documentElement).appendChild(this.style); |  498                       document.documentElement).appendChild(this.style); | 
|  507  |  499  | 
|  508       // It can happen that the frame already navigated to a different |  500       // It can happen that the frame already navigated to a different | 
|  509       // document while we were waiting for the background page to respond. |  501       // document while we were waiting for the background page to respond. | 
|  510       // In that case the sheet property will stay null, after addind the |  502       // In that case the sheet property will stay null, after addind the | 
|  511       // <style> element to the shadow DOM. |  503       // <style> element to the shadow DOM. | 
|  512       if (!this.style.sheet) |  504       if (!this.style.sheet) | 
|  513         return; |  505         return; | 
|  514     } |  506     } | 
|  515  |  507  | 
|  516     // If using shadow DOM, we have to add the ::content pseudo-element |  508     // If using shadow DOM, we have to add the ::content pseudo-element | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  531       preparedSelectors = selectors; |  523       preparedSelectors = selectors; | 
|  532     } |  524     } | 
|  533  |  525  | 
|  534     // Safari only allows 8192 primitive selectors to be injected at once[1], we |  526     // Safari only allows 8192 primitive selectors to be injected at once[1], we | 
|  535     // therefore chunk the inserted selectors into groups of 200 to be safe. |  527     // therefore chunk the inserted selectors into groups of 200 to be safe. | 
|  536     // (Chrome also has a limit, larger... but we're not certain exactly what it |  528     // (Chrome also has a limit, larger... but we're not certain exactly what it | 
|  537     //  is! Edge apparently has no such limit.) |  529     //  is! Edge apparently has no such limit.) | 
|  538     // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69
     debb75fc1de/Source/WebCore/css/RuleSet.h#L68 |  530     // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69
     debb75fc1de/Source/WebCore/css/RuleSet.h#L68 | 
|  539     for (let i = 0; i < preparedSelectors.length; i += this.selectorGroupSize) |  531     for (let i = 0; i < preparedSelectors.length; i += this.selectorGroupSize) | 
|  540     { |  532     { | 
|  541       let selector = preparedSelectors.slice(i, i + this.selectorGroupSize).join
     (", "); |  533       let selector = preparedSelectors.slice( | 
 |  534         i, i + this.selectorGroupSize | 
 |  535       ).join(", "); | 
|  542       this.style.sheet.insertRule(selector + "{display: none !important;}", |  536       this.style.sheet.insertRule(selector + "{display: none !important;}", | 
|  543                                   this.style.sheet.cssRules.length); |  537                                   this.style.sheet.cssRules.length); | 
|  544     } |  538     } | 
|  545  |  539  | 
|  546     if (this.tracer) |  540     if (this.tracer) | 
|  547       this.tracer.addSelectors(selectors, filters || selectors); |  541       this.tracer.addSelectors(selectors, filters || selectors); | 
|  548   }, |  542   }, | 
|  549  |  543  | 
|  550   apply() |  544   apply() | 
|  551   { |  545   { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  566       this.elemHideEmulation.apply(); |  560       this.elemHideEmulation.apply(); | 
|  567     }); |  561     }); | 
|  568   } |  562   } | 
|  569 }; |  563 }; | 
|  570  |  564  | 
|  571 if (document instanceof HTMLDocument) |  565 if (document instanceof HTMLDocument) | 
|  572 { |  566 { | 
|  573   checkSitekey(); |  567   checkSitekey(); | 
|  574   wrapWebSocket(); |  568   wrapWebSocket(); | 
|  575  |  569  | 
|  576   // This variable is also used by our other content scripts, outside of the |  570   elemhide = new ElemHide(); | 
|  577   // current scope. |  | 
|  578   var elemhide = new ElemHide(); |  | 
|  579   elemhide.apply(); |  571   elemhide.apply(); | 
|  580  |  572  | 
|  581   document.addEventListener("error", event => |  573   document.addEventListener("error", event => | 
|  582   { |  574   { | 
|  583     checkCollapse(event.target); |  575     checkCollapse(event.target); | 
|  584   }, true); |  576   }, true); | 
|  585  |  577  | 
|  586   document.addEventListener("load", event => |  578   document.addEventListener("load", event => | 
|  587   { |  579   { | 
|  588     let element = event.target; |  580     let element = event.target; | 
|  589     if (/^i?frame$/.test(element.localName)) |  581     if (/^i?frame$/.test(element.localName)) | 
|  590       checkCollapse(element); |  582       checkCollapse(element); | 
|  591   }, true); |  583   }, true); | 
|  592 } |  584 } | 
| OLD | NEW |