diff --git a/Libraries/ReactNative/requireNativeComponent.js b/Libraries/ReactNative/requireNativeComponent.js index 7034d871ad9..03fff7e0bce 100644 --- a/Libraries/ReactNative/requireNativeComponent.js +++ b/Libraries/ReactNative/requireNativeComponent.js @@ -12,6 +12,7 @@ */ 'use strict'; +const Platform = require('Platform'); const ReactNativeBridgeEventPlugin = require('ReactNativeBridgeEventPlugin'); const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); const UIManager = require('UIManager'); @@ -47,35 +48,30 @@ const warning = require('fbjs/lib/warning'); */ import type {ComponentInterface} from 'verifyPropTypes'; +let hasAttachedDefaultEventTypes: boolean = false; + function requireNativeComponent( viewName: string, componentInterface?: ?ComponentInterface, extraConfig?: ?{nativeOnly?: Object}, ): React$ComponentType | string { - function attachBubblingEventTypes(viewConfig) { - if (UIManager.genericBubblingEventTypes) { - viewConfig.bubblingEventTypes = merge( - viewConfig.bubblingEventTypes, - UIManager.genericBubblingEventTypes, - ); - // As genericBubblingEventTypes do not change over time, and there's - // merge of all the events happening in Fiber, we need to pass - // genericBubblingEventTypes to Fiber only once. Therefore, we can delete - // it and forget about it. - delete UIManager.genericBubblingEventTypes; - } - } - - function attachDirectEventTypes(viewConfig) { - if (UIManager.genericDirectEventTypes) { - viewConfig.directEventTypes = merge( - viewConfig.directEventTypes, - UIManager.genericDirectEventTypes, - ); - // As genericDirectEventTypes do not change over time, and there's merge - // of all the events happening in Fiber, we need to pass genericDirectEventTypes - // to Fiber only once. Therefore, we can delete it and forget about it. - delete UIManager.genericDirectEventTypes; + function attachDefaultEventTypes(viewConfig: any) { + if (Platform.OS === 'android') { + // This is supported on Android platform only, + // as lazy view managers discovery is Android-specific. + if (UIManager.ViewManagerNames) { + // Lazy view managers enabled. + viewConfig = merge(viewConfig, UIManager.getDefaultEventTypes()); + } else { + viewConfig.bubblingEventTypes = merge( + viewConfig.bubblingEventTypes, + UIManager.genericBubblingEventTypes, + ); + viewConfig.directEventTypes = merge( + viewConfig.directEventTypes, + UIManager.genericDirectEventTypes, + ); + } } } @@ -184,8 +180,10 @@ function requireNativeComponent( ); } - attachBubblingEventTypes(viewConfig); - attachDirectEventTypes(viewConfig); + if (!hasAttachedDefaultEventTypes) { + attachDefaultEventTypes(viewConfig); + hasAttachedDefaultEventTypes = true; + } // Register this view's event types with the ReactNative renderer. // This enables view managers to be initialized lazily, improving perf, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 8988f597fc6..379fd70facf 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -17,7 +17,6 @@ import android.content.res.Configuration; import com.facebook.common.logging.FLog; import com.facebook.debug.holder.PrinterHolder; import com.facebook.debug.tags.ReactDebugOverlayTags; -import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.react.animation.Animation; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; @@ -43,7 +42,7 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; - /** +/** *

Native module to allow JS to create and update native Views.

* *

@@ -115,11 +114,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements private int mBatchId = 0; - // Defines if events were already exported to JS. We do not send them more - // than once as they are stored and mixed in with Fiber for every ViewManager - // on JS side. - private boolean mEventsWereSentToJS = false; - public UIManagerModule( ReactApplicationContext reactContext, ViewManagerResolver viewManagerResolver, @@ -233,7 +227,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements } } - @DoNotStrip @ReactMethod(isBlockingSynchronousMethod = true) public @Nullable WritableMap getConstantsForViewManager(final String viewManagerName) { ViewManager targetView = @@ -249,13 +242,8 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements try { Map viewManagerConstants = UIManagerModuleConstantsHelper.createConstantsForViewManager( - targetView, - mEventsWereSentToJS ? null : UIManagerModuleConstants.getBubblingEventTypeConstants(), - mEventsWereSentToJS ? null : UIManagerModuleConstants.getDirectEventTypeConstants(), - null, - mCustomDirectEvents); + targetView, null, null, null, mCustomDirectEvents); if (viewManagerConstants != null) { - mEventsWereSentToJS = true; return Arguments.makeNativeMap(viewManagerConstants); } return null; @@ -264,9 +252,12 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements } } - /** - * Resolves Direct Event name exposed to JS from the one known to the Native side. - */ + @ReactMethod(isBlockingSynchronousMethod = true) + public WritableMap getDefaultEventTypes() { + return Arguments.makeNativeMap(UIManagerModuleConstantsHelper.getDefaultExportableEventTypes()); + } + + /** Resolves Direct Event name exposed to JS from the one known to the Native side. */ public CustomEventNamesResolver getDirectEventNamesResolver() { return new CustomEventNamesResolver() { @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java index ad456d655a8..9db8515dbbe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java @@ -24,6 +24,9 @@ import javax.annotation.Nullable; */ /* package */ class UIManagerModuleConstantsHelper { + private static final String BUBBLING_EVENTS_KEY = "bubblingEventTypes"; + private static final String DIRECT_EVENTS_KEY = "directEventTypes"; + /** * Generates a lazy discovery enabled version of {@link UIManagerModule} constants. It only * contains a list of view manager names, so that JS side is aware of the managers there are. @@ -38,6 +41,12 @@ import javax.annotation.Nullable; return constants; } + /* package */ static Map getDefaultExportableEventTypes() { + return MapBuilder.of( + BUBBLING_EVENTS_KEY, UIManagerModuleConstants.getBubblingEventTypeConstants(), + DIRECT_EVENTS_KEY, UIManagerModuleConstants.getDirectEventTypeConstants()); + } + /** * Generates map of constants that is then exposed by {@link UIManagerModule}. * Provided list of {@param viewManagers} is then used to populate content of @@ -106,9 +115,6 @@ import javax.annotation.Nullable; @Nullable Map defaultDirectEvents, @Nullable Map cumulativeBubblingEventTypes, @Nullable Map cumulativeDirectEventTypes) { - final String BUBBLING_EVENTS_KEY = "bubblingEventTypes"; - final String DIRECT_EVENTS_KEY = "directEventTypes"; - Map viewManagerConstants = MapBuilder.newHashMap(); Map viewManagerBubblingEvents = viewManager.getExportedCustomBubblingEventTypeConstants();