fixup! track iframes via ports

This commit is contained in:
tophf 2020-02-24 18:20:11 +03:00
parent fbf73a2368
commit ac5e907d72
2 changed files with 43 additions and 13 deletions

View File

@ -4,6 +4,7 @@
const iconManager = (() => { const iconManager = (() => {
const ICON_SIZES = FIREFOX || CHROME >= 2883 && !VIVALDI ? [16, 32] : [19, 38]; const ICON_SIZES = FIREFOX || CHROME >= 2883 && !VIVALDI ? [16, 32] : [19, 38];
const staleBadges = new Set();
prefs.subscribe([ prefs.subscribe([
'disableAll', 'disableAll',
@ -31,8 +32,10 @@ const iconManager = (() => {
updateIconBadge(styleIds) { updateIconBadge(styleIds) {
// FIXME: in some cases, we only have to redraw the badge. is it worth a optimization? // FIXME: in some cases, we only have to redraw the badge. is it worth a optimization?
const {frameId, tab: {id: tabId}} = this.sender; const {frameId, tab: {id: tabId}} = this.sender;
tabManager.set(tabId, 'styleIds', frameId, styleIds.length ? styleIds.map(Number) : undefined); const value = styleIds.length ? styleIds.map(Number) : undefined;
refreshIconBadgeText(tabId); tabManager.set(tabId, 'styleIds', frameId, value);
debounce(refreshStaleBadges, frameId ? 250 : 0);
staleBadges.add(tabId);
if (!frameId) refreshIcon(tabId, true); if (!frameId) refreshIcon(tabId, true);
}, },
}); });
@ -41,6 +44,18 @@ const iconManager = (() => {
if (!frameId) tabManager.set(tabId, 'styleIds', undefined); if (!frameId) tabManager.set(tabId, 'styleIds', undefined);
}); });
chrome.runtime.onConnect.addListener(port => {
if (port.name === 'iframe') {
port.onDisconnect.addListener(onPortDisconnected);
}
});
function onPortDisconnected({sender}) {
if (tabManager.get(sender.tab.id, 'styleIds')) {
API_METHODS.updateIconBadge.call({sender}, []);
}
}
function refreshIconBadgeText(tabId) { function refreshIconBadgeText(tabId) {
const text = prefs.get('show-badge') ? `${getStyleCount(tabId)}` : ''; const text = prefs.get('show-badge') ? `${getStyleCount(tabId)}` : '';
iconUtil.setBadgeText({tabId, text}); iconUtil.setBadgeText({tabId, text});
@ -110,4 +125,9 @@ const iconManager = (() => {
refreshIconBadgeText(tabId); refreshIconBadgeText(tabId);
} }
} }
function refreshStaleBadges() {
for (const tabId of staleBadges) refreshIconBadgeText(tabId);
staleBadges.clear();
}
})(); })();

View File

@ -9,18 +9,21 @@
self.INJECTED !== 1 && (() => { self.INJECTED !== 1 && (() => {
self.INJECTED = 1; self.INJECTED = 1;
let IS_TAB = !chrome.tabs || location.pathname !== '/popup.html';
const IS_FRAME = window !== parent;
const STYLE_VIA_API = !chrome.app && document instanceof XMLDocument; const STYLE_VIA_API = !chrome.app && document instanceof XMLDocument;
const styleInjector = createStyleInjector({ const styleInjector = createStyleInjector({
compare: (a, b) => a.id - b.id, compare: (a, b) => a.id - b.id,
onUpdate: onInjectorUpdate, onUpdate: onInjectorUpdate,
}); });
const initializing = init(); const initializing = init();
/** @type chrome.runtime.Port */
let port;
// if chrome.tabs is absent it's a web page, otherwise we'll check for popup/options as those aren't tabs // the popup needs a check as it's not a tab but can be opened in a tab manually for whatever reason
let isTab = !chrome.tabs; if (!IS_TAB) {
if (chrome.tabs) {
chrome.tabs.getCurrent(tab => { chrome.tabs.getCurrent(tab => {
isTab = Boolean(tab); IS_TAB = Boolean(tab);
if (tab && styleInjector.list.length) updateCount(); if (tab && styleInjector.list.length) updateCount();
}); });
} }
@ -41,7 +44,7 @@ self.INJECTED !== 1 && (() => {
let parentDomain; let parentDomain;
prefs.subscribe(['disableAll'], (key, value) => doDisableAll(value)); prefs.subscribe(['disableAll'], (key, value) => doDisableAll(value));
if (window !== parent) { if (IS_FRAME) {
prefs.subscribe(['exposeIframes'], updateExposeIframes); prefs.subscribe(['exposeIframes'], updateExposeIframes);
} }
@ -64,7 +67,7 @@ self.INJECTED !== 1 && (() => {
// dynamic about: and javascript: iframes don't have an URL yet // dynamic about: and javascript: iframes don't have an URL yet
// so we'll try the parent frame which is guaranteed to have a real URL // so we'll try the parent frame which is guaranteed to have a real URL
try { try {
if (window !== parent) { if (IS_FRAME) {
matchUrl = parent.location.href; matchUrl = parent.location.href;
} }
} catch (e) {} } catch (e) {}
@ -162,11 +165,18 @@ self.INJECTED !== 1 && (() => {
} }
function updateCount() { function updateCount() {
if (isTab) { if (!IS_TAB) return;
(STYLE_VIA_API ? if (STYLE_VIA_API) {
API.styleViaAPI({method: 'updateCount'}) : API.styleViaAPI({method: 'updateCount'}).catch(msg.ignoreError);
API.updateIconBadge(styleInjector.list.map(style => style.id)) } else {
).catch(msg.ignoreError); API.updateIconBadge(styleInjector.list.map(style => style.id)).catch(msg.ignoreError);
}
if (IS_FRAME) {
if (!port && styleInjector.list.length) {
port = chrome.runtime.connect({name: 'iframe'});
} else if (port && !styleInjector.list.length) {
port.disconnect();
}
} }
} }