From c5a8dae025812adebdebfa1e96e80c923dd527ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 17 May 2018 12:38:50 -0700 Subject: [PATCH] [Fabric] Wire up event emitters (#12847) I'm exposing a new native method to wire up the event emitter. This will use a straight fiber pointer instead of react tags to do the dispatching. --- packages/events/TopLevelEventTypes.js | 2 +- .../src/ReactFabricEventEmitter.js | 44 +++++++++++++++++++ .../src/ReactFabricHostConfig.js | 11 +++++ .../src/__mocks__/FabricUIManager.js | 2 + scripts/flow/react-native-host-hooks.js | 8 ++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 packages/react-native-renderer/src/ReactFabricEventEmitter.js diff --git a/packages/events/TopLevelEventTypes.js b/packages/events/TopLevelEventTypes.js index 3f9b8ab7e9..48eee6b954 100644 --- a/packages/events/TopLevelEventTypes.js +++ b/packages/events/TopLevelEventTypes.js @@ -7,7 +7,7 @@ * @flow */ -type RNTopLevelEventType = +export type RNTopLevelEventType = | 'topMouseDown' | 'topMouseMove' | 'topMouseUp' diff --git a/packages/react-native-renderer/src/ReactFabricEventEmitter.js b/packages/react-native-renderer/src/ReactFabricEventEmitter.js new file mode 100644 index 0000000000..94c454ac07 --- /dev/null +++ b/packages/react-native-renderer/src/ReactFabricEventEmitter.js @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2015-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. + * + * @flow + */ + +import type {Fiber} from 'react-reconciler/src/ReactFiber'; + +import {getListener, runExtractedEventsInBatch} from 'events/EventPluginHub'; +import {registrationNameModules} from 'events/EventPluginRegistry'; +import {batchedUpdates} from 'events/ReactGenericBatching'; + +import type {AnyNativeEvent} from 'events/PluginModuleType'; +import type {TopLevelType} from 'events/TopLevelEventTypes'; + +export {getListener, registrationNameModules as registrationNames}; + +/** + * Publicly exposed method on module for native objc to invoke when a top + * level event is extracted. + * @param {rootNodeID} rootNodeID React root node ID that event occurred on. + * @param {TopLevelType} topLevelType Top level type of event. + * @param {object} nativeEventParam Object passed from native. + */ +export function dispatchEvent( + target: Object, + topLevelType: TopLevelType, + nativeEvent: AnyNativeEvent, +) { + const targetFiber = (target: Fiber); + batchedUpdates(function() { + runExtractedEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + nativeEvent.target, + ); + }); + // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. +} diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js index d6d55186a0..7601062f54 100644 --- a/packages/react-native-renderer/src/ReactFabricHostConfig.js +++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js @@ -23,6 +23,8 @@ import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry'; import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev'; import invariant from 'fbjs/lib/invariant'; +import {dispatchEvent} from './ReactFabricEventEmitter'; + // Modules provided by RN: import TextInputState from 'TextInputState'; import { @@ -35,6 +37,7 @@ import { appendChild, appendChildToSet, completeRoot, + registerEventHandler, } from 'FabricUIManager'; import UIManager from 'UIManager'; @@ -48,6 +51,14 @@ type HostContext = $ReadOnly<{| isInAParentText: boolean, |}>; +// TODO: Remove this conditional once all changes have propagated. +if (registerEventHandler) { + /** + * Register the event emitter with the native bridge + */ + registerEventHandler(dispatchEvent); +} + /** * This is used for refs on host components. */ diff --git a/packages/react-native-renderer/src/__mocks__/FabricUIManager.js b/packages/react-native-renderer/src/__mocks__/FabricUIManager.js index 41bb928034..3fcf573ab8 100644 --- a/packages/react-native-renderer/src/__mocks__/FabricUIManager.js +++ b/packages/react-native-renderer/src/__mocks__/FabricUIManager.js @@ -125,6 +125,8 @@ const RCTFabricUIManager = { completeRoot: jest.fn(function completeRoot(rootTag, newChildSet) { roots.set(rootTag, newChildSet); }), + + registerEventHandler: jest.fn(function registerEventHandler(callback) {}), }; module.exports = RCTFabricUIManager; diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 5d3971b1c3..d10f4d06b9 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -13,6 +13,7 @@ import type { ReactNativeBaseComponentViewConfig, ViewConfigGetter, } from 'react-native-renderer/src/ReactNativeTypes'; +import type {RNTopLevelEventType} from 'events/TopLevelEventTypes'; declare module 'deepDiffer' { declare module.exports: (one: any, two: any) => boolean; @@ -121,6 +122,13 @@ declare module 'FabricUIManager' { declare function createChildSet(rootTag: number): Object; declare function appendChildToSet(childSet: Object, childNode: Object): void; declare function completeRoot(rootTag: number, childSet: Object): void; + declare function registerEventHandler( + callback: ( + instanceHandle: Object, + type: RNTopLevelEventType, + payload: Object, + ) => void, + ): void; } declare module 'View' {