Bug 1287007 - Only close extension tabs upon shutdown
In one of the previous patches, the viewType of popup changed from
"popup" to "tab". As a result it was closed by the `page-shutdown`
event handler in ext-tabs.js. This prevents that from happening.
Also added a test that checks whether the options page type is a tab, to
prevent future regressions.
MozReview-Commit-ID: 3Qcf08PgNqb
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -52,16 +52,22 @@ function getSender(extension, target, se
// Used by Extension.jsm
global.tabGetSender = getSender;
/* eslint-disable mozilla/balanced-listeners */
extensions.on("page-shutdown", (type, context) => {
if (context.viewType == "tab") {
+ if (context.extension.id !== context.xulBrowser.contentPrincipal.addonId) {
+ // Only close extension tabs.
+ // This check prevents about:addons from closing when it contains a
+ // WebExtension as an embedded inline options page.
+ return;
+ }
let {gBrowser} = context.xulBrowser.ownerGlobal;
if (gBrowser) {
let tab = gBrowser.getTabForBrowser(context.xulBrowser);
if (tab) {
gBrowser.removeTab(tab);
}
}
}
--- a/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js
+++ b/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js
@@ -25,16 +25,17 @@ function* loadExtension(options) {
<html>
<head>
<meta charset="utf-8">
<script src="options.js" type="text/javascript"></script>
</head>
</html>`,
"options.js": function() {
+ window.iAmOption = true;
browser.runtime.sendMessage("options.html");
browser.runtime.onMessage.addListener((msg, sender, respond) => {
if (msg == "ping") {
respond("pong");
}
});
},
},
@@ -91,16 +92,23 @@ add_tasks(function* test_inline_options(
awaitOptions(),
]);
}).then(([, tab]) => {
browser.test.assertEq("about:addons", tab.url, "Tab contains AddonManager");
browser.test.assertTrue(tab.active, "Tab is active");
browser.test.assertTrue(tab.id != firstTab, "Tab is a new tab");
optionsTab = tab.id;
+ browser.test.assertEq(0, browser.extension.getViews({type: "popup"}).length, "viewType is not popup");
+ browser.test.assertEq(1, browser.extension.getViews({type: "tab"}).length, "viewType is tab");
+ browser.test.assertEq(1, browser.extension.getViews({windowId: tab.windowId}).length, "windowId matches");
+ let views = browser.extension.getViews();
+ browser.test.assertEq(2, views.length, "Expected the options page and the background page");
+ browser.test.assertTrue(views.includes(window), "One of the views is the background page");
+ browser.test.assertTrue(views.some(w => w.iAmOption), "One of the views is the options page");
browser.test.log("Switch tabs.");
return browser.tabs.update(firstTab, {active: true});
}).then(() => {
browser.test.log("Open options page again. Expect tab re-selected, no new load.");
return browser.runtime.openOptionsPage();
}).then(() => {
@@ -190,16 +198,23 @@ add_tasks(function* test_tab_options(ext
awaitOptions(),
]);
}).then(([, tab]) => {
browser.test.assertEq(optionsURL, tab.url, "Tab contains options.html");
browser.test.assertTrue(tab.active, "Tab is active");
browser.test.assertTrue(tab.id != firstTab, "Tab is a new tab");
optionsTab = tab.id;
+ browser.test.assertEq(0, browser.extension.getViews({type: "popup"}).length, "viewType is not popup");
+ browser.test.assertEq(1, browser.extension.getViews({type: "tab"}).length, "viewType is tab");
+ browser.test.assertEq(1, browser.extension.getViews({windowId: tab.windowId}).length, "windowId matches");
+ let views = browser.extension.getViews();
+ browser.test.assertEq(2, views.length, "Expected the options page and the background page");
+ browser.test.assertTrue(views.includes(window), "One of the views is the background page");
+ browser.test.assertTrue(views.some(w => w.iAmOption), "One of the views is the options page");
browser.test.log("Switch tabs.");
return browser.tabs.update(firstTab, {active: true});
}).then(() => {
browser.test.log("Open options page again. Expect tab re-selected, no new load.");
return browser.runtime.openOptionsPage();
}).then(() => {