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: Stop using commonjs Created Feb. 21, 2017, 5:08 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
« 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 // This variable is also used by our other content scripts.
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 22 matching lines...) Expand all
172 ); 177 );
173 } 178 }
174 179
175 function checkSitekey() 180 function checkSitekey()
176 { 181 {
177 let attr = document.documentElement.getAttribute("data-adblockkey"); 182 let attr = document.documentElement.getAttribute("data-adblockkey");
178 if (attr) 183 if (attr)
179 ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr}); 184 ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr});
180 } 185 }
181 186
182 function getContentDocument(element)
183 {
184 try
185 {
186 return element.contentDocument;
187 }
188 catch (e)
189 {
190 return null;
191 }
192 }
193
194 function ElementHidingTracer(selectors) 187 function ElementHidingTracer(selectors)
195 { 188 {
196 this.selectors = selectors; 189 this.selectors = selectors;
197 190
198 this.changedNodes = []; 191 this.changedNodes = [];
199 this.timeout = null; 192 this.timeout = null;
200 193
201 this.observer = new MutationObserver(this.observe.bind(this)); 194 this.observer = new MutationObserver(this.observe.bind(this));
202 this.trace = this.trace.bind(this); 195 this.trace = this.trace.bind(this);
203 196
(...skipping 27 matching lines...) Expand all
231 break; 224 break;
232 } 225 }
233 } 226 }
234 227
235 if (matched) 228 if (matched)
236 break; 229 break;
237 } 230 }
238 } 231 }
239 232
240 if (matchedSelectors.length > 0) 233 if (matchedSelectors.length > 0)
234 {
241 ext.backgroundPage.sendMessage({ 235 ext.backgroundPage.sendMessage({
242 type: "devtools.traceElemHide", 236 type: "devtools.traceElemHide",
243 selectors: matchedSelectors 237 selectors: matchedSelectors
244 }); 238 });
239 }
245 }, 240 },
246 241
247 onTimeout() 242 onTimeout()
248 { 243 {
249 this.checkNodes(this.changedNodes); 244 this.checkNodes(this.changedNodes);
250 this.changedNodes = []; 245 this.changedNodes = [];
251 this.timeout = null; 246 this.timeout = null;
252 }, 247 },
253 248
254 observe(mutations) 249 observe(mutations)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 document.documentElement.removeChild(script); 333 document.documentElement.removeChild(script);
339 } 334 }
340 335
341 // Chrome doesn't allow us to intercept WebSockets[1], and therefore 336 // 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 337 // 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 338 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket
344 // connections from being opened. 339 // connections from being opened.
345 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 340 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
346 function wrapWebSocket() 341 function wrapWebSocket()
347 { 342 {
348 let eventName = "abpws-" + Math.random().toString(36).substr(2); 343 let randomEventName = "abpws-" + Math.random().toString(36).substr(2);
349 344
350 document.addEventListener(eventName, event => 345 document.addEventListener(randomEventName, event =>
351 { 346 {
352 ext.backgroundPage.sendMessage({ 347 ext.backgroundPage.sendMessage({
353 type: "request.websocket", 348 type: "request.websocket",
354 url: event.detail.url 349 url: event.detail.url
355 }, block => 350 }, block =>
356 { 351 {
357 document.dispatchEvent( 352 document.dispatchEvent(new CustomEvent(
358 new CustomEvent(eventName + "-" + event.detail.url, {detail: block}) 353 randomEventName + "-" + event.detail.url, {detail: block}
359 ); 354 ));
360 }); 355 });
361 }); 356 });
362 357
363 runInPageContext(eventName => 358 runInPageContext(eventName =>
364 { 359 {
365 // As far as possible we must track everything we use that could be 360 // As far as possible we must track everything we use that could be
366 // sabotaged by the website later in order to circumvent us. 361 // sabotaged by the website later in order to circumvent us.
367 let RealWebSocket = WebSocket; 362 let RealWebSocket = WebSocket;
368 let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.cl ose); 363 let RealCustomEvent = window.CustomEvent;
364 let closeWebSocket = Function.prototype.call.bind(
365 RealWebSocket.prototype.close
366 );
369 let addEventListener = document.addEventListener.bind(document); 367 let addEventListener = document.addEventListener.bind(document);
370 let removeEventListener = document.removeEventListener.bind(document); 368 let removeEventListener = document.removeEventListener.bind(document);
371 let dispatchEvent = document.dispatchEvent.bind(document); 369 let dispatchEvent = document.dispatchEvent.bind(document);
372 let CustomEvent = window.CustomEvent;
373 370
374 function checkRequest(url, callback) 371 function checkRequest(url, callback)
375 { 372 {
376 let incomingEventName = eventName + "-" + url; 373 let incomingEventName = eventName + "-" + url;
377 function listener(event) 374 function listener(event)
378 { 375 {
379 callback(event.detail); 376 callback(event.detail);
380 removeEventListener(incomingEventName, listener); 377 removeEventListener(incomingEventName, listener);
381 } 378 }
382 addEventListener(incomingEventName, listener); 379 addEventListener(incomingEventName, listener);
383 380
384 dispatchEvent(new CustomEvent(eventName, { 381 dispatchEvent(new RealCustomEvent(eventName, {detail: {url}}));
385 detail: {url: url}
386 }));
387 } 382 }
388 383
389 function WrappedWebSocket(url) 384 function WrappedWebSocket(url, ...args)
390 { 385 {
391 // Throw correct exceptions if the constructor is used improperly. 386 // Throw correct exceptions if the constructor is used improperly.
392 if (!(this instanceof WrappedWebSocket)) return RealWebSocket(); 387 if (!(this instanceof WrappedWebSocket)) return RealWebSocket();
393 if (arguments.length < 1) return new RealWebSocket(); 388 if (arguments.length < 1) return new RealWebSocket();
394 389
395 let websocket; 390 let websocket;
396 if (arguments.length == 1) 391 if (arguments.length == 1)
397 websocket = new RealWebSocket(url); 392 websocket = new RealWebSocket(url);
398 else 393 else
399 websocket = new RealWebSocket(url, arguments[1]); 394 websocket = new RealWebSocket(url, args[0]);
400 395
401 checkRequest(websocket.url, blocked => 396 checkRequest(websocket.url, blocked =>
402 { 397 {
403 if (blocked) 398 if (blocked)
404 closeWebSocket(websocket); 399 closeWebSocket(websocket);
405 }); 400 });
406 401
407 return websocket; 402 return websocket;
408 } 403 }
409 WrappedWebSocket.prototype = RealWebSocket.prototype; 404 WrappedWebSocket.prototype = RealWebSocket.prototype;
410 WebSocket = WrappedWebSocket.bind(); 405 window.WebSocket = WrappedWebSocket.bind();
411 Object.defineProperties(WebSocket, { 406 Object.defineProperties(WebSocket, {
412 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true}, 407 CONNECTING: {value: RealWebSocket.CONNECTING, enumerable: true},
413 OPEN: {value: RealWebSocket.OPEN, enumerable: true}, 408 OPEN: {value: RealWebSocket.OPEN, enumerable: true},
414 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true}, 409 CLOSING: {value: RealWebSocket.CLOSING, enumerable: true},
415 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true}, 410 CLOSED: {value: RealWebSocket.CLOSED, enumerable: true},
416 prototype: {value: RealWebSocket.prototype} 411 prototype: {value: RealWebSocket.prototype}
417 }); 412 });
418 413
419 RealWebSocket.prototype.constructor = WebSocket; 414 RealWebSocket.prototype.constructor = WebSocket;
420 }, eventName); 415 }, randomEventName);
421 } 416 }
422 417
423 function ElemHide() 418 function ElemHide()
424 { 419 {
425 this.shadow = this.createShadowTree(); 420 this.shadow = this.createShadowTree();
426 this.style = null; 421 this.style = null;
427 this.tracer = null; 422 this.tracer = null;
428 423
429 this.elemHideEmulation = new ElemHideEmulation( 424 this.elemHideEmulation = new ElemHideEmulation(
430 window, 425 window,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 shadow.appendChild(document.createElement("shadow")); 458 shadow.appendChild(document.createElement("shadow"));
464 459
465 // Stop the website from messing with our shadow root (#4191, #4298). 460 // Stop the website from messing with our shadow root (#4191, #4298).
466 if ("shadowRoot" in Element.prototype) 461 if ("shadowRoot" in Element.prototype)
467 { 462 {
468 runInPageContext(() => 463 runInPageContext(() =>
469 { 464 {
470 let ourShadowRoot = document.documentElement.shadowRoot; 465 let ourShadowRoot = document.documentElement.shadowRoot;
471 if (!ourShadowRoot) 466 if (!ourShadowRoot)
472 return; 467 return;
473 let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoo t"); 468 let desc = Object.getOwnPropertyDescriptor(Element.prototype,
469 "shadowRoot");
474 let shadowRoot = Function.prototype.call.bind(desc.get); 470 let shadowRoot = Function.prototype.call.bind(desc.get);
475 471
476 Object.defineProperty(Element.prototype, "shadowRoot", { 472 Object.defineProperty(Element.prototype, "shadowRoot", {
477 configurable: true, enumerable: true, get() 473 configurable: true, enumerable: true, get()
478 { 474 {
479 let shadow = shadowRoot(this); 475 let thisShadow = shadowRoot(this);
480 return shadow == ourShadowRoot ? null : shadow; 476 return thisShadow == ourShadowRoot ? null : shadow;
481 } 477 }
482 }); 478 });
483 }, null); 479 }, null);
484 } 480 }
485 481
486 return shadow; 482 return shadow;
487 }, 483 },
488 484
489 addSelectors(selectors) 485 addSelectors(selectors)
490 { 486 {
491 if (selectors.length == 0) 487 if (selectors.length == 0)
492 return; 488 return;
493 489
494 if (!this.style) 490 if (!this.style)
495 { 491 {
496 // Create <style> element lazily, only if we add styles. Add it to 492 // Create <style> element lazily, only if we add styles. Add it to
497 // the shadow DOM if possible. Otherwise fallback to the <head> or 493 // the shadow DOM if possible. Otherwise fallback to the <head> or
498 // <html> element. If we have injected a style element before that 494 // <html> element. If we have injected a style element before that
499 // has been removed (the sheet property is null), create a new one. 495 // has been removed (the sheet property is null), create a new one.
500 this.style = document.createElement("style"); 496 this.style = document.createElement("style");
501 (this.shadow || document.head 497 (this.shadow || document.head ||
502 || document.documentElement).appendChild(this.style); 498 document.documentElement).appendChild(this.style);
503 499
504 // It can happen that the frame already navigated to a different 500 // It can happen that the frame already navigated to a different
505 // document while we were waiting for the background page to respond. 501 // document while we were waiting for the background page to respond.
506 // In that case the sheet property will stay null, after addind the 502 // In that case the sheet property will stay null, after addind the
507 // <style> element to the shadow DOM. 503 // <style> element to the shadow DOM.
508 if (!this.style.sheet) 504 if (!this.style.sheet)
509 return; 505 return;
510 } 506 }
511 507
512 // 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
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 checkLoaded(); 570 checkLoaded();
575 }); 571 });
576 } 572 }
577 }; 573 };
578 574
579 if (document instanceof HTMLDocument) 575 if (document instanceof HTMLDocument)
580 { 576 {
581 checkSitekey(); 577 checkSitekey();
582 wrapWebSocket(); 578 wrapWebSocket();
583 579
584 // This variable is also used by our other content scripts, outside of the 580 elemhide = new ElemHide();
585 // current scope.
586 var elemhide = new ElemHide();
587 elemhide.apply(); 581 elemhide.apply();
588 582
589 document.addEventListener("error", event => 583 document.addEventListener("error", event =>
590 { 584 {
591 checkCollapse(event.target); 585 checkCollapse(event.target);
592 }, true); 586 }, true);
593 587
594 document.addEventListener("load", event => 588 document.addEventListener("load", event =>
595 { 589 {
596 let element = event.target; 590 let element = event.target;
597 if (/^i?frame$/.test(element.localName)) 591 if (/^i?frame$/.test(element.localName))
598 checkCollapse(element); 592 checkCollapse(element);
599 }, true); 593 }, true);
600 } 594 }
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