popup should wait for tab-on-demand to start loading

fixes a rare case of the popup being invoked right after switching to a lazily restored tab-on-demand, which doesn't have an URL yet in FF or has an URL but not the content script in some Chrome forks that implement tab-on-demand
This commit is contained in:
tophf 2017-08-18 14:41:27 +03:00
parent fef748d128
commit 0189fc0d6b

View File

@ -8,7 +8,11 @@ const handleEvent = {};
const ENTRY_ID_PREFIX_RAW = 'style-'; const ENTRY_ID_PREFIX_RAW = 'style-';
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW; const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
getActiveTabRealURL().then(url => { getActiveTab().then(tab =>
FIREFOX && tab.url === 'about:blank' && tab.status === 'loading'
? getTabRealURLFirefox(tab)
: getTabRealURL(tab)
).then(url => {
tabURL = URLS.supported(url) ? url : ''; tabURL = URLS.supported(url) ? url : '';
Promise.all([ Promise.all([
tabURL && getStylesSafe({matchUrl: tabURL}), tabURL && getStylesSafe({matchUrl: tabURL}),
@ -112,9 +116,17 @@ function initPopup(url) {
return; return;
} }
getActiveTab().then(tab => { getActiveTab().then(function ping(tab, retryCountdown = 10) {
chrome.tabs.sendMessage(tab.id, {method: 'ping'}, {frameId: 0}, pong => { chrome.tabs.sendMessage(tab.id, {method: 'ping'}, {frameId: 0}, pong => {
if (pong === undefined) { if (pong) {
return;
}
ignoreChromeError();
// FF and some Chrome forks (e.g. CentBrowser) implement tab-on-demand
// so we'll wait a bit to handle popup being invoked right after switching
if (retryCountdown > 0) {
setTimeout(ping, 100, tab, --retryCountdown);
} else {
document.body.classList.add('unreachable'); document.body.classList.add('unreachable');
} }
}); });
@ -443,3 +455,34 @@ function detectSloppyRegexps({entry, style}) {
$('.main-controls', entry).appendChild(indicator); $('.main-controls', entry).appendChild(indicator);
} }
} }
function getTabRealURLFirefox(tab) {
// wait for FF tab-on-demand to get a real URL (initially about:blank), 5 sec max
return new Promise(resolve => {
function onNavigation({tabId, url, frameId}) {
if (tabId === tab.id && frameId === 0) {
detach();
resolve(url);
}
}
function detach(timedOut) {
if (timedOut) {
resolve(tab.url);
} else {
debounce.unregister(detach);
}
chrome.webNavigation.onBeforeNavigate.removeListener(onNavigation);
chrome.webNavigation.onCommitted.removeListener(onNavigation);
chrome.tabs.onRemoved.removeListener(detach);
chrome.tabs.onReplaced.removeListener(detach);
}
chrome.webNavigation.onBeforeNavigate.addListener(onNavigation);
chrome.webNavigation.onCommitted.addListener(onNavigation);
chrome.tabs.onRemoved.addListener(detach);
chrome.tabs.onReplaced.addListener(detach);
debounce(detach, 5000, {timedOut: true});
});
}