diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp
index 1fa56a7bb7bd..7add074516cd 100644
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -228,25 +228,7 @@ nsresult HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
}
if (nsEventStatus_eIgnore == aVisitor.mEventStatus) {
- switch (aVisitor.mEvent->mMessage) {
- case eKeyPress:
- case eKeyUp: {
- // For backwards compat, trigger buttons with space or enter
- // (bug 25300)
- WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
- if ((keyEvent->mKeyCode == NS_VK_RETURN &&
- eKeyPress == aVisitor.mEvent->mMessage) ||
- (keyEvent->mKeyCode == NS_VK_SPACE &&
- eKeyUp == aVisitor.mEvent->mMessage)) {
- DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(),
- aVisitor.mPresContext);
- aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
- }
- } break;
-
- default:
- break;
- }
+ HandleKeyboardActivation(aVisitor);
if (aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) {
if (mForm) {
// Hold a strong ref while dispatching
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 4fb7b96b7824..61c4ab681bc7 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3593,6 +3593,22 @@ bool HTMLInputElement::StepsInputValue(
return true;
}
+static bool ActivatesWithKeyboard(uint8_t aType) {
+ switch (aType) {
+ case NS_FORM_INPUT_CHECKBOX:
+ case NS_FORM_INPUT_RADIO:
+ case NS_FORM_INPUT_BUTTON:
+ case NS_FORM_INPUT_RESET:
+ case NS_FORM_INPUT_SUBMIT:
+ case NS_FORM_INPUT_FILE:
+ case NS_FORM_INPUT_IMAGE: // Bug 34418
+ case NS_FORM_INPUT_COLOR:
+ return true;
+ default:
+ return false;
+ }
+}
+
nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
if (aVisitor.mEvent->mMessage == eFocus ||
aVisitor.mEvent->mMessage == eBlur) {
@@ -3733,6 +3749,16 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
FireChangeEventIfNeeded();
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
} else if (!preventDefault) {
+ // Checkbox and Radio try to submit on Enter press
+ if (aVisitor.mEvent->mMessage == eKeyPress &&
+ (mType == NS_FORM_INPUT_CHECKBOX || mType == NS_FORM_INPUT_RADIO) &&
+ keyEvent->mKeyCode == NS_VK_RETURN && aVisitor.mPresContext) {
+ MaybeSubmitForm(aVisitor.mPresContext);
+ } else if (ActivatesWithKeyboard(mType)) {
+ // Otherwise we maybe dispatch a synthesized click.
+ HandleKeyboardActivation(aVisitor);
+ }
+
switch (aVisitor.mEvent->mMessage) {
case eFocus: {
// see if we should select the contents of the textbox. This happens
@@ -3761,43 +3787,8 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
}
break;
}
-
- case eKeyPress:
- case eKeyUp: {
- // For backwards compat, trigger checks/radios/buttons with
- // space or enter (bug 25300)
- WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
- if ((aVisitor.mEvent->mMessage == eKeyPress &&
- keyEvent->mKeyCode == NS_VK_RETURN) ||
- (aVisitor.mEvent->mMessage == eKeyUp &&
- keyEvent->mKeyCode == NS_VK_SPACE)) {
- switch (mType) {
- case NS_FORM_INPUT_CHECKBOX:
- case NS_FORM_INPUT_RADIO: {
- // Checkbox and Radio try to submit on Enter press
- if (keyEvent->mKeyCode != NS_VK_SPACE &&
- aVisitor.mPresContext) {
- MaybeSubmitForm(aVisitor.mPresContext);
-
- break; // If we are submitting, do not send click event
- }
- // else fall through and treat Space like click...
- [[fallthrough]];
- }
- case NS_FORM_INPUT_BUTTON:
- case NS_FORM_INPUT_RESET:
- case NS_FORM_INPUT_SUBMIT:
- case NS_FORM_INPUT_FILE:
- case NS_FORM_INPUT_IMAGE: // Bug 34418
- case NS_FORM_INPUT_COLOR: {
- DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(),
- aVisitor.mPresContext);
- aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
- } // case
- } // switch
- }
- if (aVisitor.mEvent->mMessage == eKeyPress &&
- mType == NS_FORM_INPUT_RADIO && !keyEvent->IsAlt() &&
+ case eKeyPress: {
+ if (mType == NS_FORM_INPUT_RADIO && !keyEvent->IsAlt() &&
!keyEvent->IsControl() && !keyEvent->IsMeta()) {
bool isMovingBack = false;
switch (keyEvent->mKeyCode) {
@@ -3849,8 +3840,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
* not submit, period.
*/
- if (aVisitor.mEvent->mMessage == eKeyPress &&
- keyEvent->mKeyCode == NS_VK_RETURN &&
+ if (keyEvent->mKeyCode == NS_VK_RETURN &&
(IsSingleLineTextControl(false, mType) ||
mType == NS_FORM_INPUT_NUMBER || IsDateTimeInputType(mType))) {
FireChangeEventIfNeeded();
@@ -3860,8 +3850,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
}
}
- if (aVisitor.mEvent->mMessage == eKeyPress &&
- mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() &&
+ if (mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() &&
!keyEvent->IsControl() && !keyEvent->IsMeta() &&
(keyEvent->mKeyCode == NS_VK_LEFT ||
keyEvent->mKeyCode == NS_VK_RIGHT ||
@@ -3924,7 +3913,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
}
}
- } break; // eKeyPress || eKeyUp
+ } break; // eKeyPress
case eMouseDown:
case eMouseUp:
diff --git a/dom/html/HTMLSummaryElement.cpp b/dom/html/HTMLSummaryElement.cpp
index f557f3462ac4..37b52b373072 100644
--- a/dom/html/HTMLSummaryElement.cpp
+++ b/dom/html/HTMLSummaryElement.cpp
@@ -62,37 +62,7 @@ nsresult HTMLSummaryElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
}
} // event->HasMouseEventMessage()
- if (event->HasKeyEventMessage()) {
- WidgetKeyboardEvent* keyboardEvent = event->AsKeyboardEvent();
- bool dispatchClick = false;
-
- switch (event->mMessage) {
- case eKeyPress:
- if (keyboardEvent->mCharCode == ' ') {
- // Consume 'space' key to prevent scrolling the page down.
- aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
- }
-
- dispatchClick = keyboardEvent->mKeyCode == NS_VK_RETURN;
- break;
-
- case eKeyUp:
- dispatchClick = keyboardEvent->mKeyCode == NS_VK_SPACE;
- break;
-
- default:
- break;
- }
-
- if (dispatchClick) {
- rv = DispatchSimulatedClick(this, event->mFlags.mIsTrusted,
- aVisitor.mPresContext);
- if (NS_SUCCEEDED(rv)) {
- aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
- }
- }
- } // event->HasKeyEventMessage()
-
+ HandleKeyboardActivation(aVisitor);
return rv;
}
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index 8d629414737d..86d3cd4641d3 100644
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -16,6 +16,7 @@
#include "mozilla/MouseEvents.h"
#include "mozilla/PresShell.h"
#include "mozilla/TextEditor.h"
+#include "mozilla/TextEvents.h"
#include "mozilla/StaticPrefs_html5.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/StaticPrefs_accessibility.h"
@@ -2435,6 +2436,44 @@ bool nsGenericHTMLElement::PerformAccesskey(bool aKeyCausesActivation,
return focused;
}
+void nsGenericHTMLElement::HandleKeyboardActivation(
+ EventChainPostVisitor& aVisitor) {
+ const auto message = aVisitor.mEvent->mMessage;
+ if (message != eKeyUp && message != eKeyPress) {
+ return;
+ }
+
+ if (nsEventStatus_eIgnore != aVisitor.mEventStatus) {
+ return;
+ }
+
+ const WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
+ bool shouldActivate = false;
+ switch (message) {
+ case eKeyPress:
+ shouldActivate = keyEvent->mKeyCode == NS_VK_RETURN;
+ if (keyEvent->mKeyCode == NS_VK_SPACE) {
+ // Consume 'space' key to prevent scrolling the page down.
+ aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ break;
+ case eKeyUp:
+ shouldActivate = keyEvent->mKeyCode == NS_VK_SPACE;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("why didn't we bail out earlier?");
+ break;
+ }
+
+ if (!shouldActivate) {
+ return;
+ }
+
+ DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(),
+ aVisitor.mPresContext);
+ aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
+}
+
nsresult nsGenericHTMLElement::DispatchSimulatedClick(
nsGenericHTMLElement* aElement, bool aIsTrusted,
nsPresContext* aPresContext) {
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index 57281d8b0a19..91e781b9d477 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -699,11 +699,13 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
virtual mozilla::EventListenerManager* GetEventListenerManagerForAttr(
nsAtom* aAttrName, bool* aDefer) override;
- /**
- * Dispatch a simulated mouse click by keyboard to the given element.
- */
- nsresult DispatchSimulatedClick(nsGenericHTMLElement* aElement,
- bool aIsTrusted, nsPresContext* aPresContext);
+ /** Handles dispatching a simulated click on `this` on space or enter. */
+ void HandleKeyboardActivation(mozilla::EventChainPostVisitor&);
+
+ /** Dispatch a simulated mouse click by keyboard to the given element. */
+ static nsresult DispatchSimulatedClick(nsGenericHTMLElement* aElement,
+ bool aIsTrusted,
+ nsPresContext* aPresContext);
/**
* Create a URI for the given aURISpec string.