mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Extract some of the tidy up changes from 19278 (#19315)
This commit is contained in:
parent
a2b4db05bc
commit
61dd00db24
|
|
@ -85,7 +85,7 @@ import {
|
|||
enableDeprecatedFlareAPI,
|
||||
enableTrustedTypesIntegration,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {listenToReactPropEvent} from '../events/DOMModernPluginEventSystem';
|
||||
import {listenToReactEvent} from '../events/DOMModernPluginEventSystem';
|
||||
import {getEventListenerMap} from './ReactDOMComponentTree';
|
||||
|
||||
let didWarnInvalidHydration = false;
|
||||
|
|
@ -282,10 +282,7 @@ export function ensureListeningTo(
|
|||
'ensureListeningTo(): received a container that was not an element node. ' +
|
||||
'This is likely a bug in React.',
|
||||
);
|
||||
listenToReactPropEvent(
|
||||
reactPropEvent,
|
||||
((rootContainerElement: any): Element),
|
||||
);
|
||||
listenToReactEvent(reactPropEvent, ((rootContainerElement: any): Element));
|
||||
}
|
||||
|
||||
function getOwnerDocumentFromRootContainer(
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ import {
|
|||
} from './ReactDOMComponentTree';
|
||||
import {ELEMENT_NODE} from '../shared/HTMLNodeType';
|
||||
import {
|
||||
listenToTopLevelEvent,
|
||||
listenToNativeEvent,
|
||||
addEventTypeToDispatchConfig,
|
||||
} from '../events/DOMModernPluginEventSystem';
|
||||
|
||||
import {HostRoot, HostPortal} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {
|
||||
PLUGIN_EVENT_SYSTEM,
|
||||
IS_TARGET_PHASE_ONLY,
|
||||
IS_EVENT_HANDLE_NON_MANAGED_NODE,
|
||||
} from '../events/EventSystemFlags';
|
||||
|
||||
import {
|
||||
|
|
@ -71,12 +71,12 @@ function isReactScope(target: EventTarget | ReactScopeInstance): boolean {
|
|||
|
||||
function createEventHandleListener(
|
||||
type: DOMTopLevelEventType,
|
||||
capture: boolean,
|
||||
isCapturePhaseListener: boolean,
|
||||
callback: (SyntheticEvent<EventTarget>) => void,
|
||||
): ReactDOMEventHandleListener {
|
||||
return {
|
||||
callback,
|
||||
capture,
|
||||
capture: isCapturePhaseListener,
|
||||
type,
|
||||
};
|
||||
}
|
||||
|
|
@ -84,9 +84,9 @@ function createEventHandleListener(
|
|||
function registerEventOnNearestTargetContainer(
|
||||
targetFiber: Fiber,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
passive: boolean | void,
|
||||
priority: EventPriority | void,
|
||||
capture: boolean,
|
||||
isPassiveListener: boolean | void,
|
||||
listenerPriority: EventPriority | void,
|
||||
isCapturePhaseListener: boolean,
|
||||
): void {
|
||||
// If it is, find the nearest root or portal and make it
|
||||
// our event handle target container.
|
||||
|
|
@ -99,23 +99,23 @@ function registerEventOnNearestTargetContainer(
|
|||
);
|
||||
}
|
||||
const listenerMap = getEventListenerMap(targetContainer);
|
||||
listenToTopLevelEvent(
|
||||
listenToNativeEvent(
|
||||
topLevelType,
|
||||
targetContainer,
|
||||
listenerMap,
|
||||
PLUGIN_EVENT_SYSTEM,
|
||||
capture,
|
||||
passive,
|
||||
priority,
|
||||
isCapturePhaseListener,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
);
|
||||
}
|
||||
|
||||
function registerReactDOMEvent(
|
||||
target: EventTarget | ReactScopeInstance,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
passive: boolean | void,
|
||||
capture: boolean,
|
||||
priority: EventPriority | void,
|
||||
isPassiveListener: boolean | void,
|
||||
isCapturePhaseListener: boolean,
|
||||
listenerPriority: EventPriority | void,
|
||||
): void {
|
||||
// Check if the target is a DOM element.
|
||||
if ((target: any).nodeType === ELEMENT_NODE) {
|
||||
|
|
@ -132,9 +132,9 @@ function registerReactDOMEvent(
|
|||
registerEventOnNearestTargetContainer(
|
||||
targetFiber,
|
||||
topLevelType,
|
||||
passive,
|
||||
priority,
|
||||
capture,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
} else if (enableScopeAPI && isReactScope(target)) {
|
||||
const scopeTarget = ((target: any): ReactScopeInstance);
|
||||
|
|
@ -146,21 +146,21 @@ function registerReactDOMEvent(
|
|||
registerEventOnNearestTargetContainer(
|
||||
targetFiber,
|
||||
topLevelType,
|
||||
passive,
|
||||
priority,
|
||||
capture,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
} else if (isValidEventTarget(target)) {
|
||||
const eventTarget = ((target: any): EventTarget);
|
||||
const listenerMap = getEventListenerMap(eventTarget);
|
||||
listenToTopLevelEvent(
|
||||
listenToNativeEvent(
|
||||
topLevelType,
|
||||
eventTarget,
|
||||
listenerMap,
|
||||
PLUGIN_EVENT_SYSTEM | IS_TARGET_PHASE_ONLY,
|
||||
capture,
|
||||
passive,
|
||||
priority,
|
||||
PLUGIN_EVENT_SYSTEM | IS_EVENT_HANDLE_NON_MANAGED_NODE,
|
||||
isCapturePhaseListener,
|
||||
isPassiveListener,
|
||||
listenerPriority,
|
||||
);
|
||||
} else {
|
||||
invariant(
|
||||
|
|
@ -177,9 +177,9 @@ export function createEventHandle(
|
|||
): ReactDOMEventHandle {
|
||||
if (enableCreateEventHandleAPI) {
|
||||
const topLevelType = ((type: any): DOMTopLevelEventType);
|
||||
let capture = false;
|
||||
let passive = undefined; // Undefined means to use the browser default
|
||||
let priority;
|
||||
let isCapturePhaseListener = false;
|
||||
let isPassiveListener = undefined; // Undefined means to use the browser default
|
||||
let listenerPriority;
|
||||
|
||||
if (options != null) {
|
||||
const optionsCapture = options.capture;
|
||||
|
|
@ -187,17 +187,17 @@ export function createEventHandle(
|
|||
const optionsPriority = options.priority;
|
||||
|
||||
if (typeof optionsCapture === 'boolean') {
|
||||
capture = optionsCapture;
|
||||
isCapturePhaseListener = optionsCapture;
|
||||
}
|
||||
if (typeof optionsPassive === 'boolean') {
|
||||
passive = optionsPassive;
|
||||
isPassiveListener = optionsPassive;
|
||||
}
|
||||
if (typeof optionsPriority === 'number') {
|
||||
priority = optionsPriority;
|
||||
listenerPriority = optionsPriority;
|
||||
}
|
||||
}
|
||||
if (priority === undefined) {
|
||||
priority = getEventPriorityForListenerSystem(topLevelType);
|
||||
if (listenerPriority === undefined) {
|
||||
listenerPriority = getEventPriorityForListenerSystem(topLevelType);
|
||||
}
|
||||
|
||||
const registeredReactDOMEvents = new PossiblyWeakSet();
|
||||
|
|
@ -213,13 +213,19 @@ export function createEventHandle(
|
|||
);
|
||||
if (!registeredReactDOMEvents.has(target)) {
|
||||
registeredReactDOMEvents.add(target);
|
||||
registerReactDOMEvent(target, topLevelType, passive, capture, priority);
|
||||
registerReactDOMEvent(
|
||||
target,
|
||||
topLevelType,
|
||||
isPassiveListener,
|
||||
isCapturePhaseListener,
|
||||
listenerPriority,
|
||||
);
|
||||
// Add the event to our known event types list.
|
||||
addEventTypeToDispatchConfig(topLevelType);
|
||||
}
|
||||
const listener = createEventHandleListener(
|
||||
topLevelType,
|
||||
capture,
|
||||
isCapturePhaseListener,
|
||||
callback,
|
||||
);
|
||||
let targetListeners = getEventHandlerListeners(target);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ import {
|
|||
} from 'shared/ReactFeatureFlags';
|
||||
import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
|
||||
import {listenToReactPropEvent} from '../events/DOMModernPluginEventSystem';
|
||||
import {listenToReactEvent} from '../events/DOMModernPluginEventSystem';
|
||||
|
||||
export type Type = string;
|
||||
export type Props = {
|
||||
|
|
@ -1111,7 +1111,7 @@ export function makeOpaqueHydratingObject(
|
|||
}
|
||||
|
||||
export function preparePortalMount(portalInstance: Instance): void {
|
||||
listenToReactPropEvent('onMouseEnter', portalInstance);
|
||||
listenToReactEvent('onMouseEnter', portalInstance);
|
||||
}
|
||||
|
||||
export function prepareScopeUpdate(
|
||||
|
|
|
|||
|
|
@ -9,13 +9,7 @@
|
|||
|
||||
import type {TopLevelType, DOMTopLevelEventType} from './TopLevelEventTypes';
|
||||
import type {EventSystemFlags} from './EventSystemFlags';
|
||||
import type {
|
||||
AnyNativeEvent,
|
||||
DispatchQueue,
|
||||
DispatchQueueItem,
|
||||
DispatchQueueItemPhase,
|
||||
DispatchQueueItemPhaseEntry,
|
||||
} from './PluginModuleType';
|
||||
import type {AnyNativeEvent} from './PluginModuleType';
|
||||
import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
|
||||
import type {
|
||||
ElementListenerMap,
|
||||
|
|
@ -30,7 +24,7 @@ import {
|
|||
LEGACY_FB_SUPPORT,
|
||||
IS_REPLAYED,
|
||||
IS_CAPTURE_PHASE,
|
||||
IS_TARGET_PHASE_ONLY,
|
||||
IS_EVENT_HANDLE_NON_MANAGED_NODE,
|
||||
} from './EventSystemFlags';
|
||||
|
||||
import {
|
||||
|
|
@ -115,6 +109,19 @@ import * as ModernEnterLeaveEventPlugin from './plugins/ModernEnterLeaveEventPlu
|
|||
import * as ModernSelectEventPlugin from './plugins/ModernSelectEventPlugin';
|
||||
import * as ModernSimpleEventPlugin from './plugins/ModernSimpleEventPlugin';
|
||||
|
||||
type DispatchListener = {|
|
||||
instance: null | Fiber,
|
||||
listener: Function,
|
||||
currentTarget: EventTarget,
|
||||
|};
|
||||
|
||||
type DispatchEntry = {|
|
||||
event: ReactSyntheticEvent,
|
||||
listeners: Array<DispatchListener>,
|
||||
|};
|
||||
|
||||
export type DispatchQueue = Array<DispatchEntry>;
|
||||
|
||||
// TODO: remove top-level side effect.
|
||||
ModernSimpleEventPlugin.registerEvents();
|
||||
ModernEnterLeaveEventPlugin.registerEvents();
|
||||
|
|
@ -129,7 +136,7 @@ function extractEvents(
|
|||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: null | EventTarget,
|
||||
targetContainer: EventTarget,
|
||||
) {
|
||||
// TODO: we should remove the concept of a "SimpleEventPlugin".
|
||||
// This is the basic functionality of the event system. All
|
||||
|
|
@ -259,13 +266,13 @@ function executeDispatch(
|
|||
|
||||
function processDispatchQueueItemsInOrder(
|
||||
event: ReactSyntheticEvent,
|
||||
phase: DispatchQueueItemPhase,
|
||||
dispatchListeners: Array<DispatchListener>,
|
||||
inCapturePhase: boolean,
|
||||
): void {
|
||||
let previousInstance;
|
||||
if (inCapturePhase) {
|
||||
for (let i = phase.length - 1; i >= 0; i--) {
|
||||
const {instance, currentTarget, listener} = phase[i];
|
||||
for (let i = dispatchListeners.length - 1; i >= 0; i--) {
|
||||
const {instance, currentTarget, listener} = dispatchListeners[i];
|
||||
if (instance !== previousInstance && event.isPropagationStopped()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -273,8 +280,8 @@ function processDispatchQueueItemsInOrder(
|
|||
previousInstance = instance;
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < phase.length; i++) {
|
||||
const {instance, currentTarget, listener} = phase[i];
|
||||
for (let i = 0; i < dispatchListeners.length; i++) {
|
||||
const {instance, currentTarget, listener} = dispatchListeners[i];
|
||||
if (instance !== previousInstance && event.isPropagationStopped()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -290,9 +297,8 @@ export function processDispatchQueue(
|
|||
): void {
|
||||
const inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
|
||||
for (let i = 0; i < dispatchQueue.length; i++) {
|
||||
const dispatchQueueItem: DispatchQueueItem = dispatchQueue[i];
|
||||
const {event, phase} = dispatchQueueItem;
|
||||
processDispatchQueueItemsInOrder(event, phase, inCapturePhase);
|
||||
const {event, listeners} = dispatchQueue[i];
|
||||
processDispatchQueueItemsInOrder(event, listeners, inCapturePhase);
|
||||
// Modern event system doesn't use pooling.
|
||||
}
|
||||
// This would be a good time to rethrow if any of the event handlers threw.
|
||||
|
|
@ -329,13 +335,13 @@ function shouldUpgradeListener(
|
|||
);
|
||||
}
|
||||
|
||||
export function listenToTopLevelEvent(
|
||||
export function listenToNativeEvent(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
target: EventTarget,
|
||||
listenerMap: ElementListenerMap,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
capture: boolean,
|
||||
passive?: boolean,
|
||||
isCapturePhaseListener: boolean,
|
||||
isPassiveListener?: boolean,
|
||||
priority?: EventPriority,
|
||||
): void {
|
||||
// TOP_SELECTION_CHANGE needs to be attached to the document
|
||||
|
|
@ -345,11 +351,14 @@ export function listenToTopLevelEvent(
|
|||
target = (target: any).ownerDocument || target;
|
||||
listenerMap = getEventListenerMap(target);
|
||||
}
|
||||
const listenerMapKey = getListenerMapKey(topLevelType, capture);
|
||||
const listenerMapKey = getListenerMapKey(
|
||||
topLevelType,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
const listenerEntry = ((listenerMap.get(
|
||||
listenerMapKey,
|
||||
): any): ElementListenerMapEntry | void);
|
||||
const shouldUpgrade = shouldUpgradeListener(listenerEntry, passive);
|
||||
const shouldUpgrade = shouldUpgradeListener(listenerEntry, isPassiveListener);
|
||||
|
||||
// If the listener entry is empty or we should upgrade, then
|
||||
// we need to trap an event listener onto the target.
|
||||
|
|
@ -360,23 +369,23 @@ export function listenToTopLevelEvent(
|
|||
removeTrappedEventListener(
|
||||
target,
|
||||
topLevelType,
|
||||
capture,
|
||||
isCapturePhaseListener,
|
||||
((listenerEntry: any): ElementListenerMapEntry).listener,
|
||||
);
|
||||
}
|
||||
if (capture) {
|
||||
if (isCapturePhaseListener) {
|
||||
eventSystemFlags |= IS_CAPTURE_PHASE;
|
||||
}
|
||||
const listener = addTrappedEventListener(
|
||||
target,
|
||||
topLevelType,
|
||||
eventSystemFlags,
|
||||
capture,
|
||||
isCapturePhaseListener,
|
||||
false,
|
||||
passive,
|
||||
isPassiveListener,
|
||||
priority,
|
||||
);
|
||||
listenerMap.set(listenerMapKey, {passive, listener});
|
||||
listenerMap.set(listenerMapKey, {passive: isPassiveListener, listener});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +394,7 @@ function isCaptureRegistrationName(registrationName: string): boolean {
|
|||
return registrationName.substr(len - 7) === 'Capture';
|
||||
}
|
||||
|
||||
export function listenToReactPropEvent(
|
||||
export function listenToReactEvent(
|
||||
reactPropEvent: string,
|
||||
rootContainerElement: Element,
|
||||
): void {
|
||||
|
|
@ -412,7 +421,7 @@ export function listenToReactPropEvent(
|
|||
const dependency = dependencies[i];
|
||||
const capture =
|
||||
capturePhaseEvents.has(dependency) || registrationCapturePhase;
|
||||
listenToTopLevelEvent(
|
||||
listenToNativeEvent(
|
||||
dependency,
|
||||
rootContainerElement,
|
||||
listenerMap,
|
||||
|
|
@ -426,21 +435,21 @@ function addTrappedEventListener(
|
|||
targetContainer: EventTarget,
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
capture: boolean,
|
||||
isCapturePhaseListener: boolean,
|
||||
isDeferredListenerForLegacyFBSupport?: boolean,
|
||||
passive?: boolean,
|
||||
priority?: EventPriority,
|
||||
isPassiveListener?: boolean,
|
||||
listenerPriority?: EventPriority,
|
||||
): any => void {
|
||||
let listener = createEventListenerWrapperWithPriority(
|
||||
targetContainer,
|
||||
topLevelType,
|
||||
eventSystemFlags,
|
||||
priority,
|
||||
listenerPriority,
|
||||
);
|
||||
// If passive option is not supported, then the event will be
|
||||
// active and not passive.
|
||||
if (passive === true && !passiveBrowserEventsSupported) {
|
||||
passive = false;
|
||||
if (isPassiveListener === true && !passiveBrowserEventsSupported) {
|
||||
isPassiveListener = false;
|
||||
}
|
||||
|
||||
targetContainer =
|
||||
|
|
@ -472,18 +481,18 @@ function addTrappedEventListener(
|
|||
targetContainer,
|
||||
rawEventName,
|
||||
unsubscribeListener,
|
||||
capture,
|
||||
isCapturePhaseListener,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (capture) {
|
||||
if (enableCreateEventHandleAPI && passive !== undefined) {
|
||||
if (isCapturePhaseListener) {
|
||||
if (enableCreateEventHandleAPI && isPassiveListener !== undefined) {
|
||||
unsubscribeListener = addEventCaptureListenerWithPassiveFlag(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
listener,
|
||||
passive,
|
||||
isPassiveListener,
|
||||
);
|
||||
} else {
|
||||
unsubscribeListener = addEventCaptureListener(
|
||||
|
|
@ -493,12 +502,12 @@ function addTrappedEventListener(
|
|||
);
|
||||
}
|
||||
} else {
|
||||
if (enableCreateEventHandleAPI && passive !== undefined) {
|
||||
if (enableCreateEventHandleAPI && isPassiveListener !== undefined) {
|
||||
unsubscribeListener = addEventBubbleListenerWithPassiveFlag(
|
||||
targetContainer,
|
||||
rawEventName,
|
||||
listener,
|
||||
passive,
|
||||
isPassiveListener,
|
||||
);
|
||||
} else {
|
||||
unsubscribeListener = addEventBubbleListener(
|
||||
|
|
@ -551,7 +560,7 @@ export function dispatchEventForPluginEventSystem(
|
|||
targetContainer: EventTarget,
|
||||
): void {
|
||||
let ancestorInst = targetInst;
|
||||
if (eventSystemFlags & IS_TARGET_PHASE_ONLY) {
|
||||
if (eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) {
|
||||
// For TargetEvent nodes (i.e. document, window)
|
||||
ancestorInst = null;
|
||||
} else {
|
||||
|
|
@ -655,11 +664,11 @@ export function dispatchEventForPluginEventSystem(
|
|||
);
|
||||
}
|
||||
|
||||
function createDispatchQueueItemPhaseEntry(
|
||||
function createDispatchListener(
|
||||
instance: null | Fiber,
|
||||
listener: Function,
|
||||
currentTarget: EventTarget,
|
||||
): DispatchQueueItemPhaseEntry {
|
||||
): DispatchListener {
|
||||
return {
|
||||
instance,
|
||||
listener,
|
||||
|
|
@ -667,13 +676,13 @@ function createDispatchQueueItemPhaseEntry(
|
|||
};
|
||||
}
|
||||
|
||||
function createDispatchQueueItem(
|
||||
function createDispatchEntry(
|
||||
event: ReactSyntheticEvent,
|
||||
phase: DispatchQueueItemPhase,
|
||||
): DispatchQueueItem {
|
||||
listeners: Array<DispatchListener>,
|
||||
): DispatchEntry {
|
||||
return {
|
||||
event,
|
||||
phase,
|
||||
listeners,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -685,7 +694,7 @@ export function accumulateSinglePhaseListeners(
|
|||
): void {
|
||||
const bubbled = event._reactName;
|
||||
const captured = bubbled !== null ? bubbled + 'Capture' : null;
|
||||
const phase: DispatchQueueItemPhase = [];
|
||||
const listeners: Array<DispatchListener> = [];
|
||||
|
||||
// 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
|
||||
|
|
@ -708,32 +717,31 @@ export function accumulateSinglePhaseListeners(
|
|||
lastHostComponent = currentTarget;
|
||||
// For Event Handle listeners
|
||||
if (enableCreateEventHandleAPI) {
|
||||
const listeners = getEventHandlerListeners(currentTarget);
|
||||
const eventHandlerlisteners = getEventHandlerListeners(currentTarget);
|
||||
|
||||
if (listeners !== null) {
|
||||
const listenersArr = Array.from(listeners);
|
||||
for (let i = 0; i < listenersArr.length; i++) {
|
||||
const listener = listenersArr[i];
|
||||
const {callback, capture, type} = listener;
|
||||
if (eventHandlerlisteners !== null) {
|
||||
const eventHandlerlistenersArr = Array.from(eventHandlerlisteners);
|
||||
for (let i = 0; i < eventHandlerlistenersArr.length; i++) {
|
||||
const {
|
||||
callback,
|
||||
capture: isCapturePhaseListener,
|
||||
type,
|
||||
} = eventHandlerlistenersArr[i];
|
||||
if (type === targetType) {
|
||||
if (capture && inCapturePhase) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
callback,
|
||||
currentTarget,
|
||||
),
|
||||
if (isCapturePhaseListener && inCapturePhase) {
|
||||
listeners.push(
|
||||
createDispatchListener(instance, callback, currentTarget),
|
||||
);
|
||||
} else if (!capture) {
|
||||
const entry = createDispatchQueueItemPhaseEntry(
|
||||
} else if (!isCapturePhaseListener) {
|
||||
const entry = createDispatchListener(
|
||||
instance,
|
||||
callback,
|
||||
currentTarget,
|
||||
);
|
||||
if (shouldEmulateTwoPhase) {
|
||||
phase.unshift(entry);
|
||||
listeners.unshift(entry);
|
||||
} else if (!inCapturePhase) {
|
||||
phase.push(entry);
|
||||
listeners.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -744,27 +752,23 @@ export function accumulateSinglePhaseListeners(
|
|||
if (captured !== null && inCapturePhase) {
|
||||
const captureListener = getListener(instance, captured);
|
||||
if (captureListener != null) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
captureListener,
|
||||
currentTarget,
|
||||
),
|
||||
listeners.push(
|
||||
createDispatchListener(instance, captureListener, currentTarget),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (bubbled !== null) {
|
||||
const bubbleListener = getListener(instance, bubbled);
|
||||
if (bubbleListener != null) {
|
||||
const entry = createDispatchQueueItemPhaseEntry(
|
||||
const entry = createDispatchListener(
|
||||
instance,
|
||||
bubbleListener,
|
||||
currentTarget,
|
||||
);
|
||||
if (shouldEmulateTwoPhase) {
|
||||
phase.unshift(entry);
|
||||
listeners.unshift(entry);
|
||||
} else if (!inCapturePhase) {
|
||||
phase.push(entry);
|
||||
listeners.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -775,33 +779,34 @@ export function accumulateSinglePhaseListeners(
|
|||
lastHostComponent !== null
|
||||
) {
|
||||
const reactScopeInstance = stateNode;
|
||||
const listeners = getEventHandlerListeners(reactScopeInstance);
|
||||
const eventHandlerlisteners = getEventHandlerListeners(
|
||||
reactScopeInstance,
|
||||
);
|
||||
const lastCurrentTarget = ((lastHostComponent: any): Element);
|
||||
|
||||
if (listeners !== null) {
|
||||
const listenersArr = Array.from(listeners);
|
||||
for (let i = 0; i < listenersArr.length; i++) {
|
||||
const listener = listenersArr[i];
|
||||
const {callback, capture, type} = listener;
|
||||
if (eventHandlerlisteners !== null) {
|
||||
const eventHandlerlistenersArr = Array.from(eventHandlerlisteners);
|
||||
for (let i = 0; i < eventHandlerlistenersArr.length; i++) {
|
||||
const {
|
||||
callback,
|
||||
capture: isCapturePhaseListener,
|
||||
type,
|
||||
} = eventHandlerlistenersArr[i];
|
||||
if (type === targetType) {
|
||||
if (capture && inCapturePhase) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
callback,
|
||||
lastCurrentTarget,
|
||||
),
|
||||
if (isCapturePhaseListener && inCapturePhase) {
|
||||
listeners.push(
|
||||
createDispatchListener(instance, callback, lastCurrentTarget),
|
||||
);
|
||||
} else if (!capture) {
|
||||
const entry = createDispatchQueueItemPhaseEntry(
|
||||
} else if (!isCapturePhaseListener) {
|
||||
const entry = createDispatchListener(
|
||||
instance,
|
||||
callback,
|
||||
lastCurrentTarget,
|
||||
);
|
||||
if (shouldEmulateTwoPhase) {
|
||||
phase.unshift(entry);
|
||||
listeners.unshift(entry);
|
||||
} else if (!inCapturePhase) {
|
||||
phase.push(entry);
|
||||
listeners.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -810,8 +815,8 @@ export function accumulateSinglePhaseListeners(
|
|||
}
|
||||
instance = instance.return;
|
||||
}
|
||||
if (phase.length !== 0) {
|
||||
dispatchQueue.push(createDispatchQueueItem(event, phase));
|
||||
if (listeners.length !== 0) {
|
||||
dispatchQueue.push(createDispatchEntry(event, listeners));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -829,7 +834,7 @@ export function accumulateTwoPhaseListeners(
|
|||
): void {
|
||||
const bubbled = event._reactName;
|
||||
const captured = bubbled !== null ? bubbled + 'Capture' : null;
|
||||
const phase: DispatchQueueItemPhase = [];
|
||||
const listeners: Array<DispatchListener> = [];
|
||||
let instance = targetFiber;
|
||||
|
||||
// Accumulate all instances and listeners via the target -> root path.
|
||||
|
|
@ -842,32 +847,24 @@ export function accumulateTwoPhaseListeners(
|
|||
if (captured !== null) {
|
||||
const captureListener = getListener(instance, captured);
|
||||
if (captureListener != null) {
|
||||
phase.unshift(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
captureListener,
|
||||
currentTarget,
|
||||
),
|
||||
listeners.unshift(
|
||||
createDispatchListener(instance, captureListener, currentTarget),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (bubbled !== null) {
|
||||
const bubbleListener = getListener(instance, bubbled);
|
||||
if (bubbleListener != null) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
bubbleListener,
|
||||
currentTarget,
|
||||
),
|
||||
listeners.push(
|
||||
createDispatchListener(instance, bubbleListener, currentTarget),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
instance = instance.return;
|
||||
}
|
||||
if (phase.length !== 0) {
|
||||
dispatchQueue.push(createDispatchQueueItem(event, phase));
|
||||
if (listeners.length !== 0) {
|
||||
dispatchQueue.push(createDispatchEntry(event, listeners));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,13 +931,13 @@ function accumulateEnterLeaveListenersForEvent(
|
|||
event: ReactSyntheticEvent,
|
||||
target: Fiber,
|
||||
common: Fiber | null,
|
||||
capture: boolean,
|
||||
inCapturePhase: boolean,
|
||||
): void {
|
||||
const registrationName = event._reactName;
|
||||
if (registrationName === undefined) {
|
||||
return;
|
||||
}
|
||||
const phase: DispatchQueueItemPhase = [];
|
||||
const listeners: Array<DispatchListener> = [];
|
||||
|
||||
let instance = target;
|
||||
while (instance !== null) {
|
||||
|
|
@ -953,34 +950,26 @@ function accumulateEnterLeaveListenersForEvent(
|
|||
}
|
||||
if (tag === HostComponent && stateNode !== null) {
|
||||
const currentTarget = stateNode;
|
||||
if (capture) {
|
||||
if (inCapturePhase) {
|
||||
const captureListener = getListener(instance, registrationName);
|
||||
if (captureListener != null) {
|
||||
phase.unshift(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
captureListener,
|
||||
currentTarget,
|
||||
),
|
||||
listeners.unshift(
|
||||
createDispatchListener(instance, captureListener, currentTarget),
|
||||
);
|
||||
}
|
||||
} else if (!capture) {
|
||||
} else if (!inCapturePhase) {
|
||||
const bubbleListener = getListener(instance, registrationName);
|
||||
if (bubbleListener != null) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(
|
||||
instance,
|
||||
bubbleListener,
|
||||
currentTarget,
|
||||
),
|
||||
listeners.push(
|
||||
createDispatchListener(instance, bubbleListener, currentTarget),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
instance = instance.return;
|
||||
}
|
||||
if (phase.length !== 0) {
|
||||
dispatchQueue.push(createDispatchQueueItem(event, phase));
|
||||
if (listeners.length !== 0) {
|
||||
dispatchQueue.push(createDispatchEntry(event, listeners));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1018,13 +1007,13 @@ export function accumulateEnterLeaveTwoPhaseListeners(
|
|||
}
|
||||
}
|
||||
|
||||
export function accumulateEventHandleTargetListeners(
|
||||
export function accumulateEventHandleNonManagedNodeListeners(
|
||||
dispatchQueue: DispatchQueue,
|
||||
event: ReactSyntheticEvent,
|
||||
currentTarget: EventTarget,
|
||||
inCapturePhase: boolean,
|
||||
): void {
|
||||
const phase: DispatchQueueItemPhase = [];
|
||||
const listeners: Array<DispatchListener> = [];
|
||||
|
||||
const eventListeners = getEventHandlerListeners(currentTarget);
|
||||
if (eventListeners !== null) {
|
||||
|
|
@ -1033,22 +1022,18 @@ export function accumulateEventHandleTargetListeners(
|
|||
|
||||
for (let i = 0; i < listenersArr.length; i++) {
|
||||
const listener = listenersArr[i];
|
||||
const {callback, capture, type} = listener;
|
||||
const {callback, capture: isCapturePhaseListener, type} = listener;
|
||||
if (type === targetType) {
|
||||
if (inCapturePhase && capture) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(null, callback, currentTarget),
|
||||
);
|
||||
} else if (!inCapturePhase && !capture) {
|
||||
phase.push(
|
||||
createDispatchQueueItemPhaseEntry(null, callback, currentTarget),
|
||||
);
|
||||
if (inCapturePhase && isCapturePhaseListener) {
|
||||
listeners.push(createDispatchListener(null, callback, currentTarget));
|
||||
} else if (!inCapturePhase && !isCapturePhaseListener) {
|
||||
listeners.push(createDispatchListener(null, callback, currentTarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (phase.length !== 0) {
|
||||
dispatchQueue.push(createDispatchQueueItem(event, phase));
|
||||
if (listeners.length !== 0) {
|
||||
dispatchQueue.push(createDispatchEntry(event, listeners));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export type EventSystemFlags = number;
|
|||
|
||||
export const PLUGIN_EVENT_SYSTEM = 1;
|
||||
export const RESPONDER_EVENT_SYSTEM = 1 << 1;
|
||||
export const IS_TARGET_PHASE_ONLY = 1 << 2;
|
||||
export const IS_EVENT_HANDLE_NON_MANAGED_NODE = 1 << 2;
|
||||
export const IS_CAPTURE_PHASE = 1 << 3;
|
||||
export const IS_PASSIVE = 1 << 4;
|
||||
export const PASSIVE_NOT_SUPPORTED = 1 << 5;
|
||||
|
|
|
|||
|
|
@ -7,26 +7,8 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
|
||||
|
||||
export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | TouchEvent;
|
||||
|
||||
export type PluginName = string;
|
||||
|
||||
export type EventSystemFlags = number;
|
||||
|
||||
export type DispatchQueueItemPhaseEntry = {|
|
||||
instance: null | Fiber,
|
||||
listener: Function,
|
||||
currentTarget: EventTarget,
|
||||
|};
|
||||
|
||||
export type DispatchQueueItemPhase = Array<DispatchQueueItemPhaseEntry>;
|
||||
|
||||
export type DispatchQueueItem = {|
|
||||
event: ReactSyntheticEvent,
|
||||
phase: DispatchQueueItemPhase,
|
||||
|};
|
||||
|
||||
export type DispatchQueue = Array<DispatchQueueItem>;
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ import {
|
|||
} from './DOMTopLevelEventTypes';
|
||||
import {IS_REPLAYED, PLUGIN_EVENT_SYSTEM} from './EventSystemFlags';
|
||||
import {
|
||||
listenToTopLevelEvent,
|
||||
listenToNativeEvent,
|
||||
capturePhaseEvents,
|
||||
} from './DOMModernPluginEventSystem';
|
||||
import {addResponderEventSystemEvent} from './DeprecatedDOMEventResponderSystem';
|
||||
|
|
@ -240,7 +240,7 @@ function trapReplayableEventForContainer(
|
|||
listenerMap: ElementListenerMap,
|
||||
) {
|
||||
const capture = capturePhaseEvents.has(topLevelType);
|
||||
listenToTopLevelEvent(
|
||||
listenToNativeEvent(
|
||||
topLevelType,
|
||||
((container: any): Element),
|
||||
listenerMap,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
import type {AnyNativeEvent} from '../PluginModuleType';
|
||||
import type {TopLevelType} from '../TopLevelEventTypes';
|
||||
import type {DispatchQueue} from '../PluginModuleType';
|
||||
import type {DispatchQueue} from '../DOMModernPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {registerTwoPhaseEvent} from '../EventRegistry';
|
||||
|
|
|
|||
|
|
@ -9,10 +9,8 @@
|
|||
|
||||
import type {TopLevelType} from '../../events/TopLevelEventTypes';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {
|
||||
AnyNativeEvent,
|
||||
DispatchQueue,
|
||||
} from '../../events/PluginModuleType';
|
||||
import type {AnyNativeEvent} from '../../events/PluginModuleType';
|
||||
import type {DispatchQueue} from '../DOMModernPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import SyntheticEvent from '../../events/SyntheticEvent';
|
||||
|
|
@ -24,9 +22,9 @@ import {
|
|||
} from '../DOMEventProperties';
|
||||
import {
|
||||
accumulateSinglePhaseListeners,
|
||||
accumulateEventHandleTargetListeners,
|
||||
accumulateEventHandleNonManagedNodeListeners,
|
||||
} from '../DOMModernPluginEventSystem';
|
||||
import {IS_TARGET_PHASE_ONLY} from '../EventSystemFlags';
|
||||
import {IS_EVENT_HANDLE_NON_MANAGED_NODE} from '../EventSystemFlags';
|
||||
import SyntheticAnimationEvent from '../SyntheticAnimationEvent';
|
||||
import SyntheticClipboardEvent from '../SyntheticClipboardEvent';
|
||||
import SyntheticFocusEvent from '../SyntheticFocusEvent';
|
||||
|
|
@ -50,7 +48,7 @@ function extractEvents(
|
|||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
targetContainer: null | EventTarget,
|
||||
targetContainer: EventTarget,
|
||||
): void {
|
||||
const reactName = topLevelEventsToReactNames.get(topLevelType);
|
||||
if (reactName === undefined) {
|
||||
|
|
@ -155,11 +153,9 @@ function extractEvents(
|
|||
const inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
|
||||
if (
|
||||
enableCreateEventHandleAPI &&
|
||||
eventSystemFlags !== undefined &&
|
||||
eventSystemFlags & IS_TARGET_PHASE_ONLY &&
|
||||
targetContainer != null
|
||||
eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE
|
||||
) {
|
||||
accumulateEventHandleTargetListeners(
|
||||
accumulateEventHandleNonManagedNodeListeners(
|
||||
dispatchQueue,
|
||||
event,
|
||||
targetContainer,
|
||||
|
|
|
|||
|
|
@ -12,15 +12,12 @@ import type {
|
|||
AnyNativeEvent,
|
||||
PluginName,
|
||||
LegacyPluginModule,
|
||||
ModernPluginModule,
|
||||
} from './PluginModuleType';
|
||||
|
||||
import invariant from 'shared/invariant';
|
||||
|
||||
type NamesToPlugins = {
|
||||
[key: PluginName]:
|
||||
| LegacyPluginModule<AnyNativeEvent>
|
||||
| ModernPluginModule<AnyNativeEvent>,
|
||||
[key: PluginName]: LegacyPluginModule<AnyNativeEvent>,
|
||||
...,
|
||||
};
|
||||
type EventPluginOrder = null | Array<PluginName>;
|
||||
|
|
@ -90,9 +87,7 @@ function recomputePluginOrdering(): void {
|
|||
*/
|
||||
function publishEventForPlugin(
|
||||
dispatchConfig: DispatchConfig,
|
||||
pluginModule:
|
||||
| LegacyPluginModule<AnyNativeEvent>
|
||||
| ModernPluginModule<AnyNativeEvent>,
|
||||
pluginModule: LegacyPluginModule<AnyNativeEvent>,
|
||||
eventName: string,
|
||||
): boolean {
|
||||
invariant(
|
||||
|
|
@ -136,9 +131,7 @@ function publishEventForPlugin(
|
|||
*/
|
||||
function publishRegistrationName(
|
||||
registrationName: string,
|
||||
pluginModule:
|
||||
| LegacyPluginModule<AnyNativeEvent>
|
||||
| ModernPluginModule<AnyNativeEvent>,
|
||||
pluginModule: LegacyPluginModule<AnyNativeEvent>,
|
||||
eventName: string,
|
||||
): void {
|
||||
invariant(
|
||||
|
|
@ -251,20 +244,3 @@ export function injectEventPluginsByName(
|
|||
recomputePluginOrdering();
|
||||
}
|
||||
}
|
||||
|
||||
export function injectEventPlugins(
|
||||
eventPlugins: [ModernPluginModule<AnyNativeEvent>],
|
||||
): void {
|
||||
for (let i = 0; i < eventPlugins.length; i++) {
|
||||
const pluginModule = eventPlugins[i];
|
||||
plugins.push(pluginModule);
|
||||
const publishedEvents = pluginModule.eventTypes;
|
||||
for (const eventName in publishedEvents) {
|
||||
publishEventForPlugin(
|
||||
publishedEvents[eventName],
|
||||
pluginModule,
|
||||
eventName,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,31 +34,3 @@ export type LegacyPluginModule<NativeEvent> = {
|
|||
) => ?ReactSyntheticEvent,
|
||||
tapMoveThreshold?: number,
|
||||
};
|
||||
|
||||
export type DispatchQueueItemPhaseEntry = {|
|
||||
instance: null | Fiber,
|
||||
listener: Function,
|
||||
currentTarget: EventTarget,
|
||||
|};
|
||||
|
||||
export type DispatchQueueItemPhase = Array<DispatchQueueItemPhaseEntry>;
|
||||
|
||||
export type DispatchQueueItem = {|
|
||||
event: ReactSyntheticEvent,
|
||||
phase: DispatchQueueItemPhase,
|
||||
|};
|
||||
|
||||
export type DispatchQueue = Array<DispatchQueueItem>;
|
||||
|
||||
export type ModernPluginModule<NativeEvent> = {
|
||||
eventTypes: EventTypes,
|
||||
extractEvents: (
|
||||
dispatchQueue: DispatchQueue,
|
||||
topLevelType: TopLevelType,
|
||||
targetInst: null | Fiber,
|
||||
nativeTarget: NativeEvent,
|
||||
nativeEventTarget: null | EventTarget,
|
||||
eventSystemFlags: number,
|
||||
container: null | EventTarget,
|
||||
) => void,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user