mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
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:
parent
fba8996a05
commit
8d58c7c636
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -277,6 +277,11 @@ ExtensionContext = class extends BaseContext {
|
||||
}
|
||||
}
|
||||
|
||||
get docShell() {
|
||||
return this.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
}
|
||||
|
||||
get cloneScope() {
|
||||
return this.contentWindow;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user