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

Powered by Google App Engine
This is Rietveld