| 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); |
| + }); |
| +} |