Commit 92f2dbb1 authored by Julian Descottes's avatar Julian Descottes
Browse files

Bug 1543940 - Use the toolbox top window for context menus r=ochameau

Depends on D28036

If a context menu is opened in the toolbox document when running in a frame with type=content, keyboard navigation will not move to the context menu when it's opened.

Differential Revision: https://phabricator.services.mozilla.com/D27695

--HG--
extra : moz-landing-system : lando
parent 6c24dca7
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@


"use strict";
"use strict";


const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const EventEmitter = require("devtools/shared/event-emitter");
const EventEmitter = require("devtools/shared/event-emitter");
const { getCurrentZoom } = require("devtools/shared/layout/utils");
const { getCurrentZoom } = require("devtools/shared/layout/utils");


@@ -79,6 +80,12 @@ Menu.prototype.popupWithZoom = function(x, y, doc) {
 *        The document that should own the context menu.
 *        The document that should own the context menu.
 */
 */
Menu.prototype.popup = function(screenX, screenY, doc) {
Menu.prototype.popup = function(screenX, screenY, doc) {
  // The context-menu will be created in the topmost window to preserve keyboard
  // navigation (see Bug 1543940).
  // Keep a reference on the window owning the menu to hide the popup on unload.
  const win = doc.defaultView;
  doc = DevToolsUtils.getTopWindow(doc.defaultView).document;

  let popupset = doc.querySelector("popupset");
  let popupset = doc.querySelector("popupset");
  if (!popupset) {
  if (!popupset) {
    popupset = doc.createXULElement("popupset");
    popupset = doc.createXULElement("popupset");
@@ -103,9 +110,15 @@ Menu.prototype.popup = function(screenX, screenY, doc) {
  }
  }
  this._createMenuItems(popup);
  this._createMenuItems(popup);


  // The context menu will be created in the topmost chrome window. Hide it manually when
  // the owner document is unloaded.
  const onWindowUnload = () => popup.hidePopup();
  win.addEventListener("unload", onWindowUnload);

  // Remove the menu from the DOM once it's hidden.
  // Remove the menu from the DOM once it's hidden.
  popup.addEventListener("popuphidden", (e) => {
  popup.addEventListener("popuphidden", (e) => {
    if (e.target === popup) {
    if (e.target === popup) {
      win.removeEventListener("unload", onWindowUnload);
      popup.remove();
      popup.remove();
      this.emit("close");
      this.emit("close");
    }
    }
@@ -157,6 +170,11 @@ Menu.prototype._createMenuItems = function(parent) {
  });
  });
};
};


Menu.getMenuElementById = function(id, doc) {
  const menuDoc = DevToolsUtils.getTopWindow(doc.defaultView).document;
  return menuDoc.getElementById(id);
};

Menu.setApplicationMenu = () => {
Menu.setApplicationMenu = () => {
  throw Error("Not implemented");
  throw Error("Not implemented");
};
};
+5 −1
Original line number Original line Diff line number Diff line
@@ -391,6 +391,10 @@ Toolbox.prototype = {
    return DevToolsUtils.getTopWindow(this.win);
    return DevToolsUtils.getTopWindow(this.win);
  },
  },


  get topDoc() {
    return this.topWindow.document;
  },

  /**
  /**
   * Shortcut to the document containing the toolbox UI
   * Shortcut to the document containing the toolbox UI
   */
   */
@@ -3247,7 +3251,7 @@ Toolbox.prototype = {
   * @param {Number} y
   * @param {Number} y
   */
   */
  openTextBoxContextMenu: function(x, y) {
  openTextBoxContextMenu: function(x, y) {
    const menu = createEditContextMenu(this.win, "toolbox-menu");
    const menu = createEditContextMenu(this.topWindow, "toolbox-menu");


    // Fire event for tests
    // Fire event for tests
    menu.once("open", () => this.emit("menu-open"));
    menu.once("open", () => this.emit("menu-open"));
+2 −1
Original line number Original line Diff line number Diff line
@@ -768,7 +768,8 @@ class MarkupContextMenu {
    const hasA11YProps = await this.walker.hasAccessibilityProperties(
    const hasA11YProps = await this.walker.hasAccessibilityProperties(
      this.selection.nodeFront);
      this.selection.nodeFront);
    if (hasA11YProps) {
    if (hasA11YProps) {
      this.toolbox.doc.getElementById(menuItem.id).disabled = menuItem.disabled = false;
      const menuItemEl = Menu.getMenuElementById(menuItem.id, this.toolbox.doc);
      menuItemEl.disabled = menuItem.disabled = false;
    }
    }


    this.inspector.emit("node-menu-updated");
    this.inspector.emit("node-menu-updated");
+1 −1
Original line number Original line Diff line number Diff line
@@ -68,7 +68,7 @@ function showMenu(items, options) {
  if (options.useTopLevelWindow) {
  if (options.useTopLevelWindow) {
    doc = getTopLevelWindow(window).document;
    doc = getTopLevelWindow(window).document;
  } else {
  } else {
    doc = window.parent.document;
    doc = window.document;
  }
  }


  menu.popup(screenX, screenY, doc);
  menu.popup(screenX, screenY, doc);