Bug 1586591 - Remove moz-input-box. r=desktop-theme-reviewers,tgiles,emilio

Thunderbird's compose window was the last consumer outside this repo; it moved off in bug 2066237, which has landed in comm-central.

The urlbar's a11y-checks exemption goes with it, since the wrapper no longer carries the combobox role that the check keyed on; the old searchbar still does.

Differential Revision: https://phabricator.services.mozilla.com/D321477
This commit is contained in:
Dão Gottwald
2026-09-11 14:01:21 +00:00
committed by dgottwald@mozilla.com
parent e33ac8a34a
commit b03a1a7a10
11 changed files with 6 additions and 353 deletions
@@ -669,9 +669,9 @@ export class MultilineEditor extends MozLitElement {
}
// TODO(Bug 2047067): right-clicks on the inner contenteditable show
// a native context menu on Windows whose Paste command does not
// reach ProseMirror. Forward the event to the host so moz-input-box
// can show its menu. Remove this workaround once the platform bug
// is fixed.
// reach ProseMirror. Forward the event to the host so it can show
// its own menu. Remove this workaround once the platform bug is
// fixed.
event.preventDefault();
const host = view.dom.getRootNode().host;
if (host && host != view.dom) {
+1 -2
View File
@@ -593,8 +593,7 @@ var gSearchResultsPane = {
Array.prototype.every.call(nodeObject.children, this._isAnchor)) ||
forceSearch ||
this.searchableNodes.has(nodeObject.localName) ||
(nodeObject.localName?.startsWith("moz-") &&
nodeObject.localName !== "moz-input-box"))
nodeObject.localName?.startsWith("moz-"))
) {
let simpleTextNodes = this.textNodeDescendants(nodeObject);
for (let node of simpleTextNodes) {
@@ -618,12 +618,9 @@ this.AccessibilityUtils = (function () {
return false;
}
let ariaRole = node.getAttribute("role");
// There are only two cases of this pattern: <moz-input-box> and <searchbar>
const isMozInputBox =
node.tagName == "moz-input-box" &&
node.classList.contains("urlbar-input-box");
// <searchbar> is the only case of this pattern.
const isSearchbar = node.tagName == "searchbar" && node.id == "searchbar";
return (isMozInputBox || isSearchbar) && ariaRole == "combobox";
return isSearchbar && ariaRole == "combobox";
}
/**
-1
View File
@@ -939,7 +939,6 @@
"chrome://global/content/elements/checkbox.js",
"chrome://global/content/elements/menu.js",
"chrome://global/content/elements/menupopup.js",
"chrome://global/content/elements/moz-input-box.js",
"chrome://global/content/elements/notificationbox.js",
"chrome://global/content/elements/panel.js",
"chrome://global/content/elements/popupnotification.js",
-4
View File
@@ -268,14 +268,10 @@ EditContextMenu.addItems({
// Support context menus on html textareas in the parent process:
window.addEventListener("contextmenu", e => {
const HTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_NS =
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let target = e.composedTarget;
let parent = target.parentNode;
let needsContextMenu =
target.ownerDocument == document &&
!e.defaultPrevented &&
!(parent.namespaceURI == XUL_NS && parent.localName == "moz-input-box") &&
["textarea", "input"].includes(target.localName) &&
target.namespaceURI == HTML_NS;
-1
View File
@@ -154,7 +154,6 @@ toolkit.jar:
content/global/elements/moz-page-nav.mjs (widgets/moz-page-nav/moz-page-nav.mjs)
content/global/elements/moz-five-star.css (widgets/moz-five-star/moz-five-star.css)
content/global/elements/moz-five-star.mjs (widgets/moz-five-star/moz-five-star.mjs)
content/global/elements/moz-input-box.js (widgets/moz-input-box.js)
content/global/elements/moz-label.css (widgets/moz-label/moz-label.css)
content/global/elements/moz-label.mjs (widgets/moz-label/moz-label.mjs)
content/global/elements/moz-message-bar.tokens.css (widgets/moz-message-bar/moz-message-bar.tokens.css)
@@ -256,8 +256,6 @@ skip-if = [
["test_mousescroll.xhtml"]
["test_mozinputbox_dictionary.xhtml"]
["test_named_deck.html"]
["test_navigate_persist.html"]
-2
View File
@@ -260,8 +260,6 @@ skip-if = [
["test_mousescroll.xhtml"]
["test_mozinputbox_dictionary.xhtml"]
["test_named_deck.html"]
["test_navigate_persist.html"]
@@ -1,104 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
XUL Widget Test for textbox with Add and Undo Add to Dictionary
-->
<window title="Textbox Add and Undo Add to Dictionary Test" width="500" height="600"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<linkset>
<html:link rel="localization" href="toolkit/global/textActions.ftl"/>
</linkset>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<hbox>
<moz-input-box id="t1" oncontextmenu="runContextMenuTest()" spellcheck="true">
<html:input class="textbox-input" value="Hellop" spellcheck="true"/>
</moz-input-box>
</hbox>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
var inputBox;
var testNum;
function bringUpContextMenu(element)
{
synthesizeMouseAtCenter(element, { type: "contextmenu", button: 2});
}
function leftClickElement(element)
{
synthesizeMouseAtCenter(element, { button: 0 });
}
var onSpellCheck;
function startTests()
{
inputBox = document.getElementById("t1");
inputBox._input.focus();
testNum = 0;
({onSpellCheck} = ChromeUtils.importESModule(
"resource://testing-common/AsyncSpellCheckTestHelper.sys.mjs"));
onSpellCheck(inputBox._input, function () {
bringUpContextMenu(inputBox);
});
}
function runContextMenuTest()
{
SimpleTest.executeSoon(function() {
var contextMenu = inputBox.menupopup;
switch(testNum)
{
case 0: // "Add to Dictionary" button
var addToDict = inputBox.getMenuItem("spell-add-to-dictionary");
ok(!addToDict.hidden, "Is Add to Dictionary visible?");
var separator = inputBox.getMenuItem("spell-suggestions-separator");
ok(!separator.hidden, "Is separator visible?");
addToDict.doCommand();
contextMenu.hidePopup();
testNum++;
onSpellCheck(inputBox._input, function () {
bringUpContextMenu(inputBox);
});
break;
case 1: // "Undo Add to Dictionary" button
var undoAddDict = inputBox.getMenuItem("spell-undo-add-to-dictionary");
ok(!undoAddDict.hidden, "Is Undo Add to Dictioanry visible?");
separator = inputBox.getMenuItem("spell-suggestions-separator");
ok(!separator.hidden, "Is separator hidden?");
undoAddDict.doCommand();
contextMenu.hidePopup();
onSpellCheck(inputBox._input, function () {
SimpleTest.finish();
});
break;
}
});
}
SimpleTest.waitForFocus(startTests);
]]></script>
</window>
-228
View File
@@ -1,228 +0,0 @@
/* 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/. */
"use strict";
// This is loaded into chrome windows with the subscript loader. Wrap in
// a block to prevent accidentally leaking globals onto `window`.
{
const cachedFragments = {
get editMenuItems() {
return `
<menuitem data-l10n-id="text-action-undo" cmd="cmd_undo"></menuitem>
<menuitem data-l10n-id="text-action-redo" cmd="cmd_redo"></menuitem>
<menuseparator></menuseparator>
<menuitem data-l10n-id="text-action-cut" cmd="cmd_cut"></menuitem>
<menuitem data-l10n-id="text-action-copy" cmd="cmd_copy"></menuitem>
<menuitem data-l10n-id="text-action-paste" cmd="cmd_paste"></menuitem>
<menuitem data-l10n-id="text-action-delete" cmd="cmd_delete"></menuitem>
<menuitem data-l10n-id="text-action-select-all" cmd="cmd_selectAll"></menuitem>
`;
},
get normal() {
delete this.normal;
this.normal = MozXULElement.parseXULToFragment(
`
<menupopup class="textbox-contextmenu" showservicesmenu="true">
${this.editMenuItems}
</menupopup>
`
);
MozXULElement.insertFTLIfNeeded("toolkit/global/textActions.ftl");
return this.normal;
},
get spellcheck() {
delete this.spellcheck;
this.spellcheck = MozXULElement.parseXULToFragment(
`
<menupopup class="textbox-contextmenu" showservicesmenu="true">
<menuitem data-l10n-id="text-action-spell-no-suggestions" anonid="spell-no-suggestions" disabled="true"></menuitem>
<menuitem data-l10n-id="text-action-spell-add-to-dictionary" anonid="spell-add-to-dictionary" oncommand="this.parentNode.parentNode.spellCheckerUI.addToDictionary();"></menuitem>
<menuitem data-l10n-id="text-action-spell-undo-add-to-dictionary" anonid="spell-undo-add-to-dictionary" oncommand="this.parentNode.parentNode.spellCheckerUI.undoAddToDictionary();"></menuitem>
<menuseparator anonid="spell-suggestions-separator"></menuseparator>
${this.editMenuItems}
<menuseparator anonid="spell-check-separator"></menuseparator>
<menuitem data-l10n-id="text-action-spell-check-toggle" type="checkbox" anonid="spell-check-enabled" oncommand="this.parentNode.parentNode.spellCheckerUI.toggleEnabled();"></menuitem>
<menu data-l10n-id="text-action-spell-dictionaries" anonid="spell-dictionaries">
<menupopup anonid="spell-dictionaries-menu" onpopupshowing="event.stopPropagation();" onpopuphiding="event.stopPropagation();"></menupopup>
</menu>
</menupopup>
`
);
return this.spellcheck;
},
};
class MozInputBox extends MozXULElement {
static get observedAttributes() {
return ["spellcheck"];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "spellcheck" && oldValue != newValue) {
this._initUI();
}
}
connectedCallback() {
this._initUI();
}
_initUI() {
this.spellcheck = this.hasAttribute("spellcheck");
if (this.menupopup) {
this.menupopup.remove();
}
this.setAttribute("context", "_child");
this.appendChild(
this.spellcheck
? cachedFragments.spellcheck.cloneNode(true)
: cachedFragments.normal.cloneNode(true)
);
this.menupopup = this.querySelector(".textbox-contextmenu");
this.menupopup.addEventListener("popupshowing", event => {
let input = this._input;
if (document.commandDispatcher.focusedElement != input) {
input.focus();
}
this._doPopupItemEnabling(event);
});
if (this.spellcheck) {
this.menupopup.addEventListener("popuphiding", () => {
if (this.spellCheckerUI) {
this.spellCheckerUI.clearSuggestionsFromMenu();
this.spellCheckerUI.clearDictionaryListFromMenu();
}
});
}
this.menupopup.addEventListener("command", event => {
var cmd = event.originalTarget.getAttribute("cmd");
if (cmd) {
this.doCommand(cmd);
event.stopPropagation();
}
});
this.dispatchEvent(
new CustomEvent("moz-input-box-rebuilt", {
bubbles: true,
composed: false,
})
);
}
_doPopupItemEnablingSpell(event) {
var spellui = this.spellCheckerUI;
if (!spellui || !spellui.canSpellCheck) {
this._setMenuItemVisibility("spell-no-suggestions", false);
this._setMenuItemVisibility("spell-check-enabled", false);
this._setMenuItemVisibility("spell-check-separator", false);
this._setMenuItemVisibility("spell-add-to-dictionary", false);
this._setMenuItemVisibility("spell-undo-add-to-dictionary", false);
this._setMenuItemVisibility("spell-suggestions-separator", false);
this._setMenuItemVisibility("spell-dictionaries", false);
return;
}
spellui.initFromEvent(event.rangeParent, event.rangeOffset);
var enabled = spellui.enabled;
var showUndo = spellui.canSpellCheck && spellui.canUndo();
var enabledCheckbox = this.getMenuItem("spell-check-enabled");
enabledCheckbox.toggleAttribute("checked", enabled);
var overMisspelling = spellui.overMisspelling;
this._setMenuItemVisibility("spell-add-to-dictionary", overMisspelling);
this._setMenuItemVisibility("spell-undo-add-to-dictionary", showUndo);
this._setMenuItemVisibility(
"spell-suggestions-separator",
overMisspelling || showUndo
);
// suggestion list
var suggestionsSeparator = this.getMenuItem("spell-no-suggestions");
var numsug = spellui.addSuggestionsToMenuOnParent(
event.target,
suggestionsSeparator,
5
);
this._setMenuItemVisibility(
"spell-no-suggestions",
overMisspelling && numsug == 0
);
// dictionary list
var dictionariesMenu = this.getMenuItem("spell-dictionaries-menu");
var numdicts = spellui.addDictionaryListToMenu(dictionariesMenu, null);
this._setMenuItemVisibility(
"spell-dictionaries",
enabled && numdicts > 1
);
}
_doPopupItemEnabling(event) {
if (this.spellcheck) {
this._doPopupItemEnablingSpell(event);
}
let popupNode = event.target;
var children = popupNode.childNodes;
for (var i = 0; i < children.length; i++) {
var command = children[i].getAttribute("cmd");
if (command) {
var controller =
document.commandDispatcher.getControllerForCommand(command);
var enabled = controller.isCommandEnabled(command);
if (enabled) {
children[i].removeAttribute("disabled");
} else {
children[i].setAttribute("disabled", "true");
}
}
}
}
get spellCheckerUI() {
if (!this._spellCheckInitialized) {
this._spellCheckInitialized = true;
try {
const { InlineSpellChecker } = ChromeUtils.importESModule(
"resource://gre/modules/InlineSpellChecker.sys.mjs"
);
this.InlineSpellCheckerUI = new InlineSpellChecker(
this._input.editor
);
} catch (ex) {}
}
return this.InlineSpellCheckerUI;
}
getMenuItem(anonid) {
return this.querySelector(`[anonid="${anonid}"]`);
}
_setMenuItemVisibility(anonid, visible) {
this.getMenuItem(anonid).hidden = !visible;
}
doCommand(command) {
var controller =
document.commandDispatcher.getControllerForCommand(command);
controller.doCommand(command);
}
get _input() {
return this.querySelector(".textbox-input");
}
}
customElements.define("moz-input-box", MozInputBox);
}
-1
View File
@@ -121,7 +121,6 @@ h3 {
/* General styles */
moz-input-box,
html|input {
min-width: 0;
}