| Index: lib/devtools.js | 
| =================================================================== | 
| --- a/lib/devtools.js | 
| +++ b/lib/devtools.js | 
| @@ -27,26 +27,21 @@ | 
| const {extractHostFromFrame} = require("url"); | 
| const {port} = require("messaging"); | 
|  | 
| const nonRequestTypes = ["DOCUMENT", "ELEMHIDE", "GENERICBLOCK", "GENERICHIDE"]; | 
|  | 
| // Mapping of inspected tabs to their devpanel page | 
| // and recorded items. We can't use a PageMap here, | 
| // because data must persist after navigation/reload. | 
| -let panels = Object.create(null); | 
| - | 
| -function hasPanels() | 
| -{ | 
| -  return Object.keys(panels).length > 0; | 
| -} | 
| +let panels = new Map(); | 
|  | 
| function getActivePanel(page) | 
| { | 
| -  let panel = panels[page.id]; | 
| +  let panel = panels.get(page.id); | 
| if (panel && !panel.reload && !panel.reloading) | 
| return panel; | 
| return null; | 
| } | 
|  | 
| function getFilterInfo(filter) | 
| { | 
| if (!filter) | 
| @@ -208,22 +203,22 @@ | 
| /** | 
| * Checks whether a page is inspected by the devtools panel. | 
| * | 
| * @param {Page} page | 
| * @return {boolean} | 
| */ | 
| exports.hasPanel = function(page) | 
| { | 
| -  return page.id in panels; | 
| +  return panels.has(page.id); | 
| }; | 
|  | 
| function onBeforeRequest(details) | 
| { | 
| -  let panel = panels[details.tabId]; | 
| +  let panel = panels.get(details.tabId); | 
|  | 
| // Clear the devtools panel and reload the inspected tab without caching | 
| // when a new request is issued. However, make sure that we don't end up | 
| // in an infinite recursion if we already triggered a reload. | 
| if (panel.reloading) | 
| { | 
| panel.reloading = false; | 
| } | 
| @@ -238,37 +233,35 @@ | 
| if (details.method == "GET") | 
| panel.reload = true; | 
| } | 
| } | 
|  | 
| function onLoading(page) | 
| { | 
| let tabId = page.id; | 
| -  let panel = panels[tabId]; | 
| +  let panel = panels.get(tabId); | 
|  | 
| // Reloading the tab is the only way that allows bypassing all caches, in | 
| // order to see all requests in the devtools panel. Reloading must not be | 
| // performed before the tab changes to "loading", otherwise it will load the | 
| // previous URL. | 
| if (panel && panel.reload) | 
| { | 
| chrome.tabs.reload(tabId, {bypassCache: true}); | 
|  | 
| panel.reload = false; | 
| panel.reloading = true; | 
| } | 
| } | 
|  | 
| function updateFilters(filters, added) | 
| { | 
| -  for (let tabId in panels) | 
| +  for (let panel of panels.values()) | 
| { | 
| -    let panel = panels[tabId]; | 
| - | 
| for (let i = 0; i < panel.records.length; i++) | 
| { | 
| let record = panel.records[i]; | 
|  | 
| // If an added filter matches a request shown in the devtools panel, | 
| // update that record to show the new filter. Ignore filters that aren't | 
| // associated with any sub-resource request. There is no record for these | 
| // if they don't already match. In particular, in case of element hiding | 
| @@ -347,39 +340,39 @@ | 
| localOnBeforeRequest, | 
| { | 
| urls: ["http://*/*", "https://*/*"], | 
| types: ["main_frame"], | 
| tabId: inspectedTabId | 
| } | 
| ); | 
|  | 
| -  if (!hasPanels()) | 
| +  if (panels.size == 0) | 
| { | 
| ext.pages.onLoading.addListener(onLoading); | 
| FilterNotifier.on("filter.added", onFilterAdded); | 
| FilterNotifier.on("filter.removed", onFilterRemoved); | 
| FilterNotifier.on("subscription.added", onSubscriptionAdded); | 
| } | 
|  | 
| newPort.onDisconnect.addListener(() => | 
| { | 
| -    delete panels[inspectedTabId]; | 
| +    panels.delete(inspectedTabId); | 
| chrome.webRequest.onBeforeRequest.removeListener(localOnBeforeRequest); | 
|  | 
| -    if (!hasPanels()) | 
| +    if (panels.size == 0) | 
| { | 
| ext.pages.onLoading.removeListener(onLoading); | 
| FilterNotifier.off("filter.added", onFilterAdded); | 
| FilterNotifier.off("filter.removed", onFilterRemoved); | 
| FilterNotifier.off("subscription.added", onSubscriptionAdded); | 
| } | 
| }); | 
|  | 
| -  panels[inspectedTabId] = {port: newPort, records: []}; | 
| +  panels.set(inspectedTabId, {port: newPort, records: []}); | 
| }); | 
|  | 
| port.on("devtools.traceElemHide", (message, sender) => | 
| { | 
| logHiddenElements( | 
| sender.page, message.selectors, message.filters, | 
| extractHostFromFrame(sender.frame) | 
| ); | 
|  |