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