| Index: lib/options.js |
| diff --git a/lib/options.js b/lib/options.js |
| index fa39d78374b04df576ddc85aedd5aea613fffe39..88feed8d9d19e5177a18460ce62c4ca7cc97574e 100644 |
| --- a/lib/options.js |
| +++ b/lib/options.js |
| @@ -38,7 +38,53 @@ function findOptionsTab(callback) |
| // starting with Firefox 56 an extension can query for its own URLs: |
| // https://bugzilla.mozilla.org/show_bug.cgi?id=1271354 |
| let fullOptionsUrl = browser.extension.getURL(optionsUrl); |
| - callback(tabs.find(element => element.url == fullOptionsUrl)); |
| + let optionsTab = tabs.find(tab => tab.url == fullOptionsUrl); |
| + if (optionsTab) |
| + { |
| + callback(optionsTab); |
| + return; |
| + } |
| + |
| + // Newly created tabs might have about:blank as their URL in Firefox rather |
| + // than the final options page URL, we need to wait for those to finish |
| + // loading. |
| + let potentialOptionTabIds = new Set( |
| + tabs.filter(tab => tab.url == "about:blank" && tab.status == "loading") |
| + .map(tab => tab.id) |
| + ); |
| + if (potentialOptionTabIds.size == 0) |
| + { |
| + callback(); |
| + return; |
| + } |
| + let removeListener; |
| + let updateListener = (tabId, changeInfo, tab) => |
| + { |
| + if (potentialOptionTabIds.has(tabId) && |
| + changeInfo.status == "complete") |
| + { |
| + potentialOptionTabIds.delete(tabId); |
| + let urlMatch = tab.url == fullOptionsUrl; |
| + if (urlMatch || potentialOptionTabIds.size == 0) |
| + { |
| + browser.tabs.onUpdated.removeListener(updateListener); |
| + browser.tabs.onRemoved.removeListener(removeListener); |
| + callback(urlMatch ? tab : undefined); |
| + } |
| + } |
| + }; |
| + browser.tabs.onUpdated.addListener(updateListener); |
| + removeListener = removedTabId => |
| + { |
| + potentialOptionTabIds.delete(removedTabId); |
| + if (potentialOptionTabIds.size == 0) |
| + { |
| + browser.tabs.onUpdated.removeListener(updateListener); |
| + browser.tabs.onRemoved.removeListener(removeListener); |
| + callback(); |
| + } |
| + }; |
| + browser.tabs.onRemoved.addListener(removeListener); |
| }); |
| } |