Files
react/packages/react-dom/src/events/DOMEventProperties.js
T

190 lines
7.0 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.
*
* @flow
*/
import type {EventPriority} from 'shared/ReactTypes';
import type {
TopLevelType,
DOMTopLevelEventType,
} from 'legacy-events/TopLevelEventTypes';
import type {DispatchConfig} from 'legacy-events/ReactSyntheticEventType';
import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
import {
DiscreteEvent,
UserBlockingEvent,
ContinuousEvent,
} from 'shared/ReactTypes';
// Needed for SimpleEventPlugin, rather than
// do it in two places, which duplicates logic
// and increases the bundle size, we do it all
// here once. If we remove or refactor the
// SimpleEventPlugin, we should also remove or
// update the below line.
export const simpleEventPluginEventTypes = {};
export const topLevelEventsToDispatchConfig: Map<
TopLevelType,
DispatchConfig,
> = new Map();
const eventPriorities = new Map();
// We store all the DOMTopLevelEventTypes and their React Types in pairs of two.
// Furthermore, we ignore prettier so we can keep the formatting sane.
// prettier-ignore
const discreteEvents = [
DOMTopLevelEventTypes.TOP_BLUR, 'blur',
DOMTopLevelEventTypes.TOP_CANCEL, 'cancel',
DOMTopLevelEventTypes.TOP_CLICK, 'click',
DOMTopLevelEventTypes.TOP_CLOSE, 'close',
DOMTopLevelEventTypes.TOP_CONTEXT_MENU, 'contextMenu',
DOMTopLevelEventTypes.TOP_COPY, 'copy',
DOMTopLevelEventTypes.TOP_CUT, 'cut',
DOMTopLevelEventTypes.TOP_AUX_CLICK, 'auxClick',
DOMTopLevelEventTypes.TOP_DOUBLE_CLICK, 'doubleClick',
DOMTopLevelEventTypes.TOP_DRAG_END, 'dragEnd',
DOMTopLevelEventTypes.TOP_DRAG_START, 'dragStart',
DOMTopLevelEventTypes.TOP_DROP, 'drop',
DOMTopLevelEventTypes.TOP_FOCUS, 'focus',
DOMTopLevelEventTypes.TOP_INPUT, 'input',
DOMTopLevelEventTypes.TOP_INVALID, 'invalid',
DOMTopLevelEventTypes.TOP_KEY_DOWN, 'keyDown',
DOMTopLevelEventTypes.TOP_KEY_PRESS, 'keyPress',
DOMTopLevelEventTypes.TOP_KEY_UP, 'keyUp',
DOMTopLevelEventTypes.TOP_MOUSE_DOWN, 'mouseDown',
DOMTopLevelEventTypes.TOP_MOUSE_UP, 'mouseUp',
DOMTopLevelEventTypes.TOP_PASTE, 'paste',
DOMTopLevelEventTypes.TOP_PAUSE, 'pause',
DOMTopLevelEventTypes.TOP_PLAY, 'play',
DOMTopLevelEventTypes.TOP_POINTER_CANCEL, 'pointerCancel',
DOMTopLevelEventTypes.TOP_POINTER_DOWN, 'pointerDown',
DOMTopLevelEventTypes.TOP_POINTER_UP, 'pointerUp',
DOMTopLevelEventTypes.TOP_RATE_CHANGE, 'rateChange',
DOMTopLevelEventTypes.TOP_RESET, 'reset',
DOMTopLevelEventTypes.TOP_SEEKED, 'seeked',
DOMTopLevelEventTypes.TOP_SUBMIT, 'submit',
DOMTopLevelEventTypes.TOP_TOUCH_CANCEL, 'touchCancel',
DOMTopLevelEventTypes.TOP_TOUCH_END, 'touchEnd',
DOMTopLevelEventTypes.TOP_TOUCH_START, 'touchStart',
DOMTopLevelEventTypes.TOP_VOLUME_CHANGE, 'volumeChange',
];
// prettier-ignore
const userBlockingEvents = [
DOMTopLevelEventTypes.TOP_DRAG, 'drag',
DOMTopLevelEventTypes.TOP_DRAG_ENTER, 'dragEnter',
DOMTopLevelEventTypes.TOP_DRAG_EXIT, 'dragExit',
DOMTopLevelEventTypes.TOP_DRAG_LEAVE, 'dragLeave',
DOMTopLevelEventTypes.TOP_DRAG_OVER, 'dragOver',
DOMTopLevelEventTypes.TOP_MOUSE_MOVE, 'mouseMove',
DOMTopLevelEventTypes.TOP_MOUSE_OUT, 'mouseOut',
DOMTopLevelEventTypes.TOP_MOUSE_OVER, 'mouseOver',
DOMTopLevelEventTypes.TOP_POINTER_MOVE, 'pointerMove',
DOMTopLevelEventTypes.TOP_POINTER_OUT, 'pointerOut',
DOMTopLevelEventTypes.TOP_POINTER_OVER, 'pointerOver',
DOMTopLevelEventTypes.TOP_SCROLL, 'scroll',
DOMTopLevelEventTypes.TOP_TOGGLE, 'toggle',
DOMTopLevelEventTypes.TOP_TOUCH_MOVE, 'touchMove',
DOMTopLevelEventTypes.TOP_WHEEL, 'wheel',
];
// prettier-ignore
const continuousEvents = [
DOMTopLevelEventTypes.TOP_ABORT, 'abort',
DOMTopLevelEventTypes.TOP_ANIMATION_END, 'animationEnd',
DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION, 'animationIteration',
DOMTopLevelEventTypes.TOP_ANIMATION_START, 'animationStart',
DOMTopLevelEventTypes.TOP_CAN_PLAY, 'canPlay',
DOMTopLevelEventTypes.TOP_CAN_PLAY_THROUGH, 'canPlayThrough',
DOMTopLevelEventTypes.TOP_DURATION_CHANGE, 'durationChange',
DOMTopLevelEventTypes.TOP_EMPTIED, 'emptied',
DOMTopLevelEventTypes.TOP_ENCRYPTED, 'encrypted',
DOMTopLevelEventTypes.TOP_ENDED, 'ended',
DOMTopLevelEventTypes.TOP_ERROR, 'error',
DOMTopLevelEventTypes.TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture',
DOMTopLevelEventTypes.TOP_LOAD, 'load',
DOMTopLevelEventTypes.TOP_LOADED_DATA, 'loadedData',
DOMTopLevelEventTypes.TOP_LOADED_METADATA, 'loadedMetadata',
DOMTopLevelEventTypes.TOP_LOAD_START, 'loadStart',
DOMTopLevelEventTypes.TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture',
DOMTopLevelEventTypes.TOP_PLAYING, 'playing',
DOMTopLevelEventTypes.TOP_PROGRESS, 'progress',
DOMTopLevelEventTypes.TOP_SEEKING, 'seeking',
DOMTopLevelEventTypes.TOP_STALLED, 'stalled',
DOMTopLevelEventTypes.TOP_SUSPEND, 'suspend',
DOMTopLevelEventTypes.TOP_TIME_UPDATE, 'timeUpdate',
DOMTopLevelEventTypes.TOP_TRANSITION_END, 'transitionEnd',
DOMTopLevelEventTypes.TOP_WAITING, 'waiting',
];
/**
* Turns
* ['abort', ...]
* into
* eventTypes = {
* 'abort': {
* phasedRegistrationNames: {
* bubbled: 'onAbort',
* captured: 'onAbortCapture',
* },
* dependencies: [TOP_ABORT],
* },
* ...
* };
* topLevelEventsToDispatchConfig = new Map([
* [TOP_ABORT, { sameConfig }],
* ]);
*/
function processTopEventTypesByPriority(
eventTypes: Array<DOMTopLevelEventType | string>,
priority: EventPriority,
): void {
// As the event types are in pairs of two, we need to iterate
// through in twos. The events are in pairs of two to save code
// and improve init perf of processing this array, as it will
// result in far fewer object allocations and property accesses
// if we only use three arrays to process all the categories of
// instead of tuples.
for (let i = 0; i < eventTypes.length; i += 2) {
const topEvent = ((eventTypes[i]: any): DOMTopLevelEventType);
const event = ((eventTypes[i + 1]: any): string);
const capitalizedEvent = event[0].toUpperCase() + event.slice(1);
const onEvent = 'on' + capitalizedEvent;
const config = {
phasedRegistrationNames: {
bubbled: onEvent,
captured: onEvent + 'Capture',
},
dependencies: [topEvent],
eventPriority: priority,
};
eventPriorities.set(topEvent, priority);
topLevelEventsToDispatchConfig.set(topEvent, config);
simpleEventPluginEventTypes[event] = config;
}
}
processTopEventTypesByPriority(discreteEvents, DiscreteEvent);
processTopEventTypesByPriority(userBlockingEvents, UserBlockingEvent);
processTopEventTypesByPriority(continuousEvents, ContinuousEvent);
export function getEventPriorityForPluginSystem(
topLevelType: TopLevelType,
): EventPriority {
const priority = eventPriorities.get(topLevelType);
// Default to a ContinuousEvent. Note: we might
// want to warn if we can't detect the priority
// for the event.
return priority === undefined ? ContinuousEvent : priority;
}