Merge branch 'master' into devtools-v4-merge

This commit is contained in:
Brian Vaughn
2019-08-27 11:00:41 -07:00
4 changed files with 52 additions and 11 deletions
+20
View File
@@ -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
View File
@@ -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));
},