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: Addressed more feedback Created March 31, 2017, 8:23 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 | « 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-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 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 {
325 this._applyChanges(); 326 this._applyChanges();
326 } 327 }
327 }.bind(this)); 328 });
328 }, 329 },
329 _addChange(name, value) 330 _addChange(name, value)
330 { 331 {
331 if (!this._changes) 332 if (!this._changes)
332 { 333 {
333 this._changes = {}; 334 this._changes = {};
334 this._queueChanges(); 335 this._queueChanges();
335 } 336 }
336 337
337 this._changes[name] = value; 338 this._changes[name] = value;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 440
440 /* Web requests */ 441 /* Web requests */
441 442
442 let framesOfTabs = Object.create(null); 443 let framesOfTabs = Object.create(null);
443 444
444 ext.getFrame = (tabId, frameId) => 445 ext.getFrame = (tabId, frameId) =>
445 { 446 {
446 return (framesOfTabs[tabId] || {})[frameId]; 447 return (framesOfTabs[tabId] || {})[frameId];
447 }; 448 };
448 449
449 let handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG ED_CALLS_PER_10_MINUTES; 450 let handlerBehaviorChangedQuota =
451 chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES;
450 452
451 function propagateHandlerBehaviorChange() 453 function propagateHandlerBehaviorChange()
452 { 454 {
453 // Make sure to not call handlerBehaviorChanged() more often than allowed 455 // Make sure to not call handlerBehaviorChanged() more often than allowed
454 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. 456 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES.
455 // Otherwise Chrome notifies the user that this extension is causing issues. 457 // Otherwise Chrome notifies the user that this extension is causing issues.
456 if (handlerBehaviorChangedQuota > 0) 458 if (handlerBehaviorChangedQuota > 0)
457 { 459 {
458 chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav iorChange); 460 chrome.webNavigation.onBeforeNavigate.removeListener(
461 propagateHandlerBehaviorChange
462 );
459 chrome.webRequest.handlerBehaviorChanged(); 463 chrome.webRequest.handlerBehaviorChanged();
460 464
461 handlerBehaviorChangedQuota--; 465 handlerBehaviorChangedQuota--;
462 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); 466 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000);
463 } 467 }
464 } 468 }
465 469
466 ext.webRequest = { 470 ext.webRequest = {
467 onBeforeRequest: new ext._EventTarget(), 471 onBeforeRequest: new ext._EventTarget(),
468 handlerBehaviorChanged() 472 handlerBehaviorChanged()
469 { 473 {
470 // Defer handlerBehaviorChanged() until navigation occurs. 474 // Defer handlerBehaviorChanged() until navigation occurs.
471 // There wouldn't be any visible effect when calling it earlier, 475 // 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 476 // but it's an expensive operation and that way we avoid to call
473 // it multiple times, if multiple filters are added/removed. 477 // it multiple times, if multiple filters are added/removed.
474 let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; 478 let {onBeforeNavigate} = chrome.webNavigation;
475 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) 479 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange))
476 onBeforeNavigate.addListener(propagateHandlerBehaviorChange); 480 onBeforeNavigate.addListener(propagateHandlerBehaviorChange);
477 } 481 }
478 }; 482 };
479 483
480 chrome.tabs.query({}, tabs => 484 chrome.tabs.query({}, tabs =>
481 { 485 {
482 tabs.forEach(tab => 486 tabs.forEach(tab =>
483 { 487 {
484 chrome.webNavigation.getAllFrames({tabId: tab.id}, details => 488 chrome.webNavigation.getAllFrames({tabId: tab.id}, details =>
485 { 489 {
486 if (details && details.length > 0) 490 if (details && details.length > 0)
487 { 491 {
488 let frames = framesOfTabs[tab.id] = Object.create(null); 492 let frames = framesOfTabs[tab.id] = Object.create(null);
489 493
490 for (let i = 0; i < details.length; i++) 494 for (let i = 0; i < details.length; i++)
491 frames[details[i].frameId] = {url: new URL(details[i].url), parent: null}; 495 {
496 frames[details[i].frameId] = {
497 url: new URL(details[i].url),
498 parent: null
499 };
500 }
492 501
493 for (let i = 0; i < details.length; i++) 502 for (let i = 0; i < details.length; i++)
494 { 503 {
495 let parentFrameId = details[i].parentFrameId; 504 let {parentFrameId} = details[i];
496 505
497 if (parentFrameId != -1) 506 if (parentFrameId != -1)
498 frames[details[i].frameId].parent = frames[parentFrameId]; 507 frames[details[i].frameId].parent = frames[parentFrameId];
499 } 508 }
500 } 509 }
501 }); 510 });
502 }); 511 });
503 }); 512 });
504 513
505 chrome.webRequest.onBeforeRequest.addListener(details => 514 chrome.webRequest.onBeforeRequest.addListener(details =>
506 { 515 {
507 // The high-level code isn't interested in requests that aren't 516 // The high-level code isn't interested in requests that aren't
508 // related to a tab or requests loading a top-level document, 517 // related to a tab or requests loading a top-level document,
509 // those should never be blocked. 518 // those should never be blocked.
510 if (details.tabId == -1 || details.type == "main_frame") 519 if (details.tabId == -1 || details.type == "main_frame")
511 return; 520 return;
512 521
513 // We are looking for the frame that contains the element which 522 // We are looking for the frame that contains the element which
514 // has triggered this request. For most requests (e.g. images) we 523 // has triggered this request. For most requests (e.g. images) we
515 // can just use the request's frame ID, but for subdocument requests 524 // 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. 525 // (e.g. iframes) we must instead use the request's parent frame ID.
517 let frameId; 526 let {frameId, type} = details;
518 let requestType; 527 if (type == "sub_frame")
519 if (details.type == "sub_frame")
520 { 528 {
521 frameId = details.parentFrameId; 529 frameId = details.parentFrameId;
522 requestType = "SUBDOCUMENT"; 530 type = "SUBDOCUMENT";
523 }
524 else
525 {
526 frameId = details.frameId;
527 requestType = details.type.toUpperCase();
528 } 531 }
529 532
530 let frame = ext.getFrame(details.tabId, frameId); 533 let frame = ext.getFrame(details.tabId, frameId);
531 if (frame) 534 if (frame)
532 { 535 {
533 let results = ext.webRequest.onBeforeRequest._dispatch( 536 let results = ext.webRequest.onBeforeRequest._dispatch(
534 new URL(details.url), 537 new URL(details.url),
535 requestType, 538 type.toUpperCase(),
536 new Page({id: details.tabId}), 539 new Page({id: details.tabId}),
537 frame 540 frame
538 ); 541 );
539 542
540 if (results.indexOf(false) != -1) 543 if (results.indexOf(false) != -1)
541 return {cancel: true}; 544 return {cancel: true};
542 } 545 }
543 }, {urls: ["<all_urls>"]}, ["blocking"]); 546 }, {urls: ["<all_urls>"]}, ["blocking"]);
544 547
545 548
(...skipping 19 matching lines...) Expand all
565 568
566 let frame = frames[rawSender.frameId]; 569 let frame = frames[rawSender.frameId];
567 if (frame) 570 if (frame)
568 return frame.parent; 571 return frame.parent;
569 572
570 return frames[0]; 573 return frames[0];
571 } 574 }
572 }; 575 };
573 } 576 }
574 577
575 return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) != -1; 578 return ext.onMessage._dispatch(
579 message, sender, sendResponse
580 ).indexOf(true) != -1;
576 }); 581 });
577 582
578 583
579 /* Storage */ 584 /* Storage */
580 585
581 ext.storage = { 586 ext.storage = {
582 get(keys, callback) 587 get(keys, callback)
583 { 588 {
584 chrome.storage.local.get(keys, callback); 589 chrome.storage.local.get(keys, callback);
585 }, 590 },
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 /* Windows */ 673 /* Windows */
669 ext.windows = { 674 ext.windows = {
670 create(createData, callback) 675 create(createData, callback)
671 { 676 {
672 chrome.windows.create(createData, createdWindow => 677 chrome.windows.create(createData, createdWindow =>
673 { 678 {
674 afterTabLoaded(callback)(createdWindow.tabs[0]); 679 afterTabLoaded(callback)(createdWindow.tabs[0]);
675 }); 680 });
676 } 681 }
677 }; 682 };
678 } 683 }());
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