Skip to content

Commit 33d439f

Browse files
author
Brian Vaughn
committed
Merge branch 'master' into devtools-v4-merge
2 parents fb31678 + 4ef2696 commit 33d439f

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

packages/react-events/src/dom/Press.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,19 @@ function handleStopPropagation(
476476
}
477477
}
478478

479+
// After some investigation work, screen reader virtual
480+
// clicks (NVDA, Jaws, VoiceOver) do not have co-ords associated with the click
481+
// event and "detail" is always 0 (where normal clicks are > 0)
482+
function isScreenReaderVirtualClick(nativeEvent): boolean {
483+
return (
484+
nativeEvent.detail === 0 &&
485+
nativeEvent.screenX === 0 &&
486+
nativeEvent.screenY === 0 &&
487+
nativeEvent.clientX === 0 &&
488+
nativeEvent.clientY === 0
489+
);
490+
}
491+
479492
function targetIsDocument(target: null | Node): boolean {
480493
// When target is null, it is the root
481494
return target === null || target.nodeType === 9;
@@ -617,6 +630,13 @@ const pressResponderImpl = {
617630
if (state.shouldPreventClick) {
618631
nativeEvent.preventDefault();
619632
}
633+
const onPress = props.onPress;
634+
635+
if (isFunction(onPress) && isScreenReaderVirtualClick(nativeEvent)) {
636+
state.pointerType = 'keyboard';
637+
state.pressTarget = event.responderTarget;
638+
dispatchEvent(event, onPress, context, state, 'press', DiscreteEvent);
639+
}
620640
break;
621641
}
622642
}

packages/react-events/src/dom/__tests__/Press-test.internal.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,18 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => {
420420
innerTarget.pointerup({pointerType: 'mouse'});
421421
expect(onPress).toBeCalled();
422422
});
423+
424+
it('is called once after virtual screen reader "click" event', () => {
425+
const target = createEventTarget(ref.current);
426+
target.virtualclick();
427+
expect(onPress).toHaveBeenCalledTimes(1);
428+
expect(onPress).toHaveBeenCalledWith(
429+
expect.objectContaining({
430+
pointerType: 'keyboard',
431+
type: 'press',
432+
}),
433+
);
434+
});
423435
});
424436

425437
describe('onPressMove', () => {

packages/react-events/src/dom/testing-library/domEvents.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,28 +170,30 @@ function createMouseEvent(
170170
x = 0,
171171
y = 0,
172172
} = {},
173+
virtual = false,
173174
) {
174175
const modifierState = {altKey, ctrlKey, metaKey, shiftKey};
175176

176177
return createEvent(type, {
177178
altKey,
178179
buttons,
179-
clientX: x,
180-
clientY: y,
180+
clientX: virtual ? 0 : x,
181+
clientY: virtual ? 0 : y,
181182
ctrlKey,
183+
detail: virtual ? 0 : 1,
182184
getModifierState(keyArg) {
183185
createGetModifierState(keyArg, modifierState);
184186
},
185187
metaKey,
186-
movementX,
187-
movementY,
188-
offsetX,
189-
offsetY,
190-
pageX: pageX || x,
191-
pageY: pageY || y,
188+
movementX: virtual ? 0 : movementX,
189+
movementY: virtual ? 0 : movementY,
190+
offsetX: virtual ? 0 : offsetX,
191+
offsetY: virtual ? 0 : offsetY,
192+
pageX: virtual ? 0 : pageX || x,
193+
pageY: virtual ? 0 : pageY || y,
192194
preventDefault,
193-
screenX: x,
194-
screenY: y + defaultBrowserChromeSize,
195+
screenX: virtual ? 0 : x,
196+
screenY: virtual ? 0 : y + defaultBrowserChromeSize,
195197
shiftKey,
196198
});
197199
}
@@ -251,7 +253,11 @@ export function blur({relatedTarget} = {}) {
251253
}
252254

253255
export function click(payload) {
254-
return createMouseEvent('click', payload);
256+
return createMouseEvent('click', payload, false);
257+
}
258+
259+
export function virtualclick(payload) {
260+
return createMouseEvent('click', payload, true);
255261
}
256262

257263
export function contextmenu(payload) {

packages/react-events/src/dom/testing-library/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ const createEventTarget = node => ({
4444
keyup(payload) {
4545
node.dispatchEvent(domEvents.keyup(payload));
4646
},
47+
virtualclick(payload) {
48+
node.dispatchEvent(domEvents.virtualclick(payload));
49+
},
4750
scroll(payload) {
4851
node.dispatchEvent(domEvents.scroll(payload));
4952
},

0 commit comments

Comments
 (0)