diff --git a/Libraries/BugReporting/BugReporting.js b/Libraries/BugReporting/BugReporting.js index bf795899139..277f16b45e1 100644 --- a/Libraries/BugReporting/BugReporting.js +++ b/Libraries/BugReporting/BugReporting.js @@ -35,7 +35,6 @@ class BugReporting { static _extraSources: Map = new Map(); static _fileSources: Map = new Map(); static _subscription: ?EmitterSubscription = null; - static _redboxSubscription: ?EmitterSubscription = null; static _maybeInit() { if (!BugReporting._subscription) { @@ -43,11 +42,6 @@ class BugReporting { .addListener('collectBugExtraData', BugReporting.collectExtraData, null); defaultExtras(); } - - if (!BugReporting._redboxSubscription) { - BugReporting._redboxSubscription = RCTDeviceEventEmitter - .addListener('collectRedBoxExtraData', BugReporting.collectExtraData, null); - } } /** @@ -104,11 +98,6 @@ class BugReporting { BugReportingNativeModule.setExtraData && BugReportingNativeModule.setExtraData(extraData, fileData); - const RedBoxNativeModule = require('NativeModules').RedBox; - RedBoxNativeModule && - RedBoxNativeModule.setExtraData && - RedBoxNativeModule.setExtraData(extraData, 'From BugReporting.js'); - return { extras: extraData, files: fileData }; } } diff --git a/React/Modules/RCTRedBox.m b/React/Modules/RCTRedBox.m index 71728640d1f..cb20776b966 100644 --- a/React/Modules/RCTRedBox.m +++ b/React/Modules/RCTRedBox.m @@ -13,9 +13,7 @@ #import "RCTConvert.h" #import "RCTDefines.h" #import "RCTErrorInfo.h" -#import "RCTEventDispatcher.h" #import "RCTJSStackFrame.h" -#import "RCTRedBoxExtraDataViewController.h" #import "RCTUtils.h" #if RCT_DEBUG @@ -26,7 +24,6 @@ - (void)redBoxWindow:(RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame; - (void)reloadFromRedBoxWindow:(RCTRedBoxWindow *)redBoxWindow; -- (void)loadExtraDataViewController; @end @@ -36,332 +33,308 @@ @implementation RCTRedBoxWindow { - UITableView *_stackTraceTableView; - NSString *_lastErrorMessage; - NSArray *_lastStackTrace; + UITableView *_stackTraceTableView; + NSString *_lastErrorMessage; + NSArray *_lastStackTrace; } - (instancetype)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { + if ((self = [super initWithFrame:frame])) { #if TARGET_OS_TV - self.windowLevel = UIWindowLevelAlert + 1000; + self.windowLevel = UIWindowLevelAlert + 1000; #else - self.windowLevel = UIWindowLevelStatusBar - 1; + self.windowLevel = UIWindowLevelStatusBar - 1; #endif - self.backgroundColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1]; - self.hidden = YES; + self.backgroundColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1]; + self.hidden = YES; - UIViewController *rootController = [UIViewController new]; - self.rootViewController = rootController; - UIView *rootView = rootController.view; - rootView.backgroundColor = [UIColor clearColor]; + UIViewController *rootController = [UIViewController new]; + self.rootViewController = rootController; + UIView *rootView = rootController.view; + rootView.backgroundColor = [UIColor clearColor]; - const CGFloat buttonHeight = 60; + const CGFloat buttonHeight = 60; - CGRect detailsFrame = rootView.bounds; - detailsFrame.size.height -= buttonHeight; + CGRect detailsFrame = rootView.bounds; + detailsFrame.size.height -= buttonHeight; - _stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain]; - _stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _stackTraceTableView.delegate = self; - _stackTraceTableView.dataSource = self; - _stackTraceTableView.backgroundColor = [UIColor clearColor]; + _stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain]; + _stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _stackTraceTableView.delegate = self; + _stackTraceTableView.dataSource = self; + _stackTraceTableView.backgroundColor = [UIColor clearColor]; #if !TARGET_OS_TV - _stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3]; - _stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3]; + _stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone; #endif - _stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - [rootView addSubview:_stackTraceTableView]; + _stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; + [rootView addSubview:_stackTraceTableView]; -#if TARGET_OS_SIMULATOR - NSString *reloadText = @"Reload JS (\u2318R)"; - NSString *dismissText = @"Dismiss (ESC)"; - NSString *copyText = @"Copy (\u2325\u2318C)"; - NSString *extraText = @"Extra Info (\u2318E)"; -#else - NSString *reloadText = @"Reload JS"; - NSString *dismissText = @"Dismiss"; - NSString *copyText = @"Copy"; - NSString *extraText = @"Extra Info"; -#endif + #if TARGET_OS_SIMULATOR + NSString *reloadText = @"Reload JS (\u2318R)"; + NSString *dismissText = @"Dismiss (ESC)"; + NSString *copyText = @"Copy (\u2325\u2318C)"; + #else + NSString *reloadText = @"Reload JS"; + NSString *dismissText = @"Dismiss"; + NSString *copyText = @"Copy"; + #endif - UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom]; - dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin; - dismissButton.accessibilityIdentifier = @"redbox-dismiss"; - dismissButton.titleLabel.font = [UIFont systemFontOfSize:13]; - [dismissButton setTitle:dismissText forState:UIControlStateNormal]; - [dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; - [dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - [dismissButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside]; + UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom]; + dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin; + dismissButton.accessibilityIdentifier = @"redbox-dismiss"; + dismissButton.titleLabel.font = [UIFont systemFontOfSize:14]; + [dismissButton setTitle:dismissText forState:UIControlStateNormal]; + [dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; + [dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + [dismissButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside]; - UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom]; - reloadButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin; - reloadButton.accessibilityIdentifier = @"redbox-reload"; - reloadButton.titleLabel.font = [UIFont systemFontOfSize:13]; + UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom]; + reloadButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin; + reloadButton.accessibilityIdentifier = @"redbox-reload"; + reloadButton.titleLabel.font = [UIFont systemFontOfSize:14]; - [reloadButton setTitle:reloadText forState:UIControlStateNormal]; - [reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; - [reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - [reloadButton addTarget:self action:@selector(reload) forControlEvents:UIControlEventTouchUpInside]; + [reloadButton setTitle:reloadText forState:UIControlStateNormal]; + [reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; + [reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + [reloadButton addTarget:self action:@selector(reload) forControlEvents:UIControlEventTouchUpInside]; - UIButton *copyButton = [UIButton buttonWithType:UIButtonTypeCustom]; - copyButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin; - copyButton.accessibilityIdentifier = @"redbox-copy"; - copyButton.titleLabel.font = [UIFont systemFontOfSize:13]; - [copyButton setTitle:copyText forState:UIControlStateNormal]; - [copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; - [copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - [copyButton addTarget:self action:@selector(copyStack) forControlEvents:UIControlEventTouchUpInside]; + UIButton *copyButton = [UIButton buttonWithType:UIButtonTypeCustom]; + copyButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin; + copyButton.accessibilityIdentifier = @"redbox-copy"; + copyButton.titleLabel.font = [UIFont systemFontOfSize:14]; + [copyButton setTitle:copyText forState:UIControlStateNormal]; + [copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; + [copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + [copyButton addTarget:self action:@selector(copyStack) forControlEvents:UIControlEventTouchUpInside]; - UIButton *extraButton = [UIButton buttonWithType:UIButtonTypeCustom]; - extraButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin; - extraButton.accessibilityIdentifier = @"redbox-extra"; - extraButton.titleLabel.font = [UIFont systemFontOfSize:13]; - [extraButton setTitle:extraText forState:UIControlStateNormal]; - [extraButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal]; - [extraButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - [extraButton addTarget:self action:@selector(showExtraDataViewController) forControlEvents:UIControlEventTouchUpInside]; - - CGFloat buttonWidth = self.bounds.size.width / 4; - dismissButton.frame = CGRectMake(0, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); - reloadButton.frame = CGRectMake(buttonWidth, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); - copyButton.frame = CGRectMake(buttonWidth * 2, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); - extraButton.frame = CGRectMake(buttonWidth * 3, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); - - [rootView addSubview:dismissButton]; - [rootView addSubview:reloadButton]; - [rootView addSubview:copyButton]; - [rootView addSubview:extraButton]; - } - return self; + CGFloat buttonWidth = self.bounds.size.width / 3; + dismissButton.frame = CGRectMake(0, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); + reloadButton.frame = CGRectMake(buttonWidth, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); + copyButton.frame = CGRectMake(buttonWidth * 2, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight); + [rootView addSubview:dismissButton]; + [rootView addSubview:reloadButton]; + [rootView addSubview:copyButton]; + } + return self; } RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) - (void)dealloc { - _stackTraceTableView.dataSource = nil; - _stackTraceTableView.delegate = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self]; + _stackTraceTableView.dataSource = nil; + _stackTraceTableView.delegate = nil; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack isUpdate:(BOOL)isUpdate { - // Show if this is a new message, or if we're updating the previous message - if ((self.hidden && !isUpdate) || (!self.hidden && isUpdate && [_lastErrorMessage isEqualToString:message])) { - _lastStackTrace = stack; - // message is displayed using UILabel, which is unable to render text of - // unlimited length, so we truncate it - _lastErrorMessage = [message substringToIndex:MIN((NSUInteger)10000, message.length)]; + // Show if this is a new message, or if we're updating the previous message + if ((self.hidden && !isUpdate) || (!self.hidden && isUpdate && [_lastErrorMessage isEqualToString:message])) { + _lastStackTrace = stack; + // message is displayed using UILabel, which is unable to render text of + // unlimited length, so we truncate it + _lastErrorMessage = [message substringToIndex:MIN((NSUInteger)10000, message.length)]; - [_stackTraceTableView reloadData]; + [_stackTraceTableView reloadData]; - if (self.hidden) { - [_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] - atScrollPosition:UITableViewScrollPositionTop - animated:NO]; - } - - [self makeKeyAndVisible]; - [self becomeFirstResponder]; + if (self.hidden) { + [_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] + atScrollPosition:UITableViewScrollPositionTop + animated:NO]; } + + [self makeKeyAndVisible]; + [self becomeFirstResponder]; + } } - (void)dismiss { - self.hidden = YES; - [self resignFirstResponder]; - [RCTSharedApplication().delegate.window makeKeyWindow]; + self.hidden = YES; + [self resignFirstResponder]; + [RCTSharedApplication().delegate.window makeKeyWindow]; } - (void)reload { - [_actionDelegate reloadFromRedBoxWindow:self]; -} - -- (void)showExtraDataViewController -{ - [_actionDelegate loadExtraDataViewController]; + [_actionDelegate reloadFromRedBoxWindow:self]; } - (void)copyStack { - NSMutableString *fullStackTrace; + NSMutableString *fullStackTrace; - if (_lastErrorMessage != nil) { - fullStackTrace = [_lastErrorMessage mutableCopy]; - [fullStackTrace appendString:@"\n\n"]; - } - else { - fullStackTrace = [NSMutableString string]; - } + if (_lastErrorMessage != nil) { + fullStackTrace = [_lastErrorMessage mutableCopy]; + [fullStackTrace appendString:@"\n\n"]; + } + else { + fullStackTrace = [NSMutableString string]; + } - for (RCTJSStackFrame *stackFrame in _lastStackTrace) { - [fullStackTrace appendString:[NSString stringWithFormat:@"%@\n", stackFrame.methodName]]; - if (stackFrame.file) { - [fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]]; - } + for (RCTJSStackFrame *stackFrame in _lastStackTrace) { + [fullStackTrace appendString:[NSString stringWithFormat:@"%@\n", stackFrame.methodName]]; + if (stackFrame.file) { + [fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]]; } + } #if !TARGET_OS_TV - UIPasteboard *pb = [UIPasteboard generalPasteboard]; - [pb setString:fullStackTrace]; + UIPasteboard *pb = [UIPasteboard generalPasteboard]; + [pb setString:fullStackTrace]; #endif } - (NSString *)formatFrameSource:(RCTJSStackFrame *)stackFrame { - NSString *fileName = RCTNilIfNull(stackFrame.file) ? [stackFrame.file lastPathComponent] : @""; - NSString *lineInfo = [NSString stringWithFormat:@"%@:%lld", - fileName, - (long long)stackFrame.lineNumber]; + NSString *fileName = RCTNilIfNull(stackFrame.file) ? [stackFrame.file lastPathComponent] : @""; + NSString *lineInfo = [NSString stringWithFormat:@"%@:%lld", + fileName, + (long long)stackFrame.lineNumber]; - if (stackFrame.column != 0) { - lineInfo = [lineInfo stringByAppendingFormat:@":%lld", (long long)stackFrame.column]; - } - return lineInfo; + if (stackFrame.column != 0) { + lineInfo = [lineInfo stringByAppendingFormat:@":%lld", (long long)stackFrame.column]; + } + return lineInfo; } #pragma mark - TableView - (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView { - return 2; + return 2; } - (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return section == 0 ? 1 : _lastStackTrace.count; + return section == 0 ? 1 : _lastStackTrace.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == 0) { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"]; - return [self reuseCell:cell forErrorMessage:_lastErrorMessage]; - } - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; - NSUInteger index = indexPath.row; - RCTJSStackFrame *stackFrame = _lastStackTrace[index]; - return [self reuseCell:cell forStackFrame:stackFrame]; + if (indexPath.section == 0) { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"]; + return [self reuseCell:cell forErrorMessage:_lastErrorMessage]; + } + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + NSUInteger index = indexPath.row; + RCTJSStackFrame *stackFrame = _lastStackTrace[index]; + return [self reuseCell:cell forStackFrame:stackFrame]; } - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message { - if (!cell) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"msg-cell"]; - cell.textLabel.accessibilityIdentifier = @"redbox-error"; - cell.textLabel.textColor = [UIColor whiteColor]; - cell.textLabel.font = [UIFont boldSystemFontOfSize:16]; - cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping; - cell.textLabel.numberOfLines = 0; - cell.detailTextLabel.textColor = [UIColor whiteColor]; - cell.backgroundColor = [UIColor clearColor]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; - } + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"msg-cell"]; + cell.textLabel.accessibilityIdentifier = @"redbox-error"; + cell.textLabel.textColor = [UIColor whiteColor]; + cell.textLabel.font = [UIFont boldSystemFontOfSize:16]; + cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping; + cell.textLabel.numberOfLines = 0; + cell.detailTextLabel.textColor = [UIColor whiteColor]; + cell.backgroundColor = [UIColor clearColor]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } - cell.textLabel.text = message; + cell.textLabel.text = message; - return cell; + return cell; } - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame { - if (!cell) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"]; - cell.textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9]; - cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14]; - cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping; - cell.textLabel.numberOfLines = 2; - cell.detailTextLabel.textColor = [UIColor colorWithWhite:1 alpha:0.7]; - cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11]; - cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - cell.backgroundColor = [UIColor clearColor]; - cell.selectedBackgroundView = [UIView new]; - cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2]; - } + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"]; + cell.textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9]; + cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14]; + cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping; + cell.textLabel.numberOfLines = 2; + cell.detailTextLabel.textColor = [UIColor colorWithWhite:1 alpha:0.7]; + cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11]; + cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + cell.backgroundColor = [UIColor clearColor]; + cell.selectedBackgroundView = [UIView new]; + cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2]; + } - cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)"; - if (stackFrame.file) { - cell.detailTextLabel.text = [self formatFrameSource:stackFrame]; - } else { - cell.detailTextLabel.text = @""; - } - return cell; + cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)"; + if (stackFrame.file) { + cell.detailTextLabel.text = [self formatFrameSource:stackFrame]; + } else { + cell.detailTextLabel.text = @""; + } + return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == 0) { - NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; + if (indexPath.section == 0) { + NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; - NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSParagraphStyleAttributeName: paragraphStyle}; - CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; - return ceil(boundingRect.size.height) + 40; - } else { - return 50; - } + NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:16], + NSParagraphStyleAttributeName: paragraphStyle}; + CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; + return ceil(boundingRect.size.height) + 40; + } else { + return 50; + } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == 1) { - NSUInteger row = indexPath.row; - RCTJSStackFrame *stackFrame = _lastStackTrace[row]; - [_actionDelegate redBoxWindow:self openStackFrameInEditor:stackFrame]; - } - [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == 1) { + NSUInteger row = indexPath.row; + RCTJSStackFrame *stackFrame = _lastStackTrace[row]; + [_actionDelegate redBoxWindow:self openStackFrameInEditor:stackFrame]; + } + [tableView deselectRowAtIndexPath:indexPath animated:YES]; } #pragma mark - Key commands - (NSArray *)keyCommands { - // NOTE: We could use RCTKeyCommands for this, but since - // we control this window, we can use the standard, non-hacky - // mechanism instead + // NOTE: We could use RCTKeyCommands for this, but since + // we control this window, we can use the standard, non-hacky + // mechanism instead - return @[ - // Dismiss red box - [UIKeyCommand keyCommandWithInput:UIKeyInputEscape - modifierFlags:0 - action:@selector(dismiss)], + return @[ + // Dismiss red box + [UIKeyCommand keyCommandWithInput:UIKeyInputEscape + modifierFlags:0 + action:@selector(dismiss)], - // Reload - [UIKeyCommand keyCommandWithInput:@"r" - modifierFlags:UIKeyModifierCommand - action:@selector(reload)], + // Reload + [UIKeyCommand keyCommandWithInput:@"r" + modifierFlags:UIKeyModifierCommand + action:@selector(reload)], - // Copy = Cmd-Option C since Cmd-C in the simulator copies the pasteboard from - // the simulator to the desktop pasteboard. - [UIKeyCommand keyCommandWithInput:@"c" - modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate - action:@selector(copyStack)], + // Copy = Cmd-Option C since Cmd-C in the simulator copies the pasteboard from + // the simulator to the desktop pasteboard. + [UIKeyCommand keyCommandWithInput:@"c" + modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate + action:@selector(copyStack)] - // Extra data - [UIKeyCommand keyCommandWithInput:@"e" - modifierFlags:UIKeyModifierCommand - action:@selector(showExtraDataViewController)] - ]; + ]; } - (BOOL)canBecomeFirstResponder { - return YES; + return YES; } @end -@interface RCTRedBox () +@interface RCTRedBox () @end @implementation RCTRedBox { - RCTRedBoxWindow *_window; - NSMutableArray> *_errorCustomizers; - RCTRedBoxExtraDataViewController *_extraDataViewController; + RCTRedBoxWindow *_window; + NSMutableArray> *_errorCustomizers; } @synthesize bridge = _bridge; @@ -370,165 +343,140 @@ RCT_EXPORT_MODULE() - (void)registerErrorCustomizer:(id)errorCustomizer { - dispatch_async(dispatch_get_main_queue(), ^{ - if (!self->_errorCustomizers) { - self->_errorCustomizers = [NSMutableArray array]; - } - if (![self->_errorCustomizers containsObject:errorCustomizer]) { - [self->_errorCustomizers addObject:errorCustomizer]; - } - }); + dispatch_async(dispatch_get_main_queue(), ^{ + if (!self->_errorCustomizers) { + self->_errorCustomizers = [NSMutableArray array]; + } + if (![self->_errorCustomizers containsObject:errorCustomizer]) { + [self->_errorCustomizers addObject:errorCustomizer]; + } + }); } // WARNING: Should only be called from the main thread/dispatch queue. - (RCTErrorInfo *)_customizeError:(RCTErrorInfo *)error { - RCTAssertMainQueue(); - if (!self->_errorCustomizers) { - return error; - } - for (id customizer in self->_errorCustomizers) { - RCTErrorInfo *newInfo = [customizer customizeErrorInfo:error]; - if (newInfo) { - error = newInfo; - } - } + RCTAssertMainQueue(); + + if (!self->_errorCustomizers) { return error; + } + for (id customizer in self->_errorCustomizers) { + RCTErrorInfo *newInfo = [customizer customizeErrorInfo:error]; + if (newInfo) { + error = newInfo; + } + } + return error; } - (void)showError:(NSError *)error { - [self showErrorMessage:error.localizedDescription - withDetails:error.localizedFailureReason - stack:error.userInfo[RCTJSStackTraceKey]]; + [self showErrorMessage:error.localizedDescription + withDetails:error.localizedFailureReason + stack:error.userInfo[RCTJSStackTraceKey]]; } - (void)showErrorMessage:(NSString *)message { - [self showErrorMessage:message withParsedStack:nil isUpdate:NO]; + [self showErrorMessage:message withParsedStack:nil isUpdate:NO]; } - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details { - [self showErrorMessage:message withDetails:details stack:nil]; + [self showErrorMessage:message withDetails:details stack:nil]; } - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details stack:(NSArray *)stack { - NSString *combinedMessage = message; - if (details) { - combinedMessage = [NSString stringWithFormat:@"%@\n\n%@", message, details]; - } - [self showErrorMessage:combinedMessage withParsedStack:stack isUpdate:NO]; + NSString *combinedMessage = message; + if (details) { + combinedMessage = [NSString stringWithFormat:@"%@\n\n%@", message, details]; + } + [self showErrorMessage:combinedMessage withParsedStack:stack isUpdate:NO]; } - (void)showErrorMessage:(NSString *)message withRawStack:(NSString *)rawStack { - NSArray *stack = [RCTJSStackFrame stackFramesWithLines:rawStack]; - [self showErrorMessage:message withParsedStack:stack isUpdate:NO]; + NSArray *stack = [RCTJSStackFrame stackFramesWithLines:rawStack]; + [self showErrorMessage:message withParsedStack:stack isUpdate:NO]; } - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack { - [self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:NO]; + [self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:NO]; } - (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack { - [self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:YES]; + [self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:YES]; } - (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack { - [self showErrorMessage:message withParsedStack:stack isUpdate:NO]; + [self showErrorMessage:message withParsedStack:stack isUpdate:NO]; } - (void)updateErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack { - [self showErrorMessage:message withParsedStack:stack isUpdate:YES]; + [self showErrorMessage:message withParsedStack:stack isUpdate:YES]; } - (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray *)stack isUpdate:(BOOL)isUpdate { - dispatch_async(dispatch_get_main_queue(), ^{ - if (self->_extraDataViewController == nil) { - self->_extraDataViewController = [RCTRedBoxExtraDataViewController new]; - self->_extraDataViewController.actionDelegate = self; - } - [self->_bridge.eventDispatcher sendDeviceEventWithName:@"collectRedBoxExtraData" body:nil]; - - if (!self->_window) { - self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - self->_window.actionDelegate = self; - } - - RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message - stack:stack]; - errorInfo = [self _customizeError:errorInfo]; - [self->_window showErrorMessage:errorInfo.errorMessage - withStack:errorInfo.stack - isUpdate:isUpdate]; - }); -} - -- (void)loadExtraDataViewController { - dispatch_async(dispatch_get_main_queue(), ^{ - // Make sure the CMD+E shortcut doesn't call this twice - if (self->_extraDataViewController != nil && ![self->_window.rootViewController presentedViewController]) { - [self->_window.rootViewController presentViewController:self->_extraDataViewController animated:YES completion:nil]; - } - }); -} - -RCT_EXPORT_METHOD(setExtraData:(NSDictionary *)extraData forIdentifier:(NSString *)identifier) { - [_extraDataViewController addExtraData:extraData forIdentifier:identifier]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (!self->_window) { + self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + self->_window.actionDelegate = self; + } + RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message + stack:stack]; + errorInfo = [self _customizeError:errorInfo]; + [self->_window showErrorMessage:errorInfo.errorMessage + withStack:errorInfo.stack + isUpdate:isUpdate]; + }); } RCT_EXPORT_METHOD(dismiss) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self->_window dismiss]; - }); + dispatch_async(dispatch_get_main_queue(), ^{ + [self->_window dismiss]; + }); } - (void)invalidate { - [self dismiss]; + [self dismiss]; } - (void)redBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame { - NSURL *const bundleURL = _overrideBundleURL ?: _bridge.bundleURL; - if (![bundleURL.scheme hasPrefix:@"http"]) { - RCTLogWarn(@"Cannot open stack frame in editor because you're not connected to the packager."); - return; - } + NSURL *const bundleURL = _overrideBundleURL ?: _bridge.bundleURL; + if (![bundleURL.scheme hasPrefix:@"http"]) { + RCTLogWarn(@"Cannot open stack frame in editor because you're not connected to the packager."); + return; + } - NSData *stackFrameJSON = [RCTJSONStringify([stackFrame toDictionary], NULL) dataUsingEncoding:NSUTF8StringEncoding]; - NSString *postLength = [NSString stringWithFormat:@"%tu", stackFrameJSON.length]; - NSMutableURLRequest *request = [NSMutableURLRequest new]; - request.URL = [NSURL URLWithString:@"/open-stack-frame" relativeToURL:bundleURL]; - request.HTTPMethod = @"POST"; - request.HTTPBody = stackFrameJSON; - [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; - [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + NSData *stackFrameJSON = [RCTJSONStringify([stackFrame toDictionary], NULL) dataUsingEncoding:NSUTF8StringEncoding]; + NSString *postLength = [NSString stringWithFormat:@"%tu", stackFrameJSON.length]; + NSMutableURLRequest *request = [NSMutableURLRequest new]; + request.URL = [NSURL URLWithString:@"/open-stack-frame" relativeToURL:bundleURL]; + request.HTTPMethod = @"POST"; + request.HTTPBody = stackFrameJSON; + [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - [[[NSURLSession sharedSession] dataTaskWithRequest:request] resume]; -} - -- (void)reload -{ - // Window is not used and can be nil - [self reloadFromRedBoxWindow:nil]; + [[[NSURLSession sharedSession] dataTaskWithRequest:request] resume]; } - (void)reloadFromRedBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow { - if (_overrideReloadAction) { - _overrideReloadAction(); - } else { - [_bridge reload]; - } - [self dismiss]; + if (_overrideReloadAction) { + _overrideReloadAction(); + } else { + [_bridge reload]; + } + [self dismiss]; } @end @@ -537,7 +485,7 @@ RCT_EXPORT_METHOD(dismiss) - (RCTRedBox *)redBox { - return [self moduleForClass:[RCTRedBox class]]; + return [self moduleForClass:[RCTRedBox class]]; } @end diff --git a/React/Modules/RCTRedBoxExtraDataViewController.h b/React/Modules/RCTRedBoxExtraDataViewController.h deleted file mode 100644 index 48454781447..00000000000 --- a/React/Modules/RCTRedBoxExtraDataViewController.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -@protocol RCTRedBoxExtraDataActionDelegate -- (void)reload; -@end - -@interface RCTRedBoxExtraDataViewController : UIViewController - -@property (nonatomic, weak) id actionDelegate; - -- (void)addExtraData:(NSDictionary *)data forIdentifier:(NSString *)identifier; - -@end diff --git a/React/Modules/RCTRedBoxExtraDataViewController.m b/React/Modules/RCTRedBoxExtraDataViewController.m deleted file mode 100644 index 63935106809..00000000000 --- a/React/Modules/RCTRedBoxExtraDataViewController.m +++ /dev/null @@ -1,288 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "RCTRedBoxExtraDataViewController.h" - -@interface RCTRedBoxExtraDataCell : UITableViewCell - -@property (nonatomic, strong) UILabel *keyLabel; -@property (nonatomic, strong) UILabel *valueLabel; - -@end - -@implementation RCTRedBoxExtraDataCell - -- (instancetype)initWithStyle:(UITableViewCellStyle)style - reuseIdentifier:(NSString *)reuseIdentifier -{ - if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { - self.backgroundColor = [UIColor colorWithRed:0.8 - green:0 blue:0 - alpha:1]; - UILayoutGuide *contentLayout = self.contentView.layoutMarginsGuide; - - self.keyLabel = [UILabel new]; - [self.contentView addSubview:self.keyLabel]; - - self.keyLabel.translatesAutoresizingMaskIntoConstraints = NO; - [self.keyLabel.leadingAnchor - constraintEqualToAnchor:contentLayout.leadingAnchor].active = YES; - [self.keyLabel.topAnchor - constraintEqualToAnchor:contentLayout.topAnchor].active = YES; - [self.keyLabel.bottomAnchor - constraintEqualToAnchor:contentLayout.bottomAnchor].active = YES; - [self.keyLabel.widthAnchor - constraintEqualToAnchor:contentLayout.widthAnchor - multiplier:0.3].active = YES; - - self.keyLabel.textColor = [UIColor whiteColor]; - self.keyLabel.numberOfLines = 0; - self.keyLabel.lineBreakMode = UILineBreakModeWordWrap; - self.keyLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f]; - - self.valueLabel = [UILabel new]; - [self.contentView addSubview:self.valueLabel]; - - self.valueLabel.translatesAutoresizingMaskIntoConstraints = NO; - [self.valueLabel.leadingAnchor - constraintEqualToAnchor:self.keyLabel.trailingAnchor - constant:10.f].active = YES; - [self.valueLabel.trailingAnchor - constraintEqualToAnchor:contentLayout.trailingAnchor].active = YES; - [self.valueLabel.topAnchor - constraintEqualToAnchor:contentLayout.topAnchor].active = YES; - [self.valueLabel.bottomAnchor - constraintEqualToAnchor:contentLayout.bottomAnchor].active = YES; - - self.valueLabel.textColor = [UIColor whiteColor]; - self.valueLabel.numberOfLines = 0; - self.valueLabel.lineBreakMode = UILineBreakModeWordWrap; - self.valueLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f]; - } - return self; -} - -@end - -@interface RCTRedBoxExtraDataViewController () - -@end - -@implementation RCTRedBoxExtraDataViewController -{ - UITableView *_tableView; - NSMutableArray *_extraDataTitle; - NSMutableArray *_extraData; -} - -@synthesize actionDelegate = _actionDelegate; - -- (instancetype)init -{ - if (self = [super init]) { - _extraData = [NSMutableArray new]; - _extraDataTitle = [NSMutableArray new]; - self.view.backgroundColor = [UIColor colorWithRed:0.8 - green:0 - blue:0 - alpha:1]; - - _tableView = [UITableView new]; - _tableView.delegate = self; - _tableView.dataSource = self; - _tableView.backgroundColor = [UIColor clearColor]; - _tableView.estimatedRowHeight = 200; - _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - _tableView.rowHeight = UITableViewAutomaticDimension; - _tableView.allowsSelection = NO; - -#if TARGET_OS_SIMULATOR - NSString *reloadText = @"Reload JS (\u2318R)"; - NSString *dismissText = @"Dismiss (ESC)"; -#else - NSString *reloadText = @"Reload JS"; - NSString *dismissText = @"Dismiss"; -#endif - - UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom]; - dismissButton.translatesAutoresizingMaskIntoConstraints = NO; - dismissButton.accessibilityIdentifier = @"redbox-extra-data-dismiss"; - dismissButton.titleLabel.font = [UIFont systemFontOfSize:13]; - [dismissButton setTitle:dismissText forState:UIControlStateNormal]; - [dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] - forState:UIControlStateNormal]; - [dismissButton setTitleColor:[UIColor whiteColor] - forState:UIControlStateHighlighted]; - [dismissButton addTarget:self - action:@selector(dismiss) - forControlEvents:UIControlEventTouchUpInside]; - - UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom]; - reloadButton.accessibilityIdentifier = @"redbox-reload"; - reloadButton.titleLabel.font = [UIFont systemFontOfSize:13]; - [reloadButton setTitle:reloadText forState:UIControlStateNormal]; - [reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] - forState:UIControlStateNormal]; - [reloadButton setTitleColor:[UIColor whiteColor] - forState:UIControlStateHighlighted]; - [reloadButton addTarget:self - action:@selector(reload) - forControlEvents:UIControlEventTouchUpInside]; - - UIStackView *buttonStackView = [UIStackView new]; - buttonStackView.axis = UILayoutConstraintAxisHorizontal; - buttonStackView.distribution = UIStackViewDistributionEqualSpacing; - buttonStackView.alignment = UIStackViewAlignmentFill; - buttonStackView.spacing = 20; - - [buttonStackView addArrangedSubview:dismissButton]; - [buttonStackView addArrangedSubview:reloadButton]; - buttonStackView.translatesAutoresizingMaskIntoConstraints = NO; - - UIStackView *mainStackView = [UIStackView new]; - mainStackView.axis = UILayoutConstraintAxisVertical; - mainStackView.backgroundColor = [UIColor colorWithRed:0.8 - green:0 blue:0 - alpha:1]; - [mainStackView addArrangedSubview:_tableView]; - [mainStackView addArrangedSubview:buttonStackView]; - mainStackView.translatesAutoresizingMaskIntoConstraints = NO; - - [self.view addSubview:mainStackView]; - - CGFloat tableHeight = self.view.bounds.size.height - 60.f; - [_tableView.heightAnchor constraintEqualToConstant:tableHeight].active = YES; - [_tableView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor].active = YES; - - CGFloat buttonWidth = self.view.bounds.size.width / 4; - [dismissButton.heightAnchor constraintEqualToConstant:60].active = YES; - [dismissButton.widthAnchor - constraintEqualToConstant:buttonWidth].active = YES; - [reloadButton.heightAnchor constraintEqualToConstant:60].active = YES; - [reloadButton.widthAnchor - constraintEqualToConstant:buttonWidth].active = YES; - } - return self; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - [_tableView reloadData]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [[_extraData objectAtIndex:section] count]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section -{ - return 40; -} - -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section -{ - UIView *view = [UIView new]; - view.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1]; - - UILabel *header = [UILabel new]; - [view addSubview:header]; - - header.translatesAutoresizingMaskIntoConstraints = NO; - [header.leadingAnchor - constraintEqualToAnchor:view.leadingAnchor constant:5].active = YES; - [header.trailingAnchor - constraintEqualToAnchor:view.trailingAnchor].active = YES; - [header.topAnchor - constraintEqualToAnchor:view.topAnchor].active = YES; - [header.bottomAnchor - constraintEqualToAnchor:view.bottomAnchor].active = YES; - - header.textColor = [UIColor whiteColor]; - header.font = [UIFont fontWithName:@"Menlo-Bold" size:14.0f]; - header.text = [_extraDataTitle[section] uppercaseString]; - - return view; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - static NSString *reuseIdentifier = @"RedBoxExtraData"; - - RCTRedBoxExtraDataCell *cell = - (RCTRedBoxExtraDataCell *)[tableView - dequeueReusableCellWithIdentifier:reuseIdentifier]; - - if (cell == nil) { - cell = [[RCTRedBoxExtraDataCell alloc] - initWithStyle:UITableViewCellStyleDefault - reuseIdentifier:reuseIdentifier]; - } - - NSArray *dataKVPair = _extraData[indexPath.section][indexPath.row]; - cell.keyLabel.text = dataKVPair[0]; - cell.valueLabel.text = dataKVPair[1]; - - return cell; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return _extraDataTitle.count; -} - -- (void)addExtraData:(NSDictionary *)data forIdentifier:(NSString *)identifier -{ - dispatch_async(dispatch_get_main_queue(), ^{ - NSMutableArray *newData = [NSMutableArray new]; - for (id key in data) { - [newData addObject:@[[NSString stringWithFormat:@"%@", key], - [NSString stringWithFormat:@"%@", [data objectForKey:key]]]]; - } - - NSInteger idx = [self->_extraDataTitle indexOfObject:identifier]; - if (idx == NSNotFound) { - [self->_extraDataTitle addObject:identifier]; - [self->_extraData addObject:newData]; - } else { - [self->_extraData replaceObjectAtIndex:idx withObject:newData]; - } - - [self->_tableView reloadData]; - }); -} - -- (void)dismiss -{ - [self dismissViewControllerAnimated:YES completion:nil]; -} - -- (void)reload -{ - [_actionDelegate reload]; -} - -#pragma mark - Key commands - -- (NSArray *)keyCommands -{ - return @[ - // Dismiss - [UIKeyCommand keyCommandWithInput:UIKeyInputEscape - modifierFlags:0 - action:@selector(dismiss)], - // Reload - [UIKeyCommand keyCommandWithInput:@"r" - modifierFlags:UIKeyModifierCommand - action:@selector(reload)] - ]; -} - -@end diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 784a92e6a6b..f67296a798c 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -1192,8 +1192,6 @@ EBF21BFE1FC499840052F4D5 /* InspectorInterfaces.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; }; EBF21BFF1FC4998E0052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; }; EBF21C001FC499A80052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; }; - FEFAAC9E1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */; }; - FEFAAC9F1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -2270,8 +2268,6 @@ EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInterfaces.cpp; sourceTree = ""; }; EBF21BDC1FC498900052F4D5 /* libjsinspector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjsinspector.a; sourceTree = BUILT_PRODUCTS_DIR; }; EBF21BFA1FC4989A0052F4D5 /* libjsinspector-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libjsinspector-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBoxExtraDataViewController.m; sourceTree = ""; }; - FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBoxExtraDataViewController.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2480,8 +2476,6 @@ 5960C1B41F0804A00066FD5B /* RCTLayoutAnimationGroup.m */, 13F17A831B8493E5007D4C75 /* RCTRedBox.h */, 13F17A841B8493E5007D4C75 /* RCTRedBox.m */, - FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */, - FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */, 000E6CE91AB0E97F000CDF4D /* RCTSourceCode.h */, 000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */, 13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */, @@ -3470,7 +3464,6 @@ 3D80DA591DF820620028D040 /* RCTTiming.h in Headers */, 3D80DA5A1DF820620028D040 /* RCTUIManager.h in Headers */, 3D80DA5B1DF820620028D040 /* RCTFPSGraph.h in Headers */, - FEFAAC9F1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.h in Headers */, 3D80DA5D1DF820620028D040 /* RCTMacros.h in Headers */, 3D80DA5E1DF820620028D040 /* RCTProfile.h in Headers */, 3D80DA5F1DF820620028D040 /* RCTActivityIndicatorView.h in Headers */, @@ -4417,7 +4410,6 @@ 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */, 59A7B9FE1E577DBF0068EDBF /* RCTRootContentView.m in Sources */, 13E067591A70F44B002CDEE1 /* UIView+React.m in Sources */, - FEFAAC9E1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.m in Sources */, 14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */, CF2731C11E7B8DE40044CA4F /* RCTDeviceInfo.m in Sources */, 3D7AA9C41E548CD5001955CF /* NSDataBigString.mm in Sources */, diff --git a/local-cli/__mocks__/fs.js b/local-cli/__mocks__/fs.js index 9726dbe385f..30f3ef5de09 100644 --- a/local-cli/__mocks__/fs.js +++ b/local-cli/__mocks__/fs.js @@ -347,9 +347,11 @@ fs.createWriteStream.mockImplementation(filePath => { const writeStream = new stream.Writable({ write(chunk, encoding, callback) { this.__chunks.push(chunk); - callback(); - }, - final(callback) { + /** + * We can't use `final` as that has been added to Node 8.x. + * For backwards compatibility and minimal code paths, + * we update the content of a file immediately + */ node[path.basename(filePath)] = this.__chunks.join(''); callback(); },