Skip to content

Commit

Permalink
Remember ShadowNode of RawText's parent in attribute string
Browse files Browse the repository at this point in the history
Summary:
When a user clicks on some text, `RCTSurfaceTouchHandler` will call into a method on `RCTParagraphComponentView`. That method (i.e: `touchEventEmitter`) would be responsible for identifying the closest ancestral `<Text/>` component to which we should dispatch the `onPress` event, given the point where the user clicked. To answer this query, we'll use a data structure called `UIAttributedString`.

This data structure represents a string, and a corresponding mapping from sequences of its characters to some arbitrary data. In this attributed string, we'll map sequences of characters to their closest ancestral `ParagraphShadowNode` or `TextShadowNode`. That way, when we get a click event on `RCTParagraphComponentView`, we can just look at the character that was clicked, and use that information to do a lookup in the attributed string to find the shadow node who's EventEmitter is responsible for processing the click event.

Reviewed By: shergin

Differential Revision: D9696904

fbshipit-source-id: a199649981ad271afa85414ce4c3f056851348be
  • Loading branch information
RSNara authored and facebook-github-bot committed Sep 10, 2018
1 parent 4a4e083 commit 4e841f2
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 4 deletions.
1 change: 1 addition & 0 deletions ReactCommon/fabric/attributedstring/AttributedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class AttributedString:
std::string string;
TextAttributes textAttributes;
SharedShadowNode shadowNode;
SharedShadowNode parentShadowNode;
};

using Fragments = std::vector<Fragment>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ AttributedString BaseTextShadowNode::getAttributedString(
AttributedString::Fragment fragment;
fragment.string = rawTextShadowNode->getProps()->text;
fragment.textAttributes = textAttributes;
fragment.parentShadowNode = parentNode;
attributedString.appendFragment(fragment);
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
NS_ASSUME_NONNULL_BEGIN

NSString *const RCTAttributedStringIsHighlightedAttributeName = @"IsHighlighted";
NSString *const RCTAttributedStringReactTagAttributeName = @"ReactTag";
NSString *const RCTAttributedStringParentShadowNode = @"ParentShadowNode";

/**
* Constructs ready-to-render `NSAttributedString` by given `AttributedString`.
*/
NSAttributedString *RCTNSAttributedStringFromAttributedString(const facebook::react::AttributedString &attributedString);

@interface RCTSharedShadowNodeWrapper : NSObject
@property (nonatomic, assign) facebook::react::SharedShadowNode node;
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include <fabric/textlayoutmanager/RCTFontUtils.h>
#include <fabric/textlayoutmanager/RCTTextPrimitivesConversions.h>

@implementation RCTSharedShadowNodeWrapper
@end

inline static UIFont *RCTEffectiveFontFromTextAttributes(const TextAttributes &textAttributes) {
NSString *fontFamily = [NSString stringWithCString:textAttributes.fontFamily.c_str()
encoding:NSUTF8StringEncoding];
Expand Down Expand Up @@ -209,12 +212,15 @@ inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const Tex
NSMutableAttributedString *nsMutableAttributedStringFragment =
[[NSMutableAttributedString alloc] initWithAttributedString:nsAttributedStringFragment];

if (fragment.shadowNode) {
if (fragment.parentShadowNode) {
RCTSharedShadowNodeWrapper *parentShadowNode = [RCTSharedShadowNodeWrapper new];
parentShadowNode.node = fragment.parentShadowNode;

NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes = @{
RCTAttributedStringReactTagAttributeName: @(fragment.shadowNode->getTag())
RCTAttributedStringParentShadowNode: parentShadowNode
};

[nsMutableAttributedStringFragment setAttributes:additionalTextAttributes
[nsMutableAttributedStringFragment addAttributes:additionalTextAttributes
range:NSMakeRange(0, nsMutableAttributedStringFragment.length)];
}

Expand Down

0 comments on commit 4e841f2

Please sign in to comment.