Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: include.preload.js

Issue 29371763: Issue 4795 - Use modern JavaScript syntax (Closed)
Patch Set: Created Jan. 13, 2017, 12:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 var typeMap = { 18 let typeMap = {
19 "img": "IMAGE", 19 "img": "IMAGE",
20 "input": "IMAGE", 20 "input": "IMAGE",
21 "picture": "IMAGE", 21 "picture": "IMAGE",
22 "audio": "MEDIA", 22 "audio": "MEDIA",
23 "video": "MEDIA", 23 "video": "MEDIA",
24 "frame": "SUBDOCUMENT", 24 "frame": "SUBDOCUMENT",
25 "iframe": "SUBDOCUMENT", 25 "iframe": "SUBDOCUMENT",
26 "object": "OBJECT", 26 "object": "OBJECT",
27 "embed": "OBJECT" 27 "embed": "OBJECT"
28 }; 28 };
29 29
30 function getURLsFromObjectElement(element) 30 function getURLsFromObjectElement(element)
31 { 31 {
32 var url = element.getAttribute("data"); 32 let url = element.getAttribute("data");
33 if (url) 33 if (url)
34 return [url]; 34 return [url];
35 35
36 for (var i = 0; i < element.children.length; i++) 36 for (let child of element.children)
37 { 37 {
38 var child = element.children[i];
39 if (child.localName != "param") 38 if (child.localName != "param")
40 continue; 39 continue;
41 40
42 var name = child.getAttribute("name"); 41 let name = child.getAttribute("name");
43 if (name != "movie" && // Adobe Flash 42 if (name != "movie" && // Adobe Flash
44 name != "source" && // Silverlight 43 name != "source" && // Silverlight
45 name != "src" && // Real Media + Quicktime 44 name != "src" && // Real Media + Quicktime
46 name != "FileName") // Windows Media 45 name != "FileName") // Windows Media
47 continue; 46 continue;
48 47
49 var value = child.getAttribute("value"); 48 let value = child.getAttribute("value");
50 if (!value) 49 if (!value)
51 continue; 50 continue;
52 51
53 return [value]; 52 return [value];
54 } 53 }
55 54
56 return []; 55 return [];
57 } 56 }
58 57
59 function getURLsFromAttributes(element) 58 function getURLsFromAttributes(element)
60 { 59 {
61 var urls = []; 60 let urls = [];
62 61
63 if (element.src) 62 if (element.src)
64 urls.push(element.src); 63 urls.push(element.src);
65 64
66 if (element.srcset) 65 if (element.srcset)
67 { 66 {
68 var candidates = element.srcset.split(","); 67 for (let candidate of element.srcset.split(","))
69 for (var i = 0; i < candidates.length; i++)
70 { 68 {
71 var url = candidates[i].trim().replace(/\s+\S+$/, ""); 69 let url = candidate.trim().replace(/\s+\S+$/, "");
72 if (url) 70 if (url)
73 urls.push(url); 71 urls.push(url);
74 } 72 }
75 } 73 }
76 74
77 return urls; 75 return urls;
78 } 76 }
79 77
80 function getURLsFromMediaElement(element) 78 function getURLsFromMediaElement(element)
81 { 79 {
82 var urls = getURLsFromAttributes(element); 80 let urls = getURLsFromAttributes(element);
83 81
84 for (var i = 0; i < element.children.length; i++) 82 for (let child of element.children)
85 {
86 var child = element.children[i];
87 if (child.localName == "source" || child.localName == "track") 83 if (child.localName == "source" || child.localName == "track")
88 urls.push.apply(urls, getURLsFromAttributes(child)); 84 urls.push.apply(urls, getURLsFromAttributes(child));
89 }
90 85
91 if (element.poster) 86 if (element.poster)
92 urls.push(element.poster); 87 urls.push(element.poster);
93 88
94 return urls; 89 return urls;
95 } 90 }
96 91
97 function getURLsFromElement(element) 92 function getURLsFromElement(element)
98 { 93 {
99 var urls; 94 let urls;
100 switch (element.localName) 95 switch (element.localName)
101 { 96 {
102 case "object": 97 case "object":
103 urls = getURLsFromObjectElement(element); 98 urls = getURLsFromObjectElement(element);
104 break; 99 break;
105 100
106 case "video": 101 case "video":
107 case "audio": 102 case "audio":
108 case "picture": 103 case "picture":
109 urls = getURLsFromMediaElement(element); 104 urls = getURLsFromMediaElement(element);
110 break; 105 break;
111 106
112 default: 107 default:
113 urls = getURLsFromAttributes(element); 108 urls = getURLsFromAttributes(element);
114 break; 109 break;
115 } 110 }
116 111
117 for (var i = 0; i < urls.length; i++) 112 for (let i = 0; i < urls.length; i++)
118 { 113 {
119 if (/^(?!https?:)[\w-]+:/i.test(urls[i])) 114 if (/^(?!https?:)[\w-]+:/i.test(urls[i]))
120 urls.splice(i--, 1); 115 urls.splice(i--, 1);
121 } 116 }
122 117
123 return urls; 118 return urls;
124 } 119 }
125 120
126 function checkCollapse(element) 121 function checkCollapse(element)
127 { 122 {
128 var mediatype = typeMap[element.localName]; 123 let mediatype = typeMap[element.localName];
129 if (!mediatype) 124 if (!mediatype)
130 return; 125 return;
131 126
132 var urls = getURLsFromElement(element); 127 let urls = getURLsFromElement(element);
133 if (urls.length == 0) 128 if (urls.length == 0)
134 return; 129 return;
135 130
136 ext.backgroundPage.sendMessage( 131 ext.backgroundPage.sendMessage(
137 { 132 {
138 type: "filters.collapse", 133 type: "filters.collapse",
139 urls: urls, 134 urls: urls,
140 mediatype: mediatype, 135 mediatype: mediatype,
141 baseURL: document.location.href 136 baseURL: document.location.href
142 }, 137 },
143 138
144 function(collapse) 139 collapse =>
145 { 140 {
146 function collapseElement() 141 function collapseElement()
147 { 142 {
148 var propertyName = "display"; 143 let propertyName = "display";
149 var propertyValue = "none"; 144 let propertyValue = "none";
150 if (element.localName == "frame") 145 if (element.localName == "frame")
151 { 146 {
152 propertyName = "visibility"; 147 propertyName = "visibility";
153 propertyValue = "hidden"; 148 propertyValue = "hidden";
154 } 149 }
155 150
156 if (element.style.getPropertyValue(propertyName) != propertyValue || 151 if (element.style.getPropertyValue(propertyName) != propertyValue ||
157 element.style.getPropertyPriority(propertyName) != "important") 152 element.style.getPropertyPriority(propertyName) != "important")
158 element.style.setProperty(propertyName, propertyValue, "important"); 153 element.style.setProperty(propertyName, propertyValue, "important");
159 } 154 }
160 155
161 if (collapse) 156 if (collapse)
162 { 157 {
163 collapseElement(); 158 collapseElement();
164 159
165 new MutationObserver(collapseElement).observe( 160 new MutationObserver(collapseElement).observe(
166 element, { 161 element, {
167 attributes: true, 162 attributes: true,
168 attributeFilter: ["style"] 163 attributeFilter: ["style"]
169 } 164 }
170 ); 165 );
171 } 166 }
172 } 167 }
173 ); 168 );
174 } 169 }
175 170
176 function checkSitekey() 171 function checkSitekey()
177 { 172 {
178 var attr = document.documentElement.getAttribute("data-adblockkey"); 173 let attr = document.documentElement.getAttribute("data-adblockkey");
179 if (attr) 174 if (attr)
180 ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr}); 175 ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr});
181 } 176 }
182 177
183 function getContentDocument(element) 178 function getContentDocument(element)
184 { 179 {
185 try 180 try
186 { 181 {
187 return element.contentDocument; 182 return element.contentDocument;
188 } 183 }
(...skipping 12 matching lines...) Expand all
201 196
202 this.observer = new MutationObserver(this.observe.bind(this)); 197 this.observer = new MutationObserver(this.observe.bind(this));
203 this.trace = this.trace.bind(this); 198 this.trace = this.trace.bind(this);
204 199
205 if (document.readyState == "loading") 200 if (document.readyState == "loading")
206 document.addEventListener("DOMContentLoaded", this.trace); 201 document.addEventListener("DOMContentLoaded", this.trace);
207 else 202 else
208 this.trace(); 203 this.trace();
209 } 204 }
210 ElementHidingTracer.prototype = { 205 ElementHidingTracer.prototype = {
211 checkNodes: function(nodes) 206 checkNodes: nodes =>
212 { 207 {
213 var matchedSelectors = []; 208 let matchedSelectors = [];
214 209
215 // Find all selectors that match any hidden element inside the given nodes. 210 // Find all selectors that match any hidden element inside the given nodes.
216 for (var i = 0; i < this.selectors.length; i++) 211 for (let selector of this.selectors)
217 { 212 {
218 var selector = this.selectors[i]; 213 for (let node of nodes)
214 {
215 let elements = node.querySelectorAll(selector);
216 let matched = false;
219 217
220 for (var j = 0; j < nodes.length; j++) 218 for (let element of elements)
221 {
222 var elements = nodes[j].querySelectorAll(selector);
223 var matched = false;
224
225 for (var k = 0; k < elements.length; k++)
226 { 219 {
227 // Only consider selectors that actually have an effect on the 220 // Only consider selectors that actually have an effect on the
228 // computed styles, and aren't overridden by rules with higher 221 // computed styles, and aren't overridden by rules with higher
229 // priority, or haven't been circumvented in a different way. 222 // priority, or haven't been circumvented in a different way.
230 if (getComputedStyle(elements[k]).display == "none") 223 if (getComputedStyle(element).display == "none")
231 { 224 {
232 matchedSelectors.push(selector); 225 matchedSelectors.push(selector);
233 matched = true; 226 matched = true;
234 break; 227 break;
235 } 228 }
236 } 229 }
237 230
238 if (matched) 231 if (matched)
239 break; 232 break;
240 } 233 }
241 } 234 }
242 235
243 if (matchedSelectors.length > 0) 236 if (matchedSelectors.length > 0)
244 ext.backgroundPage.sendMessage({ 237 ext.backgroundPage.sendMessage({
245 type: "devtools.traceElemHide", 238 type: "devtools.traceElemHide",
246 selectors: matchedSelectors 239 selectors: matchedSelectors
247 }); 240 });
248 }, 241 },
249 242
250 onTimeout: function() 243 onTimeout: function()
251 { 244 {
252 this.checkNodes(this.changedNodes); 245 this.checkNodes(this.changedNodes);
253 this.changedNodes = []; 246 this.changedNodes = [];
254 this.timeout = null; 247 this.timeout = null;
255 }, 248 },
256 249
257 observe: function(mutations) 250 observe: function(mutations)
258 { 251 {
259 // Forget previously changed nodes that are no longer in the DOM. 252 // Forget previously changed nodes that are no longer in the DOM.
260 for (var i = 0; i < this.changedNodes.length; i++) 253 for (let i = 0; i < this.changedNodes.length; i++)
261 { 254 {
262 if (!document.contains(this.changedNodes[i])) 255 if (!document.contains(this.changedNodes[i]))
263 this.changedNodes.splice(i--, 1); 256 this.changedNodes.splice(i--, 1);
264 } 257 }
265 258
266 for (var j = 0; j < mutations.length; j++) 259 for (let mutation of mutations)
267 { 260 {
268 var mutation = mutations[j]; 261 let node = mutation.target;
269 var node = mutation.target;
270 262
271 // Ignore mutations of nodes that aren't in the DOM anymore. 263 // Ignore mutations of nodes that aren't in the DOM anymore.
272 if (!document.contains(node)) 264 if (!document.contains(node))
273 continue; 265 continue;
274 266
275 // Since querySelectorAll() doesn't consider the root itself 267 // Since querySelectorAll() doesn't consider the root itself
276 // and since CSS selectors can also match siblings, we have 268 // and since CSS selectors can also match siblings, we have
277 // to consider the parent node for attribute mutations. 269 // to consider the parent node for attribute mutations.
278 if (mutation.type == "attributes") 270 if (mutation.type == "attributes")
279 node = node.parentNode; 271 node = node.parentNode;
280 272
281 var addNode = true; 273 let addNode = true;
282 for (var k = 0; k < this.changedNodes.length; k++) 274 for (let i = 0; i < this.changedNodes.length; i++)
283 { 275 {
284 var previouslyChangedNode = this.changedNodes[k]; 276 let previouslyChangedNode = this.changedNodes[i];
285 277
286 // If we are already going to check an ancestor of this node, 278 // If we are already going to check an ancestor of this node,
287 // we can ignore this node, since it will be considered anyway 279 // we can ignore this node, since it will be considered anyway
288 // when checking one of its ancestors. 280 // when checking one of its ancestors.
289 if (previouslyChangedNode.contains(node)) 281 if (previouslyChangedNode.contains(node))
290 { 282 {
291 addNode = false; 283 addNode = false;
292 break; 284 break;
293 } 285 }
294 286
295 // If this node is an ancestor of a node that previously changed, 287 // If this node is an ancestor of a node that previously changed,
296 // we can ignore that node, since it will be considered anyway 288 // we can ignore that node, since it will be considered anyway
297 // when checking one of its ancestors. 289 // when checking one of its ancestors.
298 if (node.contains(previouslyChangedNode)) 290 if (node.contains(previouslyChangedNode))
299 this.changedNodes.splice(k--, 1); 291 this.changedNodes.splice(i--, 1);
300 } 292 }
301 293
302 if (addNode) 294 if (addNode)
303 this.changedNodes.push(node); 295 this.changedNodes.push(node);
304 } 296 }
305 297
306 // Check only nodes whose descendants have changed, and not more often 298 // Check only nodes whose descendants have changed, and not more often
307 // than once a second. Otherwise large pages with a lot of DOM mutations 299 // than once a second. Otherwise large pages with a lot of DOM mutations
308 // (like YouTube) freeze when the devtools panel is active. 300 // (like YouTube) freeze when the devtools panel is active.
309 if (this.timeout == null) 301 if (this.timeout == null)
(...skipping 17 matching lines...) Expand all
327 disconnect: function() 319 disconnect: function()
328 { 320 {
329 document.removeEventListener("DOMContentLoaded", this.trace); 321 document.removeEventListener("DOMContentLoaded", this.trace);
330 this.observer.disconnect(); 322 this.observer.disconnect();
331 clearTimeout(this.timeout); 323 clearTimeout(this.timeout);
332 } 324 }
333 }; 325 };
334 326
335 function runInPageContext(fn, arg) 327 function runInPageContext(fn, arg)
336 { 328 {
337 var script = document.createElement("script"); 329 let script = document.createElement("script");
338 script.type = "application/javascript"; 330 script.type = "application/javascript";
339 script.async = false; 331 script.async = false;
340 script.textContent = "(" + fn + ")(" + JSON.stringify(arg) + ");"; 332 script.textContent = "(" + fn + ")(" + JSON.stringify(arg) + ");";
341 document.documentElement.appendChild(script); 333 document.documentElement.appendChild(script);
342 document.documentElement.removeChild(script); 334 document.documentElement.removeChild(script);
343 } 335 }
344 336
345 // Chrome doesn't allow us to intercept WebSockets[1], and therefore 337 // Chrome doesn't allow us to intercept WebSockets[1], and therefore
346 // some ad networks are misusing them as a way to serve adverts and circumvent 338 // some ad networks are misusing them as a way to serve adverts and circumvent
347 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket 339 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket
348 // connections from being opened. 340 // connections from being opened.
349 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 341 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
350 function wrapWebSocket() 342 function wrapWebSocket()
351 { 343 {
352 var eventName = "abpws-" + Math.random().toString(36).substr(2); 344 let eventName = "abpws-" + Math.random().toString(36).substr(2);
353 345
354 document.addEventListener(eventName, function(event) 346 document.addEventListener(eventName, event =>
355 { 347 {
356 ext.backgroundPage.sendMessage({ 348 ext.backgroundPage.sendMessage({
357 type: "request.websocket", 349 type: "request.websocket",
358 url: event.detail.url 350 url: event.detail.url
359 }, function (block) 351 }, block =>
360 { 352 {
361 document.dispatchEvent( 353 document.dispatchEvent(
362 new CustomEvent(eventName + "-" + event.detail.url, {detail: block}) 354 new CustomEvent(eventName + "-" + event.detail.url, {detail: block})
363 ); 355 );
364 }); 356 });
365 }); 357 });
366 358
367 runInPageContext(function(eventName) 359 runInPageContext(eventName =>
368 { 360 {
369 // As far as possible we must track everything we use that could be 361 // As far as possible we must track everything we use that could be
370 // sabotaged by the website later in order to circumvent us. 362 // sabotaged by the website later in order to circumvent us.
371 var RealWebSocket = WebSocket; 363 let RealWebSocket = WebSocket;
372 var closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.cl ose); 364 let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.cl ose);
373 var addEventListener = document.addEventListener.bind(document); 365 let addEventListener = document.addEventListener.bind(document);
374 var removeEventListener = document.removeEventListener.bind(document); 366 let removeEventListener = document.removeEventListener.bind(document);
375 var dispatchEvent = document.dispatchEvent.bind(document); 367 let dispatchEvent = document.dispatchEvent.bind(document);
376 var CustomEvent = window.CustomEvent; 368 let CustomEvent = window.CustomEvent;
377 369
378 function checkRequest(url, callback) 370 function checkRequest(url, callback)
379 { 371 {
380 var incomingEventName = eventName + "-" + url; 372 let incomingEventName = eventName + "-" + url;
381 function listener(event) 373 function listener(event)
382 { 374 {
383 callback(event.detail); 375 callback(event.detail);
384 removeEventListener(incomingEventName, listener); 376 removeEventListener(incomingEventName, listener);
385 } 377 }
386 addEventListener(incomingEventName, listener); 378 addEventListener(incomingEventName, listener);
387 379
388 dispatchEvent(new CustomEvent(eventName, { 380 dispatchEvent(new CustomEvent(eventName, {
389 detail: {url: url} 381 detail: {url: url}
390 })); 382 }));
391 } 383 }
392 384
393 function WrappedWebSocket(url) 385 function WrappedWebSocket(url)
394 { 386 {
395 // Throw correct exceptions if the constructor is used improperly. 387 // Throw correct exceptions if the constructor is used improperly.
396 if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); 388 if (!(this instanceof WrappedWebSocket)) return RealWebSocket();
397 if (arguments.length < 1) return new RealWebSocket(); 389 if (arguments.length < 1) return new RealWebSocket();
398 390
399 var websocket; 391 let websocket;
400 if (arguments.length == 1) 392 if (arguments.length == 1)
401 websocket = new RealWebSocket(url); 393 websocket = new RealWebSocket(url);
402 else 394 else
403 websocket = new RealWebSocket(url, arguments[1]); 395 websocket = new RealWebSocket(url, arguments[1]);
404 396
405 checkRequest(websocket.url, function(blocked) 397 checkRequest(websocket.url, blocked =>
406 { 398 {
407 if (blocked) 399 if (blocked)
408 closeWebSocket(websocket); 400 closeWebSocket(websocket);
409 }); 401 });
410 402
411 return websocket; 403 return websocket;
412 } 404 }
413 WrappedWebSocket.prototype = RealWebSocket.prototype; 405 WrappedWebSocket.prototype = RealWebSocket.prototype;
414 WebSocket = WrappedWebSocket.bind(); 406 WebSocket = WrappedWebSocket.bind();
415 Object.defineProperties(WebSocket, { 407 Object.defineProperties(WebSocket, {
416 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true}, 408 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true},
417 OPEN: {value: RealWebSocket.OPEN, enumerable: true}, 409 OPEN: {value: RealWebSocket.OPEN, enumerable: true},
418 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true}, 410 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true},
419 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true}, 411 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true},
420 prototype: {value: RealWebSocket.prototype} 412 prototype: {value: RealWebSocket.prototype}
421 }); 413 });
422 414
423 RealWebSocket.prototype.constructor = WebSocket; 415 RealWebSocket.prototype.constructor = WebSocket;
424 }, eventName); 416 }, eventName);
425 } 417 }
426 418
427 function ElemHide() 419 function ElemHide()
428 { 420 {
429 this.shadow = this.createShadowTree(); 421 this.shadow = this.createShadowTree();
430 this.style = null; 422 this.style = null;
431 this.tracer = null; 423 this.tracer = null;
432 424
433 this.elemHideEmulation = new ElemHideEmulation( 425 this.elemHideEmulation = new ElemHideEmulation(
434 window, 426 window,
435 function(callback) 427 callback =>
436 { 428 {
437 ext.backgroundPage.sendMessage({ 429 ext.backgroundPage.sendMessage({
438 type: "filters.get", 430 type: "filters.get",
439 what: "elemhideemulation" 431 what: "elemhideemulation"
440 }, callback); 432 }, callback);
441 }, 433 },
442 this.addSelectors.bind(this) 434 this.addSelectors.bind(this)
443 ); 435 );
444 } 436 }
445 ElemHide.prototype = { 437 ElemHide.prototype = {
446 selectorGroupSize: 200, 438 selectorGroupSize: 200,
447 439
448 createShadowTree: function() 440 createShadowTree: () =>
449 { 441 {
450 // Use Shadow DOM if available as to not mess with with web pages that 442 // Use Shadow DOM if available as to not mess with with web pages that
451 // rely on the order of their own <style> tags (#309). However, creating 443 // rely on the order of their own <style> tags (#309). However, creating
452 // a shadow root breaks running CSS transitions. So we have to create 444 // a shadow root breaks running CSS transitions. So we have to create
453 // the shadow root before transistions might start (#452). 445 // the shadow root before transistions might start (#452).
454 if (!("createShadowRoot" in document.documentElement)) 446 if (!("createShadowRoot" in document.documentElement))
455 return null; 447 return null;
456 448
457 // Using shadow DOM causes issues on some Google websites, 449 // Using shadow DOM causes issues on some Google websites,
458 // including Google Docs, Gmail and Blogger (#1770, #2602, #2687). 450 // including Google Docs, Gmail and Blogger (#1770, #2602, #2687).
459 if (/\.(?:google|blogger)\.com$/.test(document.domain)) 451 if (/\.(?:google|blogger)\.com$/.test(document.domain))
460 return null; 452 return null;
461 453
462 // Finally since some users have both AdBlock and Adblock Plus installed we 454 // Finally since some users have both AdBlock and Adblock Plus installed we
463 // have to consider how the two extensions interact. For example we want to 455 // have to consider how the two extensions interact. For example we want to
464 // avoid creating the shadowRoot twice. 456 // avoid creating the shadowRoot twice.
465 var shadow = document.documentElement.shadowRoot || 457 let shadow = document.documentElement.shadowRoot ||
466 document.documentElement.createShadowRoot(); 458 document.documentElement.createShadowRoot();
467 shadow.appendChild(document.createElement("shadow")); 459 shadow.appendChild(document.createElement("shadow"));
468 460
469 // Stop the website from messing with our shadow root (#4191, #4298). 461 // Stop the website from messing with our shadow root (#4191, #4298).
470 if ("shadowRoot" in Element.prototype) 462 if ("shadowRoot" in Element.prototype)
471 { 463 {
472 runInPageContext(function() 464 runInPageContext(() =>
473 { 465 {
474 var ourShadowRoot = document.documentElement.shadowRoot; 466 let ourShadowRoot = document.documentElement.shadowRoot;
475 if (!ourShadowRoot) 467 if (!ourShadowRoot)
476 return; 468 return;
477 var desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoo t"); 469 let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoo t");
478 var 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: function() 473 configurable: true, enumerable: true, get: function()
482 { 474 {
483 var shadow = shadowRoot(this); 475 let shadow = shadowRoot(this);
484 return shadow == ourShadowRoot ? null : shadow; 476 return shadow == ourShadowRoot ? null : shadow;
485 } 477 }
486 }); 478 });
487 }, null); 479 }, null);
488 } 480 }
489 481
490 return shadow; 482 return shadow;
491 }, 483 },
492 484
493 addSelectors: function(selectors) 485 addSelectors: function(selectors)
(...skipping 17 matching lines...) Expand all
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
517 // before each selector, in order to match elements within the 509 // before each selector, in order to match elements within the
518 // insertion point. 510 // insertion point.
519 if (this.shadow) 511 if (this.shadow)
520 { 512 {
521 var preparedSelectors = []; 513 let preparedSelectors = [];
522 for (var i = 0; i < selectors.length; i++) 514 for (let selector of selectors)
523 { 515 {
524 var subSelectors = splitSelector(selectors[i]); 516 let subSelectors = splitSelector(selector);
525 for (var j = 0; j < subSelectors.length; j++) 517 for (let subSelector of subSelectors)
526 preparedSelectors.push("::content " + subSelectors[j]); 518 preparedSelectors.push("::content " + subSelector);
527 } 519 }
528 selectors = preparedSelectors; 520 selectors = preparedSelectors;
529 } 521 }
530 522
531 // Safari only allows 8192 primitive selectors to be injected at once[1], we 523 // Safari only allows 8192 primitive selectors to be injected at once[1], we
532 // therefore chunk the inserted selectors into groups of 200 to be safe. 524 // therefore chunk the inserted selectors into groups of 200 to be safe.
533 // (Chrome also has a limit, larger... but we're not certain exactly what it 525 // (Chrome also has a limit, larger... but we're not certain exactly what it
534 // is! Edge apparently has no such limit.) 526 // is! Edge apparently has no such limit.)
535 // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69 debb75fc1de/Source/WebCore/css/RuleSet.h#L68 527 // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69 debb75fc1de/Source/WebCore/css/RuleSet.h#L68
536 for (var i = 0; i < selectors.length; i += this.selectorGroupSize) 528 for (let i = 0; i < selectors.length; i += this.selectorGroupSize)
537 { 529 {
538 var selector = selectors.slice(i, i + this.selectorGroupSize).join(", "); 530 let selector = selectors.slice(i, i + this.selectorGroupSize).join(", ");
539 this.style.sheet.insertRule(selector + "{display: none !important;}", 531 this.style.sheet.insertRule(selector + "{display: none !important;}",
540 this.style.sheet.cssRules.length); 532 this.style.sheet.cssRules.length);
541 } 533 }
542 }, 534 },
543 535
544 apply: function() 536 apply: function()
545 { 537 {
546 var selectors = null; 538 let selectors = null;
547 var elemHideEmulationLoaded = false; 539 let elemHideEmulationLoaded = false;
548 540
549 var checkLoaded = function() 541 let checkLoaded = function()
550 { 542 {
551 if (!selectors || !elemHideEmulationLoaded) 543 if (!selectors || !elemHideEmulationLoaded)
552 return; 544 return;
553 545
554 if (this.tracer) 546 if (this.tracer)
555 this.tracer.disconnect(); 547 this.tracer.disconnect();
556 this.tracer = null; 548 this.tracer = null;
557 549
558 if (this.style && this.style.parentElement) 550 if (this.style && this.style.parentElement)
559 this.style.parentElement.removeChild(this.style); 551 this.style.parentElement.removeChild(this.style);
560 this.style = null; 552 this.style = null;
561 553
562 this.addSelectors(selectors.selectors); 554 this.addSelectors(selectors.selectors);
563 this.elemHideEmulation.apply(); 555 this.elemHideEmulation.apply();
564 556
565 if (selectors.trace) 557 if (selectors.trace)
566 this.tracer = new ElementHidingTracer(selectors.selectors); 558 this.tracer = new ElementHidingTracer(selectors.selectors);
567 }.bind(this); 559 }.bind(this);
568 560
569 ext.backgroundPage.sendMessage({type: "get-selectors"}, function(response) 561 ext.backgroundPage.sendMessage({type: "get-selectors"}, response =>
570 { 562 {
571 selectors = response; 563 selectors = response;
572 checkLoaded(); 564 checkLoaded();
573 }); 565 });
574 566
575 this.elemHideEmulation.load(function() 567 this.elemHideEmulation.load(() =>
576 { 568 {
577 elemHideEmulationLoaded = true; 569 elemHideEmulationLoaded = true;
578 checkLoaded(); 570 checkLoaded();
579 }); 571 });
580 } 572 }
581 }; 573 };
582 574
583 if (document instanceof HTMLDocument) 575 if (document instanceof HTMLDocument)
584 { 576 {
585 checkSitekey(); 577 checkSitekey();
586 wrapWebSocket(); 578 wrapWebSocket();
587 579
588 var elemhide = new ElemHide(); 580 let elemhide = new ElemHide();
589 elemhide.apply(); 581 elemhide.apply();
590 582
591 document.addEventListener("error", function(event) 583 document.addEventListener("error", event =>
592 { 584 {
593 checkCollapse(event.target); 585 checkCollapse(event.target);
594 }, true); 586 }, true);
595 587
596 document.addEventListener("load", function(event) 588 document.addEventListener("load", event =>
597 { 589 {
598 var element = event.target; 590 let element = event.target;
599 if (/^i?frame$/.test(element.localName)) 591 if (/^i?frame$/.test(element.localName))
600 checkCollapse(element); 592 checkCollapse(element);
601 }, true); 593 }, true);
602 } 594 }
OLDNEW
« chrome/ext/common.js ('K') | « ext/common.js ('k') | lib/compat.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld