Bug 1285493: Add-on Manager should not be closed when an add-on with options_ui is disabled. r=billm

MozReview-Commit-ID: 8oRK8uPphDf

--HG--
extra : rebase_source : c6dcc7da1823711e3223ba39d038e1ccc949f6fd
This commit is contained in:
Kris Maglione 2016-07-24 15:05:39 -07:00
parent fba8996a05
commit 8d58c7c636
3 changed files with 94 additions and 24 deletions

View File

@ -42,44 +42,46 @@ function getSender(context, target, sender) {
}
}
// WeakMap[ExtensionContext -> {tab, parentWindow}]
var pageDataMap = new WeakMap();
function getDocShellOwner(docShell) {
let browser = docShell.chromeEventHandler;
let xulWindow = browser.ownerGlobal;
let {gBrowser} = xulWindow;
if (gBrowser) {
let tab = gBrowser.getTabForBrowser(browser);
return {xulWindow, tab};
}
return {};
}
/* eslint-disable mozilla/balanced-listeners */
// This listener fires whenever an extension page opens in a tab
// (either initiated by the extension or the user). Its job is to fill
// in some tab-specific details and keep data around about the
// ExtensionContext.
extensions.on("page-load", (type, page, params, sender, delegate) => {
extensions.on("page-load", (type, context, params, sender, delegate) => {
if (params.type == "tab" || params.type == "popup") {
let browser = params.docShell.chromeEventHandler;
let {xulWindow, tab} = getDocShellOwner(params.docShell);
let parentWindow = browser.ownerGlobal;
page.windowId = WindowManager.getId(parentWindow);
let tab = parentWindow.gBrowser.getTabForBrowser(browser);
// FIXME: Handle tabs being moved between windows.
context.windowId = WindowManager.getId(xulWindow);
if (tab) {
sender.tabId = TabManager.getId(tab);
page.tabId = TabManager.getId(tab);
context.tabId = TabManager.getId(tab);
}
pageDataMap.set(page, {tab, parentWindow});
}
delegate.getSender = getSender;
});
extensions.on("page-unload", (type, page) => {
pageDataMap.delete(page);
});
extensions.on("page-shutdown", (type, page) => {
if (pageDataMap.has(page)) {
let {tab, parentWindow} = pageDataMap.get(page);
pageDataMap.delete(page);
extensions.on("page-shutdown", (type, context) => {
if (context.type == "tab") {
let {xulWindow, tab} = getDocShellOwner(context.docShell);
if (tab) {
parentWindow.gBrowser.removeTab(tab);
xulWindow.gBrowser.removeTab(tab);
}
}
});
@ -96,9 +98,9 @@ extensions.on("fill-browser-data", (type, browser, data, result) => {
/* eslint-enable mozilla/balanced-listeners */
global.currentWindow = function(context) {
let pageData = pageDataMap.get(context);
if (pageData) {
return pageData.parentWindow;
let {xulWindow} = getDocShellOwner(context.docShell);
if (xulWindow) {
return xulWindow;
}
return WindowManager.topWindow;
};

View File

@ -257,3 +257,66 @@ add_task(function* test_options_no_manifest() {
yield extension.awaitFinish("options-no-manifest");
yield extension.unload();
});
add_task(function* test_inline_options_uninstall() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
let extension = yield loadExtension({
manifest: {
"options_ui": {
"page": "options.html",
},
},
background: function() {
let _optionsPromise;
let awaitOptions = () => {
browser.test.assertFalse(_optionsPromise, "Should not be awaiting options already");
return new Promise(resolve => {
_optionsPromise = {resolve};
});
};
browser.runtime.onMessage.addListener((msg, sender) => {
if (msg == "options.html") {
if (_optionsPromise) {
_optionsPromise.resolve(sender.tab);
_optionsPromise = null;
} else {
browser.test.fail("Saw unexpected options page load");
}
}
});
let firstTab;
browser.tabs.query({currentWindow: true, active: true}).then(tabs => {
firstTab = tabs[0].id;
browser.test.log("Open options page. Expect fresh load.");
return Promise.all([
browser.runtime.openOptionsPage(),
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");
browser.test.sendMessage("options-ui-open");
}).catch(error => {
browser.test.fail(`Error: ${error} :: ${error.stack}`);
});
},
});
yield extension.awaitMessage("options-ui-open");
yield extension.unload();
is(gBrowser.selectedBrowser.currentURI.spec, "about:addons",
"Add-on manager tab should still be open");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
yield BrowserTestUtils.removeTab(tab);
});

View File

@ -277,6 +277,11 @@ ExtensionContext = class extends BaseContext {
}
}
get docShell() {
return this.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
}
get cloneScope() {
return this.contentWindow;
}