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

Side by Side Diff: chrome/ext/background.js

Issue 29374674: Issue 4864 - Start using ESLint for adblockpluschrome (Closed)
Patch Set: Rebased Created March 17, 2017, 12:41 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 | « chrome/devtools.js ('k') | chrome/ext/common.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 "use strict"; 18 "use strict";
19 19
20 (function()
20 { 21 {
21 /* Pages */ 22 /* Pages */
22 23
23 let Page = ext.Page = function(tab) 24 let Page = ext.Page = function(tab)
24 { 25 {
25 this.id = tab.id; 26 this.id = tab.id;
26 this._url = tab.url && new URL(tab.url); 27 this._url = tab.url && new URL(tab.url);
27 28
28 this.browserAction = new BrowserAction(tab.id); 29 this.browserAction = new BrowserAction(tab.id);
29 this.contextMenus = new ContextMenus(this); 30 this.contextMenus = new ContextMenus(this);
(...skipping 20 matching lines...) Expand all
50 sendMessage(message, responseCallback) 51 sendMessage(message, responseCallback)
51 { 52 {
52 chrome.tabs.sendMessage(this.id, message, responseCallback); 53 chrome.tabs.sendMessage(this.id, message, responseCallback);
53 } 54 }
54 }; 55 };
55 56
56 ext.getPage = id => new Page({id: parseInt(id, 10)}); 57 ext.getPage = id => new Page({id: parseInt(id, 10)});
57 58
58 function afterTabLoaded(callback) 59 function afterTabLoaded(callback)
59 { 60 {
60 return openedTab => 61 return openedTab =>
61 { 62 {
62 let onUpdated = (tabId, changeInfo, tab) => 63 let onUpdated = (tabId, changeInfo, tab) =>
63 { 64 {
64 if (tabId == openedTab.id && changeInfo.status == "complete") 65 if (tabId == openedTab.id && changeInfo.status == "complete")
65 { 66 {
66 chrome.tabs.onUpdated.removeListener(onUpdated); 67 chrome.tabs.onUpdated.removeListener(onUpdated);
67 callback(new Page(openedTab)); 68 callback(new Page(openedTab));
68 } 69 }
69 }; 70 };
70 chrome.tabs.onUpdated.addListener(onUpdated); 71 chrome.tabs.onUpdated.addListener(onUpdated);
71 }; 72 };
72 } 73 }
73 74
74 ext.pages = { 75 ext.pages = {
75 open(url, callback) 76 open(url, callback)
76 { 77 {
77 chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); 78 chrome.tabs.create({url}, callback && afterTabLoaded(callback));
78 }, 79 },
79 query(info, callback) 80 query(info, callback)
80 { 81 {
81 let rawInfo = {}; 82 let rawInfo = {};
82 for (let property in info) 83 for (let property in info)
83 { 84 {
84 switch (property) 85 switch (property)
85 { 86 {
86 case "active": 87 case "active":
87 case "lastFocusedWindow": 88 case "lastFocusedWindow":
(...skipping 27 matching lines...) Expand all
115 if (!frame) 116 if (!frame)
116 frame = frames[frameId] = {}; 117 frame = frames[frameId] = {};
117 118
118 return frame; 119 return frame;
119 } 120 }
120 121
121 function updatePageFrameStructure(frameId, tabId, url, parentFrameId) 122 function updatePageFrameStructure(frameId, tabId, url, parentFrameId)
122 { 123 {
123 if (frameId == 0) 124 if (frameId == 0)
124 { 125 {
125 let page = new Page({id: tabId, url: url}); 126 let page = new Page({id: tabId, url});
126 127
127 ext._removeFromAllPageMaps(tabId); 128 ext._removeFromAllPageMaps(tabId);
128 129
129 chrome.tabs.get(tabId, () => 130 chrome.tabs.get(tabId, () =>
130 { 131 {
131 // If the tab is prerendered, chrome.tabs.get() sets 132 // If the tab is prerendered, chrome.tabs.get() sets
132 // chrome.runtime.lastError and we have to dispatch the onLoading event, 133 // chrome.runtime.lastError and we have to dispatch the onLoading event,
133 // since the onUpdated event isn't dispatched for prerendered tabs. 134 // since the onUpdated event isn't dispatched for prerendered tabs.
134 // However, we have to keep relying on the unUpdated event for tabs that 135 // However, we have to keep relying on the unUpdated event for tabs that
135 // are already visible. Otherwise browser action changes get overridden 136 // are already visible. Otherwise browser action changes get overridden
136 // when Chrome automatically resets them on navigation. 137 // when Chrome automatically resets them on navigation.
137 if (chrome.runtime.lastError) 138 if (chrome.runtime.lastError)
138 ext.pages.onLoading._dispatch(page); 139 ext.pages.onLoading._dispatch(page);
139 }); 140 });
140 } 141 }
141 142
142 // Update frame parent and URL in frame structure 143 // Update frame parent and URL in frame structure
143 let frame = createFrame(tabId, frameId); 144 let frame = createFrame(tabId, frameId);
144 frame.url = new URL(url); 145 frame.url = new URL(url);
145 frame.parent = framesOfTabs[tabId][parentFrameId] || null; 146 frame.parent = framesOfTabs[tabId][parentFrameId] || null;
146 }; 147 }
147 148
148 chrome.webRequest.onHeadersReceived.addListener(details => 149 chrome.webRequest.onHeadersReceived.addListener(details =>
149 { 150 {
150 // We have to update the frame structure when switching to a new 151 // We have to update the frame structure when switching to a new
151 // document, so that we process any further requests made by that 152 // document, so that we process any further requests made by that
152 // document in the right context. Unfortunately, we cannot rely 153 // document in the right context. Unfortunately, we cannot rely
153 // on webNavigation.onCommitted since it isn't guaranteed to fire 154 // on webNavigation.onCommitted since it isn't guaranteed to fire
154 // before any subresources start downloading[1]. As an 155 // before any subresources start downloading[1]. As an
155 // alternative we use webRequest.onHeadersReceived for HTTP(S) 156 // alternative we use webRequest.onHeadersReceived for HTTP(S)
156 // URLs, being careful to ignore any responses that won't cause 157 // URLs, being careful to ignore any responses that won't cause
(...skipping 25 matching lines...) Expand all
182 // "Content-Disposition" with a valid and non-empty value other 183 // "Content-Disposition" with a valid and non-empty value other
183 // than "inline". 184 // than "inline".
184 // https://chromium.googlesource.com/chromium/src/+/02d3f50b/content/brows er/loader/mime_sniffing_resource_handler.cc#534 185 // https://chromium.googlesource.com/chromium/src/+/02d3f50b/content/brows er/loader/mime_sniffing_resource_handler.cc#534
185 // https://chromium.googlesource.com/chromium/src/+/02d3f50b/net/http/http _content_disposition.cc#374 186 // https://chromium.googlesource.com/chromium/src/+/02d3f50b/net/http/http _content_disposition.cc#374
186 // https://chromium.googlesource.com/chromium/src/+/16e2688e/net/http/http _util.cc#431 187 // https://chromium.googlesource.com/chromium/src/+/16e2688e/net/http/http _util.cc#431
187 if (headerName == "content-disposition") 188 if (headerName == "content-disposition")
188 { 189 {
189 let disposition = header.value.split(";")[0].replace(/[ \t]+$/, ""); 190 let disposition = header.value.split(";")[0].replace(/[ \t]+$/, "");
190 if (disposition.toLowerCase() != "inline" && 191 if (disposition.toLowerCase() != "inline" &&
191 /^[\x21-\x7E]+$/.test(disposition) && 192 /^[\x21-\x7E]+$/.test(disposition) &&
192 !/[()<>@,;:\\"/\[\]?={}]/.test(disposition)) 193 !/[()<>@,;:\\"/[\]?={}]/.test(disposition))
193 return; 194 return;
194 } 195 }
195 196
196 // The value of the "Content-Type" header also determines if Chrome will 197 // The value of the "Content-Type" header also determines if Chrome will
197 // initiate a download, or otherwise how the response will be rendered. 198 // initiate a download, or otherwise how the response will be rendered.
198 // We only need to consider responses which will result in a navigation 199 // We only need to consider responses which will result in a navigation
199 // and be rendered as HTML or similar. 200 // and be rendered as HTML or similar.
200 // Note: Chrome might render the response as HTML if the "Content-Type" 201 // Note: Chrome might render the response as HTML if the "Content-Type"
201 // header is missing, invalid or unknown. 202 // header is missing, invalid or unknown.
202 // https://chromium.googlesource.com/chromium/src/+/99f41af9/net/http/http _util.cc#66 203 // https://chromium.googlesource.com/chromium/src/+/99f41af9/net/http/http _util.cc#66
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 chrome.browserAction.setBadgeBackgroundColor({ 296 chrome.browserAction.setBadgeBackgroundColor({
296 tabId: this._tabId, 297 tabId: this._tabId,
297 color: this._changes.badgeColor 298 color: this._changes.badgeColor
298 }); 299 });
299 } 300 }
300 301
301 this._changes = null; 302 this._changes = null;
302 }, 303 },
303 _queueChanges() 304 _queueChanges()
304 { 305 {
305 chrome.tabs.get(this._tabId, function() 306 chrome.tabs.get(this._tabId, () =>
306 { 307 {
307 // If the tab is prerendered, chrome.tabs.get() sets 308 // If the tab is prerendered, chrome.tabs.get() sets
308 // chrome.runtime.lastError and we have to delay our changes 309 // chrome.runtime.lastError and we have to delay our changes
309 // until the currently visible tab is replaced with the 310 // until the currently visible tab is replaced with the
310 // prerendered tab. Otherwise chrome.browserAction.set* fails. 311 // prerendered tab. Otherwise chrome.browserAction.set* fails.
311 if (chrome.runtime.lastError) 312 if (chrome.runtime.lastError)
312 { 313 {
313 let onReplaced = (addedTabId, removedTabId) => 314 let onReplaced = (addedTabId, removedTabId) =>
314 { 315 {
315 if (addedTabId == this._tabId) 316 if (addedTabId == this._tabId)
316 { 317 {
317 chrome.tabs.onReplaced.removeListener(onReplaced); 318 chrome.tabs.onReplaced.removeListener(onReplaced);
318 this._applyChanges(); 319 this._applyChanges();
319 } 320 }
320 }; 321 };
321 chrome.tabs.onReplaced.addListener(onReplaced); 322 chrome.tabs.onReplaced.addListener(onReplaced);
322 } 323 }
323 else 324 else
324 {
325 this._applyChanges(); 325 this._applyChanges();
326 } 326 });
327 }.bind(this));
328 }, 327 },
329 _addChange(name, value) 328 _addChange(name, value)
330 { 329 {
331 if (!this._changes) 330 if (!this._changes)
332 { 331 {
333 this._changes = {}; 332 this._changes = {};
334 this._queueChanges(); 333 this._queueChanges();
335 } 334 }
336 335
337 this._changes[name] = value; 336 this._changes[name] = value;
338 }, 337 },
339 setIcon(path) 338 setIcon(path)
340 { 339 {
341 this._addChange("iconPath", path); 340 this._addChange("iconPath", path);
342 }, 341 },
343 setBadge(badge) 342 setBadge(badge)
344 { 343 {
345 if (!badge) 344 if (!badge)
346 {
347 this._addChange("badgeText", ""); 345 this._addChange("badgeText", "");
348 }
349 else 346 else
350 { 347 {
351 if ("number" in badge) 348 if ("number" in badge)
352 this._addChange("badgeText", badge.number.toString()); 349 this._addChange("badgeText", badge.number.toString());
353 350
354 if ("color" in badge) 351 if ("color" in badge)
355 this._addChange("badgeColor", badge.color); 352 this._addChange("badgeColor", badge.color);
356 } 353 }
357 } 354 }
358 }; 355 };
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 436
440 /* Web requests */ 437 /* Web requests */
441 438
442 let framesOfTabs = Object.create(null); 439 let framesOfTabs = Object.create(null);
443 440
444 ext.getFrame = (tabId, frameId) => 441 ext.getFrame = (tabId, frameId) =>
445 { 442 {
446 return (framesOfTabs[tabId] || {})[frameId]; 443 return (framesOfTabs[tabId] || {})[frameId];
447 }; 444 };
448 445
449 let handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG ED_CALLS_PER_10_MINUTES; 446 let handlerBehaviorChangedQuota =
447 chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES;
450 448
451 function propagateHandlerBehaviorChange() 449 function propagateHandlerBehaviorChange()
452 { 450 {
453 // Make sure to not call handlerBehaviorChanged() more often than allowed 451 // Make sure to not call handlerBehaviorChanged() more often than allowed
454 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. 452 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES.
455 // Otherwise Chrome notifies the user that this extension is causing issues. 453 // Otherwise Chrome notifies the user that this extension is causing issues.
456 if (handlerBehaviorChangedQuota > 0) 454 if (handlerBehaviorChangedQuota > 0)
457 { 455 {
458 chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav iorChange); 456 chrome.webNavigation.onBeforeNavigate.removeListener(
457 propagateHandlerBehaviorChange
458 );
459 chrome.webRequest.handlerBehaviorChanged(); 459 chrome.webRequest.handlerBehaviorChanged();
460 460
461 handlerBehaviorChangedQuota--; 461 handlerBehaviorChangedQuota--;
462 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); 462 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000);
463 } 463 }
464 } 464 }
465 465
466 ext.webRequest = { 466 ext.webRequest = {
467 onBeforeRequest: new ext._EventTarget(), 467 onBeforeRequest: new ext._EventTarget(),
468 handlerBehaviorChanged() 468 handlerBehaviorChanged()
469 { 469 {
470 // Defer handlerBehaviorChanged() until navigation occurs. 470 // Defer handlerBehaviorChanged() until navigation occurs.
471 // There wouldn't be any visible effect when calling it earlier, 471 // There wouldn't be any visible effect when calling it earlier,
472 // but it's an expensive operation and that way we avoid to call 472 // but it's an expensive operation and that way we avoid to call
473 // it multiple times, if multiple filters are added/removed. 473 // it multiple times, if multiple filters are added/removed.
474 let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; 474 let {onBeforeNavigate} = chrome.webNavigation;
475 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) 475 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange))
476 onBeforeNavigate.addListener(propagateHandlerBehaviorChange); 476 onBeforeNavigate.addListener(propagateHandlerBehaviorChange);
477 } 477 }
478 }; 478 };
479 479
480 chrome.tabs.query({}, tabs => 480 chrome.tabs.query({}, tabs =>
481 { 481 {
482 tabs.forEach(tab => 482 tabs.forEach(tab =>
483 { 483 {
484 chrome.webNavigation.getAllFrames({tabId: tab.id}, details => 484 chrome.webNavigation.getAllFrames({tabId: tab.id}, details =>
485 { 485 {
486 if (details && details.length > 0) 486 if (details && details.length > 0)
487 { 487 {
488 let frames = framesOfTabs[tab.id] = Object.create(null); 488 let frames = framesOfTabs[tab.id] = Object.create(null);
489 489
490 for (let i = 0; i < details.length; i++) 490 for (let i = 0; i < details.length; i++)
491 frames[details[i].frameId] = {url: new URL(details[i].url), parent: null}; 491 {
492 frames[details[i].frameId] = {
493 url: new URL(details[i].url),
494 parent: null
495 };
496 }
492 497
493 for (let i = 0; i < details.length; i++) 498 for (let i = 0; i < details.length; i++)
494 { 499 {
495 let parentFrameId = details[i].parentFrameId; 500 let {parentFrameId} = details[i];
496 501
497 if (parentFrameId != -1) 502 if (parentFrameId != -1)
498 frames[details[i].frameId].parent = frames[parentFrameId]; 503 frames[details[i].frameId].parent = frames[parentFrameId];
499 } 504 }
500 } 505 }
501 }); 506 });
502 }); 507 });
503 }); 508 });
504 509
505 chrome.webRequest.onBeforeRequest.addListener(details => 510 chrome.webRequest.onBeforeRequest.addListener(details =>
506 { 511 {
507 // The high-level code isn't interested in requests that aren't 512 // The high-level code isn't interested in requests that aren't
508 // related to a tab or requests loading a top-level document, 513 // related to a tab or requests loading a top-level document,
509 // those should never be blocked. 514 // those should never be blocked.
510 if (details.tabId == -1 || details.type == "main_frame") 515 if (details.tabId == -1 || details.type == "main_frame")
511 return; 516 return;
512 517
513 // We are looking for the frame that contains the element which 518 // We are looking for the frame that contains the element which
514 // has triggered this request. For most requests (e.g. images) we 519 // has triggered this request. For most requests (e.g. images) we
515 // can just use the request's frame ID, but for subdocument requests 520 // can just use the request's frame ID, but for subdocument requests
516 // (e.g. iframes) we must instead use the request's parent frame ID. 521 // (e.g. iframes) we must instead use the request's parent frame ID.
517 let frameId; 522 let {frameId, type} = details;
518 let requestType; 523 if (type == "sub_frame")
519 if (details.type == "sub_frame")
520 { 524 {
521 frameId = details.parentFrameId; 525 frameId = details.parentFrameId;
522 requestType = "SUBDOCUMENT"; 526 type = "SUBDOCUMENT";
523 }
524 else
525 {
526 frameId = details.frameId;
527 requestType = details.type.toUpperCase();
528 } 527 }
529 528
530 let frame = ext.getFrame(details.tabId, frameId); 529 let frame = ext.getFrame(details.tabId, frameId);
531 if (frame) 530 if (frame)
532 { 531 {
533 let results = ext.webRequest.onBeforeRequest._dispatch( 532 let results = ext.webRequest.onBeforeRequest._dispatch(
534 new URL(details.url), 533 new URL(details.url),
535 requestType, 534 type.toUpperCase(),
536 new Page({id: details.tabId}), 535 new Page({id: details.tabId}),
537 frame 536 frame
538 ); 537 );
539 538
540 if (results.indexOf(false) != -1) 539 if (results.indexOf(false) != -1)
541 return {cancel: true}; 540 return {cancel: true};
542 } 541 }
543 }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]); 542 }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]);
544 543
545 544
(...skipping 19 matching lines...) Expand all
565 564
566 let frame = frames[rawSender.frameId]; 565 let frame = frames[rawSender.frameId];
567 if (frame) 566 if (frame)
568 return frame.parent; 567 return frame.parent;
569 568
570 return frames[0]; 569 return frames[0];
571 } 570 }
572 }; 571 };
573 } 572 }
574 573
575 return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) != -1; 574 return ext.onMessage._dispatch(
575 message, sender, sendResponse
576 ).indexOf(true) != -1;
576 }); 577 });
577 578
578 579
579 /* Storage */ 580 /* Storage */
580 581
581 ext.storage = { 582 ext.storage = {
582 get(keys, callback) 583 get(keys, callback)
583 { 584 {
584 chrome.storage.local.get(keys, callback); 585 chrome.storage.local.get(keys, callback);
585 }, 586 },
(...skipping 10 matching lines...) Expand all
596 onChanged: chrome.storage.onChanged 597 onChanged: chrome.storage.onChanged
597 }; 598 };
598 599
599 /* Options */ 600 /* Options */
600 601
601 if ("openOptionsPage" in chrome.runtime) 602 if ("openOptionsPage" in chrome.runtime)
602 { 603 {
603 ext.showOptions = callback => 604 ext.showOptions = callback =>
604 { 605 {
605 if (!callback) 606 if (!callback)
606 {
607 chrome.runtime.openOptionsPage(); 607 chrome.runtime.openOptionsPage();
608 }
609 else 608 else
610 { 609 {
611 chrome.runtime.openOptionsPage(() => 610 chrome.runtime.openOptionsPage(() =>
612 { 611 {
613 if (chrome.runtime.lastError) 612 if (chrome.runtime.lastError)
614 return; 613 return;
615 614
616 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => 615 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
617 { 616 {
618 if (tabs.length > 0) 617 if (tabs.length > 0)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 { 649 {
651 let tab = tabs[0]; 650 let tab = tabs[0];
652 651
653 chrome.windows.update(tab.windowId, {focused: true}); 652 chrome.windows.update(tab.windowId, {focused: true});
654 chrome.tabs.update(tab.id, {active: true}); 653 chrome.tabs.update(tab.id, {active: true});
655 654
656 if (callback) 655 if (callback)
657 callback(new Page(tab)); 656 callback(new Page(tab));
658 } 657 }
659 else 658 else
660 {
661 ext.pages.open(optionsUrl, callback); 659 ext.pages.open(optionsUrl, callback);
662 }
663 }); 660 });
664 }); 661 });
665 }; 662 };
666 } 663 }
667 664
668 /* Windows */ 665 /* Windows */
669 ext.windows = { 666 ext.windows = {
670 create(createData, callback) 667 create(createData, callback)
671 { 668 {
672 chrome.windows.create(createData, createdWindow => 669 chrome.windows.create(createData, createdWindow =>
673 { 670 {
674 afterTabLoaded(callback)(createdWindow.tabs[0]); 671 afterTabLoaded(callback)(createdWindow.tabs[0]);
675 }); 672 });
676 } 673 }
677 }; 674 };
678 } 675 }());
OLDNEW
« no previous file with comments | « chrome/devtools.js ('k') | chrome/ext/common.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld