mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
ModernEventSystem: refactor accumulateTwoPhaseListeners (#18274)
This commit is contained in:
parent
8fe066fdac
commit
30a998debf
|
|
@ -31,4 +31,7 @@ export type ReactSyntheticEvent = {|
|
|||
nativeEventTarget: EventTarget,
|
||||
) => ReactSyntheticEvent,
|
||||
isPersistent: () => boolean,
|
||||
_dispatchInstances: null | Array<Fiber>,
|
||||
_dispatchListeners: null | Array<Function>,
|
||||
_targetInst: null | Fiber,
|
||||
|};
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ function SyntheticEvent(
|
|||
this.dispatchConfig = dispatchConfig;
|
||||
this._targetInst = targetInst;
|
||||
this.nativeEvent = nativeEvent;
|
||||
this._dispatchListeners = null;
|
||||
this._dispatchInstances = null;
|
||||
|
||||
const Interface = this.constructor.Interface;
|
||||
for (const propName in Interface) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
import type {TopLevelType} from 'legacy-events/TopLevelEventTypes';
|
||||
|
||||
import {accumulateTwoPhaseDispatchesSingle} from 'legacy-events/EventPropagators';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
|
||||
import {
|
||||
|
|
@ -29,6 +28,7 @@ import {
|
|||
} from './FallbackCompositionState';
|
||||
import SyntheticCompositionEvent from './SyntheticCompositionEvent';
|
||||
import SyntheticInputEvent from './SyntheticInputEvent';
|
||||
import {accumulateTwoPhaseListeners} from './DOMModernPluginEventSystem';
|
||||
|
||||
const END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
|
||||
const START_KEYCODE = 229;
|
||||
|
|
@ -276,7 +276,7 @@ function extractCompositionEvent(
|
|||
}
|
||||
}
|
||||
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
accumulateTwoPhaseListeners(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
|
@ -437,7 +437,7 @@ function extractBeforeInputEvent(
|
|||
);
|
||||
|
||||
event.data = chars;
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
accumulateTwoPhaseListeners(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import {runEventsInBatch} from 'legacy-events/EventBatching';
|
||||
import {accumulateTwoPhaseDispatchesSingle} from 'legacy-events/EventPropagators';
|
||||
import {enqueueStateRestore} from 'legacy-events/ReactControlledComponent';
|
||||
import {batchedUpdates} from 'legacy-events/ReactGenericBatching';
|
||||
import SyntheticEvent from 'legacy-events/SyntheticEvent';
|
||||
|
|
@ -28,6 +27,8 @@ import isEventSupported from './isEventSupported';
|
|||
import {getNodeFromInstance} from '../client/ReactDOMComponentTree';
|
||||
import {updateValueIfChanged} from '../client/inputValueTracking';
|
||||
import {setDefaultValue} from '../client/ReactDOMInput';
|
||||
import {accumulateTwoPhaseListeners} from './DOMModernPluginEventSystem';
|
||||
|
||||
import {disableInputAttributeSyncing} from 'shared/ReactFeatureFlags';
|
||||
|
||||
const eventTypes = {
|
||||
|
|
@ -59,7 +60,7 @@ function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
|
|||
event.type = 'change';
|
||||
// Flag this event loop as needing state restore.
|
||||
enqueueStateRestore(target);
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
accumulateTwoPhaseListeners(event);
|
||||
return event;
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
|
|||
import {batchedEventUpdates} from 'legacy-events/ReactGenericBatching';
|
||||
import {executeDispatchesInOrder} from 'legacy-events/EventPluginUtils';
|
||||
import {plugins} from 'legacy-events/EventPluginRegistry';
|
||||
import getListener from 'legacy-events/getListener';
|
||||
|
||||
import {HostRoot, HostPortal} from 'shared/ReactWorkTags';
|
||||
import {HostRoot, HostPortal, HostComponent} from 'shared/ReactWorkTags';
|
||||
|
||||
import {addTrappedEventListener} from './ReactDOMEventListener';
|
||||
import getEventTarget from './getEventTarget';
|
||||
|
|
@ -305,3 +306,46 @@ export function attachElementListener(listener: ReactDOMListener): void {
|
|||
export function detachElementListener(listener: ReactDOMListener): void {
|
||||
// TODO
|
||||
}
|
||||
|
||||
export function accumulateTwoPhaseListeners(event: ReactSyntheticEvent): void {
|
||||
const phasedRegistrationNames = event.dispatchConfig.phasedRegistrationNames;
|
||||
if (phasedRegistrationNames == null) {
|
||||
return;
|
||||
}
|
||||
const {bubbled, captured} = phasedRegistrationNames;
|
||||
const dispatchListeners = [];
|
||||
const dispatchInstances = [];
|
||||
let node = event._targetInst;
|
||||
let hasListeners = false;
|
||||
|
||||
// Accumulate all instances and listeners via the target -> root path.
|
||||
while (node !== null) {
|
||||
// We only care for listeners that are on HostComponents (i.e. <div>)
|
||||
if (node.tag === HostComponent) {
|
||||
// Standard React on* listeners, i.e. onClick prop
|
||||
const captureListener = getListener(node, captured);
|
||||
if (captureListener != null) {
|
||||
hasListeners = true;
|
||||
// Capture listeners/instances should go at the start, so we
|
||||
// unshift them to the start of the array.
|
||||
dispatchListeners.unshift(captureListener);
|
||||
dispatchInstances.unshift(node);
|
||||
}
|
||||
const bubbleListener = getListener(node, bubbled);
|
||||
if (bubbleListener != null) {
|
||||
hasListeners = true;
|
||||
// Bubble listeners/instances should go at the end, so we
|
||||
// push them to the end of the array.
|
||||
dispatchListeners.push(bubbleListener);
|
||||
dispatchInstances.push(node);
|
||||
}
|
||||
}
|
||||
node = node.return;
|
||||
}
|
||||
// To prevent allocation to the event unless we actually
|
||||
// have listeners we use the flag we would have set above.
|
||||
if (hasListeners) {
|
||||
event._dispatchListeners = dispatchListeners;
|
||||
event._dispatchInstances = dispatchInstances;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {accumulateTwoPhaseDispatchesSingle} from 'legacy-events/EventPropagators';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
import SyntheticEvent from 'legacy-events/SyntheticEvent';
|
||||
import isTextInputElement from 'shared/isTextInputElement';
|
||||
|
|
@ -27,6 +26,7 @@ import {getNodeFromInstance} from '../client/ReactDOMComponentTree';
|
|||
import {hasSelectionCapabilities} from '../client/ReactInputSelection';
|
||||
import {DOCUMENT_NODE} from '../shared/HTMLNodeType';
|
||||
import {isListeningToAllDependencies} from './DOMEventListenerMap';
|
||||
import {accumulateTwoPhaseListeners} from './DOMModernPluginEventSystem';
|
||||
|
||||
const skipSelectionChangeEvent =
|
||||
canUseDOM && 'documentMode' in document && document.documentMode <= 11;
|
||||
|
|
@ -135,7 +135,7 @@ function constructSelectEvent(nativeEvent, nativeEventTarget) {
|
|||
syntheticEvent.type = 'select';
|
||||
syntheticEvent.target = activeElement;
|
||||
|
||||
accumulateTwoPhaseDispatchesSingle(syntheticEvent);
|
||||
accumulateTwoPhaseListeners(syntheticEvent);
|
||||
|
||||
return syntheticEvent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
|||
import type {PluginModule} from 'legacy-events/PluginModuleType';
|
||||
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
|
||||
|
||||
import {accumulateTwoPhaseDispatchesSingle} from 'legacy-events/EventPropagators';
|
||||
import SyntheticEvent from 'legacy-events/SyntheticEvent';
|
||||
|
||||
import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
|
||||
|
|
@ -37,6 +36,7 @@ import SyntheticTransitionEvent from './SyntheticTransitionEvent';
|
|||
import SyntheticUIEvent from './SyntheticUIEvent';
|
||||
import SyntheticWheelEvent from './SyntheticWheelEvent';
|
||||
import getEventCharCode from './getEventCharCode';
|
||||
import {accumulateTwoPhaseListeners} from './DOMModernPluginEventSystem';
|
||||
|
||||
// Only used in DEV for exhaustiveness validation.
|
||||
const knownHTMLTopLevelTypes: Array<DOMTopLevelEventType> = [
|
||||
|
|
@ -191,7 +191,7 @@ const SimpleEventPlugin: PluginModule<MouseEvent> = {
|
|||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
);
|
||||
accumulateTwoPhaseDispatchesSingle(event);
|
||||
accumulateTwoPhaseListeners(event);
|
||||
return event;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user