| Index: ext/background.js |
| =================================================================== |
| --- a/ext/background.js |
| +++ b/ext/background.js |
| @@ -14,64 +14,62 @@ |
| * You should have received a copy of the GNU General Public License |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| "use strict"; |
| (function() |
| { |
| - let nonEmptyPageMaps = Object.create(null); |
| - let pageMapCounter = 0; |
| + let nonEmptyPageMaps = new Set(); |
| let PageMap = ext.PageMap = function() |
| { |
| - this._map = Object.create(null); |
| - this._id = ++pageMapCounter; |
| + this._map = new Map(); |
| }; |
| PageMap.prototype = { |
| _delete(id) |
| { |
| - delete this._map[id]; |
| + this._map.delete(id); |
| - if (Object.keys(this._map).length == 0) |
| - delete nonEmptyPageMaps[this._id]; |
| + if (this._map.size == 0) |
| + nonEmptyPageMaps.delete(this); |
| }, |
| keys() |
| { |
| - return Object.keys(this._map).map(ext.getPage); |
| + return this._map.keys(); |
| }, |
| get(page) |
| { |
| - return this._map[page.id]; |
| + return this._map.get(page.id); |
| }, |
| set(page, value) |
| { |
| - this._map[page.id] = value; |
| - nonEmptyPageMaps[this._id] = this; |
| + this._map.set(page.id, value); |
| + nonEmptyPageMaps.add(this); |
| }, |
| has(page) |
| { |
| - return page.id in this._map; |
| + return this._map.has(page.id); |
| }, |
| clear() |
| { |
| - for (let id in this._map) |
| - this._delete(id); |
| + this._map.clear(); |
| + nonEmptyPageMaps.delete(this); |
| }, |
| delete(page) |
| { |
| this._delete(page.id); |
| } |
| }; |
| ext._removeFromAllPageMaps = pageId => |
| { |
| - for (let pageMapId in nonEmptyPageMaps) |
| - nonEmptyPageMaps[pageMapId]._delete(pageId); |
| + for (let pageMap of nonEmptyPageMaps) |
| + pageMap._delete(pageId); |
| }; |
| /* Pages */ |
| let Page = ext.Page = function(tab) |
| { |
| this.id = tab.id; |
| this._url = tab.url && new URL(tab.url); |
| @@ -85,20 +83,20 @@ |
| // 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. |
| // In that case we get the url from top frame of the tab, recorded by |
| // the onBeforeRequest handler. |
| - let frames = framesOfTabs[this.id]; |
| + let frames = framesOfTabs.get(this.id); |
| if (frames) |
| { |
| - let frame = frames[0]; |
| + let frame = frames.get(0); |
| if (frame) |
| return frame.url; |
| } |
| }, |
| sendMessage(message, responseCallback) |
| { |
| chrome.tabs.sendMessage(this.id, message, responseCallback); |
| } |
| @@ -153,23 +151,29 @@ |
| chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => |
| { |
| if (changeInfo.status == "loading") |
| ext.pages.onLoading._dispatch(new Page(tab)); |
| }); |
| function createFrame(tabId, frameId) |
| { |
| - let frames = framesOfTabs[tabId]; |
| + let frames = framesOfTabs.get(tabId); |
| if (!frames) |
| - frames = framesOfTabs[tabId] = Object.create(null); |
| + { |
| + frames = new Map(); |
| + framesOfTabs.set(tabId, frames); |
| + } |
| - let frame = frames[frameId]; |
| + let frame = frames.get(frameId); |
| if (!frame) |
| - frame = frames[frameId] = {}; |
| + { |
| + frame = {}; |
| + frames.set(frameId, frame); |
| + } |
| return frame; |
| } |
| function updatePageFrameStructure(frameId, tabId, url, parentFrameId) |
| { |
| if (frameId == 0) |
| { |
| @@ -185,20 +189,23 @@ |
| // However, we have to keep relying on the unUpdated event for tabs that |
| // are already visible. Otherwise browser action changes get overridden |
| // when Chrome automatically resets them on navigation. |
| if (chrome.runtime.lastError) |
| ext.pages.onLoading._dispatch(page); |
| }); |
| } |
| - // Update frame parent and URL in frame structure |
| + // Update frame URL and parent in frame structure |
| let frame = createFrame(tabId, frameId); |
| frame.url = new URL(url); |
| - frame.parent = framesOfTabs[tabId][parentFrameId] || null; |
| + |
| + let parentFrame = framesOfTabs.get(tabId).get(parentFrameId); |
| + if (parentFrame) |
| + frame.parent = parentFrame; |
| } |
| chrome.webRequest.onHeadersReceived.addListener(details => |
| { |
| // We have to update the frame structure when switching to a new |
| // document, so that we process any further requests made by that |
| // document in the right context. Unfortunately, we cannot rely |
| // on webNavigation.onCommitted since it isn't guaranteed to fire |
| @@ -287,17 +294,17 @@ |
| } |
| }); |
| function forgetTab(tabId) |
| { |
| ext.pages.onRemoved._dispatch(tabId); |
| ext._removeFromAllPageMaps(tabId); |
| - delete framesOfTabs[tabId]; |
| + framesOfTabs.delete(tabId); |
| } |
| chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) => |
| { |
| forgetTab(removedTabId); |
| }); |
| chrome.tabs.onRemoved.addListener(forgetTab); |
| @@ -485,21 +492,22 @@ |
| { |
| if (windowId != chrome.windows.WINDOW_ID_NONE) |
| updateContextMenu(); |
| }); |
| /* Web requests */ |
| - let framesOfTabs = Object.create(null); |
| + let framesOfTabs = new Map(); |
| ext.getFrame = (tabId, frameId) => |
| { |
| - return (framesOfTabs[tabId] || {})[frameId]; |
| + let frames = framesOfTabs.get(tabId); |
| + return frames && frames.get(frameId); |
| }; |
| let handlerBehaviorChangedQuota = |
| chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; |
| function propagateHandlerBehaviorChange() |
| { |
| // Make sure to not call handlerBehaviorChanged() more often than allowed |
| @@ -534,32 +542,28 @@ |
| chrome.tabs.query({}, tabs => |
| { |
| tabs.forEach(tab => |
| { |
| chrome.webNavigation.getAllFrames({tabId: tab.id}, details => |
| { |
| if (details && details.length > 0) |
| { |
| - let frames = framesOfTabs[tab.id] = Object.create(null); |
| + let frames = new Map(); |
| + framesOfTabs.set(tab.id, frames); |
| - for (let i = 0; i < details.length; i++) |
| + for (let detail of details) |
| + frames.set(detail.frameId, {url: new URL(detail.url)}); |
| + |
| + for (let detail of details) |
| { |
| - frames[details[i].frameId] = { |
| - url: new URL(details[i].url), |
| - parent: null |
| - }; |
| - } |
| - |
| - for (let i = 0; i < details.length; i++) |
| - { |
| - let {parentFrameId} = details[i]; |
| + let {parentFrameId} = detail; |
| if (parentFrameId != -1) |
| - frames[details[i].frameId].parent = frames[parentFrameId]; |
| + frames.get(detail.frameId).parent = frames.get(parentFrameId); |
| } |
| } |
| }); |
| }); |
| }); |
| chrome.webRequest.onBeforeRequest.addListener(details => |
| { |
| @@ -606,26 +610,26 @@ |
| // If sent by popup or the background page itself, there is no "tab". |
| if ("tab" in rawSender) |
| { |
| sender.page = new Page(rawSender.tab); |
| sender.frame = { |
| url: new URL(rawSender.url), |
| get parent() |
| { |
| - let frames = framesOfTabs[rawSender.tab.id]; |
| + let frames = framesOfTabs.get(rawSender.tab.id); |
| if (!frames) |
| return null; |
| - let frame = frames[rawSender.frameId]; |
| + let frame = frames.get(rawSender.frameId); |
| if (frame) |
| - return frame.parent; |
| + return frame.parent || null; |
| - return frames[0]; |
| + return frames.get(0) || null; |
| } |
| }; |
| } |
| return ext.onMessage._dispatch( |
| message, sender, sendResponse |
| ).indexOf(true) != -1; |
| }); |