Bug 1388104 - Open the textbox context menu on any html input in the toolbox;r=gl

Right now HTML inputs do not get a context menu when being right clicked. The inspector
works around this by calling toolbox.openTextBoxContextMenu on each individual input,
but the rest of the toolbox can be served by handling this at the toolbox level.

MozReview-Commit-ID: KuRQmuf01xh

--HG--
extra : rebase_source : d1febb54888a8a82f93d54c78ddbdd40281f91ee
This commit is contained in:
Brian Grinstead 2017-08-15 15:39:32 -07:00
Родитель c063aa0150
Коммит 60bb95b790
3 изменённых файлов: 62 добавлений и 10 удалений

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

@ -3,10 +3,20 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const URL = "data:text/html;charset=utf8,test for textbox context menu";
// HTML inputs don't automatically get the 'edit' context menu, so we have
// a helper on the toolbox to do so. Make sure that shows menu items in the
// right state, and that it works for an input inside of a panel.
add_task(function* () {
let toolbox = yield openNewTabAndToolbox(URL, "inspector");
const URL = "data:text/html;charset=utf8,test for textbox context menu";
const textboxToolId = "test-tool-1";
registerCleanupFunction(() => {
gDevTools.unregisterTool(textboxToolId);
});
add_task(async function checkMenuEntryStates() {
info("Checking the state of edit menuitems with an empty clipboard");
let toolbox = await openNewTabAndToolbox(URL, "inspector");
let textboxContextMenu = toolbox.textBoxContextMenuPopup;
emptyClipboard();
@ -15,7 +25,7 @@ add_task(function* () {
let inspector = toolbox.getPanel("inspector");
let onFocus = once(inspector.searchBox, "focus");
inspector.searchBox.focus();
yield onFocus;
await onFocus;
ok(textboxContextMenu, "The textbox context menu is loaded in the toolbox");
@ -30,7 +40,7 @@ add_task(function* () {
let onContextMenuPopup = once(textboxContextMenu, "popupshowing");
textboxContextMenu.openPopupAtScreen(0, 0, true);
yield onContextMenuPopup;
await onContextMenuPopup;
is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
@ -41,11 +51,41 @@ add_task(function* () {
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
yield cleanup(toolbox);
});
function* cleanup(toolbox) {
yield toolbox.destroy();
gBrowser.removeCurrentTab();
add_task(async function automaticallyBindTexbox() {
info("Registering a tool with an input field and making sure the context menu works");
gDevTools.registerTool({
id: textboxToolId,
isTargetSupported: () => true,
url: "data:text/html;charset=utf8,<input />",
label: "Context menu works without tool intervention",
build: function (iframeWindow, toolbox) {
this.panel = createTestPanel(iframeWindow, toolbox);
return this.panel.open();
},
});
let toolbox = await openNewTabAndToolbox(URL, textboxToolId);
is(toolbox.currentToolId, textboxToolId, "The custom tool has been opened");
await checkTextBox(toolbox.getCurrentPanel().document.querySelector("input"), toolbox);
});
async function checkTextBox(textBox, {textBoxContextMenuPopup}) {
is(textBoxContextMenuPopup.state, "closed", "The menu is closed");
info("Simulating context click on the textbox and expecting the menu to open");
let onContextMenu = once(textBoxContextMenuPopup, "popupshown");
EventUtils.synthesizeMouse(textBox, 2, 2, {type: "contextmenu", button: 2},
textBox.ownerDocument.defaultView);
await onContextMenu;
is(textBoxContextMenuPopup.state, "open", "The menu is now visible");
info("Closing the menu");
let onContextMenuHidden = once(textBoxContextMenuPopup, "popuphidden");
textBoxContextMenuPopup.hidePopup();
await onContextMenuHidden;
is(textBoxContextMenuPopup.state, "closed", "The menu is closed again");
}

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

@ -203,6 +203,7 @@ function DevToolPanel(iframeWindow, toolbox) {
EventEmitter.decorate(this);
this._toolbox = toolbox;
this._window = iframeWindow;
}
DevToolPanel.prototype = {
@ -218,6 +219,10 @@ DevToolPanel.prototype = {
return deferred.promise;
},
get document() {
return this._window.document;
},
get target() {
return this._toolbox.target;
},

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

@ -442,6 +442,13 @@ Toolbox.prototype = {
this.doc.getElementById("toolbox-textbox-context-popup");
this.textBoxContextMenuPopup.addEventListener("popupshowing",
this._updateTextBoxMenuItems, true);
this.doc.addEventListener("contextmenu", (e) => {
if (e.originalTarget.closest("input") || e.originalTarget.closest("textarea")) {
e.stopPropagation();
e.preventDefault();
this.openTextBoxContextMenu(e.screenX, e.screenY);
}
}, true);
this.shortcuts = new KeyShortcuts({
window: this.doc.defaultView