Files
react-native-web/packages/dom-event-testing-library/src/domEvents.js
T
Nicolas Gallagher fe013b30dc Add dom-event-testing-libary as a private package
This is copied from facebook/react with various fixes applied (which I'll push
upstream at a later date). Necessary for testing the Responder Event System
rewrite.
2020-06-05 11:53:47 -07:00

439 lines
9.1 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
import createEvent from './createEvent';
import { buttonType, buttonsType, defaultPointerSize, defaultBrowserChromeSize } from './constants';
/**
* Native event object mocks for higher-level events.
*
* 1. Each event type defines the exact object that it accepts. This ensures
* that no arbitrary properties can be assigned to events, and the properties
* that don't exist on specific event types (e.g., 'pointerType') are not added
* to the respective native event.
*
* 2. Properties that cannot be relied on due to inconsistent browser support (e.g., 'x' and 'y') are not
* added to the native event. Others that shouldn't be arbitrarily customized (e.g., 'screenX')
* are automatically inferred from associated values.
*
* 3. PointerEvent and TouchEvent fields are normalized (e.g., 'rotationAngle' -> 'twist')
*/
function emptyFunction() {}
function createGetModifierState(keyArg, data) {
if (keyArg === 'Alt') {
return data.altKey || false;
}
if (keyArg === 'Control') {
return data.ctrlKey || false;
}
if (keyArg === 'Meta') {
return data.metaKey || false;
}
if (keyArg === 'Shift') {
return data.shiftKey || false;
}
}
/**
* KeyboardEvent
*/
function createKeyboardEvent(
type,
{
altKey = false,
ctrlKey = false,
isComposing = false,
key = '',
metaKey = false,
preventDefault = emptyFunction,
shiftKey = false
} = {}
) {
const modifierState = { altKey, ctrlKey, metaKey, shiftKey };
const eventPayload = {
altKey,
ctrlKey,
getModifierState(keyArg) {
return createGetModifierState(keyArg, modifierState);
},
isComposing,
key,
metaKey,
preventDefault,
shiftKey
};
if (isComposing) {
eventPayload.keyCode = 229;
}
return createEvent(type, eventPayload);
}
/**
* MouseEvent
*/
function createMouseEvent(
type,
{
altKey = false,
button = buttonType.none,
buttons = buttonsType.none,
ctrlKey = false,
detail = 1,
metaKey = false,
movementX = 0,
movementY = 0,
offsetX = 0,
offsetY = 0,
pageX,
pageY,
preventDefault = emptyFunction,
screenX,
screenY,
shiftKey = false,
timeStamp,
x = 0,
y = 0
} = {}
) {
const modifierState = { altKey, ctrlKey, metaKey, shiftKey };
return createEvent(type, {
altKey,
button,
buttons,
clientX: x,
clientY: y,
ctrlKey,
detail,
getModifierState(keyArg) {
return createGetModifierState(keyArg, modifierState);
},
metaKey,
movementX,
movementY,
offsetX,
offsetY,
pageX: pageX || x,
pageY: pageY || y,
preventDefault,
screenX: screenX === 0 ? screenX : x,
screenY: screenY === 0 ? screenY : y + defaultBrowserChromeSize,
shiftKey,
timeStamp
});
}
/**
* PointerEvent
*/
function createPointerEvent(
type,
{
altKey = false,
button = buttonType.none,
buttons = buttonsType.none,
ctrlKey = false,
detail = 1,
height,
metaKey = false,
movementX = 0,
movementY = 0,
offsetX = 0,
offsetY = 0,
pageX,
pageY,
pointerId,
pressure = 0,
preventDefault = emptyFunction,
pointerType = 'mouse',
screenX,
screenY,
shiftKey = false,
tangentialPressure = 0,
tiltX = 0,
tiltY = 0,
timeStamp,
twist = 0,
width,
x = 0,
y = 0
} = {}
) {
const modifierState = { altKey, ctrlKey, metaKey, shiftKey };
const isMouse = pointerType === 'mouse';
return createEvent(type, {
altKey,
button,
buttons,
clientX: x,
clientY: y,
ctrlKey,
detail,
getModifierState(keyArg) {
return createGetModifierState(keyArg, modifierState);
},
height: isMouse ? 1 : height != null ? height : defaultPointerSize,
metaKey,
movementX,
movementY,
offsetX,
offsetY,
pageX: pageX || x,
pageY: pageY || y,
pointerId,
pointerType,
pressure,
preventDefault,
releasePointerCapture: emptyFunction,
screenX: screenX === 0 ? screenX : x,
screenY: screenY === 0 ? screenY : y + defaultBrowserChromeSize,
setPointerCapture: emptyFunction,
shiftKey,
tangentialPressure,
tiltX,
tiltY,
timeStamp,
twist,
width: isMouse ? 1 : width != null ? width : defaultPointerSize
});
}
/**
* TouchEvent
*/
function createTouchEvent(type, payload) {
return createEvent(type, {
preventDefault: emptyFunction,
...payload,
detail: 0,
sourceCapabilities: {
firesTouchEvents: true
}
});
}
/**
* DOM events
*/
export function blur({ relatedTarget } = {}) {
return createEvent('blur', { relatedTarget });
}
export function click(payload) {
return createMouseEvent('click', {
button: buttonType.primary,
...payload
});
}
export function contextmenu(payload) {
return createMouseEvent('contextmenu', {
...payload,
detail: 0
});
}
export function dragstart(payload) {
return createMouseEvent('dragstart', {
...payload,
detail: 0
});
}
export function focus({ relatedTarget } = {}) {
return createEvent('focus', { relatedTarget });
}
export function focusin({ relatedTarget } = {}) {
return createEvent('focusin', { relatedTarget });
}
export function focusout({ relatedTarget } = {}) {
return createEvent('focusout', { relatedTarget });
}
export function gotpointercapture(payload) {
return createPointerEvent('gotpointercapture', payload);
}
export function keydown(payload) {
return createKeyboardEvent('keydown', payload);
}
export function keyup(payload) {
return createKeyboardEvent('keyup', payload);
}
export function lostpointercapture(payload) {
return createPointerEvent('lostpointercapture', payload);
}
export function mousedown(payload) {
// The value of 'button' and 'buttons' for 'mousedown' must not be none.
const button =
payload != null && payload.button !== buttonType.none ? payload.button : buttonType.primary;
const buttons =
payload != null && payload.buttons !== buttonsType.none ? payload.buttons : buttonsType.primary;
return createMouseEvent('mousedown', {
...payload,
button,
buttons
});
}
export function mouseenter(payload) {
return createMouseEvent('mouseenter', payload);
}
export function mouseleave(payload) {
return createMouseEvent('mouseleave', payload);
}
export function mousemove(payload) {
return createMouseEvent('mousemove', {
// 0 is also the uninitialized value (i.e., don't assume it means primary button down)
button: 0,
buttons: 0,
...payload
});
}
export function mouseout(payload) {
return createMouseEvent('mouseout', payload);
}
export function mouseover(payload) {
return createMouseEvent('mouseover', payload);
}
export function mouseup(payload) {
return createMouseEvent('mouseup', {
button: buttonType.primary,
...payload,
buttons: buttonsType.none
});
}
export function pointercancel(payload) {
return createPointerEvent('pointercancel', {
...payload,
buttons: 0,
detail: 0,
height: 1,
pageX: 0,
pageY: 0,
pressure: 0,
screenX: 0,
screenY: 0,
width: 1,
x: 0,
y: 0
});
}
export function pointerdown(payload) {
const isTouch = payload != null && payload.pointerType === 'touch';
return createPointerEvent('pointerdown', {
button: buttonType.primary,
buttons: buttonsType.primary,
pressure: isTouch ? 1 : 0.5,
...payload
});
}
export function pointerenter(payload) {
return createPointerEvent('pointerenter', payload);
}
export function pointerleave(payload) {
return createPointerEvent('pointerleave', payload);
}
export function pointermove(payload) {
return createPointerEvent('pointermove', {
...payload,
button: buttonType.none,
buttons: buttonsType.none
});
}
export function pointerout(payload) {
return createPointerEvent('pointerout', payload);
}
export function pointerover(payload) {
return createPointerEvent('pointerover', payload);
}
export function pointerup(payload) {
return createPointerEvent('pointerup', {
button: buttonType.primary,
...payload,
buttons: buttonsType.none,
pressure: 0
});
}
export function scroll() {
return createEvent('scroll', { bubbles: false });
}
export function select() {
return createEvent('select');
}
export function selectionchange() {
return createEvent('selectionchange');
}
export function touchcancel(payload) {
return createTouchEvent('touchcancel', payload);
}
export function touchend(payload) {
return createTouchEvent('touchend', payload);
}
export function touchmove(payload) {
return createTouchEvent('touchmove', payload);
}
export function touchstart(payload) {
return createTouchEvent('touchstart', payload);
}
export function virtualclick(payload) {
return createMouseEvent('click', {
button: 0,
...payload,
buttons: 0,
detail: 0,
height: 1,
pageX: 0,
pageY: 0,
pressure: 0,
screenX: 0,
screenY: 0,
width: 1,
x: 0,
y: 0
});
}