Remember ShadowNode of RawText's parent in attribute string
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
This commit is contained in:
parent
4a4e083e2a
commit
4e841f2114
|
@ -39,6 +39,7 @@ public:
|
|||
std::string string;
|
||||
TextAttributes textAttributes;
|
||||
SharedShadowNode shadowNode;
|
||||
SharedShadowNode parentShadowNode;
|
||||
};
|
||||
|
||||
using Fragments = std::vector<Fragment>;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
@ -209,12 +212,15 @@ NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedSt
|
|||
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)];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue