| Index: include.preload.js |
| diff --git a/include.preload.js b/include.preload.js |
| index 86e52c32afceb894f6591a84b0eca3b1842383ce..1c28cb6bc9ac88a2703015ab49d5978a0ee3c6e9 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"; |
| + |
| +const 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); |