openURL+message: use onTabReady instead of repeated sending
because the tab may take many seconds to start loading depending on connectivity etc.
This commit is contained in:
parent
de0920da53
commit
06ded49131
|
@ -279,6 +279,71 @@ function getTabRealURL(tab) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves when the [just created] tab is ready for communication.
|
||||||
|
* @param {Number|Tab} tabOrId
|
||||||
|
* @returns {Promise<?Tab>}
|
||||||
|
*/
|
||||||
|
function onTabReady(tabOrId) {
|
||||||
|
let tabId, tab;
|
||||||
|
if (Number.isInteger(tabOrId)) {
|
||||||
|
tabId = tabOrId;
|
||||||
|
} else {
|
||||||
|
tab = tabOrId;
|
||||||
|
tabId = tab && tab.id;
|
||||||
|
}
|
||||||
|
if (!tab) {
|
||||||
|
return getTab(tabId).then(onTabReady);
|
||||||
|
}
|
||||||
|
if (tab.status === 'complete') {
|
||||||
|
if (!FIREFOX || tab.url !== 'about:blank') {
|
||||||
|
return Promise.resolve(tab);
|
||||||
|
} else {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
chrome.webNavigation.getFrame({tabId, frameId: 0}, frame => {
|
||||||
|
ignoreChromeError();
|
||||||
|
if (frame) {
|
||||||
|
onTabReady(tab).then(resolve);
|
||||||
|
} else {
|
||||||
|
setTimeout(() => onTabReady(tabId).then(resolve));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
chrome.webNavigation.onCommitted.addListener(onCommitted);
|
||||||
|
chrome.webNavigation.onErrorOccurred.addListener(onErrorOccurred);
|
||||||
|
chrome.tabs.onRemoved.addListener(onTabRemoved);
|
||||||
|
chrome.tabs.onReplaced.addListener(onTabReplaced);
|
||||||
|
function onCommitted(info) {
|
||||||
|
if (info.tabId !== tabId) return;
|
||||||
|
unregister();
|
||||||
|
getTab(tab.id).then(resolve);
|
||||||
|
}
|
||||||
|
function onErrorOccurred(info) {
|
||||||
|
if (info.tabId !== tabId) return;
|
||||||
|
unregister();
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
function onTabRemoved(removedTabId) {
|
||||||
|
if (removedTabId !== tabId) return;
|
||||||
|
unregister();
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
function onTabReplaced(addedTabId, removedTabId) {
|
||||||
|
onTabRemoved(removedTabId);
|
||||||
|
}
|
||||||
|
function unregister() {
|
||||||
|
chrome.webNavigation.onCommitted.removeListener(onCommitted);
|
||||||
|
chrome.webNavigation.onErrorOccurred.removeListener(onErrorOccurred);
|
||||||
|
chrome.tabs.onRemoved.removeListener(onTabRemoved);
|
||||||
|
chrome.tabs.onReplaced.removeListener(onTabReplaced);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a tab or activates an existing one,
|
* Opens a tab or activates an existing one,
|
||||||
* reuses the New Tab page or about:blank if it's focused now
|
* reuses the New Tab page or about:blank if it's focused now
|
||||||
|
@ -294,8 +359,7 @@ function getTabRealURL(tab) {
|
||||||
* @param {?Boolean} [params.currentWindow]
|
* @param {?Boolean} [params.currentWindow]
|
||||||
* pass null to check all windows
|
* pass null to check all windows
|
||||||
* @param {any} [params.message]
|
* @param {any} [params.message]
|
||||||
* JSONifiable data to be sent to the tab via sendMessage() repeatedly for 200ms
|
* JSONifiable data to be sent to the tab via sendMessage()
|
||||||
* until the remote end returns a non-undefined response
|
|
||||||
* @returns {Promise<Tab>} Promise that resolves to the opened/activated tab
|
* @returns {Promise<Tab>} Promise that resolves to the opened/activated tab
|
||||||
*/
|
*/
|
||||||
function openURL({
|
function openURL({
|
||||||
|
@ -316,20 +380,15 @@ function openURL({
|
||||||
url.replace(/%2F.*/, '*').replace(/#.*/, '') :
|
url.replace(/%2F.*/, '*').replace(/#.*/, '') :
|
||||||
url.replace(/#.*/, '');
|
url.replace(/#.*/, '');
|
||||||
|
|
||||||
let task = queryTabs({url: urlQuery, currentWindow}).then(maybeSwitch);
|
const task = queryTabs({url: urlQuery, currentWindow}).then(maybeSwitch);
|
||||||
|
if (!message) {
|
||||||
if (message) {
|
return task;
|
||||||
task = task.then(function poll(tab, t0 = performance.now()) {
|
} else {
|
||||||
|
return task.then(onTabReady).then(tab => {
|
||||||
message.tabId = tab.id;
|
message.tabId = tab.id;
|
||||||
return sendMessage(message)
|
return sendMessage(message).then(() => tab);
|
||||||
.then(ack => ack !== undefined ? tab : Promise.reject())
|
|
||||||
.catch(() => {
|
|
||||||
ignoreChromeError();
|
|
||||||
return performance.now() - t0 < 200 ? poll(tab) : tab;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return task;
|
|
||||||
|
|
||||||
function maybeSwitch(tabs = []) {
|
function maybeSwitch(tabs = []) {
|
||||||
const urlFF = FIREFOX && url.replace(/%2F/g, '/');
|
const urlFF = FIREFOX && url.replace(/%2F/g, '/');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user