mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Reduce the handleTopLevel() event code indirection (#11915)
* Refactor event emitters to reduce indirection * Remove unused handleTopLevel() injection * Rename handleTopLevel() to runExtractedEventsInBatch() and remove import indirection
This commit is contained in:
@@ -164,13 +164,13 @@ export function getListener(inst: Fiber, registrationName: string) {
|
||||
* @return {*} An accumulation of synthetic events.
|
||||
* @internal
|
||||
*/
|
||||
export function extractEvents(
|
||||
function extractEvents(
|
||||
topLevelType: string,
|
||||
targetInst: Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: EventTarget,
|
||||
) {
|
||||
let events;
|
||||
): Array<ReactSyntheticEvent> | ReactSyntheticEvent | null {
|
||||
let events = null;
|
||||
for (let i = 0; i < plugins.length; i++) {
|
||||
// Not every plugin in the ordering may be loaded at runtime.
|
||||
const possiblePlugin: PluginModule<AnyNativeEvent> = plugins[i];
|
||||
@@ -189,27 +189,14 @@ export function extractEvents(
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues a synthetic event that should be dispatched when
|
||||
* `processEventQueue` is invoked.
|
||||
*
|
||||
* @param {*} events An accumulation of synthetic events.
|
||||
* @internal
|
||||
*/
|
||||
export function enqueueEvents(
|
||||
events: Array<ReactSyntheticEvent> | ReactSyntheticEvent,
|
||||
export function runEventsInBatch(
|
||||
events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null,
|
||||
simulated: boolean,
|
||||
) {
|
||||
if (events) {
|
||||
if (events !== null) {
|
||||
eventQueue = accumulateInto(eventQueue, events);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches all synthetic events on the event queue.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function processEventQueue(simulated: boolean) {
|
||||
// Set `eventQueue` to null before processing it so that we can tell if more
|
||||
// events get enqueued while processing.
|
||||
const processingEventQueue = eventQueue;
|
||||
@@ -238,3 +225,18 @@ export function processEventQueue(simulated: boolean) {
|
||||
// This would be a good time to rethrow if any of the event handlers threw.
|
||||
ReactErrorUtils.rethrowCaughtError();
|
||||
}
|
||||
|
||||
export function runExtractedEventsInBatch(
|
||||
topLevelType: string,
|
||||
targetInst: Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: EventTarget,
|
||||
) {
|
||||
const events = extractEvents(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
);
|
||||
runEventsInBatch(events, false);
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {
|
||||
enqueueEvents,
|
||||
processEventQueue,
|
||||
extractEvents,
|
||||
} from './EventPluginHub';
|
||||
|
||||
function runEventQueueInBatch(events) {
|
||||
enqueueEvents(events);
|
||||
processEventQueue(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams a fired top-level event to `EventPluginHub` where plugins have the
|
||||
* opportunity to create `ReactEvent`s to be dispatched.
|
||||
*/
|
||||
export function handleTopLevel(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
) {
|
||||
const events = extractEvents(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
);
|
||||
runEventQueueInBatch(events);
|
||||
}
|
||||
@@ -312,8 +312,7 @@ const run = function(config, hierarchyConfig, nativeEventConfig) {
|
||||
// At this point the negotiation events have been dispatched as part of the
|
||||
// extraction process, but not the side effectful events. Below, we dispatch
|
||||
// side effectful events.
|
||||
EventPluginHub.enqueueEvents(extractedEvents);
|
||||
EventPluginHub.processEventQueue(true);
|
||||
EventPluginHub.runEventsInBatch(extractedEvents, true);
|
||||
|
||||
// Ensure that every event that declared an `order`, was actually dispatched.
|
||||
expect('number of events dispatched:' + runData.dispatchCount).toBe(
|
||||
|
||||
@@ -13,13 +13,9 @@ import BeforeInputEventPlugin from '../events/BeforeInputEventPlugin';
|
||||
import ChangeEventPlugin from '../events/ChangeEventPlugin';
|
||||
import DOMEventPluginOrder from '../events/DOMEventPluginOrder';
|
||||
import EnterLeaveEventPlugin from '../events/EnterLeaveEventPlugin';
|
||||
import {handleTopLevel} from '../events/ReactBrowserEventEmitter';
|
||||
import {setHandleTopLevel} from '../events/ReactDOMEventListener';
|
||||
import SelectEventPlugin from '../events/SelectEventPlugin';
|
||||
import SimpleEventPlugin from '../events/SimpleEventPlugin';
|
||||
|
||||
setHandleTopLevel(handleTopLevel);
|
||||
|
||||
/**
|
||||
* Inject modules for resolving DOM hierarchy and plugin ordering.
|
||||
*/
|
||||
|
||||
+2
-3
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {enqueueEvents, processEventQueue} from 'events/EventPluginHub';
|
||||
import * as EventPluginHub from 'events/EventPluginHub';
|
||||
import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
|
||||
import {enqueueStateRestore} from 'events/ReactControlledComponent';
|
||||
import {batchedUpdates} from 'events/ReactGenericBatching';
|
||||
@@ -89,8 +89,7 @@ function manualDispatchChangeEvent(nativeEvent) {
|
||||
}
|
||||
|
||||
function runEventInBatch(event) {
|
||||
enqueueEvents(event);
|
||||
processEventQueue(false);
|
||||
EventPluginHub.runEventsInBatch(event, false);
|
||||
}
|
||||
|
||||
function getInstIfValueChanged(targetInst) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
import {registrationNameDependencies} from 'events/EventPluginRegistry';
|
||||
|
||||
import {
|
||||
setEnabled,
|
||||
isEnabled,
|
||||
@@ -16,8 +15,6 @@ import {
|
||||
import isEventSupported from './isEventSupported';
|
||||
import BrowserEventConstants from './BrowserEventConstants';
|
||||
|
||||
export * from 'events/ReactEventEmitterMixin';
|
||||
|
||||
const {topLevelTypes} = BrowserEventConstants;
|
||||
|
||||
/**
|
||||
|
||||
+4
-8
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import {batchedUpdates} from 'events/ReactGenericBatching';
|
||||
import {runExtractedEventsInBatch} from 'events/EventPluginHub';
|
||||
import {isFiberMounted} from 'react-reconciler/reflection';
|
||||
import {HostRoot} from 'shared/ReactTypeOfWork';
|
||||
|
||||
@@ -62,7 +63,7 @@ function releaseTopLevelCallbackBookKeeping(instance) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleTopLevelImpl(bookKeeping) {
|
||||
function handleTopLevel(bookKeeping) {
|
||||
let targetInst = bookKeeping.targetInst;
|
||||
|
||||
// Loop through the hierarchy, in case there's any nested components.
|
||||
@@ -85,7 +86,7 @@ function handleTopLevelImpl(bookKeeping) {
|
||||
|
||||
for (let i = 0; i < bookKeeping.ancestors.length; i++) {
|
||||
targetInst = bookKeeping.ancestors[i];
|
||||
_handleTopLevel(
|
||||
runExtractedEventsInBatch(
|
||||
bookKeeping.topLevelType,
|
||||
targetInst,
|
||||
bookKeeping.nativeEvent,
|
||||
@@ -96,11 +97,6 @@ function handleTopLevelImpl(bookKeeping) {
|
||||
|
||||
// TODO: can we stop exporting these?
|
||||
export let _enabled = true;
|
||||
export let _handleTopLevel: null;
|
||||
|
||||
export function setHandleTopLevel(handleTopLevel) {
|
||||
_handleTopLevel = handleTopLevel;
|
||||
}
|
||||
|
||||
export function setEnabled(enabled) {
|
||||
_enabled = !!enabled;
|
||||
@@ -180,7 +176,7 @@ export function dispatchEvent(topLevelType, nativeEvent) {
|
||||
try {
|
||||
// Event queue being processed in the same cycle allows
|
||||
// `preventDefault`.
|
||||
batchedUpdates(handleTopLevelImpl, bookKeeping);
|
||||
batchedUpdates(handleTopLevel, bookKeeping);
|
||||
} finally {
|
||||
releaseTopLevelCallbackBookKeeping(bookKeeping);
|
||||
}
|
||||
|
||||
+1
-3
@@ -388,9 +388,7 @@ function makeSimulator(eventType) {
|
||||
// Normally extractEvent enqueues a state restore, but we'll just always
|
||||
// do that since we we're by-passing it here.
|
||||
ReactControlledComponent.enqueueStateRestore(domNode);
|
||||
|
||||
EventPluginHub.enqueueEvents(event);
|
||||
EventPluginHub.processEventQueue(true);
|
||||
EventPluginHub.runEventsInBatch(event, true);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {getListener} from 'events/EventPluginHub';
|
||||
import {getListener, runExtractedEventsInBatch} from 'events/EventPluginHub';
|
||||
import {registrationNameModules} from 'events/EventPluginRegistry';
|
||||
import {batchedUpdates} from 'events/ReactGenericBatching';
|
||||
import {handleTopLevel} from 'events/ReactEventEmitterMixin';
|
||||
import warning from 'fbjs/lib/warning';
|
||||
|
||||
import {getInstanceFromNode} from './ReactNativeComponentTree';
|
||||
import ReactNativeTagHandles from './ReactNativeTagHandles';
|
||||
|
||||
export * from 'events/ReactEventEmitterMixin';
|
||||
import type {AnyNativeEvent} from 'events/PluginModuleType';
|
||||
|
||||
export {getListener, registrationNameModules as registrationNames};
|
||||
|
||||
/**
|
||||
@@ -25,7 +25,7 @@ export {getListener, registrationNameModules as registrationNames};
|
||||
*/
|
||||
|
||||
// Shared default empty native event - conserve memory.
|
||||
const EMPTY_NATIVE_EVENT = {};
|
||||
const EMPTY_NATIVE_EVENT = (({}: any): AnyNativeEvent);
|
||||
|
||||
/**
|
||||
* Selects a subsequence of `Touch`es, without destroying `touches`.
|
||||
@@ -90,12 +90,17 @@ const removeTouchesAtIndices = function(
|
||||
export function _receiveRootNodeIDEvent(
|
||||
rootNodeID: number,
|
||||
topLevelType: string,
|
||||
nativeEventParam: ?Object,
|
||||
nativeEventParam: ?AnyNativeEvent,
|
||||
) {
|
||||
const nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
|
||||
const inst = getInstanceFromNode(rootNodeID);
|
||||
batchedUpdates(function() {
|
||||
handleTopLevel(topLevelType, inst, nativeEvent, nativeEvent.target);
|
||||
runExtractedEventsInBatch(
|
||||
topLevelType,
|
||||
inst,
|
||||
nativeEvent,
|
||||
nativeEvent.target,
|
||||
);
|
||||
});
|
||||
// React Native doesn't use ReactControlledComponent but if it did, here's
|
||||
// where it would do it.
|
||||
@@ -111,7 +116,7 @@ export function _receiveRootNodeIDEvent(
|
||||
export function receiveEvent(
|
||||
rootNodeID: number,
|
||||
topLevelType: string,
|
||||
nativeEventParam: Object,
|
||||
nativeEventParam: AnyNativeEvent,
|
||||
) {
|
||||
_receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user