Bug 1353073 handle contextmenu in sidebar when remote=true, r?kmag
MozReview-Commit-ID: BSmPhaNYmYe
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -13,16 +13,54 @@ Components.utils.import("resource://gre/
Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
"resource://gre/modules/LoginHelper.jsm");
var gContextMenuContentData = null;
+function openContextMenu(aMessage) {
+ let data = aMessage.data;
+ let browser = aMessage.target;
+
+ let spellInfo = data.spellInfo;
+ if (spellInfo)
+ spellInfo.target = aMessage.target.messageManager;
+ let documentURIObject = makeURI(data.docLocation,
+ data.charSet,
+ makeURI(data.baseURI));
+ gContextMenuContentData = { isRemote: true,
+ event: aMessage.objects.event,
+ popupNode: aMessage.objects.popupNode,
+ browser,
+ editFlags: data.editFlags,
+ spellInfo,
+ principal: data.principal,
+ customMenuItems: data.customMenuItems,
+ addonInfo: data.addonInfo,
+ documentURIObject,
+ docLocation: data.docLocation,
+ charSet: data.charSet,
+ referrer: data.referrer,
+ referrerPolicy: data.referrerPolicy,
+ contentType: data.contentType,
+ contentDisposition: data.contentDisposition,
+ frameOuterWindowID: data.frameOuterWindowID,
+ selectionInfo: data.selectionInfo,
+ disableSetDesktopBackground: data.disableSetDesktopBg,
+ loginFillInfo: data.loginFillInfo,
+ parentAllowsMixedContent: data.parentAllowsMixedContent,
+ userContextId: data.userContextId,
+ };
+ let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
+ let event = gContextMenuContentData.event;
+ popup.openPopupAtScreen(event.screenX, event.screenY, true);
+}
+
function nsContextMenu(aXulMenu, aIsShift) {
this.shouldDisplay = true;
this.initMenu(aXulMenu, aIsShift);
}
// Prototype for nsContextMenu "class."
nsContextMenu.prototype = {
initMenu: function CM_initMenu(aXulMenu, aIsShift) {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4950,48 +4950,17 @@
if (tab) {
// Skip running PermitUnload since it already happened in
// the content process.
this.removeTab(tab, {skipPermitUnload: true});
}
break;
}
case "contextmenu": {
- let spellInfo = data.spellInfo;
- if (spellInfo)
- spellInfo.target = aMessage.target.messageManager;
- let documentURIObject = makeURI(data.docLocation,
- data.charSet,
- makeURI(data.baseURI));
- gContextMenuContentData = { isRemote: true,
- event: aMessage.objects.event,
- popupNode: aMessage.objects.popupNode,
- browser,
- editFlags: data.editFlags,
- spellInfo,
- principal: data.principal,
- customMenuItems: data.customMenuItems,
- addonInfo: data.addonInfo,
- documentURIObject,
- docLocation: data.docLocation,
- charSet: data.charSet,
- referrer: data.referrer,
- referrerPolicy: data.referrerPolicy,
- contentType: data.contentType,
- contentDisposition: data.contentDisposition,
- frameOuterWindowID: data.frameOuterWindowID,
- selectionInfo: data.selectionInfo,
- disableSetDesktopBackground: data.disableSetDesktopBg,
- loginFillInfo: data.loginFillInfo,
- parentAllowsMixedContent: data.parentAllowsMixedContent,
- userContextId: data.userContextId,
- };
- let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
- let event = gContextMenuContentData.event;
- popup.openPopupAtScreen(event.screenX, event.screenY, true);
+ openContextMenu(aMessage);
break;
}
case "DOMWindowFocus": {
let tab = this.getTabForBrowser(browser);
if (!tab)
return undefined;
this.selectedTab = tab;
window.focus();
--- a/browser/base/content/webext-panels.js
+++ b/browser/base/content/webext-panels.js
@@ -1,26 +1,28 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* 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/. */
// Via webext-panels.xul
/* import-globals-from browser.js */
+/* import-globals-from nsContextMenu.js */
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionParent",
"resource://gre/modules/ExtensionParent.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
promiseEvent,
} = ExtensionUtils;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
function getBrowser(sidebar) {
let browser = document.getElementById("webext-panels-browser");
if (browser) {
return Promise.resolve(browser);
}
browser = document.createElementNS(XUL_NS, "browser");
browser.setAttribute("id", "webext-panels-browser");
@@ -34,16 +36,21 @@ function getBrowser(sidebar) {
let readyPromise;
if (sidebar.remote) {
browser.setAttribute("remote", "true");
browser.setAttribute("remoteType",
E10SUtils.getRemoteTypeForURI(sidebar.uri, true,
E10SUtils.EXTENSION_REMOTE_TYPE));
readyPromise = promiseEvent(browser, "XULFrameLoaderCreated");
+
+ window.messageManager.addMessageListener("contextmenu", openContextMenu);
+ window.addEventListener("unload", () => {
+ window.messageManager.removeMessageListener("contextmenu", openContextMenu);
+ }, {once: true});
} else {
readyPromise = Promise.resolve();
}
document.documentElement.appendChild(browser);
return readyPromise.then(() => {
browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false);
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
--- a/browser/components/extensions/test/browser/browser_ext_sidebarAction.js
+++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction.js
@@ -1,14 +1,15 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
let extData = {
manifest: {
+ "permissions": ["contextMenus"],
"sidebar_action": {
"default_panel": "sidebar.html",
},
},
useAddonManager: "temporary",
files: {
"sidebar.html": `
@@ -25,16 +26,22 @@ let extData = {
"sidebar.js": function() {
window.onload = () => {
browser.test.sendMessage("sidebar");
};
},
},
background: function() {
+ browser.contextMenus.create({
+ id: "clickme-page",
+ title: "Click me!",
+ contexts: ["all"],
+ });
+
browser.test.onMessage.addListener(msg => {
if (msg === "set-panel") {
browser.sidebarAction.setPanel({panel: ""}).then(() => {
browser.test.notifyFail("empty panel settable");
}).catch(() => {
browser.test.notifyPass("unable to set empty panel");
});
}
@@ -91,12 +98,26 @@ add_task(function* sidebar_empty_panel()
// Test sidebar is opened on install
yield extension.awaitMessage("sidebar");
ok(!document.getElementById("sidebar-box").hidden, "sidebar box is visible in first window");
extension.sendMessage("set-panel");
yield extension.awaitFinish();
yield extension.unload();
});
+add_task(function* sidebar_contextmenu() {
+ let extension = ExtensionTestUtils.loadExtension(extData);
+ yield extension.startup();
+ // Test sidebar is opened on install
+ yield extension.awaitMessage("sidebar");
+
+ let contentAreaContextMenu = yield openContextMenuInSidebar();
+ let item = contentAreaContextMenu.getElementsByAttribute("label", "Click me!");
+ is(item.length, 1, "contextMenu item for page was found");
+ yield closeContextMenu(contentAreaContextMenu);
+
+ yield extension.unload();
+});
+
add_task(function* cleanup() {
// This is set on initial sidebar install.
Services.prefs.clearUserPref("extensions.sidebar-button.shown");
});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -3,17 +3,17 @@
"use strict";
/* exported CustomizableUI makeWidgetId focusWindow forceGC
* getBrowserActionWidget
* clickBrowserAction clickPageAction
* getBrowserActionPopup getPageActionPopup
* closeBrowserAction closePageAction
* promisePopupShown promisePopupHidden
- * openContextMenu closeContextMenu
+ * openContextMenu closeContextMenu openContextMenuInSidebar
* openExtensionContextMenu closeExtensionContextMenu
* openActionContextMenu openSubmenu closeActionContextMenu
* openTabContextMenu closeTabContextMenu
* imageBuffer imageBufferFromDataURI
* getListStyleImage getPanelForNode
* awaitExtensionPanel awaitPopupResize
* promiseContentDimensions alterContent
* promisePrefChangeObserved openContextMenuInFrame
@@ -227,16 +227,26 @@ function closeBrowserAction(extension, w
let group = getBrowserActionWidget(extension);
let node = win.document.getElementById(group.viewId);
CustomizableUI.hidePanelForNode(node);
return Promise.resolve();
}
+async function openContextMenuInSidebar(selector = "body") {
+ let contentAreaContextMenu = SidebarUI.browser.contentDocument.getElementById("contentAreaContextMenu");
+ let browser = SidebarUI.browser.contentDocument.getElementById("webext-panels-browser");
+ let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
+ await BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "mousedown", button: 2}, browser);
+ await BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "contextmenu"}, browser);
+ await popupShownPromise;
+ return contentAreaContextMenu;
+}
+
async function openContextMenuInFrame(frameId) {
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
let doc = gBrowser.selectedBrowser.contentDocument;
let frame = doc.getElementById(frameId);
EventUtils.synthesizeMouseAtCenter(frame.contentDocument.body, {type: "contextmenu"}, frame.contentWindow);
await popupShownPromise;
return contentAreaContextMenu;
@@ -246,18 +256,18 @@ async function openContextMenu(selector
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
await BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "mousedown", button: 2}, gBrowser.selectedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "contextmenu"}, gBrowser.selectedBrowser);
await popupShownPromise;
return contentAreaContextMenu;
}
-async function closeContextMenu() {
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
+async function closeContextMenu(contextMenu) {
+ let contentAreaContextMenu = contextMenu || document.getElementById("contentAreaContextMenu");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
contentAreaContextMenu.hidePopup();
await popupHiddenPromise;
}
function* openExtensionContextMenu(selector = "#img1") {
let contextMenu = yield openContextMenu(selector);
let topLevelMenu = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");