diff --git a/packages/events/EventPluginHub.js b/packages/events/EventPluginHub.js index 48d7d6bc51e..d59ba35ff68 100644 --- a/packages/events/EventPluginHub.js +++ b/packages/events/EventPluginHub.js @@ -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 | 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 = 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, +export function runEventsInBatch( + events: Array | 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); +} diff --git a/packages/events/ReactEventEmitterMixin.js b/packages/events/ReactEventEmitterMixin.js deleted file mode 100644 index 86bfe2e761a..00000000000 --- a/packages/events/ReactEventEmitterMixin.js +++ /dev/null @@ -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); -} diff --git a/packages/events/__tests__/ResponderEventPlugin-test.internal.js b/packages/events/__tests__/ResponderEventPlugin-test.internal.js index 6a81f4c8768..d583126f0b1 100644 --- a/packages/events/__tests__/ResponderEventPlugin-test.internal.js +++ b/packages/events/__tests__/ResponderEventPlugin-test.internal.js @@ -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( diff --git a/packages/react-dom/src/client/ReactDOMClientInjection.js b/packages/react-dom/src/client/ReactDOMClientInjection.js index cb4d2315f4c..10b3c00eebf 100644 --- a/packages/react-dom/src/client/ReactDOMClientInjection.js +++ b/packages/react-dom/src/client/ReactDOMClientInjection.js @@ -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. */ diff --git a/packages/react-dom/src/events/ChangeEventPlugin.js b/packages/react-dom/src/events/ChangeEventPlugin.js index 392beab1be4..5e0dcbb3be4 100644 --- a/packages/react-dom/src/events/ChangeEventPlugin.js +++ b/packages/react-dom/src/events/ChangeEventPlugin.js @@ -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) { diff --git a/packages/react-dom/src/events/ReactBrowserEventEmitter.js b/packages/react-dom/src/events/ReactBrowserEventEmitter.js index a9181b3fe9f..b0772c645d6 100644 --- a/packages/react-dom/src/events/ReactBrowserEventEmitter.js +++ b/packages/react-dom/src/events/ReactBrowserEventEmitter.js @@ -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; /** diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index 1fa4f67c3aa..515a0836641 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -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); } diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index d32d8eca455..6062948c016 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -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); }); }; } diff --git a/packages/react-native-renderer/src/ReactNativeEventEmitter.js b/packages/react-native-renderer/src/ReactNativeEventEmitter.js index c978f4e14ac..f75cbba0679 100644 --- a/packages/react-native-renderer/src/ReactNativeEventEmitter.js +++ b/packages/react-native-renderer/src/ReactNativeEventEmitter.js @@ -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); }