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.
Files changed (108) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Utilities/HMRClient.js +28 -1
  3. package/React/Base/RCTVersion.m +1 -1
  4. package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
  5. package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
  6. package/React/CoreModules/RCTRedBox+Internal.h +42 -0
  7. package/React/CoreModules/RCTRedBox.mm +30 -454
  8. package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
  9. package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
  10. package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
  11. package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
  12. package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
  13. package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
  14. package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
  15. package/React/CoreModules/RCTRedBoxController.mm +447 -0
  16. package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
  17. package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
  18. package/React/CoreModules/React-CoreModules.podspec +1 -0
  19. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  20. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  21. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
  22. package/ReactAndroid/gradle.properties +1 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  24. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +1 -1
  25. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +127 -26
  26. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
  27. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
  28. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
  29. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +11 -1
  30. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
  31. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
  32. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  34. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +50 -10
  35. package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
  36. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  37. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  38. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
  39. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
  40. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +14 -0
  41. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +18 -4
  42. package/ReactCommon/React-Fabric.podspec +6 -0
  43. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  44. package/ReactCommon/jsinspector-modern/HostAgent.cpp +36 -0
  45. package/ReactCommon/jsinspector-modern/HostTarget.cpp +7 -1
  46. package/ReactCommon/jsinspector-modern/HostTarget.h +25 -0
  47. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +1 -1
  48. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +4 -4
  49. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  50. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  51. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  52. package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
  53. package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
  54. package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
  55. package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
  56. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +12 -0
  57. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +3 -2
  58. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  59. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -1
  60. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +1 -1
  61. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  62. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  63. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  64. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +7 -3
  65. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +52 -29
  66. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +6 -6
  67. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  68. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  69. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +12 -5
  70. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +3 -1
  71. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +42 -0
  72. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  73. package/ReactCommon/react/debug/CMakeLists.txt +2 -1
  74. package/ReactCommon/react/debug/React-debug.podspec +7 -1
  75. package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
  76. package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
  77. package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
  78. package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
  79. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
  80. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
  81. package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
  82. package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
  83. package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
  84. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
  85. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
  86. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +135 -45
  87. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
  88. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +21 -1
  89. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
  90. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
  91. package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
  92. package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
  93. package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
  94. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
  95. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
  96. package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
  97. package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
  98. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  99. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  100. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  101. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  102. package/package.json +11 -11
  103. package/scripts/cocoapods/utils.rb +1 -0
  104. package/scripts/react_native_pods.rb +1 -0
  105. package/scripts/replace-rncore-version.js +72 -15
  106. package/src/private/featureflags/ReactNativeFeatureFlags.js +26 -1
  107. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
  108. 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
- RCTRedBoxController *_controller;
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 && ![self->_controller presentedViewController]) {
644
- [self->_controller presentViewController:self->_extraDataViewController animated:YES completion:nil];
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 RCTRedBoxController *)redBoxController
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 RCTRedBoxController *)redBoxController
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