diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index 9c0781ce448..6dd7a40420c 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -1932,7 +1932,7 @@ namespace facebook { static facebook::jsi::Value __hostFunction_NativeRedBoxSpecJSI_setExtraData(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "setExtraData", @selector(setExtraData:identifier:), args, count); + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "setExtraData", @selector(setExtraData:forIdentifier:), args, count); } static facebook::jsi::Value __hostFunction_NativeRedBoxSpecJSI_dismiss(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index f73e6409552..6bad8d4ad06 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -1990,7 +1990,7 @@ namespace facebook { @protocol NativeRedBoxSpec - (void)setExtraData:(NSDictionary *)extraData - identifier:(NSString *)identifier; + forIdentifier:(NSString *)forIdentifier; - (void)dismiss; @end diff --git a/Libraries/NativeModules/specs/NativeRedBox.js b/Libraries/NativeModules/specs/NativeRedBox.js index e132b544345..469465e3436 100644 --- a/Libraries/NativeModules/specs/NativeRedBox.js +++ b/Libraries/NativeModules/specs/NativeRedBox.js @@ -14,7 +14,7 @@ import type {TurboModule} from '../../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { - +setExtraData: (extraData: Object, identifier: string) => void; + +setExtraData: (extraData: Object, forIdentifier: string) => void; +dismiss: () => void; } diff --git a/React/Base/RCTLog.mm b/React/Base/RCTLog.mm index e01809e1440..0fbff876cd8 100644 --- a/React/Base/RCTLog.mm +++ b/React/Base/RCTLog.mm @@ -9,11 +9,13 @@ #include +#import + +#import "RCTRedBoxSetEnabled.h" #import "RCTAssert.h" #import "RCTBridge+Private.h" #import "RCTBridge.h" #import "RCTDefines.h" -#import "RCTRedBox.h" #import "RCTUtils.h" static NSString *const RCTLogFunctionStack = @"RCTLogFunctionStack"; @@ -169,7 +171,7 @@ NSString *RCTFormatLogLevel(RCTLogLevel level) @(RCTLogLevelWarning) : @"warning", @(RCTLogLevelFatal) : @"fatal", @(RCTLogLevelError) : @"error"}; - + return levelsToString[@(level)]; } @@ -177,7 +179,7 @@ NSString *RCTFormatLogSource(RCTLogSource source) { NSDictionary *sourcesToString = @{@(RCTLogSourceNative) : @"native", @(RCTLogSourceJavaScript) : @"js"}; - + return sourcesToString[@(source)]; } @@ -246,10 +248,18 @@ void _RCTLogNativeInternal(RCTLogLevel level, const char *fileName, int lineNumb dispatch_async(dispatch_get_main_queue(), ^{ // red box is thread safe, but by deferring to main queue we avoid a startup // race condition that causes the module to be accessed before it has loaded - [[RCTBridge currentBridge].redBox showErrorMessage:message withStack:stack]; + id redbox = [[RCTBridge currentBridge] moduleForName:@"RedBox" lazilyLoadIfNecessary:YES]; + if (redbox) { + void (*showErrorMessage)(id, SEL, NSString *, NSMutableArray *) = (__typeof__(showErrorMessage))objc_msgSend; + SEL showErrorMessageSEL = NSSelectorFromString(@"showErrorMessage:withStack:"); + + if ([redbox respondsToSelector:showErrorMessageSEL]) { + showErrorMessage(redbox, showErrorMessageSEL, message, stack); + } + } }); } - + #if RCT_DEBUG if (!RCTRunningInTestEnvironment()) { // Log to JS executor diff --git a/React/Base/RCTRedBoxSetEnabled.h b/React/Base/RCTRedBoxSetEnabled.h new file mode 100644 index 00000000000..5d65d7f89ae --- /dev/null +++ b/React/Base/RCTRedBoxSetEnabled.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +// In debug builds, the red box is enabled by default but it is further customizable using this method. +// However, this method only has an effect in builds where RCTRedBox is actually compiled in. +RCT_EXTERN void RCTRedBoxSetEnabled(BOOL enabled); +RCT_EXTERN BOOL RCTRedBoxGetEnabled(void); diff --git a/React/Base/RCTRedBoxSetEnabled.m b/React/Base/RCTRedBoxSetEnabled.m new file mode 100644 index 00000000000..4d6a701df9f --- /dev/null +++ b/React/Base/RCTRedBoxSetEnabled.m @@ -0,0 +1,22 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTRedBoxSetEnabled.h" + +#if RCT_DEV +static BOOL redBoxEnabled = YES; +#else +static BOOL redBoxEnabled = NO; +#endif + +void RCTRedBoxSetEnabled(BOOL enabled) { + redBoxEnabled = enabled; +} + +BOOL RCTRedBoxGetEnabled() { + return redBoxEnabled; +} diff --git a/React/CoreModules/BUCK b/React/CoreModules/BUCK index 428350fbc52..fa8236064e8 100644 --- a/React/CoreModules/BUCK +++ b/React/CoreModules/BUCK @@ -93,6 +93,9 @@ rn_apple_library( ) + react_module_plugin_providers( name = "DevSettings", native_class_func = "RCTDevSettingsCls", + ) + react_module_plugin_providers( + name = "RedBox", + native_class_func = "RCTRedBoxCls", ), plugins_header = "FBCoreModulesPlugins.h", preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_debug_preprocessor_flags() + rn_extra_build_flags() + [ diff --git a/React/CoreModules/CoreModulesPlugins.h b/React/CoreModules/CoreModulesPlugins.h index 105419334e8..538587c40aa 100644 --- a/React/CoreModules/CoreModulesPlugins.h +++ b/React/CoreModules/CoreModulesPlugins.h @@ -47,6 +47,7 @@ Class RCTAppStateCls(void) __attribute__((used)); Class RCTPerfMonitorCls(void) __attribute__((used)); Class RCTDevMenuCls(void) __attribute__((used)); Class RCTDevSettingsCls(void) __attribute__((used)); +Class RCTRedBoxCls(void) __attribute__((used)); #ifdef __cplusplus } diff --git a/React/CoreModules/CoreModulesPlugins.mm b/React/CoreModules/CoreModulesPlugins.mm index 1067d997d01..8de9f04b50c 100644 --- a/React/CoreModules/CoreModulesPlugins.mm +++ b/React/CoreModules/CoreModulesPlugins.mm @@ -36,6 +36,7 @@ Class RCTCoreModulesClassProvider(const char *name) { {"PerfMonitor", RCTPerfMonitorCls}, {"DevMenu", RCTDevMenuCls}, {"DevSettings", RCTDevSettingsCls}, + {"RedBox", RCTRedBoxCls}, }; auto p = sCoreModuleClassMap.find(name); diff --git a/React/Modules/RCTRedBox.h b/React/CoreModules/RCTRedBox.h similarity index 89% rename from React/Modules/RCTRedBox.h rename to React/CoreModules/RCTRedBox.h index e9a8b062eb3..943a9ffacf8 100644 --- a/React/Modules/RCTRedBox.h +++ b/React/CoreModules/RCTRedBox.h @@ -53,8 +53,3 @@ typedef void (^RCTRedBoxButtonPressHandler)(void); @property (nonatomic, readonly) RCTRedBox *redBox; @end - -// In debug builds, the red box is enabled by default but it is further customizable using this method. -// However, this method only has an effect in builds where RCTRedBox is actually compiled in. -RCT_EXTERN void RCTRedBoxSetEnabled(BOOL enabled); -RCT_EXTERN BOOL RCTRedBoxGetEnabled(void); diff --git a/React/Modules/RCTRedBox.m b/React/CoreModules/RCTRedBox.mm similarity index 95% rename from React/Modules/RCTRedBox.m rename to React/CoreModules/RCTRedBox.mm index e3fe60900a6..115ecf263bc 100644 --- a/React/Modules/RCTRedBox.m +++ b/React/CoreModules/RCTRedBox.mm @@ -7,31 +7,21 @@ #import "RCTRedBox.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTDefines.h" -#import "RCTErrorInfo.h" -#import "RCTEventDispatcher.h" -#import "RCTJSStackFrame.h" -#import "RCTRedBoxExtraDataViewController.h" -#import "RCTReloadCommand.h" -#import "RCTUtils.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import #import -#if RCT_DEV -static BOOL redBoxEnabled = YES; -#else -static BOOL redBoxEnabled = NO; -#endif - -void RCTRedBoxSetEnabled(BOOL enabled) { - redBoxEnabled = enabled; -} - -BOOL RCTRedBoxGetEnabled() { - return redBoxEnabled; -} +#import "CoreModulesPlugins.h" #if RCT_DEV_MENU @@ -441,7 +431,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) @end -@interface RCTRedBox () +@interface RCTRedBox () @end @implementation RCTRedBox @@ -662,19 +652,27 @@ RCT_EXPORT_METHOD(dismiss) [_customButtonHandlers addObject:handler]; } +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} + @end @implementation RCTBridge (RCTRedBox) - (RCTRedBox *)redBox { - return redBoxEnabled ? [self moduleForClass:[RCTRedBox class]] : nil; + return RCTRedBoxGetEnabled() ? [self moduleForClass:[RCTRedBox class]] : nil; } @end #else // Disabled +@interface RCTRedBox() +@end + @implementation RCTRedBox + (NSString *)moduleName { return nil; } @@ -692,10 +690,15 @@ RCT_EXPORT_METHOD(dismiss) - (void)updateErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack {} - (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack errorCookie:(int)errorCookie {} - (void)updateErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack errorCookie:(int)errorCookie {} +- (void)setExtraData:(NSDictionary *)extraData forIdentifier:(NSString *)identifier {} - (void)dismiss {} - (void)addCustomButton:(NSString *)title onPressHandler:(RCTRedBoxButtonPressHandler)handler {} +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} @end @@ -706,3 +709,7 @@ RCT_EXPORT_METHOD(dismiss) @end #endif + +Class RCTRedBoxCls(void) { + return RCTRedBox.class; +} diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeRedBoxSpec.java b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeRedBoxSpec.java index 6f7d2df753b..85fc1badcae 100644 --- a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeRedBoxSpec.java +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeRedBoxSpec.java @@ -25,7 +25,7 @@ public abstract class NativeRedBoxSpec extends ReactContextBaseJavaModule implem } @ReactMethod - public abstract void setExtraData(ReadableMap extraData, String identifier); + public abstract void setExtraData(ReadableMap extraData, String forIdentifier); @ReactMethod public abstract void dismiss();