Bug 1708422: part 13) Factor code out to `mozInlineSpellChecker::SpellCheckerTimeSlic...
[gecko.git] / toolkit / content / editMenuOverlay.js
blob8edcc31b1f8a678e018aa0468585b2ef1b5ba51b
1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // update menu items that rely on focus or on the current selection
8 function goUpdateGlobalEditMenuItems(force) {
9   // Don't bother updating the edit commands if they aren't visible in any way
10   // (i.e. the Edit menu isn't open, nor is the context menu open, nor have the
11   // cut, copy, and paste buttons been added to the toolbars) for performance.
12   // This only works in applications/on platforms that set the gEditUIVisible
13   // flag, so we check to see if that flag is defined before using it.
14   if (!force && typeof gEditUIVisible != "undefined" && !gEditUIVisible) {
15     return;
16   }
18   goUpdateCommand("cmd_undo");
19   goUpdateCommand("cmd_redo");
20   goUpdateCommand("cmd_cut");
21   goUpdateCommand("cmd_copy");
22   goUpdateCommand("cmd_paste");
23   goUpdateCommand("cmd_selectAll");
24   goUpdateCommand("cmd_delete");
25   goUpdateCommand("cmd_switchTextDirection");
28 // update menu items that relate to undo/redo
29 function goUpdateUndoEditMenuItems() {
30   goUpdateCommand("cmd_undo");
31   goUpdateCommand("cmd_redo");
34 // update menu items that depend on clipboard contents
35 function goUpdatePasteMenuItems() {
36   goUpdateCommand("cmd_paste");
39 // Inject the commandset here instead of relying on preprocessor to share this across documents.
40 window.addEventListener(
41   "DOMContentLoaded",
42   () => {
43     // Bug 371900: Remove useless oncommand attribute once bug 371900 is fixed
44     // If you remove/update the oncommand attribute for any of the cmd_*, please
45     // also remove/update the sha512 hash in the CSP within about:downloads
46     let container =
47       document.querySelector("commandset") || document.documentElement;
48     let fragment = MozXULElement.parseXULToFragment(`
49       <commandset id="editMenuCommands">
50         <commandset id="editMenuCommandSetAll" commandupdater="true" events="focus,select" />
51         <commandset id="editMenuCommandSetUndo" commandupdater="true" events="undo" />
52         <commandset id="editMenuCommandSetPaste" commandupdater="true" events="clipboard" />
53         <command id="cmd_undo" oncommand=";" />
54         <command id="cmd_redo" oncommand=";" />
55         <command id="cmd_cut" oncommand=";" />
56         <command id="cmd_copy" oncommand=";" />
57         <command id="cmd_paste" oncommand=";" />
58         <command id="cmd_delete" oncommand=";" />
59         <command id="cmd_selectAll" oncommand=";" />
60         <command id="cmd_switchTextDirection" oncommand=";" />
61       </commandset>
62     `);
64     let editMenuCommandSetAll = fragment.querySelector(
65       "#editMenuCommandSetAll"
66     );
67     editMenuCommandSetAll.addEventListener("commandupdate", function() {
68       goUpdateGlobalEditMenuItems();
69     });
71     let editMenuCommandSetUndo = fragment.querySelector(
72       "#editMenuCommandSetUndo"
73     );
74     editMenuCommandSetUndo.addEventListener("commandupdate", function() {
75       goUpdateUndoEditMenuItems();
76     });
78     let editMenuCommandSetPaste = fragment.querySelector(
79       "#editMenuCommandSetPaste"
80     );
81     editMenuCommandSetPaste.addEventListener("commandupdate", function() {
82       goUpdatePasteMenuItems();
83     });
85     fragment.firstElementChild.addEventListener("command", event => {
86       let commandID = event.target.id;
87       goDoCommand(commandID);
88     });
90     container.appendChild(fragment);
91   },
92   { once: true }
95 // Support context menus on html textareas in the parent process:
96 window.addEventListener("contextmenu", e => {
97   const HTML_NS = "http://www.w3.org/1999/xhtml";
98   let needsContextMenu =
99     e.composedTarget.ownerDocument == document &&
100     !e.defaultPrevented &&
101     e.composedTarget.parentNode.nodeName != "moz-input-box" &&
102     ((["textarea", "input"].includes(e.composedTarget.localName) &&
103       e.composedTarget.namespaceURI == HTML_NS) ||
104       e.composedTarget.closest("search-textbox"));
106   if (!needsContextMenu) {
107     return;
108   }
110   let popup = document.getElementById("textbox-contextmenu");
111   if (!popup) {
112     MozXULElement.insertFTLIfNeeded("toolkit/global/textActions.ftl");
113     document.documentElement.appendChild(
114       MozXULElement.parseXULToFragment(`
115       <menupopup id="textbox-contextmenu" class="textbox-contextmenu">
116         <menuitem data-l10n-id="text-action-undo" command="cmd_undo"></menuitem>
117         <menuitem data-l10n-id="text-action-redo" command="cmd_redo"></menuitem>
118         <menuseparator></menuseparator>
119         <menuitem data-l10n-id="text-action-cut" command="cmd_cut"></menuitem>
120         <menuitem data-l10n-id="text-action-copy" command="cmd_copy"></menuitem>
121         <menuitem data-l10n-id="text-action-paste" command="cmd_paste"></menuitem>
122         <menuitem data-l10n-id="text-action-delete" command="cmd_delete"></menuitem>
123         <menuitem data-l10n-id="text-action-select-all" command="cmd_selectAll"></menuitem>
124       </menupopup>
125     `)
126     );
127     popup = document.documentElement.lastElementChild;
128   }
130   goUpdateGlobalEditMenuItems(true);
131   popup.openPopupAtScreen(e.screenX, e.screenY, true, e);
132   // Don't show any other context menu at the same time. There can be a
133   // context menu from an ancestor too but we only want to show this one.
134   e.preventDefault();