mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-06-12 17:48:08 +08:00
Fabric: Using ShadowView instad of ShadowNode inside AttributedString
Summary: That's generally better because: * Avoids exposing ShadowNode to mounting layer; * Enables hashing and comparing the AttributedString based on actual meaningful data (not on just a pointer to ShadowNode). Reviewed By: mdvacca Differential Revision: D13205230 fbshipit-source-id: 7b79c1aad97b10d81e3faa10408be61b74f815cf
This commit is contained in:
committed by
Facebook Github Bot
parent
6c3b05f343
commit
7197aa026b
@@ -18,12 +18,12 @@ using Fragments = AttributedString::Fragments;
|
||||
#pragma mark - Fragment
|
||||
|
||||
bool Fragment::operator==(const Fragment &rhs) const {
|
||||
return std::tie(string, textAttributes, shadowNode, parentShadowNode) ==
|
||||
return std::tie(string, textAttributes, shadowView, parentShadowView) ==
|
||||
std::tie(
|
||||
rhs.string,
|
||||
rhs.textAttributes,
|
||||
rhs.shadowNode,
|
||||
rhs.parentShadowNode);
|
||||
rhs.shadowView,
|
||||
rhs.parentShadowView);
|
||||
}
|
||||
|
||||
bool Fragment::operator!=(const Fragment &rhs) const {
|
||||
@@ -90,11 +90,6 @@ SharedDebugStringConvertibleList AttributedString::getDebugChildren() const {
|
||||
auto propsList =
|
||||
fragment.textAttributes.DebugStringConvertible::getDebugProps();
|
||||
|
||||
if (fragment.shadowNode) {
|
||||
propsList.push_back(std::make_shared<DebugStringConvertibleItem>(
|
||||
"shadowNode", fragment.shadowNode->getDebugDescription()));
|
||||
}
|
||||
|
||||
list.push_back(std::make_shared<DebugStringConvertibleItem>(
|
||||
"Fragment",
|
||||
fragment.string,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <react/core/Sealable.h>
|
||||
#include <react/core/ShadowNode.h>
|
||||
#include <react/debug/DebugStringConvertible.h>
|
||||
#include <react/mounting/ShadowView.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -35,8 +36,8 @@ class AttributedString : public Sealable, public DebugStringConvertible {
|
||||
public:
|
||||
std::string string;
|
||||
TextAttributes textAttributes;
|
||||
SharedShadowNode shadowNode;
|
||||
SharedShadowNode parentShadowNode;
|
||||
ShadowView shadowView;
|
||||
ShadowView parentShadowView;
|
||||
|
||||
bool operator==(const Fragment &rhs) const;
|
||||
bool operator!=(const Fragment &rhs) const;
|
||||
@@ -89,7 +90,11 @@ struct hash<facebook::react::AttributedString::Fragment> {
|
||||
size_t operator()(
|
||||
const facebook::react::AttributedString::Fragment &fragment) const {
|
||||
return std::hash<decltype(fragment.string)>{}(fragment.string) +
|
||||
std::hash<decltype(fragment.textAttributes)>{}(fragment.textAttributes);
|
||||
std::hash<decltype(fragment.textAttributes)>{}(
|
||||
fragment.textAttributes) +
|
||||
std::hash<decltype(fragment.shadowView)>{}(fragment.shadowView) +
|
||||
std::hash<decltype(fragment.parentShadowView)>{}(
|
||||
fragment.parentShadowView);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ rn_xplat_cxx_library(
|
||||
react_native_xplat_target("fabric/debug:debug"),
|
||||
react_native_xplat_target("fabric/core:core"),
|
||||
react_native_xplat_target("fabric/graphics:graphics"),
|
||||
react_native_xplat_target("fabric/mounting:mounting"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -478,8 +478,8 @@ inline folly::dynamic toDynamic(const AttributedString &attributedString) {
|
||||
for (auto fragment : attributedString.getFragments()) {
|
||||
folly::dynamic dynamicFragment = folly::dynamic::object();
|
||||
dynamicFragment["string"] = fragment.string;
|
||||
if (fragment.parentShadowNode) {
|
||||
dynamicFragment["reactTag"] = fragment.parentShadowNode->getTag();
|
||||
if (fragment.parentShadowView.componentHandle) {
|
||||
dynamicFragment["reactTag"] = fragment.parentShadowView.tag;
|
||||
}
|
||||
dynamicFragment["textAttributes"] = toDynamic(fragment.textAttributes);
|
||||
fragments.push_back(dynamicFragment);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <react/components/text/TextProps.h>
|
||||
#include <react/components/text/TextShadowNode.h>
|
||||
#include <react/debug/DebugStringConvertibleItem.h>
|
||||
#include <react/mounting/ShadowView.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -34,10 +35,7 @@ AttributedString BaseTextShadowNode::getAttributedString(
|
||||
// `attributedString` causes a retain cycle (besides that fact that we
|
||||
// don't need it at all). Storing a `ShadowView` instance instead of
|
||||
// `ShadowNode` should properly fix this problem.
|
||||
fragment.parentShadowNode =
|
||||
std::dynamic_pointer_cast<const TextShadowNode>(parentNode)
|
||||
? parentNode
|
||||
: nullptr;
|
||||
fragment.parentShadowView = ShadowView(*parentNode);
|
||||
attributedString.appendFragment(fragment);
|
||||
continue;
|
||||
}
|
||||
@@ -56,7 +54,7 @@ AttributedString BaseTextShadowNode::getAttributedString(
|
||||
|
||||
// Any other kind of ShadowNode
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.shadowNode = childNode;
|
||||
fragment.shadowView = ShadowView(*childNode);
|
||||
fragment.textAttributes = textAttributes;
|
||||
attributedString.appendFragment(fragment);
|
||||
}
|
||||
|
||||
@@ -229,12 +229,9 @@ NSAttributedString *RCTNSAttributedStringFromAttributedString(
|
||||
for (auto fragment : attributedString.getFragments()) {
|
||||
NSAttributedString *nsAttributedStringFragment;
|
||||
|
||||
auto layoutableShadowNode =
|
||||
std::dynamic_pointer_cast<const LayoutableShadowNode>(
|
||||
fragment.shadowNode);
|
||||
auto layoutMetrics = fragment.shadowView.layoutMetrics;
|
||||
|
||||
if (layoutableShadowNode) {
|
||||
auto layoutMetrics = layoutableShadowNode->getLayoutMetrics();
|
||||
if (layoutMetrics != EmptyLayoutMetrics) {
|
||||
CGRect bounds = {.origin = {.x = layoutMetrics.frame.origin.x,
|
||||
.y = layoutMetrics.frame.origin.y},
|
||||
.size = {.width = layoutMetrics.frame.size.width,
|
||||
@@ -259,11 +256,10 @@ NSAttributedString *RCTNSAttributedStringFromAttributedString(
|
||||
[[NSMutableAttributedString alloc]
|
||||
initWithAttributedString:nsAttributedStringFragment];
|
||||
|
||||
if (fragment.parentShadowNode) {
|
||||
if (fragment.parentShadowView.componentHandle) {
|
||||
RCTWeakEventEmitterWrapper *eventEmitterWrapper =
|
||||
[RCTWeakEventEmitterWrapper new];
|
||||
eventEmitterWrapper.eventEmitter =
|
||||
fragment.parentShadowNode->getEventEmitter();
|
||||
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
|
||||
|
||||
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
|
||||
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
|
||||
|
||||
Reference in New Issue
Block a user