Index: lib/stats.js |
=================================================================== |
--- a/lib/stats.js |
+++ b/lib/stats.js |
@@ -20,79 +20,130 @@ |
"use strict"; |
const {Prefs} = require("./prefs"); |
const {BlockingFilter} = require("../adblockpluscore/lib/filterClasses"); |
const {filterNotifier} = require("../adblockpluscore/lib/filterNotifier"); |
const {port} = require("./messaging"); |
const badgeColor = "#646464"; |
+const badgeRefreshRate = 4; |
+ |
let blockedPerPage = new ext.PageMap(); |
let getBlockedPerPage = |
/** |
* Gets the number of requests blocked on the given page. |
* |
* @param {Page} page |
* @return {Number} |
*/ |
exports.getBlockedPerPage = page => blockedPerPage.get(page) || 0; |
-function updateBadge(page, blockedCount) |
+let activeTabIds = new Set(); |
+let activeTabIdByWindowId = new Map(); |
+ |
+let badgeUpdateScheduled = false; |
+ |
+function updateBadge(tabId) |
{ |
- if (Prefs.show_statsinicon) |
+ if (!Prefs.show_statsinicon) |
+ return; |
+ |
+ for (let id of (typeof tabId == "undefined" ? activeTabIds : [tabId])) |
{ |
+ let page = new ext.Page({id}); |
+ let blockedCount = blockedPerPage.get(page); |
+ |
page.browserAction.setBadge(blockedCount && { |
color: badgeColor, |
number: blockedCount |
}); |
} |
} |
+function scheduleBadgeUpdate(tabId) |
+{ |
+ if (!badgeUpdateScheduled && Prefs.show_statsinicon && |
+ (typeof tabId == "undefined" || activeTabIds.has(tabId))) |
+ { |
+ setTimeout(() => { badgeUpdateScheduled = false; updateBadge(); }, |
+ 1000 / badgeRefreshRate); |
+ badgeUpdateScheduled = true; |
+ } |
+} |
+ |
// Once nagivation for the tab has been committed to (e.g. it's no longer |
// being prerendered) we clear its badge, or if some requests were already |
// blocked beforehand we display those on the badge now. |
browser.webNavigation.onCommitted.addListener(details => |
{ |
if (details.frameId == 0) |
- { |
- let page = new ext.Page({id: details.tabId}); |
- let blocked = blockedPerPage.get(page); |
- |
- updateBadge(page, blocked); |
- } |
+ updateBadge(details.tabId); |
}); |
filterNotifier.on("filter.hitCount", (filter, newValue, oldValue, tabIds) => |
{ |
if (!(filter instanceof BlockingFilter)) |
return; |
for (let tabId of tabIds) |
{ |
let page = new ext.Page({id: tabId}); |
let blocked = blockedPerPage.get(page) || 0; |
blockedPerPage.set(page, ++blocked); |
- updateBadge(page, blocked); |
+ scheduleBadgeUpdate(tabId); |
} |
Prefs.blocked_total++; |
}); |
Prefs.on("show_statsinicon", () => |
{ |
browser.tabs.query({}, tabs => |
{ |
for (let tab of tabs) |
{ |
let page = new ext.Page(tab); |
if (Prefs.show_statsinicon) |
- updateBadge(page, blockedPerPage.get(page)); |
+ updateBadge(tab.id); |
else |
page.browserAction.setBadge(null); |
} |
}); |
}); |
port.on("stats.getBlockedPerPage", |
message => getBlockedPerPage(new ext.Page(message.tab))); |
+ |
+browser.tabs.query({active: true}, tabs => |
+{ |
+ for (let tab of tabs) |
+ { |
+ activeTabIds.add(tab.id); |
+ activeTabIdByWindowId.set(tab.windowId, tab.id); |
+ } |
+ |
+ scheduleBadgeUpdate(); |
+}); |
+ |
+browser.tabs.onActivated.addListener(tab => |
+{ |
+ let lastActiveTabId = activeTabIdByWindowId.get(tab.windowId); |
+ if (typeof lastActiveTabId != "undefined") |
+ activeTabIds.delete(lastActiveTabId); |
+ |
+ activeTabIds.add(tab.tabId); |
+ activeTabIdByWindowId.set(tab.windowId, tab.tabId); |
+ |
+ scheduleBadgeUpdate(); |
+}); |
+ |
+if ("windows" in browser) |
+{ |
+ browser.windows.onRemoved.addListener(windowId => |
+ { |
+ activeTabIds.delete(activeTabIdByWindowId.get(windowId)); |
+ activeTabIdByWindowId.delete(windowId); |
+ }); |
+} |