summaryrefslogtreecommitdiffstats
path: root/toolkit/content/editMenuOverlay.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/content/editMenuOverlay.js133
1 files changed, 133 insertions, 0 deletions
diff --git a/toolkit/content/editMenuOverlay.js b/toolkit/content/editMenuOverlay.js
new file mode 100644
index 0000000000..b0ec197224
--- /dev/null
+++ b/toolkit/content/editMenuOverlay.js
@@ -0,0 +1,133 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+
+/* 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/. */
+
+// update menu items that rely on focus or on the current selection
+function goUpdateGlobalEditMenuItems(force) {
+ // Don't bother updating the edit commands if they aren't visible in any way
+ // (i.e. the Edit menu isn't open, nor is the context menu open, nor have the
+ // cut, copy, and paste buttons been added to the toolbars) for performance.
+ // This only works in applications/on platforms that set the gEditUIVisible
+ // flag, so we check to see if that flag is defined before using it.
+ if (!force && typeof gEditUIVisible != "undefined" && !gEditUIVisible) {
+ return;
+ }
+
+ goUpdateUndoEditMenuItems();
+ goUpdateCommand("cmd_cut");
+ goUpdateCommand("cmd_copy");
+ goUpdatePasteMenuItems();
+ goUpdateCommand("cmd_selectAll");
+ goUpdateCommand("cmd_delete");
+ goUpdateCommand("cmd_switchTextDirection");
+}
+
+// update menu items that relate to undo/redo
+function goUpdateUndoEditMenuItems() {
+ goUpdateCommand("cmd_undo");
+ goUpdateCommand("cmd_redo");
+}
+
+// update menu items that depend on clipboard contents
+function goUpdatePasteMenuItems() {
+ goUpdateCommand("cmd_paste");
+ goUpdateCommand("cmd_pasteNoFormatting");
+}
+
+// Inject the commandset here instead of relying on preprocessor to share this across documents.
+window.addEventListener(
+ "DOMContentLoaded",
+ () => {
+ let container =
+ document.querySelector("commandset") || document.documentElement;
+ let fragment = MozXULElement.parseXULToFragment(`
+ <commandset id="editMenuCommands">
+ <commandset id="editMenuCommandSetAll" commandupdater="true" events="focus,select" />
+ <commandset id="editMenuCommandSetUndo" commandupdater="true" events="undo" />
+ <commandset id="editMenuCommandSetPaste" commandupdater="true" events="clipboard" />
+ <command id="cmd_undo" internal="true"/>
+ <command id="cmd_redo" internal="true" />
+ <command id="cmd_cut" internal="true" />
+ <command id="cmd_copy" internal="true" />
+ <command id="cmd_paste" internal="true" />
+ <command id="cmd_pasteNoFormatting" internal="true" />
+ <command id="cmd_delete" />
+ <command id="cmd_selectAll" internal="true" />
+ <command id="cmd_switchTextDirection" />
+ </commandset>
+ `);
+
+ let editMenuCommandSetAll = fragment.querySelector(
+ "#editMenuCommandSetAll"
+ );
+ editMenuCommandSetAll.addEventListener("commandupdate", function () {
+ goUpdateGlobalEditMenuItems();
+ });
+
+ let editMenuCommandSetUndo = fragment.querySelector(
+ "#editMenuCommandSetUndo"
+ );
+ editMenuCommandSetUndo.addEventListener("commandupdate", function () {
+ goUpdateUndoEditMenuItems();
+ });
+
+ let editMenuCommandSetPaste = fragment.querySelector(
+ "#editMenuCommandSetPaste"
+ );
+ editMenuCommandSetPaste.addEventListener("commandupdate", function () {
+ goUpdatePasteMenuItems();
+ });
+
+ fragment.firstElementChild.addEventListener("command", event => {
+ let commandID = event.target.id;
+ goDoCommand(commandID);
+ });
+
+ container.appendChild(fragment);
+ },
+ { once: true }
+);
+
+// Support context menus on html textareas in the parent process:
+window.addEventListener("contextmenu", e => {
+ const HTML_NS = "http://www.w3.org/1999/xhtml";
+ let needsContextMenu =
+ e.composedTarget.ownerDocument == document &&
+ !e.defaultPrevented &&
+ e.composedTarget.parentNode.nodeName != "moz-input-box" &&
+ ((["textarea", "input"].includes(e.composedTarget.localName) &&
+ e.composedTarget.namespaceURI == HTML_NS) ||
+ e.composedTarget.closest("search-textbox"));
+
+ if (!needsContextMenu) {
+ return;
+ }
+
+ let popup = document.getElementById("textbox-contextmenu");
+ if (!popup) {
+ MozXULElement.insertFTLIfNeeded("toolkit/global/textActions.ftl");
+ document.documentElement.appendChild(
+ MozXULElement.parseXULToFragment(`
+ <menupopup id="textbox-contextmenu" class="textbox-contextmenu">
+ <menuitem data-l10n-id="text-action-undo" command="cmd_undo"></menuitem>
+ <menuitem data-l10n-id="text-action-redo" command="cmd_redo"></menuitem>
+ <menuseparator></menuseparator>
+ <menuitem data-l10n-id="text-action-cut" command="cmd_cut"></menuitem>
+ <menuitem data-l10n-id="text-action-copy" command="cmd_copy"></menuitem>
+ <menuitem data-l10n-id="text-action-paste" command="cmd_paste"></menuitem>
+ <menuitem data-l10n-id="text-action-delete" command="cmd_delete"></menuitem>
+ <menuitem data-l10n-id="text-action-select-all" command="cmd_selectAll"></menuitem>
+ </menupopup>
+ `)
+ );
+ popup = document.documentElement.lastElementChild;
+ }
+
+ goUpdateGlobalEditMenuItems(true);
+ popup.openPopupAtScreen(e.screenX, e.screenY, true, e);
+ // Don't show any other context menu at the same time. There can be a
+ // context menu from an ancestor too but we only want to show this one.
+ e.preventDefault();
+});