react-native 0.85.2 → 0.85.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Utilities/HMRClient.js +28 -1
- package/React/Base/RCTVersion.m +1 -1
- package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
- package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
- package/React/CoreModules/RCTRedBox+Internal.h +42 -0
- package/React/CoreModules/RCTRedBox.mm +30 -454
- package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
- package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
- package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
- package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
- package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
- package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
- package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
- package/React/CoreModules/RCTRedBoxController.mm +447 -0
- package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
- package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
- package/React/CoreModules/React-CoreModules.podspec +1 -0
- package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
- package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
- package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +127 -26
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +50 -10
- package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +14 -0
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +18 -4
- package/ReactCommon/React-Fabric.podspec +6 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/jsinspector-modern/HostAgent.cpp +36 -0
- package/ReactCommon/jsinspector-modern/HostTarget.cpp +7 -1
- package/ReactCommon/jsinspector-modern/HostTarget.h +25 -0
- package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +1 -1
- package/ReactCommon/jsinspector-modern/HostTargetTracing.h +4 -4
- package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
- package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
- package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
- package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
- package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
- package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +12 -0
- package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +3 -2
- package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
- package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -1
- package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +1 -1
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
- package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
- package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +7 -3
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +52 -29
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +6 -6
- package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
- package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +12 -5
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +3 -1
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +42 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
- package/ReactCommon/react/debug/CMakeLists.txt +2 -1
- package/ReactCommon/react/debug/React-debug.podspec +7 -1
- package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
- package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
- package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
- package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
- package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
- package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
- package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
- package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
- package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +135 -45
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +21 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
- package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
- package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
- package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
- package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
- package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
- package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
- package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
- package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
- package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
- package/package.json +11 -11
- package/scripts/cocoapods/utils.rb +1 -0
- package/scripts/react_native_pods.rb +1 -0
- package/scripts/replace-rncore-version.js +72 -15
- package/src/private/featureflags/ReactNativeFeatureFlags.js +26 -1
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
- package/src/private/setup/setUpDefaultReactNativeEnvironment.js +6 -0
|
@@ -16,455 +16,15 @@
|
|
|
16
16
|
#import <React/RCTRedBoxExtraDataViewController.h>
|
|
17
17
|
#import <React/RCTReloadCommand.h>
|
|
18
18
|
#import <React/RCTUtils.h>
|
|
19
|
-
|
|
20
|
-
#import <objc/runtime.h>
|
|
19
|
+
#import <react/featureflags/ReactNativeFeatureFlags.h>
|
|
21
20
|
|
|
22
21
|
#import "CoreModulesPlugins.h"
|
|
22
|
+
#import "RCTRedBox+Internal.h"
|
|
23
|
+
#import "RCTRedBox2Controller+Internal.h"
|
|
24
|
+
#import "RCTRedBoxController+Internal.h"
|
|
23
25
|
|
|
24
26
|
#if RCT_DEV_MENU
|
|
25
27
|
|
|
26
|
-
@class RCTRedBoxController;
|
|
27
|
-
|
|
28
|
-
@interface UIButton (RCTRedBox)
|
|
29
|
-
|
|
30
|
-
@property (nonatomic) RCTRedBoxButtonPressHandler rct_handler;
|
|
31
|
-
|
|
32
|
-
- (void)rct_addBlock:(RCTRedBoxButtonPressHandler)handler forControlEvents:(UIControlEvents)controlEvents;
|
|
33
|
-
|
|
34
|
-
@end
|
|
35
|
-
|
|
36
|
-
@implementation UIButton (RCTRedBox)
|
|
37
|
-
|
|
38
|
-
- (RCTRedBoxButtonPressHandler)rct_handler
|
|
39
|
-
{
|
|
40
|
-
return objc_getAssociatedObject(self, @selector(rct_handler));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
- (void)setRct_handler:(RCTRedBoxButtonPressHandler)rct_handler
|
|
44
|
-
{
|
|
45
|
-
objc_setAssociatedObject(self, @selector(rct_handler), rct_handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
- (void)rct_callBlock
|
|
49
|
-
{
|
|
50
|
-
if (self.rct_handler) {
|
|
51
|
-
self.rct_handler();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
- (void)rct_addBlock:(RCTRedBoxButtonPressHandler)handler forControlEvents:(UIControlEvents)controlEvents
|
|
56
|
-
{
|
|
57
|
-
self.rct_handler = handler;
|
|
58
|
-
[self addTarget:self action:@selector(rct_callBlock) forControlEvents:controlEvents];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@end
|
|
62
|
-
|
|
63
|
-
@protocol RCTRedBoxControllerActionDelegate <NSObject>
|
|
64
|
-
|
|
65
|
-
- (void)redBoxController:(RCTRedBoxController *)redBoxController openStackFrameInEditor:(RCTJSStackFrame *)stackFrame;
|
|
66
|
-
- (void)reloadFromRedBoxController:(RCTRedBoxController *)redBoxController;
|
|
67
|
-
- (void)loadExtraDataViewController;
|
|
68
|
-
|
|
69
|
-
@end
|
|
70
|
-
|
|
71
|
-
@interface RCTRedBoxController : UIViewController <UITableViewDelegate, UITableViewDataSource>
|
|
72
|
-
@property (nonatomic, weak) id<RCTRedBoxControllerActionDelegate> actionDelegate;
|
|
73
|
-
@end
|
|
74
|
-
|
|
75
|
-
@implementation RCTRedBoxController {
|
|
76
|
-
UITableView *_stackTraceTableView;
|
|
77
|
-
NSString *_lastErrorMessage;
|
|
78
|
-
NSArray<RCTJSStackFrame *> *_lastStackTrace;
|
|
79
|
-
NSArray<NSString *> *_customButtonTitles;
|
|
80
|
-
NSArray<RCTRedBoxButtonPressHandler> *_customButtonHandlers;
|
|
81
|
-
int _lastErrorCookie;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
- (instancetype)initWithCustomButtonTitles:(NSArray<NSString *> *)customButtonTitles
|
|
85
|
-
customButtonHandlers:(NSArray<RCTRedBoxButtonPressHandler> *)customButtonHandlers
|
|
86
|
-
{
|
|
87
|
-
if (self = [super init]) {
|
|
88
|
-
_lastErrorCookie = -1;
|
|
89
|
-
_customButtonTitles = customButtonTitles;
|
|
90
|
-
_customButtonHandlers = customButtonHandlers;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return self;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
- (void)viewDidLoad
|
|
97
|
-
{
|
|
98
|
-
[super viewDidLoad];
|
|
99
|
-
self.view.backgroundColor = [UIColor blackColor];
|
|
100
|
-
|
|
101
|
-
const CGFloat buttonHeight = 60;
|
|
102
|
-
|
|
103
|
-
CGRect detailsFrame = self.view.bounds;
|
|
104
|
-
detailsFrame.size.height -= buttonHeight + (double)[self bottomSafeViewHeight];
|
|
105
|
-
|
|
106
|
-
_stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain];
|
|
107
|
-
_stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
108
|
-
_stackTraceTableView.delegate = self;
|
|
109
|
-
_stackTraceTableView.dataSource = self;
|
|
110
|
-
_stackTraceTableView.backgroundColor = [UIColor clearColor];
|
|
111
|
-
#if !TARGET_OS_TV
|
|
112
|
-
_stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3];
|
|
113
|
-
_stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
|
114
|
-
#endif
|
|
115
|
-
_stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
|
|
116
|
-
[self.view addSubview:_stackTraceTableView];
|
|
117
|
-
|
|
118
|
-
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
|
|
119
|
-
NSString *reloadText = @"Reload\n(\u2318R)";
|
|
120
|
-
NSString *dismissText = @"Dismiss\n(ESC)";
|
|
121
|
-
NSString *copyText = @"Copy\n(\u2325\u2318C)";
|
|
122
|
-
NSString *extraText = @"Extra Info\n(\u2318E)";
|
|
123
|
-
#else
|
|
124
|
-
NSString *reloadText = @"Reload JS";
|
|
125
|
-
NSString *dismissText = @"Dismiss";
|
|
126
|
-
NSString *copyText = @"Copy";
|
|
127
|
-
NSString *extraText = @"Extra Info";
|
|
128
|
-
#endif
|
|
129
|
-
|
|
130
|
-
UIButton *dismissButton = [self redBoxButton:dismissText
|
|
131
|
-
accessibilityIdentifier:@"redbox-dismiss"
|
|
132
|
-
selector:@selector(dismiss)
|
|
133
|
-
block:nil];
|
|
134
|
-
UIButton *reloadButton = [self redBoxButton:reloadText
|
|
135
|
-
accessibilityIdentifier:@"redbox-reload"
|
|
136
|
-
selector:@selector(reload)
|
|
137
|
-
block:nil];
|
|
138
|
-
UIButton *copyButton = [self redBoxButton:copyText
|
|
139
|
-
accessibilityIdentifier:@"redbox-copy"
|
|
140
|
-
selector:@selector(copyStack)
|
|
141
|
-
block:nil];
|
|
142
|
-
UIButton *extraButton = [self redBoxButton:extraText
|
|
143
|
-
accessibilityIdentifier:@"redbox-extra"
|
|
144
|
-
selector:@selector(showExtraDataViewController)
|
|
145
|
-
block:nil];
|
|
146
|
-
|
|
147
|
-
[NSLayoutConstraint activateConstraints:@[
|
|
148
|
-
[dismissButton.heightAnchor constraintEqualToConstant:buttonHeight],
|
|
149
|
-
[reloadButton.heightAnchor constraintEqualToConstant:buttonHeight],
|
|
150
|
-
[copyButton.heightAnchor constraintEqualToConstant:buttonHeight],
|
|
151
|
-
[extraButton.heightAnchor constraintEqualToConstant:buttonHeight]
|
|
152
|
-
]];
|
|
153
|
-
|
|
154
|
-
UIStackView *buttonStackView = [[UIStackView alloc] init];
|
|
155
|
-
buttonStackView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
156
|
-
buttonStackView.axis = UILayoutConstraintAxisHorizontal;
|
|
157
|
-
buttonStackView.distribution = UIStackViewDistributionFillEqually;
|
|
158
|
-
buttonStackView.alignment = UIStackViewAlignmentTop;
|
|
159
|
-
buttonStackView.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
|
|
160
|
-
|
|
161
|
-
[buttonStackView addArrangedSubview:dismissButton];
|
|
162
|
-
[buttonStackView addArrangedSubview:reloadButton];
|
|
163
|
-
[buttonStackView addArrangedSubview:copyButton];
|
|
164
|
-
[buttonStackView addArrangedSubview:extraButton];
|
|
165
|
-
|
|
166
|
-
[self.view addSubview:buttonStackView];
|
|
167
|
-
|
|
168
|
-
[NSLayoutConstraint activateConstraints:@[
|
|
169
|
-
[buttonStackView.heightAnchor constraintEqualToConstant:buttonHeight + [self bottomSafeViewHeight]],
|
|
170
|
-
[buttonStackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
171
|
-
[buttonStackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
|
172
|
-
[buttonStackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
|
|
173
|
-
]];
|
|
174
|
-
|
|
175
|
-
for (NSUInteger i = 0; i < [_customButtonTitles count]; i++) {
|
|
176
|
-
UIButton *button = [self redBoxButton:_customButtonTitles[i]
|
|
177
|
-
accessibilityIdentifier:@""
|
|
178
|
-
selector:nil
|
|
179
|
-
block:_customButtonHandlers[i]];
|
|
180
|
-
[button.heightAnchor constraintEqualToConstant:buttonHeight].active = YES;
|
|
181
|
-
[buttonStackView addArrangedSubview:button];
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
UIView *topBorder = [[UIView alloc] init];
|
|
185
|
-
topBorder.translatesAutoresizingMaskIntoConstraints = NO;
|
|
186
|
-
topBorder.backgroundColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
|
|
187
|
-
[topBorder.heightAnchor constraintEqualToConstant:1].active = YES;
|
|
188
|
-
|
|
189
|
-
[self.view addSubview:topBorder];
|
|
190
|
-
|
|
191
|
-
[NSLayoutConstraint activateConstraints:@[
|
|
192
|
-
[topBorder.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
193
|
-
[topBorder.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
|
194
|
-
[topBorder.bottomAnchor constraintEqualToAnchor:buttonStackView.topAnchor],
|
|
195
|
-
]];
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
- (UIButton *)redBoxButton:(NSString *)title
|
|
199
|
-
accessibilityIdentifier:(NSString *)accessibilityIdentifier
|
|
200
|
-
selector:(SEL)selector
|
|
201
|
-
block:(RCTRedBoxButtonPressHandler)block
|
|
202
|
-
{
|
|
203
|
-
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
204
|
-
button.autoresizingMask =
|
|
205
|
-
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
|
|
206
|
-
button.accessibilityIdentifier = accessibilityIdentifier;
|
|
207
|
-
button.titleLabel.font = [UIFont systemFontOfSize:13];
|
|
208
|
-
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
|
209
|
-
button.titleLabel.textAlignment = NSTextAlignmentCenter;
|
|
210
|
-
button.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
|
|
211
|
-
[button setTitle:title forState:UIControlStateNormal];
|
|
212
|
-
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
|
213
|
-
[button setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
|
|
214
|
-
if (selector) {
|
|
215
|
-
[button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
|
|
216
|
-
} else if (block) {
|
|
217
|
-
[button rct_addBlock:block forControlEvents:UIControlEventTouchUpInside];
|
|
218
|
-
}
|
|
219
|
-
return button;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
- (NSInteger)bottomSafeViewHeight
|
|
223
|
-
{
|
|
224
|
-
#if TARGET_OS_MACCATALYST
|
|
225
|
-
return 0;
|
|
226
|
-
#else
|
|
227
|
-
return RCTKeyWindow().safeAreaInsets.bottom;
|
|
228
|
-
#endif
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
232
|
-
|
|
233
|
-
- (NSString *)stripAnsi:(NSString *)text
|
|
234
|
-
{
|
|
235
|
-
NSError *error = nil;
|
|
236
|
-
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\x1b\\[[0-9;]*m"
|
|
237
|
-
options:NSRegularExpressionCaseInsensitive
|
|
238
|
-
error:&error];
|
|
239
|
-
return [regex stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:@""];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
- (void)showErrorMessage:(NSString *)message
|
|
243
|
-
withStack:(NSArray<RCTJSStackFrame *> *)stack
|
|
244
|
-
isUpdate:(BOOL)isUpdate
|
|
245
|
-
errorCookie:(int)errorCookie
|
|
246
|
-
{
|
|
247
|
-
// Remove ANSI color codes from the message
|
|
248
|
-
NSString *messageWithoutAnsi = [self stripAnsi:message];
|
|
249
|
-
|
|
250
|
-
BOOL isRootViewControllerPresented = self.presentingViewController != nil;
|
|
251
|
-
// Show if this is a new message, or if we're updating the previous message
|
|
252
|
-
BOOL isNew = !isRootViewControllerPresented && !isUpdate;
|
|
253
|
-
BOOL isUpdateForSameMessage = !isNew &&
|
|
254
|
-
(isRootViewControllerPresented && isUpdate &&
|
|
255
|
-
((errorCookie == -1 && [_lastErrorMessage isEqualToString:messageWithoutAnsi]) ||
|
|
256
|
-
(errorCookie == _lastErrorCookie)));
|
|
257
|
-
if (isNew || isUpdateForSameMessage) {
|
|
258
|
-
_lastStackTrace = stack;
|
|
259
|
-
// message is displayed using UILabel, which is unable to render text of
|
|
260
|
-
// unlimited length, so we truncate it
|
|
261
|
-
_lastErrorMessage = [messageWithoutAnsi substringToIndex:MIN((NSUInteger)10000, messageWithoutAnsi.length)];
|
|
262
|
-
_lastErrorCookie = errorCookie;
|
|
263
|
-
|
|
264
|
-
[_stackTraceTableView reloadData];
|
|
265
|
-
|
|
266
|
-
if (!isRootViewControllerPresented) {
|
|
267
|
-
[_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
|
|
268
|
-
atScrollPosition:UITableViewScrollPositionTop
|
|
269
|
-
animated:NO];
|
|
270
|
-
[RCTKeyWindow().rootViewController presentViewController:self animated:YES completion:nil];
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
- (void)dismiss
|
|
276
|
-
{
|
|
277
|
-
[self dismissViewControllerAnimated:YES completion:nil];
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
- (void)reload
|
|
281
|
-
{
|
|
282
|
-
if (_actionDelegate != nil) {
|
|
283
|
-
[_actionDelegate reloadFromRedBoxController:self];
|
|
284
|
-
} else {
|
|
285
|
-
// In bridgeless mode `RCTRedBox` gets deallocated, we need to notify listeners anyway.
|
|
286
|
-
RCTTriggerReloadCommandListeners(@"Redbox");
|
|
287
|
-
[self dismiss];
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
- (void)showExtraDataViewController
|
|
292
|
-
{
|
|
293
|
-
[_actionDelegate loadExtraDataViewController];
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
- (void)copyStack
|
|
297
|
-
{
|
|
298
|
-
NSMutableString *fullStackTrace;
|
|
299
|
-
|
|
300
|
-
if (_lastErrorMessage != nil) {
|
|
301
|
-
fullStackTrace = [_lastErrorMessage mutableCopy];
|
|
302
|
-
[fullStackTrace appendString:@"\n\n"];
|
|
303
|
-
} else {
|
|
304
|
-
fullStackTrace = [NSMutableString string];
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
for (RCTJSStackFrame *stackFrame in _lastStackTrace) {
|
|
308
|
-
[fullStackTrace appendString:[NSString stringWithFormat:@"%@\n", stackFrame.methodName]];
|
|
309
|
-
if (stackFrame.file) {
|
|
310
|
-
[fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]];
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
#if !TARGET_OS_TV
|
|
314
|
-
UIPasteboard *pb = [UIPasteboard generalPasteboard];
|
|
315
|
-
[pb setString:fullStackTrace];
|
|
316
|
-
#endif
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
- (NSString *)formatFrameSource:(RCTJSStackFrame *)stackFrame
|
|
320
|
-
{
|
|
321
|
-
NSString *fileName = RCTNilIfNull(stackFrame.file) ? [stackFrame.file lastPathComponent] : @"<unknown file>";
|
|
322
|
-
NSString *lineInfo = [NSString stringWithFormat:@"%@:%lld", fileName, (long long)stackFrame.lineNumber];
|
|
323
|
-
|
|
324
|
-
if (stackFrame.column != 0) {
|
|
325
|
-
lineInfo = [lineInfo stringByAppendingFormat:@":%lld", (long long)stackFrame.column];
|
|
326
|
-
}
|
|
327
|
-
return lineInfo;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
#pragma mark - TableView
|
|
331
|
-
|
|
332
|
-
- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView
|
|
333
|
-
{
|
|
334
|
-
return 2;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
338
|
-
{
|
|
339
|
-
return section == 0 ? 1 : _lastStackTrace.count;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
343
|
-
{
|
|
344
|
-
if (indexPath.section == 0) {
|
|
345
|
-
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"];
|
|
346
|
-
return [self reuseCell:cell forErrorMessage:_lastErrorMessage];
|
|
347
|
-
}
|
|
348
|
-
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
|
349
|
-
NSUInteger index = indexPath.row;
|
|
350
|
-
RCTJSStackFrame *stackFrame = _lastStackTrace[index];
|
|
351
|
-
return [self reuseCell:cell forStackFrame:stackFrame];
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message
|
|
355
|
-
{
|
|
356
|
-
if (!cell) {
|
|
357
|
-
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"msg-cell"];
|
|
358
|
-
cell.textLabel.accessibilityIdentifier = @"redbox-error";
|
|
359
|
-
cell.textLabel.textColor = [UIColor whiteColor];
|
|
360
|
-
|
|
361
|
-
// Prefer a monofont for formatting messages that were designed
|
|
362
|
-
// to be displayed in a terminal.
|
|
363
|
-
cell.textLabel.font = [UIFont monospacedSystemFontOfSize:14 weight:UIFontWeightBold];
|
|
364
|
-
|
|
365
|
-
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
|
366
|
-
cell.textLabel.numberOfLines = 0;
|
|
367
|
-
cell.detailTextLabel.textColor = [UIColor whiteColor];
|
|
368
|
-
cell.backgroundColor = [UIColor colorWithRed:0.82 green:0.10 blue:0.15 alpha:1.0];
|
|
369
|
-
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
cell.textLabel.text = message;
|
|
373
|
-
|
|
374
|
-
return cell;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame
|
|
378
|
-
{
|
|
379
|
-
if (!cell) {
|
|
380
|
-
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
|
|
381
|
-
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
|
|
382
|
-
cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping;
|
|
383
|
-
cell.textLabel.numberOfLines = 2;
|
|
384
|
-
cell.detailTextLabel.textColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
|
|
385
|
-
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
|
|
386
|
-
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
|
387
|
-
cell.backgroundColor = [UIColor clearColor];
|
|
388
|
-
cell.selectedBackgroundView = [UIView new];
|
|
389
|
-
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)";
|
|
393
|
-
if (stackFrame.file) {
|
|
394
|
-
cell.detailTextLabel.text = [self formatFrameSource:stackFrame];
|
|
395
|
-
} else {
|
|
396
|
-
cell.detailTextLabel.text = @"";
|
|
397
|
-
}
|
|
398
|
-
cell.textLabel.textColor = stackFrame.collapse ? [UIColor lightGrayColor] : [UIColor whiteColor];
|
|
399
|
-
cell.detailTextLabel.textColor = stackFrame.collapse ? [UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.0]
|
|
400
|
-
: [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
|
|
401
|
-
return cell;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
405
|
-
{
|
|
406
|
-
if (indexPath.section == 0) {
|
|
407
|
-
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
|
408
|
-
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
|
409
|
-
|
|
410
|
-
NSDictionary *attributes =
|
|
411
|
-
@{NSFontAttributeName : [UIFont boldSystemFontOfSize:16], NSParagraphStyleAttributeName : paragraphStyle};
|
|
412
|
-
CGRect boundingRect =
|
|
413
|
-
[_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX)
|
|
414
|
-
options:NSStringDrawingUsesLineFragmentOrigin
|
|
415
|
-
attributes:attributes
|
|
416
|
-
context:nil];
|
|
417
|
-
return ceil(boundingRect.size.height) + 40;
|
|
418
|
-
} else {
|
|
419
|
-
return 50;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|
424
|
-
{
|
|
425
|
-
if (indexPath.section == 1) {
|
|
426
|
-
NSUInteger row = indexPath.row;
|
|
427
|
-
RCTJSStackFrame *stackFrame = _lastStackTrace[row];
|
|
428
|
-
[_actionDelegate redBoxController:self openStackFrameInEditor:stackFrame];
|
|
429
|
-
}
|
|
430
|
-
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
#pragma mark - Key commands
|
|
434
|
-
|
|
435
|
-
- (NSArray<UIKeyCommand *> *)keyCommands
|
|
436
|
-
{
|
|
437
|
-
// NOTE: We could use RCTKeyCommands for this, but since
|
|
438
|
-
// we control this window, we can use the standard, non-hacky
|
|
439
|
-
// mechanism instead
|
|
440
|
-
|
|
441
|
-
return @[
|
|
442
|
-
// Dismiss red box
|
|
443
|
-
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:0 action:@selector(dismiss)],
|
|
444
|
-
|
|
445
|
-
// Reload
|
|
446
|
-
[UIKeyCommand keyCommandWithInput:@"r" modifierFlags:UIKeyModifierCommand action:@selector(reload)],
|
|
447
|
-
|
|
448
|
-
// Copy = Cmd-Option C since Cmd-C in the simulator copies the pasteboard from
|
|
449
|
-
// the simulator to the desktop pasteboard.
|
|
450
|
-
[UIKeyCommand keyCommandWithInput:@"c"
|
|
451
|
-
modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate
|
|
452
|
-
action:@selector(copyStack)],
|
|
453
|
-
|
|
454
|
-
// Extra data
|
|
455
|
-
[UIKeyCommand keyCommandWithInput:@"e"
|
|
456
|
-
modifierFlags:UIKeyModifierCommand
|
|
457
|
-
action:@selector(showExtraDataViewController)]
|
|
458
|
-
];
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
- (BOOL)canBecomeFirstResponder
|
|
462
|
-
{
|
|
463
|
-
return YES;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
@end
|
|
467
|
-
|
|
468
28
|
@interface RCTRedBox () <
|
|
469
29
|
RCTInvalidating,
|
|
470
30
|
RCTRedBoxControllerActionDelegate,
|
|
@@ -473,7 +33,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
473
33
|
@end
|
|
474
34
|
|
|
475
35
|
@implementation RCTRedBox {
|
|
476
|
-
|
|
36
|
+
id<RCTRedBoxControlling> _controller;
|
|
477
37
|
NSMutableArray<id<RCTErrorCustomizer>> *_errorCustomizers;
|
|
478
38
|
RCTRedBoxExtraDataViewController *_extraDataViewController;
|
|
479
39
|
NSMutableArray<NSString *> *_customButtonTitles;
|
|
@@ -605,6 +165,14 @@ RCT_EXPORT_MODULE()
|
|
|
605
165
|
[self showErrorMessage:message withParsedStack:stack isUpdate:YES errorCookie:errorCookie];
|
|
606
166
|
}
|
|
607
167
|
|
|
168
|
+
- (id<RCTRedBox2Controlling>)_redBox2Controller
|
|
169
|
+
{
|
|
170
|
+
if ([_controller conformsToProtocol:@protocol(RCTRedBox2Controlling)]) {
|
|
171
|
+
return (id<RCTRedBox2Controlling>)_controller;
|
|
172
|
+
}
|
|
173
|
+
return nil;
|
|
174
|
+
}
|
|
175
|
+
|
|
608
176
|
- (void)showErrorMessage:(NSString *)message
|
|
609
177
|
withParsedStack:(NSArray<RCTJSStackFrame *> *)stack
|
|
610
178
|
isUpdate:(BOOL)isUpdate
|
|
@@ -621,14 +189,21 @@ RCT_EXPORT_MODULE()
|
|
|
621
189
|
[[self->_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"collectRedBoxExtraData"
|
|
622
190
|
body:nil];
|
|
623
191
|
#pragma clang diagnostic pop
|
|
624
|
-
if (!self->_controller) {
|
|
625
|
-
self->_controller = [[RCTRedBoxController alloc] initWithCustomButtonTitles:self->_customButtonTitles
|
|
626
|
-
customButtonHandlers:self->_customButtonHandlers];
|
|
627
|
-
self->_controller.actionDelegate = self;
|
|
628
|
-
}
|
|
629
192
|
|
|
630
193
|
RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message stack:stack];
|
|
631
194
|
errorInfo = [self _customizeError:errorInfo];
|
|
195
|
+
|
|
196
|
+
if (self->_controller == nullptr) {
|
|
197
|
+
if (facebook::react::ReactNativeFeatureFlags::redBoxV2IOS()) {
|
|
198
|
+
self->_controller = [[RCTRedBox2Controller alloc] initWithCustomButtonTitles:self->_customButtonTitles
|
|
199
|
+
customButtonHandlers:self->_customButtonHandlers];
|
|
200
|
+
} else {
|
|
201
|
+
self->_controller = [[RCTRedBoxController alloc] initWithCustomButtonTitles:self->_customButtonTitles
|
|
202
|
+
customButtonHandlers:self->_customButtonHandlers];
|
|
203
|
+
}
|
|
204
|
+
self->_controller.actionDelegate = self;
|
|
205
|
+
}
|
|
206
|
+
[self _redBox2Controller].bundleURL = self->_overrideBundleURL ?: self->_bundleManager.bundleURL;
|
|
632
207
|
[self->_controller showErrorMessage:errorInfo.errorMessage
|
|
633
208
|
withStack:errorInfo.stack
|
|
634
209
|
isUpdate:isUpdate
|
|
@@ -639,9 +214,10 @@ RCT_EXPORT_MODULE()
|
|
|
639
214
|
- (void)loadExtraDataViewController
|
|
640
215
|
{
|
|
641
216
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
217
|
+
UIViewController *controller = static_cast<UIViewController *>(self->_controller);
|
|
642
218
|
// Make sure the CMD+E shortcut doesn't call this twice
|
|
643
|
-
if (self->_extraDataViewController != nil &&
|
|
644
|
-
[
|
|
219
|
+
if (self->_extraDataViewController != nil && ([controller presentedViewController] == nullptr)) {
|
|
220
|
+
[controller presentViewController:self->_extraDataViewController animated:YES completion:nil];
|
|
645
221
|
}
|
|
646
222
|
});
|
|
647
223
|
}
|
|
@@ -663,7 +239,7 @@ RCT_EXPORT_METHOD(dismiss)
|
|
|
663
239
|
[self dismiss];
|
|
664
240
|
}
|
|
665
241
|
|
|
666
|
-
- (void)redBoxController:(__unused
|
|
242
|
+
- (void)redBoxController:(__unused UIViewController *)redBoxController
|
|
667
243
|
openStackFrameInEditor:(RCTJSStackFrame *)stackFrame
|
|
668
244
|
{
|
|
669
245
|
NSURL *const bundleURL = _overrideBundleURL ?: _bundleManager.bundleURL;
|
|
@@ -690,7 +266,7 @@ RCT_EXPORT_METHOD(dismiss)
|
|
|
690
266
|
[self reloadFromRedBoxController:nil];
|
|
691
267
|
}
|
|
692
268
|
|
|
693
|
-
- (void)reloadFromRedBoxController:(__unused
|
|
269
|
+
- (void)reloadFromRedBoxController:(__unused UIViewController *)redBoxController
|
|
694
270
|
{
|
|
695
271
|
if (_overrideReloadAction) {
|
|
696
272
|
_overrideReloadAction();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#import <UIKit/UIKit.h>
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parses ANSI escape sequences in text and produces an NSAttributedString
|
|
12
|
+
* with the corresponding foreground/background colors applied.
|
|
13
|
+
*
|
|
14
|
+
* Uses the Afterglow color theme (matching LogBox's AnsiHighlight.js).
|
|
15
|
+
*/
|
|
16
|
+
@interface RCTRedBox2AnsiParser : NSObject
|
|
17
|
+
|
|
18
|
+
+ (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text
|
|
19
|
+
baseFont:(UIFont *)font
|
|
20
|
+
baseColor:(UIColor *)color;
|
|
21
|
+
|
|
22
|
+
@end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#import "RCTRedBox2AnsiParser+Internal.h"
|
|
9
|
+
|
|
10
|
+
#import <React/RCTDefines.h>
|
|
11
|
+
#import <react/debug/redbox/AnsiParser.h>
|
|
12
|
+
|
|
13
|
+
#if RCT_DEV_MENU
|
|
14
|
+
|
|
15
|
+
using facebook::react::unstable_redbox::AnsiColor;
|
|
16
|
+
using facebook::react::unstable_redbox::parseAnsi;
|
|
17
|
+
|
|
18
|
+
static UIColor *RCTUIColorFromAnsiColor(const AnsiColor &c)
|
|
19
|
+
{
|
|
20
|
+
return [UIColor colorWithRed:c.r / 255.0 green:c.g / 255.0 blue:c.b / 255.0 alpha:1.0];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@implementation RCTRedBox2AnsiParser
|
|
24
|
+
|
|
25
|
+
+ (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text baseFont:(UIFont *)font baseColor:(UIColor *)color
|
|
26
|
+
{
|
|
27
|
+
if (text == nil) {
|
|
28
|
+
return [[NSAttributedString alloc] init];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
auto spans = parseAnsi(text.UTF8String);
|
|
32
|
+
NSMutableAttributedString *result =[NSMutableAttributedString new];
|
|
33
|
+
NSDictionary *baseAttributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : color};
|
|
34
|
+
|
|
35
|
+
for (const auto &span : spans) {
|
|
36
|
+
NSString *str = [NSString stringWithUTF8String:span.text.c_str()];
|
|
37
|
+
if (str == nil) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
NSMutableDictionary *attrs = [baseAttributes mutableCopy];
|
|
41
|
+
if (span.foregroundColor.has_value()) {
|
|
42
|
+
attrs[NSForegroundColorAttributeName] = RCTUIColorFromAnsiColor(*span.foregroundColor);
|
|
43
|
+
}
|
|
44
|
+
if (span.backgroundColor.has_value()) {
|
|
45
|
+
attrs[NSBackgroundColorAttributeName] = RCTUIColorFromAnsiColor(*span.backgroundColor);
|
|
46
|
+
}
|
|
47
|
+
[result appendAttributedString:[[NSAttributedString alloc] initWithString:str attributes:attrs]];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@end
|
|
54
|
+
|
|
55
|
+
#endif
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#import <React/RCTDefines.h>
|
|
9
|
+
|
|
10
|
+
#import "RCTRedBox+Internal.h"
|
|
11
|
+
|
|
12
|
+
#if RCT_DEV_MENU
|
|
13
|
+
|
|
14
|
+
typedef void (^RCTRedBox2ButtonPressHandler)(void);
|
|
15
|
+
|
|
16
|
+
@interface RCTRedBox2Controller : UIViewController <RCTRedBox2Controlling, UITableViewDelegate, UITableViewDataSource>
|
|
17
|
+
|
|
18
|
+
@property (nonatomic, weak) id<RCTRedBoxControllerActionDelegate> actionDelegate;
|
|
19
|
+
|
|
20
|
+
- (instancetype)initWithCustomButtonTitles:(NSArray<NSString *> *)customButtonTitles
|
|
21
|
+
customButtonHandlers:(NSArray<RCTRedBox2ButtonPressHandler> *)customButtonHandlers;
|
|
22
|
+
|
|
23
|
+
- (void)showErrorMessage:(NSString *)message
|
|
24
|
+
withStack:(NSArray<RCTJSStackFrame *> *)stack
|
|
25
|
+
isUpdate:(BOOL)isUpdate
|
|
26
|
+
errorCookie:(int)errorCookie;
|
|
27
|
+
|
|
28
|
+
/// The bundle URL used by the app, for the native HMR connection.
|
|
29
|
+
@property (nonatomic, strong, nullable) NSURL *bundleURL;
|
|
30
|
+
|
|
31
|
+
- (void)dismiss;
|
|
32
|
+
@end
|
|
33
|
+
|
|
34
|
+
#endif
|