Make event config an implementation detail of each plugin (#19236)
* Merge two variables with same purpose * Replace dispatchConfig with _reactName on event object
This commit is contained in:
parent
b683c07ccc
commit
991c3b8193
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
registrationNames,
|
||||
registrationNameDependencies,
|
||||
possibleRegistrationNames,
|
||||
} from '../events/EventPluginRegistry';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
|
@ -133,7 +133,7 @@ if (__DEV__) {
|
|||
validateARIAProperties(type, props);
|
||||
validateInputProperties(type, props);
|
||||
validateUnknownProperties(type, props, {
|
||||
registrationNames,
|
||||
registrationNameDependencies,
|
||||
possibleRegistrationNames,
|
||||
});
|
||||
};
|
||||
|
@ -356,7 +356,7 @@ function setInitialDOMProperties(
|
|||
// We could have excluded it in the property list instead of
|
||||
// adding a special case here, but then it wouldn't be emitted
|
||||
// on server rendering (but we *do* want to emit it in SSR).
|
||||
} else if (registrationNames.hasOwnProperty(propKey)) {
|
||||
} else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
||||
if (nextProp != null) {
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
warnForInvalidEventListener(propKey, nextProp);
|
||||
|
@ -694,7 +694,7 @@ export function diffProperties(
|
|||
// Noop
|
||||
} else if (propKey === AUTOFOCUS) {
|
||||
// Noop. It doesn't work on updates anyway.
|
||||
} else if (registrationNames.hasOwnProperty(propKey)) {
|
||||
} else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
||||
// This is a special case. If any listener updates we need to ensure
|
||||
// that the "current" fiber pointer gets updated so we need a commit
|
||||
// to update this element.
|
||||
|
@ -781,7 +781,7 @@ export function diffProperties(
|
|||
propKey === SUPPRESS_HYDRATION_WARNING
|
||||
) {
|
||||
// Noop
|
||||
} else if (registrationNames.hasOwnProperty(propKey)) {
|
||||
} else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
||||
if (nextProp != null) {
|
||||
// We eagerly listen to this even though we haven't committed yet.
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
|
@ -978,7 +978,7 @@ export function diffHydratedProperties(
|
|||
updatePayload = [CHILDREN, '' + nextProp];
|
||||
}
|
||||
}
|
||||
} else if (registrationNames.hasOwnProperty(propKey)) {
|
||||
} else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
||||
if (nextProp != null) {
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
warnForInvalidEventListener(propKey, nextProp);
|
||||
|
|
|
@ -13,10 +13,6 @@ import type {
|
|||
DOMTopLevelEventType,
|
||||
} from '../events/TopLevelEventTypes';
|
||||
import type {EventTypes} from '../events/PluginModuleType';
|
||||
import type {
|
||||
DispatchConfig,
|
||||
CustomDispatchConfig,
|
||||
} from '../events/ReactSyntheticEventType';
|
||||
|
||||
import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
|
||||
import {
|
||||
|
@ -35,9 +31,9 @@ import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
|
|||
// update the below line.
|
||||
export const simpleEventPluginEventTypes: EventTypes = {};
|
||||
|
||||
export const topLevelEventsToDispatchConfig: Map<
|
||||
export const topLevelEventsToReactNames: Map<
|
||||
TopLevelType,
|
||||
DispatchConfig | CustomDispatchConfig,
|
||||
string | null,
|
||||
> = new Map();
|
||||
|
||||
const eventPriorities = new Map();
|
||||
|
@ -167,8 +163,8 @@ const continuousPairsForSimpleEventPlugin = [
|
|||
* },
|
||||
* ...
|
||||
* };
|
||||
* topLevelEventsToDispatchConfig = new Map([
|
||||
* [TOP_ABORT, { sameConfig }],
|
||||
* topLevelEventsToReactNames = new Map([
|
||||
* [TOP_ABORT, 'onAbort'],
|
||||
* ]);
|
||||
*/
|
||||
|
||||
|
@ -197,7 +193,7 @@ function processSimpleEventPluginPairsByPriority(
|
|||
eventPriority: priority,
|
||||
};
|
||||
eventPriorities.set(topEvent, priority);
|
||||
topLevelEventsToDispatchConfig.set(topEvent, config);
|
||||
topLevelEventsToReactNames.set(topEvent, onEvent);
|
||||
simpleEventPluginEventTypes[event] = config;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ import type {
|
|||
DispatchQueueItemPhase,
|
||||
DispatchQueueItemPhaseEntry,
|
||||
} from './PluginModuleType';
|
||||
import type {
|
||||
ReactSyntheticEvent,
|
||||
CustomDispatchConfig,
|
||||
} from './ReactSyntheticEventType';
|
||||
import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
|
||||
import type {
|
||||
ElementListenerMap,
|
||||
ElementListenerMapEntry,
|
||||
|
@ -113,7 +110,7 @@ import {
|
|||
addEventCaptureListenerWithPassiveFlag,
|
||||
} from './EventListener';
|
||||
import {removeTrappedEventListener} from './DeprecatedDOMEventResponderSystem';
|
||||
import {topLevelEventsToDispatchConfig} from './DOMEventProperties';
|
||||
import {topLevelEventsToReactNames} from './DOMEventProperties';
|
||||
import * as ModernBeforeInputEventPlugin from './plugins/ModernBeforeInputEventPlugin';
|
||||
import * as ModernChangeEventPlugin from './plugins/ModernChangeEventPlugin';
|
||||
import * as ModernEnterLeaveEventPlugin from './plugins/ModernEnterLeaveEventPlugin';
|
||||
|
@ -223,14 +220,6 @@ if (enableCreateEventHandleAPI) {
|
|||
capturePhaseEvents.add(TOP_AFTER_BLUR);
|
||||
}
|
||||
|
||||
const emptyDispatchConfigForCustomEvents: CustomDispatchConfig = {
|
||||
customEvent: true,
|
||||
phasedRegistrationNames: {
|
||||
bubbled: null,
|
||||
captured: null,
|
||||
},
|
||||
};
|
||||
|
||||
function executeDispatch(
|
||||
event: ReactSyntheticEvent,
|
||||
listener: Function,
|
||||
|
@ -639,11 +628,11 @@ export function accumulateTwoPhaseListeners(
|
|||
event: ReactSyntheticEvent,
|
||||
accumulateEventHandleListeners?: boolean,
|
||||
): void {
|
||||
const phasedRegistrationNames = event.dispatchConfig.phasedRegistrationNames;
|
||||
const bubbled = event._reactName;
|
||||
const captured = bubbled !== null ? bubbled + 'Capture' : null;
|
||||
const capturePhase: DispatchQueueItemPhase = [];
|
||||
const bubblePhase: DispatchQueueItemPhase = [];
|
||||
|
||||
const {bubbled, captured} = phasedRegistrationNames;
|
||||
// If we are not handling EventTarget only phase, then we're doing the
|
||||
// usual two phase accumulation using the React fiber tree to pick up
|
||||
// all relevant useEvent and on* prop events.
|
||||
|
@ -826,7 +815,7 @@ function accumulateEnterLeaveListenersForEvent(
|
|||
common: Fiber | null,
|
||||
capture: boolean,
|
||||
): void {
|
||||
const registrationName = event.dispatchConfig.registrationName;
|
||||
const registrationName = event._reactName;
|
||||
if (registrationName === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -944,17 +933,14 @@ export function accumulateEventTargetListeners(
|
|||
}
|
||||
|
||||
export function addEventTypeToDispatchConfig(type: DOMTopLevelEventType): void {
|
||||
const dispatchConfig = topLevelEventsToDispatchConfig.get(type);
|
||||
// If we don't have a dispatchConfig, then we're dealing with
|
||||
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).
|
||||
// We need to register an event config for this or the SimpleEventPlugin
|
||||
// will not appropriately provide a SyntheticEvent, so we use out empty
|
||||
// dispatch config for custom events.
|
||||
if (dispatchConfig === undefined) {
|
||||
topLevelEventsToDispatchConfig.set(
|
||||
type,
|
||||
emptyDispatchConfigForCustomEvents,
|
||||
);
|
||||
if (reactName === undefined) {
|
||||
topLevelEventsToReactNames.set(type, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,6 @@
|
|||
import type {TopLevelType} from './TopLevelEventTypes';
|
||||
import type {EventTypes} from './PluginModuleType';
|
||||
|
||||
import invariant from 'shared/invariant';
|
||||
|
||||
/**
|
||||
* Mapping from registration name to plugin module
|
||||
*/
|
||||
export const registrationNames = {};
|
||||
|
||||
/**
|
||||
* Mapping from registration name to event name
|
||||
*/
|
||||
|
@ -62,13 +55,16 @@ function publishRegistrationName(
|
|||
registrationName: string,
|
||||
dependencies: ?Array<TopLevelType>,
|
||||
): void {
|
||||
invariant(
|
||||
!registrationNames[registrationName],
|
||||
'EventPluginRegistry: More than one plugin attempted to publish the same ' +
|
||||
'registration name, `%s`.',
|
||||
registrationName,
|
||||
);
|
||||
registrationNames[registrationName] = true;
|
||||
if (__DEV__) {
|
||||
if (registrationNameDependencies[registrationName]) {
|
||||
console.error(
|
||||
'EventPluginRegistry: More than one plugin attempted to publish the same ' +
|
||||
'registration name, `%s`.',
|
||||
registrationName,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
registrationNameDependencies[registrationName] = dependencies;
|
||||
|
||||
if (__DEV__) {
|
||||
|
|
|
@ -22,21 +22,12 @@ export type DispatchConfig = {|
|
|||
eventPriority?: EventPriority,
|
||||
|};
|
||||
|
||||
export type CustomDispatchConfig = {|
|
||||
phasedRegistrationNames: {|
|
||||
bubbled: null,
|
||||
captured: null,
|
||||
|},
|
||||
registrationName?: string,
|
||||
customEvent: true,
|
||||
|};
|
||||
|
||||
export type ReactSyntheticEvent = {|
|
||||
dispatchConfig: DispatchConfig | CustomDispatchConfig,
|
||||
isPersistent: () => boolean,
|
||||
isPropagationStopped: () => boolean,
|
||||
_dispatchInstances?: null | Array<Fiber | null> | Fiber,
|
||||
_dispatchListeners?: null | Array<Function> | Function,
|
||||
_reactName: string,
|
||||
_targetInst: Fiber,
|
||||
type: string,
|
||||
currentTarget: null | EventTarget,
|
||||
|
|
|
@ -48,19 +48,9 @@ function functionThatReturnsFalse() {
|
|||
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by
|
||||
* normalizing browser quirks. Subclasses do not necessarily have to implement a
|
||||
* DOM interface; custom application-specific events can also subclass this.
|
||||
*
|
||||
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
||||
* @param {*} targetInst Marker identifying the event target.
|
||||
* @param {object} nativeEvent Native browser event.
|
||||
* @param {DOMEventTarget} nativeEventTarget Target node.
|
||||
*/
|
||||
function SyntheticEvent(
|
||||
dispatchConfig,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
) {
|
||||
this.dispatchConfig = dispatchConfig;
|
||||
function SyntheticEvent(reactName, targetInst, nativeEvent, nativeEventTarget) {
|
||||
this._reactName = reactName;
|
||||
this._targetInst = targetInst;
|
||||
this.nativeEvent = nativeEvent;
|
||||
|
||||
|
|
|
@ -140,11 +140,11 @@ function isKeypressCommand(nativeEvent) {
|
|||
function getCompositionEventType(topLevelType) {
|
||||
switch (topLevelType) {
|
||||
case TOP_COMPOSITION_START:
|
||||
return eventTypes.compositionStart;
|
||||
return 'onCompositionStart';
|
||||
case TOP_COMPOSITION_END:
|
||||
return eventTypes.compositionEnd;
|
||||
return 'onCompositionEnd';
|
||||
case TOP_COMPOSITION_UPDATE:
|
||||
return eventTypes.compositionUpdate;
|
||||
return 'onCompositionUpdate';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,10 +237,10 @@ function extractCompositionEvent(
|
|||
eventType = getCompositionEventType(topLevelType);
|
||||
} else if (!isComposing) {
|
||||
if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
|
||||
eventType = eventTypes.compositionStart;
|
||||
eventType = 'onCompositionStart';
|
||||
}
|
||||
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
|
||||
eventType = eventTypes.compositionEnd;
|
||||
eventType = 'onCompositionEnd';
|
||||
}
|
||||
|
||||
if (!eventType) {
|
||||
|
@ -250,9 +250,9 @@ function extractCompositionEvent(
|
|||
if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
|
||||
// The current composition is stored statically and must not be
|
||||
// overwritten while composition continues.
|
||||
if (!isComposing && eventType === eventTypes.compositionStart) {
|
||||
if (!isComposing && eventType === 'onCompositionStart') {
|
||||
isComposing = FallbackCompositionStateInitialize(nativeEventTarget);
|
||||
} else if (eventType === eventTypes.compositionEnd) {
|
||||
} else if (eventType === 'onCompositionEnd') {
|
||||
if (isComposing) {
|
||||
fallbackData = FallbackCompositionStateGetData();
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ function extractBeforeInputEvent(
|
|||
}
|
||||
|
||||
const event = new SyntheticInputEvent(
|
||||
eventTypes.beforeInput,
|
||||
'onBeforeInput',
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
|
|
@ -64,12 +64,7 @@ function createAndAccumulateChangeEvent(
|
|||
nativeEvent,
|
||||
target,
|
||||
) {
|
||||
const event = new SyntheticEvent(
|
||||
eventTypes.change,
|
||||
null,
|
||||
nativeEvent,
|
||||
target,
|
||||
);
|
||||
const event = new SyntheticEvent('onChange', null, nativeEvent, target);
|
||||
event.type = 'change';
|
||||
// Flag this event loop as needing state restore.
|
||||
enqueueStateRestore(((target: any): Node));
|
||||
|
|
|
@ -126,16 +126,16 @@ function extractEvents(
|
|||
|
||||
if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
|
||||
eventInterface = SyntheticMouseEvent;
|
||||
leaveEventType = eventTypes.mouseLeave;
|
||||
enterEventType = eventTypes.mouseEnter;
|
||||
leaveEventType = 'onMouseLeave';
|
||||
enterEventType = 'onMouseEnter';
|
||||
eventTypePrefix = 'mouse';
|
||||
} else if (
|
||||
topLevelType === TOP_POINTER_OUT ||
|
||||
topLevelType === TOP_POINTER_OVER
|
||||
) {
|
||||
eventInterface = SyntheticPointerEvent;
|
||||
leaveEventType = eventTypes.pointerLeave;
|
||||
enterEventType = eventTypes.pointerEnter;
|
||||
leaveEventType = 'onPointerLeave';
|
||||
enterEventType = 'onPointerEnter';
|
||||
eventTypePrefix = 'pointer';
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
|
|||
lastSelection = currentSelection;
|
||||
|
||||
const syntheticEvent = new SyntheticEvent(
|
||||
eventTypes.select,
|
||||
'onSelect',
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
import type {
|
||||
TopLevelType,
|
||||
DOMTopLevelEventType,
|
||||
} from '../../events/TopLevelEventTypes';
|
||||
import type {TopLevelType} from '../../events/TopLevelEventTypes';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {
|
||||
AnyNativeEvent,
|
||||
|
@ -22,7 +19,7 @@ import SyntheticEvent from '../../events/SyntheticEvent';
|
|||
|
||||
import * as DOMTopLevelEventTypes from '../DOMTopLevelEventTypes';
|
||||
import {
|
||||
topLevelEventsToDispatchConfig,
|
||||
topLevelEventsToReactNames,
|
||||
simpleEventPluginEventTypes,
|
||||
} from '../DOMEventProperties';
|
||||
import {
|
||||
|
@ -46,41 +43,6 @@ import getEventCharCode from '../getEventCharCode';
|
|||
|
||||
import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
|
||||
|
||||
// Only used in DEV for exhaustiveness validation.
|
||||
const knownHTMLTopLevelTypes: Array<DOMTopLevelEventType> = [
|
||||
DOMTopLevelEventTypes.TOP_ABORT,
|
||||
DOMTopLevelEventTypes.TOP_CANCEL,
|
||||
DOMTopLevelEventTypes.TOP_CAN_PLAY,
|
||||
DOMTopLevelEventTypes.TOP_CAN_PLAY_THROUGH,
|
||||
DOMTopLevelEventTypes.TOP_CLOSE,
|
||||
DOMTopLevelEventTypes.TOP_DURATION_CHANGE,
|
||||
DOMTopLevelEventTypes.TOP_EMPTIED,
|
||||
DOMTopLevelEventTypes.TOP_ENCRYPTED,
|
||||
DOMTopLevelEventTypes.TOP_ENDED,
|
||||
DOMTopLevelEventTypes.TOP_ERROR,
|
||||
DOMTopLevelEventTypes.TOP_INPUT,
|
||||
DOMTopLevelEventTypes.TOP_INVALID,
|
||||
DOMTopLevelEventTypes.TOP_LOAD,
|
||||
DOMTopLevelEventTypes.TOP_LOADED_DATA,
|
||||
DOMTopLevelEventTypes.TOP_LOADED_METADATA,
|
||||
DOMTopLevelEventTypes.TOP_LOAD_START,
|
||||
DOMTopLevelEventTypes.TOP_PAUSE,
|
||||
DOMTopLevelEventTypes.TOP_PLAY,
|
||||
DOMTopLevelEventTypes.TOP_PLAYING,
|
||||
DOMTopLevelEventTypes.TOP_PROGRESS,
|
||||
DOMTopLevelEventTypes.TOP_RATE_CHANGE,
|
||||
DOMTopLevelEventTypes.TOP_RESET,
|
||||
DOMTopLevelEventTypes.TOP_SEEKED,
|
||||
DOMTopLevelEventTypes.TOP_SEEKING,
|
||||
DOMTopLevelEventTypes.TOP_STALLED,
|
||||
DOMTopLevelEventTypes.TOP_SUBMIT,
|
||||
DOMTopLevelEventTypes.TOP_SUSPEND,
|
||||
DOMTopLevelEventTypes.TOP_TIME_UPDATE,
|
||||
DOMTopLevelEventTypes.TOP_TOGGLE,
|
||||
DOMTopLevelEventTypes.TOP_VOLUME_CHANGE,
|
||||
DOMTopLevelEventTypes.TOP_WAITING,
|
||||
];
|
||||
|
||||
function extractEvents(
|
||||
dispatchQueue: DispatchQueue,
|
||||
topLevelType: TopLevelType,
|
||||
|
@ -90,8 +52,8 @@ function extractEvents(
|
|||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: null | EventTarget,
|
||||
): void {
|
||||
const dispatchConfig = topLevelEventsToDispatchConfig.get(topLevelType);
|
||||
if (!dispatchConfig) {
|
||||
const reactName = topLevelEventsToReactNames.get(topLevelType);
|
||||
if (reactName === undefined) {
|
||||
return;
|
||||
}
|
||||
let EventConstructor;
|
||||
|
@ -179,25 +141,12 @@ function extractEvents(
|
|||
EventConstructor = SyntheticPointerEvent;
|
||||
break;
|
||||
default:
|
||||
if (__DEV__) {
|
||||
if (
|
||||
knownHTMLTopLevelTypes.indexOf(topLevelType) === -1 &&
|
||||
dispatchConfig.customEvent !== true
|
||||
) {
|
||||
console.error(
|
||||
'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' +
|
||||
'is likely caused by a bug in React. Please file an issue.',
|
||||
topLevelType,
|
||||
);
|
||||
}
|
||||
}
|
||||
// HTML Events
|
||||
// @see http://www.w3.org/TR/html5/index.html#events-0
|
||||
// Unknown event. This is used by createEventHandle.
|
||||
EventConstructor = SyntheticEvent;
|
||||
break;
|
||||
}
|
||||
const event = new EventConstructor(
|
||||
dispatchConfig,
|
||||
reactName,
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
|
|
@ -43,8 +43,11 @@ if (__DEV__) {
|
|||
|
||||
// We can't rely on the event system being injected on the server.
|
||||
if (eventRegistry != null) {
|
||||
const {registrationNames, possibleRegistrationNames} = eventRegistry;
|
||||
if (registrationNames.hasOwnProperty(name)) {
|
||||
const {
|
||||
registrationNameDependencies,
|
||||
possibleRegistrationNames,
|
||||
} = eventRegistry;
|
||||
if (registrationNameDependencies.hasOwnProperty(name)) {
|
||||
return true;
|
||||
}
|
||||
const registrationName = possibleRegistrationNames.hasOwnProperty(
|
||||
|
|
|
@ -491,14 +491,16 @@ function getListener(inst: Fiber, registrationName: string) {
|
|||
}
|
||||
|
||||
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
|
||||
const registrationName =
|
||||
event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
||||
let registrationName = event._reactName;
|
||||
if (propagationPhase === 'captured') {
|
||||
registrationName += 'Capture';
|
||||
}
|
||||
return getListener(inst, registrationName);
|
||||
}
|
||||
|
||||
function accumulateDispatches(inst, ignoredDirection, event) {
|
||||
if (inst && event && event.dispatchConfig.registrationName) {
|
||||
const registrationName = event.dispatchConfig.registrationName;
|
||||
if (inst && event && event._reactName) {
|
||||
const registrationName = event._reactName;
|
||||
const listener = getListener(inst, registrationName);
|
||||
if (listener) {
|
||||
if (event._dispatchListeners == null) {
|
||||
|
@ -533,13 +535,13 @@ function accumulateDirectionalDispatches(inst, phase, event) {
|
|||
}
|
||||
|
||||
function accumulateDirectDispatchesSingle(event) {
|
||||
if (event && event.dispatchConfig.registrationName) {
|
||||
if (event && event._reactName) {
|
||||
accumulateDispatches(event._targetInst, null, event);
|
||||
}
|
||||
}
|
||||
|
||||
function accumulateTwoPhaseDispatchesSingle(event) {
|
||||
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
||||
if (event && event._reactName) {
|
||||
traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
|
||||
}
|
||||
}
|
||||
|
@ -577,27 +579,14 @@ function makeSimulator(eventType) {
|
|||
'a component instance. Pass the DOM node you wish to simulate the event on instead.',
|
||||
);
|
||||
|
||||
// Reconstruct more or less what the original event system produced.
|
||||
// We could remove this indirection here but we also don't plan to invest in Simulate anyway.
|
||||
const dispatchConfig = {};
|
||||
if (directDispatchEventTypes.has(eventType)) {
|
||||
dispatchConfig.registrationName =
|
||||
'on' + eventType[0].toUpperCase() + eventType.slice(1);
|
||||
} else {
|
||||
dispatchConfig.phasedRegistrationNames = {
|
||||
bubbled: 'on' + eventType[0].toUpperCase() + eventType.slice(1),
|
||||
captured:
|
||||
'on' + eventType[0].toUpperCase() + eventType.slice(1) + 'Capture',
|
||||
};
|
||||
}
|
||||
|
||||
const reactName = 'on' + eventType[0].toUpperCase() + eventType.slice(1);
|
||||
const fakeNativeEvent = new Event();
|
||||
fakeNativeEvent.target = domNode;
|
||||
fakeNativeEvent.type = eventType.toLowerCase();
|
||||
|
||||
const targetInst = getInstanceFromNode(domNode);
|
||||
const event = new SyntheticEvent(
|
||||
dispatchConfig,
|
||||
reactName,
|
||||
targetInst,
|
||||
fakeNativeEvent,
|
||||
domNode,
|
||||
|
@ -608,10 +597,10 @@ function makeSimulator(eventType) {
|
|||
event.persist();
|
||||
Object.assign(event, eventData);
|
||||
|
||||
if (dispatchConfig.phasedRegistrationNames) {
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
} else {
|
||||
if (directDispatchEventTypes.has(eventType)) {
|
||||
accumulateDirectDispatchesSingle(event);
|
||||
} else {
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
}
|
||||
|
||||
ReactDOM.unstable_batchedUpdates(function() {
|
||||
|
|
Loading…
Reference in New Issue