Bug 1412170 - Integrate WebExtension page action context menus with the Photon page action context menu: WebExtensions changes. r?mixedpuppy
MozReview-Commit-ID: 4vBNSmCU1a0
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -68,16 +68,25 @@ this.pageAction = class extends Extensio
id: widgetId,
title: this.defaults.title,
iconURL: this.defaults.icon,
shownInUrlbar: true,
disabled: true,
onCommand: (event, buttonNode) => {
this.handleClick(event.target.ownerGlobal);
},
+ onBeforePlacedInWindow: browserWindow => {
+ if (this.extension.hasPermission("menus") ||
+ this.extension.hasPermission("contextMenus")) {
+ browserWindow.document.addEventListener("popupshowing", this);
+ }
+ },
+ onRemovedFromWindow: browserWindow => {
+ browserWindow.document.removeEventListener("popupshowing", this);
+ },
}));
}
}
onShutdown(reason) {
pageActionMap.delete(this.extension);
this.tabContext.shutdown();
@@ -146,16 +155,35 @@ this.pageAction = class extends Extensio
*/
triggerAction(window) {
let pageAction = pageActionMap.get(this.extension);
if (pageAction.getProperty(window.gBrowser.selectedTab, "show")) {
pageAction.handleClick(window);
}
}
+ handleEvent(event) {
+ switch (event.type) {
+ case "popupshowing":
+ const menu = event.target;
+ const trigger = menu.triggerNode;
+
+ if (menu.id === "pageActionContextMenu" &&
+ trigger &&
+ trigger.getAttribute("actionid") === this.browserPageAction.id) {
+ global.actionContextMenu({
+ extension: this.extension,
+ onPageAction: true,
+ menu: menu,
+ });
+ }
+ break;
+ }
+ }
+
// Handles a click event on the page action button for the given
// window.
// If the page action has a |popup| property, a panel is opened to
// that URL. Otherwise, a "click" event is emitted, and dispatched to
// the any click listeners in the add-on.
async handleClick(window) {
TelemetryStopwatch.start(popupOpenTimingHistogram, this);
let tab = window.gBrowser.selectedTab;
--- a/browser/components/extensions/test/browser/browser_ext_menus.js
+++ b/browser/components/extensions/test/browser/browser_ext_menus.js
@@ -63,20 +63,17 @@ add_task(async function test_actionConte
}
const extension = ExtensionTestUtils.loadExtension({manifest, background});
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
await extension.startup();
const tabId = await extension.awaitMessage("ready");
- // TODO bug 1412170: Allow WebExtensions to hook into the browser page action
- // context menu.
-// for (const kind of ["page", "browser"]) {
- for (const kind of ["browser"]) {
+ for (const kind of ["page", "browser"]) {
const menu = await openActionContextMenu(extension, kind);
const [submenu, second, , , , last, separator] = menu.children;
is(submenu.tagName, "menu", "Correct submenu type");
is(submenu.label, "parent", "Correct submenu title");
const popup = await openSubmenu(submenu);
is(popup, submenu.firstChild, "Correct submenu opened");
@@ -87,17 +84,17 @@ add_task(async function test_actionConte
is(second.tagName, "menuitem", "Second menu item type is correct");
is(second.label, "click 1", "Second menu item title is correct");
is(second.id, `${idPrefix}1`, "Second menu item id is correct");
is(last.label, "click 5", "Last menu item title is correct");
is(last.id, `${idPrefix}5`, "Last menu item id is correct");
is(separator.tagName, "menuseparator", "Separator after last menu item");
- await closeActionContextMenu(popup.firstChild);
+ await closeActionContextMenu(popup.firstChild, kind);
const {info, tab} = await extension.awaitMessage("click");
is(info.pageUrl, "http://example.com/", "Click info pageUrl is correct");
is(tab.id, tabId, "Click event tab ID is correct");
}
await BrowserTestUtils.removeTab(tab);
await extension.unload();
});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -388,25 +388,31 @@ function closeChromeContextMenu(menuId,
}
return hidden;
}
async function openActionContextMenu(extension, kind, win = window) {
// See comment from clickPageAction below.
SetPageProxyState("valid");
await promiseAnimationFrame(win);
- const id =
- kind == "page" ?
- `#${BrowserPageActions.urlbarButtonNodeIDForActionID(makeWidgetId(extension.id))}` :
- `#${makeWidgetId(extension.id)}-${kind}-action`;
- return openChromeContextMenu("toolbar-context-menu", id, win);
+ let buttonID;
+ let menuID;
+ if (kind == "page") {
+ buttonID = "#" + BrowserPageActions.urlbarButtonNodeIDForActionID(makeWidgetId(extension.id));
+ menuID = "pageActionContextMenu";
+ } else {
+ buttonID = `#${makeWidgetId(extension.id)}-${kind}-action`;
+ menuID = "toolbar-context-menu";
+ }
+ return openChromeContextMenu(menuID, buttonID, win);
}
-function closeActionContextMenu(itemToSelect, win = window) {
- return closeChromeContextMenu("toolbar-context-menu", itemToSelect, win);
+function closeActionContextMenu(itemToSelect, kind, win = window) {
+ let menuID = kind == "page" ? "pageActionContextMenu" : "toolbar-context-menu";
+ return closeChromeContextMenu(menuID, itemToSelect, win);
}
function openTabContextMenu(win = window) {
return openChromeContextMenu("tabContextMenu", ".tabbrowser-tab[selected]", win);
}
function closeTabContextMenu(itemToSelect, win = window) {
return closeChromeContextMenu("tabContextMenu", itemToSelect, win);