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(); |