mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge branch 'master' into devtools-v4-merge
This commit is contained in:
+20
@@ -476,6 +476,19 @@ function handleStopPropagation(
|
||||
}
|
||||
}
|
||||
|
||||
// After some investigation work, screen reader virtual
|
||||
// clicks (NVDA, Jaws, VoiceOver) do not have co-ords associated with the click
|
||||
// event and "detail" is always 0 (where normal clicks are > 0)
|
||||
function isScreenReaderVirtualClick(nativeEvent): boolean {
|
||||
return (
|
||||
nativeEvent.detail === 0 &&
|
||||
nativeEvent.screenX === 0 &&
|
||||
nativeEvent.screenY === 0 &&
|
||||
nativeEvent.clientX === 0 &&
|
||||
nativeEvent.clientY === 0
|
||||
);
|
||||
}
|
||||
|
||||
function targetIsDocument(target: null | Node): boolean {
|
||||
// When target is null, it is the root
|
||||
return target === null || target.nodeType === 9;
|
||||
@@ -617,6 +630,13 @@ const pressResponderImpl = {
|
||||
if (state.shouldPreventClick) {
|
||||
nativeEvent.preventDefault();
|
||||
}
|
||||
const onPress = props.onPress;
|
||||
|
||||
if (isFunction(onPress) && isScreenReaderVirtualClick(nativeEvent)) {
|
||||
state.pointerType = 'keyboard';
|
||||
state.pressTarget = event.responderTarget;
|
||||
dispatchEvent(event, onPress, context, state, 'press', DiscreteEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,6 +420,18 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => {
|
||||
innerTarget.pointerup({pointerType: 'mouse'});
|
||||
expect(onPress).toBeCalled();
|
||||
});
|
||||
|
||||
it('is called once after virtual screen reader "click" event', () => {
|
||||
const target = createEventTarget(ref.current);
|
||||
target.virtualclick();
|
||||
expect(onPress).toHaveBeenCalledTimes(1);
|
||||
expect(onPress).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
pointerType: 'keyboard',
|
||||
type: 'press',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onPressMove', () => {
|
||||
|
||||
+17
-11
@@ -170,28 +170,30 @@ function createMouseEvent(
|
||||
x = 0,
|
||||
y = 0,
|
||||
} = {},
|
||||
virtual = false,
|
||||
) {
|
||||
const modifierState = {altKey, ctrlKey, metaKey, shiftKey};
|
||||
|
||||
return createEvent(type, {
|
||||
altKey,
|
||||
buttons,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
clientX: virtual ? 0 : x,
|
||||
clientY: virtual ? 0 : y,
|
||||
ctrlKey,
|
||||
detail: virtual ? 0 : 1,
|
||||
getModifierState(keyArg) {
|
||||
createGetModifierState(keyArg, modifierState);
|
||||
},
|
||||
metaKey,
|
||||
movementX,
|
||||
movementY,
|
||||
offsetX,
|
||||
offsetY,
|
||||
pageX: pageX || x,
|
||||
pageY: pageY || y,
|
||||
movementX: virtual ? 0 : movementX,
|
||||
movementY: virtual ? 0 : movementY,
|
||||
offsetX: virtual ? 0 : offsetX,
|
||||
offsetY: virtual ? 0 : offsetY,
|
||||
pageX: virtual ? 0 : pageX || x,
|
||||
pageY: virtual ? 0 : pageY || y,
|
||||
preventDefault,
|
||||
screenX: x,
|
||||
screenY: y + defaultBrowserChromeSize,
|
||||
screenX: virtual ? 0 : x,
|
||||
screenY: virtual ? 0 : y + defaultBrowserChromeSize,
|
||||
shiftKey,
|
||||
});
|
||||
}
|
||||
@@ -251,7 +253,11 @@ export function blur({relatedTarget} = {}) {
|
||||
}
|
||||
|
||||
export function click(payload) {
|
||||
return createMouseEvent('click', payload);
|
||||
return createMouseEvent('click', payload, false);
|
||||
}
|
||||
|
||||
export function virtualclick(payload) {
|
||||
return createMouseEvent('click', payload, true);
|
||||
}
|
||||
|
||||
export function contextmenu(payload) {
|
||||
|
||||
@@ -44,6 +44,9 @@ const createEventTarget = node => ({
|
||||
keyup(payload) {
|
||||
node.dispatchEvent(domEvents.keyup(payload));
|
||||
},
|
||||
virtualclick(payload) {
|
||||
node.dispatchEvent(domEvents.virtualclick(payload));
|
||||
},
|
||||
scroll(payload) {
|
||||
node.dispatchEvent(domEvents.scroll(payload));
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user