Bug 1419091: Make TextInputListener handle non-native events for input and textarea too. r=masayuki
authorDave Townsend <dtownsend@oxymoronical.com>
Mon, 15 Oct 2018 12:19:30 -0700
changeset 442816 40371ad8146476cc3eb65fd1389e1a4fa9cbc91e
parent 442815 69f747a1dc7d406a88ede339845a13b99d188995
child 442817 40036a4302c376f6de9f5e767be9a0a4e4d89bf6
push id109248
push userdtownsend@mozilla.com
push dateWed, 24 Oct 2018 21:25:49 +0000
treeherdermozilla-inbound@40036a4302c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1419091
milestone65.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 1419091: Make TextInputListener handle non-native events for input and textarea too. r=masayuki platformHTMLBindings attaches event handlers directly to the <input> and <textarea> elements. This matches that by making TextInputListener look up and call the <input> and <textarea> event handlers from the static C array. There is a slight difference in that the event handlers are added to the system bubbling phase as opposed to the regular bubbling phase but in tests this does not seem to cause problems. Differential Revision: https://phabricator.services.mozilla.com/D8931
dom/html/nsTextEditorState.cpp
dom/xbl/builtin/ShortcutKeys.cpp
dom/xbl/builtin/ShortcutKeys.h
dom/xbl/moz.build
dom/xbl/nsXBLWindowKeyHandler.cpp
dom/xbl/nsXBLWindowKeyHandler.h
layout/style/res/forms.css
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -40,16 +40,19 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLTextAreaElement.h"
 #include "mozilla/dom/Text.h"
 #include "nsNumberControlFrame.h"
 #include "nsFrameSelection.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/ShortcutKeys.h"
+#include "nsXBLPrototypeHandler.h"
+#include "mozilla/dom/KeyboardEvent.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 inline nsresult
 SetEditorFlagsIfNecessary(EditorBase& aEditorBase, uint32_t aFlags)
 {
   if (aEditorBase.Flags() == aFlags) {
@@ -952,46 +955,77 @@ TextInputListener::HandleEvent(Event* aE
   if (aEvent->DefaultPrevented()) {
     return NS_OK;
   }
 
   if (!aEvent->IsTrusted()) {
     return NS_OK;
   }
 
-  WidgetKeyboardEvent* keyEvent =
-    aEvent->WidgetEventPtr()->AsKeyboardEvent();
+  RefPtr<KeyboardEvent> keyEvent = aEvent->AsKeyboardEvent();
+  if (!keyEvent) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  WidgetKeyboardEvent* widgetKeyEvent =
+      aEvent->WidgetEventPtr()->AsKeyboardEvent();
   if (!keyEvent) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  if (keyEvent->mMessage != eKeyPress) {
+  nsXBLPrototypeHandler* keyHandlers =
+      ShortcutKeys::GetHandlers(mTxtCtrlElement->IsTextArea() ?
+                                HandlerType::eTextArea : HandlerType::eInput);
+
+  RefPtr<nsAtom> eventTypeAtom =
+    ShortcutKeys::ConvertEventToDOMEventType(widgetKeyEvent);
+  for (nsXBLPrototypeHandler* handler = keyHandlers;
+       handler;
+       handler = handler->GetNextHandler()) {
+    if (!handler->EventTypeEquals(eventTypeAtom)) {
+      continue;
+    }
+
+    if (!handler->KeyEventMatched(keyEvent, 0, IgnoreModifierState())) {
+      continue;
+    }
+
+    // XXX Do we execute only one handler even if the handler neither stops
+    //     propagation nor prevents default of the event?
+    nsCOMPtr<EventTarget> target = do_QueryInterface(mTxtCtrlElement);
+    nsresult rv = handler->ExecuteHandler(target, aEvent);
+    if (NS_SUCCEEDED(rv)) {
+      return rv;
+    }
+  }
+
+  if (widgetKeyEvent->mMessage != eKeyPress) {
     return NS_OK;
   }
 
   nsIWidget::NativeKeyBindingsType nativeKeyBindingsType =
     mTxtCtrlElement->IsTextArea() ?
       nsIWidget::NativeKeyBindingsForMultiLineEditor :
       nsIWidget::NativeKeyBindingsForSingleLineEditor;
 
-  nsIWidget* widget = keyEvent->mWidget;
+  nsIWidget* widget = widgetKeyEvent->mWidget;
   // If the event is created by chrome script, the widget is nullptr.
   if (!widget) {
     widget = mFrame->GetNearestWidget();
     NS_ENSURE_TRUE(widget, NS_OK);
   }
 
   // WidgetKeyboardEvent::ExecuteEditCommands() requires non-nullptr mWidget.
   // If the event is created by chrome script, it is nullptr but we need to
   // execute native key bindings.  Therefore, we need to set widget to
   // WidgetEvent::mWidget temporarily.
-  AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(keyEvent->mWidget);
-  keyEvent->mWidget = widget;
-  if (keyEvent->ExecuteEditCommands(nativeKeyBindingsType,
-                                    DoCommandCallback, mFrame)) {
+  AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(widgetKeyEvent->mWidget);
+  widgetKeyEvent->mWidget = widget;
+  if (widgetKeyEvent->ExecuteEditCommands(nativeKeyBindingsType,
+                                          DoCommandCallback, mFrame)) {
     aEvent->PreventDefault();
   }
   return NS_OK;
 }
 
 void
 TextInputListener::OnEditActionHandled()
 {
--- a/dom/xbl/builtin/ShortcutKeys.cpp
+++ b/dom/xbl/builtin/ShortcutKeys.cpp
@@ -1,11 +1,13 @@
 #include "mozilla/ShortcutKeys.h"
 #include "../nsXBLPrototypeHandler.h"
 #include "nsContentUtils.h"
+#include "nsAtom.h"
+#include "mozilla/TextEvents.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(ShortcutKeys, nsIObserver);
 
 StaticRefPtr<ShortcutKeys> ShortcutKeys::sInstance;
 
 ShortcutKeys::ShortcutKeys()
@@ -39,16 +41,38 @@ ShortcutKeys::GetHandlers(HandlerType aT
 {
   if (!sInstance) {
     sInstance = new ShortcutKeys();
   }
 
   return sInstance->EnsureHandlers(aType);
 }
 
+/* static */ nsAtom*
+ShortcutKeys::ConvertEventToDOMEventType(const WidgetKeyboardEvent* aWidgetKeyboardEvent)
+{
+  if (aWidgetKeyboardEvent->IsKeyDownOrKeyDownOnPlugin()) {
+    return nsGkAtoms::keydown;
+  }
+  if (aWidgetKeyboardEvent->IsKeyUpOrKeyUpOnPlugin()) {
+    return nsGkAtoms::keyup;
+  }
+  // eAccessKeyNotFound event is always created from eKeyPress event and
+  // the original eKeyPress event has stopped its propagation before dispatched
+  // into the DOM tree in this process and not matched with remote content's
+  // access keys.  So, we should treat it as an eKeyPress event and execute
+  // a command if it's registered as a shortcut key.
+  if (aWidgetKeyboardEvent->mMessage == eKeyPress ||
+      aWidgetKeyboardEvent->mMessage == eAccessKeyNotFound) {
+    return nsGkAtoms::keypress;
+  }
+  MOZ_ASSERT_UNREACHABLE("All event messages relating to shortcut keys should be handled");
+  return nullptr;
+}
+
 nsXBLPrototypeHandler*
 ShortcutKeys::EnsureHandlers(HandlerType aType)
 {
   ShortcutKeyData* keyData;
   nsXBLPrototypeHandler** cache;
 
   switch (aType) {
     case HandlerType::eBrowser:
--- a/dom/xbl/builtin/ShortcutKeys.h
+++ b/dom/xbl/builtin/ShortcutKeys.h
@@ -3,19 +3,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ShortcutKeys_h
 #define mozilla_dom_ShortcutKeys_h
 
 #include "nsIObserver.h"
 
 class nsXBLPrototypeHandler;
+class nsAtom;
 
 namespace mozilla {
 
+class WidgetKeyboardEvent;
+
 typedef struct
 {
    const char16_t* event;
    const char16_t* keycode;
    const char16_t* key;
    const char16_t* modifiers;
    const char16_t* command;
 } ShortcutKeyData;
@@ -32,16 +35,19 @@ class ShortcutKeys : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   // Returns a pointer to the first handler for the given type.
   static nsXBLPrototypeHandler* GetHandlers(HandlerType aType);
 
+  // Gets the event type for a widget keyboard event.
+  static nsAtom* ConvertEventToDOMEventType(const WidgetKeyboardEvent* aWidgetKeyboardEvent);
+
 protected:
   ShortcutKeys();
   virtual ~ShortcutKeys();
 
   // Returns a pointer to the first handler for the given type.
   nsXBLPrototypeHandler* EnsureHandlers(HandlerType aType);
 
   // Maintains a strong reference to the only instance.
--- a/dom/xbl/moz.build
+++ b/dom/xbl/moz.build
@@ -7,16 +7,17 @@
 with Files("**"):
     BUG_COMPONENT = ("Core", "XBL")
 
 DIRS += ['builtin']
 
 EXPORTS += [
     'nsBindingManager.h',
     'nsXBLBinding.h',
+    'nsXBLPrototypeHandler.h',
     'nsXBLService.h',
     'nsXBLWindowKeyHandler.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'XBLChildrenElement.h',
 ]
 
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp
+++ b/dom/xbl/nsXBLWindowKeyHandler.cpp
@@ -132,17 +132,17 @@ nsXBLWindowKeyHandler::EnsureHandlers()
       mHandler = ShortcutKeys::GetHandlers(HandlerType::eBrowser);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType)
+nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent)
 {
   if (aKeyEvent->DefaultPrevented()) {
     return NS_OK;
   }
 
   // Don't process the event if it was not dispatched from a trusted source
   if (!aKeyEvent->IsTrusted()) {
     return NS_OK;
@@ -154,17 +154,17 @@ nsXBLWindowKeyHandler::WalkHandlers(Keyb
   bool isDisabled;
   nsCOMPtr<Element> el = GetElement(&isDisabled);
 
   // skip keysets that are disabled
   if (el && isDisabled) {
     return NS_OK;
   }
 
-  WalkHandlersInternal(aKeyEvent, aEventType, true);
+  WalkHandlersInternal(aKeyEvent, true);
 
   return NS_OK;
 }
 
 void
 nsXBLWindowKeyHandler::InstallKeyboardEventListenersTo(
                          EventListenerManager* aEventListenerManager)
 {
@@ -304,40 +304,16 @@ nsXBLWindowKeyHandler::CollectKeyboardSh
     if (handler->TryConvertToKeyboardShortcut(&shortcut)) {
       shortcuts.AppendElement(shortcut);
     }
   }
 
   return KeyboardMap(std::move(shortcuts));
 }
 
-nsAtom*
-nsXBLWindowKeyHandler::ConvertEventToDOMEventType(
-                         const WidgetKeyboardEvent& aWidgetKeyboardEvent) const
-{
-  if (aWidgetKeyboardEvent.IsKeyDownOrKeyDownOnPlugin()) {
-    return nsGkAtoms::keydown;
-  }
-  if (aWidgetKeyboardEvent.IsKeyUpOrKeyUpOnPlugin()) {
-    return nsGkAtoms::keyup;
-  }
-  // eAccessKeyNotFound event is always created from eKeyPress event and
-  // the original eKeyPress event has stopped its propagation before dispatched
-  // into the DOM tree in this process and not matched with remote content's
-  // access keys.  So, we should treat it as an eKeyPress event and execute
-  // a command if it's registered as a shortcut key.
-  if (aWidgetKeyboardEvent.mMessage == eKeyPress ||
-      aWidgetKeyboardEvent.mMessage == eAccessKeyNotFound) {
-    return nsGkAtoms::keypress;
-  }
-  MOZ_ASSERT_UNREACHABLE(
-    "All event messages which this instance listens to should be handled");
-  return nullptr;
-}
-
 NS_IMETHODIMP
 nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
 {
   RefPtr<KeyboardEvent> keyEvent = aEvent->AsKeyboardEvent();
   NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG);
 
   if (aEvent->EventPhase() == Event_Binding::CAPTURING_PHASE) {
     if (aEvent->WidgetEventPtr()->mFlags.mInSystemGroup) {
@@ -375,19 +351,17 @@ nsXBLWindowKeyHandler::HandleEvent(Event
 
   // If this event was handled by APZ then don't do the default action, and
   // preventDefault to prevent any other listeners from handling the event.
   if (widgetKeyboardEvent->mFlags.mHandledByAPZ) {
     aEvent->PreventDefault();
     return NS_OK;
   }
 
-  RefPtr<nsAtom> eventTypeAtom =
-    ConvertEventToDOMEventType(*widgetKeyboardEvent);
-  return WalkHandlers(keyEvent, eventTypeAtom);
+  return WalkHandlers(keyEvent);
 }
 
 void
 nsXBLWindowKeyHandler::HandleEventOnCaptureInDefaultEventGroup(
                          KeyboardEvent* aEvent)
 {
   WidgetKeyboardEvent* widgetKeyboardEvent =
     aEvent->WidgetEventPtr()->AsKeyboardEvent();
@@ -485,65 +459,63 @@ nsXBLWindowKeyHandler::IsHTMLEditableFie
 //
 // Given a particular DOM event and a pointer to the first handler in the list,
 // scan through the list to find something to handle the event. If aExecute = true,
 // the handler will be executed; otherwise just return an answer telling if a handler
 // for that event was found.
 //
 bool
 nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
-                                            nsAtom* aEventType,
                                             bool aExecute,
                                             bool* aOutReservedForChrome)
 {
   WidgetKeyboardEvent* nativeKeyboardEvent =
     aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
   MOZ_ASSERT(nativeKeyboardEvent);
 
   AutoShortcutKeyCandidateArray shortcutKeys;
   nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys);
 
   if (shortcutKeys.IsEmpty()) {
-    return WalkHandlersAndExecute(aKeyEvent, aEventType,
-                                  0, IgnoreModifierState(),
+    return WalkHandlersAndExecute(aKeyEvent, 0, IgnoreModifierState(),
                                   aExecute, aOutReservedForChrome);
   }
 
   for (uint32_t i = 0; i < shortcutKeys.Length(); ++i) {
     ShortcutKeyCandidate& key = shortcutKeys[i];
     IgnoreModifierState ignoreModifierState;
     ignoreModifierState.mShift = key.mIgnoreShift;
-    if (WalkHandlersAndExecute(aKeyEvent, aEventType,
-                               key.mCharCode, ignoreModifierState,
+    if (WalkHandlersAndExecute(aKeyEvent, key.mCharCode, ignoreModifierState,
                                aExecute, aOutReservedForChrome)) {
       return true;
     }
   }
   return false;
 }
 
 bool
 nsXBLWindowKeyHandler::WalkHandlersAndExecute(
                          KeyboardEvent* aKeyEvent,
-                         nsAtom* aEventType,
                          uint32_t aCharCode,
                          const IgnoreModifierState& aIgnoreModifierState,
                          bool aExecute,
                          bool* aOutReservedForChrome)
 {
   if (aOutReservedForChrome) {
     *aOutReservedForChrome = false;
   }
 
   WidgetKeyboardEvent* widgetKeyboardEvent =
     aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
   if (NS_WARN_IF(!widgetKeyboardEvent)) {
     return false;
   }
 
+  nsAtom* eventType = ShortcutKeys::ConvertEventToDOMEventType(widgetKeyboardEvent);
+
   // Try all of the handlers until we find one that matches the event.
   for (nsXBLPrototypeHandler* handler = mHandler;
        handler;
        handler = handler->GetNextHandler()) {
     bool stopped = aKeyEvent->IsDispatchStopped();
     if (stopped) {
       // The event is finished, don't execute any more handlers
       return false;
@@ -555,33 +527,33 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
       // never followed by keypress events.
       if (widgetKeyboardEvent->mMessage == eKeyDownOnPlugin) {
         if (!handler->EventTypeEquals(nsGkAtoms::keydown) &&
             !handler->EventTypeEquals(nsGkAtoms::keypress)) {
           continue;
         }
       // The other event types should exactly be matched with the handler's
       // event type.
-      } else if (!handler->EventTypeEquals(aEventType)) {
+      } else if (!handler->EventTypeEquals(eventType)) {
         continue;
       }
     } else {
       if (handler->EventTypeEquals(nsGkAtoms::keypress)) {
         // If the handler is a keypress event handler, we also need to check
         // if coming keydown event is a preceding event of reserved key
         // combination because if default action of a keydown event is
         // prevented, following keypress event won't be fired.  However, if
         // following keypress event is reserved, we shouldn't allow web
         // contents to prevent the default of the preceding keydown event.
-        if (aEventType != nsGkAtoms::keydown &&
-            aEventType != nsGkAtoms::keypress) {
+        if (eventType != nsGkAtoms::keydown &&
+            eventType != nsGkAtoms::keypress) {
           continue;
         }
-      } else if (!handler->EventTypeEquals(aEventType)) {
-        // Otherwise, aEventType should exactly be matched.
+      } else if (!handler->EventTypeEquals(eventType)) {
+        // Otherwise, eventType should exactly be matched.
         continue;
       }
     }
 
     // Check if the keyboard event *may* execute the handler.
     if (!handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreModifierState)) {
       continue;  // try the next one
     }
@@ -596,28 +568,28 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
 
     if (commandElement) {
       if (aExecute && !IsExecutableElement(commandElement)) {
         continue;
       }
     }
 
     if (!aExecute) {
-      if (handler->EventTypeEquals(aEventType)) {
+      if (handler->EventTypeEquals(eventType)) {
         if (aOutReservedForChrome) {
           *aOutReservedForChrome = IsReservedKey(widgetKeyboardEvent, handler);
         }
 
         return true;
       }
 
       // If the command is reserved and the event is keydown, check also if
       // the handler is for keypress because if following keypress event is
       // reserved, we shouldn't dispatch the event into web contents.
-      if (aEventType == nsGkAtoms::keydown &&
+      if (eventType == nsGkAtoms::keydown &&
           handler->EventTypeEquals(nsGkAtoms::keypress)) {
         if (IsReservedKey(widgetKeyboardEvent, handler)) {
           if (aOutReservedForChrome) {
             *aOutReservedForChrome = true;
           }
 
           return true;
         }
@@ -656,18 +628,18 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
 #ifdef XP_WIN
   // Windows native applications ignore Windows-Logo key state when checking
   // shortcut keys even if the key is pressed.  Therefore, if there is no
   // shortcut key which exactly matches current modifier state, we should
   // retry to look for a shortcut key without the Windows-Logo key press.
   if (!aIgnoreModifierState.mOS && widgetKeyboardEvent->IsOS()) {
     IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
     ignoreModifierState.mOS = true;
-    return WalkHandlersAndExecute(aKeyEvent, aEventType,
-                                  aCharCode, ignoreModifierState, aExecute);
+    return WalkHandlersAndExecute(aKeyEvent, aCharCode, ignoreModifierState,
+                                  aExecute);
   }
 #endif
 
   return false;
 }
 
 bool
 nsXBLWindowKeyHandler::IsReservedKey(WidgetKeyboardEvent* aKeyEvent,
@@ -702,20 +674,17 @@ nsXBLWindowKeyHandler::HasHandlerForEven
   NS_ENSURE_SUCCESS(rv, false);
 
   bool isDisabled;
   nsCOMPtr<Element> el = GetElement(&isDisabled);
   if (el && isDisabled) {
     return false;
   }
 
-  RefPtr<nsAtom> eventTypeAtom =
-    ConvertEventToDOMEventType(*widgetKeyboardEvent);
-  return WalkHandlersInternal(aEvent, eventTypeAtom, false,
-                              aOutReservedForChrome);
+  return WalkHandlersInternal(aEvent, false, aOutReservedForChrome);
 }
 
 already_AddRefed<Element>
 nsXBLWindowKeyHandler::GetElement(bool* aIsDisabled)
 {
   nsCOMPtr<Element> element = do_QueryReferent(mWeakPtrForElement);
   if (element && aIsDisabled) {
     *aIsDisabled = element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
--- a/dom/xbl/nsXBLWindowKeyHandler.h
+++ b/dom/xbl/nsXBLWindowKeyHandler.h
@@ -45,27 +45,26 @@ public:
   static KeyboardMap CollectKeyboardShortcuts();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
 
 protected:
   virtual ~nsXBLWindowKeyHandler();
 
-  nsresult WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType);
+  nsresult WalkHandlers(KeyboardEvent* aKeyEvent);
 
   // walk the handlers, looking for one to handle the event
   bool WalkHandlersInternal(KeyboardEvent* aKeyEvent,
-                            nsAtom* aEventType,
                             bool aExecute,
                             bool* aOutReservedForChrome = nullptr);
 
   // walk the handlers for aEvent, aCharCode and aIgnoreModifierState. Execute
   // it if aExecute = true.
-  bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent, nsAtom* aEventType,
+  bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent,
                               uint32_t aCharCode,
                               const IgnoreModifierState& aIgnoreModifierState,
                               bool aExecute,
                               bool* aOutReservedForChrome = nullptr);
 
   // HandleEvent function for the capturing phase in the default event group.
   void HandleEventOnCaptureInDefaultEventGroup(KeyboardEvent* aEvent);
   // HandleEvent function for the capturing phase in the system event group.
@@ -77,22 +76,16 @@ protected:
   bool HasHandlerForEvent(KeyboardEvent* aEvent,
                           bool* aOutReservedForChrome = nullptr);
 
   // Returns true if the key would be reserved for the given handler. A reserved
   // key is not sent to a content process or single-process equivalent.
   bool IsReservedKey(mozilla::WidgetKeyboardEvent* aKeyEvent,
                      nsXBLPrototypeHandler* aHandler);
 
-  // Returns event type for matching between aWidgetKeyboardEvent and
-  // shortcut key handlers.  This is used for calling WalkHandlers(),
-  // WalkHandlersInternal() and WalkHandlersAndExecute().
-  nsAtom* ConvertEventToDOMEventType(
-             const mozilla::WidgetKeyboardEvent& aWidgetKeyboardEvent) const;
-
   // lazily load the handlers. Overridden to handle being attached
   // to a particular element rather than the document
   nsresult EnsureHandlers();
 
   // Is an HTML editable element focused
   bool IsHTMLEditableFieldFocused();
 
   // Returns the element which was passed as a parameter to the constructor,
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -97,17 +97,16 @@ input {
   font: -moz-field;
   text-rendering: optimizeLegibility;
   line-height: normal;
   text-align: start;
   text-transform: none;
   word-spacing: normal;
   letter-spacing: normal;
   cursor: text;
-  -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#inputFields");
   text-indent: 0;
   -moz-user-select: text;
   text-shadow: none;
   overflow-clip-box: padding-box content-box;
 }
 
 input > .anonymous-div,
 input::placeholder {
@@ -129,17 +128,16 @@ textarea {
   text-rendering: optimizeLegibility;
   text-align: start;
   text-transform: none;
   word-spacing: normal;
   letter-spacing: normal;
   vertical-align: text-bottom;
   cursor: text;
   resize: both;
-  -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#textAreas");
   -moz-appearance: textfield-multiline;
   text-indent: 0;
   -moz-user-select: text;
   text-shadow: none;
   white-space: pre-wrap;
   word-wrap: break-word;
   overflow-clip-box: content-box;
 }
@@ -443,29 +441,27 @@ optgroup:disabled {
 /* hidden inputs */
 input[type="hidden"] {
   -moz-appearance: none;
   display: none !important;
   padding: unset;
   border: 0;
   cursor: auto;
   -moz-user-focus: ignore;
-  -moz-binding: none;
 }
 
 /* image buttons */
 input[type="image"] {
   -moz-appearance: none;
   padding: unset;
   border: none;
   background-color: transparent;
   font-family: sans-serif;
   font-size: small;
   cursor: pointer;
-  -moz-binding: none;
 }
 
 input[type="image"]:disabled {
   cursor: unset;
 }
 
 input[type="image"]:-moz-focusring {
   /* Don't specify the outline-color, we should always use initial value. */
@@ -477,17 +473,16 @@ input[type="file"] {
   display: inline-block;
   white-space: nowrap !important;
   overflow: hidden;
   overflow-clip-box: padding-box;
   color: unset;
 
   /* Revert rules which apply on all inputs. */
   -moz-appearance: none;
-  -moz-binding: none;
   cursor: default;
 
   border: none;
   background-color: transparent;
   padding: unset;
 }
 
 input[type="file"] > label {
@@ -547,17 +542,16 @@ input[type="checkbox"] {
 /* common features of radio buttons and check boxes */
 
 input[type="radio"],
 input[type="checkbox"] {
   box-sizing: border-box;
   cursor: default;
   /* unset some values from the general 'input' rule above: */
   padding: unset;
-  -moz-binding: unset;
   border: unset;
   background-color: unset;
   color: unset;
 }
 
 input[type="radio"]:disabled,
 input[type="radio"]:disabled:active,
 input[type="radio"]:disabled:hover,
@@ -603,17 +597,16 @@ input[type="submit"] {
   padding-inline-end: 8px;
   padding-block-end: 0px;
   padding-inline-start: 8px;
   border: 2px outset ThreeDLightShadow;
   background-color: ButtonFace;
   cursor: default;
   box-sizing: border-box;
   -moz-user-select: none;
-  -moz-binding: none;
 }
 
 /* Text-related properties for buttons: these ones are not shared with
    input[type="color"] */
 button,
 input[type="reset"],
 input[type="button"],
 input[type="submit"] {
@@ -888,17 +881,16 @@ input[type=range] {
   margin-inline-start: 0.7em;
   margin-inline-end: 0.7em;
   margin-block-start: 0;
   margin-block-end: 0;
   /* Override some rules that apply on all input types: */
   cursor: default;
   background: none;
   border: none;
-  -moz-binding: none; /* we don't want any of platformHTMLBindings.xml#inputFields */
   /* Prevent nsFrame::HandlePress setting mouse capture to this element. */
   -moz-user-select: none ! important;
 }
 
 input[type=range][orient=block] {
   inline-size: 1.3em;
   block-size: 12em;
   margin-inline-start: 0;
@@ -1010,17 +1002,16 @@ input[type=range]::-moz-range-thumb {
   background-color: #F0F0F0;
   /* Prevent nsFrame::HandlePress setting mouse capture to this element. */
   -moz-user-select: none ! important;
 }
 
 input[type="number"] {
   -moz-appearance: number-input;
   /* Has to revert some properties applied by the generic input rule. */
-  -moz-binding: none;
   inline-size: 20ch; /* It'd be nice if this matched the default inline-size
                         of <input type=text>, but that's not easy to achieve
                         due to platform differences. */
 }
 
 input[type=number]::-moz-number-wrapper {
   /* Prevent styling that would change the type of frame we construct. */
   display: flex;