RCTAttributedTextUtils.mm: Split NSAttributedString creation (#42595)

Summary:
`RCTAttributedTextUtils.mm`: Split `NSAttributedString` creation to functions in preparation for adding new logic here.

This is a minor improvement in the context of my multi-PR work on https://github.com/react-native-community/discussions-and-proposals/issues/695.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[INTERNAL] [CHANGE] - Refactor `NSAttributedString` creation in `RCTAttributedTextUtils.mm`

Pull Request resolved: https://github.com/facebook/react-native/pull/42595

Reviewed By: cipolleschi

Differential Revision: D53001495

Pulled By: sammy-SC

fbshipit-source-id: 52d28e48f0a9d88d44325a73c64737fc7ac97781
This commit is contained in:
Jakub Trzebiatowski
2024-01-25 05:08:35 -08:00
committed by Facebook GitHub Bot
parent 011152318a
commit 2dc2d4db8f
@@ -344,6 +344,55 @@ static void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText)
range:NSMakeRange(0, attributedText.length)];
}
static NSMutableAttributedString *RCTNSAttributedStringFragmentFromFragment(
const AttributedString::Fragment &fragment,
UIImage *placeholderImage)
{
if (fragment.isAttachment()) {
auto layoutMetrics = fragment.parentShadowView.layoutMetrics;
CGRect bounds = {
.origin = {.x = layoutMetrics.frame.origin.x, .y = layoutMetrics.frame.origin.y},
.size = {.width = layoutMetrics.frame.size.width, .height = layoutMetrics.frame.size.height}};
NSTextAttachment *attachment = [NSTextAttachment new];
attachment.image = placeholderImage;
attachment.bounds = bounds;
return [[NSMutableAttributedString attributedStringWithAttachment:attachment] mutableCopy];
} else {
NSString *string = [NSString stringWithUTF8String:fragment.string.c_str()];
if (fragment.textAttributes.textTransform.has_value()) {
auto textTransform = fragment.textAttributes.textTransform.value();
string = RCTNSStringFromStringApplyingTextTransform(string, textTransform);
}
return [[NSMutableAttributedString alloc]
initWithString:string
attributes:RCTNSTextAttributesFromTextAttributes(fragment.textAttributes)];
}
}
static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFromFragment(
const AttributedString::Fragment &fragment,
UIImage *placeholderImage)
{
auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
if (fragment.parentShadowView.componentHandle) {
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
[nsAttributedStringFragment addAttributes:additionalTextAttributes
range:NSMakeRange(0, nsAttributedStringFragment.length)];
}
return nsAttributedStringFragment;
}
NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedString &attributedString)
{
static UIImage *placeholderImage;
@@ -357,42 +406,8 @@ NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedSt
[nsAttributedString beginEditing];
for (auto fragment : attributedString.getFragments()) {
NSMutableAttributedString *nsAttributedStringFragment;
if (fragment.isAttachment()) {
auto layoutMetrics = fragment.parentShadowView.layoutMetrics;
CGRect bounds = {
.origin = {.x = layoutMetrics.frame.origin.x, .y = layoutMetrics.frame.origin.y},
.size = {.width = layoutMetrics.frame.size.width, .height = layoutMetrics.frame.size.height}};
NSTextAttachment *attachment = [NSTextAttachment new];
attachment.image = placeholderImage;
attachment.bounds = bounds;
nsAttributedStringFragment = [[NSMutableAttributedString attributedStringWithAttachment:attachment] mutableCopy];
} else {
NSString *string = [NSString stringWithUTF8String:fragment.string.c_str()];
if (fragment.textAttributes.textTransform.has_value()) {
auto textTransform = fragment.textAttributes.textTransform.value();
string = RCTNSStringFromStringApplyingTextTransform(string, textTransform);
}
nsAttributedStringFragment = [[NSMutableAttributedString alloc]
initWithString:string
attributes:RCTNSTextAttributesFromTextAttributes(fragment.textAttributes)];
}
if (fragment.parentShadowView.componentHandle) {
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
[nsAttributedStringFragment addAttributes:additionalTextAttributes
range:NSMakeRange(0, nsAttributedStringFragment.length)];
}
NSMutableAttributedString *nsAttributedStringFragment =
RCTNSAttributedStringFragmentWithAttributesFromFragment(fragment, placeholderImage);
[nsAttributedString appendAttributedString:nsAttributedStringFragment];
}