mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove event constants (#19276)
* Remove opaque event type * Rename type and merge files * Use literals where we have Flow coverage * Flowify some plugins * Remove constants except necessary ones
This commit is contained in:
+20
-28
@@ -91,14 +91,6 @@ import {
|
||||
listenToNonDelegatedEvent,
|
||||
} from '../events/DOMPluginEventSystem';
|
||||
import {getEventListenerMap} from './ReactDOMComponentTree';
|
||||
import {
|
||||
TOP_LOAD,
|
||||
TOP_ERROR,
|
||||
TOP_TOGGLE,
|
||||
TOP_INVALID,
|
||||
TOP_CANCEL,
|
||||
TOP_CLOSE,
|
||||
} from '../events/DOMTopLevelEventTypes';
|
||||
|
||||
let didWarnInvalidHydration = false;
|
||||
let didWarnScriptTags = false;
|
||||
@@ -542,8 +534,8 @@ export function setInitialProperties(
|
||||
let props: Object;
|
||||
switch (tag) {
|
||||
case 'dialog':
|
||||
listenToNonDelegatedEvent(TOP_CANCEL, domElement);
|
||||
listenToNonDelegatedEvent(TOP_CLOSE, domElement);
|
||||
listenToNonDelegatedEvent('cancel', domElement);
|
||||
listenToNonDelegatedEvent('close', domElement);
|
||||
props = rawProps;
|
||||
break;
|
||||
case 'iframe':
|
||||
@@ -551,7 +543,7 @@ export function setInitialProperties(
|
||||
case 'embed':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the load event.
|
||||
listenToNonDelegatedEvent(TOP_LOAD, domElement);
|
||||
listenToNonDelegatedEvent('load', domElement);
|
||||
props = rawProps;
|
||||
break;
|
||||
case 'video':
|
||||
@@ -566,7 +558,7 @@ export function setInitialProperties(
|
||||
case 'source':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the error event.
|
||||
listenToNonDelegatedEvent(TOP_ERROR, domElement);
|
||||
listenToNonDelegatedEvent('error', domElement);
|
||||
props = rawProps;
|
||||
break;
|
||||
case 'img':
|
||||
@@ -574,14 +566,14 @@ export function setInitialProperties(
|
||||
case 'link':
|
||||
// We listen to these events in case to ensure emulated bubble
|
||||
// listeners still fire for error and load events.
|
||||
listenToNonDelegatedEvent(TOP_ERROR, domElement);
|
||||
listenToNonDelegatedEvent(TOP_LOAD, domElement);
|
||||
listenToNonDelegatedEvent('error', domElement);
|
||||
listenToNonDelegatedEvent('load', domElement);
|
||||
props = rawProps;
|
||||
break;
|
||||
case 'details':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the toggle event.
|
||||
listenToNonDelegatedEvent(TOP_TOGGLE, domElement);
|
||||
listenToNonDelegatedEvent('toggle', domElement);
|
||||
props = rawProps;
|
||||
break;
|
||||
case 'input':
|
||||
@@ -589,7 +581,7 @@ export function setInitialProperties(
|
||||
props = ReactDOMInputGetHostProps(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
@@ -603,7 +595,7 @@ export function setInitialProperties(
|
||||
props = ReactDOMSelectGetHostProps(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
@@ -613,7 +605,7 @@ export function setInitialProperties(
|
||||
props = ReactDOMTextareaGetHostProps(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
@@ -947,15 +939,15 @@ export function diffHydratedProperties(
|
||||
// TODO: Make sure that we check isMounted before firing any of these events.
|
||||
switch (tag) {
|
||||
case 'dialog':
|
||||
listenToNonDelegatedEvent(TOP_CANCEL, domElement);
|
||||
listenToNonDelegatedEvent(TOP_CLOSE, domElement);
|
||||
listenToNonDelegatedEvent('cancel', domElement);
|
||||
listenToNonDelegatedEvent('close', domElement);
|
||||
break;
|
||||
case 'iframe':
|
||||
case 'object':
|
||||
case 'embed':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the load event.
|
||||
listenToNonDelegatedEvent(TOP_LOAD, domElement);
|
||||
listenToNonDelegatedEvent('load', domElement);
|
||||
break;
|
||||
case 'video':
|
||||
case 'audio':
|
||||
@@ -968,26 +960,26 @@ export function diffHydratedProperties(
|
||||
case 'source':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the error event.
|
||||
listenToNonDelegatedEvent(TOP_ERROR, domElement);
|
||||
listenToNonDelegatedEvent('error', domElement);
|
||||
break;
|
||||
case 'img':
|
||||
case 'image':
|
||||
case 'link':
|
||||
// We listen to these events in case to ensure emulated bubble
|
||||
// listeners still fire for error and load events.
|
||||
listenToNonDelegatedEvent(TOP_ERROR, domElement);
|
||||
listenToNonDelegatedEvent(TOP_LOAD, domElement);
|
||||
listenToNonDelegatedEvent('error', domElement);
|
||||
listenToNonDelegatedEvent('load', domElement);
|
||||
break;
|
||||
case 'details':
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the toggle event.
|
||||
listenToNonDelegatedEvent(TOP_TOGGLE, domElement);
|
||||
listenToNonDelegatedEvent('toggle', domElement);
|
||||
break;
|
||||
case 'input':
|
||||
ReactDOMInputInitWrapperState(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
@@ -999,7 +991,7 @@ export function diffHydratedProperties(
|
||||
ReactDOMSelectInitWrapperState(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
@@ -1008,7 +1000,7 @@ export function diffHydratedProperties(
|
||||
ReactDOMTextareaInitWrapperState(domElement, rawProps);
|
||||
// We listen to this event in case to ensure emulated bubble
|
||||
// listeners still fire for the invalid event.
|
||||
listenToNonDelegatedEvent(TOP_INVALID, domElement);
|
||||
listenToNonDelegatedEvent('invalid', domElement);
|
||||
// For controlled components we always need to ensure we're listening
|
||||
// to onChange. Even if there is no listener.
|
||||
ensureListeningTo(rootContainerElement, 'onChange', domElement);
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import type {
|
||||
SuspenseInstance,
|
||||
Props,
|
||||
} from './ReactDOMHostConfig';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
|
||||
import {
|
||||
HostComponent,
|
||||
@@ -41,7 +41,7 @@ const internalEventHandlersKey = '__reactEvents$' + randomKey;
|
||||
const internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
|
||||
|
||||
export type ElementListenerMap = Map<
|
||||
DOMTopLevelEventType | string,
|
||||
DOMEventName | string,
|
||||
ElementListenerMapEntry | null,
|
||||
>;
|
||||
|
||||
|
||||
+13
-13
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
import type {EventPriority, ReactScopeInstance} from 'shared/ReactTypes';
|
||||
import type {
|
||||
ReactDOMEventHandle,
|
||||
@@ -69,7 +69,7 @@ function isReactScope(target: EventTarget | ReactScopeInstance): boolean {
|
||||
}
|
||||
|
||||
function createEventHandleListener(
|
||||
type: DOMTopLevelEventType,
|
||||
type: DOMEventName,
|
||||
isCapturePhaseListener: boolean,
|
||||
callback: (SyntheticEvent<EventTarget>) => void,
|
||||
): ReactDOMEventHandleListener {
|
||||
@@ -82,7 +82,7 @@ function createEventHandleListener(
|
||||
|
||||
function registerEventOnNearestTargetContainer(
|
||||
targetFiber: Fiber,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
isPassiveListener: boolean | void,
|
||||
listenerPriority: EventPriority | void,
|
||||
isCapturePhaseListener: boolean,
|
||||
@@ -102,7 +102,7 @@ function registerEventOnNearestTargetContainer(
|
||||
targetContainer = ((targetContainer.parentNode: any): Element);
|
||||
}
|
||||
listenToNativeEvent(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
targetContainer,
|
||||
targetElement,
|
||||
@@ -113,7 +113,7 @@ function registerEventOnNearestTargetContainer(
|
||||
|
||||
function registerReactDOMEvent(
|
||||
target: EventTarget | ReactScopeInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
isPassiveListener: boolean | void,
|
||||
isCapturePhaseListener: boolean,
|
||||
listenerPriority: EventPriority | void,
|
||||
@@ -132,7 +132,7 @@ function registerReactDOMEvent(
|
||||
}
|
||||
registerEventOnNearestTargetContainer(
|
||||
targetFiber,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
isCapturePhaseListener,
|
||||
@@ -147,7 +147,7 @@ function registerReactDOMEvent(
|
||||
}
|
||||
registerEventOnNearestTargetContainer(
|
||||
targetFiber,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
isCapturePhaseListener,
|
||||
@@ -158,7 +158,7 @@ function registerReactDOMEvent(
|
||||
// These are valid event targets, but they are also
|
||||
// non-managed React nodes.
|
||||
listenToNativeEvent(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
eventTarget,
|
||||
null,
|
||||
@@ -180,7 +180,7 @@ export function createEventHandle(
|
||||
options?: EventHandleOptions,
|
||||
): ReactDOMEventHandle {
|
||||
if (enableCreateEventHandleAPI) {
|
||||
const topLevelType = ((type: any): DOMTopLevelEventType);
|
||||
const domEventName = ((type: any): DOMEventName);
|
||||
let isCapturePhaseListener = false;
|
||||
let isPassiveListener = undefined; // Undefined means to use the browser default
|
||||
let listenerPriority;
|
||||
@@ -201,7 +201,7 @@ export function createEventHandle(
|
||||
}
|
||||
}
|
||||
if (listenerPriority === undefined) {
|
||||
listenerPriority = getEventPriorityForListenerSystem(topLevelType);
|
||||
listenerPriority = getEventPriorityForListenerSystem(domEventName);
|
||||
}
|
||||
|
||||
const registeredReactDOMEvents = new PossiblyWeakSet();
|
||||
@@ -219,16 +219,16 @@ export function createEventHandle(
|
||||
registeredReactDOMEvents.add(target);
|
||||
registerReactDOMEvent(
|
||||
target,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isPassiveListener,
|
||||
isCapturePhaseListener,
|
||||
listenerPriority,
|
||||
);
|
||||
// Add the event to our known event types list.
|
||||
addEventTypeToDispatchConfig(topLevelType);
|
||||
addEventTypeToDispatchConfig(domEventName);
|
||||
}
|
||||
const listener = createEventHandleListener(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
callback,
|
||||
);
|
||||
|
||||
+4
-5
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {TopLevelType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {
|
||||
BoundingRect,
|
||||
@@ -79,7 +79,6 @@ import {
|
||||
enableScopeAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
|
||||
import {listenToReactEvent} from '../events/DOMPluginEventSystem';
|
||||
|
||||
export type Type = string;
|
||||
@@ -504,7 +503,7 @@ export function insertInContainerBefore(
|
||||
}
|
||||
}
|
||||
|
||||
function createEvent(type: TopLevelType, bubbles: boolean): Event {
|
||||
function createEvent(type: DOMEventName, bubbles: boolean): Event {
|
||||
const event = document.createEvent('Event');
|
||||
event.initEvent(((type: any): string), bubbles, false);
|
||||
return event;
|
||||
@@ -512,7 +511,7 @@ function createEvent(type: TopLevelType, bubbles: boolean): Event {
|
||||
|
||||
function dispatchBeforeDetachedBlur(target: HTMLElement): void {
|
||||
if (enableDeprecatedFlareAPI || enableCreateEventHandleAPI) {
|
||||
const event = createEvent(TOP_BEFORE_BLUR, true);
|
||||
const event = createEvent('beforeblur', true);
|
||||
// Dispatch "beforeblur" directly on the target,
|
||||
// so it gets picked up by the event system and
|
||||
// can propagate through the React internal tree.
|
||||
@@ -522,7 +521,7 @@ function dispatchBeforeDetachedBlur(target: HTMLElement): void {
|
||||
|
||||
function dispatchAfterDetachedBlur(target: HTMLElement): void {
|
||||
if (enableDeprecatedFlareAPI || enableCreateEventHandleAPI) {
|
||||
const event = createEvent(TOP_AFTER_BLUR, false);
|
||||
const event = createEvent('afterblur', false);
|
||||
// So we know what was detached, make the relatedTarget the
|
||||
// detached target on the "afterblur" event.
|
||||
(event: any).relatedTarget = target;
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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 getVendorPrefixedEventName from './getVendorPrefixedEventName';
|
||||
|
||||
export type DOMEventName =
|
||||
| 'abort'
|
||||
| 'afterblur' // Not a real event. This is used by event experiments.
|
||||
// These are vendor-prefixed so you should use the exported constants instead:
|
||||
// 'animationiteration' |
|
||||
// 'animationend |
|
||||
// 'animationstart' |
|
||||
| 'beforeblur' // Not a real event. This is used by event experiments.
|
||||
| 'canplay'
|
||||
| 'canplaythrough'
|
||||
| 'cancel'
|
||||
| 'change'
|
||||
| 'click'
|
||||
| 'close'
|
||||
| 'compositionend'
|
||||
| 'compositionstart'
|
||||
| 'compositionupdate'
|
||||
| 'contextmenu'
|
||||
| 'copy'
|
||||
| 'cut'
|
||||
| 'dblclick'
|
||||
| 'auxclick'
|
||||
| 'drag'
|
||||
| 'dragend'
|
||||
| 'dragenter'
|
||||
| 'dragexit'
|
||||
| 'dragleave'
|
||||
| 'dragover'
|
||||
| 'dragstart'
|
||||
| 'drop'
|
||||
| 'durationchange'
|
||||
| 'emptied'
|
||||
| 'encrypted'
|
||||
| 'ended'
|
||||
| 'error'
|
||||
| 'focusin'
|
||||
| 'focusout'
|
||||
| 'gotpointercapture'
|
||||
| 'input'
|
||||
| 'invalid'
|
||||
| 'keydown'
|
||||
| 'keypress'
|
||||
| 'keyup'
|
||||
| 'load'
|
||||
| 'loadstart'
|
||||
| 'loadeddata'
|
||||
| 'loadedmetadata'
|
||||
| 'lostpointercapture'
|
||||
| 'mousedown'
|
||||
| 'mousemove'
|
||||
| 'mouseout'
|
||||
| 'mouseover'
|
||||
| 'mouseup'
|
||||
| 'paste'
|
||||
| 'pause'
|
||||
| 'play'
|
||||
| 'playing'
|
||||
| 'pointercancel'
|
||||
| 'pointerdown'
|
||||
| 'pointerenter'
|
||||
| 'pointerleave'
|
||||
| 'pointermove'
|
||||
| 'pointerout'
|
||||
| 'pointerover'
|
||||
| 'pointerup'
|
||||
| 'progress'
|
||||
| 'ratechange'
|
||||
| 'reset'
|
||||
| 'scroll'
|
||||
| 'seeked'
|
||||
| 'seeking'
|
||||
| 'selectionchange'
|
||||
| 'stalled'
|
||||
| 'submit'
|
||||
| 'suspend'
|
||||
| 'textInput' // Intentionally camelCase. Non-standard.
|
||||
| 'timeupdate'
|
||||
| 'toggle'
|
||||
| 'touchcancel'
|
||||
| 'touchend'
|
||||
| 'touchmove'
|
||||
| 'touchstart'
|
||||
// These are vendor-prefixed so you should use the exported constants instead:
|
||||
// 'transitionend' |
|
||||
| 'volumechange'
|
||||
| 'waiting'
|
||||
| 'wheel';
|
||||
|
||||
export const ANIMATION_END: DOMEventName = getVendorPrefixedEventName(
|
||||
'animationend',
|
||||
);
|
||||
export const ANIMATION_ITERATION: DOMEventName = getVendorPrefixedEventName(
|
||||
'animationiteration',
|
||||
);
|
||||
export const ANIMATION_START: DOMEventName = getVendorPrefixedEventName(
|
||||
'animationstart',
|
||||
);
|
||||
export const TRANSITION_END: DOMEventName = getVendorPrefixedEventName(
|
||||
'transitionend',
|
||||
);
|
||||
+99
-100
@@ -8,13 +8,15 @@
|
||||
*/
|
||||
|
||||
import type {EventPriority} from 'shared/ReactTypes';
|
||||
import type {
|
||||
TopLevelType,
|
||||
DOMTopLevelEventType,
|
||||
} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
|
||||
import {registerTwoPhaseEvent} from './EventRegistry';
|
||||
import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
|
||||
import {
|
||||
ANIMATION_END,
|
||||
ANIMATION_ITERATION,
|
||||
ANIMATION_START,
|
||||
TRANSITION_END,
|
||||
} from './DOMEventNames';
|
||||
import {
|
||||
DiscreteEvent,
|
||||
UserBlockingEvent,
|
||||
@@ -24,7 +26,7 @@ import {
|
||||
import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
|
||||
|
||||
export const topLevelEventsToReactNames: Map<
|
||||
TopLevelType,
|
||||
DOMEventName,
|
||||
string | null,
|
||||
> = new Map();
|
||||
|
||||
@@ -41,104 +43,101 @@ const eventPriorities = new Map();
|
||||
|
||||
// prettier-ignore
|
||||
const discreteEventPairsForSimpleEventPlugin = [
|
||||
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_IN, 'focus',
|
||||
DOMTopLevelEventTypes.TOP_FOCUS_OUT, 'blur',
|
||||
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',
|
||||
('cancel': DOMEventName), 'cancel',
|
||||
('click': DOMEventName), 'click',
|
||||
('close': DOMEventName), 'close',
|
||||
('contextmenu': DOMEventName), 'contextMenu',
|
||||
('copy': DOMEventName), 'copy',
|
||||
('cut': DOMEventName), 'cut',
|
||||
('auxclick': DOMEventName), 'auxClick',
|
||||
('dblclick': DOMEventName), 'doubleClick', // Careful!
|
||||
('dragend': DOMEventName), 'dragEnd',
|
||||
('dragstart': DOMEventName), 'dragStart',
|
||||
('drop': DOMEventName), 'drop',
|
||||
('focusin': DOMEventName), 'focus', // Careful!
|
||||
('focusout': DOMEventName), 'blur', // Careful!
|
||||
('input': DOMEventName), 'input',
|
||||
('invalid': DOMEventName), 'invalid',
|
||||
('keydown': DOMEventName), 'keyDown',
|
||||
('keypress': DOMEventName), 'keyPress',
|
||||
('keyup': DOMEventName), 'keyUp',
|
||||
('mousedown': DOMEventName), 'mouseDown',
|
||||
('mouseup': DOMEventName), 'mouseUp',
|
||||
('paste': DOMEventName), 'paste',
|
||||
('pause': DOMEventName), 'pause',
|
||||
('play': DOMEventName), 'play',
|
||||
('pointercancel': DOMEventName), 'pointerCancel',
|
||||
('pointerdown': DOMEventName), 'pointerDown',
|
||||
('pointerup': DOMEventName), 'pointerUp',
|
||||
('ratechange': DOMEventName), 'rateChange',
|
||||
('reset': DOMEventName), 'reset',
|
||||
('seeked': DOMEventName), 'seeked',
|
||||
('submit': DOMEventName), 'submit',
|
||||
('touchcancel': DOMEventName), 'touchCancel',
|
||||
('touchend': DOMEventName), 'touchEnd',
|
||||
('touchstart': DOMEventName), 'touchStart',
|
||||
('volumechange': DOMEventName), 'volumeChange',
|
||||
];
|
||||
|
||||
const otherDiscreteEvents = [
|
||||
DOMTopLevelEventTypes.TOP_CHANGE,
|
||||
DOMTopLevelEventTypes.TOP_SELECTION_CHANGE,
|
||||
DOMTopLevelEventTypes.TOP_TEXT_INPUT,
|
||||
DOMTopLevelEventTypes.TOP_COMPOSITION_START,
|
||||
DOMTopLevelEventTypes.TOP_COMPOSITION_END,
|
||||
DOMTopLevelEventTypes.TOP_COMPOSITION_UPDATE,
|
||||
const otherDiscreteEvents: Array<DOMEventName> = [
|
||||
'change',
|
||||
'selectionchange',
|
||||
'textInput',
|
||||
'compositionstart',
|
||||
'compositionend',
|
||||
'compositionupdate',
|
||||
];
|
||||
|
||||
if (enableCreateEventHandleAPI) {
|
||||
otherDiscreteEvents.push(
|
||||
DOMTopLevelEventTypes.TOP_BEFORE_BLUR,
|
||||
DOMTopLevelEventTypes.TOP_AFTER_BLUR,
|
||||
);
|
||||
otherDiscreteEvents.push('beforeblur', 'afterblur');
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
const userBlockingPairsForSimpleEventPlugin = [
|
||||
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',
|
||||
const userBlockingPairsForSimpleEventPlugin: Array<string | DOMEventName> = [
|
||||
('drag': DOMEventName), 'drag',
|
||||
('dragenter': DOMEventName), 'dragEnter',
|
||||
('dragexit': DOMEventName), 'dragExit',
|
||||
('dragleave': DOMEventName), 'dragLeave',
|
||||
('dragover': DOMEventName), 'dragOver',
|
||||
('mousemove': DOMEventName), 'mouseMove',
|
||||
('mouseout': DOMEventName), 'mouseOut',
|
||||
('mouseover': DOMEventName), 'mouseOver',
|
||||
('pointermove': DOMEventName), 'pointerMove',
|
||||
('pointerout': DOMEventName), 'pointerOut',
|
||||
('pointerover': DOMEventName), 'pointerOver',
|
||||
('scroll': DOMEventName), 'scroll',
|
||||
('toggle': DOMEventName), 'toggle',
|
||||
('touchmove': DOMEventName), 'touchMove',
|
||||
('wheel': DOMEventName), 'wheel',
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
const continuousPairsForSimpleEventPlugin = [
|
||||
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',
|
||||
const continuousPairsForSimpleEventPlugin: Array<string | DOMEventName> = [
|
||||
('abort': DOMEventName), 'abort',
|
||||
(ANIMATION_END: DOMEventName), 'animationEnd',
|
||||
(ANIMATION_ITERATION: DOMEventName), 'animationIteration',
|
||||
(ANIMATION_START: DOMEventName), 'animationStart',
|
||||
('canplay': DOMEventName), 'canPlay',
|
||||
('canplaythrough': DOMEventName), 'canPlayThrough',
|
||||
('durationchange': DOMEventName), 'durationChange',
|
||||
('emptied': DOMEventName), 'emptied',
|
||||
('encrypted': DOMEventName), 'encrypted',
|
||||
('ended': DOMEventName), 'ended',
|
||||
('error': DOMEventName), 'error',
|
||||
('gotpointercapture': DOMEventName), 'gotPointerCapture',
|
||||
('load': DOMEventName), 'load',
|
||||
('loadeddata': DOMEventName), 'loadedData',
|
||||
('loadedmetadata': DOMEventName), 'loadedMetadata',
|
||||
('loadstart': DOMEventName), 'loadStart',
|
||||
('lostpointercapture': DOMEventName), 'lostPointerCapture',
|
||||
('playing': DOMEventName), 'playing',
|
||||
('progress': DOMEventName), 'progress',
|
||||
('seeking': DOMEventName), 'seeking',
|
||||
('stalled': DOMEventName), 'stalled',
|
||||
('suspend': DOMEventName), 'suspend',
|
||||
('timeupdate': DOMEventName), 'timeUpdate',
|
||||
(TRANSITION_END: DOMEventName), 'transitionEnd',
|
||||
('waiting': DOMEventName), 'waiting',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -148,13 +147,13 @@ const continuousPairsForSimpleEventPlugin = [
|
||||
* into
|
||||
*
|
||||
* topLevelEventsToReactNames = new Map([
|
||||
* [TOP_ABORT, 'onAbort'],
|
||||
* ['abort', 'onAbort'],
|
||||
* ]);
|
||||
*
|
||||
* and registers them.
|
||||
*/
|
||||
function registerSimplePluginEventsAndSetTheirPriorities(
|
||||
eventTypes: Array<DOMTopLevelEventType | string>,
|
||||
eventTypes: Array<DOMEventName | string>,
|
||||
priority: EventPriority,
|
||||
): void {
|
||||
// As the event types are in pairs of two, we need to iterate
|
||||
@@ -164,7 +163,7 @@ function registerSimplePluginEventsAndSetTheirPriorities(
|
||||
// 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 topEvent = ((eventTypes[i]: any): DOMEventName);
|
||||
const event = ((eventTypes[i + 1]: any): string);
|
||||
const capitalizedEvent = event[0].toUpperCase() + event.slice(1);
|
||||
const reactName = 'on' + capitalizedEvent;
|
||||
@@ -175,7 +174,7 @@ function registerSimplePluginEventsAndSetTheirPriorities(
|
||||
}
|
||||
|
||||
function setEventPriorities(
|
||||
eventTypes: Array<DOMTopLevelEventType | string>,
|
||||
eventTypes: Array<DOMEventName>,
|
||||
priority: EventPriority,
|
||||
): void {
|
||||
for (let i = 0; i < eventTypes.length; i++) {
|
||||
@@ -184,9 +183,9 @@ function setEventPriorities(
|
||||
}
|
||||
|
||||
export function getEventPriorityForPluginSystem(
|
||||
topLevelType: TopLevelType,
|
||||
domEventName: DOMEventName,
|
||||
): EventPriority {
|
||||
const priority = eventPriorities.get(topLevelType);
|
||||
const priority = eventPriorities.get(domEventName);
|
||||
// Default to a ContinuousEvent. Note: we might
|
||||
// want to warn if we can't detect the priority
|
||||
// for the event.
|
||||
@@ -194,7 +193,7 @@ export function getEventPriorityForPluginSystem(
|
||||
}
|
||||
|
||||
export function getEventPriorityForListenerSystem(
|
||||
type: DOMTopLevelEventType,
|
||||
type: DOMEventName,
|
||||
): EventPriority {
|
||||
const priority = eventPriorities.get(type);
|
||||
if (priority !== undefined) {
|
||||
|
||||
+68
-104
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {TopLevelType, DOMTopLevelEventType} from './TopLevelEventTypes';
|
||||
import type {DOMEventName} from './DOMEventNames';
|
||||
import {
|
||||
type EventSystemFlags,
|
||||
SHOULD_NOT_DEFER_CLICK_FOR_FB_SUPPORT_MODE,
|
||||
@@ -37,40 +37,6 @@ import {
|
||||
} from 'react-reconciler/src/ReactWorkTags';
|
||||
|
||||
import getEventTarget from './getEventTarget';
|
||||
import {
|
||||
TOP_LOAD,
|
||||
TOP_ABORT,
|
||||
TOP_CANCEL,
|
||||
TOP_INVALID,
|
||||
TOP_SCROLL,
|
||||
TOP_CLOSE,
|
||||
TOP_CAN_PLAY,
|
||||
TOP_CAN_PLAY_THROUGH,
|
||||
TOP_DURATION_CHANGE,
|
||||
TOP_EMPTIED,
|
||||
TOP_ENCRYPTED,
|
||||
TOP_ENDED,
|
||||
TOP_ERROR,
|
||||
TOP_WAITING,
|
||||
TOP_VOLUME_CHANGE,
|
||||
TOP_TIME_UPDATE,
|
||||
TOP_SUSPEND,
|
||||
TOP_STALLED,
|
||||
TOP_SEEKING,
|
||||
TOP_SEEKED,
|
||||
TOP_PLAY,
|
||||
TOP_PAUSE,
|
||||
TOP_LOAD_START,
|
||||
TOP_LOADED_DATA,
|
||||
TOP_LOADED_METADATA,
|
||||
TOP_RATE_CHANGE,
|
||||
TOP_PROGRESS,
|
||||
TOP_PLAYING,
|
||||
TOP_CLICK,
|
||||
TOP_SELECTION_CHANGE,
|
||||
TOP_TOGGLE,
|
||||
getRawEventName,
|
||||
} from './DOMTopLevelEventTypes';
|
||||
import {
|
||||
getClosestInstanceFromNode,
|
||||
getEventListenerMap,
|
||||
@@ -128,7 +94,7 @@ BeforeInputEventPlugin.registerEvents();
|
||||
|
||||
function extractEvents(
|
||||
dispatchQueue: DispatchQueue,
|
||||
topLevelType: TopLevelType,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
@@ -143,7 +109,7 @@ function extractEvents(
|
||||
// us to ship builds of React without the polyfilled plugins below.
|
||||
SimpleEventPlugin.extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -172,7 +138,7 @@ function extractEvents(
|
||||
if (shouldProcessPolyfillPlugins) {
|
||||
EnterLeaveEventPlugin.extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -181,7 +147,7 @@ function extractEvents(
|
||||
);
|
||||
ChangeEventPlugin.extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -190,7 +156,7 @@ function extractEvents(
|
||||
);
|
||||
SelectEventPlugin.extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -199,7 +165,7 @@ function extractEvents(
|
||||
);
|
||||
BeforeInputEventPlugin.extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -210,42 +176,42 @@ function extractEvents(
|
||||
}
|
||||
|
||||
// List of events that need to be individually attached to media elements.
|
||||
export const mediaEventTypes = [
|
||||
TOP_ABORT,
|
||||
TOP_CAN_PLAY,
|
||||
TOP_CAN_PLAY_THROUGH,
|
||||
TOP_DURATION_CHANGE,
|
||||
TOP_EMPTIED,
|
||||
TOP_ENCRYPTED,
|
||||
TOP_ENDED,
|
||||
TOP_ERROR,
|
||||
TOP_LOADED_DATA,
|
||||
TOP_LOADED_METADATA,
|
||||
TOP_LOAD_START,
|
||||
TOP_PAUSE,
|
||||
TOP_PLAY,
|
||||
TOP_PLAYING,
|
||||
TOP_PROGRESS,
|
||||
TOP_RATE_CHANGE,
|
||||
TOP_SEEKED,
|
||||
TOP_SEEKING,
|
||||
TOP_STALLED,
|
||||
TOP_SUSPEND,
|
||||
TOP_TIME_UPDATE,
|
||||
TOP_VOLUME_CHANGE,
|
||||
TOP_WAITING,
|
||||
export const mediaEventTypes: Array<DOMEventName> = [
|
||||
'abort',
|
||||
'canplay',
|
||||
'canplaythrough',
|
||||
'durationchange',
|
||||
'emptied',
|
||||
'encrypted',
|
||||
'ended',
|
||||
'error',
|
||||
'loadeddata',
|
||||
'loadedmetadata',
|
||||
'loadstart',
|
||||
'pause',
|
||||
'play',
|
||||
'playing',
|
||||
'progress',
|
||||
'ratechange',
|
||||
'seeked',
|
||||
'seeking',
|
||||
'stalled',
|
||||
'suspend',
|
||||
'timeupdate',
|
||||
'volumechange',
|
||||
'waiting',
|
||||
];
|
||||
|
||||
// We should not delegate these events to the container, but rather
|
||||
// set them on the actual target element itself. This is primarily
|
||||
// because these events do not consistently bubble in the DOM.
|
||||
export const nonDelegatedEvents: Set<DOMTopLevelEventType> = new Set([
|
||||
TOP_CANCEL,
|
||||
TOP_CLOSE,
|
||||
TOP_INVALID,
|
||||
TOP_LOAD,
|
||||
TOP_SCROLL,
|
||||
TOP_TOGGLE,
|
||||
export const nonDelegatedEvents: Set<DOMEventName> = new Set([
|
||||
'cancel',
|
||||
'close',
|
||||
'invalid',
|
||||
'load',
|
||||
'scroll',
|
||||
'toggle',
|
||||
// In order to reduce bytes, we insert the above array of media events
|
||||
// into this Set. Note: the "error" event isn't an exclusive media event,
|
||||
// and can occur on other elements too. Rather than duplicate that event,
|
||||
@@ -306,7 +272,7 @@ export function processDispatchQueue(
|
||||
}
|
||||
|
||||
function dispatchEventsForPlugins(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
targetInst: null | Fiber,
|
||||
@@ -316,7 +282,7 @@ function dispatchEventsForPlugins(
|
||||
const dispatchQueue: DispatchQueue = [];
|
||||
extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -336,13 +302,13 @@ function shouldUpgradeListener(
|
||||
}
|
||||
|
||||
export function listenToNonDelegatedEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
targetElement: Element,
|
||||
): void {
|
||||
const isCapturePhaseListener = false;
|
||||
const listenerMap = getEventListenerMap(targetElement);
|
||||
const listenerMapKey = getListenerMapKey(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
const listenerEntry = ((listenerMap.get(
|
||||
@@ -351,7 +317,7 @@ export function listenToNonDelegatedEvent(
|
||||
if (listenerEntry === undefined) {
|
||||
const listener = addTrappedEventListener(
|
||||
targetElement,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
PLUGIN_EVENT_SYSTEM | IS_NON_DELEGATED,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
@@ -360,7 +326,7 @@ export function listenToNonDelegatedEvent(
|
||||
}
|
||||
|
||||
export function listenToNativeEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
isCapturePhaseListener: boolean,
|
||||
rootContainerElement: EventTarget,
|
||||
targetElement: Element | null,
|
||||
@@ -369,10 +335,10 @@ export function listenToNativeEvent(
|
||||
eventSystemFlags?: EventSystemFlags = PLUGIN_EVENT_SYSTEM,
|
||||
): void {
|
||||
let target = rootContainerElement;
|
||||
// TOP_SELECTION_CHANGE needs to be attached to the document
|
||||
// selectionchange needs to be attached to the document
|
||||
// otherwise it won't capture incoming events that are only
|
||||
// triggered on the document directly.
|
||||
if (topLevelType === TOP_SELECTION_CHANGE) {
|
||||
if (domEventName === 'selectionchange') {
|
||||
target = (rootContainerElement: any).ownerDocument;
|
||||
}
|
||||
// If the event can be delegated (or is capture phase), we can
|
||||
@@ -382,7 +348,7 @@ export function listenToNativeEvent(
|
||||
if (
|
||||
targetElement !== null &&
|
||||
!isCapturePhaseListener &&
|
||||
nonDelegatedEvents.has(topLevelType)
|
||||
nonDelegatedEvents.has(domEventName)
|
||||
) {
|
||||
// For all non-delegated events, apart from scroll, we attach
|
||||
// their event listeners to the respective elements that their
|
||||
@@ -393,7 +359,7 @@ export function listenToNativeEvent(
|
||||
// TODO: ideally, we'd eventually apply the same logic to all
|
||||
// events from the nonDelegatedEvents list. Then we can remove
|
||||
// this special case and use the same logic for all events.
|
||||
if (topLevelType !== TOP_SCROLL) {
|
||||
if (domEventName !== 'scroll') {
|
||||
return;
|
||||
}
|
||||
eventSystemFlags |= IS_NON_DELEGATED;
|
||||
@@ -401,7 +367,7 @@ export function listenToNativeEvent(
|
||||
}
|
||||
const listenerMap = getEventListenerMap(target);
|
||||
const listenerMapKey = getListenerMapKey(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
const listenerEntry = ((listenerMap.get(
|
||||
@@ -417,7 +383,7 @@ export function listenToNativeEvent(
|
||||
if (shouldUpgrade) {
|
||||
removeTrappedEventListener(
|
||||
target,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
isCapturePhaseListener,
|
||||
((listenerEntry: any): ElementListenerMapEntry).listener,
|
||||
);
|
||||
@@ -427,7 +393,7 @@ export function listenToNativeEvent(
|
||||
}
|
||||
const listener = addTrappedEventListener(
|
||||
target,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
isCapturePhaseListener,
|
||||
false,
|
||||
@@ -490,7 +456,7 @@ export function listenToReactEvent(
|
||||
|
||||
function addTrappedEventListener(
|
||||
targetContainer: EventTarget,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
isCapturePhaseListener: boolean,
|
||||
isDeferredListenerForLegacyFBSupport?: boolean,
|
||||
@@ -499,7 +465,7 @@ function addTrappedEventListener(
|
||||
): any => void {
|
||||
let listener = createEventListenerWrapperWithPriority(
|
||||
targetContainer,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
listenerPriority,
|
||||
);
|
||||
@@ -514,8 +480,6 @@ function addTrappedEventListener(
|
||||
? (targetContainer: any).ownerDocument
|
||||
: targetContainer;
|
||||
|
||||
const rawEventName = getRawEventName(topLevelType);
|
||||
|
||||
let unsubscribeListener;
|
||||
// When legacyFBSupport is enabled, it's for when we
|
||||
// want to add a one time event listener to a container.
|
||||
@@ -533,7 +497,7 @@ function addTrappedEventListener(
|
||||
listener = function(...p) {
|
||||
removeEventListener(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
domEventName,
|
||||
unsubscribeListener,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
@@ -544,14 +508,14 @@ function addTrappedEventListener(
|
||||
if (enableCreateEventHandleAPI && isPassiveListener !== undefined) {
|
||||
unsubscribeListener = addEventCaptureListenerWithPassiveFlag(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
domEventName,
|
||||
listener,
|
||||
isPassiveListener,
|
||||
);
|
||||
} else {
|
||||
unsubscribeListener = addEventCaptureListener(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
domEventName,
|
||||
listener,
|
||||
);
|
||||
}
|
||||
@@ -559,14 +523,14 @@ function addTrappedEventListener(
|
||||
if (enableCreateEventHandleAPI && isPassiveListener !== undefined) {
|
||||
unsubscribeListener = addEventBubbleListenerWithPassiveFlag(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
domEventName,
|
||||
listener,
|
||||
isPassiveListener,
|
||||
);
|
||||
} else {
|
||||
unsubscribeListener = addEventBubbleListener(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
domEventName,
|
||||
listener,
|
||||
);
|
||||
}
|
||||
@@ -575,7 +539,7 @@ function addTrappedEventListener(
|
||||
}
|
||||
|
||||
function deferClickToDocumentForLegacyFBSupport(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
targetContainer: EventTarget,
|
||||
): void {
|
||||
// We defer all click events with legacy FB support mode on.
|
||||
@@ -584,7 +548,7 @@ function deferClickToDocumentForLegacyFBSupport(
|
||||
const isDeferredListenerForLegacyFBSupport = true;
|
||||
addTrappedEventListener(
|
||||
targetContainer,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
PLUGIN_EVENT_SYSTEM | IS_LEGACY_FB_SUPPORT_MODE,
|
||||
false,
|
||||
isDeferredListenerForLegacyFBSupport,
|
||||
@@ -603,7 +567,7 @@ function isMatchingRootContainer(
|
||||
}
|
||||
|
||||
export function dispatchEventForPluginEventSystem(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
targetInst: null | Fiber,
|
||||
@@ -626,10 +590,10 @@ export function dispatchEventForPluginEventSystem(
|
||||
// then we can defer the event to the "document", to allow
|
||||
// for legacy FB support, where the expected behavior was to
|
||||
// match React < 16 behavior of delegated clicks to the doc.
|
||||
topLevelType === TOP_CLICK &&
|
||||
domEventName === 'click' &&
|
||||
(eventSystemFlags & SHOULD_NOT_DEFER_CLICK_FOR_FB_SUPPORT_MODE) === 0
|
||||
) {
|
||||
deferClickToDocumentForLegacyFBSupport(topLevelType, targetContainer);
|
||||
deferClickToDocumentForLegacyFBSupport(domEventName, targetContainer);
|
||||
return;
|
||||
}
|
||||
if (targetInst !== null) {
|
||||
@@ -703,7 +667,7 @@ export function dispatchEventForPluginEventSystem(
|
||||
|
||||
batchedEventUpdates(() =>
|
||||
dispatchEventsForPlugins(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
ancestorInst,
|
||||
@@ -1045,7 +1009,7 @@ export function accumulateEventHandleNonManagedNodeListeners(
|
||||
const eventListeners = getEventHandlerListeners(currentTarget);
|
||||
if (eventListeners !== null) {
|
||||
const listenersArr = Array.from(eventListeners);
|
||||
const targetType = ((event.type: any): DOMTopLevelEventType);
|
||||
const targetType = ((event.type: any): DOMEventName);
|
||||
|
||||
for (let i = 0; i < listenersArr.length; i++) {
|
||||
const listener = listenersArr[i];
|
||||
@@ -1064,7 +1028,7 @@ export function accumulateEventHandleNonManagedNodeListeners(
|
||||
}
|
||||
}
|
||||
|
||||
export function addEventTypeToDispatchConfig(type: DOMTopLevelEventType): void {
|
||||
export function addEventTypeToDispatchConfig(type: DOMEventName): void {
|
||||
const reactName = topLevelEventsToReactNames.get(type);
|
||||
// If we don't have a reactName, then we're dealing with
|
||||
// an event type that React does not know about (i.e. a custom event).
|
||||
@@ -1077,8 +1041,8 @@ export function addEventTypeToDispatchConfig(type: DOMTopLevelEventType): void {
|
||||
}
|
||||
|
||||
export function getListenerMapKey(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
capture: boolean,
|
||||
): string {
|
||||
return `${getRawEventName(topLevelType)}__${capture ? 'capture' : 'bubble'}`;
|
||||
return `${domEventName}__${capture ? 'capture' : 'bubble'}`;
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* 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 {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
|
||||
import {
|
||||
unsafeCastStringToDOMTopLevelType,
|
||||
unsafeCastDOMTopLevelTypeToString,
|
||||
} from '../events/TopLevelEventTypes';
|
||||
import getVendorPrefixedEventName from './getVendorPrefixedEventName';
|
||||
|
||||
/**
|
||||
* To identify top level events in ReactDOM, we use constants defined by this
|
||||
* module. This is the only module that uses the unsafe* methods to express
|
||||
* that the constants actually correspond to the browser event names. This lets
|
||||
* us save some bundle size by avoiding a top level type -> event name map.
|
||||
* The rest of ReactDOM code should import top level types from this file.
|
||||
*/
|
||||
export const TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
|
||||
export const TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(
|
||||
getVendorPrefixedEventName('animationend'),
|
||||
);
|
||||
export const TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(
|
||||
getVendorPrefixedEventName('animationiteration'),
|
||||
);
|
||||
export const TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(
|
||||
getVendorPrefixedEventName('animationstart'),
|
||||
);
|
||||
export const TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
|
||||
export const TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType(
|
||||
'canplaythrough',
|
||||
);
|
||||
export const TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
|
||||
export const TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
|
||||
export const TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
|
||||
export const TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
|
||||
export const TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType(
|
||||
'compositionend',
|
||||
);
|
||||
export const TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType(
|
||||
'compositionstart',
|
||||
);
|
||||
export const TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType(
|
||||
'compositionupdate',
|
||||
);
|
||||
export const TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType(
|
||||
'contextmenu',
|
||||
);
|
||||
export const TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
|
||||
export const TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
|
||||
export const TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
|
||||
export const TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
|
||||
export const TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
|
||||
export const TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
|
||||
export const TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
|
||||
export const TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
|
||||
export const TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
|
||||
export const TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
|
||||
export const TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
|
||||
export const TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
|
||||
export const TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType(
|
||||
'durationchange',
|
||||
);
|
||||
export const TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
|
||||
export const TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
|
||||
export const TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
|
||||
export const TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
|
||||
export const TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType(
|
||||
'gotpointercapture',
|
||||
);
|
||||
export const TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
|
||||
export const TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
|
||||
export const TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
|
||||
export const TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
|
||||
export const TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
|
||||
export const TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
|
||||
export const TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
|
||||
export const TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
|
||||
export const TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType(
|
||||
'loadedmetadata',
|
||||
);
|
||||
export const TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType(
|
||||
'lostpointercapture',
|
||||
);
|
||||
export const TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
|
||||
export const TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
|
||||
export const TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
|
||||
export const TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
|
||||
export const TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
|
||||
export const TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
|
||||
export const TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
|
||||
export const TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
|
||||
export const TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
|
||||
export const TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType(
|
||||
'pointercancel',
|
||||
);
|
||||
export const TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType(
|
||||
'pointerdown',
|
||||
);
|
||||
export const TOP_POINTER_ENTER = unsafeCastStringToDOMTopLevelType(
|
||||
'pointerenter',
|
||||
);
|
||||
export const TOP_POINTER_LEAVE = unsafeCastStringToDOMTopLevelType(
|
||||
'pointerleave',
|
||||
);
|
||||
export const TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType(
|
||||
'pointermove',
|
||||
);
|
||||
export const TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
|
||||
export const TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType(
|
||||
'pointerover',
|
||||
);
|
||||
export const TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
|
||||
export const TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
|
||||
export const TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
|
||||
export const TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
|
||||
export const TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
|
||||
export const TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
|
||||
export const TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
|
||||
export const TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType(
|
||||
'selectionchange',
|
||||
);
|
||||
export const TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
|
||||
export const TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
|
||||
export const TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
|
||||
export const TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
|
||||
export const TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
|
||||
export const TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
|
||||
export const TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType(
|
||||
'touchcancel',
|
||||
);
|
||||
export const TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
|
||||
export const TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
|
||||
export const TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
|
||||
export const TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(
|
||||
getVendorPrefixedEventName('transitionend'),
|
||||
);
|
||||
export const TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType(
|
||||
'volumechange',
|
||||
);
|
||||
export const TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
|
||||
export const TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
|
||||
|
||||
export const TOP_AFTER_BLUR = unsafeCastStringToDOMTopLevelType('afterblur');
|
||||
export const TOP_BEFORE_BLUR = unsafeCastStringToDOMTopLevelType('beforeblur');
|
||||
|
||||
export const TOP_FOCUS_IN = unsafeCastStringToDOMTopLevelType('focusin');
|
||||
export const TOP_FOCUS_OUT = unsafeCastStringToDOMTopLevelType('focusout');
|
||||
|
||||
export function getRawEventName(topLevelType: DOMTopLevelEventType): string {
|
||||
return unsafeCastDOMTopLevelTypeToString(topLevelType);
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import type {
|
||||
ReactDOMResponderContext,
|
||||
ReactDOMResponderEvent,
|
||||
} from '../shared/ReactDOMTypes';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
import {
|
||||
batchedEventUpdates,
|
||||
discreteUpdates,
|
||||
@@ -40,7 +40,6 @@ import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
|
||||
import {enqueueStateRestore} from './ReactDOMControlledComponent';
|
||||
import {createEventListenerWrapper} from './ReactDOMEventListener';
|
||||
import {passiveBrowserEventsSupported} from './checkPassiveEvents';
|
||||
import {getRawEventName} from './DOMTopLevelEventTypes';
|
||||
import {
|
||||
addEventCaptureListener,
|
||||
addEventCaptureListenerWithPassiveFlag,
|
||||
@@ -77,7 +76,7 @@ export function setListenToResponderEventTypes(
|
||||
}
|
||||
|
||||
const rootEventTypesToEventResponderInstances: Map<
|
||||
DOMTopLevelEventType | string,
|
||||
DOMEventName | string,
|
||||
Set<ReactDOMEventResponderInstance>,
|
||||
> = new Map();
|
||||
|
||||
@@ -311,7 +310,7 @@ function getActiveDocument(): Document {
|
||||
}
|
||||
|
||||
function createDOMResponderEvent(
|
||||
topLevelType: string,
|
||||
domEventName: string,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: Element | Document,
|
||||
passive: boolean,
|
||||
@@ -334,7 +333,7 @@ function createDOMResponderEvent(
|
||||
passive,
|
||||
pointerType: eventPointerType,
|
||||
target: nativeEventTarget,
|
||||
type: topLevelType,
|
||||
type: domEventName,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -370,7 +369,7 @@ function validateResponderTargetEventTypes(
|
||||
}
|
||||
|
||||
function traverseAndHandleEventResponderInstances(
|
||||
topLevelType: string,
|
||||
domEventName: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: Document | Element,
|
||||
@@ -386,7 +385,7 @@ function traverseAndHandleEventResponderInstances(
|
||||
|
||||
const visitedResponders = new Set();
|
||||
const responderEvent = createDOMResponderEvent(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
isPassiveEvent,
|
||||
@@ -411,7 +410,7 @@ function traverseAndHandleEventResponderInstances(
|
||||
if (
|
||||
!visitedResponders.has(responder) &&
|
||||
validateResponderTargetEventTypes(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
responder,
|
||||
isPassive,
|
||||
) &&
|
||||
@@ -434,14 +433,14 @@ function traverseAndHandleEventResponderInstances(
|
||||
node = node.return;
|
||||
}
|
||||
// Root phase
|
||||
const passive = rootEventTypesToEventResponderInstances.get(topLevelType);
|
||||
const passive = rootEventTypesToEventResponderInstances.get(domEventName);
|
||||
const rootEventResponderInstances = [];
|
||||
if (passive !== undefined) {
|
||||
rootEventResponderInstances.push(...Array.from(passive));
|
||||
}
|
||||
if (!isPassive) {
|
||||
const active = rootEventTypesToEventResponderInstances.get(
|
||||
topLevelType + '_active',
|
||||
domEventName + '_active',
|
||||
);
|
||||
if (active !== undefined) {
|
||||
rootEventResponderInstances.push(...Array.from(active));
|
||||
@@ -519,7 +518,7 @@ function validateResponderContext(): void {
|
||||
}
|
||||
|
||||
export function DEPRECATED_dispatchEventForResponderEventSystem(
|
||||
topLevelType: string,
|
||||
domEventName: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: Document | Element,
|
||||
@@ -541,7 +540,7 @@ export function DEPRECATED_dispatchEventForResponderEventSystem(
|
||||
try {
|
||||
batchedEventUpdates(() => {
|
||||
traverseAndHandleEventResponderInstances(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetFiber,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -598,7 +597,7 @@ function DEPRECATED_registerRootEventType(
|
||||
|
||||
export function addResponderEventSystemEvent(
|
||||
document: Document,
|
||||
topLevelType: string,
|
||||
domEventName: string,
|
||||
passive: boolean,
|
||||
): any => void {
|
||||
let eventFlags = RESPONDER_EVENT_SYSTEM;
|
||||
@@ -618,27 +617,26 @@ export function addResponderEventSystemEvent(
|
||||
// Check if interactive and wrap in discreteUpdates
|
||||
const listener = createEventListenerWrapper(
|
||||
document,
|
||||
((topLevelType: any): DOMTopLevelEventType),
|
||||
((domEventName: any): DOMEventName),
|
||||
eventFlags,
|
||||
);
|
||||
if (passiveBrowserEventsSupported) {
|
||||
return addEventCaptureListenerWithPassiveFlag(
|
||||
document,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
listener,
|
||||
passive,
|
||||
);
|
||||
} else {
|
||||
return addEventCaptureListener(document, topLevelType, listener);
|
||||
return addEventCaptureListener(document, domEventName, listener);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeTrappedEventListener(
|
||||
targetContainer: EventTarget,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
capture: boolean,
|
||||
listener: any => void,
|
||||
): void {
|
||||
const rawEventName = getRawEventName(topLevelType);
|
||||
removeEventListener(targetContainer, rawEventName, listener, capture);
|
||||
removeEventListener(targetContainer, domEventName, listener, capture);
|
||||
}
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {TopLevelType} from './TopLevelEventTypes';
|
||||
import type {DOMEventName} from './DOMEventNames';
|
||||
|
||||
/**
|
||||
* Mapping from registration name to event name
|
||||
@@ -25,7 +25,7 @@ export const possibleRegistrationNames = __DEV__ ? {} : (null: any);
|
||||
|
||||
export function registerTwoPhaseEvent(
|
||||
registrationName: string,
|
||||
dependencies: ?Array<TopLevelType>,
|
||||
dependencies: ?Array<DOMEventName>,
|
||||
): void {
|
||||
registerDirectEvent(registrationName, dependencies);
|
||||
registerDirectEvent(registrationName + 'Capture', dependencies);
|
||||
@@ -33,7 +33,7 @@ export function registerTwoPhaseEvent(
|
||||
|
||||
export function registerDirectEvent(
|
||||
registrationName: string,
|
||||
dependencies: ?Array<TopLevelType>,
|
||||
dependencies: ?Array<DOMEventName>,
|
||||
) {
|
||||
if (__DEV__) {
|
||||
if (registrationNameDependencies[registrationName]) {
|
||||
|
||||
+26
-26
@@ -11,7 +11,7 @@ import type {AnyNativeEvent} from '../events/PluginModuleType';
|
||||
import type {EventPriority} from 'shared/ReactTypes';
|
||||
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
|
||||
// Intentionally not named imports because Rollup would use dynamic dispatch for
|
||||
// CommonJS interop named imports.
|
||||
@@ -82,12 +82,12 @@ export function isEnabled() {
|
||||
|
||||
export function createEventListenerWrapper(
|
||||
targetContainer: EventTarget,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
): Function {
|
||||
return dispatchEvent.bind(
|
||||
null,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
);
|
||||
@@ -95,13 +95,13 @@ export function createEventListenerWrapper(
|
||||
|
||||
export function createEventListenerWrapperWithPriority(
|
||||
targetContainer: EventTarget,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
priority?: EventPriority,
|
||||
): Function {
|
||||
const eventPriority =
|
||||
priority === undefined
|
||||
? getEventPriorityForPluginSystem(topLevelType)
|
||||
? getEventPriorityForPluginSystem(domEventName)
|
||||
: priority;
|
||||
let listenerWrapper;
|
||||
switch (eventPriority) {
|
||||
@@ -118,14 +118,14 @@ export function createEventListenerWrapperWithPriority(
|
||||
}
|
||||
return listenerWrapper.bind(
|
||||
null,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
);
|
||||
}
|
||||
|
||||
function dispatchDiscreteEvent(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
@@ -140,7 +140,7 @@ function dispatchDiscreteEvent(
|
||||
}
|
||||
discreteUpdates(
|
||||
dispatchEvent,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
@@ -148,7 +148,7 @@ function dispatchDiscreteEvent(
|
||||
}
|
||||
|
||||
function dispatchUserBlockingUpdate(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
@@ -161,7 +161,7 @@ function dispatchUserBlockingUpdate(
|
||||
UserBlockingPriority,
|
||||
dispatchEvent.bind(
|
||||
null,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
@@ -173,7 +173,7 @@ function dispatchUserBlockingUpdate(
|
||||
}
|
||||
|
||||
export function dispatchEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
@@ -181,13 +181,13 @@ export function dispatchEvent(
|
||||
if (!_enabled) {
|
||||
return;
|
||||
}
|
||||
if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {
|
||||
if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(domEventName)) {
|
||||
// If we already have a queue of discrete events, and this is another discrete
|
||||
// event, then we can't dispatch it regardless of its target, since they
|
||||
// need to dispatch in order.
|
||||
queueDiscreteEvent(
|
||||
null, // Flags that we're not actually blocked on anything as far as we know.
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -196,7 +196,7 @@ export function dispatchEvent(
|
||||
}
|
||||
|
||||
const blockedOn = attemptToDispatchEvent(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -204,15 +204,15 @@ export function dispatchEvent(
|
||||
|
||||
if (blockedOn === null) {
|
||||
// We successfully dispatched this event.
|
||||
clearIfContinuousEvent(topLevelType, nativeEvent);
|
||||
clearIfContinuousEvent(domEventName, nativeEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReplayableDiscreteEvent(topLevelType)) {
|
||||
if (isReplayableDiscreteEvent(domEventName)) {
|
||||
// This this to be replayed later once the target is available.
|
||||
queueDiscreteEvent(
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -223,7 +223,7 @@ export function dispatchEvent(
|
||||
if (
|
||||
queueIfContinuousEvent(
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -234,14 +234,14 @@ export function dispatchEvent(
|
||||
|
||||
// We need to clear only if we didn't queue because
|
||||
// queueing is accummulative.
|
||||
clearIfContinuousEvent(topLevelType, nativeEvent);
|
||||
clearIfContinuousEvent(domEventName, nativeEvent);
|
||||
|
||||
// This is not replayable so we'll invoke it but without a target,
|
||||
// in case the event system needs to trace it.
|
||||
if (enableDeprecatedFlareAPI) {
|
||||
if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) {
|
||||
dispatchEventForPluginEventSystem(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
null,
|
||||
@@ -251,7 +251,7 @@ export function dispatchEvent(
|
||||
if (eventSystemFlags & RESPONDER_EVENT_SYSTEM) {
|
||||
// React Flare event system
|
||||
DEPRECATED_dispatchEventForResponderEventSystem(
|
||||
(topLevelType: any),
|
||||
(domEventName: any),
|
||||
null,
|
||||
nativeEvent,
|
||||
getEventTarget(nativeEvent),
|
||||
@@ -260,7 +260,7 @@ export function dispatchEvent(
|
||||
}
|
||||
} else {
|
||||
dispatchEventForPluginEventSystem(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
null,
|
||||
@@ -271,7 +271,7 @@ export function dispatchEvent(
|
||||
|
||||
// Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
|
||||
export function attemptToDispatchEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
@@ -322,7 +322,7 @@ export function attemptToDispatchEvent(
|
||||
if (enableDeprecatedFlareAPI) {
|
||||
if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) {
|
||||
dispatchEventForPluginEventSystem(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
targetInst,
|
||||
@@ -332,7 +332,7 @@ export function attemptToDispatchEvent(
|
||||
if (eventSystemFlags & RESPONDER_EVENT_SYSTEM) {
|
||||
// React Flare event system
|
||||
DEPRECATED_dispatchEventForResponderEventSystem(
|
||||
(topLevelType: any),
|
||||
(domEventName: any),
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -341,7 +341,7 @@ export function attemptToDispatchEvent(
|
||||
}
|
||||
} else {
|
||||
dispatchEventForPluginEventSystem(
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
targetInst,
|
||||
|
||||
+86
-130
@@ -9,7 +9,7 @@
|
||||
|
||||
import type {AnyNativeEvent} from '../events/PluginModuleType';
|
||||
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
import type {ElementListenerMap} from '../client/ReactDOMComponentTree';
|
||||
import type {EventSystemFlags} from './EventSystemFlags';
|
||||
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
getClosestInstanceFromNode,
|
||||
getEventListenerMap,
|
||||
} from '../client/ReactDOMComponentTree';
|
||||
import {unsafeCastDOMTopLevelTypeToString} from '../events/TopLevelEventTypes';
|
||||
import {HostRoot, SuspenseComponent} from 'react-reconciler/src/ReactWorkTags';
|
||||
|
||||
let attemptSynchronousHydration: (fiber: Object) => void;
|
||||
@@ -87,53 +86,13 @@ type PointerEvent = Event & {
|
||||
...
|
||||
};
|
||||
|
||||
import {
|
||||
TOP_MOUSE_DOWN,
|
||||
TOP_MOUSE_UP,
|
||||
TOP_TOUCH_CANCEL,
|
||||
TOP_TOUCH_END,
|
||||
TOP_TOUCH_START,
|
||||
TOP_AUX_CLICK,
|
||||
TOP_DOUBLE_CLICK,
|
||||
TOP_POINTER_CANCEL,
|
||||
TOP_POINTER_DOWN,
|
||||
TOP_POINTER_UP,
|
||||
TOP_DRAG_END,
|
||||
TOP_DRAG_START,
|
||||
TOP_DROP,
|
||||
TOP_COMPOSITION_END,
|
||||
TOP_COMPOSITION_START,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_INPUT,
|
||||
TOP_TEXT_INPUT,
|
||||
TOP_COPY,
|
||||
TOP_CUT,
|
||||
TOP_PASTE,
|
||||
TOP_CLICK,
|
||||
TOP_CHANGE,
|
||||
TOP_CONTEXT_MENU,
|
||||
TOP_RESET,
|
||||
TOP_SUBMIT,
|
||||
TOP_DRAG_ENTER,
|
||||
TOP_DRAG_LEAVE,
|
||||
TOP_MOUSE_OVER,
|
||||
TOP_MOUSE_OUT,
|
||||
TOP_POINTER_OVER,
|
||||
TOP_POINTER_OUT,
|
||||
TOP_GOT_POINTER_CAPTURE,
|
||||
TOP_LOST_POINTER_CAPTURE,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_FOCUS_OUT,
|
||||
} from './DOMTopLevelEventTypes';
|
||||
import {IS_REPLAYED} from './EventSystemFlags';
|
||||
import {listenToNativeEvent} from './DOMPluginEventSystem';
|
||||
import {addResponderEventSystemEvent} from './DeprecatedDOMEventResponderSystem';
|
||||
|
||||
type QueuedReplayableEvent = {|
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
targetContainers: Array<EventTarget>,
|
||||
@@ -172,80 +131,77 @@ export function hasQueuedContinuousEvents(): boolean {
|
||||
return hasAnyQueuedContinuousEvents;
|
||||
}
|
||||
|
||||
const discreteReplayableEvents = [
|
||||
TOP_MOUSE_DOWN,
|
||||
TOP_MOUSE_UP,
|
||||
TOP_TOUCH_CANCEL,
|
||||
TOP_TOUCH_END,
|
||||
TOP_TOUCH_START,
|
||||
TOP_AUX_CLICK,
|
||||
TOP_DOUBLE_CLICK,
|
||||
TOP_POINTER_CANCEL,
|
||||
TOP_POINTER_DOWN,
|
||||
TOP_POINTER_UP,
|
||||
TOP_DRAG_END,
|
||||
TOP_DRAG_START,
|
||||
TOP_DROP,
|
||||
TOP_COMPOSITION_END,
|
||||
TOP_COMPOSITION_START,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_INPUT,
|
||||
TOP_TEXT_INPUT,
|
||||
TOP_COPY,
|
||||
TOP_CUT,
|
||||
TOP_PASTE,
|
||||
TOP_CLICK,
|
||||
TOP_CHANGE,
|
||||
TOP_CONTEXT_MENU,
|
||||
TOP_RESET,
|
||||
TOP_SUBMIT,
|
||||
const discreteReplayableEvents: Array<DOMEventName> = [
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'touchcancel',
|
||||
'touchend',
|
||||
'touchstart',
|
||||
'auxclick',
|
||||
'dblclick',
|
||||
'pointercancel',
|
||||
'pointerdown',
|
||||
'pointerup',
|
||||
'dragend',
|
||||
'dragstart',
|
||||
'drop',
|
||||
'compositionend',
|
||||
'compositionstart',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'input',
|
||||
'textInput', // Intentionally camelCase
|
||||
'copy',
|
||||
'cut',
|
||||
'paste',
|
||||
'click',
|
||||
'change',
|
||||
'contextmenu',
|
||||
'reset',
|
||||
'submit',
|
||||
];
|
||||
|
||||
const continuousReplayableEvents = [
|
||||
TOP_DRAG_ENTER,
|
||||
TOP_DRAG_LEAVE,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_MOUSE_OVER,
|
||||
TOP_MOUSE_OUT,
|
||||
TOP_POINTER_OVER,
|
||||
TOP_POINTER_OUT,
|
||||
TOP_GOT_POINTER_CAPTURE,
|
||||
TOP_LOST_POINTER_CAPTURE,
|
||||
const continuousReplayableEvents: Array<DOMEventName> = [
|
||||
'dragenter',
|
||||
'dragleave',
|
||||
'focusin',
|
||||
'focusout',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'pointerover',
|
||||
'pointerout',
|
||||
'gotpointercapture',
|
||||
'lostpointercapture',
|
||||
];
|
||||
|
||||
export function isReplayableDiscreteEvent(
|
||||
eventType: DOMTopLevelEventType,
|
||||
): boolean {
|
||||
export function isReplayableDiscreteEvent(eventType: DOMEventName): boolean {
|
||||
return discreteReplayableEvents.indexOf(eventType) > -1;
|
||||
}
|
||||
|
||||
function trapReplayableEventForContainer(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
container: Container,
|
||||
) {
|
||||
listenToNativeEvent(topLevelType, false, ((container: any): Element), null);
|
||||
listenToNativeEvent(domEventName, false, ((container: any): Element), null);
|
||||
}
|
||||
|
||||
function trapReplayableEventForDocument(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
document: Document,
|
||||
listenerMap: ElementListenerMap,
|
||||
) {
|
||||
if (enableDeprecatedFlareAPI) {
|
||||
// Trap events for the responder system.
|
||||
const topLevelTypeString = unsafeCastDOMTopLevelTypeToString(topLevelType);
|
||||
// TODO: Ideally we shouldn't need these to be active but
|
||||
// if we only have a passive listener, we at least need it
|
||||
// to still pretend to be active so that Flare gets those
|
||||
// events.
|
||||
const activeEventKey = topLevelTypeString + '_active';
|
||||
const activeEventKey = domEventName + '_active';
|
||||
if (!listenerMap.has(activeEventKey)) {
|
||||
const listener = addResponderEventSystemEvent(
|
||||
document,
|
||||
topLevelTypeString,
|
||||
domEventName,
|
||||
false,
|
||||
);
|
||||
listenerMap.set(activeEventKey, {passive: false, listener});
|
||||
@@ -259,27 +215,27 @@ export function eagerlyTrapReplayableEvents(
|
||||
) {
|
||||
const listenerMapForDoc = getEventListenerMap(document);
|
||||
// Discrete
|
||||
discreteReplayableEvents.forEach(topLevelType => {
|
||||
trapReplayableEventForContainer(topLevelType, container);
|
||||
trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
|
||||
discreteReplayableEvents.forEach(domEventName => {
|
||||
trapReplayableEventForContainer(domEventName, container);
|
||||
trapReplayableEventForDocument(domEventName, document, listenerMapForDoc);
|
||||
});
|
||||
// Continuous
|
||||
continuousReplayableEvents.forEach(topLevelType => {
|
||||
trapReplayableEventForContainer(topLevelType, container);
|
||||
trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
|
||||
continuousReplayableEvents.forEach(domEventName => {
|
||||
trapReplayableEventForContainer(domEventName, container);
|
||||
trapReplayableEventForDocument(domEventName, document, listenerMapForDoc);
|
||||
});
|
||||
}
|
||||
|
||||
function createQueuedReplayableEvent(
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
): QueuedReplayableEvent {
|
||||
return {
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags: eventSystemFlags | IS_REPLAYED,
|
||||
nativeEvent,
|
||||
targetContainers: [targetContainer],
|
||||
@@ -288,14 +244,14 @@ function createQueuedReplayableEvent(
|
||||
|
||||
export function queueDiscreteEvent(
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
): void {
|
||||
const queuedEvent = createQueuedReplayableEvent(
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -329,30 +285,30 @@ export function queueDiscreteEvent(
|
||||
|
||||
// Resets the replaying for this type of continuous event to no event.
|
||||
export function clearIfContinuousEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
): void {
|
||||
switch (topLevelType) {
|
||||
case TOP_FOCUS_IN:
|
||||
case TOP_FOCUS_OUT:
|
||||
switch (domEventName) {
|
||||
case 'focusin':
|
||||
case 'focusout':
|
||||
queuedFocus = null;
|
||||
break;
|
||||
case TOP_DRAG_ENTER:
|
||||
case TOP_DRAG_LEAVE:
|
||||
case 'dragenter':
|
||||
case 'dragleave':
|
||||
queuedDrag = null;
|
||||
break;
|
||||
case TOP_MOUSE_OVER:
|
||||
case TOP_MOUSE_OUT:
|
||||
case 'mouseover':
|
||||
case 'mouseout':
|
||||
queuedMouse = null;
|
||||
break;
|
||||
case TOP_POINTER_OVER:
|
||||
case TOP_POINTER_OUT: {
|
||||
case 'pointerover':
|
||||
case 'pointerout': {
|
||||
const pointerId = ((nativeEvent: any): PointerEvent).pointerId;
|
||||
queuedPointers.delete(pointerId);
|
||||
break;
|
||||
}
|
||||
case TOP_GOT_POINTER_CAPTURE:
|
||||
case TOP_LOST_POINTER_CAPTURE: {
|
||||
case 'gotpointercapture':
|
||||
case 'lostpointercapture': {
|
||||
const pointerId = ((nativeEvent: any): PointerEvent).pointerId;
|
||||
queuedPointerCaptures.delete(pointerId);
|
||||
break;
|
||||
@@ -363,7 +319,7 @@ export function clearIfContinuousEvent(
|
||||
function accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
existingQueuedEvent: null | QueuedReplayableEvent,
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
@@ -374,7 +330,7 @@ function accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
) {
|
||||
const queuedEvent = createQueuedReplayableEvent(
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
nativeEvent,
|
||||
@@ -405,7 +361,7 @@ function accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
|
||||
export function queueIfContinuousEvent(
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
domEventName: DOMEventName,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
@@ -413,44 +369,44 @@ export function queueIfContinuousEvent(
|
||||
// These set relatedTarget to null because the replayed event will be treated as if we
|
||||
// moved from outside the window (no target) onto the target once it hydrates.
|
||||
// Instead of mutating we could clone the event.
|
||||
switch (topLevelType) {
|
||||
case TOP_FOCUS_IN: {
|
||||
switch (domEventName) {
|
||||
case 'focusin': {
|
||||
const focusEvent = ((nativeEvent: any): FocusEvent);
|
||||
queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
queuedFocus,
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
focusEvent,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case TOP_DRAG_ENTER: {
|
||||
case 'dragenter': {
|
||||
const dragEvent = ((nativeEvent: any): DragEvent);
|
||||
queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
queuedDrag,
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
dragEvent,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case TOP_MOUSE_OVER: {
|
||||
case 'mouseover': {
|
||||
const mouseEvent = ((nativeEvent: any): MouseEvent);
|
||||
queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
queuedMouse,
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
mouseEvent,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case TOP_POINTER_OVER: {
|
||||
case 'pointerover': {
|
||||
const pointerEvent = ((nativeEvent: any): PointerEvent);
|
||||
const pointerId = pointerEvent.pointerId;
|
||||
queuedPointers.set(
|
||||
@@ -458,7 +414,7 @@ export function queueIfContinuousEvent(
|
||||
accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
queuedPointers.get(pointerId) || null,
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
pointerEvent,
|
||||
@@ -466,7 +422,7 @@ export function queueIfContinuousEvent(
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case TOP_GOT_POINTER_CAPTURE: {
|
||||
case 'gotpointercapture': {
|
||||
const pointerEvent = ((nativeEvent: any): PointerEvent);
|
||||
const pointerId = pointerEvent.pointerId;
|
||||
queuedPointerCaptures.set(
|
||||
@@ -474,7 +430,7 @@ export function queueIfContinuousEvent(
|
||||
accumulateOrCreateContinuousQueuedReplayableEvent(
|
||||
queuedPointerCaptures.get(pointerId) || null,
|
||||
blockedOn,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
pointerEvent,
|
||||
@@ -559,7 +515,7 @@ function attemptReplayContinuousQueuedEvent(
|
||||
while (targetContainers.length > 0) {
|
||||
const targetContainer = targetContainers[0];
|
||||
const nextBlockedOn = attemptToDispatchEvent(
|
||||
queuedEvent.topLevelType,
|
||||
queuedEvent.domEventName,
|
||||
queuedEvent.eventSystemFlags,
|
||||
targetContainer,
|
||||
queuedEvent.nativeEvent,
|
||||
@@ -608,7 +564,7 @@ function replayUnblockedEvents() {
|
||||
while (targetContainers.length > 0) {
|
||||
const targetContainer = targetContainers[0];
|
||||
const nextBlockedOn = attemptToDispatchEvent(
|
||||
nextDiscreteEvent.topLevelType,
|
||||
nextDiscreteEvent.domEventName,
|
||||
nextDiscreteEvent.eventSystemFlags,
|
||||
targetContainer,
|
||||
nextDiscreteEvent.nativeEvent,
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {EventPriority} from 'shared/ReactTypes';
|
||||
import type {TopLevelType} from './TopLevelEventTypes';
|
||||
import type {DOMEventName} from './DOMEventNames';
|
||||
|
||||
export type DispatchConfig = {|
|
||||
dependencies?: Array<TopLevelType>,
|
||||
dependencies?: Array<DOMEventName>,
|
||||
phasedRegistrationNames: {|
|
||||
bubbled: null | string,
|
||||
captured: null | string,
|
||||
|
||||
+87
-19
@@ -7,22 +7,90 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export opaque type DOMTopLevelEventType = string;
|
||||
|
||||
// Do not use the below two methods directly!
|
||||
// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
|
||||
// (It is the only module that is allowed to access these methods.)
|
||||
|
||||
export function unsafeCastStringToDOMTopLevelType(
|
||||
topLevelType: string,
|
||||
): DOMTopLevelEventType {
|
||||
return topLevelType;
|
||||
}
|
||||
|
||||
export function unsafeCastDOMTopLevelTypeToString(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
): string {
|
||||
return topLevelType;
|
||||
}
|
||||
|
||||
export type TopLevelType = DOMTopLevelEventType;
|
||||
export type TopLevelType =
|
||||
| 'abort'
|
||||
// Dynamic and vendor-prefixed at the usage site:
|
||||
// 'animationiteration' |
|
||||
// 'animationend |
|
||||
// 'animationstart' |
|
||||
| 'canplay'
|
||||
| 'canplaythrough'
|
||||
| 'cancel'
|
||||
| 'change'
|
||||
| 'click'
|
||||
| 'close'
|
||||
| 'compositionend'
|
||||
| 'compositionstart'
|
||||
| 'compositionupdate'
|
||||
| 'contextmenu'
|
||||
| 'copy'
|
||||
| 'cut'
|
||||
| 'dblclick'
|
||||
| 'auxclick'
|
||||
| 'drag'
|
||||
| 'dragend'
|
||||
| 'dragenter'
|
||||
| 'dragexit'
|
||||
| 'dragleave'
|
||||
| 'dragover'
|
||||
| 'dragstart'
|
||||
| 'drop'
|
||||
| 'durationchange'
|
||||
| 'emptied'
|
||||
| 'encrypted'
|
||||
| 'ended'
|
||||
| 'error'
|
||||
| 'gotpointercapture'
|
||||
| 'input'
|
||||
| 'invalid'
|
||||
| 'keydown'
|
||||
| 'keypress'
|
||||
| 'keyup'
|
||||
| 'load'
|
||||
| 'loadstart'
|
||||
| 'loadeddata'
|
||||
| 'loadedmetadata'
|
||||
| 'lostpointercapture'
|
||||
| 'mousedown'
|
||||
| 'mousemove'
|
||||
| 'mouseout'
|
||||
| 'mouseover'
|
||||
| 'mouseup'
|
||||
| 'paste'
|
||||
| 'pause'
|
||||
| 'play'
|
||||
| 'playing'
|
||||
| 'pointercancel'
|
||||
| 'pointerdown'
|
||||
| 'pointerenter'
|
||||
| 'pointerleave'
|
||||
| 'pointermove'
|
||||
| 'pointerout'
|
||||
| 'pointerover'
|
||||
| 'pointerup'
|
||||
| 'progress'
|
||||
| 'ratechange'
|
||||
| 'reset'
|
||||
| 'scroll'
|
||||
| 'seeked'
|
||||
| 'seeking'
|
||||
| 'selectionchange'
|
||||
| 'stalled'
|
||||
| 'submit'
|
||||
| 'suspend'
|
||||
| 'textInput'
|
||||
| 'timeupdate'
|
||||
| 'toggle'
|
||||
| 'touchcancel'
|
||||
| 'touchend'
|
||||
| 'touchmove'
|
||||
| 'touchstart'
|
||||
// Dynamic and vendor-prefixed at the usage site:
|
||||
// 'transitionend' |
|
||||
| 'volumechange'
|
||||
| 'waiting'
|
||||
| 'wheel'
|
||||
| 'afterblur'
|
||||
| 'beforeblur'
|
||||
| 'focusin'
|
||||
| 'focusout';
|
||||
|
||||
+87
-101
@@ -3,25 +3,19 @@
|
||||
*
|
||||
* 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 {TopLevelType} from '../../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../../events/DOMEventNames';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {AnyNativeEvent} from '../../events/PluginModuleType';
|
||||
import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
|
||||
import {registerTwoPhaseEvent} from '../EventRegistry';
|
||||
import {
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_COMPOSITION_START,
|
||||
TOP_COMPOSITION_END,
|
||||
TOP_COMPOSITION_UPDATE,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
TOP_TEXT_INPUT,
|
||||
TOP_PASTE,
|
||||
} from '../DOMTopLevelEventTypes';
|
||||
import {
|
||||
getData as FallbackCompositionStateGetData,
|
||||
initialize as FallbackCompositionStateInitialize,
|
||||
@@ -63,34 +57,34 @@ const SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
|
||||
|
||||
function registerEvents() {
|
||||
registerTwoPhaseEvent('onBeforeInput', [
|
||||
TOP_COMPOSITION_END,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_TEXT_INPUT,
|
||||
TOP_PASTE,
|
||||
'compositionend',
|
||||
'keypress',
|
||||
'textInput',
|
||||
'paste',
|
||||
]);
|
||||
registerTwoPhaseEvent('onCompositionEnd', [
|
||||
TOP_COMPOSITION_END,
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
'compositionend',
|
||||
'focusout',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'mousedown',
|
||||
]);
|
||||
registerTwoPhaseEvent('onCompositionStart', [
|
||||
TOP_COMPOSITION_START,
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
'compositionstart',
|
||||
'focusout',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'mousedown',
|
||||
]);
|
||||
registerTwoPhaseEvent('onCompositionUpdate', [
|
||||
TOP_COMPOSITION_UPDATE,
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_PRESS,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
'compositionupdate',
|
||||
'focusout',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'mousedown',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -102,7 +96,7 @@ let hasSpaceKeypress = false;
|
||||
* This is required because Firefox fires `keypress` events for key commands
|
||||
* (cut, copy, select-all, etc.) even though no character is inserted.
|
||||
*/
|
||||
function isKeypressCommand(nativeEvent) {
|
||||
function isKeypressCommand(nativeEvent: any) {
|
||||
return (
|
||||
(nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
|
||||
// ctrlKey && altKey is equivalent to AltGr, and is not a command.
|
||||
@@ -112,17 +106,14 @@ function isKeypressCommand(nativeEvent) {
|
||||
|
||||
/**
|
||||
* Translate native top level events into event types.
|
||||
*
|
||||
* @param {string} topLevelType
|
||||
* @return {object}
|
||||
*/
|
||||
function getCompositionEventType(topLevelType) {
|
||||
switch (topLevelType) {
|
||||
case TOP_COMPOSITION_START:
|
||||
function getCompositionEventType(domEventName: DOMEventName) {
|
||||
switch (domEventName) {
|
||||
case 'compositionstart':
|
||||
return 'onCompositionStart';
|
||||
case TOP_COMPOSITION_END:
|
||||
case 'compositionend':
|
||||
return 'onCompositionEnd';
|
||||
case TOP_COMPOSITION_UPDATE:
|
||||
case 'compositionupdate':
|
||||
return 'onCompositionUpdate';
|
||||
}
|
||||
}
|
||||
@@ -130,34 +121,32 @@ function getCompositionEventType(topLevelType) {
|
||||
/**
|
||||
* Does our fallback best-guess model think this event signifies that
|
||||
* composition has begun?
|
||||
*
|
||||
* @param {string} topLevelType
|
||||
* @param {object} nativeEvent
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isFallbackCompositionStart(topLevelType, nativeEvent) {
|
||||
return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
|
||||
function isFallbackCompositionStart(
|
||||
domEventName: DOMEventName,
|
||||
nativeEvent: any,
|
||||
): boolean {
|
||||
return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does our fallback mode think that this event is the end of composition?
|
||||
*
|
||||
* @param {string} topLevelType
|
||||
* @param {object} nativeEvent
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
|
||||
switch (topLevelType) {
|
||||
case TOP_KEY_UP:
|
||||
function isFallbackCompositionEnd(
|
||||
domEventName: DOMEventName,
|
||||
nativeEvent: any,
|
||||
): boolean {
|
||||
switch (domEventName) {
|
||||
case 'keyup':
|
||||
// Command keys insert or clear IME input.
|
||||
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
|
||||
case TOP_KEY_DOWN:
|
||||
case 'keydown':
|
||||
// Expect IME keyCode on each keydown. If we get any other
|
||||
// code we must have exited earlier.
|
||||
return nativeEvent.keyCode !== START_KEYCODE;
|
||||
case TOP_KEY_PRESS:
|
||||
case TOP_MOUSE_DOWN:
|
||||
case TOP_FOCUS_OUT:
|
||||
case 'keypress':
|
||||
case 'mousedown':
|
||||
case 'focusout':
|
||||
// Events are not possible without cancelling IME.
|
||||
return true;
|
||||
default:
|
||||
@@ -174,7 +163,7 @@ function isFallbackCompositionEnd(topLevelType, nativeEvent) {
|
||||
* @param {object} nativeEvent
|
||||
* @return {?string}
|
||||
*/
|
||||
function getDataFromCustomEvent(nativeEvent) {
|
||||
function getDataFromCustomEvent(nativeEvent: any) {
|
||||
const detail = nativeEvent.detail;
|
||||
if (typeof detail === 'object' && 'data' in detail) {
|
||||
return detail.data;
|
||||
@@ -192,7 +181,7 @@ function getDataFromCustomEvent(nativeEvent) {
|
||||
* @param {object} nativeEvent
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isUsingKoreanIME(nativeEvent) {
|
||||
function isUsingKoreanIME(nativeEvent: any) {
|
||||
return nativeEvent.locale === 'ko';
|
||||
}
|
||||
|
||||
@@ -204,7 +193,7 @@ let isComposing = false;
|
||||
*/
|
||||
function extractCompositionEvent(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -213,12 +202,12 @@ function extractCompositionEvent(
|
||||
let fallbackData;
|
||||
|
||||
if (canUseCompositionEvent) {
|
||||
eventType = getCompositionEventType(topLevelType);
|
||||
eventType = getCompositionEventType(domEventName);
|
||||
} else if (!isComposing) {
|
||||
if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
|
||||
if (isFallbackCompositionStart(domEventName, nativeEvent)) {
|
||||
eventType = 'onCompositionStart';
|
||||
}
|
||||
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
|
||||
} else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
|
||||
eventType = 'onCompositionEnd';
|
||||
}
|
||||
|
||||
@@ -259,16 +248,14 @@ function extractCompositionEvent(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TopLevelType} topLevelType Number from `TopLevelType`.
|
||||
* @param {object} nativeEvent Native browser event.
|
||||
* @return {?string} The string corresponding to this `beforeInput` event.
|
||||
*/
|
||||
function getNativeBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
switch (topLevelType) {
|
||||
case TOP_COMPOSITION_END:
|
||||
function getNativeBeforeInputChars(
|
||||
domEventName: DOMEventName,
|
||||
nativeEvent: any,
|
||||
): ?string {
|
||||
switch (domEventName) {
|
||||
case 'compositionend':
|
||||
return getDataFromCustomEvent(nativeEvent);
|
||||
case TOP_KEY_PRESS:
|
||||
case 'keypress':
|
||||
/**
|
||||
* If native `textInput` events are available, our goal is to make
|
||||
* use of them. However, there is a special case: the spacebar key.
|
||||
@@ -291,7 +278,7 @@ function getNativeBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
hasSpaceKeypress = true;
|
||||
return SPACEBAR_CHAR;
|
||||
|
||||
case TOP_TEXT_INPUT:
|
||||
case 'textInput':
|
||||
// Record the characters to be added to the DOM.
|
||||
const chars = nativeEvent.data;
|
||||
|
||||
@@ -313,21 +300,20 @@ function getNativeBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
/**
|
||||
* For browsers that do not provide the `textInput` event, extract the
|
||||
* appropriate string to use for SyntheticInputEvent.
|
||||
*
|
||||
* @param {number} topLevelType Number from `TopLevelEventTypes`.
|
||||
* @param {object} nativeEvent Native browser event.
|
||||
* @return {?string} The fallback string for this `beforeInput` event.
|
||||
*/
|
||||
function getFallbackBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
function getFallbackBeforeInputChars(
|
||||
domEventName: DOMEventName,
|
||||
nativeEvent: any,
|
||||
): ?string {
|
||||
// If we are currently composing (IME) and using a fallback to do so,
|
||||
// try to extract the composed characters from the fallback object.
|
||||
// If composition event is available, we extract a string only at
|
||||
// compositionevent, otherwise extract it at fallback events.
|
||||
if (isComposing) {
|
||||
if (
|
||||
topLevelType === TOP_COMPOSITION_END ||
|
||||
domEventName === 'compositionend' ||
|
||||
(!canUseCompositionEvent &&
|
||||
isFallbackCompositionEnd(topLevelType, nativeEvent))
|
||||
isFallbackCompositionEnd(domEventName, nativeEvent))
|
||||
) {
|
||||
const chars = FallbackCompositionStateGetData();
|
||||
FallbackCompositionStateReset();
|
||||
@@ -337,12 +323,12 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (topLevelType) {
|
||||
case TOP_PASTE:
|
||||
switch (domEventName) {
|
||||
case 'paste':
|
||||
// If a paste event occurs after a keypress, throw out the input
|
||||
// chars. Paste events should not lead to BeforeInput events.
|
||||
return null;
|
||||
case TOP_KEY_PRESS:
|
||||
case 'keypress':
|
||||
/**
|
||||
* As of v27, Firefox may fire keypress events even when no character
|
||||
* will be inserted. A few possibilities:
|
||||
@@ -373,7 +359,7 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
case TOP_COMPOSITION_END:
|
||||
case 'compositionend':
|
||||
return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)
|
||||
? null
|
||||
: nativeEvent.data;
|
||||
@@ -390,7 +376,7 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
|
||||
*/
|
||||
function extractBeforeInputEvent(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
@@ -398,9 +384,9 @@ function extractBeforeInputEvent(
|
||||
let chars;
|
||||
|
||||
if (canUseTextInputEvent) {
|
||||
chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
|
||||
chars = getNativeBeforeInputChars(domEventName, nativeEvent);
|
||||
} else {
|
||||
chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
|
||||
chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
|
||||
}
|
||||
|
||||
// If no characters are being inserted, no BeforeInput event should
|
||||
@@ -439,24 +425,24 @@ function extractBeforeInputEvent(
|
||||
* `composition` event types.
|
||||
*/
|
||||
function extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
) {
|
||||
dispatchQueue: DispatchQueue,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
): void {
|
||||
extractCompositionEvent(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
);
|
||||
extractBeforeInputEvent(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
domEventName,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
||||
+36
-36
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
import type {AnyNativeEvent} from '../PluginModuleType';
|
||||
import type {TopLevelType} from '../TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../DOMEventNames';
|
||||
import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
@@ -16,16 +16,6 @@ import {SyntheticEvent} from '../SyntheticEvent';
|
||||
import isTextInputElement from '../isTextInputElement';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
|
||||
import {
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_CHANGE,
|
||||
TOP_CLICK,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_INPUT,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_UP,
|
||||
TOP_SELECTION_CHANGE,
|
||||
} from '../DOMTopLevelEventTypes';
|
||||
import getEventTarget from '../getEventTarget';
|
||||
import isEventSupported from '../isEventSupported';
|
||||
import {getNodeFromInstance} from '../../client/ReactDOMComponentTree';
|
||||
@@ -42,14 +32,14 @@ import {
|
||||
|
||||
function registerEvents() {
|
||||
registerTwoPhaseEvent('onChange', [
|
||||
TOP_CHANGE,
|
||||
TOP_CLICK,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_INPUT,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_UP,
|
||||
TOP_SELECTION_CHANGE,
|
||||
'change',
|
||||
'click',
|
||||
'focusin',
|
||||
'focusout',
|
||||
'input',
|
||||
'keydown',
|
||||
'keyup',
|
||||
'selectionchange',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -116,8 +106,8 @@ function getInstIfValueChanged(targetInst: Object) {
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetInstForChangeEvent(topLevelType, targetInst) {
|
||||
if (topLevelType === TOP_CHANGE) {
|
||||
function getTargetInstForChangeEvent(domEventName: DOMEventName, targetInst) {
|
||||
if (domEventName === 'change') {
|
||||
return targetInst;
|
||||
}
|
||||
}
|
||||
@@ -171,8 +161,12 @@ function handlePropertyChange(nativeEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
|
||||
if (topLevelType === TOP_FOCUS_IN) {
|
||||
function handleEventsForInputEventPolyfill(
|
||||
domEventName: DOMEventName,
|
||||
target,
|
||||
targetInst,
|
||||
) {
|
||||
if (domEventName === 'focusin') {
|
||||
// In IE9, propertychange fires for most input events but is buggy and
|
||||
// doesn't fire when text is deleted, but conveniently, selectionchange
|
||||
// appears to fire in all of the remaining cases so we catch those and
|
||||
@@ -185,17 +179,20 @@ function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
|
||||
// missed a blur event somehow.
|
||||
stopWatchingForValueChange();
|
||||
startWatchingForValueChange(target, targetInst);
|
||||
} else if (topLevelType === TOP_FOCUS_OUT) {
|
||||
} else if (domEventName === 'focusout') {
|
||||
stopWatchingForValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
// For IE8 and IE9.
|
||||
function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
|
||||
function getTargetInstForInputEventPolyfill(
|
||||
domEventName: DOMEventName,
|
||||
targetInst,
|
||||
) {
|
||||
if (
|
||||
topLevelType === TOP_SELECTION_CHANGE ||
|
||||
topLevelType === TOP_KEY_UP ||
|
||||
topLevelType === TOP_KEY_DOWN
|
||||
domEventName === 'selectionchange' ||
|
||||
domEventName === 'keyup' ||
|
||||
domEventName === 'keydown'
|
||||
) {
|
||||
// On the selectionchange event, the target is just document which isn't
|
||||
// helpful for us so just check activeElement instead.
|
||||
@@ -226,14 +223,17 @@ function shouldUseClickEvent(elem) {
|
||||
);
|
||||
}
|
||||
|
||||
function getTargetInstForClickEvent(topLevelType, targetInst) {
|
||||
if (topLevelType === TOP_CLICK) {
|
||||
function getTargetInstForClickEvent(domEventName: DOMEventName, targetInst) {
|
||||
if (domEventName === 'click') {
|
||||
return getInstIfValueChanged(targetInst);
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
|
||||
if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
|
||||
function getTargetInstForInputOrChangeEvent(
|
||||
domEventName: DOMEventName,
|
||||
targetInst,
|
||||
) {
|
||||
if (domEventName === 'input' || domEventName === 'change') {
|
||||
return getInstIfValueChanged(targetInst);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ function handleControlledInputBlur(node: HTMLInputElement) {
|
||||
*/
|
||||
function extractEvents(
|
||||
dispatchQueue: DispatchQueue,
|
||||
topLevelType: TopLevelType,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
@@ -287,7 +287,7 @@ function extractEvents(
|
||||
}
|
||||
|
||||
if (getTargetInstFunc) {
|
||||
const inst = getTargetInstFunc(topLevelType, targetInst);
|
||||
const inst = getTargetInstFunc(domEventName, targetInst);
|
||||
if (inst) {
|
||||
createAndAccumulateChangeEvent(
|
||||
dispatchQueue,
|
||||
@@ -300,11 +300,11 @@ function extractEvents(
|
||||
}
|
||||
|
||||
if (handleEventFunc) {
|
||||
handleEventFunc(topLevelType, targetNode, targetInst);
|
||||
handleEventFunc(domEventName, targetNode, targetInst);
|
||||
}
|
||||
|
||||
// When blurring, set the value attribute for number inputs
|
||||
if (topLevelType === TOP_FOCUS_OUT) {
|
||||
if (domEventName === 'focusout') {
|
||||
handleControlledInputBlur(((targetNode: any): HTMLInputElement));
|
||||
}
|
||||
}
|
||||
|
||||
+33
-36
@@ -3,15 +3,16 @@
|
||||
*
|
||||
* 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 {AnyNativeEvent} from '../PluginModuleType';
|
||||
import type {DOMEventName} from '../DOMEventNames';
|
||||
import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {registerDirectEvent} from '../EventRegistry';
|
||||
import {
|
||||
TOP_MOUSE_OUT,
|
||||
TOP_MOUSE_OVER,
|
||||
TOP_POINTER_OUT,
|
||||
TOP_POINTER_OVER,
|
||||
} from '../DOMTopLevelEventTypes';
|
||||
import {IS_REPLAYED} from 'react-dom/src/events/EventSystemFlags';
|
||||
import {
|
||||
SyntheticEvent,
|
||||
@@ -28,10 +29,10 @@ import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {getNearestMountedFiber} from 'react-reconciler/src/ReactFiberTreeReflection';
|
||||
|
||||
function registerEvents() {
|
||||
registerDirectEvent('onMouseEnter', [TOP_MOUSE_OUT, TOP_MOUSE_OVER]);
|
||||
registerDirectEvent('onMouseLeave', [TOP_MOUSE_OUT, TOP_MOUSE_OVER]);
|
||||
registerDirectEvent('onPointerEnter', [TOP_POINTER_OUT, TOP_POINTER_OVER]);
|
||||
registerDirectEvent('onPointerLeave', [TOP_POINTER_OUT, TOP_POINTER_OVER]);
|
||||
registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
|
||||
registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
|
||||
registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
|
||||
registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,21 +43,22 @@ function registerEvents() {
|
||||
* the `mouseover` top-level event.
|
||||
*/
|
||||
function extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
dispatchQueue: DispatchQueue,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
) {
|
||||
const isOverEvent =
|
||||
topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
|
||||
domEventName === 'mouseover' || domEventName === 'pointerover';
|
||||
const isOutEvent =
|
||||
topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
|
||||
domEventName === 'mouseout' || domEventName === 'pointerout';
|
||||
|
||||
if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0) {
|
||||
const related = nativeEvent.relatedTarget || nativeEvent.fromElement;
|
||||
const related =
|
||||
(nativeEvent: any).relatedTarget || (nativeEvent: any).fromElement;
|
||||
if (related) {
|
||||
// Due to the fact we don't add listeners to the document with the
|
||||
// modern event system and instead attach listeners to roots, we
|
||||
@@ -75,12 +77,13 @@ function extractEvents(
|
||||
}
|
||||
|
||||
let win;
|
||||
if (nativeEventTarget.window === nativeEventTarget) {
|
||||
// TODO: why is this nullable in the types but we read from it?
|
||||
if ((nativeEventTarget: any).window === nativeEventTarget) {
|
||||
// `nativeEventTarget` is probably a window object.
|
||||
win = nativeEventTarget;
|
||||
} else {
|
||||
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
|
||||
const doc = nativeEventTarget.ownerDocument;
|
||||
const doc = (nativeEventTarget: any).ownerDocument;
|
||||
if (doc) {
|
||||
win = doc.defaultView || doc.parentWindow;
|
||||
} else {
|
||||
@@ -91,9 +94,9 @@ function extractEvents(
|
||||
let from;
|
||||
let to;
|
||||
if (isOutEvent) {
|
||||
const related = nativeEvent.relatedTarget || nativeEvent.toElement;
|
||||
const related = nativeEvent.relatedTarget || (nativeEvent: any).toElement;
|
||||
from = targetInst;
|
||||
to = related ? getClosestInstanceFromNode(related) : null;
|
||||
to = related ? getClosestInstanceFromNode((related: any)) : null;
|
||||
if (to !== null) {
|
||||
const nearestMounted = getNearestMountedFiber(to);
|
||||
if (
|
||||
@@ -114,17 +117,11 @@ function extractEvents(
|
||||
return;
|
||||
}
|
||||
|
||||
let eventInterface, leaveEventType, enterEventType, eventTypePrefix;
|
||||
|
||||
if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
|
||||
eventInterface = MouseEventInterface;
|
||||
leaveEventType = 'onMouseLeave';
|
||||
enterEventType = 'onMouseEnter';
|
||||
eventTypePrefix = 'mouse';
|
||||
} else if (
|
||||
topLevelType === TOP_POINTER_OUT ||
|
||||
topLevelType === TOP_POINTER_OVER
|
||||
) {
|
||||
let eventInterface = MouseEventInterface;
|
||||
let leaveEventType = 'onMouseLeave';
|
||||
let enterEventType = 'onMouseEnter';
|
||||
let eventTypePrefix = 'mouse';
|
||||
if (domEventName === 'pointerout' || domEventName === 'pointerover') {
|
||||
eventInterface = PointerEventInterface;
|
||||
leaveEventType = 'onPointerLeave';
|
||||
enterEventType = 'onPointerEnter';
|
||||
@@ -159,7 +156,7 @@ function extractEvents(
|
||||
// If we are not processing the first ancestor, then we
|
||||
// should not process the same nativeEvent again, as we
|
||||
// will have already processed it in the first ancestor.
|
||||
const nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
|
||||
const nativeTargetInst = getClosestInstanceFromNode((nativeEventTarget: any));
|
||||
if (nativeTargetInst !== targetInst) {
|
||||
enter = null;
|
||||
}
|
||||
|
||||
+39
-53
@@ -3,25 +3,21 @@
|
||||
*
|
||||
* 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 {AnyNativeEvent} from '../PluginModuleType';
|
||||
import type {DOMEventName} from '../DOMEventNames';
|
||||
import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
import {SyntheticEvent} from '../../events/SyntheticEvent';
|
||||
import isTextInputElement from '../isTextInputElement';
|
||||
import shallowEqual from 'shared/shallowEqual';
|
||||
|
||||
import {registerTwoPhaseEvent} from '../EventRegistry';
|
||||
import {
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_CONTEXT_MENU,
|
||||
TOP_DRAG_END,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
TOP_MOUSE_UP,
|
||||
TOP_SELECTION_CHANGE,
|
||||
} from '../DOMTopLevelEventTypes';
|
||||
import getActiveElement from '../../client/getActiveElement';
|
||||
import {
|
||||
getNodeFromInstance,
|
||||
@@ -34,21 +30,17 @@ import {accumulateTwoPhaseListeners} from '../DOMPluginEventSystem';
|
||||
const skipSelectionChangeEvent =
|
||||
canUseDOM && 'documentMode' in document && document.documentMode <= 11;
|
||||
|
||||
const rootTargetDependencies = [
|
||||
TOP_FOCUS_OUT,
|
||||
TOP_CONTEXT_MENU,
|
||||
TOP_DRAG_END,
|
||||
TOP_FOCUS_IN,
|
||||
TOP_KEY_DOWN,
|
||||
TOP_KEY_UP,
|
||||
TOP_MOUSE_DOWN,
|
||||
TOP_MOUSE_UP,
|
||||
];
|
||||
|
||||
function registerEvents() {
|
||||
registerTwoPhaseEvent('onSelect', [
|
||||
...rootTargetDependencies,
|
||||
TOP_SELECTION_CHANGE,
|
||||
'focusout',
|
||||
'contextmenu',
|
||||
'dragend',
|
||||
'focusin',
|
||||
'keydown',
|
||||
'keyup',
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'selectionchange',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -62,11 +54,8 @@ let mouseDown = false;
|
||||
*
|
||||
* The return value will not be consistent across nodes or browsers, but
|
||||
* two identical selections on the same node will return identical objects.
|
||||
*
|
||||
* @param {DOMElement} node
|
||||
* @return {object}
|
||||
*/
|
||||
function getSelection(node) {
|
||||
function getSelection(node: any) {
|
||||
if ('selectionStart' in node && hasSelectionCapabilities(node)) {
|
||||
return {
|
||||
start: node.selectionStart,
|
||||
@@ -87,11 +76,8 @@ function getSelection(node) {
|
||||
|
||||
/**
|
||||
* Get document associated with the event target.
|
||||
*
|
||||
* @param {object} nativeEventTarget
|
||||
* @return {Document}
|
||||
*/
|
||||
function getEventTargetDocument(eventTarget) {
|
||||
function getEventTargetDocument(eventTarget: any) {
|
||||
return eventTarget.window === eventTarget
|
||||
? eventTarget.document
|
||||
: eventTarget.nodeType === DOCUMENT_NODE
|
||||
@@ -159,23 +145,23 @@ function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
|
||||
* - Fires after user input.
|
||||
*/
|
||||
function extractEvents(
|
||||
dispatchQueue,
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
eventSystemFlags,
|
||||
targetContainer,
|
||||
dispatchQueue: DispatchQueue,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
) {
|
||||
const eventListenerMap = getEventListenerMap(targetContainer);
|
||||
// Track whether all listeners exists for this plugin. If none exist, we do
|
||||
// not extract events. See #3639.
|
||||
if (
|
||||
// If we are handling TOP_SELECTION_CHANGE, then we don't need to
|
||||
// check for the other dependencies, as TOP_SELECTION_CHANGE is only
|
||||
// If we are handling selectionchange, then we don't need to
|
||||
// check for the other dependencies, as selectionchange is only
|
||||
// event attached from the onChange plugin and we don't expose an
|
||||
// onSelectionChange event from React.
|
||||
topLevelType !== TOP_SELECTION_CHANGE &&
|
||||
domEventName !== 'selectionchange' &&
|
||||
!eventListenerMap.has('onSelect') &&
|
||||
!eventListenerMap.has('onSelectCapture')
|
||||
) {
|
||||
@@ -184,11 +170,11 @@ function extractEvents(
|
||||
|
||||
const targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
|
||||
|
||||
switch (topLevelType) {
|
||||
switch (domEventName) {
|
||||
// Track the input node that has focus.
|
||||
case TOP_FOCUS_IN:
|
||||
case 'focusin':
|
||||
if (
|
||||
isTextInputElement(targetNode) ||
|
||||
isTextInputElement((targetNode: any)) ||
|
||||
targetNode.contentEditable === 'true'
|
||||
) {
|
||||
activeElement = targetNode;
|
||||
@@ -196,19 +182,19 @@ function extractEvents(
|
||||
lastSelection = null;
|
||||
}
|
||||
break;
|
||||
case TOP_FOCUS_OUT:
|
||||
case 'focusout':
|
||||
activeElement = null;
|
||||
activeElementInst = null;
|
||||
lastSelection = null;
|
||||
break;
|
||||
// Don't fire the event while the user is dragging. This matches the
|
||||
// semantics of the native select event.
|
||||
case TOP_MOUSE_DOWN:
|
||||
case 'mousedown':
|
||||
mouseDown = true;
|
||||
break;
|
||||
case TOP_CONTEXT_MENU:
|
||||
case TOP_MOUSE_UP:
|
||||
case TOP_DRAG_END:
|
||||
case 'contextmenu':
|
||||
case 'mouseup':
|
||||
case 'dragend':
|
||||
mouseDown = false;
|
||||
constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
|
||||
break;
|
||||
@@ -221,13 +207,13 @@ function extractEvents(
|
||||
// keyup, but we check on keydown as well in the case of holding down a
|
||||
// key, when multiple keydown events are fired but only one keyup is.
|
||||
// This is also our approach for IE handling, for the reason above.
|
||||
case TOP_SELECTION_CHANGE:
|
||||
case 'selectionchange':
|
||||
if (skipSelectionChangeEvent) {
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case TOP_KEY_DOWN:
|
||||
case TOP_KEY_UP:
|
||||
case 'keydown':
|
||||
case 'keyup':
|
||||
constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
|
||||
}
|
||||
|
||||
|
||||
+56
-51
@@ -7,7 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {TopLevelType} from '../../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../../events/DOMEventNames';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {AnyNativeEvent} from '../../events/PluginModuleType';
|
||||
import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
@@ -28,7 +28,12 @@ import {
|
||||
WheelEventInterface,
|
||||
} from '../../events/SyntheticEvent';
|
||||
|
||||
import * as DOMTopLevelEventTypes from '../DOMTopLevelEventTypes';
|
||||
import {
|
||||
ANIMATION_END,
|
||||
ANIMATION_ITERATION,
|
||||
ANIMATION_START,
|
||||
TRANSITION_END,
|
||||
} from '../DOMEventNames';
|
||||
import {
|
||||
topLevelEventsToReactNames,
|
||||
registerSimpleEvents,
|
||||
@@ -49,20 +54,20 @@ import {
|
||||
|
||||
function extractEvents(
|
||||
dispatchQueue: DispatchQueue,
|
||||
topLevelType: TopLevelType,
|
||||
domEventName: DOMEventName,
|
||||
targetInst: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: EventTarget,
|
||||
): void {
|
||||
const reactName = topLevelEventsToReactNames.get(topLevelType);
|
||||
const reactName = topLevelEventsToReactNames.get(domEventName);
|
||||
if (reactName === undefined) {
|
||||
return;
|
||||
}
|
||||
let EventInterface;
|
||||
switch (topLevelType) {
|
||||
case DOMTopLevelEventTypes.TOP_KEY_PRESS:
|
||||
switch (domEventName) {
|
||||
case 'keypress':
|
||||
// Firefox creates a keypress event for function keys too. This removes
|
||||
// the unwanted keypress events. Enter is however both printable and
|
||||
// non-printable. One would expect Tab to be as well (but it isn't).
|
||||
@@ -70,78 +75,78 @@ function extractEvents(
|
||||
return;
|
||||
}
|
||||
/* falls through */
|
||||
case DOMTopLevelEventTypes.TOP_KEY_DOWN:
|
||||
case DOMTopLevelEventTypes.TOP_KEY_UP:
|
||||
case 'keydown':
|
||||
case 'keyup':
|
||||
EventInterface = KeyboardEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_FOCUS_IN:
|
||||
case DOMTopLevelEventTypes.TOP_FOCUS_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_BEFORE_BLUR:
|
||||
case DOMTopLevelEventTypes.TOP_AFTER_BLUR:
|
||||
case 'focusin':
|
||||
case 'focusout':
|
||||
case 'beforeblur':
|
||||
case 'afterblur':
|
||||
EventInterface = FocusEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_CLICK:
|
||||
case 'click':
|
||||
// Firefox creates a click event on right mouse clicks. This removes the
|
||||
// unwanted click events.
|
||||
if (nativeEvent.button === 2) {
|
||||
return;
|
||||
}
|
||||
/* falls through */
|
||||
case DOMTopLevelEventTypes.TOP_AUX_CLICK:
|
||||
case DOMTopLevelEventTypes.TOP_DOUBLE_CLICK:
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_DOWN:
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_MOVE:
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_UP:
|
||||
case 'auxclick':
|
||||
case 'dblclick':
|
||||
case 'mousedown':
|
||||
case 'mousemove':
|
||||
case 'mouseup':
|
||||
// TODO: Disabled elements should not respond to mouse events
|
||||
/* falls through */
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_CONTEXT_MENU:
|
||||
case 'mouseout':
|
||||
case 'mouseover':
|
||||
case 'contextmenu':
|
||||
EventInterface = MouseEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_DRAG:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_END:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_ENTER:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_EXIT:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_LEAVE:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_START:
|
||||
case DOMTopLevelEventTypes.TOP_DROP:
|
||||
case 'drag':
|
||||
case 'dragend':
|
||||
case 'dragenter':
|
||||
case 'dragexit':
|
||||
case 'dragleave':
|
||||
case 'dragover':
|
||||
case 'dragstart':
|
||||
case 'drop':
|
||||
EventInterface = DragEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_CANCEL:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_END:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_MOVE:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_START:
|
||||
case 'touchcancel':
|
||||
case 'touchend':
|
||||
case 'touchmove':
|
||||
case 'touchstart':
|
||||
EventInterface = TouchEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_END:
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION:
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_START:
|
||||
case ANIMATION_END:
|
||||
case ANIMATION_ITERATION:
|
||||
case ANIMATION_START:
|
||||
EventInterface = AnimationEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_TRANSITION_END:
|
||||
case TRANSITION_END:
|
||||
EventInterface = TransitionEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_SCROLL:
|
||||
case 'scroll':
|
||||
EventInterface = UIEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_WHEEL:
|
||||
case 'wheel':
|
||||
EventInterface = WheelEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_COPY:
|
||||
case DOMTopLevelEventTypes.TOP_CUT:
|
||||
case DOMTopLevelEventTypes.TOP_PASTE:
|
||||
case 'copy':
|
||||
case 'cut':
|
||||
case 'paste':
|
||||
EventInterface = ClipboardEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_GOT_POINTER_CAPTURE:
|
||||
case DOMTopLevelEventTypes.TOP_LOST_POINTER_CAPTURE:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_CANCEL:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_DOWN:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_MOVE:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_UP:
|
||||
case 'gotpointercapture':
|
||||
case 'lostpointercapture':
|
||||
case 'pointercancel':
|
||||
case 'pointerdown':
|
||||
case 'pointermove':
|
||||
case 'pointerout':
|
||||
case 'pointerover':
|
||||
case 'pointerup':
|
||||
EventInterface = PointerEventInterface;
|
||||
break;
|
||||
default:
|
||||
@@ -179,7 +184,7 @@ function extractEvents(
|
||||
// TODO: ideally, we'd eventually add all events from
|
||||
// nonDelegatedEvents list in DOMPluginEventSystem.
|
||||
// Then we can remove this special list.
|
||||
topLevelType === DOMTopLevelEventTypes.TOP_SCROLL;
|
||||
domEventName === 'scroll';
|
||||
}
|
||||
|
||||
accumulateSinglePhaseListeners(
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import type {
|
||||
EventPriority,
|
||||
ReactScopeInstance,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {DOMEventName} from '../events/DOMEventNames';
|
||||
|
||||
type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch;
|
||||
|
||||
@@ -86,5 +86,5 @@ export type ReactDOMEventHandle = (
|
||||
export type ReactDOMEventHandleListener = {|
|
||||
callback: (SyntheticEvent<EventTarget>) => void,
|
||||
capture: boolean,
|
||||
type: DOMTopLevelEventType,
|
||||
type: DOMEventName,
|
||||
|};
|
||||
|
||||
Reference in New Issue
Block a user