From 85aa69ad4bc45f0b0a6a8748fb7eef51e900a36f Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 12:21:09 -0500 Subject: [PATCH 001/143] fix: rename "mouseEnter" to "mouseOver" The "mouseEnter" event in browsers does not bubble, while "mouseOver" does. --- Libraries/Components/Touchable/TouchableOpacity.js | 2 +- Libraries/Components/Touchable/TouchableWithoutFeedback.js | 4 ++-- .../__tests__/__snapshots__/TouchableHighlight-test.js.snap | 2 +- Libraries/Components/View/ReactNativeViewAttributes.js | 2 +- Libraries/Components/View/ViewPropTypes.js | 2 +- RNTester/js/DragnDropExample.macos.js | 2 +- React/Base/RCTTouchHandler.m | 6 +++--- React/Views/RCTViewManager.m | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 7470099842..45b263d0d3 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -259,7 +259,7 @@ var TouchableOpacity = createReactClass({ onResponderMove={this.touchableHandleResponderMove} onResponderRelease={this.touchableHandleResponderRelease} onResponderTerminate={this.touchableHandleResponderTerminate} - onMouseEnter={this.props.onMouseEnter} + onMouseOver={this.props.onMouseOver} onMouseLeave={this.props.onMouseLeave} onContextMenuItemClick={this.props.onContextMenuItemClick} contextMenu={this.props.contextMenu}> diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index b55f63eb42..53050254fc 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -110,7 +110,7 @@ const TouchableWithoutFeedback = createReactClass({ * views. */ hitSlop: EdgeInsetsPropType, - onMouseEnter: PropTypes.func, + onMouseOver: PropTypes.func, onMouseLeave: PropTypes.func, onContextMenuItemClick: PropTypes.func, contextMenu: PropTypes.array, @@ -213,7 +213,7 @@ const TouchableWithoutFeedback = createReactClass({ onResponderMove: this.touchableHandleResponderMove, onResponderRelease: this.touchableHandleResponderRelease, onResponderTerminate: this.touchableHandleResponderTerminate, - onMouseEnter: this.props.onMouseEnter, + onMouseOver: this.props.onMouseOver, onMouseLeave: this.props.onMouseLeave, onContextMenuItemClick: this.props.onContextMenuItemClick, contextMenu: this.props.contextMenu, diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap index 091bc6e748..ad62ff6d41 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap @@ -11,7 +11,7 @@ exports[`TouchableHighlight renders correctly 1`] = ` isTVSelectable={true} nativeID={undefined} onLayout={undefined} - onMouseEnter={undefined} + onMouseOver={undefined} onMouseLeave={undefined} onResponderGrant={[Function]} onResponderMove={[Function]} diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 2648ff966b..8e7a8f13bd 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -30,7 +30,7 @@ ReactNativeViewAttributes.UIView = { renderToHardwareTextureAndroid: true, shouldRasterizeIOS: true, onLayout: true, - onMouseEnter: true, + onMouseOver: true, onMouseLeave: true, onAccessibilityTap: true, onMagicTap: true, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index d9771b890a..1370dfdf80 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -433,7 +433,7 @@ module.exports = { * Desktop specific events * @platform macos */ - onMouseEnter: PropTypes.func, + onMouseOver: PropTypes.func, onMouseLeave: PropTypes.func, onDragEnter: PropTypes.func, onDragLeave: PropTypes.func, diff --git a/RNTester/js/DragnDropExample.macos.js b/RNTester/js/DragnDropExample.macos.js index 43eab54820..f6564f9a11 100644 --- a/RNTester/js/DragnDropExample.macos.js +++ b/RNTester/js/DragnDropExample.macos.js @@ -41,7 +41,7 @@ class DragExample extends React.Component { this.state.mouseOver ? 'orange' : 'white', padding: 40, alignItems: 'center'}} draggedTypes={['NSFilenamesPboardType']} - onMouseEnter={() => this.setState({mouseOver: true})} + onMouseOver={() => this.setState({mouseOver: true})} onMouseLeave={() => this.setState({mouseOver: false})} onDragEnter={() => this.setState({dragOver: true})} onDragLeave={() => this.setState({dragOver: false})} diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index 412eda07b1..4b82a4261b 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -47,7 +47,7 @@ @implementation RCTTouchHandler CFTimeInterval _mostRecentEnqueueJS; /* - * Storing tag to dispatch mouseEnter and mouseLeave events + * Storing tag to dispatch mouseOver and mouseLeave events */ NSNumber *_currentMouseOverTag; } @@ -338,11 +338,11 @@ - (void)mouseMoved:(NSEvent *)event [_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent" args:@[_currentMouseOverTag, @"topMouseLeave"]]; [_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent" - args:@[reactTag, @"topMouseEnter"]]; + args:@[reactTag, @"topMouseOver"]]; _currentMouseOverTag = reactTag; } else if (_currentMouseOverTag == 0) { [_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent" - args:@[reactTag, @"topMouseEnter"]]; + args:@[reactTag, @"topMouseOver"]]; _currentMouseOverTag = reactTag; } } diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index d95ab58749..fc9a922337 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -73,7 +73,7 @@ - (RCTShadowView *)shadowView @"touchEnd", // Mouse events - @"mouseEnter", + @"mouseOver", @"mouseLeave", ]; } From 024d4bda4f312e0e77c461510fd67114370729ee Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 12:21:37 -0500 Subject: [PATCH 002/143] fix: rename "mouseLeave" to "mouseOut" The "mouseLeave" event in browsers does not bubble, while "mouseOut" does. --- Libraries/Components/Touchable/TouchableOpacity.js | 2 +- Libraries/Components/Touchable/TouchableWithoutFeedback.js | 4 ++-- .../__tests__/__snapshots__/TouchableHighlight-test.js.snap | 2 +- Libraries/Components/View/ReactNativeViewAttributes.js | 2 +- Libraries/Components/View/ViewPropTypes.js | 2 +- RNTester/js/DragnDropExample.macos.js | 2 +- React/Base/RCTTouchHandler.m | 4 ++-- React/Views/RCTViewManager.m | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 45b263d0d3..8b09f39324 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -260,7 +260,7 @@ var TouchableOpacity = createReactClass({ onResponderRelease={this.touchableHandleResponderRelease} onResponderTerminate={this.touchableHandleResponderTerminate} onMouseOver={this.props.onMouseOver} - onMouseLeave={this.props.onMouseLeave} + onMouseOut={this.props.onMouseOut} onContextMenuItemClick={this.props.onContextMenuItemClick} contextMenu={this.props.contextMenu}> {this.props.children} diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index 53050254fc..d9250db14b 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -111,7 +111,7 @@ const TouchableWithoutFeedback = createReactClass({ */ hitSlop: EdgeInsetsPropType, onMouseOver: PropTypes.func, - onMouseLeave: PropTypes.func, + onMouseOut: PropTypes.func, onContextMenuItemClick: PropTypes.func, contextMenu: PropTypes.array, }, @@ -214,7 +214,7 @@ const TouchableWithoutFeedback = createReactClass({ onResponderRelease: this.touchableHandleResponderRelease, onResponderTerminate: this.touchableHandleResponderTerminate, onMouseOver: this.props.onMouseOver, - onMouseLeave: this.props.onMouseLeave, + onMouseOut: this.props.onMouseOut, onContextMenuItemClick: this.props.onContextMenuItemClick, contextMenu: this.props.contextMenu, style, diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap index ad62ff6d41..07852b5d88 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap @@ -12,7 +12,7 @@ exports[`TouchableHighlight renders correctly 1`] = ` nativeID={undefined} onLayout={undefined} onMouseOver={undefined} - onMouseLeave={undefined} + onMouseOut={undefined} onResponderGrant={[Function]} onResponderMove={[Function]} onResponderRelease={[Function]} diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 8e7a8f13bd..8f26351dac 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -31,7 +31,7 @@ ReactNativeViewAttributes.UIView = { shouldRasterizeIOS: true, onLayout: true, onMouseOver: true, - onMouseLeave: true, + onMouseOut: true, onAccessibilityTap: true, onMagicTap: true, collapsable: true, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index 1370dfdf80..c171402b52 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -434,7 +434,7 @@ module.exports = { * @platform macos */ onMouseOver: PropTypes.func, - onMouseLeave: PropTypes.func, + onMouseOut: PropTypes.func, onDragEnter: PropTypes.func, onDragLeave: PropTypes.func, onDrop: PropTypes.func, diff --git a/RNTester/js/DragnDropExample.macos.js b/RNTester/js/DragnDropExample.macos.js index f6564f9a11..221960f6bc 100644 --- a/RNTester/js/DragnDropExample.macos.js +++ b/RNTester/js/DragnDropExample.macos.js @@ -42,7 +42,7 @@ class DragExample extends React.Component { padding: 40, alignItems: 'center'}} draggedTypes={['NSFilenamesPboardType']} onMouseOver={() => this.setState({mouseOver: true})} - onMouseLeave={() => this.setState({mouseOver: false})} + onMouseOut={() => this.setState({mouseOver: false})} onDragEnter={() => this.setState({dragOver: true})} onDragLeave={() => this.setState({dragOver: false})} onDrop={(e) => this.setState({files: e.nativeEvent.files, dragOver: false})}> diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index 4b82a4261b..6ce83514ce 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -47,7 +47,7 @@ @implementation RCTTouchHandler CFTimeInterval _mostRecentEnqueueJS; /* - * Storing tag to dispatch mouseOver and mouseLeave events + * Storing tag to dispatch mouseOver and mouseOut events */ NSNumber *_currentMouseOverTag; } @@ -336,7 +336,7 @@ - (void)mouseMoved:(NSEvent *)event } if (_currentMouseOverTag != reactTag && _currentMouseOverTag.intValue > 0) { [_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent" - args:@[_currentMouseOverTag, @"topMouseLeave"]]; + args:@[_currentMouseOverTag, @"topMouseOut"]]; [_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent" args:@[reactTag, @"topMouseOver"]]; _currentMouseOverTag = reactTag; diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index fc9a922337..94fa320177 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -74,7 +74,7 @@ - (RCTShadowView *)shadowView // Mouse events @"mouseOver", - @"mouseLeave", + @"mouseOut", ]; } From 92c33f5f2581b9b44bbc02c9eb53010201d9709f Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 12:37:23 -0500 Subject: [PATCH 003/143] feat: add RCTWindow By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling. The RCTWindow class reimplements input event handling, which solves the following issues: - Skip "touchStart" events that target a focused NSTextView - Emit "mouseOut" event when the mouse leaves the RCTWindow - Emit "touchCancel" when the mouse leaves the RCTWindow - Support "mouseMove" events (which can be coalesced) - Emit "mouseMove" event right after "mouseUp" events - Blur the focused NSTextView when clicking outside it - Support "contextMenu" events - Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events - Use "convertPoint:toView:" to compute the relative mouse location --- React/Base/RCTMouseEvent.h | 23 +++ React/Base/RCTMouseEvent.m | 78 ++++++++ React/Base/RCTRootContentView.m | 20 +- React/React.xcodeproj/project.pbxproj | 20 ++ React/Views/NSView+React.h | 2 + React/Views/NSView+React.m | 11 ++ React/Views/RCTViewManager.m | 2 + React/Views/RCTWindow.h | 24 +++ React/Views/RCTWindow.m | 273 ++++++++++++++++++++++++++ 9 files changed, 451 insertions(+), 2 deletions(-) create mode 100644 React/Base/RCTMouseEvent.h create mode 100644 React/Base/RCTMouseEvent.m create mode 100644 React/Views/RCTWindow.h create mode 100644 React/Views/RCTWindow.m diff --git a/React/Base/RCTMouseEvent.h b/React/Base/RCTMouseEvent.h new file mode 100644 index 0000000000..2023d096c4 --- /dev/null +++ b/React/Base/RCTMouseEvent.h @@ -0,0 +1,23 @@ +/** + * 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 + +#import + +@interface RCTMouseEvent : NSObject + +- (instancetype)initWithEventName:(NSString *)eventName + target:(NSNumber *)target + userInfo:(NSDictionary *)userInfo + coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER; + +@property (readonly) NSTimeInterval timestamp; + +@end diff --git a/React/Base/RCTMouseEvent.m b/React/Base/RCTMouseEvent.m new file mode 100644 index 0000000000..4686f55fdb --- /dev/null +++ b/React/Base/RCTMouseEvent.m @@ -0,0 +1,78 @@ +/** + * 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 "RCTMouseEvent.h" + +#import "RCTAssert.h" + +@implementation RCTMouseEvent +{ + NSDictionary *_userInfo; + uint16_t _coalescingKey; +} + +@synthesize eventName = _eventName; +@synthesize viewTag = _viewTag; + +- (instancetype)initWithEventName:(NSString *)eventName + target:(NSNumber *)target + userInfo:(NSDictionary *)userInfo + coalescingKey:(uint16_t)coalescingKey +{ + if (self = [super init]) { + _viewTag = target; + _userInfo = userInfo; + _eventName = eventName; + _coalescingKey = coalescingKey; + } + return self; +} + +RCT_NOT_IMPLEMENTED(- (instancetype)init) + +#pragma mark - RCTEvent + +- (BOOL)canCoalesce +{ + return [_eventName isEqual:@"mouseMove"]; +} + +// We coalesce only move events, while holding some assumptions that seem reasonable but there are no explicit guarantees about them. +- (id)coalesceWithEvent:(id)newEvent +{ + RCTAssert([newEvent isKindOfClass:[RCTMouseEvent class]], @"Mouse event cannot be coalesced with any other type of event, such as provided %@", newEvent); + return ((RCTMouseEvent *)newEvent).timestamp > self.timestamp ? newEvent : self; +} + ++ (NSString *)moduleDotMethod +{ + return @"RCTEventEmitter.receiveEvent"; +} + +- (NSArray *)arguments +{ + return @[_viewTag, RCTNormalizeInputEventName(_eventName), _userInfo]; +} + +- (uint16_t)coalescingKey +{ + return _coalescingKey; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p; name = %@; coalescing key = %hu>", [self class], self, _eventName, _coalescingKey]; +} + +- (NSTimeInterval)timestamp +{ + return [_userInfo[@"timestamp"] doubleValue]; +} + +@end diff --git a/React/Base/RCTRootContentView.m b/React/Base/RCTRootContentView.m index 06f17326cf..393318e369 100644 --- a/React/Base/RCTRootContentView.m +++ b/React/Base/RCTRootContentView.m @@ -15,6 +15,7 @@ #import "RCTRootViewInternal.h" #import "RCTTouchHandler.h" #import "RCTUIManager.h" +#import "RCTWindow.h" #import "NSView+React.h" @implementation RCTRootContentView @@ -28,8 +29,6 @@ - (instancetype)initWithFrame:(CGRect)frame _bridge = bridge; self.reactTag = reactTag; _sizeFlexibility = sizeFlexibility; - _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; - [_touchHandler attachToView:self]; [_bridge.uiManager registerRootView:self]; } return self; @@ -108,4 +107,21 @@ - (void)invalidate //} } +- (void)viewDidMoveToWindow +{ + if (self.window == nil) { + return; + } + // RCTWindow handles all touches within + if ([self.window isKindOfClass:RCTWindow.class] == NO) { + if (_touchHandler == nil) { + _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; + [_touchHandler attachToView:self]; + } + } else if (_touchHandler) { + [_touchHandler detachFromView:self]; + _touchHandler = nil; + } +} + @end diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 20c44d446b..c2e9ac24ab 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -1038,6 +1038,12 @@ 66CD94B71F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94B01F1045E700CB3C7C /* RCTMaskedViewManager.m */; }; 66CD94B81F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94B01F1045E700CB3C7C /* RCTMaskedViewManager.m */; }; 68EFE4EE1CF6EB3900A1DE13 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; }; + 702B7FF8221C88AF0027174A /* RCTWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; + 702B7FF9221C88AF0027174A /* RCTWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 702B7FF7221C88AF0027174A /* RCTWindow.m */; }; + 702B7FFC221C88BB0027174A /* RCTMouseEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */; }; + 702B7FFD221C88BB0027174A /* RCTMouseEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */; }; + 702B7FFE221C88CE0027174A /* RCTMouseEvent.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */; }; + 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; 830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; }; 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; }; 83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8B1B62640A00BE0E65 /* RCTModalHostView.m */; }; @@ -1469,6 +1475,8 @@ dstPath = include/React; dstSubfolderSpec = 16; files = ( + 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */, + 702B7FFE221C88CE0027174A /* RCTMouseEvent.h in Copy Headers */, D4EEE3542020933B00C4CBB6 /* UIImageUtils.h in Copy Headers */, 59EDBCBD1FDF4E43003573DE /* RCTScrollableProtocol.h in Copy Headers */, 59EDBCBE1FDF4E43003573DE /* RCTScrollContentShadowView.h in Copy Headers */, @@ -2064,6 +2072,10 @@ 68EFE4EC1CF6EB3000A1DE13 /* RCTBundleURLProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBundleURLProvider.h; sourceTree = ""; }; 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBundleURLProvider.m; sourceTree = ""; }; 6A15FB0C1BDF663500531DFB /* RCTRootViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootViewInternal.h; sourceTree = ""; }; + 702B7FF6221C88AF0027174A /* RCTWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWindow.h; sourceTree = ""; }; + 702B7FF7221C88AF0027174A /* RCTWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWindow.m; sourceTree = ""; }; + 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMouseEvent.h; sourceTree = ""; }; + 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMouseEvent.m; sourceTree = ""; }; 830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; }; 830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; }; 830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; }; @@ -2445,6 +2457,8 @@ 13C156021AB1A2840079392D /* RCTWebView.m */, 13C156031AB1A2840079392D /* RCTWebViewManager.h */, 13C156041AB1A2840079392D /* RCTWebViewManager.m */, + 702B7FF6221C88AF0027174A /* RCTWindow.h */, + 702B7FF7221C88AF0027174A /* RCTWindow.m */, 59D031E41F8353D3008361F0 /* SafeAreaView */, 59EDBC9B1FDF4E0C003573DE /* ScrollView */, 83F15A171B7CC46900F10295 /* NSView+Private.h */, @@ -2768,6 +2782,8 @@ 14C2CA731B3AC64300E6CBB2 /* RCTModuleData.mm */, 14C2CA6F1B3AC63800E6CBB2 /* RCTModuleMethod.h */, C606692D1F3CC60500E67165 /* RCTModuleMethod.mm */, + 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */, + 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */, 006FC4121D9B20820057AAAD /* RCTMultipartDataTask.h */, 006FC4131D9B20820057AAAD /* RCTMultipartDataTask.m */, 001BFCCE1D8381DE008E587E /* RCTMultipartStreamReader.h */, @@ -3212,6 +3228,7 @@ 3D80DA221DF820620028D040 /* RCTBridge+Private.h in Headers */, 599FAA461FB274980058CCF6 /* RCTSurfaceStage.h in Headers */, 599FAA361FB274980058CCF6 /* RCTSurface.h in Headers */, + 702B7FFC221C88BB0027174A /* RCTMouseEvent.h in Headers */, 3D80DA231DF820620028D040 /* RCTBridgeDelegate.h in Headers */, 3D80DA241DF820620028D040 /* RCTBridgeMethod.h in Headers */, 3D7BFD151EA8E351008DFB7A /* RCTPackagerClient.h in Headers */, @@ -3323,6 +3340,7 @@ 3DF1BE831F26576400068F1A /* JSCTracing.h in Headers */, 3D80DA721DF820620028D040 /* RCTModalHostViewManager.h in Headers */, 13134C9C1E296B2A00B9F3CB /* RCTCxxModule.h in Headers */, + 702B7FF8221C88AF0027174A /* RCTWindow.h in Headers */, 594F0A321FD23228007FBE96 /* RCTSurfaceHostingView.h in Headers */, 3D80DA771DF820620028D040 /* RCTPicker.h in Headers */, 3D80DA781DF820620028D040 /* RCTPickerManager.h in Headers */, @@ -4142,6 +4160,7 @@ 001BFCD01D8381DE008E587E /* RCTMultipartStreamReader.m in Sources */, 133CAE8E1B8E5CFD00F6AD92 /* RCTDatePicker.m in Sources */, 14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */, + 702B7FF9221C88AF0027174A /* RCTWindow.m in Sources */, D49593E6202C96FF00A7694B /* YGNode.cpp in Sources */, 594F0A341FD23228007FBE96 /* RCTSurfaceHostingView.mm in Sources */, 13134C861E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */, @@ -4255,6 +4274,7 @@ 135A9BFC1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm in Sources */, 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */, 83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */, + 702B7FFD221C88BB0027174A /* RCTMouseEvent.m in Sources */, 83A1FE8F1B62643A00BE0E65 /* RCTModalHostViewManager.m in Sources */, 13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */, 1384E2091E806D4E00545659 /* RCTNativeModule.mm in Sources */, diff --git a/React/Views/NSView+React.h b/React/Views/NSView+React.h index 3fee72d909..2559b5909a 100644 --- a/React/Views/NSView+React.h +++ b/React/Views/NSView+React.h @@ -114,4 +114,6 @@ */ @property (nonatomic, assign) BOOL clipsToBounds; +- (NSView *)reactHitTest:(NSPoint)point; + @end diff --git a/React/Views/NSView+React.m b/React/Views/NSView+React.m index 382e3f3afe..149ecb65c6 100644 --- a/React/Views/NSView+React.m +++ b/React/Views/NSView+React.m @@ -295,4 +295,15 @@ - (NSView *)reactAccessibilityElement return self; } +#pragma mark - Interaction + +- (NSView *)reactHitTest:(NSPoint)point +{ + NSView *view = [self hitTest:point]; + while (view && !view.reactTag) { + view = view.superview; + } + return view; +} + @end diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 94fa320177..fb08b2c267 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -73,8 +73,10 @@ - (RCTShadowView *)shadowView @"touchEnd", // Mouse events + @"mouseMove", @"mouseOver", @"mouseOut", + @"contextMenu", ]; } diff --git a/React/Views/RCTWindow.h b/React/Views/RCTWindow.h new file mode 100644 index 0000000000..71ac4f0a48 --- /dev/null +++ b/React/Views/RCTWindow.h @@ -0,0 +1,24 @@ +/** + * 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 + +#import "RCTBridge.h" +#import "RCTRootView.h" + +@interface RCTWindow : NSWindow + +- (instancetype)initWithBridge:(RCTBridge *)bridge + contentRect:(NSRect)contentRect + styleMask:(NSWindowStyleMask)style + defer:(BOOL)defer NS_DESIGNATED_INITIALIZER; + +@property (nullable, strong) RCTRootView *contentView; + +@end diff --git a/React/Views/RCTWindow.m b/React/Views/RCTWindow.m new file mode 100644 index 0000000000..fd17aa7e93 --- /dev/null +++ b/React/Views/RCTWindow.m @@ -0,0 +1,273 @@ +/** + * 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 "RCTWindow.h" + +#import "RCTMouseEvent.h" +#import "RCTTouchEvent.h" +#import "NSView+React.h" + +@implementation RCTWindow +{ + RCTBridge *_bridge; + + NSMutableDictionary *_mouseInfo; + NSView *_hoveredView; + NSView *_clickedView; + NSEventType _clickType; + uint16_t _coalescingKey; + + BOOL _inContentView; + BOOL _enabled; +} + +RCT_NOT_IMPLEMENTED(- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag) + +- (instancetype)initWithBridge:(RCTBridge *)bridge + contentRect:(NSRect)contentRect + styleMask:(NSWindowStyleMask)style + defer:(BOOL)defer +{ + self = [super initWithContentRect:contentRect + styleMask:style + backing:NSBackingStoreBuffered + defer:defer]; + + if (self) { + _bridge = bridge; + + _mouseInfo = [NSMutableDictionary new]; + _mouseInfo[@"changedTouches"] = @[]; // Required for "mouseMove" events + _mouseInfo[@"identifier"] = @0; // Required for "touch*" events + + // The owner must set "contentView" manually. + super.contentView = nil; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_javaScriptDidLoad:) + name:RCTJavaScriptDidLoadNotification + object:bridge]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_bridgeWillReload:) + name:RCTBridgeWillReloadNotification + object:bridge]; + } + + return self; +} + +@dynamic contentView; + +- (void)sendEvent:(NSEvent *)event +{ + [super sendEvent:event]; + + // Avoid sending JS events too early. + if (_enabled == NO) { + return; + } + + NSEventType type = event.type; + + if (type == NSEventTypeMouseEntered) { + if (event.trackingArea.owner == self.contentView) { + _inContentView = YES; + } + return; + } + + if (type == NSEventTypeMouseExited) { + if (event.trackingArea.owner == self.contentView) { + _inContentView = NO; + + if (_clickedView) { + if (_clickType == NSEventTypeLeftMouseDown) { + [self _sendTouchEvent:@"touchCancel"]; + } + _clickedView = nil; + _clickType = 0; + } + + [self _setHoveredView:nil]; + } + return; + } + + if (type != NSEventTypeMouseMoved && + type != NSEventTypeLeftMouseDragged && + type != NSEventTypeLeftMouseUp && + type != NSEventTypeLeftMouseDown && + type != NSEventTypeRightMouseUp && + type != NSEventTypeRightMouseDown) { + return; + } + + NSView *targetView = [self.contentView reactHitTest:event.locationInWindow]; + [self _readMouseEvent:event withTarget:targetView]; + + if (_clickedView) { + if (type == NSEventTypeLeftMouseDragged) { + if (_clickType == NSEventTypeLeftMouseDown) { + [self _sendTouchEvent:@"touchMove"]; + } + return; + } + } else { + if (type == NSEventTypeMouseMoved) { + if (_inContentView == NO) { + return; // Ignore "mouseMove" events outside the "contentView" + } + + [self _setHoveredView:targetView]; + return; + } + + if (targetView == nil) { + return; + } + + if (type == NSEventTypeLeftMouseDown || type == NSEventTypeRightMouseDown) { + // When the "firstResponder" is a NSTextView, "mouseUp" and "mouseDragged" events are swallowed, + // so we should skip tracking of "mouseDown" events in order to avoid corrupted state. + if ([self.firstResponder isKindOfClass:NSTextView.class]) { + NSView *clickedView = [self.contentView hitTest:event.locationInWindow]; + NSView *fieldEditor = (NSView *)self.firstResponder; + if ([clickedView isDescendantOf:fieldEditor]) { + return; + } + + // Blur the field editor when clicking outside it. + [self makeFirstResponder:nil]; + } + + if (type == NSEventTypeLeftMouseDown) { + [self _sendTouchEvent:@"touchStart"]; + } + + _clickedView = targetView; + _clickType = type; + return; + } + } + + if (type == NSEventTypeLeftMouseUp) { + if (_clickType == NSEventTypeLeftMouseDown) { + [self _sendTouchEvent:@"touchEnd"]; + _clickedView = nil; + _clickType = 0; + } + + // Update the "hoveredView" now, instead of waiting for the next "mouseMove" event. + [self _setHoveredView:targetView]; + return; + } + + if (type == NSEventTypeRightMouseUp) { + if (_clickType == NSEventTypeRightMouseDown) { + // Right clicks must end in the same React "ancestor chain" they started in. + if ([_clickedView isDescendantOf:targetView]) { + [self _sendMouseEvent:@"contextMenu"]; + } + _clickedView = nil; + _clickType = 0; + } + + // Update the "hoveredView" now, instead of waiting for the next "mouseMove" event. + [self _setHoveredView:targetView]; + return; + } +} + +#pragma mark - Private methods + +static inline BOOL hasFlag(NSUInteger flags, NSUInteger flag) { + return (flags & flag) == flag; +} + +- (void)_readMouseEvent:(NSEvent *)event withTarget:(NSView *)view +{ + CGPoint absoluteLocation = event.locationInWindow; + CGPoint relativeLocation = [self.contentView convertPoint:absoluteLocation toView:view]; + + _mouseInfo[@"pageX"] = @(RCTSanitizeNaNValue(absoluteLocation.x, @"touchData.pageX")); + _mouseInfo[@"pageY"] = @(RCTSanitizeNaNValue(absoluteLocation.y, @"touchData.pageY")); + _mouseInfo[@"locationX"] = @(RCTSanitizeNaNValue(relativeLocation.x, @"touchData.locationX")); + _mouseInfo[@"locationY"] = @(RCTSanitizeNaNValue(relativeLocation.x, @"touchData.locationY")); + _mouseInfo[@"timestamp"] = @(event.timestamp * 1000); // in ms, for JS + _mouseInfo[@"target"] = view.reactTag; + + NSUInteger flags = event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask; + _mouseInfo[@"altKey"] = @(hasFlag(flags, NSEventModifierFlagOption)); + _mouseInfo[@"ctrlKey"] = @(hasFlag(flags, NSEventModifierFlagControl)); + _mouseInfo[@"metaKey"] = @(hasFlag(flags, NSEventModifierFlagCommand)); + _mouseInfo[@"shiftKey"] = @(hasFlag(flags, NSEventModifierFlagShift)); +} + +- (void)_setHoveredView:(NSView *)view +{ + if (_hoveredView && !(view && view == _hoveredView)) { + _mouseInfo[@"target"] = _hoveredView.reactTag; + _hoveredView = nil; + + [self _sendMouseEvent:@"mouseOut"]; + } + + if (view) { + _mouseInfo[@"target"] = view.reactTag; + + if (_hoveredView == nil) { + _hoveredView = view; + [self _sendMouseEvent:@"mouseOver"]; + } + + [self _sendMouseEvent:@"mouseMove"]; + } +} + +- (void)_sendMouseEvent:(NSString *)eventName +{ + RCTMouseEvent *event = [[RCTMouseEvent alloc] initWithEventName:eventName + target:_mouseInfo[@"target"] + userInfo:_mouseInfo + coalescingKey:_coalescingKey]; + + if (![eventName isEqualToString:@"mouseMove"]) { + _coalescingKey++; + } + + [_bridge.eventDispatcher sendEvent:event]; +} + +- (void)_sendTouchEvent:(NSString *)eventName +{ + RCTTouchEvent *event = [[RCTTouchEvent alloc] initWithEventName:eventName + reactTag:self.contentView.reactTag + reactTouches:@[_mouseInfo] + changedIndexes:@[@0] + coalescingKey:_coalescingKey]; + + if (![eventName isEqualToString:@"touchMove"]) { + _coalescingKey++; + } + + [_bridge.eventDispatcher sendEvent:event]; +} + +- (void)_javaScriptDidLoad:(__unused NSNotification *)notification +{ + _enabled = YES; +} + +- (void)_bridgeWillReload:(__unused NSNotification *)notification +{ + _enabled = NO; +} + +@end From e34e535ec10a42f664a2e290c64058b7e80d1de0 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 12:30:08 -0500 Subject: [PATCH 004/143] feat: add "onMouseMove" prop --- Libraries/Components/Touchable/TouchableOpacity.js | 1 + Libraries/Components/Touchable/TouchableWithoutFeedback.js | 2 ++ Libraries/Components/View/ReactNativeViewAttributes.js | 1 + Libraries/Components/View/ViewPropTypes.js | 1 + 4 files changed, 5 insertions(+) diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 8b09f39324..baeb28a39a 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -259,6 +259,7 @@ var TouchableOpacity = createReactClass({ onResponderMove={this.touchableHandleResponderMove} onResponderRelease={this.touchableHandleResponderRelease} onResponderTerminate={this.touchableHandleResponderTerminate} + onMouseMove={this.props.onMouseMove} onMouseOver={this.props.onMouseOver} onMouseOut={this.props.onMouseOut} onContextMenuItemClick={this.props.onContextMenuItemClick} diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index d9250db14b..fce97b4a2a 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -110,6 +110,7 @@ const TouchableWithoutFeedback = createReactClass({ * views. */ hitSlop: EdgeInsetsPropType, + onMouseMove: PropTypes.func, onMouseOver: PropTypes.func, onMouseOut: PropTypes.func, onContextMenuItemClick: PropTypes.func, @@ -213,6 +214,7 @@ const TouchableWithoutFeedback = createReactClass({ onResponderMove: this.touchableHandleResponderMove, onResponderRelease: this.touchableHandleResponderRelease, onResponderTerminate: this.touchableHandleResponderTerminate, + onMouseMove: this.props.onMouseMove, onMouseOver: this.props.onMouseOver, onMouseOut: this.props.onMouseOut, onContextMenuItemClick: this.props.onContextMenuItemClick, diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 8f26351dac..f093b6b418 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -30,6 +30,7 @@ ReactNativeViewAttributes.UIView = { renderToHardwareTextureAndroid: true, shouldRasterizeIOS: true, onLayout: true, + onMouseMove: true, onMouseOver: true, onMouseOut: true, onAccessibilityTap: true, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index c171402b52..5a75ec8892 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -433,6 +433,7 @@ module.exports = { * Desktop specific events * @platform macos */ + onMouseMove: PropTypes.func, onMouseOver: PropTypes.func, onMouseOut: PropTypes.func, onDragEnter: PropTypes.func, From 6ca113184d131e91811d1dc04432f99d4a084d6f Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 14:10:03 -0500 Subject: [PATCH 005/143] feat: add "onContextMenu" prop --- Libraries/Components/Touchable/TouchableOpacity.js | 1 + Libraries/Components/Touchable/TouchableWithoutFeedback.js | 2 ++ Libraries/Components/View/ReactNativeViewAttributes.js | 1 + Libraries/Components/View/ViewPropTypes.js | 1 + 4 files changed, 5 insertions(+) diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index baeb28a39a..1bf17b3dc1 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -262,6 +262,7 @@ var TouchableOpacity = createReactClass({ onMouseMove={this.props.onMouseMove} onMouseOver={this.props.onMouseOver} onMouseOut={this.props.onMouseOut} + onContextMenu={this.props.onContextMenu} onContextMenuItemClick={this.props.onContextMenuItemClick} contextMenu={this.props.contextMenu}> {this.props.children} diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index fce97b4a2a..390426fa8c 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -113,6 +113,7 @@ const TouchableWithoutFeedback = createReactClass({ onMouseMove: PropTypes.func, onMouseOver: PropTypes.func, onMouseOut: PropTypes.func, + onContextMenu: PropTypes.func, onContextMenuItemClick: PropTypes.func, contextMenu: PropTypes.array, }, @@ -217,6 +218,7 @@ const TouchableWithoutFeedback = createReactClass({ onMouseMove: this.props.onMouseMove, onMouseOver: this.props.onMouseOver, onMouseOut: this.props.onMouseOut, + onContextMenu: this.props.onContextMenu, onContextMenuItemClick: this.props.onContextMenuItemClick, contextMenu: this.props.contextMenu, style, diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index f093b6b418..bad80fe220 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -33,6 +33,7 @@ ReactNativeViewAttributes.UIView = { onMouseMove: true, onMouseOver: true, onMouseOut: true, + onContextMenu: true, onAccessibilityTap: true, onMagicTap: true, collapsable: true, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index 5a75ec8892..1a1254b9ff 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -439,6 +439,7 @@ module.exports = { onDragEnter: PropTypes.func, onDragLeave: PropTypes.func, onDrop: PropTypes.func, + onContextMenu: PropTypes.func, onContextMenuItemClick: PropTypes.func, /** * Mapped to toolTip property of NSView. Used to show extra information when From 05744ed55d2b73af4b460769fce45ef3e1c2bc78 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 12:32:49 -0500 Subject: [PATCH 006/143] use RCTWindow in RNTester/AppDelegate.m --- RNTester/RNTester/AppDelegate.m | 60 +++++++++++++-------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/RNTester/RNTester/AppDelegate.m b/RNTester/RNTester/AppDelegate.m index 2c5edb6987..6bbece42f6 100644 --- a/RNTester/RNTester/AppDelegate.m +++ b/RNTester/RNTester/AppDelegate.m @@ -21,6 +21,7 @@ #import #import #import +#import @interface AppDelegate() @@ -28,54 +29,33 @@ @interface AppDelegate() @implementation AppDelegate - --(id)init { - if(self = [super init]) { - - // -- Init Window - NSRect contentSize = NSMakeRect(200, 500, 1000, 500); - - self.window = [[NSWindow alloc] initWithContentRect:contentSize - styleMask:NSTitledWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask - backing:NSBackingStoreBuffered - defer:NO]; - NSWindowController *windowController = [[NSWindowController alloc] initWithWindow:self.window]; - - [[self window] setTitle:@"RNTester"]; - [[self window] setTitleVisibility:NSWindowTitleHidden]; - [windowController showWindow:self.window]; - - [windowController setShouldCascadeWindows:NO]; - [windowController setWindowFrameAutosaveName:@"RNTester"]; - [self setDefaultURL]; - - // -- Init Toolbar - NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"mainToolbar"]; - [toolbar setDelegate:self]; - [toolbar setSizeMode:NSToolbarSizeModeRegular]; - - [self.window setToolbar:toolbar]; - - // -- Init Menu - [self setUpMainMenu]; - } - return self; + NSToolbar *_toolbar; } - (void)applicationDidFinishLaunching:(NSNotification * __unused)aNotification { + [self setDefaultURL]; _bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:@{@"argv": [self argv]}]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:_bridge - moduleName:@"RNTesterApp" - initialProperties:nil]; + _window = [[RCTWindow alloc] initWithBridge:_bridge + contentRect:NSMakeRect(200, 500, 1000, 500) + styleMask:(NSTitledWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask) + defer:NO]; + + _window.title = @"RNTester"; + _window.titleVisibility = NSWindowTitleHidden; + [self setUpToolbar]; + [self setUpMainMenu]; + _window.contentView = [[RCTRootView alloc] initWithBridge:_bridge + moduleName:@"RNTesterApp" + initialProperties:nil]; - [self.window setContentView:rootView]; + [_window makeKeyAndOrderFront:nil]; } - (void)setDefaultURL @@ -105,6 +85,14 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge onComplete:loadCallback]; } +- (void)setUpToolbar +{ + NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"mainToolbar"]; + toolbar.delegate = self; + toolbar.sizeMode = NSToolbarSizeModeRegular; + _window.toolbar = toolbar; +} + - (NSArray *)toolbarAllowedItemIdentifiers:(__unused NSToolbar *)toolbar { return @[NSToolbarFlexibleSpaceItemIdentifier, @"searchBar", NSToolbarFlexibleSpaceItemIdentifier, @"resetButton"]; From fc74bcf6a32aac937984965d9133e275b7d93bd3 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 9 Jan 2018 22:24:24 -0800 Subject: [PATCH 007/143] Revert D6641403: [RN] Refined -[RCTUIManager createView:] Differential Revision: D6641403 fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1 --- React/Modules/RCTUIManager.m | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 48da79c2f1..214d155cfd 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -763,7 +763,7 @@ - (void)_removeChildren:(NSArray *)children // First one: We want to delete the view from view hierarchy. // Second one: We want to animate this view, which implies the existence of this view in the hierarchy. // So, we have to remove this view from React's view hierarchy but postpone removing from UIKit's hierarchy. - // Here the problem: the default implementation of `-[UIView removeReactSubview:]` also removes the view from UIKit's hierarchy. + // Here the problem: the default implementation of `-[NSView removeReactSubview:]` also removes the view from UIKit's hierarchy. // So, let's temporary restore the view back after removing. // To do so, we have to memorize original `superview` (which can differ from `container`) and an index of removed view. NSView *originalSuperview = removedChild.superview; @@ -906,8 +906,8 @@ - (void)_manageChildren:(NSNumber *)containerTag NSArray> *temporarilyRemovedChildren = [self _childrenToRemoveFromContainer:container atIndices:moveFromIndices]; - BOOL isUIViewRegistry = ((id)registry == (id)_viewRegistry); - if (isUIViewRegistry && _layoutAnimationGroup.deletingLayoutAnimation) { + BOOL isNSViewRegistry = ((id)registry == (id)_viewRegistry); + if (isNSViewRegistry && _layoutAnimationGroup.deletingLayoutAnimation) { [self _removeChildren:(NSArray *)permanentlyRemovedChildren fromContainer:(NSView *)container withAnimation:_layoutAnimationGroup]; @@ -963,19 +963,21 @@ - (void)_manageChildren:(NSNumber *)containerTag // Dispatch view creation directly to the main thread instead of adding to // UIBlocks array. This way, it doesn't get deferred until after layout. - __block NSView *preliminaryCreatedView; - + __weak RCTUIManager *weakManager = self; RCTExecuteOnMainQueue(^{ - preliminaryCreatedView = [componentData createViewWithTag:reactTag]; - }); - - [self addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - if (!preliminaryCreatedView) { + RCTUIManager *uiManager = weakManager; + if (!uiManager) { return; } + NSView *view = [componentData createViewWithTag:reactTag]; + if (view) { + uiManager->_viewRegistry[reactTag] = view; + } + }); - uiManager->_viewRegistry[reactTag] = preliminaryCreatedView; - [componentData setProps:props forView:preliminaryCreatedView]; + [self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + NSView *view = viewRegistry[reactTag]; + [componentData setProps:props forView:view]; }]; [self _shadowView:shadowView didReceiveUpdatedProps:[props allKeys]]; From 418b845829b7c67256d2599374de3e188622121a Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Wed, 10 Jan 2018 04:30:27 -0800 Subject: [PATCH 008/143] Move utility functions to utils file Reviewed By: emilsjolander Differential Revision: D6682933 fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03 --- React/React.xcodeproj/project.pbxproj | 8 ++++++++ ReactCommon/yoga/yoga/Utils.cpp | 23 +++++++++++++++++++++++ ReactCommon/yoga/yoga/Utils.h | 17 +++++++++++++++++ ReactCommon/yoga/yoga/YGNode.cpp | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 18 +----------------- 5 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 ReactCommon/yoga/yoga/Utils.cpp create mode 100644 ReactCommon/yoga/yoga/Utils.h diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index c2e9ac24ab..9fbbb7bb54 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -1044,6 +1044,8 @@ 702B7FFD221C88BB0027174A /* RCTMouseEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */; }; 702B7FFE221C88CE0027174A /* RCTMouseEvent.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */; }; 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; + 705EDE2922107DD0000CAA67 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2722107DD0000CAA67 /* Utils.h */; }; + 705EDE2A22107DD0000CAA67 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2822107DD0000CAA67 /* Utils.cpp */; }; 830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; }; 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; }; 83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8B1B62640A00BE0E65 /* RCTModalHostView.m */; }; @@ -2076,6 +2078,8 @@ 702B7FF7221C88AF0027174A /* RCTWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWindow.m; sourceTree = ""; }; 702B7FFA221C88BB0027174A /* RCTMouseEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMouseEvent.h; sourceTree = ""; }; 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMouseEvent.m; sourceTree = ""; }; + 705EDE2722107DD0000CAA67 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; + 705EDE2822107DD0000CAA67 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = ""; }; 830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; }; 830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; }; 830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; }; @@ -2192,6 +2196,8 @@ 130A77021DF767AF001F9587 /* yoga */ = { isa = PBXGroup; children = ( + 705EDE2822107DD0000CAA67 /* Utils.cpp */, + 705EDE2722107DD0000CAA67 /* Utils.h */, D49593E4202C96FF00A7694B /* YGNode.cpp */, D49593E3202C96FF00A7694B /* YGNode.h */, 5376C5E11FC6DDB20083513D /* YGNodePrint.cpp */, @@ -3312,6 +3318,7 @@ 3D80DA5A1DF820620028D040 /* RCTUIManager.h in Headers */, 3D80DA5B1DF820620028D040 /* RCTFPSGraph.h in Headers */, 3D80DA5D1DF820620028D040 /* RCTMacros.h in Headers */, + 705EDE2922107DD0000CAA67 /* Utils.h in Headers */, 3D80DA5E1DF820620028D040 /* RCTProfile.h in Headers */, 3D80DA5F1DF820620028D040 /* RCTActivityIndicatorView.h in Headers */, 3D80DA601DF820620028D040 /* RCTActivityIndicatorViewManager.h in Headers */, @@ -4165,6 +4172,7 @@ 594F0A341FD23228007FBE96 /* RCTSurfaceHostingView.mm in Sources */, 13134C861E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */, 13B07FEF1A69327A00A75B9A /* RCTAlertManager.m in Sources */, + 705EDE2A22107DD0000CAA67 /* Utils.cpp in Sources */, 599FAA4C1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */, D4EEE2F7201DF63F00C4CBB6 /* RCTButton.m in Sources */, 352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */, diff --git a/ReactCommon/yoga/yoga/Utils.cpp b/ReactCommon/yoga/yoga/Utils.cpp new file mode 100644 index 0000000000..e8c270366f --- /dev/null +++ b/ReactCommon/yoga/yoga/Utils.cpp @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2014-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. + */ + +#include "Utils.h" + +bool YGValueEqual(const YGValue a, const YGValue b) { + if (a.unit != b.unit) { + return false; + } + + if (a.unit == YGUnitUndefined || + (std::isnan(a.value) && std::isnan(b.value))) { + return true; + } + + return fabs(a.value - b.value) < 0.0001f; +} diff --git a/ReactCommon/yoga/yoga/Utils.h b/ReactCommon/yoga/yoga/Utils.h new file mode 100644 index 0000000000..11a908d37d --- /dev/null +++ b/ReactCommon/yoga/yoga/Utils.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2014-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. + */ + +#include "Yoga-internal.h" + +inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionRow || + flexDirection == YGFlexDirectionRowReverse; +} + +bool YGValueEqual(const YGValue a, const YGValue b); diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 5099a2467b..71d927b226 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -9,6 +9,7 @@ #include "YGNode.h" #include +#include "Utils.h" void* YGNode::getContext() const { return context_; diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 186c6ce469..82cd9f6766 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -10,6 +10,7 @@ #include "Yoga.h" #include #include +#include "Utils.h" #include "YGNode.h" #include "YGNodePrint.h" #include "Yoga-internal.h" @@ -747,19 +748,6 @@ bool YGLayoutNodeInternal(const YGNodeRef node, const char *reason, const YGConfigRef config); -bool YGValueEqual(const YGValue a, const YGValue b) { - if (a.unit != b.unit) { - return false; - } - - if (a.unit == YGUnitUndefined || - (std::isnan(a.value) && std::isnan(b.value))) { - return true; - } - - return fabs(a.value - b.value) < 0.0001f; -} - bool YGFloatsEqual(const float a, const float b) { if (YGFloatIsUndefined(a)) { return YGFloatIsUndefined(b); @@ -792,10 +780,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { - return flexDirection == YGFlexDirectionRow || flexDirection == YGFlexDirectionRowReverse; -} - static inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { return flexDirection == YGFlexDirectionColumn || flexDirection == YGFlexDirectionColumnReverse; } From eb3c81870932c14a43c13ad54a9bb7d7fcf8eab1 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Tue, 9 Jan 2018 04:21:58 -0800 Subject: [PATCH 009/143] Fix warnings of casting and null pointer handling Reviewed By: emilsjolander Differential Revision: D6675111 fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e --- ReactCommon/yoga/yoga/YGNode.cpp | 2 +- ReactCommon/yoga/yoga/YGNodePrint.cpp | 2 +- ReactCommon/yoga/yoga/Yoga.cpp | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 71d927b226..d09394dbd3 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -386,7 +386,7 @@ void YGNode::cloneChildrenIfNeeded() { // YGNodeRemoveChild in yoga.cpp has a forked variant of this algorithm // optimized for deletions. - const uint32_t childCount = children_.size(); + const uint32_t childCount = static_cast(children_.size()); if (childCount == 0) { // This is an empty set. Nothing to clone. return; diff --git a/ReactCommon/yoga/yoga/YGNodePrint.cpp b/ReactCommon/yoga/yoga/YGNodePrint.cpp index e49903acc9..0951e955a9 100644 --- a/ReactCommon/yoga/yoga/YGNodePrint.cpp +++ b/ReactCommon/yoga/yoga/YGNodePrint.cpp @@ -212,7 +212,7 @@ void YGNodeToString( } appendFormatedString(str, ">"); - const uint32_t childCount = node->getChildren().size(); + const uint32_t childCount = static_cast(node->getChildren().size()); if (options & YGPrintOptionsChildren && childCount > 0) { for (uint32_t i = 0; i < childCount; i++) { appendFormatedString(str, "\n"); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 82cd9f6766..c843dc54e8 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -322,7 +322,9 @@ YGConfigRef YGConfigGetDefault() { YGConfigRef YGConfigNew(void) { const YGConfigRef config = (const YGConfigRef)malloc(sizeof(YGConfig)); YGAssert(config != nullptr, "Could not allocate memory for config"); - + if (config == nullptr) { + abort(); + } gConfigInstanceCount++; memcpy(config, &gYGConfigDefaults, sizeof(YGConfig)); return config; @@ -434,7 +436,7 @@ YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) { } uint32_t YGNodeGetChildCount(const YGNodeRef node) { - return node->getChildren().size(); + return static_cast(node->getChildren().size()); } YGNodeRef YGNodeGetParent(const YGNodeRef node) { @@ -1879,7 +1881,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, return; } - const uint32_t childCount = node->getChildren().size(); + const uint32_t childCount = YGNodeGetChildCount(node); if (childCount == 0) { YGNodeEmptyContainerSetMeasuredDimensions(node, availableWidth, @@ -3540,7 +3542,7 @@ static void YGRoundToPixelGrid(const YGNodeRef node, absoluteNodeTop, pointScaleFactor, false, textRounding), YGDimensionHeight); - const uint32_t childCount = node->getChildren().size(); + const uint32_t childCount = YGNodeGetChildCount(node); for (uint32_t i = 0; i < childCount; i++) { YGRoundToPixelGrid(YGNodeGetChild(node, i), pointScaleFactor, absoluteNodeLeft, absoluteNodeTop); } From e327a7229a1425f0d62b5639314bdcd7b86df072 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 10 Jan 2018 09:45:08 -0800 Subject: [PATCH 010/143] Introducing on-dirty handler (aka `YGNodeSetDirtiedFunc`) Summary: Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it. We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure. Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `` where all content of all nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node. Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win. Reviewed By: emilsjolander Differential Revision: D6597856 fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0 --- ReactCommon/yoga/yoga/YGNode.cpp | 21 ++++++++++++++++++++- ReactCommon/yoga/yoga/YGNode.h | 4 ++++ ReactCommon/yoga/yoga/Yoga.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index d09394dbd3..9ee729b568 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -35,6 +35,10 @@ YGBaselineFunc YGNode::getBaseline() const { return baseline_; } +YGDirtiedFunc YGNode::getDirtied() const { + return dirtied_; +} + YGStyle& YGNode::getStyle() { return style_; } @@ -128,6 +132,10 @@ void YGNode::setBaseLineFunc(YGBaselineFunc baseLineFunc) { baseline_ = baseLineFunc; } +void YGNode::setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { + dirtied_ = dirtiedFunc; +} + void YGNode::setStyle(YGStyle style) { style_ = style; } @@ -169,7 +177,13 @@ void YGNode::setConfig(YGConfigRef config) { } void YGNode::setDirty(bool isDirty) { + if (isDirty == isDirty_) { + return; + } isDirty_ = isDirty; + if (isDirty && dirtied_) { + dirtied_(this); + } } bool YGNode::removeChild(YGNodeRef child) { @@ -238,6 +252,7 @@ YGNode::YGNode() nodeType_(YGNodeTypeDefault), measure_(nullptr), baseline_(nullptr), + dirtied_(nullptr), style_(gYGNodeStyleDefaults), layout_(gYGNodeLayoutDefaults), lineIndex_(0), @@ -255,6 +270,7 @@ YGNode::YGNode(const YGNode& node) nodeType_(node.nodeType_), measure_(node.measure_), baseline_(node.baseline_), + dirtied_(node.dirtied_), style_(node.style_), layout_(node.layout_), lineIndex_(node.lineIndex_), @@ -276,6 +292,7 @@ YGNode::YGNode( YGNodeType nodeType, YGMeasureFunc measure, YGBaselineFunc baseline, + YGDirtiedFunc dirtied, YGStyle style, YGLayout layout, uint32_t lineIndex, @@ -291,6 +308,7 @@ YGNode::YGNode( nodeType_(nodeType), measure_(measure), baseline_(baseline), + dirtied_(dirtied), style_(style), layout_(layout), lineIndex_(lineIndex), @@ -316,6 +334,7 @@ YGNode& YGNode::operator=(const YGNode& node) { nodeType_ = node.getNodeType(); measure_ = node.getMeasure(); baseline_ = node.getBaseline(); + dirtied_ = node.getDirtied(); style_ = node.style_; layout_ = node.layout_; lineIndex_ = node.getLineIndex(); @@ -415,7 +434,7 @@ void YGNode::cloneChildrenIfNeeded() { void YGNode::markDirtyAndPropogate() { if (!isDirty_) { - isDirty_ = true; + setDirty(true); setLayoutComputedFlexBasis(YGUndefined); if (parent_) { parent_->markDirtyAndPropogate(); diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 46e0c2f7fd..79947e7132 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -20,6 +20,7 @@ struct YGNode { YGNodeType nodeType_; YGMeasureFunc measure_; YGBaselineFunc baseline_; + YGDirtiedFunc dirtied_; YGStyle style_; YGLayout layout_; uint32_t lineIndex_; @@ -43,6 +44,7 @@ struct YGNode { YGNodeType nodeType, YGMeasureFunc measure, YGBaselineFunc baseline, + YGDirtiedFunc dirtied, YGStyle style, YGLayout layout, uint32_t lineIndex, @@ -60,6 +62,7 @@ struct YGNode { YGNodeType getNodeType() const; YGMeasureFunc getMeasure() const; YGBaselineFunc getBaseline() const; + YGDirtiedFunc getDirtied() const; // For Perfomance reasons passing as reference. YGStyle& getStyle(); // For Perfomance reasons passing as reference. @@ -82,6 +85,7 @@ struct YGNode { void setNodeType(YGNodeType nodeTye); void setMeasureFunc(YGMeasureFunc measureFunc); void setBaseLineFunc(YGBaselineFunc baseLineFunc); + void setDirtiedFunc(YGDirtiedFunc dirtiedFunc); void setStyle(YGStyle style); void setStyleFlexDirection(YGFlexDirection direction); void setStyleAlignContent(YGAlign alignContent); diff --git a/ReactCommon/yoga/yoga/Yoga.h b/ReactCommon/yoga/yoga/Yoga.h index 90f1f5fc05..28326019fb 100644 --- a/ReactCommon/yoga/yoga/Yoga.h +++ b/ReactCommon/yoga/yoga/Yoga.h @@ -56,6 +56,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node, float height, YGMeasureMode heightMode); typedef float (*YGBaselineFunc)(YGNodeRef node, const float width, const float height); +typedef void (*YGDirtiedFunc)(YGNodeRef node); typedef void (*YGPrintFunc)(YGNodeRef node); typedef int (*YGLogger)(const YGConfigRef config, const YGNodeRef node, From ea64e65834830c3b4e82c1c3310abfb6b2179fcc Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:35 -0800 Subject: [PATCH 011/143] Moved YGNodeLeading position as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6682929 fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f --- ReactCommon/yoga/yoga/Utils.cpp | 8 +++ ReactCommon/yoga/yoga/Utils.h | 52 +++++++++++++++- ReactCommon/yoga/yoga/YGNode.cpp | 20 ++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga-internal.h | 1 - ReactCommon/yoga/yoga/Yoga.cpp | 89 +++------------------------ 6 files changed, 89 insertions(+), 82 deletions(-) diff --git a/ReactCommon/yoga/yoga/Utils.cpp b/ReactCommon/yoga/yoga/Utils.cpp index e8c270366f..d7f548e616 100644 --- a/ReactCommon/yoga/yoga/Utils.cpp +++ b/ReactCommon/yoga/yoga/Utils.cpp @@ -9,6 +9,14 @@ #include "Utils.h" +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction) { + return YGFlexDirectionIsColumn(flexDirection) + ? YGResolveFlexDirection(YGFlexDirectionRow, direction) + : YGFlexDirectionColumn; +} + bool YGValueEqual(const YGValue a, const YGValue b) { if (a.unit != b.unit) { return false; diff --git a/ReactCommon/yoga/yoga/Utils.h b/ReactCommon/yoga/yoga/Utils.h index 11a908d37d..019ed5e50f 100644 --- a/ReactCommon/yoga/yoga/Utils.h +++ b/ReactCommon/yoga/yoga/Utils.h @@ -7,11 +7,61 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#pragma once +#include "YGNode.h" #include "Yoga-internal.h" +bool YGValueEqual(const YGValue a, const YGValue b); + +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction); + inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { return flexDirection == YGFlexDirectionRow || flexDirection == YGFlexDirectionRowReverse; } -bool YGValueEqual(const YGValue a, const YGValue b); +inline float YGResolveValue(const YGValue value, const float parentSize) { + switch (value.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return YGUndefined; + case YGUnitPoint: + return value.value; + case YGUnitPercent: + return value.value * parentSize / 100.0f; + } + return YGUndefined; +} + +inline bool YGNodeIsLeadingPosDefined( + const YGNodeRef node, + const YGFlexDirection axis) { + return (YGFlexDirectionIsRow(axis) && + YGComputedEdgeValue( + node->getStyle().position, YGEdgeStart, &YGValueUndefined) + ->unit != YGUnitUndefined) || + YGComputedEdgeValue( + node->getStyle().position, leading[axis], &YGValueUndefined) + ->unit != YGUnitUndefined; +} + +inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionColumn || + flexDirection == YGFlexDirectionColumnReverse; +} + +inline YGFlexDirection YGResolveFlexDirection( + const YGFlexDirection flexDirection, + const YGDirection direction) { + if (direction == YGDirectionRTL) { + if (flexDirection == YGFlexDirectionRow) { + return YGFlexDirectionRowReverse; + } else if (flexDirection == YGFlexDirectionRowReverse) { + return YGFlexDirectionRow; + } + } + + return flexDirection; +} diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 9ee729b568..b1b5f4d82a 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -82,6 +82,26 @@ YGValue YGNode::getResolvedDimension(int index) { std::array YGNode::getResolvedDimensions() const { return resolvedDimensions_; } + +float YGNode::getLeadingPosition( + const YGFlexDirection axis, + const float axisSize) { + if (YGFlexDirectionIsRow(axis)) { + const YGValue* leadingPosition = + YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined); + if (leadingPosition->unit != YGUnitUndefined) { + return YGResolveValue(*leadingPosition, axisSize); + } + } + + const YGValue* leadingPosition = + YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined); + + return leadingPosition->unit == YGUnitUndefined + ? 0.0f + : YGResolveValue(*leadingPosition, axisSize); +} + // Setters void YGNode::setContext(void* context) { diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 79947e7132..1a05c6e0bd 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -76,6 +76,7 @@ struct YGNode { bool isDirty() const; std::array getResolvedDimensions() const; YGValue getResolvedDimension(int index); + float getLeadingPosition(const YGFlexDirection axis, const float axisSize); // Setters diff --git a/ReactCommon/yoga/yoga/Yoga-internal.h b/ReactCommon/yoga/yoga/Yoga-internal.h index 1ea80704ad..081c934453 100644 --- a/ReactCommon/yoga/yoga/Yoga-internal.h +++ b/ReactCommon/yoga/yoga/Yoga-internal.h @@ -28,7 +28,6 @@ YG_EXTERN_C_END extern const std::array trailing; extern const std::array leading; -extern bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection); extern bool YGValueEqual(const YGValue a, const YGValue b); extern const YGValue YGValueUndefined; extern const YGValue YGValueAuto; diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index c843dc54e8..3d4a301be1 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -151,21 +151,6 @@ const YGValue* YGComputedEdgeValue( return defaultValue; } -static inline float YGResolveValue( - const YGValue value, - const float parentSize) { - switch (value.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return YGUndefined; - case YGUnitPoint: - return value.value; - case YGUnitPercent: - return value.value * parentSize / 100.0f; - } - return YGUndefined; -} - static inline float YGResolveValueMargin( const YGValue value, const float parentSize) { @@ -782,10 +767,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { - return flexDirection == YGFlexDirectionColumn || flexDirection == YGFlexDirectionColumnReverse; -} - static inline float YGNodeLeadingMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -967,26 +948,6 @@ static float YGBaseline(const YGNodeRef node) { return baseline + baselineChild->getLayout().position[YGEdgeTop]; } -static inline YGFlexDirection YGResolveFlexDirection(const YGFlexDirection flexDirection, - const YGDirection direction) { - if (direction == YGDirectionRTL) { - if (flexDirection == YGFlexDirectionRow) { - return YGFlexDirectionRowReverse; - } else if (flexDirection == YGFlexDirectionRowReverse) { - return YGFlexDirectionRow; - } - } - - return flexDirection; -} - -static YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection, - const YGDirection direction) { - return YGFlexDirectionIsColumn(flexDirection) - ? YGResolveFlexDirection(YGFlexDirectionRow, direction) - : YGFlexDirectionColumn; -} - static inline bool YGNodeIsFlex(const YGNodeRef node) { return ( node->getStyle().positionType == YGPositionTypeRelative && @@ -1038,15 +999,6 @@ static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDi return !YGFloatIsUndefined(value) && value >= 0.0f; } -static inline bool YGNodeIsLeadingPosDefined(const YGNodeRef node, const YGFlexDirection axis) { - return (YGFlexDirectionIsRow(axis) && - YGComputedEdgeValue( - node->getStyle().position, YGEdgeStart, &YGValueUndefined) - ->unit != YGUnitUndefined) || - YGComputedEdgeValue( - node->getStyle().position, leading[axis], &YGValueUndefined) - ->unit != YGUnitUndefined; -} static inline bool YGNodeIsTrailingPosDefined(const YGNodeRef node, const YGFlexDirection axis) { return (YGFlexDirectionIsRow(axis) && @@ -1058,27 +1010,6 @@ static inline bool YGNodeIsTrailingPosDefined(const YGNodeRef node, const YGFlex ->unit != YGUnitUndefined; } -static float YGNodeLeadingPosition(const YGNodeRef node, - const YGFlexDirection axis, - const float axisSize) { - if (YGFlexDirectionIsRow(axis)) { - const YGValue* leadingPosition = YGComputedEdgeValue( - node->getStyle().position, YGEdgeStart, &YGValueUndefined); - if (leadingPosition->unit != YGUnitUndefined) { - return YGResolveValue( - *leadingPosition, - axisSize); // leadingPosition->resolveValue(axisSize); - } - } - - const YGValue* leadingPosition = YGComputedEdgeValue( - node->getStyle().position, leading[axis], &YGValueUndefined); - - return leadingPosition->unit == YGUnitUndefined - ? 0.0f - : YGResolveValue(*leadingPosition, axisSize); -} - static float YGNodeTrailingPosition(const YGNodeRef node, const YGFlexDirection axis, const float axisSize) { @@ -1157,8 +1088,9 @@ static void YGNodeSetChildTrailingPosition(const YGNodeRef node, static float YGNodeRelativePosition(const YGNodeRef node, const YGFlexDirection axis, const float axisSize) { - return YGNodeIsLeadingPosDefined(node, axis) ? YGNodeLeadingPosition(node, axis, axisSize) - : -YGNodeTrailingPosition(node, axis, axisSize); + return YGNodeIsLeadingPosDefined(node, axis) + ? node->getLeadingPosition(axis, axisSize) + : -YGNodeTrailingPosition(node, axis, axisSize); } static void YGConstrainMaxSizeForMode(const YGNodeRef node, @@ -1414,7 +1346,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (YGNodeLeadingBorder(node, YGFlexDirectionRow) + YGNodeTrailingBorder(node, YGFlexDirectionRow)) - - (YGNodeLeadingPosition(child, YGFlexDirectionRow, width) + + (child->getLeadingPosition(YGFlexDirectionRow, width) + YGNodeTrailingPosition(child, YGFlexDirectionRow, width)); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } @@ -1433,7 +1365,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (YGNodeLeadingBorder(node, YGFlexDirectionColumn) + YGNodeTrailingBorder(node, YGFlexDirectionColumn)) - - (YGNodeLeadingPosition(child, YGFlexDirectionColumn, height) + + (child->getLeadingPosition(YGFlexDirectionColumn, height) + YGNodeTrailingPosition(child, YGFlexDirectionColumn, height)); childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, height, width); } @@ -2572,7 +2504,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // defined, we override the position to whatever the user said // (and margin/border). child->setLayoutPosition( - YGNodeLeadingPosition(child, mainAxis, availableInnerMainDim) + + child->getLeadingPosition(mainAxis, availableInnerMainDim) + YGNodeLeadingBorder(node, mainAxis) + YGNodeLeadingMargin(child, mainAxis, availableInnerWidth), pos[mainAxis]); @@ -2664,8 +2596,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, const bool isChildLeadingPosDefined = YGNodeIsLeadingPosDefined(child, crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( - YGNodeLeadingPosition( - child, crossAxis, availableInnerCrossDim) + + child->getLeadingPosition(crossAxis, availableInnerCrossDim) + YGNodeLeadingBorder(node, crossAxis) + YGNodeLeadingMargin(child, crossAxis, availableInnerWidth), pos[crossAxis]); @@ -2948,10 +2879,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignBaseline: { child->setLayoutPosition( currentLead + maxAscentForCurrentLine - YGBaseline(child) + - YGNodeLeadingPosition( - child, - YGFlexDirectionColumn, - availableInnerCrossDim), + child->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim), YGEdgeTop); break; From 17845e2d2034091aa3e04d33adeb44b58a2eea6e Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:38 -0800 Subject: [PATCH 012/143] Moved isLeadingPos defined as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6682956 fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5 --- ReactCommon/yoga/yoga/Utils.h | 12 ------------ ReactCommon/yoga/yoga/YGNode.cpp | 8 ++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 27 +++++++++++++++------------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/ReactCommon/yoga/yoga/Utils.h b/ReactCommon/yoga/yoga/Utils.h index 019ed5e50f..7f3bf76364 100644 --- a/ReactCommon/yoga/yoga/Utils.h +++ b/ReactCommon/yoga/yoga/Utils.h @@ -35,18 +35,6 @@ inline float YGResolveValue(const YGValue value, const float parentSize) { return YGUndefined; } -inline bool YGNodeIsLeadingPosDefined( - const YGNodeRef node, - const YGFlexDirection axis) { - return (YGFlexDirectionIsRow(axis) && - YGComputedEdgeValue( - node->getStyle().position, YGEdgeStart, &YGValueUndefined) - ->unit != YGUnitUndefined) || - YGComputedEdgeValue( - node->getStyle().position, leading[axis], &YGValueUndefined) - ->unit != YGUnitUndefined; -} - inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { return flexDirection == YGFlexDirectionColumn || flexDirection == YGFlexDirectionColumnReverse; diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index b1b5f4d82a..449a8e8993 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -102,6 +102,14 @@ float YGNode::getLeadingPosition( : YGResolveValue(*leadingPosition, axisSize); } +bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) { + return (YGFlexDirectionIsRow(axis) && + YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined) + ->unit != YGUnitUndefined) || + YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined) + ->unit != YGUnitUndefined; +} + // Setters void YGNode::setContext(void* context) { diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 1a05c6e0bd..20243d5127 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -77,6 +77,7 @@ struct YGNode { std::array getResolvedDimensions() const; YGValue getResolvedDimension(int index); float getLeadingPosition(const YGFlexDirection axis, const float axisSize); + bool isLeadingPositionDefined(const YGFlexDirection axis); // Setters diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 3d4a301be1..45c6e34db3 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1088,7 +1088,7 @@ static void YGNodeSetChildTrailingPosition(const YGNodeRef node, static float YGNodeRelativePosition(const YGNodeRef node, const YGFlexDirection axis, const float axisSize) { - return YGNodeIsLeadingPosDefined(node, axis) + return node->isLeadingPositionDefined(axis) ? node->getLeadingPosition(axis, axisSize) : -YGNodeTrailingPosition(node, axis, axisSize); } @@ -1341,7 +1341,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, // If the child doesn't have a specified width, compute the width based // on the left/right // offsets if they're defined. - if (YGNodeIsLeadingPosDefined(child, YGFlexDirectionRow) && + if (child->isLeadingPositionDefined(YGFlexDirectionRow) && YGNodeIsTrailingPosDefined(child, YGFlexDirectionRow)) { childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (YGNodeLeadingBorder(node, YGFlexDirectionRow) + @@ -1360,7 +1360,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, // If the child doesn't have a specified height, compute the height // based on the top/bottom // offsets if they're defined. - if (YGNodeIsLeadingPosDefined(child, YGFlexDirectionColumn) && + if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && YGNodeIsTrailingPosDefined(child, YGFlexDirectionColumn)) { childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (YGNodeLeadingBorder(node, YGFlexDirectionColumn) + @@ -1430,7 +1430,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, "abs-layout", config); - if (YGNodeIsTrailingPosDefined(child, mainAxis) && !YGNodeIsLeadingPosDefined(child, mainAxis)) { + if (YGNodeIsTrailingPosDefined(child, mainAxis) && + !child->isLeadingPositionDefined(mainAxis)) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - @@ -1440,7 +1441,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child, mainAxis, isMainAxisRow ? width : height), leading[mainAxis]); } else if ( - !YGNodeIsLeadingPosDefined(child, mainAxis) && + !child->isLeadingPositionDefined(mainAxis) && node->getStyle().justifyContent == YGJustifyCenter) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[mainAxis]] - @@ -1448,7 +1449,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, 2.0f, leading[mainAxis]); } else if ( - !YGNodeIsLeadingPosDefined(child, mainAxis) && + !child->isLeadingPositionDefined(mainAxis) && node->getStyle().justifyContent == YGJustifyFlexEnd) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[mainAxis]] - @@ -1457,7 +1458,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, } if (YGNodeIsTrailingPosDefined(child, crossAxis) && - !YGNodeIsLeadingPosDefined(child, crossAxis)) { + !child->isLeadingPositionDefined(crossAxis)) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - @@ -1467,15 +1468,16 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child, crossAxis, isMainAxisRow ? height : width), leading[crossAxis]); - } else if (!YGNodeIsLeadingPosDefined(child, crossAxis) && - YGNodeAlignItem(node, child) == YGAlignCenter) { + } else if ( + !child->isLeadingPositionDefined(crossAxis) && + YGNodeAlignItem(node, child) == YGAlignCenter) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]]) / 2.0f, leading[crossAxis]); } else if ( - !YGNodeIsLeadingPosDefined(child, crossAxis) && + !child->isLeadingPositionDefined(crossAxis) && ((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^ (node->getStyle().flexWrap == YGWrapWrapReverse))) { child->setLayoutPosition( @@ -2498,7 +2500,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, continue; } if (child->getStyle().positionType == YGPositionTypeAbsolute && - YGNodeIsLeadingPosDefined(child, mainAxis)) { + child->isLeadingPositionDefined(mainAxis)) { if (performLayout) { // In case the child is position absolute and has left/top being // defined, we override the position to whatever the user said @@ -2593,7 +2595,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, // top/left/bottom/right // set, override all the previously computed positions to set it // correctly. - const bool isChildLeadingPosDefined = YGNodeIsLeadingPosDefined(child, crossAxis); + const bool isChildLeadingPosDefined = + child->isLeadingPositionDefined(crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( child->getLeadingPosition(crossAxis, availableInnerCrossDim) + From bf7f6df985fc5767b9bd59a7e363272577aed231 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:40 -0800 Subject: [PATCH 013/143] Moved is isTrailingPos defined as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6683190 fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea --- ReactCommon/yoga/yoga/YGNode.cpp | 8 ++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 19 ++++--------------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 449a8e8993..8d9527a0b8 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -110,6 +110,14 @@ bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) { ->unit != YGUnitUndefined; } +bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) { + return (YGFlexDirectionIsRow(axis) && + YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined) + ->unit != YGUnitUndefined) || + YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined) + ->unit != YGUnitUndefined; +} + // Setters void YGNode::setContext(void* context) { diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 20243d5127..866c21ed1e 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -78,6 +78,7 @@ struct YGNode { YGValue getResolvedDimension(int index); float getLeadingPosition(const YGFlexDirection axis, const float axisSize); bool isLeadingPositionDefined(const YGFlexDirection axis); + bool isTrailingPosDefined(const YGFlexDirection axis); // Setters diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 45c6e34db3..494535fb44 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -999,17 +999,6 @@ static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDi return !YGFloatIsUndefined(value) && value >= 0.0f; } - -static inline bool YGNodeIsTrailingPosDefined(const YGNodeRef node, const YGFlexDirection axis) { - return (YGFlexDirectionIsRow(axis) && - YGComputedEdgeValue( - node->getStyle().position, YGEdgeEnd, &YGValueUndefined) - ->unit != YGUnitUndefined) || - YGComputedEdgeValue( - node->getStyle().position, trailing[axis], &YGValueUndefined) - ->unit != YGUnitUndefined; -} - static float YGNodeTrailingPosition(const YGNodeRef node, const YGFlexDirection axis, const float axisSize) { @@ -1342,7 +1331,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, // on the left/right // offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionRow) && - YGNodeIsTrailingPosDefined(child, YGFlexDirectionRow)) { + child->isTrailingPosDefined(YGFlexDirectionRow)) { childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (YGNodeLeadingBorder(node, YGFlexDirectionRow) + YGNodeTrailingBorder(node, YGFlexDirectionRow)) - @@ -1361,7 +1350,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, // based on the top/bottom // offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && - YGNodeIsTrailingPosDefined(child, YGFlexDirectionColumn)) { + child->isTrailingPosDefined(YGFlexDirectionColumn)) { childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (YGNodeLeadingBorder(node, YGFlexDirectionColumn) + YGNodeTrailingBorder(node, YGFlexDirectionColumn)) - @@ -1430,7 +1419,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, "abs-layout", config); - if (YGNodeIsTrailingPosDefined(child, mainAxis) && + if (child->isTrailingPosDefined(mainAxis) && !child->isLeadingPositionDefined(mainAxis)) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[mainAxis]] - @@ -1457,7 +1446,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, leading[mainAxis]); } - if (YGNodeIsTrailingPosDefined(child, crossAxis) && + if (child->isTrailingPosDefined(crossAxis) && !child->isLeadingPositionDefined(crossAxis)) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[crossAxis]] - From 24885b3504d1b97ae2fb0a1d118189aa839b2369 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:41 -0800 Subject: [PATCH 014/143] Moved getTrailingPosition function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6683205 fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e --- ReactCommon/yoga/yoga/YGNode.cpp | 19 ++++++++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 33 +++++++------------------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 8d9527a0b8..a3fcc113f4 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -102,6 +102,25 @@ float YGNode::getLeadingPosition( : YGResolveValue(*leadingPosition, axisSize); } +float YGNode::getTrailingPosition( + const YGFlexDirection axis, + const float axisSize) { + if (YGFlexDirectionIsRow(axis)) { + const YGValue* trailingPosition = + YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined); + if (trailingPosition->unit != YGUnitUndefined) { + return YGResolveValue(*trailingPosition, axisSize); + } + } + + const YGValue* trailingPosition = + YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined); + + return trailingPosition->unit == YGUnitUndefined + ? 0.0f + : YGResolveValue(*trailingPosition, axisSize); +} + bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) { return (YGFlexDirectionIsRow(axis) && YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined) diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 866c21ed1e..bd99b1fe7b 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -79,6 +79,7 @@ struct YGNode { float getLeadingPosition(const YGFlexDirection axis, const float axisSize); bool isLeadingPositionDefined(const YGFlexDirection axis); bool isTrailingPosDefined(const YGFlexDirection axis); + float getTrailingPosition(const YGFlexDirection axis, const float axisSize); // Setters diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 494535fb44..ddfe3faabe 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -999,25 +999,6 @@ static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDi return !YGFloatIsUndefined(value) && value >= 0.0f; } -static float YGNodeTrailingPosition(const YGNodeRef node, - const YGFlexDirection axis, - const float axisSize) { - if (YGFlexDirectionIsRow(axis)) { - const YGValue* trailingPosition = YGComputedEdgeValue( - node->getStyle().position, YGEdgeEnd, &YGValueUndefined); - if (trailingPosition->unit != YGUnitUndefined) { - return YGResolveValue(*trailingPosition, axisSize); - } - } - - const YGValue* trailingPosition = YGComputedEdgeValue( - node->getStyle().position, trailing[axis], &YGValueUndefined); - - return trailingPosition->unit == YGUnitUndefined - ? 0.0f - : YGResolveValue(*trailingPosition, axisSize); -} - static float YGNodeBoundAxisWithinMinAndMax(const YGNodeRef node, const YGFlexDirection axis, const float value, @@ -1079,7 +1060,7 @@ static float YGNodeRelativePosition(const YGNodeRef node, const float axisSize) { return node->isLeadingPositionDefined(axis) ? node->getLeadingPosition(axis, axisSize) - : -YGNodeTrailingPosition(node, axis, axisSize); + : -node->getTrailingPosition(axis, axisSize); } static void YGConstrainMaxSizeForMode(const YGNodeRef node, @@ -1336,7 +1317,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, (YGNodeLeadingBorder(node, YGFlexDirectionRow) + YGNodeTrailingBorder(node, YGFlexDirectionRow)) - (child->getLeadingPosition(YGFlexDirectionRow, width) + - YGNodeTrailingPosition(child, YGFlexDirectionRow, width)); + child->getTrailingPosition(YGFlexDirectionRow, width)); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } } @@ -1355,7 +1336,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, (YGNodeLeadingBorder(node, YGFlexDirectionColumn) + YGNodeTrailingBorder(node, YGFlexDirectionColumn)) - (child->getLeadingPosition(YGFlexDirectionColumn, height) + - YGNodeTrailingPosition(child, YGFlexDirectionColumn, height)); + child->getTrailingPosition(YGFlexDirectionColumn, height)); childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, height, width); } } @@ -1426,8 +1407,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->getLayout().measuredDimensions[dim[mainAxis]] - YGNodeTrailingBorder(node, mainAxis) - YGNodeTrailingMargin(child, mainAxis, width) - - YGNodeTrailingPosition( - child, mainAxis, isMainAxisRow ? width : height), + child->getTrailingPosition( + mainAxis, isMainAxisRow ? width : height), leading[mainAxis]); } else if ( !child->isLeadingPositionDefined(mainAxis) && @@ -1453,8 +1434,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->getLayout().measuredDimensions[dim[crossAxis]] - YGNodeTrailingBorder(node, crossAxis) - YGNodeTrailingMargin(child, crossAxis, width) - - YGNodeTrailingPosition( - child, crossAxis, isMainAxisRow ? height : width), + child->getTrailingPosition( + crossAxis, isMainAxisRow ? height : width), leading[crossAxis]); } else if ( From 76ac3ce60a54feae64be4bf31a85ea17704c51da Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:45 -0800 Subject: [PATCH 015/143] Moved getLeadingMargin as a function on YGNode Reviewed By: emilsjolander Differential Revision: D6683270 fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c --- ReactCommon/yoga/yoga/Utils.h | 6 ++++ ReactCommon/yoga/yoga/YGNode.cpp | 13 ++++++++ ReactCommon/yoga/yoga/YGNode.h | 2 ++ ReactCommon/yoga/yoga/Yoga.cpp | 53 ++++++++++---------------------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/ReactCommon/yoga/yoga/Utils.h b/ReactCommon/yoga/yoga/Utils.h index 7f3bf76364..7876585964 100644 --- a/ReactCommon/yoga/yoga/Utils.h +++ b/ReactCommon/yoga/yoga/Utils.h @@ -53,3 +53,9 @@ inline YGFlexDirection YGResolveFlexDirection( return flexDirection; } + +static inline float YGResolveValueMargin( + const YGValue value, + const float parentSize) { + return value.unit == YGUnitAuto ? 0 : YGResolveValue(value, parentSize); +} diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index a3fcc113f4..21d5db9c7d 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -137,6 +137,19 @@ bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) { ->unit != YGUnitUndefined; } +float YGNode::getLeadingMargin( + const YGFlexDirection axis, + const float widthSize) { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeStart].unit != YGUnitUndefined) { + return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize); + } + + return YGResolveValueMargin( + *YGComputedEdgeValue(style_.margin, leading[axis], &YGValueZero), + widthSize); +} + // Setters void YGNode::setContext(void* context) { diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index bd99b1fe7b..273015ece4 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -76,10 +76,12 @@ struct YGNode { bool isDirty() const; std::array getResolvedDimensions() const; YGValue getResolvedDimension(int index); + float getLeadingPosition(const YGFlexDirection axis, const float axisSize); bool isLeadingPositionDefined(const YGFlexDirection axis); bool isTrailingPosDefined(const YGFlexDirection axis); float getTrailingPosition(const YGFlexDirection axis, const float axisSize); + float getLeadingMargin(const YGFlexDirection axis, const float widthSize); // Setters diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index ddfe3faabe..5a60d95953 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -151,12 +151,6 @@ const YGValue* YGComputedEdgeValue( return defaultValue; } -static inline float YGResolveValueMargin( - const YGValue value, - const float parentSize) { - return value.unit == YGUnitAuto ? 0 : YGResolveValue(value, parentSize); -} - void* YGNodeGetContext(YGNodeRef node) { return node->getContext(); } @@ -764,24 +758,10 @@ static const std::array pos = {{ YGEdgeLeft, YGEdgeRight, }}; + static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static inline float YGNodeLeadingMargin(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().margin[YGEdgeStart].unit != YGUnitUndefined) { - return YGResolveValueMargin( - node->getStyle().margin[YGEdgeStart], widthSize); - } - - return YGResolveValueMargin( - *YGComputedEdgeValue( - node->getStyle().margin, leading[axis], &YGValueZero), - widthSize); -} - static float YGNodeTrailingMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -878,7 +858,8 @@ static inline float YGNodeTrailingPaddingAndBorder(const YGNodeRef node, static inline float YGNodeMarginForAxis(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGNodeLeadingMargin(node, axis, widthSize) + YGNodeTrailingMargin(node, axis, widthSize); + return node->getLeadingMargin(axis, widthSize) + + YGNodeTrailingMargin(node, axis, widthSize); } static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, @@ -977,7 +958,7 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + - YGNodeLeadingMargin(node, axis, widthSize) + + node->getLeadingMargin(axis, widthSize) + YGNodeTrailingMargin(node, axis, widthSize); } @@ -1103,13 +1084,13 @@ static void YGNodeSetPosition(const YGNodeRef node, const float relativePositionCross = YGNodeRelativePosition(node, crossAxis, crossSize); node->setLayoutPosition( - YGNodeLeadingMargin(node, mainAxis, parentWidth) + relativePositionMain, + node->getLeadingMargin(mainAxis, parentWidth) + relativePositionMain, leading[mainAxis]); node->setLayoutPosition( YGNodeTrailingMargin(node, mainAxis, parentWidth) + relativePositionMain, trailing[mainAxis]); node->setLayoutPosition( - YGNodeLeadingMargin(node, crossAxis, parentWidth) + relativePositionCross, + node->getLeadingMargin(crossAxis, parentWidth) + relativePositionCross, leading[crossAxis]); node->setLayoutPosition( YGNodeTrailingMargin(node, crossAxis, parentWidth) + @@ -1746,11 +1727,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGResolveFlexDirection(YGFlexDirectionColumn, direction); node->setLayoutMargin( - YGNodeLeadingMargin(node, flexRowDirection, parentWidth), YGEdgeStart); + node->getLeadingMargin(flexRowDirection, parentWidth), YGEdgeStart); node->setLayoutMargin( YGNodeTrailingMargin(node, flexRowDirection, parentWidth), YGEdgeEnd); node->setLayoutMargin( - YGNodeLeadingMargin(node, flexColumnDirection, parentWidth), YGEdgeTop); + node->getLeadingMargin(flexColumnDirection, parentWidth), YGEdgeTop); node->setLayoutMargin( YGNodeTrailingMargin(node, flexColumnDirection, parentWidth), YGEdgeBottom); @@ -2478,7 +2459,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, child->setLayoutPosition( child->getLeadingPosition(mainAxis, availableInnerMainDim) + YGNodeLeadingBorder(node, mainAxis) + - YGNodeLeadingMargin(child, mainAxis, availableInnerWidth), + child->getLeadingMargin(mainAxis, availableInnerWidth), pos[mainAxis]); } } else { @@ -2571,7 +2552,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, child->setLayoutPosition( child->getLeadingPosition(crossAxis, availableInnerCrossDim) + YGNodeLeadingBorder(node, crossAxis) + - YGNodeLeadingMargin(child, crossAxis, availableInnerWidth), + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); } // If leading position is not defined or calculations result in Nan, default to border + margin @@ -2579,7 +2560,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( YGNodeLeadingBorder(node, crossAxis) + - YGNodeLeadingMargin(child, crossAxis, availableInnerWidth), + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); } } else { @@ -2751,9 +2732,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)); } if (YGNodeAlignItem(node, child) == YGAlignBaseline) { - const float ascent = - YGBaseline(child) + - YGNodeLeadingMargin(child, YGFlexDirectionColumn, availableInnerWidth); + const float ascent = YGBaseline(child) + + child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + YGNodeMarginForAxis( @@ -2779,8 +2760,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignFlexStart: { child->setLayoutPosition( currentLead + - YGNodeLeadingMargin( - child, crossAxis, availableInnerWidth), + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); break; } @@ -2805,8 +2785,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignStretch: { child->setLayoutPosition( currentLead + - YGNodeLeadingMargin( - child, crossAxis, availableInnerWidth), + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); // Remeasure child with the line height as it as been only measured with the From aa0ecc92a7e1b37484788643c863c806ff65291a Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:46 -0800 Subject: [PATCH 016/143] Moved trailingmargin function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6683313 fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5 --- ReactCommon/yoga/yoga/YGNode.cpp | 13 ++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 2 +- ReactCommon/yoga/yoga/Yoga.cpp | 36 +++++++++----------------------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 21d5db9c7d..0058453ac7 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -150,6 +150,19 @@ float YGNode::getLeadingMargin( widthSize); } +float YGNode::getTrailingMargin( + const YGFlexDirection axis, + const float widthSize) { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { + return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize); + } + + return YGResolveValueMargin( + *YGComputedEdgeValue(style_.margin, trailing[axis], &YGValueZero), + widthSize); +} + // Setters void YGNode::setContext(void* context) { diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 273015ece4..ba93f8598b 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -82,7 +82,7 @@ struct YGNode { bool isTrailingPosDefined(const YGFlexDirection axis); float getTrailingPosition(const YGFlexDirection axis, const float axisSize); float getLeadingMargin(const YGFlexDirection axis, const float widthSize); - + float getTrailingMargin(const YGFlexDirection axis, const float widthSize); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 5a60d95953..f3a837b968 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -762,20 +762,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static float YGNodeTrailingMargin(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().margin[YGEdgeEnd].unit != YGUnitUndefined) { - return YGResolveValueMargin(node->getStyle().margin[YGEdgeEnd], widthSize); - } - - return YGResolveValueMargin( - *YGComputedEdgeValue( - node->getStyle().margin, trailing[axis], &YGValueZero), - widthSize); -} - static float YGNodeLeadingPadding(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -859,7 +845,7 @@ static inline float YGNodeMarginForAxis(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { return node->getLeadingMargin(axis, widthSize) + - YGNodeTrailingMargin(node, axis, widthSize); + node->getTrailingMargin(axis, widthSize); } static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, @@ -959,7 +945,7 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node, const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + node->getLeadingMargin(axis, widthSize) + - YGNodeTrailingMargin(node, axis, widthSize); + node->getTrailingMargin(axis, widthSize); } static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, @@ -1087,14 +1073,13 @@ static void YGNodeSetPosition(const YGNodeRef node, node->getLeadingMargin(mainAxis, parentWidth) + relativePositionMain, leading[mainAxis]); node->setLayoutPosition( - YGNodeTrailingMargin(node, mainAxis, parentWidth) + relativePositionMain, + node->getTrailingMargin(mainAxis, parentWidth) + relativePositionMain, trailing[mainAxis]); node->setLayoutPosition( node->getLeadingMargin(crossAxis, parentWidth) + relativePositionCross, leading[crossAxis]); node->setLayoutPosition( - YGNodeTrailingMargin(node, crossAxis, parentWidth) + - relativePositionCross, + node->getTrailingMargin(crossAxis, parentWidth) + relativePositionCross, trailing[crossAxis]); } @@ -1387,7 +1372,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - YGNodeTrailingBorder(node, mainAxis) - - YGNodeTrailingMargin(child, mainAxis, width) - + child->getTrailingMargin(mainAxis, width) - child->getTrailingPosition( mainAxis, isMainAxisRow ? width : height), leading[mainAxis]); @@ -1414,7 +1399,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - YGNodeTrailingBorder(node, crossAxis) - - YGNodeTrailingMargin(child, crossAxis, width) - + child->getTrailingMargin(crossAxis, width) - child->getTrailingPosition( crossAxis, isMainAxisRow ? height : width), leading[crossAxis]); @@ -1729,12 +1714,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->setLayoutMargin( node->getLeadingMargin(flexRowDirection, parentWidth), YGEdgeStart); node->setLayoutMargin( - YGNodeTrailingMargin(node, flexRowDirection, parentWidth), YGEdgeEnd); + node->getTrailingMargin(flexRowDirection, parentWidth), YGEdgeEnd); node->setLayoutMargin( node->getLeadingMargin(flexColumnDirection, parentWidth), YGEdgeTop); node->setLayoutMargin( - YGNodeTrailingMargin(node, flexColumnDirection, parentWidth), - YGEdgeBottom); + node->getTrailingMargin(flexColumnDirection, parentWidth), YGEdgeBottom); node->setLayoutBorder( YGNodeLeadingBorder(node, flexRowDirection), YGEdgeStart); @@ -2767,8 +2751,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignFlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - YGNodeTrailingMargin( - child, crossAxis, availableInnerWidth) - + child->getTrailingMargin( + crossAxis, availableInnerWidth) - child->getLayout().measuredDimensions[dim[crossAxis]], pos[crossAxis]); break; From 78bac4c75c3a8652efb0347edd831637983f73a8 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 11 Jan 2018 04:47:48 -0800 Subject: [PATCH 017/143] Moved setPosition as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6683387 fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e --- ReactCommon/yoga/yoga/YGNode.cpp | 40 ++++++++++++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 8 +++++ ReactCommon/yoga/yoga/Yoga.cpp | 57 ++++---------------------------- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 0058453ac7..caee38443c 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -326,6 +326,46 @@ void YGNode::setLayoutDimension(float dimension, int index) { layout_.dimensions[index] = dimension; } +// If both left and right are defined, then use left. Otherwise return +// +left or -right depending on which is defined. +float YGNode::relativePosition( + const YGFlexDirection axis, + const float axisSize) { + return isLeadingPositionDefined(axis) ? getLeadingPosition(axis, axisSize) + : -getTrailingPosition(axis, axisSize); +} + +void YGNode::setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float parentWidth) { + /* Root nodes should be always layouted as LTR, so we don't return negative + * values. */ + const YGDirection directionRespectingRoot = + parent_ != nullptr ? direction : YGDirectionLTR; + const YGFlexDirection mainAxis = + YGResolveFlexDirection(style_.flexDirection, directionRespectingRoot); + const YGFlexDirection crossAxis = + YGFlexDirectionCross(mainAxis, directionRespectingRoot); + + const float relativePositionMain = relativePosition(mainAxis, mainSize); + const float relativePositionCross = relativePosition(crossAxis, crossSize); + + setLayoutPosition( + getLeadingMargin(mainAxis, parentWidth) + relativePositionMain, + leading[mainAxis]); + setLayoutPosition( + getTrailingMargin(mainAxis, parentWidth) + relativePositionMain, + trailing[mainAxis]); + setLayoutPosition( + getLeadingMargin(crossAxis, parentWidth) + relativePositionCross, + leading[crossAxis]); + setLayoutPosition( + getTrailingMargin(crossAxis, parentWidth) + relativePositionCross, + trailing[crossAxis]); +} + YGNode::YGNode() : context_(nullptr), print_(nullptr), diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index ba93f8598b..ac81b3bb72 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -31,6 +31,8 @@ struct YGNode { bool isDirty_; std::array resolvedDimensions_; + float relativePosition(const YGFlexDirection axis, const float axisSize); + public: YGNode(); ~YGNode(); @@ -110,6 +112,12 @@ struct YGNode { void setLayoutHadOverflow(bool hadOverflow); void setLayoutDimension(float dimension, int index); + void setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float parentWidth); + // Other methods YGValue marginLeadingValue(const YGFlexDirection axis) const; YGValue marginTrailingValue(const YGFlexDirection axis) const; diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index f3a837b968..a25936c4a5 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1020,16 +1020,6 @@ static void YGNodeSetChildTrailingPosition(const YGNodeRef node, trailing[axis]); } -// If both left and right are defined, then use left. Otherwise return -// +left or -right depending on which is defined. -static float YGNodeRelativePosition(const YGNodeRef node, - const YGFlexDirection axis, - const float axisSize) { - return node->isLeadingPositionDefined(axis) - ? node->getLeadingPosition(axis, axisSize) - : -node->getTrailingPosition(axis, axisSize); -} - static void YGConstrainMaxSizeForMode(const YGNodeRef node, const enum YGFlexDirection axis, const float parentAxisSize, @@ -1054,35 +1044,6 @@ static void YGConstrainMaxSizeForMode(const YGNodeRef node, } } -static void YGNodeSetPosition(const YGNodeRef node, - const YGDirection direction, - const float mainSize, - const float crossSize, - const float parentWidth) { - /* Root nodes should be always layouted as LTR, so we don't return negative values. */ - const YGDirection directionRespectingRoot = - node->getParent() != nullptr ? direction : YGDirectionLTR; - const YGFlexDirection mainAxis = YGResolveFlexDirection( - node->getStyle().flexDirection, directionRespectingRoot); - const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, directionRespectingRoot); - - const float relativePositionMain = YGNodeRelativePosition(node, mainAxis, mainSize); - const float relativePositionCross = YGNodeRelativePosition(node, crossAxis, crossSize); - - node->setLayoutPosition( - node->getLeadingMargin(mainAxis, parentWidth) + relativePositionMain, - leading[mainAxis]); - node->setLayoutPosition( - node->getTrailingMargin(mainAxis, parentWidth) + relativePositionMain, - trailing[mainAxis]); - node->setLayoutPosition( - node->getLeadingMargin(crossAxis, parentWidth) + relativePositionCross, - leading[crossAxis]); - node->setLayoutPosition( - node->getTrailingMargin(crossAxis, parentWidth) + relativePositionCross, - trailing[crossAxis]); -} - static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, const YGNodeRef child, const float width, @@ -1887,11 +1848,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (performLayout) { // Set the initial position (relative to the parent). const YGDirection childDirection = YGNodeResolveDirection(child, direction); - YGNodeSetPosition(child, - childDirection, - availableInnerMainDim, - availableInnerCrossDim, - availableInnerWidth); + child->setPosition( + childDirection, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth); } // Absolute-positioned children don't participate in flex layout. Add them @@ -3477,12 +3438,8 @@ void YGNodeCalculateLayout(const YGNodeRef node, true, "initial", node->getConfig())) { - YGNodeSetPosition( - node, - node->getLayout().direction, - parentWidth, - parentHeight, - parentWidth); + node->setPosition( + node->getLayout().direction, parentWidth, parentHeight, parentWidth); YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f); if (gPrintTree) { From b711ec8c2256b6248058ad94c43d7150b694fd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gregorczyk?= Date: Thu, 11 Jan 2018 13:02:06 -0800 Subject: [PATCH 018/143] (almost) kill fbjsc Reviewed By: johnislarry Differential Revision: D6701327 fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634 --- ReactCommon/cxxreact/JSCExecutor.cpp | 4 ---- ReactCommon/jschelpers/JSCWrapper.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index 75e929fa9c..91c7716cbb 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -39,10 +39,6 @@ #include "RecoverableError.h" #include "SystraceSection.h" -#if defined(WITH_JSC_MEMORY_PRESSURE) -#include -#endif - #if defined(WITH_FB_JSC_TUNING) && defined(__ANDROID__) #include #endif diff --git a/ReactCommon/jschelpers/JSCWrapper.h b/ReactCommon/jschelpers/JSCWrapper.h index ff9d7890f7..c722199c2d 100644 --- a/ReactCommon/jschelpers/JSCWrapper.h +++ b/ReactCommon/jschelpers/JSCWrapper.h @@ -13,10 +13,6 @@ #include #include -#if WITH_FBJSCEXTENSIONS -#include -#endif - #if defined(JSCINTERNAL) || (!defined(__APPLE__)) #define JSC_IMPORT extern "C" #else From 7697d99c36137deb39d738a6a2a50056f70e6028 Mon Sep 17 00:00:00 2001 From: Alex Dvornikov Date: Thu, 11 Jan 2018 14:11:00 -0800 Subject: [PATCH 019/143] Report module id as string and as double, in case of invalid values are passed to nativeRequire Differential Revision: D6695769 fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a --- ReactCommon/cxxreact/JSCUtils.cpp | 24 +++++++++--------------- ReactCommon/jschelpers/Value.cpp | 9 +++++++++ ReactCommon/jschelpers/Value.h | 9 +++++++++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/ReactCommon/cxxreact/JSCUtils.cpp b/ReactCommon/cxxreact/JSCUtils.cpp index 96ede8f6ae..74942bc629 100644 --- a/ReactCommon/cxxreact/JSCUtils.cpp +++ b/ReactCommon/cxxreact/JSCUtils.cpp @@ -2,6 +2,8 @@ #include "JSCUtils.h" +#include + namespace facebook { namespace react { @@ -17,28 +19,20 @@ std::pair parseNativeRequireParameters( const JSGlobalContextRef& context, const JSValueRef arguments[], size_t argumentCount) { - double moduleId = 0, bundleId = 0; + uint32_t moduleId = 0, bundleId = 0; + // use "getNumber" & "folly::to" to throw explicitely in case of an overflow + // error during conversion if (argumentCount == 1) { - moduleId = Value(context, arguments[0]).asNumber(); + moduleId = folly::to(Value(context, arguments[0]).getNumberOrThrow()); } else if (argumentCount == 2) { - moduleId = Value(context, arguments[0]).asNumber(); - bundleId = Value(context, arguments[1]).asNumber(); + moduleId = folly::to(Value(context, arguments[0]).getNumberOrThrow()); + bundleId = folly::to(Value(context, arguments[1]).getNumberOrThrow()); } else { throw std::invalid_argument("Got wrong number of args"); } - if (moduleId < 0) { - throw std::invalid_argument(folly::to("Received invalid module ID: ", - Value(context, arguments[0]).toString().str())); - } - - if (bundleId < 0) { - throw std::invalid_argument(folly::to("Received invalid bundle ID: ", - Value(context, arguments[1]).toString().str())); - } - - return std::make_pair(static_cast(bundleId), static_cast(moduleId)); + return std::make_pair(bundleId, moduleId); } } diff --git a/ReactCommon/jschelpers/Value.cpp b/ReactCommon/jschelpers/Value.cpp index f084335f30..72e303b18a 100644 --- a/ReactCommon/jschelpers/Value.cpp +++ b/ReactCommon/jschelpers/Value.cpp @@ -191,6 +191,15 @@ Value Value::makeError(JSContextRef ctx, const char *error, const char *stack) } } +void Value::throwTypeException(const std::string &expectedType) const { + std::string wat("TypeError: Expected "); + wat += expectedType; + wat += ", instead got '"; + wat += toString().str(); + wat += "'"; + throw JSException(wat.c_str()); +} + Object::operator Value() const { return Value(m_context, m_obj); } diff --git a/ReactCommon/jschelpers/Value.h b/ReactCommon/jschelpers/Value.h index d78103a841..e7df097096 100644 --- a/ReactCommon/jschelpers/Value.h +++ b/ReactCommon/jschelpers/Value.h @@ -302,6 +302,13 @@ class Value : public noncopyable { } } + double getNumberOrThrow() const { + if (!isNumber()) { + throwTypeException("Number"); + } + return JSC_JSValueToNumber(context(), m_value, nullptr); + } + int32_t asInteger() const { return static_cast(asNumber()); } @@ -355,7 +362,9 @@ class Value : public noncopyable { JSContextRef m_context; JSValueRef m_value; + void throwTypeException(const std::string &expectedType) const; static JSValueRef fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj); + }; } } From 3acb91a1aa06a228f507e8f0e2988f559adefaba Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 11 Jan 2018 18:34:32 -0800 Subject: [PATCH 020/143] Proper check for RCTRootShadowView in RCTUIManager Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense. Reviewed By: mmmulani Differential Revision: D6701107 fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c --- React/Modules/RCTUIManager.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 214d155cfd..8c2d419943 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -541,7 +541,10 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * }); } - if (RCTIsReactRootView(reactTag)) { + if ( + RCTIsReactRootView(reactTag) && + [shadowView isKindOfClass:[RCTRootShadowView class]] + ) { CGSize contentSize = shadowView.frame.size; RCTExecuteOnMainQueue(^{ From 8a157c2519b95d8e125c9586e4d34d0c44d20071 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 11 Jan 2018 18:34:34 -0800 Subject: [PATCH 021/143] Missing moving pieces of RCTSurfaceHostingView Summary: Now it actually works. Reviewed By: mmmulani Differential Revision: D6701105 fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb --- .../RCTSurfaceHostingView.mm | 51 ++++++++++++------- .../RCTSurfaceSizeMeasureMode.h | 12 +++++ .../RCTSurfaceSizeMeasureMode.mm | 38 ++++++++++++++ React/React.xcodeproj/project.pbxproj | 6 +++ 4 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm index 395009e0dd..bfb866c914 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm @@ -61,6 +61,24 @@ - (instancetype)initWithSurface:(RCTSurface *)surface return self; } +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + + CGSize minimumSize; + CGSize maximumSize; + + RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + self.bounds.size, + _sizeMeasureMode, + minimumSize, + maximumSize + ); + + [_surface setMinimumSize:minimumSize + maximumSize:maximumSize]; +} + - (CGSize)intrinsicContentSize { if (RCTSurfaceStageIsPreparing(_stage)) { @@ -78,31 +96,21 @@ - (CGSize)sizeThatFits:(CGSize)size { if (RCTSurfaceStageIsPreparing(_stage)) { if (_activityIndicatorView) { - return _activityIndicatorView.fittingSize; } return CGSizeZero; } - CGSize minimumSize = CGSizeZero; - CGSize maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + CGSize minimumSize; + CGSize maximumSize; - if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) { - minimumSize.width = size.width; - maximumSize.width = size.width; - } - else if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) { - maximumSize.width = size.width; - } - - if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) { - minimumSize.height = size.height; - maximumSize.height = size.height; - } - else if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) { - maximumSize.height = size.height; - } + RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + size, + _sizeMeasureMode, + minimumSize, + maximumSize + ); return [_surface sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize]; @@ -144,6 +152,8 @@ - (void)setIsActivityIndicatorViewVisible:(BOOL)visible return; } + _isActivityIndicatorViewVisible = visible; + if (visible) { if (_activityIndicatorViewFactory) { _activityIndicatorView = _activityIndicatorViewFactory(); @@ -165,6 +175,8 @@ - (void)setIsSurfaceViewVisible:(BOOL)visible return; } + _isSurfaceViewVisible = visible; + if (visible) { _surfaceView = _surface.view; _surfaceView.frame = self.bounds; @@ -182,7 +194,7 @@ - (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorV { _activityIndicatorViewFactory = activityIndicatorViewFactory; if (_isActivityIndicatorViewVisible) { - _isActivityIndicatorViewVisible = NO; + self.isActivityIndicatorViewVisible = NO; self.isActivityIndicatorViewVisible = YES; } } @@ -191,6 +203,7 @@ - (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorV - (void)_invalidateLayout { + [self invalidateIntrinsicContentSize]; [self.superview setNeedsLayout:YES]; } diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h index 7fabc5d01f..e09eecc43b 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h @@ -9,6 +9,8 @@ #import +#import + /** * Bitmask defines how size constrains from `-[UIView sizeThatFits:]` * are translated to `-[RCTSurface sizeThatFitsMinimumSize:maximumSize:]`. @@ -21,3 +23,13 @@ typedef NS_OPTIONS(NSInteger, RCTSurfaceSizeMeasureMode) { RCTSurfaceSizeMeasureModeHeightExact = 1 << 2, RCTSurfaceSizeMeasureModeHeightAtMost = 2 << 2, }; + +/** + * Returns size constraints based on `size` and `sizeMeasureMode`. + */ +RCT_EXTERN void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + CGSize size, + RCTSurfaceSizeMeasureMode sizeMeasureMode, + CGSize &minimumSize, + CGSize &maximumSize +); diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm new file mode 100644 index 0000000000..22cada768f --- /dev/null +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm @@ -0,0 +1,38 @@ +/** + * 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 + +#import "RCTSurfaceSizeMeasureMode.h" + +void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + CGSize size, + RCTSurfaceSizeMeasureMode sizeMeasureMode, + CGSize &minimumSize, + CGSize &maximumSize +) { + minimumSize = CGSizeZero; + maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + + if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) { + minimumSize.width = size.width; + maximumSize.width = size.width; + } + else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) { + maximumSize.width = size.width; + } + + if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) { + minimumSize.height = size.height; + maximumSize.height = size.height; + } + else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) { + maximumSize.height = size.height; + } +} diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 9fbbb7bb54..3edd0b0fec 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -1046,6 +1046,8 @@ 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; 705EDE2922107DD0000CAA67 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2722107DD0000CAA67 /* Utils.h */; }; 705EDE2A22107DD0000CAA67 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2822107DD0000CAA67 /* Utils.cpp */; }; + 705EDE2C221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */; }; + 705EDE2D221082D9000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */; }; 830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; }; 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; }; 83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8B1B62640A00BE0E65 /* RCTModalHostView.m */; }; @@ -2080,6 +2082,7 @@ 702B7FFB221C88BB0027174A /* RCTMouseEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMouseEvent.m; sourceTree = ""; }; 705EDE2722107DD0000CAA67 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; 705EDE2822107DD0000CAA67 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = ""; }; + 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceSizeMeasureMode.mm; sourceTree = ""; }; 830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; }; 830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; }; 830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; }; @@ -2623,6 +2626,7 @@ 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */, 594F0A301FD23228007FBE96 /* RCTSurfaceHostingView.mm */, 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */, + 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */, ); path = SurfaceHostingView; sourceTree = ""; @@ -3918,6 +3922,7 @@ 2D3B5E991D9B089A00451313 /* RCTDisplayLink.m in Sources */, 2D3B5EA11D9B08B600451313 /* RCTModuleData.mm in Sources */, 590D7C001EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */, + 705EDE2D221082D9000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */, 2D3B5EAE1D9B08F800451313 /* RCTEventEmitter.m in Sources */, 2D3B5ECA1D9B095F00451313 /* RCTComponentData.m in Sources */, 2D3B5EA31D9B08BE00451313 /* RCTParserUtils.m in Sources */, @@ -4231,6 +4236,7 @@ A2440AA31DF8D854006E7BFC /* RCTReloadCommand.m in Sources */, 3DF1BE821F26576400068F1A /* JSCTracing.cpp in Sources */, 6577348F1EE8354A00A0E9EA /* RCTInspector.mm in Sources */, + 705EDE2C221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */, 13A0C2891B74F71200B29F6F /* RCTDevLoadingView.m in Sources */, 13B07FF21A69327A00A75B9A /* RCTTiming.m in Sources */, 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */, From c66e5acb94a32064cdab02b58dfaad99eca2f3df Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 14 Jan 2018 19:32:24 -0800 Subject: [PATCH 022/143] Prettier for Text.js Summary: Trivial. Reviewed By: sahrens Differential Revision: D6715229 fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4 --- Libraries/Text/Text.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index d5582890a2..c86c7a3d7f 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -8,6 +8,7 @@ * * @providesModule Text * @flow + * @format */ 'use strict'; @@ -423,10 +424,10 @@ const Text = createReactClass({ return {isInAParentText: true}; }, childContextTypes: { - isInAParentText: PropTypes.bool + isInAParentText: PropTypes.bool, }, contextTypes: { - isInAParentText: PropTypes.bool + isInAParentText: PropTypes.bool, }, /** * Only assigned if touch is needed. @@ -449,10 +450,11 @@ const Text = createReactClass({ if (this.props.onStartShouldSetResponder || this._hasPressHandler()) { if (!this._handlers) { this._handlers = { - onStartShouldSetResponder: (): bool => { - const shouldSetFromProps = this.props.onStartShouldSetResponder && - // $FlowFixMe(>=0.41.0) - this.props.onStartShouldSetResponder(); + onStartShouldSetResponder: (): boolean => { + const shouldSetFromProps = + this.props.onStartShouldSetResponder && + // $FlowFixMe(>=0.41.0) + this.props.onStartShouldSetResponder(); const setResponder = shouldSetFromProps || this._hasPressHandler(); if (setResponder && !this.touchableHandleActivePressIn) { // Attach and bind all the other handlers only the first time a touch @@ -463,7 +465,10 @@ const Text = createReactClass({ } } this.touchableHandleActivePressIn = () => { - if (this.props.suppressHighlighting || !this._hasPressHandler()) { + if ( + this.props.suppressHighlighting || + !this._hasPressHandler() + ) { return; } this.setState({ @@ -472,7 +477,10 @@ const Text = createReactClass({ }; this.touchableHandleActivePressOut = () => { - if (this.props.suppressHighlighting || !this._hasPressHandler()) { + if ( + this.props.suppressHighlighting || + !this._hasPressHandler() + ) { return; } this.setState({ @@ -514,12 +522,15 @@ const Text = createReactClass({ this.props.onResponderTerminate && this.props.onResponderTerminate.apply(this, arguments); }.bind(this), - onResponderTerminationRequest: function(): bool { + onResponderTerminationRequest: function(): boolean { // Allow touchable or props.onResponderTerminationRequest to deny // the request var allowTermination = this.touchableHandleResponderTerminationRequest(); if (allowTermination && this.props.onResponderTerminationRequest) { - allowTermination = this.props.onResponderTerminationRequest.apply(this, arguments); + allowTermination = this.props.onResponderTerminationRequest.apply( + this, + arguments, + ); } return allowTermination; }.bind(this), @@ -534,7 +545,7 @@ const Text = createReactClass({ if (newProps.selectionColor != null) { newProps = { ...newProps, - selectionColor: processColor(newProps.selectionColor) + selectionColor: processColor(newProps.selectionColor), }; } if (Touchable.TOUCH_TARGET_DEBUG && newProps.onPress) { @@ -556,13 +567,13 @@ type RectOffset = { left: number, right: number, bottom: number, -} +}; var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; var RCTText = createReactNativeComponentClass( viewConfig.uiViewClassName, - () => viewConfig + () => viewConfig, ); var RCTVirtualText = RCTText; From 86d9d5862fc4f90479f5a6acb8096668c1e26084 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 14 Jan 2018 19:32:31 -0800 Subject: [PATCH 023/143] Slight modernizing of Text.js to make it compatible with coming changes Reviewed By: sahrens Differential Revision: D6688488 fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c --- Libraries/Text/Text.js | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index c86c7a3d7f..ed53b43d79 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -15,37 +15,20 @@ const ColorPropType = require('ColorPropType'); const EdgeInsetsPropType = require('EdgeInsetsPropType'); const NativeMethodsMixin = require('NativeMethodsMixin'); -const Platform = require('Platform'); const React = require('React'); const PropTypes = require('prop-types'); -const ReactNativeViewAttributes = require('ReactNativeViewAttributes'); const StyleSheetPropType = require('StyleSheetPropType'); const TextStylePropTypes = require('TextStylePropTypes'); const Touchable = require('Touchable'); +const UIManager = require('UIManager'); const createReactClass = require('create-react-class'); -const createReactNativeComponentClass = require('createReactNativeComponentClass'); +const requireNativeComponent = require('requireNativeComponent'); const mergeFast = require('mergeFast'); const processColor = require('processColor'); const stylePropType = StyleSheetPropType(TextStylePropTypes); -const viewConfig = { - validAttributes: mergeFast(ReactNativeViewAttributes.UIView, { - isHighlighted: true, - numberOfLines: true, - ellipsizeMode: true, - allowFontScaling: true, - disabled: true, - selectable: true, - selectionColor: true, - adjustsFontSizeToFit: true, - minimumFontScale: true, - textBreakStrategy: true, - }), - uiViewClassName: 'RCTText', -}; - /** * A React component for displaying text. * @@ -419,7 +402,6 @@ const Text = createReactClass({ }); }, mixins: [NativeMethodsMixin], - viewConfig: viewConfig, getChildContext(): Object { return {isInAParentText: true}; }, @@ -569,21 +551,11 @@ type RectOffset = { bottom: number, }; -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; - -var RCTText = createReactNativeComponentClass( - viewConfig.uiViewClassName, - () => viewConfig, -); -var RCTVirtualText = RCTText; +const PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; -if (Platform.OS === 'android') { - RCTVirtualText = createReactNativeComponentClass('RCTVirtualText', () => ({ - validAttributes: mergeFast(ReactNativeViewAttributes.UIView, { - isHighlighted: true, - }), - uiViewClassName: 'RCTVirtualText', - })); -} +const RCTText = requireNativeComponent('RCTText'); +const RCTVirtualText = UIManager.RCTVirtualText + ? requireNativeComponent('RCTVirtualText') + : RCTText; module.exports = Text; From 49e37611f6d6bbeb55fb80f5e4d2bffa97dd0f43 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 14 Jan 2018 19:32:22 -0800 Subject: [PATCH 024/143] Prettier for TextInput.js Summary: Trivial. Reviewed By: sahrens Differential Revision: D6690929 fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670 --- Libraries/Components/TextInput/TextInput.js | 31 ++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 0ecb7f466e..ffe3212b6d 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -8,6 +8,7 @@ * * @providesModule TextInput * @flow + * @format */ 'use strict'; @@ -389,8 +390,8 @@ const TextInput = createReactClass({ */ password: PropTypes.bool, /** - * The highlight and cursor color of the text input. - */ + * The highlight and cursor color of the text input. + */ selectionColor: ColorPropType, /** * An instance of `DocumentSelectionState`, this is some state that is responsible for @@ -577,7 +578,7 @@ const TextInput = createReactClass({ } else if (this.isFocused()) { this.blur(); } - } + }, ); if (this.props.autoFocus) { this.context.onFocusRequested(this); @@ -592,7 +593,7 @@ const TextInput = createReactClass({ }, getChildContext: function(): Object { - return { isInAParentText: true }; + return {isInAParentText: true}; }, childContextTypes: { @@ -603,7 +604,7 @@ const TextInput = createReactClass({ * Removes all text from the `TextInput`. */ clear: function() { - this.setNativeProps({ text: '' }); + this.setNativeProps({text: ''}); }, render: function() { @@ -620,8 +621,8 @@ const TextInput = createReactClass({ return typeof this.props.value === 'string' ? this.props.value : typeof this.props.defaultValue === 'string' - ? this.props.defaultValue - : ''; + ? this.props.defaultValue + : ''; }, _setNativeRef: function(ref: any) { @@ -648,7 +649,7 @@ const TextInput = createReactClass({ const error = new Error( 'TextInput prop `' + propKey + - '` is only supported with multiline.' + '` is only supported with multiline.', ); warning(false, '%s', error.stack); } @@ -674,10 +675,14 @@ const TextInput = createReactClass({ React.Children.forEach(children, () => ++childCount); invariant( !(props.value && childCount), - 'Cannot specify both value and children.' + 'Cannot specify both value and children.', ); if (childCount >= 1) { - children = {children}; + children = ( + + {children} + + ); } if (props.inputView) { children = [children, props.inputView]; @@ -732,7 +737,7 @@ const TextInput = createReactClass({ React.Children.forEach(children, () => ++childCount); invariant( !(this.props.value && childCount), - 'Cannot specify both value and children.' + 'Cannot specify both value and children.', ); if (childCount > 1) { children = {children}; @@ -843,7 +848,7 @@ const TextInput = createReactClass({ // Selection is also a controlled prop, if the native value doesn't match // JS, update to the JS value. - const { selection } = this.props; + const {selection} = this.props; if ( this._lastNativeSelection && selection && @@ -887,4 +892,4 @@ var styles = StyleSheet.create({ }, }); -module.exports = TextInput; +module.exports = TextInput; \ No newline at end of file From a34a30ce327ac686cfb596bc40555b2b0c5524e9 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 14 Jan 2018 19:32:28 -0800 Subject: [PATCH 025/143] Modern TextInput's render function for iOS Reviewed By: sahrens Differential Revision: D6690930 fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa --- Libraries/Components/TextInput/TextInput.js | 67 +++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index ffe3212b6d..94c1f4ffc1 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -52,9 +52,14 @@ const onlyMultiline = { if (Platform.OS === 'android') { var AndroidTextInput = requireNativeComponent('AndroidTextInput', null); } else if (Platform.OS === 'ios' || Platform.OS === 'macos') { - var RCTMultilineTextInputView = requireNativeComponent('RCTMultilineTextInputView', null); - var RCTSinglelineTextInputView = requireNativeComponent('RCTTextField', null); - var RCTSecureTextField = requireNativeComponent('RCTSecureTextField', null); + var RCTMultilineTextInputView = requireNativeComponent( + 'RCTMultilineTextInputView', + null, + ); + var RCTSinglelineTextInputView = requireNativeComponent( + 'RCTSinglelineTextInputView', + null, + ); } type Event = Object; @@ -609,7 +614,9 @@ const TextInput = createReactClass({ render: function() { if (Platform.OS === 'ios') { - return this._renderIOS(); + return UIManager.RCTVirtualText + ? this._renderIOS() + : this._renderIOSLegacy(); } else if (Platform.OS === 'macos') { return this._renderIOS(); } else if (Platform.OS === 'android') { @@ -629,7 +636,7 @@ const TextInput = createReactClass({ this._inputRef = ref; }, - _renderIOS: function() { + _renderIOSLegacy: function() { var textContainer; var props = Object.assign({}, this.props); @@ -722,6 +729,56 @@ const TextInput = createReactClass({ ); }, + _renderIOS: function() { + var props = Object.assign({}, this.props); + props.style = [this.props.style]; + + if (props.selection && props.selection.end == null) { + props.selection = { + start: props.selection.start, + end: props.selection.start, + }; + } + + const RCTTextInputView = props.multiline + ? RCTMultilineTextInputView + : RCTSinglelineTextInputView; + + if (props.multiline) { + props.style.unshift(styles.multilineInput); + } + + const textContainer = ( + + ); + + return ( + + {textContainer} + + ); + }, + _renderAndroid: function() { const props = Object.assign({}, this.props); props.style = [this.props.style]; From a2d4757a570fd0ae393fe51935ca95e0ba4910f2 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 14 Jan 2018 19:32:33 -0800 Subject: [PATCH 026/143] Generalization of `isInAParentText` context Summary: Currently `isInAParentText` context works as imaginary `isInAAncestorText` context (not like a real `isInAParentText`). Let's imagine we have hierarchy like: `View -> Text -> Text* -> View* -> Text* -> Text* -> View*` With current implementation all nodes marked with asterisk have `isInAParentText` context, which is incorrect (because some of them actually in View context). With the new implemetations it will work like this: `View -> Text -> Text* -> View* -> Text -> Text* -> View*` So, only nodes which have (or ) as a parent will have `isInAParentText` context. This change allows to select proper `Text` vs. `VirtualText` component in cases where and components can interleave each other. Reviewed By: sahrens Differential Revision: D6690495 fbshipit-source-id: f7c59b23d0eaf68a1d08036b858d99c9547f7878 --- Libraries/Components/TextInput/TextInput.js | 22 ++++++++++++-------- Libraries/Components/View/View.js | 15 +++++++++----- Libraries/Components/View/ViewContext.js | 23 +++++++++++++++++++++ Libraries/Image/Image.android.js | 12 ++++------- Libraries/Text/Text.js | 17 ++++++++------- 5 files changed, 59 insertions(+), 30 deletions(-) create mode 100644 Libraries/Components/View/ViewContext.js diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 94c1f4ffc1..a68b33d933 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -32,6 +32,7 @@ const TimerMixin = require('react-timer-mixin'); const TouchableWithoutFeedback = require('TouchableWithoutFeedback'); const UIManager = require('UIManager'); const ViewPropTypes = require('ViewPropTypes'); +const {ViewContextTypes} = require('ViewContext'); /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error * found when Flow v0.54 was deployed. To see the error delete this comment and @@ -49,6 +50,8 @@ const onlyMultiline = { children: true, }; +import type {ViewChildContext} from 'ViewContext'; + if (Platform.OS === 'android') { var AndroidTextInput = requireNativeComponent('AndroidTextInput', null); } else if (Platform.OS === 'ios' || Platform.OS === 'macos') { @@ -557,11 +560,6 @@ const TextInput = createReactClass({ ); }, - contextTypes: { - onFocusRequested: PropTypes.func, - focusEmitter: PropTypes.instanceOf(EventEmitter), - }, - _inputRef: (undefined: any), _focusSubscription: (undefined: ?Function), _lastNativeText: (undefined: ?string), @@ -597,12 +595,18 @@ const TextInput = createReactClass({ } }, - getChildContext: function(): Object { - return {isInAParentText: true}; + getChildContext(): ViewChildContext { + return { + isInAParentText: true, + }; }, - childContextTypes: { - isInAParentText: PropTypes.bool, + childContextTypes: ViewContextTypes, + + contextTypes: { + ...ViewContextTypes, + onFocusRequested: PropTypes.func, + focusEmitter: PropTypes.instanceOf(EventEmitter), }, /** diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index f10f183c08..83d6bbbef9 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -13,17 +13,18 @@ const NativeMethodsMixin = require('NativeMethodsMixin'); const Platform = require('Platform'); -const PropTypes = require('prop-types'); const React = require('React'); const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); const ReactNativeViewAttributes = require('ReactNativeViewAttributes'); const ViewPropTypes = require('ViewPropTypes'); +const {ViewContextTypes} = require('ViewContext'); const createReactClass = require('create-react-class'); const invariant = require('fbjs/lib/invariant'); const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; +import type {ViewChildContext} from 'ViewContext'; export type Props = ViewProps; @@ -52,14 +53,18 @@ const View = createReactClass({ */ viewConfig: { uiViewClassName: 'RCTView', - validAttributes: ReactNativeViewAttributes.RCTView + validAttributes: ReactNativeViewAttributes.RCTView, }, - contextTypes: { - isInAParentText: PropTypes.bool, + childContextTypes: ViewContextTypes, + + getChildContext(): ViewChildContext { + return { + isInAParentText: false, + }; }, - render: function() { + render() { invariant( !(this.context.isInAParentText && Platform.OS === 'android'), 'Nesting of within is not supported on Android.'); diff --git a/Libraries/Components/View/ViewContext.js b/Libraries/Components/View/ViewContext.js new file mode 100644 index 0000000000..ed73187b0b --- /dev/null +++ b/Libraries/Components/View/ViewContext.js @@ -0,0 +1,23 @@ +/** + * 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. + * + * @providesModule ViewContext + * @flow + * @format + */ +'use strict'; + +const PropTypes = require('prop-types'); + +export type ViewChildContext = {| + +isInAParentText: boolean, +|}; + +export const ViewContextTypes = { + isInAParentText: PropTypes.bool, +}; diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index 1105134e45..3640f18944 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -21,20 +21,18 @@ var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var Set = require('Set'); var StyleSheet = require('StyleSheet'); var StyleSheetPropType = require('StyleSheetPropType'); -var View = require('View'); var ViewPropTypes = require('ViewPropTypes'); var ViewStylePropTypes = require('ViewStylePropTypes'); var createReactClass = require('create-react-class'); -var filterObject = require('fbjs/lib/filterObject'); var flattenStyle = require('flattenStyle'); var merge = require('merge'); var requireNativeComponent = require('requireNativeComponent'); var resolveAssetSource = require('resolveAssetSource'); -var { - ImageLoader, -} = NativeModules; +const {ViewContextTypes} = require('ViewContext'); + +var {ImageLoader} = NativeModules; let _requestId = 1; function generateRequestId() { @@ -254,9 +252,7 @@ var Image = createReactClass({ validAttributes: ReactNativeViewAttributes.RCTView, }, - contextTypes: { - isInAParentText: PropTypes.bool - }, + contextTypes: ViewContextTypes, render: function() { const source = resolveAssetSource(this.props.source); diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index ed53b43d79..dc5055eff2 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -26,9 +26,12 @@ const createReactClass = require('create-react-class'); const requireNativeComponent = require('requireNativeComponent'); const mergeFast = require('mergeFast'); const processColor = require('processColor'); +const {ViewContextTypes} = require('ViewContext'); const stylePropType = StyleSheetPropType(TextStylePropTypes); +import type {ViewChildContext} from 'ViewContext'; + /** * A React component for displaying text. * @@ -402,15 +405,13 @@ const Text = createReactClass({ }); }, mixins: [NativeMethodsMixin], - getChildContext(): Object { - return {isInAParentText: true}; - }, - childContextTypes: { - isInAParentText: PropTypes.bool, - }, - contextTypes: { - isInAParentText: PropTypes.bool, + getChildContext(): ViewChildContext { + return { + isInAParentText: true, + }; }, + childContextTypes: ViewContextTypes, + contextTypes: ViewContextTypes, /** * Only assigned if touch is needed. */ From 17c769cfe4d2876fda513a4eac5272ee811d41a0 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 05:33:37 -0800 Subject: [PATCH 027/143] Refactored the flexbox step to determine available space in main and cross dim Reviewed By: emilsjolander Differential Revision: D6693777 fbshipit-source-id: d6c87670e74bdc22b32916c2d77fe423d831b378 --- ReactCommon/yoga/yoga/Yoga.cpp | 51 +++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index a25936c4a5..9c40451579 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1557,6 +1557,39 @@ static void YGZeroOutLayoutRecursivly(const YGNodeRef node) { } } +static float YGNodeCalculateAvailableInnerDim( + const YGNodeRef node, + YGFlexDirection axis, + float availableDim, + float parentDim) { + YGFlexDirection direction = + YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn; + YGDimension dimension = + YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; + + const float margin = YGNodeMarginForAxis(node, direction, parentDim); + const float paddingAndBorder = + YGNodePaddingAndBorderForAxis(node, direction, parentDim); + + float availableInnerDim = availableDim - margin - paddingAndBorder; + // Max dimension overrides predefined dimension value; Min dimension in turn + // overrides both of the above + if (!YGFloatIsUndefined(availableInnerDim)) { + // We want to make sure our available height does not violate min and max + // constraints + const float minInnerDim = + YGResolveValue(node->getStyle().minDimensions[dimension], parentDim) - + paddingAndBorder; + const float maxInnerDim = + YGResolveValue(node->getStyle().maxDimensions[dimension], parentDim) - + paddingAndBorder; + availableInnerDim = + fmaxf(fminf(availableInnerDim, maxInnerDim), minInnerDim); + } + + return availableInnerDim; +} + // // This is the main routine that implements a subset of the flexbox layout // algorithm @@ -1775,7 +1808,6 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentWidth); const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentWidth); - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS const float minInnerWidth = YGResolveValue( node->getStyle().minDimensions[YGDimensionWidth], parentWidth) - @@ -1795,19 +1827,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; - // Max dimension overrides predefined dimension value; Min dimension in turn overrides both of the - // above - float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - if (!YGFloatIsUndefined(availableInnerWidth)) { - // We want to make sure our available width does not violate min and max constraints - availableInnerWidth = fmaxf(fminf(availableInnerWidth, maxInnerWidth), minInnerWidth); - } + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - if (!YGFloatIsUndefined(availableInnerHeight)) { - // We want to make sure our available height does not violate min and max constraints - availableInnerHeight = fmaxf(fminf(availableInnerHeight, maxInnerHeight), minInnerHeight); - } + float availableInnerWidth = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionRow, availableWidth, parentWidth); + float availableInnerHeight = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionColumn, availableHeight, parentHeight); float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; From 40155288a02c8765eb0b61352257a5ab868ab45a Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:40 -0800 Subject: [PATCH 028/143] Refactored step3 of flexbox algorithm Reviewed By: emilsjolander Differential Revision: D6702749 fbshipit-source-id: 15dcc94ae30ac185e4d1c7d6e3744a40cfa47317 --- ReactCommon/yoga/yoga/Yoga.cpp | 185 ++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 74 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 9c40451579..d4171d619d 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1590,6 +1590,87 @@ static float YGNodeCalculateAvailableInnerDim( return availableInnerDim; } +static void YGNodeComputeFlexBasisForChildren( + const YGNodeRef node, + const float availableInnerWidth, + const float availableInnerHeight, + YGMeasureMode widthMeasureMode, + YGMeasureMode heightMeasureMode, + YGDirection direction, + YGFlexDirection mainAxis, + const YGConfigRef config, + bool performLayout, + float& totalOuterFlexBasis) { + YGNodeRef singleFlexChild = nullptr; + YGVector children = node->getChildren(); + YGMeasureMode measureModeMainDim = + YGFlexDirectionIsRow(mainAxis) ? widthMeasureMode : heightMeasureMode; + // If there is only one child with flexGrow + flexShrink it means we can set + // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the + // child to exactly match the remaining space + if (measureModeMainDim == YGMeasureModeExactly) { + for (auto child : children) { + if (singleFlexChild != nullptr) { + if (YGNodeIsFlex(child)) { + // There is already a flexible child, abort + singleFlexChild = nullptr; + break; + } + } else if ( + child->resolveFlexGrow() > 0.0f && + child->resolveFlexShrink() > 0.0f) { + singleFlexChild = child; + } + } + } + + for (auto child : children) { + child->resolveDimension(); + if (child->getStyle().display == YGDisplayNone) { + YGZeroOutLayoutRecursivly(child); + child->setHasNewLayout(true); + child->setDirty(false); + continue; + } + if (child->getStyle().positionType == YGPositionTypeAbsolute) { + continue; + } + if (performLayout) { + // Set the initial position (relative to the parent). + const YGDirection childDirection = + YGNodeResolveDirection(child, direction); + const float mainDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerWidth + : availableInnerHeight; + const float crossDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerHeight + : availableInnerWidth; + child->setPosition( + childDirection, mainDim, crossDim, availableInnerWidth); + } + if (child == singleFlexChild) { + child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); + child->setLayoutComputedFlexBasis(0); + } else { + YGNodeComputeFlexBasisForChild( + node, + child, + availableInnerWidth, + widthMeasureMode, + availableInnerHeight, + availableInnerWidth, + availableInnerHeight, + heightMeasureMode, + direction, + config); + } + + totalOuterFlexBasis += child->getLayout().computedFlexBasis + + YGNodeMarginForAxis(child, mainAxis, availableInnerWidth); + ; + } +} + // // This is the main routine that implements a subset of the flexbox layout // algorithm @@ -1827,59 +1908,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - - float availableInnerWidth = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionRow, availableWidth, parentWidth); - float availableInnerHeight = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionColumn, availableHeight, parentHeight); - - float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; - const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // If there is only one child with flexGrow + flexShrink it means we can set the - // computedFlexBasis to 0 instead of measuring and shrinking / flexing the child to exactly - // match the remaining space - YGNodeRef singleFlexChild = nullptr; - if (measureModeMainDim == YGMeasureModeExactly) { - for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef child = YGNodeGetChild(node, i); - if (singleFlexChild) { - if (YGNodeIsFlex(child)) { - // There is already a flexible child, abort. - singleFlexChild = nullptr; - break; - } - } else if ( - child->resolveFlexGrow() > 0.0f && - child->resolveFlexShrink() > 0.0f) { - singleFlexChild = child; - } - } - } - - float totalOuterFlexBasis = 0; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef child = node->getChild(i); - if (child->getStyle().display == YGDisplayNone) { - YGZeroOutLayoutRecursivly(child); - child->setHasNewLayout(true); - child->setDirty(false); - continue; - } - child->resolveDimension(); - if (performLayout) { - // Set the initial position (relative to the parent). - const YGDirection childDirection = YGNodeResolveDirection(child, direction); - child->setPosition( - childDirection, - availableInnerMainDim, - availableInnerCrossDim, - availableInnerWidth); - } - + // Make a private linkedlist of absolutely positioned child + for (auto child : node->getChildren()) { // Absolute-positioned children don't participate in flex layout. Add them // to a list that we can process later. if (child->getStyle().positionType == YGPositionTypeAbsolute) { @@ -1893,36 +1923,43 @@ static void YGNodelayoutImpl(const YGNodeRef node, } currentAbsoluteChild = child; child->setNextChild(nullptr); - } else { - if (child == singleFlexChild) { - child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); - child->setLayoutComputedFlexBasis(0); - } else { - YGNodeComputeFlexBasisForChild(node, - child, - availableInnerWidth, - widthMeasureMode, - availableInnerHeight, - availableInnerWidth, - availableInnerHeight, - heightMeasureMode, - direction, - config); - } } - - totalOuterFlexBasis += child->getLayout().computedFlexBasis + - YGNodeMarginForAxis(child, mainAxis, availableInnerWidth); - ; } + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS + + float availableInnerWidth = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionRow, availableWidth, parentWidth); + float availableInnerHeight = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionColumn, availableHeight, parentHeight); + + float availableInnerMainDim = + isMainAxisRow ? availableInnerWidth : availableInnerHeight; + const float availableInnerCrossDim = + isMainAxisRow ? availableInnerHeight : availableInnerWidth; + + float totalOuterFlexBasis = 0; + + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM + + YGNodeComputeFlexBasisForChildren( + node, + availableInnerWidth, + availableInnerHeight, + widthMeasureMode, + heightMeasureMode, + direction, + mainAxis, + config, + performLayout, + totalOuterFlexBasis); + const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined ? false : totalOuterFlexBasis > availableInnerMainDim; if (isNodeFlexWrap && flexBasisOverflows && measureModeMainDim == YGMeasureModeAtMost) { measureModeMainDim = YGMeasureModeExactly; } - // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES // Indexes of children that represent the first and last items in the line. From 63cbc254e2ca37b955fef570ef8154f704ddbf6e Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:43 -0800 Subject: [PATCH 029/143] Moved YGNodeIsFlex as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711536 fbshipit-source-id: e60be7da55e3e8d254eb253c141d219a37a76087 --- ReactCommon/yoga/yoga/YGNode.cpp | 6 ++++++ ReactCommon/yoga/yoga/YGNode.h | 13 ++++++------- ReactCommon/yoga/yoga/Yoga.cpp | 10 ++-------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index caee38443c..c5ddd2f82c 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -590,3 +590,9 @@ float YGNode::resolveFlexShrink() { } return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink; } + +bool YGNode::isNodeFlexible() { + return ( + (style_.positionType == YGPositionTypeRelative) && + (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index ac81b3bb72..ef094237e6 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -111,7 +111,11 @@ struct YGNode { void setLayoutMeasuredDimension(float measuredDimension, int index); void setLayoutHadOverflow(bool hadOverflow); void setLayoutDimension(float dimension, int index); - + void setLayoutDirection(YGDirection direction); + void setLayoutMargin(float margin, int index); + void setLayoutBorder(float border, int index); + void setLayoutPadding(float padding, int index); + void setLayoutPosition(float position, int index); void setPosition( const YGDirection direction, const float mainSize, @@ -131,15 +135,10 @@ struct YGNode { /// Removes the first occurrence of child bool removeChild(YGNodeRef child); void removeChild(uint32_t index); - void setLayoutDirection(YGDirection direction); - void setLayoutMargin(float margin, int index); - void setLayoutBorder(float border, int index); - void setLayoutPadding(float padding, int index); - void setLayoutPosition(float position, int index); - // Other methods void cloneChildrenIfNeeded(); void markDirtyAndPropogate(); float resolveFlexGrow(); float resolveFlexShrink(); + bool isNodeFlexible(); }; diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index d4171d619d..275ccc6cf6 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -915,12 +915,6 @@ static float YGBaseline(const YGNodeRef node) { return baseline + baselineChild->getLayout().position[YGEdgeTop]; } -static inline bool YGNodeIsFlex(const YGNodeRef node) { - return ( - node->getStyle().positionType == YGPositionTypeRelative && - (node->resolveFlexGrow() != 0 || node->resolveFlexShrink() != 0)); -} - static bool YGIsBaselineLayout(const YGNodeRef node) { if (YGFlexDirectionIsColumn(node->getStyle().flexDirection)) { return false; @@ -1611,7 +1605,7 @@ static void YGNodeComputeFlexBasisForChildren( if (measureModeMainDim == YGMeasureModeExactly) { for (auto child : children) { if (singleFlexChild != nullptr) { - if (YGNodeIsFlex(child)) { + if (child->isNodeFlexible()) { // There is already a flexible child, abort singleFlexChild = nullptr; break; @@ -2033,7 +2027,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, sizeConsumedOnCurrentLine += flexBasisWithMinAndMaxConstraints + childMarginMainAxis; itemsOnLine++; - if (YGNodeIsFlex(child)) { + if (child->isNodeFlexible()) { totalFlexGrowFactors += child->resolveFlexGrow(); // Unlike the grow factor, the shrink factor is scaled relative to the child dimension. From 76f43afa74a14828aa3c265922f050b2eede58b9 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:44 -0800 Subject: [PATCH 030/143] Move leading border function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711523 fbshipit-source-id: 76e90083a9dd0728dc9557cc3b0a1f431f3afd5d --- ReactCommon/yoga/yoga/YGNode.cpp | 12 +++++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 35 ++++++++------------------------ 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index c5ddd2f82c..c7e01fd20c 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -596,3 +596,15 @@ bool YGNode::isNodeFlexible() { (style_.positionType == YGPositionTypeRelative) && (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); } + +float YGNode::getLeadingBorder(const YGFlexDirection axis) { + if (YGFlexDirectionIsRow(axis) && + style_.border[YGEdgeStart].unit != YGUnitUndefined && + style_.border[YGEdgeStart].value >= 0.0f) { + return style_.border[YGEdgeStart].value; + } + + return fmaxf( + YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value, + 0.0f); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index ef094237e6..d122133d7b 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -85,6 +85,7 @@ struct YGNode { float getTrailingPosition(const YGFlexDirection axis, const float axisSize); float getLeadingMargin(const YGFlexDirection axis, const float widthSize); float getTrailingMargin(const YGFlexDirection axis, const float widthSize); + float getLeadingBorder(const YGFlexDirection flexDirection); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 275ccc6cf6..9ad8f22d45 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -797,21 +797,6 @@ static float YGNodeTrailingPadding(const YGNodeRef node, 0.0f); } -static float YGNodeLeadingBorder( - const YGNodeRef node, - const YGFlexDirection axis) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().border[YGEdgeStart].unit != YGUnitUndefined && - node->getStyle().border[YGEdgeStart].value >= 0.0f) { - return node->getStyle().border[YGEdgeStart].value; - } - - return fmaxf( - YGComputedEdgeValue(node->getStyle().border, leading[axis], &YGValueZero) - ->value, - 0.0f); -} - static float YGNodeTrailingBorder( const YGNodeRef node, const YGFlexDirection axis) { @@ -832,7 +817,7 @@ static inline float YGNodeLeadingPaddingAndBorder( const YGFlexDirection axis, const float widthSize) { return YGNodeLeadingPadding(node, axis, widthSize) + - YGNodeLeadingBorder(node, axis); + node->getLeadingBorder(axis); } static inline float YGNodeTrailingPaddingAndBorder(const YGNodeRef node, @@ -1235,7 +1220,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, if (child->isLeadingPositionDefined(YGFlexDirectionRow) && child->isTrailingPosDefined(YGFlexDirectionRow)) { childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - - (YGNodeLeadingBorder(node, YGFlexDirectionRow) + + (node->getLeadingBorder(YGFlexDirectionRow) + YGNodeTrailingBorder(node, YGFlexDirectionRow)) - (child->getLeadingPosition(YGFlexDirectionRow, width) + child->getTrailingPosition(YGFlexDirectionRow, width)); @@ -1254,7 +1239,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && child->isTrailingPosDefined(YGFlexDirectionColumn)) { childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - - (YGNodeLeadingBorder(node, YGFlexDirectionColumn) + + (node->getLeadingBorder(YGFlexDirectionColumn) + YGNodeTrailingBorder(node, YGFlexDirectionColumn)) - (child->getLeadingPosition(YGFlexDirectionColumn, height) + child->getTrailingPosition(YGFlexDirectionColumn, height)); @@ -1789,12 +1774,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->setLayoutMargin( node->getTrailingMargin(flexColumnDirection, parentWidth), YGEdgeBottom); - node->setLayoutBorder( - YGNodeLeadingBorder(node, flexRowDirection), YGEdgeStart); + node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); node->setLayoutBorder( YGNodeTrailingBorder(node, flexRowDirection), YGEdgeEnd); - node->setLayoutBorder( - YGNodeLeadingBorder(node, flexColumnDirection), YGEdgeTop); + node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop); node->setLayoutBorder( YGNodeTrailingBorder(node, flexColumnDirection), YGEdgeBottom); @@ -2459,7 +2442,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // (and margin/border). child->setLayoutPosition( child->getLeadingPosition(mainAxis, availableInnerMainDim) + - YGNodeLeadingBorder(node, mainAxis) + + node->getLeadingBorder(mainAxis) + child->getLeadingMargin(mainAxis, availableInnerWidth), pos[mainAxis]); } @@ -2501,7 +2484,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, } else if (performLayout) { child->setLayoutPosition( child->getLayout().position[pos[mainAxis]] + - YGNodeLeadingBorder(node, mainAxis) + leadingMainDim, + node->getLeadingBorder(mainAxis) + leadingMainDim, pos[mainAxis]); } } @@ -2552,7 +2535,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (isChildLeadingPosDefined) { child->setLayoutPosition( child->getLeadingPosition(crossAxis, availableInnerCrossDim) + - YGNodeLeadingBorder(node, crossAxis) + + node->getLeadingBorder(crossAxis) + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); } @@ -2560,7 +2543,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (!isChildLeadingPosDefined || YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( - YGNodeLeadingBorder(node, crossAxis) + + node->getLeadingBorder(crossAxis) + child->getLeadingMargin(crossAxis, availableInnerWidth), pos[crossAxis]); } From 31fa91d538a10e76d52426f0128904cbe1265c40 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:46 -0800 Subject: [PATCH 031/143] Move trailing border function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711666 fbshipit-source-id: fe4fdfc2db59d03beb763317e1a6f9de52f851d4 --- ReactCommon/yoga/yoga/YGNode.cpp | 13 +++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 31 ++++++++----------------------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index c7e01fd20c..ebe733e760 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -608,3 +608,16 @@ float YGNode::getLeadingBorder(const YGFlexDirection axis) { YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value, 0.0f); } + +float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) { + if (YGFlexDirectionIsRow(flexDirection) && + style_.border[YGEdgeEnd].unit != YGUnitUndefined && + style_.border[YGEdgeEnd].value >= 0.0f) { + return style_.border[YGEdgeEnd].value; + } + + return fmaxf( + YGComputedEdgeValue(style_.border, trailing[flexDirection], &YGValueZero) + ->value, + 0.0f); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index d122133d7b..a99580a74e 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -86,6 +86,7 @@ struct YGNode { float getLeadingMargin(const YGFlexDirection axis, const float widthSize); float getTrailingMargin(const YGFlexDirection axis, const float widthSize); float getLeadingBorder(const YGFlexDirection flexDirection); + float getTrailingBorder(const YGFlexDirection flexDirection); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 9ad8f22d45..3b536141d1 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -797,21 +797,6 @@ static float YGNodeTrailingPadding(const YGNodeRef node, 0.0f); } -static float YGNodeTrailingBorder( - const YGNodeRef node, - const YGFlexDirection axis) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().border[YGEdgeEnd].unit != YGUnitUndefined && - node->getStyle().border[YGEdgeEnd].value >= 0.0f) { - return node->getStyle().border[YGEdgeEnd].value; - } - - return fmaxf( - YGComputedEdgeValue(node->getStyle().border, trailing[axis], &YGValueZero) - ->value, - 0.0f); -} - static inline float YGNodeLeadingPaddingAndBorder( const YGNodeRef node, const YGFlexDirection axis, @@ -823,7 +808,8 @@ static inline float YGNodeLeadingPaddingAndBorder( static inline float YGNodeTrailingPaddingAndBorder(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGNodeTrailingPadding(node, axis, widthSize) + YGNodeTrailingBorder(node, axis); + return YGNodeTrailingPadding(node, axis, widthSize) + + node->getTrailingBorder(axis); } static inline float YGNodeMarginForAxis(const YGNodeRef node, @@ -1221,7 +1207,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->isTrailingPosDefined(YGFlexDirectionRow)) { childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (node->getLeadingBorder(YGFlexDirectionRow) + - YGNodeTrailingBorder(node, YGFlexDirectionRow)) - + node->getTrailingBorder(YGFlexDirectionRow)) - (child->getLeadingPosition(YGFlexDirectionRow, width) + child->getTrailingPosition(YGFlexDirectionRow, width)); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); @@ -1240,7 +1226,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->isTrailingPosDefined(YGFlexDirectionColumn)) { childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (node->getLeadingBorder(YGFlexDirectionColumn) + - YGNodeTrailingBorder(node, YGFlexDirectionColumn)) - + node->getTrailingBorder(YGFlexDirectionColumn)) - (child->getLeadingPosition(YGFlexDirectionColumn, height) + child->getTrailingPosition(YGFlexDirectionColumn, height)); childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, height, width); @@ -1311,7 +1297,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->setLayoutPosition( node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - - YGNodeTrailingBorder(node, mainAxis) - + node->getTrailingBorder(mainAxis) - child->getTrailingMargin(mainAxis, width) - child->getTrailingPosition( mainAxis, isMainAxisRow ? width : height), @@ -1338,7 +1324,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->setLayoutPosition( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - - YGNodeTrailingBorder(node, crossAxis) - + node->getTrailingBorder(crossAxis) - child->getTrailingMargin(crossAxis, width) - child->getTrailingPosition( crossAxis, isMainAxisRow ? height : width), @@ -1775,11 +1761,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->getTrailingMargin(flexColumnDirection, parentWidth), YGEdgeBottom); node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); - node->setLayoutBorder( - YGNodeTrailingBorder(node, flexRowDirection), YGEdgeEnd); + node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), YGEdgeEnd); node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop); node->setLayoutBorder( - YGNodeTrailingBorder(node, flexColumnDirection), YGEdgeBottom); + node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( YGNodeLeadingPadding(node, flexRowDirection, parentWidth), YGEdgeStart); From ed3588afa5d7839a8ec4f2b9de06ba79e3657e78 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:50 -0800 Subject: [PATCH 032/143] Resolve direction function is now as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711755 fbshipit-source-id: a0e80596e10f0c7fb7a31b75377da4db846c4bbb --- ReactCommon/yoga/yoga/YGNode.cpp | 9 +++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 14 ++------------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index ebe733e760..112fa28064 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -510,6 +510,15 @@ void YGNode::resolveDimension() { } } +YGDirection YGNode::resolveDirection(const YGDirection parentDirection) { + if (style_.direction == YGDirectionInherit) { + return parentDirection > YGDirectionInherit ? parentDirection + : YGDirectionLTR; + } else { + return style_.direction; + } +} + void YGNode::clearChildren() { children_.clear(); children_.shrink_to_fit(); diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index a99580a74e..3b24ecbc40 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -129,6 +129,7 @@ struct YGNode { YGValue marginTrailingValue(const YGFlexDirection axis) const; YGValue resolveFlexBasisPtr() const; void resolveDimension(); + YGDirection resolveDirection(const YGDirection parentDirection); void clearChildren(); /// Replaces the occurrences of oldChild with newChild void replaceChild(YGNodeRef oldChild, YGNodeRef newChild); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 3b536141d1..67db51bafb 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -837,15 +837,6 @@ static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef chil return align; } -static inline YGDirection YGNodeResolveDirection(const YGNodeRef node, - const YGDirection parentDirection) { - if (node->getStyle().direction == YGDirectionInherit) { - return parentDirection > YGDirectionInherit ? parentDirection : YGDirectionLTR; - } else { - return node->getStyle().direction; - } -} - static float YGBaseline(const YGNodeRef node) { if (node->getBaseline() != nullptr) { const float baseline = node->getBaseline()( @@ -1602,8 +1593,7 @@ static void YGNodeComputeFlexBasisForChildren( } if (performLayout) { // Set the initial position (relative to the parent). - const YGDirection childDirection = - YGNodeResolveDirection(child, direction); + const YGDirection childDirection = child->resolveDirection(direction); const float mainDim = YGFlexDirectionIsRow(mainAxis) ? availableInnerWidth : availableInnerHeight; @@ -1744,7 +1734,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, "YGMeasureModeUndefined"); // Set the resolved resolution in the node's layout. - const YGDirection direction = YGNodeResolveDirection(node, parentDirection); + const YGDirection direction = node->resolveDirection(parentDirection); node->setLayoutDirection(direction); const YGFlexDirection flexRowDirection = YGResolveFlexDirection(YGFlexDirectionRow, direction); From 375cfcc0d579a43dbc2411a66d6f5f3bfdc0dda6 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:51 -0800 Subject: [PATCH 033/143] Moved leading padding function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711830 fbshipit-source-id: d2f6f55ec23b007bb51f8a91385e02236f46dc7b --- ReactCommon/yoga/yoga/YGNode.cpp | 15 +++++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 2 ++ ReactCommon/yoga/yoga/Yoga.cpp | 24 +++--------------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 112fa28064..90bff5de8b 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -630,3 +630,18 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) { ->value, 0.0f); } + +float YGNode::getLeadingPadding( + const YGFlexDirection axis, + const float widthSize) { + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeStart].unit != YGUnitUndefined && + YGResolveValue(style_.padding[YGEdgeStart], widthSize) >= 0.0f) { + return YGResolveValue(style_.padding[YGEdgeStart], widthSize); + } + return fmaxf( + YGResolveValue( + *YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero), + widthSize), + 0.0f); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 3b24ecbc40..71966ad709 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -79,6 +79,7 @@ struct YGNode { std::array getResolvedDimensions() const; YGValue getResolvedDimension(int index); + // Methods related to positions, margin, padding and border float getLeadingPosition(const YGFlexDirection axis, const float axisSize); bool isLeadingPositionDefined(const YGFlexDirection axis); bool isTrailingPosDefined(const YGFlexDirection axis); @@ -87,6 +88,7 @@ struct YGNode { float getTrailingMargin(const YGFlexDirection axis, const float widthSize); float getLeadingBorder(const YGFlexDirection flexDirection); float getTrailingBorder(const YGFlexDirection flexDirection); + float getLeadingPadding(const YGFlexDirection axis, const float widthSize); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 67db51bafb..bb1625616d 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -762,24 +762,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static float YGNodeLeadingPadding(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().padding[YGEdgeStart].unit != YGUnitUndefined && - YGResolveValue(node->getStyle().padding[YGEdgeStart], widthSize) >= - 0.0f) { - return YGResolveValue(node->getStyle().padding[YGEdgeStart], widthSize); - } - - return fmaxf( - YGResolveValue( - *YGComputedEdgeValue( - node->getStyle().padding, leading[axis], &YGValueZero), - widthSize), - 0.0f); -} - static float YGNodeTrailingPadding(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -801,7 +783,7 @@ static inline float YGNodeLeadingPaddingAndBorder( const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGNodeLeadingPadding(node, axis, widthSize) + + return node->getLeadingPadding(axis, widthSize) + node->getLeadingBorder(axis); } @@ -1757,11 +1739,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( - YGNodeLeadingPadding(node, flexRowDirection, parentWidth), YGEdgeStart); + node->getLeadingPadding(flexRowDirection, parentWidth), YGEdgeStart); node->setLayoutPadding( YGNodeTrailingPadding(node, flexRowDirection, parentWidth), YGEdgeEnd); node->setLayoutPadding( - YGNodeLeadingPadding(node, flexColumnDirection, parentWidth), YGEdgeTop); + node->getLeadingPadding(flexColumnDirection, parentWidth), YGEdgeTop); node->setLayoutPadding( YGNodeTrailingPadding(node, flexColumnDirection, parentWidth), YGEdgeBottom); From 2d77b19d958c8d8f45ff0fa867ba5051d033336b Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:53 -0800 Subject: [PATCH 034/143] Move trailing padding function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711897 fbshipit-source-id: fa2e1a8e31242358a6e94aef51368e2c2c58b79d --- ReactCommon/yoga/yoga/YGNode.cpp | 15 +++++++++++++++ ReactCommon/yoga/yoga/YGNode.h | 1 + ReactCommon/yoga/yoga/Yoga.cpp | 24 +++--------------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 90bff5de8b..7b4d98e1c4 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -645,3 +645,18 @@ float YGNode::getLeadingPadding( widthSize), 0.0f); } + +float YGNode::getTrailingPadding( + const YGFlexDirection axis, + const float widthSize) { + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeEnd].unit != YGUnitUndefined && + YGResolveValue(style_.padding[YGEdgeEnd], widthSize) >= 0.0f) { + return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + } + return fmaxf( + YGResolveValue( + *YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero), + widthSize), + 0.0f); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 71966ad709..21a8455645 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -89,6 +89,7 @@ struct YGNode { float getLeadingBorder(const YGFlexDirection flexDirection); float getTrailingBorder(const YGFlexDirection flexDirection); float getLeadingPadding(const YGFlexDirection axis, const float widthSize); + float getTrailingPadding(const YGFlexDirection axis, const float widthSize); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index bb1625616d..a6b89f88d2 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -762,23 +762,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static float YGNodeTrailingPadding(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { - if (YGFlexDirectionIsRow(axis) && - node->getStyle().padding[YGEdgeEnd].unit != YGUnitUndefined && - YGResolveValue(node->getStyle().padding[YGEdgeEnd], widthSize) >= 0.0f) { - return YGResolveValue(node->getStyle().padding[YGEdgeEnd], widthSize); - } - - return fmaxf( - YGResolveValue( - *YGComputedEdgeValue( - node->getStyle().padding, trailing[axis], &YGValueZero), - widthSize), - 0.0f); -} - static inline float YGNodeLeadingPaddingAndBorder( const YGNodeRef node, const YGFlexDirection axis, @@ -790,7 +773,7 @@ static inline float YGNodeLeadingPaddingAndBorder( static inline float YGNodeTrailingPaddingAndBorder(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGNodeTrailingPadding(node, axis, widthSize) + + return node->getTrailingPadding(axis, widthSize) + node->getTrailingBorder(axis); } @@ -1741,12 +1724,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->setLayoutPadding( node->getLeadingPadding(flexRowDirection, parentWidth), YGEdgeStart); node->setLayoutPadding( - YGNodeTrailingPadding(node, flexRowDirection, parentWidth), YGEdgeEnd); + node->getTrailingPadding(flexRowDirection, parentWidth), YGEdgeEnd); node->setLayoutPadding( node->getLeadingPadding(flexColumnDirection, parentWidth), YGEdgeTop); node->setLayoutPadding( - YGNodeTrailingPadding(node, flexColumnDirection, parentWidth), - YGEdgeBottom); + node->getTrailingPadding(flexColumnDirection, parentWidth), YGEdgeBottom); if (node->getMeasure() != nullptr) { YGNodeWithMeasureFuncSetMeasuredDimensions(node, From 46b9c97c1c485cc29836101ce145f75f70dcf2ea Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 15 Jan 2018 10:09:55 -0800 Subject: [PATCH 035/143] Moved leadingpaddingnandborder function as a method on YGNode Reviewed By: emilsjolander Differential Revision: D6711991 fbshipit-source-id: 41ad7191bf8df6fe3131106436dc0c87e9dee297 --- ReactCommon/yoga/yoga/YGNode.cpp | 6 ++++++ ReactCommon/yoga/yoga/YGNode.h | 3 +++ ReactCommon/yoga/yoga/Yoga.cpp | 16 ++++------------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 7b4d98e1c4..223dd91911 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/yoga/YGNode.cpp @@ -660,3 +660,9 @@ float YGNode::getTrailingPadding( widthSize), 0.0f); } + +float YGNode::getLeadingPaddingAndBorder( + const YGFlexDirection axis, + const float widthSize) { + return getLeadingPadding(axis, widthSize) + getLeadingBorder(axis); +} diff --git a/ReactCommon/yoga/yoga/YGNode.h b/ReactCommon/yoga/yoga/YGNode.h index 21a8455645..fab9a3ff0c 100644 --- a/ReactCommon/yoga/yoga/YGNode.h +++ b/ReactCommon/yoga/yoga/YGNode.h @@ -90,6 +90,9 @@ struct YGNode { float getTrailingBorder(const YGFlexDirection flexDirection); float getLeadingPadding(const YGFlexDirection axis, const float widthSize); float getTrailingPadding(const YGFlexDirection axis, const float widthSize); + float getLeadingPaddingAndBorder( + const YGFlexDirection axis, + const float widthSize); // Setters void setContext(void* context); diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index a6b89f88d2..b4f30dd0f1 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -762,14 +762,6 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static inline float YGNodeLeadingPaddingAndBorder( - const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { - return node->getLeadingPadding(axis, widthSize) + - node->getLeadingBorder(axis); -} - static inline float YGNodeTrailingPaddingAndBorder(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -787,8 +779,8 @@ static inline float YGNodeMarginForAxis(const YGNodeRef node, static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGNodeLeadingPaddingAndBorder(node, axis, widthSize) + - YGNodeTrailingPaddingAndBorder(node, axis, widthSize); + return node->getLeadingPaddingAndBorder(axis, widthSize) + + YGNodeTrailingPaddingAndBorder(node, axis, widthSize); } static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) { @@ -1785,11 +1777,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGNodeRef currentAbsoluteChild = nullptr; const float leadingPaddingAndBorderMain = - YGNodeLeadingPaddingAndBorder(node, mainAxis, parentWidth); + node->getLeadingPaddingAndBorder(mainAxis, parentWidth); const float trailingPaddingAndBorderMain = YGNodeTrailingPaddingAndBorder(node, mainAxis, parentWidth); const float leadingPaddingAndBorderCross = - YGNodeLeadingPaddingAndBorder(node, crossAxis, parentWidth); + node->getLeadingPaddingAndBorder(crossAxis, parentWidth); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, parentWidth); const float paddingAndBorderAxisCross = YGNodePaddingAndBorderForAxis(node, crossAxis, parentWidth); From b141e832e1e892d537fa8ea0cc61582fef694944 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 15 Jan 2018 15:35:51 -0800 Subject: [PATCH 036/143] Exposing `setDirtiedFunc` as plain C function YGNodeSetDirtiedFunc Summary: Trivial. Those lines were lost during rebasing of the original commit. Reviewed By: priteshrnandgaonkar Differential Revision: D6717696 fbshipit-source-id: a5dce25427c8977352b3ae7ea01e546a540e0c13 --- RNTester/js/TextExample.ios.js | 12 ++++++++++++ ReactCommon/yoga/yoga/Yoga.cpp | 8 ++++++++ ReactCommon/yoga/yoga/Yoga.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/RNTester/js/TextExample.ios.js b/RNTester/js/TextExample.ios.js index 1980ced736..b4e2a84829 100644 --- a/RNTester/js/TextExample.ios.js +++ b/RNTester/js/TextExample.ios.js @@ -233,8 +233,20 @@ exports.examples = [ render: function() { return ( + The text + + Text Inside + Another text Inside + + Total inseption + + Insepted Text Inside + + + The text should wrap if it goes on multiple lines. See, this is going to the next line. + The text after. ); }, diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index b4f30dd0f1..f357eeaf20 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -175,6 +175,14 @@ void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc) { node->setBaseLineFunc(baselineFunc); } +YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) { + return node->getDirtied(); +} + +void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc) { + node->setDirtiedFunc(dirtiedFunc); +} + YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node) { return node->getPrintFunc(); } diff --git a/ReactCommon/yoga/yoga/Yoga.h b/ReactCommon/yoga/yoga/Yoga.h index 28326019fb..df16fce4cb 100644 --- a/ReactCommon/yoga/yoga/Yoga.h +++ b/ReactCommon/yoga/yoga/Yoga.h @@ -166,6 +166,8 @@ YGMeasureFunc YGNodeGetMeasureFunc(YGNodeRef node); void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); YGBaselineFunc YGNodeGetBaselineFunc(YGNodeRef node); void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc); +YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node); +void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node); void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); bool YGNodeGetHasNewLayout(YGNodeRef node); From d877bc8dc576cf6b7de2c287db7e21f15672fda0 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 15 Jan 2018 15:25:10 -0800 Subject: [PATCH 037/143] Removed unused core from Image.android.js Summary: Trivial. Reviewed By: sahrens Differential Revision: D6721449 fbshipit-source-id: 6ae001d4161167e0e86b1dc134c1621b3974b489 --- Libraries/Image/Image.android.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index 3640f18944..a262131060 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -18,11 +18,9 @@ var NativeModules = require('NativeModules'); var React = require('React'); var PropTypes = require('prop-types'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); -var Set = require('Set'); var StyleSheet = require('StyleSheet'); var StyleSheetPropType = require('StyleSheetPropType'); var ViewPropTypes = require('ViewPropTypes'); -var ViewStylePropTypes = require('ViewStylePropTypes'); var createReactClass = require('create-react-class'); var flattenStyle = require('flattenStyle'); @@ -62,19 +60,6 @@ function generateRequestId() { * More example code in ImageExample.js */ -var ImageViewAttributes = merge(ReactNativeViewAttributes.UIView, { - src: true, - loadingIndicatorSrc: true, - resizeMethod: true, - resizeMode: true, - progressiveRenderingEnabled: true, - fadeDuration: true, - shouldNotifyLoadEvents: true, -}); - -var ViewStyleKeys = new Set(Object.keys(ViewStylePropTypes)); -var ImageSpecificStyleKeys = new Set(Object.keys(ImageStylePropTypes).filter(x => !ViewStyleKeys.has(x))); - var Image = createReactClass({ displayName: 'Image', propTypes: { From 6abd8e4d720dc9f30b65b789f4b13439cf158976 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Tue, 16 Jan 2018 08:57:11 -0800 Subject: [PATCH 038/143] Fix for failing screenshot tests Reviewed By: emilsjolander Differential Revision: D6726745 fbshipit-source-id: 99f91aabe2337b23953724545f97695238f2124e --- ReactCommon/yoga/yoga/Yoga.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index f357eeaf20..c5413af24b 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1553,9 +1553,6 @@ static void YGNodeComputeFlexBasisForChildren( child->setDirty(false); continue; } - if (child->getStyle().positionType == YGPositionTypeAbsolute) { - continue; - } if (performLayout) { // Set the initial position (relative to the parent). const YGDirection childDirection = child->resolveDirection(direction); @@ -1568,6 +1565,10 @@ static void YGNodeComputeFlexBasisForChildren( child->setPosition( childDirection, mainDim, crossDim, availableInnerWidth); } + + if (child->getStyle().positionType == YGPositionTypeAbsolute) { + continue; + } if (child == singleFlexChild) { child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); child->setLayoutComputedFlexBasis(0); From f7ff286aa0d5884e07d52b92e1e50857b21e3eaa Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Tue, 16 Jan 2018 09:31:21 -0800 Subject: [PATCH 039/143] Use vector instead of linked list Reviewed By: emilsjolander Differential Revision: D6722959 fbshipit-source-id: 4e81176802b9a9319bc5f385c824a06be14a83a2 --- ReactCommon/yoga/yoga/Yoga.cpp | 275 +++++++++++++++------------------ 1 file changed, 121 insertions(+), 154 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index c5413af24b..42b9003317 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -1782,9 +1782,6 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float mainAxisParentSize = isMainAxisRow ? parentWidth : parentHeight; const float crossAxisParentSize = isMainAxisRow ? parentHeight : parentWidth; - YGNodeRef firstAbsoluteChild = nullptr; - YGNodeRef currentAbsoluteChild = nullptr; - const float leadingPaddingAndBorderMain = node->getLeadingPaddingAndBorder(mainAxis, parentWidth); const float trailingPaddingAndBorderMain = @@ -1822,27 +1819,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGResolveValue( node->getStyle().maxDimensions[YGDimensionHeight], parentHeight) - paddingAndBorderAxisColumn; + const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; - // Make a private linkedlist of absolutely positioned child - for (auto child : node->getChildren()) { - // Absolute-positioned children don't participate in flex layout. Add them - // to a list that we can process later. - if (child->getStyle().positionType == YGPositionTypeAbsolute) { - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild == nullptr) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild != nullptr) { - currentAbsoluteChild->setNextChild(child); - } - currentAbsoluteChild = child; - child->setNextChild(nullptr); - } - } - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = YGNodeCalculateAvailableInnerDim( @@ -1909,65 +1889,54 @@ static void YGNodelayoutImpl(const YGNodeRef node, float totalFlexGrowFactors = 0; float totalFlexShrinkScaledFactors = 0; - // Maintain a linked list of the child nodes that can shrink and/or grow. - YGNodeRef firstRelativeChild = nullptr; - YGNodeRef currentRelativeChild = nullptr; + // Maintain a vector of the child nodes that can shrink and/or grow. + std::vector relativeChildren; // Add items to the current line until it's full or we run out of items. for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) { const YGNodeRef child = node->getChild(i); - if (child->getStyle().display == YGDisplayNone) { + if (child->getStyle().display == YGDisplayNone || + child->getStyle().positionType == YGPositionTypeAbsolute) { continue; } child->setLineIndex(lineCount); + const float childMarginMainAxis = + YGNodeMarginForAxis(child, mainAxis, availableInnerWidth); + const float flexBasisWithMinAndMaxConstraints = + YGNodeBoundAxisWithinMinAndMax( + child, + mainAxis, + child->getLayout().computedFlexBasis, + mainAxisParentSize); + + // If this is a multi-line flow and this item pushes us over the + // available size, we've + // hit the end of the current line. Break out of the loop and lay out + // the current line. + if (sizeConsumedOnCurrentLineIncludingMinConstraint + + flexBasisWithMinAndMaxConstraints + childMarginMainAxis > + availableInnerMainDim && + isNodeFlexWrap && itemsOnLine > 0) { + break; + } - if (child->getStyle().positionType != YGPositionTypeAbsolute) { - const float childMarginMainAxis = YGNodeMarginForAxis(child, mainAxis, availableInnerWidth); - const float flexBasisWithMaxConstraints = fminf( - YGResolveValue( - child->getStyle().maxDimensions[dim[mainAxis]], - mainAxisParentSize), - child->getLayout().computedFlexBasis); - const float flexBasisWithMinAndMaxConstraints = fmaxf( - YGResolveValue( - child->getStyle().minDimensions[dim[mainAxis]], - mainAxisParentSize), - flexBasisWithMaxConstraints); - - // If this is a multi-line flow and this item pushes us over the - // available size, we've - // hit the end of the current line. Break out of the loop and lay out - // the current line. - if (sizeConsumedOnCurrentLineIncludingMinConstraint + flexBasisWithMinAndMaxConstraints + - childMarginMainAxis > - availableInnerMainDim && - isNodeFlexWrap && itemsOnLine > 0) { - break; - } - - sizeConsumedOnCurrentLineIncludingMinConstraint += - flexBasisWithMinAndMaxConstraints + childMarginMainAxis; - sizeConsumedOnCurrentLine += flexBasisWithMinAndMaxConstraints + childMarginMainAxis; - itemsOnLine++; + sizeConsumedOnCurrentLineIncludingMinConstraint += + flexBasisWithMinAndMaxConstraints + childMarginMainAxis; + sizeConsumedOnCurrentLine += + flexBasisWithMinAndMaxConstraints + childMarginMainAxis; + itemsOnLine++; - if (child->isNodeFlexible()) { - totalFlexGrowFactors += child->resolveFlexGrow(); + if (child->isNodeFlexible()) { + totalFlexGrowFactors += child->resolveFlexGrow(); - // Unlike the grow factor, the shrink factor is scaled relative to the child dimension. - totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * - child->getLayout().computedFlexBasis; - } - - // Store a private linked list of children that need to be layed out. - if (firstRelativeChild == nullptr) { - firstRelativeChild = child; - } - if (currentRelativeChild != nullptr) { - currentRelativeChild->setNextChild(child); - } - currentRelativeChild = child; - child->setNextChild(nullptr); + // Unlike the grow factor, the shrink factor is scaled relative to the + // child dimension. + totalFlexShrinkScaledFactors += + -child->resolveFlexShrink() * child->getLayout().computedFlexBasis; } + + // Store a private linked list of children that need to be layed out. + relativeChildren.push_back(child); } // The total flex factor needs to be floored to 1. @@ -2060,18 +2029,13 @@ static void YGNodelayoutImpl(const YGNodeRef node, // First pass: detect the flex items whose min/max constraints trigger float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != nullptr) { - childFlexBasis = fminf( - YGResolveValue( - currentRelativeChild->getStyle().maxDimensions[dim[mainAxis]], - mainAxisParentSize), - fmaxf( - YGResolveValue( - currentRelativeChild->getStyle() - .minDimensions[dim[mainAxis]], - mainAxisParentSize), - currentRelativeChild->getLayout().computedFlexBasis)); + + for (auto currentRelativeChild : relativeChildren) { + childFlexBasis = YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis, + mainAxisParentSize); if (remainingFreeSpace < 0) { flexShrinkScaledFactor = @@ -2079,14 +2043,15 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Is this child able to shrink? if (flexShrinkScaledFactor != 0) { - baseMainSize = - childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = YGNodeBoundAxis(currentRelativeChild, - mainAxis, - baseMainSize, - availableInnerMainDim, - availableInnerWidth); + baseMainSize = childFlexBasis + + remainingFreeSpace / totalFlexShrinkScaledFactors * + flexShrinkScaledFactor; + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); if (baseMainSize != boundMainSize) { // By excluding this item's size and flex factor from remaining, // this item's @@ -2103,13 +2068,14 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Is this child able to grow? if (flexGrowFactor != 0) { - baseMainSize = - childFlexBasis + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; - boundMainSize = YGNodeBoundAxis(currentRelativeChild, - mainAxis, - baseMainSize, - availableInnerMainDim, - availableInnerWidth); + baseMainSize = childFlexBasis + + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); if (baseMainSize != boundMainSize) { // By excluding this item's size and flex factor from remaining, @@ -2133,18 +2099,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Second pass: resolve the sizes of the flexible items deltaFreeSpace = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != nullptr) { - childFlexBasis = fminf( - YGResolveValue( - currentRelativeChild->getStyle().maxDimensions[dim[mainAxis]], - mainAxisParentSize), - fmaxf( - YGResolveValue( - currentRelativeChild->getStyle() - .minDimensions[dim[mainAxis]], - mainAxisParentSize), - currentRelativeChild->getLayout().computedFlexBasis)); + for (auto currentRelativeChild : relativeChildren) { + childFlexBasis = YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis, + mainAxisParentSize); float updatedMainSize = childFlexBasis; if (remainingFreeSpace < 0) { @@ -2157,38 +2117,39 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (totalFlexShrinkScaledFactors == 0) { childSize = childFlexBasis + flexShrinkScaledFactor; } else { - childSize = - childFlexBasis + - (remainingFreeSpace / totalFlexShrinkScaledFactors) * flexShrinkScaledFactor; + childSize = childFlexBasis + + (remainingFreeSpace / totalFlexShrinkScaledFactors) * + flexShrinkScaledFactor; } - updatedMainSize = YGNodeBoundAxis(currentRelativeChild, - mainAxis, - childSize, - availableInnerMainDim, - availableInnerWidth); + updatedMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + childSize, + availableInnerMainDim, + availableInnerWidth); } } else if (remainingFreeSpace > 0) { flexGrowFactor = currentRelativeChild->resolveFlexGrow(); // Is this child able to grow? if (flexGrowFactor != 0) { - updatedMainSize = - YGNodeBoundAxis(currentRelativeChild, - mainAxis, - childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor, - availableInnerMainDim, - availableInnerWidth); + updatedMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + childFlexBasis + + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor, + availableInnerMainDim, + availableInnerWidth); } } deltaFreeSpace -= updatedMainSize - childFlexBasis; - const float marginMain = - YGNodeMarginForAxis(currentRelativeChild, mainAxis, availableInnerWidth); - const float marginCross = - YGNodeMarginForAxis(currentRelativeChild, crossAxis, availableInnerWidth); + const float marginMain = YGNodeMarginForAxis( + currentRelativeChild, mainAxis, availableInnerWidth); + const float marginCross = YGNodeMarginForAxis( + currentRelativeChild, crossAxis, availableInnerWidth); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -2216,12 +2177,14 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGUnitAuto) { childCrossSize = availableInnerCrossDim; childCrossMeasureMode = YGMeasureModeExactly; - } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, - crossAxis, - availableInnerCrossDim)) { + } else if (!YGNodeIsStyleDimDefined( + currentRelativeChild, + crossAxis, + availableInnerCrossDim)) { childCrossSize = availableInnerCrossDim; - childCrossMeasureMode = - YGFloatIsUndefined(childCrossSize) ? YGMeasureModeUndefined : YGMeasureModeAtMost; + childCrossMeasureMode = YGFloatIsUndefined(childCrossSize) + ? YGMeasureModeUndefined + : YGMeasureModeAtMost; } else { childCrossSize = YGResolveValue( @@ -2263,7 +2226,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGUnitAuto; const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; - const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; + const float childHeight = + !isMainAxisRow ? childMainSize : childCrossSize; const YGMeasureMode childWidthMeasureMode = isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; @@ -2272,17 +2236,18 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Recursively call the layout algorithm for this child with the updated // main size. - YGLayoutNodeInternal(currentRelativeChild, - childWidth, - childHeight, - direction, - childWidthMeasureMode, - childHeightMeasureMode, - availableInnerWidth, - availableInnerHeight, - performLayout && !requiresStretchLayout, - "flex", - config); + YGLayoutNodeInternal( + currentRelativeChild, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + availableInnerWidth, + availableInnerHeight, + performLayout && !requiresStretchLayout, + "flex", + config); node->setLayoutHadOverflow( node->getLayout().hadOverflow | currentRelativeChild->getLayout().hadOverflow); @@ -2866,16 +2831,18 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (performLayout) { // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN - for (currentAbsoluteChild = firstAbsoluteChild; - currentAbsoluteChild != nullptr; - currentAbsoluteChild = currentAbsoluteChild->getNextChild()) { - YGNodeAbsoluteLayoutChild(node, - currentAbsoluteChild, - availableInnerWidth, - isMainAxisRow ? measureModeMainDim : measureModeCrossDim, - availableInnerHeight, - direction, - config); + for (auto child : node->getChildren()) { + if (child->getStyle().positionType != YGPositionTypeAbsolute) { + continue; + } + YGNodeAbsoluteLayoutChild( + node, + child, + availableInnerWidth, + isMainAxisRow ? measureModeMainDim : measureModeCrossDim, + availableInnerHeight, + direction, + config); } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN From 51d15cc43686be3b9ca21a6c17ff0dbd631f0f50 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 16 Jan 2018 12:11:23 -0800 Subject: [PATCH 040/143] Tweaking -[RCTSurface synchronouslyWaitForStage:] Summary: Waiting for layout is now available on main thread. Reviewed By: mmmulani Differential Revision: D6719836 fbshipit-source-id: ef655095e999df5f77e69c5931459cce1aaeb1f0 --- React/Base/Surface/RCTSurface.h | 9 ++++++--- React/Base/Surface/RCTSurface.mm | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/React/Base/Surface/RCTSurface.h b/React/Base/Surface/RCTSurface.h index 603f0e851a..44a53f6569 100644 --- a/React/Base/Surface/RCTSurface.h +++ b/React/Base/Surface/RCTSurface.h @@ -84,7 +84,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (atomic, assign, readonly) CGSize maximumSize; - /** * Simple shortcut to `-[RCTSurface setMinimumSize:size maximumSize:size]`. */ @@ -109,8 +108,12 @@ NS_ASSUME_NONNULL_BEGIN /** * Synchronously blocks the current thread up to given `timeout` until - * the Surface will not have given `stage`. - * Do nothing, if called from the main or `UIManager` queue. + * the Surface reaches `stage`. + * Limitations: + * - Do nothing, if called on `UIManager` queue. + * - Calling on the main queue with `RCTSurfaceStageSurfaceDidInitialMounting` + * stage temporary is not supported; in this case the stage will be + * downgraded to `RCTSurfaceStageSurfaceDidInitialLayout`. */ - (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout; diff --git a/React/Base/Surface/RCTSurface.mm b/React/Base/Surface/RCTSurface.mm index 736400953d..5002c9f6dd 100644 --- a/React/Base/Surface/RCTSurface.mm +++ b/React/Base/Surface/RCTSurface.mm @@ -435,6 +435,16 @@ - (CGSize)intrinsicSize - (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout { + if (RCTIsMainQueue() && (stage == RCTSurfaceStageSurfaceDidInitialRendering)) { + // This case *temporary* does not supported. + stage = RCTSurfaceStageSurfaceDidInitialLayout; + } + + if (RCTIsUIManagerQueue()) { + RCTLogInfo(@"Synchronous waiting is not supported on UIManager queue."); + return NO; + } + dispatch_semaphore_t semaphore; switch (stage) { case RCTSurfaceStageSurfaceDidInitialLayout: @@ -447,16 +457,6 @@ - (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval RCTAssert(NO, @"Only waiting for `RCTSurfaceStageSurfaceDidInitialRendering` and `RCTSurfaceStageSurfaceDidInitialLayout` stages is supported."); } - if (RCTIsMainQueue()) { - RCTLogInfo(@"Synchronous waiting is not supported on the main queue."); - return NO; - } - - if (RCTIsUIManagerQueue()) { - RCTLogInfo(@"Synchronous waiting is not supported on UIManager queue."); - return NO; - } - BOOL timeoutOccured = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC)); if (!timeoutOccured) { // Balancing the semaphore. From bf49df1111473fabd98f866cf73ebcbb0c69a106 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 16 Jan 2018 12:39:14 -0800 Subject: [PATCH 041/143] Introduced -[RCTShadowView contentFrame] Summary: Another trivial sugar/helper to access computed by Yoga layout metrics. We will use it soon in the new Text render/layout engine. Reviewed By: mmmulani Differential Revision: D6671979 fbshipit-source-id: d36933415c2fa50bae5cc171434d8f0b281955b7 --- React/Views/RCTShadowView+Layout.h | 1 + React/Views/RCTShadowView+Layout.m | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/React/Views/RCTShadowView+Layout.h b/React/Views/RCTShadowView+Layout.h index dbe8135d63..770529e135 100644 --- a/React/Views/RCTShadowView+Layout.h +++ b/React/Views/RCTShadowView+Layout.h @@ -26,6 +26,7 @@ RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value); @property (nonatomic, readonly) NSEdgeInsets borderAsInsets; @property (nonatomic, readonly) NSEdgeInsets compoundInsets; @property (nonatomic, readonly) CGSize availableSize; +@property (nonatomic, readonly) CGRect contentFrame; #pragma mark - Measuring diff --git a/React/Views/RCTShadowView+Layout.m b/React/Views/RCTShadowView+Layout.m index bf571b989f..e4f40f5762 100644 --- a/React/Views/RCTShadowView+Layout.m +++ b/React/Views/RCTShadowView+Layout.m @@ -89,6 +89,12 @@ - (NSSize)availableSize return NSEdgeInsetsInsetRect((CGRect){CGPointZero, self.frame.size}, self.compoundInsets).size; } +- (CGRect)contentFrame +{ + CGRect bounds = (CGRect){CGPointZero, self.frame.size}; + return NSEdgeInsetsInsetRect(bounds, self.compoundInsets); +} + #pragma mark - Measuring - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize From 4b34af8a356b3e41b2ee8d5b5e912cdda086fb8f Mon Sep 17 00:00:00 2001 From: Alex Dvornikov Date: Tue, 16 Jan 2018 15:15:32 -0800 Subject: [PATCH 042/143] Add Bundle Splitting support for source code bundles Reviewed By: amnn Differential Revision: D6695431 fbshipit-source-id: 76f4c09b7caadabad5b327af29c02afe61f31abd --- ReactCommon/cxxreact/JSCExecutor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index 91c7716cbb..09452f153b 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -455,6 +455,10 @@ namespace facebook { void JSCExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) { if (m_bundleRegistry) { m_bundleRegistry->registerBundle(bundleId, bundlePath); + } else { + auto sourceUrl = String(m_context, bundlePath.c_str()); + auto source = adoptString(JSBigFileString::fromPath(bundlePath)); + evaluateScript(m_context, source, sourceUrl); } } From ba32b1023fc061ca02a77b22f0bab7af62f9d777 Mon Sep 17 00:00:00 2001 From: Scott Wolchok Date: Sat, 20 Jan 2018 12:01:45 -0800 Subject: [PATCH 043/143] Fix dependencies Reviewed By: adamjernst Differential Revision: D6754488 fbshipit-source-id: 49f2a45d024c7bd6b52f51f7705bcd167a499e47 --- ReactCommon/cxxreact/BUCK | 9 +++++++++ ReactCommon/jschelpers/BUCK | 2 ++ 2 files changed, 11 insertions(+) diff --git a/ReactCommon/cxxreact/BUCK b/ReactCommon/cxxreact/BUCK index be74424e5e..48fbb110f0 100644 --- a/ReactCommon/cxxreact/BUCK +++ b/ReactCommon/cxxreact/BUCK @@ -51,7 +51,9 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "xplat//folly:headers_only", "xplat//folly:molly", + "xplat//folly:scope_guard", ], ) @@ -69,7 +71,9 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "xplat//folly:headers_only", "xplat//folly:molly", + "xplat//third-party/glog:glog", ":module", ], ) @@ -143,9 +147,14 @@ rn_xplat_cxx_library( ":module", ":jsbigstring", "xplat//fbsystrace:fbsystrace", + "xplat//folly:headers_only", "xplat//folly:molly", react_native_xplat_target("jschelpers:jschelpers"), react_native_xplat_target("jsinspector:jsinspector"), react_native_xplat_target("microprofiler:microprofiler"), + "xplat//folly:optional", + "xplat//third-party/glog:glog", + react_native_xplat_target("jschelpers:jscinternalhelpers"), + react_native_xplat_target("privatedata:privatedata"), ] + JSC_DEPS, ) diff --git a/ReactCommon/jschelpers/BUCK b/ReactCommon/jschelpers/BUCK index 013936bbf7..ab53fbfb1f 100644 --- a/ReactCommon/jschelpers/BUCK +++ b/ReactCommon/jschelpers/BUCK @@ -46,6 +46,8 @@ rn_xplat_cxx_library( ], deps = JSC_INTERNAL_DEPS + [ "xplat//folly:molly", + "xplat//third-party/glog:glog", + react_native_xplat_target("privatedata:privatedata"), ], ) From 249024e1fa30d2d46fdf61fc38e0436b05cdfbde Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Tue, 23 Jan 2018 06:35:51 -0800 Subject: [PATCH 044/143] Made logging logic dynamic to log string length Reviewed By: emilsjolander Differential Revision: D6784491 fbshipit-source-id: 26e4520a84be355ff992b808297ce7a95b3d09e3 --- .../main/jni/first-party/yogajni/jni/YGJNI.cpp | 15 +++++++++------ ReactCommon/yoga/yoga/YGNodePrint.cpp | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp index a7676a97a3..fd2ed9c387 100644 --- a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp +++ b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp @@ -158,8 +158,9 @@ static int YGJNILogFunc(const YGConfigRef config, YGLogLevel level, const char *format, va_list args) { - char buffer[256]; - int result = vsnprintf(buffer, sizeof(buffer), format, args); + int result = vsnprintf(NULL, 0, format, args); + std::vector buffer(1 + result); + vsnprintf(buffer.data(), buffer.size(), format, args); static auto logFunc = findClassStatic("com/facebook/yoga/YogaLogger") @@ -170,10 +171,12 @@ static int YGJNILogFunc(const YGConfigRef config, if (auto obj = YGNodeJobject(node)->lockLocal()) { auto jlogger = reinterpret_cast *>(YGConfigGetContext(config)); - logFunc(jlogger->get(), - obj, - logLevelFromInt(JYogaLogLevel::javaClassStatic(), static_cast(level)), - Environment::current()->NewStringUTF(buffer)); + logFunc( + jlogger->get(), + obj, + logLevelFromInt( + JYogaLogLevel::javaClassStatic(), static_cast(level)), + Environment::current()->NewStringUTF(buffer.data())); } return result; diff --git a/ReactCommon/yoga/yoga/YGNodePrint.cpp b/ReactCommon/yoga/yoga/YGNodePrint.cpp index 0951e955a9..6e5047145a 100644 --- a/ReactCommon/yoga/yoga/YGNodePrint.cpp +++ b/ReactCommon/yoga/yoga/YGNodePrint.cpp @@ -29,15 +29,15 @@ static bool areFourValuesEqual(const std::array& four) { } static void appendFormatedString(string* str, const char* fmt, ...) { - char buffer[1024]; va_list args; va_start(args, fmt); va_list argsCopy; va_copy(argsCopy, args); + std::vector buf(1 + vsnprintf(NULL, 0, fmt, args)); va_end(args); - vsnprintf(buffer, 1024, fmt, argsCopy); + vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); - string result = string(buffer); + string result = string(buf.begin(), buf.end() - 1); str->append(result); } From a0caeb5fce39e18f41f5a5ddbed45ca31c4e0b07 Mon Sep 17 00:00:00 2001 From: Alex Dvornikov Date: Tue, 23 Jan 2018 09:56:21 -0800 Subject: [PATCH 045/143] Check for nullptr when accessing isInspectable method Reviewed By: javache Differential Revision: D6785733 fbshipit-source-id: 1bbb884746e671124b7d2d950a3419ea33d70522 --- React/CxxBridge/RCTCxxBridge.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 39e65fb63e..da9aff2908 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -191,11 +191,12 @@ + (void)initialize - (JSGlobalContextRef)jsContextRef { - return (JSGlobalContextRef)(self->_reactInstance ? self->_reactInstance->getJavaScriptContext() : nullptr); + return (JSGlobalContextRef)(_reactInstance ? _reactInstance->getJavaScriptContext() : nullptr); } -- (BOOL)isInspectable { - return self->_reactInstance->isInspectable(); +- (BOOL)isInspectable +{ + return _reactInstance ? _reactInstance->isInspectable() : NO; } - (instancetype)initWithParentBridge:(RCTBridge *)bridge From d5f393276b647768d87aa7de107405bde840ee52 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 23 Jan 2018 23:17:57 -0800 Subject: [PATCH 046/143] The New on iOS Summary: This is a complete rewrite of RCTText, the part of React Native which manages Text and TextInput components. Key points: * It's understandable now. It follows a simple architectural pattern, and it's easy to debug and iterate. Text flow layout is a first-class citizen in React Native layout system now, not just a wired special case. It also brings entirely new possibilities such as nested interleaving and components. * All -specific APIs were removed from UIManager and co (it's about ~16 public methods which were used exclusively only by ). * It relies on new Yoga measurement/cloning API and on-dirty handler. So, it removes built-in dirty propagation subsystem from RN completely. * It caches string fragments properly and granularly on a per-node basis which makes updating text-containing components more performant. * It does not instantiate NSView for virtual components which reduces memory utilization. * It drastically improves capabilities (e.g. rich text inside single line is now supported). Screenshots: https://cl.ly/2j3r1V0L0324 https://cl.ly/3N2V3C3d3q3R Reviewed By: mmmulani Differential Revision: D6617326 fbshipit-source-id: 35d4d81b35c9870e9557d0211c0e934e6072a41e --- .../Text/BaseText/RCTBaseTextShadowView.h | 26 + .../Text/BaseText/RCTBaseTextShadowView.m | 125 +++ .../Text/BaseText/RCTBaseTextViewManager.h | 18 + .../Text/BaseText/RCTBaseTextViewManager.m | 57 ++ Libraries/Text/RCTConvert+Text.h | 4 + .../Text/RCTText.xcodeproj/project.pbxproj | 470 +++++++--- Libraries/Text/RCTTextAttributes.h | 85 ++ Libraries/Text/RCTTextAttributes.m | 270 ++++++ Libraries/Text/RawText/RCTRawTextShadowView.h | 20 + Libraries/Text/RawText/RCTRawTextShadowView.m | 35 + .../Text/RawText/RCTRawTextViewManager.h | 18 + .../Text/RawText/RCTRawTextViewManager.m | 30 + .../Text/Text/NSTextStorage+FontScaling.h | 22 + .../Text/Text/NSTextStorage+FontScaling.m | 139 +++ Libraries/Text/Text/RCTTextShadowView.h | 55 +- Libraries/Text/Text/RCTTextShadowView.m | 800 +++++------------- Libraries/Text/Text/RCTTextView.h | 16 +- Libraries/Text/Text/RCTTextView.m | 279 +++--- Libraries/Text/Text/RCTTextViewManager.h | 4 +- Libraries/Text/Text/RCTTextViewManager.m | 151 ++-- .../Multiline/RCTMultilineTextInputView.h | 27 +- .../Multiline/RCTMultilineTextInputView.m | 367 +------- .../RCTMultilineTextInputViewManager.h | 4 + .../RCTMultilineTextInputViewManager.m | 21 +- .../Text/TextInput/Multiline/RCTUITextView.h | 17 +- .../Text/TextInput/Multiline/RCTUITextView.m | 141 ++- .../TextInput/RCTBackedTextInputDelegate.h | 6 +- .../RCTBackedTextInputDelegateAdapter.h | 14 +- .../RCTBackedTextInputDelegateAdapter.m | 108 +-- .../RCTBackedTextInputViewProtocol.h | 30 +- .../TextInput/RCTBaseTextInputShadowView.h | 27 + .../TextInput/RCTBaseTextInputShadowView.m | 251 ++++++ .../Text/TextInput/RCTBaseTextInputView.h | 52 +- .../Text/TextInput/RCTBaseTextInputView.m | 326 +++++-- .../TextInput/RCTBaseTextInputViewManager.h | 4 +- .../TextInput/RCTBaseTextInputViewManager.m | 89 +- .../Singleline/RCTSinglelineTextInputView.h | 12 +- .../Singleline/RCTSinglelineTextInputView.m | 113 +-- .../RCTSinglelineTextInputViewManager.h | 4 + .../RCTSinglelineTextInputViewManager.m | 24 +- .../TextInput/Singleline/RCTUITextField.h | 10 +- .../TextInput/Singleline/RCTUITextField.m | 70 +- .../VirtualText/RCTVirtualTextShadowView.h | 14 + .../VirtualText/RCTVirtualTextShadowView.m | 75 ++ .../VirtualText/RCTVirtualTextViewManager.h | 14 + .../VirtualText/RCTVirtualTextViewManager.m | 28 + React/Modules/RCTAccessibilityManager.m | 3 +- React/Modules/RCTUIManager.m | 57 +- React/Views/RCTComponentData.h | 2 - React/Views/RCTComponentData.m | 17 - React/Views/RCTShadowView.h | 12 +- React/Views/RCTShadowView.m | 91 +- React/Views/RCTViewManager.h | 14 - React/Views/RCTViewManager.m | 10 - 54 files changed, 2684 insertions(+), 1994 deletions(-) create mode 100644 Libraries/Text/BaseText/RCTBaseTextShadowView.h create mode 100644 Libraries/Text/BaseText/RCTBaseTextShadowView.m create mode 100644 Libraries/Text/BaseText/RCTBaseTextViewManager.h create mode 100644 Libraries/Text/BaseText/RCTBaseTextViewManager.m create mode 100644 Libraries/Text/RCTTextAttributes.h create mode 100644 Libraries/Text/RCTTextAttributes.m create mode 100644 Libraries/Text/RawText/RCTRawTextShadowView.h create mode 100644 Libraries/Text/RawText/RCTRawTextShadowView.m create mode 100644 Libraries/Text/RawText/RCTRawTextViewManager.h create mode 100644 Libraries/Text/RawText/RCTRawTextViewManager.m create mode 100644 Libraries/Text/Text/NSTextStorage+FontScaling.h create mode 100644 Libraries/Text/Text/NSTextStorage+FontScaling.m create mode 100644 Libraries/Text/TextInput/RCTBaseTextInputShadowView.h create mode 100644 Libraries/Text/TextInput/RCTBaseTextInputShadowView.m create mode 100644 Libraries/Text/VirtualText/RCTVirtualTextShadowView.h create mode 100644 Libraries/Text/VirtualText/RCTVirtualTextShadowView.m create mode 100644 Libraries/Text/VirtualText/RCTVirtualTextViewManager.h create mode 100644 Libraries/Text/VirtualText/RCTVirtualTextViewManager.m diff --git a/Libraries/Text/BaseText/RCTBaseTextShadowView.h b/Libraries/Text/BaseText/RCTBaseTextShadowView.h new file mode 100644 index 0000000000..736eed8ac0 --- /dev/null +++ b/Libraries/Text/BaseText/RCTBaseTextShadowView.h @@ -0,0 +1,26 @@ +/** + * 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 + +#import "RCTTextAttributes.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const RCTBaseTextShadowViewEmbeddedShadowViewAttributeName; + +@interface RCTBaseTextShadowView : RCTShadowView + +@property (nonatomic, strong) RCTTextAttributes *textAttributes; + +- (NSAttributedString *)attributedTextWithBaseTextAttributes:(nullable RCTTextAttributes *)baseTextAttributes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/BaseText/RCTBaseTextShadowView.m b/Libraries/Text/BaseText/RCTBaseTextShadowView.m new file mode 100644 index 0000000000..efafad36de --- /dev/null +++ b/Libraries/Text/BaseText/RCTBaseTextShadowView.m @@ -0,0 +1,125 @@ +/** + * 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 "RCTBaseTextShadowView.h" + +#import + +#import "RCTRawTextShadowView.h" +#import "RCTVirtualTextShadowView.h" + +NSString *const RCTBaseTextShadowViewEmbeddedShadowViewAttributeName = @"RCTBaseTextShadowViewEmbeddedShadowViewAttributeName"; + +@implementation RCTBaseTextShadowView +{ + NSAttributedString *_Nullable _cachedAttributedText; + RCTTextAttributes *_Nullable _cachedTextAttributes; +} + +- (instancetype)init +{ + if (self = [super init]) { + _textAttributes = [RCTTextAttributes new]; + } + + return self; +} + +- (void)setReactTag:(NSNumber *)reactTag +{ + [super setReactTag:reactTag]; + _textAttributes.tag = reactTag; +} + +#pragma mark - attributedString + +- (NSAttributedString *)attributedTextWithBaseTextAttributes:(nullable RCTTextAttributes *)baseTextAttributes +{ + RCTTextAttributes *textAttributes; + + if (baseTextAttributes) { + textAttributes = [baseTextAttributes copy]; + [textAttributes applyTextAttributes:self.textAttributes]; + } else { + textAttributes = [self.textAttributes copy]; + } + + if (_cachedAttributedText && [_cachedTextAttributes isEqual:textAttributes]) { + return _cachedAttributedText; + } + + NSMutableAttributedString *attributedText = [NSMutableAttributedString new]; + + [attributedText beginEditing]; + + for (RCTShadowView *shadowView in self.reactSubviews) { + // Special Case: RCTRawTextShadowView + if ([shadowView isKindOfClass:[RCTRawTextShadowView class]]) { + RCTRawTextShadowView *rawTextShadowView = (RCTRawTextShadowView *)shadowView; + NSString *text = rawTextShadowView.text; + if (text) { + NSAttributedString *rawTextAttributedString = + [[NSAttributedString alloc] initWithString:rawTextShadowView.text + attributes:textAttributes.effectiveTextAttributes]; + [attributedText appendAttributedString:rawTextAttributedString]; + } + continue; + } + + // Special Case: RCTBaseTextShadowView + if ([shadowView isKindOfClass:[RCTBaseTextShadowView class]]) { + RCTBaseTextShadowView *baseTextShadowView = (RCTBaseTextShadowView *)shadowView; + NSAttributedString *baseTextAttributedString = + [baseTextShadowView attributedTextWithBaseTextAttributes:textAttributes]; + [attributedText appendAttributedString:baseTextAttributedString]; + continue; + } + + // Generic Case: Any RCTShadowView + NSTextAttachment *attachment = [NSTextAttachment new]; + NSMutableAttributedString *embeddedShadowViewAttributedString = [NSMutableAttributedString new]; + [embeddedShadowViewAttributedString beginEditing]; + [embeddedShadowViewAttributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]]; + [embeddedShadowViewAttributedString addAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName + value:shadowView + range:(NSRange){0, embeddedShadowViewAttributedString.length}]; + [embeddedShadowViewAttributedString endEditing]; + [attributedText appendAttributedString:embeddedShadowViewAttributedString]; + } + + [attributedText endEditing]; + + [self clearLayout]; + + _cachedAttributedText = [attributedText copy]; + _cachedTextAttributes = textAttributes; + + return _cachedAttributedText; +} + +- (void)dirtyLayout +{ + [super dirtyLayout]; + _cachedAttributedText = nil; + _cachedTextAttributes = nil; +} + +- (void)didUpdateReactSubviews +{ + [super didUpdateReactSubviews]; + [self dirtyLayout]; +} + +- (void)didSetProps:(NSArray *)changedProps +{ + [super didSetProps:changedProps]; + [self dirtyLayout]; +} + +@end diff --git a/Libraries/Text/BaseText/RCTBaseTextViewManager.h b/Libraries/Text/BaseText/RCTBaseTextViewManager.h new file mode 100644 index 0000000000..da73cf0708 --- /dev/null +++ b/Libraries/Text/BaseText/RCTBaseTextViewManager.h @@ -0,0 +1,18 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTBaseTextViewManager : RCTViewManager + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/BaseText/RCTBaseTextViewManager.m b/Libraries/Text/BaseText/RCTBaseTextViewManager.m new file mode 100644 index 0000000000..89640c7e9a --- /dev/null +++ b/Libraries/Text/BaseText/RCTBaseTextViewManager.m @@ -0,0 +1,57 @@ +/** + * 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 "RCTBaseTextViewManager.h" + +@implementation RCTBaseTextViewManager + +RCT_EXPORT_MODULE(RCTBaseText) + +- (UIView *)view +{ + RCTAssert(NO, @"The `-[RCTBaseTextViewManager view]` property must be overridden in subclass."); + return nil; +} + +- (RCTShadowView *)shadowView +{ + RCTAssert(NO, @"The `-[RCTBaseTextViewManager shadowView]` property must be overridden in subclass."); + return nil; +} + +#pragma mark - Text Attributes + +// Color +RCT_REMAP_SHADOW_PROPERTY(color, textAttributes.foregroundColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(backgroundColor, textAttributes.backgroundColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(opacity, textAttributes.opacity, CGFloat) +// Font +RCT_REMAP_SHADOW_PROPERTY(fontFamily, textAttributes.fontFamily, NSString) +RCT_REMAP_SHADOW_PROPERTY(fontSize, textAttributes.fontSize, CGFloat) +RCT_REMAP_SHADOW_PROPERTY(fontWeight, textAttributes.fontWeight, NSString) +RCT_REMAP_SHADOW_PROPERTY(fontStyle, textAttributes.fontStyle, NSString) +RCT_REMAP_SHADOW_PROPERTY(fontVariant, textAttributes.fontVariant, NSArray) +RCT_REMAP_SHADOW_PROPERTY(allowFontScaling, textAttributes.allowFontScaling, BOOL) +RCT_REMAP_SHADOW_PROPERTY(letterSpacing, textAttributes.letterSpacing, CGFloat) +// Paragraph Styles +RCT_REMAP_SHADOW_PROPERTY(lineHeight, textAttributes.lineHeight, CGFloat) +RCT_REMAP_SHADOW_PROPERTY(textAlign, textAttributes.alignment, NSTextAlignment) +RCT_REMAP_SHADOW_PROPERTY(writingDirection, textAttributes.baseWritingDirection, NSWritingDirection) +// Decoration +RCT_REMAP_SHADOW_PROPERTY(textDecorationColor, textAttributes.textDecorationColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(textDecorationStyle, textAttributes.textDecorationStyle, NSUnderlineStyle) +RCT_REMAP_SHADOW_PROPERTY(textDecorationLine, textAttributes.textDecorationLine, RCTTextDecorationLineType) +// Shadow +RCT_REMAP_SHADOW_PROPERTY(textShadowOffset, textAttributes.textShadowOffset, CGSize) +RCT_REMAP_SHADOW_PROPERTY(textShadowRadius, textAttributes.textShadowRadius, CGFloat) +RCT_REMAP_SHADOW_PROPERTY(textShadowColor, textAttributes.textShadowColor, UIColor) +// Special +RCT_REMAP_SHADOW_PROPERTY(isHighlighted, textAttributes.isHighlighted, BOOL) + +@end diff --git a/Libraries/Text/RCTConvert+Text.h b/Libraries/Text/RCTConvert+Text.h index 794b1e4e1c..242d1cc207 100644 --- a/Libraries/Text/RCTConvert+Text.h +++ b/Libraries/Text/RCTConvert+Text.h @@ -9,9 +9,13 @@ #import +NS_ASSUME_NONNULL_BEGIN + @interface RCTConvert (Text) // //+ (NSTextAutocorrectionType)NSTextAutocorrectionType:(id)json; //+ (NSTextSpellCheckingType)NSTextSpellCheckingType:(id)json; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index d3117cbcff..586f3aa8d5 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -7,41 +7,102 @@ objects = { /* Begin PBXBuildFile section */ - 59E604521FE9CAF100BD90C5 /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E6042F1FE9CAF100BD90C5 /* RCTTextShadowView.m */; }; - 59E604531FE9CAF100BD90C5 /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E6042F1FE9CAF100BD90C5 /* RCTTextShadowView.m */; }; - 59E604541FE9CAF100BD90C5 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604311FE9CAF100BD90C5 /* RCTTextView.m */; }; - 59E604551FE9CAF100BD90C5 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604311FE9CAF100BD90C5 /* RCTTextView.m */; }; - 59E604561FE9CAF100BD90C5 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604331FE9CAF100BD90C5 /* RCTTextViewManager.m */; }; - 59E604571FE9CAF100BD90C5 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604331FE9CAF100BD90C5 /* RCTTextViewManager.m */; }; - 59E604581FE9CAF100BD90C5 /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604341FE9CAF100BD90C5 /* RCTRawTextShadowView.m */; }; - 59E604591FE9CAF100BD90C5 /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604341FE9CAF100BD90C5 /* RCTRawTextShadowView.m */; }; - 59E6045A1FE9CAF100BD90C5 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604361FE9CAF100BD90C5 /* RCTRawTextViewManager.m */; }; - 59E6045B1FE9CAF100BD90C5 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E604361FE9CAF100BD90C5 /* RCTRawTextViewManager.m */; }; - 59E604731FE9CB3F00BD90C5 /* RCTFontAttributes.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = A85C82981F742AA20036C019 /* RCTFontAttributes.h */; }; - 59E604741FE9CB3F00BD90C5 /* RCTFontAttributesDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = A85C82BA1F742D8F0036C019 /* RCTFontAttributesDelegate.h */; }; - 59E604751FE9CB3F00BD90C5 /* RCTRawTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E6042C1FE9CAF100BD90C5 /* RCTRawTextShadowView.h */; }; - 59E604761FE9CB3F00BD90C5 /* RCTRawTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604351FE9CAF100BD90C5 /* RCTRawTextViewManager.h */; }; - 59E604771FE9CB3F00BD90C5 /* RCTTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E6042E1FE9CAF100BD90C5 /* RCTTextShadowView.h */; }; - 59E604781FE9CB3F00BD90C5 /* RCTTextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604301FE9CAF100BD90C5 /* RCTTextView.h */; }; - 59E604791FE9CB3F00BD90C5 /* RCTTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604321FE9CAF100BD90C5 /* RCTTextViewManager.h */; }; - 59E604881FE9CB4A00BD90C5 /* RCTFontAttributes.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = A85C82981F742AA20036C019 /* RCTFontAttributes.h */; }; - 59E604891FE9CB4A00BD90C5 /* RCTFontAttributesDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = A85C82BA1F742D8F0036C019 /* RCTFontAttributesDelegate.h */; }; - 59E6048A1FE9CB4A00BD90C5 /* RCTRawTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E6042C1FE9CAF100BD90C5 /* RCTRawTextShadowView.h */; }; - 59E6048B1FE9CB4A00BD90C5 /* RCTRawTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604351FE9CAF100BD90C5 /* RCTRawTextViewManager.h */; }; - 59E6048C1FE9CB4A00BD90C5 /* RCTTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E6042E1FE9CAF100BD90C5 /* RCTTextShadowView.h */; }; - 59E6048D1FE9CB4A00BD90C5 /* RCTTextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604301FE9CAF100BD90C5 /* RCTTextView.h */; }; - 59E6048E1FE9CB4A00BD90C5 /* RCTTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59E604321FE9CAF100BD90C5 /* RCTTextViewManager.h */; }; - 59E8C5CC1F8833D100204F5E /* RCTFontAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A85C82991F742AA20036C019 /* RCTFontAttributes.m */; }; - A85C829A1F742AA20036C019 /* RCTFontAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A85C82991F742AA20036C019 /* RCTFontAttributes.m */; }; - D4EEE317201FA3B300C4CBB6 /* RCTMultilineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE303201FA3B100C4CBB6 /* RCTMultilineTextInputView.m */; }; - D4EEE318201FA3B300C4CBB6 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE307201FA3B100C4CBB6 /* RCTUITextView.m */; }; - D4EEE31A201FA3B300C4CBB6 /* RCTShadowTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE30C201FA3B200C4CBB6 /* RCTShadowTextView.m */; }; - D4EEE31B201FA3B300C4CBB6 /* RCTTextSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE30D201FA3B200C4CBB6 /* RCTTextSelection.m */; }; - D4EEE31C201FA3B300C4CBB6 /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE310201FA3B200C4CBB6 /* RCTTextFieldManager.m */; }; - D4EEE31D201FA3B300C4CBB6 /* RCTSecureTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE312201FA3B200C4CBB6 /* RCTSecureTextField.m */; }; - D4EEE31E201FA3B300C4CBB6 /* RCTTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE313201FA3B200C4CBB6 /* RCTTextField.m */; }; - D4EEE31F201FA3B300C4CBB6 /* RCTShadowTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE315201FA3B300C4CBB6 /* RCTShadowTextField.m */; }; - D4EEE320201FA3B300C4CBB6 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EEE316201FA3B300C4CBB6 /* RCTTextViewManager.m */; }; + 5956B130200FEBAA008D9D16 /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FD200FEBA9008D9D16 /* RCTRawTextShadowView.m */; }; + 5956B131200FEBAA008D9D16 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FE200FEBA9008D9D16 /* RCTRawTextViewManager.m */; }; + 5956B132200FEBAA008D9D16 /* RCTSinglelineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */; }; + 5956B133200FEBAA008D9D16 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B103200FEBA9008D9D16 /* RCTUITextField.m */; }; + 5956B134200FEBAA008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B106200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.m */; }; + 5956B135200FEBAA008D9D16 /* RCTBaseTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10A200FEBA9008D9D16 /* RCTBaseTextInputView.m */; }; + 5956B136200FEBAA008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10D200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.m */; }; + 5956B137200FEBAA008D9D16 /* RCTBaseTextInputShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10F200FEBA9008D9D16 /* RCTBaseTextInputShadowView.m */; }; + 5956B138200FEBAA008D9D16 /* RCTTextSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B110200FEBA9008D9D16 /* RCTTextSelection.m */; }; + 5956B139200FEBAA008D9D16 /* RCTBaseTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B111200FEBA9008D9D16 /* RCTBaseTextInputViewManager.m */; }; + 5956B13A200FEBAA008D9D16 /* RCTMultilineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B115200FEBA9008D9D16 /* RCTMultilineTextInputView.m */; }; + 5956B13B200FEBAA008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B118200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.m */; }; + 5956B13C200FEBAA008D9D16 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B119200FEBA9008D9D16 /* RCTUITextView.m */; }; + 5956B13D200FEBAA008D9D16 /* RCTBaseTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11E200FEBA9008D9D16 /* RCTBaseTextShadowView.m */; }; + 5956B13E200FEBAA008D9D16 /* RCTBaseTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11F200FEBA9008D9D16 /* RCTBaseTextViewManager.m */; }; + 5956B13F200FEBAA008D9D16 /* RCTTextAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B120200FEBA9008D9D16 /* RCTTextAttributes.m */; }; + 5956B140200FEBAA008D9D16 /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B122200FEBAA008D9D16 /* RCTTextShadowView.m */; }; + 5956B141200FEBAA008D9D16 /* NSTextStorage+FontScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B125200FEBAA008D9D16 /* NSTextStorage+FontScaling.m */; }; + 5956B142200FEBAA008D9D16 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B127200FEBAA008D9D16 /* RCTTextViewManager.m */; }; + 5956B143200FEBAA008D9D16 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B128200FEBAA008D9D16 /* RCTTextView.m */; }; + 5956B144200FEBAA008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; + 5956B145200FEBAA008D9D16 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */; }; + 5956B146200FEBAA008D9D16 /* RCTConvert+Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */; }; + 5956B160200FF324008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11D200FEBA9008D9D16 /* RCTBaseTextShadowView.h */; }; + 5956B161200FF324008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11C200FEBA9008D9D16 /* RCTBaseTextViewManager.h */; }; + 5956B162200FF324008D9D16 /* RCTRawTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FC200FEBA9008D9D16 /* RCTRawTextShadowView.h */; }; + 5956B163200FF324008D9D16 /* RCTRawTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */; }; + 5956B164200FF324008D9D16 /* RCTConvert+Text.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */; }; + 5956B165200FF324008D9D16 /* RCTTextAttributes.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11A200FEBA9008D9D16 /* RCTTextAttributes.h */; }; + 5956B166200FF324008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B129200FEBAA008D9D16 /* NSTextStorage+FontScaling.h */; }; + 5956B167200FF324008D9D16 /* RCTTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B126200FEBAA008D9D16 /* RCTTextShadowView.h */; }; + 5956B168200FF324008D9D16 /* RCTTextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B123200FEBAA008D9D16 /* RCTTextView.h */; }; + 5956B169200FF324008D9D16 /* RCTTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B124200FEBAA008D9D16 /* RCTTextViewManager.h */; }; + 5956B16A200FF324008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B117200FEBA9008D9D16 /* RCTMultilineTextInputView.h */; }; + 5956B16B200FF324008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B114200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.h */; }; + 5956B16C200FF324008D9D16 /* RCTUITextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B116200FEBA9008D9D16 /* RCTUITextView.h */; }; + 5956B16D200FF324008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10C200FEBA9008D9D16 /* RCTBackedTextInputDelegate.h */; }; + 5956B16E200FF324008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B107200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.h */; }; + 5956B16F200FF324008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B112200FEBA9008D9D16 /* RCTBackedTextInputViewProtocol.h */; }; + 5956B170200FF324008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B109200FEBA9008D9D16 /* RCTBaseTextInputShadowView.h */; }; + 5956B171200FF324008D9D16 /* RCTBaseTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10E200FEBA9008D9D16 /* RCTBaseTextInputView.h */; }; + 5956B172200FF324008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10B200FEBA9008D9D16 /* RCTBaseTextInputViewManager.h */; }; + 5956B173200FF324008D9D16 /* RCTTextSelection.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B108200FEBA9008D9D16 /* RCTTextSelection.h */; }; + 5956B174200FF324008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */; }; + 5956B175200FF324008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */; }; + 5956B176200FF324008D9D16 /* RCTUITextField.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B105200FEBA9008D9D16 /* RCTUITextField.h */; }; + 5956B177200FF324008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */; }; + 5956B178200FF324008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */; }; + 5956B179200FF338008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11D200FEBA9008D9D16 /* RCTBaseTextShadowView.h */; }; + 5956B17A200FF338008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11C200FEBA9008D9D16 /* RCTBaseTextViewManager.h */; }; + 5956B17B200FF338008D9D16 /* RCTRawTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FC200FEBA9008D9D16 /* RCTRawTextShadowView.h */; }; + 5956B17C200FF338008D9D16 /* RCTRawTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */; }; + 5956B17D200FF338008D9D16 /* RCTConvert+Text.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */; }; + 5956B17E200FF338008D9D16 /* RCTTextAttributes.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11A200FEBA9008D9D16 /* RCTTextAttributes.h */; }; + 5956B17F200FF338008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B129200FEBAA008D9D16 /* NSTextStorage+FontScaling.h */; }; + 5956B180200FF338008D9D16 /* RCTTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B126200FEBAA008D9D16 /* RCTTextShadowView.h */; }; + 5956B181200FF338008D9D16 /* RCTTextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B123200FEBAA008D9D16 /* RCTTextView.h */; }; + 5956B182200FF338008D9D16 /* RCTTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B124200FEBAA008D9D16 /* RCTTextViewManager.h */; }; + 5956B183200FF338008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B117200FEBA9008D9D16 /* RCTMultilineTextInputView.h */; }; + 5956B184200FF338008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B114200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.h */; }; + 5956B185200FF338008D9D16 /* RCTUITextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B116200FEBA9008D9D16 /* RCTUITextView.h */; }; + 5956B186200FF338008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10C200FEBA9008D9D16 /* RCTBackedTextInputDelegate.h */; }; + 5956B187200FF338008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B107200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.h */; }; + 5956B188200FF338008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B112200FEBA9008D9D16 /* RCTBackedTextInputViewProtocol.h */; }; + 5956B189200FF338008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B109200FEBA9008D9D16 /* RCTBaseTextInputShadowView.h */; }; + 5956B18A200FF338008D9D16 /* RCTBaseTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10E200FEBA9008D9D16 /* RCTBaseTextInputView.h */; }; + 5956B18B200FF338008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10B200FEBA9008D9D16 /* RCTBaseTextInputViewManager.h */; }; + 5956B18C200FF338008D9D16 /* RCTTextSelection.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B108200FEBA9008D9D16 /* RCTTextSelection.h */; }; + 5956B18D200FF338008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */; }; + 5956B18E200FF338008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */; }; + 5956B18F200FF338008D9D16 /* RCTUITextField.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B105200FEBA9008D9D16 /* RCTUITextField.h */; }; + 5956B190200FF338008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */; }; + 5956B191200FF338008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */; }; + 5956B192200FF35C008D9D16 /* RCTBaseTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11E200FEBA9008D9D16 /* RCTBaseTextShadowView.m */; }; + 5956B193200FF35C008D9D16 /* RCTBaseTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11F200FEBA9008D9D16 /* RCTBaseTextViewManager.m */; }; + 5956B194200FF35C008D9D16 /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FD200FEBA9008D9D16 /* RCTRawTextShadowView.m */; }; + 5956B195200FF35C008D9D16 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FE200FEBA9008D9D16 /* RCTRawTextViewManager.m */; }; + 5956B196200FF35C008D9D16 /* RCTConvert+Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */; }; + 5956B197200FF35C008D9D16 /* RCTTextAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B120200FEBA9008D9D16 /* RCTTextAttributes.m */; }; + 5956B198200FF35C008D9D16 /* NSTextStorage+FontScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B125200FEBAA008D9D16 /* NSTextStorage+FontScaling.m */; }; + 5956B199200FF35C008D9D16 /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B122200FEBAA008D9D16 /* RCTTextShadowView.m */; }; + 5956B19A200FF35C008D9D16 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B128200FEBAA008D9D16 /* RCTTextView.m */; }; + 5956B19B200FF35C008D9D16 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B127200FEBAA008D9D16 /* RCTTextViewManager.m */; }; + 5956B19C200FF35C008D9D16 /* RCTMultilineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B115200FEBA9008D9D16 /* RCTMultilineTextInputView.m */; }; + 5956B19D200FF35C008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B118200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.m */; }; + 5956B19E200FF35C008D9D16 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B119200FEBA9008D9D16 /* RCTUITextView.m */; }; + 5956B19F200FF35C008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10D200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.m */; }; + 5956B1A0200FF35C008D9D16 /* RCTBaseTextInputShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10F200FEBA9008D9D16 /* RCTBaseTextInputShadowView.m */; }; + 5956B1A1200FF35C008D9D16 /* RCTBaseTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10A200FEBA9008D9D16 /* RCTBaseTextInputView.m */; }; + 5956B1A2200FF35C008D9D16 /* RCTBaseTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B111200FEBA9008D9D16 /* RCTBaseTextInputViewManager.m */; }; + 5956B1A3200FF35C008D9D16 /* RCTTextSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B110200FEBA9008D9D16 /* RCTTextSelection.m */; }; + 5956B1A4200FF35C008D9D16 /* RCTSinglelineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */; }; + 5956B1A5200FF35C008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B106200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.m */; }; + 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B103200FEBA9008D9D16 /* RCTUITextField.m */; }; + 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */; }; + 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -51,13 +112,31 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( - 59E604881FE9CB4A00BD90C5 /* RCTFontAttributes.h in Copy Headers */, - 59E604891FE9CB4A00BD90C5 /* RCTFontAttributesDelegate.h in Copy Headers */, - 59E6048A1FE9CB4A00BD90C5 /* RCTRawTextShadowView.h in Copy Headers */, - 59E6048B1FE9CB4A00BD90C5 /* RCTRawTextViewManager.h in Copy Headers */, - 59E6048C1FE9CB4A00BD90C5 /* RCTTextShadowView.h in Copy Headers */, - 59E6048D1FE9CB4A00BD90C5 /* RCTTextView.h in Copy Headers */, - 59E6048E1FE9CB4A00BD90C5 /* RCTTextViewManager.h in Copy Headers */, + 5956B160200FF324008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, + 5956B161200FF324008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */, + 5956B162200FF324008D9D16 /* RCTRawTextShadowView.h in Copy Headers */, + 5956B163200FF324008D9D16 /* RCTRawTextViewManager.h in Copy Headers */, + 5956B164200FF324008D9D16 /* RCTConvert+Text.h in Copy Headers */, + 5956B165200FF324008D9D16 /* RCTTextAttributes.h in Copy Headers */, + 5956B166200FF324008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */, + 5956B167200FF324008D9D16 /* RCTTextShadowView.h in Copy Headers */, + 5956B168200FF324008D9D16 /* RCTTextView.h in Copy Headers */, + 5956B169200FF324008D9D16 /* RCTTextViewManager.h in Copy Headers */, + 5956B16A200FF324008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */, + 5956B16B200FF324008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */, + 5956B16C200FF324008D9D16 /* RCTUITextView.h in Copy Headers */, + 5956B16D200FF324008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */, + 5956B16E200FF324008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */, + 5956B16F200FF324008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */, + 5956B170200FF324008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */, + 5956B171200FF324008D9D16 /* RCTBaseTextInputView.h in Copy Headers */, + 5956B172200FF324008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */, + 5956B173200FF324008D9D16 /* RCTTextSelection.h in Copy Headers */, + 5956B174200FF324008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */, + 5956B175200FF324008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */, + 5956B176200FF324008D9D16 /* RCTUITextField.h in Copy Headers */, + 5956B177200FF324008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */, + 5956B178200FF324008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */, ); name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; @@ -68,13 +147,31 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( - 59E604731FE9CB3F00BD90C5 /* RCTFontAttributes.h in Copy Headers */, - 59E604741FE9CB3F00BD90C5 /* RCTFontAttributesDelegate.h in Copy Headers */, - 59E604751FE9CB3F00BD90C5 /* RCTRawTextShadowView.h in Copy Headers */, - 59E604761FE9CB3F00BD90C5 /* RCTRawTextViewManager.h in Copy Headers */, - 59E604771FE9CB3F00BD90C5 /* RCTTextShadowView.h in Copy Headers */, - 59E604781FE9CB3F00BD90C5 /* RCTTextView.h in Copy Headers */, - 59E604791FE9CB3F00BD90C5 /* RCTTextViewManager.h in Copy Headers */, + 5956B179200FF338008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, + 5956B17A200FF338008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */, + 5956B17B200FF338008D9D16 /* RCTRawTextShadowView.h in Copy Headers */, + 5956B17C200FF338008D9D16 /* RCTRawTextViewManager.h in Copy Headers */, + 5956B17D200FF338008D9D16 /* RCTConvert+Text.h in Copy Headers */, + 5956B17E200FF338008D9D16 /* RCTTextAttributes.h in Copy Headers */, + 5956B17F200FF338008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */, + 5956B180200FF338008D9D16 /* RCTTextShadowView.h in Copy Headers */, + 5956B181200FF338008D9D16 /* RCTTextView.h in Copy Headers */, + 5956B182200FF338008D9D16 /* RCTTextViewManager.h in Copy Headers */, + 5956B183200FF338008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */, + 5956B184200FF338008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */, + 5956B185200FF338008D9D16 /* RCTUITextView.h in Copy Headers */, + 5956B186200FF338008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */, + 5956B187200FF338008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */, + 5956B188200FF338008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */, + 5956B189200FF338008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */, + 5956B18A200FF338008D9D16 /* RCTBaseTextInputView.h in Copy Headers */, + 5956B18B200FF338008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */, + 5956B18C200FF338008D9D16 /* RCTTextSelection.h in Copy Headers */, + 5956B18D200FF338008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */, + 5956B18E200FF338008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */, + 5956B18F200FF338008D9D16 /* RCTUITextField.h in Copy Headers */, + 5956B190200FF338008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */, + 5956B191200FF338008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */, ); name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; @@ -84,53 +181,70 @@ /* Begin PBXFileReference section */ 2D2A287B1D9B048500D4039D /* libRCTText-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTText-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 58B5119B1A9E6C1200147676 /* libRCTText.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTText.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 59E6042C1FE9CAF100BD90C5 /* RCTRawTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRawTextShadowView.h; sourceTree = ""; }; - 59E6042E1FE9CAF100BD90C5 /* RCTTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextShadowView.h; sourceTree = ""; }; - 59E6042F1FE9CAF100BD90C5 /* RCTTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextShadowView.m; sourceTree = ""; }; - 59E604301FE9CAF100BD90C5 /* RCTTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextView.h; sourceTree = ""; }; - 59E604311FE9CAF100BD90C5 /* RCTTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextView.m; sourceTree = ""; }; - 59E604321FE9CAF100BD90C5 /* RCTTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextViewManager.h; sourceTree = ""; }; - 59E604331FE9CAF100BD90C5 /* RCTTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextViewManager.m; sourceTree = ""; }; - 59E604341FE9CAF100BD90C5 /* RCTRawTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextShadowView.m; sourceTree = ""; }; - 59E604351FE9CAF100BD90C5 /* RCTRawTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRawTextViewManager.h; sourceTree = ""; }; - 59E604361FE9CAF100BD90C5 /* RCTRawTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextViewManager.m; sourceTree = ""; }; - A85C82981F742AA20036C019 /* RCTFontAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFontAttributes.h; sourceTree = ""; }; - A85C82991F742AA20036C019 /* RCTFontAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFontAttributes.m; sourceTree = ""; }; - A85C82BA1F742D8F0036C019 /* RCTFontAttributesDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFontAttributesDelegate.h; sourceTree = ""; }; - D4EEE303201FA3B100C4CBB6 /* RCTMultilineTextInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTMultilineTextInputView.m; path = TextInputLegacy/RCTMultilineTextInputView.m; sourceTree = ""; }; - D4EEE304201FA3B100C4CBB6 /* RCTShadowTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTShadowTextField.h; path = TextInputLegacy/RCTShadowTextField.h; sourceTree = ""; }; - D4EEE305201FA3B100C4CBB6 /* RCTShadowTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTShadowTextView.h; path = TextInputLegacy/RCTShadowTextView.h; sourceTree = ""; }; - D4EEE306201FA3B100C4CBB6 /* RCTTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextField.h; path = TextInputLegacy/RCTTextField.h; sourceTree = ""; }; - D4EEE307201FA3B100C4CBB6 /* RCTUITextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTUITextView.m; path = TextInputLegacy/RCTUITextView.m; sourceTree = ""; }; - D4EEE308201FA3B100C4CBB6 /* RCTTextFieldManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextFieldManager.h; path = TextInputLegacy/RCTTextFieldManager.h; sourceTree = ""; }; - D4EEE309201FA3B100C4CBB6 /* RCTTextSelection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextSelection.h; path = TextInputLegacy/RCTTextSelection.h; sourceTree = ""; }; - D4EEE30A201FA3B100C4CBB6 /* RCTSecureTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTSecureTextField.h; path = TextInputLegacy/RCTSecureTextField.h; sourceTree = ""; }; - D4EEE30C201FA3B200C4CBB6 /* RCTShadowTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTShadowTextView.m; path = TextInputLegacy/RCTShadowTextView.m; sourceTree = ""; }; - D4EEE30D201FA3B200C4CBB6 /* RCTTextSelection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextSelection.m; path = TextInputLegacy/RCTTextSelection.m; sourceTree = ""; }; - D4EEE30E201FA3B200C4CBB6 /* RCTMultilineTextInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTMultilineTextInputView.h; path = TextInputLegacy/RCTMultilineTextInputView.h; sourceTree = ""; }; - D4EEE30F201FA3B200C4CBB6 /* RCTTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextViewManager.h; path = TextInputLegacy/RCTTextViewManager.h; sourceTree = ""; }; - D4EEE310201FA3B200C4CBB6 /* RCTTextFieldManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextFieldManager.m; path = TextInputLegacy/RCTTextFieldManager.m; sourceTree = ""; }; - D4EEE311201FA3B200C4CBB6 /* RCTUITextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTUITextView.h; path = TextInputLegacy/RCTUITextView.h; sourceTree = ""; }; - D4EEE312201FA3B200C4CBB6 /* RCTSecureTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTSecureTextField.m; path = TextInputLegacy/RCTSecureTextField.m; sourceTree = ""; }; - D4EEE313201FA3B200C4CBB6 /* RCTTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextField.m; path = TextInputLegacy/RCTTextField.m; sourceTree = ""; }; - D4EEE315201FA3B300C4CBB6 /* RCTShadowTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTShadowTextField.m; path = TextInputLegacy/RCTShadowTextField.m; sourceTree = ""; }; - D4EEE316201FA3B300C4CBB6 /* RCTTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextViewManager.m; path = TextInputLegacy/RCTTextViewManager.m; sourceTree = ""; }; + 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Text.h"; sourceTree = ""; }; + 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRawTextViewManager.h; sourceTree = ""; }; + 5956B0FC200FEBA9008D9D16 /* RCTRawTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRawTextShadowView.h; sourceTree = ""; }; + 5956B0FD200FEBA9008D9D16 /* RCTRawTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextShadowView.m; sourceTree = ""; }; + 5956B0FE200FEBA9008D9D16 /* RCTRawTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextViewManager.m; sourceTree = ""; }; + 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSinglelineTextInputView.m; sourceTree = ""; }; + 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSinglelineTextInputViewManager.h; sourceTree = ""; }; + 5956B103200FEBA9008D9D16 /* RCTUITextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUITextField.m; sourceTree = ""; }; + 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSinglelineTextInputView.h; sourceTree = ""; }; + 5956B105200FEBA9008D9D16 /* RCTUITextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUITextField.h; sourceTree = ""; }; + 5956B106200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSinglelineTextInputViewManager.m; sourceTree = ""; }; + 5956B107200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputDelegateAdapter.h; sourceTree = ""; }; + 5956B108200FEBA9008D9D16 /* RCTTextSelection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextSelection.h; sourceTree = ""; }; + 5956B109200FEBA9008D9D16 /* RCTBaseTextInputShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputShadowView.h; sourceTree = ""; }; + 5956B10A200FEBA9008D9D16 /* RCTBaseTextInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputView.m; sourceTree = ""; }; + 5956B10B200FEBA9008D9D16 /* RCTBaseTextInputViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputViewManager.h; sourceTree = ""; }; + 5956B10C200FEBA9008D9D16 /* RCTBackedTextInputDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputDelegate.h; sourceTree = ""; }; + 5956B10D200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBackedTextInputDelegateAdapter.m; sourceTree = ""; }; + 5956B10E200FEBA9008D9D16 /* RCTBaseTextInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputView.h; sourceTree = ""; }; + 5956B10F200FEBA9008D9D16 /* RCTBaseTextInputShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputShadowView.m; sourceTree = ""; }; + 5956B110200FEBA9008D9D16 /* RCTTextSelection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextSelection.m; sourceTree = ""; }; + 5956B111200FEBA9008D9D16 /* RCTBaseTextInputViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputViewManager.m; sourceTree = ""; }; + 5956B112200FEBA9008D9D16 /* RCTBackedTextInputViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputViewProtocol.h; sourceTree = ""; }; + 5956B114200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMultilineTextInputViewManager.h; sourceTree = ""; }; + 5956B115200FEBA9008D9D16 /* RCTMultilineTextInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMultilineTextInputView.m; sourceTree = ""; }; + 5956B116200FEBA9008D9D16 /* RCTUITextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUITextView.h; sourceTree = ""; }; + 5956B117200FEBA9008D9D16 /* RCTMultilineTextInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMultilineTextInputView.h; sourceTree = ""; }; + 5956B118200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMultilineTextInputViewManager.m; sourceTree = ""; }; + 5956B119200FEBA9008D9D16 /* RCTUITextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUITextView.m; sourceTree = ""; }; + 5956B11A200FEBA9008D9D16 /* RCTTextAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextAttributes.h; sourceTree = ""; }; + 5956B11C200FEBA9008D9D16 /* RCTBaseTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextViewManager.h; sourceTree = ""; }; + 5956B11D200FEBA9008D9D16 /* RCTBaseTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextShadowView.h; sourceTree = ""; }; + 5956B11E200FEBA9008D9D16 /* RCTBaseTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextShadowView.m; sourceTree = ""; }; + 5956B11F200FEBA9008D9D16 /* RCTBaseTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextViewManager.m; sourceTree = ""; }; + 5956B120200FEBA9008D9D16 /* RCTTextAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextAttributes.m; sourceTree = ""; }; + 5956B122200FEBAA008D9D16 /* RCTTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextShadowView.m; sourceTree = ""; }; + 5956B123200FEBAA008D9D16 /* RCTTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextView.h; sourceTree = ""; }; + 5956B124200FEBAA008D9D16 /* RCTTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextViewManager.h; sourceTree = ""; }; + 5956B125200FEBAA008D9D16 /* NSTextStorage+FontScaling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTextStorage+FontScaling.m"; sourceTree = ""; }; + 5956B126200FEBAA008D9D16 /* RCTTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTextShadowView.h; sourceTree = ""; }; + 5956B127200FEBAA008D9D16 /* RCTTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextViewManager.m; sourceTree = ""; }; + 5956B128200FEBAA008D9D16 /* RCTTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextView.m; sourceTree = ""; }; + 5956B129200FEBAA008D9D16 /* NSTextStorage+FontScaling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextStorage+FontScaling.h"; sourceTree = ""; }; + 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextViewManager.m; sourceTree = ""; }; + 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextShadowView.h; sourceTree = ""; }; + 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextViewManager.h; sourceTree = ""; }; + 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextShadowView.m; sourceTree = ""; }; + 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Text.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( - D4EEE302201FA3A100C4CBB6 /* TextInputLegacy */, + 5956B11B200FEBA9008D9D16 /* BaseText */, 58B5119C1A9E6C1200147676 /* Products */, - A85C82981F742AA20036C019 /* RCTFontAttributes.h */, - A85C82991F742AA20036C019 /* RCTFontAttributes.m */, - A85C82BA1F742D8F0036C019 /* RCTFontAttributesDelegate.h */, - 59E6042C1FE9CAF100BD90C5 /* RCTRawTextShadowView.h */, - 59E604341FE9CAF100BD90C5 /* RCTRawTextShadowView.m */, - 59E604351FE9CAF100BD90C5 /* RCTRawTextViewManager.h */, - 59E604361FE9CAF100BD90C5 /* RCTRawTextViewManager.m */, - 59E6042D1FE9CAF100BD90C5 /* Text */, + 5956B0FA200FEBA9008D9D16 /* RawText */, + 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */, + 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */, + 5956B11A200FEBA9008D9D16 /* RCTTextAttributes.h */, + 5956B120200FEBA9008D9D16 /* RCTTextAttributes.m */, + 5956B121200FEBAA008D9D16 /* Text */, + 5956B0FF200FEBA9008D9D16 /* TextInput */, + 5956B12A200FEBAA008D9D16 /* VirtualText */, ); indentWidth = 2; sourceTree = ""; @@ -146,42 +260,99 @@ name = Products; sourceTree = ""; }; - 59E6042D1FE9CAF100BD90C5 /* Text */ = { + 5956B0FA200FEBA9008D9D16 /* RawText */ = { isa = PBXGroup; children = ( - 59E6042E1FE9CAF100BD90C5 /* RCTTextShadowView.h */, - 59E6042F1FE9CAF100BD90C5 /* RCTTextShadowView.m */, - 59E604301FE9CAF100BD90C5 /* RCTTextView.h */, - 59E604311FE9CAF100BD90C5 /* RCTTextView.m */, - 59E604321FE9CAF100BD90C5 /* RCTTextViewManager.h */, - 59E604331FE9CAF100BD90C5 /* RCTTextViewManager.m */, + 5956B0FC200FEBA9008D9D16 /* RCTRawTextShadowView.h */, + 5956B0FD200FEBA9008D9D16 /* RCTRawTextShadowView.m */, + 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */, + 5956B0FE200FEBA9008D9D16 /* RCTRawTextViewManager.m */, + ); + path = RawText; + sourceTree = ""; + }; + 5956B0FF200FEBA9008D9D16 /* TextInput */ = { + isa = PBXGroup; + children = ( + 5956B113200FEBA9008D9D16 /* Multiline */, + 5956B10C200FEBA9008D9D16 /* RCTBackedTextInputDelegate.h */, + 5956B107200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.h */, + 5956B10D200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.m */, + 5956B112200FEBA9008D9D16 /* RCTBackedTextInputViewProtocol.h */, + 5956B109200FEBA9008D9D16 /* RCTBaseTextInputShadowView.h */, + 5956B10F200FEBA9008D9D16 /* RCTBaseTextInputShadowView.m */, + 5956B10E200FEBA9008D9D16 /* RCTBaseTextInputView.h */, + 5956B10A200FEBA9008D9D16 /* RCTBaseTextInputView.m */, + 5956B10B200FEBA9008D9D16 /* RCTBaseTextInputViewManager.h */, + 5956B111200FEBA9008D9D16 /* RCTBaseTextInputViewManager.m */, + 5956B108200FEBA9008D9D16 /* RCTTextSelection.h */, + 5956B110200FEBA9008D9D16 /* RCTTextSelection.m */, + 5956B100200FEBA9008D9D16 /* Singleline */, + ); + path = TextInput; + sourceTree = ""; + }; + 5956B100200FEBA9008D9D16 /* Singleline */ = { + isa = PBXGroup; + children = ( + 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */, + 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */, + 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */, + 5956B106200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.m */, + 5956B105200FEBA9008D9D16 /* RCTUITextField.h */, + 5956B103200FEBA9008D9D16 /* RCTUITextField.m */, + ); + path = Singleline; + sourceTree = ""; + }; + 5956B113200FEBA9008D9D16 /* Multiline */ = { + isa = PBXGroup; + children = ( + 5956B117200FEBA9008D9D16 /* RCTMultilineTextInputView.h */, + 5956B115200FEBA9008D9D16 /* RCTMultilineTextInputView.m */, + 5956B114200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.h */, + 5956B118200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.m */, + 5956B116200FEBA9008D9D16 /* RCTUITextView.h */, + 5956B119200FEBA9008D9D16 /* RCTUITextView.m */, + ); + path = Multiline; + sourceTree = ""; + }; + 5956B11B200FEBA9008D9D16 /* BaseText */ = { + isa = PBXGroup; + children = ( + 5956B11D200FEBA9008D9D16 /* RCTBaseTextShadowView.h */, + 5956B11E200FEBA9008D9D16 /* RCTBaseTextShadowView.m */, + 5956B11C200FEBA9008D9D16 /* RCTBaseTextViewManager.h */, + 5956B11F200FEBA9008D9D16 /* RCTBaseTextViewManager.m */, + ); + path = BaseText; + sourceTree = ""; + }; + 5956B121200FEBAA008D9D16 /* Text */ = { + isa = PBXGroup; + children = ( + 5956B129200FEBAA008D9D16 /* NSTextStorage+FontScaling.h */, + 5956B125200FEBAA008D9D16 /* NSTextStorage+FontScaling.m */, + 5956B126200FEBAA008D9D16 /* RCTTextShadowView.h */, + 5956B122200FEBAA008D9D16 /* RCTTextShadowView.m */, + 5956B123200FEBAA008D9D16 /* RCTTextView.h */, + 5956B128200FEBAA008D9D16 /* RCTTextView.m */, + 5956B124200FEBAA008D9D16 /* RCTTextViewManager.h */, + 5956B127200FEBAA008D9D16 /* RCTTextViewManager.m */, ); path = Text; sourceTree = ""; }; - D4EEE302201FA3A100C4CBB6 /* TextInputLegacy */ = { + 5956B12A200FEBAA008D9D16 /* VirtualText */ = { isa = PBXGroup; children = ( - D4EEE30E201FA3B200C4CBB6 /* RCTMultilineTextInputView.h */, - D4EEE303201FA3B100C4CBB6 /* RCTMultilineTextInputView.m */, - D4EEE30A201FA3B100C4CBB6 /* RCTSecureTextField.h */, - D4EEE312201FA3B200C4CBB6 /* RCTSecureTextField.m */, - D4EEE304201FA3B100C4CBB6 /* RCTShadowTextField.h */, - D4EEE315201FA3B300C4CBB6 /* RCTShadowTextField.m */, - D4EEE305201FA3B100C4CBB6 /* RCTShadowTextView.h */, - D4EEE30C201FA3B200C4CBB6 /* RCTShadowTextView.m */, - D4EEE306201FA3B100C4CBB6 /* RCTTextField.h */, - D4EEE313201FA3B200C4CBB6 /* RCTTextField.m */, - D4EEE308201FA3B100C4CBB6 /* RCTTextFieldManager.h */, - D4EEE310201FA3B200C4CBB6 /* RCTTextFieldManager.m */, - D4EEE309201FA3B100C4CBB6 /* RCTTextSelection.h */, - D4EEE30D201FA3B200C4CBB6 /* RCTTextSelection.m */, - D4EEE30F201FA3B200C4CBB6 /* RCTTextViewManager.h */, - D4EEE316201FA3B300C4CBB6 /* RCTTextViewManager.m */, - D4EEE311201FA3B200C4CBB6 /* RCTUITextView.h */, - D4EEE307201FA3B100C4CBB6 /* RCTUITextView.m */, + 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */, + 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */, + 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */, + 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */, ); - name = TextInputLegacy; + path = VirtualText; sourceTree = ""; }; /* End PBXGroup section */ @@ -260,12 +431,29 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 59E604571FE9CAF100BD90C5 /* RCTTextViewManager.m in Sources */, - 59E604531FE9CAF100BD90C5 /* RCTTextShadowView.m in Sources */, - 59E604591FE9CAF100BD90C5 /* RCTRawTextShadowView.m in Sources */, - 59E604551FE9CAF100BD90C5 /* RCTTextView.m in Sources */, - 59E8C5CC1F8833D100204F5E /* RCTFontAttributes.m in Sources */, - 59E6045B1FE9CAF100BD90C5 /* RCTRawTextViewManager.m in Sources */, + 5956B192200FF35C008D9D16 /* RCTBaseTextShadowView.m in Sources */, + 5956B193200FF35C008D9D16 /* RCTBaseTextViewManager.m in Sources */, + 5956B194200FF35C008D9D16 /* RCTRawTextShadowView.m in Sources */, + 5956B195200FF35C008D9D16 /* RCTRawTextViewManager.m in Sources */, + 5956B196200FF35C008D9D16 /* RCTConvert+Text.m in Sources */, + 5956B197200FF35C008D9D16 /* RCTTextAttributes.m in Sources */, + 5956B198200FF35C008D9D16 /* NSTextStorage+FontScaling.m in Sources */, + 5956B199200FF35C008D9D16 /* RCTTextShadowView.m in Sources */, + 5956B19A200FF35C008D9D16 /* RCTTextView.m in Sources */, + 5956B19B200FF35C008D9D16 /* RCTTextViewManager.m in Sources */, + 5956B19C200FF35C008D9D16 /* RCTMultilineTextInputView.m in Sources */, + 5956B19D200FF35C008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */, + 5956B19E200FF35C008D9D16 /* RCTUITextView.m in Sources */, + 5956B19F200FF35C008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */, + 5956B1A0200FF35C008D9D16 /* RCTBaseTextInputShadowView.m in Sources */, + 5956B1A1200FF35C008D9D16 /* RCTBaseTextInputView.m in Sources */, + 5956B1A2200FF35C008D9D16 /* RCTBaseTextInputViewManager.m in Sources */, + 5956B1A3200FF35C008D9D16 /* RCTTextSelection.m in Sources */, + 5956B1A4200FF35C008D9D16 /* RCTSinglelineTextInputView.m in Sources */, + 5956B1A5200FF35C008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */, + 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */, + 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */, + 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -273,21 +461,29 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 59E604561FE9CAF100BD90C5 /* RCTTextViewManager.m in Sources */, - D4EEE318201FA3B300C4CBB6 /* RCTUITextView.m in Sources */, - D4EEE31C201FA3B300C4CBB6 /* RCTTextFieldManager.m in Sources */, - D4EEE31D201FA3B300C4CBB6 /* RCTSecureTextField.m in Sources */, - 59E604521FE9CAF100BD90C5 /* RCTTextShadowView.m in Sources */, - D4EEE320201FA3B300C4CBB6 /* RCTTextViewManager.m in Sources */, - D4EEE31A201FA3B300C4CBB6 /* RCTShadowTextView.m in Sources */, - D4EEE31F201FA3B300C4CBB6 /* RCTShadowTextField.m in Sources */, - D4EEE31B201FA3B300C4CBB6 /* RCTTextSelection.m in Sources */, - D4EEE317201FA3B300C4CBB6 /* RCTMultilineTextInputView.m in Sources */, - 59E604581FE9CAF100BD90C5 /* RCTRawTextShadowView.m in Sources */, - D4EEE31E201FA3B300C4CBB6 /* RCTTextField.m in Sources */, - 59E604541FE9CAF100BD90C5 /* RCTTextView.m in Sources */, - A85C829A1F742AA20036C019 /* RCTFontAttributes.m in Sources */, - 59E6045A1FE9CAF100BD90C5 /* RCTRawTextViewManager.m in Sources */, + 5956B13D200FEBAA008D9D16 /* RCTBaseTextShadowView.m in Sources */, + 5956B140200FEBAA008D9D16 /* RCTTextShadowView.m in Sources */, + 5956B131200FEBAA008D9D16 /* RCTRawTextViewManager.m in Sources */, + 5956B137200FEBAA008D9D16 /* RCTBaseTextInputShadowView.m in Sources */, + 5956B146200FEBAA008D9D16 /* RCTConvert+Text.m in Sources */, + 5956B13F200FEBAA008D9D16 /* RCTTextAttributes.m in Sources */, + 5956B143200FEBAA008D9D16 /* RCTTextView.m in Sources */, + 5956B13C200FEBAA008D9D16 /* RCTUITextView.m in Sources */, + 5956B136200FEBAA008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */, + 5956B13E200FEBAA008D9D16 /* RCTBaseTextViewManager.m in Sources */, + 5956B145200FEBAA008D9D16 /* RCTVirtualTextShadowView.m in Sources */, + 5956B142200FEBAA008D9D16 /* RCTTextViewManager.m in Sources */, + 5956B135200FEBAA008D9D16 /* RCTBaseTextInputView.m in Sources */, + 5956B144200FEBAA008D9D16 /* RCTVirtualTextViewManager.m in Sources */, + 5956B13B200FEBAA008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */, + 5956B134200FEBAA008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */, + 5956B139200FEBAA008D9D16 /* RCTBaseTextInputViewManager.m in Sources */, + 5956B138200FEBAA008D9D16 /* RCTTextSelection.m in Sources */, + 5956B130200FEBAA008D9D16 /* RCTRawTextShadowView.m in Sources */, + 5956B141200FEBAA008D9D16 /* NSTextStorage+FontScaling.m in Sources */, + 5956B132200FEBAA008D9D16 /* RCTSinglelineTextInputView.m in Sources */, + 5956B13A200FEBAA008D9D16 /* RCTMultilineTextInputView.m in Sources */, + 5956B133200FEBAA008D9D16 /* RCTUITextField.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Libraries/Text/RCTTextAttributes.h b/Libraries/Text/RCTTextAttributes.h new file mode 100644 index 0000000000..7752c2c66b --- /dev/null +++ b/Libraries/Text/RCTTextAttributes.h @@ -0,0 +1,85 @@ +/** + * 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const RCTTextAttributesIsHighlightedAttributeName; +extern NSString *const RCTTextAttributesTagAttributeName; + +/** + * Represents knowledge about all supported *text* attributes + * assigned to some text component such as , , + * and . + */ +@interface RCTTextAttributes : NSObject + +// Color +@property (nonatomic, strong, nullable) UIColor *foregroundColor; +@property (nonatomic, strong, nullable) UIColor *backgroundColor; +@property (nonatomic, assign) CGFloat opacity; +// Font +@property (nonatomic, copy, nullable) NSString *fontFamily; +@property (nonatomic, assign) CGFloat fontSize; +@property (nonatomic, assign) CGFloat fontSizeMultiplier; +@property (nonatomic, copy, nullable) NSString *fontWeight; +@property (nonatomic, copy, nullable) NSString *fontStyle; +@property (nonatomic, copy, nullable) NSArray *fontVariant; +@property (nonatomic, assign) BOOL allowFontScaling; +@property (nonatomic, assign) CGFloat letterSpacing; +// Paragraph Styles +@property (nonatomic, assign) CGFloat lineHeight; +@property (nonatomic, assign) NSTextAlignment alignment; +@property (nonatomic, assign) NSWritingDirection baseWritingDirection; +// Decoration +@property (nonatomic, strong, nullable) UIColor *textDecorationColor; +@property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; +@property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine; +// Shadow +@property (nonatomic, assign) CGSize textShadowOffset; +@property (nonatomic, assign) CGFloat textShadowRadius; +@property (nonatomic, strong, nullable) UIColor *textShadowColor; +// Special +@property (nonatomic, assign) BOOL isHighlighted; +@property (nonatomic, strong, nullable) NSNumber *tag; +@property (nonatomic, assign) UIUserInterfaceLayoutDirection layoutDirection; + +#pragma mark - Inheritance + +- (void)applyTextAttributes:(RCTTextAttributes *)textAttributes; + +#pragma mark - Adapters + +/** + * Text attributes in NSAttributedString terms. + */ +- (NSDictionary *)effectiveTextAttributes; + +/** + * Constructed font. + */ +- (UIFont *)effectiveFont; + +/** + * Font size multiplier reflects `allowFontScaling` and `fontSizeMultiplier`. + */ +- (CGFloat)effectiveFontSizeMultiplier; + +/** + * Foreground and background colors with opacity and right defaults. + */ +- (UIColor *)effectiveForegroundColor; +- (UIColor *)effectiveBackgroundColor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/RCTTextAttributes.m b/Libraries/Text/RCTTextAttributes.m new file mode 100644 index 0000000000..26d63bdda8 --- /dev/null +++ b/Libraries/Text/RCTTextAttributes.m @@ -0,0 +1,270 @@ +/** + * 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 "RCTTextAttributes.h" + +#import +#import +#import + +NSString *const RCTTextAttributesIsHighlightedAttributeName = @"RCTTextAttributesIsHighlightedAttributeName"; +NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttributeName"; + +@implementation RCTTextAttributes + +- (instancetype)init +{ + if (self = [super init]) { + _fontSize = NAN; + _letterSpacing = NAN; + _textDecorationStyle = NSUnderlineStyleSingle; + _fontSizeMultiplier = NAN; + _alignment = NSTextAlignmentNatural; + _baseWritingDirection = NSWritingDirectionNatural; + _textShadowRadius = NAN; + _opacity = NAN; + } + + return self; +} + +- (void)applyTextAttributes:(RCTTextAttributes *)textAttributes +{ + // Note: All lines marked with `*` does not use explicit/correct rules to compare old and new values becuase + // their types do not have special designated value representing undefined/unspecified/inherit meaning. + // We will address this in the future. + + // Color + _foregroundColor = textAttributes->_foregroundColor ?: _foregroundColor; + _backgroundColor = textAttributes->_backgroundColor ?: _backgroundColor; + _opacity = !isnan(textAttributes->_opacity) ? (isnan(_opacity) ? 1.0 : _opacity) * textAttributes->_opacity : _opacity; + + // Font + _fontFamily = textAttributes->_fontFamily ?: _fontFamily; + _fontSize = !isnan(textAttributes->_fontSize) ? textAttributes->_fontSize : _fontSize; + _fontSizeMultiplier = !isnan(textAttributes->_fontSizeMultiplier) ? textAttributes->_fontSizeMultiplier : _fontSizeMultiplier; + _fontWeight = textAttributes->_fontWeight ?: _fontWeight; + _fontStyle = textAttributes->_fontStyle ?: _fontStyle; + _fontVariant = textAttributes->_fontVariant ?: _fontVariant; + _allowFontScaling = textAttributes->_allowFontScaling || _allowFontScaling; // * + _letterSpacing = !isnan(textAttributes->_letterSpacing) ? textAttributes->_letterSpacing : _letterSpacing; + + // Paragraph Styles + _lineHeight = !isnan(textAttributes->_lineHeight) ? textAttributes->_lineHeight : _lineHeight; + _alignment = textAttributes->_alignment != NSTextAlignmentNatural ? textAttributes->_alignment : _alignment; // * + _baseWritingDirection = textAttributes->_baseWritingDirection != NSWritingDirectionNatural ? textAttributes->_baseWritingDirection : _baseWritingDirection; // * + + // Decoration + _textDecorationColor = textAttributes->_textDecorationColor ?: _textDecorationColor; + _textDecorationStyle = textAttributes->_textDecorationStyle != NSUnderlineStyleSingle ? textAttributes->_textDecorationStyle : _textDecorationStyle; // * + _textDecorationLine = textAttributes->_textDecorationLine != RCTTextDecorationLineTypeNone ? textAttributes->_textDecorationLine : _textDecorationLine; // * + + // Shadow + _textShadowOffset = !CGSizeEqualToSize(textAttributes->_textShadowOffset, CGSizeZero) ? textAttributes->_textShadowOffset : _textShadowOffset; // * + _textShadowRadius = !isnan(textAttributes->_textShadowRadius) ? textAttributes->_textShadowRadius : _textShadowRadius; + _textShadowColor = textAttributes->_textShadowColor ?: _textShadowColor; + + // Special + _isHighlighted = textAttributes->_isHighlighted || _isHighlighted; // * + _tag = textAttributes->_tag ?: _tag; + _layoutDirection = textAttributes->_layoutDirection != UIUserInterfaceLayoutDirectionLeftToRight ? textAttributes->_layoutDirection : _layoutDirection; +} + +- (NSDictionary *)effectiveTextAttributes +{ + NSMutableDictionary *attributes = + [NSMutableDictionary dictionaryWithCapacity:10]; + + // Font + UIFont *font = self.effectiveFont; + if (font) { + attributes[NSFontAttributeName] = font; + } + + // Colors + UIColor *effectiveForegroundColor = self.effectiveForegroundColor; + + if (_foregroundColor || !isnan(_opacity)) { + attributes[NSForegroundColorAttributeName] = effectiveForegroundColor; + } + + if (_backgroundColor || !isnan(_opacity)) { + attributes[NSBackgroundColorAttributeName] = self.effectiveBackgroundColor; + } + + // Kerning + if (!isnan(_letterSpacing)) { + attributes[NSKernAttributeName] = @(_letterSpacing); + } + + // Paragraph Style + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + BOOL isParagraphStyleUsed = NO; + if (_alignment != NSTextAlignmentNatural) { + NSTextAlignment alignment = _alignment; + if (_layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) { + if (alignment == NSTextAlignmentRight) { + alignment = NSTextAlignmentLeft; + } else if (alignment == NSTextAlignmentLeft) { + alignment = NSTextAlignmentRight; + } + } + + paragraphStyle.alignment = alignment; + isParagraphStyleUsed = YES; + } + + if (_baseWritingDirection != NSWritingDirectionNatural) { + paragraphStyle.baseWritingDirection = _baseWritingDirection; + isParagraphStyleUsed = YES; + } + + if (!isnan(_lineHeight)) { + CGFloat lineHeight = _lineHeight * self.effectiveFontSizeMultiplier; + paragraphStyle.minimumLineHeight = lineHeight; + paragraphStyle.maximumLineHeight = lineHeight; + isParagraphStyleUsed = YES; + } + + if (isParagraphStyleUsed) { + attributes[NSParagraphStyleAttributeName] = paragraphStyle; + } + + // Decoration + BOOL isTextDecorationEnabled = NO; + if (_textDecorationLine == RCTTextDecorationLineTypeUnderline || + _textDecorationLine == RCTTextDecorationLineTypeUnderlineStrikethrough) { + isTextDecorationEnabled = YES; + attributes[NSUnderlineStyleAttributeName] = @(_textDecorationStyle); + } + + if (_textDecorationLine == RCTTextDecorationLineTypeStrikethrough || + _textDecorationLine == RCTTextDecorationLineTypeUnderlineStrikethrough){ + isTextDecorationEnabled = YES; + attributes[NSStrikethroughStyleAttributeName] = @(_textDecorationStyle); + } + + if (_textDecorationColor || isTextDecorationEnabled) { + attributes[NSStrikethroughColorAttributeName] = _textDecorationColor ?: effectiveForegroundColor; + attributes[NSUnderlineColorAttributeName] = _textDecorationColor ?: effectiveForegroundColor; + } + + // Shadow + if (!CGSizeEqualToSize(_textShadowOffset, CGSizeZero)) { + NSShadow *shadow = [NSShadow new]; + shadow.shadowOffset = _textShadowOffset; + shadow.shadowBlurRadius = _textShadowRadius; + shadow.shadowColor = _textShadowColor; + attributes[NSShadowAttributeName] = shadow; + } + + // Special + if (_isHighlighted) { + attributes[RCTTextAttributesIsHighlightedAttributeName] = @YES; + } + + if (_tag) { + attributes[RCTTextAttributesTagAttributeName] = _tag; + } + + return [attributes copy]; +} + +- (UIFont *)effectiveFont +{ + // FIXME: RCTFont has thread-safety issues and must be rewritten. + return [RCTFont updateFont:nil + withFamily:_fontFamily + size:@(isnan(_fontSize) ? 0 : _fontSize) + weight:_fontWeight + style:_fontStyle + variant:_fontVariant + scaleMultiplier:self.effectiveFontSizeMultiplier]; +} + +- (CGFloat)effectiveFontSizeMultiplier +{ + return _allowFontScaling && !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0; +} + +- (UIColor *)effectiveForegroundColor +{ + UIColor *effectiveForegroundColor = _foregroundColor ?: [UIColor blackColor]; + + if (!isnan(_opacity)) { + effectiveForegroundColor = [effectiveForegroundColor colorWithAlphaComponent:CGColorGetAlpha(effectiveForegroundColor.CGColor) * _opacity]; + } + + return effectiveForegroundColor; +} + +- (UIColor *)effectiveBackgroundColor +{ + UIColor *effectiveBackgroundColor = _backgroundColor;// ?: [[UIColor whiteColor] colorWithAlphaComponent:0]; + + if (effectiveBackgroundColor && !isnan(_opacity)) { + effectiveBackgroundColor = [effectiveBackgroundColor colorWithAlphaComponent:CGColorGetAlpha(effectiveBackgroundColor.CGColor) * _opacity]; + } + + return effectiveBackgroundColor ?: [UIColor clearColor]; +} + +- (RCTTextAttributes *)copyWithZone:(NSZone *)zone +{ + RCTTextAttributes *textAttributes = [RCTTextAttributes new]; + [textAttributes applyTextAttributes:self]; + return textAttributes; +} + +#pragma mark - NSObject + +- (BOOL)isEqual:(RCTTextAttributes *)textAttributes +{ + if (self == textAttributes) { + return YES; + } + +#define RCTTextAttributesCompareFloats(a) ((a == textAttributes->a) || (isnan(a) && isnan(textAttributes->a))) +#define RCTTextAttributesCompareSize(a) CGSizeEqualToSize(a, textAttributes->a) +#define RCTTextAttributesCompareObjects(a) ((a == textAttributes->a) || [a isEqual:textAttributes->a]) +#define RCTTextAttributesCompareStrings(a) ((a == textAttributes->a) || [a isEqualToString:textAttributes->a]) +#define RCTTextAttributesCompareOthers(a) (a == textAttributes->a) + + return + RCTTextAttributesCompareObjects(_foregroundColor) && + RCTTextAttributesCompareObjects(_backgroundColor) && + RCTTextAttributesCompareFloats(_opacity) && + // Font + RCTTextAttributesCompareObjects(_fontFamily) && + RCTTextAttributesCompareFloats(_fontSize) && + RCTTextAttributesCompareFloats(_fontSizeMultiplier) && + RCTTextAttributesCompareStrings(_fontWeight) && + RCTTextAttributesCompareObjects(_fontStyle) && + RCTTextAttributesCompareObjects(_fontVariant) && + RCTTextAttributesCompareOthers(_allowFontScaling) && + RCTTextAttributesCompareFloats(_letterSpacing) && + // Paragraph Styles + RCTTextAttributesCompareFloats(_lineHeight) && + RCTTextAttributesCompareFloats(_alignment) && + RCTTextAttributesCompareOthers(_baseWritingDirection) && + // Decoration + RCTTextAttributesCompareObjects(_textDecorationColor) && + RCTTextAttributesCompareOthers(_textDecorationStyle) && + RCTTextAttributesCompareOthers(_textDecorationLine) && + // Shadow + RCTTextAttributesCompareSize(_textShadowOffset) && + RCTTextAttributesCompareFloats(_textShadowRadius) && + RCTTextAttributesCompareObjects(_textShadowColor) && + // Special + RCTTextAttributesCompareOthers(_isHighlighted) && + RCTTextAttributesCompareObjects(_tag) && + RCTTextAttributesCompareOthers(_layoutDirection); +} + +@end diff --git a/Libraries/Text/RawText/RCTRawTextShadowView.h b/Libraries/Text/RawText/RCTRawTextShadowView.h new file mode 100644 index 0000000000..52e61f0ba9 --- /dev/null +++ b/Libraries/Text/RawText/RCTRawTextShadowView.h @@ -0,0 +1,20 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTRawTextShadowView : RCTShadowView + +@property (nonatomic, copy, nullable) NSString *text; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/RawText/RCTRawTextShadowView.m b/Libraries/Text/RawText/RCTRawTextShadowView.m new file mode 100644 index 0000000000..d350d29684 --- /dev/null +++ b/Libraries/Text/RawText/RCTRawTextShadowView.m @@ -0,0 +1,35 @@ +/** + * 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 "RCTRawTextShadowView.h" + +#import + +@implementation RCTRawTextShadowView + +- (void)setText:(NSString *)text +{ + if (_text != text && ![_text isEqualToString:text]) { + _text = [text copy]; + [self dirtyLayout]; + } +} + +- (void)dirtyLayout +{ + [self.superview dirtyLayout]; +} + +- (NSString *)description +{ + NSString *superDescription = super.description; + return [[superDescription substringToIndex:superDescription.length - 1] stringByAppendingFormat:@"; text: %@>", self.text]; +} + +@end diff --git a/Libraries/Text/RawText/RCTRawTextViewManager.h b/Libraries/Text/RawText/RCTRawTextViewManager.h new file mode 100644 index 0000000000..38d83e385b --- /dev/null +++ b/Libraries/Text/RawText/RCTRawTextViewManager.h @@ -0,0 +1,18 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTRawTextViewManager : RCTViewManager + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/RawText/RCTRawTextViewManager.m b/Libraries/Text/RawText/RCTRawTextViewManager.m new file mode 100644 index 0000000000..17233cdc79 --- /dev/null +++ b/Libraries/Text/RawText/RCTRawTextViewManager.m @@ -0,0 +1,30 @@ +/** + * 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 "RCTRawTextViewManager.h" + +#import "RCTRawTextShadowView.h" + +@implementation RCTRawTextViewManager + +RCT_EXPORT_MODULE(RCTRawText) + +- (UIView *)view +{ + return [UIView new]; +} + +- (RCTShadowView *)shadowView +{ + return [RCTRawTextShadowView new]; +} + +RCT_EXPORT_SHADOW_PROPERTY(text, NSString) + +@end diff --git a/Libraries/Text/Text/NSTextStorage+FontScaling.h b/Libraries/Text/Text/NSTextStorage+FontScaling.h new file mode 100644 index 0000000000..f3ea09ab26 --- /dev/null +++ b/Libraries/Text/Text/NSTextStorage+FontScaling.h @@ -0,0 +1,22 @@ +/** + * 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 + +@interface NSTextStorage (FontScaling) + +- (void)scaleFontSizeToFitSize:(CGSize)size + minimumFontSize:(CGFloat)minimumFontSize + maximumFontSize:(CGFloat)maximumFontSize; + +- (void)scaleFontSizeWithRatio:(CGFloat)ratio + minimumFontSize:(CGFloat)minimumFontSize + maximumFontSize:(CGFloat)maximumFontSize; + +@end diff --git a/Libraries/Text/Text/NSTextStorage+FontScaling.m b/Libraries/Text/Text/NSTextStorage+FontScaling.m new file mode 100644 index 0000000000..4233bef967 --- /dev/null +++ b/Libraries/Text/Text/NSTextStorage+FontScaling.m @@ -0,0 +1,139 @@ +/** + * 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 "NSTextStorage+FontScaling.h" + +typedef NS_OPTIONS(NSInteger, RCTTextSizeComparisonOptions) { + RCTTextSizeComparisonSmaller = 1 << 0, + RCTTextSizeComparisonLarger = 1 << 1, + RCTTextSizeComparisonWithinRange = 1 << 2, +}; + +@implementation NSTextStorage (FontScaling) + +- (void)scaleFontSizeToFitSize:(CGSize)size + minimumFontSize:(CGFloat)minimumFontSize + maximumFontSize:(CGFloat)maximumFontSize +{ + CGFloat bottomRatio = 1.0/128.0; + CGFloat topRatio = 128.0; + CGFloat ratio = 1.0; + + NSAttributedString *originalAttributedString = [self copy]; + + CGFloat lastRatioWhichFits = 0.02; + + while (true) { + [self scaleFontSizeWithRatio:ratio + minimumFontSize:minimumFontSize + maximumFontSize:maximumFontSize]; + + RCTTextSizeComparisonOptions comparsion = + [self compareToSize:size thresholdRatio:0.01]; + + if ( + (comparsion & RCTTextSizeComparisonWithinRange) && + (comparsion & RCTTextSizeComparisonSmaller) + ) { + return; + } else if (comparsion & RCTTextSizeComparisonSmaller) { + bottomRatio = ratio; + lastRatioWhichFits = ratio; + } else { + topRatio = ratio; + } + + ratio = (topRatio + bottomRatio) / 2.0; + + CGFloat kRatioThreshold = 0.005; + if ( + ABS(topRatio - bottomRatio) < kRatioThreshold || + ABS(topRatio - ratio) < kRatioThreshold || + ABS(bottomRatio - ratio) < kRatioThreshold + ) { + [self replaceCharactersInRange:(NSRange){0, self.length} + withAttributedString:originalAttributedString]; + + [self scaleFontSizeWithRatio:lastRatioWhichFits + minimumFontSize:minimumFontSize + maximumFontSize:maximumFontSize]; + return; + } + + [self replaceCharactersInRange:(NSRange){0, self.length} + withAttributedString:originalAttributedString]; + } +} + + +- (RCTTextSizeComparisonOptions)compareToSize:(CGSize)size thresholdRatio:(CGFloat)thresholdRatio +{ + NSLayoutManager *layoutManager = self.layoutManagers.firstObject; + NSTextContainer *textContainer = layoutManager.textContainers.firstObject; + + [layoutManager ensureLayoutForTextContainer:textContainer]; + + // Does it fit the text container? + NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; + NSRange truncatedGlyphRange = [layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:glyphRange.length - 1]; + + if (truncatedGlyphRange.location != NSNotFound) { + return RCTTextSizeComparisonLarger; + } + + CGSize measuredSize = [layoutManager usedRectForTextContainer:textContainer].size; + + // Does it fit the size? + BOOL fitsSize = + size.width >= measuredSize.width && + size.height >= measuredSize.height; + + CGSize thresholdSize = (CGSize){ + size.width * thresholdRatio, + size.height * thresholdRatio, + }; + + RCTTextSizeComparisonOptions result = 0; + + result |= (fitsSize) ? RCTTextSizeComparisonSmaller : RCTTextSizeComparisonLarger; + + if (ABS(measuredSize.width - size.width) < thresholdSize.width) { + result = result | RCTTextSizeComparisonWithinRange; + } + + return result; +} + +- (void)scaleFontSizeWithRatio:(CGFloat)ratio + minimumFontSize:(CGFloat)minimumFontSize + maximumFontSize:(CGFloat)maximumFontSize +{ + [self beginEditing]; + + [self enumerateAttribute:NSFontAttributeName + inRange:(NSRange){0, self.length} + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock: + ^(UIFont *_Nullable font, NSRange range, BOOL *_Nonnull stop) { + if (!font) { + return; + } + + CGFloat fontSize = MAX(MIN(font.pointSize * ratio, maximumFontSize), minimumFontSize); + + [self addAttribute:NSFontAttributeName + value:[font fontWithSize:fontSize] + range:range]; + } + ]; + + [self endEditing]; +} + +@end diff --git a/Libraries/Text/Text/RCTTextShadowView.h b/Libraries/Text/Text/RCTTextShadowView.h index df087cc6b1..6cdd8fdd31 100644 --- a/Libraries/Text/Text/RCTTextShadowView.h +++ b/Libraries/Text/Text/RCTTextShadowView.h @@ -8,49 +8,22 @@ */ #import -#import - -typedef NS_ENUM(NSInteger, RCTSizeComparison) -{ - RCTSizeTooLarge, - RCTSizeTooSmall, - RCTSizeWithinRange, -}; - - -extern NSString *const RCTIsHighlightedAttributeName; -extern NSString *const RCTReactTagAttributeName; - -@interface RCTTextShadowView : RCTShadowView - -@property (nonatomic, strong) NSColor *color; -@property (nonatomic, strong) NSColor *backgroundColor; -@property (nonatomic, copy) NSString *fontFamily; -@property (nonatomic, assign) CGFloat fontSize; -@property (nonatomic, copy) NSString *fontWeight; -@property (nonatomic, copy) NSString *fontStyle; -@property (nonatomic, copy) NSArray *fontVariant; -@property (nonatomic, assign) BOOL isHighlighted; -@property (nonatomic, assign) CGFloat letterSpacing; -@property (nonatomic, assign) CGFloat lineHeight; -@property (nonatomic, assign) NSUInteger numberOfLines; -@property (nonatomic, assign) NSLineBreakMode ellipsizeMode; -@property (nonatomic, assign) CGSize shadowOffset; -@property (nonatomic, assign) NSTextAlignment textAlign; -@property (nonatomic, assign) NSWritingDirection writingDirection; -@property (nonatomic, strong) NSColor *textDecorationColor; -@property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; -@property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine; -@property (nonatomic, assign) CGFloat fontSizeMultiplier; -@property (nonatomic, assign) BOOL allowFontScaling; -@property (nonatomic, assign) CGFloat opacity; -@property (nonatomic, assign) CGSize textShadowOffset; -@property (nonatomic, assign) CGFloat textShadowRadius; -@property (nonatomic, strong) NSColor *textShadowColor; + +#import "RCTBaseTextShadowView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTTextShadowView : RCTBaseTextShadowView + +- (instancetype)initWithBridge:(RCTBridge *)bridge; + +@property (nonatomic, assign) NSInteger maximumNumberOfLines; +@property (nonatomic, assign) NSLineBreakMode lineBreakMode; @property (nonatomic, assign) BOOL adjustsFontSizeToFit; @property (nonatomic, assign) CGFloat minimumFontScale; -@property (nonatomic, assign) BOOL selectable; -- (void)recomputeText; +- (void)uiManagerWillPerformMounting; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index e7bc8d1127..4f29f057b9 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -9,680 +9,336 @@ #import "RCTTextShadowView.h" -// TODO: (critical) Fix accessibility -// #import #import -#import -#import -#import #import #import -#import +#import -#import "RCTRawTextShadowView.h" +#import "NSTextStorage+FontScaling.h" #import "RCTTextView.h" -#import "RCTMultilineTextInputView.h" - -NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName"; -NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName"; - -static NSString *const kShadowViewAttributeName = @"RCTShadowViewAttributeName"; - -static CGFloat const kAutoSizeWidthErrorMargin = 0.05f; -static CGFloat const kAutoSizeHeightErrorMargin = 0.025f; -static CGFloat const kAutoSizeGranularity = 0.001f; @implementation RCTTextShadowView { - NSTextStorage *_cachedTextStorage; - CGFloat _cachedTextStorageWidth; - CGFloat _cachedTextStorageWidthMode; - NSAttributedString *_cachedAttributedString; - CGFloat _effectiveLetterSpacing; - NSUserInterfaceLayoutDirection _cachedLayoutDirection; + __weak RCTBridge *_bridge; + BOOL _needsUpdateView; + NSMapTable *_cachedTextStorages; } -static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) +- (instancetype)initWithBridge:(RCTBridge *)bridge { - RCTTextShadowView *shadowText = (__bridge RCTTextShadowView *)YGNodeGetContext(node); - NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode]; - [shadowText calculateTextFrame:textStorage]; - NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; - NSTextContainer *textContainer = layoutManager.textContainers.firstObject; - CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size; - - YGSize result; - result.width = RCTCeilPixelValue(computedSize.width); - if (shadowText->_effectiveLetterSpacing < 0) { - result.width -= shadowText->_effectiveLetterSpacing; + if (self = [super init]) { + _bridge = bridge; + _cachedTextStorages = [NSMapTable strongToStrongObjectsMapTable]; + _needsUpdateView = YES; + YGNodeSetMeasureFunc(self.yogaNode, RCTTextShadowViewMeasure); } - result.height = RCTCeilPixelValue(computedSize.height); - return result; -} -- (instancetype)init -{ - if ((self = [super init])) { - _fontSize = NAN; - _letterSpacing = NAN; - _isHighlighted = NO; - _textDecorationStyle = NSUnderlineStyleSingle; - _opacity = 1.0; - _cachedTextStorageWidth = -1; - _cachedTextStorageWidthMode = -1; - _fontSizeMultiplier = 1.0; - _textAlign = NSTextAlignmentNatural; - _writingDirection = NSWritingDirectionNatural; - _cachedLayoutDirection = NSUserInterfaceLayoutDirectionLeftToRight; - - YGNodeSetMeasureFunc(self.yogaNode, RCTMeasure); - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(contentSizeMultiplierDidChange:) - name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification - object:nil]; - } return self; } -- (void)dealloc +- (BOOL)isYogaLeafNode { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + return YES; } -- (NSString *)description +- (void)dirtyLayout { - NSString *superDescription = super.description; - return [[superDescription substringToIndex:superDescription.length - 1] stringByAppendingFormat:@"; text: %@>", [self attributedString].string]; + [super dirtyLayout]; + YGNodeMarkDirty(self.yogaNode); + [self invalidateCache]; } -- (BOOL)isYogaLeafNode +- (void)invalidateCache { - return YES; + [_cachedTextStorages removeAllObjects]; + _needsUpdateView = YES; } -- (void)contentSizeMultiplierDidChange:(NSNotification *)note -{ - YGNodeMarkDirty(self.yogaNode); - [self dirtyText]; -} +#pragma mark - RCTUIManagerObserver -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks - parentProperties:(NSDictionary *)parentProperties +- (void)uiManagerWillPerformMounting { - if ([[self reactSuperview] isKindOfClass:[RCTTextShadowView class]]) { - return parentProperties; + if (YGNodeIsDirty(self.yogaNode)) { + return; } - parentProperties = [super processUpdatedProperties:applierBlocks - parentProperties:parentProperties]; - - CGFloat availableWidth = self.availableSize.width; - NSNumber *parentTag = [[self reactSuperview] reactTag]; - NSTextStorage *textStorage = [self buildTextStorageForWidth:availableWidth widthMode:YGMeasureModeExactly]; - CGRect textFrame = [self calculateTextFrame:textStorage]; - BOOL selectable = _selectable; - [applierBlocks addObject:^(NSDictionary *viewRegistry) { - RCTTextView *view = (RCTTextView *)viewRegistry[self.reactTag]; - view.textFrame = textFrame; - view.textStorage = textStorage; - view.selectable = selectable; - - /** - * NOTE: this logic is included to support rich text editing inside multiline - * `` controls. It is required in order to ensure that the - * textStorage (aka attributed string) is copied over from the RCTTextShadowView - * to the RCTTextView view in time to be used to update the editable text content. - * TODO: we should establish a delegate relationship betweeen RCTMultilineTextInputView - * and its contaned RCTTextView element when they get inserted and get rid of this - */ - NSView *parentView = viewRegistry[parentTag]; - if ([parentView respondsToSelector:@selector(performTextUpdate)]) { - [(RCTMultilineTextInputView *)parentView performTextUpdate]; - } - }]; + if (!_needsUpdateView) { + return; + } + _needsUpdateView = NO; + + CGRect contentFrame = self.contentFrame; + NSTextStorage *textStorage = [self textStorageAndLayoutManagerThatFitsSize:self.contentFrame.size + exclusiveOwnership:YES]; + + NSNumber *tag = self.reactTag; + NSMutableArray *descendantViewTags = [NSMutableArray new]; + [textStorage enumerateAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName + inRange:NSMakeRange(0, textStorage.length) + options:0 + usingBlock: + ^(RCTShadowView *shadowView, NSRange range, __unused BOOL *stop) { + if (!shadowView) { + return; + } - return parentProperties; -} + [descendantViewTags addObject:shadowView.reactTag]; + } + ]; -- (void)applyLayoutNode:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition -{ - [super applyLayoutNode:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; - [self dirtyPropagation]; -} + [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RCTTextView *textView = (RCTTextView *)viewRegistry[tag]; + if (!textView) { + return; + } -- (void)applyLayoutToChildren:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition -{ - // Run layout on subviews. - CGFloat availableWidth = self.availableSize.width; - NSTextStorage *textStorage = [self buildTextStorageForWidth:availableWidth widthMode:YGMeasureModeExactly]; - NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; - NSTextContainer *textContainer = layoutManager.textContainers.firstObject; - NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; - NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; - [layoutManager.textStorage enumerateAttribute:kShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) { - if (child) { - YGNodeRef childNode = child.yogaNode; - float width = YGNodeStyleGetWidth(childNode).value; - float height = YGNodeStyleGetHeight(childNode).value; - if (YGFloatIsUndefined(width) || YGFloatIsUndefined(height)) { - RCTLogError(@"Views nested within a must have a width and height"); + NSMutableArray *descendantViews = + [NSMutableArray arrayWithCapacity:descendantViewTags.count]; + [descendantViewTags enumerateObjectsUsingBlock:^(NSNumber *_Nonnull descendantViewTag, NSUInteger index, BOOL *_Nonnull stop) { + UIView *descendantView = viewRegistry[descendantViewTag]; + if (!descendantView) { + return; } - NSFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil]; - CGRect glyphRect = [layoutManager boundingRectForGlyphRange:range inTextContainer:textContainer]; - CGRect childFrame = {{ - RCTRoundPixelValue(glyphRect.origin.x), - RCTRoundPixelValue(glyphRect.origin.y + glyphRect.size.height - height + font.descender) - }, { - RCTRoundPixelValue(width), - RCTRoundPixelValue(height) - }}; - NSRange truncatedGlyphRange = [layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:range.location]; - BOOL childIsTruncated = NSIntersectionRange(range, truncatedGlyphRange).length != 0; + [descendantViews addObject:descendantView]; + }]; - [child collectUpdatedFrames:viewsWithNewFrame - withFrame:childFrame - hidden:childIsTruncated - absolutePosition:absolutePosition]; - } + // Removing all references to Shadow Views to avoid unnececery retainning. + [textStorage removeAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName range:NSMakeRange(0, textStorage.length)]; + + [textView setTextStorage:textStorage + contentFrame:contentFrame + descendantViews:descendantViews]; }]; } -- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(YGMeasureMode)widthMode +- (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText { - if ( - _cachedTextStorage && - (width == _cachedTextStorageWidth || (isnan(width) && isnan(_cachedTextStorageWidth))) && - widthMode == _cachedTextStorageWidthMode && - _cachedLayoutDirection == self.layoutDirection - ) { - return _cachedTextStorage; - } - - NSLayoutManager *layoutManager = [NSLayoutManager new]; - - NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedString]; - [textStorage addLayoutManager:layoutManager]; + __block CGFloat maximumLineHeight = 0; + + [attributedText enumerateAttribute:NSParagraphStyleAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock: + ^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { + if (!paragraphStyle) { + return; + } - NSTextContainer *textContainer = [NSTextContainer new]; - textContainer.lineFragmentPadding = 0.0; + maximumLineHeight = MAX(paragraphStyle.maximumLineHeight, maximumLineHeight); + } + ]; - if (_numberOfLines > 0) { - textContainer.lineBreakMode = _ellipsizeMode; - } else { - textContainer.lineBreakMode = NSLineBreakByClipping; + if (maximumLineHeight == 0) { + // `lineHeight` was not specified, nothing to do. + return; } - textContainer.maximumNumberOfLines = _numberOfLines; - textContainer.size = (CGSize){ - widthMode == YGMeasureModeUndefined || isnan(width) ? CGFLOAT_MAX : width, - CGFLOAT_MAX - }; + [attributedText beginEditing]; - [layoutManager addTextContainer:textContainer]; - [layoutManager ensureLayoutForTextContainer:textContainer]; - - _cachedTextStorageWidth = width; - _cachedTextStorageWidthMode = widthMode; - _cachedTextStorage = textStorage; + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock: + ^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (!font) { + return; + } - return textStorage; -} + if (maximumLineHeight <= font.lineHeight) { + return; + } -- (void)dirtyText -{ - [super dirtyText]; - _cachedTextStorage = nil; -} + CGFloat baseLineOffset = maximumLineHeight / 2.0 - font.lineHeight / 2.0; -- (void)recomputeText -{ - [self attributedString]; - [self setTextComputed]; - [self dirtyPropagation]; -} + [attributedText addAttribute:NSBaselineOffsetAttributeName + value:@(baseLineOffset) + range:range]; + } + ]; -- (NSAttributedString *)attributedString -{ - return [self _attributedStringWithFontFamily:nil - fontSize:nil - fontWeight:nil - fontStyle:nil - letterSpacing:nil - useBackgroundColor:YES - foregroundColor:self.color ?: [NSColor textColor] - backgroundColor:self.backgroundColor - opacity:self.opacity]; + [attributedText endEditing]; } -- (NSAttributedString *)_attributedStringWithFontFamily:(NSString *)fontFamily - fontSize:(NSNumber *)fontSize - fontWeight:(NSString *)fontWeight - fontStyle:(NSString *)fontStyle - letterSpacing:(NSNumber *)letterSpacing - useBackgroundColor:(BOOL)useBackgroundColor - foregroundColor:(NSColor *)foregroundColor - backgroundColor:(NSColor *)backgroundColor - opacity:(CGFloat)opacity +- (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size { - if ( - ![self isTextDirty] && - _cachedAttributedString && - _cachedLayoutDirection == self.layoutDirection - ) { - return _cachedAttributedString; - } - - _cachedLayoutDirection = self.layoutDirection; + NSMutableAttributedString *attributedText = + [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; - if (_fontSize && !isnan(_fontSize)) { - fontSize = @(_fontSize); - } - if (_fontWeight) { - fontWeight = _fontWeight; - } - if (_fontStyle) { - fontStyle = _fontStyle; - } - if (_fontFamily) { - fontFamily = _fontFamily; - } - if (!isnan(_letterSpacing)) { - letterSpacing = @(_letterSpacing); - } + [attributedText beginEditing]; - _effectiveLetterSpacing = letterSpacing.doubleValue; - - NSFont *font = [RCTFont updateFont:nil - withFamily:fontFamily - size:fontSize - weight:fontWeight - style:fontStyle - variant:_fontVariant - scaleMultiplier:_allowFontScaling ? _fontSizeMultiplier : 1.0]; - - CGFloat heightOfTallestSubview = 0.0; - NSMutableAttributedString *attributedString = [NSMutableAttributedString new]; - for (RCTShadowView *child in [self reactSubviews]) { - if ([child isKindOfClass:[RCTTextShadowView class]]) { - RCTTextShadowView *shadowText = (RCTTextShadowView *)child; - [attributedString appendAttributedString: - [shadowText _attributedStringWithFontFamily:fontFamily - fontSize:fontSize - fontWeight:fontWeight - fontStyle:fontStyle - letterSpacing:letterSpacing - useBackgroundColor:YES - foregroundColor:shadowText.color ?: foregroundColor - backgroundColor:shadowText.backgroundColor ?: backgroundColor - opacity:opacity * shadowText.opacity]]; - [child setTextComputed]; - } else if ([child isKindOfClass:[RCTRawTextShadowView class]]) { - RCTRawTextShadowView *shadowRawText = (RCTRawTextShadowView *)child; - [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]]; - [child setTextComputed]; - } else { - float width = YGNodeStyleGetWidth(child.yogaNode).value; - float height = YGNodeStyleGetHeight(child.yogaNode).value; - if (YGFloatIsUndefined(width) || YGFloatIsUndefined(height)) { - RCTLogError(@"Views nested within a must have a width and height"); + [attributedText enumerateAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:0 + usingBlock: + ^(RCTShadowView *shadowView, NSRange range, __unused BOOL *stop) { + if (!shadowView) { + return; } + + CGSize fittingSize = [shadowView sizeThatFitsMinimumSize:CGSizeZero + maximumSize:size]; NSTextAttachment *attachment = [NSTextAttachment new]; - attachment.bounds = (CGRect){CGPointZero, {width, height}}; - NSMutableAttributedString *attachmentString = [NSMutableAttributedString new]; - [attachmentString appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]]; - [attachmentString addAttribute:kShadowViewAttributeName value:child range:(NSRange){0, attachmentString.length}]; - [attributedString appendAttributedString:attachmentString]; - if (height > heightOfTallestSubview) { - heightOfTallestSubview = height; - } - // Don't call setTextComputed on this child. RCTTextViewManager takes care of - // processing inline UIViews. + attachment.bounds = (CGRect){CGPointZero, fittingSize}; + [attributedText addAttribute:NSAttachmentAttributeName value:attachment range:range]; } - } - - [self _addAttribute:NSForegroundColorAttributeName - withValue:[foregroundColor colorWithAlphaComponent:CGColorGetAlpha(foregroundColor.CGColor) * opacity] - toAttributedString:attributedString]; - - if (_isHighlighted) { - [self _addAttribute:RCTIsHighlightedAttributeName withValue:@YES toAttributedString:attributedString]; - } - if (useBackgroundColor && backgroundColor) { - [self _addAttribute:NSBackgroundColorAttributeName - withValue:[backgroundColor colorWithAlphaComponent:CGColorGetAlpha(backgroundColor.CGColor) * opacity] - toAttributedString:attributedString]; - } + ]; - [self _addAttribute:NSFontAttributeName withValue:font toAttributedString:attributedString]; - [self _addAttribute:NSKernAttributeName withValue:letterSpacing toAttributedString:attributedString]; - [self _addAttribute:RCTReactTagAttributeName withValue:self.reactTag toAttributedString:attributedString]; -// [self _setParagraphStyleOnAttributedString:attributedString -// fontLineHeight:[NSLayoutManager defaultLineHeightForFont: font] -// heightOfTallestSubview:heightOfTallestSubview]; + [attributedText endEditing]; - // create a non-mutable attributedString for use by the Text system which avoids copies down the line - _cachedAttributedString = [[NSAttributedString alloc] initWithAttributedString:attributedString]; - YGNodeMarkDirty(self.yogaNode); - - return _cachedAttributedString; + return [attributedText copy]; } -- (void)_addAttribute:(NSString *)attribute withValue:(id)attributeValue toAttributedString:(NSMutableAttributedString *)attributedString +- (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size + exclusiveOwnership:(BOOL)exclusiveOwnership { - [attributedString enumerateAttribute:attribute inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { - if (!value && attributeValue) { - [attributedString addAttribute:attribute value:attributeValue range:range]; - } - }]; -} + NSValue *key = [NSValue valueWithCGSize:size]; + NSTextStorage *cachedTextStorage = [_cachedTextStorages objectForKey:key]; -/* - * LineHeight works the same way line-height works in the web: if children and self have - * varying lineHeights, we simply take the max. - */ -- (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attributedString - fontLineHeight:(CGFloat)fontLineHeight - heightOfTallestSubview:(CGFloat)heightOfTallestSubview -{ - __block BOOL hasParagraphStyle = NO; + if (cachedTextStorage) { + if (exclusiveOwnership) { + [_cachedTextStorages removeObjectForKey:key]; + } - if (_lineHeight != 0.0 || _textAlign != NSTextAlignmentNatural) { - hasParagraphStyle = YES; + return cachedTextStorage; } - CGFloat fontSizeMultiplier = _allowFontScaling ? _fontSizeMultiplier : 1.0; - - // Text line height - __block float compoundLineHeight = _lineHeight * fontSizeMultiplier; + NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:size]; - // Checking for `maximumLineHeight` on each of our children and updating `compoundLineHeight` with the maximum value on the go. - [attributedString enumerateAttribute:NSParagraphStyleAttributeName - inRange:(NSRange){0, attributedString.length} - options:0 - usingBlock:^(NSParagraphStyle *paragraphStyle, NSRange range, BOOL *stop) { + textContainer.lineFragmentPadding = 0.0; // Note, the default value is 5. + textContainer.lineBreakMode = + _maximumNumberOfLines > 0 ? _lineBreakMode : NSLineBreakByClipping; + textContainer.maximumNumberOfLines = _maximumNumberOfLines; - if (!paragraphStyle) { - return; - } + NSLayoutManager *layoutManager = [NSLayoutManager new]; + [layoutManager addTextContainer:textContainer]; - hasParagraphStyle = YES; - compoundLineHeight = MAX(compoundLineHeight, paragraphStyle.maximumLineHeight); - }]; + NSTextStorage *textStorage = + [[NSTextStorage alloc] initWithAttributedString:[self attributedTextWithMeasuredAttachmentsThatFitSize:size]]; - compoundLineHeight = MAX(round(compoundLineHeight), ceilf(heightOfTallestSubview)); + [self postprocessAttributedText:textStorage]; - // Text alignment - NSTextAlignment textAlign = _textAlign; - if (textAlign == NSTextAlignmentRight || textAlign == NSTextAlignmentLeft) { - if (_cachedLayoutDirection == NSUserInterfaceLayoutDirectionRightToLeft) { - if (textAlign == NSTextAlignmentRight) { - textAlign = NSTextAlignmentLeft; - } else { - textAlign = NSTextAlignmentRight; - } - } - } + [textStorage addLayoutManager:layoutManager]; - if (hasParagraphStyle) { - NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; - paragraphStyle.alignment = textAlign; - paragraphStyle.baseWritingDirection = _writingDirection; - paragraphStyle.minimumLineHeight = compoundLineHeight; - paragraphStyle.maximumLineHeight = compoundLineHeight; - [attributedString addAttribute:NSParagraphStyleAttributeName - value:paragraphStyle - range:(NSRange){0, attributedString.length}]; - - if (compoundLineHeight > fontLineHeight) { - [attributedString addAttribute:NSBaselineOffsetAttributeName - value:@(compoundLineHeight / 2 - fontLineHeight / 2) - range:(NSRange){0, attributedString.length}]; - } + if (_adjustsFontSizeToFit) { + CGFloat minimumFontSize = + MAX(_minimumFontScale * (self.textAttributes.effectiveFont.pointSize), 4.0); + [textStorage scaleFontSizeToFitSize:size + minimumFontSize:minimumFontSize + maximumFontSize:72.0]; } - // Text decoration - if (_textDecorationLine == RCTTextDecorationLineTypeUnderline || - _textDecorationLine == RCTTextDecorationLineTypeUnderlineStrikethrough) { - [self _addAttribute:NSUnderlineStyleAttributeName withValue:@(_textDecorationStyle) - toAttributedString:attributedString]; - } - if (_textDecorationLine == RCTTextDecorationLineTypeStrikethrough || - _textDecorationLine == RCTTextDecorationLineTypeUnderlineStrikethrough){ - [self _addAttribute:NSStrikethroughStyleAttributeName withValue:@(_textDecorationStyle) - toAttributedString:attributedString]; - } - if (_textDecorationColor) { - [self _addAttribute:NSStrikethroughColorAttributeName withValue:_textDecorationColor - toAttributedString:attributedString]; - [self _addAttribute:NSUnderlineColorAttributeName withValue:_textDecorationColor - toAttributedString:attributedString]; + if (!exclusiveOwnership) { + [_cachedTextStorages setObject:textStorage forKey:key]; } - // Text shadow - if (!CGSizeEqualToSize(_textShadowOffset, CGSizeZero)) { - NSShadow *shadow = [NSShadow new]; - shadow.shadowOffset = _textShadowOffset; - shadow.shadowBlurRadius = _textShadowRadius; - shadow.shadowColor = _textShadowColor; - [self _addAttribute:NSShadowAttributeName withValue:shadow toAttributedString:attributedString]; - } + return textStorage; } -#pragma mark Autosizing - -- (CGRect)calculateTextFrame:(NSTextStorage *)textStorage +- (void)applyLayoutWithFrame:(CGRect)frame + layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout + absolutePosition:(CGPoint)absolutePosition { - CGRect textFrame = UIEdgeInsetsInsetRect((CGRect){CGPointZero, self.frame.size}, - self.compoundInsets); - - if (_adjustsFontSizeToFit) { - textFrame = [self updateStorage:textStorage toFitFrame:textFrame]; + if (self.textAttributes.layoutDirection != layoutDirection) { + self.textAttributes.layoutDirection = layoutDirection; + [self invalidateCache]; } - return textFrame; + [super applyLayoutWithFrame:frame + layoutDirection:layoutDirection + viewsWithUpdatedLayout:viewsWithUpdatedLayout + absolutePosition:absolutePosition]; } -- (CGRect)updateStorage:(NSTextStorage *)textStorage toFitFrame:(CGRect)frame +- (void)applyLayoutToChildren:(YGNodeRef)node + viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame + absolutePosition:(CGPoint)absolutePosition { - BOOL fits = [self attemptScale:1.0f - inStorage:textStorage - forFrame:frame]; - CGSize requiredSize; - if (!fits) { - requiredSize = [self calculateOptimumScaleInFrame:frame - forStorage:textStorage - minScale:self.minimumFontScale - maxScale:1.0 - prevMid:INT_MAX]; - } else { - requiredSize = [self calculateSize:textStorage]; - } + NSTextStorage *textStorage = + [self textStorageAndLayoutManagerThatFitsSize:self.availableSize + exclusiveOwnership:NO]; + NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; + NSTextContainer *textContainer = layoutManager.textContainers.firstObject; + NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; + NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange + actualGlyphRange:NULL]; + + [textStorage enumerateAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName + inRange:characterRange + options:0 + usingBlock: + ^(RCTShadowView *shadowView, NSRange range, BOOL *stop) { + if (!shadowView) { + return; + } - // Vertically center draw position for new text sizing. - frame.origin.y = self.compoundInsets.top + RCTRoundPixelValue((CGRectGetHeight(frame) - requiredSize.height) / 2.0f); - return frame; -} + CGRect glyphRect = [layoutManager boundingRectForGlyphRange:range + inTextContainer:textContainer]; -- (CGSize)calculateOptimumScaleInFrame:(CGRect)frame - forStorage:(NSTextStorage *)textStorage - minScale:(CGFloat)minScale - maxScale:(CGFloat)maxScale - prevMid:(CGFloat)prevMid -{ - CGFloat midScale = (minScale + maxScale) / 2.0f; - if (round((prevMid / kAutoSizeGranularity)) == round((midScale / kAutoSizeGranularity))) { - //Bail because we can't meet error margin. - return [self calculateSize:textStorage]; - } else { - RCTSizeComparison comparison = [self attemptScale:midScale - inStorage:textStorage - forFrame:frame]; - if (comparison == RCTSizeWithinRange) { - return [self calculateSize:textStorage]; - } else if (comparison == RCTSizeTooLarge) { - return [self calculateOptimumScaleInFrame:frame - forStorage:textStorage - minScale:minScale - maxScale:midScale - kAutoSizeGranularity - prevMid:midScale]; - } else { - return [self calculateOptimumScaleInFrame:frame - forStorage:textStorage - minScale:midScale + kAutoSizeGranularity - maxScale:maxScale - prevMid:midScale]; - } - } -} + NSTextAttachment *attachment = + [textStorage attribute:NSAttachmentAttributeName atIndex:range.location effectiveRange:nil]; -- (RCTSizeComparison)attemptScale:(CGFloat)scale - inStorage:(NSTextStorage *)textStorage - forFrame:(CGRect)frame -{ - NSLayoutManager *layoutManager = [textStorage.layoutManagers firstObject]; - NSTextContainer *textContainer = [layoutManager.textContainers firstObject]; - - NSRange glyphRange = NSMakeRange(0, textStorage.length); - [textStorage beginEditing]; - [textStorage enumerateAttribute:NSFontAttributeName - inRange:glyphRange - options:0 - usingBlock:^(NSFont *font, NSRange range, BOOL *stop) - { - if (font) { - NSFont *originalFont = [self.attributedString attribute:NSFontAttributeName - atIndex:range.location - effectiveRange:&range]; - - NSFont *newFont = [NSFont fontWithName: originalFont.fontName size:originalFont.pointSize * scale]; - [textStorage removeAttribute:NSFontAttributeName range:range]; - [textStorage addAttribute:NSFontAttributeName value:newFont range:range]; - } - }]; + CGSize attachmentSize = attachment.bounds.size; - [textStorage endEditing]; + UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil]; - NSInteger linesRequired = [self numberOfLinesRequired:[textStorage.layoutManagers firstObject]]; - CGSize requiredSize = [self calculateSize:textStorage]; + CGRect frame = {{ + RCTRoundPixelValue(glyphRect.origin.x), + RCTRoundPixelValue(glyphRect.origin.y + glyphRect.size.height - attachmentSize.height + font.descender) + }, { + RCTRoundPixelValue(attachmentSize.width), + RCTRoundPixelValue(attachmentSize.height) + }}; - BOOL fitSize = requiredSize.height <= CGRectGetHeight(frame) && - requiredSize.width <= CGRectGetWidth(frame); + UIUserInterfaceLayoutDirection layoutDirection = self.textAttributes.layoutDirection; - BOOL fitLines = linesRequired <= textContainer.maximumNumberOfLines || - textContainer.maximumNumberOfLines == 0; + YGNodeCalculateLayout( + shadowView.yogaNode, + frame.size.width, + frame.size.height, + layoutDirection == UIUserInterfaceLayoutDirectionLeftToRight ? YGDirectionLTR : YGDirectionRTL); - if (fitLines && fitSize) { - if ((requiredSize.width + (CGRectGetWidth(frame) * kAutoSizeWidthErrorMargin)) > CGRectGetWidth(frame) && - (requiredSize.height + (CGRectGetHeight(frame) * kAutoSizeHeightErrorMargin)) > CGRectGetHeight(frame)) - { - return RCTSizeWithinRange; - } else { - return RCTSizeTooSmall; + [shadowView applyLayoutWithFrame:frame + layoutDirection:layoutDirection + viewsWithUpdatedLayout:viewsWithNewFrame + absolutePosition:absolutePosition]; } - } else { - return RCTSizeTooLarge; - } -} - -// Via Apple Text Layout Programming Guide -// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html -- (NSInteger)numberOfLinesRequired:(NSLayoutManager *)layoutManager -{ - NSInteger numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs]; - NSRange lineRange; - for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ - (void) [layoutManager lineFragmentRectForGlyphAtIndex:index - effectiveRange:&lineRange]; - index = NSMaxRange(lineRange); - } - - return numberOfLines; + ]; } -// Via Apple Text Layout Programming Guide -//https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html -- (CGSize)calculateSize:(NSTextStorage *)storage +static YGSize RCTTextShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { - NSLayoutManager *layoutManager = [storage.layoutManagers firstObject]; - NSTextContainer *textContainer = [layoutManager.textContainers firstObject]; + CGSize maximumSize = (CGSize){ + widthMode == YGMeasureModeUndefined ? CGFLOAT_MAX : RCTCoreGraphicsFloatFromYogaFloat(width), + heightMode == YGMeasureModeUndefined ? CGFLOAT_MAX : RCTCoreGraphicsFloatFromYogaFloat(height), + }; - [textContainer setLineBreakMode:NSLineBreakByWordWrapping]; - NSInteger maxLines = [textContainer maximumNumberOfLines]; - [textContainer setMaximumNumberOfLines:0]; - (void) [layoutManager glyphRangeForTextContainer:textContainer]; - CGSize requiredSize = [layoutManager usedRectForTextContainer:textContainer].size; - [textContainer setMaximumNumberOfLines:maxLines]; + RCTTextShadowView *shadowTextView = (__bridge RCTTextShadowView *)YGNodeGetContext(node); - return requiredSize; -} + NSTextStorage *textStorage = + [shadowTextView textStorageAndLayoutManagerThatFitsSize:maximumSize + exclusiveOwnership:NO]; -#define RCT_TEXT_PROPERTY(setProp, ivar, type) \ -- (void)set##setProp:(type)value; \ -{ \ - ivar = value; \ - [self dirtyText]; \ -} + NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; + NSTextContainer *textContainer = layoutManager.textContainers.firstObject; + [layoutManager ensureLayoutForTextContainer:textContainer]; + CGSize size = [layoutManager usedRectForTextContainer:textContainer].size; -RCT_TEXT_PROPERTY(AdjustsFontSizeToFit, _adjustsFontSizeToFit, BOOL) -RCT_TEXT_PROPERTY(Color, _color, NSColor *) -RCT_TEXT_PROPERTY(FontFamily, _fontFamily, NSString *) -RCT_TEXT_PROPERTY(FontSize, _fontSize, CGFloat) -RCT_TEXT_PROPERTY(FontWeight, _fontWeight, NSString *) -RCT_TEXT_PROPERTY(FontStyle, _fontStyle, NSString *) -RCT_TEXT_PROPERTY(FontVariant, _fontVariant, NSArray *) -RCT_TEXT_PROPERTY(IsHighlighted, _isHighlighted, BOOL) -RCT_TEXT_PROPERTY(LetterSpacing, _letterSpacing, CGFloat) -RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat) -RCT_TEXT_PROPERTY(NumberOfLines, _numberOfLines, NSUInteger) -RCT_TEXT_PROPERTY(EllipsizeMode, _ellipsizeMode, NSLineBreakMode) -RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment) -RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, NSColor *); -RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLineType); -RCT_TEXT_PROPERTY(TextDecorationStyle, _textDecorationStyle, NSUnderlineStyle); -RCT_TEXT_PROPERTY(WritingDirection, _writingDirection, NSWritingDirection) -RCT_TEXT_PROPERTY(Opacity, _opacity, CGFloat) -RCT_TEXT_PROPERTY(TextShadowOffset, _textShadowOffset, CGSize); -RCT_TEXT_PROPERTY(TextShadowRadius, _textShadowRadius, CGFloat); -RCT_TEXT_PROPERTY(TextShadowColor, _textShadowColor, NSColor *); - -- (void)setAllowFontScaling:(BOOL)allowFontScaling -{ - _allowFontScaling = allowFontScaling; - for (RCTShadowView *child in [self reactSubviews]) { - if ([child isKindOfClass:[RCTTextShadowView class]]) { - ((RCTTextShadowView *)child).allowFontScaling = allowFontScaling; - } + CGFloat letterSpacing = shadowTextView.textAttributes.letterSpacing; + if (!isnan(letterSpacing) && letterSpacing < 0) { + size.width -= letterSpacing; } - [self dirtyText]; -} -- (void)setFontSizeMultiplier:(CGFloat)fontSizeMultiplier -{ - _fontSizeMultiplier = fontSizeMultiplier; - if (_fontSizeMultiplier == 0) { - RCTLogError(@"fontSizeMultiplier value must be > zero."); - _fontSizeMultiplier = 1.0; - } - for (RCTShadowView *child in [self reactSubviews]) { - if ([child isKindOfClass:[RCTTextShadowView class]]) { - ((RCTTextShadowView *)child).fontSizeMultiplier = fontSizeMultiplier; - } - } - [self dirtyText]; -} + size = (CGSize){ + MIN(RCTCeilPixelValue(size.width), maximumSize.width), + MIN(RCTCeilPixelValue(size.height), maximumSize.height) + }; -- (void)setMinimumFontScale:(CGFloat)minimumFontScale -{ - if (minimumFontScale >= 0.01) { - _minimumFontScale = minimumFontScale; - } - [self dirtyText]; + return (YGSize){ + RCTYogaFloatFromCoreGraphicsFloat(size.width), + RCTYogaFloatFromCoreGraphicsFloat(size.height) + }; } @end diff --git a/Libraries/Text/Text/RCTTextView.h b/Libraries/Text/Text/RCTTextView.h index 66fd19c59a..c8ba22adcb 100644 --- a/Libraries/Text/Text/RCTTextView.h +++ b/Libraries/Text/Text/RCTTextView.h @@ -7,16 +7,18 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import -CGRect UIEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets); +NS_ASSUME_NONNULL_BEGIN -@interface RCTTextView : NSView +@interface RCTTextView : UIView -@property (nonatomic, assign) NSEdgeInsets contentInset; -@property (nonatomic, strong) NSTextStorage *textStorage; -@property (nonatomic, assign) CGRect textFrame; @property (nonatomic, assign) BOOL selectable; -@property (nonatomic, assign) BOOL respondsToLiveResizing; +- (void)setTextStorage:(NSTextStorage *)textStorage + contentFrame:(CGRect)contentFrame + descendantViews:(NSArray *)descendantViews; + @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index e2489a54b1..d065e8073a 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -9,114 +9,39 @@ #import "RCTTextView.h" -#import -// #import +#import #import -#import +#import #import "RCTTextShadowView.h" -// https://github.com/BigZaphod/Chameleon/blob/84605ede274bd82b330d72dd6ac41e64eb925fd7/UIKit/Classes/UIGeometry.h -CGRect UIEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { - rect.origin.x += insets.left; - rect.origin.y += insets.top; - rect.size.width -= (insets.left + insets.right); - rect.size.height -= (insets.top + insets.bottom); - return rect; -} - -@implementation NSBezierPath (BezierPathQuartzUtilities) -// This method works only in OS X v10.2 and later. -- (CGPathRef)quartzPath -{ - long i, numElements; - - // Need to begin a path here. - CGPathRef immutablePath = NULL; - - // Then draw the path elements. - numElements = [self elementCount]; - if (numElements > 0) - { - CGMutablePathRef path = CGPathCreateMutable(); - NSPoint points[3]; - BOOL didClosePath = YES; - - for (i = 0; i < numElements; i++) - { - switch ([self elementAtIndex:i associatedPoints:points]) - { - case NSMoveToBezierPathElement: - CGPathMoveToPoint(path, NULL, points[0].x, points[0].y); - break; - - case NSLineToBezierPathElement: - CGPathAddLineToPoint(path, NULL, points[0].x, points[0].y); - didClosePath = NO; - break; - - case NSCurveToBezierPathElement: - CGPathAddCurveToPoint(path, NULL, points[0].x, points[0].y, - points[1].x, points[1].y, - points[2].x, points[2].y); - didClosePath = NO; - break; - - case NSClosePathBezierPathElement: - CGPathCloseSubpath(path); - didClosePath = YES; - break; - } - } - - // Be sure the path is closed or Quartz may not do valid hit detection. - if (!didClosePath) - CGPathCloseSubpath(path); - - immutablePath = CGPathCreateCopy(path); - CGPathRelease(path); - } - - return immutablePath; // TODO: potential leak -} -@end - -static void collectNonTextDescendants(RCTTextView *view, NSMutableArray *nonTextDescendants) -{ - for (NSView *child in view.reactSubviews) { - if ([child isKindOfClass:[RCTTextView class]]) { - collectNonTextDescendants((RCTTextView *)child, nonTextDescendants); - } else if (!CGRectEqualToRect(child.frame, CGRectZero)) { - [nonTextDescendants addObject:child]; - } - } -} - @implementation RCTTextView { - NSTextStorage *_textStorage; CAShapeLayer *_highlightLayer; + UILongPressGestureRecognizer *_longPressGestureRecognizer; + + NSArray *_Nullable _descendantViews; + NSTextStorage *_Nullable _textStorage; + CGRect _contentFrame; } - (instancetype)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - _textStorage = [NSTextStorage new]; + if (self = [super initWithFrame:frame]) { + self.isAccessibilityElement = YES; + self.accessibilityTraits |= UIAccessibilityTraitStaticText; + self.opaque = NO; + self.contentMode = UIViewContentModeRedraw; } return self; } -- (BOOL)isFlipped -{ - return YES; -} - - (NSString *)description { NSString *superDescription = super.description; NSRange semicolonRange = [superDescription rangeOfString:@";"]; - NSString *replacement = [NSString stringWithFormat:@"; reactTag: %@; text: %@", self.reactTag, self.textStorage.string]; + NSString *replacement = [NSString stringWithFormat:@"; reactTag: %@; text: %@", self.reactTag, _textStorage.string]; return [superDescription stringByReplacingCharactersInRange:semicolonRange withString:replacement]; } @@ -138,15 +63,11 @@ - (void)setSelectable:(BOOL)selectable - (void)reactSetFrame:(CGRect)frame { - [super reactSetFrame:frame]; -} - -- (void)reactSetInheritedBackgroundColor:(NSColor *)inheritedBackgroundColor -{ - if (self.wantsLayer == NO) { - self.wantsLayer = YES; - } - self.layer.backgroundColor = [inheritedBackgroundColor CGColor]; + // Text looks super weird if its frame is animated. + // This disables the frame animation, without affecting opacity, etc. + [UIView performWithoutAnimation:^{ + [super reactSetFrame:frame]; + }]; } - (void)didUpdateReactSubviews @@ -155,71 +76,82 @@ - (void)didUpdateReactSubviews } - (void)setTextStorage:(NSTextStorage *)textStorage + contentFrame:(CGRect)contentFrame + descendantViews:(NSArray *)descendantViews { - if (_textStorage != textStorage) { - _textStorage = textStorage; - - // Update subviews - NSMutableArray *nonTextDescendants = [NSMutableArray new]; - collectNonTextDescendants(self, nonTextDescendants); - NSArray *subviews = self.subviews; - if (![subviews isEqualToArray:nonTextDescendants]) { - for (NSView *child in subviews) { - if (![nonTextDescendants containsObject:child]) { - [child removeFromSuperview]; - } - } - for (NSView *child in nonTextDescendants) { - [self addSubview:child]; - } - } + _textStorage = textStorage; + _contentFrame = contentFrame; - [self setNeedsDisplay:YES]; + // FIXME: Optimize this. + for (UIView *view in _descendantViews) { + [view removeFromSuperview]; } + + _descendantViews = descendantViews; + + for (UIView *view in descendantViews) { + [self addSubview:view]; + } + + [self setNeedsDisplay]; } -- (void)drawRect:(CGRect)dirtyRect +- (void)drawRect:(CGRect)rect { - NSLayoutManager *layoutManager = [_textStorage.layoutManagers firstObject]; - NSTextContainer *textContainer = [layoutManager.textContainers firstObject]; - - NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; - CGRect textFrame = self.textFrame; - [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin]; - [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin]; + if (!_textStorage) { + return; + } - __block NSBezierPath *highlightPath = nil; - NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; - [layoutManager.textStorage enumerateAttribute:RCTIsHighlightedAttributeName inRange:characterRange options:0 usingBlock:^(NSNumber *value, NSRange range, BOOL *_) { - if (!value.boolValue) { - return; - } + NSLayoutManager *layoutManager = _textStorage.layoutManagers.firstObject; + NSTextContainer *textContainer = layoutManager.textContainers.firstObject; - [layoutManager enumerateEnclosingRectsForGlyphRange:range withinSelectedGlyphRange:range inTextContainer:textContainer usingBlock:^(CGRect enclosingRect, __unused BOOL *__) { - NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2) xRadius:2 yRadius:2]; - if (highlightPath) { - [highlightPath appendBezierPath:path]; - } else { - highlightPath = path; + NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; + [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:_contentFrame.origin]; + [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:_contentFrame.origin]; + + __block UIBezierPath *highlightPath = nil; + NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange + actualGlyphRange:NULL]; + [_textStorage enumerateAttribute:RCTTextAttributesIsHighlightedAttributeName + inRange:characterRange + options:0 + usingBlock: + ^(NSNumber *value, NSRange range, __unused BOOL *stop) { + if (!value.boolValue) { + return; } - }]; + + [layoutManager enumerateEnclosingRectsForGlyphRange:range + withinSelectedGlyphRange:range + inTextContainer:textContainer + usingBlock: + ^(CGRect enclosingRect, __unused BOOL *anotherStop) { + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2) cornerRadius:2]; + if (highlightPath) { + [highlightPath appendPath:path]; + } else { + highlightPath = path; + } + } + ]; }]; if (highlightPath) { if (!_highlightLayer) { _highlightLayer = [CAShapeLayer layer]; - _highlightLayer.fillColor = [NSColor colorWithWhite:0 alpha:0.25].CGColor; + _highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor; [self.layer addSublayer:_highlightLayer]; } - _highlightLayer.position = (CGPoint){_contentInset.left, _contentInset.top}; - _highlightLayer.path = highlightPath.quartzPath; + _highlightLayer.position = _contentFrame.origin; + _highlightLayer.path = highlightPath.CGPath; } else { [_highlightLayer removeFromSuperlayer]; _highlightLayer = nil; } } + - (NSNumber *)reactTagAtPoint:(CGPoint)point { NSNumber *reactTag = self.reactTag; @@ -234,14 +166,15 @@ - (NSNumber *)reactTagAtPoint:(CGPoint)point // If the point is not before (fraction == 0.0) the first character and not // after (fraction == 1.0) the last character, then the attribute is valid. if (_textStorage.length > 0 && (fraction > 0 || characterIndex > 0) && (fraction < 1 || characterIndex < _textStorage.length - 1)) { - reactTag = [_textStorage attribute:RCTReactTagAttributeName atIndex:characterIndex effectiveRange:NULL]; + reactTag = [_textStorage attribute:RCTTextAttributesTagAttributeName atIndex:characterIndex effectiveRange:NULL]; } + return reactTag; } -- (void)viewDidMoveToWindow +- (void)didMoveToWindow { - [super viewDidMoveToWindow]; + [super didMoveToWindow]; if (!self.window) { self.layer.contents = nil; @@ -249,12 +182,11 @@ - (void)viewDidMoveToWindow [_highlightLayer removeFromSuperlayer]; _highlightLayer = nil; } - } else if (_textStorage.length) { - [self setNeedsDisplay:YES]; + } else if (_textStorage) { + [self setNeedsDisplay]; } } - #pragma mark - Accessibility - (NSString *)accessibilityLabel @@ -270,11 +202,32 @@ - (NSString *)accessibilityLabel - (void)enableContextMenu { - + _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; + [self addGestureRecognizer:_longPressGestureRecognizer]; } - (void)disableContextMenu { + [self removeGestureRecognizer:_longPressGestureRecognizer]; + _longPressGestureRecognizer = nil; +} + +- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture +{ +#if !TARGET_OS_TV + UIMenuController *menuController = [UIMenuController sharedMenuController]; + + if (menuController.isMenuVisible) { + return; + } + + if (!self.isFirstResponder) { + [self becomeFirstResponder]; + } + + [menuController setTargetRect:self.bounds inView:self]; + [menuController setMenuVisible:YES animated:YES]; +#endif } - (BOOL)canBecomeFirstResponder @@ -282,19 +235,35 @@ - (BOOL)canBecomeFirstResponder return _selectable; } -//- (BOOL)canPerformAction:(SEL)action withSender:(id)sender -//{ -// if (_selectable && action == @selector(copy:)) { -// return YES; -// } -// -// return [self.nextResponder canPerformAction:action withSender:sender]; -//} +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender +{ + if (_selectable && action == @selector(copy:)) { + return YES; + } + + return [self.nextResponder canPerformAction:action withSender:sender]; +} - (void)copy:(id)sender { #if !TARGET_OS_TV - #endif + NSAttributedString *attributedText = _textStorage; + + NSMutableDictionary *item = [NSMutableDictionary new]; + + NSData *rtf = [attributedText dataFromRange:NSMakeRange(0, attributedText.length) + documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType} + error:nil]; + + if (rtf) { + [item setObject:rtf forKey:(id)kUTTypeFlatRTFD]; + } + + [item setObject:attributedText.string forKey:(id)kUTTypeUTF8PlainText]; + + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + pasteboard.items = @[item]; +#endif } @end diff --git a/Libraries/Text/Text/RCTTextViewManager.h b/Libraries/Text/Text/RCTTextViewManager.h index 9028878bd3..957c88d477 100644 --- a/Libraries/Text/Text/RCTTextViewManager.h +++ b/Libraries/Text/Text/RCTTextViewManager.h @@ -9,6 +9,8 @@ #import -@interface RCTTextViewManager : RCTViewManager +#import "RCTBaseTextViewManager.h" + +@interface RCTTextViewManager : RCTBaseTextViewManager @end diff --git a/Libraries/Text/Text/RCTTextViewManager.m b/Libraries/Text/Text/RCTTextViewManager.m index 1d5a4165a0..58b559de18 100644 --- a/Libraries/Text/Text/RCTTextViewManager.m +++ b/Libraries/Text/Text/RCTTextViewManager.m @@ -9,129 +9,86 @@ #import "RCTTextViewManager.h" -#import -// #import -#import -#import -#import +#import #import -#import +#import +#import +#import -#import "RCTRawTextShadowView.h" #import "RCTTextShadowView.h" #import "RCTTextView.h" -#import "RCTMultilineTextInputView.h" - -static void collectDirtyNonTextDescendants(RCTTextShadowView *shadowView, NSMutableArray *nonTextDescendants) { - for (RCTShadowView *child in shadowView.reactSubviews) { - if ([child isKindOfClass:[RCTTextShadowView class]]) { - collectDirtyNonTextDescendants((RCTTextShadowView *)child, nonTextDescendants); - } else if ([child isKindOfClass:[RCTRawTextShadowView class]]) { - // no-op - } else if ([child isTextDirty]) { - [nonTextDescendants addObject:child]; - } - } -} - -@interface RCTTextShadowView (Private) -- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(YGMeasureMode)widthMode; +@interface RCTTextViewManager () @end - @implementation RCTTextViewManager +{ + NSHashTable *_shadowViews; + CGFloat _fontSizeMultiplier; +} RCT_EXPORT_MODULE(RCTText) -- (NSView *)view +RCT_REMAP_SHADOW_PROPERTY(numberOfLines, maximumNumberOfLines, NSInteger) +RCT_REMAP_SHADOW_PROPERTY(ellipsizeMode, lineBreakMode, NSLineBreakMode) +RCT_REMAP_SHADOW_PROPERTY(adjustsFontSizeToFit, adjustsFontSizeToFit, BOOL) +RCT_REMAP_SHADOW_PROPERTY(minimumFontScale, minimumFontScale, CGFloat) + +RCT_EXPORT_VIEW_PROPERTY(selectable, BOOL) + +- (void)setBridge:(RCTBridge *)bridge +{ + [super setBridge:bridge]; + _shadowViews = [NSHashTable weakObjectsHashTable]; + + [bridge.uiManager.observerCoordinator addObserver:self]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleDidUpdateMultiplierNotification) + name:RCTAccessibilityManagerDidUpdateMultiplierNotification + object:bridge.accessibilityManager]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (UIView *)view { return [RCTTextView new]; } - (RCTShadowView *)shadowView { - return [RCTTextShadowView new]; + RCTTextShadowView *shadowView = [[RCTTextShadowView alloc] initWithBridge:self.bridge]; + shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; + [_shadowViews addObject:shadowView]; + return shadowView; } -#pragma mark - Shadow properties - -RCT_EXPORT_SHADOW_PROPERTY(color, NSColor) -RCT_EXPORT_SHADOW_PROPERTY(backgroundColor, NSColor) -RCT_EXPORT_SHADOW_PROPERTY(fontFamily, NSString) -RCT_EXPORT_SHADOW_PROPERTY(fontSize, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(fontWeight, NSString) -RCT_EXPORT_SHADOW_PROPERTY(fontStyle, NSString) -RCT_EXPORT_SHADOW_PROPERTY(fontVariant, NSArray) -RCT_EXPORT_SHADOW_PROPERTY(isHighlighted, BOOL) -RCT_EXPORT_SHADOW_PROPERTY(letterSpacing, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(lineHeight, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(numberOfLines, NSUInteger) -RCT_EXPORT_SHADOW_PROPERTY(ellipsizeMode, NSLineBreakMode) -RCT_EXPORT_SHADOW_PROPERTY(textAlign, NSTextAlignment) -RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle) -RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, NSColor) -RCT_EXPORT_SHADOW_PROPERTY(textDecorationLine, RCTTextDecorationLineType) -RCT_EXPORT_SHADOW_PROPERTY(writingDirection, NSWritingDirection) -RCT_EXPORT_SHADOW_PROPERTY(allowFontScaling, BOOL) -RCT_EXPORT_SHADOW_PROPERTY(opacity, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(textShadowOffset, CGSize) -RCT_EXPORT_SHADOW_PROPERTY(textShadowRadius, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(textShadowColor, NSColor) -RCT_EXPORT_SHADOW_PROPERTY(adjustsFontSizeToFit, BOOL) -RCT_EXPORT_SHADOW_PROPERTY(minimumFontScale, CGFloat) -RCT_EXPORT_SHADOW_PROPERTY(selectable, BOOL) - -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary *)shadowViewRegistry +#pragma mark - RCTUIManagerObserver + +- (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager { - for (RCTShadowView *rootView in shadowViewRegistry.allValues) { - if (![rootView isReactRootView]) { - // This isn't a root view - continue; - } - - if (![rootView isTextDirty]) { - // No text processing to be done - continue; - } - - NSMutableArray *queue = [NSMutableArray arrayWithObject:rootView]; - for (NSInteger i = 0; i < queue.count; i++) { - RCTShadowView *shadowView = queue[i]; - RCTAssert([shadowView isTextDirty], @"Don't process any nodes that don't have dirty text"); - - if ([shadowView isKindOfClass:[RCTTextShadowView class]]) { - // ((RCTTextShadowView *)shadowView).fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; - [(RCTTextShadowView *)shadowView recomputeText]; - collectDirtyNonTextDescendants((RCTTextShadowView *)shadowView, queue); - } else if ([shadowView isKindOfClass:[RCTRawTextShadowView class]]) { - RCTLogError(@"Raw text cannot be used outside of a tag. Not rendering string: '%@'", - [(RCTRawTextShadowView *)shadowView text]); - } else { - for (RCTShadowView *child in [shadowView reactSubviews]) { - if ([child isTextDirty]) { - [queue addObject:child]; - } - } - } - - [shadowView setTextComputed]; - } + for (RCTTextShadowView *shadowView in _shadowViews) { + [shadowView uiManagerWillPerformMounting]; } - - return nil; } -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTTextShadowView *)shadowView +#pragma mark - Font Size Multiplier + +- (void)handleDidUpdateMultiplierNotification { - NSNumber *reactTag = shadowView.reactTag; - NSEdgeInsets padding = shadowView.paddingAsInsets; + CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; + + for (RCTTextShadowView *shadowView in _shadowViews) { + shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; + [shadowView dirtyLayout]; + } - return ^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RCTTextView *text = viewRegistry[reactTag]; - text.contentInset = padding; - }; + [self.bridge.uiManager setNeedsLayout]; } @end diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h index 1a6e7d7c09..7d28023597 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h @@ -7,33 +7,12 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import - -#import -#import - #import "RCTBaseTextInputView.h" -@class RCTBridge; +NS_ASSUME_NONNULL_BEGIN @interface RCTMultilineTextInputView : RCTBaseTextInputView -//@property (nonatomic, assign) BOOL blurOnSubmit; -//@property (nonatomic, assign) BOOL clearTextOnFocus; -//@property (nonatomic, assign) BOOL selectTextOnFocus; -@property (nonatomic, assign) NSEdgeInsets contentInset; -@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; -@property (nonatomic, copy) NSString *text; -@property (nonatomic, strong) NSColor *placeholderTextColor; -@property (nonatomic, copy) NSString *placeholder; -@property (nonatomic, strong) NSFont *font; -// @property (nonatomic, assign) NSInteger mostRecentEventCount; -@property (nonatomic, strong) NSNumber *maxLength; - -@property (nonatomic, copy) RCTDirectEventBlock onChange; -@property (nonatomic, copy) RCTDirectEventBlock onTextInput; -@property (nonatomic, copy) RCTDirectEventBlock onScroll; - -- (void)performTextUpdate; - @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m index 41e88f7557..d97c95172e 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m @@ -9,383 +9,60 @@ #import "RCTMultilineTextInputView.h" -#import -#import -#import -#import #import -#import -#import "RCTTextShadowView.h" -#import "RCTTextView.h" -#import "RCTTextSelection.h" #import "RCTUITextView.h" -@interface RCTMultilineTextInputView () - -@end - @implementation RCTMultilineTextInputView { - RCTUITextView *_backedTextInput; - RCTTextView *_richTextView; - NSAttributedString *_pendingAttributedText; - - NSString *_predictedText; - - BOOL _blockTextShouldChange; - BOOL _nativeUpdatesInFlight; + RCTUITextView *_backedTextInputView; } - (instancetype)initWithBridge:(RCTBridge *)bridge { - RCTAssertParam(bridge); - if (self = [super initWithBridge:bridge]) { // `blurOnSubmit` defaults to `false` for by design. - _blurOnSubmit = NO; + self.blurOnSubmit = NO; - _backedTextInput = [[RCTUITextView alloc] initWithFrame:self.bounds]; - _backedTextInput.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - _backedTextInput.backgroundColor = [NSColor clearColor]; - _backedTextInput.textColor = [NSColor blackColor]; + _backedTextInputView = [[RCTUITextView alloc] initWithFrame:self.bounds]; + _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _backedTextInputView.backgroundColor = [UIColor clearColor]; + _backedTextInputView.textColor = [UIColor blackColor]; // This line actually removes 5pt (default value) left and right padding in UITextView. - _backedTextInput.textContainer.lineFragmentPadding = 0; -//#if !TARGET_OS_TV -// _backedTextInput.scrollsToTop = NO; -//#endif -// _backedTextInput.scrollEnabled = YES; - _backedTextInput.textInputDelegate = self; - _backedTextInput.font = self.fontAttributes.font; + _backedTextInputView.textContainer.lineFragmentPadding = 0; +#if !TARGET_OS_TV + _backedTextInputView.scrollsToTop = NO; +#endif + _backedTextInputView.scrollEnabled = YES; + _backedTextInputView.textInputDelegate = self; - [self addSubview:_backedTextInput]; + [self addSubview:_backedTextInputView]; } + return self; } RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) -RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) +RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)coder) - (id)backedTextInputView { - return _backedTextInput; -} - -#pragma mark - RCTComponent - -- (void)insertReactSubview:(NSView *)subview atIndex:(NSInteger)index -{ - [super insertReactSubview:subview atIndex:index]; - - if ([subview isKindOfClass:[RCTTextView class]]) { - if (_richTextView) { - RCTLogError(@"Tried to insert a second into - there can only be one."); - } - _richTextView = (RCTTextView *)subview; - - // If this is in rich text editing mode, and the child node providing rich text - // styling has a backgroundColor, then the attributedText produced by the child node will have an - // NSBackgroundColor attribute. We need to forward this attribute to the text view manually because the text view - // always has a clear background color in `initWithBridge:`. - // - // TODO: This should be removed when the related hack in -performPendingTextUpdate is removed. - if (subview.layer.backgroundColor) { - NSMutableDictionary *attrs = [_backedTextInput.typingAttributes mutableCopy]; - NSColor *backgroundColor = [NSColor colorWithCGColor:subview.layer.backgroundColor]; - attrs[NSBackgroundColorAttributeName] = backgroundColor; - _backedTextInput.typingAttributes = attrs; - } - - [self performTextUpdate]; - } -} - -- (void)removeReactSubview:(NSView *)subview -{ - [super removeReactSubview:subview]; - if (_richTextView == subview) { - _richTextView = nil; - [self performTextUpdate]; - } -} - -- (void)didUpdateReactSubviews -{ - // Do nothing, as we don't allow non-text subviews. -} - -#pragma mark - Routine - -- (void)setMostRecentEventCount:(NSInteger)mostRecentEventCount -{ - _mostRecentEventCount = mostRecentEventCount; - - // Props are set after uiBlockToAmendWithShadowViewRegistry, which means that - // at the time performTextUpdate is called, _mostRecentEventCount will be - // behind _eventCount, with the result that performPendingTextUpdate will do - // nothing. For that reason we call it again here after mostRecentEventCount - // has been set. - [self performPendingTextUpdate]; -} - -- (void)performTextUpdate -{ - if (_richTextView) { - _pendingAttributedText = _richTextView.textStorage; - [self performPendingTextUpdate]; - } else if (!self.text) { - _backedTextInput.attributedString = nil; - } -} - -static NSAttributedString *removeReactTagFromString(NSAttributedString *string) -{ - if (string.length == 0) { - return string; - } else { - NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:string]; - [mutableString removeAttribute:RCTReactTagAttributeName range:NSMakeRange(0, mutableString.length)]; - return mutableString; - } -} - -- (void)performPendingTextUpdate -{ - if (!_pendingAttributedText || _mostRecentEventCount < _nativeEventCount || _nativeUpdatesInFlight) { - return; - } - - // The underlying node that produces _pendingAttributedText has a react tag attribute on it that causes the - // -isEqualToAttributedString: comparison below to spuriously fail. We don't want that comparison to fail unless it - // needs to because when the comparison fails, we end up setting attributedText on the text view, which clears - // autocomplete state for CKJ text input. - // - // TODO: Kill this after we finish passing all style/attribute info into JS. - _pendingAttributedText = removeReactTagFromString(_pendingAttributedText); - - if ([_backedTextInput.attributedText isEqualToAttributedString:_pendingAttributedText]) { - _pendingAttributedText = nil; // Don't try again. - return; - } - - // When we update the attributed text, there might be pending autocorrections - // that will get accepted by default. In order for this to not garble our text, - // we temporarily block all textShouldChange events so they are not applied. - _blockTextShouldChange = YES; - - UITextRange *selection = _backedTextInput.selectedTextRange; - NSInteger oldTextLength = _backedTextInput.attributedText.length; - - _backedTextInput.attributedText = _pendingAttributedText; - _predictedText = _pendingAttributedText.string; - _pendingAttributedText = nil; - - if (selection.empty) { - // maintain cursor position relative to the end of the old text - NSInteger start = [_backedTextInput offsetFromPosition:_backedTextInput.beginningOfDocument toPosition:selection.start]; - NSInteger offsetFromEnd = oldTextLength - start; - NSInteger newOffset = _backedTextInput.attributedText.length - offsetFromEnd; - NSTextPosition *position = [_backedTextInput positionFromPosition:_backedTextInput.beginningOfDocument offset:newOffset]; - [_backedTextInput setSelectedTextRange:[_backedTextInput textRangeFromPosition:position toPosition:position] - notifyDelegate:YES]; - } - - [_backedTextInput layoutIfNeeded]; - - [self invalidateContentSize]; - - _blockTextShouldChange = NO; -} - -#pragma mark - Properties - -- (NSFont *)font -{ - return _backedTextInput.font; -} - -- (void)setFont:(NSFont *)font -{ - _backedTextInput.font = font; - [self setNeedsLayout]; -} - -- (NSString *)text -{ - return _backedTextInput.text; -} - -- (void)setText:(NSString *)text -{ - NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; - if (eventLag == 0 && ![text isEqualToString:_backedTextInput.text]) { - UITextRange *selection = _backedTextInput.selectedTextRange; - NSInteger oldTextLength = _backedTextInput.text.length; - - _predictedText = text; - _backedTextInput.text = text; - - if (selection.empty) { - // maintain cursor position relative to the end of the old text - NSInteger start = [_backedTextInput offsetFromPosition:_backedTextInput.beginningOfDocument toPosition:selection.start]; - NSInteger offsetFromEnd = oldTextLength - start; - NSInteger newOffset = text.length - offsetFromEnd; - UITextPosition *position = [_backedTextInput positionFromPosition:_backedTextInput.beginningOfDocument offset:newOffset]; - [_backedTextInput setSelectedTextRange:[_backedTextInput textRangeFromPosition:position toPosition:position] - notifyDelegate:YES]; - } - - [self invalidateContentSize]; - } else if (eventLag > RCTTextUpdateLagWarningThreshold) { - RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", self.text, (long long)eventLag); - } -} - -#pragma mark - RCTBackedTextInputDelegate - -- (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text -{ - if (!_backedTextInput.textWasPasted) { - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeKeyPress - reactTag:self.reactTag - text:nil - key:text - eventCount:_nativeEventCount]; - } - - // So we need to track that there is a native update in flight just in case JS manages to come back around and update - // things /before/ UITextView can update itself asynchronously. If there is a native update in flight, we defer the - // JS update when it comes in and apply the deferred update once textViewDidChange fires with the native update applied. - if (_blockTextShouldChange) { - return NO; - } - - if (_maxLength) { - NSUInteger allowedLength = _maxLength.integerValue - _backedTextInput.text.length + range.length; - if (text.length > allowedLength) { - // If we typed/pasted more than one character, limit the text inputted - if (text.length > 1) { - // Truncate the input string so the result is exactly maxLength - NSString *limitedString = [text substringToIndex:allowedLength]; - NSMutableString *newString = _backedTextInput.text.mutableCopy; - [newString replaceCharactersInRange:range withString:limitedString]; - _backedTextInput.text = newString; - _predictedText = newString; - - // Collapse selection at end of insert to match normal paste behavior - UITextPosition *insertEnd = [_backedTextInput positionFromPosition:_backedTextInput.beginningOfDocument - offset:(range.location + allowedLength)]; - [_backedTextInput setSelectedTextRange:[_backedTextInput textRangeFromPosition:insertEnd toPosition:insertEnd] - notifyDelegate:YES]; - - [self textInputDidChange]; - } - return NO; - } - } - - _nativeUpdatesInFlight = YES; - - if (range.location + range.length > _predictedText.length) { - // _predictedText got out of sync in a bad way, so let's just force sync it. Haven't been able to repro this, but - // it's causing a real crash here: #6523822 - _predictedText = _backedTextInput.text; - } - - NSString *previousText = [_predictedText substringWithRange:range]; - if (_predictedText) { - _predictedText = [_predictedText stringByReplacingCharactersInRange:range withString:text]; - } else { - _predictedText = text; - } - - if (_onTextInput) { - _onTextInput(@{ - @"text": text, - @"previousText": previousText ?: @"", - @"range": @{ - @"start": @(range.location), - @"end": @(range.location + range.length) - }, - @"eventCount": @(_nativeEventCount), - }); - } - - return YES; -} - -static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange, NSRange *secondRange) -{ - NSInteger firstMismatch = -1; - for (NSUInteger ii = 0; ii < MAX(first.length, second.length); ii++) { - if (ii >= first.length || ii >= second.length || [first characterAtIndex:ii] != [second characterAtIndex:ii]) { - firstMismatch = ii; - break; - } - } - - if (firstMismatch == -1) { - return NO; - } - - NSUInteger ii = second.length; - NSUInteger lastMismatch = first.length; - while (ii > firstMismatch && lastMismatch > firstMismatch) { - if ([first characterAtIndex:(lastMismatch - 1)] != [second characterAtIndex:(ii - 1)]) { - break; - } - ii--; - lastMismatch--; - } - - *firstRange = NSMakeRange(firstMismatch, lastMismatch - firstMismatch); - *secondRange = NSMakeRange(firstMismatch, ii - firstMismatch); - return YES; -} - -- (void)textInputDidChange -{ - [self invalidateContentSize]; - - // Detect when _backedTextInput updates happend that didn't invoke `shouldChangeTextInRange` - // (e.g. typing simplified chinese in pinyin will insert and remove spaces without - // calling shouldChangeTextInRange). This will cause JS to get out of sync so we - // update the mismatched range. - NSRange currentRange; - NSRange predictionRange; - if (findMismatch(_backedTextInput.text, _predictedText, ¤tRange, &predictionRange)) { - NSString *replacement = [_backedTextInput.text substringWithRange:currentRange]; - [self textInputShouldChangeTextInRange:predictionRange replacementText:replacement]; - // JS will assume the selection changed based on the location of our shouldChangeTextInRange, so reset it. - [self textInputDidChangeSelection]; - _predictedText = _backedTextInput.text; - } - - _nativeUpdatesInFlight = NO; - _nativeEventCount++; - - if (!self.reactTag || !_onChange) { - return; - } - - _onChange(@{ - @"text": self.text, - @"target": self.reactTag, - @"eventCount": @(_nativeEventCount), - }); + return _backedTextInputView; } #pragma mark - UIScrollViewDelegate -- (void)scrollViewDidScroll:(NSScrollView *)scrollView +- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (_onScroll) { + RCTDirectEventBlock onScroll = self.onScroll; + + if (onScroll) { CGPoint contentOffset = scrollView.contentOffset; CGSize contentSize = scrollView.contentSize; CGSize size = scrollView.bounds.size; - NSEdgeInsets contentInset = scrollView.contentInset; + UIEdgeInsets contentInset = scrollView.contentInset; - _onScroll(@{ + onScroll(@{ @"contentOffset": @{ @"x": @(contentOffset.x), @"y": @(contentOffset.y) diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.h b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.h index 322cfa1679..b2053435fc 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.h +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.h @@ -9,6 +9,10 @@ #import "RCTBaseTextInputViewManager.h" +NS_ASSUME_NONNULL_BEGIN + @interface RCTMultilineTextInputViewManager : RCTBaseTextInputViewManager @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index c405570f0c..de84955739 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -9,38 +9,19 @@ #import "RCTMultilineTextInputViewManager.h" -#import -#import -#import -#import -#import - -#import "RCTConvert+Text.h" -#import "RCTMultilineTextInputShadowView.h" #import "RCTMultilineTextInputView.h" @implementation RCTMultilineTextInputViewManager RCT_EXPORT_MODULE() -- (RCTShadowView *)shadowView -{ - return [RCTMultilineTextInputShadowView new]; -} - -- (NSView *)view +- (UIView *)view { return [[RCTMultilineTextInputView alloc] initWithBridge:self.bridge]; } #pragma mark - Multiline (aka TextView) specific properties -RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onContentSizeChange, RCTBubblingEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) - #if !TARGET_OS_TV RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.dataDetectorTypes, UIDataDetectorTypes) #endif diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index 2ce9dcf6ba..104e105904 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" @@ -18,20 +18,17 @@ NS_ASSUME_NONNULL_BEGIN /* * Just regular UITextView... but much better! */ - -@interface RCTUITextView : NSTextView +@interface RCTUITextView : UITextView - (instancetype)initWithFrame:(CGRect)frame textContainer:(nullable NSTextContainer *)textContainer NS_UNAVAILABLE; -- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; @property (nonatomic, weak) id textInputDelegate; -// - (void)setText:(NSString *)text; -- (void)setAttributedText:(NSAttributedString *)attributedText; -@property (nonatomic, strong) NSAttributedString *placeholderAttributedString; -@property (nonatomic, assign) BOOL textWasPasted; -@property (nonatomic, copy, nullable) NSString *placeholderText; -@property (nonatomic, assign, nullable) NSColor *placeholderTextColor; +@property (nonatomic, assign, readonly) BOOL textWasPasted; +@property (nonatomic, copy, nullable) NSString *placeholder; +@property (nonatomic, strong, nullable) UIColor *placeholderColor; + @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; @end diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index de4738fd3c..3462b833ff 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -7,47 +7,43 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import #import "RCTUITextView.h" -#import #import - -CGRect UIEdgeInsetsSizeRect(CGRect rect, CGSize insets) { -// rect.origin.x += insets.left; - // rect.origin.y += insets.top; - rect.size.width -= (insets.width); - rect.size.height -= (insets.height); - return rect; -} - +#import #import "RCTBackedTextInputDelegateAdapter.h" @implementation RCTUITextView { - NSTextField *_placeholderView; - NSTextView *_detachedTextView; + UILabel *_placeholderView; + UITextView *_detachedTextView; RCTBackedTextViewDelegateAdapter *_textInputDelegateAdapter; } -static NSFont *defaultPlaceholderFont() +static UIFont *defaultPlaceholderFont() { - return [NSFont systemFontOfSize:17]; + return [UIFont systemFontOfSize:17]; } -static NSColor *defaultPlaceholderTextColor() +static UIColor *defaultPlaceholderColor() { // Default placeholder color from UITextField. - return [NSColor colorWithRed:0 green:0 blue:0.0980392 alpha:0.22]; + return [UIColor colorWithRed:0 green:0 blue:0.0980392 alpha:0.22]; } - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - _placeholderView = [[NSTextField alloc] initWithFrame:self.bounds]; -// _placeholderView.isAccessibilityElement = NO; -// _placeholderView.numberOfLines = 0; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textDidChange) + name:UITextViewTextDidChangeNotification + object:self]; + + _placeholderView = [[UILabel alloc] initWithFrame:self.bounds]; + _placeholderView.isAccessibilityElement = NO; + _placeholderView.numberOfLines = 0; + _placeholderView.textColor = defaultPlaceholderColor(); [self addSubview:_placeholderView]; _textInputDelegateAdapter = [[RCTBackedTextViewDelegateAdapter alloc] initWithTextView:self]; @@ -56,23 +52,27 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} - (NSString *)accessibilityLabel { NSMutableString *accessibilityLabel = [NSMutableString new]; - + NSString *superAccessibilityLabel = [super accessibilityLabel]; if (superAccessibilityLabel.length > 0) { [accessibilityLabel appendString:superAccessibilityLabel]; } - - if (self.placeholder.length > 0 && self.text.length == 0) { + + if (self.placeholder.length > 0 && self.attributedText.string.length == 0) { if (accessibilityLabel.length > 0) { [accessibilityLabel appendString:@" "]; } [accessibilityLabel appendString:self.placeholder]; } - + return accessibilityLabel; } @@ -80,11 +80,11 @@ - (NSString *)accessibilityLabel - (void)setPlaceholder:(NSString *)placeholder { - _placeholderText = placeholderText; - _placeholderView.stringValue = _placeholderText; + _placeholder = placeholder; + _placeholderView.text = _placeholder; } -- (void)setPlaceholderTextColor:(NSColor *)placeholderTextColor +- (void)setPlaceholderColor:(UIColor *)placeholderColor { _placeholderColor = placeholderColor; _placeholderView.textColor = _placeholderColor ?: defaultPlaceholderColor(); @@ -98,28 +98,27 @@ - (void)textDidChange #pragma mark - Overrides -- (void)setFont:(NSFont *)font +- (void)setFont:(UIFont *)font { - // [super setFont:font]; - [[super textStorage] setFont:font]; + [super setFont:font]; _placeholderView.font = font ?: defaultPlaceholderFont(); } - (void)setTextAlignment:(NSTextAlignment)textAlignment { - // [super setTextAlignment:textAlignment]; - // _placeholderView.textAlignment = textAlignment; + [super setTextAlignment:textAlignment]; + _placeholderView.textAlignment = textAlignment; } - (void)setText:(NSString *)text { - [self setString:text]; + [super setText:text]; [self textDidChange]; } - (void)setAttributedText:(NSAttributedString *)attributedText { - [self.textStorage setAttributedString:attributedText]; + [super setAttributedText:attributedText]; [self textDidChange]; } @@ -146,16 +145,46 @@ - (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated { // Turning off scroll animation. // This fixes the problem also known as "flaky scrolling". - // [super setContentOffset:contentOffset animated:NO]; + [super setContentOffset:contentOffset animated:NO]; } #pragma mark - Layout -- (void)layout +- (CGFloat)preferredMaxLayoutWidth { - [super layout]; + // Returning size DOES contain `textContainerInset` (aka `padding`). + return _preferredMaxLayoutWidth ?: self.placeholderSize.width; +} - CGRect textFrame = UIEdgeInsetsSizeRect(self.bounds, self.textContainerInset); +- (CGSize)placeholderSize +{ + UIEdgeInsets textContainerInset = self.textContainerInset; + NSString *placeholder = self.placeholder ?: @""; + CGSize placeholderSize = [placeholder sizeWithAttributes:@{NSFontAttributeName: self.font ?: defaultPlaceholderFont()}]; + placeholderSize = CGSizeMake(RCTCeilPixelValue(placeholderSize.width), RCTCeilPixelValue(placeholderSize.height)); + placeholderSize.width += textContainerInset.left + textContainerInset.right; + placeholderSize.height += textContainerInset.top + textContainerInset.bottom; + // Returning size DOES contain `textContainerInset` (aka `padding`; as `sizeThatFits:` does). + return placeholderSize; +} + +- (CGSize)contentSize +{ + CGSize contentSize = super.contentSize; + CGSize placeholderSize = self.placeholderSize; + // When a text input is empty, it actually displays a placehoder. + // So, we have to consider `placeholderSize` as a minimum `contentSize`. + // Returning size DOES contain `textContainerInset` (aka `padding`). + return CGSizeMake( + MAX(contentSize.width, placeholderSize.width), + MAX(contentSize.height, placeholderSize.height)); +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGRect textFrame = UIEdgeInsetsInsetRect(self.bounds, self.textContainerInset); CGFloat placeholderHeight = [_placeholderView sizeThatFits:textFrame.size].height; textFrame.size.height = MIN(placeholderHeight, textFrame.size.height); _placeholderView.frame = textFrame; @@ -164,20 +193,48 @@ - (void)layout - (CGSize)intrinsicContentSize { // Returning size DOES contain `textContainerInset` (aka `padding`). - return [self sizeThatFits:CGSizeMake(self.preferredMaxLayoutWidth, INFINITY)]; + return [self sizeThatFits:CGSizeMake(self.preferredMaxLayoutWidth, CGFLOAT_MAX)]; } - (CGSize)sizeThatFits:(CGSize)size { - NSRect rect = [super.layoutManager usedRectForTextContainer:super.textContainer]; - return CGSizeMake(MIN(rect.size.width, size.width), rect.size.height); + // Returned fitting size depends on text size and placeholder size. + CGSize textSize = [self fixedSizeThatFits:size]; + CGSize placeholderSize = self.placeholderSize; + // Returning size DOES contain `textContainerInset` (aka `padding`). + return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height)); +} + +- (CGSize)fixedSizeThatFits:(CGSize)size +{ + // UITextView on iOS 8 has a bug that automatically scrolls to the top + // when calling `sizeThatFits:`. Use a copy so that self is not screwed up. + static BOOL useCustomImplementation = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + useCustomImplementation = ![[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,0,0}]; + }); + + if (!useCustomImplementation) { + return [super sizeThatFits:size]; + } + + if (!_detachedTextView) { + _detachedTextView = [UITextView new]; + } + + _detachedTextView.attributedText = self.attributedText; + _detachedTextView.font = self.font; + _detachedTextView.textContainerInset = self.textContainerInset; + + return [_detachedTextView sizeThatFits:size]; } #pragma mark - Placeholder - (void)invalidatePlaceholderVisibility { - BOOL isVisible = _placeholderText.length != 0 && self.string.length == 0; + BOOL isVisible = _placeholder.length != 0 && self.attributedText.length == 0; _placeholderView.hidden = !isVisible; } diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h index 444f0aa1b0..d124ef2ec5 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h @@ -7,10 +7,12 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import @protocol RCTBackedTextInputViewProtocol; +NS_ASSUME_NONNULL_BEGIN + @protocol RCTBackedTextInputDelegate - (BOOL)textInputShouldBeginEditing; // Return `NO` to disallow editing. @@ -28,3 +30,5 @@ - (void)textInputDidChangeSelection; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index c4a96c746e..b9914c2355 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -7,18 +7,20 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" #import "RCTBackedTextInputDelegate.h" +NS_ASSUME_NONNULL_BEGIN + #pragma mark - RCTBackedTextFieldDelegateAdapter (for UITextField) @interface RCTBackedTextFieldDelegateAdapter : NSObject -- (instancetype)initWithTextField:(NSTextField *)backedTextInput; +- (instancetype)initWithTextField:(UITextField *)backedTextInputView; -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange *)textRange; +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; - (void)selectedTextRangeWasSet; @end @@ -27,8 +29,10 @@ @interface RCTBackedTextViewDelegateAdapter : NSObject -- (instancetype)initWithTextView:(NSTextView *)backedTextInput; +- (instancetype)initWithTextView:(UITextView *)backedTextInputView; -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange *)textRange; +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index a904823475..856d708f6f 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -13,23 +13,23 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingContext; -@interface RCTBackedTextFieldDelegateAdapter () +@interface RCTBackedTextFieldDelegateAdapter () @end @implementation RCTBackedTextFieldDelegateAdapter { - __weak NSTextField *_backedTextInput; + __weak UITextField *_backedTextInputView; BOOL _textDidChangeIsComing; - NSRange *_previousSelectedTextRange; + UITextRange *_previousSelectedTextRange; } -- (instancetype)initWithTextField:(NSTextField *)backedTextInput +- (instancetype)initWithTextField:(UITextField *)backedTextInputView { if (self = [super init]) { - _backedTextInput = backedTextInput; - backedTextInput.delegate = self; + _backedTextInputView = backedTextInputView; + backedTextInputView.delegate = self; - [_backedTextInput addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged]; - [_backedTextInput addTarget:self action:@selector(textFieldDidEndEditingOnExit) forControlEvents:UIControlEventEditingDidEndOnExit]; + [_backedTextInputView addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged]; + [_backedTextInputView addTarget:self action:@selector(textFieldDidEndEditingOnExit) forControlEvents:UIControlEventEditingDidEndOnExit]; } return self; @@ -37,51 +37,51 @@ - (instancetype)initWithTextField:(NSTextField * - (void)dealloc { - [_backedTextInput removeTarget:self action:nil forControlEvents:UIControlEventEditingChanged]; - [_backedTextInput removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit]; + [_backedTextInputView removeTarget:self action:nil forControlEvents:UIControlEventEditingChanged]; + [_backedTextInputView removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit]; } #pragma mark - UITextFieldDelegate -- (BOOL)textFieldShouldBeginEditing:(__unused NSTextField *)textField +- (BOOL)textFieldShouldBeginEditing:(__unused UITextField *)textField { - return [_backedTextInput.textInputDelegate textInputShouldBeginEditing]; + return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)textFieldDidBeginEditing:(__unused NSTextField *)textField +- (void)textFieldDidBeginEditing:(__unused UITextField *)textField { - [_backedTextInput.textInputDelegate textInputDidBeginEditing]; + [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } -- (BOOL)textFieldShouldEndEditing:(__unused NSTextField *)textField +- (BOOL)textFieldShouldEndEditing:(__unused UITextField *)textField { - return [_backedTextInput.textInputDelegate textInputShouldEndEditing]; + return [_backedTextInputView.textInputDelegate textInputShouldEndEditing]; } -- (void)textFieldDidEndEditing:(__unused NSTextField *)textField +- (void)textFieldDidEndEditing:(__unused UITextField *)textField { if (_textDidChangeIsComing) { // iOS does't call `textViewDidChange:` delegate method if the change was happened because of autocorrection // which was triggered by losing focus. So, we call it manually. _textDidChangeIsComing = NO; - [_backedTextInput.textInputDelegate textInputDidChange]; + [_backedTextInputView.textInputDelegate textInputDidChange]; } - [_backedTextInput.textInputDelegate textInputDidEndEditing]; + [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } -- (BOOL)textField:(__unused NSTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string +- (BOOL)textField:(__unused UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - BOOL result = [_backedTextInput.textInputDelegate textInputShouldChangeTextInRange:range replacementText:string]; + BOOL result = [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:range replacementText:string]; if (result) { _textDidChangeIsComing = YES; } return result; } -- (BOOL)textFieldShouldReturn:(__unused NSTextField *)textField +- (BOOL)textFieldShouldReturn:(__unused UITextField *)textField { - return [_backedTextInput.textInputDelegate textInputShouldReturn]; + return [_backedTextInputView.textInputDelegate textInputShouldReturn]; } #pragma mark - UIControlEventEditing* Family Events @@ -89,7 +89,7 @@ - (BOOL)textFieldShouldReturn:(__unused NSTextField *)textField - (void)textFieldDidChange { _textDidChangeIsComing = NO; - [_backedTextInput.textInputDelegate textInputDidChange]; + [_backedTextInputView.textInputDelegate textInputDidChange]; // `selectedTextRangeWasSet` isn't triggered during typing. [self textFieldProbablyDidChangeSelection]; @@ -97,22 +97,22 @@ - (void)textFieldDidChange - (void)textFieldDidEndEditingOnExit { - [_backedTextInput.textInputDelegate textInputDidReturn]; + [_backedTextInputView.textInputDelegate textInputDidReturn]; } #pragma mark - UIKeyboardInput (private UIKit protocol) // This method allows us to detect a [Backspace] `keyPress` // even when there is no more text in the `UITextField`. -- (BOOL)keyboardInputShouldDelete:(__unused NSTextField *)textField +- (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField { - [_backedTextInput.textInputDelegate textInputShouldChangeTextInRange:NSMakeRange(0, 0) replacementText:@""]; + [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:NSMakeRange(0, 0) replacementText:@""]; return YES; } #pragma mark - Public Interface -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange *)textRange +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange { _previousSelectedTextRange = textRange; } @@ -126,32 +126,32 @@ - (void)selectedTextRangeWasSet - (void)textFieldProbablyDidChangeSelection { - if ([_backedTextInput.selectedTextRange isEqual:_previousSelectedTextRange]) { + if ([_backedTextInputView.selectedTextRange isEqual:_previousSelectedTextRange]) { return; } - _previousSelectedTextRange = _backedTextInput.selectedTextRange; - [_backedTextInput.textInputDelegate textInputDidChangeSelection]; + _previousSelectedTextRange = _backedTextInputView.selectedTextRange; + [_backedTextInputView.textInputDelegate textInputDidChangeSelection]; } @end #pragma mark - RCTBackedTextViewDelegateAdapter (for UITextView) -@interface RCTBackedTextViewDelegateAdapter () +@interface RCTBackedTextViewDelegateAdapter () @end @implementation RCTBackedTextViewDelegateAdapter { - __weak NSTextView *_backedTextInput; + __weak UITextView *_backedTextInputView; BOOL _textDidChangeIsComing; - NSRange *_previousSelectedTextRange; + UITextRange *_previousSelectedTextRange; } -- (instancetype)initWithTextView:(NSTextView *)backedTextInput +- (instancetype)initWithTextView:(UITextView *)backedTextInputView { if (self = [super init]) { - _backedTextInput = backedTextInput; - backedTextInput.delegate = self; + _backedTextInputView = backedTextInputView; + backedTextInputView.delegate = self; } return self; @@ -159,19 +159,19 @@ - (instancetype)initWithTextView:(NSTextView *)b #pragma mark - UITextViewDelegate -- (BOOL)textViewShouldBeginEditing:(__unused NSTextView *)textView +- (BOOL)textViewShouldBeginEditing:(__unused UITextView *)textView { - return [_backedTextInput.textInputDelegate textInputShouldBeginEditing]; + return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)textViewDidBeginEditing:(__unused NSTextView *)textView +- (void)textViewDidBeginEditing:(__unused UITextView *)textView { - [_backedTextInput.textInputDelegate textInputDidBeginEditing]; + [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } - (BOOL)textViewShouldEndEditing:(__unused UITextView *)textView { - return [_backedTextInput.textInputDelegate textInputShouldEndEditing]; + return [_backedTextInputView.textInputDelegate textInputShouldEndEditing]; } - (void)textViewDidEndEditing:(__unused UITextView *)textView @@ -180,24 +180,24 @@ - (void)textViewDidEndEditing:(__unused UITextView *)textView // iOS does't call `textViewDidChange:` delegate method if the change was happened because of autocorrection // which was triggered by losing focus. So, we call it manually. _textDidChangeIsComing = NO; - [_backedTextInput.textInputDelegate textInputDidChange]; + [_backedTextInputView.textInputDelegate textInputDidChange]; } - [_backedTextInput.textInputDelegate textInputDidEndEditing]; + [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } -- (BOOL)textView:(__unused NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text +- (BOOL)textView:(__unused UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { // Custom implementation of `textInputShouldReturn` and `textInputDidReturn` pair for `UITextView`. - if (!_backedTextInput.textWasPasted && [text isEqualToString:@"\n"]) { - if ([_backedTextInput.textInputDelegate textInputShouldReturn]) { - [_backedTextInput.textInputDelegate textInputDidReturn]; - [_backedTextInput endEditing:NO]; + if (!_backedTextInputView.textWasPasted && [text isEqualToString:@"\n"]) { + if ([_backedTextInputView.textInputDelegate textInputShouldReturn]) { + [_backedTextInputView.textInputDelegate textInputDidReturn]; + [_backedTextInputView endEditing:NO]; return NO; } } - BOOL result = [_backedTextInput.textInputDelegate textInputShouldChangeTextInRange:range replacementText:text]; + BOOL result = [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:range replacementText:text]; if (result) { _textDidChangeIsComing = YES; } @@ -207,7 +207,7 @@ - (BOOL)textView:(__unused NSTextView *)textView shouldChangeTextInRange:(NSRang - (void)textViewDidChange:(__unused UITextView *)textView { _textDidChangeIsComing = NO; - [_backedTextInput.textInputDelegate textInputDidChange]; + [_backedTextInputView.textInputDelegate textInputDidChange]; } - (void)textViewDidChangeSelection:(__unused UITextView *)textView @@ -226,12 +226,12 @@ - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)tex - (void)textViewProbablyDidChangeSelection { - if ([_backedTextInput.selectedTextRange isEqual:_previousSelectedTextRange]) { + if ([_backedTextInputView.selectedTextRange isEqual:_previousSelectedTextRange]) { return; } - _previousSelectedTextRange = _backedTextInput.selectedTextRange; - [_backedTextInput.textInputDelegate textInputDidChangeSelection]; + _previousSelectedTextRange = _backedTextInputView.selectedTextRange; + [_backedTextInputView.textInputDelegate textInputDidChangeSelection]; } @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index e60de04816..32a2a6ae3e 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -7,20 +7,23 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import @protocol RCTBackedTextInputDelegate; -@protocol RCTBackedTextInputViewProtocol +NS_ASSUME_NONNULL_BEGIN -@property (nonatomic, copy, nullable) NSString *text; -@property (nonatomic, strong, nullable) NSColor *textColor; +@protocol RCTBackedTextInputViewProtocol + +@property (nonatomic, strong, nullable) UIColor *textColor; +@property (nonatomic, strong, nullable) UIFont *font; +@property (nonatomic, copy, nullable) NSAttributedString *attributedText; @property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) NSColor *placeholderColor; +@property (nonatomic, strong, nullable) UIColor *placeholderColor; +@property (nonatomic, assign) NSTextAlignment textAlignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, strong, nullable) NSFont *font; -@property (nonatomic, assign) NSEdgeInsets textContainerInset; -@property (nonatomic, strong, nullable) NSView *inputAccessoryView; +@property (nonatomic, assign) UIEdgeInsets textContainerInset; +@property (nonatomic, strong, nullable) UIView *inputAccessoryView; @property (nonatomic, weak, nullable) id textInputDelegate; @property (nonatomic, readonly) CGSize contentSize; @@ -29,7 +32,14 @@ // explicitly specify should `delegate` be notified about the change or not. // If the change was initiated programmatically, we must NOT notify the delegate. // If the change was a result of user actions (like typing or touches), we MUST notify the delegate. -- (void)setSelectedTextRange:(NSRange)selectedTextRange NS_UNAVAILABLE; -- (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate; +- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE; +- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate; + +// This protocol disallows direct access to `text` property because +// unwise usage of it can break the `attributeText` behavior. +// Use `attributedText.string` instead. +@property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.h b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.h new file mode 100644 index 0000000000..3f1e8185b3 --- /dev/null +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.h @@ -0,0 +1,27 @@ +/** + * 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 "RCTBaseTextShadowView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTBaseTextInputShadowView : RCTBaseTextShadowView + +- (instancetype)initWithBridge:(RCTBridge *)bridge; + +@property (nonatomic, copy, nullable) NSString *text; +@property (nonatomic, copy, nullable) NSString *placeholder; +@property (nonatomic, assign) NSInteger maximumNumberOfLines; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange; + +- (void)uiManagerWillPerformMounting; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m new file mode 100644 index 0000000000..e145d4a3b0 --- /dev/null +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -0,0 +1,251 @@ +/** + * 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 "RCTBaseTextInputShadowView.h" + +#import +#import +#import +#import + +#import "NSTextStorage+FontScaling.h" +#import "RCTBaseTextInputView.h" + +@implementation RCTBaseTextInputShadowView +{ + __weak RCTBridge *_bridge; + NSAttributedString *_Nullable _previousAttributedText; + BOOL _needsUpdateView; + NSAttributedString *_Nullable _localAttributedText; + CGSize _previousContentSize; + + NSTextStorage *_textStorage; + NSTextContainer *_textContainer; + NSLayoutManager *_layoutManager; +} + +- (instancetype)initWithBridge:(RCTBridge *)bridge +{ + if (self = [super init]) { + _bridge = bridge; + _needsUpdateView = YES; + + YGNodeSetMeasureFunc(self.yogaNode, RCTBaseTextInputShadowViewMeasure); + } + + return self; +} + +- (BOOL)isYogaLeafNode +{ + return YES; +} + +- (void)setLocalData:(NSObject *)localData +{ + NSAttributedString *attributedText = (NSAttributedString *)localData; + + if ([attributedText isEqualToAttributedString:_localAttributedText]) { + return; + } + + _localAttributedText = attributedText; + [self dirtyLayout]; +} + +- (void)dirtyLayout +{ + [super dirtyLayout]; + _needsUpdateView = YES; + YGNodeMarkDirty(self.yogaNode); + [self invalidateContentSize]; +} + +- (void)invalidateContentSize +{ + if (!_onContentSizeChange) { + return; + } + + CGSize maximumSize = self.frame.size; + + if (_maximumNumberOfLines == 1) { + maximumSize.width = CGFLOAT_MAX; + } else { + maximumSize.height = CGFLOAT_MAX; + } + + CGSize contentSize = [self sizeThatFitsMinimumSize:(CGSize)CGSizeZero maximumSize:maximumSize]; + + if (CGSizeEqualToSize(_previousContentSize, contentSize)) { + return; + } + _previousContentSize = contentSize; + + _onContentSizeChange(@{ + @"contentSize": @{ + @"height": @(contentSize.height), + @"width": @(contentSize.width), + }, + @"target": self.reactTag, + }); +} + +#pragma mark - RCTUIManagerObserver + +- (void)uiManagerWillPerformMounting +{ + if (YGNodeIsDirty(self.yogaNode)) { + return; + } + + if (!_needsUpdateView) { + return; + } + _needsUpdateView = NO; + + UIEdgeInsets borderInsets = self.borderAsInsets; + UIEdgeInsets paddingInsets = self.paddingAsInsets; + + RCTTextAttributes *textAttributes = [self.textAttributes copy]; + + NSMutableAttributedString *attributedText = + [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; + + // Removing all references to Shadow Views and tags to avoid unnececery retainning + // and problems with comparing the strings. + [attributedText removeAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName + range:NSMakeRange(0, attributedText.length)]; + + [attributedText removeAttribute:RCTTextAttributesTagAttributeName + range:NSMakeRange(0, attributedText.length)]; + + if (self.text.length) { + NSAttributedString *propertyAttributedText = + [[NSAttributedString alloc] initWithString:self.text + attributes:self.textAttributes.effectiveTextAttributes]; + [attributedText insertAttributedString:propertyAttributedText atIndex:0]; + } + + BOOL isAttributedTextChanged = NO; + if (![_previousAttributedText isEqualToAttributedString:attributedText]) { + // We have to follow `set prop` pattern: + // If the value has not changed, we must not notify the view about the change, + // otherwise we may break local (temporary) state of the text input. + isAttributedTextChanged = YES; + _previousAttributedText = [attributedText copy]; + } + + NSNumber *tag = self.reactTag; + + [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RCTBaseTextInputView *baseTextInputView = (RCTBaseTextInputView *)viewRegistry[tag]; + if (!baseTextInputView) { + return; + } + + baseTextInputView.textAttributes = textAttributes; + baseTextInputView.reactBorderInsets = borderInsets; + baseTextInputView.reactPaddingInsets = paddingInsets; + + if (isAttributedTextChanged) { + baseTextInputView.attributedText = attributedText; + } + }]; +} + +#pragma mark - + +- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +{ + // Only for the very first render when we don't have `_localAttributedText`, + // we use value directly from the property and/or nested content. + NSAttributedString *attributedText = + _localAttributedText ?: [self attributedTextWithBaseTextAttributes:nil]; + + if (attributedText.length == 0) { + // It's impossible to measure empty attributed string because all attributes are + // assosiated with some characters, so no characters means no data. + + // Placeholder also can represent the intrinsic size when it is visible. + NSString *text = self.placeholder; + if (!text.length) { + // Zero-width space + text = @"\u200B"; + } + attributedText = [[NSAttributedString alloc] initWithString:text attributes:self.textAttributes.effectiveTextAttributes]; + } + + if (!_textStorage) { + _textContainer = [NSTextContainer new]; + _textContainer.lineFragmentPadding = 0.0; // Note, the default value is 5. + _layoutManager = [NSLayoutManager new]; + [_layoutManager addTextContainer:_textContainer]; + _textStorage = [NSTextStorage new]; + [_textStorage addLayoutManager:_layoutManager]; + } + + _textContainer.size = maximumSize; + _textContainer.maximumNumberOfLines = _maximumNumberOfLines; + [_textStorage replaceCharactersInRange:(NSRange){0, _textStorage.length} + withAttributedString:attributedText]; + [_layoutManager ensureLayoutForTextContainer:_textContainer]; + CGSize size = [_layoutManager usedRectForTextContainer:_textContainer].size; + + return (CGSize){ + MAX(minimumSize.width, MIN(RCTCeilPixelValue(size.width), maximumSize.width)), + MAX(minimumSize.height, MIN(RCTCeilPixelValue(size.height), maximumSize.height)) + }; +} + +static YGSize RCTBaseTextInputShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) +{ + RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node); + + CGSize minimumSize = CGSizeMake(0, 0); + CGSize maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + + CGSize size = { + RCTCoreGraphicsFloatFromYogaFloat(width), + RCTCoreGraphicsFloatFromYogaFloat(height) + }; + + switch (widthMode) { + case YGMeasureModeUndefined: + break; + case YGMeasureModeExactly: + minimumSize.width = size.width; + maximumSize.width = size.width; + break; + case YGMeasureModeAtMost: + maximumSize.width = size.width; + break; + } + + switch (heightMode) { + case YGMeasureModeUndefined: + break; + case YGMeasureModeExactly: + minimumSize.height = size.height; + maximumSize.height = size.height; + break; + case YGMeasureModeAtMost: + maximumSize.height = size.height; + break; + } + + CGSize measuredSize = [shadowView sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize]; + + return (YGSize){ + RCTYogaFloatFromCoreGraphicsFloat(measuredSize.width), + RCTYogaFloatFromCoreGraphicsFloat(measuredSize.height) + }; +} + +@end diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index 8edebf4391..56c8d2b947 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -7,26 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import +#import "RCTBackedTextInputDelegate.h" #import "RCTBackedTextInputViewProtocol.h" -#import "RCTFontAttributes.h" -#import "RCTFontAttributesDelegate.h" @class RCTBridge; @class RCTEventDispatcher; +@class RCTTextAttributes; @class RCTTextSelection; -@interface RCTBaseTextInputView : RCTView { -@protected - __weak RCTBridge *_bridge; - RCTEventDispatcher *_eventDispatcher; - NSInteger _nativeEventCount; - NSInteger _mostRecentEventCount; - BOOL _blurOnSubmit; -} +NS_ASSUME_NONNULL_BEGIN + +@interface RCTBaseTextInputView : RCTView - (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER; @@ -34,35 +29,26 @@ - (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; -@property (nonatomic, readonly) NSView *backedTextInputView; - -@property (nonatomic, assign) NSEdgeInsets reactPaddingInsets; -@property (nonatomic, assign) NSEdgeInsets reactBorderInsets; -@property (nonatomic, assign, readonly) CGSize contentSize; +@property (nonatomic, readonly) UIView *backedTextInputView; -@property (nonatomic, copy) RCTDirectEventBlock onContentSizeChange; -@property (nonatomic, copy) RCTDirectEventBlock onSelectionChange; +@property (nonatomic, strong, nullable) RCTTextAttributes *textAttributes; +@property (nonatomic, assign) UIEdgeInsets reactPaddingInsets; +@property (nonatomic, assign) UIEdgeInsets reactBorderInsets; -@property (nonatomic, readonly, strong) RCTFontAttributes *fontAttributes; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onSelectionChange; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onChange; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onTextInput; +@property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; @property (nonatomic, assign) NSInteger mostRecentEventCount; @property (nonatomic, assign) BOOL blurOnSubmit; @property (nonatomic, assign) BOOL selectTextOnFocus; @property (nonatomic, assign) BOOL clearTextOnFocus; @property (nonatomic, copy) RCTTextSelection *selection; - -- (void)setFont:(NSFont *)font; - -- (void)invalidateContentSize; - -// Temporary exposure of particial `RCTBackedTextInputDelegate` support. -// In the future all methods of the protocol should move to this class. -- (BOOL)textInputShouldBeginEditing; -- (void)textInputDidBeginEditing; -- (BOOL)textInputShouldReturn; -- (void)textInputDidReturn; -- (void)textInputDidChangeSelection; -- (BOOL)textInputShouldEndEditing; -- (void)textInputDidEndEditing; +@property (nonatomic, strong, nullable) NSNumber *maxLength; +@property (nonatomic, copy) NSAttributedString *attributedText; @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 6a6e616763..91f6a980f2 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -15,13 +15,17 @@ #import #import #import -#import +#import +#import "RCTTextAttributes.h" #import "RCTTextSelection.h" @implementation RCTBaseTextInputView { - CGSize _previousContentSize; + __weak RCTBridge *_bridge; + __weak RCTEventDispatcher *_eventDispatcher; BOOL _hasInputAccesoryView; + NSString *_Nullable _predictedText; + NSInteger _nativeEventCount; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -31,8 +35,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge if (self = [super initWithFrame:CGRectZero]) { _bridge = bridge; _eventDispatcher = bridge.eventDispatcher; - _fontAttributes = [[RCTFontAttributes alloc] initWithAccessibilityManager:bridge.accessibilityManager]; - _fontAttributes.delegate = self; } return self; @@ -42,26 +44,40 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)decoder) RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) -- (id)backedTextInputView +- (UIView *)backedTextInputView { RCTAssert(NO, @"-[RCTBaseTextInputView backedTextInputView] must be implemented in subclass."); return nil; } -- (void)setFont:(NSFont *)font +#pragma mark - RCTComponent + +- (void)didUpdateReactSubviews { - self.backedTextInputView.font = font; - [self invalidateContentSize]; + // Do nothing. } -- (void)fontAttributesDidChangeWithFont:(NSFont *)font +#pragma mark - Properties + +- (void)setTextAttributes:(RCTTextAttributes *)textAttributes { - self.font = font; + _textAttributes = textAttributes; + [self enforceTextAttributesIfNeeded]; } -#pragma mark - Properties +- (void)enforceTextAttributesIfNeeded +{ + id backedTextInputView = self.backedTextInputView; + if (backedTextInputView.attributedText.string.length != 0) { + return; + } -- (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets + backedTextInputView.font = _textAttributes.effectiveFont; + backedTextInputView.textColor = _textAttributes.effectiveForegroundColor; + backedTextInputView.textAlignment = _textAttributes.alignment; +} + +- (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets { _reactPaddingInsets = reactPaddingInsets; // We apply `paddingInsets` as `backedTextInputView`'s `textContainerInset`. @@ -69,20 +85,55 @@ - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets [self setNeedsLayout]; } -- (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets +- (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets { _reactBorderInsets = reactBorderInsets; // We apply `borderInsets` as `backedTextInputView` layout offset. - self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); + self.backedTextInputView.frame = UIEdgeInsetsInsetRect(self.bounds, reactBorderInsets); [self setNeedsLayout]; } +- (NSAttributedString *)attributedText +{ + return self.backedTextInputView.attributedText; +} + +- (void)setAttributedText:(NSAttributedString *)attributedText +{ + NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; + + if (eventLag == 0 && ![attributedText.string isEqualToString:self.backedTextInputView.attributedText.string]) { + UITextRange *selection = self.backedTextInputView.selectedTextRange; + NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length; + + self.backedTextInputView.attributedText = attributedText; + + if (selection.empty) { + // Maintaining a cursor position relative to the end of the old text. + NSInteger offsetStart = + [self.backedTextInputView offsetFromPosition:self.backedTextInputView.beginningOfDocument + toPosition:selection.start]; + NSInteger offsetFromEnd = oldTextLength - offsetStart; + NSInteger newOffset = attributedText.string.length - offsetFromEnd; + UITextPosition *position = + [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument + offset:newOffset]; + [self.backedTextInputView setSelectedTextRange:[self.backedTextInputView textRangeFromPosition:position toPosition:position] + notifyDelegate:YES]; + } + + [self updateLocalData]; + } else if (eventLag > RCTTextUpdateLagWarningThreshold) { + RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", self.backedTextInputView.attributedText.string, (long long)eventLag); + } +} + - (RCTTextSelection *)selection { - id backedTextInput = self.backedTextInputView; - NSTextRange *selectedTextRange = backedTextInput.selectedTextRange; - return [[RCTTextSelection new] initWithStart:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.start] - end:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.end]]; + id backedTextInputView = self.backedTextInputView; + UITextRange *selectedTextRange = backedTextInputView.selectedTextRange; + return [[RCTTextSelection new] initWithStart:[backedTextInputView offsetFromPosition:backedTextInputView.beginningOfDocument toPosition:selectedTextRange.start] + end:[backedTextInputView offsetFromPosition:backedTextInputView.beginningOfDocument toPosition:selectedTextRange.end]]; } - (void)setSelection:(RCTTextSelection *)selection @@ -91,18 +142,18 @@ - (void)setSelection:(RCTTextSelection *)selection return; } - id backedTextInput = self.backedTextInputView; + id backedTextInputView = self.backedTextInputView; - NSRange previousSelectedTextRange = backedTextInput.; - NSTextPosition *start = [backedTextInput positionFromPosition:backedTextInput.beginningOfDocument offset:selection.start]; - NSTextPosition *end = [backedTextInput positionFromPosition:backedTextInput.beginningOfDocument offset:selection.end]; - NSRange selectedTextRange = [backedTextInput textRangeFromPosition:start toPosition:end]; + UITextRange *previousSelectedTextRange = backedTextInputView.selectedTextRange; + UITextPosition *start = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument offset:selection.start]; + UITextPosition *end = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument offset:selection.end]; + UITextRange *selectedTextRange = [backedTextInputView textRangeFromPosition:start toPosition:end]; NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; if (eventLag == 0 && ![previousSelectedTextRange isEqual:selectedTextRange]) { - [backedTextInput setSelectedTextRange:selectedTextRange notifyDelegate:NO]; + [backedTextInputView setSelectedTextRange:selectedTextRange notifyDelegate:NO]; } else if (eventLag > RCTTextUpdateLagWarningThreshold) { - RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", backedTextInput.text, (long long)eventLag); + RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", backedTextInputView.attributedText.string, (long long)eventLag); } } @@ -116,7 +167,7 @@ - (BOOL)textInputShouldBeginEditing - (void)textInputDidBeginEditing { if (_clearTextOnFocus) { - self.backedTextInputView.text = @""; + self.backedTextInputView.attributedText = [NSAttributedString new]; } if (_selectTextOnFocus) { @@ -125,7 +176,27 @@ - (void)textInputDidBeginEditing [_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus reactTag:self.reactTag - text:self.backedTextInputView.text + text:self.backedTextInputView.attributedText.string + key:nil + eventCount:_nativeEventCount]; +} + +- (BOOL)textInputShouldEndEditing +{ + return YES; +} + +- (void)textInputDidEndEditing +{ + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeEnd + reactTag:self.reactTag + text:self.backedTextInputView.attributedText.string + key:nil + eventCount:_nativeEventCount]; + + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur + reactTag:self.reactTag + text:self.backedTextInputView.attributedText.string key:nil eventCount:_nativeEventCount]; } @@ -139,7 +210,7 @@ - (BOOL)textInputShouldReturn // (no connection to any specific "submitting" process). [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit reactTag:self.reactTag - text:self.backedTextInputView.text + text:self.backedTextInputView.attributedText.string key:nil eventCount:_nativeEventCount]; @@ -151,74 +222,138 @@ - (void)textInputDidReturn // Does nothing. } -- (void)textInputDidChangeSelection +- (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { - if (!_onSelectionChange) { - return; + id backedTextInputView = self.backedTextInputView; + + if (!backedTextInputView.textWasPasted) { + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeKeyPress + reactTag:self.reactTag + text:nil + key:text + eventCount:_nativeEventCount]; } - RCTTextSelection *selection = self.selection; - _onSelectionChange(@{ - @"selection": @{ - @"start": @(selection.start), - @"end": @(selection.end), - }, - }); -} + if (_maxLength) { + NSUInteger allowedLength = _maxLength.integerValue - backedTextInputView.attributedText.string.length + range.length; + + if (text.length > allowedLength) { + // If we typed/pasted more than one character, limit the text inputted. + if (text.length > 1) { + // Truncate the input string so the result is exactly maxLength + NSString *limitedString = [text substringToIndex:allowedLength]; + NSMutableAttributedString *newAttributedText = [backedTextInputView.attributedText mutableCopy]; + [newAttributedText replaceCharactersInRange:range withString:limitedString]; + backedTextInputView.attributedText = newAttributedText; + _predictedText = newAttributedText.string; + + // Collapse selection at end of insert to match normal paste behavior. + UITextPosition *insertEnd = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument + offset:(range.location + allowedLength)]; + [backedTextInputView setSelectedTextRange:[backedTextInputView textRangeFromPosition:insertEnd toPosition:insertEnd] + notifyDelegate:YES]; + + [self textInputDidChange]; + } + + return NO; + } + } -- (BOOL)textInputShouldEndEditing -{ - return YES; -} + if (range.location + range.length > _predictedText.length) { + // _predictedText got out of sync in a bad way, so let's just force sync it. Haven't been able to repro this, but + // it's causing a real crash here: #6523822 + _predictedText = backedTextInputView.attributedText.string; + } -- (void)textInputDidEndEditing -{ - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeEnd - reactTag:self.reactTag - text:self.backedTextInputView.text - key:nil - eventCount:_nativeEventCount]; + NSString *previousText = [_predictedText substringWithRange:range] ?: @""; - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur + if (_predictedText) { + _predictedText = [_predictedText stringByReplacingCharactersInRange:range withString:text]; + } else { + _predictedText = text; + } + + if (_onTextInput) { + _onTextInput(@{ + @"text": text, + @"previousText": previousText, + @"range": @{ + @"start": @(range.location), + @"end": @(range.location + range.length) + }, + @"eventCount": @(_nativeEventCount), + }); + } + + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange reactTag:self.reactTag - text:self.backedTextInputView.text + text:backedTextInputView.attributedText.string key:nil eventCount:_nativeEventCount]; -} -#pragma mark - Content Size (in Yoga terms, without any insets) + return YES; +} -- (CGSize)contentSize +- (void)textInputDidChange { - CGSize contentSize = self.backedTextInputView.contentSize; - UIEdgeInsets reactPaddingInsets = self.reactPaddingInsets; - contentSize.width -= reactPaddingInsets.left + reactPaddingInsets.right; - contentSize.height -= reactPaddingInsets.top + reactPaddingInsets.bottom; - // Returning value does NOT include border and padding insets. - return contentSize; + [self updateLocalData]; + + id backedTextInputView = self.backedTextInputView; + + // Detect when `backedTextInputView` updates happend that didn't invoke `shouldChangeTextInRange` + // (e.g. typing simplified chinese in pinyin will insert and remove spaces without + // calling shouldChangeTextInRange). This will cause JS to get out of sync so we + // update the mismatched range. + NSRange currentRange; + NSRange predictionRange; + if (findMismatch(backedTextInputView.attributedText.string, _predictedText, ¤tRange, &predictionRange)) { + NSString *replacement = [backedTextInputView.attributedText.string substringWithRange:currentRange]; + [self textInputShouldChangeTextInRange:predictionRange replacementText:replacement]; + // JS will assume the selection changed based on the location of our shouldChangeTextInRange, so reset it. + [self textInputDidChangeSelection]; + _predictedText = backedTextInputView.attributedText.string; + } + + _nativeEventCount++; + + if (_onChange) { + _onChange(@{ + @"text": self.attributedText.string, + @"target": self.reactTag, + @"eventCount": @(_nativeEventCount), + }); + } + + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange + reactTag:self.reactTag + text:backedTextInputView.attributedText.string + key:nil + eventCount:_nativeEventCount]; } -- (void)invalidateContentSize +- (void)textInputDidChangeSelection { - // Updates `contentSize` property and notifies Yoga about the change, if necessary. - CGSize contentSize = self.contentSize; - - if (CGSizeEqualToSize(_previousContentSize, contentSize)) { + if (!_onSelectionChange) { return; } - _previousContentSize = contentSize; - [_bridge.uiManager setIntrinsicContentSize:contentSize forView:self]; + RCTTextSelection *selection = self.selection; - if (_onContentSizeChange) { - _onContentSizeChange(@{ - @"contentSize": @{ - @"height": @(contentSize.height), - @"width": @(contentSize.width), - }, - @"target": self.reactTag, - }); - } + _onSelectionChange(@{ + @"selection": @{ + @"start": @(selection.start), + @"end": @(selection.end), + }, + }); +} + +- (void)updateLocalData +{ + [self enforceTextAttributesIfNeeded]; + + [_bridge.uiManager setLocalData:[self.backedTextInputView.attributedText copy] + forView:self]; } #pragma mark - Layout (in UIKit terms, with all insets) @@ -251,12 +386,6 @@ - (CGSize)sizeThatFits:(CGSize)size return fittingSize; } -- (void)layoutSubviews -{ - [super layoutSubviews]; - [self invalidateContentSize]; -} - #pragma mark - Accessibility - (UIView *)reactAccessibilityElement @@ -343,4 +472,35 @@ - (void)handleInputAccessoryDoneButton } } +#pragma mark - Helpers + +static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange, NSRange *secondRange) +{ + NSInteger firstMismatch = -1; + for (NSUInteger ii = 0; ii < MAX(first.length, second.length); ii++) { + if (ii >= first.length || ii >= second.length || [first characterAtIndex:ii] != [second characterAtIndex:ii]) { + firstMismatch = ii; + break; + } + } + + if (firstMismatch == -1) { + return NO; + } + + NSUInteger ii = second.length; + NSUInteger lastMismatch = first.length; + while (ii > firstMismatch && lastMismatch > firstMismatch) { + if ([first characterAtIndex:(lastMismatch - 1)] != [second characterAtIndex:(ii - 1)]) { + break; + } + ii--; + lastMismatch--; + } + + *firstRange = NSMakeRange(firstMismatch, lastMismatch - firstMismatch); + *secondRange = NSMakeRange(firstMismatch, ii - firstMismatch); + return YES; +} + @end diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.h b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.h index 0d5b669c92..710536aaa4 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.h @@ -7,8 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import "RCTBaseTextViewManager.h" -@interface RCTBaseTextInputViewManager : RCTViewManager +@interface RCTBaseTextInputViewManager : RCTBaseTextViewManager @end diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index f4fe8305d9..7e98eda2de 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -9,31 +9,36 @@ #import "RCTBaseTextInputViewManager.h" +#import #import #import #import #import #import +#import +#import -#import "RCTConvert+Text.h" +#import "RCTBaseTextInputShadowView.h" #import "RCTBaseTextInputView.h" +#import "RCTConvert+Text.h" + +@interface RCTBaseTextInputViewManager () + +@end @implementation RCTBaseTextInputViewManager +{ + NSHashTable *_shadowViews; +} RCT_EXPORT_MODULE() #pragma mark - Unified properties -RCT_REMAP_VIEW_PROPERTY(allowFontScaling, fontAttributes.allowFontScaling, BOOL) RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) -RCT_REMAP_VIEW_PROPERTY(color, backedTextInputView.textColor, UIColor) RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL) RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL) -RCT_REMAP_VIEW_PROPERTY(fontSize, fontAttributes.fontSize, NSNumber) -RCT_REMAP_VIEW_PROPERTY(fontWeight, fontAttributes.fontWeight, NSString) -RCT_REMAP_VIEW_PROPERTY(fontStyle, fontAttributes.fontStyle, NSString) -RCT_REMAP_VIEW_PROPERTY(fontFamily, fontAttributes.fontFamily, NSString) RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) RCT_REMAP_VIEW_PROPERTY(keyboardType, backedTextInputView.keyboardType, UIKeyboardType) RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString) @@ -42,26 +47,74 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, UIColor) RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) -RCT_REMAP_VIEW_PROPERTY(textAlign, backedTextInputView.textAlignment, NSTextAlignment) +RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) +RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber) RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(selection, RCTTextSelection) -RCT_EXPORT_VIEW_PROPERTY(text, NSString) + +RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowView +RCT_EXPORT_SHADOW_PROPERTY(text, NSString) +RCT_EXPORT_SHADOW_PROPERTY(placeholder, NSString) +RCT_EXPORT_SHADOW_PROPERTY(onContentSizeChange, RCTBubblingEventBlock) + + +- (RCTShadowView *)shadowView { - NSNumber *reactTag = shadowView.reactTag; - NSEdgeInsets borderAsInsets = shadowView.borderAsInsets; - NSEdgeInsets paddingAsInsets = shadowView.paddingAsInsets; - return ^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RCTBaseTextInputView *view = viewRegistry[reactTag]; - view.reactBorderInsets = borderAsInsets; - view.reactPaddingInsets = paddingAsInsets; - }; + RCTBaseTextInputShadowView *shadowView = [[RCTBaseTextInputShadowView alloc] initWithBridge:self.bridge]; + shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; + [_shadowViews addObject:shadowView]; + return shadowView; +} + +- (void)setBridge:(RCTBridge *)bridge +{ + [super setBridge:bridge]; + + _shadowViews = [NSHashTable weakObjectsHashTable]; + + [bridge.uiManager.observerCoordinator addObserver:self]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleDidUpdateMultiplierNotification) + name:RCTAccessibilityManagerDidUpdateMultiplierNotification + object:bridge.accessibilityManager]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - RCTUIManagerObserver + +- (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager +{ + for (RCTBaseTextInputShadowView *shadowView in _shadowViews) { + [shadowView uiManagerWillPerformMounting]; + } +} + +#pragma mark - Font Size Multiplier + +- (void)handleDidUpdateMultiplierNotification +{ + CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; + + for (RCTBaseTextInputShadowView *shadowView in _shadowViews) { + shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; + [shadowView dirtyLayout]; + } + + [self.bridge.uiManager setNeedsLayout]; } @end diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.h b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.h index 7e3e89072c..5338e0c630 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.h +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.h @@ -7,18 +7,12 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import - -#import -#import - #import "RCTBaseTextInputView.h" -@class RCTUITextField; +NS_ASSUME_NONNULL_BEGIN @interface RCTSinglelineTextInputView : RCTBaseTextInputView -@property (nonatomic, assign) BOOL caretHidden; -@property (nonatomic, strong) NSNumber *maxLength; - @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m index 1300b441f3..4f4959b636 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m @@ -10,133 +10,36 @@ #import "RCTSinglelineTextInputView.h" #import -#import -#import -#import -#import -#import -#import -#import "RCTBackedTextInputDelegate.h" -#import "RCTTextSelection.h" #import "RCTUITextField.h" -@interface RCTSinglelineTextInputView () - -@end - @implementation RCTSinglelineTextInputView { - RCTUITextField *_backedTextInput; - BOOL _submitted; - CGSize _previousContentSize; + RCTUITextField *_backedTextInputView; } - (instancetype)initWithBridge:(RCTBridge *)bridge { if (self = [super initWithBridge:bridge]) { // `blurOnSubmit` defaults to `true` for by design. - _blurOnSubmit = YES; + self.blurOnSubmit = YES; - _backedTextInput = [[RCTUITextField alloc] initWithFrame:self.bounds]; - _backedTextInput.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - _backedTextInput.textInputDelegate = self; - _backedTextInput.font = self.fontAttributes.font; + _backedTextInputView = [[RCTUITextField alloc] initWithFrame:self.bounds]; + _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _backedTextInputView.textInputDelegate = self; - [self addSubview:_backedTextInput]; + [self addSubview:_backedTextInputView]; } return self; } RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) -RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) +RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)coder) - (id)backedTextInputView { - return _backedTextInput; -} - -- (void)sendKeyValueForString:(NSString *)string -{ - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeKeyPress - reactTag:self.reactTag - text:nil - key:string - eventCount:_nativeEventCount]; -} - -#pragma mark - Properties - -- (NSString *)text -{ - return _backedTextInput.text; -} - -- (void)setText:(NSString *)text -{ - NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; - if (eventLag == 0 && ![text isEqualToString:self.text]) { - UITextRange *selection = _backedTextInput.selectedTextRange; - NSInteger oldTextLength = _backedTextInput.text.length; - - _backedTextInput.text = text; - - if (selection.empty) { - // maintain cursor position relative to the end of the old text - NSInteger offsetStart = [_backedTextInput offsetFromPosition:_backedTextInput.beginningOfDocument toPosition:selection.start]; - NSInteger offsetFromEnd = oldTextLength - offsetStart; - NSInteger newOffset = text.length - offsetFromEnd; - UITextPosition *position = [_backedTextInput positionFromPosition:_backedTextInput.beginningOfDocument offset:newOffset]; - [_backedTextInput setSelectedTextRange:[_backedTextInput textRangeFromPosition:position toPosition:position] - notifyDelegate:YES]; - } - } else if (eventLag > RCTTextUpdateLagWarningThreshold) { - RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", _backedTextInput.text, (long long)eventLag); - } -} - -#pragma mark - RCTBackedTextInputDelegate - -- (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string -{ - // Only allow single keypresses for `onKeyPress`, pasted text will not be sent. - if (!_backedTextInput.textWasPasted) { - [self sendKeyValueForString:string]; - } - - if (_maxLength != nil && ![string isEqualToString:@"\n"]) { // Make sure forms can be submitted via return. - NSUInteger allowedLength = _maxLength.integerValue - MIN(_maxLength.integerValue, _backedTextInput.text.length) + range.length; - if (string.length > allowedLength) { - if (string.length > 1) { - // Truncate the input string so the result is exactly `maxLength`. - NSString *limitedString = [string substringToIndex:allowedLength]; - NSMutableString *newString = _backedTextInput.text.mutableCopy; - [newString replaceCharactersInRange:range withString:limitedString]; - _backedTextInput.text = newString; - - // Collapse selection at end of insert to match normal paste behavior. - UITextPosition *insertEnd = [_backedTextInput positionFromPosition:_backedTextInput.beginningOfDocument - offset:(range.location + allowedLength)]; - [_backedTextInput setSelectedTextRange:[_backedTextInput textRangeFromPosition:insertEnd toPosition:insertEnd] - notifyDelegate:YES]; - [self textInputDidChange]; - } - return NO; - } - } - - return YES; -} - -- (void)textInputDidChange -{ - _nativeEventCount++; - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange - reactTag:self.reactTag - text:_backedTextInput.text - key:nil - eventCount:_nativeEventCount]; + return _backedTextInputView; } @end diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.h b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.h index 90f5fbda24..57439e6bf3 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.h +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.h @@ -9,6 +9,10 @@ #import "RCTBaseTextInputViewManager.h" +NS_ASSUME_NONNULL_BEGIN + @interface RCTSinglelineTextInputViewManager : RCTBaseTextInputViewManager @end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m index 36d424c965..6a74da53c9 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m @@ -9,15 +9,8 @@ #import "RCTSinglelineTextInputViewManager.h" -#import -#import -#import -#import - -#import "RCTConvert+Text.h" -#import "RCTSinglelineTextInputShadowView.h" +#import "RCTBaseTextInputShadowView.h" #import "RCTSinglelineTextInputView.h" -#import "RCTUITextField.h" @implementation RCTSinglelineTextInputViewManager @@ -25,18 +18,17 @@ @implementation RCTSinglelineTextInputViewManager - (RCTShadowView *)shadowView { - return [RCTSinglelineTextInputShadowView new]; + RCTBaseTextInputShadowView *shadowView = + (RCTBaseTextInputShadowView *)[super shadowView]; + + shadowView.maximumNumberOfLines = 1; + + return shadowView; } -- (NSView *)view +- (UIView *)view { return [[RCTSinglelineTextInputView alloc] initWithBridge:self.bridge]; } -#pragma mark - Singleline (aka TextField) specific properties - -RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) -RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) -RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) - @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index 686bb6c543..27ae073006 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN /* * Just regular UITextField... but much better! */ -@interface RCTUITextField : NSTextField +@interface RCTUITextField : UITextField - (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; @@ -24,9 +24,9 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) BOOL caretHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) NSColor *placeholderColor; -@property (nonatomic, assign) NSEdgeInsets textContainerInset; +@property (nonatomic, strong, nullable) UIColor *placeholderColor; +@property (nonatomic, assign) UIEdgeInsets textContainerInset; +@property (nonatomic, assign, getter=isEditable) BOOL editable; @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 7247b73491..4b21e594b1 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -10,7 +10,7 @@ #import "RCTUITextField.h" #import -#import +#import #import "RCTBackedTextInputDelegateAdapter.h" @@ -21,6 +21,10 @@ @implementation RCTUITextField { - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_textDidChange) + name:UITextFieldTextDidChangeNotification + object:self]; _textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self]; } @@ -40,21 +44,19 @@ - (void)_textDidChange #pragma mark - Properties -- (void)setTextContainerInset:(NSEdgeInsets)textContainerInset +- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset { _textContainerInset = textContainerInset; - [self setNeedsLayout:YES]; + [self setNeedsLayout]; } - (void)setPlaceholder:(NSString *)placeholder { - if (placeholder != nil && ![_placeholder isEqual:placeholder]) { - _placeholder = placeholder; - [self updatePlaceholder]; - } + [super setPlaceholder:placeholder]; + [self _updatePlaceholder]; } -- (void)setPlaceholderColor:(NSColor *)placeholderColor +- (void)setPlaceholderColor:(UIColor *)placeholderColor { _placeholderColor = placeholderColor; [self _updatePlaceholder]; @@ -70,10 +72,8 @@ - (void)_updatePlaceholder if (_placeholderColor) { [attributes setObject:_placeholderColor forKey:NSForegroundColorAttributeName]; } - - - self.placeholderAttributedString = [[NSAttributedString alloc] initWithString:self.placeholder + self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attributes]; } @@ -89,44 +89,36 @@ - (void)setEditable:(BOOL)editable #pragma mark - Caret Manipulation -//- (CGRect)caretRectForPosition:(UITextPosition *)position -//{ -// if (_caretHidden) { -// return CGRectZero; -// } -// -// return [super caretRectForPosition:position]; -//} +- (CGRect)caretRectForPosition:(UITextPosition *)position +{ + if (_caretHidden) { + return CGRectZero; + } + + return [super caretRectForPosition:position]; +} #pragma mark - Positioning Overrides -static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { - rect.origin.x += insets.left; - rect.origin.y += insets.top; - rect.size.width -= (insets.left + insets.right); - rect.size.height -= (insets.top + insets.bottom); - return rect; +- (CGRect)textRectForBounds:(CGRect)bounds +{ + return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); } -//- (CGRect)textRectForBounds:(CGRect)bounds -//{ -// return NSEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); -//} - -//- (CGRect)editingRectForBounds:(CGRect)bounds -//{ -// return [self textRectForBounds:bounds]; -//} +- (CGRect)editingRectForBounds:(CGRect)bounds +{ + return [self textRectForBounds:bounds]; +} #pragma mark - Overrides -- (void)setSelectedTextRange:(NSRange)selectedTextRange +- (void)setSelectedTextRange:(UITextRange *)selectedTextRange { - [[super currentEditor] setSelectedRange:selectedTextRange]; + [super setSelectedTextRange:selectedTextRange]; [_textInputDelegateAdapter selectedTextRangeWasSet]; } -- (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate +- (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) { // We have to notify an adapter that following selection change was initiated programmatically, @@ -134,12 +126,12 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not [_textInputDelegateAdapter skipNextTextInputDidChangeSelectionEventWithTextRange:selectedTextRange]; } - [[super currentEditor] setSelectedRange:selectedTextRange]; + [super setSelectedTextRange:selectedTextRange]; } - (void)paste:(id)sender { - [[super currentEditor] paste:sender]; + [super paste:sender]; _textWasPasted = YES; } diff --git a/Libraries/Text/VirtualText/RCTVirtualTextShadowView.h b/Libraries/Text/VirtualText/RCTVirtualTextShadowView.h new file mode 100644 index 0000000000..ae5d158b0e --- /dev/null +++ b/Libraries/Text/VirtualText/RCTVirtualTextShadowView.h @@ -0,0 +1,14 @@ +/** + * 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 "RCTBaseTextShadowView.h" + +@interface RCTVirtualTextShadowView : RCTBaseTextShadowView + +@end diff --git a/Libraries/Text/VirtualText/RCTVirtualTextShadowView.m b/Libraries/Text/VirtualText/RCTVirtualTextShadowView.m new file mode 100644 index 0000000000..b5710f13c0 --- /dev/null +++ b/Libraries/Text/VirtualText/RCTVirtualTextShadowView.m @@ -0,0 +1,75 @@ +/** + * 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 "RCTVirtualTextShadowView.h" + +#import +#import + +#import "RCTRawTextShadowView.h" + +@implementation RCTVirtualTextShadowView { + BOOL _isLayoutDirty; +} + +#pragma mark - Life Cycle + +- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)index +{ + [super insertReactSubview:subview atIndex:index]; + + [self dirtyLayout]; + + if (![subview isKindOfClass:[RCTVirtualTextShadowView class]]) { + YGNodeSetDirtiedFunc(subview.yogaNode, RCTVirtualTextShadowViewYogaNodeDirtied); + } + +} + +- (void)removeReactSubview:(RCTShadowView *)subview +{ + if (![subview isKindOfClass:[RCTVirtualTextShadowView class]]) { + YGNodeSetDirtiedFunc(subview.yogaNode, NULL); + } + + [self dirtyLayout]; + + [super removeReactSubview:subview]; +} + +#pragma mark - Layout + +- (void)dirtyLayout +{ + [super dirtyLayout]; + + if (_isLayoutDirty) { + return; + } + _isLayoutDirty = YES; + + [self.superview dirtyLayout]; +} + +- (void)clearLayout +{ + _isLayoutDirty = NO; +} + +static void RCTVirtualTextShadowViewYogaNodeDirtied(YGNodeRef node) +{ + RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node); + + RCTVirtualTextShadowView *virtualTextShadowView = + (RCTVirtualTextShadowView *)shadowView.reactSuperview; + + [virtualTextShadowView dirtyLayout]; +} + +@end diff --git a/Libraries/Text/VirtualText/RCTVirtualTextViewManager.h b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.h new file mode 100644 index 0000000000..b7225dbb51 --- /dev/null +++ b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.h @@ -0,0 +1,14 @@ +/** + * 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 "RCTBaseTextViewManager.h" + +@interface RCTVirtualTextViewManager : RCTBaseTextViewManager + +@end diff --git a/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m new file mode 100644 index 0000000000..64cf161720 --- /dev/null +++ b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m @@ -0,0 +1,28 @@ +/** + * 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 "RCTVirtualTextViewManager.h" + +#import "RCTVirtualTextShadowView.h" + +@implementation RCTVirtualTextViewManager + +RCT_EXPORT_MODULE(RCTVirtualText) + +- (UIView *)view +{ + return [UIView new]; +} + +- (RCTShadowView *)shadowView +{ + return [RCTVirtualTextShadowView new]; +} + +@end diff --git a/React/Modules/RCTAccessibilityManager.m b/React/Modules/RCTAccessibilityManager.m index 2caba67225..9c81c9351d 100644 --- a/React/Modules/RCTAccessibilityManager.m +++ b/React/Modules/RCTAccessibilityManager.m @@ -59,7 +59,8 @@ + (BOOL)requiresMainQueueSetup - (instancetype)init { - if ((self = [super init])) { + if (self = [super init]) { + _multiplier = 1.0; // TODO: can this be moved out of the startup path? [[NSNotificationCenter defaultCenter] addObserver:self diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 8c2d419943..e496eeea10 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -511,23 +511,12 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * } } - // These are blocks to be executed on each view, immediately after - // reactSetFrame: has been called. Note that if reactSetFrame: is not called, - // these won't be called either, so this is not a suitable place to update - // properties that aren't related to layout. - NSMutableDictionary *updateBlocks = - [NSMutableDictionary new]; for (RCTShadowView *shadowView in viewsWithNewFrames) { // We have to do this after we build the parentsAreNew array. shadowView.newView = NO; NSNumber *reactTag = shadowView.reactTag; - RCTViewManager *manager = [_componentDataByName[shadowView.viewName] manager]; - RCTViewManagerUIBlock block = [manager uiBlockToAmendWithShadowView:shadowView]; - if (block) { - updateBlocks[reactTag] = block; - } if (shadowView.onLayout) { CGRect frame = shadowView.frame; @@ -600,7 +589,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * view.reactLayoutDirection = layoutDirection; } - RCTViewManagerUIBlock updateBlock = updateBlocks[reactTag]; if (creatingLayoutAnimation) { // Animate view creation @@ -625,31 +613,19 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * } else if ([property isEqualToString:@"opacity"]) { view.layer.opacity = finalOpacity; } - if (updateBlock) { - updateBlock(self, viewRegistry); - } } withCompletionBlock:completion]; } else if (updatingLayoutAnimation) { // Animate view update [updatingLayoutAnimation performAnimations:^{ - [[view animator] setFrame:frame]; [view reactSetFrame:frame]; - if (updateBlock) { - updateBlock(self, viewRegistry); - } } withCompletionBlock:completion]; } else { - // Workaround for https://github.com/ptmt/react-native-macos/issues/47 - // Need to speedup layout or make a cancelling mechanism - if (!view.isReactRootView) { - [view reactSetFrame:frame]; - } - if (updateBlock) { - updateBlock(self, viewRegistry); - } + + // Update without animation + [view reactSetFrame:frame]; completion(YES); } } @@ -659,20 +635,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * }; } -- (void)_amendPendingUIBlocksWithStylePropagationUpdateForShadowView:(RCTShadowView *)topView -{ - NSMutableSet *applierBlocks = [NSMutableSet setWithCapacity:1]; - [topView collectUpdatedProperties:applierBlocks parentProperties:@{}]; - - if (applierBlocks.count) { - [self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - for (RCTApplierBlock block in applierBlocks) { - block(viewRegistry); - } - }]; - } -} - /** * A method to be called from JS, which takes a container ID and then releases * all subviews for that container upon receipt. @@ -1075,13 +1037,6 @@ - (void)batchDidComplete */ - (void)_layoutAndMount { - // Gather blocks to be executed now that all view hierarchy manipulations have - // been completed (note that these may still take place before layout has finished) - for (RCTComponentData *componentData in _componentDataByName.allValues) { - RCTViewManagerUIBlock uiBlock = [componentData uiBlockToAmendWithShadowViewRegistry:_shadowViewRegistry]; - [self addUIBlock:uiBlock]; - } - [self _dispatchPropsDidChangeEvents]; [self _dispatchChildrenDidChangeEvents]; @@ -1095,12 +1050,6 @@ - (void)_layoutAndMount [_observerCoordinator uiManagerDidPerformLayout:self]; - // Properies propagation - for (NSNumber *reactTag in _rootViewTags) { - RCTRootShadowView *rootView = (RCTRootShadowView *)_shadowViewRegistry[reactTag]; - [self _amendPendingUIBlocksWithStylePropagationUpdateForShadowView:rootView]; - } - [_observerCoordinator uiManagerWillPerformMounting:self]; [self flushUIBlocksWithCompletion:^{ diff --git a/React/Views/RCTComponentData.h b/React/Views/RCTComponentData.h index b4264472d8..946e28da3d 100644 --- a/React/Views/RCTComponentData.h +++ b/React/Views/RCTComponentData.h @@ -34,6 +34,4 @@ - (NSDictionary *)viewConfig; -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary *)registry; - @end diff --git a/React/Views/RCTComponentData.m b/React/Views/RCTComponentData.m index 06038b9416..3c3d547791 100644 --- a/React/Views/RCTComponentData.m +++ b/React/Views/RCTComponentData.m @@ -40,7 +40,6 @@ @implementation RCTComponentData id _defaultView; // Only needed for RCT_CUSTOM_VIEW_PROPERTY RCTPropBlockDictionary *_viewPropBlocks; RCTPropBlockDictionary *_shadowPropBlocks; - BOOL _implementsUIBlockToAmendWithShadowViewRegistry; __weak RCTBridge *_bridge; } @@ -56,14 +55,6 @@ - (instancetype)initWithManagerClass:(Class)managerClass _shadowPropBlocks = [NSMutableDictionary new]; _name = moduleNameForClass(managerClass); - - _implementsUIBlockToAmendWithShadowViewRegistry = NO; - Class cls = _managerClass; - while (cls != [RCTViewManager class]) { - _implementsUIBlockToAmendWithShadowViewRegistry = _implementsUIBlockToAmendWithShadowViewRegistry || - RCTClassOverridesInstanceMethod(cls, @selector(uiBlockToAmendWithShadowViewRegistry:)); - cls = [cls superclass]; - } } return self; } @@ -439,14 +430,6 @@ - (void)setProps:(NSDictionary *)props forShadowView:(RCTShadowV }; } -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary *)registry -{ - if (_implementsUIBlockToAmendWithShadowViewRegistry) { - return [[self manager] uiBlockToAmendWithShadowViewRegistry:registry]; - } - return nil; -} - static NSString *moduleNameForClass(Class managerClass) { // Hackety hack, this partially re-implements RCTBridgeModuleNameForClass diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index d435076b42..364595f9f1 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -225,6 +225,11 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER; +- (void)applyLayoutWithFrame:(CGRect)frame + layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout + absolutePosition:(CGPoint)absolutePosition; + /** * Enumerate the child nodes and tell them to apply layout. */ @@ -252,13 +257,6 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ - (BOOL)isYogaLeafNode; -- (void)dirtyPropagation NS_REQUIRES_SUPER; -- (BOOL)isPropagationDirty; - -- (void)dirtyText NS_REQUIRES_SUPER; -- (void)setTextComputed NS_REQUIRES_SUPER; -- (BOOL)isTextDirty; - /** * As described in RCTComponent protocol. */ diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 83a03d8ae0..6392acce96 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -213,38 +213,53 @@ - (void)applyLayoutNode:(YGNodeRef)node } #endif + CGRect frame = CGRectMake(YGNodeLayoutGetLeft(node), YGNodeLayoutGetTop(node), YGNodeLayoutGetWidth(node), YGNodeLayoutGetHeight(node)); + + // Even if `YGNodeLayoutGetDirection` can return `YGDirectionInherit` here, it actually means + // that Yoga will use LTR layout for the view (even if layout process is not finished yet). + UIUserInterfaceLayoutDirection layoutDirection = YGNodeLayoutGetDirection(_yogaNode) == YGDirectionRTL ? UIUserInterfaceLayoutDirectionRightToLeft : UIUserInterfaceLayoutDirectionLeftToRight; + + [self applyLayoutWithFrame:frame + layoutDirection:layoutDirection + viewsWithUpdatedLayout:viewsWithNewFrame + absolutePosition:absolutePosition]; +} + +- (void)applyLayoutWithFrame:(CGRect)frame + layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout + absolutePosition:(CGPoint)absolutePosition +{ CGPoint absoluteTopLeft = { - absolutePosition.x + YGNodeLayoutGetLeft(node), - absolutePosition.y + YGNodeLayoutGetTop(node) + absolutePosition.x + frame.origin.x, + absolutePosition.y + frame.origin.y }; CGPoint absoluteBottomRight = { - absolutePosition.x + YGNodeLayoutGetLeft(node) + YGNodeLayoutGetWidth(node), - absolutePosition.y + YGNodeLayoutGetTop(node) + YGNodeLayoutGetHeight(node) + absolutePosition.x + frame.origin.x + frame.size.width, + absolutePosition.y + frame.origin.y + frame.size.height }; - CGRect frame = {{ - RCTRoundPixelValue(YGNodeLayoutGetLeft(node)), - RCTRoundPixelValue(YGNodeLayoutGetTop(node)), + CGRect roundedFrame = {{ + RCTRoundPixelValue(frame.origin.x), + RCTRoundPixelValue(frame.origin.y), }, { RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x), RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y) }}; - // Even if `YGNodeLayoutGetDirection` can return `YGDirectionInherit` here, it actually means - // that Yoga will use LTR layout for the view (even if layout process is not finished yet). - NSUserInterfaceLayoutDirection updatedLayoutDirection = YGNodeLayoutGetDirection(_yogaNode) == YGDirectionRTL ? NSUserInterfaceLayoutDirectionRightToLeft : NSUserInterfaceLayoutDirectionLeftToRight; - - if (!CGRectEqualToRect(frame, _frame) || _layoutDirection != updatedLayoutDirection) { - _frame = frame; - _layoutDirection = updatedLayoutDirection; - [viewsWithNewFrame addObject:self]; + if (!CGRectEqualToRect(_frame, roundedFrame) || _layoutDirection != layoutDirection) { + _frame = roundedFrame; + _layoutDirection = layoutDirection; + [viewsWithUpdatedLayout addObject:self]; } - absolutePosition.x += YGNodeLayoutGetLeft(node); - absolutePosition.y += YGNodeLayoutGetTop(node); + absolutePosition.x += frame.origin.x; + absolutePosition.y += frame.origin.y; - [self applyLayoutToChildren:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; + [self applyLayoutToChildren:_yogaNode + viewsWithNewFrame:viewsWithUpdatedLayout + absolutePosition:absolutePosition]; } - (void)applyLayoutToChildren:(YGNodeRef)node @@ -381,37 +396,6 @@ - (BOOL)isYogaLeafNode return NO; } -- (void)dirtyPropagation -{ - if (_propagationLifecycle != RCTUpdateLifecycleDirtied) { - _propagationLifecycle = RCTUpdateLifecycleDirtied; - [_superview dirtyPropagation]; - } -} - -- (BOOL)isPropagationDirty -{ - return _propagationLifecycle != RCTUpdateLifecycleComputed; -} - -- (void)dirtyText -{ - if (_textLifecycle != RCTUpdateLifecycleDirtied) { - _textLifecycle = RCTUpdateLifecycleDirtied; - [_superview dirtyText]; - } -} - -- (BOOL)isTextDirty -{ - return _textLifecycle != RCTUpdateLifecycleComputed; -} - -- (void)setTextComputed -{ - _textLifecycle = RCTUpdateLifecycleComputed; -} - - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex { RCTAssert(self.canHaveSubviews, @"Attempt to insert subview inside leaf view."); @@ -421,14 +405,10 @@ - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex YGNodeInsertChild(_yogaNode, subview.yogaNode, (uint32_t)atIndex); } subview->_superview = self; - [self dirtyText]; - [self dirtyPropagation]; } - (void)removeReactSubview:(RCTShadowView *)subview { - [subview dirtyText]; - [subview dirtyPropagation]; subview->_superview = nil; [_reactSubviews removeObject:subview]; if (![self isYogaLeafNode]) { @@ -562,7 +542,6 @@ - (float)border##prop##Width \ - (void)set##setProp:(YGValue)value \ { \ RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \ - [self dirtyText]; \ } \ - (YGValue)getProp \ { \ @@ -573,7 +552,6 @@ - (YGValue)getProp \ - (void)set##setProp:(YGValue)value \ { \ RCT_SET_YGVALUE(value, YGNodeStyleSet##cssProp, _yogaNode); \ - [self dirtyText]; \ } \ - (YGValue)getProp \ { \ @@ -593,7 +571,6 @@ - (YGValue)getProp \ - (void)set##setProp:(YGValue)value \ { \ RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge); \ - [self dirtyText]; \ } \ - (YGValue)getProp \ { \ @@ -610,7 +587,6 @@ - (void)setLeft:(YGValue)value { YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeStart : YGEdgeLeft; RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge); - [self dirtyText]; } - (YGValue)left { @@ -622,7 +598,6 @@ - (void)setRight:(YGValue)value { YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeEnd : YGEdgeRight; RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge); - [self dirtyText]; } - (YGValue)right { diff --git a/React/Views/RCTViewManager.h b/React/Views/RCTViewManager.h index 23d50cd915..ffb772a19a 100644 --- a/React/Views/RCTViewManager.h +++ b/React/Views/RCTViewManager.h @@ -63,20 +63,6 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary *)customBubblingEventTypes __deprecated_msg("Use RCTBubblingEventBlock props instead."); -/** - * Called to notify manager that layout has finished, in case any calculated - * properties need to be copied over from shadow view to view. - */ -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowView; - -/** - * Called after view hierarchy manipulation has finished, and all shadow props - * have been set, but before layout has been performed. Useful for performing - * custom layout logic or tasks that involve walking the view hierarchy. - * To be deprecated, hopefully. - */ -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary *)shadowViewRegistry; - /** * This handles the simple case, where JS and native property names match. */ diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index fb08b2c267..8871f6a804 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -80,16 +80,6 @@ - (RCTShadowView *)shadowView ]; } -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(__unused RCTShadowView *)shadowView -{ - return nil; -} - -- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(__unused NSDictionary *)shadowViewRegistry -{ - return nil; -} - - (void)checkLayerExists:(NSView *)view { if (!view.layer) { From 2fe43c0c9f2f203bd631e8b7c7b7ae23659c7ddf Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 11 Jan 2018 19:00:27 -0800 Subject: [PATCH 047/143] Support for inherited events in view managers Summary: We currently support inherited view props but not event handlers, this diff fixes it. This change will allow to unify set of supported events for single- and multli-line s and avoid code duplication. Reviewed By: sahrens Differential Revision: D6690281 fbshipit-source-id: f142828bd7deae92fb306914b7cefd10da8b43f7 --- .../ReactNative/requireNativeComponent.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Libraries/ReactNative/requireNativeComponent.js b/Libraries/ReactNative/requireNativeComponent.js index c7ffc9fb17..ed7717f602 100644 --- a/Libraries/ReactNative/requireNativeComponent.js +++ b/Libraries/ReactNative/requireNativeComponent.js @@ -133,18 +133,34 @@ function requireNativeComponent( } let baseModuleName = viewConfig.baseModuleName; - let nativeProps = {...viewConfig.NativeProps}; + let bubblingEventTypes = viewConfig.bubblingEventTypes; + let directEventTypes = viewConfig.directEventTypes; + let nativeProps = viewConfig.NativeProps; while (baseModuleName) { const baseModule = UIManager[baseModuleName]; if (!baseModule) { warning(false, 'Base module "%s" does not exist', baseModuleName); baseModuleName = null; } else { - nativeProps = {...nativeProps, ...baseModule.NativeProps}; + bubblingEventTypes = { + ...baseModule.bubblingEventTypes, + ...bubblingEventTypes, + }; + directEventTypes = { + ...baseModule.directEventTypes, + ...directEventTypes, + }; + nativeProps = { + ...baseModule.NativeProps, + ...nativeProps, + }; baseModuleName = baseModule.baseModuleName; } } + viewConfig.bubblingEventTypes = bubblingEventTypes; + viewConfig.directEventTypes = directEventTypes; + for (const key in nativeProps) { let useAttribute = false; const attribute = {}; From d8d845437f3915dd0aeb9af3942e34082ee00bfd Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 25 Jan 2018 13:40:28 -0800 Subject: [PATCH 048/143] Proper attributed strings comparsion in RCTBaseTextInputView Summary: Now, in the new model, we transfer text attributes with actual text via attributed text to a native text component, so previous text-only comparsion is not sufficient anymore. Depends on D6600685. Differential Revision: D6809833 fbshipit-source-id: 475b7426cf3c6694781790d99ef32466606da2f2 --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 91f6a980f2..13b8150582 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -102,7 +102,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText { NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; - if (eventLag == 0 && ![attributedText.string isEqualToString:self.backedTextInputView.attributedText.string]) { + if (eventLag == 0 && ![attributedText isEqualToAttributedString:self.backedTextInputView.attributedText]) { UITextRange *selection = self.backedTextInputView.selectedTextRange; NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length; From 4270b54e2a84188394a01e59b6f4010e203fed86 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 25 Jan 2018 21:13:38 -0800 Subject: [PATCH 049/143] Fixed a bug when does not redraw native view on relayout Summary: `contentFrame` is now always provided by shadow thread (with attributed string and embedded views), so we have to update it on every single relayout. Reviewed By: yungsters Differential Revision: D6817401 fbshipit-source-id: c2a1f314f34a2187053eb11ce0744c935edbb8ae --- Libraries/Text/Text/RCTTextShadowView.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index 4f29f057b9..a6f75459e1 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -235,6 +235,21 @@ - (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size return textStorage; } +- (void)applyLayoutNode:(YGNodeRef)node + viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame + absolutePosition:(CGPoint)absolutePosition +{ + if (YGNodeGetHasNewLayout(self.yogaNode)) { + // If the view got new layout, we have to redraw it because `contentFrame` + // and sizes of embedded views may change. + _needsUpdateView = YES; + } + + [super applyLayoutNode:node + viewsWithNewFrame:viewsWithNewFrame + absolutePosition:absolutePosition]; +} + - (void)applyLayoutWithFrame:(CGRect)frame layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout From ab636b9fb429ce2743c1bc3cde2f786318cfc8db Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 29 Jan 2018 10:39:27 -0800 Subject: [PATCH 050/143] Removed outdated assertion in RCTShadowView related to breaking change in Yoga Summary: It's been more than two years; I think everyone already migrated and learned the new behavior. Reviewed By: emilsjolander Differential Revision: D6829885 fbshipit-source-id: a86d56fb7235a137e9ce6e360d7ae2224b047313 --- React/Views/RCTShadowView.m | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 6392acce96..ebdb728755 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -203,16 +203,6 @@ - (void)applyLayoutNode:(YGNodeRef)node return; } -#if RCT_DEBUG - // This works around a breaking change in Yoga layout where setting flexBasis needs to be set explicitly, instead of relying on flex to propagate. - // We check for it by seeing if a width/height is provided along with a flexBasis of 0 and the width/height is laid out as 0. - if (YGNodeStyleGetFlexBasis(node).unit == YGUnitPoint && YGNodeStyleGetFlexBasis(node).value == 0 && - ((YGNodeStyleGetWidth(node).unit == YGUnitPoint && YGNodeStyleGetWidth(node).value > 0 && YGNodeLayoutGetWidth(node) == 0) || - (YGNodeStyleGetHeight(node).unit == YGUnitPoint && YGNodeStyleGetHeight(node).value > 0 && YGNodeLayoutGetHeight(node) == 0))) { - RCTLogError(@"View was rendered with explicitly set width/height but with a 0 flexBasis. (This might be fixed by changing flex: to flexGrow:) View: %@", self); - } -#endif - CGRect frame = CGRectMake(YGNodeLayoutGetLeft(node), YGNodeLayoutGetTop(node), YGNodeLayoutGetWidth(node), YGNodeLayoutGetHeight(node)); // Even if `YGNodeLayoutGetDirection` can return `YGDirectionInherit` here, it actually means From eea0fa8c0022624b2ba0b136f27ebdb7ddeba34b Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 30 Jan 2018 14:26:25 -0800 Subject: [PATCH 051/143] Fixing clowntown in RCTSurfaceRootShadowView Summary: Obvious. Reviewed By: mmmulani Differential Revision: D6829844 fbshipit-source-id: 6c49be990fbcc3be2b5595866c3d1fd42a3eb3e9 --- React/Base/Surface/RCTSurfaceRootShadowView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/React/Base/Surface/RCTSurfaceRootShadowView.m b/React/Base/Surface/RCTSurfaceRootShadowView.m index 2c762fa658..bbd2b146a8 100644 --- a/React/Base/Surface/RCTSurfaceRootShadowView.m +++ b/React/Base/Surface/RCTSurfaceRootShadowView.m @@ -47,8 +47,8 @@ - (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)m { YGNodeRef yogaNode = self.yogaNode; - YGNodeStyleSetMinWidth(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximimSize.width)); - YGNodeStyleSetMinHeight(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximimSize.height)); + YGNodeStyleSetMinWidth(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width)); + YGNodeStyleSetMinHeight(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height)); YGNodeCalculateLayout( self.yogaNode, From 1e1cd5322cf0907c110536eaab5807b8a9f500dd Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 31 Jan 2018 15:03:25 -0800 Subject: [PATCH 052/143] Fixed typo in RCTSurfaceRootShadowView Summary: Trivial. Special thanks to janicduplessis Created from Diffusion's 'Open in Editor' feature. Reviewed By: fkgozali Differential Revision: D6863932 fbshipit-source-id: d40a30271adc5c8d47149ab920e2ac11158ab756 --- React/Base/Surface/RCTSurfaceRootShadowView.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/React/Base/Surface/RCTSurfaceRootShadowView.m b/React/Base/Surface/RCTSurfaceRootShadowView.m index bbd2b146a8..37a4c206ef 100644 --- a/React/Base/Surface/RCTSurfaceRootShadowView.m +++ b/React/Base/Surface/RCTSurfaceRootShadowView.m @@ -43,7 +43,7 @@ - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex } } -- (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximimSize +- (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize { YGNodeRef yogaNode = self.yogaNode; @@ -52,8 +52,8 @@ - (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)m YGNodeCalculateLayout( self.yogaNode, - RCTYogaFloatFromCoreGraphicsFloat(maximimSize.width), - RCTYogaFloatFromCoreGraphicsFloat(maximimSize.height), + RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width), + RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height), _baseDirection ); } From 0e6f724a1631d5f24de32f8a0b38ba0666fcb7f1 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 1 Feb 2018 14:00:12 -0800 Subject: [PATCH 053/143] Fixed double `onChange` event triggering from on iOS Summary: The problem was recently introduced in the last refactoring of the Text module. There are two problem actually: (1) Compare this current code with stable version. In the stable version the event is only triggered here: https://github.com/facebook/react-native/blob/0.52-stable/Libraries/Text/RCTTextField.m#L132-L140 In the new version the event is triggered in two places (which is obviously wrong). (2) Executing `[_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange:...]` and _onChange() actually do the same thing. Historically, the single-line used the first approach and multi-line used second one. When we unify the logic, mixed both of them, which was apparenly wrong. So, we have to remove another call of `[_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange:...]`. The the future we have to completly remove usage of `_eventDispatcher` from this component. Depends on D6854770. Reviewed By: fkgozali Differential Revision: D6869678 fbshipit-source-id: 6705ee8dda2681ae184ef6716238cc8b62efeff1 --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 13b8150582..177b4afccd 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -286,12 +286,6 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin }); } - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange - reactTag:self.reactTag - text:backedTextInputView.attributedText.string - key:nil - eventCount:_nativeEventCount]; - return YES; } @@ -324,12 +318,6 @@ - (void)textInputDidChange @"eventCount": @(_nativeEventCount), }); } - - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange - reactTag:self.reactTag - text:backedTextInputView.attributedText.string - key:nil - eventCount:_nativeEventCount]; } - (void)textInputDidChangeSelection From 9cc7f95a0bd0930b349834d75b0357d6fba52631 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 5 Feb 2018 22:15:35 -0800 Subject: [PATCH 054/143] `[RCTShadowView isHidden]` was removed Summary: It's unused. Use `display` prop instead to control visiblity of the view. Reviewed By: fkgozali Differential Revision: D6888104 fbshipit-source-id: dd37a365033ec36bdfcfa305ec6a965a10dec2cd --- React/Modules/RCTUIManager.m | 7 ------- React/Views/RCTShadowView.h | 6 ------ 2 files changed, 13 deletions(-) diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index e496eeea10..bd7ac63701 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -489,7 +489,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * NSUserInterfaceLayoutDirection layoutDirection; BOOL isNew; BOOL parentIsNew; - BOOL isHidden; } RCTFrameData; // Construct arrays then hand off to main thread @@ -506,7 +505,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * shadowView.layoutDirection, shadowView.isNewView, shadowView.superview.isNewView, - shadowView.isHidden, }; } } @@ -563,7 +561,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * NSView *view = viewRegistry[reactTag]; CGRect frame = frameData.frame; - BOOL isHidden = frameData.isHidden; NSUserInterfaceLayoutDirection layoutDirection = frameData.layoutDirection; BOOL isNew = frameData.isNew; RCTLayoutAnimation *updatingLayoutAnimation = isNew ? nil : layoutAnimationGroup.updatingLayoutAnimation; @@ -581,10 +578,6 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * } }; - if (view.isHidden != isHidden) { - view.hidden = isHidden; - } - if (view.reactLayoutDirection != layoutDirection) { view.reactLayoutDirection = layoutDirection; } diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index 364595f9f1..ae18ceeb7b 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -76,12 +76,6 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ @property (nonatomic, assign, getter=isNewView) BOOL newView; -/** - * isHidden - RCTUIManager uses this to determine whether or not the UIView should be hidden. Useful if the - * ShadowView determines that its UIView will be clipped and wants to hide it. - */ -@property (nonatomic, assign, getter=isHidden) BOOL hidden; - /** * Computed layout direction of the view. */ From 6331503b7be9a2b5f562a2bd99cc8f6353852a34 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 5 Feb 2018 22:15:29 -0800 Subject: [PATCH 055/143] `processUpdatedProperties` & `collectUpdatedProperties` was removed from RCTShadowView Summary: This is leftovers from last reimplementation; nobody uses it and it does not hooked up with UIManager. Reviewed By: fkgozali Differential Revision: D6887795 fbshipit-source-id: 9e2e29af4ba959270096eeb494666d1cacaeba32 --- React/Views/RCTShadowView.h | 21 --------------------- React/Views/RCTShadowView.m | 24 ------------------------ 2 files changed, 45 deletions(-) diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index ae18ceeb7b..a9faf325c8 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -16,12 +16,6 @@ @class RCTRootShadowView; @class RCTSparseArray; -typedef NS_ENUM(NSUInteger, RCTUpdateLifecycle) { - RCTUpdateLifecycleUninitialized = 0, - RCTUpdateLifecycleComputed, - RCTUpdateLifecycleDirtied, -}; - typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry); /** @@ -183,21 +177,6 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ @property (nonatomic, assign) CGSize intrinsicContentSize; -/** - * Calculate property changes that need to be propagated to the view. - * The applierBlocks set contains RCTApplierBlock functions that must be applied - * on the main thread in order to update the view. - */ -- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks - parentProperties:(NSDictionary *)parentProperties; - -/** - * Process the updated properties and apply them to view. Shadow view classes - * that add additional propagating properties should override this method. - */ -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks - parentProperties:(NSDictionary *)parentProperties NS_REQUIRES_SUPER; - /** * Can be called by a parent on a child in order to calculate all views whose frame needs * updating in that branch. Adds these frames to `viewsWithNewFrame`. Useful if layout diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index ebdb728755..297094210f 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -34,8 +34,6 @@ typedef NS_ENUM(unsigned int, meta_prop_t) { @implementation RCTShadowView { - RCTUpdateLifecycle _propagationLifecycle; - RCTUpdateLifecycle _textLifecycle; NSDictionary *_lastParentProperties; NSMutableArray *_reactSubviews; BOOL _recomputePadding; @@ -264,26 +262,6 @@ - (void)applyLayoutToChildren:(YGNodeRef)node } } -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks - parentProperties:(NSDictionary *)parentProperties -{ - return parentProperties; -} - -- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks - parentProperties:(NSDictionary *)parentProperties -{ - if (_propagationLifecycle == RCTUpdateLifecycleComputed && [parentProperties isEqualToDictionary:_lastParentProperties]) { - return; - } - _propagationLifecycle = RCTUpdateLifecycleComputed; - _lastParentProperties = parentProperties; - NSDictionary *nextProps = [self processUpdatedProperties:applierBlocks parentProperties:parentProperties]; - for (RCTShadowView *child in _reactSubviews) { - [child collectUpdatedProperties:applierBlocks parentProperties:nextProps]; - } -} - - (void)collectUpdatedFrames:(NSMutableSet *)viewsWithNewFrame withFrame:(CGRect)frame hidden:(BOOL)hidden @@ -354,8 +332,6 @@ - (instancetype)init _intrinsicContentSize = CGSizeMake(NSViewNoIntrinsicMetric, NSViewNoIntrinsicMetric); _newView = YES; - _propagationLifecycle = RCTUpdateLifecycleUninitialized; - _textLifecycle = RCTUpdateLifecycleUninitialized; _reactSubviews = [NSMutableArray array]; From b3b11ed91ab3550807f194b2c1fb0e16aa2b8ba1 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 5 Feb 2018 22:15:32 -0800 Subject: [PATCH 056/143] Removed `[ShadowView collectUpdatedFrames:]` Summary: Another juicy leftover from old Text implementation. Reviewed By: fkgozali Differential Revision: D6887942 fbshipit-source-id: d0363d06d566554c03d0ae3293597daf9c387028 --- React/Views/RCTShadowView.h | 11 ----------- React/Views/RCTShadowView.m | 28 ---------------------------- 2 files changed, 39 deletions(-) diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index a9faf325c8..550bfda56b 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -177,17 +177,6 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ @property (nonatomic, assign) CGSize intrinsicContentSize; -/** - * Can be called by a parent on a child in order to calculate all views whose frame needs - * updating in that branch. Adds these frames to `viewsWithNewFrame`. Useful if layout - * enters a view where flex doesn't apply (e.g. Text) and then you want to resume flex - * layout on a subview. - */ -- (void)collectUpdatedFrames:(NSMutableSet *)viewsWithNewFrame - withFrame:(CGRect)frame - hidden:(BOOL)hidden - absolutePosition:(CGPoint)absolutePosition; - /** * Apply the CSS layout. * This method also calls `applyLayoutToChildren:` internally. The functionality diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 297094210f..21665f1243 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -262,34 +262,6 @@ - (void)applyLayoutToChildren:(YGNodeRef)node } } -- (void)collectUpdatedFrames:(NSMutableSet *)viewsWithNewFrame - withFrame:(CGRect)frame - hidden:(BOOL)hidden - absolutePosition:(CGPoint)absolutePosition -{ - // This is not the core layout method. It is only used by RCTTextShadowView to layout - // nested views. - - if (_hidden != hidden) { - // The hidden state has changed. Even if the frame hasn't changed, add - // this ShadowView to viewsWithNewFrame so the UIManager will process - // this ShadowView's UIView and update its hidden state. - _hidden = hidden; - [viewsWithNewFrame addObject:self]; - } - - if (!CGRectEqualToRect(frame, _frame)) { - YGNodeStyleSetPositionType(_yogaNode, YGPositionTypeAbsolute); - YGNodeStyleSetWidth(_yogaNode, frame.size.width); - YGNodeStyleSetHeight(_yogaNode, frame.size.height); - YGNodeStyleSetPosition(_yogaNode, YGEdgeLeft, frame.origin.x); - YGNodeStyleSetPosition(_yogaNode, YGEdgeTop, frame.origin.y); - } - - YGNodeCalculateLayout(_yogaNode, frame.size.width, frame.size.height, YGDirectionInherit); - [self applyLayoutNode:_yogaNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; -} - - (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor { CGPoint offset = CGPointZero; From 77c916e01484c1c5fe118431c9addc9d793d1f53 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 5 Feb 2018 22:15:37 -0800 Subject: [PATCH 057/143] Removing our own implementation of round-to-pixel algorithm Summary: > Okay, I don't remember where we first met > But hey, admitting is the first step This issue has a looong history. The original algorithm was introduced by Nick Lockwood (nicklockwood Hey Nick! We miss you!) a while ago and from the very beginning this has one small error that basically makes it useless (try to find it yourself, it's fun!) The problem was discovered and fixed twice (D4133643, D4983054), but every time we found that our infra was not ready for this, so we reverted and abandoned the change. As part of the last attempt to finally solve the issue, I ported the algorithm to Yoga where it lives today and works very well for Lytho and CK. For now, the vision is clear: * The basic algorithm should live in Yoga for unification and performance reasons. * We still have to have `absolutePostion` as part of this API because it might be useful for some components which implement its own custom/non-Yoga-based layout. * We have to enable it in RN eventually. So, this is the first step: Removing old, broken code which we don't plan to fix and use. Make React Native crisp again! Reviewed By: fkgozali Differential Revision: D6888662 fbshipit-source-id: 2e5098d9935dcbe05d66c777dad3a9ec8ac87ec3 --- React/Views/RCTShadowView.m | 51 ++----------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 21665f1243..b6ca0485b9 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -154,35 +154,6 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT], YGNodeStyleSetBorder(node, YGEdgeAll, metaProps[META_PROP_ALL].value); } -// The absolute stuff is so that we can take into account our absolute position when rounding in order to -// snap to the pixel grid. For example, say you have the following structure: -// -// +--------+---------+--------+ -// | |+-------+| | -// | || || | -// | |+-------+| | -// +--------+---------+--------+ -// -// Say the screen width is 320 pts so the three big views will get the following x bounds from our layout system: -// {0, 106.667}, {106.667, 213.333}, {213.333, 320} -// -// Assuming screen scale is 2, these numbers must be rounded to the nearest 0.5 to fit the pixel grid: -// {0, 106.5}, {106.5, 213.5}, {213.5, 320} -// You'll notice that the three widths are 106.5, 107, 106.5. -// -// This is great for the parent views but it gets trickier when we consider rounding for the subview. -// -// When we go to round the bounds for the subview in the middle, it's relative bounds are {0, 106.667} -// which gets rounded to {0, 106.5}. This will cause the subview to be one pixel smaller than it should be. -// this is why we need to pass in the absolute position in order to do the rounding relative to the screen's -// grid rather than the view's grid. -// -// After passing in the absolutePosition of {106.667, y}, we do the following calculations: -// absoluteLeft = round(absolutePosition.x + viewPosition.left) = round(106.667 + 0) = 106.5 -// absoluteRight = round(absolutePosition.x + viewPosition.left + viewSize.left) + round(106.667 + 0 + 106.667) = 213.5 -// width = 213.5 - 106.5 = 107 -// You'll notice that this is the same width we calculated for the parent view because we've taken its position into account. - - (void)applyLayoutNode:(YGNodeRef)node viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame absolutePosition:(CGPoint)absolutePosition @@ -218,26 +189,8 @@ - (void)applyLayoutWithFrame:(CGRect)frame viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout absolutePosition:(CGPoint)absolutePosition { - CGPoint absoluteTopLeft = { - absolutePosition.x + frame.origin.x, - absolutePosition.y + frame.origin.y - }; - - CGPoint absoluteBottomRight = { - absolutePosition.x + frame.origin.x + frame.size.width, - absolutePosition.y + frame.origin.y + frame.size.height - }; - - CGRect roundedFrame = {{ - RCTRoundPixelValue(frame.origin.x), - RCTRoundPixelValue(frame.origin.y), - }, { - RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x), - RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y) - }}; - - if (!CGRectEqualToRect(_frame, roundedFrame) || _layoutDirection != layoutDirection) { - _frame = roundedFrame; + if (!CGRectEqualToRect(_frame, frame) || _layoutDirection != layoutDirection) { + _frame = frame; _layoutDirection = layoutDirection; [viewsWithUpdatedLayout addObject:self]; } From 258309e39232e28924e2e3aa762b6606de4e3f10 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 5 Feb 2018 22:15:41 -0800 Subject: [PATCH 058/143] Enabling round-to-pixel Yoga feature for RN (iOS) Summary: This change enables built-in Yoga mechanism which rounds producing layout metrics to closest "pixel" values. See previous diff for more context. Reviewed By: fkgozali Differential Revision: D6889762 fbshipit-source-id: bc2eea44704db4b377e2e14fab9f67be8c935719 --- .../testTabBarExample_1-iOS10@2x.png | Bin 79577 -> 79650 bytes .../testTabBarExample_1-iOS11@2x.png | Bin 79721 -> 79754 bytes .../testTabBarExample_1@2x.png | Bin 79888 -> 79887 bytes React/Views/RCTShadowView.m | 3 +-- 4 files changed, 1 insertion(+), 2 deletions(-) diff --git a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testTabBarExample_1-iOS10@2x.png b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testTabBarExample_1-iOS10@2x.png index 3f455893b72be095124173c1f205843747de346e..66c1403e18a001324f517b06350fe1414a6ae698 100644 GIT binary patch literal 79650 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 diff --git a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testTabBarExample_1-iOS11@2x.png b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testTabBarExample_1-iOS11@2x.png index ff34070cd5803785e253cba40cdb1905a368266c..238678f04960a267e6749f202986581d96e861c6 100644 GIT binary patch delta 19453 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 delta 19484 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 SQE?MsSVw|GgX#}P|NLM6qmq08 literal 79888 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 Yd_wA4b8I0e88EKHAz{IF2V#EyFAIjDu>b%7 diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index b6ca0485b9..eaf3e2ad71 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -50,8 +50,7 @@ + (YGConfigRef)yogaConfig static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ yogaConfig = YGConfigNew(); - // Turnig off pixel rounding. - YGConfigSetPointScaleFactor(yogaConfig, 0.0); + YGConfigSetPointScaleFactor(yogaConfig, RCTScreenScale()); YGConfigSetUseLegacyStretchBehaviour(yogaConfig, true); }); return yogaConfig; From db5cd53ed494b0596358a3a8ab7634ed334e17c9 Mon Sep 17 00:00:00 2001 From: Ben Nham Date: Thu, 8 Feb 2018 10:11:47 -0800 Subject: [PATCH 059/143] always create debugger websocket connection Reviewed By: Hypuk, pakoito Differential Revision: D6918269 fbshipit-source-id: 3175c75d4e8459a61d7907555ab9bd4e95002853 --- React/Modules/RCTDevSettings.mm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/React/Modules/RCTDevSettings.mm b/React/Modules/RCTDevSettings.mm index 1b9bb44352..7de283c510 100644 --- a/React/Modules/RCTDevSettings.mm +++ b/React/Modules/RCTDevSettings.mm @@ -195,13 +195,11 @@ - (void)setBridge:(RCTBridge *)bridge // finished with its initialisation. But it does finish by the time it // relinquishes control of the main thread, so only queue on the JS thread // after the current main thread operation is done. - if (self.isNuclideDebuggingAvailable) { - dispatch_async(dispatch_get_main_queue(), ^{ - [bridge dispatchBlock:^{ - [RCTInspectorDevServerHelper connectWithBundleURL:bridge.bundleURL]; - } queue:RCTJSThread]; - }); - } + dispatch_async(dispatch_get_main_queue(), ^{ + [bridge dispatchBlock:^{ + [RCTInspectorDevServerHelper connectWithBundleURL:bridge.bundleURL]; + } queue:RCTJSThread]; + }); #endif } From ff45ab136d0b0c9b45403da0949b7100dcb89c2d Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 12 Feb 2018 00:04:16 -0800 Subject: [PATCH 060/143] Reimagining of RCTShadowView layout API Summary: This is reimagining of interoperability layer between Yoga and ShadowViews (at least in Yoga -> RN part). Goals: * Make it clear and easy. * Make clear separation between "what layout what", now parent always layout children, noone layout itself. * Make possible to interleave Yoga layout with custom imperative layout (may be used in SafeAreaView, Text, Modal, InputAccessoryView and so on). Reviewed By: mmmulani Differential Revision: D6863654 fbshipit-source-id: 5a6a933874f121d46f744aab99a31ae42ddd4a1b --- Libraries/Text/Text/RCTTextShadowView.m | 58 ++---- .../TextInput/RCTBaseTextInputShadowView.m | 7 +- React/Base/Surface/RCTSurfaceRootShadowView.h | 6 +- React/Base/Surface/RCTSurfaceRootShadowView.m | 33 +-- React/Modules/RCTUIManager.m | 27 ++- React/React.xcodeproj/project.pbxproj | 11 +- React/Views/RCTLayout.h | 77 +++++++ React/Views/RCTLayout.m | 145 +++++++++++++ React/Views/RCTRootShadowView.h | 6 +- React/Views/RCTRootShadowView.m | 23 ++- React/Views/RCTShadowView+Layout.h | 14 -- React/Views/RCTShadowView+Layout.m | 72 +------ React/Views/RCTShadowView.h | 52 ++--- React/Views/RCTShadowView.m | 193 +++++++++++------- .../ScrollView/RCTScrollContentShadowView.m | 43 +--- 15 files changed, 457 insertions(+), 310 deletions(-) create mode 100644 React/Views/RCTLayout.h create mode 100644 React/Views/RCTLayout.m diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index a6f75459e1..f423726313 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -235,40 +235,24 @@ - (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size return textStorage; } -- (void)applyLayoutNode:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition +- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics + layoutContext:(RCTLayoutContext)layoutContext { - if (YGNodeGetHasNewLayout(self.yogaNode)) { - // If the view got new layout, we have to redraw it because `contentFrame` - // and sizes of embedded views may change. + // If the view got new `contentFrame`, we have to redraw it because + // and sizes of embedded views may change. + if (!CGRectEqualToRect(self.layoutMetrics.contentFrame, layoutMetrics.contentFrame)) { _needsUpdateView = YES; } - [super applyLayoutNode:node - viewsWithNewFrame:viewsWithNewFrame - absolutePosition:absolutePosition]; -} - -- (void)applyLayoutWithFrame:(CGRect)frame - layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection - viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout - absolutePosition:(CGPoint)absolutePosition -{ - if (self.textAttributes.layoutDirection != layoutDirection) { - self.textAttributes.layoutDirection = layoutDirection; + if (self.textAttributes.layoutDirection != layoutMetrics.layoutDirection) { + self.textAttributes.layoutDirection = layoutMetrics.layoutDirection; [self invalidateCache]; } - [super applyLayoutWithFrame:frame - layoutDirection:layoutDirection - viewsWithUpdatedLayout:viewsWithUpdatedLayout - absolutePosition:absolutePosition]; + [super layoutWithMetrics:layoutMetrics layoutContext:layoutContext]; } -- (void)applyLayoutToChildren:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition +- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext { NSTextStorage *textStorage = [self textStorageAndLayoutManagerThatFitsSize:self.availableSize @@ -280,9 +264,9 @@ - (void)applyLayoutToChildren:(YGNodeRef)node actualGlyphRange:NULL]; [textStorage enumerateAttribute:RCTBaseTextShadowViewEmbeddedShadowViewAttributeName - inRange:characterRange - options:0 - usingBlock: + inRange:characterRange + options:0 + usingBlock: ^(RCTShadowView *shadowView, NSRange range, BOOL *stop) { if (!shadowView) { return; @@ -306,18 +290,14 @@ - (void)applyLayoutToChildren:(YGNodeRef)node RCTRoundPixelValue(attachmentSize.height) }}; - UIUserInterfaceLayoutDirection layoutDirection = self.textAttributes.layoutDirection; - - YGNodeCalculateLayout( - shadowView.yogaNode, - frame.size.width, - frame.size.height, - layoutDirection == UIUserInterfaceLayoutDirectionLeftToRight ? YGDirectionLTR : YGDirectionRTL); + RCTLayoutContext localLayoutContext = layoutContext; + localLayoutContext.absolutePosition.x += frame.origin.x; + localLayoutContext.absolutePosition.y += frame.origin.y; - [shadowView applyLayoutWithFrame:frame - layoutDirection:layoutDirection - viewsWithUpdatedLayout:viewsWithNewFrame - absolutePosition:absolutePosition]; + [shadowView layoutWithMinimumSize:frame.size + maximumSize:frame.size + layoutDirection:self.layoutMetrics.layoutDirection + layoutContext:localLayoutContext]; } ]; } diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index e145d4a3b0..faaaf775f0 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -47,6 +47,11 @@ - (BOOL)isYogaLeafNode return YES; } +- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext +{ + // Do nothing. +} + - (void)setLocalData:(NSObject *)localData { NSAttributedString *attributedText = (NSAttributedString *)localData; @@ -73,7 +78,7 @@ - (void)invalidateContentSize return; } - CGSize maximumSize = self.frame.size; + CGSize maximumSize = self.layoutMetrics.frame.size; if (_maximumNumberOfLines == 1) { maximumSize.width = CGFLOAT_MAX; diff --git a/React/Base/Surface/RCTSurfaceRootShadowView.h b/React/Base/Surface/RCTSurfaceRootShadowView.h index 86b12c393f..e3ff17506c 100644 --- a/React/Base/Surface/RCTSurfaceRootShadowView.h +++ b/React/Base/Surface/RCTSurfaceRootShadowView.h @@ -29,10 +29,6 @@ */ @property (nonatomic, assign) YGDirection baseDirection; -/** - * Calculate all views whose frame needs updating after layout has been calculated. - * Returns a set contains the shadowviews that need updating. - */ -- (NSSet *)collectViewsWithUpdatedFrames; +- (void)layoutWithAffectedShadowViews:(NSHashTable *)affectedShadowViews; @end diff --git a/React/Base/Surface/RCTSurfaceRootShadowView.m b/React/Base/Surface/RCTSurfaceRootShadowView.m index 37a4c206ef..fb4d28deb9 100644 --- a/React/Base/Surface/RCTSurfaceRootShadowView.m +++ b/React/Base/Surface/RCTSurfaceRootShadowView.m @@ -43,37 +43,26 @@ - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex } } -- (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +- (void)layoutWithAffectedShadowViews:(NSHashTable *)affectedShadowViews { - YGNodeRef yogaNode = self.yogaNode; + NSHashTable *other = [NSHashTable new]; - YGNodeStyleSetMinWidth(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width)); - YGNodeStyleSetMinHeight(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height)); + RCTLayoutContext layoutContext = {}; + layoutContext.absolutePosition = CGPointZero; + layoutContext.affectedShadowViews = affectedShadowViews; + layoutContext.other = other; - YGNodeCalculateLayout( - self.yogaNode, - RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width), - RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height), - _baseDirection - ); -} - -- (NSSet *)collectViewsWithUpdatedFrames -{ - [self calculateLayoutWithMinimumSize:_minimumSize - maximumSize:_maximumSize]; + [self layoutWithMinimumSize:_minimumSize + maximumSize:_maximumSize + layoutDirection:RCTUIKitLayoutDirectionFromYogaLayoutDirection(_baseDirection) + layoutContext:layoutContext]; - NSMutableSet *viewsWithNewFrame = [NSMutableSet set]; - [self applyLayoutNode:self.yogaNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero]; - - self.intrinsicSize = self.frame.size; + self.intrinsicSize = self.layoutMetrics.frame.size; if (_isRendered && !_isLaidOut) { [_delegate rootShadowViewDidStartLayingOut:self]; _isLaidOut = YES; } - - return viewsWithNewFrame; } - (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index bd7ac63701..791ed4d236 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -472,14 +472,10 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * { RCTAssertUIManagerQueue(); - // This is nuanced. In the JS thread, we create a new update buffer - // `frameTags`/`frames` that is created/mutated in the JS thread. We access - // these structures in the UI-thread block. `NSMutableArray` is not thread - // safe so we rely on the fact that we never mutate it after it's passed to - // the main thread. - NSSet *viewsWithNewFrames = [rootShadowView collectViewsWithUpdatedFrames]; - - if (!viewsWithNewFrames.count) { + NSHashTable *affectedShadowViews = [NSHashTable weakObjectsHashTable]; + [rootShadowView layoutWithAffectedShadowViews:affectedShadowViews]; + + if (!affectedShadowViews.count) { // no frame change results in no UI update block return nil; } @@ -492,24 +488,25 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * } RCTFrameData; // Construct arrays then hand off to main thread - NSUInteger count = viewsWithNewFrames.count; + NSUInteger count = affectedShadowViews.count; NSMutableArray *reactTags = [[NSMutableArray alloc] initWithCapacity:count]; NSMutableData *framesData = [[NSMutableData alloc] initWithLength:sizeof(RCTFrameData) * count]; { NSUInteger index = 0; RCTFrameData *frameDataArray = (RCTFrameData *)framesData.mutableBytes; - for (RCTShadowView *shadowView in viewsWithNewFrames) { + for (RCTShadowView *shadowView in affectedShadowViews) { reactTags[index] = shadowView.reactTag; + RCTLayoutMetrics layoutMetrics = shadowView.layoutMetrics; frameDataArray[index++] = (RCTFrameData){ - shadowView.frame, - shadowView.layoutDirection, + layoutMetrics.frame, + layoutMetrics.layoutDirection, shadowView.isNewView, shadowView.superview.isNewView, }; } } - for (RCTShadowView *shadowView in viewsWithNewFrames) { + for (RCTShadowView *shadowView in affectedShadowViews) { // We have to do this after we build the parentsAreNew array. shadowView.newView = NO; @@ -517,7 +514,7 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * NSNumber *reactTag = shadowView.reactTag; if (shadowView.onLayout) { - CGRect frame = shadowView.frame; + CGRect frame = shadowView.layoutMetrics.frame; shadowView.onLayout(@{ @"layout": @{ @"x": @(frame.origin.x), @@ -532,7 +529,7 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * RCTIsReactRootView(reactTag) && [shadowView isKindOfClass:[RCTRootShadowView class]] ) { - CGSize contentSize = shadowView.frame.size; + CGSize contentSize = shadowView.layoutMetrics.frame.size; RCTExecuteOnMainQueue(^{ NSView *view = self->_viewRegistry[reactTag]; diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 3edd0b0fec..ce91138e36 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -1046,8 +1046,10 @@ 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; 705EDE2922107DD0000CAA67 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2722107DD0000CAA67 /* Utils.h */; }; 705EDE2A22107DD0000CAA67 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2822107DD0000CAA67 /* Utils.cpp */; }; + 70BA7CC32217790F006B6654 /* RCTLayout.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 70D4B5142217707C0007C3F1 /* RCTLayout.h */; }; + 70D4B5162217707D0007C3F1 /* RCTLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 70D4B5142217707C0007C3F1 /* RCTLayout.h */; }; + 70D4B5172217707D0007C3F1 /* RCTLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 70D4B5152217707C0007C3F1 /* RCTLayout.m */; }; 705EDE2C221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */; }; - 705EDE2D221082D9000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */; }; 830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; }; 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; }; 83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8B1B62640A00BE0E65 /* RCTModalHostView.m */; }; @@ -1481,6 +1483,7 @@ files = ( 702B7FFF221C88D70027174A /* RCTWindow.h in Copy Headers */, 702B7FFE221C88CE0027174A /* RCTMouseEvent.h in Copy Headers */, + 70BA7CC32217790F006B6654 /* RCTLayout.h in Copy Headers */, D4EEE3542020933B00C4CBB6 /* UIImageUtils.h in Copy Headers */, 59EDBCBD1FDF4E43003573DE /* RCTScrollableProtocol.h in Copy Headers */, 59EDBCBE1FDF4E43003573DE /* RCTScrollContentShadowView.h in Copy Headers */, @@ -2083,6 +2086,8 @@ 705EDE2722107DD0000CAA67 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; 705EDE2822107DD0000CAA67 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = ""; }; 705EDE2B221082CB000CAA67 /* RCTSurfaceSizeMeasureMode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceSizeMeasureMode.mm; sourceTree = ""; }; + 70D4B5142217707C0007C3F1 /* RCTLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLayout.h; sourceTree = ""; }; + 70D4B5152217707C0007C3F1 /* RCTLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLayout.m; sourceTree = ""; }; 830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; }; 830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; }; 830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; }; @@ -2417,6 +2422,8 @@ 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */, 3D37B5801D522B190042D5B5 /* RCTFont.h */, 3D37B5811D522B190042D5B5 /* RCTFont.mm */, + 70D4B5142217707C0007C3F1 /* RCTLayout.h */, + 70D4B5152217707C0007C3F1 /* RCTLayout.m */, 66CD94AD1F1045E700CB3C7C /* RCTMaskedView.h */, 66CD94AE1F1045E700CB3C7C /* RCTMaskedView.m */, 66CD94AF1F1045E700CB3C7C /* RCTMaskedViewManager.h */, @@ -3383,6 +3390,7 @@ 3D80DA901DF820620028D040 /* RCTWebView.h in Headers */, 3D80DA911DF820620028D040 /* RCTWebViewManager.h in Headers */, 3D80DA931DF820620028D040 /* NSView+Private.h in Headers */, + 70D4B5162217707D0007C3F1 /* RCTLayout.h in Headers */, 3D80DA941DF820620028D040 /* NSView+React.h in Headers */, 599FAA481FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */, ); @@ -4283,6 +4291,7 @@ 657734911EE8354A00A0E9EA /* RCTInspectorPackagerConnection.m in Sources */, 68EFE4EE1CF6EB3900A1DE13 /* RCTBundleURLProvider.m in Sources */, B95154321D1B34B200FE7B80 /* RCTActivityIndicatorView.m in Sources */, + 70D4B5172217707D0007C3F1 /* RCTLayout.m in Sources */, 5960C1BB1F0804A00066FD5B /* RCTLayoutAnimationGroup.m in Sources */, 13F17A851B8493E5007D4C75 /* RCTRedBox.m in Sources */, 135A9BFC1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm in Sources */, diff --git a/React/Views/RCTLayout.h b/React/Views/RCTLayout.h new file mode 100644 index 0000000000..79af03ecd7 --- /dev/null +++ b/React/Views/RCTLayout.h @@ -0,0 +1,77 @@ +/** + * 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 + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@class RCTShadowView; + +typedef NS_ENUM(NSInteger, RCTDisplayType) { + RCTDisplayTypeNone, + RCTDisplayTypeFlex, + RCTDisplayTypeInline, +}; + +struct RCTLayoutMetrics { + CGRect frame; + CGRect contentFrame; + UIEdgeInsets borderWidth; + RCTDisplayType displayType; + UIUserInterfaceLayoutDirection layoutDirection; +}; +typedef struct CG_BOXABLE RCTLayoutMetrics RCTLayoutMetrics; + +struct RCTLayoutContext { + CGPoint absolutePosition; + __unsafe_unretained NSHashTable *_Nonnull affectedShadowViews; + __unsafe_unretained NSHashTable *_Nonnull other; +}; +typedef struct CG_BOXABLE RCTLayoutContext RCTLayoutContext; + +static inline BOOL RCTLayoutMetricsEqualToLayoutMetrics(RCTLayoutMetrics a, RCTLayoutMetrics b) +{ + return + CGRectEqualToRect(a.frame, b.frame) && + CGRectEqualToRect(a.contentFrame, b.contentFrame) && + UIEdgeInsetsEqualToEdgeInsets(a.borderWidth, b.borderWidth) && + a.displayType == b.displayType && + a.layoutDirection == b.layoutDirection; +} + +RCT_EXTERN RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode); + +/** + * Converts float values between Yoga and CoreGraphics representations, + * especially in terms of edge cases. + */ +RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value); +RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value); + +/** + * Converts compound `YGValue` to simple `CGFloat` value. + */ +RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue); + +/** + * Converts `YGDirection` to `UIUserInterfaceLayoutDirection` and vise versa. + */ +RCT_EXTERN YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction); +RCT_EXTERN UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction); + +/** + * Converts `YGDisplay` to `RCTDisplayType` and vise versa. + */ +RCT_EXTERN YGDisplay RCTYogaDisplayTypeFromReactDisplayType(RCTDisplayType displayType); +RCT_EXTERN RCTDisplayType RCTReactDisplayTypeFromYogaDisplayType(YGDisplay displayType); + +NS_ASSUME_NONNULL_END diff --git a/React/Views/RCTLayout.m b/React/Views/RCTLayout.m new file mode 100644 index 0000000000..60727621d9 --- /dev/null +++ b/React/Views/RCTLayout.m @@ -0,0 +1,145 @@ +/** + * 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 + +#import "RCTAssert.h" +#import "RCTShadowView+Layout.h" + +RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode) +{ + RCTLayoutMetrics layoutMetrics; + + CGRect frame = (CGRect){ + (CGPoint){ + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetLeft(yogaNode)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetTop(yogaNode)) + }, + (CGSize){ + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetWidth(yogaNode)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetHeight(yogaNode)) + } + }; + + UIEdgeInsets padding = (UIEdgeInsets){ + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight)) + }; + + UIEdgeInsets borderWidth = (UIEdgeInsets){ + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight)) + }; + + UIEdgeInsets compoundInsets = (UIEdgeInsets){ + borderWidth.top + padding.top, + borderWidth.left + padding.left, + borderWidth.bottom + padding.bottom, + borderWidth.right + padding.right + }; + + CGRect bounds = (CGRect){CGPointZero, frame.size}; + CGRect contentFrame = UIEdgeInsetsInsetRect(bounds, compoundInsets); + + layoutMetrics.frame = frame; + layoutMetrics.borderWidth = borderWidth; + layoutMetrics.contentFrame = contentFrame; + layoutMetrics.displayType = RCTReactDisplayTypeFromYogaDisplayType(YGNodeStyleGetDisplay(yogaNode)); + layoutMetrics.layoutDirection = RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGNodeLayoutGetDirection(yogaNode)); + + return layoutMetrics; +} + + +/** + * Yoga and CoreGraphics have different opinions about how "infinity" value + * should be represented. + * Yoga uses `NAN` which requires additional effort to compare all those values, + * whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with + * standard `==` operator. + */ + +float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value) +{ + if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) { + return YGUndefined; + } + + return value; +} + +CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value) +{ + if (value == YGUndefined || isnan(value) || isinf(value)) { + return CGFLOAT_MAX; + } + + return value; +} + +CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue) +{ + switch (value.unit) { + case YGUnitPoint: + return RCTCoreGraphicsFloatFromYogaFloat(value.value); + case YGUnitPercent: + return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue; + case YGUnitAuto: + case YGUnitUndefined: + return baseFloatValue; + } +} + +YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction) +{ + switch (direction) { + case UIUserInterfaceLayoutDirectionRightToLeft: + return YGDirectionRTL; + case UIUserInterfaceLayoutDirectionLeftToRight: + return YGDirectionLTR; + } +} + +UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction) +{ + switch (direction) { + case YGDirectionInherit: + case YGDirectionLTR: + return UIUserInterfaceLayoutDirectionLeftToRight; + case YGDirectionRTL: + return UIUserInterfaceLayoutDirectionRightToLeft; + } +} + +YGDisplay RCTYogaDisplayTypeFromReactDisplayType(RCTDisplayType displayType) +{ + switch (displayType) { + case RCTDisplayTypeNone: + return YGDisplayNone; + case RCTDisplayTypeFlex: + return YGDisplayFlex; + case RCTDisplayTypeInline: + RCTAssert(NO, @"RCTDisplayTypeInline cannot be converted to YGDisplay value."); + return YGDisplayNone; + } +} + +RCTDisplayType RCTReactDisplayTypeFromYogaDisplayType(YGDisplay displayType) +{ + switch (displayType) { + case YGDisplayFlex: + return RCTDisplayTypeFlex; + case YGDisplayNone: + return RCTDisplayTypeNone; + } +} diff --git a/React/Views/RCTRootShadowView.h b/React/Views/RCTRootShadowView.h index 95b96edf11..8f1d0108c2 100644 --- a/React/Views/RCTRootShadowView.h +++ b/React/Views/RCTRootShadowView.h @@ -25,10 +25,6 @@ */ @property (nonatomic, assign) YGDirection baseDirection; -/** - * Calculate all views whose frame needs updating after layout has been calculated. - * Returns a set contains the shadowviews that need updating. - */ -- (NSSet *)collectViewsWithUpdatedFrames; +- (void)layoutWithAffectedShadowViews:(NSHashTable *)affectedShadowViews; @end diff --git a/React/Views/RCTRootShadowView.m b/React/Views/RCTRootShadowView.m index 15b5b6f7cb..87dad3d8ed 100644 --- a/React/Views/RCTRootShadowView.m +++ b/React/Views/RCTRootShadowView.m @@ -10,30 +10,33 @@ #import "RCTRootShadowView.h" #import "RCTI18nUtil.h" +#import "RCTShadowView+Layout.h" @implementation RCTRootShadowView - (instancetype)init { - self = [super init]; - if (self) { + if (self = [super init]) { _baseDirection = [[RCTI18nUtil sharedInstance] isRTL] ? YGDirectionRTL : YGDirectionLTR; _availableSize = CGSizeMake(INFINITY, INFINITY); } + return self; } -- (NSSet *)collectViewsWithUpdatedFrames +- (void)layoutWithAffectedShadowViews:(NSHashTable *)affectedShadowViews { - // Treating `INFINITY` as `YGUndefined` (which equals `NAN`). - float availableWidth = _availableSize.width == INFINITY ? YGUndefined : _availableSize.width; - float availableHeight = _availableSize.height == INFINITY ? YGUndefined : _availableSize.height; + NSHashTable *other = [NSHashTable new]; - YGNodeCalculateLayout(self.yogaNode, availableWidth, availableHeight, _baseDirection); + RCTLayoutContext layoutContext = {}; + layoutContext.absolutePosition = CGPointZero; + layoutContext.affectedShadowViews = affectedShadowViews; + layoutContext.other = other; - NSMutableSet *viewsWithNewFrame = [NSMutableSet set]; - [self applyLayoutNode:self.yogaNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero]; - return viewsWithNewFrame; + [self layoutWithMinimumSize:CGSizeZero + maximumSize:_availableSize + layoutDirection:RCTUIKitLayoutDirectionFromYogaLayoutDirection(_baseDirection) + layoutContext:layoutContext]; } @end diff --git a/React/Views/RCTShadowView+Layout.h b/React/Views/RCTShadowView+Layout.h index 770529e135..564cb6d702 100644 --- a/React/Views/RCTShadowView+Layout.h +++ b/React/Views/RCTShadowView+Layout.h @@ -11,13 +11,6 @@ #import -/** - * Converts float values between Yoga and CoreGraphics representations, - * especially in terms of edge cases. - */ -RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value); -RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value); - @interface RCTShadowView (Layout) #pragma mark - Computed Layout-Inferred Metrics @@ -28,13 +21,6 @@ RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value); @property (nonatomic, readonly) CGSize availableSize; @property (nonatomic, readonly) CGRect contentFrame; -#pragma mark - Measuring - -/** - * Measures shadow view without side-effects. - */ -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize; - #pragma mark - Dirty Propagation Control /** diff --git a/React/Views/RCTShadowView+Layout.m b/React/Views/RCTShadowView+Layout.m index e4f40f5762..896f6dea7d 100644 --- a/React/Views/RCTShadowView+Layout.m +++ b/React/Views/RCTShadowView+Layout.m @@ -11,31 +11,7 @@ #import -/** - * Yoga and CoreGraphics have different opinions about how "infinity" value - * should be represented. - * Yoga uses `NAN` which requires additional effort to compare all those values, - * whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with - * standard `==` operator. - */ - -float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value) -{ - if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) { - return YGUndefined; - } - - return value; -} - -CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value) -{ - if (value == YGUndefined || isnan(value) || isinf(value)) { - return CGFLOAT_MAX; - } - - return value; -} +#import "RCTAssert.h" @implementation RCTShadowView (Layout) @@ -76,56 +52,14 @@ - (NSEdgeInsets)compoundInsets }; } -static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { - rect.origin.x += insets.left; - rect.origin.y += insets.top; - rect.size.width -= (insets.left + insets.right); - rect.size.height -= (insets.top + insets.bottom); - return rect; -} - - (NSSize)availableSize { - return NSEdgeInsetsInsetRect((CGRect){CGPointZero, self.frame.size}, self.compoundInsets).size; + return self.layoutMetrics.contentFrame.size; } - (CGRect)contentFrame { - CGRect bounds = (CGRect){CGPointZero, self.frame.size}; - return NSEdgeInsetsInsetRect(bounds, self.compoundInsets); -} - -#pragma mark - Measuring - -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize -{ - YGNodeRef clonnedYogaNode = YGNodeClone(self.yogaNode); - YGNodeRef constraintYogaNode = YGNodeNewWithConfig([[self class] yogaConfig]); - - YGNodeInsertChild(constraintYogaNode, clonnedYogaNode, 0); - - YGNodeStyleSetMinWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width)); - YGNodeStyleSetMinHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height)); - YGNodeStyleSetMaxWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width)); - YGNodeStyleSetMaxHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height)); - - YGNodeCalculateLayout( - constraintYogaNode, - YGUndefined, - YGUndefined, - self.layoutDirection - ); - - CGSize measuredSize = (CGSize){ - RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetWidth(constraintYogaNode)), - RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetHeight(constraintYogaNode)), - }; - - YGNodeRemoveChild(constraintYogaNode, clonnedYogaNode); - YGNodeFree(constraintYogaNode); - YGNodeFree(clonnedYogaNode); - - return measuredSize; + return self.layoutMetrics.contentFrame; } #pragma mark - Dirty Propagation Control diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index 550bfda56b..e0fb9af11b 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -10,6 +10,7 @@ #import #import +#import #import #import @@ -51,6 +52,11 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry @property (nonatomic, copy) NSString *viewName; @property (nonatomic, copy) RCTDirectEventBlock onLayout; +/** + * Computed layout of the view. + */ +@property (nonatomic, assign) RCTLayoutMetrics layoutMetrics; + /** * In some cases we need a way to specify some environmental data to shadow view * to improve layout (or do something similar), so `localData` serves these needs. @@ -70,11 +76,6 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ @property (nonatomic, assign, getter=isNewView) BOOL newView; -/** - * Computed layout direction of the view. - */ -@property (nonatomic, assign, readonly) NSUserInterfaceLayoutDirection layoutDirection; - /** * Position and dimensions. * Defaults to { 0, 0, NAN, NAN }. @@ -166,38 +167,39 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ @property (nonatomic, assign) YGOverflow overflow; -/** - * Computed position of the view. - */ -@property (nonatomic, assign, readonly) CGRect frame; - /** * Represents the natural size of the view, which is used when explicit size is not set or is ambiguous. * Defaults to `{UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric}`. */ @property (nonatomic, assign) CGSize intrinsicContentSize; +#pragma mark - Layout + /** - * Apply the CSS layout. - * This method also calls `applyLayoutToChildren:` internally. The functionality - * is split into two methods so subclasses can override `applyLayoutToChildren:` - * while using default implementation of `applyLayoutNode:`. + * Initiates layout starts from the view. */ -- (void)applyLayoutNode:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER; +- (void)layoutWithMinimumSize:(CGSize)minimumSize + maximumSize:(CGSize)maximumSize + layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + layoutContext:(RCTLayoutContext)layoutContext; -- (void)applyLayoutWithFrame:(CGRect)frame - layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection - viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout - absolutePosition:(CGPoint)absolutePosition; +/** + * Applies computed layout metrics to the view. + */ +- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics + layoutContext:(RCTLayoutContext)layoutContext; + +/** + * Calculates (if needed) and applies layout to subviews. + */ +- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext; /** - * Enumerate the child nodes and tell them to apply layout. + * Measures shadow view without side-effects. + * Default implementation uses Yoga for measuring. */ -- (void)applyLayoutToChildren:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition; +- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize + maximumSize:(CGSize)maximumSize; /** * Returns whether or not this view can have any subviews. diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index eaf3e2ad71..446551c59d 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -12,6 +12,7 @@ #import "RCTConvert.h" #import "RCTI18nUtil.h" #import "RCTLog.h" +#import "RCTShadowView+Layout.h" #import "RCTUtils.h" #import "NSView+Private.h" #import "NSView+React.h" @@ -153,82 +154,21 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT], YGNodeStyleSetBorder(node, YGEdgeAll, metaProps[META_PROP_ALL].value); } -- (void)applyLayoutNode:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition -{ - if (!YGNodeGetHasNewLayout(node)) { - return; - } - - RCTAssert(!YGNodeIsDirty(node), @"Attempt to get layout metrics from dirtied Yoga node."); - - YGNodeSetHasNewLayout(node, false); - - if (YGNodeStyleGetDisplay(node) == YGDisplayNone) { - // If the node is hidden (has `display: none;`), its (and its descendants) - // layout metrics are invalid and/or dirtied, so we have to stop here. - return; - } - - CGRect frame = CGRectMake(YGNodeLayoutGetLeft(node), YGNodeLayoutGetTop(node), YGNodeLayoutGetWidth(node), YGNodeLayoutGetHeight(node)); - - // Even if `YGNodeLayoutGetDirection` can return `YGDirectionInherit` here, it actually means - // that Yoga will use LTR layout for the view (even if layout process is not finished yet). - UIUserInterfaceLayoutDirection layoutDirection = YGNodeLayoutGetDirection(_yogaNode) == YGDirectionRTL ? UIUserInterfaceLayoutDirectionRightToLeft : UIUserInterfaceLayoutDirectionLeftToRight; - - [self applyLayoutWithFrame:frame - layoutDirection:layoutDirection - viewsWithUpdatedLayout:viewsWithNewFrame - absolutePosition:absolutePosition]; -} - -- (void)applyLayoutWithFrame:(CGRect)frame - layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection - viewsWithUpdatedLayout:(NSMutableSet *)viewsWithUpdatedLayout - absolutePosition:(CGPoint)absolutePosition -{ - if (!CGRectEqualToRect(_frame, frame) || _layoutDirection != layoutDirection) { - _frame = frame; - _layoutDirection = layoutDirection; - [viewsWithUpdatedLayout addObject:self]; - } - - absolutePosition.x += frame.origin.x; - absolutePosition.y += frame.origin.y; - - [self applyLayoutToChildren:_yogaNode - viewsWithNewFrame:viewsWithUpdatedLayout - absolutePosition:absolutePosition]; -} - -- (void)applyLayoutToChildren:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition -{ - for (unsigned int i = 0; i < YGNodeGetChildCount(node); ++i) { - RCTShadowView *child = (RCTShadowView *)_reactSubviews[i]; - [child applyLayoutNode:YGNodeGetChild(node, i) - viewsWithNewFrame:viewsWithNewFrame - absolutePosition:absolutePosition]; - } -} - - (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor { CGPoint offset = CGPointZero; NSInteger depth = 30; // max depth to search RCTShadowView *shadowView = self; while (depth && shadowView && shadowView != ancestor) { - offset.x += shadowView.frame.origin.x; - offset.y += shadowView.frame.origin.y; + offset.x += shadowView.layoutMetrics.frame.origin.x; + offset.y += shadowView.layoutMetrics.frame.origin.y; shadowView = shadowView->_superview; depth--; } if (ancestor != shadowView) { return CGRectNull; } - return (CGRect){offset, self.frame.size}; + return (CGRect){offset, self.layoutMetrics.frame.size}; } - (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor @@ -244,9 +184,7 @@ - (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor - (instancetype)init { - if ((self = [super init])) { - _frame = CGRectMake(0, 0, YGUndefined, YGUndefined); - + if (self = [super init]) { for (unsigned int ii = 0; ii < META_PROP_COUNT; ii++) { _paddingMetaProps[ii] = YGValueUndefined; _marginMetaProps[ii] = YGValueUndefined; @@ -316,12 +254,125 @@ - (RCTShadowView *)reactSuperview return _superview; } +#pragma mark - Layout + +- (void)layoutWithMinimumSize:(CGSize)minimumSize + maximumSize:(CGSize)maximumSize + layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + layoutContext:(RCTLayoutContext)layoutContext +{ + YGNodeRef yogaNode = _yogaNode; + + CGSize oldMinimumSize = (CGSize){ + RCTCoreGraphicsFloatFromYogaValue(YGNodeStyleGetMinWidth(yogaNode), 0.0), + RCTCoreGraphicsFloatFromYogaValue(YGNodeStyleGetMinHeight(yogaNode), 0.0) + }; + + if (!CGSizeEqualToSize(oldMinimumSize, minimumSize)) { + YGNodeStyleSetMinWidth(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width)); + YGNodeStyleSetMinHeight(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height)); + } + + YGNodeCalculateLayout( + yogaNode, + RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width), + RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height), + RCTYogaLayoutDirectionFromUIKitLayoutDirection(layoutDirection) + ); + + RCTAssert(!YGNodeIsDirty(yogaNode), @"Attempt to get layout metrics from dirtied Yoga node."); + + if (!YGNodeGetHasNewLayout(yogaNode)) { + return; + } + + RCTLayoutMetrics layoutMetrics = RCTLayoutMetricsFromYogaNode(yogaNode); + + layoutContext.absolutePosition.x += layoutMetrics.frame.origin.x; + layoutContext.absolutePosition.y += layoutMetrics.frame.origin.y; + + [self layoutWithMetrics:layoutMetrics + layoutContext:layoutContext]; + + [self layoutSubviewsWithContext:layoutContext]; +} + +- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics + layoutContext:(RCTLayoutContext)layoutContext +{ + if (!RCTLayoutMetricsEqualToLayoutMetrics(self.layoutMetrics, layoutMetrics)) { + self.layoutMetrics = layoutMetrics; + [layoutContext.affectedShadowViews addObject:self]; + } +} + +- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext +{ + RCTLayoutMetrics layoutMetrics = self.layoutMetrics; + + if (layoutMetrics.displayType == RCTDisplayTypeNone) { + return; + } + + for (RCTShadowView *childShadowView in _reactSubviews) { + YGNodeRef childYogaNode = childShadowView.yogaNode; + + RCTAssert(!YGNodeIsDirty(childYogaNode), @"Attempt to get layout metrics from dirtied Yoga node."); + + if (!YGNodeGetHasNewLayout(childYogaNode)) { + continue; + } + + RCTLayoutMetrics childLayoutMetrics = RCTLayoutMetricsFromYogaNode(childYogaNode); + + layoutContext.absolutePosition.x += childLayoutMetrics.frame.origin.x; + layoutContext.absolutePosition.y += childLayoutMetrics.frame.origin.y; + + [childShadowView layoutWithMetrics:childLayoutMetrics + layoutContext:layoutContext]; + + // Recursive call. + [childShadowView layoutSubviewsWithContext:layoutContext]; + } +} + +- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +{ + YGNodeRef clonnedYogaNode = YGNodeClone(self.yogaNode); + YGNodeRef constraintYogaNode = YGNodeNewWithConfig([[self class] yogaConfig]); + + YGNodeInsertChild(constraintYogaNode, clonnedYogaNode, 0); + + YGNodeStyleSetMinWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width)); + YGNodeStyleSetMinHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height)); + YGNodeStyleSetMaxWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width)); + YGNodeStyleSetMaxHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height)); + + YGNodeCalculateLayout( + constraintYogaNode, + YGUndefined, + YGUndefined, + self.layoutMetrics.layoutDirection + ); + + CGSize measuredSize = (CGSize){ + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetWidth(constraintYogaNode)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetHeight(constraintYogaNode)), + }; + + YGNodeRemoveChild(constraintYogaNode, clonnedYogaNode); + YGNodeFree(constraintYogaNode); + YGNodeFree(clonnedYogaNode); + + return measuredSize; +} + - (NSNumber *)reactTagAtPoint:(CGPoint)point { for (RCTShadowView *shadowView in _reactSubviews) { - if (CGRectContainsPoint(shadowView.frame, point)) { + if (CGRectContainsPoint(shadowView.layoutMetrics.frame, point)) { CGPoint relativePoint = point; - CGPoint origin = shadowView.frame.origin; + CGPoint origin = shadowView.layoutMetrics.frame.origin; relativePoint.x -= origin.x; relativePoint.y -= origin.y; return [shadowView reactTagAtPoint:relativePoint]; @@ -333,9 +384,7 @@ - (NSNumber *)reactTagAtPoint:(CGPoint)point - (NSString *)description { NSString *description = super.description; - description = [[description substringToIndex:description.length - 1] - stringByAppendingFormat:@"; viewName: %@; reactTag: %@; frame: %f; %f;>", - self.viewName, self.reactTag, self.frame.size.height, self.frame.size.width]; + description = [[description substringToIndex:description.length - 1] stringByAppendingFormat:@"; viewName: %@; reactTag: %@; frame: %@>", self.viewName, self.reactTag, NSStringFromCGRect(self.layoutMetrics.frame)]; return description; } diff --git a/React/Views/ScrollView/RCTScrollContentShadowView.m b/React/Views/ScrollView/RCTScrollContentShadowView.m index 7c06811123..d53a658edb 100644 --- a/React/Views/ScrollView/RCTScrollContentShadowView.m +++ b/React/Views/ScrollView/RCTScrollContentShadowView.m @@ -13,43 +13,22 @@ #import "RCTUtils.h" -@interface RCTShadowView () { - // This will be removed after t15757916, which will remove - // side-effects from `setFrame:` method. - @public CGRect _frame; -} -@end - @implementation RCTScrollContentShadowView -- (void)applyLayoutNode:(YGNodeRef)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame - absolutePosition:(CGPoint)absolutePosition +- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics + layoutContext:(RCTLayoutContext)layoutContext { - // Call super method if LTR layout is enforced. - if (YGNodeLayoutGetDirection(self.yogaNode) != YGDirectionRTL) { - [super applyLayoutNode:node - viewsWithNewFrame:viewsWithNewFrame - absolutePosition:absolutePosition]; - return; + if (layoutMetrics.layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) { + // Motivation: + // Yoga place `contentView` on the right side of `scrollView` when RTL layout is enfoced. + // That breaks everything; it is completely pointless to (re)position `contentView` + // because it is `contentView`'s job. So, we work around it here. + + layoutContext.absolutePosition.x += layoutMetrics.frame.size.width; + layoutMetrics.frame.origin.x = 0; } - // Motivation: - // Yoga place `contentView` on the right side of `scrollView` when RTL layout is enfoced. - // That breaks everything; it is completly pointless to (re)position `contentView` - // because it is `contentView`'s job. So, we work around it here. - - // Step 1. Compensate `absolutePosition` change. - CGFloat xCompensation = YGNodeLayoutGetRight(node) - YGNodeLayoutGetLeft(node); - absolutePosition.x += xCompensation; - - // Step 2. Call super method. - [super applyLayoutNode:node - viewsWithNewFrame:viewsWithNewFrame - absolutePosition:absolutePosition]; - - // Step 3. Reset the position. - _frame.origin.x = RCTRoundPixelValue(YGNodeLayoutGetRight(node)); + [super layoutWithMetrics:layoutMetrics layoutContext:layoutContext]; } @end From c8dfd6b0d12596faaa2db2d0f32f39cbe32da78d Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 15 Feb 2018 17:40:14 -0800 Subject: [PATCH 061/143] `base-line` metric exposure for Summary: Now (both bersions) exposes base-line metric to Yoga. Before: https://cl.ly/0G1Q29450O0y After: https://cl.ly/2X103V3O0322 Reviewed By: yungsters Differential Revision: D6957054 fbshipit-source-id: d76d96f56720d710a4230c53beafdb0b2521e8a9 --- .../TextInput/RCTBaseTextInputShadowView.m | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index faaaf775f0..0d60c3c49d 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -37,6 +37,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _needsUpdateView = YES; YGNodeSetMeasureFunc(self.yogaNode, RCTBaseTextInputShadowViewMeasure); + YGNodeSetBaselineFunc(self.yogaNode, RCTTextInputShadowViewBaseline); } return self; @@ -167,7 +168,7 @@ - (void)uiManagerWillPerformMounting #pragma mark - -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +- (NSAttributedString *)measurableAttributedText { // Only for the very first render when we don't have `_localAttributedText`, // we use value directly from the property and/or nested content. @@ -187,6 +188,13 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximu attributedText = [[NSAttributedString alloc] initWithString:text attributes:self.textAttributes.effectiveTextAttributes]; } + return attributedText; +} + +- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +{ + NSAttributedString *attributedText = [self measurableAttributedText]; + if (!_textStorage) { _textContainer = [NSTextContainer new]; _textContainer.lineFragmentPadding = 0.0; // Note, the default value is 5. @@ -209,6 +217,26 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximu }; } +- (CGFloat)lastBaselineForSize:(CGSize)size +{ + NSAttributedString *attributedText = [self measurableAttributedText]; + + __block CGFloat maximumDescender = 0.0; + + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock: + ^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (maximumDescender > font.descender) { + maximumDescender = font.descender; + } + } + ]; + + return size.height + maximumDescender; +} + static YGSize RCTBaseTextInputShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node); @@ -253,4 +281,18 @@ static YGSize RCTBaseTextInputShadowViewMeasure(YGNodeRef node, float width, YGM }; } +static float RCTTextInputShadowViewBaseline(YGNodeRef node, const float width, const float height) +{ + RCTBaseTextInputShadowView *shadowTextView = (__bridge RCTBaseTextInputShadowView *)YGNodeGetContext(node); + + CGSize size = (CGSize){ + RCTCoreGraphicsFloatFromYogaFloat(width), + RCTCoreGraphicsFloatFromYogaFloat(height) + }; + + CGFloat lastBaseline = [shadowTextView lastBaselineForSize:size]; + + return RCTYogaFloatFromCoreGraphicsFloat(lastBaseline); +} + @end From 23ee96d7d167c91f476f510e9424440b4f96bb9a Mon Sep 17 00:00:00 2001 From: Cristiano Santos Date: Mon, 19 Mar 2018 02:10:36 -0700 Subject: [PATCH 062/143] Wrong height when TextInput has an empty string Summary: The caret/cursor did not appear when the TextInput was empty. Found that the cause was because the frame of the TextInput had an height of 0 Just fill and clear a TextInput and the caret/cursor will always appear there. Closes https://github.com/facebook/react-native/pull/18355 Differential Revision: D7319723 Pulled By: shergin fbshipit-source-id: b0249ab5493b6ac310d1898ff20c0bad78cf82c9 --- Libraries/Text/TextInput/RCTBaseTextInputShadowView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index 0d60c3c49d..80b6578ced 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -182,8 +182,8 @@ - (NSAttributedString *)measurableAttributedText // Placeholder also can represent the intrinsic size when it is visible. NSString *text = self.placeholder; if (!text.length) { - // Zero-width space - text = @"\u200B"; + // Note: `zero-width space` is insufficient in some cases. + text = @"I"; } attributedText = [[NSAttributedString alloc] initWithString:text attributes:self.textAttributes.effectiveTextAttributes]; } From a9373fd39b9a5f9166be8ab77b87124ba181747e Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Tue, 17 Apr 2018 07:53:19 -0700 Subject: [PATCH 063/143] Update ModuleRegistry if there're new modules registered Reviewed By: fkgozali Differential Revision: D7638394 fbshipit-source-id: c1690da7977f0335bc661df5f19dc9f473150d41 --- React/CxxBridge/RCTCxxBridge.mm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index da9aff2908..6aaa0df1cb 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -310,7 +310,7 @@ - (void)start [self registerExtraModules]; // Initialize all native modules that cannot be loaded lazily - [self _initModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO]; + (void)[self _initializeModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO]; [_performanceLogger markStopForTag:RCTPLNativeModuleInit]; @@ -623,9 +623,9 @@ - (void)registerExtraModules RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); } -- (void)_initModules:(NSArray> *)modules - withDispatchGroup:(dispatch_group_t)dispatchGroup - lazilyDiscovered:(BOOL)lazilyDiscovered +- (NSArray *)_initializeModules:(NSArray> *)modules + withDispatchGroup:(dispatch_group_t)dispatchGroup + lazilyDiscovered:(BOOL)lazilyDiscovered { RCTAssert(!(RCTIsMainQueue() && lazilyDiscovered), @"Lazy discovery can only happen off the Main Queue"); @@ -676,11 +676,15 @@ - (void)_initModules:(NSArray> *)modules RCTProfileHookModules(self); } #endif + return moduleDataById; } - (void)registerAdditionalModuleClasses:(NSArray *)modules { - [self _initModules:modules withDispatchGroup:NULL lazilyDiscovered:YES]; + NSArray *newModules = [self _initializeModules:modules withDispatchGroup:NULL lazilyDiscovered:YES]; + if (_reactInstance) { + _reactInstance->getModuleRegistry().registerModules(createNativeModules(newModules, self, _reactInstance)); + } } - (void)_prepareModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup From 9f9cbc773f327d7153868eb85cb7dc5092c2faa5 Mon Sep 17 00:00:00 2001 From: hamaron Date: Thu, 14 Jun 2018 18:06:05 -0700 Subject: [PATCH 064/143] iOS: Fixed the bug where a Backspace event was emitted when entering characters after clearing a text in TextInput by an empty string (#18627) Summary: The bug #18374 was caused by the loose condition to execute `stringByReplacingCharactersInRange` in the method `textInputShouldChangeTextInRange` . As a result, `findMismatch` wrongly returning `true` which ends up the Backspace event being fired in another `textInputShouldChangeTextInRange` call in `textInputDidChange`. Closes https://github.com/facebook/react-native/pull/18627 Differential Revision: D8436331 Pulled By: hramos fbshipit-source-id: ec75a6ca926061cbf7cb106db652f2b4a71c9a0c --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 177b4afccd..2b00a8b047 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -268,7 +268,12 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin NSString *previousText = [_predictedText substringWithRange:range] ?: @""; - if (_predictedText) { + // After clearing the text by replacing it with an empty string, `_predictedText` + // still preserves the deleted text. + // As the first character in the TextInput always comes with the range value (0, 0), + // we should check the range value in order to avoid appending a character to the deleted string + // (which caused the issue #18374) + if (!NSEqualRanges(range, NSMakeRange(0, 0)) && _predictedText) { _predictedText = [_predictedText stringByReplacingCharactersInRange:range withString:text]; } else { _predictedText = text; From 10964ddc4b673a87f93ef91af1d5ce9889592f7b Mon Sep 17 00:00:00 2001 From: Douglas Date: Tue, 26 Jun 2018 17:38:09 -0700 Subject: [PATCH 065/143] Suppress spurious warning about RCTCxxModule (#19880) Summary: On a relatively stock / default setup of RN on iOS you'll see the warning "Class RCTCxxModule was not exported. Did you forget to use RCT_EXPORT_MODULE()?" pop up on every launch. This change resolves that issue. Fixes #14806 . This supersedes PR #19794 . Try a fresh project by following the RN iOS tutorial, and observe that there are no more warnings after making this change. [IOS] [MINOR] [CxxBridge] - Fix "Class RCTCxxModule was not exported" Closes https://github.com/facebook/react-native/pull/19880 Differential Revision: D8653809 Pulled By: hramos fbshipit-source-id: c48529c2d74ddd40a90bc0e06e405078e25b72e3 --- React/Base/RCTBridge.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 3995143a90..b79da67d50 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -98,6 +98,9 @@ void RCTVerifyAllModulesExported(NSArray *extraModules) for (unsigned int i = 0; i < classCount; i++) { Class cls = classes[i]; + if (strncmp(class_getName(cls), "RCTCxxModule", strlen("RCTCxxModule")) == 0) { + continue; + } Class superclass = cls; while (superclass) { if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule))) { From 0f66e3a3801fcc34356c54828d18ed4e73da7581 Mon Sep 17 00:00:00 2001 From: Mehdi Mulani Date: Mon, 23 Jul 2018 14:44:20 -0700 Subject: [PATCH 066/143] Use module copies in RCTBridge APIs Summary: This array can be modified while it's being iterated, so we need to take a copy. I also found another crash and guarded against it. Reviewed By: fkgozali Differential Revision: D8955708 fbshipit-source-id: 76250bc5d451776e74505733c0f3c14e555fb576 --- React/Base/RCTBridge.m | 2 +- React/CxxBridge/RCTCxxBridge.mm | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index b79da67d50..3a310e8d4d 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -238,7 +238,7 @@ - (id)moduleForClass:(Class)moduleClass - (NSArray *)modulesConformingToProtocol:(Protocol *)protocol { NSMutableArray *modules = [NSMutableArray new]; - for (Class moduleClass in self.moduleClasses) { + for (Class moduleClass in [self.moduleClasses copy]) { if ([moduleClass conformsToProtocol:protocol]) { id module = [self moduleForClass:moduleClass]; if (module) { diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 6aaa0df1cb..59e0d13d1c 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -532,8 +532,9 @@ - (NSArray *)configForModuleName:(NSString *)moduleName RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge initModulesWithDispatchGroup:] autoexported moduleData", nil); - NSMutableArray *moduleDataByID = [NSMutableArray arrayWithCapacity:moduleClasses.count]; - for (Class moduleClass in moduleClasses) { + NSArray *moduleClassesCopy = [moduleClasses copy]; + NSMutableArray *moduleDataByID = [NSMutableArray arrayWithCapacity:moduleClassesCopy.count]; + for (Class moduleClass in moduleClassesCopy) { NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass); // Don't initialize the old executor in the new bridge. From c92115ecf7fcd5bad44994f92ba496cc8135a9c1 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 24 Jul 2018 19:42:06 -0700 Subject: [PATCH 067/143] Catch JS bundle load failure and prevent calls to JS after that Summary: There are cases where JS bundle fails to be evaluated, which throws an exception already, but then there were pending calls into JS which would fail in a weird way. This prevents those calls (because it's mostly meaningless at that point). For now, those extra calls will still throw an exception, but with a specific message so that it doesn't confuse people. Reviewed By: yungsters Differential Revision: D8961622 fbshipit-source-id: 3f67fb63fdfa9fc5b249de0096e893b07956776a --- ReactCommon/cxxreact/NativeToJsBridge.cpp | 35 ++++++++++++++++++----- ReactCommon/cxxreact/NativeToJsBridge.h | 5 ++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp index f8ae2856e6..2375945c18 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Instance.h" #include "JSBigString.h" @@ -95,7 +96,8 @@ void NativeToJsBridge::loadApplication( std::unique_ptr startupScript, std::string startupScriptSourceURL) { runOnExecutorQueue( - [bundleRegistryWrap=folly::makeMoveWrapper(std::move(bundleRegistry)), + [this, + bundleRegistryWrap=folly::makeMoveWrapper(std::move(bundleRegistry)), startupScript=folly::makeMoveWrapper(std::move(startupScript)), startupScriptSourceURL=std::move(startupScriptSourceURL)] (JSExecutor* executor) mutable { @@ -103,8 +105,13 @@ void NativeToJsBridge::loadApplication( if (bundleRegistry) { executor->setBundleRegistry(std::move(bundleRegistry)); } - executor->loadApplicationScript(std::move(*startupScript), - std::move(startupScriptSourceURL)); + try { + executor->loadApplicationScript(std::move(*startupScript), + std::move(startupScriptSourceURL)); + } catch (...) { + m_applicationScriptHasFailure = true; + throw; + } }); } @@ -115,8 +122,13 @@ void NativeToJsBridge::loadApplicationSync( if (bundleRegistry) { m_executor->setBundleRegistry(std::move(bundleRegistry)); } - m_executor->loadApplicationScript(std::move(startupScript), - std::move(startupScriptSourceURL)); + try { + m_executor->loadApplicationScript(std::move(startupScript), + std::move(startupScriptSourceURL)); + } catch (...) { + m_applicationScriptHasFailure = true; + throw; + } } void NativeToJsBridge::callFunction( @@ -132,8 +144,13 @@ void NativeToJsBridge::callFunction( systraceCookie); #endif - runOnExecutorQueue([module = std::move(module), method = std::move(method), arguments = std::move(arguments), systraceCookie] + runOnExecutorQueue([this, module = std::move(module), method = std::move(method), arguments = std::move(arguments), systraceCookie] (JSExecutor* executor) { + if (m_applicationScriptHasFailure) { + LOG(ERROR) << "Attempting to call JS function on a bad application bundle: " << module.c_str() << "." << method.c_str() << "()"; + throw std::runtime_error("Attempting to call JS function on a bad application bundle: " + module + "." + method + "()"); + } + #ifdef WITH_FBSYSTRACE FbSystraceAsyncFlow::end( TRACE_TAG_REACT_CXX_BRIDGE, @@ -158,8 +175,12 @@ void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& argume systraceCookie); #endif - runOnExecutorQueue([callbackId, arguments = std::move(arguments), systraceCookie] + runOnExecutorQueue([this, callbackId, arguments = std::move(arguments), systraceCookie] (JSExecutor* executor) { + if (m_applicationScriptHasFailure) { + LOG(ERROR) << "Attempting to call JS callback on a bad application bundle: " << callbackId; + throw std::runtime_error("Attempting to invoke JS callback on a bad application bundle."); + } #ifdef WITH_FBSYSTRACE FbSystraceAsyncFlow::end( TRACE_TAG_REACT_CXX_BRIDGE, diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h index 586766e387..10047ab086 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/ReactCommon/cxxreact/NativeToJsBridge.h @@ -123,6 +123,11 @@ class NativeToJsBridge { std::unique_ptr m_executor; std::shared_ptr m_executorMessageQueueThread; + // Keep track of whether the JS bundle containing the application logic causes + // exception when evaluated initially. If so, more calls to JS will very + // likely fail as well, so this flag can help prevent them. + bool m_applicationScriptHasFailure = false; + #ifdef WITH_FBSYSTRACE std::atomic_uint_least32_t m_systraceCookie = ATOMIC_VAR_INIT(); #endif From 4954f68ad2de9f2a82d012a4dc0f3a6c66e4eedd Mon Sep 17 00:00:00 2001 From: magicien Date: Mon, 10 Sep 2018 17:45:04 -0700 Subject: [PATCH 068/143] Fix #18272 TextInput.setNativeProps({text: ''}) to work (#18278) Summary: Fix #18272. Calling textInputRef.setNativeProps({text: ''}) or textInputRef.clear() should clear the text input. - All tests of `yarn run test` are passed - Test with [the sample app](https://github.com/magicien/react-native-textinput-clear). - TextInput.clear() and TextInput.setNativeProps({ text: '***' }) worked - When clear() or setNativeProps() called, onChange/onChangeText wasn't called - Same behavior as react 0.53.0 - When non-string values are given to `setNativeProps({text: ___})`, its behavior is the same as react 0.53.0. - Value Type | Result ---------- | ------------ null | same as empty string '' undefined | nothing changes number | throw error function | throw error object | throw error - When clear() or setNativeProps() called, attributed text keeps the attributes - When `value` prop is set, the text can't be changed - `clear()` doesn't work from the second time - `setNativeProps({text '***'})` doesn't work from the second time - Even when `value` prop is set, you can change the text ![ScreenShot_0.54.0](https://raw.githubusercontent.com/magicien/react-native-textinput-clear/master/screenshot/0.54.0_test.gif) - `clear()` works every time - `setNativeProps({text '****'})` works every time ![ScreenShot_Clear_1](https://raw.githubusercontent.com/magicien/react-native-textinput-clear/master/screenshot/clear_test_1.gif) ![ScreenShot_Clear_2](https://raw.githubusercontent.com/magicien/react-native-textinput-clear/master/screenshot/clear_test_2.gif) - The text keeps the attributes (font family, size, color, text align) ![ScreenShot_Slider](https://raw.githubusercontent.com/magicien/react-native-textinput-clear/master/screenshot/attributed_text_test.gif) - If `value` prop is set, the text should not be changed ![ScreenShot_Value](https://raw.githubusercontent.com/magicien/react-native-textinput-clear/master/screenshot/value_test.gif) [IOS] [BUGFIX] [TextInput] - Fix TextInput.clear() and TextInput.setNativeProps({text: ''}) to work Pull Request resolved: https://github.com/facebook/react-native/pull/18278 Reviewed By: shergin Differential Revision: D9692561 Pulled By: hramos fbshipit-source-id: b7ce8f6740fdf666e71d6a85743331ca4805edcb --- .../Text/TextInput/RCTBaseTextInputShadowView.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index 80b6578ced..1e56989396 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -25,6 +25,7 @@ @implementation RCTBaseTextInputShadowView NSAttributedString *_Nullable _localAttributedText; CGSize _previousContentSize; + NSString *_text; NSTextStorage *_textStorage; NSTextContainer *_textContainer; NSLayoutManager *_layoutManager; @@ -103,6 +104,20 @@ - (void)invalidateContentSize }); } +- (NSString *)text +{ + return _text; +} + +- (void)setText:(NSString *)text +{ + _text = text; + // Clear `_previousAttributedText` to notify the view about the change + // when `text` native prop is set. + _previousAttributedText = nil; + [self dirtyLayout]; +} + #pragma mark - RCTUIManagerObserver - (void)uiManagerWillPerformMounting From bff1e1f855cd0b0d64f9c44730cc2381bb0ec46e Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 2 Nov 2018 11:23:40 -0700 Subject: [PATCH 069/143] Added lock around RN module initialization to fix crash Summary: T35879909 is a UBN caused by a race condition in RN initialization. I haven't been able to repro, but the crash logs point to a bad memory access in this method. Another thread must be deallocating something concurrently. This is a quick fix to patch into v197. Reviewed By: fkgozali Differential Revision: D12904277 fbshipit-source-id: 5740183f9a7c8f2c45ca627662891cb0c1048764 --- React/CxxBridge/RCTCxxBridge.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 59e0d13d1c..da89edd06b 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -682,9 +682,11 @@ - (void)registerExtraModules - (void)registerAdditionalModuleClasses:(NSArray *)modules { - NSArray *newModules = [self _initializeModules:modules withDispatchGroup:NULL lazilyDiscovered:YES]; - if (_reactInstance) { - _reactInstance->getModuleRegistry().registerModules(createNativeModules(newModules, self, _reactInstance)); + @synchronized (self) { + NSArray *newModules = [self _initializeModules:modules withDispatchGroup:NULL lazilyDiscovered:YES]; + if (_reactInstance) { + _reactInstance->getModuleRegistry().registerModules(createNativeModules(newModules, self, _reactInstance)); + } } } From 0bc7e76cc6ce2ac5542fafe9fed737f8166a72e1 Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 2 Nov 2018 18:16:43 -0700 Subject: [PATCH 070/143] Added locking around RN bridge cxx module registry to avoid crash Summary: D12904277 was my sad, optimistic attempt to fix this crash. As @[100006577537606:Slobodan] mentioned on T35879909, the real issue is that moduleRegistry is being created (using _moduleDataByID dict) concurrently while we try to append to this dict. I added locks around these usage of _moduleDataByID. Reviewed By: fkgozali Differential Revision: D12911108 fbshipit-source-id: 2435b7a477c27585898f351c4a0d4c1bd4056756 --- React/CxxBridge/RCTCxxBridge.mm | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index da89edd06b..7b752f8e0f 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -158,6 +158,7 @@ @implementation RCTCxxBridge { BOOL _wasBatchActive; BOOL _didInvalidate; + BOOL _moduleRegistryCreated; NSMutableArray *_pendingCalls; std::atomic _pendingCount; @@ -172,6 +173,7 @@ @implementation RCTCxxBridge // JS thread management NSThread *_jsThread; std::shared_ptr _jsMessageThread; + std::mutex _moduleRegistryLock; // This is uniquely owned, but weak_ptr is used. std::shared_ptr _reactInstance; @@ -219,9 +221,9 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge */ _valid = YES; _loading = YES; + _moduleRegistryCreated = NO; _pendingCalls = [NSMutableArray new]; _displayLink = [RCTDisplayLink new]; - _moduleDataByName = [NSMutableDictionary new]; _moduleClassesByID = [NSMutableArray new]; _moduleDataByID = [NSMutableArray new]; @@ -456,7 +458,7 @@ - (BOOL)moduleIsInitialized:(Class)moduleClass return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance; } -- (std::shared_ptr)_buildModuleRegistry +- (std::shared_ptr)_buildModuleRegistryUnlocked { if (!self.valid) { return {}; @@ -503,12 +505,7 @@ - (void)_initializeBridge:(std::shared_ptr)executorFactory executorFactory = std::make_shared(self, executorFactory); #endif - // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance - _reactInstance->initializeBridge( - std::make_unique(self), - executorFactory, - _jsMessageThread, - [self _buildModuleRegistry]); + [self _initializeBridgeLocked:executorFactory]; #if RCT_PROFILE if (RCTProfileIsProfiling()) { @@ -522,6 +519,19 @@ - (void)_initializeBridge:(std::shared_ptr)executorFactory RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); } +- (void)_initializeBridgeLocked:(std::shared_ptr)executorFactory +{ + std::lock_guard guard(_moduleRegistryLock); + + // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance + _reactInstance->initializeBridge( + std::make_unique(self), + executorFactory, + _jsMessageThread, + [self _buildModuleRegistryUnlocked]); + _moduleRegistryCreated = YES; +} + - (NSArray *)configForModuleName:(NSString *)moduleName { return _moduleDataByName[moduleName].config; @@ -682,11 +692,13 @@ - (void)registerExtraModules - (void)registerAdditionalModuleClasses:(NSArray *)modules { - @synchronized (self) { + std::lock_guard guard(_moduleRegistryLock); + if (_moduleRegistryCreated) { NSArray *newModules = [self _initializeModules:modules withDispatchGroup:NULL lazilyDiscovered:YES]; - if (_reactInstance) { - _reactInstance->getModuleRegistry().registerModules(createNativeModules(newModules, self, _reactInstance)); - } + assert(_reactInstance); // at this point you must have reactInstance as you already called reactInstance->initialzeBridge + _reactInstance->getModuleRegistry().registerModules(createNativeModules(newModules, self, _reactInstance)); + } else { + [self registerModulesForClasses:modules]; } } From c9426aaa810f3bc02ff427336be0689309c72e7f Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 9 Nov 2018 17:11:58 -0800 Subject: [PATCH 071/143] Reset module registry flag when resetting React Instance Summary: D12911108 fixed a UBN race condition by adding a flag for module registry. This flag was never reset if react instance gets reset, causing an assert to fire in IG. Reviewed By: fkgozali Differential Revision: D13010651 fbshipit-source-id: e20453f3c546d759a58fd7fb93553f774410905f --- React/CxxBridge/RCTCxxBridge.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 7b752f8e0f..363062496a 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -837,6 +837,7 @@ - (void)handleError:(NSError *)error _loading = NO; _valid = NO; + _moduleRegistryCreated = NO; dispatch_async(dispatch_get_main_queue(), ^{ if (self->_jsMessageThread) { @@ -930,6 +931,7 @@ - (void)invalidate _loading = NO; _valid = NO; _didInvalidate = YES; + _moduleRegistryCreated = NO; if ([RCTBridge currentBridge] == self) { [RCTBridge setCurrentBridge:nil]; From 0b9d2c089219ebe068f34964596ac9d3b45e2992 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 21 Jan 2019 00:24:48 -0800 Subject: [PATCH 072/143] Fix isBatchActive of RCTCxxBridge (#22785) Summary: Seems we lost handler of `isBatchActive` from [RCTBatchedBridge a86171a](https://github.com/facebook/react-native/blob/a86171a48284c440226a79a26c6d6a4704d401e9/React/Base/RCTBatchedBridge.m) to [RCTCxxBridge 5bc7e39](https://github.com/facebook/react-native/commit/b774820dc29eae5a09e570384636d353afe213c2#diff-a2a67635fffd7b690d14dc17ae563a71). Changelog: ---------- [iOS] [fixed] - Fix isBatchActive of RCTCxxBridge Pull Request resolved: https://github.com/facebook/react-native/pull/22785 Reviewed By: mhorowitz Differential Revision: D13731897 Pulled By: cpojer fbshipit-source-id: 8d6b85bcea8fe8997a93b4e1ac8b8007422ca20e --- React/CxxBridge/RCTCxxBridge.mm | 3 +-- ReactCommon/cxxreact/Instance.cpp | 4 ++++ ReactCommon/cxxreact/Instance.h | 1 + ReactCommon/cxxreact/NativeToJsBridge.cpp | 8 ++++++++ ReactCommon/cxxreact/NativeToJsBridge.h | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 363062496a..96c727583b 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -156,7 +156,6 @@ void onBatchComplete() override { @implementation RCTCxxBridge { - BOOL _wasBatchActive; BOOL _didInvalidate; BOOL _moduleRegistryCreated; @@ -1308,7 +1307,7 @@ - (void)stopProfiling:(void (^)(NSData *))callback - (BOOL)isBatchActive { - return _wasBatchActive; + return _reactInstance ? _reactInstance->isBatchActive() : NO; } @end diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp index c3fd8cf607..d5581bd560 100644 --- a/ReactCommon/cxxreact/Instance.cpp +++ b/ReactCommon/cxxreact/Instance.cpp @@ -147,6 +147,10 @@ bool Instance::isInspectable() { return nativeToJsBridge_ ? nativeToJsBridge_->isInspectable() : false; } +bool Instance::isBatchActive() { + return nativeToJsBridge_ ? nativeToJsBridge_->isBatchActive() : false; +} + void Instance::callJSFunction(std::string &&module, std::string &&method, folly::dynamic &¶ms) { callback_->incrementPendingJSCalls(); diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h index bcd0bea395..a47fc787a8 100644 --- a/ReactCommon/cxxreact/Instance.h +++ b/ReactCommon/cxxreact/Instance.h @@ -56,6 +56,7 @@ class RN_EXPORT Instance { std::unique_ptr jsonValue); void *getJavaScriptContext(); bool isInspectable(); + bool isBatchActive(); void callJSFunction(std::string &&module, std::string &&method, folly::dynamic &¶ms); void callJSCallback(uint64_t callbackId, folly::dynamic &¶ms); diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp index 2375945c18..a84a298c1e 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -34,6 +34,10 @@ class JsToNativeBridge : public react::ExecutorDelegate { return m_registry; } + bool isBatchActive() { + return m_batchHadNativeModuleCalls; + } + void callNativeModules( JSExecutor& executor, folly::dynamic&& calls, bool isEndOfBatch) override { @@ -215,6 +219,10 @@ bool NativeToJsBridge::isInspectable() { return m_executor->isInspectable(); } +bool NativeToJsBridge::isBatchActive() { + return m_delegate->isBatchActive(); +} + #ifdef WITH_JSC_MEMORY_PRESSURE void NativeToJsBridge::handleMemoryPressure(int pressureLevel) { runOnExecutorQueue([=] (JSExecutor* executor) { diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h index 10047ab086..7e4f05639b 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/ReactCommon/cxxreact/NativeToJsBridge.h @@ -102,6 +102,7 @@ class NativeToJsBridge { void setGlobalVariable(std::string propName, std::unique_ptr jsonValue); void* getJavaScriptContext(); bool isInspectable(); + bool isBatchActive(); #ifdef WITH_JSC_MEMORY_PRESSURE void handleMemoryPressure(int pressureLevel); From 42a9a5f9fd893cdf4eda41a0d5a5745b7951d518 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 11:58:07 -0500 Subject: [PATCH 073/143] fix: use AppKit equivalents of UIKit classes Only classes with feature parity are substituted in this commit. --- .../Text/BaseText/RCTBaseTextViewManager.m | 10 ++--- Libraries/Text/RCTTextAttributes.h | 18 ++++----- Libraries/Text/RCTTextAttributes.m | 20 +++++----- .../Text/RawText/RCTRawTextViewManager.m | 4 +- .../Text/Text/NSTextStorage+FontScaling.h | 2 +- .../Text/Text/NSTextStorage+FontScaling.m | 4 +- Libraries/Text/Text/RCTTextShadowView.m | 10 ++--- Libraries/Text/Text/RCTTextView.h | 6 +-- Libraries/Text/Text/RCTTextView.m | 38 ++++++------------- Libraries/Text/Text/RCTTextViewManager.m | 2 +- .../Multiline/RCTMultilineTextInputView.m | 12 +++--- .../RCTMultilineTextInputViewManager.m | 2 +- .../Text/TextInput/Multiline/RCTUITextView.h | 8 ++-- .../Text/TextInput/Multiline/RCTUITextView.m | 22 +++++------ .../TextInput/RCTBackedTextInputDelegate.h | 2 +- .../RCTBackedTextInputDelegateAdapter.h | 10 ++--- .../RCTBackedTextInputDelegateAdapter.m | 4 +- .../RCTBackedTextInputViewProtocol.h | 12 +++--- .../TextInput/RCTBaseTextInputShadowView.m | 8 ++-- .../Text/TextInput/RCTBaseTextInputView.h | 8 ++-- .../Text/TextInput/RCTBaseTextInputView.m | 14 +++---- .../TextInput/RCTBaseTextInputViewManager.m | 4 +- .../Singleline/RCTSinglelineTextInputView.m | 2 +- .../RCTSinglelineTextInputViewManager.m | 2 +- .../TextInput/Singleline/RCTUITextField.h | 10 ++--- .../TextInput/Singleline/RCTUITextField.m | 10 ++--- .../VirtualText/RCTVirtualTextViewManager.m | 4 +- .../RCTSurfaceSizeMeasureMode.mm | 2 +- React/Views/RCTLayout.h | 12 +++--- React/Views/RCTLayout.m | 28 +++++++++----- React/Views/RCTShadowView.h | 2 +- React/Views/RCTShadowView.m | 7 +++- .../ScrollView/RCTScrollContentShadowView.m | 2 +- 33 files changed, 150 insertions(+), 151 deletions(-) diff --git a/Libraries/Text/BaseText/RCTBaseTextViewManager.m b/Libraries/Text/BaseText/RCTBaseTextViewManager.m index 89640c7e9a..207608af28 100644 --- a/Libraries/Text/BaseText/RCTBaseTextViewManager.m +++ b/Libraries/Text/BaseText/RCTBaseTextViewManager.m @@ -13,7 +13,7 @@ @implementation RCTBaseTextViewManager RCT_EXPORT_MODULE(RCTBaseText) -- (UIView *)view +- (NSView *)view { RCTAssert(NO, @"The `-[RCTBaseTextViewManager view]` property must be overridden in subclass."); return nil; @@ -28,8 +28,8 @@ - (RCTShadowView *)shadowView #pragma mark - Text Attributes // Color -RCT_REMAP_SHADOW_PROPERTY(color, textAttributes.foregroundColor, UIColor) -RCT_REMAP_SHADOW_PROPERTY(backgroundColor, textAttributes.backgroundColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(color, textAttributes.foregroundColor, NSColor) +RCT_REMAP_SHADOW_PROPERTY(backgroundColor, textAttributes.backgroundColor, NSColor) RCT_REMAP_SHADOW_PROPERTY(opacity, textAttributes.opacity, CGFloat) // Font RCT_REMAP_SHADOW_PROPERTY(fontFamily, textAttributes.fontFamily, NSString) @@ -44,13 +44,13 @@ - (RCTShadowView *)shadowView RCT_REMAP_SHADOW_PROPERTY(textAlign, textAttributes.alignment, NSTextAlignment) RCT_REMAP_SHADOW_PROPERTY(writingDirection, textAttributes.baseWritingDirection, NSWritingDirection) // Decoration -RCT_REMAP_SHADOW_PROPERTY(textDecorationColor, textAttributes.textDecorationColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(textDecorationColor, textAttributes.textDecorationColor, NSColor) RCT_REMAP_SHADOW_PROPERTY(textDecorationStyle, textAttributes.textDecorationStyle, NSUnderlineStyle) RCT_REMAP_SHADOW_PROPERTY(textDecorationLine, textAttributes.textDecorationLine, RCTTextDecorationLineType) // Shadow RCT_REMAP_SHADOW_PROPERTY(textShadowOffset, textAttributes.textShadowOffset, CGSize) RCT_REMAP_SHADOW_PROPERTY(textShadowRadius, textAttributes.textShadowRadius, CGFloat) -RCT_REMAP_SHADOW_PROPERTY(textShadowColor, textAttributes.textShadowColor, UIColor) +RCT_REMAP_SHADOW_PROPERTY(textShadowColor, textAttributes.textShadowColor, NSColor) // Special RCT_REMAP_SHADOW_PROPERTY(isHighlighted, textAttributes.isHighlighted, BOOL) diff --git a/Libraries/Text/RCTTextAttributes.h b/Libraries/Text/RCTTextAttributes.h index 7752c2c66b..32e6d24ef6 100644 --- a/Libraries/Text/RCTTextAttributes.h +++ b/Libraries/Text/RCTTextAttributes.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import @@ -24,8 +24,8 @@ extern NSString *const RCTTextAttributesTagAttributeName; @interface RCTTextAttributes : NSObject // Color -@property (nonatomic, strong, nullable) UIColor *foregroundColor; -@property (nonatomic, strong, nullable) UIColor *backgroundColor; +@property (nonatomic, strong, nullable) NSColor *foregroundColor; +@property (nonatomic, strong, nullable) NSColor *backgroundColor; @property (nonatomic, assign) CGFloat opacity; // Font @property (nonatomic, copy, nullable) NSString *fontFamily; @@ -41,17 +41,17 @@ extern NSString *const RCTTextAttributesTagAttributeName; @property (nonatomic, assign) NSTextAlignment alignment; @property (nonatomic, assign) NSWritingDirection baseWritingDirection; // Decoration -@property (nonatomic, strong, nullable) UIColor *textDecorationColor; +@property (nonatomic, strong, nullable) NSColor *textDecorationColor; @property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; @property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine; // Shadow @property (nonatomic, assign) CGSize textShadowOffset; @property (nonatomic, assign) CGFloat textShadowRadius; -@property (nonatomic, strong, nullable) UIColor *textShadowColor; +@property (nonatomic, strong, nullable) NSColor *textShadowColor; // Special @property (nonatomic, assign) BOOL isHighlighted; @property (nonatomic, strong, nullable) NSNumber *tag; -@property (nonatomic, assign) UIUserInterfaceLayoutDirection layoutDirection; +@property (nonatomic, assign) NSUserInterfaceLayoutDirection layoutDirection; #pragma mark - Inheritance @@ -67,7 +67,7 @@ extern NSString *const RCTTextAttributesTagAttributeName; /** * Constructed font. */ -- (UIFont *)effectiveFont; +- (NSFont *)effectiveFont; /** * Font size multiplier reflects `allowFontScaling` and `fontSizeMultiplier`. @@ -77,8 +77,8 @@ extern NSString *const RCTTextAttributesTagAttributeName; /** * Foreground and background colors with opacity and right defaults. */ -- (UIColor *)effectiveForegroundColor; -- (UIColor *)effectiveBackgroundColor; +- (NSColor *)effectiveForegroundColor; +- (NSColor *)effectiveBackgroundColor; @end diff --git a/Libraries/Text/RCTTextAttributes.m b/Libraries/Text/RCTTextAttributes.m index 26d63bdda8..530b5dcb3a 100644 --- a/Libraries/Text/RCTTextAttributes.m +++ b/Libraries/Text/RCTTextAttributes.m @@ -73,7 +73,7 @@ - (void)applyTextAttributes:(RCTTextAttributes *)textAttributes // Special _isHighlighted = textAttributes->_isHighlighted || _isHighlighted; // * _tag = textAttributes->_tag ?: _tag; - _layoutDirection = textAttributes->_layoutDirection != UIUserInterfaceLayoutDirectionLeftToRight ? textAttributes->_layoutDirection : _layoutDirection; + _layoutDirection = textAttributes->_layoutDirection != NSUserInterfaceLayoutDirectionLeftToRight ? textAttributes->_layoutDirection : _layoutDirection; } - (NSDictionary *)effectiveTextAttributes @@ -82,13 +82,13 @@ - (void)applyTextAttributes:(RCTTextAttributes *)textAttributes [NSMutableDictionary dictionaryWithCapacity:10]; // Font - UIFont *font = self.effectiveFont; + NSFont *font = self.effectiveFont; if (font) { attributes[NSFontAttributeName] = font; } // Colors - UIColor *effectiveForegroundColor = self.effectiveForegroundColor; + NSColor *effectiveForegroundColor = self.effectiveForegroundColor; if (_foregroundColor || !isnan(_opacity)) { attributes[NSForegroundColorAttributeName] = effectiveForegroundColor; @@ -108,7 +108,7 @@ - (void)applyTextAttributes:(RCTTextAttributes *)textAttributes BOOL isParagraphStyleUsed = NO; if (_alignment != NSTextAlignmentNatural) { NSTextAlignment alignment = _alignment; - if (_layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) { + if (_layoutDirection == NSUserInterfaceLayoutDirectionRightToLeft) { if (alignment == NSTextAlignmentRight) { alignment = NSTextAlignmentLeft; } else if (alignment == NSTextAlignmentLeft) { @@ -176,7 +176,7 @@ - (void)applyTextAttributes:(RCTTextAttributes *)textAttributes return [attributes copy]; } -- (UIFont *)effectiveFont +- (NSFont *)effectiveFont { // FIXME: RCTFont has thread-safety issues and must be rewritten. return [RCTFont updateFont:nil @@ -193,9 +193,9 @@ - (CGFloat)effectiveFontSizeMultiplier return _allowFontScaling && !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0; } -- (UIColor *)effectiveForegroundColor +- (NSColor *)effectiveForegroundColor { - UIColor *effectiveForegroundColor = _foregroundColor ?: [UIColor blackColor]; + NSColor *effectiveForegroundColor = _foregroundColor ?: [NSColor blackColor]; if (!isnan(_opacity)) { effectiveForegroundColor = [effectiveForegroundColor colorWithAlphaComponent:CGColorGetAlpha(effectiveForegroundColor.CGColor) * _opacity]; @@ -204,15 +204,15 @@ - (UIColor *)effectiveForegroundColor return effectiveForegroundColor; } -- (UIColor *)effectiveBackgroundColor +- (NSColor *)effectiveBackgroundColor { - UIColor *effectiveBackgroundColor = _backgroundColor;// ?: [[UIColor whiteColor] colorWithAlphaComponent:0]; + NSColor *effectiveBackgroundColor = _backgroundColor;// ?: [[NSColor whiteColor] colorWithAlphaComponent:0]; if (effectiveBackgroundColor && !isnan(_opacity)) { effectiveBackgroundColor = [effectiveBackgroundColor colorWithAlphaComponent:CGColorGetAlpha(effectiveBackgroundColor.CGColor) * _opacity]; } - return effectiveBackgroundColor ?: [UIColor clearColor]; + return effectiveBackgroundColor ?: [NSColor clearColor]; } - (RCTTextAttributes *)copyWithZone:(NSZone *)zone diff --git a/Libraries/Text/RawText/RCTRawTextViewManager.m b/Libraries/Text/RawText/RCTRawTextViewManager.m index 17233cdc79..3aea9e8f25 100644 --- a/Libraries/Text/RawText/RCTRawTextViewManager.m +++ b/Libraries/Text/RawText/RCTRawTextViewManager.m @@ -15,9 +15,9 @@ @implementation RCTRawTextViewManager RCT_EXPORT_MODULE(RCTRawText) -- (UIView *)view +- (NSView *)view { - return [UIView new]; + return [NSView new]; } - (RCTShadowView *)shadowView diff --git a/Libraries/Text/Text/NSTextStorage+FontScaling.h b/Libraries/Text/Text/NSTextStorage+FontScaling.h index f3ea09ab26..9abc3c45f8 100644 --- a/Libraries/Text/Text/NSTextStorage+FontScaling.h +++ b/Libraries/Text/Text/NSTextStorage+FontScaling.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import @interface NSTextStorage (FontScaling) diff --git a/Libraries/Text/Text/NSTextStorage+FontScaling.m b/Libraries/Text/Text/NSTextStorage+FontScaling.m index 4233bef967..60f73eac60 100644 --- a/Libraries/Text/Text/NSTextStorage+FontScaling.m +++ b/Libraries/Text/Text/NSTextStorage+FontScaling.m @@ -120,7 +120,7 @@ - (void)scaleFontSizeWithRatio:(CGFloat)ratio inRange:(NSRange){0, self.length} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock: - ^(UIFont *_Nullable font, NSRange range, BOOL *_Nonnull stop) { + ^(NSFont *_Nullable font, NSRange range, BOOL *_Nonnull stop) { if (!font) { return; } @@ -128,7 +128,7 @@ - (void)scaleFontSizeWithRatio:(CGFloat)ratio CGFloat fontSize = MAX(MIN(font.pointSize * ratio, maximumFontSize), minimumFontSize); [self addAttribute:NSFontAttributeName - value:[font fontWithSize:fontSize] + value:[NSFont fontWithDescriptor:font.fontDescriptor size:fontSize] range:range]; } ]; diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index f423726313..ea72fc310b 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -86,16 +86,16 @@ - (void)uiManagerWillPerformMounting } ]; - [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { RCTTextView *textView = (RCTTextView *)viewRegistry[tag]; if (!textView) { return; } - NSMutableArray *descendantViews = + NSMutableArray *descendantViews = [NSMutableArray arrayWithCapacity:descendantViewTags.count]; [descendantViewTags enumerateObjectsUsingBlock:^(NSNumber *_Nonnull descendantViewTag, NSUInteger index, BOOL *_Nonnull stop) { - UIView *descendantView = viewRegistry[descendantViewTag]; + NSView *descendantView = viewRegistry[descendantViewTag]; if (!descendantView) { return; } @@ -140,7 +140,7 @@ - (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText inRange:NSMakeRange(0, attributedText.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock: - ^(UIFont *font, NSRange range, __unused BOOL *stop) { + ^(NSFont *font, NSRange range, __unused BOOL *stop) { if (!font) { return; } @@ -280,7 +280,7 @@ - (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext CGSize attachmentSize = attachment.bounds.size; - UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil]; + NSFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil]; CGRect frame = {{ RCTRoundPixelValue(glyphRect.origin.x), diff --git a/Libraries/Text/Text/RCTTextView.h b/Libraries/Text/Text/RCTTextView.h index c8ba22adcb..00a64787ec 100644 --- a/Libraries/Text/Text/RCTTextView.h +++ b/Libraries/Text/Text/RCTTextView.h @@ -7,17 +7,17 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import NS_ASSUME_NONNULL_BEGIN -@interface RCTTextView : UIView +@interface RCTTextView : NSView @property (nonatomic, assign) BOOL selectable; - (void)setTextStorage:(NSTextStorage *)textStorage contentFrame:(CGRect)contentFrame - descendantViews:(NSArray *)descendantViews; + descendantViews:(NSArray *)descendantViews; @end diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index d065e8073a..ae340c47a4 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -12,7 +12,7 @@ #import #import -#import +#import #import "RCTTextShadowView.h" @@ -21,7 +21,7 @@ @implementation RCTTextView CAShapeLayer *_highlightLayer; UILongPressGestureRecognizer *_longPressGestureRecognizer; - NSArray *_Nullable _descendantViews; + NSArray *_Nullable _descendantViews; NSTextStorage *_Nullable _textStorage; CGRect _contentFrame; } @@ -77,19 +77,19 @@ - (void)didUpdateReactSubviews - (void)setTextStorage:(NSTextStorage *)textStorage contentFrame:(CGRect)contentFrame - descendantViews:(NSArray *)descendantViews + descendantViews:(NSArray *)descendantViews { _textStorage = textStorage; _contentFrame = contentFrame; // FIXME: Optimize this. - for (UIView *view in _descendantViews) { + for (NSView *view in _descendantViews) { [view removeFromSuperview]; } _descendantViews = descendantViews; - for (UIView *view in descendantViews) { + for (NSView *view in descendantViews) { [self addSubview:view]; } @@ -140,7 +140,7 @@ - (void)drawRect:(CGRect)rect if (highlightPath) { if (!_highlightLayer) { _highlightLayer = [CAShapeLayer layer]; - _highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor; + _highlightLayer.fillColor = [NSColor colorWithWhite:0 alpha:0.25].CGColor; [self.layer addSublayer:_highlightLayer]; } _highlightLayer.position = _contentFrame.origin; @@ -172,9 +172,9 @@ - (NSNumber *)reactTagAtPoint:(CGPoint)point return reactTag; } -- (void)didMoveToWindow +- (void)viewDidMoveToWindow { - [super didMoveToWindow]; + [super viewDidMoveToWindow]; if (!self.window) { self.layer.contents = nil; @@ -235,34 +235,20 @@ - (BOOL)canBecomeFirstResponder return _selectable; } -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender +- (BOOL)tryToPerform:(SEL)action with:(id)object { if (_selectable && action == @selector(copy:)) { return YES; } - return [self.nextResponder canPerformAction:action withSender:sender]; + return [self.nextResponder tryToPerform:action with:object]; } - (void)copy:(id)sender { #if !TARGET_OS_TV - NSAttributedString *attributedText = _textStorage; - - NSMutableDictionary *item = [NSMutableDictionary new]; - - NSData *rtf = [attributedText dataFromRange:NSMakeRange(0, attributedText.length) - documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType} - error:nil]; - - if (rtf) { - [item setObject:rtf forKey:(id)kUTTypeFlatRTFD]; - } - - [item setObject:attributedText.string forKey:(id)kUTTypeUTF8PlainText]; - - UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; - pasteboard.items = @[item]; + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard clearContents]; [pasteboard writeObjects:@[_textStorage]]; #endif } diff --git a/Libraries/Text/Text/RCTTextViewManager.m b/Libraries/Text/Text/RCTTextViewManager.m index 58b559de18..8f8b222d51 100644 --- a/Libraries/Text/Text/RCTTextViewManager.m +++ b/Libraries/Text/Text/RCTTextViewManager.m @@ -55,7 +55,7 @@ - (void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (UIView *)view +- (NSView *)view { return [RCTTextView new]; } diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m index d97c95172e..c7c4ed373e 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m @@ -25,9 +25,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge self.blurOnSubmit = NO; _backedTextInputView = [[RCTUITextView alloc] initWithFrame:self.bounds]; - _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _backedTextInputView.backgroundColor = [UIColor clearColor]; - _backedTextInputView.textColor = [UIColor blackColor]; + _backedTextInputView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _backedTextInputView.backgroundColor = [NSColor clearColor]; + _backedTextInputView.textColor = [NSColor blackColor]; // This line actually removes 5pt (default value) left and right padding in UITextView. _backedTextInputView.textContainer.lineFragmentPadding = 0; #if !TARGET_OS_TV @@ -50,9 +50,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return _backedTextInputView; } -#pragma mark - UIScrollViewDelegate +#pragma mark - NSScrollViewDelegate -- (void)scrollViewDidScroll:(UIScrollView *)scrollView +- (void)scrollViewDidScroll:(NSScrollView *)scrollView { RCTDirectEventBlock onScroll = self.onScroll; @@ -60,7 +60,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView CGPoint contentOffset = scrollView.contentOffset; CGSize contentSize = scrollView.contentSize; CGSize size = scrollView.bounds.size; - UIEdgeInsets contentInset = scrollView.contentInset; + NSEdgeInsets contentInset = scrollView.contentInset; onScroll(@{ @"contentOffset": @{ diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index de84955739..36beb97e3f 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -15,7 +15,7 @@ @implementation RCTMultilineTextInputViewManager RCT_EXPORT_MODULE() -- (UIView *)view +- (NSView *)view { return [[RCTMultilineTextInputView alloc] initWithBridge:self.bridge]; } diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index 104e105904..ef62b6bfb3 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" @@ -16,9 +16,9 @@ NS_ASSUME_NONNULL_BEGIN /* - * Just regular UITextView... but much better! + * Just regular NSTextView... but much better! */ -@interface RCTUITextView : UITextView +@interface RCTUITextView : NSTextView - (instancetype)initWithFrame:(CGRect)frame textContainer:(nullable NSTextContainer *)textContainer NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) UIColor *placeholderColor; +@property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 3462b833ff..ddf9dec960 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -10,7 +10,7 @@ #import "RCTUITextView.h" #import -#import +#import #import "RCTBackedTextInputDelegateAdapter.h" @@ -21,15 +21,15 @@ @implementation RCTUITextView RCTBackedTextViewDelegateAdapter *_textInputDelegateAdapter; } -static UIFont *defaultPlaceholderFont() +static NSFont *defaultPlaceholderFont() { - return [UIFont systemFontOfSize:17]; + return [NSFont systemFontOfSize:17]; } -static UIColor *defaultPlaceholderColor() +static NSColor *defaultPlaceholderColor() { // Default placeholder color from UITextField. - return [UIColor colorWithRed:0 green:0 blue:0.0980392 alpha:0.22]; + return [NSColor colorWithRed:0 green:0 blue:0.0980392 alpha:0.22]; } - (instancetype)initWithFrame:(CGRect)frame @@ -37,7 +37,7 @@ - (instancetype)initWithFrame:(CGRect)frame if (self = [super initWithFrame:frame]) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) - name:UITextViewTextDidChangeNotification + name:NSControlTextDidChangeNotification object:self]; _placeholderView = [[UILabel alloc] initWithFrame:self.bounds]; @@ -84,7 +84,7 @@ - (void)setPlaceholder:(NSString *)placeholder _placeholderView.text = _placeholder; } -- (void)setPlaceholderColor:(UIColor *)placeholderColor +- (void)setPlaceholderColor:(NSColor *)placeholderColor { _placeholderColor = placeholderColor; _placeholderView.textColor = _placeholderColor ?: defaultPlaceholderColor(); @@ -98,7 +98,7 @@ - (void)textDidChange #pragma mark - Overrides -- (void)setFont:(UIFont *)font +- (void)setFont:(NSFont *)font { [super setFont:font]; _placeholderView.font = font ?: defaultPlaceholderFont(); @@ -158,7 +158,7 @@ - (CGFloat)preferredMaxLayoutWidth - (CGSize)placeholderSize { - UIEdgeInsets textContainerInset = self.textContainerInset; + NSEdgeInsets textContainerInset = self.textContainerInset; NSString *placeholder = self.placeholder ?: @""; CGSize placeholderSize = [placeholder sizeWithAttributes:@{NSFontAttributeName: self.font ?: defaultPlaceholderFont()}]; placeholderSize = CGSizeMake(RCTCeilPixelValue(placeholderSize.width), RCTCeilPixelValue(placeholderSize.height)); @@ -184,7 +184,7 @@ - (void)layoutSubviews { [super layoutSubviews]; - CGRect textFrame = UIEdgeInsetsInsetRect(self.bounds, self.textContainerInset); + CGRect textFrame = NSEdgeInsetsInsetRect(self.bounds, self.textContainerInset); CGFloat placeholderHeight = [_placeholderView sizeThatFits:textFrame.size].height; textFrame.size.height = MIN(placeholderHeight, textFrame.size.height); _placeholderView.frame = textFrame; @@ -220,7 +220,7 @@ - (CGSize)fixedSizeThatFits:(CGSize)size } if (!_detachedTextView) { - _detachedTextView = [UITextView new]; + _detachedTextView = [NSTextView new]; } _detachedTextView.attributedText = self.attributedText; diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h index d124ef2ec5..ed6a4fd238 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import @protocol RCTBackedTextInputViewProtocol; diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index b9914c2355..b297190b5f 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -7,29 +7,29 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" #import "RCTBackedTextInputDelegate.h" NS_ASSUME_NONNULL_BEGIN -#pragma mark - RCTBackedTextFieldDelegateAdapter (for UITextField) +#pragma mark - RCTBackedTextFieldDelegateAdapter (for NSTextField) @interface RCTBackedTextFieldDelegateAdapter : NSObject -- (instancetype)initWithTextField:(UITextField *)backedTextInputView; +- (instancetype)initWithTextField:(NSTextField *)backedTextInputView; - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; - (void)selectedTextRangeWasSet; @end -#pragma mark - RCTBackedTextViewDelegateAdapter (for UITextView) +#pragma mark - RCTBackedTextViewDelegateAdapter (for NSTextView) @interface RCTBackedTextViewDelegateAdapter : NSObject -- (instancetype)initWithTextView:(UITextView *)backedTextInputView; +- (instancetype)initWithTextView:(NSTextView *)backedTextInputView; - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 856d708f6f..245f3a7273 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -9,7 +9,7 @@ #import "RCTBackedTextInputDelegateAdapter.h" -#pragma mark - RCTBackedTextFieldDelegateAdapter (for UITextField) +#pragma mark - RCTBackedTextFieldDelegateAdapter (for NSTextField) static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingContext; @@ -41,7 +41,7 @@ - (void)dealloc [_backedTextInputView removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit]; } -#pragma mark - UITextFieldDelegate +#pragma mark - NSTextFieldDelegate - (BOOL)textFieldShouldBeginEditing:(__unused UITextField *)textField { diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 32a2a6ae3e..ce20b7d5f7 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import @protocol RCTBackedTextInputDelegate; @@ -15,15 +15,15 @@ NS_ASSUME_NONNULL_BEGIN @protocol RCTBackedTextInputViewProtocol -@property (nonatomic, strong, nullable) UIColor *textColor; -@property (nonatomic, strong, nullable) UIFont *font; +@property (nonatomic, strong, nullable) NSColor *textColor; +@property (nonatomic, strong, nullable) NSFont *font; @property (nonatomic, copy, nullable) NSAttributedString *attributedText; @property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) UIColor *placeholderColor; +@property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) NSTextAlignment textAlignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, assign) UIEdgeInsets textContainerInset; -@property (nonatomic, strong, nullable) UIView *inputAccessoryView; +@property (nonatomic, assign) NSEdgeInsets textContainerInset; +@property (nonatomic, strong, nullable) NSView *inputAccessoryView; @property (nonatomic, weak, nullable) id textInputDelegate; @property (nonatomic, readonly) CGSize contentSize; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index 1e56989396..b4a045f19b 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -131,8 +131,8 @@ - (void)uiManagerWillPerformMounting } _needsUpdateView = NO; - UIEdgeInsets borderInsets = self.borderAsInsets; - UIEdgeInsets paddingInsets = self.paddingAsInsets; + NSEdgeInsets borderInsets = self.borderAsInsets; + NSEdgeInsets paddingInsets = self.paddingAsInsets; RCTTextAttributes *textAttributes = [self.textAttributes copy]; @@ -165,7 +165,7 @@ - (void)uiManagerWillPerformMounting NSNumber *tag = self.reactTag; - [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { RCTBaseTextInputView *baseTextInputView = (RCTBaseTextInputView *)viewRegistry[tag]; if (!baseTextInputView) { return; @@ -242,7 +242,7 @@ - (CGFloat)lastBaselineForSize:(CGSize)size inRange:NSMakeRange(0, attributedText.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock: - ^(UIFont *font, NSRange range, __unused BOOL *stop) { + ^(NSFont *font, NSRange range, __unused BOOL *stop) { if (maximumDescender > font.descender) { maximumDescender = font.descender; } diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index 56c8d2b947..9d50ef65ce 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import @@ -29,11 +29,11 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; -@property (nonatomic, readonly) UIView *backedTextInputView; +@property (nonatomic, readonly) NSView *backedTextInputView; @property (nonatomic, strong, nullable) RCTTextAttributes *textAttributes; -@property (nonatomic, assign) UIEdgeInsets reactPaddingInsets; -@property (nonatomic, assign) UIEdgeInsets reactBorderInsets; +@property (nonatomic, assign) NSEdgeInsets reactPaddingInsets; +@property (nonatomic, assign) NSEdgeInsets reactBorderInsets; @property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange; @property (nonatomic, copy, nullable) RCTDirectEventBlock onSelectionChange; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 2b00a8b047..e94a2127a5 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -15,7 +15,7 @@ #import #import #import -#import +#import #import "RCTTextAttributes.h" #import "RCTTextSelection.h" @@ -44,7 +44,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)decoder) RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) -- (UIView *)backedTextInputView +- (NSView *)backedTextInputView { RCTAssert(NO, @"-[RCTBaseTextInputView backedTextInputView] must be implemented in subclass."); return nil; @@ -77,7 +77,7 @@ - (void)enforceTextAttributesIfNeeded backedTextInputView.textAlignment = _textAttributes.alignment; } -- (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets +- (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets { _reactPaddingInsets = reactPaddingInsets; // We apply `paddingInsets` as `backedTextInputView`'s `textContainerInset`. @@ -85,11 +85,11 @@ - (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets [self setNeedsLayout]; } -- (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets +- (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets { _reactBorderInsets = reactBorderInsets; // We apply `borderInsets` as `backedTextInputView` layout offset. - self.backedTextInputView.frame = UIEdgeInsetsInsetRect(self.bounds, reactBorderInsets); + self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); [self setNeedsLayout]; } @@ -381,7 +381,7 @@ - (CGSize)sizeThatFits:(CGSize)size #pragma mark - Accessibility -- (UIView *)reactAccessibilityElement +- (NSView *)reactAccessibilityElement { return self.backedTextInputView; } @@ -413,7 +413,7 @@ - (void)didSetProps:(NSArray *)changedProps - (void)invalidateInputAccessoryView { #if !TARGET_OS_TV - UIView *textInputView = self.backedTextInputView; + NSView *textInputView = self.backedTextInputView; UIKeyboardType keyboardType = textInputView.keyboardType; // These keyboard types (all are number pads) don't have a "Done" button by default, diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 7e98eda2de..34dafbd0a6 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -42,10 +42,10 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) RCT_REMAP_VIEW_PROPERTY(keyboardType, backedTextInputView.keyboardType, UIKeyboardType) RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString) -RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, UIColor) +RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, NSColor) RCT_REMAP_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType) RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) -RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, UIColor) +RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, NSColor) RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m index 4f4959b636..d67b4b95ed 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m @@ -25,7 +25,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge self.blurOnSubmit = YES; _backedTextInputView = [[RCTUITextField alloc] initWithFrame:self.bounds]; - _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _backedTextInputView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; _backedTextInputView.textInputDelegate = self; [self addSubview:_backedTextInputView]; diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m index 6a74da53c9..3b854c8e26 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.m @@ -26,7 +26,7 @@ - (RCTShadowView *)shadowView return shadowView; } -- (UIView *)view +- (NSView *)view { return [[RCTSinglelineTextInputView alloc] initWithBridge:self.bridge]; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index 27ae073006..64e9ace0de 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -7,16 +7,16 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTBackedTextInputViewProtocol.h" NS_ASSUME_NONNULL_BEGIN /* - * Just regular UITextField... but much better! + * Just regular NSTextField... but much better! */ -@interface RCTUITextField : UITextField +@interface RCTUITextField : NSTextField - (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE; @@ -24,8 +24,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) BOOL caretHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, strong, nullable) UIColor *placeholderColor; -@property (nonatomic, assign) UIEdgeInsets textContainerInset; +@property (nonatomic, strong, nullable) NSColor *placeholderColor; +@property (nonatomic, assign) NSEdgeInsets textContainerInset; @property (nonatomic, assign, getter=isEditable) BOOL editable; @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 4b21e594b1..4285388b8f 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -10,7 +10,7 @@ #import "RCTUITextField.h" #import -#import +#import #import "RCTBackedTextInputDelegateAdapter.h" @@ -23,7 +23,7 @@ - (instancetype)initWithFrame:(CGRect)frame if (self = [super initWithFrame:frame]) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange) - name:UITextFieldTextDidChangeNotification + name:NSControlTextDidChangeNotification object:self]; _textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self]; @@ -44,7 +44,7 @@ - (void)_textDidChange #pragma mark - Properties -- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset +- (void)setTextContainerInset:(NSEdgeInsets)textContainerInset { _textContainerInset = textContainerInset; [self setNeedsLayout]; @@ -56,7 +56,7 @@ - (void)setPlaceholder:(NSString *)placeholder [self _updatePlaceholder]; } -- (void)setPlaceholderColor:(UIColor *)placeholderColor +- (void)setPlaceholderColor:(NSColor *)placeholderColor { _placeholderColor = placeholderColor; [self _updatePlaceholder]; @@ -102,7 +102,7 @@ - (CGRect)caretRectForPosition:(UITextPosition *)position - (CGRect)textRectForBounds:(CGRect)bounds { - return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); + return NSEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); } - (CGRect)editingRectForBounds:(CGRect)bounds diff --git a/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m index 64cf161720..b88a5fc9ab 100644 --- a/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m +++ b/Libraries/Text/VirtualText/RCTVirtualTextViewManager.m @@ -15,9 +15,9 @@ @implementation RCTVirtualTextViewManager RCT_EXPORT_MODULE(RCTVirtualText) -- (UIView *)view +- (NSView *)view { - return [UIView new]; + return [NSView new]; } - (RCTShadowView *)shadowView diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm index 22cada768f..d60b78b1d6 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import "RCTSurfaceSizeMeasureMode.h" diff --git a/React/Views/RCTLayout.h b/React/Views/RCTLayout.h index 79af03ecd7..1c6e6e0582 100644 --- a/React/Views/RCTLayout.h +++ b/React/Views/RCTLayout.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import #import #import @@ -25,9 +25,9 @@ typedef NS_ENUM(NSInteger, RCTDisplayType) { struct RCTLayoutMetrics { CGRect frame; CGRect contentFrame; - UIEdgeInsets borderWidth; + NSEdgeInsets borderWidth; RCTDisplayType displayType; - UIUserInterfaceLayoutDirection layoutDirection; + NSUserInterfaceLayoutDirection layoutDirection; }; typedef struct CG_BOXABLE RCTLayoutMetrics RCTLayoutMetrics; @@ -43,7 +43,7 @@ static inline BOOL RCTLayoutMetricsEqualToLayoutMetrics(RCTLayoutMetrics a, RCTL return CGRectEqualToRect(a.frame, b.frame) && CGRectEqualToRect(a.contentFrame, b.contentFrame) && - UIEdgeInsetsEqualToEdgeInsets(a.borderWidth, b.borderWidth) && + NSEdgeInsetsEqual(a.borderWidth, b.borderWidth) && a.displayType == b.displayType && a.layoutDirection == b.layoutDirection; } @@ -65,8 +65,8 @@ RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat base /** * Converts `YGDirection` to `UIUserInterfaceLayoutDirection` and vise versa. */ -RCT_EXTERN YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction); -RCT_EXTERN UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction); +RCT_EXTERN YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(NSUserInterfaceLayoutDirection direction); +RCT_EXTERN NSUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction); /** * Converts `YGDisplay` to `RCTDisplayType` and vise versa. diff --git a/React/Views/RCTLayout.m b/React/Views/RCTLayout.m index 60727621d9..c8c7285344 100644 --- a/React/Views/RCTLayout.m +++ b/React/Views/RCTLayout.m @@ -12,6 +12,14 @@ #import "RCTAssert.h" #import "RCTShadowView+Layout.h" +static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { + rect.origin.x += insets.left; + rect.origin.y += insets.top; + rect.size.width -= (insets.left + insets.right); + rect.size.height -= (insets.top + insets.bottom); + return rect; +} + RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode) { RCTLayoutMetrics layoutMetrics; @@ -27,21 +35,21 @@ RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode) } }; - UIEdgeInsets padding = (UIEdgeInsets){ + NSEdgeInsets padding = (NSEdgeInsets){ RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight)) }; - UIEdgeInsets borderWidth = (UIEdgeInsets){ + NSEdgeInsets borderWidth = (NSEdgeInsets){ RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)), RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight)) }; - UIEdgeInsets compoundInsets = (UIEdgeInsets){ + NSEdgeInsets compoundInsets = (NSEdgeInsets){ borderWidth.top + padding.top, borderWidth.left + padding.left, borderWidth.bottom + padding.bottom, @@ -49,7 +57,7 @@ RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode) }; CGRect bounds = (CGRect){CGPointZero, frame.size}; - CGRect contentFrame = UIEdgeInsetsInsetRect(bounds, compoundInsets); + CGRect contentFrame = NSEdgeInsetsInsetRect(bounds, compoundInsets); layoutMetrics.frame = frame; layoutMetrics.borderWidth = borderWidth; @@ -100,24 +108,24 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue) } } -YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction) +YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(NSUserInterfaceLayoutDirection direction) { switch (direction) { - case UIUserInterfaceLayoutDirectionRightToLeft: + case NSUserInterfaceLayoutDirectionRightToLeft: return YGDirectionRTL; - case UIUserInterfaceLayoutDirectionLeftToRight: + case NSUserInterfaceLayoutDirectionLeftToRight: return YGDirectionLTR; } } -UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction) +NSUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction) { switch (direction) { case YGDirectionInherit: case YGDirectionLTR: - return UIUserInterfaceLayoutDirectionLeftToRight; + return NSUserInterfaceLayoutDirectionLeftToRight; case YGDirectionRTL: - return UIUserInterfaceLayoutDirectionRightToLeft; + return NSUserInterfaceLayoutDirectionRightToLeft; } } diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index e0fb9af11b..b6dda71eb0 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -180,7 +180,7 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry */ - (void)layoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize - layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + layoutDirection:(NSUserInterfaceLayoutDirection)layoutDirection layoutContext:(RCTLayoutContext)layoutContext; /** diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 446551c59d..b23f41a500 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -258,7 +258,7 @@ - (RCTShadowView *)reactSuperview - (void)layoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize - layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection + layoutDirection:(NSUserInterfaceLayoutDirection)layoutDirection layoutContext:(RCTLayoutContext)layoutContext { YGNodeRef yogaNode = _yogaNode; @@ -381,6 +381,11 @@ - (NSNumber *)reactTagAtPoint:(CGPoint)point return self.reactTag; } +static inline NSString* NSStringFromCGRect(const CGRect rect) +{ + return NSStringFromRect(NSRectFromCGRect(rect)); +} + - (NSString *)description { NSString *description = super.description; diff --git a/React/Views/ScrollView/RCTScrollContentShadowView.m b/React/Views/ScrollView/RCTScrollContentShadowView.m index d53a658edb..aaf4cd0f06 100644 --- a/React/Views/ScrollView/RCTScrollContentShadowView.m +++ b/React/Views/ScrollView/RCTScrollContentShadowView.m @@ -18,7 +18,7 @@ @implementation RCTScrollContentShadowView - (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext { - if (layoutMetrics.layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) { + if (layoutMetrics.layoutDirection == NSUserInterfaceLayoutDirectionRightToLeft) { // Motivation: // Yoga place `contentView` on the right side of `scrollView` when RTL layout is enfoced. // That breaks everything; it is completely pointless to (re)position `contentView` From 1dfb5370f85a68c5e49e0d97a2b38ab10a661474 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 14:28:29 -0500 Subject: [PATCH 074/143] remove "editable" property from RCTUITextField This property is already provided by NSTextField --- Libraries/Text/TextInput/Singleline/RCTUITextField.h | 1 - Libraries/Text/TextInput/Singleline/RCTUITextField.m | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index 64e9ace0de..54bcf2f12c 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -26,7 +26,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) NSEdgeInsets textContainerInset; -@property (nonatomic, assign, getter=isEditable) BOOL editable; @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 4285388b8f..79b9fb3589 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -77,16 +77,6 @@ - (void)_updatePlaceholder attributes:attributes]; } -- (BOOL)isEditable -{ - return self.isEnabled; -} - -- (void)setEditable:(BOOL)editable -{ - self.enabled = editable; -} - #pragma mark - Caret Manipulation - (CGRect)caretRectForPosition:(UITextPosition *)position From 270ed99c408826fe19e599eb2c03b37894c84989 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 14:48:33 -0500 Subject: [PATCH 075/143] override "isFlipped" to YES in RCTTextView --- Libraries/Text/Text/RCTTextView.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index ae340c47a4..ab09d7cb73 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -252,4 +252,9 @@ - (void)copy:(id)sender #endif } +- (BOOL)isFlipped +{ + return YES; +} + @end From 5c8a0119e095fd65efe20abfb88aace828f956f0 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 16:34:20 -0500 Subject: [PATCH 076/143] pass YES to RCTUITextField#setNeedsLayout --- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 79b9fb3589..b9ad706530 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -47,7 +47,7 @@ - (void)_textDidChange - (void)setTextContainerInset:(NSEdgeInsets)textContainerInset { _textContainerInset = textContainerInset; - [self setNeedsLayout]; + [self setNeedsLayout:YES]; } - (void)setPlaceholder:(NSString *)placeholder From c3c8baada563381c73d7f8ffa100b1f2ae1cc352 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 17:35:06 -0500 Subject: [PATCH 077/143] replace UITextRange usage with NSRange --- .../Text/TextInput/Multiline/RCTUITextView.m | 5 +-- .../RCTBackedTextInputDelegateAdapter.h | 4 +- .../RCTBackedTextInputDelegateAdapter.m | 12 +++--- .../RCTBackedTextInputViewProtocol.h | 4 +- .../Text/TextInput/RCTBaseTextInputView.m | 40 +++++++++---------- .../TextInput/Singleline/RCTUITextField.m | 10 ++--- 6 files changed, 37 insertions(+), 38 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index ddf9dec960..c4c953ca90 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -124,15 +124,14 @@ - (void)setAttributedText:(NSAttributedString *)attributedText #pragma mark - Overrides -- (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate +- (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) { // We have to notify an adapter that following selection change was initiated programmatically, // so the adapter must not generate a notification for it. [_textInputDelegateAdapter skipNextTextInputDidChangeSelectionEventWithTextRange:selectedTextRange]; } - - [super setSelectedTextRange:selectedTextRange]; + [super setSelectedRange:selectedTextRange]; } - (void)paste:(id)sender diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index b297190b5f..a9b4b8aef9 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithTextField:(NSTextField *)backedTextInputView; -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange; - (void)selectedTextRangeWasSet; @end @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithTextView:(NSTextView *)backedTextInputView; -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange; @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 245f3a7273..561d963e19 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -19,7 +19,7 @@ @interface RCTBackedTextFieldDelegateAdapter () @implementation RCTBackedTextFieldDelegateAdapter { __weak UITextField *_backedTextInputView; BOOL _textDidChangeIsComing; - UITextRange *_previousSelectedTextRange; + NSRange _previousSelectedTextRange; } - (instancetype)initWithTextField:(UITextField *)backedTextInputView @@ -112,7 +112,7 @@ - (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField #pragma mark - Public Interface -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange { _previousSelectedTextRange = textRange; } @@ -126,7 +126,7 @@ - (void)selectedTextRangeWasSet - (void)textFieldProbablyDidChangeSelection { - if ([_backedTextInputView.selectedTextRange isEqual:_previousSelectedTextRange]) { + if (NSEqualRanges(_backedTextInputView.selectedTextRange, _previousSelectedTextRange)) { return; } @@ -144,7 +144,7 @@ @interface RCTBackedTextViewDelegateAdapter () @implementation RCTBackedTextViewDelegateAdapter { __weak UITextView *_backedTextInputView; BOOL _textDidChangeIsComing; - UITextRange *_previousSelectedTextRange; + NSRange _previousSelectedTextRange; } - (instancetype)initWithTextView:(UITextView *)backedTextInputView @@ -217,7 +217,7 @@ - (void)textViewDidChangeSelection:(__unused UITextView *)textView #pragma mark - Public Interface -- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange +- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange { _previousSelectedTextRange = textRange; } @@ -226,7 +226,7 @@ - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)tex - (void)textViewProbablyDidChangeSelection { - if ([_backedTextInputView.selectedTextRange isEqual:_previousSelectedTextRange]) { + if (NSEqualRanges(_backedTextInputView.selectedTextRange, _previousSelectedTextRange)) { return; } diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index ce20b7d5f7..eed3b2f81a 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -32,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN // explicitly specify should `delegate` be notified about the change or not. // If the change was initiated programmatically, we must NOT notify the delegate. // If the change was a result of user actions (like typing or touches), we MUST notify the delegate. -- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE; -- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate; +@property (nonatomic, readonly) NSRange selectedTextRange; +- (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate; // This protocol disallows direct access to `text` property because // unwise usage of it can break the `attributeText` behavior. diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index e94a2127a5..eb13cee97c 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -103,22 +103,22 @@ - (void)setAttributedText:(NSAttributedString *)attributedText NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; if (eventLag == 0 && ![attributedText isEqualToAttributedString:self.backedTextInputView.attributedText]) { - UITextRange *selection = self.backedTextInputView.selectedTextRange; + NSRange selection = self.backedTextInputView.selectedTextRange; NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length; self.backedTextInputView.attributedText = attributedText; - if (selection.empty) { + if (selection.length == 0) { // Maintaining a cursor position relative to the end of the old text. - NSInteger offsetStart = - [self.backedTextInputView offsetFromPosition:self.backedTextInputView.beginningOfDocument - toPosition:selection.start]; + NSInteger offsetStart = selection.location; +// [self.backedTextInputView offsetFromPosition:self.backedTextInputView.beginningOfDocument +// toPosition:selection.start]; NSInteger offsetFromEnd = oldTextLength - offsetStart; NSInteger newOffset = attributedText.string.length - offsetFromEnd; - UITextPosition *position = - [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument - offset:newOffset]; - [self.backedTextInputView setSelectedTextRange:[self.backedTextInputView textRangeFromPosition:position toPosition:position] +// UITextPosition *position = +// [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument +// offset:newOffset]; + [self.backedTextInputView setSelectedTextRange:(NSRange){newOffset, 0} notifyDelegate:YES]; } @@ -131,9 +131,9 @@ - (void)setAttributedText:(NSAttributedString *)attributedText - (RCTTextSelection *)selection { id backedTextInputView = self.backedTextInputView; - UITextRange *selectedTextRange = backedTextInputView.selectedTextRange; - return [[RCTTextSelection new] initWithStart:[backedTextInputView offsetFromPosition:backedTextInputView.beginningOfDocument toPosition:selectedTextRange.start] - end:[backedTextInputView offsetFromPosition:backedTextInputView.beginningOfDocument toPosition:selectedTextRange.end]]; + NSRange selectedTextRange = [backedTextInputView selectedTextRange]; + return [[RCTTextSelection new] initWithStart:selectedTextRange.location + end:selectedTextRange.location + selectedTextRange.length]; } - (void)setSelection:(RCTTextSelection *)selection @@ -144,13 +144,13 @@ - (void)setSelection:(RCTTextSelection *)selection id backedTextInputView = self.backedTextInputView; - UITextRange *previousSelectedTextRange = backedTextInputView.selectedTextRange; - UITextPosition *start = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument offset:selection.start]; - UITextPosition *end = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument offset:selection.end]; - UITextRange *selectedTextRange = [backedTextInputView textRangeFromPosition:start toPosition:end]; + NSRange previousSelectedTextRange = [backedTextInputView selectedTextRange]; + NSRange selectedTextRange = (NSRange){selection.start, selection.end - selection.start}; + + NSInteger eventLag = _nativeEventCount - _mostRecentEventCount; - if (eventLag == 0 && ![previousSelectedTextRange isEqual:selectedTextRange]) { + if (eventLag == 0 && !NSEqualRanges(previousSelectedTextRange, selectedTextRange)) { [backedTextInputView setSelectedTextRange:selectedTextRange notifyDelegate:NO]; } else if (eventLag > RCTTextUpdateLagWarningThreshold) { RCTLogWarn(@"Native TextInput(%@) is %lld events ahead of JS - try to make your JS faster.", backedTextInputView.attributedText.string, (long long)eventLag); @@ -248,11 +248,11 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin _predictedText = newAttributedText.string; // Collapse selection at end of insert to match normal paste behavior. - UITextPosition *insertEnd = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument - offset:(range.location + allowedLength)]; - [backedTextInputView setSelectedTextRange:[backedTextInputView textRangeFromPosition:insertEnd toPosition:insertEnd] + [backedTextInputView setSelectedTextRange:(NSRange){range.location + allowedLength, 0} notifyDelegate:YES]; + + [self textInputDidChange]; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index b9ad706530..afcf0ac527 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -102,13 +102,12 @@ - (CGRect)editingRectForBounds:(CGRect)bounds #pragma mark - Overrides -- (void)setSelectedTextRange:(UITextRange *)selectedTextRange +- (NSRange)selectedTextRange { - [super setSelectedTextRange:selectedTextRange]; - [_textInputDelegateAdapter selectedTextRangeWasSet]; + return self.currentEditor.selectedRange; } -- (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate +- (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) { // We have to notify an adapter that following selection change was initiated programmatically, @@ -116,7 +115,8 @@ - (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BO [_textInputDelegateAdapter skipNextTextInputDidChangeSelectionEventWithTextRange:selectedTextRange]; } - [super setSelectedTextRange:selectedTextRange]; + self.currentEditor.selectedRange = selectedTextRange; + [_textInputDelegateAdapter selectedTextRangeWasSet]; } - (void)paste:(id)sender From b59d51e3a880cadbd016a8f81e0c32d744430f58 Mon Sep 17 00:00:00 2001 From: Alec Larson Date: Wed, 27 Feb 2019 13:38:28 -0500 Subject: [PATCH 078/143] remove UITextInput protocol --- Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index eed3b2f81a..eb23542cc7 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN -@protocol RCTBackedTextInputViewProtocol +@protocol RCTBackedTextInputViewProtocol @property (nonatomic, strong, nullable) NSColor *textColor; @property (nonatomic, strong, nullable) NSFont *font; From 088a36b411ec6beae2ba4b2567da78a21ca9e7db Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 17:38:30 -0500 Subject: [PATCH 079/143] make RCTBackedText* classes compile --- .../RCTBackedTextInputDelegateAdapter.m | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 561d963e19..785aea6177 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -13,52 +13,51 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingContext; -@interface RCTBackedTextFieldDelegateAdapter () +@interface RCTBackedTextFieldDelegateAdapter () @end @implementation RCTBackedTextFieldDelegateAdapter { - __weak UITextField *_backedTextInputView; + __weak NSTextField *_backedTextInputView; BOOL _textDidChangeIsComing; NSRange _previousSelectedTextRange; } -- (instancetype)initWithTextField:(UITextField *)backedTextInputView +- (instancetype)initWithTextField:(NSTextField *)backedTextInputView { if (self = [super init]) { _backedTextInputView = backedTextInputView; backedTextInputView.delegate = self; - [_backedTextInputView addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged]; - [_backedTextInputView addTarget:self action:@selector(textFieldDidEndEditingOnExit) forControlEvents:UIControlEventEditingDidEndOnExit]; + } return self; } -- (void)dealloc -{ - [_backedTextInputView removeTarget:self action:nil forControlEvents:UIControlEventEditingChanged]; - [_backedTextInputView removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit]; -} + + + + + #pragma mark - NSTextFieldDelegate -- (BOOL)textFieldShouldBeginEditing:(__unused UITextField *)textField +- (BOOL)control:(__unused NSControl *)control textShouldBeginEditing:(__unused NSText *)fieldEditor { return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)textFieldDidBeginEditing:(__unused UITextField *)textField +- (void)controlTextDidBeginEditing:(__unused NSNotification *)notification { [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } -- (BOOL)textFieldShouldEndEditing:(__unused UITextField *)textField +- (BOOL)control:(__unused NSControl *)control textShouldEndEditing:(__unused NSText *)fieldEditor { return [_backedTextInputView.textInputDelegate textInputShouldEndEditing]; } -- (void)textFieldDidEndEditing:(__unused UITextField *)textField +- (void)controlTextDidEndEditing:(__unused NSNotification *)notification { if (_textDidChangeIsComing) { // iOS does't call `textViewDidChange:` delegate method if the change was happened because of autocorrection @@ -70,7 +69,7 @@ - (void)textFieldDidEndEditing:(__unused UITextField *)textField [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } -- (BOOL)textField:(__unused UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string +- (BOOL)textField:(__unused NSTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { BOOL result = [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:range replacementText:string]; if (result) { @@ -79,14 +78,14 @@ - (BOOL)textField:(__unused UITextField *)textField shouldChangeCharactersInRang return result; } -- (BOOL)textFieldShouldReturn:(__unused UITextField *)textField -{ - return [_backedTextInputView.textInputDelegate textInputShouldReturn]; -} +//- (BOOL)textFieldShouldReturn:(__unused NSTextField *)textField +//{ +// return [_backedTextInputView.textInputDelegate textInputShouldReturn]; +//} #pragma mark - UIControlEventEditing* Family Events -- (void)textFieldDidChange +- (void)controlTextDidChange:(NSNotification *)notification { _textDidChangeIsComing = NO; [_backedTextInputView.textInputDelegate textInputDidChange]; @@ -95,20 +94,20 @@ - (void)textFieldDidChange [self textFieldProbablyDidChangeSelection]; } -- (void)textFieldDidEndEditingOnExit -{ - [_backedTextInputView.textInputDelegate textInputDidReturn]; -} + + + + #pragma mark - UIKeyboardInput (private UIKit protocol) // This method allows us to detect a [Backspace] `keyPress` // even when there is no more text in the `UITextField`. -- (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField -{ - [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:NSMakeRange(0, 0) replacementText:@""]; - return YES; -} +//- (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField +//{ +// [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:NSMakeRange(0, 0) replacementText:@""]; +// return YES; +//} #pragma mark - Public Interface @@ -138,16 +137,16 @@ - (void)textFieldProbablyDidChangeSelection #pragma mark - RCTBackedTextViewDelegateAdapter (for UITextView) -@interface RCTBackedTextViewDelegateAdapter () +@interface RCTBackedTextViewDelegateAdapter () @end @implementation RCTBackedTextViewDelegateAdapter { - __weak UITextView *_backedTextInputView; + __unsafe_unretained NSTextView *_backedTextInputView; BOOL _textDidChangeIsComing; NSRange _previousSelectedTextRange; } -- (instancetype)initWithTextView:(UITextView *)backedTextInputView +- (instancetype)initWithTextView:(NSTextView *)backedTextInputView { if (self = [super init]) { _backedTextInputView = backedTextInputView; @@ -157,24 +156,24 @@ - (instancetype)initWithTextView:(UITextView *)b return self; } -#pragma mark - UITextViewDelegate +#pragma mark - NSTextViewDelegate -- (BOOL)textViewShouldBeginEditing:(__unused UITextView *)textView +- (BOOL)textShouldBeginEditing:(__unused NSText *)text { return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)textViewDidBeginEditing:(__unused UITextView *)textView +- (void)textDidBeginEditing:(__unused NSNotification *)notification { [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } -- (BOOL)textViewShouldEndEditing:(__unused UITextView *)textView +- (BOOL)textShouldEndEditing:(__unused NSText *)text { return [_backedTextInputView.textInputDelegate textInputShouldEndEditing]; } -- (void)textViewDidEndEditing:(__unused UITextView *)textView +- (void)textDidEndEditing:(__unused NSNotification *)notification { if (_textDidChangeIsComing) { // iOS does't call `textViewDidChange:` delegate method if the change was happened because of autocorrection @@ -186,9 +185,9 @@ - (void)textViewDidEndEditing:(__unused UITextView *)textView [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } -- (BOOL)textView:(__unused UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text +- (BOOL)textView:(__unused NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementString:(NSString *)text { - // Custom implementation of `textInputShouldReturn` and `textInputDidReturn` pair for `UITextView`. + // Custom implementation of `textInputShouldReturn` and `textInputDidReturn` pair for `NSTextView`. if (!_backedTextInputView.textWasPasted && [text isEqualToString:@"\n"]) { if ([_backedTextInputView.textInputDelegate textInputShouldReturn]) { [_backedTextInputView.textInputDelegate textInputDidReturn]; @@ -204,13 +203,13 @@ - (BOOL)textView:(__unused UITextView *)textView shouldChangeTextInRange:(NSRang return result; } -- (void)textViewDidChange:(__unused UITextView *)textView +- (void)textDidChange:(__unused NSNotification *)notification { _textDidChangeIsComing = NO; [_backedTextInputView.textInputDelegate textInputDidChange]; } -- (void)textViewDidChangeSelection:(__unused UITextView *)textView +- (void)textViewDidChangeSelection:(__unused NSNotification *)notification { [self textViewProbablyDidChangeSelection]; } From bc0ae1c478fc459881db90892bb17622624f6bb2 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 18:04:44 -0500 Subject: [PATCH 080/143] comment out unsupported UITextInput protocol methods --- .../TextInput/Singleline/RCTUITextField.m | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index afcf0ac527..8f302090fc 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -79,26 +79,26 @@ - (void)_updatePlaceholder #pragma mark - Caret Manipulation -- (CGRect)caretRectForPosition:(UITextPosition *)position -{ - if (_caretHidden) { - return CGRectZero; - } - - return [super caretRectForPosition:position]; -} +//- (CGRect)caretRectForPosition:(UITextPosition *)position +//{ +// if (_caretHidden) { +// return CGRectZero; +// } +// +// return [super caretRectForPosition:position]; +//} #pragma mark - Positioning Overrides -- (CGRect)textRectForBounds:(CGRect)bounds -{ - return NSEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); -} +//- (CGRect)textRectForBounds:(CGRect)bounds +//{ +// return NSEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); +//} -- (CGRect)editingRectForBounds:(CGRect)bounds -{ - return [self textRectForBounds:bounds]; -} +//- (CGRect)editingRectForBounds:(CGRect)bounds +//{ +// return [self textRectForBounds:bounds]; +//} #pragma mark - Overrides From f9e2946008cf5e7dc66d6f77de89bafed3f063d0 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 19:42:17 -0500 Subject: [PATCH 081/143] remove UILongPressGestureRecognizer usage in RCTTextView Note: Excess whitespace ensures that future patches can be applied without any edits. --- Libraries/Text/Text/RCTTextView.m | 78 +++++++++++++++---------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index ab09d7cb73..219ffa89d8 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -19,7 +19,7 @@ @implementation RCTTextView { CAShapeLayer *_highlightLayer; - UILongPressGestureRecognizer *_longPressGestureRecognizer; + NSArray *_Nullable _descendantViews; NSTextStorage *_Nullable _textStorage; @@ -45,21 +45,21 @@ - (NSString *)description return [superDescription stringByReplacingCharactersInRange:semicolonRange withString:replacement]; } -- (void)setSelectable:(BOOL)selectable -{ - if (_selectable == selectable) { - return; - } - _selectable = selectable; - if (_selectable) { - [self enableContextMenu]; - } - else { - [self disableContextMenu]; - } -} + + + + + + + + + + + + + - (void)reactSetFrame:(CGRect)frame { @@ -198,37 +198,37 @@ - (NSString *)accessibilityLabel return _textStorage.string; } -#pragma mark - Context Menu -- (void)enableContextMenu -{ - _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; - [self addGestureRecognizer:_longPressGestureRecognizer]; -} -- (void)disableContextMenu -{ - [self removeGestureRecognizer:_longPressGestureRecognizer]; - _longPressGestureRecognizer = nil; -} -- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture -{ -#if !TARGET_OS_TV - UIMenuController *menuController = [UIMenuController sharedMenuController]; - if (menuController.isMenuVisible) { - return; - } - if (!self.isFirstResponder) { - [self becomeFirstResponder]; - } - [menuController setTargetRect:self.bounds inView:self]; - [menuController setMenuVisible:YES animated:YES]; -#endif -} + + + + + + + + + + + + + + + + + + + + + + + + + - (BOOL)canBecomeFirstResponder { From e9d3baaca82716ac5835ff0ee376a92f4eccdca4 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Mon, 11 Feb 2019 19:59:07 -0500 Subject: [PATCH 082/143] fix: "drawRect" method of RCTTextView --- Libraries/Text/NSBezierPath+CGPath.h | 20 +++++++ Libraries/Text/NSBezierPath+CGPath.m | 60 +++++++++++++++++++ .../Text/RCTText.xcodeproj/project.pbxproj | 8 +++ Libraries/Text/Text/RCTTextView.m | 9 +-- 4 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 Libraries/Text/NSBezierPath+CGPath.h create mode 100644 Libraries/Text/NSBezierPath+CGPath.m diff --git a/Libraries/Text/NSBezierPath+CGPath.h b/Libraries/Text/NSBezierPath+CGPath.h new file mode 100644 index 0000000000..ad20b455e6 --- /dev/null +++ b/Libraries/Text/NSBezierPath+CGPath.h @@ -0,0 +1,20 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface NSBezierPath (CGPath) + +- (CGPathRef)CGPath; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/NSBezierPath+CGPath.m b/Libraries/Text/NSBezierPath+CGPath.m new file mode 100644 index 0000000000..838c3d1907 --- /dev/null +++ b/Libraries/Text/NSBezierPath+CGPath.m @@ -0,0 +1,60 @@ +/** + * 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 "NSBezierPath+CGPath.h" + +@implementation NSBezierPath (CGPath) + +// Taken from: https://stackoverflow.com/a/1956021/2228559 +- (CGPathRef)CGPath +{ + CGPathRef path = NULL; + + NSInteger numElements = self.elementCount; + if (numElements > 0) { + CGMutablePathRef mutablePath = CGPathCreateMutable(); + BOOL didClosePath = YES; + + for (NSInteger i = 0; i < numElements; i++) { + NSPoint p[3]; + switch ([self elementAtIndex:i associatedPoints:p]) { + case NSMoveToBezierPathElement: + CGPathMoveToPoint(mutablePath, NULL, p[0].x, p[0].y); + break; + + case NSLineToBezierPathElement: + CGPathAddLineToPoint(mutablePath, NULL, p[0].x, p[0].y); + didClosePath = NO; + break; + + case NSCurveToBezierPathElement: + CGPathAddCurveToPoint(mutablePath, NULL, p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y); + didClosePath = NO; + break; + + case NSClosePathBezierPathElement: + CGPathCloseSubpath(mutablePath); + didClosePath = YES; + break; + } + } + + // Be sure the path is closed or Quartz may not do valid hit detection. + if (!didClosePath) { + CGPathCloseSubpath(mutablePath); + } + + path = CGPathCreateCopy(path); + CGPathRelease(mutablePath); + } + + return path; +} + +@end diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 586f3aa8d5..c0fb167c76 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -103,6 +103,8 @@ 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B103200FEBA9008D9D16 /* RCTUITextField.m */; }; 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */; }; 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; + 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; + 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -112,6 +114,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */, 5956B160200FF324008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, 5956B161200FF324008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */, 5956B162200FF324008D9D16 /* RCTRawTextShadowView.h in Copy Headers */, @@ -229,12 +232,16 @@ 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextViewManager.h; sourceTree = ""; }; 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextShadowView.m; sourceTree = ""; }; 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Text.m"; sourceTree = ""; }; + 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+CGPath.h"; sourceTree = ""; }; + 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( + 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */, + 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */, 5956B11B200FEBA9008D9D16 /* BaseText */, 58B5119C1A9E6C1200147676 /* Products */, 5956B0FA200FEBA9008D9D16 /* RawText */, @@ -473,6 +480,7 @@ 5956B13E200FEBAA008D9D16 /* RCTBaseTextViewManager.m in Sources */, 5956B145200FEBAA008D9D16 /* RCTVirtualTextShadowView.m in Sources */, 5956B142200FEBAA008D9D16 /* RCTTextViewManager.m in Sources */, + 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */, 5956B135200FEBAA008D9D16 /* RCTBaseTextInputView.m in Sources */, 5956B144200FEBAA008D9D16 /* RCTVirtualTextViewManager.m in Sources */, 5956B13B200FEBAA008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */, diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index 219ffa89d8..a3b9c34016 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -9,12 +9,13 @@ #import "RCTTextView.h" -#import +#import #import #import #import "RCTTextShadowView.h" +#import "NSBezierPath+CGPath.h" @implementation RCTTextView { @@ -110,7 +111,7 @@ - (void)drawRect:(CGRect)rect [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:_contentFrame.origin]; [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:_contentFrame.origin]; - __block UIBezierPath *highlightPath = nil; + __block NSBezierPath *highlightPath = nil; NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; [_textStorage enumerateAttribute:RCTTextAttributesIsHighlightedAttributeName @@ -127,9 +128,9 @@ - (void)drawRect:(CGRect)rect inTextContainer:textContainer usingBlock: ^(CGRect enclosingRect, __unused BOOL *anotherStop) { - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2) cornerRadius:2]; + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2) xRadius:2 yRadius:2]; if (highlightPath) { - [highlightPath appendPath:path]; + [highlightPath appendBezierPath:path]; } else { highlightPath = path; } From 9c04b2f55c31eb6cb957709e5097f428f3856216 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 11:10:23 -0500 Subject: [PATCH 083/143] fix: cant set "opaque" property in RCTTextView --- Libraries/Text/Text/RCTTextView.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index a3b9c34016..3641413f2b 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -32,7 +32,6 @@ - (instancetype)initWithFrame:(CGRect)frame if (self = [super initWithFrame:frame]) { self.isAccessibilityElement = YES; self.accessibilityTraits |= UIAccessibilityTraitStaticText; - self.opaque = NO; self.contentMode = UIViewContentModeRedraw; } return self; From 3c82a2b6e8ce8339c6aec8d20a39c15e72d23d86 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 11:11:53 -0500 Subject: [PATCH 084/143] add "NSView:performWithoutAnimation" static method --- Libraries/Text/Text/RCTTextView.m | 2 +- React/Views/NSView+React.h | 2 ++ React/Views/NSView+React.m | 13 ++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index 3641413f2b..5d3547cf62 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -65,7 +65,7 @@ - (void)reactSetFrame:(CGRect)frame { // Text looks super weird if its frame is animated. // This disables the frame animation, without affecting opacity, etc. - [UIView performWithoutAnimation:^{ + [NSView performWithoutAnimation:^{ [super reactSetFrame:frame]; }]; } diff --git a/React/Views/NSView+React.h b/React/Views/NSView+React.h index 2559b5909a..816b87f1c2 100644 --- a/React/Views/NSView+React.h +++ b/React/Views/NSView+React.h @@ -116,4 +116,6 @@ - (NSView *)reactHitTest:(NSPoint)point; ++ (void)performWithoutAnimation:(void (^)(void))actionsWithoutAnimation; + @end diff --git a/React/Views/NSView+React.m b/React/Views/NSView+React.m index 149ecb65c6..de1466ec56 100644 --- a/React/Views/NSView+React.m +++ b/React/Views/NSView+React.m @@ -9,7 +9,7 @@ #import "NSView+React.h" #import -#import +#import #import @@ -306,4 +306,15 @@ - (NSView *)reactHitTest:(NSPoint)point return view; } +#pragma mark - UIKit parity + ++ (void)performWithoutAnimation:(void (^)(void))actionsWithoutAnimation +{ + [CATransaction begin]; + [CATransaction setValue:(id)kCFBooleanTrue + forKey:kCATransactionDisableActions]; + actionsWithoutAnimation(); + [CATransaction commit]; +} + @end From 832fa706832c360d1318b12365571ae5f11d4437 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 11:12:09 -0500 Subject: [PATCH 085/143] fix: pass YES to "RCTTextView:setNeedsDisplay" --- Libraries/Text/Text/RCTTextView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index 5d3547cf62..d856904870 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -93,7 +93,7 @@ - (void)setTextStorage:(NSTextStorage *)textStorage [self addSubview:view]; } - [self setNeedsDisplay]; + [self setNeedsDisplay:YES]; } - (void)drawRect:(CGRect)rect @@ -183,7 +183,7 @@ - (void)viewDidMoveToWindow _highlightLayer = nil; } } else if (_textStorage) { - [self setNeedsDisplay]; + [self setNeedsDisplay:YES]; } } From 8736d514e2141bc76c16a82adc9ea2dc11ec83f3 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 12:24:41 -0500 Subject: [PATCH 086/143] fix: "paste" method of RCTUITextField --- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 8f302090fc..9c5ad1d01a 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -121,7 +121,7 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not - (void)paste:(id)sender { - [super paste:sender]; + [self.currentEditor paste:sender]; _textWasPasted = YES; } From 0ffdee5bebe15a4c725c97fe3d64706ce9fcd18e Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 15:22:31 -0500 Subject: [PATCH 087/143] disable "inputAccessoryView" related code This property is relevant to the iOS keyboard only. --- .../RCTBackedTextInputViewProtocol.h | 2 +- .../Text/TextInput/RCTBaseTextInputView.m | 120 +++++++++--------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index eb23542cc7..923794e026 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) NSTextAlignment textAlignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, assign) NSEdgeInsets textContainerInset; -@property (nonatomic, strong, nullable) NSView *inputAccessoryView; +//@property (nonatomic, strong, nullable) NSView *inputAccessoryView; @property (nonatomic, weak, nullable) id textInputDelegate; @property (nonatomic, readonly) CGSize contentSize; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index eb13cee97c..0ba68c379b 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -23,7 +23,7 @@ @implementation RCTBaseTextInputView { __weak RCTBridge *_bridge; __weak RCTEventDispatcher *_eventDispatcher; - BOOL _hasInputAccesoryView; +// BOOL _hasInputAccesoryView; NSString *_Nullable _predictedText; NSInteger _nativeEventCount; } @@ -405,65 +405,65 @@ - (void)didMoveToWindow #pragma mark - Custom Input Accessory View -- (void)didSetProps:(NSArray *)changedProps -{ - [self invalidateInputAccessoryView]; -} - -- (void)invalidateInputAccessoryView -{ -#if !TARGET_OS_TV - NSView *textInputView = self.backedTextInputView; - UIKeyboardType keyboardType = textInputView.keyboardType; - - // These keyboard types (all are number pads) don't have a "Done" button by default, - // so we create an `inputAccessoryView` with this button for them. - BOOL shouldHaveInputAccesoryView = - ( - keyboardType == UIKeyboardTypeNumberPad || - keyboardType == UIKeyboardTypePhonePad || - keyboardType == UIKeyboardTypeDecimalPad || - keyboardType == UIKeyboardTypeASCIICapableNumberPad - ) && - textInputView.returnKeyType == UIReturnKeyDone; - - if (_hasInputAccesoryView == shouldHaveInputAccesoryView) { - return; - } - - _hasInputAccesoryView = shouldHaveInputAccesoryView; - - if (shouldHaveInputAccesoryView) { - UIToolbar *toolbarView = [[UIToolbar alloc] init]; - [toolbarView sizeToFit]; - UIBarButtonItem *flexibleSpace = - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace - target:nil - action:nil]; - UIBarButtonItem *doneButton = - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self - action:@selector(handleInputAccessoryDoneButton)]; - toolbarView.items = @[flexibleSpace, doneButton]; - textInputView.inputAccessoryView = toolbarView; - } - else { - textInputView.inputAccessoryView = nil; - } - - // We have to call `reloadInputViews` for focused text inputs to update an accessory view. - if (textInputView.isFirstResponder) { - [textInputView reloadInputViews]; - } -#endif -} - -- (void)handleInputAccessoryDoneButton -{ - if ([self textInputShouldReturn]) { - [self.backedTextInputView endEditing:YES]; - } -} +//- (void)didSetProps:(NSArray *)changedProps +//{ +// [self invalidateInputAccessoryView]; +//} +// +//- (void)invalidateInputAccessoryView +//{ +//#if !TARGET_OS_TV +// NSView *textInputView = self.backedTextInputView; +// UIKeyboardType keyboardType = textInputView.keyboardType; +// +// // These keyboard types (all are number pads) don't have a "Done" button by default, +// // so we create an `inputAccessoryView` with this button for them. +// BOOL shouldHaveInputAccesoryView = +// ( +// keyboardType == UIKeyboardTypeNumberPad || +// keyboardType == UIKeyboardTypePhonePad || +// keyboardType == UIKeyboardTypeDecimalPad || +// keyboardType == UIKeyboardTypeASCIICapableNumberPad +// ) && +// textInputView.returnKeyType == UIReturnKeyDone; +// +// if (_hasInputAccesoryView == shouldHaveInputAccesoryView) { +// return; +// } +// +// _hasInputAccesoryView = shouldHaveInputAccesoryView; +// +// if (shouldHaveInputAccesoryView) { +// UIToolbar *toolbarView = [[UIToolbar alloc] init]; +// [toolbarView sizeToFit]; +// UIBarButtonItem *flexibleSpace = +// [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace +// target:nil +// action:nil]; +// UIBarButtonItem *doneButton = +// [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone +// target:self +// action:@selector(handleInputAccessoryDoneButton)]; +// toolbarView.items = @[flexibleSpace, doneButton]; +// textInputView.inputAccessoryView = toolbarView; +// } +// else { +// textInputView.inputAccessoryView = nil; +// } +// +// // We have to call `reloadInputViews` for focused text inputs to update an accessory view. +// if (textInputView.isFirstResponder) { +// [textInputView reloadInputViews]; +// } +//#endif +//} +// +//- (void)handleInputAccessoryDoneButton +//{ +// if ([self textInputShouldReturn]) { +// [self.backedTextInputView endEditing:YES]; +// } +//} #pragma mark - Helpers From 2b8f1bce61e9b45abc7f08000f46c0bf4e8cb056 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 16:54:17 -0500 Subject: [PATCH 088/143] disable RCTAccessibilityManager for now Help wanted! --- Libraries/Text/Text/RCTTextView.m | 4 +-- Libraries/Text/Text/RCTTextViewManager.m | 34 +++++++++---------- .../Text/TextInput/Multiline/RCTUITextView.m | 2 +- .../Text/TextInput/RCTBaseTextInputView.m | 2 +- .../TextInput/RCTBaseTextInputViewManager.m | 34 +++++++++---------- React/Modules/RCTDeviceInfo.m | 2 +- React/Modules/RCTUIManager.m | 6 ++-- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index d856904870..7be095913f 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -30,8 +30,8 @@ @implementation RCTTextView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - self.isAccessibilityElement = YES; - self.accessibilityTraits |= UIAccessibilityTraitStaticText; +// self.isAccessibilityElement = YES; +// self.accessibilityTraits |= UIAccessibilityTraitStaticText; self.contentMode = UIViewContentModeRedraw; } return self; diff --git a/Libraries/Text/Text/RCTTextViewManager.m b/Libraries/Text/Text/RCTTextViewManager.m index 8f8b222d51..47fc8aaca9 100644 --- a/Libraries/Text/Text/RCTTextViewManager.m +++ b/Libraries/Text/Text/RCTTextViewManager.m @@ -9,7 +9,7 @@ #import "RCTTextViewManager.h" -#import +//#import #import #import #import @@ -44,10 +44,10 @@ - (void)setBridge:(RCTBridge *)bridge [bridge.uiManager.observerCoordinator addObserver:self]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleDidUpdateMultiplierNotification) - name:RCTAccessibilityManagerDidUpdateMultiplierNotification - object:bridge.accessibilityManager]; +// [[NSNotificationCenter defaultCenter] addObserver:self +// selector:@selector(handleDidUpdateMultiplierNotification) +// name:RCTAccessibilityManagerDidUpdateMultiplierNotification +// object:bridge.accessibilityManager]; } - (void)dealloc @@ -63,7 +63,7 @@ - (NSView *)view - (RCTShadowView *)shadowView { RCTTextShadowView *shadowView = [[RCTTextShadowView alloc] initWithBridge:self.bridge]; - shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; +// shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; [_shadowViews addObject:shadowView]; return shadowView; } @@ -79,16 +79,16 @@ - (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager #pragma mark - Font Size Multiplier -- (void)handleDidUpdateMultiplierNotification -{ - CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; - - for (RCTTextShadowView *shadowView in _shadowViews) { - shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; - [shadowView dirtyLayout]; - } - - [self.bridge.uiManager setNeedsLayout]; -} +//- (void)handleDidUpdateMultiplierNotification +//{ +// CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; +// +// for (RCTTextShadowView *shadowView in _shadowViews) { +// shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; +// [shadowView dirtyLayout]; +// } +// +// [self.bridge.uiManager setNeedsLayout]; +//} @end diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index c4c953ca90..559eed915e 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -41,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame object:self]; _placeholderView = [[UILabel alloc] initWithFrame:self.bounds]; - _placeholderView.isAccessibilityElement = NO; +// _placeholderView.isAccessibilityElement = NO; _placeholderView.numberOfLines = 0; _placeholderView.textColor = defaultPlaceholderColor(); [self addSubview:_placeholderView]; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 0ba68c379b..c694bade77 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -9,7 +9,7 @@ #import "RCTBaseTextInputView.h" -#import +//#import #import #import #import diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 34dafbd0a6..bbf3202d11 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -9,7 +9,7 @@ #import "RCTBaseTextInputViewManager.h" -#import +//#import #import #import #import @@ -70,7 +70,7 @@ @implementation RCTBaseTextInputViewManager - (RCTShadowView *)shadowView { RCTBaseTextInputShadowView *shadowView = [[RCTBaseTextInputShadowView alloc] initWithBridge:self.bridge]; - shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; +// shadowView.textAttributes.fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; [_shadowViews addObject:shadowView]; return shadowView; } @@ -83,10 +83,10 @@ - (void)setBridge:(RCTBridge *)bridge [bridge.uiManager.observerCoordinator addObserver:self]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleDidUpdateMultiplierNotification) - name:RCTAccessibilityManagerDidUpdateMultiplierNotification - object:bridge.accessibilityManager]; +// [[NSNotificationCenter defaultCenter] addObserver:self +// selector:@selector(handleDidUpdateMultiplierNotification) +// name:RCTAccessibilityManagerDidUpdateMultiplierNotification +// object:bridge.accessibilityManager]; } - (void)dealloc @@ -105,16 +105,16 @@ - (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager #pragma mark - Font Size Multiplier -- (void)handleDidUpdateMultiplierNotification -{ - CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; - - for (RCTBaseTextInputShadowView *shadowView in _shadowViews) { - shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; - [shadowView dirtyLayout]; - } - - [self.bridge.uiManager setNeedsLayout]; -} +//- (void)handleDidUpdateMultiplierNotification +//{ +// CGFloat fontSizeMultiplier = self.bridge.accessibilityManager.multiplier; +// +// for (RCTBaseTextInputShadowView *shadowView in _shadowViews) { +// shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; +// [shadowView dirtyLayout]; +// } +// +// [self.bridge.uiManager setNeedsLayout]; +//} @end diff --git a/React/Modules/RCTDeviceInfo.m b/React/Modules/RCTDeviceInfo.m index 6eff2a50a6..0d99176b79 100644 --- a/React/Modules/RCTDeviceInfo.m +++ b/React/Modules/RCTDeviceInfo.m @@ -10,7 +10,7 @@ #import "RCTDeviceInfo.h" #import -#import "RCTAccessibilityManager.h" +//#import "RCTAccessibilityManager.h" #import "RCTAssert.h" #import "RCTEventDispatcher.h" #import "RCTUtils.h" diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 791ed4d236..32c1d63456 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -12,7 +12,7 @@ #import #import -#import "RCTAccessibilityManager.h" +//#import "RCTAccessibilityManager.h" #import "RCTAssert.h" #import "RCTBridge+Private.h" #import "RCTBridge.h" @@ -175,8 +175,8 @@ - (void)didReceiveNewContentSizeMultiplier // Report the event across the bridge. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateContentSizeMultiplier" - body:@([_bridge.accessibilityManager multiplier])]; +// [_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateContentSizeMultiplier" +// body:@([_bridge.accessibilityManager multiplier])]; #pragma clang diagnostic pop RCTExecuteOnUIManagerQueue(^{ From 0b9a411488835e6471e0841e1bbfbf6f16b77ad3 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 12 Feb 2019 17:03:14 -0500 Subject: [PATCH 089/143] fix: "postprocessAttributedText" method of RCTTextShadowView --- Libraries/Text/NSFont+LineHeight.h | 20 +++++++++++++++++++ Libraries/Text/NSFont+LineHeight.m | 20 +++++++++++++++++++ .../Text/RCTText.xcodeproj/project.pbxproj | 8 ++++++++ Libraries/Text/Text/RCTTextShadowView.m | 1 + 4 files changed, 49 insertions(+) create mode 100644 Libraries/Text/NSFont+LineHeight.h create mode 100644 Libraries/Text/NSFont+LineHeight.m diff --git a/Libraries/Text/NSFont+LineHeight.h b/Libraries/Text/NSFont+LineHeight.h new file mode 100644 index 0000000000..cddd349482 --- /dev/null +++ b/Libraries/Text/NSFont+LineHeight.h @@ -0,0 +1,20 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface NSFont (LineHeight) + +- (CGFloat)lineHeight; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/NSFont+LineHeight.m b/Libraries/Text/NSFont+LineHeight.m new file mode 100644 index 0000000000..de76ce0c59 --- /dev/null +++ b/Libraries/Text/NSFont+LineHeight.m @@ -0,0 +1,20 @@ +/** + * 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 "NSFont+LineHeight.h" + +@implementation NSFont (LineHeight) + +// Taken from: https://github.com/bvanderveen/Thor/blob/0ea3cbd031df6c00fffc54a9b35de7ef787ea36f/Thor/Classes/NSFont%2BLineHeight.m#L5-L7 +- (CGFloat)lineHeight +{ + return ceilf(self.ascender + ABS(self.descender) + self.leading); +} + +@end diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index c0fb167c76..6ce4aa01e9 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -105,6 +105,8 @@ 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */; }; + 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; + 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -114,6 +116,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */, 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */, 5956B160200FF324008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, 5956B161200FF324008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */, @@ -234,12 +237,16 @@ 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Text.m"; sourceTree = ""; }; 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+CGPath.h"; sourceTree = ""; }; 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; + 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+LineHeight.h"; sourceTree = ""; }; + 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSFont+LineHeight.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( + 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */, + 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */, 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */, 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */, 5956B11B200FEBA9008D9D16 /* BaseText */, @@ -485,6 +492,7 @@ 5956B144200FEBAA008D9D16 /* RCTVirtualTextViewManager.m in Sources */, 5956B13B200FEBAA008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */, 5956B134200FEBAA008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */, + 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */, 5956B139200FEBAA008D9D16 /* RCTBaseTextInputViewManager.m in Sources */, 5956B138200FEBAA008D9D16 /* RCTTextSelection.m in Sources */, 5956B130200FEBAA008D9D16 /* RCTRawTextShadowView.m in Sources */, diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index ea72fc310b..7f82782dc1 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -15,6 +15,7 @@ #import #import "NSTextStorage+FontScaling.h" +#import "NSFont+LineHeight.h" #import "RCTTextView.h" @implementation RCTTextShadowView From 245b3fac63a69fea2a949ab2d00e4886599f8201 Mon Sep 17 00:00:00 2001 From: Alec Larson Date: Wed, 27 Feb 2019 13:47:16 -0500 Subject: [PATCH 090/143] disable scroll-related RCTUITextView methods Unlike UITextView, the NSTextView class is not inherently scrollable. --- .../Multiline/RCTMultilineTextInputView.m | 74 +++++++++---------- .../Text/TextInput/Multiline/RCTUITextView.m | 12 +-- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m index c7c4ed373e..34fea76810 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m @@ -30,10 +30,10 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _backedTextInputView.textColor = [NSColor blackColor]; // This line actually removes 5pt (default value) left and right padding in UITextView. _backedTextInputView.textContainer.lineFragmentPadding = 0; -#if !TARGET_OS_TV - _backedTextInputView.scrollsToTop = NO; -#endif - _backedTextInputView.scrollEnabled = YES; +//#if !TARGET_OS_TV +// _backedTextInputView.scrollsToTop = NO; +//#endif +// _backedTextInputView.scrollEnabled = YES; _backedTextInputView.textInputDelegate = self; [self addSubview:_backedTextInputView]; @@ -52,38 +52,38 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge #pragma mark - NSScrollViewDelegate -- (void)scrollViewDidScroll:(NSScrollView *)scrollView -{ - RCTDirectEventBlock onScroll = self.onScroll; - - if (onScroll) { - CGPoint contentOffset = scrollView.contentOffset; - CGSize contentSize = scrollView.contentSize; - CGSize size = scrollView.bounds.size; - NSEdgeInsets contentInset = scrollView.contentInset; - - onScroll(@{ - @"contentOffset": @{ - @"x": @(contentOffset.x), - @"y": @(contentOffset.y) - }, - @"contentInset": @{ - @"top": @(contentInset.top), - @"left": @(contentInset.left), - @"bottom": @(contentInset.bottom), - @"right": @(contentInset.right) - }, - @"contentSize": @{ - @"width": @(contentSize.width), - @"height": @(contentSize.height) - }, - @"layoutMeasurement": @{ - @"width": @(size.width), - @"height": @(size.height) - }, - @"zoomScale": @(scrollView.zoomScale ?: 1), - }); - } -} +//- (void)scrollViewDidScroll:(NSScrollView *)scrollView +//{ +// RCTDirectEventBlock onScroll = self.onScroll; +// +// if (onScroll) { +// CGPoint contentOffset = scrollView.contentOffset; +// CGSize contentSize = scrollView.contentSize; +// CGSize size = scrollView.bounds.size; +// NSEdgeInsets contentInset = scrollView.contentInset; +// +// onScroll(@{ +// @"contentOffset": @{ +// @"x": @(contentOffset.x), +// @"y": @(contentOffset.y) +// }, +// @"contentInset": @{ +// @"top": @(contentInset.top), +// @"left": @(contentInset.left), +// @"bottom": @(contentInset.bottom), +// @"right": @(contentInset.right) +// }, +// @"contentSize": @{ +// @"width": @(contentSize.width), +// @"height": @(contentSize.height) +// }, +// @"layoutMeasurement": @{ +// @"width": @(size.width), +// @"height": @(size.height) +// }, +// @"zoomScale": @(scrollView.zoomScale ?: 1), +// }); +// } +//} @end diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 559eed915e..298e7cc962 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -140,12 +140,12 @@ - (void)paste:(id)sender _textWasPasted = YES; } -- (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated -{ - // Turning off scroll animation. - // This fixes the problem also known as "flaky scrolling". - [super setContentOffset:contentOffset animated:NO]; -} +//- (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated +//{ +// // Turning off scroll animation. +// // This fixes the problem also known as "flaky scrolling". +// [super setContentOffset:contentOffset animated:NO]; +//} #pragma mark - Layout From ba3c9244584788896674eaa75670e6572ff43d5e Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 09:05:30 -0500 Subject: [PATCH 091/143] fix: "sizeThatFits" method of RCTUITextView Currently, the given NSSize is not respected at all, which needs to be fixed! Note: Excess whitespace ensures that future patches can be applied without any edits. --- .../Text/TextInput/Multiline/RCTUITextView.m | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 298e7cc962..61880486f0 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -17,7 +17,7 @@ @implementation RCTUITextView { UILabel *_placeholderView; - UITextView *_detachedTextView; + RCTBackedTextViewDelegateAdapter *_textInputDelegateAdapter; } @@ -198,36 +198,37 @@ - (CGSize)intrinsicContentSize - (CGSize)sizeThatFits:(CGSize)size { // Returned fitting size depends on text size and placeholder size. - CGSize textSize = [self fixedSizeThatFits:size]; + [self.layoutManager ensureLayoutForTextContainer:self.textContainer]; + CGSize textSize = [self.layoutManager usedRectForTextContainer:self.textContainer].size; CGSize placeholderSize = self.placeholderSize; // Returning size DOES contain `textContainerInset` (aka `padding`). return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height)); } -- (CGSize)fixedSizeThatFits:(CGSize)size -{ - // UITextView on iOS 8 has a bug that automatically scrolls to the top - // when calling `sizeThatFits:`. Use a copy so that self is not screwed up. - static BOOL useCustomImplementation = NO; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - useCustomImplementation = ![[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,0,0}]; - }); - if (!useCustomImplementation) { - return [super sizeThatFits:size]; - } - if (!_detachedTextView) { - _detachedTextView = [NSTextView new]; - } - _detachedTextView.attributedText = self.attributedText; - _detachedTextView.font = self.font; - _detachedTextView.textContainerInset = self.textContainerInset; - return [_detachedTextView sizeThatFits:size]; -} + + + + + + + + + + + + + + + + + + + + #pragma mark - Placeholder From e27c4cfeecf2486e3e224c788b0fa3ae0049a9d9 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 10:24:43 -0500 Subject: [PATCH 092/143] add "valueWithCGSize" static method to NSValue This static method exists on iOS but not macOS. --- Libraries/Text/NSValue+CoreGraphics.h | 20 +++++++++++++++++++ Libraries/Text/NSValue+CoreGraphics.m | 20 +++++++++++++++++++ .../Text/RCTText.xcodeproj/project.pbxproj | 8 ++++++++ Libraries/Text/Text/RCTTextShadowView.m | 1 + 4 files changed, 49 insertions(+) create mode 100644 Libraries/Text/NSValue+CoreGraphics.h create mode 100644 Libraries/Text/NSValue+CoreGraphics.m diff --git a/Libraries/Text/NSValue+CoreGraphics.h b/Libraries/Text/NSValue+CoreGraphics.h new file mode 100644 index 0000000000..eb6e0236ad --- /dev/null +++ b/Libraries/Text/NSValue+CoreGraphics.h @@ -0,0 +1,20 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface NSValue (CoreGraphics) + ++ (NSValue *)valueWithCGSize:(CGSize)size; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/NSValue+CoreGraphics.m b/Libraries/Text/NSValue+CoreGraphics.m new file mode 100644 index 0000000000..521e4f01c7 --- /dev/null +++ b/Libraries/Text/NSValue+CoreGraphics.m @@ -0,0 +1,20 @@ +/** + * 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 "NSValue+CoreGraphics.h" + +@implementation NSValue (CoreGraphics) + +// Taken from: https://github.com/dbainbridge/mapbox-osx/blob/3461e73eddd397c415c873d317d346d1d351787a/Map/src/NSValue%2BiOS.m#L32-L35 ++ (NSValue *)valueWithCGSize:(CGSize)size +{ + return [NSValue valueWithSize:NSSizeFromCGSize(size)]; +} + +@end diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 6ce4aa01e9..0bc63e0c16 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -107,6 +107,8 @@ 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */; }; 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */; }; + 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */; }; + 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -116,6 +118,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */, 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */, 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */, 5956B160200FF324008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, @@ -239,12 +242,16 @@ 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+LineHeight.h"; sourceTree = ""; }; 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSFont+LineHeight.m"; sourceTree = ""; }; + 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSValue+CoreGraphics.h"; sourceTree = ""; }; + 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSValue+CoreGraphics.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( + 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */, + 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */, 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */, 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */, 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */, @@ -487,6 +494,7 @@ 5956B13E200FEBAA008D9D16 /* RCTBaseTextViewManager.m in Sources */, 5956B145200FEBAA008D9D16 /* RCTVirtualTextShadowView.m in Sources */, 5956B142200FEBAA008D9D16 /* RCTTextViewManager.m in Sources */, + 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */, 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */, 5956B135200FEBAA008D9D16 /* RCTBaseTextInputView.m in Sources */, 5956B144200FEBAA008D9D16 /* RCTVirtualTextViewManager.m in Sources */, diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index 7f82782dc1..4c64aee88a 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -15,6 +15,7 @@ #import #import "NSTextStorage+FontScaling.h" +#import "NSValue+CoreGraphics.h" #import "NSFont+LineHeight.h" #import "RCTTextView.h" From 21720977be17c1e1bfc77b444559e0af29ac146f Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 10:37:22 -0500 Subject: [PATCH 093/143] feat: add NSLabel for placeholder Thanks to @lhecker for the NSLabel class, which is more memory-efficient than using NSTextField. This shares placeholder logic between RCTUITextField and RCTUITextView. --- Libraries/Text/NSLabel.h | 42 ++++ Libraries/Text/NSLabel.m | 237 ++++++++++++++++++ .../Text/RCTText.xcodeproj/project.pbxproj | 14 +- .../Text/TextInput/Multiline/RCTUITextView.h | 4 +- .../Text/TextInput/Multiline/RCTUITextView.m | 110 +------- .../RCTBackedTextInputViewProtocol.h | 4 +- .../Text/TextInput/RCTBaseTextInputView.h | 2 + .../Text/TextInput/RCTBaseTextInputView.m | 95 ++++++- .../TextInput/RCTBaseTextInputViewManager.m | 4 +- .../TextInput/Singleline/RCTUITextField.h | 2 +- .../TextInput/Singleline/RCTUITextField.m | 54 ---- 11 files changed, 389 insertions(+), 179 deletions(-) create mode 100644 Libraries/Text/NSLabel.h create mode 100644 Libraries/Text/NSLabel.m diff --git a/Libraries/Text/NSLabel.h b/Libraries/Text/NSLabel.h new file mode 100644 index 0000000000..cf97b66017 --- /dev/null +++ b/Libraries/Text/NSLabel.h @@ -0,0 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Leonard Hecker + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#import + +@interface NSLabel : NSView + +@property (nonatomic, copy) NSString *text; +@property (nonatomic, copy) NSAttributedString *attributedText; +@property (nonatomic, retain) NSFont *font; +@property (nonatomic, retain) NSColor *textColor; +@property (nonatomic, retain) NSColor *backgroundColor; +@property (nonatomic, assign) NSInteger numberOfLines; +@property (nonatomic, assign) NSTextAlignment alignment; +@property (nonatomic, assign) NSLineBreakMode lineBreakMode; +@property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; + +- (instancetype)init; +- (instancetype)initWithFrame:(NSRect)frameRect NS_DESIGNATED_INITIALIZER; + +@end diff --git a/Libraries/Text/NSLabel.m b/Libraries/Text/NSLabel.m new file mode 100644 index 0000000000..2f81889175 --- /dev/null +++ b/Libraries/Text/NSLabel.m @@ -0,0 +1,237 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Leonard Hecker + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#import "NSLabel.h" + +#import + +@implementation NSLabel +{ + NSRect _drawingRect; +} + +#pragma mark - NSView overrides + +- (instancetype)init +{ + return [self initWithFrame:NSZeroRect]; +} + +- (instancetype)initWithFrame:(NSRect)frameRect +{ + if (self = [super initWithFrame:frameRect]) { + // _text, _attributedText and _preferredMaxLayoutWidth are nil/0 by default + self.font = self.defaultFont; + self.textColor = self.defaultTextColor; + self.backgroundColor = self.defaultBackgroundColor; + self.numberOfLines = 1; + self.alignment = NSTextAlignmentLeft; + self.lineBreakMode = NSLineBreakByTruncatingTail; + } + + return self; +} + +RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)coder) + +- (BOOL)isOpaque +{ + return self.backgroundColor.alphaComponent == 1.0; +} + +- (CGFloat)baselineOffsetFromBottom +{ + return self.drawingRect.origin.y; +} + +- (NSSize)intrinsicContentSize +{ + return self.drawingRect.size; +} + +- (void)invalidateIntrinsicContentSize +{ + _drawingRect = NSZeroRect; + [super invalidateIntrinsicContentSize]; +} + +- (void)drawRect:(NSRect)dirtyRect +{ + NSRect bounds = self.bounds; + NSRect drawRect = {self.drawingRect.origin, bounds.size}; + NSString* text = nil; + NSAttributedString* attributedText = nil; + + [self.backgroundColor setFill]; + NSRectFillUsingOperation(bounds, NSCompositeSourceOver); + + if ((text = self.text)) { + [text drawWithRect:drawRect options:self.drawingOptions attributes:@{ + NSFontAttributeName : self.font, + NSForegroundColorAttributeName : self.textColor, + NSBackgroundColorAttributeName : self.backgroundColor, + NSParagraphStyleAttributeName : self.drawingParagraphStyle, + }]; + } else if ((attributedText = self.attributedText)) { + [attributedText drawWithRect:drawRect options:self.drawingOptions]; + } +} + +#pragma mark - Private + +- (NSRect)drawingRect +{ + // invalidated by [NSLabel invalidateIntrinsicContentSize] + + NSString* text = nil; + NSAttributedString* attributedText = nil; + + if (NSIsEmptyRect(_drawingRect) && ((text = self.text) || (attributedText = self.attributedText))) { + NSSize size = NSMakeSize(self.preferredMaxLayoutWidth, 0.0); + + if (text) { + _drawingRect = [text boundingRectWithSize:size options:self.drawingOptions attributes:@{ + NSFontAttributeName : self.font, + NSForegroundColorAttributeName : self.textColor, + NSBackgroundColorAttributeName : self.backgroundColor, + NSParagraphStyleAttributeName : self.drawingParagraphStyle, + }]; + } else { + _drawingRect = [attributedText boundingRectWithSize:size options:self.drawingOptions]; + } + + _drawingRect = (NSRect) { + { + ceil(-_drawingRect.origin.x), + ceil(-_drawingRect.origin.y), + }, { + ceil(_drawingRect.size.width), + ceil(_drawingRect.size.height), + } + }; + } + + return _drawingRect; +} + +- (NSStringDrawingOptions)drawingOptions +{ + NSStringDrawingOptions options = NSStringDrawingUsesFontLeading; + + if (self.numberOfLines == 0) { + options |= NSStringDrawingUsesLineFragmentOrigin; + } + + return options; +} + +- (NSParagraphStyle*)drawingParagraphStyle +{ + NSMutableParagraphStyle* ps = [NSMutableParagraphStyle new]; + ps.alignment = self.alignment; + ps.lineBreakMode = self.lineBreakMode; + return ps; +} + +- (NSFont*)defaultFont +{ + return [NSFont labelFontOfSize:12.0]; +} + +- (NSColor*)defaultTextColor +{ + return [NSColor blackColor]; +} + +- (NSColor*)defaultBackgroundColor +{ + return [NSColor clearColor]; +} + +#pragma mark - Display setters + +- (void)setText:(NSString*)text +{ + _text = [text copy]; + _attributedText = nil; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setAttributedText:(NSAttributedString*)attributedText +{ + _text = nil; + _attributedText = [attributedText copy]; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setFont:(NSFont*)font +{ + _font = font ? font : self.defaultFont; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setTextColor:(NSColor*)textColor +{ + _textColor = textColor ? textColor : self.defaultTextColor; + [self setNeedsDisplay:YES]; +} + +- (void)setBackgroundColor:(NSColor*)backgroundColor +{ + _backgroundColor = backgroundColor ? backgroundColor : self.defaultBackgroundColor; + [self setNeedsDisplay:YES]; +} + +- (void)setNumberOfLines:(NSInteger)numberOfLines +{ + _numberOfLines = numberOfLines; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setAlignment:(NSTextAlignment)alignment +{ + _alignment = alignment; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode +{ + _lineBreakMode = lineBreakMode; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +- (void)setPreferredMaxLayoutWidth:(CGFloat)preferredMaxLayoutWidth +{ + _preferredMaxLayoutWidth = preferredMaxLayoutWidth; + [self invalidateIntrinsicContentSize]; + [self setNeedsDisplay:YES]; +} + +@end diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 0bc63e0c16..c5917c7d14 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -103,12 +103,14 @@ 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B103200FEBA9008D9D16 /* RCTUITextField.m */; }; 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */; }; 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; + 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */; }; + 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */; }; + 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE4422138919000CAA67 /* NSLabel.h */; }; + 70588F652227336100CD1EEA /* NSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE422213890E000CAA67 /* NSLabel.m */; }; 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; - 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */; }; 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; - 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */; }; 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */; }; - 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */; }; + 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -118,6 +120,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */, 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */, 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */, 70DB420B2225E4470019CAF9 /* NSBezierPath+CGPath.h in Copy Headers */, @@ -244,12 +247,16 @@ 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSFont+LineHeight.m"; sourceTree = ""; }; 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSValue+CoreGraphics.h"; sourceTree = ""; }; 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSValue+CoreGraphics.m"; sourceTree = ""; }; + 705EDE422213890E000CAA67 /* NSLabel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSLabel.m; sourceTree = ""; }; + 705EDE4422138919000CAA67 /* NSLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSLabel.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( + 705EDE4422138919000CAA67 /* NSLabel.h */, + 705EDE422213890E000CAA67 /* NSLabel.m */, 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */, 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */, 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */, @@ -482,6 +489,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 70588F652227336100CD1EEA /* NSLabel.m in Sources */, 5956B13D200FEBAA008D9D16 /* RCTBaseTextShadowView.m in Sources */, 5956B140200FEBAA008D9D16 /* RCTTextShadowView.m in Sources */, 5956B131200FEBAA008D9D16 /* RCTRawTextViewManager.m in Sources */, diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index ef62b6bfb3..e563cc2fc6 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, weak) id textInputDelegate; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) NSColor *placeholderColor; +// @property (nonatomic, copy, nullable) NSString *placeholder; +// @property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 61880486f0..ad59ebae9f 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -16,22 +16,9 @@ @implementation RCTUITextView { - UILabel *_placeholderView; - RCTBackedTextViewDelegateAdapter *_textInputDelegateAdapter; } -static NSFont *defaultPlaceholderFont() -{ - return [NSFont systemFontOfSize:17]; -} - -static NSColor *defaultPlaceholderColor() -{ - // Default placeholder color from UITextField. - return [NSColor colorWithRed:0 green:0 blue:0.0980392 alpha:0.22]; -} - - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { @@ -40,12 +27,6 @@ - (instancetype)initWithFrame:(CGRect)frame name:NSControlTextDidChangeNotification object:self]; - _placeholderView = [[UILabel alloc] initWithFrame:self.bounds]; -// _placeholderView.isAccessibilityElement = NO; - _placeholderView.numberOfLines = 0; - _placeholderView.textColor = defaultPlaceholderColor(); - [self addSubview:_placeholderView]; - _textInputDelegateAdapter = [[RCTBackedTextViewDelegateAdapter alloc] initWithTextView:self]; } @@ -60,56 +41,24 @@ - (void)dealloc - (NSString *)accessibilityLabel { NSMutableString *accessibilityLabel = [NSMutableString new]; - + NSString *superAccessibilityLabel = [super accessibilityLabel]; if (superAccessibilityLabel.length > 0) { [accessibilityLabel appendString:superAccessibilityLabel]; } - - if (self.placeholder.length > 0 && self.attributedText.string.length == 0) { - if (accessibilityLabel.length > 0) { - [accessibilityLabel appendString:@" "]; - } - [accessibilityLabel appendString:self.placeholder]; - } - + return accessibilityLabel; } #pragma mark - Properties -- (void)setPlaceholder:(NSString *)placeholder -{ - _placeholder = placeholder; - _placeholderView.text = _placeholder; -} - -- (void)setPlaceholderColor:(NSColor *)placeholderColor -{ - _placeholderColor = placeholderColor; - _placeholderView.textColor = _placeholderColor ?: defaultPlaceholderColor(); -} - - (void)textDidChange { _textWasPasted = NO; - [self invalidatePlaceholderVisibility]; } #pragma mark - Overrides -- (void)setFont:(NSFont *)font -{ - [super setFont:font]; - _placeholderView.font = font ?: defaultPlaceholderFont(); -} - -- (void)setTextAlignment:(NSTextAlignment)textAlignment -{ - [super setTextAlignment:textAlignment]; - _placeholderView.textAlignment = textAlignment; -} - - (void)setText:(NSString *)text { [super setText:text]; @@ -149,28 +98,10 @@ - (void)paste:(id)sender #pragma mark - Layout -- (CGFloat)preferredMaxLayoutWidth -{ - // Returning size DOES contain `textContainerInset` (aka `padding`). - return _preferredMaxLayoutWidth ?: self.placeholderSize.width; -} - -- (CGSize)placeholderSize -{ - NSEdgeInsets textContainerInset = self.textContainerInset; - NSString *placeholder = self.placeholder ?: @""; - CGSize placeholderSize = [placeholder sizeWithAttributes:@{NSFontAttributeName: self.font ?: defaultPlaceholderFont()}]; - placeholderSize = CGSizeMake(RCTCeilPixelValue(placeholderSize.width), RCTCeilPixelValue(placeholderSize.height)); - placeholderSize.width += textContainerInset.left + textContainerInset.right; - placeholderSize.height += textContainerInset.top + textContainerInset.bottom; - // Returning size DOES contain `textContainerInset` (aka `padding`; as `sizeThatFits:` does). - return placeholderSize; -} - - (CGSize)contentSize { CGSize contentSize = super.contentSize; - CGSize placeholderSize = self.placeholderSize; + CGSize placeholderSize = CGSizeZero; // When a text input is empty, it actually displays a placehoder. // So, we have to consider `placeholderSize` as a minimum `contentSize`. // Returning size DOES contain `textContainerInset` (aka `padding`). @@ -200,42 +131,9 @@ - (CGSize)sizeThatFits:(CGSize)size // Returned fitting size depends on text size and placeholder size. [self.layoutManager ensureLayoutForTextContainer:self.textContainer]; CGSize textSize = [self.layoutManager usedRectForTextContainer:self.textContainer].size; - CGSize placeholderSize = self.placeholderSize; + CGSize placeholderSize = CGSizeZero; // Returning size DOES contain `textContainerInset` (aka `padding`). return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height)); } - - - - - - - - - - - - - - - - - - - - - - - - - -#pragma mark - Placeholder - -- (void)invalidatePlaceholderVisibility -{ - BOOL isVisible = _placeholder.length != 0 && self.attributedText.length == 0; - _placeholderView.hidden = !isVisible; -} - @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 923794e026..944cc6686e 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -18,8 +18,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong, nullable) NSColor *textColor; @property (nonatomic, strong, nullable) NSFont *font; @property (nonatomic, copy, nullable) NSAttributedString *attributedText; -@property (nonatomic, copy, nullable) NSString *placeholder; -@property (nonatomic, strong, nullable) NSColor *placeholderColor; +// @property (nonatomic, copy, nullable) NSString *placeholder; +// @property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) NSTextAlignment textAlignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, assign) NSEdgeInsets textContainerInset; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index 9d50ef65ce..c4de0e8843 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -48,6 +48,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy) RCTTextSelection *selection; @property (nonatomic, strong, nullable) NSNumber *maxLength; @property (nonatomic, copy) NSAttributedString *attributedText; +@property (nonatomic, copy, nullable) NSString *placeholder; +@property (nonatomic, strong, nullable) NSColor *placeholderColor; @end diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index c694bade77..9bb6eb9c32 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -17,6 +17,7 @@ #import #import +#import "NSLabel.h" #import "RCTTextAttributes.h" #import "RCTTextSelection.h" @@ -26,6 +27,7 @@ @implementation RCTBaseTextInputView { // BOOL _hasInputAccesoryView; NSString *_Nullable _predictedText; NSInteger _nativeEventCount; + NSLabel *_placeholderView; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -62,19 +64,13 @@ - (void)didUpdateReactSubviews - (void)setTextAttributes:(RCTTextAttributes *)textAttributes { _textAttributes = textAttributes; - [self enforceTextAttributesIfNeeded]; -} -- (void)enforceTextAttributesIfNeeded -{ id backedTextInputView = self.backedTextInputView; - if (backedTextInputView.attributedText.string.length != 0) { - return; - } - backedTextInputView.font = _textAttributes.effectiveFont; backedTextInputView.textColor = _textAttributes.effectiveForegroundColor; backedTextInputView.textAlignment = _textAttributes.alignment; + + [self updatePlaceholderStyle]; } - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets @@ -82,6 +78,7 @@ - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets _reactPaddingInsets = reactPaddingInsets; // We apply `paddingInsets` as `backedTextInputView`'s `textContainerInset`. self.backedTextInputView.textContainerInset = reactPaddingInsets; + [self updatePlaceholderFrame]; [self setNeedsLayout]; } @@ -90,6 +87,7 @@ - (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets _reactBorderInsets = reactBorderInsets; // We apply `borderInsets` as `backedTextInputView` layout offset. self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); + [self updatePlaceholderFrame]; [self setNeedsLayout]; } @@ -107,6 +105,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length; self.backedTextInputView.attributedText = attributedText; + [self updatePlaceholderVisibility]; if (selection.length == 0) { // Maintaining a cursor position relative to the end of the old text. @@ -168,6 +167,7 @@ - (void)textInputDidBeginEditing { if (_clearTextOnFocus) { self.backedTextInputView.attributedText = [NSAttributedString new]; + [self updatePlaceholderVisibility]; } if (_selectTextOnFocus) { @@ -297,6 +297,7 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin - (void)textInputDidChange { [self updateLocalData]; + [self updatePlaceholderVisibility]; id backedTextInputView = self.backedTextInputView; @@ -343,7 +344,7 @@ - (void)textInputDidChangeSelection - (void)updateLocalData { - [self enforceTextAttributesIfNeeded]; +// [self enforceTextAttributesIfNeeded]; [_bridge.uiManager setLocalData:[self.backedTextInputView.attributedText copy] forView:self]; @@ -496,4 +497,80 @@ static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange, return YES; } +#pragma mark - Placeholder + +- (NSLabel *)placeholderView +{ + if (_placeholderView == nil) { + _placeholderView = [[NSLabel alloc] initWithFrame:NSZeroRect]; + [self updatePlaceholderStyle]; + [self addSubview:_placeholderView positioned:NSWindowBelow relativeTo:self.backedTextInputView]; + } + return _placeholderView; +} + +- (NSString *)placeholder +{ + return _placeholderView.text; +} + +- (void)setPlaceholder:(NSString *)placeholder +{ + if (placeholder) { + // Use "self" to ensure "placeholderView" exists. + self.placeholderView.text = placeholder; + [self updatePlaceholderFrame]; + } else if (_placeholderView) { + [_placeholderView removeFromSuperview]; + _placeholderView = nil; + } +} + +- (NSColor *)placeholderColor +{ + return _placeholderView.textColor; +} + +- (void)setPlaceholderColor:(NSColor *)color +{ + // Use "self" to ensure "placeholderView" exists. + self.placeholderView.textColor = color ?: _textAttributes.effectiveForegroundColor; +} + +- (void)updatePlaceholderStyle +{ + if (_placeholderView && _textAttributes) { + _placeholderView.font = _textAttributes.effectiveFont; + _placeholderView.textColor = _textAttributes.effectiveForegroundColor; + _placeholderView.alignment = _textAttributes.alignment; + } +} + +- (void)updatePlaceholderFrame +{ + if (_placeholderView) { + NSEdgeInsets insets = self.reactCompoundInsets; + CGFloat maxWidth = self.bounds.size.width - (insets.left + insets.right); + if (maxWidth != _placeholderView.preferredMaxLayoutWidth) { + _placeholderView.preferredMaxLayoutWidth = maxWidth; + } + NSRect bounds = (NSRect){NSZeroPoint, _placeholderView.intrinsicContentSize}; + _placeholderView.frame = NSOffsetRect(bounds, insets.left, insets.top - 1); + } +} + +- (void)updatePlaceholderVisibility +{ + if (_placeholderView) { + BOOL hidden = _placeholderView.text.length == 0 || self.attributedText.length > 0; + _placeholderView.hidden = hidden; + } +} + +- (void)setFrame:(NSRect)frame +{ + [super setFrame:frame]; + [self updatePlaceholderFrame]; +} + @end diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index bbf3202d11..c11950e6c8 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -41,8 +41,8 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL) RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) RCT_REMAP_VIEW_PROPERTY(keyboardType, backedTextInputView.keyboardType, UIKeyboardType) -RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString) -RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, NSColor) +RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString) +RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, placeholderColor, NSColor) RCT_REMAP_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType) RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, NSColor) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index 54bcf2f12c..037e7e6186 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) BOOL caretHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, strong, nullable) NSColor *placeholderColor; +// @property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) NSEdgeInsets textContainerInset; @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 9c5ad1d01a..bca43ae0f3 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -50,33 +50,6 @@ - (void)setTextContainerInset:(NSEdgeInsets)textContainerInset [self setNeedsLayout:YES]; } -- (void)setPlaceholder:(NSString *)placeholder -{ - [super setPlaceholder:placeholder]; - [self _updatePlaceholder]; -} - -- (void)setPlaceholderColor:(NSColor *)placeholderColor -{ - _placeholderColor = placeholderColor; - [self _updatePlaceholder]; -} - -- (void)_updatePlaceholder -{ - if (self.placeholder == nil) { - return; - } - - NSMutableDictionary *attributes = [NSMutableDictionary new]; - if (_placeholderColor) { - [attributes setObject:_placeholderColor forKey:NSForegroundColorAttributeName]; - } - - self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder - attributes:attributes]; -} - #pragma mark - Caret Manipulation //- (CGRect)caretRectForPosition:(UITextPosition *)position @@ -125,31 +98,4 @@ - (void)paste:(id)sender _textWasPasted = YES; } -#pragma mark - Layout - -- (CGSize)contentSize -{ - // Returning size DOES contain `textContainerInset` (aka `padding`). - return self.intrinsicContentSize; -} - -- (CGSize)intrinsicContentSize -{ - // Note: `placeholder` defines intrinsic size for ``. - NSString *text = self.placeholder ?: @""; - CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: self.font}]; - size = CGSizeMake(RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height)); - size.width += _textContainerInset.left + _textContainerInset.right; - size.height += _textContainerInset.top + _textContainerInset.bottom; - // Returning size DOES contain `textContainerInset` (aka `padding`). - return size; -} - -- (CGSize)sizeThatFits:(CGSize)size -{ - // All size values here contain `textContainerInset` (aka `padding`). - CGSize intrinsicSize = self.intrinsicContentSize; - return CGSizeMake(MIN(size.width, intrinsicSize.width), MIN(size.height, intrinsicSize.height)); -} - @end From bd53b7ab6548863af2fa42df1f0e7f25fa939a79 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 10:40:37 -0500 Subject: [PATCH 094/143] fix: "setReactBorderInsets" method of RCTBaseTextInputView --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 9bb6eb9c32..6fbd97a0e7 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -82,6 +82,14 @@ - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets [self setNeedsLayout]; } +static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { + rect.origin.x += insets.left; + rect.origin.y += insets.top; + rect.size.width -= (insets.left + insets.right); + rect.size.height -= (insets.top + insets.bottom); + return rect; +} + - (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets { _reactBorderInsets = reactBorderInsets; From be21162d0ca391339f6e5edae0d6ab4a7e0a7049 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 10:41:22 -0500 Subject: [PATCH 095/143] fix: call "setNeedsLayout" and "setNeedsDisplay" with YES Affected classes: - RCTTextView - RCTUITextField - RCTBaseTextInputView --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 6fbd97a0e7..5d429be12c 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -79,7 +79,7 @@ - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets // We apply `paddingInsets` as `backedTextInputView`'s `textContainerInset`. self.backedTextInputView.textContainerInset = reactPaddingInsets; [self updatePlaceholderFrame]; - [self setNeedsLayout]; + [self setNeedsLayout:YES]; } static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { @@ -96,7 +96,7 @@ - (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets // We apply `borderInsets` as `backedTextInputView` layout offset. self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); [self updatePlaceholderFrame]; - [self setNeedsLayout]; + [self setNeedsLayout:YES]; } - (NSAttributedString *)attributedText From 24f61905ce6740859743d0b0cae7c77e1ad726e2 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 11:39:40 -0500 Subject: [PATCH 096/143] rename "textAlignment" property to "alignment" --- Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h | 2 +- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 944cc6686e..6310b3374d 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) NSAttributedString *attributedText; // @property (nonatomic, copy, nullable) NSString *placeholder; // @property (nonatomic, strong, nullable) NSColor *placeholderColor; -@property (nonatomic, assign) NSTextAlignment textAlignment; +@property (nonatomic, assign) NSTextAlignment alignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, assign) NSEdgeInsets textContainerInset; //@property (nonatomic, strong, nullable) NSView *inputAccessoryView; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 5d429be12c..825fce6e37 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -68,7 +68,7 @@ - (void)setTextAttributes:(RCTTextAttributes *)textAttributes id backedTextInputView = self.backedTextInputView; backedTextInputView.font = _textAttributes.effectiveFont; backedTextInputView.textColor = _textAttributes.effectiveForegroundColor; - backedTextInputView.textAlignment = _textAttributes.alignment; + backedTextInputView.alignment = _textAttributes.alignment; [self updatePlaceholderStyle]; } From 0c4690816d8e33d3c7520c3f9974b0134a8d6027 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 10:58:32 -0500 Subject: [PATCH 097/143] make RCTUITextView conform to RCTBackedTextInputViewProtocol --- .../Text/TextInput/Multiline/RCTUITextView.m | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index ad59ebae9f..2f5594619d 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -59,20 +59,35 @@ - (void)textDidChange #pragma mark - Overrides +- (NSString *)text +{ + return self.string; +} + - (void)setText:(NSString *)text { - [super setText:text]; + [self setString:text]; [self textDidChange]; } +- (NSAttributedString *)attributedText +{ + return self.textStorage; +} + - (void)setAttributedText:(NSAttributedString *)attributedText { - [super setAttributedText:attributedText]; + [self.textStorage setAttributedString:attributedText]; [self textDidChange]; } #pragma mark - Overrides +- (NSRange)selectedTextRange +{ + return self.selectedRange; +} + - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) { From eefd9eba3e47d62c57afeca8ebc5e0a5f9eb16e2 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 11:00:13 -0500 Subject: [PATCH 098/143] make RCTUITextField conform to RCTBackedTextInputViewProtocol --- .../TextInput/Singleline/RCTUITextField.m | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index bca43ae0f3..dd067c9212 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -18,6 +18,8 @@ @implementation RCTUITextField { RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter; } +@dynamic font, alignment; // NSTextField provides these properties + - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { @@ -98,4 +100,26 @@ - (void)paste:(id)sender _textWasPasted = YES; } +#pragma mark - RCTBackedTextInputViewProtocol + +- (NSString *)text +{ + return self.stringValue; +} + +- (void)setText:(NSString *)text +{ + self.stringValue = text; +} + +- (NSAttributedString *)attributedText +{ + return self.attributedStringValue; +} + +- (void)setAttributedText:(NSAttributedString *)attributedText +{ + self.attributedStringValue = attributedText; +} + @end From ff2deff4ca53b9a36d4b0771e71fa4e948de95b8 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 17:56:41 -0500 Subject: [PATCH 099/143] comment out "RCTConvert+Text" methods --- Libraries/Text/RCTConvert+Text.m | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Libraries/Text/RCTConvert+Text.m b/Libraries/Text/RCTConvert+Text.m index 5e4815b1e7..d1b2e13fce 100644 --- a/Libraries/Text/RCTConvert+Text.m +++ b/Libraries/Text/RCTConvert+Text.m @@ -11,20 +11,20 @@ @implementation RCTConvert (Text) -+ (UITextAutocorrectionType)UITextAutocorrectionType:(id)json -{ - return - json == nil ? UITextAutocorrectionTypeDefault : - [RCTConvert BOOL:json] ? UITextAutocorrectionTypeYes : - UITextAutocorrectionTypeNo; -} - -+ (UITextSpellCheckingType)UITextSpellCheckingType:(id)json -{ - return - json == nil ? UITextSpellCheckingTypeDefault : - [RCTConvert BOOL:json] ? UITextSpellCheckingTypeYes : - UITextSpellCheckingTypeNo; -} +//+ (UITextAutocorrectionType)UITextAutocorrectionType:(id)json +//{ +// return +// json == nil ? UITextAutocorrectionTypeDefault : +// [RCTConvert BOOL:json] ? UITextAutocorrectionTypeYes : +// UITextAutocorrectionTypeNo; +//} +// +//+ (UITextSpellCheckingType)UITextSpellCheckingType:(id)json +//{ +// return +// json == nil ? UITextSpellCheckingTypeDefault : +// [RCTConvert BOOL:json] ? UITextSpellCheckingTypeYes : +// UITextSpellCheckingTypeNo; +//} @end From 3ceed4529944a1280125dbb30839ad72628f2cb7 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 18:11:15 -0500 Subject: [PATCH 100/143] add "paddingInsets" property to RCTBackedTextInputViewProtocol The "textContainerInset" property already exists on NSTextView, and its type is NSSize while RCTBackedInputViewProtocol expects the type to be NSEdgeInsets, so a new property name is necessary. --- .../Text/TextInput/Multiline/RCTUITextView.h | 2 +- .../Text/TextInput/Multiline/RCTUITextView.m | 16 ++++++++++++++++ .../TextInput/RCTBackedTextInputViewProtocol.h | 2 +- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 +- .../Text/TextInput/Singleline/RCTUITextField.h | 2 +- .../Text/TextInput/Singleline/RCTUITextField.m | 4 ++-- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index e563cc2fc6..bb56fe491b 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) BOOL textWasPasted; // @property (nonatomic, copy, nullable) NSString *placeholder; // @property (nonatomic, strong, nullable) NSColor *placeholderColor; - +@property (nonatomic, assign) NSEdgeInsets paddingInsets; @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; @end diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 2f5594619d..8d8c15cadc 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -151,4 +151,20 @@ - (CGSize)sizeThatFits:(CGSize)size return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height)); } +#pragma mark - Padding + +- (void)setPaddingInsets:(NSEdgeInsets)paddingInsets +{ + _paddingInsets = paddingInsets; + self.textContainerInset = (NSSize){paddingInsets.right, paddingInsets.bottom}; +} + +- (NSPoint)textContainerOrigin +{ + return (NSPoint){ + _paddingInsets.left - _paddingInsets.right, + _paddingInsets.top - _paddingInsets.bottom + }; +} + @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 6310b3374d..1c1b68bdf1 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN // @property (nonatomic, strong, nullable) NSColor *placeholderColor; @property (nonatomic, assign) NSTextAlignment alignment; @property (nonatomic, assign, readonly) BOOL textWasPasted; -@property (nonatomic, assign) NSEdgeInsets textContainerInset; +@property (nonatomic, assign) NSEdgeInsets paddingInsets; //@property (nonatomic, strong, nullable) NSView *inputAccessoryView; @property (nonatomic, weak, nullable) id textInputDelegate; @property (nonatomic, readonly) CGSize contentSize; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 825fce6e37..5e4bc6fc1d 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -77,7 +77,7 @@ - (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets { _reactPaddingInsets = reactPaddingInsets; // We apply `paddingInsets` as `backedTextInputView`'s `textContainerInset`. - self.backedTextInputView.textContainerInset = reactPaddingInsets; + self.backedTextInputView.paddingInsets = reactPaddingInsets; [self updatePlaceholderFrame]; [self setNeedsLayout:YES]; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index 037e7e6186..2da138c3f4 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) BOOL caretHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; // @property (nonatomic, strong, nullable) NSColor *placeholderColor; -@property (nonatomic, assign) NSEdgeInsets textContainerInset; +@property (nonatomic, assign) NSEdgeInsets paddingInsets; @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index dd067c9212..783aa72dc1 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -46,9 +46,9 @@ - (void)_textDidChange #pragma mark - Properties -- (void)setTextContainerInset:(NSEdgeInsets)textContainerInset +- (void)setPaddingInsets:(NSEdgeInsets)paddingInsets { - _textContainerInset = textContainerInset; + _paddingInsets = paddingInsets; [self setNeedsLayout:YES]; } From dce36bc2ea4babda1da3157e83b51ddb519d9107 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 18:18:03 -0500 Subject: [PATCH 101/143] add "endEditing:" method to NSTextView This is not identical to "UIView:endEditing:" (which searches the subview tree for the first responder), but it does the job (for now). --- .../Text/TextInput/Multiline/RCTUITextView.h | 6 ++++++ .../Text/TextInput/Multiline/RCTUITextView.m | 16 ++++++++++++++++ .../RCTBackedTextInputDelegateAdapter.m | 1 + 3 files changed, 23 insertions(+) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index bb56fe491b..febcb0874b 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -33,4 +33,10 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface NSTextView (EditingControl) + +- (BOOL)endEditing:(BOOL)force; + +@end + NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 8d8c15cadc..d625c4ecf3 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -168,3 +168,19 @@ - (NSPoint)textContainerOrigin } @end + +@implementation NSTextView (EditingControl) + +- (BOOL)endEditing:(BOOL)force +{ + if (self != self.window.firstResponder) { + return YES; + } + if (force || [self.delegate textShouldEndEditing:self]) { + [self.window makeFirstResponder:nil]; + return YES; + } + return NO; +} + +@end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 785aea6177..daed31c28b 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -8,6 +8,7 @@ */ #import "RCTBackedTextInputDelegateAdapter.h" +#import "RCTUITextView.h" #pragma mark - RCTBackedTextFieldDelegateAdapter (for NSTextField) From db0f63fc5689f9699ebb9c17ddd1ee1a5334aae5 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 13 Feb 2019 21:30:38 -0500 Subject: [PATCH 102/143] add AppKit to RCTText.xcodeproj --- .../Text/RCTText.xcodeproj/project.pbxproj | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index c5917c7d14..62010a27fa 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -107,6 +107,7 @@ 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */; }; 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE4422138919000CAA67 /* NSLabel.h */; }; 70588F652227336100CD1EEA /* NSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE422213890E000CAA67 /* NSLabel.m */; }; + 70588F6922273F2300CD1EEA /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70588F6822273F2300CD1EEA /* AppKit.framework */; }; 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */; }; @@ -241,6 +242,7 @@ 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextViewManager.h; sourceTree = ""; }; 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextShadowView.m; sourceTree = ""; }; 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Text.m"; sourceTree = ""; }; + 70588F6822273F2300CD1EEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+CGPath.h"; sourceTree = ""; }; 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+LineHeight.h"; sourceTree = ""; }; @@ -251,6 +253,17 @@ 705EDE4422138919000CAA67 /* NSLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSLabel.h; sourceTree = ""; }; /* End PBXFileReference section */ +/* Begin PBXFrameworksBuildPhase section */ + 70588F6622273F1B00CD1EEA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 70588F6922273F2300CD1EEA /* AppKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + /* Begin PBXGroup section */ 58B511921A9E6C1200147676 = { isa = PBXGroup; @@ -273,6 +286,7 @@ 5956B121200FEBAA008D9D16 /* Text */, 5956B0FF200FEBA9008D9D16 /* TextInput */, 5956B12A200FEBAA008D9D16 /* VirtualText */, + 70588F6722273F2200CD1EEA /* Frameworks */, ); indentWidth = 2; sourceTree = ""; @@ -383,6 +397,14 @@ path = VirtualText; sourceTree = ""; }; + 70588F6722273F2200CD1EEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 70588F6822273F2300CD1EEA /* AppKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -408,6 +430,7 @@ buildPhases = ( 599DF25E1F0306540079B53E /* Copy Headers */, 58B511971A9E6C1200147676 /* Sources */, + 70588F6622273F1B00CD1EEA /* Frameworks */, ); buildRules = ( ); From 4a4329c51b0b8a3b3abd17d85e3879d82d347c11 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Thu, 14 Feb 2019 10:20:48 -0500 Subject: [PATCH 103/143] add "sizeThatFits:" to RCTBackedTextInputViewProtocol --- Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 1c1b68bdf1..aca6544a2b 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -40,6 +40,8 @@ NS_ASSUME_NONNULL_BEGIN // Use `attributedText.string` instead. @property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; +- (CGSize)sizeThatFits:(CGSize)size; + @end NS_ASSUME_NONNULL_END From d55733f9cadd9c423dd20c15fd93625a05266985 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Thu, 14 Feb 2019 11:41:48 -0500 Subject: [PATCH 104/143] remove incompatible TextInput props --- Libraries/Text/TextInput/RCTBaseTextInputViewManager.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index c11950e6c8..53af1d0c86 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -38,17 +38,17 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL) -RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL) -RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) -RCT_REMAP_VIEW_PROPERTY(keyboardType, backedTextInputView.keyboardType, UIKeyboardType) + + + RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString) RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, placeholderColor, NSColor) -RCT_REMAP_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType) + RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, NSColor) RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) -RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) + RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber) From 8ee8c2fef21d3f034cda3a763424d7fa2150ec36 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Thu, 14 Feb 2019 11:42:04 -0500 Subject: [PATCH 105/143] disable unsupported TextInput props --- .../Text/TextInput/RCTBaseTextInputViewManager.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 53af1d0c86..08f85b7498 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -35,8 +35,8 @@ @implementation RCTBaseTextInputViewManager #pragma mark - Unified properties -RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) -RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) +//RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) +//RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL) @@ -45,9 +45,9 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, placeholderColor, NSColor) RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) -RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, NSColor) -RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) -RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) +//RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, NSColor) +//RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) +//RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) @@ -58,7 +58,7 @@ @implementation RCTBaseTextInputViewManager RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) +//RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) From c78f13124cb41369d7d502accdc68e0ea222e566 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 15 Feb 2019 17:06:34 -0500 Subject: [PATCH 106/143] remove tvOS build targets They were causing "ghost errors" (see here: https://stackoverflow.com/a/41645841/2228559) --- Libraries/ART/ART.xcodeproj/project.pbxproj | 127 -- .../Image/RCTImage.xcodeproj/project.pbxproj | 141 -- .../RCTLinking.xcodeproj/project.pbxproj | 74 - .../RCTAnimation.xcodeproj/project.pbxproj | 197 -- .../RCTNetwork.xcodeproj/project.pbxproj | 84 - .../RCTTest/RCTTest.xcodeproj/project.pbxproj | 121 +- .../RCTSettings.xcodeproj/project.pbxproj | 78 +- .../Text/RCTText.xcodeproj/project.pbxproj | 179 -- .../RCTWebSocket.xcodeproj/project.pbxproj | 179 -- .../xcschemes/RNTester-tvOS.xcscheme | 134 -- React/React.xcodeproj/project.pbxproj | 1961 +---------------- 11 files changed, 19 insertions(+), 3256 deletions(-) delete mode 100644 RNTester/RNTester.xcodeproj/xcshareddata/xcschemes/RNTester-tvOS.xcscheme diff --git a/Libraries/ART/ART.xcodeproj/project.pbxproj b/Libraries/ART/ART.xcodeproj/project.pbxproj index 16272a5d1d..9dcf59b154 100644 --- a/Libraries/ART/ART.xcodeproj/project.pbxproj +++ b/Libraries/ART/ART.xcodeproj/project.pbxproj @@ -25,24 +25,6 @@ 0CF68B141AF0549300FF9E5C /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */; }; 0CF68B151AF0549300FF9E5C /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */; }; 0CF68B161AF0549300FF9E5C /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */; }; - 325CF7AD1E5F2ABA00AC9606 /* ARTBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */; }; - 325CF7AE1E5F2ABA00AC9606 /* ARTLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */; }; - 325CF7AF1E5F2ABA00AC9606 /* ARTPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */; }; - 325CF7B01E5F2ABA00AC9606 /* ARTRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */; }; - 325CF7B11E5F2ABA00AC9606 /* ARTSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */; }; - 325CF7B21E5F2ABA00AC9606 /* ARTGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */; }; - 325CF7B31E5F2ABA00AC9606 /* ARTNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */; }; - 325CF7B41E5F2ABA00AC9606 /* ARTRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */; }; - 325CF7B51E5F2ABA00AC9606 /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */; }; - 325CF7B61E5F2ABA00AC9606 /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */; }; - 325CF7B71E5F2ABA00AC9606 /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */; }; - 325CF7B81E5F2ABA00AC9606 /* ARTGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */; }; - 325CF7B91E5F2ABA00AC9606 /* ARTNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE01AF0549300FF9E5C /* ARTNode.m */; }; - 325CF7BA1E5F2ABA00AC9606 /* ARTRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */; }; - 325CF7BB1E5F2ABA00AC9606 /* ARTShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE41AF0549300FF9E5C /* ARTShape.m */; }; - 325CF7BC1E5F2ABA00AC9606 /* ARTSurfaceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */; }; - 325CF7BD1E5F2ABA00AC9606 /* ARTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE81AF0549300FF9E5C /* ARTText.m */; }; - 325CF7BE1E5F2ABA00AC9606 /* RCTConvert+ART.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -55,15 +37,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 323A12851E5F266B004975B8 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -107,7 +80,6 @@ 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceViewManager.m; sourceTree = ""; }; 0CF68B031AF0549300FF9E5C /* ARTTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextManager.h; sourceTree = ""; }; 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTTextManager.m; sourceTree = ""; }; - 323A12871E5F266B004975B8 /* libART-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libART-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -118,13 +90,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 323A12841E5F266B004975B8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -161,7 +126,6 @@ isa = PBXGroup; children = ( 0CF68AC11AF0540F00FF9E5C /* libART.a */, - 323A12871E5F266B004975B8 /* libART-tvOS.a */, ); name = Products; sourceTree = ""; @@ -222,23 +186,6 @@ productReference = 0CF68AC11AF0540F00FF9E5C /* libART.a */; productType = "com.apple.product-type.library.static"; }; - 323A12861E5F266B004975B8 /* ART-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 323A128D1E5F266B004975B8 /* Build configuration list for PBXNativeTarget "ART-tvOS" */; - buildPhases = ( - 323A12831E5F266B004975B8 /* Sources */, - 323A12841E5F266B004975B8 /* Frameworks */, - 323A12851E5F266B004975B8 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "ART-tvOS"; - productName = "ART-tvOS"; - productReference = 323A12871E5F266B004975B8 /* libART-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -250,10 +197,6 @@ 0CF68AC01AF0540F00FF9E5C = { CreatedOnToolsVersion = 6.2; }; - 323A12861E5F266B004975B8 = { - CreatedOnToolsVersion = 6.2; - ProvisioningStyle = Automatic; - }; }; }; buildConfigurationList = 0CF68ABC1AF0540F00FF9E5C /* Build configuration list for PBXProject "ART" */; @@ -269,7 +212,6 @@ projectRoot = ""; targets = ( 0CF68AC01AF0540F00FF9E5C /* ART */, - 323A12861E5F266B004975B8 /* ART-tvOS */, ); }; /* End PBXProject section */ @@ -300,31 +242,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 323A12831E5F266B004975B8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 325CF7B71E5F2ABA00AC9606 /* ARTTextManager.m in Sources */, - 325CF7B21E5F2ABA00AC9606 /* ARTGroupManager.m in Sources */, - 325CF7AF1E5F2ABA00AC9606 /* ARTPattern.m in Sources */, - 325CF7BD1E5F2ABA00AC9606 /* ARTText.m in Sources */, - 325CF7B31E5F2ABA00AC9606 /* ARTNodeManager.m in Sources */, - 325CF7B81E5F2ABA00AC9606 /* ARTGroup.m in Sources */, - 325CF7B41E5F2ABA00AC9606 /* ARTRenderableManager.m in Sources */, - 325CF7BC1E5F2ABA00AC9606 /* ARTSurfaceView.m in Sources */, - 325CF7B01E5F2ABA00AC9606 /* ARTRadialGradient.m in Sources */, - 325CF7B61E5F2ABA00AC9606 /* ARTSurfaceViewManager.m in Sources */, - 325CF7BB1E5F2ABA00AC9606 /* ARTShape.m in Sources */, - 325CF7BA1E5F2ABA00AC9606 /* ARTRenderable.m in Sources */, - 325CF7BE1E5F2ABA00AC9606 /* RCTConvert+ART.m in Sources */, - 325CF7B91E5F2ABA00AC9606 /* ARTNode.m in Sources */, - 325CF7B11E5F2ABA00AC9606 /* ARTSolidColor.m in Sources */, - 325CF7AE1E5F2ABA00AC9606 /* ARTLinearGradient.m in Sources */, - 325CF7AD1E5F2ABA00AC9606 /* ARTBrush.m in Sources */, - 325CF7B51E5F2ABA00AC9606 /* ARTShapeManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ @@ -424,41 +341,6 @@ }; name = Release; }; - 323A128E1E5F266B004975B8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 323A128F1E5F266B004975B8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -480,15 +362,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 323A128D1E5F266B004975B8 /* Build configuration list for PBXNativeTarget "ART-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 323A128E1E5F266B004975B8 /* Debug */, - 323A128F1E5F266B004975B8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 0CF68AB91AF0540F00FF9E5C /* Project object */; diff --git a/Libraries/Image/RCTImage.xcodeproj/project.pbxproj b/Libraries/Image/RCTImage.xcodeproj/project.pbxproj index fe13264c31..3420ea2545 100644 --- a/Libraries/Image/RCTImage.xcodeproj/project.pbxproj +++ b/Libraries/Image/RCTImage.xcodeproj/project.pbxproj @@ -14,23 +14,9 @@ 139A38841C4D587C00862840 /* RCTResizeMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 139A38831C4D587C00862840 /* RCTResizeMode.m */; }; 13EF7F7F1BC825B1003F47DD /* RCTLocalAssetImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF7F7E1BC825B1003F47DD /* RCTLocalAssetImageLoader.m */; }; 143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; }; - 2D3B5F1A1D9B0D0400451313 /* RCTImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD34C261D4B8FE900268922 /* RCTImageCache.m */; }; - 2D3B5F1B1D9B0D0700451313 /* RCTImageBlurUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF314711C9B0DD30049118E /* RCTImageBlurUtils.m */; }; - 2D3B5F1C1D9B0D1300451313 /* RCTResizeMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 139A38831C4D587C00862840 /* RCTResizeMode.m */; }; - 2D3B5F1D1D9B0D1300451313 /* RCTLocalAssetImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF7F7E1BC825B1003F47DD /* RCTLocalAssetImageLoader.m */; }; - 2D3B5F1E1D9B0D1300451313 /* RCTGIFImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */; }; - 2D3B5F1F1D9B0D1300451313 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 354631671B69857700AA0B86 /* RCTImageEditingManager.m */; }; - 2D3B5F201D9B0D1300451313 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; }; - 2D3B5F211D9B0D1300451313 /* RCTImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5A81AA8C4A30002E2BE /* RCTImageView.m */; }; - 2D3B5F221D9B0D1300451313 /* RCTImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */; }; - 2D3B5F231D9B0D1300451313 /* RCTImageStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */; }; - 2D3B5F241D9B0D1300451313 /* RCTImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 134B00A11B54232B00EC8DFB /* RCTImageUtils.m */; }; 35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */; }; 354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 354631671B69857700AA0B86 /* RCTImageEditingManager.m */; }; 3D302E181DF8228100D6DDAE /* RCTImageUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 134B00A01B54232B00EC8DFB /* RCTImageUtils.h */; }; - 3D302F211DF8269200D6DDAE /* RCTImageUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 134B00A01B54232B00EC8DFB /* RCTImageUtils.h */; }; - 3DA05A5A1EE0312600805843 /* RCTImageShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */; }; - 3DA05A5B1EE0312900805843 /* RCTImageShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */; }; 3DED3A8A1DE6F79800336DD7 /* RCTGIFImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5B01AA8C50D0002E2BE /* RCTGIFImageDecoder.h */; }; 3DED3A8B1DE6F79800336DD7 /* RCTImageBlurUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = EEF314701C9B0DD30049118E /* RCTImageBlurUtils.h */; }; 3DED3A8C1DE6F79800336DD7 /* RCTImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD34C251D4B8FE900268922 /* RCTImageCache.h */; }; @@ -42,17 +28,6 @@ 3DED3A921DE6F79800336DD7 /* RCTImageViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5A91AA8C4A30002E2BE /* RCTImageViewManager.h */; }; 3DED3A931DE6F79800336DD7 /* RCTLocalAssetImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 13EF7F7D1BC825B1003F47DD /* RCTLocalAssetImageLoader.h */; }; 3DED3A941DE6F79800336DD7 /* RCTResizeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5FA63E1DE4B44A0058FD77 /* RCTResizeMode.h */; }; - 3DED3A961DE6F7A400336DD7 /* RCTGIFImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5B01AA8C50D0002E2BE /* RCTGIFImageDecoder.h */; }; - 3DED3A971DE6F7A400336DD7 /* RCTImageBlurUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = EEF314701C9B0DD30049118E /* RCTImageBlurUtils.h */; }; - 3DED3A981DE6F7A400336DD7 /* RCTImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD34C251D4B8FE900268922 /* RCTImageCache.h */; }; - 3DED3A991DE6F7A400336DD7 /* RCTImageEditingManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 354631661B69857700AA0B86 /* RCTImageEditingManager.h */; }; - 3DED3A9A1DE6F7A400336DD7 /* RCTImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5FA63C1DE4B44A0058FD77 /* RCTImageLoader.h */; }; - 3DED3A9B1DE6F7A400336DD7 /* RCTImageStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5FA63D1DE4B44A0058FD77 /* RCTImageStoreManager.h */; }; - 3DED3A9C1DE6F7A400336DD7 /* RCTImageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 134B00A01B54232B00EC8DFB /* RCTImageUtils.h */; }; - 3DED3A9D1DE6F7A400336DD7 /* RCTImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5A71AA8C4A30002E2BE /* RCTImageView.h */; }; - 3DED3A9E1DE6F7A400336DD7 /* RCTImageViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5A91AA8C4A30002E2BE /* RCTImageViewManager.h */; }; - 3DED3A9F1DE6F7A400336DD7 /* RCTLocalAssetImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 13EF7F7D1BC825B1003F47DD /* RCTLocalAssetImageLoader.h */; }; - 3DED3AA01DE6F7A400336DD7 /* RCTResizeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5FA63E1DE4B44A0058FD77 /* RCTResizeMode.h */; }; 59AB092A1EDE5DD1009F97B5 /* RCTImageShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */; }; 59AB092B1EDE5DD1009F97B5 /* RCTImageShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */; }; CCD34C271D4B8FE900268922 /* RCTImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD34C261D4B8FE900268922 /* RCTImageCache.m */; }; @@ -71,17 +46,6 @@ name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; }; - 3D302F201DF8268700D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/RCTImage; - dstSubfolderSpec = 16; - files = ( - 3D302F211DF8269200D6DDAE /* RCTImageUtils.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -97,7 +61,6 @@ 13EF7F7D1BC825B1003F47DD /* RCTLocalAssetImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLocalAssetImageLoader.h; sourceTree = ""; }; 13EF7F7E1BC825B1003F47DD /* RCTLocalAssetImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLocalAssetImageLoader.m; sourceTree = ""; }; 143879371AAD32A300F088A5 /* RCTImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoader.m; sourceTree = ""; }; - 2D2A283A1D9B042B00D4039D /* libRCTImage-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTImage-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageStoreManager.m; sourceTree = ""; }; 354631661B69857700AA0B86 /* RCTImageEditingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTImageEditingManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 354631671B69857700AA0B86 /* RCTImageEditingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageEditingManager.m; sourceTree = ""; }; @@ -174,7 +137,6 @@ isa = PBXGroup; children = ( 58B5115D1A9E6B3D00147676 /* libRCTImage.a */, - 2D2A283A1D9B042B00D4039D /* libRCTImage-tvOS.a */, ); name = Products; sourceTree = ""; @@ -201,45 +163,9 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3DED3A951DE6F79D00336DD7 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DED3A961DE6F7A400336DD7 /* RCTGIFImageDecoder.h in Headers */, - 3DED3A971DE6F7A400336DD7 /* RCTImageBlurUtils.h in Headers */, - 3DED3A981DE6F7A400336DD7 /* RCTImageCache.h in Headers */, - 3DED3A991DE6F7A400336DD7 /* RCTImageEditingManager.h in Headers */, - 3DED3A9A1DE6F7A400336DD7 /* RCTImageLoader.h in Headers */, - 3DED3A9B1DE6F7A400336DD7 /* RCTImageStoreManager.h in Headers */, - 3DED3A9C1DE6F7A400336DD7 /* RCTImageUtils.h in Headers */, - 3DA05A5A1EE0312600805843 /* RCTImageShadowView.h in Headers */, - 3DED3A9D1DE6F7A400336DD7 /* RCTImageView.h in Headers */, - 3DED3A9E1DE6F7A400336DD7 /* RCTImageViewManager.h in Headers */, - 3DED3A9F1DE6F7A400336DD7 /* RCTLocalAssetImageLoader.h in Headers */, - 3DED3AA01DE6F7A400336DD7 /* RCTResizeMode.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 2D2A28391D9B042B00D4039D /* RCTImage-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28421D9B042B00D4039D /* Build configuration list for PBXNativeTarget "RCTImage-tvOS" */; - buildPhases = ( - 3DED3A951DE6F79D00336DD7 /* Headers */, - 3D302F201DF8268700D6DDAE /* Copy Headers */, - 2D2A28361D9B042B00D4039D /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTImage-tvOS"; - productName = "RCTImage-tvOS"; - productReference = 2D2A283A1D9B042B00D4039D /* libRCTImage-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 58B5115C1A9E6B3D00147676 /* RCTImage */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511711A9E6B3D00147676 /* Build configuration list for PBXNativeTarget "RCTImage" */; @@ -267,10 +193,6 @@ LastUpgradeCheck = 0810; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A28391D9B042B00D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B5115C1A9E6B3D00147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -289,31 +211,11 @@ projectRoot = ""; targets = ( 58B5115C1A9E6B3D00147676 /* RCTImage */, - 2D2A28391D9B042B00D4039D /* RCTImage-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A28361D9B042B00D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F231D9B0D1300451313 /* RCTImageStoreManager.m in Sources */, - 2D3B5F1A1D9B0D0400451313 /* RCTImageCache.m in Sources */, - 2D3B5F1D1D9B0D1300451313 /* RCTLocalAssetImageLoader.m in Sources */, - 2D3B5F1F1D9B0D1300451313 /* RCTImageEditingManager.m in Sources */, - 2D3B5F1E1D9B0D1300451313 /* RCTGIFImageDecoder.m in Sources */, - 2D3B5F1C1D9B0D1300451313 /* RCTResizeMode.m in Sources */, - 2D3B5F221D9B0D1300451313 /* RCTImageViewManager.m in Sources */, - 2D3B5F211D9B0D1300451313 /* RCTImageView.m in Sources */, - 3DA05A5B1EE0312900805843 /* RCTImageShadowView.m in Sources */, - 2D3B5F201D9B0D1300451313 /* RCTImageLoader.m in Sources */, - 2D3B5F1B1D9B0D0700451313 /* RCTImageBlurUtils.m in Sources */, - 2D3B5F241D9B0D1300451313 /* RCTImageUtils.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511591A9E6B3D00147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -336,40 +238,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A28401D9B042B00D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTImage; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A28411D9B042B00D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTImage; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 58B5116F1A9E6B3D00147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -496,15 +364,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28421D9B042B00D4039D /* Build configuration list for PBXNativeTarget "RCTImage-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28401D9B042B00D4039D /* Debug */, - 2D2A28411D9B042B00D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511581A9E6B3D00147676 /* Build configuration list for PBXProject "RCTImage" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/LinkingIOS/RCTLinking.xcodeproj/project.pbxproj b/Libraries/LinkingIOS/RCTLinking.xcodeproj/project.pbxproj index e9661cc7a1..38a27d4bd0 100644 --- a/Libraries/LinkingIOS/RCTLinking.xcodeproj/project.pbxproj +++ b/Libraries/LinkingIOS/RCTLinking.xcodeproj/project.pbxproj @@ -8,14 +8,12 @@ /* Begin PBXBuildFile section */ 148699CF1ABD045300480536 /* RCTLinkingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 148699CE1ABD045300480536 /* RCTLinkingManager.m */; }; - 2D3B5F251D9B0DE600451313 /* RCTLinkingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 148699CE1ABD045300480536 /* RCTLinkingManager.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libRCTLinking.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTLinking.a; sourceTree = BUILT_PRODUCTS_DIR; }; 148699CD1ABD045300480536 /* RCTLinkingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLinkingManager.h; sourceTree = ""; }; 148699CE1ABD045300480536 /* RCTLinkingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLinkingManager.m; sourceTree = ""; }; - 2D2A28471D9B043800D4039D /* libRCTLinking-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTLinking-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -33,7 +31,6 @@ 148699CD1ABD045300480536 /* RCTLinkingManager.h */, 148699CE1ABD045300480536 /* RCTLinkingManager.m */, 134814211AA4EA7D00B7C361 /* Products */, - 2D2A28471D9B043800D4039D /* libRCTLinking-tvOS.a */, ); indentWidth = 2; sourceTree = ""; @@ -43,21 +40,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2D2A28461D9B043800D4039D /* RCTLinking-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A284F1D9B043800D4039D /* Build configuration list for PBXNativeTarget "RCTLinking-tvOS" */; - buildPhases = ( - 2D2A28431D9B043800D4039D /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTLinking-tvOS"; - productName = "RCTLinking-tvOS"; - productReference = 2D2A28471D9B043800D4039D /* libRCTLinking-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 58B511DA1A9E6C8500147676 /* RCTLinking */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTLinking" */; @@ -82,10 +64,6 @@ LastUpgradeCheck = 0610; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A28461D9B043800D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B511DA1A9E6C8500147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -104,20 +82,11 @@ projectRoot = ""; targets = ( 58B511DA1A9E6C8500147676 /* RCTLinking */, - 2D2A28461D9B043800D4039D /* RCTLinking-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A28431D9B043800D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F251D9B0DE600451313 /* RCTLinkingManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511D71A9E6C8500147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -129,40 +98,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A284D1D9B043800D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A284E1D9B043800D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 58B511ED1A9E6C8500147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -270,15 +205,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A284F1D9B043800D4039D /* Build configuration list for PBXNativeTarget "RCTLinking-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A284D1D9B043800D4039D /* Debug */, - 2D2A284E1D9B043800D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTLinking" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/NativeAnimation/RCTAnimation.xcodeproj/project.pbxproj b/Libraries/NativeAnimation/RCTAnimation.xcodeproj/project.pbxproj index d9274c4884..9416449b15 100644 --- a/Libraries/NativeAnimation/RCTAnimation.xcodeproj/project.pbxproj +++ b/Libraries/NativeAnimation/RCTAnimation.xcodeproj/project.pbxproj @@ -17,49 +17,10 @@ 13E501EE1D07A6C9005F35D8 /* RCTStyleAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E31D07A6C9005F35D8 /* RCTStyleAnimatedNode.m */; }; 13E501EF1D07A6C9005F35D8 /* RCTTransformAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E51D07A6C9005F35D8 /* RCTTransformAnimatedNode.m */; }; 13E501F01D07A6C9005F35D8 /* RCTValueAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E71D07A6C9005F35D8 /* RCTValueAnimatedNode.m */; }; - 192F69811E823F4A008692C7 /* RCTAnimationUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501B71D07A644005F35D8 /* RCTAnimationUtils.h */; }; - 192F69821E823F4A008692C7 /* RCTNativeAnimatedModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501BD1D07A644005F35D8 /* RCTNativeAnimatedModule.h */; }; - 192F69831E823F4A008692C7 /* RCTNativeAnimatedNodesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DA09161DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.h */; }; - 192F69841E823F4A008692C7 /* RCTAnimationDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 94C1294A1D4069170025F25C /* RCTAnimationDriver.h */; }; - 192F69851E823F4A008692C7 /* RCTEventAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 19F00F201DC8847500113FEE /* RCTEventAnimation.h */; }; - 192F69861E823F4A008692C7 /* RCTFrameAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 94C1294C1D4069170025F25C /* RCTFrameAnimation.h */; }; - 192F69871E823F4A008692C7 /* RCTSpringAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 94C1294E1D4069170025F25C /* RCTSpringAnimation.h */; }; - 192F69881E823F4A008692C7 /* RCTDivisionAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C9894931D999639008027DB /* RCTDivisionAnimatedNode.h */; }; - 192F69891E823F4A008692C7 /* RCTDiffClampAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 193F64F21D776EC6004D1CAA /* RCTDiffClampAnimatedNode.h */; }; - 192F698A1E823F4A008692C7 /* RCTAdditionAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501D61D07A6C9005F35D8 /* RCTAdditionAnimatedNode.h */; }; - 192F698B1E823F4A008692C7 /* RCTAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501D81D07A6C9005F35D8 /* RCTAnimatedNode.h */; }; - 192F698C1E823F4A008692C7 /* RCTInterpolationAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501DC1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.h */; }; - 192F698D1E823F4A008692C7 /* RCTModuloAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DAE3F71D7334A70059942F /* RCTModuloAnimatedNode.h */; }; - 192F698E1E823F4A008692C7 /* RCTMultiplicationAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501DE1D07A6C9005F35D8 /* RCTMultiplicationAnimatedNode.h */; }; - 192F698F1E823F4A008692C7 /* RCTPropsAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501E01D07A6C9005F35D8 /* RCTPropsAnimatedNode.h */; }; - 192F69901E823F4A008692C7 /* RCTStyleAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501E21D07A6C9005F35D8 /* RCTStyleAnimatedNode.h */; }; - 192F69911E823F4A008692C7 /* RCTTransformAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501E41D07A6C9005F35D8 /* RCTTransformAnimatedNode.h */; }; - 192F69921E823F4A008692C7 /* RCTValueAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501E61D07A6C9005F35D8 /* RCTValueAnimatedNode.h */; }; - 192F69941E823F78008692C7 /* RCTAnimationUtils.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501B71D07A644005F35D8 /* RCTAnimationUtils.h */; }; - 192F69951E823F78008692C7 /* RCTNativeAnimatedModule.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501BD1D07A644005F35D8 /* RCTNativeAnimatedModule.h */; }; - 192F69961E823F78008692C7 /* RCTNativeAnimatedNodesManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 94DA09161DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.h */; }; - 192F69971E823F78008692C7 /* RCTAnimationDriver.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 94C1294A1D4069170025F25C /* RCTAnimationDriver.h */; }; - 192F69981E823F78008692C7 /* RCTEventAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 19F00F201DC8847500113FEE /* RCTEventAnimation.h */; }; - 192F69991E823F78008692C7 /* RCTFrameAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 94C1294C1D4069170025F25C /* RCTFrameAnimation.h */; }; - 192F699A1E823F78008692C7 /* RCTSpringAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 94C1294E1D4069170025F25C /* RCTSpringAnimation.h */; }; - 192F699B1E823F78008692C7 /* RCTDivisionAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5C9894931D999639008027DB /* RCTDivisionAnimatedNode.h */; }; - 192F699C1E823F78008692C7 /* RCTDiffClampAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 193F64F21D776EC6004D1CAA /* RCTDiffClampAnimatedNode.h */; }; - 192F699D1E823F78008692C7 /* RCTAdditionAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501D61D07A6C9005F35D8 /* RCTAdditionAnimatedNode.h */; }; - 192F699E1E823F78008692C7 /* RCTAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501D81D07A6C9005F35D8 /* RCTAnimatedNode.h */; }; - 192F699F1E823F78008692C7 /* RCTInterpolationAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501DC1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.h */; }; - 192F69A01E823F78008692C7 /* RCTModuloAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 94DAE3F71D7334A70059942F /* RCTModuloAnimatedNode.h */; }; - 192F69A11E823F78008692C7 /* RCTMultiplicationAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501DE1D07A6C9005F35D8 /* RCTMultiplicationAnimatedNode.h */; }; - 192F69A21E823F78008692C7 /* RCTPropsAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E01D07A6C9005F35D8 /* RCTPropsAnimatedNode.h */; }; - 192F69A31E823F78008692C7 /* RCTStyleAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E21D07A6C9005F35D8 /* RCTStyleAnimatedNode.h */; }; - 192F69A41E823F78008692C7 /* RCTTransformAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E41D07A6C9005F35D8 /* RCTTransformAnimatedNode.h */; }; - 192F69A51E823F78008692C7 /* RCTValueAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E61D07A6C9005F35D8 /* RCTValueAnimatedNode.h */; }; 193F64F41D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */; }; 194804ED1E975D8E00623005 /* RCTDecayAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 194804EB1E975D8E00623005 /* RCTDecayAnimation.h */; }; 194804EE1E975D8E00623005 /* RCTDecayAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 194804EC1E975D8E00623005 /* RCTDecayAnimation.m */; }; 194804EF1E975DB500623005 /* RCTDecayAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 194804EB1E975D8E00623005 /* RCTDecayAnimation.h */; }; - 194804F01E975DCF00623005 /* RCTDecayAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 194804EB1E975D8E00623005 /* RCTDecayAnimation.h */; }; - 194804F11E975DD700623005 /* RCTDecayAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 194804EB1E975D8E00623005 /* RCTDecayAnimation.h */; }; - 194804F21E977DDB00623005 /* RCTDecayAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 194804EC1E975D8E00623005 /* RCTDecayAnimation.m */; }; 1980B70E1E80D1C4004DC789 /* RCTAnimationUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501B71D07A644005F35D8 /* RCTAnimationUtils.h */; }; 1980B7101E80D1C4004DC789 /* RCTNativeAnimatedModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E501BD1D07A644005F35D8 /* RCTNativeAnimatedModule.h */; }; 1980B7121E80D1C4004DC789 /* RCTNativeAnimatedNodesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DA09161DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.h */; }; @@ -97,24 +58,7 @@ 1980B7441E80DD6F004DC789 /* RCTTransformAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E41D07A6C9005F35D8 /* RCTTransformAnimatedNode.h */; }; 1980B7451E80DD6F004DC789 /* RCTValueAnimatedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 13E501E61D07A6C9005F35D8 /* RCTValueAnimatedNode.h */; }; 19F00F221DC8847500113FEE /* RCTEventAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 19F00F211DC8847500113FEE /* RCTEventAnimation.m */; }; - 19F00F231DC8848E00113FEE /* RCTEventAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 19F00F211DC8847500113FEE /* RCTEventAnimation.m */; }; - 2D3B5EF21D9B0B3100451313 /* RCTAnimationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501B81D07A644005F35D8 /* RCTAnimationUtils.m */; }; - 2D3B5EF41D9B0B3700451313 /* RCTNativeAnimatedModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501BE1D07A644005F35D8 /* RCTNativeAnimatedModule.m */; }; - 2D3B5EF51D9B0B4800451313 /* RCTDivisionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */; }; - 2D3B5EF61D9B0B4800451313 /* RCTDiffClampAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */; }; - 2D3B5EF71D9B0B4800451313 /* RCTAdditionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501D71D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m */; }; - 2D3B5EF81D9B0B4800451313 /* RCTAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501D91D07A6C9005F35D8 /* RCTAnimatedNode.m */; }; - 2D3B5EFA1D9B0B4800451313 /* RCTInterpolationAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501DD1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.m */; }; - 2D3B5EFB1D9B0B4800451313 /* RCTModuloAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DAE3F81D7334A70059942F /* RCTModuloAnimatedNode.m */; }; - 2D3B5EFC1D9B0B4800451313 /* RCTMultiplicationAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501DF1D07A6C9005F35D8 /* RCTMultiplicationAnimatedNode.m */; }; - 2D3B5EFD1D9B0B4800451313 /* RCTPropsAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E11D07A6C9005F35D8 /* RCTPropsAnimatedNode.m */; }; - 2D3B5EFE1D9B0B4800451313 /* RCTStyleAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E31D07A6C9005F35D8 /* RCTStyleAnimatedNode.m */; }; - 2D3B5EFF1D9B0B4800451313 /* RCTTransformAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E51D07A6C9005F35D8 /* RCTTransformAnimatedNode.m */; }; - 2D3B5F001D9B0B4800451313 /* RCTValueAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E71D07A6C9005F35D8 /* RCTValueAnimatedNode.m */; }; 5C9894951D999639008027DB /* RCTDivisionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */; }; - 944244D01DB962DA0032A02B /* RCTFrameAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C1294D1D4069170025F25C /* RCTFrameAnimation.m */; }; - 944244D11DB962DC0032A02B /* RCTSpringAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C1294F1D4069170025F25C /* RCTSpringAnimation.m */; }; - 9476E8EC1DC9232D005D5CD1 /* RCTNativeAnimatedNodesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DA09171DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.m */; }; 94C129511D40692B0025F25C /* RCTFrameAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C1294D1D4069170025F25C /* RCTFrameAnimation.m */; }; 94C129521D40692B0025F25C /* RCTSpringAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C1294F1D4069170025F25C /* RCTSpringAnimation.m */; }; 94DA09181DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DA09171DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.m */; }; @@ -122,34 +66,6 @@ /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 192F69931E823F4F008692C7 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/RCTAnimation; - dstSubfolderSpec = 16; - files = ( - 194804F11E975DD700623005 /* RCTDecayAnimation.h in CopyFiles */, - 192F69941E823F78008692C7 /* RCTAnimationUtils.h in CopyFiles */, - 192F69951E823F78008692C7 /* RCTNativeAnimatedModule.h in CopyFiles */, - 192F69961E823F78008692C7 /* RCTNativeAnimatedNodesManager.h in CopyFiles */, - 192F69971E823F78008692C7 /* RCTAnimationDriver.h in CopyFiles */, - 192F69981E823F78008692C7 /* RCTEventAnimation.h in CopyFiles */, - 192F69991E823F78008692C7 /* RCTFrameAnimation.h in CopyFiles */, - 192F699A1E823F78008692C7 /* RCTSpringAnimation.h in CopyFiles */, - 192F699B1E823F78008692C7 /* RCTDivisionAnimatedNode.h in CopyFiles */, - 192F699C1E823F78008692C7 /* RCTDiffClampAnimatedNode.h in CopyFiles */, - 192F699D1E823F78008692C7 /* RCTAdditionAnimatedNode.h in CopyFiles */, - 192F699E1E823F78008692C7 /* RCTAnimatedNode.h in CopyFiles */, - 192F699F1E823F78008692C7 /* RCTInterpolationAnimatedNode.h in CopyFiles */, - 192F69A01E823F78008692C7 /* RCTModuloAnimatedNode.h in CopyFiles */, - 192F69A11E823F78008692C7 /* RCTMultiplicationAnimatedNode.h in CopyFiles */, - 192F69A21E823F78008692C7 /* RCTPropsAnimatedNode.h in CopyFiles */, - 192F69A31E823F78008692C7 /* RCTStyleAnimatedNode.h in CopyFiles */, - 192F69A41E823F78008692C7 /* RCTTransformAnimatedNode.h in CopyFiles */, - 192F69A51E823F78008692C7 /* RCTValueAnimatedNode.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1980B7311E80D21C004DC789 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -208,7 +124,6 @@ 194804EC1E975D8E00623005 /* RCTDecayAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDecayAnimation.m; sourceTree = ""; }; 19F00F201DC8847500113FEE /* RCTEventAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTEventAnimation.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 19F00F211DC8847500113FEE /* RCTEventAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventAnimation.m; sourceTree = ""; }; - 2D2A28201D9B03D100D4039D /* libRCTAnimation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAnimation.a; sourceTree = BUILT_PRODUCTS_DIR; }; 5C9894931D999639008027DB /* RCTDivisionAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTDivisionAnimatedNode.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDivisionAnimatedNode.m; sourceTree = ""; }; 94C1294A1D4069170025F25C /* RCTAnimationDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTAnimationDriver.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -272,7 +187,6 @@ 94C129491D4069170025F25C /* Drivers */, 13E501D51D07A6C9005F35D8 /* Nodes */, 134814211AA4EA7D00B7C361 /* Products */, - 2D2A28201D9B03D100D4039D /* libRCTAnimation.a */, ); indentWidth = 2; sourceTree = ""; @@ -298,32 +212,6 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 192F69801E823F2E008692C7 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 194804F01E975DCF00623005 /* RCTDecayAnimation.h in Headers */, - 192F69811E823F4A008692C7 /* RCTAnimationUtils.h in Headers */, - 192F69821E823F4A008692C7 /* RCTNativeAnimatedModule.h in Headers */, - 192F69831E823F4A008692C7 /* RCTNativeAnimatedNodesManager.h in Headers */, - 192F69841E823F4A008692C7 /* RCTAnimationDriver.h in Headers */, - 192F69851E823F4A008692C7 /* RCTEventAnimation.h in Headers */, - 192F69861E823F4A008692C7 /* RCTFrameAnimation.h in Headers */, - 192F69871E823F4A008692C7 /* RCTSpringAnimation.h in Headers */, - 192F69881E823F4A008692C7 /* RCTDivisionAnimatedNode.h in Headers */, - 192F69891E823F4A008692C7 /* RCTDiffClampAnimatedNode.h in Headers */, - 192F698A1E823F4A008692C7 /* RCTAdditionAnimatedNode.h in Headers */, - 192F698B1E823F4A008692C7 /* RCTAnimatedNode.h in Headers */, - 192F698C1E823F4A008692C7 /* RCTInterpolationAnimatedNode.h in Headers */, - 192F698D1E823F4A008692C7 /* RCTModuloAnimatedNode.h in Headers */, - 192F698E1E823F4A008692C7 /* RCTMultiplicationAnimatedNode.h in Headers */, - 192F698F1E823F4A008692C7 /* RCTPropsAnimatedNode.h in Headers */, - 192F69901E823F4A008692C7 /* RCTStyleAnimatedNode.h in Headers */, - 192F69911E823F4A008692C7 /* RCTTransformAnimatedNode.h in Headers */, - 192F69921E823F4A008692C7 /* RCTValueAnimatedNode.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1980B70D1E80D1B5004DC789 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -353,23 +241,6 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 2D2A281F1D9B03D100D4039D /* RCTAnimation-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28281D9B03D100D4039D /* Build configuration list for PBXNativeTarget "RCTAnimation-tvOS" */; - buildPhases = ( - 2D2A281C1D9B03D100D4039D /* Sources */, - 192F69801E823F2E008692C7 /* Headers */, - 192F69931E823F4F008692C7 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTAnimation-tvOS"; - productName = "RCTAnimation-tvOS"; - productReference = 2D2A28201D9B03D100D4039D /* libRCTAnimation.a */; - productType = "com.apple.product-type.library.static"; - }; 58B511DA1A9E6C8500147676 /* RCTAnimation */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimation" */; @@ -396,10 +267,6 @@ LastUpgradeCheck = 0730; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A281F1D9B03D100D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B511DA1A9E6C8500147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -418,37 +285,11 @@ projectRoot = ""; targets = ( 58B511DA1A9E6C8500147676 /* RCTAnimation */, - 2D2A281F1D9B03D100D4039D /* RCTAnimation-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A281C1D9B03D100D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F001D9B0B4800451313 /* RCTValueAnimatedNode.m in Sources */, - 2D3B5EFB1D9B0B4800451313 /* RCTModuloAnimatedNode.m in Sources */, - 2D3B5EF21D9B0B3100451313 /* RCTAnimationUtils.m in Sources */, - 2D3B5EF51D9B0B4800451313 /* RCTDivisionAnimatedNode.m in Sources */, - 2D3B5EF71D9B0B4800451313 /* RCTAdditionAnimatedNode.m in Sources */, - 19F00F231DC8848E00113FEE /* RCTEventAnimation.m in Sources */, - 2D3B5EF41D9B0B3700451313 /* RCTNativeAnimatedModule.m in Sources */, - 2D3B5EF61D9B0B4800451313 /* RCTDiffClampAnimatedNode.m in Sources */, - 2D3B5EF81D9B0B4800451313 /* RCTAnimatedNode.m in Sources */, - 2D3B5EFE1D9B0B4800451313 /* RCTStyleAnimatedNode.m in Sources */, - 2D3B5EFA1D9B0B4800451313 /* RCTInterpolationAnimatedNode.m in Sources */, - 2D3B5EFF1D9B0B4800451313 /* RCTTransformAnimatedNode.m in Sources */, - 2D3B5EFC1D9B0B4800451313 /* RCTMultiplicationAnimatedNode.m in Sources */, - 2D3B5EFD1D9B0B4800451313 /* RCTPropsAnimatedNode.m in Sources */, - 944244D01DB962DA0032A02B /* RCTFrameAnimation.m in Sources */, - 944244D11DB962DC0032A02B /* RCTSpringAnimation.m in Sources */, - 9476E8EC1DC9232D005D5CD1 /* RCTNativeAnimatedNodesManager.m in Sources */, - 194804F21E977DDB00623005 /* RCTDecayAnimation.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511D71A9E6C8500147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -477,35 +318,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A28261D9B03D100D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RCTAnimation; - SDKROOT = appletvos; - }; - name = Debug; - }; - 2D2A28271D9B03D100D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RCTAnimation; - SDKROOT = appletvos; - }; - name = Release; - }; 58B511ED1A9E6C8500147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -622,15 +434,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28281D9B03D100D4039D /* Build configuration list for PBXNativeTarget "RCTAnimation-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28261D9B03D100D4039D /* Debug */, - 2D2A28271D9B03D100D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimation" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/Network/RCTNetwork.xcodeproj/project.pbxproj b/Libraries/Network/RCTNetwork.xcodeproj/project.pbxproj index 83a81e3e62..9860adf58f 100644 --- a/Libraries/Network/RCTNetwork.xcodeproj/project.pbxproj +++ b/Libraries/Network/RCTNetwork.xcodeproj/project.pbxproj @@ -11,12 +11,6 @@ 1372B7371AB03E7B00659ED6 /* RCTNetInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */; }; 13D6D66A1B5FCF8200883BE9 /* RCTNetworkTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */; }; 13EF800E1BCBE015003F47DD /* RCTFileRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */; }; - 2D3B5F261D9B0EAB00451313 /* RCTNetworkTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */; }; - 2D3B5F271D9B0EB400451313 /* RCTHTTPRequestHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.mm */; }; - 2D3B5F281D9B0EB400451313 /* RCTFileRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */; }; - 2D3B5F291D9B0EB400451313 /* RCTDataRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 134E96991BCEB7F800AFFDA1 /* RCTDataRequestHandler.m */; }; - 2D3B5F2A1D9B0EB400451313 /* RCTNetInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */; }; - 2D3B5F2B1D9B0EB400451313 /* RCTNetworking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 58B512071A9E6CE300147676 /* RCTNetworking.mm */; }; 352DA0BA1B17855800AA15A8 /* RCTHTTPRequestHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.mm */; }; 58B512081A9E6CE300147676 /* RCTNetworking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 58B512071A9E6CE300147676 /* RCTNetworking.mm */; }; /* End PBXBuildFile section */ @@ -30,7 +24,6 @@ 13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTask.m; sourceTree = ""; }; 13EF800C1BCBE015003F47DD /* RCTFileRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFileRequestHandler.h; sourceTree = ""; }; 13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFileRequestHandler.m; sourceTree = ""; }; - 2D2A28541D9B044C00D4039D /* libRCTNetwork-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTNetwork-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 352DA0B71B17855800AA15A8 /* RCTHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTHTTPRequestHandler.h; sourceTree = ""; }; 352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTHTTPRequestHandler.mm; sourceTree = ""; }; 3D5FA63F1DE4B4790058FD77 /* RCTNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworking.h; sourceTree = ""; }; @@ -65,7 +58,6 @@ isa = PBXGroup; children = ( 58B511DB1A9E6C8500147676 /* libRCTNetwork.a */, - 2D2A28541D9B044C00D4039D /* libRCTNetwork-tvOS.a */, ); name = Products; sourceTree = ""; @@ -73,21 +65,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2D2A28531D9B044C00D4039D /* RCTNetwork-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A285C1D9B044C00D4039D /* Build configuration list for PBXNativeTarget "RCTNetwork-tvOS" */; - buildPhases = ( - 2D2A28501D9B044C00D4039D /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTNetwork-tvOS"; - productName = "RCTNetwork-tvOS"; - productReference = 2D2A28541D9B044C00D4039D /* libRCTNetwork-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 58B511DA1A9E6C8500147676 /* RCTNetwork */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTNetwork" */; @@ -112,10 +89,6 @@ LastUpgradeCheck = 0810; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A28531D9B044C00D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B511DA1A9E6C8500147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -134,25 +107,11 @@ projectRoot = ""; targets = ( 58B511DA1A9E6C8500147676 /* RCTNetwork */, - 2D2A28531D9B044C00D4039D /* RCTNetwork-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A28501D9B044C00D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F2A1D9B0EB400451313 /* RCTNetInfo.m in Sources */, - 2D3B5F261D9B0EAB00451313 /* RCTNetworkTask.m in Sources */, - 2D3B5F281D9B0EB400451313 /* RCTFileRequestHandler.m in Sources */, - 2D3B5F271D9B0EB400451313 /* RCTHTTPRequestHandler.mm in Sources */, - 2D3B5F2B1D9B0EB400451313 /* RCTNetworking.mm in Sources */, - 2D3B5F291D9B0EB400451313 /* RCTDataRequestHandler.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511D71A9E6C8500147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -169,40 +128,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A285A1D9B044C00D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A285B1D9B044C00D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 58B511ED1A9E6C8500147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -325,15 +250,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A285C1D9B044C00D4039D /* Build configuration list for PBXNativeTarget "RCTNetwork-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A285A1D9B044C00D4039D /* Debug */, - 2D2A285B1D9B044C00D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTNetwork" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj b/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj index e80e605813..abbc44e114 100644 --- a/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj +++ b/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj @@ -7,16 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - 2D3B5F2D1D9B0F2800451313 /* RCTSnapshotManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9913A84A1BBE833400D70E66 /* RCTSnapshotManager.m */; }; - 2D3B5F2E1D9B0F2B00451313 /* RCTTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135341AB3C56F00882537 /* RCTTestModule.m */; }; - 2D3B5F2F1D9B0F2E00451313 /* RCTTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135361AB3C56F00882537 /* RCTTestRunner.m */; }; - 2D3B5F301D9B0F3D00451313 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE71AB964CD007446E2 /* FBSnapshotTestController.m */; }; - 2D3B5F311D9B0F4200451313 /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE91AB964CD007446E2 /* UIImage+Compare.m */; }; - 2D3B5F321D9B0F4500451313 /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FEB1AB964CD007446E2 /* UIImage+Diff.m */; }; 3D3030281DF82A6300D6DDAE /* RCTTestRunner.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 585135351AB3C56F00882537 /* RCTTestRunner.h */; }; - 3D30302A1DF82A8300D6DDAE /* RCTTestRunner.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 585135351AB3C56F00882537 /* RCTTestRunner.h */; }; 3DED3AA21DE6FC3400336DD7 /* RCTTestRunner.h in Headers */ = {isa = PBXBuildFile; fileRef = 585135351AB3C56F00882537 /* RCTTestRunner.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 3DED3AA41DE6FC4C00336DD7 /* RCTTestRunner.h in Headers */ = {isa = PBXBuildFile; fileRef = 585135351AB3C56F00882537 /* RCTTestRunner.h */; settings = {ATTRIBUTES = (Private, ); }; }; 585135371AB3C56F00882537 /* RCTTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135341AB3C56F00882537 /* RCTTestModule.m */; }; 585135381AB3C57000882537 /* RCTTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135361AB3C56F00882537 /* RCTTestRunner.m */; }; 58E64FED1AB964CD007446E2 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE71AB964CD007446E2 /* FBSnapshotTestController.m */; }; @@ -37,21 +29,9 @@ name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; }; - 3D3030291DF82A6E00D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/RCTTest; - dstSubfolderSpec = 16; - files = ( - 3D30302A1DF82A8300D6DDAE /* RCTTestRunner.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 2D2A286E1D9B047700D4039D /* libRCTTest-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTTest-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 580C376F1AB104AF0015E709 /* libRCTTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTTest.a; sourceTree = BUILT_PRODUCTS_DIR; }; 585135331AB3C56F00882537 /* RCTTestModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTestModule.h; sourceTree = ""; }; 585135341AB3C56F00882537 /* RCTTestModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTestModule.m; sourceTree = ""; }; @@ -70,13 +50,6 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 2D2A286B1D9B047700D4039D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 580C376C1AB104AF0015E709 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -108,7 +81,6 @@ isa = PBXGroup; children = ( 580C376F1AB104AF0015E709 /* libRCTTest.a */, - 2D2A286E1D9B047700D4039D /* libRCTTest-tvOS.a */, ); name = Products; sourceTree = ""; @@ -139,35 +111,9 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3DED3AA31DE6FC4700336DD7 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DED3AA41DE6FC4C00336DD7 /* RCTTestRunner.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 2D2A286D1D9B047700D4039D /* RCTTest-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28761D9B047700D4039D /* Build configuration list for PBXNativeTarget "RCTTest-tvOS" */; - buildPhases = ( - 3DED3AA31DE6FC4700336DD7 /* Headers */, - 3D3030291DF82A6E00D6DDAE /* Copy Headers */, - 2D2A286A1D9B047700D4039D /* Sources */, - 2D2A286B1D9B047700D4039D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTTest-tvOS"; - productName = "RCTTest-tvOS"; - productReference = 2D2A286E1D9B047700D4039D /* libRCTTest-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 580C376E1AB104AF0015E709 /* RCTTest */ = { isa = PBXNativeTarget; buildConfigurationList = 580C37831AB104AF0015E709 /* Build configuration list for PBXNativeTarget "RCTTest" */; @@ -195,10 +141,6 @@ LastUpgradeCheck = 0610; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A286D1D9B047700D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 580C376E1AB104AF0015E709 = { CreatedOnToolsVersion = 6.1.1; }; @@ -217,25 +159,11 @@ projectRoot = ""; targets = ( 580C376E1AB104AF0015E709 /* RCTTest */, - 2D2A286D1D9B047700D4039D /* RCTTest-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A286A1D9B047700D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F311D9B0F4200451313 /* UIImage+Compare.m in Sources */, - 2D3B5F2F1D9B0F2E00451313 /* RCTTestRunner.m in Sources */, - 2D3B5F321D9B0F4500451313 /* UIImage+Diff.m in Sources */, - 2D3B5F301D9B0F3D00451313 /* FBSnapshotTestController.m in Sources */, - 2D3B5F2D1D9B0F2800451313 /* RCTSnapshotManager.m in Sources */, - 2D3B5F2E1D9B0F2B00451313 /* RCTTestModule.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 580C376B1AB104AF0015E709 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -252,42 +180,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A28741D9B047700D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTTest; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A28751D9B047700D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTTest; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 580C37811AB104AF0015E709 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -325,7 +217,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -368,7 +260,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -412,15 +304,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28761D9B047700D4039D /* Build configuration list for PBXNativeTarget "RCTTest-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28741D9B047700D4039D /* Debug */, - 2D2A28751D9B047700D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 580C376A1AB104AF0015E709 /* Build configuration list for PBXProject "RCTTest" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/Settings/RCTSettings.xcodeproj/project.pbxproj b/Libraries/Settings/RCTSettings.xcodeproj/project.pbxproj index cf4cea1c7d..a01167e412 100644 --- a/Libraries/Settings/RCTSettings.xcodeproj/project.pbxproj +++ b/Libraries/Settings/RCTSettings.xcodeproj/project.pbxproj @@ -8,14 +8,12 @@ /* Begin PBXBuildFile section */ 13DBA45E1AEE749000A17CF8 /* RCTSettingsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DBA45D1AEE749000A17CF8 /* RCTSettingsManager.m */; }; - 2D3B5F2C1D9B0ECA00451313 /* RCTSettingsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DBA45D1AEE749000A17CF8 /* RCTSettingsManager.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libRCTSettings.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTSettings.a; sourceTree = BUILT_PRODUCTS_DIR; }; 13DBA45C1AEE749000A17CF8 /* RCTSettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSettingsManager.h; sourceTree = ""; }; 13DBA45D1AEE749000A17CF8 /* RCTSettingsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSettingsManager.m; sourceTree = ""; }; - 2D2A28611D9B046600D4039D /* libRCTSettings-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTSettings-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -33,7 +31,6 @@ 13DBA45C1AEE749000A17CF8 /* RCTSettingsManager.h */, 13DBA45D1AEE749000A17CF8 /* RCTSettingsManager.m */, 134814211AA4EA7D00B7C361 /* Products */, - 2D2A28611D9B046600D4039D /* libRCTSettings-tvOS.a */, ); indentWidth = 2; sourceTree = ""; @@ -43,21 +40,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2D2A28601D9B046600D4039D /* RCTSettings-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28691D9B046600D4039D /* Build configuration list for PBXNativeTarget "RCTSettings-tvOS" */; - buildPhases = ( - 2D2A285D1D9B046600D4039D /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTSettings-tvOS"; - productName = "RCTSettings-tvOS"; - productReference = 2D2A28611D9B046600D4039D /* libRCTSettings-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 58B511DA1A9E6C8500147676 /* RCTSettings */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTSettings" */; @@ -82,10 +64,6 @@ LastUpgradeCheck = 0610; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A28601D9B046600D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B511DA1A9E6C8500147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -104,20 +82,11 @@ projectRoot = ""; targets = ( 58B511DA1A9E6C8500147676 /* RCTSettings */, - 2D2A28601D9B046600D4039D /* RCTSettings-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A285D1D9B046600D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F2C1D9B0ECA00451313 /* RCTSettingsManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511D71A9E6C8500147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -129,40 +98,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A28671D9B046600D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A28681D9B046600D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 58B511ED1A9E6C8500147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -200,7 +135,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -243,7 +178,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -276,15 +211,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28691D9B046600D4039D /* Build configuration list for PBXNativeTarget "RCTSettings-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28671D9B046600D4039D /* Debug */, - 2D2A28681D9B046600D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTSettings" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 62010a27fa..51d005e852 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -55,54 +55,6 @@ 5956B176200FF324008D9D16 /* RCTUITextField.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B105200FEBA9008D9D16 /* RCTUITextField.h */; }; 5956B177200FF324008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */; }; 5956B178200FF324008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */; }; - 5956B179200FF338008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11D200FEBA9008D9D16 /* RCTBaseTextShadowView.h */; }; - 5956B17A200FF338008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11C200FEBA9008D9D16 /* RCTBaseTextViewManager.h */; }; - 5956B17B200FF338008D9D16 /* RCTRawTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FC200FEBA9008D9D16 /* RCTRawTextShadowView.h */; }; - 5956B17C200FF338008D9D16 /* RCTRawTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */; }; - 5956B17D200FF338008D9D16 /* RCTConvert+Text.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */; }; - 5956B17E200FF338008D9D16 /* RCTTextAttributes.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B11A200FEBA9008D9D16 /* RCTTextAttributes.h */; }; - 5956B17F200FF338008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B129200FEBAA008D9D16 /* NSTextStorage+FontScaling.h */; }; - 5956B180200FF338008D9D16 /* RCTTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B126200FEBAA008D9D16 /* RCTTextShadowView.h */; }; - 5956B181200FF338008D9D16 /* RCTTextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B123200FEBAA008D9D16 /* RCTTextView.h */; }; - 5956B182200FF338008D9D16 /* RCTTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B124200FEBAA008D9D16 /* RCTTextViewManager.h */; }; - 5956B183200FF338008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B117200FEBA9008D9D16 /* RCTMultilineTextInputView.h */; }; - 5956B184200FF338008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B114200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.h */; }; - 5956B185200FF338008D9D16 /* RCTUITextView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B116200FEBA9008D9D16 /* RCTUITextView.h */; }; - 5956B186200FF338008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10C200FEBA9008D9D16 /* RCTBackedTextInputDelegate.h */; }; - 5956B187200FF338008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B107200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.h */; }; - 5956B188200FF338008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B112200FEBA9008D9D16 /* RCTBackedTextInputViewProtocol.h */; }; - 5956B189200FF338008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B109200FEBA9008D9D16 /* RCTBaseTextInputShadowView.h */; }; - 5956B18A200FF338008D9D16 /* RCTBaseTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10E200FEBA9008D9D16 /* RCTBaseTextInputView.h */; }; - 5956B18B200FF338008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B10B200FEBA9008D9D16 /* RCTBaseTextInputViewManager.h */; }; - 5956B18C200FF338008D9D16 /* RCTTextSelection.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B108200FEBA9008D9D16 /* RCTTextSelection.h */; }; - 5956B18D200FF338008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */; }; - 5956B18E200FF338008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */; }; - 5956B18F200FF338008D9D16 /* RCTUITextField.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B105200FEBA9008D9D16 /* RCTUITextField.h */; }; - 5956B190200FF338008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12C200FEBAA008D9D16 /* RCTVirtualTextShadowView.h */; }; - 5956B191200FF338008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5956B12D200FEBAA008D9D16 /* RCTVirtualTextViewManager.h */; }; - 5956B192200FF35C008D9D16 /* RCTBaseTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11E200FEBA9008D9D16 /* RCTBaseTextShadowView.m */; }; - 5956B193200FF35C008D9D16 /* RCTBaseTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B11F200FEBA9008D9D16 /* RCTBaseTextViewManager.m */; }; - 5956B194200FF35C008D9D16 /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FD200FEBA9008D9D16 /* RCTRawTextShadowView.m */; }; - 5956B195200FF35C008D9D16 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B0FE200FEBA9008D9D16 /* RCTRawTextViewManager.m */; }; - 5956B196200FF35C008D9D16 /* RCTConvert+Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */; }; - 5956B197200FF35C008D9D16 /* RCTTextAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B120200FEBA9008D9D16 /* RCTTextAttributes.m */; }; - 5956B198200FF35C008D9D16 /* NSTextStorage+FontScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B125200FEBAA008D9D16 /* NSTextStorage+FontScaling.m */; }; - 5956B199200FF35C008D9D16 /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B122200FEBAA008D9D16 /* RCTTextShadowView.m */; }; - 5956B19A200FF35C008D9D16 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B128200FEBAA008D9D16 /* RCTTextView.m */; }; - 5956B19B200FF35C008D9D16 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B127200FEBAA008D9D16 /* RCTTextViewManager.m */; }; - 5956B19C200FF35C008D9D16 /* RCTMultilineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B115200FEBA9008D9D16 /* RCTMultilineTextInputView.m */; }; - 5956B19D200FF35C008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B118200FEBA9008D9D16 /* RCTMultilineTextInputViewManager.m */; }; - 5956B19E200FF35C008D9D16 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B119200FEBA9008D9D16 /* RCTUITextView.m */; }; - 5956B19F200FF35C008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10D200FEBA9008D9D16 /* RCTBackedTextInputDelegateAdapter.m */; }; - 5956B1A0200FF35C008D9D16 /* RCTBaseTextInputShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10F200FEBA9008D9D16 /* RCTBaseTextInputShadowView.m */; }; - 5956B1A1200FF35C008D9D16 /* RCTBaseTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B10A200FEBA9008D9D16 /* RCTBaseTextInputView.m */; }; - 5956B1A2200FF35C008D9D16 /* RCTBaseTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B111200FEBA9008D9D16 /* RCTBaseTextInputViewManager.m */; }; - 5956B1A3200FF35C008D9D16 /* RCTTextSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B110200FEBA9008D9D16 /* RCTTextSelection.m */; }; - 5956B1A4200FF35C008D9D16 /* RCTSinglelineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */; }; - 5956B1A5200FF35C008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B106200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.m */; }; - 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B103200FEBA9008D9D16 /* RCTUITextField.m */; }; - 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */; }; - 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956B12B200FEBAA008D9D16 /* RCTVirtualTextViewManager.m */; }; 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */; }; 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */; }; 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE4422138919000CAA67 /* NSLabel.h */; }; @@ -154,45 +106,9 @@ name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; }; - 599DF2601F0306AD0079B53E /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/RCTText; - dstSubfolderSpec = 16; - files = ( - 5956B179200FF338008D9D16 /* RCTBaseTextShadowView.h in Copy Headers */, - 5956B17A200FF338008D9D16 /* RCTBaseTextViewManager.h in Copy Headers */, - 5956B17B200FF338008D9D16 /* RCTRawTextShadowView.h in Copy Headers */, - 5956B17C200FF338008D9D16 /* RCTRawTextViewManager.h in Copy Headers */, - 5956B17D200FF338008D9D16 /* RCTConvert+Text.h in Copy Headers */, - 5956B17E200FF338008D9D16 /* RCTTextAttributes.h in Copy Headers */, - 5956B17F200FF338008D9D16 /* NSTextStorage+FontScaling.h in Copy Headers */, - 5956B180200FF338008D9D16 /* RCTTextShadowView.h in Copy Headers */, - 5956B181200FF338008D9D16 /* RCTTextView.h in Copy Headers */, - 5956B182200FF338008D9D16 /* RCTTextViewManager.h in Copy Headers */, - 5956B183200FF338008D9D16 /* RCTMultilineTextInputView.h in Copy Headers */, - 5956B184200FF338008D9D16 /* RCTMultilineTextInputViewManager.h in Copy Headers */, - 5956B185200FF338008D9D16 /* RCTUITextView.h in Copy Headers */, - 5956B186200FF338008D9D16 /* RCTBackedTextInputDelegate.h in Copy Headers */, - 5956B187200FF338008D9D16 /* RCTBackedTextInputDelegateAdapter.h in Copy Headers */, - 5956B188200FF338008D9D16 /* RCTBackedTextInputViewProtocol.h in Copy Headers */, - 5956B189200FF338008D9D16 /* RCTBaseTextInputShadowView.h in Copy Headers */, - 5956B18A200FF338008D9D16 /* RCTBaseTextInputView.h in Copy Headers */, - 5956B18B200FF338008D9D16 /* RCTBaseTextInputViewManager.h in Copy Headers */, - 5956B18C200FF338008D9D16 /* RCTTextSelection.h in Copy Headers */, - 5956B18D200FF338008D9D16 /* RCTSinglelineTextInputView.h in Copy Headers */, - 5956B18E200FF338008D9D16 /* RCTSinglelineTextInputViewManager.h in Copy Headers */, - 5956B18F200FF338008D9D16 /* RCTUITextField.h in Copy Headers */, - 5956B190200FF338008D9D16 /* RCTVirtualTextShadowView.h in Copy Headers */, - 5956B191200FF338008D9D16 /* RCTVirtualTextViewManager.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 2D2A287B1D9B048500D4039D /* libRCTText-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTText-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 58B5119B1A9E6C1200147676 /* libRCTText.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTText.a; sourceTree = BUILT_PRODUCTS_DIR; }; 5956B0F9200FEBA9008D9D16 /* RCTConvert+Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Text.h"; sourceTree = ""; }; 5956B0FB200FEBA9008D9D16 /* RCTRawTextViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRawTextViewManager.h; sourceTree = ""; }; @@ -297,7 +213,6 @@ isa = PBXGroup; children = ( 58B5119B1A9E6C1200147676 /* libRCTText.a */, - 2D2A287B1D9B048500D4039D /* libRCTText-tvOS.a */, ); name = Products; sourceTree = ""; @@ -408,22 +323,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2D2A287A1D9B048500D4039D /* RCTText-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28831D9B048500D4039D /* Build configuration list for PBXNativeTarget "RCTText-tvOS" */; - buildPhases = ( - 599DF2601F0306AD0079B53E /* Copy Headers */, - 2D2A28771D9B048500D4039D /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "RCTText-tvOS"; - productName = "RCTText-tvOS"; - productReference = 2D2A287B1D9B048500D4039D /* libRCTText-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 58B5119A1A9E6C1200147676 /* RCTText */ = { isa = PBXNativeTarget; buildConfigurationList = 58B511AF1A9E6C1300147676 /* Build configuration list for PBXNativeTarget "RCTText" */; @@ -450,10 +349,6 @@ LastUpgradeCheck = 0610; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A287A1D9B048500D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 58B5119A1A9E6C1200147676 = { CreatedOnToolsVersion = 6.1.1; }; @@ -472,42 +367,11 @@ projectRoot = ""; targets = ( 58B5119A1A9E6C1200147676 /* RCTText */, - 2D2A287A1D9B048500D4039D /* RCTText-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A28771D9B048500D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5956B192200FF35C008D9D16 /* RCTBaseTextShadowView.m in Sources */, - 5956B193200FF35C008D9D16 /* RCTBaseTextViewManager.m in Sources */, - 5956B194200FF35C008D9D16 /* RCTRawTextShadowView.m in Sources */, - 5956B195200FF35C008D9D16 /* RCTRawTextViewManager.m in Sources */, - 5956B196200FF35C008D9D16 /* RCTConvert+Text.m in Sources */, - 5956B197200FF35C008D9D16 /* RCTTextAttributes.m in Sources */, - 5956B198200FF35C008D9D16 /* NSTextStorage+FontScaling.m in Sources */, - 5956B199200FF35C008D9D16 /* RCTTextShadowView.m in Sources */, - 5956B19A200FF35C008D9D16 /* RCTTextView.m in Sources */, - 5956B19B200FF35C008D9D16 /* RCTTextViewManager.m in Sources */, - 5956B19C200FF35C008D9D16 /* RCTMultilineTextInputView.m in Sources */, - 5956B19D200FF35C008D9D16 /* RCTMultilineTextInputViewManager.m in Sources */, - 5956B19E200FF35C008D9D16 /* RCTUITextView.m in Sources */, - 5956B19F200FF35C008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */, - 5956B1A0200FF35C008D9D16 /* RCTBaseTextInputShadowView.m in Sources */, - 5956B1A1200FF35C008D9D16 /* RCTBaseTextInputView.m in Sources */, - 5956B1A2200FF35C008D9D16 /* RCTBaseTextInputViewManager.m in Sources */, - 5956B1A3200FF35C008D9D16 /* RCTTextSelection.m in Sources */, - 5956B1A4200FF35C008D9D16 /* RCTSinglelineTextInputView.m in Sources */, - 5956B1A5200FF35C008D9D16 /* RCTSinglelineTextInputViewManager.m in Sources */, - 5956B1A6200FF35C008D9D16 /* RCTUITextField.m in Sources */, - 5956B1A7200FF35C008D9D16 /* RCTVirtualTextShadowView.m in Sources */, - 5956B1A8200FF35C008D9D16 /* RCTVirtualTextViewManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 58B511971A9E6C1200147676 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -545,40 +409,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 2D2A28811D9B048500D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D2A28821D9B048500D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; 58B511AD1A9E6C1300147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -695,15 +525,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28831D9B048500D4039D /* Build configuration list for PBXNativeTarget "RCTText-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28811D9B048500D4039D /* Debug */, - 2D2A28821D9B048500D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 58B511961A9E6C1200147676 /* Build configuration list for PBXProject "RCTText" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj b/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj index e6350493c8..688ae3650c 100644 --- a/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj +++ b/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj @@ -9,17 +9,10 @@ /* Begin PBXBuildFile section */ 1338BBE01B04ACC80064A9C9 /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDD1B04ACC80064A9C9 /* RCTSRWebSocket.m */; }; 1338BBE11B04ACC80064A9C9 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */; }; - 2D3B5F3D1D9B165B00451313 /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDD1B04ACC80064A9C9 /* RCTSRWebSocket.m */; }; - 2D3B5F3E1D9B165B00451313 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */; }; - 2D3B5F401D9B165B00451313 /* RCTWebSocketModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C86DF7B1ADF695F0047B81A /* RCTWebSocketModule.m */; }; - 2DC5E5281F3A6CFD000EE84B /* libfishhook-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC5E5271F3A6CFD000EE84B /* libfishhook-tvOS.a */; }; 3C86DF7C1ADF695F0047B81A /* RCTWebSocketModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C86DF7B1ADF695F0047B81A /* RCTWebSocketModule.m */; }; 3DBE0D141F3B185A0099AA32 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 3DBE0D121F3B185A0099AA32 /* fishhook.c */; }; - 3DBE0D151F3B185A0099AA32 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 3DBE0D121F3B185A0099AA32 /* fishhook.c */; }; 3DBE0D801F3B1AF00099AA32 /* fishhook.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DBE0D131F3B185A0099AA32 /* fishhook.h */; }; - 3DBE0D821F3B1B0C0099AA32 /* fishhook.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DBE0D131F3B185A0099AA32 /* fishhook.h */; }; A12E9E2E1E5DEC4E0029001B /* RCTReconnectingWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = A12E9E2D1E5DEC4E0029001B /* RCTReconnectingWebSocket.m */; }; - A12E9E2F1E5DEC550029001B /* RCTReconnectingWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = A12E9E2D1E5DEC4E0029001B /* RCTReconnectingWebSocket.m */; }; D426ACCE20D56EFD003B4C4D /* libfishhook.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DBE0D001F3B181A0099AA32 /* libfishhook.a */; }; /* End PBXBuildFile section */ @@ -31,13 +24,6 @@ remoteGlobalIDString = 3DBE0CF41F3B181A0099AA32; remoteInfo = fishhook; }; - 3DBE0D101F3B184D0099AA32 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3C86DF3E1ADF2C930047B81A /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3DBE0D011F3B181C0099AA32; - remoteInfo = "fishhook-tvOS"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -51,16 +37,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3DBE0D811F3B1B010099AA32 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/fishhook; - dstSubfolderSpec = 16; - files = ( - 3DBE0D821F3B1B0C0099AA32 /* fishhook.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -69,13 +45,11 @@ 1338BBDE1B04ACC80064A9C9 /* RCTWebSocketExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketExecutor.h; sourceTree = ""; }; 1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketExecutor.m; sourceTree = ""; }; 13526A511F362F7F0008EF00 /* libfishhook.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libfishhook.a; sourceTree = ""; }; - 2D2A28881D9B049200D4039D /* libRCTWebSocket-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTWebSocket-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2DC5E5271F3A6CFD000EE84B /* libfishhook-tvOS.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfishhook-tvOS.a"; path = "../fishhook/build/Debug-appletvos/libfishhook-tvOS.a"; sourceTree = ""; }; 3C86DF461ADF2C930047B81A /* libRCTWebSocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWebSocket.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3C86DF7A1ADF695F0047B81A /* RCTWebSocketModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketModule.h; sourceTree = ""; }; 3C86DF7B1ADF695F0047B81A /* RCTWebSocketModule.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketModule.m; sourceTree = ""; tabWidth = 2; }; 3DBE0D001F3B181A0099AA32 /* libfishhook.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfishhook.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3DBE0D0D1F3B181C0099AA32 /* libfishhook-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libfishhook-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3DBE0D121F3B185A0099AA32 /* fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fishhook.c; path = ../fishhook/fishhook.c; sourceTree = ""; }; 3DBE0D131F3B185A0099AA32 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = ../fishhook/fishhook.h; sourceTree = ""; }; A12E9E2C1E5DEC4E0029001B /* RCTReconnectingWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTReconnectingWebSocket.h; sourceTree = ""; }; @@ -91,14 +65,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2DC5E5151F3A6C39000EE84B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2DC5E5281F3A6CFD000EE84B /* libfishhook-tvOS.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -136,9 +102,7 @@ isa = PBXGroup; children = ( 3C86DF461ADF2C930047B81A /* libRCTWebSocket.a */, - 2D2A28881D9B049200D4039D /* libRCTWebSocket-tvOS.a */, 3DBE0D001F3B181A0099AA32 /* libfishhook.a */, - 3DBE0D0D1F3B181C0099AA32 /* libfishhook-tvOS.a */, ); name = Products; sourceTree = ""; @@ -146,23 +110,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2D2A28871D9B049200D4039D /* RCTWebSocket-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A28901D9B049200D4039D /* Build configuration list for PBXNativeTarget "RCTWebSocket-tvOS" */; - buildPhases = ( - 2D2A28841D9B049200D4039D /* Sources */, - 2DC5E5151F3A6C39000EE84B /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3DBE0D111F3B184D0099AA32 /* PBXTargetDependency */, - ); - name = "RCTWebSocket-tvOS"; - productName = "RCTWebSocket-tvOS"; - productReference = 2D2A28881D9B049200D4039D /* libRCTWebSocket-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; 3C86DF451ADF2C930047B81A /* RCTWebSocket */ = { isa = PBXNativeTarget; buildConfigurationList = 3C86DF5A1ADF2C930047B81A /* Build configuration list for PBXNativeTarget "RCTWebSocket" */; @@ -196,22 +143,6 @@ productReference = 3DBE0D001F3B181A0099AA32 /* libfishhook.a */; productType = "com.apple.product-type.library.static"; }; - 3DBE0D011F3B181C0099AA32 /* fishhook-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3DBE0D0A1F3B181C0099AA32 /* Build configuration list for PBXNativeTarget "fishhook-tvOS" */; - buildPhases = ( - 3DBE0D811F3B1B010099AA32 /* CopyFiles */, - 3DBE0D021F3B181C0099AA32 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "fishhook-tvOS"; - productName = "RCTWebSocket-tvOS"; - productReference = 3DBE0D0D1F3B181C0099AA32 /* libfishhook-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -221,10 +152,6 @@ LastUpgradeCheck = 0630; ORGANIZATIONNAME = Facebook; TargetAttributes = { - 2D2A28871D9B049200D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; 3C86DF451ADF2C930047B81A = { CreatedOnToolsVersion = 6.3; }; @@ -243,25 +170,12 @@ projectRoot = ""; targets = ( 3C86DF451ADF2C930047B81A /* RCTWebSocket */, - 2D2A28871D9B049200D4039D /* RCTWebSocket-tvOS */, 3DBE0CF41F3B181A0099AA32 /* fishhook */, - 3DBE0D011F3B181C0099AA32 /* fishhook-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 2D2A28841D9B049200D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3B5F3E1D9B165B00451313 /* RCTWebSocketExecutor.m in Sources */, - 2D3B5F401D9B165B00451313 /* RCTWebSocketModule.m in Sources */, - A12E9E2F1E5DEC550029001B /* RCTReconnectingWebSocket.m in Sources */, - 2D3B5F3D1D9B165B00451313 /* RCTSRWebSocket.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3C86DF421ADF2C930047B81A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -281,14 +195,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3DBE0D021F3B181C0099AA32 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DBE0D151F3B185A0099AA32 /* fishhook.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -297,46 +203,9 @@ target = 3DBE0CF41F3B181A0099AA32 /* fishhook */; targetProxy = 3DBE0D0E1F3B18490099AA32 /* PBXContainerItemProxy */; }; - 3DBE0D111F3B184D0099AA32 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3DBE0D011F3B181C0099AA32 /* fishhook-tvOS */; - targetProxy = 3DBE0D101F3B184D0099AA32 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 2D2A288E1D9B049200D4039D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - WARNING_CFLAGS = ""; - }; - name = Debug; - }; - 2D2A288F1D9B049200D4039D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - WARNING_CFLAGS = ""; - }; - name = Release; - }; 3C86DF581ADF2C930047B81A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -483,48 +352,9 @@ }; name = Release; }; - 3DBE0D0B1F3B181C0099AA32 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 3DBE0D0C1F3B181C0099AA32 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2D2A28901D9B049200D4039D /* Build configuration list for PBXNativeTarget "RCTWebSocket-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A288E1D9B049200D4039D /* Debug */, - 2D2A288F1D9B049200D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 3C86DF411ADF2C930047B81A /* Build configuration list for PBXProject "RCTWebSocket" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -552,15 +382,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3DBE0D0A1F3B181C0099AA32 /* Build configuration list for PBXNativeTarget "fishhook-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3DBE0D0B1F3B181C0099AA32 /* Debug */, - 3DBE0D0C1F3B181C0099AA32 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 3C86DF3E1ADF2C930047B81A /* Project object */; diff --git a/RNTester/RNTester.xcodeproj/xcshareddata/xcschemes/RNTester-tvOS.xcscheme b/RNTester/RNTester.xcodeproj/xcshareddata/xcschemes/RNTester-tvOS.xcscheme deleted file mode 100644 index df1600ff8a..0000000000 --- a/RNTester/RNTester.xcodeproj/xcshareddata/xcschemes/RNTester-tvOS.xcscheme +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index ce91138e36..ba5efc9506 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -13,38 +13,21 @@ 008341F61D1DB34400876D9A /* RCTJSStackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */; }; 130443A11E3FEAA900D93A67 /* RCTFollyConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304439F1E3FEAA900D93A67 /* RCTFollyConvert.h */; }; 130443A21E3FEAA900D93A67 /* RCTFollyConvert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 130443A01E3FEAA900D93A67 /* RCTFollyConvert.mm */; }; - 130443A31E3FEAAE00D93A67 /* RCTFollyConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304439F1E3FEAA900D93A67 /* RCTFollyConvert.h */; }; - 130443A41E3FEAC600D93A67 /* RCTFollyConvert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 130443A01E3FEAA900D93A67 /* RCTFollyConvert.mm */; }; 130443C61E401A8C00D93A67 /* RCTConvert+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 130443C41E401A8C00D93A67 /* RCTConvert+Transform.m */; }; - 130443DB1E401ADD00D93A67 /* RCTConvert+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 130443C41E401A8C00D93A67 /* RCTConvert+Transform.m */; }; 130443DC1E401AF400D93A67 /* RCTConvert+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 130443C31E401A8C00D93A67 /* RCTConvert+Transform.h */; }; - 130443DD1E401AF500D93A67 /* RCTConvert+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 130443C31E401A8C00D93A67 /* RCTConvert+Transform.h */; }; 130E3D881E6A082100ACE484 /* RCTDevSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 130E3D861E6A082100ACE484 /* RCTDevSettings.h */; }; 130E3D891E6A082100ACE484 /* RCTDevSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = 130E3D871E6A082100ACE484 /* RCTDevSettings.mm */; }; - 130E3D8A1E6A083600ACE484 /* RCTDevSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 130E3D861E6A082100ACE484 /* RCTDevSettings.h */; }; - 130E3D8B1E6A083900ACE484 /* RCTDevSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = 130E3D871E6A082100ACE484 /* RCTDevSettings.mm */; }; 13134C861E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C741E296B2A00B9F3CB /* RCTCxxBridge.mm */; }; - 13134C871E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C741E296B2A00B9F3CB /* RCTCxxBridge.mm */; }; 13134C8C1E296B2A00B9F3CB /* RCTMessageThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C771E296B2A00B9F3CB /* RCTMessageThread.h */; }; - 13134C8D1E296B2A00B9F3CB /* RCTMessageThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C771E296B2A00B9F3CB /* RCTMessageThread.h */; }; 13134C8E1E296B2A00B9F3CB /* RCTMessageThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C781E296B2A00B9F3CB /* RCTMessageThread.mm */; }; - 13134C8F1E296B2A00B9F3CB /* RCTMessageThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C781E296B2A00B9F3CB /* RCTMessageThread.mm */; }; 13134C941E296B2A00B9F3CB /* RCTObjcExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C7B1E296B2A00B9F3CB /* RCTObjcExecutor.h */; }; - 13134C951E296B2A00B9F3CB /* RCTObjcExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C7B1E296B2A00B9F3CB /* RCTObjcExecutor.h */; }; 13134C961E296B2A00B9F3CB /* RCTObjcExecutor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C7C1E296B2A00B9F3CB /* RCTObjcExecutor.mm */; }; - 13134C971E296B2A00B9F3CB /* RCTObjcExecutor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C7C1E296B2A00B9F3CB /* RCTObjcExecutor.mm */; }; 13134C981E296B2A00B9F3CB /* RCTCxxMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C7E1E296B2A00B9F3CB /* RCTCxxMethod.h */; }; - 13134C991E296B2A00B9F3CB /* RCTCxxMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C7E1E296B2A00B9F3CB /* RCTCxxMethod.h */; }; 13134C9A1E296B2A00B9F3CB /* RCTCxxMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C7F1E296B2A00B9F3CB /* RCTCxxMethod.mm */; }; - 13134C9B1E296B2A00B9F3CB /* RCTCxxMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C7F1E296B2A00B9F3CB /* RCTCxxMethod.mm */; }; 13134C9C1E296B2A00B9F3CB /* RCTCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C801E296B2A00B9F3CB /* RCTCxxModule.h */; }; - 13134C9D1E296B2A00B9F3CB /* RCTCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C801E296B2A00B9F3CB /* RCTCxxModule.h */; }; 13134C9E1E296B2A00B9F3CB /* RCTCxxModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C811E296B2A00B9F3CB /* RCTCxxModule.mm */; }; - 13134C9F1E296B2A00B9F3CB /* RCTCxxModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C811E296B2A00B9F3CB /* RCTCxxModule.mm */; }; 13134CA01E296B2A00B9F3CB /* RCTCxxUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C821E296B2A00B9F3CB /* RCTCxxUtils.h */; }; - 13134CA11E296B2A00B9F3CB /* RCTCxxUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 13134C821E296B2A00B9F3CB /* RCTCxxUtils.h */; }; 13134CA21E296B2A00B9F3CB /* RCTCxxUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C831E296B2A00B9F3CB /* RCTCxxUtils.mm */; }; - 13134CA31E296B2A00B9F3CB /* RCTCxxUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13134C831E296B2A00B9F3CB /* RCTCxxUtils.mm */; }; 131B6AF41AF1093D00FFC3E0 /* RCTSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6AF11AF1093D00FFC3E0 /* RCTSegmentedControl.m */; }; 131B6AF51AF1093D00FFC3E0 /* RCTSegmentedControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6AF31AF1093D00FFC3E0 /* RCTSegmentedControlManager.m */; }; 133957881DF76D3500EC27BE /* YGEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 130A77031DF767AF001F9587 /* YGEnums.h */; }; @@ -53,23 +36,15 @@ 133CAE8E1B8E5CFD00F6AD92 /* RCTDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 133CAE8D1B8E5CFD00F6AD92 /* RCTDatePicker.m */; }; 13456E931ADAD2DE009F94A7 /* RCTConvert+CoreLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 13456E921ADAD2DE009F94A7 /* RCTConvert+CoreLocation.m */; }; 134D63C31F1FEC4B008872B5 /* RCTCxxBridgeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 134D63C21F1FEC4B008872B5 /* RCTCxxBridgeDelegate.h */; }; - 134D63C41F1FEC65008872B5 /* RCTCxxBridgeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 134D63C21F1FEC4B008872B5 /* RCTCxxBridgeDelegate.h */; }; 13513F3C1B1F43F400FCE529 /* RCTProgressViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13513F3B1B1F43F400FCE529 /* RCTProgressViewManager.m */; }; 135A9BFB1E7B0EAE00587AEB /* RCTJSCErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = 135A9BF91E7B0EAE00587AEB /* RCTJSCErrorHandling.h */; }; 135A9BFC1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm in Sources */ = {isa = PBXBuildFile; fileRef = 135A9BFA1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm */; }; 135A9BFF1E7B0EE600587AEB /* RCTJSCHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 135A9BFD1E7B0EE600587AEB /* RCTJSCHelpers.h */; }; 135A9C001E7B0EE600587AEB /* RCTJSCHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 135A9BFE1E7B0EE600587AEB /* RCTJSCHelpers.mm */; }; - 135A9C011E7B0F4700587AEB /* systemJSCWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19DED2281E77E29200F089BB /* systemJSCWrapper.cpp */; }; 135A9C021E7B0F4800587AEB /* systemJSCWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19DED2281E77E29200F089BB /* systemJSCWrapper.cpp */; }; - 135A9C031E7B0F6100587AEB /* RCTJSCErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = 135A9BF91E7B0EAE00587AEB /* RCTJSCErrorHandling.h */; }; - 135A9C041E7B0F6400587AEB /* RCTJSCErrorHandling.mm in Sources */ = {isa = PBXBuildFile; fileRef = 135A9BFA1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm */; }; - 135A9C051E7B0F7500587AEB /* RCTJSCHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 135A9BFE1E7B0EE600587AEB /* RCTJSCHelpers.mm */; }; - 135A9C061E7B0F7800587AEB /* RCTJSCHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 135A9BFD1E7B0EE600587AEB /* RCTJSCHelpers.h */; }; 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7091AB030C200659ED6 /* RCTAppState.m */; }; 1384E2081E806D4E00545659 /* RCTNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 1384E2061E806D4E00545659 /* RCTNativeModule.h */; }; 1384E2091E806D4E00545659 /* RCTNativeModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1384E2071E806D4E00545659 /* RCTNativeModule.mm */; }; - 1384E20A1E806D5700545659 /* RCTNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 1384E2061E806D4E00545659 /* RCTNativeModule.h */; }; - 1384E20B1E806D5B00545659 /* RCTNativeModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1384E2071E806D4E00545659 /* RCTNativeModule.mm */; }; 139D7E911E25C70B00323FB7 /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E391E25C5A300323FB7 /* bignum-dtoa.cc */; }; 139D7E931E25C70B00323FB7 /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E3B1E25C5A300323FB7 /* bignum.cc */; }; 139D7E951E25C70B00323FB7 /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E3D1E25C5A300323FB7 /* cached-powers.cc */; }; @@ -124,10 +99,6 @@ 13E41EEB1C05CA0B00CD8DAC /* RCTProfileTrampoline-i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 14BF717F1C04793D00C97D0C /* RCTProfileTrampoline-i386.S */; }; 13EBC6711E2870DE00880AC5 /* JSCWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D7A27DD1DE32541002E3F95 /* JSCWrapper.cpp */; }; 13EBC6731E2870DE00880AC5 /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B10C1E0369AD0018521A /* Value.cpp */; }; - 13EBC6771E2870E400880AC5 /* JSCHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B1071E0369AD0018521A /* JSCHelpers.cpp */; }; - 13EBC6781E2870E400880AC5 /* JSCWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D7A27DD1DE32541002E3F95 /* JSCWrapper.cpp */; }; - 13EBC6791E2870E400880AC5 /* Unicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B10A1E0369AD0018521A /* Unicode.cpp */; }; - 13EBC67A1E2870E400880AC5 /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B10C1E0369AD0018521A /* Value.cpp */; }; 13EBC67B1E28723000880AC5 /* Unicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B10A1E0369AD0018521A /* Unicode.cpp */; }; 13EBC67D1E28725900880AC5 /* JSCHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B1071E0369AD0018521A /* JSCHelpers.cpp */; }; 13EBC67E1E28726000880AC5 /* JSCHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1081E0369AD0018521A /* JSCHelpers.h */; }; @@ -155,21 +126,6 @@ 13F8877E1E29726200C3C7A1 /* NativeToJsBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0CF1E03699D0018521A /* NativeToJsBridge.cpp */; }; 13F8877F1E29726200C3C7A1 /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0D11E03699D0018521A /* Platform.cpp */; }; 13F887801E29726200C3C7A1 /* SampleCxxModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0D31E03699D0018521A /* SampleCxxModule.cpp */; }; - 13F887821E29726300C3C7A1 /* CxxNativeModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0A81E03699D0018521A /* CxxNativeModule.cpp */; }; - 13F887841E29726300C3C7A1 /* Instance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0AE1E03699D0018521A /* Instance.cpp */; }; - 13F887851E29726300C3C7A1 /* JSCExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0B21E03699D0018521A /* JSCExecutor.cpp */; }; - 13F887871E29726300C3C7A1 /* JSCLegacyTracing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0B61E03699D0018521A /* JSCLegacyTracing.cpp */; }; - 13F887881E29726300C3C7A1 /* JSCMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0B81E03699D0018521A /* JSCMemory.cpp */; }; - 13F887891E29726300C3C7A1 /* JSCNativeModules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0BA1E03699D0018521A /* JSCNativeModules.cpp */; }; - 13F8878A1E29726300C3C7A1 /* JSCPerfStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0BC1E03699D0018521A /* JSCPerfStats.cpp */; }; - 13F8878B1E29726300C3C7A1 /* JSCSamplingProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0BE1E03699D0018521A /* JSCSamplingProfiler.cpp */; }; - 13F8878C1E29726300C3C7A1 /* JSCUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0C21E03699D0018521A /* JSCUtils.cpp */; }; - 13F8878E1E29726300C3C7A1 /* JSIndexedRAMBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0C61E03699D0018521A /* JSIndexedRAMBundle.cpp */; }; - 13F8878F1E29726300C3C7A1 /* MethodCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0CA1E03699D0018521A /* MethodCall.cpp */; }; - 13F887901E29726300C3C7A1 /* ModuleRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0CC1E03699D0018521A /* ModuleRegistry.cpp */; }; - 13F887911E29726300C3C7A1 /* NativeToJsBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0CF1E03699D0018521A /* NativeToJsBridge.cpp */; }; - 13F887921E29726300C3C7A1 /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0D11E03699D0018521A /* Platform.cpp */; }; - 13F887931E29726300C3C7A1 /* SampleCxxModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B0D31E03699D0018521A /* SampleCxxModule.cpp */; }; 13F8879F1E29741900C3C7A1 /* BitsFunctexcept.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F8879C1E29740700C3C7A1 /* BitsFunctexcept.cpp */; }; 13F887A21E2977FF00C3C7A1 /* MallocImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F887A01E2977D800C3C7A1 /* MallocImpl.cpp */; }; 142014191B32094000CC17BA /* RCTPerformanceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 142014171B32094000CC17BA /* RCTPerformanceLogger.m */; }; @@ -185,7 +141,6 @@ 14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */; }; 14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; }; 199B8A6F1F44DB16005DEF67 /* RCTVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */; }; - 199B8A761F44DEDA005DEF67 /* RCTVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */; }; 19F61BFA1E8495CD00571D81 /* bignum-dtoa.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3A1E25C5A300323FB7 /* bignum-dtoa.h */; }; 19F61BFB1E8495CD00571D81 /* bignum.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3C1E25C5A300323FB7 /* bignum.h */; }; 19F61BFC1E8495CD00571D81 /* cached-powers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3E1E25C5A300323FB7 /* cached-powers.h */; }; @@ -196,10 +151,6 @@ 19F61C011E8495CD00571D81 /* ieee.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E471E25C5A300323FB7 /* ieee.h */; }; 19F61C021E8495CD00571D81 /* strtod.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E491E25C5A300323FB7 /* strtod.h */; }; 19F61C031E8495CD00571D81 /* utils.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E4A1E25C5A300323FB7 /* utils.h */; }; - 19F61C041E8495FF00571D81 /* JSCHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1081E0369AD0018521A /* JSCHelpers.h */; }; - 19F61C051E8495FF00571D81 /* noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1091E0369AD0018521A /* noncopyable.h */; }; - 19F61C061E8495FF00571D81 /* Unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10B1E0369AD0018521A /* Unicode.h */; }; - 19F61C071E8495FF00571D81 /* Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10D1E0369AD0018521A /* Value.h */; }; 27595AA41E575C7800CCE2B1 /* CxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A71E03699D0018521A /* CxxModule.h */; }; 27595AA51E575C7800CCE2B1 /* CxxNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A91E03699D0018521A /* CxxNativeModule.h */; }; 27595AA61E575C7800CCE2B1 /* JSExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0AB1E03699D0018521A /* JSExecutor.h */; }; @@ -222,292 +173,36 @@ 27595ABB1E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; }; 27595ABC1E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; }; 27595ABD1E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; }; - 27595ABF1E575C7800CCE2B1 /* CxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A71E03699D0018521A /* CxxModule.h */; }; - 27595AC01E575C7800CCE2B1 /* CxxNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A91E03699D0018521A /* CxxNativeModule.h */; }; - 27595AC11E575C7800CCE2B1 /* JSExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0AB1E03699D0018521A /* JSExecutor.h */; }; - 27595AC41E575C7800CCE2B1 /* Instance.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0AF1E03699D0018521A /* Instance.h */; }; - 27595AC51E575C7800CCE2B1 /* JsArgumentHelpers-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B01E03699D0018521A /* JsArgumentHelpers-inl.h */; }; - 27595AC61E575C7800CCE2B1 /* JsArgumentHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B11E03699D0018521A /* JsArgumentHelpers.h */; }; - 27595AC71E575C7800CCE2B1 /* JSCExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B31E03699D0018521A /* JSCExecutor.h */; }; - 27595AC91E575C7800CCE2B1 /* JSCLegacyTracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B71E03699D0018521A /* JSCLegacyTracing.h */; }; - 27595ACA1E575C7800CCE2B1 /* JSCMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B91E03699D0018521A /* JSCMemory.h */; }; - 27595ACB1E575C7800CCE2B1 /* JSCNativeModules.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BB1E03699D0018521A /* JSCNativeModules.h */; }; - 27595ACC1E575C7800CCE2B1 /* JSCPerfStats.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BD1E03699D0018521A /* JSCPerfStats.h */; }; - 27595ACD1E575C7800CCE2B1 /* JSCSamplingProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BF1E03699D0018521A /* JSCSamplingProfiler.h */; }; - 27595ACE1E575C7800CCE2B1 /* JSCUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C31E03699D0018521A /* JSCUtils.h */; }; - 27595AD01E575C7800CCE2B1 /* JSIndexedRAMBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C71E03699D0018521A /* JSIndexedRAMBundle.h */; }; - 27595AD11E575C7800CCE2B1 /* MessageQueueThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C91E03699D0018521A /* MessageQueueThread.h */; }; - 27595AD21E575C7800CCE2B1 /* MethodCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CB1E03699D0018521A /* MethodCall.h */; }; - 27595AD31E575C7800CCE2B1 /* ModuleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CD1E03699D0018521A /* ModuleRegistry.h */; }; - 27595AD41E575C7800CCE2B1 /* NativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CE1E03699D0018521A /* NativeModule.h */; }; - 27595AD51E575C7800CCE2B1 /* NativeToJsBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D01E03699D0018521A /* NativeToJsBridge.h */; }; - 27595AD61E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; }; - 27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; }; - 27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; }; - 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; }; - 2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; }; - 2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; }; - 2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; }; - 2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; }; - 2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; }; - 2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; }; - 2D3B5E971D9B089000451313 /* RCTBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */; }; - 2D3B5E981D9B089500451313 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; }; - 2D3B5E991D9B089A00451313 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */; }; - 2D3B5E9A1D9B089D00451313 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; }; - 2D3B5E9B1D9B08A000451313 /* RCTFrameUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */; }; - 2D3B5E9C1D9B08A300451313 /* RCTImageSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BB3D011BECD54500932C10 /* RCTImageSource.m */; }; - 2D3B5E9E1D9B08AD00451313 /* RCTJSStackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */; }; - 2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */; }; - 2D3B5EA01D9B08B200451313 /* RCTLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4E1A601E3B00E9B192 /* RCTLog.mm */; }; - 2D3B5EA11D9B08B600451313 /* RCTModuleData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA731B3AC64300E6CBB2 /* RCTModuleData.mm */; }; - 2D3B5EA31D9B08BE00451313 /* RCTParserUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A6E20D1C19AA0C00845B82 /* RCTParserUtils.m */; }; - 2D3B5EA41D9B08C200451313 /* RCTPerformanceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 142014171B32094000CC17BA /* RCTPerformanceLogger.m */; }; - 2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; }; - 2D3B5EA61D9B08CA00451313 /* RCTTouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 391E86A21C623EC800009732 /* RCTTouchEvent.m */; }; - 2D3B5EA71D9B08CE00451313 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; }; - 2D3B5EA81D9B08D300451313 /* RCTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA501A601E3B00E9B192 /* RCTUtils.m */; }; - 2D3B5EAE1D9B08F800451313 /* RCTEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D9FEEA1CDCCECF00158BD7 /* RCTEventEmitter.m */; }; - 2D3B5EB01D9B08FE00451313 /* RCTAlertManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FE81A69327A00A75B9A /* RCTAlertManager.m */; }; - 2D3B5EB11D9B090100451313 /* RCTAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7091AB030C200659ED6 /* RCTAppState.m */; }; - 2D3B5EB21D9B090300451313 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; }; - 2D3B5EB41D9B090A00451313 /* RCTDevLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A0C2861B74F71200B29F6F /* RCTDevLoadingView.m */; }; - 2D3B5EB51D9B091100451313 /* RCTDevMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A0C2881B74F71200B29F6F /* RCTDevMenu.m */; }; - 2D3B5EB61D9B091400451313 /* RCTExceptionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */; }; - 2D3B5EB71D9B091800451313 /* RCTRedBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 13F17A841B8493E5007D4C75 /* RCTRedBox.m */; }; - 2D3B5EB81D9B091B00451313 /* RCTSourceCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */; }; - 2D3B5EBA1D9B092100451313 /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */; }; - 2D3B5EBB1D9B092300451313 /* RCTI18nManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B233E6E91D2D845D00BC68BA /* RCTI18nManager.m */; }; - 2D3B5EBD1D9B092A00451313 /* RCTTiming.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FEE1A69327A00A75B9A /* RCTTiming.m */; }; - 2D3B5EBE1D9B092D00451313 /* RCTUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067491A70F434002CDEE1 /* RCTUIManager.m */; }; - 2D3B5EC01D9B093600451313 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */; }; - 2D3B5EC11D9B093900451313 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; }; - 2D3B5EC21D9B093B00451313 /* RCTProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF811BCFF28A00208362 /* RCTProfile.m */; }; - 2D3B5EC31D9B094800451313 /* RCTProfileTrampoline-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF821BCFF28A00208362 /* RCTProfileTrampoline-arm.S */; }; - 2D3B5EC41D9B094B00451313 /* RCTProfileTrampoline-arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF831BCFF28A00208362 /* RCTProfileTrampoline-arm64.S */; }; - 2D3B5EC51D9B094D00451313 /* RCTProfileTrampoline-i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 14BF717F1C04793D00C97D0C /* RCTProfileTrampoline-i386.S */; }; - 2D3B5EC61D9B095000451313 /* RCTProfileTrampoline-x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF851BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S */; }; - 2D3B5EC71D9B095600451313 /* RCTActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B95154311D1B34B200FE7B80 /* RCTActivityIndicatorView.m */; }; - 2D3B5EC81D9B095800451313 /* RCTActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080191A69489C00A75B9A /* RCTActivityIndicatorViewManager.m */; }; - 2D3B5EC91D9B095C00451313 /* RCTBorderDrawing.m in Sources */ = {isa = PBXBuildFile; fileRef = 13CC8A811B17642100940AE7 /* RCTBorderDrawing.m */; }; - 2D3B5ECA1D9B095F00451313 /* RCTComponentData.m in Sources */ = {isa = PBXBuildFile; fileRef = 13AB90C01B6FA36700713B4F /* RCTComponentData.m */; }; - 2D3B5ECB1D9B096200451313 /* RCTConvert+CoreLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 13456E921ADAD2DE009F94A7 /* RCTConvert+CoreLocation.m */; }; - 2D3B5ECF1D9B096F00451313 /* RCTFont.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D37B5811D522B190042D5B5 /* RCTFont.mm */; }; - 2D3B5ED41D9B097D00451313 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8B1B62640A00BE0E65 /* RCTModalHostView.m */; }; - 2D3B5ED51D9B098000451313 /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; }; - 2D3B5ED61D9B098400451313 /* RCTModalHostViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1FE8E1B62643A00BE0E65 /* RCTModalHostViewManager.m */; }; - 2D3B5EDD1D9B09A300451313 /* RCTProgressViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13513F3B1B1F43F400FCE529 /* RCTProgressViewManager.m */; }; - 2D3B5EE01D9B09AD00451313 /* RCTRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BCE8081C99CB9D00DD7AAD /* RCTRootShadowView.m */; }; - 2D3B5EE31D9B09B700451313 /* RCTSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6AF11AF1093D00FFC3E0 /* RCTSegmentedControl.m */; }; - 2D3B5EE41D9B09BB00451313 /* RCTSegmentedControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6AF31AF1093D00FFC3E0 /* RCTSegmentedControlManager.m */; }; - 2D3B5EE51D9B09BE00451313 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */; }; - 2D3B5EEE1D9B09DA00451313 /* RCTView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067501A70F44B002CDEE1 /* RCTView.m */; }; - 2D3B5EEF1D9B09DC00451313 /* RCTViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */; }; - 2D3B5EF11D9B09E700451313 /* NSView+React.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067541A70F44B002CDEE1 /* NSView+React.m */; }; - 2D74EAFA1DAE9590003B751B /* RCTMultipartDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 006FC4131D9B20820057AAAD /* RCTMultipartDataTask.m */; }; - 2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 001BFCCF1D8381DE008E587E /* RCTMultipartStreamReader.m */; }; 352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */; }; 369123E11DDC75850095B341 /* RCTJSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */; }; 391E86A41C623EC800009732 /* RCTTouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 391E86A21C623EC800009732 /* RCTTouchEvent.m */; }; - 3D05745A1DE5FFF500184BB4 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */; }; - 3D0B84221EC0B3F600B2BD8E /* RCTResizeMode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0851DE4F3A000E03CC6 /* RCTResizeMode.h */; }; - 3D0B84231EC0B40D00B2BD8E /* RCTImageLoader.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0831DE4F3A000E03CC6 /* RCTImageLoader.h */; }; - 3D0B84241EC0B40D00B2BD8E /* RCTImageStoreManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0841DE4F3A000E03CC6 /* RCTImageStoreManager.h */; }; - 3D0B84251EC0B42600B2BD8E /* RCTNetworking.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA07A1DE4F2EA00E03CC6 /* RCTNetworking.h */; }; - 3D0B84261EC0B42600B2BD8E /* RCTNetworkTask.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA07B1DE4F2EA00E03CC6 /* RCTNetworkTask.h */; }; - 3D0B84271EC0B45400B2BD8E /* RCTLinkingManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA08B1DE4F4DD00E03CC6 /* RCTLinkingManager.h */; }; - 3D0B842A1EC0B49400B2BD8E /* RCTTVRemoteHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0B84281EC0B49400B2BD8E /* RCTTVRemoteHandler.h */; }; - 3D0B842B1EC0B49400B2BD8E /* RCTTVRemoteHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B84291EC0B49400B2BD8E /* RCTTVRemoteHandler.m */; }; - 3D0B842F1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; }; - 3D0B84301EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B842E1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m */; }; 3D0E378A1F1CC40000DCAC9F /* RCTWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; 3D0E378C1F1CC58C00DCAC9F /* RCTWebSocketObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E378B1F1CC58C00DCAC9F /* RCTWebSocketObserver.h */; }; - 3D0E378D1F1CC58F00DCAC9F /* RCTWebSocketObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E378B1F1CC58C00DCAC9F /* RCTWebSocketObserver.h */; }; - 3D0E378E1F1CC59100DCAC9F /* RCTWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; 3D0E378F1F1CC5CF00DCAC9F /* RCTWebSocketModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; - 3D0E37901F1CC5E100DCAC9F /* RCTWebSocketModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; 3D1E68DB1CABD13900DD7465 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */; }; - 3D302F1E1DF8265A00D6DDAE /* JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; - 3D302F1F1DF8265A00D6DDAE /* JSCWrapper.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DE1DE32541002E3F95 /* JSCWrapper.h */; }; - 3D302F241DF828F800D6DDAE /* RCTImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0831DE4F3A000E03CC6 /* RCTImageLoader.h */; }; - 3D302F251DF828F800D6DDAE /* RCTImageStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0841DE4F3A000E03CC6 /* RCTImageStoreManager.h */; }; - 3D302F261DF828F800D6DDAE /* RCTResizeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0851DE4F3A000E03CC6 /* RCTResizeMode.h */; }; - 3D302F271DF828F800D6DDAE /* RCTLinkingManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA08B1DE4F4DD00E03CC6 /* RCTLinkingManager.h */; }; - 3D302F281DF828F800D6DDAE /* RCTNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA07A1DE4F2EA00E03CC6 /* RCTNetworking.h */; }; - 3D302F291DF828F800D6DDAE /* RCTNetworkTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA07B1DE4F2EA00E03CC6 /* RCTNetworkTask.h */; }; - 3D302F2A1DF828F800D6DDAE /* RCTPushNotificationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA08D1DE4F4EE00E03CC6 /* RCTPushNotificationManager.h */; }; - 3D302F2B1DF828F800D6DDAE /* RCTAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */; }; - 3D302F2C1DF828F800D6DDAE /* RCTBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */; }; - 3D302F2D1DF828F800D6DDAE /* RCTBridge+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A43DB81C1F849600794BC8 /* RCTBridge+Private.h */; }; - 3D302F2E1DF828F800D6DDAE /* RCTBridgeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482F9E61B55B927000ADFF3 /* RCTBridgeDelegate.h */; }; - 3D302F2F1DF828F800D6DDAE /* RCTBridgeMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AFBCA11C07287B00BBAEAA /* RCTBridgeMethod.h */; }; - 3D302F301DF828F800D6DDAE /* RCTBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 830213F31A654E0800B993E6 /* RCTBridgeModule.h */; }; - 3D302F311DF828F800D6DDAE /* RCTBundleURLProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EFE4EC1CF6EB3000A1DE13 /* RCTBundleURLProvider.h */; }; - 3D302F321DF828F800D6DDAE /* RCTConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBACA1A6023D300E9B192 /* RCTConvert.h */; }; - 3D302F331DF828F800D6DDAE /* RCTDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AF1F851AE6E777005F5298 /* RCTDefines.h */; }; - 3D302F341DF828F800D6DDAE /* RCTDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D1E68D81CABD13900DD7465 /* RCTDisplayLink.h */; }; - 3D302F351DF828F800D6DDAE /* RCTErrorCustomizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EDCA8A21D3591E700450C31 /* RCTErrorCustomizer.h */; }; - 3D302F361DF828F800D6DDAE /* RCTErrorInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EDCA8A31D3591E700450C31 /* RCTErrorInfo.h */; }; - 3D302F371DF828F800D6DDAE /* RCTEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA651A601EF300E9B192 /* RCTEventDispatcher.h */; }; - 3D302F381DF828F800D6DDAE /* RCTFrameUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1436DD071ADE7AA000A5ED7D /* RCTFrameUpdate.h */; }; - 3D302F391DF828F800D6DDAE /* RCTImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 13BB3D001BECD54500932C10 /* RCTImageSource.h */; }; - 3D302F3A1DF828F800D6DDAE /* RCTInvalidating.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */; }; - 3D302F3B1DF828F800D6DDAE /* RCTJavaScriptExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */; }; - 3D302F3C1DF828F800D6DDAE /* RCTJavaScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */; }; - 3D302F3D1DF828F800D6DDAE /* RCTJSStackFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 008341F51D1DB34400876D9A /* RCTJSStackFrame.h */; }; - 3D302F3E1DF828F800D6DDAE /* RCTKeyCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */; }; - 3D302F3F1DF828F800D6DDAE /* RCTLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4D1A601E3B00E9B192 /* RCTLog.h */; }; - 3D302F401DF828F800D6DDAE /* RCTModuleData.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C2CA721B3AC64300E6CBB2 /* RCTModuleData.h */; }; - 3D302F411DF828F800D6DDAE /* RCTModuleMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C2CA6F1B3AC63800E6CBB2 /* RCTModuleMethod.h */; }; - 3D302F421DF828F800D6DDAE /* RCTMultipartDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 006FC4121D9B20820057AAAD /* RCTMultipartDataTask.h */; }; - 3D302F431DF828F800D6DDAE /* RCTMultipartStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 001BFCCE1D8381DE008E587E /* RCTMultipartStreamReader.h */; }; - 3D302F441DF828F800D6DDAE /* RCTNullability.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A6E20F1C19ABC700845B82 /* RCTNullability.h */; }; - 3D302F451DF828F800D6DDAE /* RCTParserUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A6E20C1C19AA0C00845B82 /* RCTParserUtils.h */; }; - 3D302F461DF828F800D6DDAE /* RCTPerformanceLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 142014181B32094000CC17BA /* RCTPerformanceLogger.h */; }; - 3D302F471DF828F800D6DDAE /* RCTPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7749421DC1065C007EC8D8 /* RCTPlatform.h */; }; - 3D302F481DF828F800D6DDAE /* RCTRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 830A229C1A66C68A008503DA /* RCTRootView.h */; }; - 3D302F491DF828F800D6DDAE /* RCTRootViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AFBCA21C07287B00BBAEAA /* RCTRootViewDelegate.h */; }; - 3D302F4A1DF828F800D6DDAE /* RCTRootViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A15FB0C1BDF663500531DFB /* RCTRootViewInternal.h */; }; - 3D302F4B1DF828F800D6DDAE /* RCTTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 391E86A31C623EC800009732 /* RCTTouchEvent.h */; }; - 3D302F4C1DF828F800D6DDAE /* RCTTouchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */; }; - 3D302F4D1DF828F800D6DDAE /* RCTURLRequestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1345A83A1B265A0E00583190 /* RCTURLRequestDelegate.h */; }; - 3D302F4E1DF828F800D6DDAE /* RCTURLRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1345A83B1B265A0E00583190 /* RCTURLRequestHandler.h */; }; - 3D302F4F1DF828F800D6DDAE /* RCTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */; }; - 3D302F541DF828F800D6DDAE /* RCTJSCSamplingProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 369123DF1DDC75850095B341 /* RCTJSCSamplingProfiler.h */; }; - 3D302F561DF828F800D6DDAE /* RCTAlertManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13B07FE71A69327A00A75B9A /* RCTAlertManager.h */; }; - 3D302F571DF828F800D6DDAE /* RCTAppState.h in Headers */ = {isa = PBXBuildFile; fileRef = 1372B7081AB030C200659ED6 /* RCTAppState.h */; }; - 3D302F581DF828F800D6DDAE /* RCTAsyncLocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */; }; - 3D302F591DF828F800D6DDAE /* RCTClipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 13D033611C1837FE0021DC29 /* RCTClipboard.h */; }; - 3D302F5A1DF828F800D6DDAE /* RCTDevLoadingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A0C2851B74F71200B29F6F /* RCTDevLoadingView.h */; }; - 3D302F5B1DF828F800D6DDAE /* RCTDevMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A0C2871B74F71200B29F6F /* RCTDevMenu.h */; }; - 3D302F5C1DF828F800D6DDAE /* RCTEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 13D9FEE91CDCCECF00158BD7 /* RCTEventEmitter.h */; }; - 3D302F5D1DF828F800D6DDAE /* RCTExceptionsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */; }; - 3D302F5E1DF828F800D6DDAE /* RCTI18nManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B233E6E81D2D843200BC68BA /* RCTI18nManager.h */; }; - 3D302F5F1DF828F800D6DDAE /* RCTI18nUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 352DCFEE1D19F4C20056D623 /* RCTI18nUtil.h */; }; - 3D302F611DF828F800D6DDAE /* RCTRedBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 13F17A831B8493E5007D4C75 /* RCTRedBox.h */; }; - 3D302F621DF828F800D6DDAE /* RCTSourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 000E6CE91AB0E97F000CDF4D /* RCTSourceCode.h */; }; - 3D302F641DF828F800D6DDAE /* RCTTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 13B07FED1A69327A00A75B9A /* RCTTiming.h */; }; - 3D302F651DF828F800D6DDAE /* RCTUIManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E067481A70F434002CDEE1 /* RCTUIManager.h */; }; - 3D302F661DF828F800D6DDAE /* RCTFPSGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F7A0EE1BDA714B003C6C10 /* RCTFPSGraph.h */; }; - 3D302F681DF828F800D6DDAE /* RCTMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BF71811C04795500C97D0C /* RCTMacros.h */; }; - 3D302F691DF828F800D6DDAE /* RCTProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 1450FF801BCFF28A00208362 /* RCTProfile.h */; }; - 3D302F6A1DF828F800D6DDAE /* RCTActivityIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = B95154301D1B34B200FE7B80 /* RCTActivityIndicatorView.h */; }; - 3D302F6B1DF828F800D6DDAE /* RCTActivityIndicatorViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13B080181A69489C00A75B9A /* RCTActivityIndicatorViewManager.h */; }; - 3D302F6C1DF828F800D6DDAE /* RCTAnimationType.h in Headers */ = {isa = PBXBuildFile; fileRef = 13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */; }; - 3D302F6D1DF828F800D6DDAE /* RCTAutoInsetsProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */; }; - 3D302F6E1DF828F800D6DDAE /* RCTBorderDrawing.h in Headers */ = {isa = PBXBuildFile; fileRef = 13CC8A801B17642100940AE7 /* RCTBorderDrawing.h */; }; - 3D302F6F1DF828F800D6DDAE /* RCTBorderStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = ACDD3FDA1BC7430D00E7DE33 /* RCTBorderStyle.h */; }; - 3D302F701DF828F800D6DDAE /* RCTComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 13C325281AA63B6A0048765F /* RCTComponent.h */; }; - 3D302F711DF828F800D6DDAE /* RCTComponentData.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AB90BF1B6FA36700713B4F /* RCTComponentData.h */; }; - 3D302F721DF828F800D6DDAE /* RCTConvert+CoreLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 13456E911ADAD2DE009F94A7 /* RCTConvert+CoreLocation.h */; }; - 3D302F761DF828F800D6DDAE /* RCTFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D37B5801D522B190042D5B5 /* RCTFont.h */; }; - 3D302F7B1DF828F800D6DDAE /* RCTModalHostView.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A1FE8A1B62640A00BE0E65 /* RCTModalHostView.h */; }; - 3D302F7C1DF828F800D6DDAE /* RCTModalHostViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 83392EB11B6634E10013B15F /* RCTModalHostViewController.h */; }; - 3D302F7D1DF828F800D6DDAE /* RCTModalHostViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A1FE8D1B62643A00BE0E65 /* RCTModalHostViewManager.h */; }; - 3D302F841DF828F800D6DDAE /* RCTPointerEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = 13442BF31AA90E0B0037E5B0 /* RCTPointerEvents.h */; }; - 3D302F851DF828F800D6DDAE /* RCTProgressViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13513F3A1B1F43F400FCE529 /* RCTProgressViewManager.h */; }; - 3D302F881DF828F800D6DDAE /* RCTRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 13BCE8071C99CB9D00DD7AAD /* RCTRootShadowView.h */; }; - 3D302F8C1DF828F800D6DDAE /* RCTSegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 131B6AF01AF1093D00FFC3E0 /* RCTSegmentedControl.h */; }; - 3D302F8D1DF828F800D6DDAE /* RCTSegmentedControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 131B6AF21AF1093D00FFC3E0 /* RCTSegmentedControlManager.h */; }; - 3D302F8E1DF828F800D6DDAE /* RCTShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */; }; - 3D302F8F1DF828F800D6DDAE /* RCTSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AF20431AE707F8005F5298 /* RCTSlider.h */; }; - 3D302F901DF828F800D6DDAE /* RCTSliderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F484541AABFCE100FDF6B9 /* RCTSliderManager.h */; }; - 3D302F911DF828F800D6DDAE /* RCTSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F362071AABD06A001CE568 /* RCTSwitch.h */; }; - 3D302F921DF828F800D6DDAE /* RCTSwitchManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F362091AABD06A001CE568 /* RCTSwitchManager.h */; }; - 3D302F971DF828F800D6DDAE /* RCTTextDecorationLineType.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationLineType.h */; }; - 3D302F981DF828F800D6DDAE /* RCTView.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E0674F1A70F44B002CDEE1 /* RCTView.h */; }; - 3D302F991DF828F800D6DDAE /* RCTViewControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 13442BF41AA90E0B0037E5B0 /* RCTViewControllerProtocol.h */; }; - 3D302F9A1DF828F800D6DDAE /* RCTViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E0674D1A70F44B002CDEE1 /* RCTViewManager.h */; }; - 3D302F9F1DF828F800D6DDAE /* NSView+React.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E067531A70F44B002CDEE1 /* NSView+React.h */; }; - 3D3030221DF8294C00D6DDAE /* JSBundleType.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D3CD8F51DE5FB2300167DC4 /* JSBundleType.h */; }; - 3D3030231DF8294C00D6DDAE /* oss-compat-util.h in Headers */ = {isa = PBXBuildFile; fileRef = AC70D2EE1DE48AC5002E6351 /* oss-compat-util.h */; }; - 3D3030251DF8295E00D6DDAE /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; - 3D3030261DF8295E00D6DDAE /* JSCWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DE1DE32541002E3F95 /* JSCWrapper.h */; }; 3D37B5821D522B190042D5B5 /* RCTFont.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D37B5811D522B190042D5B5 /* RCTFont.mm */; }; 3D383D1F1EBD27A8005632C8 /* RCTBridge+Private.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14A43DB81C1F849600794BC8 /* RCTBridge+Private.h */; }; - 3D383D201EBD27AF005632C8 /* RCTBridge+Private.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14A43DB81C1F849600794BC8 /* RCTBridge+Private.h */; }; - 3D383D251EBD27B6005632C8 /* Conv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139D849F1E273B5600323FB7 /* Conv.cpp */; }; - 3D383D261EBD27B6005632C8 /* StringBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F887531E2971C500C3C7A1 /* StringBase.cpp */; }; - 3D383D271EBD27B6005632C8 /* raw_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EDB1E25DBDC00323FB7 /* raw_logging.cc */; }; - 3D383D281EBD27B6005632C8 /* signalhandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EDC1E25DBDC00323FB7 /* signalhandler.cc */; }; - 3D383D291EBD27B6005632C8 /* dynamic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139D84A21E273B5600323FB7 /* dynamic.cpp */; }; - 3D383D2A1EBD27B6005632C8 /* utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EE01E25DBDC00323FB7 /* utilities.cc */; }; - 3D383D2B1EBD27B6005632C8 /* MallocImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F887A01E2977D800C3C7A1 /* MallocImpl.cpp */; }; - 3D383D2C1EBD27B6005632C8 /* Bits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139D849D1E273B5600323FB7 /* Bits.cpp */; }; - 3D383D2D1EBD27B6005632C8 /* symbolize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EDE1E25DBDC00323FB7 /* symbolize.cc */; }; - 3D383D2E1EBD27B6005632C8 /* vlog_is_on.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EE21E25DBDC00323FB7 /* vlog_is_on.cc */; }; - 3D383D2F1EBD27B6005632C8 /* Unicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F887541E2971C500C3C7A1 /* Unicode.cpp */; }; - 3D383D301EBD27B6005632C8 /* demangle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7F081E25DE3700323FB7 /* demangle.cc */; }; - 3D383D311EBD27B6005632C8 /* Demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F887521E2971C500C3C7A1 /* Demangle.cpp */; }; - 3D383D331EBD27B6005632C8 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7EDA1E25DBDC00323FB7 /* logging.cc */; }; - 3D383D341EBD27B6005632C8 /* json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139D84A71E273B5600323FB7 /* json.cpp */; }; - 3D383D351EBD27B6005632C8 /* BitsFunctexcept.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13F8879C1E29740700C3C7A1 /* BitsFunctexcept.cpp */; }; - 3D383D401EBD27B9005632C8 /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E391E25C5A300323FB7 /* bignum-dtoa.cc */; }; - 3D383D411EBD27B9005632C8 /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E3B1E25C5A300323FB7 /* bignum.cc */; }; - 3D383D421EBD27B9005632C8 /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E3D1E25C5A300323FB7 /* cached-powers.cc */; }; - 3D383D431EBD27B9005632C8 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E3F1E25C5A300323FB7 /* diy-fp.cc */; }; - 3D383D441EBD27B9005632C8 /* double-conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E411E25C5A300323FB7 /* double-conversion.cc */; }; - 3D383D451EBD27B9005632C8 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E431E25C5A300323FB7 /* fast-dtoa.cc */; }; - 3D383D461EBD27B9005632C8 /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E451E25C5A300323FB7 /* fixed-dtoa.cc */; }; - 3D383D471EBD27B9005632C8 /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = 139D7E481E25C5A300323FB7 /* strtod.cc */; }; - 3D383D4A1EBD27B9005632C8 /* bignum-dtoa.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3A1E25C5A300323FB7 /* bignum-dtoa.h */; }; - 3D383D4B1EBD27B9005632C8 /* bignum.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3C1E25C5A300323FB7 /* bignum.h */; }; - 3D383D4C1EBD27B9005632C8 /* cached-powers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3E1E25C5A300323FB7 /* cached-powers.h */; }; - 3D383D4D1EBD27B9005632C8 /* diy-fp.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E401E25C5A300323FB7 /* diy-fp.h */; }; - 3D383D4E1EBD27B9005632C8 /* double-conversion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E421E25C5A300323FB7 /* double-conversion.h */; }; - 3D383D4F1EBD27B9005632C8 /* fast-dtoa.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E441E25C5A300323FB7 /* fast-dtoa.h */; }; - 3D383D501EBD27B9005632C8 /* fixed-dtoa.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E461E25C5A300323FB7 /* fixed-dtoa.h */; }; - 3D383D511EBD27B9005632C8 /* ieee.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E471E25C5A300323FB7 /* ieee.h */; }; - 3D383D521EBD27B9005632C8 /* strtod.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E491E25C5A300323FB7 /* strtod.h */; }; - 3D383D531EBD27B9005632C8 /* utils.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E4A1E25C5A300323FB7 /* utils.h */; }; - 3D383D551EBD27B9005632C8 /* bignum-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E3A1E25C5A300323FB7 /* bignum-dtoa.h */; }; - 3D383D561EBD27B9005632C8 /* bignum.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E3C1E25C5A300323FB7 /* bignum.h */; }; - 3D383D571EBD27B9005632C8 /* cached-powers.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E3E1E25C5A300323FB7 /* cached-powers.h */; }; - 3D383D581EBD27B9005632C8 /* diy-fp.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E401E25C5A300323FB7 /* diy-fp.h */; }; - 3D383D591EBD27B9005632C8 /* double-conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E421E25C5A300323FB7 /* double-conversion.h */; }; - 3D383D5A1EBD27B9005632C8 /* fast-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E441E25C5A300323FB7 /* fast-dtoa.h */; }; - 3D383D5B1EBD27B9005632C8 /* fixed-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E461E25C5A300323FB7 /* fixed-dtoa.h */; }; - 3D383D5C1EBD27B9005632C8 /* ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E471E25C5A300323FB7 /* ieee.h */; }; - 3D383D5D1EBD27B9005632C8 /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E491E25C5A300323FB7 /* strtod.h */; }; - 3D383D5E1EBD27B9005632C8 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 139D7E4A1E25C5A300323FB7 /* utils.h */; }; 3D383D6D1EBD2940005632C8 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7E881E25C6D100323FB7 /* libdouble-conversion.a */; }; 3D383D6E1EBD2940005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */; }; 3D383D6F1EBD2940005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7ECE1E25DB7D00323FB7 /* libthird-party.a */; }; - 3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */; }; - 3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D3C1EBD27B6005632C8 /* libthird-party.a */; }; 3D3CD93D1DE5FC1400167DC4 /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; 3D3CD93E1DE5FC1400167DC4 /* JSCWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DE1DE32541002E3F95 /* JSCWrapper.h */; }; 3D3CD9411DE5FC5300167DC4 /* libcxxreact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD9251DE5FBEC00167DC4 /* libcxxreact.a */; }; 3D3CD9451DE5FC7100167DC4 /* JSBundleType.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D3CD8F51DE5FB2300167DC4 /* JSBundleType.h */; }; 3D3CD9471DE5FC7800167DC4 /* oss-compat-util.h in Headers */ = {isa = PBXBuildFile; fileRef = AC70D2EE1DE48AC5002E6351 /* oss-compat-util.h */; }; 3D74547C1E54758900E74ADD /* JSBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454781E54757500E74ADD /* JSBigString.h */; }; - 3D74547D1E54758900E74ADD /* JSBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454781E54757500E74ADD /* JSBigString.h */; }; - 3D74547E1E54759A00E74ADD /* JSModulesUnbundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C81E03699D0018521A /* JSModulesUnbundle.h */; }; 3D74547F1E54759E00E74ADD /* JSModulesUnbundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C81E03699D0018521A /* JSModulesUnbundle.h */; }; 3D7454801E5475AF00E74ADD /* RecoverableError.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454791E54757500E74ADD /* RecoverableError.h */; }; - 3D7454811E5475AF00E74ADD /* RecoverableError.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454791E54757500E74ADD /* RecoverableError.h */; }; 3D7749441DC1065C007EC8D8 /* RCTPlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D7749431DC1065C007EC8D8 /* RCTPlatform.m */; }; 3D7AA9C41E548CD5001955CF /* NSDataBigString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D7AA9C31E548CD5001955CF /* NSDataBigString.mm */; }; - 3D7AA9C51E548CDB001955CF /* NSDataBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454B31E54786200E74ADD /* NSDataBigString.h */; }; - 3D7AA9C61E548CDD001955CF /* NSDataBigString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D7AA9C31E548CD5001955CF /* NSDataBigString.mm */; }; 3D7BFD151EA8E351008DFB7A /* RCTPackagerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0B1EA8E351008DFB7A /* RCTPackagerClient.h */; }; - 3D7BFD161EA8E351008DFB7A /* RCTPackagerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0B1EA8E351008DFB7A /* RCTPackagerClient.h */; }; 3D7BFD171EA8E351008DFB7A /* RCTPackagerClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D7BFD0C1EA8E351008DFB7A /* RCTPackagerClient.m */; }; - 3D7BFD181EA8E351008DFB7A /* RCTPackagerClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D7BFD0C1EA8E351008DFB7A /* RCTPackagerClient.m */; }; 3D7BFD1D1EA8E351008DFB7A /* RCTPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0F1EA8E351008DFB7A /* RCTPackagerConnection.h */; }; - 3D7BFD1E1EA8E351008DFB7A /* RCTPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0F1EA8E351008DFB7A /* RCTPackagerConnection.h */; }; 3D7BFD1F1EA8E351008DFB7A /* RCTPackagerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D7BFD101EA8E351008DFB7A /* RCTPackagerConnection.mm */; }; - 3D7BFD201EA8E351008DFB7A /* RCTPackagerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D7BFD101EA8E351008DFB7A /* RCTPackagerConnection.mm */; }; 3D7BFD291EA8E37B008DFB7A /* RCTDevSettings.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130E3D861E6A082100ACE484 /* RCTDevSettings.h */; }; 3D7BFD2D1EA8E3FA008DFB7A /* RCTReconnectingWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD2B1EA8E3FA008DFB7A /* RCTReconnectingWebSocket.h */; }; - 3D7BFD2E1EA8E3FA008DFB7A /* RCTReconnectingWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD2B1EA8E3FA008DFB7A /* RCTReconnectingWebSocket.h */; }; 3D7BFD2F1EA8E3FA008DFB7A /* RCTSRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD2C1EA8E3FA008DFB7A /* RCTSRWebSocket.h */; }; - 3D7BFD301EA8E3FA008DFB7A /* RCTSRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD2C1EA8E3FA008DFB7A /* RCTSRWebSocket.h */; }; 3D7BFD311EA8E41F008DFB7A /* RCTPackagerClient.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0B1EA8E351008DFB7A /* RCTPackagerClient.h */; }; - 3D7BFD331EA8E433008DFB7A /* RCTPackagerClient.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD0B1EA8E351008DFB7A /* RCTPackagerClient.h */; }; - 3D7BFD351EA8E43F008DFB7A /* RCTDevSettings.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130E3D861E6A082100ACE484 /* RCTDevSettings.h */; }; - 3D80D9181DF6F7A80028D040 /* JSBundleType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2EB1DE48A22002E6351 /* JSBundleType.cpp */; }; - 3D80D91B1DF6F8200028D040 /* RCTPlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D7749431DC1065C007EC8D8 /* RCTPlatform.m */; }; 3D80D91F1DF6FA890028D040 /* RCTImageLoader.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0831DE4F3A000E03CC6 /* RCTImageLoader.h */; }; 3D80D9201DF6FA890028D040 /* RCTImageStoreManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0841DE4F3A000E03CC6 /* RCTImageStoreManager.h */; }; 3D80D9211DF6FA890028D040 /* RCTResizeMode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1FA0851DE4F3A000E03CC6 /* RCTResizeMode.h */; }; @@ -699,8 +394,6 @@ 3D80DA911DF820620028D040 /* RCTWebViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 13C156031AB1A2840079392D /* RCTWebViewManager.h */; }; 3D80DA931DF820620028D040 /* NSView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F15A171B7CC46900F10295 /* NSView+Private.h */; }; 3D80DA941DF820620028D040 /* NSView+React.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E067531A70F44B002CDEE1 /* NSView+React.h */; }; - 3D8ED92C1E5B120100D83D20 /* libcxxreact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD9321DE5FBEE00167DC4 /* libcxxreact.a */; }; - 3D8ED92D1E5B120100D83D20 /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3C06751DE3340C00C268FA /* libyoga.a */; }; 3DA9819E1E5B0DBB004F2374 /* NSDataBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D7454B31E54786200E74ADD /* NSDataBigString.h */; }; 3DA981A01E5B0E34004F2374 /* CxxModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A71E03699D0018521A /* CxxModule.h */; }; 3DA981A11E5B0E34004F2374 /* CxxNativeModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A91E03699D0018521A /* CxxNativeModule.h */; }; @@ -729,180 +422,36 @@ 3DA981BC1E5B0E34004F2374 /* RecoverableError.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7454791E54757500E74ADD /* RecoverableError.h */; }; 3DA981BD1E5B0E34004F2374 /* SampleCxxModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; }; 3DA981BE1E5B0E34004F2374 /* SystraceSection.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; }; - 3DA981BF1E5B0F29004F2374 /* RCTAssert.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */; }; - 3DA981C01E5B0F29004F2374 /* RCTBridge.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */; }; - 3DA981C21E5B0F29004F2374 /* RCTBridgeDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1482F9E61B55B927000ADFF3 /* RCTBridgeDelegate.h */; }; - 3DA981C31E5B0F29004F2374 /* RCTBridgeMethod.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13AFBCA11C07287B00BBAEAA /* RCTBridgeMethod.h */; }; - 3DA981C41E5B0F29004F2374 /* RCTBridgeModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 830213F31A654E0800B993E6 /* RCTBridgeModule.h */; }; - 3DA981C51E5B0F29004F2374 /* RCTBundleURLProvider.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 68EFE4EC1CF6EB3000A1DE13 /* RCTBundleURLProvider.h */; }; - 3DA981C61E5B0F29004F2374 /* RCTConvert.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBACA1A6023D300E9B192 /* RCTConvert.h */; }; - 3DA981C71E5B0F29004F2374 /* RCTDefines.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13AF1F851AE6E777005F5298 /* RCTDefines.h */; }; - 3DA981C81E5B0F29004F2374 /* RCTDisplayLink.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D1E68D81CABD13900DD7465 /* RCTDisplayLink.h */; }; - 3DA981C91E5B0F29004F2374 /* RCTErrorCustomizer.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3EDCA8A21D3591E700450C31 /* RCTErrorCustomizer.h */; }; - 3DA981CA1E5B0F29004F2374 /* RCTErrorInfo.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3EDCA8A31D3591E700450C31 /* RCTErrorInfo.h */; }; - 3DA981CB1E5B0F29004F2374 /* RCTEventDispatcher.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA651A601EF300E9B192 /* RCTEventDispatcher.h */; }; - 3DA981CC1E5B0F29004F2374 /* RCTFrameUpdate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1436DD071ADE7AA000A5ED7D /* RCTFrameUpdate.h */; }; - 3DA981CD1E5B0F29004F2374 /* RCTImageSource.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13BB3D001BECD54500932C10 /* RCTImageSource.h */; }; - 3DA981CE1E5B0F29004F2374 /* RCTInvalidating.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */; }; - 3DA981CF1E5B0F29004F2374 /* RCTJavaScriptExecutor.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */; }; - 3DA981D01E5B0F29004F2374 /* RCTJavaScriptLoader.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */; }; - 3DA981D11E5B0F29004F2374 /* RCTJSStackFrame.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 008341F51D1DB34400876D9A /* RCTJSStackFrame.h */; }; - 3DA981D21E5B0F29004F2374 /* RCTKeyCommands.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */; }; - 3DA981D31E5B0F29004F2374 /* RCTLog.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4D1A601E3B00E9B192 /* RCTLog.h */; }; - 3DA981D41E5B0F29004F2374 /* RCTModuleData.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14C2CA721B3AC64300E6CBB2 /* RCTModuleData.h */; }; - 3DA981D51E5B0F29004F2374 /* RCTModuleMethod.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14C2CA6F1B3AC63800E6CBB2 /* RCTModuleMethod.h */; }; - 3DA981D61E5B0F29004F2374 /* RCTMultipartDataTask.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 006FC4121D9B20820057AAAD /* RCTMultipartDataTask.h */; }; - 3DA981D71E5B0F29004F2374 /* RCTMultipartStreamReader.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 001BFCCE1D8381DE008E587E /* RCTMultipartStreamReader.h */; }; - 3DA981D81E5B0F29004F2374 /* RCTNullability.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13A6E20F1C19ABC700845B82 /* RCTNullability.h */; }; - 3DA981D91E5B0F29004F2374 /* RCTParserUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13A6E20C1C19AA0C00845B82 /* RCTParserUtils.h */; }; - 3DA981DA1E5B0F29004F2374 /* RCTPerformanceLogger.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 142014181B32094000CC17BA /* RCTPerformanceLogger.h */; }; - 3DA981DB1E5B0F29004F2374 /* RCTPlatform.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7749421DC1065C007EC8D8 /* RCTPlatform.h */; }; - 3DA981DC1E5B0F29004F2374 /* RCTReloadCommand.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = A2440AA01DF8D854006E7BFC /* RCTReloadCommand.h */; }; - 3DA981DD1E5B0F29004F2374 /* RCTRootContentView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59A7B9FB1E577DBF0068EDBF /* RCTRootContentView.h */; }; - 3DA981DE1E5B0F29004F2374 /* RCTRootView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 830A229C1A66C68A008503DA /* RCTRootView.h */; }; - 3DA981DF1E5B0F29004F2374 /* RCTRootViewDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13AFBCA21C07287B00BBAEAA /* RCTRootViewDelegate.h */; }; - 3DA981E11E5B0F29004F2374 /* RCTTouchEvent.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 391E86A31C623EC800009732 /* RCTTouchEvent.h */; }; - 3DA981E21E5B0F29004F2374 /* RCTTouchHandler.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */; }; - 3DA981E31E5B0F29004F2374 /* RCTURLRequestDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1345A83A1B265A0E00583190 /* RCTURLRequestDelegate.h */; }; - 3DA981E41E5B0F29004F2374 /* RCTURLRequestHandler.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1345A83B1B265A0E00583190 /* RCTURLRequestHandler.h */; }; - 3DA981E51E5B0F29004F2374 /* RCTUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */; }; - 3DA981E91E5B0F7F004F2374 /* RCTJSCSamplingProfiler.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 369123DF1DDC75850095B341 /* RCTJSCSamplingProfiler.h */; }; - 3DA981EB1E5B0F7F004F2374 /* RCTAlertManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13B07FE71A69327A00A75B9A /* RCTAlertManager.h */; }; - 3DA981EC1E5B0F7F004F2374 /* RCTAppState.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1372B7081AB030C200659ED6 /* RCTAppState.h */; }; - 3DA981ED1E5B0F7F004F2374 /* RCTAsyncLocalStorage.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */; }; - 3DA981EE1E5B0F7F004F2374 /* RCTClipboard.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13D033611C1837FE0021DC29 /* RCTClipboard.h */; }; - 3DA981EF1E5B0F7F004F2374 /* RCTDevLoadingView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13A0C2851B74F71200B29F6F /* RCTDevLoadingView.h */; }; - 3DA981F01E5B0F7F004F2374 /* RCTDevMenu.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13A0C2871B74F71200B29F6F /* RCTDevMenu.h */; }; - 3DA981F11E5B0F7F004F2374 /* RCTEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13D9FEE91CDCCECF00158BD7 /* RCTEventEmitter.h */; }; - 3DA981F21E5B0F7F004F2374 /* RCTExceptionsManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */; }; - 3DA981F31E5B0F7F004F2374 /* RCTI18nManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = B233E6E81D2D843200BC68BA /* RCTI18nManager.h */; }; - 3DA981F41E5B0F7F004F2374 /* RCTI18nUtil.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 352DCFEE1D19F4C20056D623 /* RCTI18nUtil.h */; }; - 3DA981F61E5B0F7F004F2374 /* RCTRedBox.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13F17A831B8493E5007D4C75 /* RCTRedBox.h */; }; - 3DA981F71E5B0F7F004F2374 /* RCTSourceCode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 000E6CE91AB0E97F000CDF4D /* RCTSourceCode.h */; }; - 3DA981F91E5B0F7F004F2374 /* RCTTiming.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13B07FED1A69327A00A75B9A /* RCTTiming.h */; }; - 3DA981FA1E5B0F7F004F2374 /* RCTUIManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13E067481A70F434002CDEE1 /* RCTUIManager.h */; }; - 3DA981FB1E5B0F7F004F2374 /* RCTFPSGraph.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14F7A0EE1BDA714B003C6C10 /* RCTFPSGraph.h */; }; - 3DA981FD1E5B0F7F004F2374 /* RCTMacros.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14BF71811C04795500C97D0C /* RCTMacros.h */; }; - 3DA981FE1E5B0F7F004F2374 /* RCTProfile.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 1450FF801BCFF28A00208362 /* RCTProfile.h */; }; - 3DA981FF1E5B0F7F004F2374 /* RCTActivityIndicatorView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = B95154301D1B34B200FE7B80 /* RCTActivityIndicatorView.h */; }; - 3DA982001E5B0F7F004F2374 /* RCTActivityIndicatorViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13B080181A69489C00A75B9A /* RCTActivityIndicatorViewManager.h */; }; - 3DA982011E5B0F7F004F2374 /* RCTAnimationType.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */; }; - 3DA982021E5B0F7F004F2374 /* RCTAutoInsetsProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */; }; - 3DA982031E5B0F7F004F2374 /* RCTBorderDrawing.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13CC8A801B17642100940AE7 /* RCTBorderDrawing.h */; }; - 3DA982041E5B0F7F004F2374 /* RCTBorderStyle.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = ACDD3FDA1BC7430D00E7DE33 /* RCTBorderStyle.h */; }; - 3DA982051E5B0F7F004F2374 /* RCTComponent.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13C325281AA63B6A0048765F /* RCTComponent.h */; }; - 3DA982061E5B0F7F004F2374 /* RCTComponentData.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13AB90BF1B6FA36700713B4F /* RCTComponentData.h */; }; - 3DA982071E5B0F7F004F2374 /* RCTConvert+CoreLocation.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13456E911ADAD2DE009F94A7 /* RCTConvert+CoreLocation.h */; }; - 3DA9820A1E5B0F7F004F2374 /* RCTDatePicker.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 133CAE8C1B8E5CFD00F6AD92 /* RCTDatePicker.h */; }; - 3DA9820B1E5B0F7F004F2374 /* RCTDatePickerManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */; }; - 3DA9820C1E5B0F7F004F2374 /* RCTFont.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D37B5801D522B190042D5B5 /* RCTFont.h */; }; - 3DA982111E5B0F7F004F2374 /* RCTModalHostView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83A1FE8A1B62640A00BE0E65 /* RCTModalHostView.h */; }; - 3DA982121E5B0F7F004F2374 /* RCTModalHostViewController.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83392EB11B6634E10013B15F /* RCTModalHostViewController.h */; }; - 3DA982131E5B0F7F004F2374 /* RCTModalHostViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 83A1FE8D1B62643A00BE0E65 /* RCTModalHostViewManager.h */; }; - 3DA982181E5B0F7F004F2374 /* RCTPicker.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 58114A121AAE854800E7D092 /* RCTPicker.h */; }; - 3DA982191E5B0F7F004F2374 /* RCTPickerManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 58114A141AAE854800E7D092 /* RCTPickerManager.h */; }; - 3DA9821A1E5B0F7F004F2374 /* RCTPointerEvents.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13442BF31AA90E0B0037E5B0 /* RCTPointerEvents.h */; }; - 3DA9821B1E5B0F7F004F2374 /* RCTProgressViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13513F3A1B1F43F400FCE529 /* RCTProgressViewManager.h */; }; - 3DA9821E1E5B0F7F004F2374 /* RCTRootShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13BCE8071C99CB9D00DD7AAD /* RCTRootShadowView.h */; }; - 3DA982241E5B0F7F004F2374 /* RCTSegmentedControl.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 131B6AF01AF1093D00FFC3E0 /* RCTSegmentedControl.h */; }; - 3DA982251E5B0F7F004F2374 /* RCTSegmentedControlManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 131B6AF21AF1093D00FFC3E0 /* RCTSegmentedControlManager.h */; }; - 3DA982261E5B0F7F004F2374 /* RCTShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */; }; - 3DA982271E5B0F7F004F2374 /* RCTSlider.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13AF20431AE707F8005F5298 /* RCTSlider.h */; }; - 3DA982281E5B0F7F004F2374 /* RCTSliderManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14F484541AABFCE100FDF6B9 /* RCTSliderManager.h */; }; - 3DA982291E5B0F7F004F2374 /* RCTSwitch.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14F362071AABD06A001CE568 /* RCTSwitch.h */; }; - 3DA9822A1E5B0F7F004F2374 /* RCTSwitchManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 14F362091AABD06A001CE568 /* RCTSwitchManager.h */; }; - 3DA9822F1E5B0F7F004F2374 /* RCTTextDecorationLineType.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationLineType.h */; }; - 3DA982311E5B0F7F004F2374 /* RCTView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13E0674F1A70F44B002CDEE1 /* RCTView.h */; }; - 3DA982321E5B0F7F004F2374 /* RCTViewControllerProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13442BF41AA90E0B0037E5B0 /* RCTViewControllerProtocol.h */; }; - 3DA982331E5B0F7F004F2374 /* RCTViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13E0674D1A70F44B002CDEE1 /* RCTViewManager.h */; }; - 3DA982341E5B0F7F004F2374 /* RCTWebView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13C156011AB1A2840079392D /* RCTWebView.h */; }; - 3DA982351E5B0F7F004F2374 /* RCTWebViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13C156031AB1A2840079392D /* RCTWebViewManager.h */; }; - 3DA982381E5B0F7F004F2374 /* NSView+React.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13E067531A70F44B002CDEE1 /* NSView+React.h */; }; - 3DA982391E5B0F8A004F2374 /* NSView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F15A171B7CC46900F10295 /* NSView+Private.h */; }; - 3DA9823B1E5B1053004F2374 /* CxxModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A71E03699D0018521A /* CxxModule.h */; }; - 3DA9823C1E5B1053004F2374 /* CxxNativeModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0A91E03699D0018521A /* CxxNativeModule.h */; }; - 3DA9823D1E5B1053004F2374 /* JSExecutor.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0AB1E03699D0018521A /* JSExecutor.h */; }; - 3DA982401E5B1053004F2374 /* Instance.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0AF1E03699D0018521A /* Instance.h */; }; - 3DA982411E5B1053004F2374 /* JsArgumentHelpers-inl.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B01E03699D0018521A /* JsArgumentHelpers-inl.h */; }; - 3DA982421E5B1053004F2374 /* JsArgumentHelpers.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B11E03699D0018521A /* JsArgumentHelpers.h */; }; - 3DA982431E5B1053004F2374 /* JSBigString.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7454781E54757500E74ADD /* JSBigString.h */; }; - 3DA982441E5B1053004F2374 /* JSBundleType.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D3CD8F51DE5FB2300167DC4 /* JSBundleType.h */; }; - 3DA982451E5B1053004F2374 /* JSCExecutor.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B31E03699D0018521A /* JSCExecutor.h */; }; - 3DA982471E5B1053004F2374 /* JSCLegacyTracing.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B71E03699D0018521A /* JSCLegacyTracing.h */; }; - 3DA982481E5B1053004F2374 /* JSCMemory.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0B91E03699D0018521A /* JSCMemory.h */; }; - 3DA982491E5B1053004F2374 /* JSCNativeModules.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BB1E03699D0018521A /* JSCNativeModules.h */; }; - 3DA9824A1E5B1053004F2374 /* JSCPerfStats.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BD1E03699D0018521A /* JSCPerfStats.h */; }; - 3DA9824B1E5B1053004F2374 /* JSCSamplingProfiler.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0BF1E03699D0018521A /* JSCSamplingProfiler.h */; }; - 3DA9824C1E5B1053004F2374 /* JSCUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C31E03699D0018521A /* JSCUtils.h */; }; - 3DA9824E1E5B1053004F2374 /* JSIndexedRAMBundle.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C71E03699D0018521A /* JSIndexedRAMBundle.h */; }; - 3DA9824F1E5B1053004F2374 /* JSModulesUnbundle.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C81E03699D0018521A /* JSModulesUnbundle.h */; }; - 3DA982501E5B1053004F2374 /* MessageQueueThread.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0C91E03699D0018521A /* MessageQueueThread.h */; }; - 3DA982511E5B1053004F2374 /* MethodCall.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CB1E03699D0018521A /* MethodCall.h */; }; - 3DA982521E5B1053004F2374 /* ModuleRegistry.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CD1E03699D0018521A /* ModuleRegistry.h */; }; - 3DA982531E5B1053004F2374 /* NativeModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0CE1E03699D0018521A /* NativeModule.h */; }; - 3DA982541E5B1053004F2374 /* NativeToJsBridge.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D01E03699D0018521A /* NativeToJsBridge.h */; }; - 3DA982551E5B1053004F2374 /* oss-compat-util.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = AC70D2EE1DE48AC5002E6351 /* oss-compat-util.h */; }; - 3DA982561E5B1053004F2374 /* Platform.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; }; - 3DA982571E5B1053004F2374 /* RecoverableError.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7454791E54757500E74ADD /* RecoverableError.h */; }; - 3DA982581E5B1053004F2374 /* SampleCxxModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; }; - 3DA982591E5B1053004F2374 /* SystraceSection.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; }; 3DA9825A1E5B1079004F2374 /* JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; 3DA9825B1E5B1079004F2374 /* JSCHelpers.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1081E0369AD0018521A /* JSCHelpers.h */; }; 3DA9825C1E5B1079004F2374 /* JSCWrapper.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DE1DE32541002E3F95 /* JSCWrapper.h */; }; 3DA9825D1E5B1079004F2374 /* noncopyable.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1091E0369AD0018521A /* noncopyable.h */; }; 3DA9825E1E5B1079004F2374 /* Unicode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10B1E0369AD0018521A /* Unicode.h */; }; 3DA9825F1E5B1079004F2374 /* Value.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10D1E0369AD0018521A /* Value.h */; }; - 3DA982601E5B1089004F2374 /* JSCHelpers.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1081E0369AD0018521A /* JSCHelpers.h */; }; - 3DA982611E5B1089004F2374 /* noncopyable.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B1091E0369AD0018521A /* noncopyable.h */; }; - 3DA982621E5B1089004F2374 /* Unicode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10B1E0369AD0018521A /* Unicode.h */; }; - 3DA982631E5B1089004F2374 /* Value.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D92B10D1E0369AD0018521A /* Value.h */; }; - 3DC159E41E83E1AE007B1282 /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A7B9FC1E577DBF0068EDBF /* RCTRootContentView.m */; }; 3DC159E51E83E1E9007B1282 /* JSBigString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27B958731E57587D0096647A /* JSBigString.cpp */; }; - 3DC159E61E83E1FA007B1282 /* JSBigString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27B958731E57587D0096647A /* JSBigString.cpp */; }; - 3DCD185D1DF978E7007FE5A1 /* RCTReloadCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = A2440AA11DF8D854006E7BFC /* RCTReloadCommand.m */; }; - 3DDEC1521DDCE0CA0020BBDF /* RCTJSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */; }; 3DE4F8681DF85D8E00B9E5A0 /* YGEnums.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77031DF767AF001F9587 /* YGEnums.h */; }; 3DE4F8691DF85D8E00B9E5A0 /* YGMacros.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77041DF767AF001F9587 /* YGMacros.h */; }; 3DE4F86A1DF85D8E00B9E5A0 /* Yoga.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77081DF767AF001F9587 /* Yoga.h */; }; 3DF1BE821F26576400068F1A /* JSCTracing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DF1BE801F26576400068F1A /* JSCTracing.cpp */; }; 3DF1BE831F26576400068F1A /* JSCTracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DF1BE811F26576400068F1A /* JSCTracing.h */; }; - 3DF1BE841F26577000068F1A /* JSCTracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DF1BE811F26576400068F1A /* JSCTracing.h */; }; - 3DF1BE851F26577300068F1A /* JSCTracing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DF1BE801F26576400068F1A /* JSCTracing.cpp */; }; - 3DFE0D161DF8574D00459392 /* YGEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 130A77031DF767AF001F9587 /* YGEnums.h */; }; - 3DFE0D171DF8574D00459392 /* YGMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 130A77041DF767AF001F9587 /* YGMacros.h */; }; - 3DFE0D191DF8574D00459392 /* Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 130A77081DF767AF001F9587 /* Yoga.h */; }; - 3DFE0D1A1DF8575800459392 /* YGEnums.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77031DF767AF001F9587 /* YGEnums.h */; }; - 3DFE0D1B1DF8575800459392 /* YGMacros.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77041DF767AF001F9587 /* YGMacros.h */; }; - 3DFE0D1C1DF8575800459392 /* Yoga.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 130A77081DF767AF001F9587 /* Yoga.h */; }; 3EDCA8A51D3591E700450C31 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; }; 5376C5E41FC6DDBC0083513D /* YGNodePrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5376C5E11FC6DDB20083513D /* YGNodePrint.cpp */; }; - 5376C5E51FC6DDBD0083513D /* YGNodePrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5376C5E11FC6DDB20083513D /* YGNodePrint.cpp */; }; 5376C5E61FC6DDC10083513D /* YGNodePrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5376C5E01FC6DDB20083513D /* YGNodePrint.h */; }; - 5376C5E71FC6DDC20083513D /* YGNodePrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5376C5E01FC6DDB20083513D /* YGNodePrint.h */; }; 53D123971FBF1DF5001B8A10 /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3C059A1DE3340900C268FA /* libyoga.a */; }; 53D1239A1FBF1EF2001B8A10 /* YGEnums.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53CBF1861FB4FE80002CBB31 /* YGEnums.cpp */; }; - 53D1239B1FBF1EF4001B8A10 /* YGEnums.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53CBF1861FB4FE80002CBB31 /* YGEnums.cpp */; }; 53D1239E1FBF1EFB001B8A10 /* Yoga-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CBF1851FB4FE80002CBB31 /* Yoga-internal.h */; }; - 53D1239F1FBF1EFB001B8A10 /* Yoga-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CBF1851FB4FE80002CBB31 /* Yoga-internal.h */; }; 53D123A01FBF1EFF001B8A10 /* Yoga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53CBF1871FB4FE80002CBB31 /* Yoga.cpp */; }; - 53D123A11FBF1EFF001B8A10 /* Yoga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53CBF1871FB4FE80002CBB31 /* Yoga.cpp */; }; 53D123B21FBF220F001B8A10 /* Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 130A77081DF767AF001F9587 /* Yoga.h */; }; 58114A161AAE854800E7D092 /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A131AAE854800E7D092 /* RCTPicker.m */; }; 58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; }; 58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; }; 58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; }; 590D7BFD1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; }; - 590D7BFE1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; }; 590D7BFF1EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; }; - 590D7C001EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; }; 59283CA01FD67321000EAAB9 /* RCTSurfaceStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59283C9F1FD67320000EAAB9 /* RCTSurfaceStage.m */; }; - 59283CA11FD67321000EAAB9 /* RCTSurfaceStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59283C9F1FD67320000EAAB9 /* RCTSurfaceStage.m */; }; 594F0A321FD23228007FBE96 /* RCTSurfaceHostingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */; }; - 594F0A331FD23228007FBE96 /* RCTSurfaceHostingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */; }; 594F0A341FD23228007FBE96 /* RCTSurfaceHostingView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 594F0A301FD23228007FBE96 /* RCTSurfaceHostingView.mm */; }; - 594F0A351FD23228007FBE96 /* RCTSurfaceHostingView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 594F0A301FD23228007FBE96 /* RCTSurfaceHostingView.mm */; }; 594F0A361FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */; }; - 594F0A371FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */; }; 594F0A381FD233A2007FBE96 /* RCTSurface.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; }; 594F0A391FD233A2007FBE96 /* RCTSurfaceDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; }; 594F0A3A1FD233A2007FBE96 /* RCTSurfaceRootShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; }; @@ -912,131 +461,63 @@ 594F0A3E1FD233A2007FBE96 /* RCTSurfaceView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; }; 594F0A3F1FD233A2007FBE96 /* RCTSurfaceHostingView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */; }; 594F0A401FD233A2007FBE96 /* RCTSurfaceSizeMeasureMode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */; }; - 594F0A411FD233BD007FBE96 /* RCTSurface.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; }; - 594F0A421FD233BD007FBE96 /* RCTSurfaceDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; }; - 594F0A431FD233BD007FBE96 /* RCTSurfaceRootShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; }; - 594F0A441FD233BD007FBE96 /* RCTSurfaceRootShadowViewDelegate.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */; }; - 594F0A451FD233BD007FBE96 /* RCTSurfaceRootView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */; }; - 594F0A461FD233BD007FBE96 /* RCTSurfaceStage.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */; }; - 594F0A471FD233BD007FBE96 /* RCTSurfaceView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; }; - 594F0A481FD233BD007FBE96 /* RCTSurfaceHostingView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */; }; - 594F0A491FD233BD007FBE96 /* RCTSurfaceSizeMeasureMode.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */; }; 59500D431F71C63F00B122B7 /* RCTUIManagerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 59500D411F71C63700B122B7 /* RCTUIManagerUtils.h */; }; - 59500D441F71C63F00B122B7 /* RCTUIManagerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 59500D411F71C63700B122B7 /* RCTUIManagerUtils.h */; }; 59500D451F71C63F00B122B7 /* RCTUIManagerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 59500D421F71C63F00B122B7 /* RCTUIManagerUtils.m */; }; - 59500D461F71C63F00B122B7 /* RCTUIManagerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 59500D421F71C63F00B122B7 /* RCTUIManagerUtils.m */; }; 59500D471F71C66700B122B7 /* RCTUIManagerUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59500D411F71C63700B122B7 /* RCTUIManagerUtils.h */; }; - 59500D481F71C67600B122B7 /* RCTUIManagerUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59500D411F71C63700B122B7 /* RCTUIManagerUtils.h */; }; 5960C1B51F0804A00066FD5B /* RCTLayoutAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B11F0804A00066FD5B /* RCTLayoutAnimation.h */; }; - 5960C1B61F0804A00066FD5B /* RCTLayoutAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B11F0804A00066FD5B /* RCTLayoutAnimation.h */; }; 5960C1B71F0804A00066FD5B /* RCTLayoutAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5960C1B21F0804A00066FD5B /* RCTLayoutAnimation.m */; }; - 5960C1B81F0804A00066FD5B /* RCTLayoutAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5960C1B21F0804A00066FD5B /* RCTLayoutAnimation.m */; }; 5960C1B91F0804A00066FD5B /* RCTLayoutAnimationGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B31F0804A00066FD5B /* RCTLayoutAnimationGroup.h */; }; - 5960C1BA1F0804A00066FD5B /* RCTLayoutAnimationGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B31F0804A00066FD5B /* RCTLayoutAnimationGroup.h */; }; 5960C1BB1F0804A00066FD5B /* RCTLayoutAnimationGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 5960C1B41F0804A00066FD5B /* RCTLayoutAnimationGroup.m */; }; - 5960C1BC1F0804A00066FD5B /* RCTLayoutAnimationGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 5960C1B41F0804A00066FD5B /* RCTLayoutAnimationGroup.m */; }; 5960C1BD1F0804DF0066FD5B /* RCTLayoutAnimation.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B11F0804A00066FD5B /* RCTLayoutAnimation.h */; }; 5960C1BE1F0804DF0066FD5B /* RCTLayoutAnimationGroup.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B31F0804A00066FD5B /* RCTLayoutAnimationGroup.h */; }; - 5960C1BF1F0804F50066FD5B /* RCTLayoutAnimation.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B11F0804A00066FD5B /* RCTLayoutAnimation.h */; }; - 5960C1C01F0804F50066FD5B /* RCTLayoutAnimationGroup.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 5960C1B31F0804A00066FD5B /* RCTLayoutAnimationGroup.h */; }; 597633361F4E021D005BE8A4 /* RCTShadowView+Internal.m in Sources */ = {isa = PBXBuildFile; fileRef = 597633341F4E021D005BE8A4 /* RCTShadowView+Internal.m */; }; - 597633371F4E021D005BE8A4 /* RCTShadowView+Internal.m in Sources */ = {isa = PBXBuildFile; fileRef = 597633341F4E021D005BE8A4 /* RCTShadowView+Internal.m */; }; 597633381F4E021D005BE8A4 /* RCTShadowView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 597633351F4E021D005BE8A4 /* RCTShadowView+Internal.h */; }; - 597633391F4E021D005BE8A4 /* RCTShadowView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 597633351F4E021D005BE8A4 /* RCTShadowView+Internal.h */; }; - 598FD1921F816A2A006C54CB /* RAMBundleRegistry.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = C6D380181F71D75B00621378 /* RAMBundleRegistry.h */; }; - 598FD1931F817284006C54CB /* PrivateDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */; }; - 598FD1941F8172A9006C54CB /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; - 598FD1951F817335006C54CB /* RCTModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 91076A881F743AB00081B4FA /* RCTModalManager.h */; }; - 598FD1961F817335006C54CB /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; }; 598FD1971F817336006C54CB /* RCTModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 91076A881F743AB00081B4FA /* RCTModalManager.h */; }; 599FAA361FB274980058CCF6 /* RCTSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; }; - 599FAA371FB274980058CCF6 /* RCTSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; }; 599FAA381FB274980058CCF6 /* RCTSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2B1FB274970058CCF6 /* RCTSurface.mm */; }; - 599FAA391FB274980058CCF6 /* RCTSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2B1FB274970058CCF6 /* RCTSurface.mm */; }; 599FAA3A1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; }; - 599FAA3B1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; }; 599FAA3C1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; }; - 599FAA3D1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; }; 599FAA3E1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */; }; - 599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */; }; 599FAA401FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */; }; - 599FAA411FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */; }; 599FAA421FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */; }; - 599FAA431FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */; }; 599FAA441FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */; }; - 599FAA451FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */; }; 599FAA461FB274980058CCF6 /* RCTSurfaceStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */; }; - 599FAA471FB274980058CCF6 /* RCTSurfaceStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */; }; 599FAA481FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */; }; - 599FAA491FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */; }; 599FAA4A1FB274980058CCF6 /* RCTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; }; - 599FAA4B1FB274980058CCF6 /* RCTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; }; 599FAA4C1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */; }; - 599FAA4D1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */; }; 59A7B9FD1E577DBF0068EDBF /* RCTRootContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A7B9FB1E577DBF0068EDBF /* RCTRootContentView.h */; }; 59A7B9FE1E577DBF0068EDBF /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A7B9FC1E577DBF0068EDBF /* RCTRootContentView.m */; }; 59B1EBC91EBD46250047B19B /* RCTShadowView+Layout.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; }; - 59B1EBCA1EBD47520047B19B /* RCTShadowView+Layout.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; }; 59EB6DBB1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB6DB91EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h */; }; - 59EB6DBC1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB6DB91EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h */; }; 59EB6DBD1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 59EB6DBA1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm */; }; - 59EB6DBE1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 59EB6DBA1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm */; }; 59EB6DBF1EBD6FFC0072A5E7 /* RCTUIManagerObserverCoordinator.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EB6DB91EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h */; }; - 59EB6DC01EBD70130072A5E7 /* RCTUIManagerObserverCoordinator.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EB6DB91EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h */; }; 59EDBCA71FDF4E0C003573DE /* RCTScrollableProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9C1FDF4E0C003573DE /* RCTScrollableProtocol.h */; }; - 59EDBCA81FDF4E0C003573DE /* RCTScrollableProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9C1FDF4E0C003573DE /* RCTScrollableProtocol.h */; }; 59EDBCA91FDF4E0C003573DE /* RCTScrollContentShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9D1FDF4E0C003573DE /* RCTScrollContentShadowView.h */; }; - 59EDBCAA1FDF4E0C003573DE /* RCTScrollContentShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9D1FDF4E0C003573DE /* RCTScrollContentShadowView.h */; }; 59EDBCAB1FDF4E0C003573DE /* RCTScrollContentShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBC9E1FDF4E0C003573DE /* RCTScrollContentShadowView.m */; }; - 59EDBCAC1FDF4E0C003573DE /* RCTScrollContentShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBC9E1FDF4E0C003573DE /* RCTScrollContentShadowView.m */; }; 59EDBCAD1FDF4E0C003573DE /* RCTScrollContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9F1FDF4E0C003573DE /* RCTScrollContentView.h */; }; - 59EDBCAE1FDF4E0C003573DE /* RCTScrollContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9F1FDF4E0C003573DE /* RCTScrollContentView.h */; }; 59EDBCAF1FDF4E0C003573DE /* RCTScrollContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA01FDF4E0C003573DE /* RCTScrollContentView.m */; }; - 59EDBCB01FDF4E0C003573DE /* RCTScrollContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA01FDF4E0C003573DE /* RCTScrollContentView.m */; }; 59EDBCB11FDF4E0C003573DE /* RCTScrollContentViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA11FDF4E0C003573DE /* RCTScrollContentViewManager.h */; }; - 59EDBCB21FDF4E0C003573DE /* RCTScrollContentViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA11FDF4E0C003573DE /* RCTScrollContentViewManager.h */; }; 59EDBCB31FDF4E0C003573DE /* RCTScrollContentViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA21FDF4E0C003573DE /* RCTScrollContentViewManager.m */; }; - 59EDBCB41FDF4E0C003573DE /* RCTScrollContentViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA21FDF4E0C003573DE /* RCTScrollContentViewManager.m */; }; 59EDBCB51FDF4E0C003573DE /* RCTScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA31FDF4E0C003573DE /* RCTScrollView.h */; }; - 59EDBCB61FDF4E0C003573DE /* RCTScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA31FDF4E0C003573DE /* RCTScrollView.h */; }; 59EDBCB71FDF4E0C003573DE /* RCTScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA41FDF4E0C003573DE /* RCTScrollView.m */; }; - 59EDBCB81FDF4E0C003573DE /* RCTScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA41FDF4E0C003573DE /* RCTScrollView.m */; }; 59EDBCB91FDF4E0C003573DE /* RCTScrollViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA51FDF4E0C003573DE /* RCTScrollViewManager.h */; }; - 59EDBCBA1FDF4E0C003573DE /* RCTScrollViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA51FDF4E0C003573DE /* RCTScrollViewManager.h */; }; 59EDBCBB1FDF4E0C003573DE /* RCTScrollViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA61FDF4E0C003573DE /* RCTScrollViewManager.m */; }; - 59EDBCBC1FDF4E0C003573DE /* RCTScrollViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EDBCA61FDF4E0C003573DE /* RCTScrollViewManager.m */; }; 59EDBCBD1FDF4E43003573DE /* RCTScrollableProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9C1FDF4E0C003573DE /* RCTScrollableProtocol.h */; }; 59EDBCBE1FDF4E43003573DE /* RCTScrollContentShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9D1FDF4E0C003573DE /* RCTScrollContentShadowView.h */; }; 59EDBCBF1FDF4E43003573DE /* RCTScrollContentView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9F1FDF4E0C003573DE /* RCTScrollContentView.h */; }; 59EDBCC01FDF4E43003573DE /* RCTScrollContentViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA11FDF4E0C003573DE /* RCTScrollContentViewManager.h */; }; 59EDBCC11FDF4E43003573DE /* RCTScrollView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA31FDF4E0C003573DE /* RCTScrollView.h */; }; 59EDBCC21FDF4E43003573DE /* RCTScrollViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA51FDF4E0C003573DE /* RCTScrollViewManager.h */; }; - 59EDBCC31FDF4E55003573DE /* RCTScrollableProtocol.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9C1FDF4E0C003573DE /* RCTScrollableProtocol.h */; }; - 59EDBCC41FDF4E55003573DE /* RCTScrollContentShadowView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9D1FDF4E0C003573DE /* RCTScrollContentShadowView.h */; }; - 59EDBCC51FDF4E55003573DE /* RCTScrollContentView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBC9F1FDF4E0C003573DE /* RCTScrollContentView.h */; }; - 59EDBCC61FDF4E55003573DE /* RCTScrollContentViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA11FDF4E0C003573DE /* RCTScrollContentViewManager.h */; }; - 59EDBCC71FDF4E55003573DE /* RCTScrollView.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA31FDF4E0C003573DE /* RCTScrollView.h */; }; - 59EDBCC81FDF4E55003573DE /* RCTScrollViewManager.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 59EDBCA51FDF4E0C003573DE /* RCTScrollViewManager.h */; }; 657734841EE834C900A0E9EA /* RCTInspectorDevServerHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 657734821EE834C900A0E9EA /* RCTInspectorDevServerHelper.h */; }; 657734851EE834C900A0E9EA /* RCTInspectorDevServerHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 657734831EE834C900A0E9EA /* RCTInspectorDevServerHelper.mm */; }; - 657734861EE834D900A0E9EA /* RCTInspectorDevServerHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 657734831EE834C900A0E9EA /* RCTInspectorDevServerHelper.mm */; }; - 657734871EE834E000A0E9EA /* RCTInspectorDevServerHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 657734821EE834C900A0E9EA /* RCTInspectorDevServerHelper.h */; }; 6577348E1EE8354A00A0E9EA /* RCTInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 6577348A1EE8354A00A0E9EA /* RCTInspector.h */; }; 6577348F1EE8354A00A0E9EA /* RCTInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6577348B1EE8354A00A0E9EA /* RCTInspector.mm */; }; 657734901EE8354A00A0E9EA /* RCTInspectorPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6577348C1EE8354A00A0E9EA /* RCTInspectorPackagerConnection.h */; }; 657734911EE8354A00A0E9EA /* RCTInspectorPackagerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6577348D1EE8354A00A0E9EA /* RCTInspectorPackagerConnection.m */; }; - 657734921EE8356100A0E9EA /* RCTInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 6577348A1EE8354A00A0E9EA /* RCTInspector.h */; }; - 657734931EE8356100A0E9EA /* RCTInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6577348B1EE8354A00A0E9EA /* RCTInspector.mm */; }; - 657734941EE8356100A0E9EA /* RCTInspectorPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6577348C1EE8354A00A0E9EA /* RCTInspectorPackagerConnection.h */; }; - 657734951EE8356100A0E9EA /* RCTInspectorPackagerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6577348D1EE8354A00A0E9EA /* RCTInspectorPackagerConnection.m */; }; 66CD94B11F1045E700CB3C7C /* RCTMaskedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CD94AD1F1045E700CB3C7C /* RCTMaskedView.h */; }; - 66CD94B21F1045E700CB3C7C /* RCTMaskedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CD94AD1F1045E700CB3C7C /* RCTMaskedView.h */; }; 66CD94B31F1045E700CB3C7C /* RCTMaskedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94AE1F1045E700CB3C7C /* RCTMaskedView.m */; }; - 66CD94B41F1045E700CB3C7C /* RCTMaskedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94AE1F1045E700CB3C7C /* RCTMaskedView.m */; }; 66CD94B51F1045E700CB3C7C /* RCTMaskedViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CD94AF1F1045E700CB3C7C /* RCTMaskedViewManager.h */; }; - 66CD94B61F1045E700CB3C7C /* RCTMaskedViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CD94AF1F1045E700CB3C7C /* RCTMaskedViewManager.h */; }; 66CD94B71F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94B01F1045E700CB3C7C /* RCTMaskedViewManager.m */; }; - 66CD94B81F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CD94B01F1045E700CB3C7C /* RCTMaskedViewManager.m */; }; 68EFE4EE1CF6EB3900A1DE13 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; }; 702B7FF8221C88AF0027174A /* RCTWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 702B7FF6221C88AF0027174A /* RCTWindow.h */; }; 702B7FF9221C88AF0027174A /* RCTWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 702B7FF7221C88AF0027174A /* RCTWindow.m */; }; @@ -1064,37 +545,24 @@ 916F9C2D1F743F57002E5920 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; }; 9936F3371F5F2F480010BF04 /* PrivateDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */; }; 9936F3381F5F2F480010BF04 /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; - 9936F3391F5F2F5C0010BF04 /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; - 9936F33A1F5F2F7C0010BF04 /* PrivateDataBase.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; - 9936F33B1F5F2F9D0010BF04 /* PrivateDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */; }; 9936F33C1F5F2FE70010BF04 /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; 9936F33D1F5F2FF40010BF04 /* PrivateDataBase.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; }; 9936F33E1F5F2FFC0010BF04 /* PrivateDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */; }; A2440AA21DF8D854006E7BFC /* RCTReloadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = A2440AA01DF8D854006E7BFC /* RCTReloadCommand.h */; }; A2440AA31DF8D854006E7BFC /* RCTReloadCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = A2440AA11DF8D854006E7BFC /* RCTReloadCommand.m */; }; - A2440AA41DF8D865006E7BFC /* RCTReloadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = A2440AA01DF8D854006E7BFC /* RCTReloadCommand.h */; }; AC70D2E91DE489E4002E6351 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */; }; B233E6EA1D2D845D00BC68BA /* RCTI18nManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B233E6E91D2D845D00BC68BA /* RCTI18nManager.m */; }; B95154321D1B34B200FE7B80 /* RCTActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B95154311D1B34B200FE7B80 /* RCTActivityIndicatorView.m */; }; C60128AB1F3D1258009DF9FF /* RCTCxxConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = C60128A91F3D1258009DF9FF /* RCTCxxConvert.h */; }; - C60128AC1F3D1258009DF9FF /* RCTCxxConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = C60128A91F3D1258009DF9FF /* RCTCxxConvert.h */; }; C60128AD1F3D1258009DF9FF /* RCTCxxConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = C60128AA1F3D1258009DF9FF /* RCTCxxConvert.m */; }; - C60128AE1F3D1258009DF9FF /* RCTCxxConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = C60128AA1F3D1258009DF9FF /* RCTCxxConvert.m */; }; C606692E1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = C606692D1F3CC60500E67165 /* RCTModuleMethod.mm */; }; - C606692F1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = C606692D1F3CC60500E67165 /* RCTModuleMethod.mm */; }; C60669361F3CCF1B00E67165 /* RCTManagedPointer.mm in Sources */ = {isa = PBXBuildFile; fileRef = C60669351F3CCF1B00E67165 /* RCTManagedPointer.mm */; }; - C60669371F3CCF1B00E67165 /* RCTManagedPointer.mm in Sources */ = {isa = PBXBuildFile; fileRef = C60669351F3CCF1B00E67165 /* RCTManagedPointer.mm */; }; C654505E1F3BD9280090799B /* RCTManagedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = C654505D1F3BD9280090799B /* RCTManagedPointer.h */; }; - C654505F1F3BD9280090799B /* RCTManagedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = C654505D1F3BD9280090799B /* RCTManagedPointer.h */; }; C669D8981F72E3DE006748EB /* RAMBundleRegistry.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = C6D380181F71D75B00621378 /* RAMBundleRegistry.h */; }; C6D3801A1F71D76100621378 /* RAMBundleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D380181F71D75B00621378 /* RAMBundleRegistry.h */; }; - C6D3801B1F71D76200621378 /* RAMBundleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D380181F71D75B00621378 /* RAMBundleRegistry.h */; }; C6D3801C1F71D76700621378 /* RAMBundleRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D380191F71D75B00621378 /* RAMBundleRegistry.cpp */; }; - C6D3801D1F71D76800621378 /* RAMBundleRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D380191F71D75B00621378 /* RAMBundleRegistry.cpp */; }; CF2731C01E7B8DE40044CA4F /* RCTDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CF2731BE1E7B8DE40044CA4F /* RCTDeviceInfo.h */; }; CF2731C11E7B8DE40044CA4F /* RCTDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2731BF1E7B8DE40044CA4F /* RCTDeviceInfo.m */; }; - CF2731C21E7B8DEF0044CA4F /* RCTDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CF2731BE1E7B8DE40044CA4F /* RCTDeviceInfo.h */; }; - CF2731C31E7B8DF30044CA4F /* RCTDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2731BF1E7B8DE40044CA4F /* RCTDeviceInfo.m */; }; D426ACD020D57642003B4C4D /* RCTAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = D426ACCF20D57642003B4C4D /* RCTAppearance.h */; }; D426ACD220D57659003B4C4D /* RCTAppearance.m in Sources */ = {isa = PBXBuildFile; fileRef = D426ACD120D57659003B4C4D /* RCTAppearance.m */; }; D49593DE202C937C00A7694B /* RCTCursorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D49593D8202C937B00A7694B /* RCTCursorManager.h */; }; @@ -1116,12 +584,8 @@ D4EEE3542020933B00C4CBB6 /* UIImageUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = D4EEE2FE201F95F900C4CBB6 /* UIImageUtils.h */; }; EBF21BBC1FC498270052F4D5 /* InspectorInterfaces.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; }; EBF21BBD1FC498270052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; }; - EBF21BBE1FC498630052F4D5 /* InspectorInterfaces.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; }; EBF21BFB1FC498FC0052F4D5 /* InspectorInterfaces.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; }; EBF21BFC1FC4990B0052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; }; - 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 */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1139,34 +603,6 @@ remoteGlobalIDString = 139D7E871E25C6D100323FB7; remoteInfo = "double-conversion"; }; - 3D0574541DE5FF9600184BB4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3D3C059B1DE3340C00C268FA; - remoteInfo = "yoga-tvOS"; - }; - 3D0574561DE5FF9600184BB4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3D3CD9261DE5FBEE00167DC4; - remoteInfo = "cxxreact-tvOS"; - }; - 3D383D631EBD27CE005632C8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3D383D211EBD27B6005632C8; - remoteInfo = "third-party-tvOS"; - }; - 3D383D651EBD27DB005632C8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3D383D3D1EBD27B9005632C8; - remoteInfo = "double-conversion-tvOS"; - }; 3D3CD94B1DE5FCE700167DC4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -1181,13 +617,6 @@ remoteGlobalIDString = 3D3CD8FF1DE5FBD600167DC4; remoteInfo = jschelpers; }; - 3DC159E71E83E2A0007B1282 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3D3CD90C1DE5FBD800167DC4; - remoteInfo = "jschelpers-tvOS"; - }; 53D123981FBF1E0C001B8A10 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -1202,13 +631,6 @@ remoteGlobalIDString = 9936F2F81F5F2E4B0010BF04; remoteInfo = privatedata; }; - 9936F3411F5F30640010BF04 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9936F3141F5F2E5B0010BF04; - remoteInfo = "privatedata-tvOS"; - }; 9936F3431F5F30780010BF04 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -1216,13 +638,6 @@ remoteGlobalIDString = 9936F2F81F5F2E4B0010BF04; remoteInfo = privatedata; }; - 9936F3451F5F30830010BF04 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9936F3141F5F2E5B0010BF04; - remoteInfo = "privatedata-tvOS"; - }; EBF21C011FC499D10052F4D5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -1230,13 +645,6 @@ remoteGlobalIDString = EBF21BBF1FC498900052F4D5; remoteInfo = jsinspector; }; - EBF21C031FC499D80052F4D5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EBF21BDD1FC4989A0052F4D5; - remoteInfo = "jsinspector-tvOS"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -1259,222 +667,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D302E191DF8249100D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/React; - dstSubfolderSpec = 16; - files = ( - 59EDBCC31FDF4E55003573DE /* RCTScrollableProtocol.h in Copy Headers */, - 59EDBCC41FDF4E55003573DE /* RCTScrollContentShadowView.h in Copy Headers */, - 59EDBCC51FDF4E55003573DE /* RCTScrollContentView.h in Copy Headers */, - 59EDBCC61FDF4E55003573DE /* RCTScrollContentViewManager.h in Copy Headers */, - 59EDBCC71FDF4E55003573DE /* RCTScrollView.h in Copy Headers */, - 59EDBCC81FDF4E55003573DE /* RCTScrollViewManager.h in Copy Headers */, - 594F0A411FD233BD007FBE96 /* RCTSurface.h in Copy Headers */, - 594F0A421FD233BD007FBE96 /* RCTSurfaceDelegate.h in Copy Headers */, - 594F0A431FD233BD007FBE96 /* RCTSurfaceRootShadowView.h in Copy Headers */, - 594F0A441FD233BD007FBE96 /* RCTSurfaceRootShadowViewDelegate.h in Copy Headers */, - 594F0A451FD233BD007FBE96 /* RCTSurfaceRootView.h in Copy Headers */, - 594F0A461FD233BD007FBE96 /* RCTSurfaceStage.h in Copy Headers */, - 594F0A471FD233BD007FBE96 /* RCTSurfaceView.h in Copy Headers */, - 594F0A481FD233BD007FBE96 /* RCTSurfaceHostingView.h in Copy Headers */, - 594F0A491FD233BD007FBE96 /* RCTSurfaceSizeMeasureMode.h in Copy Headers */, - 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */, - 59500D481F71C67600B122B7 /* RCTUIManagerUtils.h in Copy Headers */, - 3D0E37901F1CC5E100DCAC9F /* RCTWebSocketModule.h in Copy Headers */, - 5960C1BF1F0804F50066FD5B /* RCTLayoutAnimation.h in Copy Headers */, - 5960C1C01F0804F50066FD5B /* RCTLayoutAnimationGroup.h in Copy Headers */, - 59EB6DC01EBD70130072A5E7 /* RCTUIManagerObserverCoordinator.h in Copy Headers */, - 59B1EBCA1EBD47520047B19B /* RCTShadowView+Layout.h in Copy Headers */, - 3D0B84271EC0B45400B2BD8E /* RCTLinkingManager.h in Copy Headers */, - 3D0B84251EC0B42600B2BD8E /* RCTNetworking.h in Copy Headers */, - 3D0B84261EC0B42600B2BD8E /* RCTNetworkTask.h in Copy Headers */, - 3D0B84231EC0B40D00B2BD8E /* RCTImageLoader.h in Copy Headers */, - 3D0B84241EC0B40D00B2BD8E /* RCTImageStoreManager.h in Copy Headers */, - 3D0B84221EC0B3F600B2BD8E /* RCTResizeMode.h in Copy Headers */, - 3D383D201EBD27AF005632C8 /* RCTBridge+Private.h in Copy Headers */, - 3D7BFD351EA8E43F008DFB7A /* RCTDevSettings.h in Copy Headers */, - 3D7BFD331EA8E433008DFB7A /* RCTPackagerClient.h in Copy Headers */, - 3DA981E91E5B0F7F004F2374 /* RCTJSCSamplingProfiler.h in Copy Headers */, - 3DA981EB1E5B0F7F004F2374 /* RCTAlertManager.h in Copy Headers */, - 3DA981EC1E5B0F7F004F2374 /* RCTAppState.h in Copy Headers */, - 3DA981ED1E5B0F7F004F2374 /* RCTAsyncLocalStorage.h in Copy Headers */, - 3DA981EE1E5B0F7F004F2374 /* RCTClipboard.h in Copy Headers */, - 3DA981EF1E5B0F7F004F2374 /* RCTDevLoadingView.h in Copy Headers */, - 3DA981F01E5B0F7F004F2374 /* RCTDevMenu.h in Copy Headers */, - 3DA981F11E5B0F7F004F2374 /* RCTEventEmitter.h in Copy Headers */, - 3DA981F21E5B0F7F004F2374 /* RCTExceptionsManager.h in Copy Headers */, - 3DA981F31E5B0F7F004F2374 /* RCTI18nManager.h in Copy Headers */, - 3DA981F41E5B0F7F004F2374 /* RCTI18nUtil.h in Copy Headers */, - 3DA981F61E5B0F7F004F2374 /* RCTRedBox.h in Copy Headers */, - 3DA981F71E5B0F7F004F2374 /* RCTSourceCode.h in Copy Headers */, - 3DA981F91E5B0F7F004F2374 /* RCTTiming.h in Copy Headers */, - 3DA981FA1E5B0F7F004F2374 /* RCTUIManager.h in Copy Headers */, - 3DA981FB1E5B0F7F004F2374 /* RCTFPSGraph.h in Copy Headers */, - 3DA981FD1E5B0F7F004F2374 /* RCTMacros.h in Copy Headers */, - 3DA981FE1E5B0F7F004F2374 /* RCTProfile.h in Copy Headers */, - 3DA981FF1E5B0F7F004F2374 /* RCTActivityIndicatorView.h in Copy Headers */, - 3DA982001E5B0F7F004F2374 /* RCTActivityIndicatorViewManager.h in Copy Headers */, - 3DA982011E5B0F7F004F2374 /* RCTAnimationType.h in Copy Headers */, - 3DA982021E5B0F7F004F2374 /* RCTAutoInsetsProtocol.h in Copy Headers */, - 3DA982031E5B0F7F004F2374 /* RCTBorderDrawing.h in Copy Headers */, - 3DA982041E5B0F7F004F2374 /* RCTBorderStyle.h in Copy Headers */, - 3DA982051E5B0F7F004F2374 /* RCTComponent.h in Copy Headers */, - 3DA982061E5B0F7F004F2374 /* RCTComponentData.h in Copy Headers */, - 3DA982071E5B0F7F004F2374 /* RCTConvert+CoreLocation.h in Copy Headers */, - 3DA9820A1E5B0F7F004F2374 /* RCTDatePicker.h in Copy Headers */, - 3DA9820B1E5B0F7F004F2374 /* RCTDatePickerManager.h in Copy Headers */, - 3DA9820C1E5B0F7F004F2374 /* RCTFont.h in Copy Headers */, - 3DA982111E5B0F7F004F2374 /* RCTModalHostView.h in Copy Headers */, - 3DA982121E5B0F7F004F2374 /* RCTModalHostViewController.h in Copy Headers */, - 3DA982131E5B0F7F004F2374 /* RCTModalHostViewManager.h in Copy Headers */, - 3DA982181E5B0F7F004F2374 /* RCTPicker.h in Copy Headers */, - 3DA982191E5B0F7F004F2374 /* RCTPickerManager.h in Copy Headers */, - 3DA9821A1E5B0F7F004F2374 /* RCTPointerEvents.h in Copy Headers */, - 3DA9821B1E5B0F7F004F2374 /* RCTProgressViewManager.h in Copy Headers */, - 3DA9821E1E5B0F7F004F2374 /* RCTRootShadowView.h in Copy Headers */, - 3DA982241E5B0F7F004F2374 /* RCTSegmentedControl.h in Copy Headers */, - 3DA982251E5B0F7F004F2374 /* RCTSegmentedControlManager.h in Copy Headers */, - 3DA982261E5B0F7F004F2374 /* RCTShadowView.h in Copy Headers */, - 3DA982271E5B0F7F004F2374 /* RCTSlider.h in Copy Headers */, - 3DA982281E5B0F7F004F2374 /* RCTSliderManager.h in Copy Headers */, - 3DA982291E5B0F7F004F2374 /* RCTSwitch.h in Copy Headers */, - 3DA9822A1E5B0F7F004F2374 /* RCTSwitchManager.h in Copy Headers */, - 3DA9822F1E5B0F7F004F2374 /* RCTTextDecorationLineType.h in Copy Headers */, - 3DA982311E5B0F7F004F2374 /* RCTView.h in Copy Headers */, - 3DA982321E5B0F7F004F2374 /* RCTViewControllerProtocol.h in Copy Headers */, - 3DA982331E5B0F7F004F2374 /* RCTViewManager.h in Copy Headers */, - 3DA982341E5B0F7F004F2374 /* RCTWebView.h in Copy Headers */, - 3DA982351E5B0F7F004F2374 /* RCTWebViewManager.h in Copy Headers */, - 3DA982381E5B0F7F004F2374 /* NSView+React.h in Copy Headers */, - 3DA981BF1E5B0F29004F2374 /* RCTAssert.h in Copy Headers */, - 3DA981C01E5B0F29004F2374 /* RCTBridge.h in Copy Headers */, - 3DA981C21E5B0F29004F2374 /* RCTBridgeDelegate.h in Copy Headers */, - 3DA981C31E5B0F29004F2374 /* RCTBridgeMethod.h in Copy Headers */, - 3DA981C41E5B0F29004F2374 /* RCTBridgeModule.h in Copy Headers */, - 3DA981C51E5B0F29004F2374 /* RCTBundleURLProvider.h in Copy Headers */, - 3DA981C61E5B0F29004F2374 /* RCTConvert.h in Copy Headers */, - 3DA981C71E5B0F29004F2374 /* RCTDefines.h in Copy Headers */, - 3DA981C81E5B0F29004F2374 /* RCTDisplayLink.h in Copy Headers */, - 3DA981C91E5B0F29004F2374 /* RCTErrorCustomizer.h in Copy Headers */, - 3DA981CA1E5B0F29004F2374 /* RCTErrorInfo.h in Copy Headers */, - 3DA981CB1E5B0F29004F2374 /* RCTEventDispatcher.h in Copy Headers */, - 3DA981CC1E5B0F29004F2374 /* RCTFrameUpdate.h in Copy Headers */, - 3DA981CD1E5B0F29004F2374 /* RCTImageSource.h in Copy Headers */, - 3DA981CE1E5B0F29004F2374 /* RCTInvalidating.h in Copy Headers */, - 3DA981CF1E5B0F29004F2374 /* RCTJavaScriptExecutor.h in Copy Headers */, - 3DA981D01E5B0F29004F2374 /* RCTJavaScriptLoader.h in Copy Headers */, - 3DA981D11E5B0F29004F2374 /* RCTJSStackFrame.h in Copy Headers */, - 3DA981D21E5B0F29004F2374 /* RCTKeyCommands.h in Copy Headers */, - 3DA981D31E5B0F29004F2374 /* RCTLog.h in Copy Headers */, - 3DA981D41E5B0F29004F2374 /* RCTModuleData.h in Copy Headers */, - 3DA981D51E5B0F29004F2374 /* RCTModuleMethod.h in Copy Headers */, - 3DA981D61E5B0F29004F2374 /* RCTMultipartDataTask.h in Copy Headers */, - 3DA981D71E5B0F29004F2374 /* RCTMultipartStreamReader.h in Copy Headers */, - 3DA981D81E5B0F29004F2374 /* RCTNullability.h in Copy Headers */, - 3DA981D91E5B0F29004F2374 /* RCTParserUtils.h in Copy Headers */, - 3DA981DA1E5B0F29004F2374 /* RCTPerformanceLogger.h in Copy Headers */, - 3DA981DB1E5B0F29004F2374 /* RCTPlatform.h in Copy Headers */, - 3DA981DC1E5B0F29004F2374 /* RCTReloadCommand.h in Copy Headers */, - 3DA981DD1E5B0F29004F2374 /* RCTRootContentView.h in Copy Headers */, - 3DA981DE1E5B0F29004F2374 /* RCTRootView.h in Copy Headers */, - 3DA981DF1E5B0F29004F2374 /* RCTRootViewDelegate.h in Copy Headers */, - 3DA981E11E5B0F29004F2374 /* RCTTouchEvent.h in Copy Headers */, - 3DA981E21E5B0F29004F2374 /* RCTTouchHandler.h in Copy Headers */, - 3DA981E31E5B0F29004F2374 /* RCTURLRequestDelegate.h in Copy Headers */, - 3DA981E41E5B0F29004F2374 /* RCTURLRequestHandler.h in Copy Headers */, - 3DA981E51E5B0F29004F2374 /* RCTUtils.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; - 3D302F171DF825FE00D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/yoga; - dstSubfolderSpec = 16; - files = ( - 3DFE0D1A1DF8575800459392 /* YGEnums.h in Copy Headers */, - 3DFE0D1B1DF8575800459392 /* YGMacros.h in Copy Headers */, - 3DFE0D1C1DF8575800459392 /* Yoga.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; - 3D302F1B1DF8263300D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/cxxreact; - dstSubfolderSpec = 16; - files = ( - 598FD1921F816A2A006C54CB /* RAMBundleRegistry.h in Copy Headers */, - 3DA9823B1E5B1053004F2374 /* CxxModule.h in Copy Headers */, - 3DA9823C1E5B1053004F2374 /* CxxNativeModule.h in Copy Headers */, - 3DA9823D1E5B1053004F2374 /* JSExecutor.h in Copy Headers */, - 3DA982401E5B1053004F2374 /* Instance.h in Copy Headers */, - 3DA982411E5B1053004F2374 /* JsArgumentHelpers-inl.h in Copy Headers */, - 3DA982421E5B1053004F2374 /* JsArgumentHelpers.h in Copy Headers */, - 3DA982431E5B1053004F2374 /* JSBigString.h in Copy Headers */, - 3DA982441E5B1053004F2374 /* JSBundleType.h in Copy Headers */, - 3DA982451E5B1053004F2374 /* JSCExecutor.h in Copy Headers */, - 3DA982471E5B1053004F2374 /* JSCLegacyTracing.h in Copy Headers */, - 3DA982481E5B1053004F2374 /* JSCMemory.h in Copy Headers */, - 3DA982491E5B1053004F2374 /* JSCNativeModules.h in Copy Headers */, - 3DA9824A1E5B1053004F2374 /* JSCPerfStats.h in Copy Headers */, - 3DA9824B1E5B1053004F2374 /* JSCSamplingProfiler.h in Copy Headers */, - 3DA9824C1E5B1053004F2374 /* JSCUtils.h in Copy Headers */, - 3DA9824E1E5B1053004F2374 /* JSIndexedRAMBundle.h in Copy Headers */, - 3DA9824F1E5B1053004F2374 /* JSModulesUnbundle.h in Copy Headers */, - 3DA982501E5B1053004F2374 /* MessageQueueThread.h in Copy Headers */, - 3DA982511E5B1053004F2374 /* MethodCall.h in Copy Headers */, - 3DA982521E5B1053004F2374 /* ModuleRegistry.h in Copy Headers */, - 3DA982531E5B1053004F2374 /* NativeModule.h in Copy Headers */, - 3DA982541E5B1053004F2374 /* NativeToJsBridge.h in Copy Headers */, - 3DA982551E5B1053004F2374 /* oss-compat-util.h in Copy Headers */, - 3DA982561E5B1053004F2374 /* Platform.h in Copy Headers */, - 3DA982571E5B1053004F2374 /* RecoverableError.h in Copy Headers */, - 3DA982581E5B1053004F2374 /* SampleCxxModule.h in Copy Headers */, - 3DA982591E5B1053004F2374 /* SystraceSection.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; - 3D302F1D1DF8264A00D6DDAE /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/jschelpers; - dstSubfolderSpec = 16; - files = ( - 3DA982601E5B1089004F2374 /* JSCHelpers.h in Copy Headers */, - 3DA982611E5B1089004F2374 /* noncopyable.h in Copy Headers */, - 3DA982621E5B1089004F2374 /* Unicode.h in Copy Headers */, - 3DA982631E5B1089004F2374 /* Value.h in Copy Headers */, - 3D302F1E1DF8265A00D6DDAE /* JavaScriptCore.h in Copy Headers */, - 3D302F1F1DF8265A00D6DDAE /* JSCWrapper.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; - 3D383D491EBD27B9005632C8 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - 3D383D4A1EBD27B9005632C8 /* bignum-dtoa.h in CopyFiles */, - 3D383D4B1EBD27B9005632C8 /* bignum.h in CopyFiles */, - 3D383D4C1EBD27B9005632C8 /* cached-powers.h in CopyFiles */, - 3D383D4D1EBD27B9005632C8 /* diy-fp.h in CopyFiles */, - 3D383D4E1EBD27B9005632C8 /* double-conversion.h in CopyFiles */, - 3D383D4F1EBD27B9005632C8 /* fast-dtoa.h in CopyFiles */, - 3D383D501EBD27B9005632C8 /* fixed-dtoa.h in CopyFiles */, - 3D383D511EBD27B9005632C8 /* ieee.h in CopyFiles */, - 3D383D521EBD27B9005632C8 /* strtod.h in CopyFiles */, - 3D383D531EBD27B9005632C8 /* utils.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3D80D91E1DF6FA530028D040 /* Copy Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -1686,17 +878,6 @@ name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; }; - 9936F31E1F5F2E5B0010BF04 /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/privatedata; - dstSubfolderSpec = 16; - files = ( - 9936F33A1F5F2F7C0010BF04 /* PrivateDataBase.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; EBF21BCB1FC498900052F4D5 /* Copy Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -1708,17 +889,6 @@ name = "Copy Headers"; runOnlyForDeploymentPostprocessing = 0; }; - EBF21BE91FC4989A0052F4D5 /* Copy Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = include/jsinspector; - dstSubfolderSpec = 16; - files = ( - EBF21BFE1FC499840052F4D5 /* InspectorInterfaces.h in Copy Headers */, - ); - name = "Copy Headers"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -1912,7 +1082,6 @@ 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVersion.h; sourceTree = ""; }; 19DED2281E77E29200F089BB /* systemJSCWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = systemJSCWrapper.cpp; sourceTree = ""; }; 27B958731E57587D0096647A /* JSBigString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBigString.cpp; sourceTree = ""; }; - 2D2A28131D9B038B00D4039D /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 352DCFEE1D19F4C20056D623 /* RCTI18nUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTI18nUtil.h; sourceTree = ""; }; 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTI18nUtil.m; sourceTree = ""; }; 369123DF1DDC75850095B341 /* RCTJSCSamplingProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSCSamplingProfiler.h; sourceTree = ""; }; @@ -1936,15 +1105,10 @@ 3D1FA08D1DE4F4EE00E03CC6 /* RCTPushNotificationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTPushNotificationManager.h; path = PushNotificationIOS/RCTPushNotificationManager.h; sourceTree = ""; }; 3D37B5801D522B190042D5B5 /* RCTFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTFont.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 3D37B5811D522B190042D5B5 /* RCTFont.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTFont.mm; sourceTree = ""; }; - 3D383D3C1EBD27B6005632C8 /* libthird-party.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libthird-party.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libdouble-conversion.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3D3C059A1DE3340900C268FA /* libyoga.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libyoga.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3D3C06751DE3340C00C268FA /* libyoga.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libyoga.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3D3CD8F51DE5FB2300167DC4 /* JSBundleType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBundleType.h; sourceTree = ""; }; 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjschelpers.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjschelpers.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3D3CD9251DE5FBEC00167DC4 /* libcxxreact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcxxreact.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3D3CD9321DE5FBEE00167DC4 /* libcxxreact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcxxreact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3D7454781E54757500E74ADD /* JSBigString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBigString.h; sourceTree = ""; }; 3D7454791E54757500E74ADD /* RecoverableError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecoverableError.h; sourceTree = ""; }; 3D7454B31E54786200E74ADD /* NSDataBigString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSDataBigString.h; sourceTree = ""; }; @@ -2118,7 +1282,6 @@ 91076A871F743AB00081B4FA /* RCTModalManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTModalManager.m; sourceTree = ""; }; 91076A881F743AB00081B4FA /* RCTModalManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTModalManager.h; sourceTree = ""; }; 9936F3131F5F2E4B0010BF04 /* libprivatedata.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libprivatedata.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libprivatedata-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrivateDataBase.cpp; path = privatedata/PrivateDataBase.cpp; sourceTree = ""; }; 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrivateDataBase.h; path = privatedata/PrivateDataBase.h; sourceTree = ""; }; A2440AA01DF8D854006E7BFC /* RCTReloadCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTReloadCommand.h; sourceTree = ""; }; @@ -2160,7 +1323,6 @@ EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInterfaces.h; sourceTree = ""; }; 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; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2176,19 +1338,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D3C088B1DE342FE00C268FA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */, - 2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */, - 3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */, - 3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */, - 3D8ED92C1E5B120100D83D20 /* libcxxreact.a in Frameworks */, - 3D8ED92D1E5B120100D83D20 /* libyoga.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -2714,21 +1863,13 @@ isa = PBXGroup; children = ( 83CBBA2E1A601D0E00E9B192 /* libReact.a */, - 2D2A28131D9B038B00D4039D /* libReact.a */, 3D3C059A1DE3340900C268FA /* libyoga.a */, - 3D3C06751DE3340C00C268FA /* libyoga.a */, 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */, - 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */, 3D3CD9251DE5FBEC00167DC4 /* libcxxreact.a */, - 3D3CD9321DE5FBEE00167DC4 /* libcxxreact.a */, 139D7E881E25C6D100323FB7 /* libdouble-conversion.a */, 139D7ECE1E25DB7D00323FB7 /* libthird-party.a */, - 3D383D3C1EBD27B6005632C8 /* libthird-party.a */, - 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */, 9936F3131F5F2E4B0010BF04 /* libprivatedata.a */, - 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */, EBF21BDC1FC498900052F4D5 /* libjsinspector.a */, - EBF21BFA1FC4989A0052F4D5 /* libjsinspector-tvOS.a */, ); name = Products; sourceTree = ""; @@ -2929,238 +2070,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D302F231DF828D100D6DDAE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DA982391E5B0F8A004F2374 /* NSView+Private.h in Headers */, - 13134C8D1E296B2A00B9F3CB /* RCTMessageThread.h in Headers */, - 598FD1941F8172A9006C54CB /* PrivateDataBase.h in Headers */, - 3D7AA9C51E548CDB001955CF /* NSDataBigString.h in Headers */, - 5960C1BA1F0804A00066FD5B /* RCTLayoutAnimationGroup.h in Headers */, - 13134C991E296B2A00B9F3CB /* RCTCxxMethod.h in Headers */, - 3D0E378D1F1CC58F00DCAC9F /* RCTWebSocketObserver.h in Headers */, - 3D302F471DF828F800D6DDAE /* RCTPlatform.h in Headers */, - 13134C951E296B2A00B9F3CB /* RCTObjcExecutor.h in Headers */, - 590D7BFE1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */, - 13134C9D1E296B2A00B9F3CB /* RCTCxxModule.h in Headers */, - 66CD94B61F1045E700CB3C7C /* RCTMaskedViewManager.h in Headers */, - 130443A31E3FEAAE00D93A67 /* RCTFollyConvert.h in Headers */, - 3D7BFD1E1EA8E351008DFB7A /* RCTPackagerConnection.h in Headers */, - 3D302F241DF828F800D6DDAE /* RCTImageLoader.h in Headers */, - 3D302F251DF828F800D6DDAE /* RCTImageStoreManager.h in Headers */, - C60128AC1F3D1258009DF9FF /* RCTCxxConvert.h in Headers */, - 3D302F261DF828F800D6DDAE /* RCTResizeMode.h in Headers */, - 3D302F271DF828F800D6DDAE /* RCTLinkingManager.h in Headers */, - 3D7BFD161EA8E351008DFB7A /* RCTPackagerClient.h in Headers */, - 3D302F281DF828F800D6DDAE /* RCTNetworking.h in Headers */, - 3D302F291DF828F800D6DDAE /* RCTNetworkTask.h in Headers */, - 3D7BFD2E1EA8E3FA008DFB7A /* RCTReconnectingWebSocket.h in Headers */, - 3D302F2A1DF828F800D6DDAE /* RCTPushNotificationManager.h in Headers */, - 3D302F2B1DF828F800D6DDAE /* RCTAssert.h in Headers */, - 3D302F2C1DF828F800D6DDAE /* RCTBridge.h in Headers */, - 3D302F2D1DF828F800D6DDAE /* RCTBridge+Private.h in Headers */, - 3D302F2E1DF828F800D6DDAE /* RCTBridgeDelegate.h in Headers */, - 3D302F2F1DF828F800D6DDAE /* RCTBridgeMethod.h in Headers */, - 130E3D8A1E6A083600ACE484 /* RCTDevSettings.h in Headers */, - 3D0E378E1F1CC59100DCAC9F /* RCTWebSocketModule.h in Headers */, - 3D302F301DF828F800D6DDAE /* RCTBridgeModule.h in Headers */, - 3D302F311DF828F800D6DDAE /* RCTBundleURLProvider.h in Headers */, - 3D302F321DF828F800D6DDAE /* RCTConvert.h in Headers */, - 3D302F331DF828F800D6DDAE /* RCTDefines.h in Headers */, - 3D0B842F1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h in Headers */, - 3D302F341DF828F800D6DDAE /* RCTDisplayLink.h in Headers */, - 3D302F351DF828F800D6DDAE /* RCTErrorCustomizer.h in Headers */, - 3D302F361DF828F800D6DDAE /* RCTErrorInfo.h in Headers */, - 3D302F371DF828F800D6DDAE /* RCTEventDispatcher.h in Headers */, - 59EDBCAA1FDF4E0C003573DE /* RCTScrollContentShadowView.h in Headers */, - 594F0A371FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h in Headers */, - 3D302F381DF828F800D6DDAE /* RCTFrameUpdate.h in Headers */, - 3D302F391DF828F800D6DDAE /* RCTImageSource.h in Headers */, - 597633391F4E021D005BE8A4 /* RCTShadowView+Internal.h in Headers */, - 3D302F3A1DF828F800D6DDAE /* RCTInvalidating.h in Headers */, - 3D302F3B1DF828F800D6DDAE /* RCTJavaScriptExecutor.h in Headers */, - 3D302F3C1DF828F800D6DDAE /* RCTJavaScriptLoader.h in Headers */, - 3D302F3D1DF828F800D6DDAE /* RCTJSStackFrame.h in Headers */, - 599FAA491FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */, - 59EDBCB61FDF4E0C003573DE /* RCTScrollView.h in Headers */, - 3D302F3E1DF828F800D6DDAE /* RCTKeyCommands.h in Headers */, - 135A9C031E7B0F6100587AEB /* RCTJSCErrorHandling.h in Headers */, - 599FAA411FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */, - 3D302F3F1DF828F800D6DDAE /* RCTLog.h in Headers */, - 599FAA431FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */, - 3D302F401DF828F800D6DDAE /* RCTModuleData.h in Headers */, - 5960C1B61F0804A00066FD5B /* RCTLayoutAnimation.h in Headers */, - 3D302F411DF828F800D6DDAE /* RCTModuleMethod.h in Headers */, - 3D302F421DF828F800D6DDAE /* RCTMultipartDataTask.h in Headers */, - 3D302F431DF828F800D6DDAE /* RCTMultipartStreamReader.h in Headers */, - 199B8A761F44DEDA005DEF67 /* RCTVersion.h in Headers */, - 3D302F441DF828F800D6DDAE /* RCTNullability.h in Headers */, - 3D302F451DF828F800D6DDAE /* RCTParserUtils.h in Headers */, - 3D302F461DF828F800D6DDAE /* RCTPerformanceLogger.h in Headers */, - 3D302F481DF828F800D6DDAE /* RCTRootView.h in Headers */, - 3D302F491DF828F800D6DDAE /* RCTRootViewDelegate.h in Headers */, - 3D302F4A1DF828F800D6DDAE /* RCTRootViewInternal.h in Headers */, - 59EDBCB21FDF4E0C003573DE /* RCTScrollContentViewManager.h in Headers */, - 3D302F4B1DF828F800D6DDAE /* RCTTouchEvent.h in Headers */, - 3D302F4C1DF828F800D6DDAE /* RCTTouchHandler.h in Headers */, - 3D302F4D1DF828F800D6DDAE /* RCTURLRequestDelegate.h in Headers */, - 3D302F4E1DF828F800D6DDAE /* RCTURLRequestHandler.h in Headers */, - 59500D441F71C63F00B122B7 /* RCTUIManagerUtils.h in Headers */, - 3D302F4F1DF828F800D6DDAE /* RCTUtils.h in Headers */, - 3D302F541DF828F800D6DDAE /* RCTJSCSamplingProfiler.h in Headers */, - 3D302F561DF828F800D6DDAE /* RCTAlertManager.h in Headers */, - 3D302F571DF828F800D6DDAE /* RCTAppState.h in Headers */, - 3D302F581DF828F800D6DDAE /* RCTAsyncLocalStorage.h in Headers */, - 3D302F591DF828F800D6DDAE /* RCTClipboard.h in Headers */, - 3D302F5A1DF828F800D6DDAE /* RCTDevLoadingView.h in Headers */, - 59EDBCBA1FDF4E0C003573DE /* RCTScrollViewManager.h in Headers */, - 3D0B842A1EC0B49400B2BD8E /* RCTTVRemoteHandler.h in Headers */, - 3D302F5B1DF828F800D6DDAE /* RCTDevMenu.h in Headers */, - 657734921EE8356100A0E9EA /* RCTInspector.h in Headers */, - 3D302F5C1DF828F800D6DDAE /* RCTEventEmitter.h in Headers */, - 3D302F5D1DF828F800D6DDAE /* RCTExceptionsManager.h in Headers */, - 599FAA4B1FB274980058CCF6 /* RCTSurfaceView.h in Headers */, - 599FAA3D1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */, - 3D302F5E1DF828F800D6DDAE /* RCTI18nManager.h in Headers */, - 3D302F5F1DF828F800D6DDAE /* RCTI18nUtil.h in Headers */, - 3D302F611DF828F800D6DDAE /* RCTRedBox.h in Headers */, - 3D302F621DF828F800D6DDAE /* RCTSourceCode.h in Headers */, - 3D302F641DF828F800D6DDAE /* RCTTiming.h in Headers */, - 3D302F651DF828F800D6DDAE /* RCTUIManager.h in Headers */, - 599FAA3B1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */, - 3D302F661DF828F800D6DDAE /* RCTFPSGraph.h in Headers */, - 3D302F681DF828F800D6DDAE /* RCTMacros.h in Headers */, - 3D302F691DF828F800D6DDAE /* RCTProfile.h in Headers */, - 3DF1BE841F26577000068F1A /* JSCTracing.h in Headers */, - 3D302F6A1DF828F800D6DDAE /* RCTActivityIndicatorView.h in Headers */, - 3D302F6B1DF828F800D6DDAE /* RCTActivityIndicatorViewManager.h in Headers */, - 3D7BFD301EA8E3FA008DFB7A /* RCTSRWebSocket.h in Headers */, - 59EDBCA81FDF4E0C003573DE /* RCTScrollableProtocol.h in Headers */, - 3D302F6C1DF828F800D6DDAE /* RCTAnimationType.h in Headers */, - 598FD1951F817335006C54CB /* RCTModalManager.h in Headers */, - 657734871EE834E000A0E9EA /* RCTInspectorDevServerHelper.h in Headers */, - 3D302F6D1DF828F800D6DDAE /* RCTAutoInsetsProtocol.h in Headers */, - 3D302F6E1DF828F800D6DDAE /* RCTBorderDrawing.h in Headers */, - 3D302F6F1DF828F800D6DDAE /* RCTBorderStyle.h in Headers */, - 3D302F701DF828F800D6DDAE /* RCTComponent.h in Headers */, - 3D302F711DF828F800D6DDAE /* RCTComponentData.h in Headers */, - 3D302F721DF828F800D6DDAE /* RCTConvert+CoreLocation.h in Headers */, - 3D302F761DF828F800D6DDAE /* RCTFont.h in Headers */, - 3D302F7B1DF828F800D6DDAE /* RCTModalHostView.h in Headers */, - 1384E20A1E806D5700545659 /* RCTNativeModule.h in Headers */, - 3D302F7C1DF828F800D6DDAE /* RCTModalHostViewController.h in Headers */, - 3D302F7D1DF828F800D6DDAE /* RCTModalHostViewManager.h in Headers */, - 594F0A331FD23228007FBE96 /* RCTSurfaceHostingView.h in Headers */, - 130443DD1E401AF500D93A67 /* RCTConvert+Transform.h in Headers */, - 134D63C41F1FEC65008872B5 /* RCTCxxBridgeDelegate.h in Headers */, - 135A9C061E7B0F7800587AEB /* RCTJSCHelpers.h in Headers */, - 3D302F841DF828F800D6DDAE /* RCTPointerEvents.h in Headers */, - 59EB6DBC1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h in Headers */, - 657734941EE8356100A0E9EA /* RCTInspectorPackagerConnection.h in Headers */, - 3D302F851DF828F800D6DDAE /* RCTProgressViewManager.h in Headers */, - EBF21BBE1FC498630052F4D5 /* InspectorInterfaces.h in Headers */, - C654505F1F3BD9280090799B /* RCTManagedPointer.h in Headers */, - A2440AA41DF8D865006E7BFC /* RCTReloadCommand.h in Headers */, - 3D302F881DF828F800D6DDAE /* RCTRootShadowView.h in Headers */, - CF2731C21E7B8DEF0044CA4F /* RCTDeviceInfo.h in Headers */, - 599FAA371FB274980058CCF6 /* RCTSurface.h in Headers */, - 3D302F8C1DF828F800D6DDAE /* RCTSegmentedControl.h in Headers */, - 66CD94B21F1045E700CB3C7C /* RCTMaskedView.h in Headers */, - 3D302F8D1DF828F800D6DDAE /* RCTSegmentedControlManager.h in Headers */, - 3D302F8E1DF828F800D6DDAE /* RCTShadowView.h in Headers */, - 3D302F8F1DF828F800D6DDAE /* RCTSlider.h in Headers */, - 3D302F901DF828F800D6DDAE /* RCTSliderManager.h in Headers */, - 3D302F911DF828F800D6DDAE /* RCTSwitch.h in Headers */, - 3D302F921DF828F800D6DDAE /* RCTSwitchManager.h in Headers */, - 59EDBCAE1FDF4E0C003573DE /* RCTScrollContentView.h in Headers */, - 3D302F971DF828F800D6DDAE /* RCTTextDecorationLineType.h in Headers */, - 3D302F981DF828F800D6DDAE /* RCTView.h in Headers */, - 3D302F991DF828F800D6DDAE /* RCTViewControllerProtocol.h in Headers */, - 3D302F9A1DF828F800D6DDAE /* RCTViewManager.h in Headers */, - 3D302F9F1DF828F800D6DDAE /* NSView+React.h in Headers */, - 599FAA471FB274980058CCF6 /* RCTSurfaceStage.h in Headers */, - 13134CA11E296B2A00B9F3CB /* RCTCxxUtils.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D30301C1DF8292200D6DDAE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 53D1239F1FBF1EFB001B8A10 /* Yoga-internal.h in Headers */, - 3DFE0D161DF8574D00459392 /* YGEnums.h in Headers */, - 3DFE0D171DF8574D00459392 /* YGMacros.h in Headers */, - 5376C5E71FC6DDC20083513D /* YGNodePrint.h in Headers */, - 3DFE0D191DF8574D00459392 /* Yoga.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D3030211DF8294400D6DDAE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3D74547E1E54759A00E74ADD /* JSModulesUnbundle.h in Headers */, - C6D3801B1F71D76200621378 /* RAMBundleRegistry.h in Headers */, - 27595AD51E575C7800CCE2B1 /* NativeToJsBridge.h in Headers */, - 27595AC41E575C7800CCE2B1 /* Instance.h in Headers */, - 27595AD11E575C7800CCE2B1 /* MessageQueueThread.h in Headers */, - 27595ACE1E575C7800CCE2B1 /* JSCUtils.h in Headers */, - 3D7454811E5475AF00E74ADD /* RecoverableError.h in Headers */, - 27595AC51E575C7800CCE2B1 /* JsArgumentHelpers-inl.h in Headers */, - 27595AC91E575C7800CCE2B1 /* JSCLegacyTracing.h in Headers */, - 27595AD61E575C7800CCE2B1 /* Platform.h in Headers */, - 27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */, - 27595AC61E575C7800CCE2B1 /* JsArgumentHelpers.h in Headers */, - 27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */, - 27595AD21E575C7800CCE2B1 /* MethodCall.h in Headers */, - 3D3030221DF8294C00D6DDAE /* JSBundleType.h in Headers */, - 27595ACA1E575C7800CCE2B1 /* JSCMemory.h in Headers */, - 3D74547D1E54758900E74ADD /* JSBigString.h in Headers */, - 27595AC71E575C7800CCE2B1 /* JSCExecutor.h in Headers */, - 27595ACD1E575C7800CCE2B1 /* JSCSamplingProfiler.h in Headers */, - 27595ABF1E575C7800CCE2B1 /* CxxModule.h in Headers */, - 27595AD41E575C7800CCE2B1 /* NativeModule.h in Headers */, - 27595ACB1E575C7800CCE2B1 /* JSCNativeModules.h in Headers */, - 3D3030231DF8294C00D6DDAE /* oss-compat-util.h in Headers */, - 27595AC01E575C7800CCE2B1 /* CxxNativeModule.h in Headers */, - 27595AD01E575C7800CCE2B1 /* JSIndexedRAMBundle.h in Headers */, - 27595AD31E575C7800CCE2B1 /* ModuleRegistry.h in Headers */, - 27595ACC1E575C7800CCE2B1 /* JSCPerfStats.h in Headers */, - 27595AC11E575C7800CCE2B1 /* JSExecutor.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D3030241DF8295800D6DDAE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 19F61C041E8495FF00571D81 /* JSCHelpers.h in Headers */, - 19F61C051E8495FF00571D81 /* noncopyable.h in Headers */, - 19F61C061E8495FF00571D81 /* Unicode.h in Headers */, - 19F61C071E8495FF00571D81 /* Value.h in Headers */, - 3D3030251DF8295E00D6DDAE /* JavaScriptCore.h in Headers */, - 3D3030261DF8295E00D6DDAE /* JSCWrapper.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D383D541EBD27B9005632C8 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3D383D551EBD27B9005632C8 /* bignum-dtoa.h in Headers */, - 3D383D561EBD27B9005632C8 /* bignum.h in Headers */, - 3D383D571EBD27B9005632C8 /* cached-powers.h in Headers */, - 3D383D581EBD27B9005632C8 /* diy-fp.h in Headers */, - 3D383D591EBD27B9005632C8 /* double-conversion.h in Headers */, - 3D383D5A1EBD27B9005632C8 /* fast-dtoa.h in Headers */, - 3D383D5B1EBD27B9005632C8 /* fixed-dtoa.h in Headers */, - 3D383D5C1EBD27B9005632C8 /* ieee.h in Headers */, - 3D383D5D1EBD27B9005632C8 /* strtod.h in Headers */, - 3D383D5E1EBD27B9005632C8 /* utils.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3D3C04BB1DE3340900C268FA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3404,14 +2313,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9936F3171F5F2E5B0010BF04 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 9936F3391F5F2F5C0010BF04 /* PrivateDataBase.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EBF21BC41FC498900052F4D5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3419,13 +2320,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EBF21BE21FC4989A0052F4D5 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -3463,62 +2357,6 @@ productReference = 139D7ECE1E25DB7D00323FB7 /* libthird-party.a */; productType = "com.apple.product-type.library.static"; }; - 2D2A28121D9B038B00D4039D /* React-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D2A281B1D9B038B00D4039D /* Build configuration list for PBXNativeTarget "React-tvOS" */; - buildPhases = ( - 2D6948301DA3088700B3FA97 /* Start Packager */, - 3D302F231DF828D100D6DDAE /* Headers */, - 3D302E191DF8249100D6DDAE /* Copy Headers */, - 2D2A280F1D9B038B00D4039D /* Sources */, - 2D6948201DA3042200B3FA97 /* Include RCTJSCProfiler */, - 3D3C088B1DE342FE00C268FA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3D0574551DE5FF9600184BB4 /* PBXTargetDependency */, - 3D0574571DE5FF9600184BB4 /* PBXTargetDependency */, - ); - name = "React-tvOS"; - productName = "React-tvOS"; - productReference = 2D2A28131D9B038B00D4039D /* libReact.a */; - productType = "com.apple.product-type.library.static"; - }; - 3D383D211EBD27B6005632C8 /* third-party-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3D383D391EBD27B6005632C8 /* Build configuration list for PBXNativeTarget "third-party-tvOS" */; - buildPhases = ( - 3D383D241EBD27B6005632C8 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - 3D383D661EBD27DB005632C8 /* PBXTargetDependency */, - ); - name = "third-party-tvOS"; - productName = "third-party"; - productReference = 3D383D3C1EBD27B6005632C8 /* libthird-party.a */; - productType = "com.apple.product-type.library.static"; - }; - 3D383D3D1EBD27B9005632C8 /* double-conversion-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3D383D5F1EBD27B9005632C8 /* Build configuration list for PBXNativeTarget "double-conversion-tvOS" */; - buildPhases = ( - 3D383D3E1EBD27B9005632C8 /* Install Third Party */, - 3D383D541EBD27B9005632C8 /* Headers */, - 3D383D3F1EBD27B9005632C8 /* Sources */, - 3D383D491EBD27B9005632C8 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "double-conversion-tvOS"; - productName = ThirdParty; - productReference = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; - productType = "com.apple.product-type.library.static"; - }; 3D3C04B91DE3340900C268FA /* yoga */ = { isa = PBXNativeTarget; buildConfigurationList = 3D3C05971DE3340900C268FA /* Build configuration list for PBXNativeTarget "yoga" */; @@ -3536,23 +2374,6 @@ productReference = 3D3C059A1DE3340900C268FA /* libyoga.a */; productType = "com.apple.product-type.library.static"; }; - 3D3C059B1DE3340C00C268FA /* yoga-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3D3C06721DE3340C00C268FA /* Build configuration list for PBXNativeTarget "yoga-tvOS" */; - buildPhases = ( - 3D30301C1DF8292200D6DDAE /* Headers */, - 3D302F171DF825FE00D6DDAE /* Copy Headers */, - 3D3C06181DE3340C00C268FA /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "yoga-tvOS"; - productName = "React-tvOS"; - productReference = 3D3C06751DE3340C00C268FA /* libyoga.a */; - productType = "com.apple.product-type.library.static"; - }; 3D3CD8FF1DE5FBD600167DC4 /* jschelpers */ = { isa = PBXNativeTarget; buildConfigurationList = 3D3CD9081DE5FBD600167DC4 /* Build configuration list for PBXNativeTarget "jschelpers" */; @@ -3572,25 +2393,6 @@ productReference = 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */; productType = "com.apple.product-type.library.static"; }; - 3D3CD90C1DE5FBD800167DC4 /* jschelpers-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3D3CD9151DE5FBD800167DC4 /* Build configuration list for PBXNativeTarget "jschelpers-tvOS" */; - buildPhases = ( - 3D3030241DF8295800D6DDAE /* Headers */, - 3D302F1D1DF8264A00D6DDAE /* Copy Headers */, - 3D3CD9121DE5FBD800167DC4 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - 9936F3461F5F30830010BF04 /* PBXTargetDependency */, - 3D383D641EBD27CE005632C8 /* PBXTargetDependency */, - ); - name = "jschelpers-tvOS"; - productName = "React-tvOS"; - productReference = 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */; - productType = "com.apple.product-type.library.static"; - }; 3D3CD9191DE5FBEC00167DC4 /* cxxreact */ = { isa = PBXNativeTarget; buildConfigurationList = 3D3CD9221DE5FBEC00167DC4 /* Build configuration list for PBXNativeTarget "cxxreact" */; @@ -3611,26 +2413,6 @@ productReference = 3D3CD9251DE5FBEC00167DC4 /* libcxxreact.a */; productType = "com.apple.product-type.library.static"; }; - 3D3CD9261DE5FBEE00167DC4 /* cxxreact-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3D3CD92F1DE5FBEE00167DC4 /* Build configuration list for PBXNativeTarget "cxxreact-tvOS" */; - buildPhases = ( - 3D3030211DF8294400D6DDAE /* Headers */, - 3D302F1B1DF8263300D6DDAE /* Copy Headers */, - 3D3CD92C1DE5FBEE00167DC4 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - EBF21C041FC499D80052F4D5 /* PBXTargetDependency */, - 9936F3421F5F30640010BF04 /* PBXTargetDependency */, - 3DC159E81E83E2A0007B1282 /* PBXTargetDependency */, - ); - name = "cxxreact-tvOS"; - productName = "React-tvOS"; - productReference = 3D3CD9321DE5FBEE00167DC4 /* libcxxreact.a */; - productType = "com.apple.product-type.library.static"; - }; 83CBBA2D1A601D0E00E9B192 /* React */ = { isa = PBXNativeTarget; buildConfigurationList = 83CBBA3F1A601D0F00E9B192 /* Build configuration list for PBXNativeTarget "React" */; @@ -3670,23 +2452,6 @@ productReference = 9936F3131F5F2E4B0010BF04 /* libprivatedata.a */; productType = "com.apple.product-type.library.static"; }; - 9936F3141F5F2E5B0010BF04 /* privatedata-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9936F32C1F5F2E5B0010BF04 /* Build configuration list for PBXNativeTarget "privatedata-tvOS" */; - buildPhases = ( - 9936F3171F5F2E5B0010BF04 /* Headers */, - 9936F31E1F5F2E5B0010BF04 /* Copy Headers */, - 9936F3261F5F2E5B0010BF04 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "privatedata-tvOS"; - productName = "React-tvOS"; - productReference = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; EBF21BBF1FC498900052F4D5 /* jsinspector */ = { isa = PBXNativeTarget; buildConfigurationList = EBF21BD91FC498900052F4D5 /* Build configuration list for PBXNativeTarget "jsinspector" */; @@ -3704,23 +2469,6 @@ productReference = EBF21BDC1FC498900052F4D5 /* libjsinspector.a */; productType = "com.apple.product-type.library.static"; }; - EBF21BDD1FC4989A0052F4D5 /* jsinspector-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = EBF21BF71FC4989A0052F4D5 /* Build configuration list for PBXNativeTarget "jsinspector-tvOS" */; - buildPhases = ( - EBF21BE21FC4989A0052F4D5 /* Headers */, - EBF21BE91FC4989A0052F4D5 /* Copy Headers */, - EBF21BF11FC4989A0052F4D5 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "jsinspector-tvOS"; - productName = "React-tvOS"; - productReference = EBF21BFA1FC4989A0052F4D5 /* libjsinspector-tvOS.a */; - productType = "com.apple.product-type.library.static"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -3740,16 +2488,6 @@ DevelopmentTeam = V9WTTPBFK9; ProvisioningStyle = Automatic; }; - 2D2A28121D9B038B00D4039D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; - 3D383D211EBD27B6005632C8 = { - DevelopmentTeam = V9WTTPBFK9; - }; - 3D383D3D1EBD27B9005632C8 = { - DevelopmentTeam = V9WTTPBFK9; - }; 83CBBA2D1A601D0E00E9B192 = { CreatedOnToolsVersion = 6.1.1; }; @@ -3769,21 +2507,13 @@ projectRoot = ""; targets = ( 83CBBA2D1A601D0E00E9B192 /* React */, - 2D2A28121D9B038B00D4039D /* React-tvOS */, 3D3C04B91DE3340900C268FA /* yoga */, - 3D3C059B1DE3340C00C268FA /* yoga-tvOS */, 3D3CD9191DE5FBEC00167DC4 /* cxxreact */, - 3D3CD9261DE5FBEE00167DC4 /* cxxreact-tvOS */, 3D3CD8FF1DE5FBD600167DC4 /* jschelpers */, - 3D3CD90C1DE5FBD800167DC4 /* jschelpers-tvOS */, EBF21BBF1FC498900052F4D5 /* jsinspector */, - EBF21BDD1FC4989A0052F4D5 /* jsinspector-tvOS */, 139D7ECD1E25DB7D00323FB7 /* third-party */, - 3D383D211EBD27B6005632C8 /* third-party-tvOS */, 139D7E871E25C6D100323FB7 /* double-conversion */, - 3D383D3D1EBD27B9005632C8 /* double-conversion-tvOS */, 9936F2F81F5F2E4B0010BF04 /* privatedata */, - 9936F3141F5F2E5B0010BF04 /* privatedata-tvOS */, ); }; /* End PBXProject section */ @@ -3833,20 +2563,23 @@ shellPath = /bin/sh; shellScript = "cd \"$SRCROOT/..\"\nexec ./scripts/macos-install-third-party.sh"; }; - 2D6948201DA3042200B3FA97 /* Include RCTJSCProfiler */ = { - isa = PBXShellScriptBuildPhase; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 139D7E841E25C6D100323FB7 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "Include RCTJSCProfiler"; - outputPaths = ( + 139D7E911E25C70B00323FB7 /* bignum-dtoa.cc in Sources */, + 139D7E931E25C70B00323FB7 /* bignum.cc in Sources */, + 139D7E951E25C70B00323FB7 /* cached-powers.cc in Sources */, + 139D7E971E25C70B00323FB7 /* diy-fp.cc in Sources */, + 139D7E991E25C70B00323FB7 /* double-conversion.cc in Sources */, + 139D7E9B1E25C70B00323FB7 /* fast-dtoa.cc in Sources */, + 139D7E9D1E25C70B00323FB7 /* fixed-dtoa.cc in Sources */, + 139D7EA01E25C70B00323FB7 /* strtod.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [[ \"$CONFIGURATION\" == \"Debug\" ]] && [[ -d \"/tmp/RCTJSCProfiler\" ]]; then\nfind \"${CONFIGURATION_BUILD_DIR}\" -name '*.app' | xargs -I{} sh -c 'cp -r /tmp/RCTJSCProfiler \"$1\"' -- {}\nfi"; - showEnvVarsInLog = 0; }; 2D6948301DA3088700B3FA97 /* Start Packager */ = { isa = PBXShellScriptBuildPhase; @@ -3863,40 +2596,8 @@ shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\nif nc -w 5 -z localhost 8081 ; then\nif ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\necho \"Port 8081 already in use, packager is either not running or not running correctly\"\nexit 2\nfi\nelse\nopen \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\nfi\nfi"; showEnvVarsInLog = 0; }; - 3D383D3E1EBD27B9005632C8 /* Install Third Party */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Install Third Party"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd \"$SRCROOT/..\"\nexec ./scripts/macos-install-third-party.sh"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 139D7E841E25C6D100323FB7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 139D7E911E25C70B00323FB7 /* bignum-dtoa.cc in Sources */, - 139D7E931E25C70B00323FB7 /* bignum.cc in Sources */, - 139D7E951E25C70B00323FB7 /* cached-powers.cc in Sources */, - 139D7E971E25C70B00323FB7 /* diy-fp.cc in Sources */, - 139D7E991E25C70B00323FB7 /* double-conversion.cc in Sources */, - 139D7E9B1E25C70B00323FB7 /* fast-dtoa.cc in Sources */, - 139D7E9D1E25C70B00323FB7 /* fixed-dtoa.cc in Sources */, - 139D7EA01E25C70B00323FB7 /* strtod.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 139D7ECA1E25DB7D00323FB7 /* Sources */ = { - isa = PBXSourcesBuildPhase; + 139D7ECA1E25DB7D00323FB7 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 139D84B01E273B5600323FB7 /* Conv.cpp in Sources */, @@ -3918,163 +2619,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2D2A280F1D9B038B00D4039D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 598FD1931F817284006C54CB /* PrivateDataBase.cpp in Sources */, - 3DC159E41E83E1AE007B1282 /* RCTRootContentView.m in Sources */, - 3D80D91B1DF6F8200028D040 /* RCTPlatform.m in Sources */, - 2D3B5EC91D9B095C00451313 /* RCTBorderDrawing.m in Sources */, - 66CD94B81F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */, - 2D3B5E991D9B089A00451313 /* RCTDisplayLink.m in Sources */, - 2D3B5EA11D9B08B600451313 /* RCTModuleData.mm in Sources */, - 590D7C001EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */, - 705EDE2D221082D9000CAA67 /* RCTSurfaceSizeMeasureMode.mm in Sources */, - 2D3B5EAE1D9B08F800451313 /* RCTEventEmitter.m in Sources */, - 2D3B5ECA1D9B095F00451313 /* RCTComponentData.m in Sources */, - 2D3B5EA31D9B08BE00451313 /* RCTParserUtils.m in Sources */, - 59500D461F71C63F00B122B7 /* RCTUIManagerUtils.m in Sources */, - 599FAA4D1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */, - 59EDBCB41FDF4E0C003573DE /* RCTScrollContentViewManager.m in Sources */, - 2D3B5EA01D9B08B200451313 /* RCTLog.mm in Sources */, - 5960C1BC1F0804A00066FD5B /* RCTLayoutAnimationGroup.m in Sources */, - 2D3B5ECF1D9B096F00451313 /* RCTFont.mm in Sources */, - 2D3B5ED51D9B098000451313 /* RCTModalHostViewController.m in Sources */, - 657734931EE8356100A0E9EA /* RCTInspector.mm in Sources */, - 59EB6DBE1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm in Sources */, - 2D3B5E971D9B089000451313 /* RCTBridge.m in Sources */, - 2D3B5E9B1D9B08A000451313 /* RCTFrameUpdate.m in Sources */, - 2D3B5EE41D9B09BB00451313 /* RCTSegmentedControlManager.m in Sources */, - 59EDBCB81FDF4E0C003573DE /* RCTScrollView.m in Sources */, - 13134C9F1E296B2A00B9F3CB /* RCTCxxModule.mm in Sources */, - 2D3B5EE31D9B09B700451313 /* RCTSegmentedControl.m in Sources */, - 130443A41E3FEAC600D93A67 /* RCTFollyConvert.mm in Sources */, - 3D7BFD201EA8E351008DFB7A /* RCTPackagerConnection.mm in Sources */, - 5960C1B81F0804A00066FD5B /* RCTLayoutAnimation.m in Sources */, - 2D3B5EB71D9B091800451313 /* RCTRedBox.m in Sources */, - 3D7AA9C61E548CDD001955CF /* NSDataBigString.mm in Sources */, - 13134C8F1E296B2A00B9F3CB /* RCTMessageThread.mm in Sources */, - 2D3B5EF11D9B09E700451313 /* NSView+React.m in Sources */, - 2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */, - C60669371F3CCF1B00E67165 /* RCTManagedPointer.mm in Sources */, - 2D3B5EE01D9B09AD00451313 /* RCTRootShadowView.m in Sources */, - 2D3B5EBA1D9B092100451313 /* RCTI18nUtil.m in Sources */, - 2D3B5EB41D9B090A00451313 /* RCTDevLoadingView.m in Sources */, - 2D3B5EEF1D9B09DC00451313 /* RCTViewManager.m in Sources */, - 13134C971E296B2A00B9F3CB /* RCTObjcExecutor.mm in Sources */, - 594F0A351FD23228007FBE96 /* RCTSurfaceHostingView.mm in Sources */, - 130E3D8B1E6A083900ACE484 /* RCTDevSettings.mm in Sources */, - 2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */, - 3DF1BE851F26577300068F1A /* JSCTracing.cpp in Sources */, - 2D3B5EB61D9B091400451313 /* RCTExceptionsManager.m in Sources */, - 2D3B5ED41D9B097D00451313 /* RCTModalHostView.m in Sources */, - 599FAA391FB274980058CCF6 /* RCTSurface.mm in Sources */, - C606692F1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */, - 2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */, - 2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */, - 13134C871E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */, - CF2731C31E7B8DF30044CA4F /* RCTDeviceInfo.m in Sources */, - 599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */, - EBF21C001FC499A80052F4D5 /* InspectorInterfaces.cpp in Sources */, - 597633371F4E021D005BE8A4 /* RCTShadowView+Internal.m in Sources */, - 2D3B5EB11D9B090100451313 /* RCTAppState.m in Sources */, - 1384E20B1E806D5B00545659 /* RCTNativeModule.mm in Sources */, - 2D3B5EC21D9B093B00451313 /* RCTProfile.m in Sources */, - 2D3B5ECB1D9B096200451313 /* RCTConvert+CoreLocation.m in Sources */, - 2D3B5EEE1D9B09DA00451313 /* RCTView.m in Sources */, - 2D3B5E981D9B089500451313 /* RCTConvert.m in Sources */, - 3D7BFD181EA8E351008DFB7A /* RCTPackagerClient.m in Sources */, - 2D3B5EA71D9B08CE00451313 /* RCTTouchHandler.m in Sources */, - 3D05745A1DE5FFF500184BB4 /* RCTJavaScriptLoader.mm in Sources */, - 2D3B5EA41D9B08C200451313 /* RCTPerformanceLogger.m in Sources */, - 2D3B5E9E1D9B08AD00451313 /* RCTJSStackFrame.m in Sources */, - 13134CA31E296B2A00B9F3CB /* RCTCxxUtils.mm in Sources */, - 2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */, - 2D3B5EB81D9B091B00451313 /* RCTSourceCode.m in Sources */, - 2D3B5EB51D9B091100451313 /* RCTDevMenu.m in Sources */, - 59EDBCAC1FDF4E0C003573DE /* RCTScrollContentShadowView.m in Sources */, - 2D3B5EBD1D9B092A00451313 /* RCTTiming.m in Sources */, - 135A9C041E7B0F6400587AEB /* RCTJSCErrorHandling.mm in Sources */, - 2D3B5EA81D9B08D300451313 /* RCTUtils.m in Sources */, - 599FAA451FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */, - 2D3B5EC81D9B095800451313 /* RCTActivityIndicatorViewManager.m in Sources */, - 598FD1961F817335006C54CB /* RCTModalManager.m in Sources */, - 3DCD185D1DF978E7007FE5A1 /* RCTReloadCommand.m in Sources */, - 130443DB1E401ADD00D93A67 /* RCTConvert+Transform.m in Sources */, - 3D0B84301EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m in Sources */, - 2D3B5EC61D9B095000451313 /* RCTProfileTrampoline-x86_64.S in Sources */, - 2D3B5EA61D9B08CA00451313 /* RCTTouchEvent.m in Sources */, - 2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */, - 2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */, - 59EDBCBC1FDF4E0C003573DE /* RCTScrollViewManager.m in Sources */, - 59EDBCB01FDF4E0C003573DE /* RCTScrollContentView.m in Sources */, - 2D3B5EB01D9B08FE00451313 /* RCTAlertManager.m in Sources */, - 13134C9B1E296B2A00B9F3CB /* RCTCxxMethod.mm in Sources */, - 2D3B5E9C1D9B08A300451313 /* RCTImageSource.m in Sources */, - 3DDEC1521DDCE0CA0020BBDF /* RCTJSCSamplingProfiler.m in Sources */, - 2D3B5EC31D9B094800451313 /* RCTProfileTrampoline-arm.S in Sources */, - 3D0B842B1EC0B49400B2BD8E /* RCTTVRemoteHandler.m in Sources */, - 657734861EE834D900A0E9EA /* RCTInspectorDevServerHelper.mm in Sources */, - 66CD94B41F1045E700CB3C7C /* RCTMaskedView.m in Sources */, - 2D74EAFA1DAE9590003B751B /* RCTMultipartDataTask.m in Sources */, - 2D3B5EC51D9B094D00451313 /* RCTProfileTrampoline-i386.S in Sources */, - 657734951EE8356100A0E9EA /* RCTInspectorPackagerConnection.m in Sources */, - 59283CA11FD67321000EAAB9 /* RCTSurfaceStage.m in Sources */, - 2D3B5EC41D9B094B00451313 /* RCTProfileTrampoline-arm64.S in Sources */, - 2D3B5EBB1D9B092300451313 /* RCTI18nManager.m in Sources */, - 2D3B5EBE1D9B092D00451313 /* RCTUIManager.m in Sources */, - C60128AE1F3D1258009DF9FF /* RCTCxxConvert.m in Sources */, - 2D3B5EDD1D9B09A300451313 /* RCTProgressViewManager.m in Sources */, - 2D3B5EC11D9B093900451313 /* RCTFPSGraph.m in Sources */, - 2D3B5E9A1D9B089D00451313 /* RCTEventDispatcher.m in Sources */, - 2D3B5ED61D9B098400451313 /* RCTModalHostViewManager.m in Sources */, - 2D3B5EE51D9B09BE00451313 /* RCTShadowView.m in Sources */, - 135A9C051E7B0F7500587AEB /* RCTJSCHelpers.mm in Sources */, - 2D3B5EC71D9B095600451313 /* RCTActivityIndicatorView.m in Sources */, - 2D3B5EB21D9B090300451313 /* RCTAsyncLocalStorage.m in Sources */, - 2D3B5EC01D9B093600451313 /* RCTPerfMonitor.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D383D241EBD27B6005632C8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3D383D251EBD27B6005632C8 /* Conv.cpp in Sources */, - 3D383D261EBD27B6005632C8 /* StringBase.cpp in Sources */, - 3D383D271EBD27B6005632C8 /* raw_logging.cc in Sources */, - 3D383D281EBD27B6005632C8 /* signalhandler.cc in Sources */, - 3D383D291EBD27B6005632C8 /* dynamic.cpp in Sources */, - 3D383D2A1EBD27B6005632C8 /* utilities.cc in Sources */, - 3D383D2B1EBD27B6005632C8 /* MallocImpl.cpp in Sources */, - 3D383D2C1EBD27B6005632C8 /* Bits.cpp in Sources */, - 3D383D2D1EBD27B6005632C8 /* symbolize.cc in Sources */, - 3D383D2E1EBD27B6005632C8 /* vlog_is_on.cc in Sources */, - 3D383D2F1EBD27B6005632C8 /* Unicode.cpp in Sources */, - 3D383D301EBD27B6005632C8 /* demangle.cc in Sources */, - 3D383D311EBD27B6005632C8 /* Demangle.cpp in Sources */, - 3D383D331EBD27B6005632C8 /* logging.cc in Sources */, - 3D383D341EBD27B6005632C8 /* json.cpp in Sources */, - 3D383D351EBD27B6005632C8 /* BitsFunctexcept.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D383D3F1EBD27B9005632C8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3D383D401EBD27B9005632C8 /* bignum-dtoa.cc in Sources */, - 3D383D411EBD27B9005632C8 /* bignum.cc in Sources */, - 3D383D421EBD27B9005632C8 /* cached-powers.cc in Sources */, - 3D383D431EBD27B9005632C8 /* diy-fp.cc in Sources */, - 3D383D441EBD27B9005632C8 /* double-conversion.cc in Sources */, - 3D383D451EBD27B9005632C8 /* fast-dtoa.cc in Sources */, - 3D383D461EBD27B9005632C8 /* fixed-dtoa.cc in Sources */, - 3D383D471EBD27B9005632C8 /* strtod.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3D3C05301DE3340900C268FA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4085,16 +2629,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D3C06181DE3340C00C268FA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 53D123A11FBF1EFF001B8A10 /* Yoga.cpp in Sources */, - 53D1239B1FBF1EF4001B8A10 /* YGEnums.cpp in Sources */, - 5376C5E51FC6DDBD0083513D /* YGNodePrint.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3D3CD9051DE5FBD600167DC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4107,18 +2641,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D3CD9121DE5FBD800167DC4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13EBC6791E2870E400880AC5 /* Unicode.cpp in Sources */, - 13EBC6781E2870E400880AC5 /* JSCWrapper.cpp in Sources */, - 13EBC6771E2870E400880AC5 /* JSCHelpers.cpp in Sources */, - 135A9C011E7B0F4700587AEB /* systemJSCWrapper.cpp in Sources */, - 13EBC67A1E2870E400880AC5 /* Value.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 3D3CD91F1DE5FBEC00167DC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4144,31 +2666,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 3D3CD92C1DE5FBEE00167DC4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DC159E61E83E1FA007B1282 /* JSBigString.cpp in Sources */, - 13F8878E1E29726300C3C7A1 /* JSIndexedRAMBundle.cpp in Sources */, - 13F887901E29726300C3C7A1 /* ModuleRegistry.cpp in Sources */, - C6D3801D1F71D76800621378 /* RAMBundleRegistry.cpp in Sources */, - 13F887851E29726300C3C7A1 /* JSCExecutor.cpp in Sources */, - 13F887871E29726300C3C7A1 /* JSCLegacyTracing.cpp in Sources */, - 13F8878A1E29726300C3C7A1 /* JSCPerfStats.cpp in Sources */, - 13F887841E29726300C3C7A1 /* Instance.cpp in Sources */, - 13F8878C1E29726300C3C7A1 /* JSCUtils.cpp in Sources */, - 13F8878B1E29726300C3C7A1 /* JSCSamplingProfiler.cpp in Sources */, - 13F887881E29726300C3C7A1 /* JSCMemory.cpp in Sources */, - 3D80D9181DF6F7A80028D040 /* JSBundleType.cpp in Sources */, - 13F8878F1E29726300C3C7A1 /* MethodCall.cpp in Sources */, - 13F887921E29726300C3C7A1 /* Platform.cpp in Sources */, - 13F887911E29726300C3C7A1 /* NativeToJsBridge.cpp in Sources */, - 13F887821E29726300C3C7A1 /* CxxNativeModule.cpp in Sources */, - 13F887891E29726300C3C7A1 /* JSCNativeModules.cpp in Sources */, - 13F887931E29726300C3C7A1 /* SampleCxxModule.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 83CBBA2A1A601D0E00E9B192 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4316,14 +2813,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9936F3261F5F2E5B0010BF04 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9936F33B1F5F2F9D0010BF04 /* PrivateDataBase.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EBF21BD31FC498900052F4D5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4332,14 +2821,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EBF21BF11FC4989A0052F4D5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EBF21BFF1FC4998E0052F4D5 /* InspectorInterfaces.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -4353,26 +2834,6 @@ target = 139D7E871E25C6D100323FB7 /* double-conversion */; targetProxy = 1320081C1E283DCB00F0C457 /* PBXContainerItemProxy */; }; - 3D0574551DE5FF9600184BB4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3D3C059B1DE3340C00C268FA /* yoga-tvOS */; - targetProxy = 3D0574541DE5FF9600184BB4 /* PBXContainerItemProxy */; - }; - 3D0574571DE5FF9600184BB4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3D3CD9261DE5FBEE00167DC4 /* cxxreact-tvOS */; - targetProxy = 3D0574561DE5FF9600184BB4 /* PBXContainerItemProxy */; - }; - 3D383D641EBD27CE005632C8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3D383D211EBD27B6005632C8 /* third-party-tvOS */; - targetProxy = 3D383D631EBD27CE005632C8 /* PBXContainerItemProxy */; - }; - 3D383D661EBD27DB005632C8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3D383D3D1EBD27B9005632C8 /* double-conversion-tvOS */; - targetProxy = 3D383D651EBD27DB005632C8 /* PBXContainerItemProxy */; - }; 3D3CD94C1DE5FCE700167DC4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 3D3CD9191DE5FBEC00167DC4 /* cxxreact */; @@ -4383,11 +2844,6 @@ target = 3D3CD8FF1DE5FBD600167DC4 /* jschelpers */; targetProxy = 3D3CD94F1DE5FDB900167DC4 /* PBXContainerItemProxy */; }; - 3DC159E81E83E2A0007B1282 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3D3CD90C1DE5FBD800167DC4 /* jschelpers-tvOS */; - targetProxy = 3DC159E71E83E2A0007B1282 /* PBXContainerItemProxy */; - }; 53D123991FBF1E0C001B8A10 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 3D3C04B91DE3340900C268FA /* yoga */; @@ -4398,31 +2854,16 @@ target = 9936F2F81F5F2E4B0010BF04 /* privatedata */; targetProxy = 9936F33F1F5F305D0010BF04 /* PBXContainerItemProxy */; }; - 9936F3421F5F30640010BF04 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 9936F3141F5F2E5B0010BF04 /* privatedata-tvOS */; - targetProxy = 9936F3411F5F30640010BF04 /* PBXContainerItemProxy */; - }; 9936F3441F5F30780010BF04 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 9936F2F81F5F2E4B0010BF04 /* privatedata */; targetProxy = 9936F3431F5F30780010BF04 /* PBXContainerItemProxy */; }; - 9936F3461F5F30830010BF04 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 9936F3141F5F2E5B0010BF04 /* privatedata-tvOS */; - targetProxy = 9936F3451F5F30830010BF04 /* PBXContainerItemProxy */; - }; EBF21C021FC499D10052F4D5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EBF21BBF1FC498900052F4D5 /* jsinspector */; targetProxy = EBF21C011FC499D10052F4D5 /* PBXContainerItemProxy */; }; - EBF21C041FC499D80052F4D5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EBF21BDD1FC4989A0052F4D5 /* jsinspector-tvOS */; - targetProxy = EBF21C031FC499D80052F4D5 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -4500,118 +2941,6 @@ }; name = Release; }; - 2D2A28191D9B038B00D4039D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = React; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/React; - SDKROOT = appletvos; - }; - name = Debug; - }; - 2D2A281A1D9B038B00D4039D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = React; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/React; - SDKROOT = appletvos; - }; - name = Release; - }; - 3D383D3A1EBD27B6005632C8 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = V9WTTPBFK9; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "third-party"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - USER_HEADER_SEARCH_PATHS = ""; - }; - name = Debug; - }; - 3D383D3B1EBD27B6005632C8 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = V9WTTPBFK9; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "third-party"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - USER_HEADER_SEARCH_PATHS = ""; - }; - name = Release; - }; - 3D383D601EBD27B9005632C8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = V9WTTPBFK9; - OTHER_LDFLAGS = "-ObjC"; - PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include/double-conversion"; - PRODUCT_NAME = "double-conversion"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 3D383D611EBD27B9005632C8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = V9WTTPBFK9; - OTHER_LDFLAGS = "-ObjC"; - PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include/double-conversion"; - PRODUCT_NAME = "double-conversion"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - }; - name = Release; - }; 3D3C05981DE3340900C268FA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -4641,42 +2970,6 @@ }; name = Release; }; - 3D3C06731DE3340C00C268FA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = yoga; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/yoga; - SDKROOT = appletvos; - }; - name = Debug; - }; - 3D3C06741DE3340C00C268FA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = yoga; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/yoga; - SDKROOT = appletvos; - }; - name = Release; - }; 3D3CD9091DE5FBD600167DC4 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; @@ -4708,44 +3001,6 @@ }; name = Release; }; - 3D3CD9161DE5FBD800167DC4 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = jschelpers; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/jschelpers; - SDKROOT = appletvos; - }; - name = Debug; - }; - 3D3CD9171DE5FBD800167DC4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = jschelpers; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/jschelpers; - SDKROOT = appletvos; - }; - name = Release; - }; 3D3CD9231DE5FBEC00167DC4 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; @@ -4777,44 +3032,6 @@ }; name = Release; }; - 3D3CD9301DE5FBEE00167DC4 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = cxxreact; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/cxxreact; - SDKROOT = appletvos; - }; - name = Debug; - }; - 3D3CD9311DE5FBEE00167DC4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = cxxreact; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/cxxreact; - SDKROOT = appletvos; - }; - name = Release; - }; 83CBBA201A601CBA00E9B192 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -4981,44 +3198,6 @@ }; name = Release; }; - 9936F32D1F5F2E5B0010BF04 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/privatedata; - SDKROOT = appletvos; - }; - name = Debug; - }; - 9936F32E1F5F2E5B0010BF04 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/privatedata; - SDKROOT = appletvos; - }; - name = Release; - }; EBF21BDA1FC498900052F4D5 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; @@ -5050,44 +3229,6 @@ }; name = Release; }; - EBF21BF81FC4989A0052F4D5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/jsinspector; - SDKROOT = appletvos; - }; - name = Debug; - }; - EBF21BF91FC4989A0052F4D5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3D788F841EBD2D240063D616 /* third-party.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/jsinspector; - SDKROOT = appletvos; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -5109,33 +3250,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2D2A281B1D9B038B00D4039D /* Build configuration list for PBXNativeTarget "React-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D2A28191D9B038B00D4039D /* Debug */, - 2D2A281A1D9B038B00D4039D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3D383D391EBD27B6005632C8 /* Build configuration list for PBXNativeTarget "third-party-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D383D3A1EBD27B6005632C8 /* Debug */, - 3D383D3B1EBD27B6005632C8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3D383D5F1EBD27B9005632C8 /* Build configuration list for PBXNativeTarget "double-conversion-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D383D601EBD27B9005632C8 /* Debug */, - 3D383D611EBD27B9005632C8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 3D3C05971DE3340900C268FA /* Build configuration list for PBXNativeTarget "yoga" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5145,15 +3259,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3D3C06721DE3340C00C268FA /* Build configuration list for PBXNativeTarget "yoga-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D3C06731DE3340C00C268FA /* Debug */, - 3D3C06741DE3340C00C268FA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 3D3CD9081DE5FBD600167DC4 /* Build configuration list for PBXNativeTarget "jschelpers" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5163,15 +3268,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3D3CD9151DE5FBD800167DC4 /* Build configuration list for PBXNativeTarget "jschelpers-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D3CD9161DE5FBD800167DC4 /* Debug */, - 3D3CD9171DE5FBD800167DC4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 3D3CD9221DE5FBEC00167DC4 /* Build configuration list for PBXNativeTarget "cxxreact" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5181,15 +3277,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3D3CD92F1DE5FBEE00167DC4 /* Build configuration list for PBXNativeTarget "cxxreact-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D3CD9301DE5FBEE00167DC4 /* Debug */, - 3D3CD9311DE5FBEE00167DC4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "React" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5217,15 +3304,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 9936F32C1F5F2E5B0010BF04 /* Build configuration list for PBXNativeTarget "privatedata-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9936F32D1F5F2E5B0010BF04 /* Debug */, - 9936F32E1F5F2E5B0010BF04 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; EBF21BD91FC498900052F4D5 /* Build configuration list for PBXNativeTarget "jsinspector" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5235,15 +3313,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EBF21BF71FC4989A0052F4D5 /* Build configuration list for PBXNativeTarget "jsinspector-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - EBF21BF81FC4989A0052F4D5 /* Debug */, - EBF21BF91FC4989A0052F4D5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; From c3b98422b6060f380f8c00177fd3b1ced58f23c8 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 15 Feb 2019 20:21:02 -0500 Subject: [PATCH 107/143] declare that NSTextField conforms to NSTextViewDelegate The "field editor" is a NSTextView that makes the active NSTextField its delegate, which means that our NSTextField subclass can implement methods declared in the NSTextViewDelegate protocol. --- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 783aa72dc1..f9718df6e9 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -14,6 +14,10 @@ #import "RCTBackedTextInputDelegateAdapter.h" +// The "field editor" is a NSTextView whose delegate is this NSTextField. +@interface NSTextField () +@end + @implementation RCTUITextField { RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter; } From 2a1d3a7082b026a4bb29d666b12047116f7ad76f Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 15 Feb 2019 20:29:53 -0500 Subject: [PATCH 108/143] fix: "onFocus" prop of RCTUITextField --- .../Text/TextInput/RCTBackedTextInputDelegateAdapter.h | 1 + .../Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 2 +- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index a9b4b8aef9..708d2e1130 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange; - (void)selectedTextRangeWasSet; +- (void)textFieldDidFocus; @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index daed31c28b..d8df11b897 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -48,7 +48,7 @@ - (BOOL)control:(__unused NSControl *)control textShouldBeginEditing:(__unused N return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)controlTextDidBeginEditing:(__unused NSNotification *)notification +- (void)textFieldDidFocus { [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index f9718df6e9..6678569bb1 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -104,6 +104,15 @@ - (void)paste:(id)sender _textWasPasted = YES; } +- (BOOL)becomeFirstResponder +{ + if ([super becomeFirstResponder]) { + [_textInputDelegateAdapter textFieldDidFocus]; + return YES; + } + return NO; +} + #pragma mark - RCTBackedTextInputViewProtocol - (NSString *)text From 206a2b61299dc1e505184474c6d76a31ff2edeb5 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 10:42:03 -0500 Subject: [PATCH 109/143] fix: "onBlur" prop of RCTUITextField Use the "textDidEndEditing:" method of NSTextViewDelegate, which may be called even when the NSTextField is still focused. For example, the default behavior of the Tab/Enter keys is to "end editing" but remain focused. --- .../Text/TextInput/RCTBackedTextInputDelegateAdapter.h | 1 + .../Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 2 +- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index 708d2e1130..68a1f7efc4 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange; - (void)selectedTextRangeWasSet; - (void)textFieldDidFocus; +- (void)textFieldDidBlur; @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index d8df11b897..eda6494c77 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -58,7 +58,7 @@ - (BOOL)control:(__unused NSControl *)control textShouldEndEditing:(__unused NST return [_backedTextInputView.textInputDelegate textInputShouldEndEditing]; } -- (void)controlTextDidEndEditing:(__unused NSNotification *)notification +- (void)textFieldDidBlur { if (_textDidChangeIsComing) { // iOS does't call `textViewDidChange:` delegate method if the change was happened because of autocorrection diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 6678569bb1..50e9f78823 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -104,6 +104,14 @@ - (void)paste:(id)sender _textWasPasted = YES; } +- (void)textDidEndEditing:(NSNotification *)notification +{ + [super textDidEndEditing:notification]; + if (self.currentEditor == nil) { + [_textInputDelegateAdapter textFieldDidBlur]; + } +} + - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { From 8a0ef5da8f39082582b57b058fac58f4a5b99009 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 12:36:35 -0500 Subject: [PATCH 110/143] fix: change validation in RCTUITextField The "textField:shouldChangeCharactersInRange:replacementString:" method of NSTextFieldDelegate is not called for some reason. Instead, use the "textView:shouldChangeTextInRange:replacementString:" method of NSTextViewDelegate. --- .../Text/TextInput/RCTBackedTextInputDelegateAdapter.h | 1 + .../Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 4 ++-- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index 68a1f7efc4..b8db87be65 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)selectedTextRangeWasSet; - (void)textFieldDidFocus; - (void)textFieldDidBlur; +- (BOOL)shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index eda6494c77..cd95f8b03e 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -70,9 +70,9 @@ - (void)textFieldDidBlur [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } -- (BOOL)textField:(__unused NSTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string +- (BOOL)shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { - BOOL result = [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:range replacementText:string]; + BOOL result = [_backedTextInputView.textInputDelegate textInputShouldChangeTextInRange:range replacementText:text]; if (result) { _textDidChangeIsComing = YES; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 50e9f78823..2176c22c70 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -104,6 +104,14 @@ - (void)paste:(id)sender _textWasPasted = YES; } +- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementString:(NSString *)string +{ + if ([super textView:textView shouldChangeTextInRange:range replacementString:string]) { + return [_textInputDelegateAdapter shouldChangeTextInRange:range replacementText:string]; + } + return NO; +} + - (void)textDidEndEditing:(NSNotification *)notification { [super textDidEndEditing:notification]; From 3ee1a5fa316d77202a13ad94e8769569c8f99546 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 12:40:27 -0500 Subject: [PATCH 111/143] fix: skip "textViewProbablyDidChangeSelection" if not firstResponder For whatever reason, the "textViewDidChangeSelection:" method of NSTextViewDelegate is sometimes called even when the NSTextView is not the first responder. --- Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index cd95f8b03e..02564db93f 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -212,7 +212,9 @@ - (void)textDidChange:(__unused NSNotification *)notification - (void)textViewDidChangeSelection:(__unused NSNotification *)notification { - [self textViewProbablyDidChangeSelection]; + if (_backedTextInputView == _backedTextInputView.window.firstResponder) { + [self textViewProbablyDidChangeSelection]; + } } #pragma mark - Public Interface From a5b9b3b879ad0aa565aec371a86ad6bfe778b7c8 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 12:44:40 -0500 Subject: [PATCH 112/143] improve "textInputDidChange" method of RCTBaseTextInputView --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 5e4bc6fc1d..1e43e92666 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -307,7 +307,7 @@ - (void)textInputDidChange [self updateLocalData]; [self updatePlaceholderVisibility]; - id backedTextInputView = self.backedTextInputView; + NSString *text = self.attributedText.string; // Detect when `backedTextInputView` updates happend that didn't invoke `shouldChangeTextInRange` // (e.g. typing simplified chinese in pinyin will insert and remove spaces without @@ -315,19 +315,19 @@ - (void)textInputDidChange // update the mismatched range. NSRange currentRange; NSRange predictionRange; - if (findMismatch(backedTextInputView.attributedText.string, _predictedText, ¤tRange, &predictionRange)) { - NSString *replacement = [backedTextInputView.attributedText.string substringWithRange:currentRange]; + if (findMismatch(text, _predictedText, ¤tRange, &predictionRange)) { + NSString *replacement = [text substringWithRange:currentRange]; [self textInputShouldChangeTextInRange:predictionRange replacementText:replacement]; // JS will assume the selection changed based on the location of our shouldChangeTextInRange, so reset it. [self textInputDidChangeSelection]; - _predictedText = backedTextInputView.attributedText.string; + _predictedText = text; } _nativeEventCount++; if (_onChange) { _onChange(@{ - @"text": self.attributedText.string, + @"text": text, @"target": self.reactTag, @"eventCount": @(_nativeEventCount), }); From ef85ce063905b048be8f801b6f53de7ce6f58edd Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 12:46:45 -0500 Subject: [PATCH 113/143] fix: "onSelectionChange" prop of RCTUITextField Use the "textViewDidChangeSelection:" method of NSTextViewDelegate, since there is no equivalent method in NSTextFieldDelegate. --- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 2176c22c70..e27764d45d 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -104,6 +104,12 @@ - (void)paste:(id)sender _textWasPasted = YES; } +- (void)textViewDidChangeSelection:(NSNotification *)notification +{ + [super textViewDidChangeSelection:notification]; + [_textInputDelegateAdapter selectedTextRangeWasSet]; +} + - (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementString:(NSString *)string { if ([super textView:textView shouldChangeTextInRange:range replacementString:string]) { From 35a62cbced006758e9ec1d6b6b02b2064f97258b Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 16 Feb 2019 13:31:38 -0500 Subject: [PATCH 114/143] fix: "onKeyPress" prop of TextInput The replacement text in "shouldChangeTextInRange:replacementText:" may be a mutable string, so we need to copy it to prevent changes to the "_predictedText" internal property. --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 1e43e92666..ef138fe567 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -284,7 +284,7 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin if (!NSEqualRanges(range, NSMakeRange(0, 0)) && _predictedText) { _predictedText = [_predictedText stringByReplacingCharactersInRange:range withString:text]; } else { - _predictedText = text; + _predictedText = [text copy]; } if (_onTextInput) { From e4d66e9e30d6ae2dc9414ec6d04b35177ef40103 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 19 Feb 2019 14:45:18 -0500 Subject: [PATCH 115/143] fix: unwanted RCTView clipping of top-left corner --- React/Views/RCTView.m | 1 + 1 file changed, 1 insertion(+) diff --git a/React/Views/RCTView.m b/React/Views/RCTView.m index e355b3d5c5..1943ac7558 100644 --- a/React/Views/RCTView.m +++ b/React/Views/RCTView.m @@ -646,6 +646,7 @@ - (void)displayLayer:(CALayer *)layer } layer.contents = (id)image; + layer.contentsScale = [image recommendedLayerContentsScale:0.0]; layer.contentsCenter = contentsCenter; layer.magnificationFilter = kCAFilterNearest; layer.needsDisplayOnBoundsChange = YES; From c0a7538c7795c4ac54e52075f5cb1baed7e66195 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 11:43:09 -0500 Subject: [PATCH 116/143] fix: "onFocus" event of multiline TextInput Overriding "becomeFirstResponder" is the only way to know when a NSTextView becomes focused. The "onFocus" event must be delayed until the next event loop, or the "selectTextOnFocus" prop will not work. --- Libraries/Text/TextInput/Multiline/RCTUITextView.m | 9 +++++++++ .../Text/TextInput/RCTBackedTextInputDelegateAdapter.h | 1 + .../Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index d625c4ecf3..f16fe1cacd 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -98,6 +98,15 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not [super setSelectedRange:selectedTextRange]; } +- (BOOL)becomeFirstResponder +{ + if ([super becomeFirstResponder]) { + [_textInputDelegateAdapter performSelector:@selector(textViewDidFocus) withObject:nil afterDelay:0.0]; + return YES; + } + return NO; +} + - (void)paste:(id)sender { [super paste:sender]; diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h index b8db87be65..3db40c6293 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h @@ -35,6 +35,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithTextView:(NSTextView *)backedTextInputView; - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(NSRange)textRange; +- (void)textViewDidFocus; @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 02564db93f..e95846c0d0 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -164,7 +164,7 @@ - (BOOL)textShouldBeginEditing:(__unused NSText *)text return [_backedTextInputView.textInputDelegate textInputShouldBeginEditing]; } -- (void)textDidBeginEditing:(__unused NSNotification *)notification +- (void)textViewDidFocus { [_backedTextInputView.textInputDelegate textInputDidBeginEditing]; } From 671050e431e06813159e767da50c0cb1829c0c9c Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 11:45:52 -0500 Subject: [PATCH 117/143] remove "contentSize" and "sizeThatFits:" from RCTBackedTextInputViewProtocol These are not required for TextInput to work as expected. --- .../Text/TextInput/Multiline/RCTUITextView.m | 40 ------------------- .../RCTBackedTextInputViewProtocol.h | 4 +- .../Text/TextInput/RCTBaseTextInputView.m | 36 ++++++++--------- 3 files changed, 19 insertions(+), 61 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index f16fe1cacd..c2258354e4 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -120,46 +120,6 @@ - (void)paste:(id)sender // [super setContentOffset:contentOffset animated:NO]; //} -#pragma mark - Layout - -- (CGSize)contentSize -{ - CGSize contentSize = super.contentSize; - CGSize placeholderSize = CGSizeZero; - // When a text input is empty, it actually displays a placehoder. - // So, we have to consider `placeholderSize` as a minimum `contentSize`. - // Returning size DOES contain `textContainerInset` (aka `padding`). - return CGSizeMake( - MAX(contentSize.width, placeholderSize.width), - MAX(contentSize.height, placeholderSize.height)); -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - CGRect textFrame = NSEdgeInsetsInsetRect(self.bounds, self.textContainerInset); - CGFloat placeholderHeight = [_placeholderView sizeThatFits:textFrame.size].height; - textFrame.size.height = MIN(placeholderHeight, textFrame.size.height); - _placeholderView.frame = textFrame; -} - -- (CGSize)intrinsicContentSize -{ - // Returning size DOES contain `textContainerInset` (aka `padding`). - return [self sizeThatFits:CGSizeMake(self.preferredMaxLayoutWidth, CGFLOAT_MAX)]; -} - -- (CGSize)sizeThatFits:(CGSize)size -{ - // Returned fitting size depends on text size and placeholder size. - [self.layoutManager ensureLayoutForTextContainer:self.textContainer]; - CGSize textSize = [self.layoutManager usedRectForTextContainer:self.textContainer].size; - CGSize placeholderSize = CGSizeZero; - // Returning size DOES contain `textContainerInset` (aka `padding`). - return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height)); -} - #pragma mark - Padding - (void)setPaddingInsets:(NSEdgeInsets)paddingInsets diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index aca6544a2b..ad735f4331 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) NSEdgeInsets paddingInsets; //@property (nonatomic, strong, nullable) NSView *inputAccessoryView; @property (nonatomic, weak, nullable) id textInputDelegate; -@property (nonatomic, readonly) CGSize contentSize; +//@property (nonatomic, readonly) CGSize contentSize; // This protocol disallows direct access to `selectedTextRange` property because // unwise usage of it can break the `delegate` behavior. So, we always have to @@ -40,8 +40,6 @@ NS_ASSUME_NONNULL_BEGIN // Use `attributedText.string` instead. @property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; -- (CGSize)sizeThatFits:(CGSize)size; - @end NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index ef138fe567..e8c79b1390 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -369,24 +369,24 @@ - (CGSize)intrinsicContentSize return size; } -- (CGSize)sizeThatFits:(CGSize)size -{ - CGFloat compoundHorizontalBorderInset = _reactBorderInsets.left + _reactBorderInsets.right; - CGFloat compoundVerticalBorderInset = _reactBorderInsets.top + _reactBorderInsets.bottom; - - size.width -= compoundHorizontalBorderInset; - size.height -= compoundVerticalBorderInset; - - // Note: `paddingInsets` was already included in `backedTextInputView` size - // because it was applied as `textContainerInset`. - CGSize fittingSize = [self.backedTextInputView sizeThatFits:size]; - - fittingSize.width += compoundHorizontalBorderInset; - fittingSize.height += compoundVerticalBorderInset; - - // Returning value DOES include border and padding insets. - return fittingSize; -} +//- (CGSize)sizeThatFits:(CGSize)size +//{ +// CGFloat compoundHorizontalBorderInset = _reactBorderInsets.left + _reactBorderInsets.right; +// CGFloat compoundVerticalBorderInset = _reactBorderInsets.top + _reactBorderInsets.bottom; +// +// size.width -= compoundHorizontalBorderInset; +// size.height -= compoundVerticalBorderInset; +// +// // Note: `paddingInsets` was already included in `backedTextInputView` size +// // because it was applied as `textContainerInset`. +// CGSize fittingSize = [self.backedTextInputView sizeThatFits:size]; +// +// fittingSize.width += compoundHorizontalBorderInset; +// fittingSize.height += compoundVerticalBorderInset; +// +// // Returning value DOES include border and padding insets. +// return fittingSize; +//} #pragma mark - Accessibility From 0f594131ff81dc9fe19abb532098cbb3f11097e6 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 11:59:34 -0500 Subject: [PATCH 118/143] clear selection of multiline TextInput on blur --- Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index e95846c0d0..0ce0eac707 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -183,6 +183,9 @@ - (void)textDidEndEditing:(__unused NSNotification *)notification [_backedTextInputView.textInputDelegate textInputDidChange]; } + // Silently clear the selection when editing ends. + [_backedTextInputView setSelectedTextRange:(NSRange){0, 0} notifyDelegate:NO]; + [_backedTextInputView.textInputDelegate textInputDidEndEditing]; } From e0c4bc1f561179e430868f05609d12e781983b99 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 12:00:25 -0500 Subject: [PATCH 119/143] clip the bounds of TextInput --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index e8c79b1390..db86d1065c 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -37,6 +37,8 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge if (self = [super initWithFrame:CGRectZero]) { _bridge = bridge; _eventDispatcher = bridge.eventDispatcher; + + self.clipsToBounds = YES; } return self; From 0ab120f18ea0310370fd96928d17d23967cba5e6 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 12:50:42 -0500 Subject: [PATCH 120/143] fix: TextInput visual bugs --- .../Text/TextInput/Multiline/RCTUITextView.m | 10 +-- .../TextInput/Singleline/RCTUITextField.m | 62 ++++++++++++++++--- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index c2258354e4..5d1895852a 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -125,15 +125,7 @@ - (void)paste:(id)sender - (void)setPaddingInsets:(NSEdgeInsets)paddingInsets { _paddingInsets = paddingInsets; - self.textContainerInset = (NSSize){paddingInsets.right, paddingInsets.bottom}; -} - -- (NSPoint)textContainerOrigin -{ - return (NSPoint){ - _paddingInsets.left - _paddingInsets.right, - _paddingInsets.top - _paddingInsets.bottom - }; + self.textContainerInset = (NSSize){paddingInsets.left, paddingInsets.top}; } @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index e27764d45d..8581681ad0 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -11,6 +11,7 @@ #import #import +#import #import "RCTBackedTextInputDelegateAdapter.h" @@ -18,6 +19,10 @@ @interface NSTextField () @end +@interface RCTUITextFieldCell : NSTextFieldCell +@property (nullable, assign) RCTUITextField *controlView; +@end + @implementation RCTUITextField { RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter; } @@ -32,6 +37,17 @@ - (instancetype)initWithFrame:(CGRect)frame name:NSControlTextDidChangeNotification object:self]; + self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + self.allowsEditingTextAttributes = NO; + self.drawsBackground = NO; + self.focusRingType = NSFocusRingTypeNone; + self.bordered = NO; + self.bezeled = NO; + + self.cell.scrollable = YES; + self.cell.usesSingleLineMode = YES; + object_setClass(self.cell, RCTUITextFieldCell.class); + _textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self]; } @@ -48,14 +64,6 @@ - (void)_textDidChange _textWasPasted = NO; } -#pragma mark - Properties - -- (void)setPaddingInsets:(NSEdgeInsets)paddingInsets -{ - _paddingInsets = paddingInsets; - [self setNeedsLayout:YES]; -} - #pragma mark - Caret Manipulation //- (CGRect)caretRectForPosition:(UITextPosition *)position @@ -129,6 +137,7 @@ - (void)textDidEndEditing:(NSNotification *)notification - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { + self.currentEditor.textContainerInset = (NSSize){_paddingInsets.left, _paddingInsets.top}; [_textInputDelegateAdapter textFieldDidFocus]; return YES; } @@ -157,4 +166,41 @@ - (void)setAttributedText:(NSAttributedString *)attributedText self.attributedStringValue = attributedText; } +- (void)setPaddingInsets:(NSEdgeInsets)paddingInsets +{ + // Account for strange rendering offset. (NSTextView doesn't have this issue) + paddingInsets.top -= 1; + paddingInsets.left -= 2; + + _paddingInsets = paddingInsets; +} + +@end + +@implementation RCTUITextFieldCell + +@dynamic controlView; + +static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { + rect.origin.x += insets.left; + rect.origin.y += insets.top; + rect.size.width -= (insets.left + insets.right); + rect.size.height -= (insets.top + insets.bottom); + return rect; +} + +- (NSRect)drawingRectForBounds:(NSRect)bounds +{ + NSRect rect = [super drawingRectForBounds:bounds]; + return NSEdgeInsetsInsetRect(rect, self.controlView.paddingInsets); +} + +- (NSText *)setUpFieldEditorAttributes:(NSTextView *)fieldEditor +{ + fieldEditor.font = self.font; + fieldEditor.textColor = self.textColor; + fieldEditor.backgroundColor = NSColor.clearColor; + return fieldEditor; +} + @end From 6118d62c043374833b8dcf0a0f5805b0af119220 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 12:53:31 -0500 Subject: [PATCH 121/143] add "selectAll:" method to RCTBackedTextInputViewProtocol --- Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h | 2 ++ Libraries/Text/TextInput/Singleline/RCTUITextField.m | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index ad735f4331..0e23826bbf 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -40,6 +40,8 @@ NS_ASSUME_NONNULL_BEGIN // Use `attributedText.string` instead. @property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; +- (void)selectAll:(nullable id)sender; + @end NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 8581681ad0..889a4b4771 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -175,6 +175,11 @@ - (void)setPaddingInsets:(NSEdgeInsets)paddingInsets _paddingInsets = paddingInsets; } +- (void)selectAll:(nullable id)sender +{ + [self.currentEditor selectAll:sender]; +} + @end @implementation RCTUITextFieldCell From 08fe7b1595ec1144bf6957a0c36ee55f66cc8c4b Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 12:58:09 -0500 Subject: [PATCH 122/143] fix: "selectTextOnFocus" prop for 1-line TextInput The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder"). To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop. --- Libraries/Text/TextInput/Singleline/RCTUITextField.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 889a4b4771..e47d1f0197 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -138,7 +138,7 @@ - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { self.currentEditor.textContainerInset = (NSSize){_paddingInsets.left, _paddingInsets.top}; - [_textInputDelegateAdapter textFieldDidFocus]; + [_textInputDelegateAdapter performSelector:@selector(textFieldDidFocus) withObject:nil afterDelay:0.0]; return YES; } return NO; From 2d4746f1538824ec9c526f9359b7a29f585d22cc Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 12:59:33 -0500 Subject: [PATCH 123/143] remove unnecessary methods from RCTUITextField --- .../TextInput/Singleline/RCTUITextField.m | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index e47d1f0197..6b1f0811b6 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -64,29 +64,6 @@ - (void)_textDidChange _textWasPasted = NO; } -#pragma mark - Caret Manipulation - -//- (CGRect)caretRectForPosition:(UITextPosition *)position -//{ -// if (_caretHidden) { -// return CGRectZero; -// } -// -// return [super caretRectForPosition:position]; -//} - -#pragma mark - Positioning Overrides - -//- (CGRect)textRectForBounds:(CGRect)bounds -//{ -// return NSEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); -//} - -//- (CGRect)editingRectForBounds:(CGRect)bounds -//{ -// return [self textRectForBounds:bounds]; -//} - #pragma mark - Overrides - (NSRange)selectedTextRange From 3ddc57f49aee9f263ab0882d2b02fea080dff4c4 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Fri, 22 Feb 2019 14:05:04 -0500 Subject: [PATCH 124/143] fix: multiline TextInput padding --- Libraries/Components/TextInput/TextInput.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index a68b33d933..932d1a7ad2 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -22,7 +22,6 @@ const createReactClass = require('create-react-class'); const PropTypes = require('prop-types'); const NativeModules = require('NativeModules'); const ReactNative = require('ReactNative'); -const StyleSheet = require('StyleSheet'); const Text = require('Text'); const TextInputState = require('TextInputState'); /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error @@ -698,7 +697,6 @@ const TextInput = createReactClass({ if (props.inputView) { children = [children, props.inputView]; } - props.style.unshift(styles.multilineInput); textContainer = ( Date: Fri, 22 Feb 2019 15:39:01 -0500 Subject: [PATCH 125/143] feat: support tabbing between TextInput views --- Libraries/Text/TextInput/Multiline/RCTUITextView.m | 14 ++++++++++++++ React/Views/RCTWindow.m | 3 +++ 2 files changed, 17 insertions(+) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 5d1895852a..87196d1fa1 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -107,6 +107,20 @@ - (BOOL)becomeFirstResponder return NO; } +- (void)keyDown:(NSEvent *)event +{ + // Intercept "tab" key for focus control. + if (event.keyCode == 48) { + if (event.modifierFlags & NSShiftKeyMask) { + [self.window selectPreviousKeyView:nil]; + } else { + [self.window selectNextKeyView:nil]; + } + } else { + [super keyDown:event]; + } +} + - (void)paste:(id)sender { [super paste:sender]; diff --git a/React/Views/RCTWindow.m b/React/Views/RCTWindow.m index fd17aa7e93..ac5517a8ec 100644 --- a/React/Views/RCTWindow.m +++ b/React/Views/RCTWindow.m @@ -46,6 +46,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _mouseInfo[@"changedTouches"] = @[]; // Required for "mouseMove" events _mouseInfo[@"identifier"] = @0; // Required for "touch*" events + self.initialFirstResponder = nil; + self.autorecalculatesKeyViewLoop = YES; + // The owner must set "contentView" manually. super.contentView = nil; From 1e6f77a2825370925d9dc516b0a4be3b4fec0ec5 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 23 Feb 2019 14:42:43 -0500 Subject: [PATCH 126/143] fix: TextInput cursor defaults to end of text The cursor still goes where the user clicked. This change affects programmatic focus and tabbing. --- Libraries/Text/TextInput/Multiline/RCTUITextView.m | 3 +++ Libraries/Text/TextInput/Singleline/RCTUITextField.m | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 87196d1fa1..30d3da681b 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -101,6 +101,9 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { + // Move the cursor to the end of the current text. Note: Mouse clicks override this selection (which is intended). + self.selectedRange = NSMakeRange(self.textStorage.length, 0); + [_textInputDelegateAdapter performSelector:@selector(textViewDidFocus) withObject:nil afterDelay:0.0]; return YES; } diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 6b1f0811b6..bfdd65c43f 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -114,6 +114,9 @@ - (void)textDidEndEditing:(NSNotification *)notification - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { + // Move the cursor to the end of the current text. Note: Mouse clicks override this selection (which is intended). + self.currentEditor.selectedRange = NSMakeRange(self.stringValue.length, 0); + self.currentEditor.textContainerInset = (NSSize){_paddingInsets.left, _paddingInsets.top}; [_textInputDelegateAdapter performSelector:@selector(textFieldDidFocus) withObject:nil afterDelay:0.0]; return YES; From 02273b7aa66aac41073be763a8f9f5ed961d148e Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 23 Feb 2019 17:20:12 -0500 Subject: [PATCH 127/143] fix: race condition with RCTNativeModule::invoke and invalid bridge Taken from: https://github.com/facebook/react-native/commit/29245e96cb90fbf26e2b3aa1f946db57ddcdde2b --- React/CxxModule/RCTNativeModule.mm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/React/CxxModule/RCTNativeModule.mm b/React/CxxModule/RCTNativeModule.mm index 25e62cb330..6971575552 100644 --- a/React/CxxModule/RCTNativeModule.mm +++ b/React/CxxModule/RCTNativeModule.mm @@ -73,11 +73,16 @@ invokeInner(weakBridge, weakModuleData, methodId, std::move(params)); }; - dispatch_queue_t queue = m_moduleData.methodQueue; - if (queue == RCTJSThread) { - block(); - } else if (queue) { - dispatch_async(queue, block); + if (m_bridge.valid) { + dispatch_queue_t queue = m_moduleData.methodQueue; + if (queue == RCTJSThread) { + block(); + } else if (queue) { + dispatch_async(queue, block); + } + } else { + RCTLogError(@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) with an invalid bridge.", + methodId, m_moduleData.name); } } From 46147031e77d6539ad3fbefb244ba4c18638aaa1 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 10:26:47 -0500 Subject: [PATCH 128/143] Properly validate JS->native method calls Between invalidating a bridge and suspending its JS thread, native modules may have their methods called. Only warn when a native module has been invalidated, which happens right before its JS thread is suspended. Avoid initializing a native module's instance if its bridge is invalidated. --- React/Base/RCTModuleData.h | 1 + React/Base/RCTModuleData.mm | 13 +++++++++---- React/CxxBridge/RCTCxxBridge.mm | 9 +++------ React/CxxModule/RCTNativeModule.mm | 6 +++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index e12d8d1bf1..74a0e557ae 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -53,6 +53,7 @@ typedef id(^RCTBridgeModuleProvider)(void); @property (nonatomic, strong, readonly) Class moduleClass; @property (nonatomic, copy, readonly) NSString *name; +@property (nonatomic, assign, readonly) BOOL valid; /** * Returns the module methods. Note that this will gather the methods the first diff --git a/React/Base/RCTModuleData.mm b/React/Base/RCTModuleData.mm index e333f0e2f7..05d3242e0d 100644 --- a/React/Base/RCTModuleData.mm +++ b/React/Base/RCTModuleData.mm @@ -27,6 +27,7 @@ @implementation RCTModuleData RCTBridgeModuleProvider _moduleProvider; std::mutex _instanceLock; BOOL _setupComplete; + BOOL _valid; } @synthesize methods = _methods; @@ -84,6 +85,7 @@ - (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge { if (self = [super init]) { + _valid = YES; _bridge = bridge; _moduleClass = moduleClass; _moduleProvider = [moduleProvider copy]; @@ -96,6 +98,7 @@ - (instancetype)initWithModuleInstance:(id)instance bridge:(RCTBridge *)bridge { if (self = [super init]) { + _valid = YES; _bridge = bridge; _instance = instance; _moduleClass = [instance class]; @@ -372,15 +375,17 @@ - (NSArray *)config - (dispatch_queue_t)methodQueue { - (void)[self instance]; - RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@, bridge.valid: %d)", - self, _instance, _bridge.valid); + if (_bridge.valid) { + id instance = self.instance; + RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@)", + self, instance); + } return _methodQueue; } - (void)invalidate { - _methodQueue = nil; + _valid = NO; } - (NSString *)description diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 96c727583b..3715d91c77 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -951,20 +951,17 @@ - (void)invalidate // wrappers) or we may have invalid pointers still in flight. dispatch_group_t moduleInvalidation = dispatch_group_create(); for (RCTModuleData *moduleData in self->_moduleDataByID) { + [moduleData invalidate]; + // Be careful when grabbing an instance here, we don't want to instantiate // any modules just to invalidate them. - if (![moduleData hasInstance]) { - continue; - } - - if ([moduleData.instance respondsToSelector:@selector(invalidate)]) { + if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(invalidate)]) { dispatch_group_enter(moduleInvalidation); [self dispatchBlock:^{ [(id)moduleData.instance invalidate]; dispatch_group_leave(moduleInvalidation); } queue:moduleData.methodQueue]; } - [moduleData invalidate]; } if (dispatch_group_wait(moduleInvalidation, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC))) { diff --git a/React/CxxModule/RCTNativeModule.mm b/React/CxxModule/RCTNativeModule.mm index 6971575552..15928d69ec 100644 --- a/React/CxxModule/RCTNativeModule.mm +++ b/React/CxxModule/RCTNativeModule.mm @@ -73,7 +73,7 @@ invokeInner(weakBridge, weakModuleData, methodId, std::move(params)); }; - if (m_bridge.valid) { + if (m_moduleData.valid) { dispatch_queue_t queue = m_moduleData.methodQueue; if (queue == RCTJSThread) { block(); @@ -81,8 +81,8 @@ dispatch_async(queue, block); } } else { - RCTLogError(@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) with an invalid bridge.", - methodId, m_moduleData.name); + RCTLogWarn(@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) after the module was invalidated.", + methodId, m_moduleData.name); } } From 2439b702b1784bd49daf18d7a02fc740149ec559 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 15:30:26 -0500 Subject: [PATCH 129/143] feat: add RCTFieldEditor This gives each RCTUITextField its own field editor. This is required in order to fix paste detection and the blurOnSubmit prop. --- .../Text/RCTText.xcodeproj/project.pbxproj | 8 +++++++ .../TextInput/Singleline/RCTFieldEditor.h | 23 ++++++++++++++++++ .../TextInput/Singleline/RCTFieldEditor.m | 24 +++++++++++++++++++ .../TextInput/Singleline/RCTUITextField.m | 16 +++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 Libraries/Text/TextInput/Singleline/RCTFieldEditor.h create mode 100644 Libraries/Text/TextInput/Singleline/RCTFieldEditor.m diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 51d005e852..0e7be03d66 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -60,6 +60,8 @@ 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 705EDE4422138919000CAA67 /* NSLabel.h */; }; 70588F652227336100CD1EEA /* NSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE422213890E000CAA67 /* NSLabel.m */; }; 70588F6922273F2300CD1EEA /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70588F6822273F2300CD1EEA /* AppKit.framework */; }; + 70588F6C222741ED00CD1EEA /* RCTFieldEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = 70588F6B222741EC00CD1EEA /* RCTFieldEditor.m */; }; + 70588F6D222741F600CD1EEA /* RCTFieldEditor.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 70588F6A222741EC00CD1EEA /* RCTFieldEditor.h */; }; 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */; }; @@ -73,6 +75,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70588F6D222741F600CD1EEA /* RCTFieldEditor.h in Copy Headers */, 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */, 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */, 70588F392227118900CD1EEA /* NSFont+LineHeight.h in Copy Headers */, @@ -159,6 +162,8 @@ 5956B12E200FEBAA008D9D16 /* RCTVirtualTextShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextShadowView.m; sourceTree = ""; }; 5956B12F200FEBAA008D9D16 /* RCTConvert+Text.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Text.m"; sourceTree = ""; }; 70588F6822273F2300CD1EEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 70588F6A222741EC00CD1EEA /* RCTFieldEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFieldEditor.h; sourceTree = ""; }; + 70588F6B222741EC00CD1EEA /* RCTFieldEditor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFieldEditor.m; sourceTree = ""; }; 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+CGPath.h"; sourceTree = ""; }; 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+LineHeight.h"; sourceTree = ""; }; @@ -252,6 +257,8 @@ 5956B100200FEBA9008D9D16 /* Singleline */ = { isa = PBXGroup; children = ( + 70588F6A222741EC00CD1EEA /* RCTFieldEditor.h */, + 70588F6B222741EC00CD1EEA /* RCTFieldEditor.m */, 5956B104200FEBA9008D9D16 /* RCTSinglelineTextInputView.h */, 5956B101200FEBA9008D9D16 /* RCTSinglelineTextInputView.m */, 5956B102200FEBA9008D9D16 /* RCTSinglelineTextInputViewManager.h */, @@ -387,6 +394,7 @@ 5956B13C200FEBAA008D9D16 /* RCTUITextView.m in Sources */, 5956B136200FEBAA008D9D16 /* RCTBackedTextInputDelegateAdapter.m in Sources */, 5956B13E200FEBAA008D9D16 /* RCTBaseTextViewManager.m in Sources */, + 70588F6C222741ED00CD1EEA /* RCTFieldEditor.m in Sources */, 5956B145200FEBAA008D9D16 /* RCTVirtualTextShadowView.m in Sources */, 5956B142200FEBAA008D9D16 /* RCTTextViewManager.m in Sources */, 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */, diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h new file mode 100644 index 0000000000..71ee752fb8 --- /dev/null +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h @@ -0,0 +1,23 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@class RCTFieldEditor; + +@protocol RCTFieldEditorDelegate +@end + +@interface RCTFieldEditor : NSTextView +@property (nullable, weak) id delegate; +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m new file mode 100644 index 0000000000..47c779a6a6 --- /dev/null +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m @@ -0,0 +1,24 @@ +/** + * 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 "RCTFieldEditor.h" + +@implementation RCTFieldEditor + +@dynamic delegate; + +- (instancetype)init +{ + if (self = [super init]) { + self.fieldEditor = YES; + } + return self; +} + +@end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index bfdd65c43f..e3e0a7e5b0 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -14,6 +14,7 @@ #import #import "RCTBackedTextInputDelegateAdapter.h" +#import "RCTFieldEditor.h" // The "field editor" is a NSTextView whose delegate is this NSTextField. @interface NSTextField () @@ -23,6 +24,10 @@ @interface RCTUITextFieldCell : NSTextFieldCell @property (nullable, assign) RCTUITextField *controlView; @end +@interface RCTUITextField (RCTFieldEditor) +- (RCTFieldEditor *)currentEditor; +@end + @implementation RCTUITextField { RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter; } @@ -163,6 +168,9 @@ - (void)selectAll:(nullable id)sender @end @implementation RCTUITextFieldCell +{ + RCTFieldEditor *_fieldEditor; +} @dynamic controlView; @@ -180,6 +188,14 @@ - (NSRect)drawingRectForBounds:(NSRect)bounds return NSEdgeInsetsInsetRect(rect, self.controlView.paddingInsets); } +- (NSTextView *)fieldEditorForView:(NSView *)controlView +{ + if (_fieldEditor == nil) { + _fieldEditor = [RCTFieldEditor new]; + } + return _fieldEditor; +} + - (NSText *)setUpFieldEditorAttributes:(NSTextView *)fieldEditor { fieldEditor.font = self.font; From 50b6997c16031bed758a1bcf14445ad40c2b6fcb Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 15:35:48 -0500 Subject: [PATCH 130/143] fix: paste detection in RCTUITextField --- .../Text/TextInput/Singleline/RCTFieldEditor.h | 2 ++ .../Text/TextInput/Singleline/RCTFieldEditor.m | 12 ++++++++++++ .../Text/TextInput/Singleline/RCTUITextField.m | 13 +++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h index 71ee752fb8..037eed1d7e 100644 --- a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h @@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN @class RCTFieldEditor; @protocol RCTFieldEditorDelegate +@optional +- (void)fieldEditor:(RCTFieldEditor *)editor didPaste:(NSString *)text; @end @interface RCTFieldEditor : NSTextView diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m index 47c779a6a6..1ae275ad4b 100644 --- a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m @@ -21,4 +21,16 @@ - (instancetype)init return self; } +- (void)paste:(id)sender +{ + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + NSString *text = [pasteboard stringForType:NSPasteboardTypeString]; + + if (text && [self.delegate respondsToSelector:@selector(fieldEditor:didPaste:)]) { + [self.delegate fieldEditor:self didPaste:text]; + } + + [super paste:sender]; +} + @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index e3e0a7e5b0..1959dd5dc5 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -88,12 +88,6 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not [_textInputDelegateAdapter selectedTextRangeWasSet]; } -- (void)paste:(id)sender -{ - [self.currentEditor paste:sender]; - _textWasPasted = YES; -} - - (void)textViewDidChangeSelection:(NSNotification *)notification { [super textViewDidChangeSelection:notification]; @@ -165,6 +159,13 @@ - (void)selectAll:(nullable id)sender [self.currentEditor selectAll:sender]; } +#pragma mark - RCTFieldEditorDelegate + +- (void)fieldEditor:(RCTFieldEditor *)editor didPaste:(NSString *)text +{ + _textWasPasted = YES; +} + @end @implementation RCTUITextFieldCell From 06461a18f58fd729e11f8e3c42ced278d877a72a Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 15:25:28 -0500 Subject: [PATCH 131/143] fix: TextInput "blurOnSubmit" prop --- Libraries/Text/NSText+Editing.h | 20 +++++++++++ Libraries/Text/NSText+Editing.m | 26 +++++++++++++++ .../Text/RCTText.xcodeproj/project.pbxproj | 8 +++++ .../Text/TextInput/Multiline/RCTUITextView.h | 6 ---- .../Text/TextInput/Multiline/RCTUITextView.m | 33 ++++--------------- .../RCTBackedTextInputDelegateAdapter.m | 6 +--- .../Text/TextInput/RCTBaseTextInputView.m | 17 +++------- .../TextInput/Singleline/RCTFieldEditor.h | 1 + .../TextInput/Singleline/RCTFieldEditor.m | 9 +++++ .../TextInput/Singleline/RCTUITextField.m | 9 +++++ 10 files changed, 85 insertions(+), 50 deletions(-) create mode 100644 Libraries/Text/NSText+Editing.h create mode 100644 Libraries/Text/NSText+Editing.m diff --git a/Libraries/Text/NSText+Editing.h b/Libraries/Text/NSText+Editing.h new file mode 100644 index 0000000000..0705bef972 --- /dev/null +++ b/Libraries/Text/NSText+Editing.h @@ -0,0 +1,20 @@ +/** + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface NSText (Editing) + +- (BOOL)endEditing:(BOOL)force; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/NSText+Editing.m b/Libraries/Text/NSText+Editing.m new file mode 100644 index 0000000000..ff5898718d --- /dev/null +++ b/Libraries/Text/NSText+Editing.m @@ -0,0 +1,26 @@ +/** + * 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 "NSText+Editing.h" + +@implementation NSText (Editing) + +- (BOOL)endEditing:(BOOL)force +{ + if (self != self.window.firstResponder) { + return YES; + } + if (force || [self.delegate textShouldEndEditing:self]) { + [self.window makeFirstResponder:nil]; + return YES; + } + return NO; +} + +@end diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj index 0e7be03d66..2725edc2a1 100644 --- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj +++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj @@ -62,6 +62,8 @@ 70588F6922273F2300CD1EEA /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70588F6822273F2300CD1EEA /* AppKit.framework */; }; 70588F6C222741ED00CD1EEA /* RCTFieldEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = 70588F6B222741EC00CD1EEA /* RCTFieldEditor.m */; }; 70588F6D222741F600CD1EEA /* RCTFieldEditor.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 70588F6A222741EC00CD1EEA /* RCTFieldEditor.h */; }; + 70588F702227427700CD1EEA /* NSText+Editing.m in Sources */ = {isa = PBXBuildFile; fileRef = 70588F6E2227427600CD1EEA /* NSText+Editing.m */; }; + 70588F712227428000CD1EEA /* NSText+Editing.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 70588F6F2227427700CD1EEA /* NSText+Editing.h */; }; 705EDE3022132863000CAA67 /* NSBezierPath+CGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */; }; 705EDE3D221378CC000CAA67 /* NSFont+LineHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3C221378CC000CAA67 /* NSFont+LineHeight.m */; }; 705EDE4022137BE7000CAA67 /* NSValue+CoreGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 705EDE3F22137BE7000CAA67 /* NSValue+CoreGraphics.m */; }; @@ -75,6 +77,7 @@ dstPath = include/RCTText; dstSubfolderSpec = 16; files = ( + 70588F712227428000CD1EEA /* NSText+Editing.h in Copy Headers */, 70588F6D222741F600CD1EEA /* RCTFieldEditor.h in Copy Headers */, 70588F642227335B00CD1EEA /* NSLabel.h in Copy Headers */, 70588F3A222715DD00CD1EEA /* NSValue+CoreGraphics.h in Copy Headers */, @@ -164,6 +167,8 @@ 70588F6822273F2300CD1EEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 70588F6A222741EC00CD1EEA /* RCTFieldEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFieldEditor.h; sourceTree = ""; }; 70588F6B222741EC00CD1EEA /* RCTFieldEditor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFieldEditor.m; sourceTree = ""; }; + 70588F6E2227427600CD1EEA /* NSText+Editing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSText+Editing.m"; sourceTree = ""; }; + 70588F6F2227427700CD1EEA /* NSText+Editing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSText+Editing.h"; sourceTree = ""; }; 705EDE2E22132863000CAA67 /* NSBezierPath+CGPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+CGPath.h"; sourceTree = ""; }; 705EDE2F22132863000CAA67 /* NSBezierPath+CGPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+CGPath.m"; sourceTree = ""; }; 705EDE3B221378CC000CAA67 /* NSFont+LineHeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+LineHeight.h"; sourceTree = ""; }; @@ -189,6 +194,8 @@ 58B511921A9E6C1200147676 = { isa = PBXGroup; children = ( + 70588F6F2227427700CD1EEA /* NSText+Editing.h */, + 70588F6E2227427600CD1EEA /* NSText+Editing.m */, 705EDE4422138919000CAA67 /* NSLabel.h */, 705EDE422213890E000CAA67 /* NSLabel.m */, 705EDE3E22137BE7000CAA67 /* NSValue+CoreGraphics.h */, @@ -408,6 +415,7 @@ 5956B138200FEBAA008D9D16 /* RCTTextSelection.m in Sources */, 5956B130200FEBAA008D9D16 /* RCTRawTextShadowView.m in Sources */, 5956B141200FEBAA008D9D16 /* NSTextStorage+FontScaling.m in Sources */, + 70588F702227427700CD1EEA /* NSText+Editing.m in Sources */, 5956B132200FEBAA008D9D16 /* RCTSinglelineTextInputView.m in Sources */, 5956B13A200FEBAA008D9D16 /* RCTMultilineTextInputView.m in Sources */, 5956B133200FEBAA008D9D16 /* RCTUITextField.m in Sources */, diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index febcb0874b..bb56fe491b 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -33,10 +33,4 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface NSTextView (EditingControl) - -- (BOOL)endEditing:(BOOL)force; - -@end - NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 30d3da681b..e2c3237b08 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -22,11 +22,6 @@ @implementation RCTUITextView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textDidChange) - name:NSControlTextDidChangeNotification - object:self]; - _textInputDelegateAdapter = [[RCTBackedTextViewDelegateAdapter alloc] initWithTextView:self]; } @@ -50,13 +45,6 @@ - (NSString *)accessibilityLabel return accessibilityLabel; } -#pragma mark - Properties - -- (void)textDidChange -{ - _textWasPasted = NO; -} - #pragma mark - Overrides - (NSString *)text @@ -78,7 +66,6 @@ - (NSAttributedString *)attributedText - (void)setAttributedText:(NSAttributedString *)attributedText { [self.textStorage setAttributedString:attributedText]; - [self textDidChange]; } #pragma mark - Overrides @@ -126,8 +113,8 @@ - (void)keyDown:(NSEvent *)event - (void)paste:(id)sender { - [super paste:sender]; _textWasPasted = YES; + [super paste:sender]; } //- (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated @@ -145,20 +132,12 @@ - (void)setPaddingInsets:(NSEdgeInsets)paddingInsets self.textContainerInset = (NSSize){paddingInsets.left, paddingInsets.top}; } -@end - -@implementation NSTextView (EditingControl) - -- (BOOL)endEditing:(BOOL)force +- (void)didChangeText { - if (self != self.window.firstResponder) { - return YES; - } - if (force || [self.delegate textShouldEndEditing:self]) { - [self.window makeFirstResponder:nil]; - return YES; - } - return NO; + [super didChangeText]; + + _textWasPasted = NO; + [self invalidateIntrinsicContentSize]; } @end diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index 0ce0eac707..ec7118be76 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -9,6 +9,7 @@ #import "RCTBackedTextInputDelegateAdapter.h" #import "RCTUITextView.h" +#import "NSText+Editing.h" #pragma mark - RCTBackedTextFieldDelegateAdapter (for NSTextField) @@ -79,11 +80,6 @@ - (BOOL)shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text return result; } -//- (BOOL)textFieldShouldReturn:(__unused NSTextField *)textField -//{ -// return [_backedTextInputView.textInputDelegate textInputShouldReturn]; -//} - #pragma mark - UIControlEventEditing* Family Events - (void)controlTextDidChange:(NSNotification *)notification diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index db86d1065c..b9a4b8b2e2 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -213,23 +213,16 @@ - (void)textInputDidEndEditing - (BOOL)textInputShouldReturn { - // We send `submit` event here, in `textInputShouldReturn` - // (not in `textInputDidReturn)`, because of semantic of the event: - // `onSubmitEditing` is called when "Submit" button - // (the blue key on onscreen keyboard) did pressed - // (no connection to any specific "submitting" process). - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit - reactTag:self.reactTag - text:self.backedTextInputView.attributedText.string - key:nil - eventCount:_nativeEventCount]; - return _blurOnSubmit; } - (void)textInputDidReturn { - // Does nothing. + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit + reactTag:self.reactTag + text:self.backedTextInputView.attributedText.string + key:nil + eventCount:_nativeEventCount]; } - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h index 037eed1d7e..80bc2bd0e5 100644 --- a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol RCTFieldEditorDelegate @optional - (void)fieldEditor:(RCTFieldEditor *)editor didPaste:(NSString *)text; +- (void)fieldEditorDidReturn:(RCTFieldEditor *)editor; @end @interface RCTFieldEditor : NSTextView diff --git a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m index 1ae275ad4b..a474013af9 100644 --- a/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m +++ b/Libraries/Text/TextInput/Singleline/RCTFieldEditor.m @@ -33,4 +33,13 @@ - (void)paste:(id)sender [super paste:sender]; } +- (void)keyDown:(NSEvent *)event +{ + [super keyDown:event]; + + if (event.keyCode == 36 && [self.delegate respondsToSelector:@selector(fieldEditorDidReturn:)]) { + [self.delegate fieldEditorDidReturn:self]; + } +} + @end diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 1959dd5dc5..45da45ea64 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -15,6 +15,7 @@ #import "RCTBackedTextInputDelegateAdapter.h" #import "RCTFieldEditor.h" +#import "NSText+Editing.h" // The "field editor" is a NSTextView whose delegate is this NSTextField. @interface NSTextField () @@ -166,6 +167,14 @@ - (void)fieldEditor:(RCTFieldEditor *)editor didPaste:(NSString *)text _textWasPasted = YES; } +- (void)fieldEditorDidReturn:(RCTFieldEditor *)editor +{ + if ([self.textInputDelegate textInputShouldReturn]) { + [self.textInputDelegate textInputDidReturn]; + [self.currentEditor endEditing:NO]; + } +} + @end @implementation RCTUITextFieldCell From 37808bc62593bd5a403b3bc62d1c4db4bcc938c4 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:03:50 -0500 Subject: [PATCH 132/143] feat: wrap multiline TextInput with NSScrollView --- .../Multiline/RCTMultilineTextInputView.h | 16 +++ .../Multiline/RCTMultilineTextInputView.m | 135 +++++++++++++----- .../RCTMultilineTextInputViewManager.m | 2 + .../Text/TextInput/Multiline/RCTUITextView.m | 15 -- .../Text/TextInput/RCTBaseTextInputView.h | 2 +- .../Text/TextInput/RCTBaseTextInputView.m | 2 - .../TextInput/RCTBaseTextInputViewManager.m | 1 - .../Singleline/RCTSinglelineTextInputView.m | 16 +++ 8 files changed, 132 insertions(+), 57 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h index 7d28023597..dc43082674 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h @@ -11,8 +11,24 @@ NS_ASSUME_NONNULL_BEGIN +@class RCTTextScrollView; + @interface RCTMultilineTextInputView : RCTBaseTextInputView +@property (nonatomic, copy) RCTDirectEventBlock onScroll; +@end + +#pragma mark - + +@protocol RCTTextScrollViewDelegate +- (void)scrollViewDidScroll:(RCTTextScrollView *)scrollView; +@end + +#pragma mark - +@interface RCTTextScrollView : NSScrollView +@property (nonatomic, weak) id delegate; +@property (nonatomic, assign) BOOL scrollEnabled; +@property (readonly) NSPoint contentOffset; @end NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m index 34fea76810..507a75f401 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m @@ -10,12 +10,17 @@ #import "RCTMultilineTextInputView.h" #import +#import #import "RCTUITextView.h" +@interface RCTMultilineTextInputView () +@end + @implementation RCTMultilineTextInputView { RCTUITextView *_backedTextInputView; + RCTTextScrollView *_scrollView; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -30,18 +35,36 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _backedTextInputView.textColor = [NSColor blackColor]; // This line actually removes 5pt (default value) left and right padding in UITextView. _backedTextInputView.textContainer.lineFragmentPadding = 0; -//#if !TARGET_OS_TV -// _backedTextInputView.scrollsToTop = NO; -//#endif -// _backedTextInputView.scrollEnabled = YES; _backedTextInputView.textInputDelegate = self; - [self addSubview:_backedTextInputView]; + _scrollView = [[RCTTextScrollView alloc] initWithFrame:NSZeroRect]; + _scrollView.documentView = _backedTextInputView; + _scrollView.delegate = self; + + [self addSubview:_scrollView]; } return self; } +- (void)setFrame:(NSRect)frame +{ + [super setFrame:frame]; + _scrollView.frameSize = frame.size; +} + +- (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets +{ + [super setReactBorderInsets:reactBorderInsets]; + _scrollView.contentInsets = self.reactCompoundInsets; +} + +- (void)setReactPaddingInsets:(NSEdgeInsets)reactPaddingInsets +{ + [super setReactPaddingInsets:reactPaddingInsets]; + _scrollView.contentInsets = self.reactCompoundInsets; +} + RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)coder) @@ -52,38 +75,74 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge #pragma mark - NSScrollViewDelegate -//- (void)scrollViewDidScroll:(NSScrollView *)scrollView -//{ -// RCTDirectEventBlock onScroll = self.onScroll; -// -// if (onScroll) { -// CGPoint contentOffset = scrollView.contentOffset; -// CGSize contentSize = scrollView.contentSize; -// CGSize size = scrollView.bounds.size; -// NSEdgeInsets contentInset = scrollView.contentInset; -// -// onScroll(@{ -// @"contentOffset": @{ -// @"x": @(contentOffset.x), -// @"y": @(contentOffset.y) -// }, -// @"contentInset": @{ -// @"top": @(contentInset.top), -// @"left": @(contentInset.left), -// @"bottom": @(contentInset.bottom), -// @"right": @(contentInset.right) -// }, -// @"contentSize": @{ -// @"width": @(contentSize.width), -// @"height": @(contentSize.height) -// }, -// @"layoutMeasurement": @{ -// @"width": @(size.width), -// @"height": @(size.height) -// }, -// @"zoomScale": @(scrollView.zoomScale ?: 1), -// }); -// } -//} +- (void)scrollViewDidScroll:(RCTTextScrollView *)scrollView +{ + RCTDirectEventBlock onScroll = self.onScroll; + + if (onScroll) { + NSSize size = scrollView.bounds.size; + NSSize contentSize = scrollView.contentSize; + NSPoint contentOffset = scrollView.contentOffset; + NSEdgeInsets contentInset = scrollView.contentInsets; + + onScroll(@{ + @"contentOffset": @{ + @"x": @(contentOffset.x), + @"y": @(contentOffset.y) + }, + @"contentInset": @{ + @"top": @(contentInset.top), + @"left": @(contentInset.left), + @"bottom": @(contentInset.bottom), + @"right": @(contentInset.right) + }, + @"contentSize": @{ + @"width": @(contentSize.width), + @"height": @(contentSize.height) + }, + @"layoutMeasurement": @{ + @"width": @(size.width), + @"height": @(size.height) + }, + @"zoomScale": @(1), + @"target": self.reactTag, + }); + } +} + +@end + +@implementation RCTTextScrollView + +- (instancetype)initWithFrame:(NSRect)frame +{ + if (self = [super initWithFrame:frame]) { + self.drawsBackground = NO; + self.hasVerticalScroller = YES; + self.automaticallyAdjustsContentInsets = NO; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_didScroll) + name:NSViewBoundsDidChangeNotification + object:self.contentView]; + } + + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (NSPoint)contentOffset +{ + return self.contentView.bounds.origin; +} + +- (void)_didScroll +{ + [self.delegate scrollViewDidScroll:self]; +} @end diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index 36beb97e3f..912dc63e28 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -26,4 +26,6 @@ - (NSView *)view RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.dataDetectorTypes, UIDataDetectorTypes) #endif +RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) + @end diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index e2c3237b08..fd86ca6eba 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -117,21 +117,6 @@ - (void)paste:(id)sender [super paste:sender]; } -//- (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated -//{ -// // Turning off scroll animation. -// // This fixes the problem also known as "flaky scrolling". -// [super setContentOffset:contentOffset animated:NO]; -//} - -#pragma mark - Padding - -- (void)setPaddingInsets:(NSEdgeInsets)paddingInsets -{ - _paddingInsets = paddingInsets; - self.textContainerInset = (NSSize){paddingInsets.left, paddingInsets.top}; -} - - (void)didChangeText { [super didChangeText]; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index c4de0e8843..e81b9159ef 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) RCTDirectEventBlock onSelectionChange; @property (nonatomic, copy, nullable) RCTDirectEventBlock onChange; @property (nonatomic, copy, nullable) RCTDirectEventBlock onTextInput; -@property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; +//@property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; @property (nonatomic, assign) NSInteger mostRecentEventCount; @property (nonatomic, assign) BOOL blurOnSubmit; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index b9a4b8b2e2..472ae87376 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -95,8 +95,6 @@ static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { - (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets { _reactBorderInsets = reactBorderInsets; - // We apply `borderInsets` as `backedTextInputView` layout offset. - self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); [self updatePlaceholderFrame]; [self setNeedsLayout:YES]; } diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 08f85b7498..0941371224 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -58,7 +58,6 @@ @implementation RCTBaseTextInputViewManager RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) -//RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) diff --git a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m index d67b4b95ed..7324c09747 100644 --- a/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m +++ b/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.m @@ -42,4 +42,20 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return _backedTextInputView; } +static inline CGRect NSEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) { + rect.origin.x += insets.left; + rect.origin.y += insets.top; + rect.size.width -= (insets.left + insets.right); + rect.size.height -= (insets.top + insets.bottom); + return rect; +} + +- (void)setReactBorderInsets:(NSEdgeInsets)reactBorderInsets +{ + // We apply `borderInsets` as `backedTextInputView` layout offset. + self.backedTextInputView.frame = NSEdgeInsetsInsetRect(self.bounds, reactBorderInsets); + + [super setReactBorderInsets:reactBorderInsets]; +} + @end From 058a44633cbfb681ad5d10e4dafdf000530a6164 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:07:31 -0500 Subject: [PATCH 133/143] disable "dataDetectorTypes" prop --- .../TextInput/Multiline/RCTMultilineTextInputViewManager.m | 6 +++--- React/Views/RCTWebViewManager.m | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index 912dc63e28..cccabc9134 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -22,9 +22,9 @@ - (NSView *)view #pragma mark - Multiline (aka TextView) specific properties -#if !TARGET_OS_TV -RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.dataDetectorTypes, UIDataDetectorTypes) -#endif +//#if !TARGET_OS_TV +//RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.dataDetectorTypes, UIDataDetectorTypes) +//#endif RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) diff --git a/React/Views/RCTWebViewManager.m b/React/Views/RCTWebViewManager.m index f36e75e57a..7d4605f7f6 100644 --- a/React/Views/RCTWebViewManager.m +++ b/React/Views/RCTWebViewManager.m @@ -49,7 +49,7 @@ - (NSView *)view RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock) RCT_REMAP_VIEW_PROPERTY(allowsInlineMediaPlayback, _webView.allowsInlineMediaPlayback, BOOL) RCT_REMAP_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, _webView.mediaPlaybackRequiresUserAction, BOOL) -RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, _webView.dataDetectorTypes, UIDataDetectorTypes) +//RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, _webView.dataDetectorTypes, UIDataDetectorTypes) RCT_EXPORT_METHOD(goBack:(nonnull NSNumber *)reactTag) { From a2618f86fcf624c81b5efdbdcbdc1b09c99430f9 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:09:06 -0500 Subject: [PATCH 134/143] remove "text" property from RCTBackedTextInputViewProtocol --- .../Text/TextInput/Multiline/RCTUITextView.m | 19 ++++--------------- .../RCTBackedTextInputViewProtocol.h | 2 +- .../TextInput/Singleline/RCTUITextField.m | 10 ---------- 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index fd86ca6eba..a3d93e8ace 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -33,6 +33,8 @@ - (void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; } +#pragma mark - Properties + - (NSString *)accessibilityLabel { NSMutableString *accessibilityLabel = [NSMutableString new]; @@ -45,19 +47,6 @@ - (NSString *)accessibilityLabel return accessibilityLabel; } -#pragma mark - Overrides - -- (NSString *)text -{ - return self.string; -} - -- (void)setText:(NSString *)text -{ - [self setString:text]; - [self textDidChange]; -} - - (NSAttributedString *)attributedText { return self.textStorage; @@ -68,8 +57,6 @@ - (void)setAttributedText:(NSAttributedString *)attributedText [self.textStorage setAttributedString:attributedText]; } -#pragma mark - Overrides - - (NSRange)selectedTextRange { return self.selectedRange; @@ -85,6 +72,8 @@ - (void)setSelectedTextRange:(NSRange)selectedTextRange notifyDelegate:(BOOL)not [super setSelectedRange:selectedTextRange]; } +#pragma mark - Overrides + - (BOOL)becomeFirstResponder { if ([super becomeFirstResponder]) { diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 0e23826bbf..b7614378fa 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -38,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN // This protocol disallows direct access to `text` property because // unwise usage of it can break the `attributeText` behavior. // Use `attributedText.string` instead. -@property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; +//@property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE; - (void)selectAll:(nullable id)sender; diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 45da45ea64..dc0727ec3f 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -126,16 +126,6 @@ - (BOOL)becomeFirstResponder #pragma mark - RCTBackedTextInputViewProtocol -- (NSString *)text -{ - return self.stringValue; -} - -- (void)setText:(NSString *)text -{ - self.stringValue = text; -} - - (NSAttributedString *)attributedText { return self.attributedStringValue; From 311d030470328cccf692a87fd5697ccfe38b55c8 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:11:19 -0500 Subject: [PATCH 135/143] remove excess whitespace The plan to preserve line numbers did not work out due to the amount of required changes, so there's really no point in keeping this whitespace around. --- .../TextInput/RCTBackedTextInputDelegateAdapter.m | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m index ec7118be76..cf77e9afb1 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +++ b/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m @@ -29,19 +29,11 @@ - (instancetype)initWithTextField:(NSTextField * if (self = [super init]) { _backedTextInputView = backedTextInputView; backedTextInputView.delegate = self; - - } return self; } - - - - - - #pragma mark - NSTextFieldDelegate - (BOOL)control:(__unused NSControl *)control textShouldBeginEditing:(__unused NSText *)fieldEditor @@ -91,11 +83,6 @@ - (void)controlTextDidChange:(NSNotification *)notification [self textFieldProbablyDidChangeSelection]; } - - - - - #pragma mark - UIKeyboardInput (private UIKit protocol) // This method allows us to detect a [Backspace] `keyPress` From 92e428019337d4820a9407027173d4e5a3bcea40 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:28:33 -0500 Subject: [PATCH 136/143] test: add "unsupported" property to examples When truthy, the example is not rendered. This allows for less conflicts when merging examples from upstream. --- RNTester/js/RNTesterExampleContainer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RNTester/js/RNTesterExampleContainer.js b/RNTester/js/RNTesterExampleContainer.js index 635cd02147..44de267417 100644 --- a/RNTester/js/RNTesterExampleContainer.js +++ b/RNTester/js/RNTesterExampleContainer.js @@ -19,6 +19,9 @@ const RNTesterPage = require('./RNTesterPage'); class RNTesterExampleContainer extends React.Component { renderExample(example, i) { + if (example.unsupported) { + return null; + } // Filter platform-specific examples var {title, description, platform} = example; if (platform) { From 453b2e982d44db7db44a7bf2230e43c584fb7c7d Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 16:35:14 -0500 Subject: [PATCH 137/143] test: sync TextInputExample with upstream/0.54-stable --- RNTester/js/TextInputExample.macos.js | 1115 +++++++++++++++---------- 1 file changed, 662 insertions(+), 453 deletions(-) diff --git a/RNTester/js/TextInputExample.macos.js b/RNTester/js/TextInputExample.macos.js index 7246a025a1..c2a73781a7 100644 --- a/RNTester/js/TextInputExample.macos.js +++ b/RNTester/js/TextInputExample.macos.js @@ -1,24 +1,20 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. * + * @format * @flow - * @providesModule TextInputExample */ + 'use strict'; -var React = require('react'); -var ReactNative = require('react-native'); -var { - Text, - TextInput, - View, - StyleSheet, -} = ReactNative; +const Button = require('Button'); +const InputAccessoryView = require('InputAccessoryView'); +const React = require('react'); +const ReactNative = require('react-native'); +const {Text, TextInput, View, StyleSheet, Slider, Switch, Alert} = ReactNative; class WithLabel extends React.Component<$FlowFixMeProps> { render() { @@ -41,8 +37,8 @@ class TextEventsExample extends React.Component<{}, $FlowFixMeState> { prev3Text: '', }; - updateText = (text) => { - this.setState((state) => { + updateText = text => { + this.setState(state => { return { curText: text, prevText: state.curText, @@ -56,32 +52,36 @@ class TextEventsExample extends React.Component<{}, $FlowFixMeState> { return ( this.updateText('onFocus')} onBlur={() => this.updateText('onBlur')} - onChange={(event) => this.updateText( - 'onChange text: ' + event.nativeEvent.text - )} - onEndEditing={(event) => this.updateText( - 'onEndEditing text: ' + event.nativeEvent.text - )} - onSubmitEditing={(event) => this.updateText( - 'onSubmitEditing text: ' + event.nativeEvent.text - )} - onSelectionChange={(event) => this.updateText( - 'onSelectionChange range: ' + - event.nativeEvent.selection.start + ',' + - event.nativeEvent.selection.end - )} - onKeyPress={(event) => { + onChange={event => + this.updateText('onChange text: ' + event.nativeEvent.text) + } + onEndEditing={event => + this.updateText('onEndEditing text: ' + event.nativeEvent.text) + } + onSubmitEditing={event => + this.updateText('onSubmitEditing text: ' + event.nativeEvent.text) + } + onSelectionChange={event => + this.updateText( + 'onSelectionChange range: ' + + event.nativeEvent.selection.start + + ',' + + (event.nativeEvent.selection.end || ''), + ) + } + onKeyPress={event => { this.updateText('onKeyPress key: ' + event.nativeEvent.key); }} style={styles.default} /> - {this.state.curText}{'\n'} + {this.state.curText} + {'\n'} (prev: {this.state.prevText}){'\n'} (prev2: {this.state.prev2Text}){'\n'} (prev3: {this.state.prev3Text}) @@ -91,21 +91,56 @@ class TextEventsExample extends React.Component<{}, $FlowFixMeState> { } } +class TextInputAccessoryViewExample extends React.Component<{}, *> { + /* $FlowFixMe(>=0.85.0 site=react_native_ios_fb) This comment suppresses an + * error found when Flow v0.85 was deployed. To see the error, delete this + * comment and run Flow. */ + constructor(props) { + super(props); + this.state = {text: 'Placeholder Text'}; + } + + render() { + const inputAccessoryViewID = 'inputAccessoryView1'; + return ( + + this.setState({text})} + value={this.state.text} + /> + + +