зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1481400 - Centralize keyboard activation code. r=masayuki
Differential Revision: https://phabricator.services.mozilla.com/D116584
This commit is contained in:
Родитель
1a8ab36ef2
Коммит
88bb474e07
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче