-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <Text> and <View> components. * All <Text>-specific APIs were removed from UIManager and co (it's about ~16 public methods which were used exclusively only by <Text>). * 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 UIView for virtual components which reduces memory utilization. * It drastically improves <TextInput> capabilities (e.g. rich text inside single line <TextInput> is now supported). Screenshots: https://cl.ly/2j3r1V0L0324 https://cl.ly/3N2V3C3d3q3R Reviewed By: mmmulani Differential Revision: D6617326 fbshipit-source-id: 35d4d81b35c9870e9557d0211c0e934e6072a41e
- Loading branch information
1 parent
cd263a2
commit 2716f53
Showing
57 changed files
with
2,425 additions
and
2,078 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <React/RCTShadowView.h> | ||
|
||
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <React/RCTShadowView+Layout.h> | ||
|
||
#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<NSString *> *)changedProps | ||
{ | ||
[super didSetProps:changedProps]; | ||
[self dirtyLayout]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
2716f53
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shergin should this be the cause for #18219 ?