Bug 1513325 - Remove textbox binding. r=emilio,dao
authorTim Nguyen <ntim.bugs@gmail.com>
Wed, 09 Oct 2019 09:27:28 +0000
changeset 496930 59f0469f5a486ddea7543100b3f335706b072955
parent 496929 96917f5eb072c52c4a9d005d40123d8af1b1354f
child 496931 3a4012655a64037ce150dadaf10e6a77059f2c9e
push id36671
push usershindli@mozilla.com
push dateWed, 09 Oct 2019 16:04:03 +0000
treeherdermozilla-central@0efb4f268d16 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio, dao
bugs1513325
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1513325 - Remove textbox binding. r=emilio,dao Differential Revision: https://phabricator.services.mozilla.com/D38955
accessible/base/XULMap.h
accessible/tests/mochitest/events/test_focus_general.xul
accessible/tests/mochitest/relations/test_general.xul
browser/components/customizableui/PanelMultiView.jsm
browser/components/preferences/connection.js
browser/themes/windows/preferences/in-content-new/preferences.css
devtools/client/shared/SplitView.jsm
devtools/client/storage/ui.js
dom/base/Element.cpp
dom/base/nsFocusManager.cpp
dom/l10n/L10nOverlays.cpp
dom/xul/nsXULElement.cpp
dom/xul/nsXULElement.h
layout/xul/nsBoxFrame.cpp
toolkit/content/editMenuOverlay.js
toolkit/content/jar.mn
toolkit/content/preferencesBindings.js
toolkit/content/widgets/textbox.xml
toolkit/content/xul.css
toolkit/themes/linux/global/autocomplete.css
toolkit/themes/linux/global/global.css
toolkit/themes/linux/global/textbox.css
toolkit/themes/osx/global/autocomplete.css
toolkit/themes/osx/global/global.css
toolkit/themes/osx/global/textbox.css
toolkit/themes/shared/in-content/common.inc.css
toolkit/themes/windows/global/autocomplete.css
toolkit/themes/windows/global/global.css
toolkit/themes/windows/global/textbox.css
--- a/accessible/base/XULMap.h
+++ b/accessible/base/XULMap.h
@@ -77,20 +77,16 @@ XULMAP(panel, [](Element* aElement, Acce
 
   return new EnumRoleAccessible<roles::PANE>(aElement, aContext->Document());
 })
 
 XULMAP(popup, [](Element* aElement, Accessible* aContext) {
   return CreateMenupopupAccessible(aElement, aContext);
 })
 
-XULMAP(textbox, [](Element* aElement, Accessible* aContext) -> Accessible* {
-  return new EnumRoleAccessible<roles::SECTION>(aElement, aContext->Document());
-})
-
 XULMAP(tree, [](Element* aElement, Accessible* aContext) -> Accessible* {
   nsIContent* child =
       nsTreeUtils::GetDescendantChild(aElement, nsGkAtoms::treechildren);
   if (!child) return nullptr;
 
   nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame());
   if (!treeFrame) return nullptr;
 
--- a/accessible/tests/mochitest/events/test_focus_general.xul
+++ b/accessible/tests/mochitest/events/test_focus_general.xul
@@ -1,14 +1,15 @@
 <?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"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         title="Accessible focus event testing">
 
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
@@ -24,17 +25,17 @@
 
     var gQueue = null;
     function doTests()
     {
       // Test focus events.
       gQueue = new eventQueue();
 
       gQueue.push(new synthFocus("textbox",
-                                 new focusChecker(getNode("textbox").inputField)));
+                                 new focusChecker(getNode("textbox"))));
       gQueue.push(new synthFocusOnFrame("editabledoc"));
       gQueue.push(new synthFocus("radioclothes",
                                  new focusChecker("radiosweater")));
       gQueue.push(new synthDownKey("radiosweater",
                                    new focusChecker("radiojacket")));
       gQueue.push(new synthFocus("checkbox"));
       gQueue.push(new synthFocus("button"));
       gQueue.push(new synthFocus("checkbutton"));
@@ -78,17 +79,17 @@
       </a>
       <p id="display"></p>
       <div id="content" style="display: none"></div>
       <pre id="test">
       </pre>
     </body>
 
     <vbox flex="1">
-      <textbox id="textbox" value="hello"/>
+      <html:input id="textbox" value="hello"/>
       <iframe id="editabledoc" src="focus.html"/>
       <radiogroup id="radioclothes">
         <radio id="radiosweater" label="radiosweater"/>
         <radio id="radiocap" label="radiocap" disabled="true"/>
         <radio id="radiojacket" label="radiojacket"/>
       </radiogroup>
       <checkbox id="checkbox" label="checkbox"/>
       <button id="button" label="button"/>
--- a/accessible/tests/mochitest/relations/test_general.xul
+++ b/accessible/tests/mochitest/relations/test_general.xul
@@ -94,19 +94,16 @@
       testRelation("flowto", RELATION_FLOWS_TO, "flowfrom");
       testRelation("flowfrom", RELATION_FLOWS_FROM, "flowto");
 
       // aria-flowto, multiple relations
       testRelation("flowto1", RELATION_FLOWS_TO, ["flowfrom1", "flowfrom2"]);
       testRelation("flowfrom1", RELATION_FLOWS_FROM, "flowto1");
       testRelation("flowfrom2", RELATION_FLOWS_FROM, "flowto1");
 
-      // 'default button' relation
-      testRelation("textbox", RELATION_DEFAULT_BUTTON, "submit");
-
       // 'labelled by'/'label for' relation for xul:groupbox and xul:label
       var groupboxAcc = getAccessible("groupbox");
       var labelAcc = groupboxAcc.firstChild;
       testRelation(labelAcc, RELATION_LABEL_FOR, groupboxAcc);
       testRelation(groupboxAcc, RELATION_LABELLED_BY, labelAcc);
 
       // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
       // (fixed in bug 366527)
@@ -200,19 +197,16 @@
 
     <description id="flowto1" aria-flowto="flowfrom1 flowfrom2">flow to</description>
     <description id="flowfrom1">flow from</description>
     <description id="flowfrom2">flow from</description>
 
     <description id="flowto" aria-flowto="flowfrom">flow to</description>
     <description id="flowfrom">flow from</description>
 
-    <textbox id="textbox"/>
-    <button id="submit" default="true" label="Default"/>
-
     <groupbox id="groupbox">
       <label value="caption"/>
     </groupbox>
 
     <tabbox>
       <tabs>
         <tab label="tab1" id="tab1"/>
         <tab label="tab2" id="tab2" linkedpanel="tabpanel2"/>
@@ -228,9 +222,8 @@
         <tabpanel id="tabpanel2">
           <description>tabpanel2</description>
         </tabpanel>
       </tabpanels>
     </tabbox>
 
  </vbox>
 </window>
-
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -1514,17 +1514,16 @@ var PanelView = class extends Associated
   /**
    * Determine whether an element can only be navigated to with tab/shift+tab,
    * not the arrow keys.
    */
   _isNavigableWithTabOnly(element) {
     let tag = element.localName;
     return (
       tag == "menulist" ||
-      tag == "textbox" ||
       tag == "input" ||
       tag == "textarea" ||
       // Allow tab to reach embedded documents.
       tag == "browser" ||
       tag == "iframe"
     );
   }
 
--- a/browser/components/preferences/connection.js
+++ b/browser/components/preferences/connection.js
@@ -365,17 +365,16 @@ var gConnectionsDialog = {
     return undefined;
   },
 
   getProxyControls() {
     let controlGroup = document.getElementById("networkProxyType");
     return [
       ...controlGroup.querySelectorAll(":scope > radio"),
       ...controlGroup.querySelectorAll("label"),
-      ...controlGroup.querySelectorAll("textbox"),
       ...controlGroup.querySelectorAll("checkbox"),
       ...document.querySelectorAll("#networkProxySOCKSVersion > radio"),
       ...document.querySelectorAll("#ConnectionsDialogPane > checkbox"),
     ];
   },
 
   // Update the UI to show/hide the extension controlled message for
   // proxy settings.
--- a/browser/themes/windows/preferences/in-content-new/preferences.css
+++ b/browser/themes/windows/preferences/in-content-new/preferences.css
@@ -2,14 +2,8 @@
    - 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/. */
 
 %include ../../../shared/incontentprefs/preferences.inc.css
 
 .actionsMenu > .menulist-label-box > .menulist-icon {
   margin-inline-end: 9px;
 }
-
-textbox + button {
-  margin-inline-start: -4px;
-  margin-top: 4px;
-  margin-bottom: 4px;
-}
--- a/devtools/client/shared/SplitView.jsm
+++ b/devtools/client/shared/SplitView.jsm
@@ -45,17 +45,16 @@ this.SplitView = function SplitView(aRoo
       }
       return node;
     }
 
     // do not steal focus from inside iframes or textboxes
     if (
       aEvent.target.ownerDocument != this._nav.ownerDocument ||
       aEvent.target.tagName == "input" ||
-      aEvent.target.tagName == "textbox" ||
       aEvent.target.tagName == "textarea" ||
       aEvent.target.classList.contains("textbox")
     ) {
       return false;
     }
 
     // handle keyboard navigation within the items list
     let newFocusOrdinal;
--- a/devtools/client/storage/ui.js
+++ b/devtools/client/storage/ui.js
@@ -1273,20 +1273,17 @@ class StorageUI {
         // Stop Propagation to prevent opening up of split console
         event.stopPropagation();
         event.preventDefault();
       }
     } else if (
       event.keyCode == KeyCodes.DOM_VK_BACK_SPACE ||
       event.keyCode == KeyCodes.DOM_VK_DELETE
     ) {
-      if (
-        this.table.selectedRow &&
-        !["input", "textbox"].includes(event.target.localName)
-      ) {
+      if (this.table.selectedRow && event.target.localName != "input") {
         this.onRemoveItem();
         event.stopPropagation();
         event.preventDefault();
       }
     }
   }
 
   /**
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -522,34 +522,18 @@ void Element::ClearStyleStateLocks() {
   DeleteProperty(nsGkAtoms::lockedStyleStates);
   ClearHasLockedStyleStates();
 
   NotifyStyleStateChange(locks.mLocks);
 }
 
 #ifdef MOZ_XBL
 static bool MayNeedToLoadXBLBinding(const Element& aElement) {
-  if (!aElement.IsAnyOfXULElements(nsGkAtoms::textbox)) {
-    // Other elements no longer have XBL bindings. Please don't add to the list
-    // above unless completely necessary.
-    return false;
-  }
-  if (!aElement.IsInComposedDoc()) {
-    return false;
-  }
-  // If we have a frame, the frame has already loaded the binding.
-  if (aElement.GetPrimaryFrame() || !aElement.OwnerDoc()->GetPresShell()) {
-    return false;
-  }
-  // If we have a binding, well..
-  if (aElement.GetXBLBinding()) {
-    return false;
-  }
-  // We need to try.
-  return true;
+  // Clean this up in https://bugzilla.mozilla.org/show_bug.cgi?id=1585823
+  return false;
 }
 #endif
 
 JSObject* Element::WrapObject(JSContext* aCx,
                               JS::Handle<JSObject*> aGivenProto) {
   JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
   if (!obj) {
     return nullptr;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -332,27 +332,22 @@ Element* nsFocusManager::GetRedirectedFo
             numberControlFrame->GetAnonTextControl();
         return textControl;
       }
     }
   }
 
 #ifdef MOZ_XUL
   if (aContent->IsXULElement()) {
-    if (aContent->IsXULElement(nsGkAtoms::textbox)) {
-      return aContent->OwnerDoc()->GetAnonymousElementByAttribute(
-          aContent, nsGkAtoms::anonid, NS_LITERAL_STRING("input"));
-    } else {
-      nsCOMPtr<nsIDOMXULMenuListElement> menulist =
-          aContent->AsElement()->AsXULMenuList();
-      if (menulist) {
-        RefPtr<Element> inputField;
-        menulist->GetInputField(getter_AddRefs(inputField));
-        return inputField;
-      }
+    nsCOMPtr<nsIDOMXULMenuListElement> menulist =
+        aContent->AsElement()->AsXULMenuList();
+    if (menulist) {
+      RefPtr<Element> inputField;
+      menulist->GetInputField(getter_AddRefs(inputField));
+      return inputField;
     }
   }
 #endif
 
   return nullptr;
 }
 
 // static
--- a/dom/l10n/L10nOverlays.cpp
+++ b/dom/l10n/L10nOverlays.cpp
@@ -94,19 +94,16 @@ bool L10nOverlays::IsAttrNameLocalizable
       return nameAtom == nsGkAtoms::value;
     }
     if (elemName == nsGkAtoms::key) {
       return nameAtom == nsGkAtoms::key || nameAtom == nsGkAtoms::keycode;
     }
     if (elemName == nsGkAtoms::label) {
       return nameAtom == nsGkAtoms::value;
     }
-    if (elemName == nsGkAtoms::textbox) {
-      return nameAtom == nsGkAtoms::placeholder || nameAtom == nsGkAtoms::value;
-    }
   }
 
   return false;
 }
 
 already_AddRefed<nsINode> L10nOverlays::CreateTextNodeFromTextContent(
     Element* aElement, ErrorResult& aRv) {
   nsAutoString content;
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -104,22 +104,16 @@ uint32_t nsXULPrototypeAttribute::gNumCa
 
 //----------------------------------------------------------------------
 // nsXULElement
 //
 
 nsXULElement::nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : nsStyledElement(std::move(aNodeInfo)), mBindingParent(nullptr) {
   XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
-
-  // We may be READWRITE by default; check.
-  if (IsReadWriteTextElement()) {
-    AddStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
-    RemoveStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
-  }
 }
 
 nsXULElement::~nsXULElement() {}
 
 void nsXULElement::MaybeUpdatePrivateLifetime() {
   if (AttrValueIs(kNameSpaceID_None, nsGkAtoms::windowtype,
                   NS_LITERAL_STRING("navigator:browser"), eCaseMatters)) {
     return;
@@ -520,18 +514,17 @@ bool nsXULElement::PerformAccesskey(bool
           fm->SetFocus(elementToFocus, nsIFocusManager::FLAG_BYKEY);
 
           // Return true if the element became focused.
           nsPIDOMWindowOuter* window = OwnerDoc()->GetWindow();
           focused = (window && window->GetFocusedElement());
         }
       }
     }
-    if (aKeyCausesActivation &&
-        !content->IsAnyOfXULElements(nsGkAtoms::textbox, nsGkAtoms::menulist)) {
+    if (aKeyCausesActivation && !content->IsXULElement(nsGkAtoms::menulist)) {
       elm->ClickWithInputSource(MouseEvent_Binding::MOZ_SOURCE_KEYBOARD,
                                 aIsTrustedEvent);
     }
   } else {
     return content->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent);
   }
 
   return focused;
@@ -1187,27 +1180,16 @@ nsresult nsXULElement::AddPopupListener(
                                     TrustedEventsAtSystemGroupBubble());
   } else {
     manager->AddEventListenerByType(listener, NS_LITERAL_STRING("mousedown"),
                                     TrustedEventsAtSystemGroupBubble());
   }
   return NS_OK;
 }
 
-EventStates nsXULElement::IntrinsicState() const {
-  EventStates state = nsStyledElement::IntrinsicState();
-
-  if (IsReadWriteTextElement()) {
-    state |= NS_EVENT_STATE_MOZ_READWRITE;
-    state &= ~NS_EVENT_STATE_MOZ_READONLY;
-  }
-
-  return state;
-}
-
 //----------------------------------------------------------------------
 
 nsresult nsXULElement::MakeHeavyweight(nsXULPrototypeElement* aPrototype) {
   if (!aPrototype) {
     return NS_OK;
   }
 
   size_t i;
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -356,17 +356,16 @@ class nsXULElement : public nsStyledElem
                                    bool aWithMouse) override;
 
   virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
                                               int32_t aModType) const override;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo*,
                          nsINode** aResult) const override;
-  virtual mozilla::EventStates IntrinsicState() const override;
 
   virtual void RecompileScriptEventListeners() override;
 
   // This function should ONLY be used by BindToTree implementations.
   // The function exists solely because XUL elements store the binding
   // parent as a member instead of in the slots, as Element does.
   void SetXULBindingParent(Element* aBindingParent) {
     mBindingParent = aBindingParent;
@@ -603,21 +602,16 @@ class nsXULElement : public nsStyledElem
                                    const nsAString* aIs);
   friend void NS_TrustedNewXULElement(mozilla::dom::Element** aResult,
                                       mozilla::dom::NodeInfo* aNodeInfo);
 
   static already_AddRefed<nsXULElement> CreateFromPrototype(
       nsXULPrototypeElement* aPrototype, mozilla::dom::NodeInfo* aNodeInfo,
       bool aIsScriptable, bool aIsRoot);
 
-  bool IsReadWriteTextElement() const {
-    return IsAnyOfXULElements(nsGkAtoms::textbox, nsGkAtoms::textarea) &&
-           !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
-  }
-
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aGivenProto) override;
 
   void MaybeUpdatePrivateLifetime();
 
   bool IsEventStoppedFromAnonymousScrollbar(mozilla::EventMessage aMessage);
 
   MOZ_CAN_RUN_SCRIPT
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -1140,18 +1140,18 @@ nsresult nsBoxFrame::GetFrameName(nsAStr
 
 // If you make changes to this function, check its counterparts
 // in nsTextBoxFrame and nsXULLabelFrame
 void nsBoxFrame::RegUnregAccessKey(bool aDoReg) {
   MOZ_ASSERT(mContent);
 
   // only support accesskeys for the following elements
   if (!mContent->IsAnyOfXULElements(nsGkAtoms::button, nsGkAtoms::toolbarbutton,
-                                    nsGkAtoms::checkbox, nsGkAtoms::textbox,
-                                    nsGkAtoms::tab, nsGkAtoms::radio)) {
+                                    nsGkAtoms::checkbox, nsGkAtoms::tab,
+                                    nsGkAtoms::radio)) {
     return;
   }
 
   nsAutoString accessKey;
   mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey,
                                  accessKey);
 
   if (accessKey.IsEmpty()) return;
--- a/toolkit/content/editMenuOverlay.js
+++ b/toolkit/content/editMenuOverlay.js
@@ -90,18 +90,16 @@ window.addEventListener(
     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";
-  // Note that there's not a risk of e.target being XBL anonymous content for <textbox> (which manages
-  // its own context menu), because e.target will be the XBL binding parent in that case.
   let needsContextMenu =
     e.target.ownerDocument == document &&
     !e.defaultPrevented &&
     e.target.parentNode.nodeName != "moz-input-box" &&
     ((["textarea", "input"].includes(e.target.localName) &&
       e.target.namespaceURI == HTML_NS) ||
       e.target.closest("search-textbox"));
 
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -61,17 +61,16 @@ toolkit.jar:
    content/global/viewZoomOverlay.js
 #endif
    content/global/widgets.css
    content/global/bindings/calendar.js         (widgets/calendar.js)
    content/global/bindings/datekeeper.js       (widgets/datekeeper.js)
    content/global/bindings/datepicker.js       (widgets/datepicker.js)
    content/global/bindings/datetimebox.css     (widgets/datetimebox.css)
    content/global/bindings/spinner.js          (widgets/spinner.js)
-   content/global/bindings/textbox.xml         (widgets/textbox.xml)
    content/global/bindings/timekeeper.js       (widgets/timekeeper.js)
    content/global/bindings/timepicker.js       (widgets/timepicker.js)
    content/global/elements/autocomplete-input.js              (widgets/autocomplete-input.js)
    content/global/elements/autocomplete-popup.js              (widgets/autocomplete-popup.js)
    content/global/elements/autocomplete-richlistitem.js       (widgets/autocomplete-richlistitem.js)
    content/global/elements/browser-custom-element.js          (widgets/browser-custom-element.js)
    content/global/elements/button.js           (widgets/button.js)
    content/global/elements/checkbox.js         (widgets/checkbox.js)
--- a/toolkit/content/preferencesBindings.js
+++ b/toolkit/content/preferencesBindings.js
@@ -436,23 +436,16 @@ const Preferences = (window.Preferences 
             element.removeAttribute(attribute);
           }
         } else {
           element.setAttribute(attribute, value);
         }
       }
       if (aElement.localName == "checkbox") {
         setValue(aElement, "checked", val);
-      } else if (aElement.localName == "textbox") {
-        // XXXmano Bug 303998: Avoid a caret placement issue if either the
-        // preference observer or its setter calls updateElements as a result
-        // of the input event handler.
-        if (aElement.value !== val) {
-          setValue(aElement, "value", val);
-        }
       } else {
         setValue(aElement, "value", val);
       }
     }
 
     getElementValue(aElement) {
       if (Preferences._syncToPrefListeners.has(aElement)) {
         try {
@@ -494,17 +487,16 @@ const Preferences = (window.Preferences 
     }
 
     isElementEditable(aElement) {
       switch (aElement.localName) {
         case "checkbox":
         case "input":
         case "radiogroup":
         case "textarea":
-        case "textbox":
         case "menulist":
           return true;
       }
       return false;
     }
 
     updateElements() {
       if (!this.id) {
deleted file mode 100644
--- a/toolkit/content/widgets/textbox.xml
+++ /dev/null
@@ -1,198 +0,0 @@
-<?xml version="1.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/. -->
-
-<!-- This files relies on these specific Chrome/XBL globals -->
-<!-- globals ChromeWindow -->
-
-
-<!DOCTYPE bindings [
-  <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
-  %textcontextDTD;
-]>
-
-<bindings id="textboxBindings"
-   xmlns="http://www.mozilla.org/xbl"
-   xmlns:html="http://www.w3.org/1999/xhtml"
-   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   xmlns:xbl="http://www.mozilla.org/xbl">
-
-  <binding id="textbox">
-    <content>
-      <children/>
-      <xul:moz-input-box anonid="moz-input-box" flex="1" xbl:inherits="context,spellcheck">
-        <html:input class="textbox-input" anonid="input"
-                    xbl:inherits="value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,noinitialfocus,mozactionhint,spellcheck"/>
-      </xul:moz-input-box>
-    </content>
-
-    <implementation>
-      <!-- nsIDOMXULLabeledControlElement -->
-      <field name="crop">""</field>
-      <field name="image">""</field>
-      <field name="command">""</field>
-      <field name="accessKey">""</field>
-
-      <field name="mInputField">null</field>
-      <field name="mIgnoreClick">false</field>
-      <field name="mEditor">null</field>
-
-      <property name="inputField" readonly="true">
-        <getter><![CDATA[
-          if (!this.mInputField)
-            this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input");
-          return this.mInputField;
-        ]]></getter>
-      </property>
-
-      <property name="value"      onset="this.inputField.value = val; return val;"
-                                  onget="return this.inputField.value;"/>
-      <property name="defaultValue" onset="this.inputField.defaultValue = val; return val;"
-                                  onget="return this.inputField.defaultValue;"/>
-      <property name="label"      onset="this.setAttribute('label', val); return val;"
-                                  onget="return this.getAttribute('label') || this.placeholder;" />
-      <property name="placeholder" onset="this.inputField.placeholder = val; return val;"
-                                  onget="return this.inputField.placeholder;"/>
-      <property name="emptyText"  onset="this.placeholder = val; return val;"
-                                  onget="return this.placeholder;"/>
-      <property name="type"       onset="if (val) this.setAttribute('type', val);
-                                         else this.removeAttribute('type'); return val;"
-                                  onget="return this.getAttribute('type');"/>
-      <property name="maxLength"  onset="this.inputField.maxLength = val; return val;"
-                                  onget="return this.inputField.maxLength;"/>
-      <property name="disabled"   onset="this.inputField.disabled = val;
-                                         if (val) this.setAttribute('disabled', 'true');
-                                         else this.removeAttribute('disabled'); return val;"
-                                  onget="return this.inputField.disabled;"/>
-      <property name="tabIndex"   onget="return parseInt(this.getAttribute('tabindex'));"
-                                  onset="this.inputField.tabIndex = val;
-                                         if (val) this.setAttribute('tabindex', val);
-                                         else this.removeAttribute('tabindex'); return val;"/>
-      <property name="size"       onset="this.inputField.size = val; return val;"
-                                  onget="return this.inputField.size;"/>
-      <property name="readOnly"   onset="this.inputField.readOnly = val;
-                                         if (val) this.setAttribute('readonly', 'true');
-                                         else this.removeAttribute('readonly'); return val;"
-                                  onget="return this.inputField.readOnly;"/>
-
-      <property name="editor" readonly="true">
-        <getter><![CDATA[
-          if (!this.mEditor) {
-            this.mEditor = this.inputField.editor;
-          }
-          return this.mEditor;
-        ]]></getter>
-      </property>
-
-      <method name="reset">
-        <body><![CDATA[
-          this.value = this.defaultValue;
-          try {
-            this.editor.transactionManager.clear();
-            return true;
-          } catch (e) {}
-          return false;
-        ]]></body>
-      </method>
-
-      <method name="select">
-        <body>
-          this.inputField.select();
-        </body>
-      </method>
-
-      <method name="setUserInput">
-        <parameter name="value"/>
-        <body><![CDATA[
-          this.inputField.setUserInput(value);
-        ]]></body>
-      </method>
-
-      <property name="controllers"    readonly="true" onget="return this.inputField.controllers"/>
-      <property name="textLength"     readonly="true"
-                                      onget="return this.inputField.textLength;"/>
-      <property name="selectionStart" onset="this.inputField.selectionStart = val; return val;"
-                                      onget="return this.inputField.selectionStart;"/>
-      <property name="selectionEnd"   onset="this.inputField.selectionEnd = val; return val;"
-                                      onget="return this.inputField.selectionEnd;"/>
-
-      <method name="setSelectionRange">
-        <parameter name="aSelectionStart"/>
-        <parameter name="aSelectionEnd"/>
-        <body>
-          // According to https://html.spec.whatwg.org/#do-not-apply,
-          // setSelectionRange() is only available on a limited set of input types.
-          if (this.inputField.type == "text") {
-            this.inputField.setSelectionRange( aSelectionStart, aSelectionEnd );
-          }
-        </body>
-      </method>
-
-      <constructor><![CDATA[
-        var str = this._cachedInputFieldValue;
-        if (str) {
-          this.inputField.value = str;
-          delete this._cachedInputFieldValue;
-        }
-
-        if (this.hasAttribute("emptytext"))
-          this.placeholder = this.getAttribute("emptytext");
-      ]]></constructor>
-
-      <destructor>
-        <![CDATA[
-          var field = this.inputField;
-          if (field && field.value) {
-            this._cachedInputFieldValue = field.value;
-          }
-
-          this.mInputField = null;
-        ]]>
-      </destructor>
-
-    </implementation>
-
-    <handlers>
-      <handler event="focus" phase="capturing">
-        <![CDATA[
-          if (this.hasAttribute("focused"))
-            return;
-
-          switch (event.originalTarget) {
-            case this:
-              // Forward focus to actual HTML input
-              this.inputField.focus();
-              this.setAttribute("focused", "true");
-              break;
-            case this.inputField:
-              this.setAttribute("focused", "true");
-              break;
-            default:
-              // Otherwise, allow other children (e.g. URL bar buttons) to get focus
-              break;
-          }
-        ]]>
-      </handler>
-
-      <handler event="blur" phase="capturing">
-        <![CDATA[
-          this.removeAttribute("focused");
-        ]]>
-      </handler>
-
-      <handler event="mousedown">
-        <![CDATA[
-          this.mIgnoreClick = this.hasAttribute("focused");
-
-          if (!this.mIgnoreClick) {
-            this.setSelectionRange(0, 0);
-            if (event.originalTarget == this ||
-                event.originalTarget == this.inputField.parentNode)
-              this.inputField.focus();
-          }
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
-</bindings>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -429,18 +429,17 @@ tooltip[titletip="true"] {
   -moz-box-orient: inherit;
   -moz-box-pack: inherit;
   -moz-box-align: inherit;
   -moz-box-direction: inherit;
 }
 
 /********** textbox **********/
 
-textbox {
-  -moz-binding: url("chrome://global/content/bindings/textbox.xml#textbox");
+search-textbox {
   -moz-user-select: text;
   text-shadow: none;
 }
 
 /* Prefix with (xul|*):root to workaround HTML tests loading xul.css */
 :root html|textarea:not([resizable="true"]) {
   resize: none;
 }
@@ -448,20 +447,16 @@ textbox {
 @supports -moz-bool-pref("layout.css.emulate-moz-box-with-flex") {
   html|*.textbox-input {
     /* Be block-level, so that -moz-box-flex can take effect, when we are an item
        in a -moz-box being emulated by modified modern flex. */
     display: block;
   }
 }
 
-.textbox-contextmenu:-moz-locale-dir(rtl) {
-  direction: rtl;
-}
-
 /********** autocomplete textbox **********/
 
 /* SeaMonkey uses its own autocomplete and the toolkit's autocomplete widget */
 %ifndef MOZ_SUITE
 
 panel[type="autocomplete-richlistbox"] {
   -moz-binding: none;
 }
--- a/toolkit/themes/linux/global/autocomplete.css
+++ b/toolkit/themes/linux/global/autocomplete.css
@@ -100,15 +100,8 @@ html|span.ac-tag {
 .ac-tags-text,
 .ac-separator-text,
 .ac-url-text,
 .ac-action-text,
 .ac-text-overflow-container {
   padding: 0 !important;
   margin: 0 !important;
 }
-
-/* ::::: textboxes inside toolbarpaletteitems ::::: */
-
-toolbarpaletteitem > toolbaritem > textbox > moz-input-box > html|*.textbox-input,
-toolbarpaletteitem > toolbaritem > * > textbox > moz-input-box > html|*.textbox-input {
-  visibility: hidden;
-}
--- a/toolkit/themes/linux/global/global.css
+++ b/toolkit/themes/linux/global/global.css
@@ -211,17 +211,17 @@ xul|label[disabled="true"] {
   text-decoration: underline;
 }
 
 .text-link:-moz-focusring {
   outline: 1px dotted;
 }
 
 html|input {
-  margin: 2px 4px; /* matches xul <textbox> default margin */
+  margin: 2px 4px;
 }
 
 xul|notification > xul|hbox > xul|button {
   margin-top: 0;
   margin-bottom: 0;
 }
 
 xul|popupnotificationcontent {
--- a/toolkit/themes/linux/global/textbox.css
+++ b/toolkit/themes/linux/global/textbox.css
@@ -1,26 +1,25 @@
 /* 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/. */
 
 /* ===== textbox.css ==================================================
-  == Styles used by the XUL textbox element.
+  == Styles used by the XUL search-textbox element.
   ======================================================================= */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
-/* ::::: textbox ::::: */
+/* ::::: search textbox ::::: */
 
-textbox,
 search-textbox {
   -moz-appearance: textfield;
   cursor: text;
-  margin: 2px 4px;
+  margin: 2px 4px; /* matches <input> global.css margin */
   padding: 2px 2px 3px;
   padding-inline-start: 4px;
   background-color: -moz-Field;
   color: -moz-FieldText;
 }
 
 html|*.textbox-input {
   -moz-appearance: none;
@@ -31,54 +30,42 @@ html|*.textbox-input {
   color: inherit;
   font: inherit;
   text-shadow: inherit;
   box-sizing: border-box;
   -moz-box-flex: 1;
   text-align: inherit;
 }
 
-.textbox-contextmenu {
-  cursor: default;
-}
-
 /* ..... readonly state ..... */
 
-textbox[readonly="true"],
 search-textbox[readonly="true"] {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
 /* ..... disabled state ..... */
 
-textbox[disabled="true"],
 search-textbox[disabled="true"] {
   cursor: default;
   background-color: -moz-Dialog;
   color: GrayText;
 }
 
-/* ::::: search textbox ::::: */
+/* ::::: icons ::::: */
 
 search-textbox:not([searchbutton]) > .textbox-search-sign {
   list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
   margin-inline-end: 5px;
 }
 
 .textbox-search-icon[searchbutton] {
   list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
 }
 
 .textbox-search-clear {
   list-style-image: url(chrome://global/skin/icons/searchfield-cancel.svg);
 }
 
-.textbox-search-icon[searchbutton]:not([disabled]) ,
+.textbox-search-icon[searchbutton]:not([disabled]),
 .textbox-search-clear:not([disabled]) {
   cursor: pointer;
 }
-
-/* ::::: textboxes inside toolbarpaletteitems ::::: */
-
-toolbarpaletteitem > toolbaritem > textbox > moz-input-box > html|*.textbox-input {
-  visibility: hidden;
-}
--- a/toolkit/themes/osx/global/autocomplete.css
+++ b/toolkit/themes/osx/global/autocomplete.css
@@ -88,15 +88,8 @@ html|span.ac-tag {
 .ac-tags-text,
 .ac-separator-text,
 .ac-url-text,
 .ac-action-text,
 .ac-text-overflow-container {
   padding: 0 !important;
   margin: 0 !important;
 }
-
-/* ::::: textboxes inside toolbarpaletteitems ::::: */
-
-toolbarpaletteitem > toolbaritem > textbox > moz-input-box > html|*.textbox-input,
-toolbarpaletteitem > toolbaritem > * > textbox > moz-input-box > html|*.textbox-input {
-  visibility: hidden;
-}
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -168,17 +168,17 @@ xul|label[disabled="true"] {
   text-decoration: underline;
 }
 
 .text-link:-moz-focusring {
   box-shadow: var(--focus-ring-box-shadow);
 }
 
 html|input {
-  margin: 4px; /* matches xul <textbox> default margin */
+  margin: 4px;
 }
 
 xul|notification > xul|hbox > xul|button {
   margin: 0 3px;
   padding: 1px 10px;
   min-width: 60px;
   min-height: 16px;
   -moz-appearance: none;
--- a/toolkit/themes/osx/global/textbox.css
+++ b/toolkit/themes/osx/global/textbox.css
@@ -1,66 +1,51 @@
 /* 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/. */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
-textbox,
 search-textbox {
-  -moz-appearance: textfield;
+  -moz-appearance: searchfield;
+  font-size: 12px;
   cursor: text;
-  margin: 4px;
-  padding: 0px;
+  margin: 4px; /* matches <input> global.css margin */
+  padding: 1px;
   background-color: -moz-Field;
   color: -moz-FieldText;
 }
 
 html|*.textbox-input {
   -moz-appearance: none;
   margin: 0;
   border: none;
   padding: 0 1px;
   background-color: transparent;
   color: inherit;
   font: inherit;
   text-shadow: inherit;
   box-sizing: border-box;
   -moz-box-flex: 1;
-}
-
-html|*.textbox-input {
   text-align: inherit;
 }
 
-.textbox-contextmenu {
-  cursor: default;
-}
-
-textbox[readonly="true"],
 search-textbox[readonly="true"] {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
-textbox[disabled="true"],
 search-textbox[disabled="true"] {
   cursor: default;
   background-color: -moz-Dialog;
   color: GrayText;
 }
 
-/* ::::: search box ::::: */
-
-search-textbox {
-  -moz-appearance: searchfield;
-  padding: 1px;
-  font-size: 12px;
-}
+/* ::::: icons ::::: */
 
 .textbox-search-clear {
   list-style-image: url(chrome://global/skin/icons/searchfield-cancel.svg);
   margin-bottom: 1px;
 }
 
 .textbox-search-clear:not([disabled]) {
   cursor: default;
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -457,28 +457,26 @@ xul|menulist > xul|menupopup xul|menusep
 
 html|input[type="email"],
 html|input[type="tel"],
 html|input[type="text"],
 html|input[type="password"],
 html|input[type="url"],
 html|input[type="number"],
 html|textarea,
-xul|textbox,
 xul|search-textbox {
   -moz-appearance: none;
   border: 1px solid var(--in-content-box-border-color);
   border-radius: 2px;
   /* !important to override disabled styling from textbox.css. We reduce the
      opacity instead of changing colors. */
   color: inherit !important;
   background-color: var(--in-content-box-background) !important;
 }
 
-xul|textbox,
 xul|search-textbox {
   min-height: 30px;
   padding-right: 8px;
   padding-left: 8px;
 }
 
 html|input[type="email"],
 html|input[type="tel"],
@@ -495,48 +493,44 @@ html|textarea {
 
 html|input[type="email"]:enabled:not(:focus):hover,
 html|input[type="tel"]:enabled:not(:focus):hover,
 html|input[type="text"]:enabled:not(:focus):hover,
 html|input[type="password"]:enabled:not(:focus):hover,
 html|input[type="url"]:enabled:not(:focus):hover,
 html|input[type="number"]:enabled:not(:focus):hover,
 html|textarea:enabled:not(:focus):hover,
-xul|textbox:not([disabled="true"]):not([focused]):hover,
 xul|search-textbox:not([disabled="true"]):not([focused]):hover {
   border-color: var(--in-content-border-hover);
 }
 
 html|input[type="email"]:focus,
 html|input[type="tel"]:focus,
 html|input[type="text"]:focus,
 html|input[type="password"]:focus,
 html|input[type="url"]:focus,
 html|input[type="number"]:focus,
 html|textarea:focus,
-xul|textbox[focused],
 xul|search-textbox[focused] {
   border-color: var(--in-content-border-active);
   box-shadow: 0 0 0 1px var(--in-content-border-active),
     0 0 0 4px var(--in-content-border-active-shadow);
 }
 
 html|input[type="email"]:-moz-ui-invalid,
 html|input[type="tel"]:-moz-ui-invalid,
 html|input[type="text"]:-moz-ui-invalid,
 html|input[type="password"]:-moz-ui-invalid,
 html|input[type="url"]:-moz-ui-invalid,
 html|input[type="number"]:-moz-ui-invalid,
 html|textarea:-moz-ui-invalid {
   border-color: var(--in-content-border-invalid);
 }
 
-/* Don't show the field error outlines and focus borders at the same time.
-   This doesn't apply to XUL <textbox> since they don't expose validity
-   attributes */
+/* Don't show the field error outlines and focus borders at the same time. */
 html|input[type="email"]:-moz-ui-invalid:focus,
 html|input[type="tel"]:-moz-ui-invalid:focus,
 html|input[type="text"]:-moz-ui-invalid:focus,
 html|input[type="password"]:-moz-ui-invalid:focus,
 html|input[type="url"]:-moz-ui-invalid:focus,
 html|input[type="number"]:-moz-ui-invalid:focus,
 html|textarea:-moz-ui-invalid:focus {
   box-shadow: 0 0 0 3px var(--in-content-border-invalid-shadow);
@@ -544,17 +538,16 @@ html|textarea:-moz-ui-invalid:focus {
 
 html|input[type="email"]:disabled,
 html|input[type="tel"]:disabled,
 html|input[type="text"]:disabled,
 html|input[type="password"]:disabled,
 html|input[type="url"]:disabled,
 html|input[type="number"]:disabled,
 html|textarea:disabled,
-xul|textbox[disabled="true"],
 xul|search-textbox[disabled="true"] {
   opacity: 0.4;
 }
 
 /* Links */
 
 html|a,
 .text-link {
--- a/toolkit/themes/windows/global/autocomplete.css
+++ b/toolkit/themes/windows/global/autocomplete.css
@@ -98,15 +98,8 @@ html|span.ac-tag {
 .ac-tags-text,
 .ac-separator-text,
 .ac-url-text,
 .ac-action-text,
 .ac-text-overflow-container {
   padding: 0 !important;
   margin: 0 !important;
 }
-
-/* ::::: textboxes inside toolbarpaletteitems ::::: */
-
-toolbarpaletteitem > toolbaritem > textbox > moz-input-box > html|*.textbox-input,
-toolbarpaletteitem > toolbaritem > * > textbox > moz-input-box  > html|*.textbox-input {
-  visibility: hidden;
-}
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -220,16 +220,16 @@ xul|label[disabled="true"] {
   text-decoration: underline;
 }
 
 .text-link:-moz-focusring {
   outline: 1px dotted;
 }
 
 html|input {
-  margin: 2px 4px; /* matches xul <textbox> default margin */
+  margin: 2px 4px;
 }
 
 xul|popupnotificationcontent {
   margin-top: .5em;
 }
 
 %include ../../shared/notification-popup.inc.css
--- a/toolkit/themes/windows/global/textbox.css
+++ b/toolkit/themes/windows/global/textbox.css
@@ -1,26 +1,25 @@
 /* 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/. */
 
 /* ===== textbox.css ==================================================
-  == Styles used by the XUL textbox element.
+  == Styles used by the XUL search-textbox element.
   ======================================================================= */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
-/* ::::: textbox ::::: */
+/* ::::: search textbox ::::: */
 
-textbox,
 search-textbox {
   -moz-appearance: textfield;
   cursor: text;
-  margin: 2px 4px;
+  margin: 2px 4px; /* matches <input> global.css margin */
   padding: 2px 2px 3px;
   padding-inline-start: 4px;
   background-color: -moz-Field;
   color: -moz-FieldText;
 }
 
 html|*.textbox-input {
   -moz-appearance: none;
@@ -31,44 +30,32 @@ html|*.textbox-input {
   color: inherit;
   font: inherit;
   text-shadow: inherit;
   box-sizing: border-box;
   -moz-box-flex: 1;
   text-align: inherit;
 }
 
-@media (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
-  textbox html|*.textbox-input::placeholder {
-    font-style: italic;
-  }
-}
-
-.textbox-contextmenu {
-  cursor: default;
-}
-
 /* ..... readonly state ..... */
 
-textbox[readonly="true"],
 search-textbox[readonly="true"] {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
 /* ..... disabled state ..... */
 
-textbox[disabled="true"],
 search-textbox[disabled="true"] {
   cursor: default;
   background-color: -moz-Dialog;
   color: GrayText;
 }
 
-/* ::::: search textbox ::::: */
+/* ::::: icons ::::: */
 
 search-textbox:not([searchbutton]) > .textbox-search-sign {
   list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
   margin-inline-end: 5px;
 }
 
 .textbox-search-icon[searchbutton] {
   list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
@@ -85,14 +72,8 @@ search-textbox:not([searchbutton]) > .te
 
 .textbox-search-clear {
   list-style-image: url(chrome://global/skin/icons/searchfield-cancel.svg);
 }
 
 .textbox-search-clear:not([disabled]) {
   cursor: default;
 }
-
-/* ::::: textboxes inside toolbarpaletteitems ::::: */
-
-toolbarpaletteitem > toolbaritem > textbox > moz-input-box > html|*.textbox-input {
-  visibility: hidden;
-}