зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602384 - Make sure menu.onShown API event is still emitted after a destroyed extension context. r=robwu
Differential Revision: https://phabricator.services.mozilla.com/D60493 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e409c9441c
Коммит
324d405b13
|
@ -41,8 +41,10 @@ var gRootItems = new Map();
|
|||
// Menu IDs that were eligible for being shown in the current menu.
|
||||
var gShownMenuItems = new DefaultMap(() => []);
|
||||
|
||||
// Set of extensions that are listening to onShown.
|
||||
var gOnShownSubscribers = new Set();
|
||||
// Map[Extension -> Set[Contexts]]
|
||||
// A DefaultMap (keyed by extension) which keeps track of the
|
||||
// contexts with a subscribed onShown event listener.
|
||||
var gOnShownSubscribers = new DefaultMap(() => new Set());
|
||||
|
||||
// If id is not specified for an item we use an integer.
|
||||
var gNextMenuItemID = 0;
|
||||
|
@ -571,7 +573,9 @@ var gMenuBuilder = {
|
|||
if (contextData.onBrowserAction || contextData.onPageAction) {
|
||||
dispatchOnShownEvent(contextData.extension);
|
||||
} else {
|
||||
gOnShownSubscribers.forEach(dispatchOnShownEvent);
|
||||
for (const extension of gOnShownSubscribers.keys()) {
|
||||
dispatchOnShownEvent(extension);
|
||||
}
|
||||
}
|
||||
|
||||
this.contextData = contextData;
|
||||
|
@ -1270,10 +1274,14 @@ this.menusInternal = class extends ExtensionAPI {
|
|||
let tab = nativeTab && extension.tabManager.convert(nativeTab);
|
||||
fire.sync(info, tab);
|
||||
};
|
||||
gOnShownSubscribers.add(extension);
|
||||
gOnShownSubscribers.get(extension).add(context);
|
||||
extension.on("webext-menu-shown", listener);
|
||||
return () => {
|
||||
gOnShownSubscribers.delete(extension);
|
||||
const contexts = gOnShownSubscribers.get(extension);
|
||||
contexts.delete(context);
|
||||
if (contexts.size === 0) {
|
||||
gOnShownSubscribers.delete(extension);
|
||||
}
|
||||
extension.off("webext-menu-shown", listener);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -141,6 +141,7 @@ skip-if = (verify && (os == 'linux' || os == 'mac'))
|
|||
[browser_ext_menus_event_order.js]
|
||||
[browser_ext_menus_events.js]
|
||||
skip-if = os == 'linux' #Bug 1433892
|
||||
[browser_ext_menus_events_after_context_destroy.js]
|
||||
[browser_ext_menus_incognito.js]
|
||||
[browser_ext_menus_refresh.js]
|
||||
[browser_ext_menus_replace_menu.js]
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// This test does verify that the menus API events are still emitted when
|
||||
// there are extension context alive with subscribed listeners
|
||||
// (See Bug 1602384).
|
||||
add_task(async function test_subscribed_events_fired_after_context_destroy() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["menus"],
|
||||
},
|
||||
files: {
|
||||
"page.html": `<!DOCTYPE html>
|
||||
<meta charset="uft-8"><script src="page.js"></script>
|
||||
Extension Page
|
||||
`,
|
||||
"page.js": async function() {
|
||||
browser.menus.onShown.addListener(() => {
|
||||
browser.test.sendMessage("menu-onShown");
|
||||
});
|
||||
browser.menus.onHidden.addListener(() => {
|
||||
browser.test.sendMessage("menu-onHidden");
|
||||
});
|
||||
// Call an API method implemented in the parent process
|
||||
// to ensure the menu listeners are subscribed in the
|
||||
// parent process.
|
||||
await browser.runtime.getBrowserInfo();
|
||||
browser.test.sendMessage("page-loaded");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
const pageURL = `moz-extension://${extension.uuid}/page.html`;
|
||||
|
||||
info("Loading extension page in a tab");
|
||||
const tab1 = BrowserTestUtils.addTab(gBrowser, pageURL);
|
||||
await extension.awaitMessage("page-loaded");
|
||||
|
||||
info("Loading extension page in another tab");
|
||||
const tab2 = BrowserTestUtils.addTab(gBrowser, pageURL);
|
||||
await extension.awaitMessage("page-loaded");
|
||||
|
||||
info("Select the first tab");
|
||||
gBrowser.selectedTab = tab1;
|
||||
|
||||
info("Remove the second tab");
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
|
||||
info("Open a context menu and expect menu.onShown to be fired");
|
||||
await window.promiseDocumentFlushed(() => {});
|
||||
await openContextMenu("body");
|
||||
await extension.awaitMessage("menu-onShown");
|
||||
|
||||
info("Close context menu and expect menu.onHidden to be fired");
|
||||
await closeExtensionContextMenu();
|
||||
await extension.awaitMessage("menu-onHidden");
|
||||
|
||||
ok(true, "The expected menu events have been fired");
|
||||
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
|
||||
await extension.unload();
|
||||
});
|
Загрузка…
Ссылка в новой задаче