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

Side by Side Diff: ext/background.js

Issue 29723558: Issue 6482 - Use ES6 classes (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Patch Set: Created March 15, 2018, 7:46 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 | « no previous file | ext/common.js » ('j') | include.preload.js » ('J')
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-present eyeo GmbH 3 * Copyright (C) 2006-present 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 { 20 {
21 let nonEmptyPageMaps = new Set(); 21 let nonEmptyPageMaps = new Set();
22 22
23 let PageMap = ext.PageMap = function() 23 ext.PageMap = class
24 { 24 {
25 this._map = new Map(); 25 constructor()
26 }; 26 {
27 PageMap.prototype = { 27 this._map = new Map();
28 }
29
28 _delete(id) 30 _delete(id)
29 { 31 {
30 this._map.delete(id); 32 this._map.delete(id);
31 33
32 if (this._map.size == 0) 34 if (this._map.size == 0)
33 nonEmptyPageMaps.delete(this); 35 nonEmptyPageMaps.delete(this);
34 }, 36 }
37
Manish Jethani 2018/03/15 07:54:10 I think it's better with a blank line between the
35 keys() 38 keys()
36 { 39 {
37 return Array.from(this._map.keys()).map(ext.getPage); 40 return Array.from(this._map.keys()).map(ext.getPage);
38 }, 41 }
42
39 get(page) 43 get(page)
40 { 44 {
41 return this._map.get(page.id); 45 return this._map.get(page.id);
42 }, 46 }
47
43 set(page, value) 48 set(page, value)
44 { 49 {
45 this._map.set(page.id, value); 50 this._map.set(page.id, value);
46 nonEmptyPageMaps.add(this); 51 nonEmptyPageMaps.add(this);
47 }, 52 }
53
48 has(page) 54 has(page)
49 { 55 {
50 return this._map.has(page.id); 56 return this._map.has(page.id);
51 }, 57 }
58
52 clear() 59 clear()
53 { 60 {
54 this._map.clear(); 61 this._map.clear();
55 nonEmptyPageMaps.delete(this); 62 nonEmptyPageMaps.delete(this);
56 }, 63 }
64
57 delete(page) 65 delete(page)
58 { 66 {
59 this._delete(page.id); 67 this._delete(page.id);
60 } 68 }
61 }; 69 };
Manish Jethani 2018/03/15 07:54:10 Note that this is a class expression so it ends in
62 70
63 ext._removeFromAllPageMaps = pageId => 71 ext._removeFromAllPageMaps = pageId =>
64 { 72 {
65 for (let pageMap of nonEmptyPageMaps) 73 for (let pageMap of nonEmptyPageMaps)
66 pageMap._delete(pageId); 74 pageMap._delete(pageId);
67 }; 75 };
68 76
69 /* Pages */ 77 /* Pages */
70 78
71 let Page = ext.Page = function(tab) 79 ext.Page = class
72 { 80 {
73 this.id = tab.id; 81 constructor(tab)
74 this._url = tab.url && new URL(tab.url); 82 {
83 this.id = tab.id;
84 this._url = tab.url && new URL(tab.url);
75 85
76 this.browserAction = new BrowserAction(tab.id); 86 this.browserAction = new BrowserAction(tab.id);
77 this.contextMenus = new ContextMenus(this); 87 this.contextMenus = new ContextMenus(this);
78 }; 88 }
79 Page.prototype = { 89
80 get url() 90 get url()
81 { 91 {
82 // usually our Page objects are created from Chrome's Tab objects, which 92 // usually our Page objects are created from Chrome's Tab objects, which
83 // provide the url. So we can return the url given in the constructor. 93 // provide the url. So we can return the url given in the constructor.
84 if (this._url) 94 if (this._url)
85 return this._url; 95 return this._url;
86 96
87 // but sometimes we only have the tab id when we create a Page object. 97 // but sometimes we only have the tab id when we create a Page object.
88 // In that case we get the url from top frame of the tab, recorded by 98 // In that case we get the url from top frame of the tab, recorded by
89 // the onBeforeRequest handler. 99 // the onBeforeRequest handler.
90 let frames = framesOfTabs.get(this.id); 100 let frames = framesOfTabs.get(this.id);
91 if (frames) 101 if (frames)
92 { 102 {
93 let frame = frames.get(0); 103 let frame = frames.get(0);
94 if (frame) 104 if (frame)
95 return frame.url; 105 return frame.url;
96 } 106 }
97 }, 107 }
108
98 sendMessage(message, responseCallback) 109 sendMessage(message, responseCallback)
99 { 110 {
100 browser.tabs.sendMessage(this.id, message, responseCallback); 111 browser.tabs.sendMessage(this.id, message, responseCallback);
101 } 112 }
102 }; 113 };
103 114
104 ext.getPage = id => new Page({id: parseInt(id, 10)}); 115 ext.getPage = id => new ext.Page({id: parseInt(id, 10)});
Manish Jethani 2018/03/15 07:54:10 There was no real need for the local PageMap varia
105 116
106 function afterTabLoaded(callback) 117 function afterTabLoaded(callback)
107 { 118 {
108 return openedTab => 119 return openedTab =>
109 { 120 {
110 let onUpdated = (tabId, changeInfo, tab) => 121 let onUpdated = (tabId, changeInfo, tab) =>
111 { 122 {
112 if (tabId == openedTab.id && changeInfo.status == "complete") 123 if (tabId == openedTab.id && changeInfo.status == "complete")
113 { 124 {
114 browser.tabs.onUpdated.removeListener(onUpdated); 125 browser.tabs.onUpdated.removeListener(onUpdated);
115 callback(new Page(openedTab)); 126 callback(new ext.Page(openedTab));
116 } 127 }
117 }; 128 };
118 browser.tabs.onUpdated.addListener(onUpdated); 129 browser.tabs.onUpdated.addListener(onUpdated);
119 }; 130 };
120 } 131 }
121 132
122 ext.pages = { 133 ext.pages = {
123 onLoading: new ext._EventTarget(), 134 onLoading: new ext._EventTarget(),
124 onActivated: new ext._EventTarget(), 135 onActivated: new ext._EventTarget(),
125 onRemoved: new ext._EventTarget() 136 onRemoved: new ext._EventTarget()
126 }; 137 };
127 138
128 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => 139 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) =>
129 { 140 {
130 if (changeInfo.status == "loading") 141 if (changeInfo.status == "loading")
131 ext.pages.onLoading._dispatch(new Page(tab)); 142 ext.pages.onLoading._dispatch(new ext.Page(tab));
132 }); 143 });
133 144
134 function createFrame(tabId, frameId) 145 function createFrame(tabId, frameId)
135 { 146 {
136 let frames = framesOfTabs.get(tabId); 147 let frames = framesOfTabs.get(tabId);
137 if (!frames) 148 if (!frames)
138 { 149 {
139 frames = new Map(); 150 frames = new Map();
140 framesOfTabs.set(tabId, frames); 151 framesOfTabs.set(tabId, frames);
141 } 152 }
142 153
143 let frame = frames.get(frameId); 154 let frame = frames.get(frameId);
144 if (!frame) 155 if (!frame)
145 { 156 {
146 frame = {}; 157 frame = {};
147 frames.set(frameId, frame); 158 frames.set(frameId, frame);
148 } 159 }
149 160
150 return frame; 161 return frame;
151 } 162 }
152 163
153 function updatePageFrameStructure(frameId, tabId, url, parentFrameId) 164 function updatePageFrameStructure(frameId, tabId, url, parentFrameId)
154 { 165 {
155 if (frameId == 0) 166 if (frameId == 0)
156 { 167 {
157 let page = new Page({id: tabId, url}); 168 let page = new ext.Page({id: tabId, url});
158 169
159 ext._removeFromAllPageMaps(tabId); 170 ext._removeFromAllPageMaps(tabId);
160 171
161 browser.tabs.get(tabId, () => 172 browser.tabs.get(tabId, () =>
162 { 173 {
163 // If the tab is prerendered, browser.tabs.get() sets 174 // If the tab is prerendered, browser.tabs.get() sets
164 // browser.runtime.lastError and we have to dispatch the onLoading 175 // browser.runtime.lastError and we have to dispatch the onLoading
165 // event, since the onUpdated event isn't dispatched for prerendered 176 // event, since the onUpdated event isn't dispatched for prerendered
166 // tabs. However, we have to keep relying on the onUpdated event for 177 // tabs. However, we have to keep relying on the onUpdated event for
167 // tabs that are already visible. Otherwise browser action changes get 178 // tabs that are already visible. Otherwise browser action changes get
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 296
286 browser.tabs.onReplaced.addListener((addedTabId, removedTabId) => 297 browser.tabs.onReplaced.addListener((addedTabId, removedTabId) =>
287 { 298 {
288 forgetTab(removedTabId); 299 forgetTab(removedTabId);
289 }); 300 });
290 301
291 browser.tabs.onRemoved.addListener(forgetTab); 302 browser.tabs.onRemoved.addListener(forgetTab);
292 303
293 browser.tabs.onActivated.addListener(details => 304 browser.tabs.onActivated.addListener(details =>
294 { 305 {
295 ext.pages.onActivated._dispatch(new Page({id: details.tabId})); 306 ext.pages.onActivated._dispatch(new ext.Page({id: details.tabId}));
296 }); 307 });
297 308
298 309
299 /* Browser actions */ 310 /* Browser actions */
300 311
301 let BrowserAction = function(tabId) 312 class BrowserAction
302 { 313 {
303 this._tabId = tabId; 314 constructor(tabId)
304 this._changes = null; 315 {
305 }; 316 this._tabId = tabId;
306 BrowserAction.prototype = { 317 this._changes = null;
318 }
319
307 _applyChanges() 320 _applyChanges()
308 { 321 {
309 if ("iconPath" in this._changes) 322 if ("iconPath" in this._changes)
310 { 323 {
311 // Firefox for Android displays the browser action not as an icon but 324 // Firefox for Android displays the browser action not as an icon but
312 // as a menu item. There is no icon, but such an option may be added in 325 // as a menu item. There is no icon, but such an option may be added in
313 // the future. 326 // the future.
314 // https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 327 // https://bugzilla.mozilla.org/show_bug.cgi?id=1331746
315 if ("setIcon" in browser.browserAction) 328 if ("setIcon" in browser.browserAction)
316 { 329 {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 if ("setBadgeBackgroundColor" in browser.browserAction) 369 if ("setBadgeBackgroundColor" in browser.browserAction)
357 { 370 {
358 browser.browserAction.setBadgeBackgroundColor({ 371 browser.browserAction.setBadgeBackgroundColor({
359 tabId: this._tabId, 372 tabId: this._tabId,
360 color: this._changes.badgeColor 373 color: this._changes.badgeColor
361 }); 374 });
362 } 375 }
363 } 376 }
364 377
365 this._changes = null; 378 this._changes = null;
366 }, 379 }
380
367 _queueChanges() 381 _queueChanges()
368 { 382 {
369 browser.tabs.get(this._tabId, () => 383 browser.tabs.get(this._tabId, () =>
370 { 384 {
371 // If the tab is prerendered, browser.tabs.get() sets 385 // If the tab is prerendered, browser.tabs.get() sets
372 // browser.runtime.lastError and we have to delay our changes 386 // browser.runtime.lastError and we have to delay our changes
373 // until the currently visible tab is replaced with the 387 // until the currently visible tab is replaced with the
374 // prerendered tab. Otherwise browser.browserAction.set* fails. 388 // prerendered tab. Otherwise browser.browserAction.set* fails.
375 if (browser.runtime.lastError) 389 if (browser.runtime.lastError)
376 { 390 {
377 let onReplaced = (addedTabId, removedTabId) => 391 let onReplaced = (addedTabId, removedTabId) =>
378 { 392 {
379 if (addedTabId == this._tabId) 393 if (addedTabId == this._tabId)
380 { 394 {
381 browser.tabs.onReplaced.removeListener(onReplaced); 395 browser.tabs.onReplaced.removeListener(onReplaced);
382 this._applyChanges(); 396 this._applyChanges();
383 } 397 }
384 }; 398 };
385 browser.tabs.onReplaced.addListener(onReplaced); 399 browser.tabs.onReplaced.addListener(onReplaced);
386 } 400 }
387 else 401 else
388 { 402 {
389 this._applyChanges(); 403 this._applyChanges();
390 } 404 }
391 }); 405 });
392 }, 406 }
407
393 _addChange(name, value) 408 _addChange(name, value)
394 { 409 {
395 if (!this._changes) 410 if (!this._changes)
396 { 411 {
397 this._changes = {}; 412 this._changes = {};
398 this._queueChanges(); 413 this._queueChanges();
399 } 414 }
400 415
401 this._changes[name] = value; 416 this._changes[name] = value;
402 }, 417 }
418
403 setIcon(path) 419 setIcon(path)
404 { 420 {
405 this._addChange("iconPath", path); 421 this._addChange("iconPath", path);
406 }, 422 }
423
407 setBadge(badge) 424 setBadge(badge)
408 { 425 {
409 if (!badge) 426 if (!badge)
410 { 427 {
411 this._addChange("badgeText", ""); 428 this._addChange("badgeText", "");
412 } 429 }
413 else 430 else
414 { 431 {
415 if ("number" in badge) 432 if ("number" in badge)
416 this._addChange("badgeText", badge.number.toString()); 433 this._addChange("badgeText", badge.number.toString());
417 434
418 if ("color" in badge) 435 if ("color" in badge)
419 this._addChange("badgeColor", badge.color); 436 this._addChange("badgeColor", badge.color);
420 } 437 }
421 } 438 }
422 }; 439 }
423 440
424 441
425 /* Context menus */ 442 /* Context menus */
426 443
427 let contextMenuItems = new ext.PageMap(); 444 let contextMenuItems = new ext.PageMap();
428 let contextMenuUpdating = false; 445 let contextMenuUpdating = false;
429 446
430 let updateContextMenu = () => 447 let updateContextMenu = () =>
431 { 448 {
432 // Firefox for Android does not support context menus. 449 // Firefox for Android does not support context menus.
(...skipping 17 matching lines...) Expand all
450 if (!items) 467 if (!items)
451 return; 468 return;
452 469
453 items.forEach(item => 470 items.forEach(item =>
454 { 471 {
455 browser.contextMenus.create({ 472 browser.contextMenus.create({
456 title: item.title, 473 title: item.title,
457 contexts: item.contexts, 474 contexts: item.contexts,
458 onclick(info, tab) 475 onclick(info, tab)
459 { 476 {
460 item.onclick(new Page(tab)); 477 item.onclick(new ext.Page(tab));
461 } 478 }
462 }); 479 });
463 }); 480 });
464 }); 481 });
465 }); 482 });
466 }; 483 };
467 484
468 let ContextMenus = function(page) 485 class ContextMenus
469 { 486 {
470 this._page = page; 487 constructor(page)
471 }; 488 {
472 ContextMenus.prototype = { 489 this._page = page;
490 }
491
473 create(item) 492 create(item)
474 { 493 {
475 let items = contextMenuItems.get(this._page); 494 let items = contextMenuItems.get(this._page);
476 if (!items) 495 if (!items)
477 contextMenuItems.set(this._page, items = []); 496 contextMenuItems.set(this._page, items = []);
478 497
479 items.push(item); 498 items.push(item);
480 updateContextMenu(); 499 updateContextMenu();
481 }, 500 }
501
482 remove(item) 502 remove(item)
483 { 503 {
484 let items = contextMenuItems.get(this._page); 504 let items = contextMenuItems.get(this._page);
485 if (items) 505 if (items)
486 { 506 {
487 let index = items.indexOf(item); 507 let index = items.indexOf(item);
488 if (index != -1) 508 if (index != -1)
489 { 509 {
490 items.splice(index, 1); 510 items.splice(index, 1);
491 updateContextMenu(); 511 updateContextMenu();
492 } 512 }
493 } 513 }
494 } 514 }
495 }; 515 }
496 516
497 browser.tabs.onActivated.addListener(updateContextMenu); 517 browser.tabs.onActivated.addListener(updateContextMenu);
498 518
499 if ("windows" in browser) 519 if ("windows" in browser)
500 { 520 {
501 browser.windows.onFocusChanged.addListener(windowId => 521 browser.windows.onFocusChanged.addListener(windowId =>
502 { 522 {
503 if (windowId != browser.windows.WINDOW_ID_NONE) 523 if (windowId != browser.windows.WINDOW_ID_NONE)
504 updateContextMenu(); 524 updateContextMenu();
505 }); 525 });
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 if (type == "sub_frame") 632 if (type == "sub_frame")
613 frameId = details.parentFrameId; 633 frameId = details.parentFrameId;
614 634
615 // Sometimes requests are not associated with a browser tab and 635 // Sometimes requests are not associated with a browser tab and
616 // in this case we want to still be able to view the url being called. 636 // in this case we want to still be able to view the url being called.
617 let frame = null; 637 let frame = null;
618 let page = null; 638 let page = null;
619 if (details.tabId != -1) 639 if (details.tabId != -1)
620 { 640 {
621 frame = ext.getFrame(details.tabId, frameId); 641 frame = ext.getFrame(details.tabId, frameId);
622 page = new Page({id: details.tabId}); 642 page = new ext.Page({id: details.tabId});
623 } 643 }
624 644
625 if (ext.webRequest.onBeforeRequest._dispatch( 645 if (ext.webRequest.onBeforeRequest._dispatch(
626 url, type, page, frame).includes(false)) 646 url, type, page, frame).includes(false))
627 return {cancel: true}; 647 return {cancel: true};
628 }, {urls: ["<all_urls>"]}, ["blocking"]); 648 }, {urls: ["<all_urls>"]}, ["blocking"]);
629 649
630 650
631 /* Message passing */ 651 /* Message passing */
632 652
633 browser.runtime.onMessage.addListener((message, rawSender, sendResponse) => 653 browser.runtime.onMessage.addListener((message, rawSender, sendResponse) =>
634 { 654 {
635 let sender = {}; 655 let sender = {};
636 656
637 // Add "page" and "frame" if the message was sent by a content script. 657 // Add "page" and "frame" if the message was sent by a content script.
638 // If sent by popup or the background page itself, there is no "tab". 658 // If sent by popup or the background page itself, there is no "tab".
639 if ("tab" in rawSender) 659 if ("tab" in rawSender)
640 { 660 {
641 sender.page = new Page(rawSender.tab); 661 sender.page = new ext.Page(rawSender.tab);
642 sender.frame = { 662 sender.frame = {
643 id: rawSender.frameId, 663 id: rawSender.frameId,
644 // In Edge requests from internal extension pages 664 // In Edge requests from internal extension pages
645 // (protocol ms-browser-extension://) do no have a sender URL. 665 // (protocol ms-browser-extension://) do no have a sender URL.
646 url: rawSender.url ? new URL(rawSender.url) : null, 666 url: rawSender.url ? new URL(rawSender.url) : null,
647 get parent() 667 get parent()
648 { 668 {
649 let frames = framesOfTabs.get(rawSender.tab.id); 669 let frames = framesOfTabs.get(rawSender.tab.id);
650 670
651 if (!frames) 671 if (!frames)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 ext.windows = { 710 ext.windows = {
691 create(createData, callback) 711 create(createData, callback)
692 { 712 {
693 browser.windows.create(createData, createdWindow => 713 browser.windows.create(createData, createdWindow =>
694 { 714 {
695 afterTabLoaded(callback)(createdWindow.tabs[0]); 715 afterTabLoaded(callback)(createdWindow.tabs[0]);
696 }); 716 });
697 } 717 }
698 }; 718 };
699 } 719 }
OLDNEW
« no previous file with comments | « no previous file | ext/common.js » ('j') | include.preload.js » ('J')

Powered by Google App Engine
This is Rietveld