From 6af124f538c4ee9b3cb3fbc0a3871e1cf42040b9 Mon Sep 17 00:00:00 2001 From: Dean Brophy Date: Sun, 5 Nov 2017 21:14:26 -0700 Subject: [PATCH 1/2] Add Flow types for EventPluginHub --- packages/events/EventPluginHub.js | 38 ++++++++++++------- packages/events/PluginModuleType.js | 2 +- packages/events/ReactSyntheticEventType.js | 1 + packages/events/accumulateInto.js | 2 +- packages/events/forEachAccumulated.js | 2 +- .../src/ReactNativeBridgeEventPlugin.js | 4 +- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/packages/events/EventPluginHub.js b/packages/events/EventPluginHub.js index 2eb53d0471b4..58580cd25528 100644 --- a/packages/events/EventPluginHub.js +++ b/packages/events/EventPluginHub.js @@ -3,6 +3,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * @flow */ import ReactErrorUtils from 'shared/ReactErrorUtils'; @@ -20,11 +21,16 @@ import { import accumulateInto from './accumulateInto'; import forEachAccumulated from './forEachAccumulated'; +import type {PluginModule} from './PluginModuleType'; +import type {ReactSyntheticEvent} from './ReactSyntheticEventType'; +import type {Fiber} from 'react-reconciler/src/ReactFiber'; +import type {AnyNativeEvent} from './PluginModuleType'; + /** * Internal queue of events that have accumulated their dispatches and are * waiting to have their dispatches executed. */ -var eventQueue = null; +var eventQueue: ?(Array | ReactSyntheticEvent) = null; /** * Dispatches an event and releases it back into the pool, unless persistent. @@ -33,7 +39,10 @@ var eventQueue = null; * @param {boolean} simulated If the event is simulated (changes exn behavior) * @private */ -var executeDispatchesAndRelease = function(event, simulated) { +var executeDispatchesAndRelease = function( + event: ReactSyntheticEvent, + simulated, +) { if (event) { executeDispatchesInOrder(event, simulated); @@ -42,10 +51,10 @@ var executeDispatchesAndRelease = function(event, simulated) { } } }; -var executeDispatchesAndReleaseSimulated = function(e) { +var executeDispatchesAndReleaseSimulated = function(e: ReactSyntheticEvent) { return executeDispatchesAndRelease(e, true); }; -var executeDispatchesAndReleaseTopLevel = function(e) { +var executeDispatchesAndReleaseTopLevel = function(e: ReactSyntheticEvent) { return executeDispatchesAndRelease(e, false); }; @@ -120,7 +129,7 @@ export const injection = { * @param {string} registrationName Name of listener (e.g. `onClick`). * @return {?function} The stored callback. */ -export function getListener(inst, registrationName) { +export function getListener(inst: Fiber, registrationName: string) { var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not @@ -156,15 +165,15 @@ export function getListener(inst, registrationName) { * @internal */ export function extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, + topLevelType: string, + targetInst: Fiber, + nativeEvent: AnyNativeEvent, + nativeEventTarget: EventTarget, ) { var events; for (var i = 0; i < plugins.length; i++) { // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + var possiblePlugin: PluginModule = plugins[i]; if (possiblePlugin) { var extractedEvents = possiblePlugin.extractEvents( topLevelType, @@ -187,7 +196,9 @@ export function extractEvents( * @param {*} events An accumulation of synthetic events. * @internal */ -export function enqueueEvents(events) { +export function enqueueEvents( + events: Array | ReactSyntheticEvent, +) { if (events) { eventQueue = accumulateInto(eventQueue, events); } @@ -198,12 +209,13 @@ export function enqueueEvents(events) { * * @internal */ -export function processEventQueue(simulated) { +export function processEventQueue(simulated: boolean) { // Set `eventQueue` to null before processing it so that we can tell if more // events get enqueued while processing. var processingEventQueue = eventQueue; eventQueue = null; - if (simulated) { + + if (simulated && processingEventQueue) { forEachAccumulated( processingEventQueue, executeDispatchesAndReleaseSimulated, diff --git a/packages/events/PluginModuleType.js b/packages/events/PluginModuleType.js index 5aea597c7c5e..5657ac3514b6 100644 --- a/packages/events/PluginModuleType.js +++ b/packages/events/PluginModuleType.js @@ -26,6 +26,6 @@ export type PluginModule = { targetInst: Fiber, nativeTarget: NativeEvent, nativeEventTarget: EventTarget, - ) => null | ReactSyntheticEvent, + ) => ?ReactSyntheticEvent, tapMoveThreshold?: number, }; diff --git a/packages/events/ReactSyntheticEventType.js b/packages/events/ReactSyntheticEventType.js index 2791963f3a8b..9f68f83bc127 100644 --- a/packages/events/ReactSyntheticEventType.js +++ b/packages/events/ReactSyntheticEventType.js @@ -27,4 +27,5 @@ export type ReactSyntheticEvent = { nativeTarget: Event, nativeEventTarget: EventTarget, ) => ReactSyntheticEvent, + isPersistent: () => boolean, } & SyntheticEvent<>; diff --git a/packages/events/accumulateInto.js b/packages/events/accumulateInto.js index 53166834a9f3..156c8411c723 100644 --- a/packages/events/accumulateInto.js +++ b/packages/events/accumulateInto.js @@ -23,7 +23,7 @@ import invariant from 'fbjs/lib/invariant'; */ function accumulateInto( - current: ?(T | Array), + current: ?(Array | T), next: T | Array, ): T | Array { invariant( diff --git a/packages/events/forEachAccumulated.js b/packages/events/forEachAccumulated.js index 49ae3d8db770..d037effcf7e7 100644 --- a/packages/events/forEachAccumulated.js +++ b/packages/events/forEachAccumulated.js @@ -17,7 +17,7 @@ * @param {?} [scope] Scope used as `this` in a callback. */ function forEachAccumulated( - arr: ?(T | Array), + arr: ?(Array | T), cb: (elem: T) => void, scope: ?any, ) { diff --git a/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js b/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js index 734fa9977fa1..936a765800b9 100644 --- a/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js +++ b/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js @@ -8,7 +8,7 @@ */ import type {ReactNativeBaseComponentViewConfig} from './ReactNativeTypes'; - +import type {AnyNativeEvent} from 'events/PluginModuleType'; import { accumulateTwoPhaseDispatches, accumulateDirectDispatches, @@ -28,7 +28,7 @@ const ReactNativeBridgeEventPlugin = { extractEvents: function( topLevelType: string, targetInst: Object, - nativeEvent: Event, + nativeEvent: AnyNativeEvent, nativeEventTarget: Object, ): ?Object { const bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; From 2148f5fc43f51cb6a1c5bf7293a261d1cb669fb0 Mon Sep 17 00:00:00 2001 From: Dean Brophy Date: Tue, 14 Nov 2017 10:25:18 -0700 Subject: [PATCH 2/2] add boolean and remove extraneous typing --- packages/events/EventPluginHub.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/events/EventPluginHub.js b/packages/events/EventPluginHub.js index 58580cd25528..7da9a5ea7a79 100644 --- a/packages/events/EventPluginHub.js +++ b/packages/events/EventPluginHub.js @@ -41,7 +41,7 @@ var eventQueue: ?(Array | ReactSyntheticEvent) = null; */ var executeDispatchesAndRelease = function( event: ReactSyntheticEvent, - simulated, + simulated: boolean, ) { if (event) { executeDispatchesInOrder(event, simulated); @@ -51,10 +51,10 @@ var executeDispatchesAndRelease = function( } } }; -var executeDispatchesAndReleaseSimulated = function(e: ReactSyntheticEvent) { +var executeDispatchesAndReleaseSimulated = function(e) { return executeDispatchesAndRelease(e, true); }; -var executeDispatchesAndReleaseTopLevel = function(e: ReactSyntheticEvent) { +var executeDispatchesAndReleaseTopLevel = function(e) { return executeDispatchesAndRelease(e, false); }; @@ -215,7 +215,11 @@ export function processEventQueue(simulated: boolean) { var processingEventQueue = eventQueue; eventQueue = null; - if (simulated && processingEventQueue) { + if (!processingEventQueue) { + return; + } + + if (simulated) { forEachAccumulated( processingEventQueue, executeDispatchesAndReleaseSimulated,