Skip to content

Commit

Permalink
React events: ignore device buttons that aren't for primary interacti…
Browse files Browse the repository at this point in the history
…ons (#15402)

The Pointer Events spec mentions that the value of `button` in a nativeEvent
can be anything between 0 and 5 for "down" events. We only care about those
with a value of 0.
  • Loading branch information
necolas authored Apr 12, 2019
1 parent 38bd570 commit 8cf963c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 26 deletions.
52 changes: 26 additions & 26 deletions packages/react-events/src/Press.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ const PressResponder = {
props: PressProps,
state: PressState,
): void {
const {target, type, nativeEvent} = event;
const {target, type} = event;
const nativeEvent: any = event.nativeEvent;
switch (type) {
/**
Expand All @@ -442,21 +443,23 @@ const PressResponder = {
const pointerType = getPointerType(nativeEvent);
state.pointerType = pointerType;
if (pointerType === 'mouse' || type === 'mousedown') {
if (
// Ignore right- and middle-clicks
nativeEvent.button === 1 ||
nativeEvent.button === 2 ||
// Ignore pressing on hit slop area with mouse
context.isPositionWithinTouchHitTarget(
target.ownerDocument,
(nativeEvent: any).x,
(nativeEvent: any).y,
)
) {
return;
}
// Ignore any device buttons except left-mouse and touch/pen contact
if (nativeEvent.button > 0) {
return;
}
// Ignore pressing on hit slop area with mouse
if (
(pointerType === 'mouse' || type === 'mousedown') &&
context.isPositionWithinTouchHitTarget(
target.ownerDocument,
nativeEvent.x,
nativeEvent.y,
)
) {
return;
}

state.pressTarget = target;
state.isPressWithinResponderRegion = true;
dispatchPressStartEvents(context, props, state);
Expand Down Expand Up @@ -574,7 +577,7 @@ const PressResponder = {

if (type !== 'touchcancel' && props.onPress) {
// Find if the X/Y of the end touch is still that of the original target
const changedTouch = (nativeEvent: any).changedTouches[0];
const changedTouch = nativeEvent.changedTouches[0];
const doc = (target: any).ownerDocument;
const fromTarget = doc.elementFromPoint(
changedTouch.screenX,
Expand Down Expand Up @@ -607,14 +610,11 @@ const PressResponder = {
*/
case 'keydown':
case 'keypress': {
if (
!context.hasOwnership() &&
isValidKeyPress((nativeEvent: any).key)
) {
if (!context.hasOwnership() && isValidKeyPress(nativeEvent.key)) {
if (state.isPressed) {
// Prevent spacebar press from scrolling the window
if ((nativeEvent: any).key === ' ') {
(nativeEvent: any).preventDefault();
if (nativeEvent.key === ' ') {
nativeEvent.preventDefault();
}
} else {
const pointerType = getPointerType(nativeEvent);
Expand All @@ -627,7 +627,7 @@ const PressResponder = {
break;
}
case 'keyup': {
if (state.isPressed && isValidKeyPress((nativeEvent: any).key)) {
if (state.isPressed && isValidKeyPress(nativeEvent.key)) {
const wasLongPressed = state.isLongPressed;
dispatchPressEndEvents(context, props, state);
if (state.pressTarget !== null && props.onPress) {
Expand Down Expand Up @@ -659,11 +659,11 @@ const PressResponder = {

case 'click': {
if (isAnchorTagElement(target)) {
const {ctrlKey, metaKey, shiftKey} = ((nativeEvent: any): MouseEvent);
const {ctrlKey, metaKey, shiftKey} = (nativeEvent: MouseEvent);
// Check "open in new window/tab" and "open context menu" key modifiers
const preventDefault = props.preventDefault;
if (preventDefault !== false && !shiftKey && !metaKey && !ctrlKey) {
(nativeEvent: any).preventDefault();
nativeEvent.preventDefault();
}
}
break;
Expand All @@ -672,7 +672,7 @@ const PressResponder = {
case 'contextmenu': {
if (state.isPressed) {
if (props.preventDefault !== false) {
(nativeEvent: any).preventDefault();
nativeEvent.preventDefault();
} else {
state.shouldSkipMouseAfterTouch = false;
dispatchPressEndEvents(context, props, state);
Expand Down
7 changes: 7 additions & 0 deletions packages/react-events/src/__tests__/Press-test.internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ describe('Event responder: Press', () => {
expect(onPressStart).toHaveBeenCalledTimes(1);
});

it('ignores any events not caused by left-click or touch/pen contact', () => {
ref.current.dispatchEvent(createPointerEvent('pointerdown', {button: 1}));
ref.current.dispatchEvent(createPointerEvent('pointerdown', {button: 5}));
ref.current.dispatchEvent(createPointerEvent('mousedown', {button: 2}));
expect(onPressStart).toHaveBeenCalledTimes(0);
});

it('is called once after "keydown" events for Enter', () => {
ref.current.dispatchEvent(createKeyboardEvent('keydown', {key: 'Enter'}));
ref.current.dispatchEvent(createKeyboardEvent('keydown', {key: 'Enter'}));
Expand Down

0 comments on commit 8cf963c

Please sign in to comment.