| Index: include.preload.js |
| =================================================================== |
| --- a/include.preload.js |
| +++ b/include.preload.js |
| @@ -30,16 +30,18 @@ |
| ["audio", "MEDIA"], |
| ["video", "MEDIA"], |
| ["frame", "SUBDOCUMENT"], |
| ["iframe", "SUBDOCUMENT"], |
| ["object", "OBJECT"], |
| ["embed", "OBJECT"] |
| ]); |
| +const selectorGroupSize = 1024; |
|
Manish Jethani
2018/03/15 07:54:10
There's no reason for this to be a member of ElemH
|
| + |
| function getURLsFromObjectElement(element) |
| { |
| let url = element.getAttribute("data"); |
| if (url) |
| return [url]; |
| for (let child of element.children) |
| { |
| @@ -185,39 +187,41 @@ |
| function checkSitekey() |
| { |
| let attr = document.documentElement.getAttribute("data-adblockkey"); |
| if (attr) |
| browser.runtime.sendMessage({type: "filters.addKey", token: attr}); |
| } |
| -function ElementHidingTracer() |
| +class ElementHidingTracer |
| { |
| - this.selectors = []; |
| - this.changedNodes = []; |
| - this.timeout = null; |
| - this.observer = new MutationObserver(this.observe.bind(this)); |
| - this.trace = this.trace.bind(this); |
| + constructor() |
| + { |
| + this.selectors = []; |
| + this.changedNodes = []; |
| + this.timeout = null; |
| + this.observer = new MutationObserver(this.observe.bind(this)); |
| + this.trace = this.trace.bind(this); |
| - if (document.readyState == "loading") |
| - document.addEventListener("DOMContentLoaded", this.trace); |
| - else |
| - this.trace(); |
| -} |
| -ElementHidingTracer.prototype = { |
| + if (document.readyState == "loading") |
| + document.addEventListener("DOMContentLoaded", this.trace); |
| + else |
| + this.trace(); |
| + } |
| + |
| addSelectors(selectors, filters) |
| { |
| let pairs = selectors.map((sel, i) => [sel, filters && filters[i]]); |
| if (document.readyState != "loading") |
| this.checkNodes([document], pairs); |
| this.selectors.push(...pairs); |
| - }, |
| + } |
| checkNodes(nodes, pairs) |
| { |
| let selectors = []; |
| let filters = []; |
| for (let [selector, filter] of pairs) |
| { |
| @@ -248,24 +252,24 @@ |
| if (selectors.length > 0 || filters.length > 0) |
| { |
| browser.runtime.sendMessage({ |
| type: "devtools.traceElemHide", |
| selectors, filters |
| }); |
| } |
| - }, |
| + } |
| onTimeout() |
| { |
| this.checkNodes(this.changedNodes, this.selectors); |
| this.changedNodes = []; |
| this.timeout = null; |
| - }, |
| + } |
| observe(mutations) |
| { |
| // Forget previously changed nodes that are no longer in the DOM. |
| for (let i = 0; i < this.changedNodes.length; i++) |
| { |
| if (!document.contains(this.changedNodes[i])) |
| this.changedNodes.splice(i--, 1); |
| @@ -310,55 +314,55 @@ |
| this.changedNodes.push(node); |
| } |
| // Check only nodes whose descendants have changed, and not more often |
| // than once a second. Otherwise large pages with a lot of DOM mutations |
| // (like YouTube) freeze when the devtools panel is active. |
| if (this.timeout == null) |
| this.timeout = setTimeout(this.onTimeout.bind(this), 1000); |
| - }, |
| + } |
| trace() |
| { |
| this.checkNodes([document], this.selectors); |
| this.observer.observe( |
| document, |
| { |
| childList: true, |
| attributes: true, |
| subtree: true |
| } |
| ); |
| - }, |
| + } |
| disconnect() |
| { |
| document.removeEventListener("DOMContentLoaded", this.trace); |
| this.observer.disconnect(); |
| clearTimeout(this.timeout); |
| } |
| -}; |
| +} |
| -function ElemHide() |
| +class ElemHide |
| { |
| - this.shadow = this.createShadowTree(); |
| - this.styles = new Map(); |
| - this.tracer = null; |
| - this.inline = true; |
| - this.inlineEmulated = true; |
| + constructor() |
| + { |
| + this.shadow = this.createShadowTree(); |
| + this.styles = new Map(); |
| + this.tracer = null; |
| + this.inline = true; |
| + this.inlineEmulated = true; |
| - this.elemHideEmulation = new ElemHideEmulation( |
| - this.addSelectors.bind(this), |
| - this.hideElements.bind(this) |
| - ); |
| -} |
| -ElemHide.prototype = { |
| - selectorGroupSize: 1024, |
| + this.elemHideEmulation = new ElemHideEmulation( |
| + this.addSelectors.bind(this), |
| + this.hideElements.bind(this) |
| + ); |
| + } |
| createShadowTree() |
| { |
| // Use Shadow DOM if available as to not mess with with web pages that |
| // rely on the order of their own <style> tags (#309). However, creating |
| // a shadow root breaks running CSS transitions. So we have to create |
| // the shadow root before transistions might start (#452). |
| if (!("createShadowRoot" in document.documentElement)) |
| @@ -378,17 +382,17 @@ |
| // Finally since some users have both AdBlock and Adblock Plus installed we |
| // have to consider how the two extensions interact. For example we want to |
| // avoid creating the shadowRoot twice. |
| let shadow = document.documentElement.shadowRoot || |
| document.documentElement.createShadowRoot(); |
| shadow.appendChild(document.createElement("content")); |
| return shadow; |
| - }, |
| + } |
| addSelectorsInline(selectors, groupName) |
| { |
| let style = this.styles.get(groupName); |
| if (style) |
| { |
| while (style.sheet.cssRules.length > 0) |
| @@ -442,25 +446,25 @@ |
| // size of 2). Since we don't know the sizes of the selectors here, we |
| // simply split them into groups of 1,024, based on the reasonable |
| // assumption that the average selector won't have a size greater than 8. |
| // The alternative would be to calculate the sizes of the selectors and |
| // divide them up accordingly, but this approach is more efficient and has |
| // worked well in practice. In theory this could still lead to some |
| // selectors not working on Chromium, but it is highly unlikely. |
| // See issue #6298 and https://crbug.com/804179 |
| - for (let i = 0; i < preparedSelectors.length; i += this.selectorGroupSize) |
| + for (let i = 0; i < preparedSelectors.length; i += selectorGroupSize) |
| { |
| let selector = preparedSelectors.slice( |
| - i, i + this.selectorGroupSize |
| + i, i + selectorGroupSize |
| ).join(", "); |
| style.sheet.insertRule(selector + "{display: none !important;}", |
| style.sheet.cssRules.length); |
| } |
| - }, |
| + } |
| addSelectors(selectors, filters) |
| { |
| if (this.inline || this.inlineEmulated) |
| { |
| // Insert the style rules inline if we have been instructed by the |
| // background page to do so. This is usually the case, except on platforms |
| // that do support user stylesheets via the browser.tabs.insertCSS API |
| @@ -478,32 +482,32 @@ |
| type: "elemhide.injectSelectors", |
| selectors, |
| groupName: "emulated" |
| }); |
| } |
| if (this.tracer) |
| this.tracer.addSelectors(selectors, filters); |
| - }, |
| + } |
| hideElements(elements, filters) |
| { |
| for (let element of elements) |
| hideElement(element); |
| if (this.tracer) |
| { |
| browser.runtime.sendMessage({ |
| type: "devtools.traceElemHide", |
| selectors: [], |
| filters |
| }); |
| } |
| - }, |
| + } |
| apply() |
| { |
| browser.runtime.sendMessage({type: "elemhide.getSelectors"}, response => |
| { |
| if (this.tracer) |
| this.tracer.disconnect(); |
| this.tracer = null; |
| @@ -523,17 +527,17 @@ |
| // Prefer CSS selectors for -abp-has and -abp-contains unless the |
| // background page has asked us to use inline styles. |
| this.elemHideEmulation.useInlineStyles = this.inline || |
| this.inlineEmulated; |
| this.elemHideEmulation.apply(response.emulatedPatterns); |
| }); |
| } |
| -}; |
| +} |
| if (document instanceof HTMLDocument) |
| { |
| checkSitekey(); |
| elemhide = new ElemHide(); |
| elemhide.apply(); |