| Index: ext/background.js |
| =================================================================== |
| --- a/ext/background.js |
| +++ b/ext/background.js |
| @@ -15,73 +15,83 @@ |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| "use strict"; |
| { |
| let nonEmptyPageMaps = new Set(); |
| - let PageMap = ext.PageMap = function() |
| + ext.PageMap = class |
| { |
| - this._map = new Map(); |
| - }; |
| - PageMap.prototype = { |
| + constructor() |
| + { |
| + this._map = new Map(); |
| + } |
| + |
| _delete(id) |
| { |
| this._map.delete(id); |
| if (this._map.size == 0) |
| nonEmptyPageMaps.delete(this); |
| - }, |
| + } |
| + |
|
Manish Jethani
2018/03/15 07:54:10
I think it's better with a blank line between the
|
| keys() |
| { |
| return Array.from(this._map.keys()).map(ext.getPage); |
| - }, |
| + } |
| + |
| get(page) |
| { |
| return this._map.get(page.id); |
| - }, |
| + } |
| + |
| set(page, value) |
| { |
| this._map.set(page.id, value); |
| nonEmptyPageMaps.add(this); |
| - }, |
| + } |
| + |
| has(page) |
| { |
| return this._map.has(page.id); |
| - }, |
| + } |
| + |
| clear() |
| { |
| this._map.clear(); |
| nonEmptyPageMaps.delete(this); |
| - }, |
| + } |
| + |
| delete(page) |
| { |
| this._delete(page.id); |
| } |
| }; |
|
Manish Jethani
2018/03/15 07:54:10
Note that this is a class expression so it ends in
|
| ext._removeFromAllPageMaps = pageId => |
| { |
| for (let pageMap of nonEmptyPageMaps) |
| pageMap._delete(pageId); |
| }; |
| /* Pages */ |
| - let Page = ext.Page = function(tab) |
| + ext.Page = class |
| { |
| - this.id = tab.id; |
| - this._url = tab.url && new URL(tab.url); |
| + constructor(tab) |
| + { |
| + this.id = tab.id; |
| + this._url = tab.url && new URL(tab.url); |
| - this.browserAction = new BrowserAction(tab.id); |
| - this.contextMenus = new ContextMenus(this); |
| - }; |
| - Page.prototype = { |
| + this.browserAction = new BrowserAction(tab.id); |
| + this.contextMenus = new ContextMenus(this); |
| + } |
| + |
| get url() |
| { |
| // usually our Page objects are created from Chrome's Tab objects, which |
| // provide the url. So we can return the url given in the constructor. |
| if (this._url) |
| return this._url; |
| // but sometimes we only have the tab id when we create a Page object. |
| @@ -89,51 +99,52 @@ |
| // the onBeforeRequest handler. |
| let frames = framesOfTabs.get(this.id); |
| if (frames) |
| { |
| let frame = frames.get(0); |
| if (frame) |
| return frame.url; |
| } |
| - }, |
| + } |
| + |
| sendMessage(message, responseCallback) |
| { |
| browser.tabs.sendMessage(this.id, message, responseCallback); |
| } |
| }; |
| - ext.getPage = id => new Page({id: parseInt(id, 10)}); |
| + 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
|
| function afterTabLoaded(callback) |
| { |
| return openedTab => |
| { |
| let onUpdated = (tabId, changeInfo, tab) => |
| { |
| if (tabId == openedTab.id && changeInfo.status == "complete") |
| { |
| browser.tabs.onUpdated.removeListener(onUpdated); |
| - callback(new Page(openedTab)); |
| + callback(new ext.Page(openedTab)); |
| } |
| }; |
| browser.tabs.onUpdated.addListener(onUpdated); |
| }; |
| } |
| ext.pages = { |
| onLoading: new ext._EventTarget(), |
| onActivated: new ext._EventTarget(), |
| onRemoved: new ext._EventTarget() |
| }; |
| browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => |
| { |
| if (changeInfo.status == "loading") |
| - ext.pages.onLoading._dispatch(new Page(tab)); |
| + ext.pages.onLoading._dispatch(new ext.Page(tab)); |
| }); |
| function createFrame(tabId, frameId) |
| { |
| let frames = framesOfTabs.get(tabId); |
| if (!frames) |
| { |
| frames = new Map(); |
| @@ -149,17 +160,17 @@ |
| return frame; |
| } |
| function updatePageFrameStructure(frameId, tabId, url, parentFrameId) |
| { |
| if (frameId == 0) |
| { |
| - let page = new Page({id: tabId, url}); |
| + let page = new ext.Page({id: tabId, url}); |
| ext._removeFromAllPageMaps(tabId); |
| browser.tabs.get(tabId, () => |
| { |
| // If the tab is prerendered, browser.tabs.get() sets |
| // browser.runtime.lastError and we have to dispatch the onLoading |
| // event, since the onUpdated event isn't dispatched for prerendered |
| @@ -287,28 +298,30 @@ |
| { |
| forgetTab(removedTabId); |
| }); |
| browser.tabs.onRemoved.addListener(forgetTab); |
| browser.tabs.onActivated.addListener(details => |
| { |
| - ext.pages.onActivated._dispatch(new Page({id: details.tabId})); |
| + ext.pages.onActivated._dispatch(new ext.Page({id: details.tabId})); |
| }); |
| /* Browser actions */ |
| - let BrowserAction = function(tabId) |
| + class BrowserAction |
| { |
| - this._tabId = tabId; |
| - this._changes = null; |
| - }; |
| - BrowserAction.prototype = { |
| + constructor(tabId) |
| + { |
| + this._tabId = tabId; |
| + this._changes = null; |
| + } |
| + |
| _applyChanges() |
| { |
| if ("iconPath" in this._changes) |
| { |
| // Firefox for Android displays the browser action not as an icon but |
| // as a menu item. There is no icon, but such an option may be added in |
| // the future. |
| // https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 |
| @@ -358,17 +371,18 @@ |
| browser.browserAction.setBadgeBackgroundColor({ |
| tabId: this._tabId, |
| color: this._changes.badgeColor |
| }); |
| } |
| } |
| this._changes = null; |
| - }, |
| + } |
| + |
| _queueChanges() |
| { |
| browser.tabs.get(this._tabId, () => |
| { |
| // If the tab is prerendered, browser.tabs.get() sets |
| // browser.runtime.lastError and we have to delay our changes |
| // until the currently visible tab is replaced with the |
| // prerendered tab. Otherwise browser.browserAction.set* fails. |
| @@ -384,47 +398,50 @@ |
| }; |
| browser.tabs.onReplaced.addListener(onReplaced); |
| } |
| else |
| { |
| this._applyChanges(); |
| } |
| }); |
| - }, |
| + } |
| + |
| _addChange(name, value) |
| { |
| if (!this._changes) |
| { |
| this._changes = {}; |
| this._queueChanges(); |
| } |
| this._changes[name] = value; |
| - }, |
| + } |
| + |
| setIcon(path) |
| { |
| this._addChange("iconPath", path); |
| - }, |
| + } |
| + |
| setBadge(badge) |
| { |
| if (!badge) |
| { |
| this._addChange("badgeText", ""); |
| } |
| else |
| { |
| if ("number" in badge) |
| this._addChange("badgeText", badge.number.toString()); |
| if ("color" in badge) |
| this._addChange("badgeColor", badge.color); |
| } |
| } |
| - }; |
| + } |
| /* Context menus */ |
| let contextMenuItems = new ext.PageMap(); |
| let contextMenuUpdating = false; |
| let updateContextMenu = () => |
| @@ -452,52 +469,55 @@ |
| items.forEach(item => |
| { |
| browser.contextMenus.create({ |
| title: item.title, |
| contexts: item.contexts, |
| onclick(info, tab) |
| { |
| - item.onclick(new Page(tab)); |
| + item.onclick(new ext.Page(tab)); |
| } |
| }); |
| }); |
| }); |
| }); |
| }; |
| - let ContextMenus = function(page) |
| + class ContextMenus |
| { |
| - this._page = page; |
| - }; |
| - ContextMenus.prototype = { |
| + constructor(page) |
| + { |
| + this._page = page; |
| + } |
| + |
| create(item) |
| { |
| let items = contextMenuItems.get(this._page); |
| if (!items) |
| contextMenuItems.set(this._page, items = []); |
| items.push(item); |
| updateContextMenu(); |
| - }, |
| + } |
| + |
| remove(item) |
| { |
| let items = contextMenuItems.get(this._page); |
| if (items) |
| { |
| let index = items.indexOf(item); |
| if (index != -1) |
| { |
| items.splice(index, 1); |
| updateContextMenu(); |
| } |
| } |
| } |
| - }; |
| + } |
| browser.tabs.onActivated.addListener(updateContextMenu); |
| if ("windows" in browser) |
| { |
| browser.windows.onFocusChanged.addListener(windowId => |
| { |
| if (windowId != browser.windows.WINDOW_ID_NONE) |
| @@ -614,17 +634,17 @@ |
| // Sometimes requests are not associated with a browser tab and |
| // in this case we want to still be able to view the url being called. |
| let frame = null; |
| let page = null; |
| if (details.tabId != -1) |
| { |
| frame = ext.getFrame(details.tabId, frameId); |
| - page = new Page({id: details.tabId}); |
| + page = new ext.Page({id: details.tabId}); |
| } |
| if (ext.webRequest.onBeforeRequest._dispatch( |
| url, type, page, frame).includes(false)) |
| return {cancel: true}; |
| }, {urls: ["<all_urls>"]}, ["blocking"]); |
| @@ -633,17 +653,17 @@ |
| browser.runtime.onMessage.addListener((message, rawSender, sendResponse) => |
| { |
| let sender = {}; |
| // Add "page" and "frame" if the message was sent by a content script. |
| // If sent by popup or the background page itself, there is no "tab". |
| if ("tab" in rawSender) |
| { |
| - sender.page = new Page(rawSender.tab); |
| + sender.page = new ext.Page(rawSender.tab); |
| sender.frame = { |
| id: rawSender.frameId, |
| // In Edge requests from internal extension pages |
| // (protocol ms-browser-extension://) do no have a sender URL. |
| url: rawSender.url ? new URL(rawSender.url) : null, |
| get parent() |
| { |
| let frames = framesOfTabs.get(rawSender.tab.id); |