Index: include.preload.js |
diff --git a/include.preload.js b/include.preload.js |
index 86e52c32afceb894f6591a84b0eca3b1842383ce..b5013df07fa7f8df18b7a45b2143cd6bd509bb54 100644 |
--- a/include.preload.js |
+++ b/include.preload.js |
@@ -15,7 +15,9 @@ |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
-var typeMap = { |
+"use strict"; |
+ |
+let typeMap = { |
"img": "IMAGE", |
"input": "IMAGE", |
"picture": "IMAGE", |
@@ -29,24 +31,23 @@ var typeMap = { |
function getURLsFromObjectElement(element) |
{ |
- var url = element.getAttribute("data"); |
+ let url = element.getAttribute("data"); |
if (url) |
return [url]; |
- for (var i = 0; i < element.children.length; i++) |
+ for (let child of element.children) |
{ |
- var child = element.children[i]; |
if (child.localName != "param") |
continue; |
- var name = child.getAttribute("name"); |
+ let name = child.getAttribute("name"); |
if (name != "movie" && // Adobe Flash |
name != "source" && // Silverlight |
name != "src" && // Real Media + Quicktime |
name != "FileName") // Windows Media |
continue; |
- var value = child.getAttribute("value"); |
+ let value = child.getAttribute("value"); |
if (!value) |
continue; |
@@ -58,17 +59,16 @@ function getURLsFromObjectElement(element) |
function getURLsFromAttributes(element) |
{ |
- var urls = []; |
+ let urls = []; |
if (element.src) |
urls.push(element.src); |
if (element.srcset) |
{ |
- var candidates = element.srcset.split(","); |
- for (var i = 0; i < candidates.length; i++) |
+ for (let candidate of element.srcset.split(",")) |
{ |
- var url = candidates[i].trim().replace(/\s+\S+$/, ""); |
+ let url = candidate.trim().replace(/\s+\S+$/, ""); |
if (url) |
urls.push(url); |
} |
@@ -79,11 +79,10 @@ function getURLsFromAttributes(element) |
function getURLsFromMediaElement(element) |
{ |
- var urls = getURLsFromAttributes(element); |
+ let urls = getURLsFromAttributes(element); |
- for (var i = 0; i < element.children.length; i++) |
+ for (let child of element.children) |
{ |
- var child = element.children[i]; |
if (child.localName == "source" || child.localName == "track") |
urls.push.apply(urls, getURLsFromAttributes(child)); |
} |
@@ -96,7 +95,7 @@ function getURLsFromMediaElement(element) |
function getURLsFromElement(element) |
{ |
- var urls; |
+ let urls; |
switch (element.localName) |
{ |
case "object": |
@@ -114,7 +113,7 @@ function getURLsFromElement(element) |
break; |
} |
- for (var i = 0; i < urls.length; i++) |
+ for (let i = 0; i < urls.length; i++) |
{ |
if (/^(?!https?:)[\w-]+:/i.test(urls[i])) |
urls.splice(i--, 1); |
@@ -125,11 +124,11 @@ function getURLsFromElement(element) |
function checkCollapse(element) |
{ |
- var mediatype = typeMap[element.localName]; |
+ let mediatype = typeMap[element.localName]; |
if (!mediatype) |
return; |
- var urls = getURLsFromElement(element); |
+ let urls = getURLsFromElement(element); |
if (urls.length == 0) |
return; |
@@ -141,12 +140,12 @@ function checkCollapse(element) |
baseURL: document.location.href |
}, |
- function(collapse) |
+ collapse => |
{ |
function collapseElement() |
{ |
- var propertyName = "display"; |
- var propertyValue = "none"; |
+ let propertyName = "display"; |
+ let propertyValue = "none"; |
if (element.localName == "frame") |
{ |
propertyName = "visibility"; |
@@ -175,7 +174,7 @@ function checkCollapse(element) |
function checkSitekey() |
{ |
- var attr = document.documentElement.getAttribute("data-adblockkey"); |
+ let attr = document.documentElement.getAttribute("data-adblockkey"); |
if (attr) |
ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr}); |
} |
@@ -208,26 +207,24 @@ function ElementHidingTracer(selectors) |
this.trace(); |
} |
ElementHidingTracer.prototype = { |
- checkNodes: function(nodes) |
+ checkNodes(nodes) |
{ |
- var matchedSelectors = []; |
+ let matchedSelectors = []; |
// Find all selectors that match any hidden element inside the given nodes. |
- for (var i = 0; i < this.selectors.length; i++) |
+ for (let selector of this.selectors) |
{ |
- var selector = this.selectors[i]; |
- |
- for (var j = 0; j < nodes.length; j++) |
+ for (let node of nodes) |
{ |
- var elements = nodes[j].querySelectorAll(selector); |
- var matched = false; |
+ let elements = node.querySelectorAll(selector); |
+ let matched = false; |
- for (var k = 0; k < elements.length; k++) |
+ for (let element of elements) |
{ |
// Only consider selectors that actually have an effect on the |
// computed styles, and aren't overridden by rules with higher |
// priority, or haven't been circumvented in a different way. |
- if (getComputedStyle(elements[k]).display == "none") |
+ if (getComputedStyle(element).display == "none") |
{ |
matchedSelectors.push(selector); |
matched = true; |
@@ -247,26 +244,25 @@ ElementHidingTracer.prototype = { |
}); |
}, |
- onTimeout: function() |
+ onTimeout() |
{ |
this.checkNodes(this.changedNodes); |
this.changedNodes = []; |
this.timeout = null; |
}, |
- observe: function(mutations) |
+ observe(mutations) |
{ |
// Forget previously changed nodes that are no longer in the DOM. |
- for (var i = 0; i < this.changedNodes.length; i++) |
+ for (let i = 0; i < this.changedNodes.length; i++) |
{ |
if (!document.contains(this.changedNodes[i])) |
this.changedNodes.splice(i--, 1); |
} |
- for (var j = 0; j < mutations.length; j++) |
+ for (let mutation of mutations) |
{ |
- var mutation = mutations[j]; |
- var node = mutation.target; |
+ let node = mutation.target; |
// Ignore mutations of nodes that aren't in the DOM anymore. |
if (!document.contains(node)) |
@@ -278,10 +274,10 @@ ElementHidingTracer.prototype = { |
if (mutation.type == "attributes") |
node = node.parentNode; |
- var addNode = true; |
- for (var k = 0; k < this.changedNodes.length; k++) |
+ let addNode = true; |
+ for (let i = 0; i < this.changedNodes.length; i++) |
{ |
- var previouslyChangedNode = this.changedNodes[k]; |
+ let previouslyChangedNode = this.changedNodes[i]; |
// If we are already going to check an ancestor of this node, |
// we can ignore this node, since it will be considered anyway |
@@ -296,7 +292,7 @@ ElementHidingTracer.prototype = { |
// we can ignore that node, since it will be considered anyway |
// when checking one of its ancestors. |
if (node.contains(previouslyChangedNode)) |
- this.changedNodes.splice(k--, 1); |
+ this.changedNodes.splice(i--, 1); |
} |
if (addNode) |
@@ -310,7 +306,7 @@ ElementHidingTracer.prototype = { |
this.timeout = setTimeout(this.onTimeout.bind(this), 1000); |
}, |
- trace: function() |
+ trace() |
{ |
this.checkNodes([document]); |
@@ -324,7 +320,7 @@ ElementHidingTracer.prototype = { |
); |
}, |
- disconnect: function() |
+ disconnect() |
{ |
document.removeEventListener("DOMContentLoaded", this.trace); |
this.observer.disconnect(); |
@@ -334,7 +330,7 @@ ElementHidingTracer.prototype = { |
function runInPageContext(fn, arg) |
{ |
- var script = document.createElement("script"); |
+ let script = document.createElement("script"); |
script.type = "application/javascript"; |
script.async = false; |
script.textContent = "(" + fn + ")(" + JSON.stringify(arg) + ");"; |
@@ -349,14 +345,14 @@ function runInPageContext(fn, arg) |
// [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 |
function wrapWebSocket() |
{ |
- var eventName = "abpws-" + Math.random().toString(36).substr(2); |
+ let eventName = "abpws-" + Math.random().toString(36).substr(2); |
- document.addEventListener(eventName, function(event) |
+ document.addEventListener(eventName, event => |
{ |
ext.backgroundPage.sendMessage({ |
type: "request.websocket", |
url: event.detail.url |
- }, function (block) |
+ }, block => |
{ |
document.dispatchEvent( |
new CustomEvent(eventName + "-" + event.detail.url, {detail: block}) |
@@ -364,20 +360,20 @@ function wrapWebSocket() |
}); |
}); |
- runInPageContext(function(eventName) |
+ runInPageContext(eventName => |
{ |
// As far as possible we must track everything we use that could be |
// sabotaged by the website later in order to circumvent us. |
- var RealWebSocket = WebSocket; |
- var closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.close); |
- var addEventListener = document.addEventListener.bind(document); |
- var removeEventListener = document.removeEventListener.bind(document); |
- var dispatchEvent = document.dispatchEvent.bind(document); |
- var CustomEvent = window.CustomEvent; |
+ let RealWebSocket = WebSocket; |
+ let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.close); |
+ let addEventListener = document.addEventListener.bind(document); |
+ let removeEventListener = document.removeEventListener.bind(document); |
+ let dispatchEvent = document.dispatchEvent.bind(document); |
+ let CustomEvent = window.CustomEvent; |
function checkRequest(url, callback) |
{ |
- var incomingEventName = eventName + "-" + url; |
+ let incomingEventName = eventName + "-" + url; |
function listener(event) |
{ |
callback(event.detail); |
@@ -396,13 +392,13 @@ function wrapWebSocket() |
if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); |
if (arguments.length < 1) return new RealWebSocket(); |
- var websocket; |
+ let websocket; |
if (arguments.length == 1) |
websocket = new RealWebSocket(url); |
else |
websocket = new RealWebSocket(url, arguments[1]); |
- checkRequest(websocket.url, function(blocked) |
+ checkRequest(websocket.url, blocked => |
{ |
if (blocked) |
closeWebSocket(websocket); |
@@ -432,7 +428,7 @@ function ElemHide() |
this.elemHideEmulation = new ElemHideEmulation( |
window, |
- function(callback) |
+ callback => |
{ |
ext.backgroundPage.sendMessage({ |
type: "filters.get", |
@@ -445,7 +441,7 @@ function ElemHide() |
ElemHide.prototype = { |
selectorGroupSize: 200, |
- createShadowTree: function() |
+ 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 |
@@ -462,25 +458,25 @@ ElemHide.prototype = { |
// 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. |
- var shadow = document.documentElement.shadowRoot || |
+ let shadow = document.documentElement.shadowRoot || |
document.documentElement.createShadowRoot(); |
shadow.appendChild(document.createElement("shadow")); |
// Stop the website from messing with our shadow root (#4191, #4298). |
if ("shadowRoot" in Element.prototype) |
{ |
- runInPageContext(function() |
+ runInPageContext(() => |
{ |
- var ourShadowRoot = document.documentElement.shadowRoot; |
+ let ourShadowRoot = document.documentElement.shadowRoot; |
if (!ourShadowRoot) |
return; |
- var desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoot"); |
- var shadowRoot = Function.prototype.call.bind(desc.get); |
+ let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoot"); |
+ let shadowRoot = Function.prototype.call.bind(desc.get); |
Object.defineProperty(Element.prototype, "shadowRoot", { |
- configurable: true, enumerable: true, get: function() |
+ configurable: true, enumerable: true, get() |
{ |
- var shadow = shadowRoot(this); |
+ let shadow = shadowRoot(this); |
return shadow == ourShadowRoot ? null : shadow; |
} |
}); |
@@ -490,7 +486,7 @@ ElemHide.prototype = { |
return shadow; |
}, |
- addSelectors: function(selectors) |
+ addSelectors(selectors) |
{ |
if (selectors.length == 0) |
return; |
@@ -518,12 +514,12 @@ ElemHide.prototype = { |
// insertion point. |
if (this.shadow) |
{ |
- var preparedSelectors = []; |
- for (var i = 0; i < selectors.length; i++) |
+ let preparedSelectors = []; |
+ for (let selector of selectors) |
{ |
- var subSelectors = splitSelector(selectors[i]); |
- for (var j = 0; j < subSelectors.length; j++) |
- preparedSelectors.push("::content " + subSelectors[j]); |
+ let subSelectors = splitSelector(selector); |
+ for (let subSelector of subSelectors) |
+ preparedSelectors.push("::content " + subSelector); |
} |
selectors = preparedSelectors; |
} |
@@ -533,20 +529,20 @@ ElemHide.prototype = { |
// (Chrome also has a limit, larger... but we're not certain exactly what it |
// is! Edge apparently has no such limit.) |
// [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69debb75fc1de/Source/WebCore/css/RuleSet.h#L68 |
- for (var i = 0; i < selectors.length; i += this.selectorGroupSize) |
+ for (let i = 0; i < selectors.length; i += this.selectorGroupSize) |
{ |
- var selector = selectors.slice(i, i + this.selectorGroupSize).join(", "); |
+ let selector = selectors.slice(i, i + this.selectorGroupSize).join(", "); |
this.style.sheet.insertRule(selector + "{display: none !important;}", |
this.style.sheet.cssRules.length); |
} |
}, |
- apply: function() |
+ apply() |
{ |
- var selectors = null; |
- var elemHideEmulationLoaded = false; |
+ let selectors = null; |
+ let elemHideEmulationLoaded = false; |
- var checkLoaded = function() |
+ let checkLoaded = function() |
{ |
if (!selectors || !elemHideEmulationLoaded) |
return; |
@@ -566,13 +562,13 @@ ElemHide.prototype = { |
this.tracer = new ElementHidingTracer(selectors.selectors); |
}.bind(this); |
- ext.backgroundPage.sendMessage({type: "get-selectors"}, function(response) |
+ ext.backgroundPage.sendMessage({type: "get-selectors"}, response => |
{ |
selectors = response; |
checkLoaded(); |
}); |
- this.elemHideEmulation.load(function() |
+ this.elemHideEmulation.load(() => |
{ |
elemHideEmulationLoaded = true; |
checkLoaded(); |
@@ -585,17 +581,19 @@ if (document instanceof HTMLDocument) |
checkSitekey(); |
wrapWebSocket(); |
+ // This variable is also used by our other content scripts, outside of the |
+ // current scope. |
var elemhide = new ElemHide(); |
elemhide.apply(); |
- document.addEventListener("error", function(event) |
+ document.addEventListener("error", event => |
{ |
checkCollapse(event.target); |
}, true); |
- document.addEventListener("load", function(event) |
+ document.addEventListener("load", event => |
{ |
- var element = event.target; |
+ let element = event.target; |
if (/^i?frame$/.test(element.localName)) |
checkCollapse(element); |
}, true); |