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

Side by Side Diff: include.preload.js

Issue 29374674: Issue 4864 - Start using ESLint for adblockpluschrome (Closed)
Patch Set: Use var for ext declarations again Created Feb. 8, 2017, 9:02 a.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 /* globals ElemHideEmulation, splitSelector */
19
18 "use strict"; 20 "use strict";
19 21
20 const typeMap = { 22 // This variable is also used by our other content scripts.
Sebastian Noack 2017/02/09 01:04:50 This comment is kinda redundant with the /* global
wspee 2017/03/02 10:27:13 You might want to also comment on this? But as far
kzar 2017/03/07 11:41:35 Yes, I think for now this stuff will stay as it is
21 "img": "IMAGE", 23 let elemhide;
22 "input": "IMAGE", 24
23 "picture": "IMAGE", 25 const typeMap = new Map([
24 "audio": "MEDIA", 26 ["img", "IMAGE"],
25 "video": "MEDIA", 27 ["input", "IMAGE"],
26 "frame": "SUBDOCUMENT", 28 ["picture", "IMAGE"],
27 "iframe": "SUBDOCUMENT", 29 ["audio", "MEDIA"],
28 "object": "OBJECT", 30 ["video", "MEDIA"],
29 "embed": "OBJECT" 31 ["frame", "SUBDOCUMENT"],
30 }; 32 ["iframe", "SUBDOCUMENT"],
33 ["object", "OBJECT"],
34 ["embed", "OBJECT"]
35 ]);
31 36
32 function getURLsFromObjectElement(element) 37 function getURLsFromObjectElement(element)
33 { 38 {
34 let url = element.getAttribute("data"); 39 let url = element.getAttribute("data");
35 if (url) 40 if (url)
36 return [url]; 41 return [url];
37 42
38 for (let child of element.children) 43 for (let child of element.children)
39 { 44 {
40 if (child.localName != "param") 45 if (child.localName != "param")
41 continue; 46 continue;
42 47
43 let name = child.getAttribute("name"); 48 let name = child.getAttribute("name");
44 if (name != "movie" && // Adobe Flash 49 if (name != "movie" && // Adobe Flash
45 name != "source" && // Silverlight 50 name != "source" && // Silverlight
46 name != "src" && // Real Media + Quicktime 51 name != "src" && // Real Media + Quicktime
47 name != "FileName") // Windows Media 52 name != "FileName") // Windows Media
48 continue; 53 continue;
49 54
50 let value = child.getAttribute("value"); 55 let value = child.getAttribute("value");
51 if (!value) 56 if (!value)
52 continue; 57 continue;
53 58
54 return [value]; 59 return [value];
55 } 60 }
56 61
(...skipping 20 matching lines...) Expand all
77 return urls; 82 return urls;
78 } 83 }
79 84
80 function getURLsFromMediaElement(element) 85 function getURLsFromMediaElement(element)
81 { 86 {
82 let urls = getURLsFromAttributes(element); 87 let urls = getURLsFromAttributes(element);
83 88
84 for (let child of element.children) 89 for (let child of element.children)
85 { 90 {
86 if (child.localName == "source" || child.localName == "track") 91 if (child.localName == "source" || child.localName == "track")
87 urls.push.apply(urls, getURLsFromAttributes(child)); 92 urls.push(...getURLsFromAttributes(child));
88 } 93 }
89 94
90 if (element.poster) 95 if (element.poster)
91 urls.push(element.poster); 96 urls.push(element.poster);
92 97
93 return urls; 98 return urls;
94 } 99 }
95 100
96 function getURLsFromElement(element) 101 function getURLsFromElement(element)
97 { 102 {
(...skipping 19 matching lines...) Expand all
117 { 122 {
118 if (/^(?!https?:)[\w-]+:/i.test(urls[i])) 123 if (/^(?!https?:)[\w-]+:/i.test(urls[i]))
119 urls.splice(i--, 1); 124 urls.splice(i--, 1);
120 } 125 }
121 126
122 return urls; 127 return urls;
123 } 128 }
124 129
125 function checkCollapse(element) 130 function checkCollapse(element)
126 { 131 {
127 let mediatype = typeMap[element.localName]; 132 let mediatype = typeMap.get(element.localName);
128 if (!mediatype) 133 if (!mediatype)
129 return; 134 return;
130 135
131 let urls = getURLsFromElement(element); 136 let urls = getURLsFromElement(element);
132 if (urls.length == 0) 137 if (urls.length == 0)
133 return; 138 return;
134 139
135 ext.backgroundPage.sendMessage( 140 ext.backgroundPage.sendMessage(
136 { 141 {
137 type: "filters.collapse", 142 type: "filters.collapse",
138 urls: urls, 143 urls,
139 mediatype: mediatype, 144 mediatype,
140 baseURL: document.location.href 145 baseURL: document.location.href
141 }, 146 },
142 147
143 collapse => 148 collapse =>
144 { 149 {
145 function collapseElement() 150 function collapseElement()
146 { 151 {
147 let propertyName = "display"; 152 let propertyName = "display";
148 let propertyValue = "none"; 153 let propertyValue = "none";
149 if (element.localName == "frame") 154 if (element.localName == "frame")
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 break; 236 break;
232 } 237 }
233 } 238 }
234 239
235 if (matched) 240 if (matched)
236 break; 241 break;
237 } 242 }
238 } 243 }
239 244
240 if (matchedSelectors.length > 0) 245 if (matchedSelectors.length > 0)
246 {
241 ext.backgroundPage.sendMessage({ 247 ext.backgroundPage.sendMessage({
242 type: "devtools.traceElemHide", 248 type: "devtools.traceElemHide",
243 selectors: matchedSelectors 249 selectors: matchedSelectors
244 }); 250 });
251 }
245 }, 252 },
246 253
247 onTimeout() 254 onTimeout()
248 { 255 {
249 this.checkNodes(this.changedNodes); 256 this.checkNodes(this.changedNodes);
250 this.changedNodes = []; 257 this.changedNodes = [];
251 this.timeout = null; 258 this.timeout = null;
252 }, 259 },
253 260
254 observe(mutations) 261 observe(mutations)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 document.documentElement.removeChild(script); 345 document.documentElement.removeChild(script);
339 } 346 }
340 347
341 // Chrome doesn't allow us to intercept WebSockets[1], and therefore 348 // Chrome doesn't allow us to intercept WebSockets[1], and therefore
342 // some ad networks are misusing them as a way to serve adverts and circumvent 349 // some ad networks are misusing them as a way to serve adverts and circumvent
343 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket 350 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket
344 // connections from being opened. 351 // connections from being opened.
345 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 352 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
346 function wrapWebSocket() 353 function wrapWebSocket()
347 { 354 {
348 let eventName = "abpws-" + Math.random().toString(36).substr(2); 355 let randomEventName = "abpws-" + Math.random().toString(36).substr(2);
349 356
350 document.addEventListener(eventName, event => 357 document.addEventListener(randomEventName, event =>
351 { 358 {
352 ext.backgroundPage.sendMessage({ 359 ext.backgroundPage.sendMessage({
353 type: "request.websocket", 360 type: "request.websocket",
354 url: event.detail.url 361 url: event.detail.url
355 }, block => 362 }, block =>
356 { 363 {
357 document.dispatchEvent( 364 document.dispatchEvent(new CustomEvent(
358 new CustomEvent(eventName + "-" + event.detail.url, {detail: block}) 365 randomEventName + "-" + event.detail.url, {detail: block}
Sebastian Noack 2017/02/09 01:04:50 If you rename the argument to "detail", you can us
kzar 2017/02/20 10:27:31 I think block is a better name for the variable th
359 ); 366 ));
360 }); 367 });
361 }); 368 });
362 369
363 runInPageContext(eventName => 370 runInPageContext(eventName =>
364 { 371 {
365 // As far as possible we must track everything we use that could be 372 // As far as possible we must track everything we use that could be
366 // sabotaged by the website later in order to circumvent us. 373 // sabotaged by the website later in order to circumvent us.
367 let RealWebSocket = WebSocket; 374 let RealWebSocket = WebSocket;
368 let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.cl ose); 375 let RealCustomEvent = window.CustomEvent;
376 let closeWebSocket = Function.prototype.call.bind(
377 RealWebSocket.prototype.close
378 );
369 let addEventListener = document.addEventListener.bind(document); 379 let addEventListener = document.addEventListener.bind(document);
370 let removeEventListener = document.removeEventListener.bind(document); 380 let removeEventListener = document.removeEventListener.bind(document);
371 let dispatchEvent = document.dispatchEvent.bind(document); 381 let dispatchEvent = document.dispatchEvent.bind(document);
372 let CustomEvent = window.CustomEvent;
373 382
374 function checkRequest(url, callback) 383 function checkRequest(url, callback)
375 { 384 {
376 let incomingEventName = eventName + "-" + url; 385 let incomingEventName = eventName + "-" + url;
377 function listener(event) 386 function listener(event)
378 { 387 {
379 callback(event.detail); 388 callback(event.detail);
380 removeEventListener(incomingEventName, listener); 389 removeEventListener(incomingEventName, listener);
381 } 390 }
382 addEventListener(incomingEventName, listener); 391 addEventListener(incomingEventName, listener);
383 392
384 dispatchEvent(new CustomEvent(eventName, { 393 dispatchEvent(new RealCustomEvent(eventName, {detail: {url}}));
385 detail: {url: url}
386 }));
387 } 394 }
388 395
389 function WrappedWebSocket(url) 396 function WrappedWebSocket(url, ...args)
390 { 397 {
391 // Throw correct exceptions if the constructor is used improperly. 398 // Throw correct exceptions if the constructor is used improperly.
392 if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); 399 if (!(this instanceof WrappedWebSocket)) return RealWebSocket();
393 if (arguments.length < 1) return new RealWebSocket(); 400 if (arguments.length < 1) return new RealWebSocket();
394 401
395 let websocket; 402 let websocket;
396 if (arguments.length == 1) 403 if (arguments.length == 1)
397 websocket = new RealWebSocket(url); 404 websocket = new RealWebSocket(url);
398 else 405 else
399 websocket = new RealWebSocket(url, arguments[1]); 406 websocket = new RealWebSocket(url, args[0]);
400 407
401 checkRequest(websocket.url, blocked => 408 checkRequest(websocket.url, blocked =>
402 { 409 {
403 if (blocked) 410 if (blocked)
404 closeWebSocket(websocket); 411 closeWebSocket(websocket);
405 }); 412 });
406 413
407 return websocket; 414 return websocket;
408 } 415 }
409 WrappedWebSocket.prototype = RealWebSocket.prototype; 416 WrappedWebSocket.prototype = RealWebSocket.prototype;
410 WebSocket = WrappedWebSocket.bind(); 417 window.WebSocket = WrappedWebSocket.bind();
411 Object.defineProperties(WebSocket, { 418 Object.defineProperties(WebSocket, {
412 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true}, 419 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true},
413 OPEN: {value: RealWebSocket.OPEN, enumerable: true}, 420 OPEN: {value: RealWebSocket.OPEN, enumerable: true},
414 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true}, 421 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true},
415 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true}, 422 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true},
416 prototype: {value: RealWebSocket.prototype} 423 prototype: {value: RealWebSocket.prototype}
417 }); 424 });
418 425
419 RealWebSocket.prototype.constructor = WebSocket; 426 RealWebSocket.prototype.constructor = WebSocket;
420 }, eventName); 427 }, randomEventName);
421 } 428 }
422 429
423 function ElemHide() 430 function ElemHide()
424 { 431 {
425 this.shadow = this.createShadowTree(); 432 this.shadow = this.createShadowTree();
426 this.style = null; 433 this.style = null;
427 this.tracer = null; 434 this.tracer = null;
428 435
429 this.elemHideEmulation = new ElemHideEmulation( 436 this.elemHideEmulation = new ElemHideEmulation(
430 window, 437 window,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 shadow.appendChild(document.createElement("shadow")); 470 shadow.appendChild(document.createElement("shadow"));
464 471
465 // Stop the website from messing with our shadow root (#4191, #4298). 472 // Stop the website from messing with our shadow root (#4191, #4298).
466 if ("shadowRoot" in Element.prototype) 473 if ("shadowRoot" in Element.prototype)
467 { 474 {
468 runInPageContext(() => 475 runInPageContext(() =>
469 { 476 {
470 let ourShadowRoot = document.documentElement.shadowRoot; 477 let ourShadowRoot = document.documentElement.shadowRoot;
471 if (!ourShadowRoot) 478 if (!ourShadowRoot)
472 return; 479 return;
473 let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoo t"); 480 let desc = Object.getOwnPropertyDescriptor(Element.prototype,
481 "shadowRoot");
474 let shadowRoot = Function.prototype.call.bind(desc.get); 482 let shadowRoot = Function.prototype.call.bind(desc.get);
475 483
476 Object.defineProperty(Element.prototype, "shadowRoot", { 484 Object.defineProperty(Element.prototype, "shadowRoot", {
477 configurable: true, enumerable: true, get() 485 configurable: true, enumerable: true, get()
478 { 486 {
479 let shadow = shadowRoot(this); 487 let thisShadow = shadowRoot(this);
480 return shadow == ourShadowRoot ? null : shadow; 488 return thisShadow == ourShadowRoot ? null : shadow;
481 } 489 }
482 }); 490 });
483 }, null); 491 }, null);
484 } 492 }
485 493
486 return shadow; 494 return shadow;
487 }, 495 },
488 496
489 addSelectors(selectors) 497 addSelectors(selectors)
490 { 498 {
491 if (selectors.length == 0) 499 if (selectors.length == 0)
492 return; 500 return;
493 501
494 if (!this.style) 502 if (!this.style)
495 { 503 {
496 // Create <style> element lazily, only if we add styles. Add it to 504 // Create <style> element lazily, only if we add styles. Add it to
497 // the shadow DOM if possible. Otherwise fallback to the <head> or 505 // the shadow DOM if possible. Otherwise fallback to the <head> or
498 // <html> element. If we have injected a style element before that 506 // <html> element. If we have injected a style element before that
499 // has been removed (the sheet property is null), create a new one. 507 // has been removed (the sheet property is null), create a new one.
500 this.style = document.createElement("style"); 508 this.style = document.createElement("style");
501 (this.shadow || document.head 509 (this.shadow || document.head ||
502 || document.documentElement).appendChild(this.style); 510 document.documentElement).appendChild(this.style);
Sebastian Noack 2017/02/09 01:04:50 Is the fallback to document.documentElement even s
kzar 2017/02/20 10:27:31 I have no idea.
503 511
504 // It can happen that the frame already navigated to a different 512 // It can happen that the frame already navigated to a different
505 // document while we were waiting for the background page to respond. 513 // document while we were waiting for the background page to respond.
506 // In that case the sheet property will stay null, after addind the 514 // In that case the sheet property will stay null, after addind the
507 // <style> element to the shadow DOM. 515 // <style> element to the shadow DOM.
508 if (!this.style.sheet) 516 if (!this.style.sheet)
509 return; 517 return;
510 } 518 }
511 519
512 // If using shadow DOM, we have to add the ::content pseudo-element 520 // If using shadow DOM, we have to add the ::content pseudo-element
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 checkLoaded(); 582 checkLoaded();
575 }); 583 });
576 } 584 }
577 }; 585 };
578 586
579 if (document instanceof HTMLDocument) 587 if (document instanceof HTMLDocument)
580 { 588 {
581 checkSitekey(); 589 checkSitekey();
582 wrapWebSocket(); 590 wrapWebSocket();
583 591
584 // This variable is also used by our other content scripts, outside of the 592 elemhide = new ElemHide();
585 // current scope.
586 var elemhide = new ElemHide();
587 elemhide.apply(); 593 elemhide.apply();
588 594
589 document.addEventListener("error", event => 595 document.addEventListener("error", event =>
590 { 596 {
591 checkCollapse(event.target); 597 checkCollapse(event.target);
592 }, true); 598 }, true);
593 599
594 document.addEventListener("load", event => 600 document.addEventListener("load", event =>
595 { 601 {
596 let element = event.target; 602 let element = event.target;
597 if (/^i?frame$/.test(element.localName)) 603 if (/^i?frame$/.test(element.localName))
598 checkCollapse(element); 604 checkCollapse(element);
599 }, true); 605 }, true);
600 } 606 }
OLDNEW

Powered by Google App Engine
This is Rietveld