Bug 1333403 - Part 3: Fix using browser.menus from multiple contexts r=kmag

MozReview-Commit-ID: XlP72cr0VT

--HG--
extra : rebase_source : fb2ad1fe054aaedeecb7006aef62cb442d4899ab
This commit is contained in:
Tomislav Jovanovic 2017-04-25 23:51:26 +02:00
Родитель 2e019f4e0b
Коммит 05b61a9cc0
4 изменённых файлов: 62 добавлений и 21 удалений

Просмотреть файл

@ -616,16 +616,23 @@ const menuTracker = {
},
};
var gExtensionCount = 0;
this.menusInternal = class extends ExtensionAPI {
constructor(extension) {
super(extension);
if (!gMenuMap.size) {
menuTracker.register();
}
gMenuMap.set(extension, new Map());
}
onShutdown(reason) {
let {extension} = this;
if (gMenuMap.has(extension)) {
gMenuMap.delete(extension);
gRootItems.delete(extension);
if (--gExtensionCount == 0) {
if (!gMenuMap.size) {
menuTracker.unregister();
}
}
@ -634,11 +641,6 @@ this.menusInternal = class extends ExtensionAPI {
getAPI(context) {
let {extension} = context;
gMenuMap.set(extension, new Map());
if (++gExtensionCount == 1) {
menuTracker.register();
}
return {
menusInternal: {
create: function(createProperties) {

Просмотреть файл

@ -3,6 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html";
add_task(async function test_permissions() {
function background() {
browser.test.sendMessage("apis", {
@ -185,8 +187,7 @@ add_task(async function test_onclick_frameid() {
}
const extension = ExtensionTestUtils.loadExtension({manifest, background});
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser,
"http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
await extension.startup();
await extension.awaitMessage("ready");
@ -208,3 +209,49 @@ add_task(async function test_onclick_frameid() {
await BrowserTestUtils.removeTab(tab);
await extension.unload();
});
add_task(async function test_multiple_contexts_init() {
const manifest = {
permissions: ["menus"],
};
function background() {
browser.menus.create({id: "parent", title: "parent"});
browser.tabs.create({url: "tab.html", active: false});
}
const files = {
"tab.html": "<!DOCTYPE html><meta charset=utf-8><script src=tab.js></script>",
"tab.js": function() {
browser.menus.create({parentId: "parent", id: "child", title: "child"});
browser.menus.onClicked.addListener(info => {
browser.test.sendMessage("click", info);
});
browser.test.sendMessage("ready");
},
};
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
const extension = ExtensionTestUtils.loadExtension({manifest, background, files});
await extension.startup();
await extension.awaitMessage("ready");
const menu = await openContextMenu();
const items = menu.getElementsByAttribute("label", "parent");
is(items.length, 1, "Found parent menu item");
is(items[0].tagName, "menu", "And it has children");
const popup = await openSubmenu(items[0]);
is(popup.firstChild.label, "child", "Correct child menu item");
await closeExtensionContextMenu(popup.firstChild);
const info = await extension.awaitMessage("click");
is(info.menuItemId, "child", "onClicked the correct item");
await BrowserTestUtils.removeTab(tab);
await extension.unload();
});

Просмотреть файл

@ -309,7 +309,7 @@ async function closeExtensionContextMenu(itemToSelect, modifiers = {}) {
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
EventUtils.synthesizeMouseAtCenter(itemToSelect, modifiers);
await popupHiddenPromise;
return popupHiddenPromise;
}
async function openChromeContextMenu(menuId, target, win = window) {

Просмотреть файл

@ -1010,7 +1010,7 @@ class SchemaAPIManager extends EventEmitter {
module.loaded = true;
return this._initModule(module, this.global[name]);
return this.global[name];
}
/**
* aSynchronously loads an API module, if not already loaded, and
@ -1037,7 +1037,7 @@ class SchemaAPIManager extends EventEmitter {
module.loaded = true;
return this._initModule(module, this.global[name]);
return this.global[name];
});
return module.asyncLoaded;
@ -1076,14 +1076,6 @@ class SchemaAPIManager extends EventEmitter {
return true;
}
_initModule(info, cls) {
// FIXME: This both a) does nothing, and b) is not used anymore.
cls.namespaceName = cls.namespaceName;
cls.scopes = new Set(info.scopes);
return cls;
}
_checkLoadModule(module, name) {
if (!module) {
throw new Error(`Module '${name}' does not exist`);