diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm index 9497b406f5..9a64f5c30d 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm @@ -8,8 +8,8 @@ #import "RCTParagraphComponentView.h" #import +#import #import -#import #import #import #import @@ -21,7 +21,7 @@ using namespace facebook::react; @implementation RCTParagraphComponentView { - ParagraphShadowNode::ConcreteState::Shared _state; + SharedParagraphLocalData _paragraphLocalData; ParagraphAttributes _paragraphAttributes; } @@ -63,32 +63,32 @@ using namespace facebook::react; _paragraphAttributes = paragraphProps->paragraphAttributes; } -- (void)updateState:(State::Shared)state oldState:(State::Shared)oldState +- (void)updateLocalData:(SharedLocalData)localData oldLocalData:(SharedLocalData)oldLocalData { - _state = std::static_pointer_cast(state); - assert(_state); + _paragraphLocalData = std::static_pointer_cast(localData); + assert(_paragraphLocalData); [self setNeedsDisplay]; } - (void)prepareForRecycle { [super prepareForRecycle]; - _state.reset(); + _paragraphLocalData.reset(); } - (void)drawRect:(CGRect)rect { - if (!_state) { + if (!_paragraphLocalData) { return; } - SharedTextLayoutManager textLayoutManager = _state->getData().layoutManager; + SharedTextLayoutManager textLayoutManager = _paragraphLocalData->getTextLayoutManager(); RCTTextLayoutManager *nativeTextLayoutManager = (__bridge RCTTextLayoutManager *)textLayoutManager->getNativeTextLayoutManager(); CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); - [nativeTextLayoutManager drawAttributedString:_state->getData().attributedString + [nativeTextLayoutManager drawAttributedString:_paragraphLocalData->getAttributedString() paragraphAttributes:_paragraphAttributes frame:frame]; } @@ -102,26 +102,26 @@ using namespace facebook::react; return superAccessibilityLabel; } - if (!_state) { + if (!_paragraphLocalData) { return nil; } - return RCTNSStringFromString(_state->getData().attributedString.getString()); + return RCTNSStringFromString(_paragraphLocalData->getAttributedString().getString()); } - (SharedTouchEventEmitter)touchEventEmitterAtPoint:(CGPoint)point { - if (!_state) { + if (!_paragraphLocalData) { return _eventEmitter; } - SharedTextLayoutManager textLayoutManager = _state->getData().layoutManager; + SharedTextLayoutManager textLayoutManager = _paragraphLocalData->getTextLayoutManager(); RCTTextLayoutManager *nativeTextLayoutManager = (__bridge RCTTextLayoutManager *)textLayoutManager->getNativeTextLayoutManager(); CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); SharedEventEmitter eventEmitter = - [nativeTextLayoutManager getEventEmitterWithAttributeString:_state->getData().attributedString + [nativeTextLayoutManager getEventEmitterWithAttributeString:_paragraphLocalData->getAttributedString() paragraphAttributes:_paragraphAttributes frame:frame atPoint:point]; diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h index a0dd2abff7..83a5292392 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h @@ -64,7 +64,7 @@ class ParagraphComponentDescriptor final private: SharedTextLayoutManager textLayoutManager_; - std::unique_ptr measureCache_; + std::unique_ptr measureCache_; }; } // namespace react diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp new file mode 100644 index 0000000000..fb9426da99 --- /dev/null +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp @@ -0,0 +1,58 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "ParagraphLocalData.h" + +#include +#include + +namespace facebook { +namespace react { + +AttributedString ParagraphLocalData::getAttributedString() const { + return attributedString_; +} + +void ParagraphLocalData::setAttributedString( + AttributedString attributedString) { + ensureUnsealed(); + attributedString_ = attributedString; +} + +SharedTextLayoutManager ParagraphLocalData::getTextLayoutManager() const { + return textLayoutManager_; +} + +void ParagraphLocalData::setTextLayoutManager( + SharedTextLayoutManager textLayoutManager) { + ensureUnsealed(); + textLayoutManager_ = textLayoutManager; +} + +#ifdef ANDROID + +folly::dynamic ParagraphLocalData::getDynamic() const { + return toDynamic(*this); +} + +#endif + +#pragma mark - DebugStringConvertible + +#if RN_DEBUG_STRING_CONVERTIBLE +std::string ParagraphLocalData::getDebugName() const { + return "ParagraphLocalData"; +} + +SharedDebugStringConvertibleList ParagraphLocalData::getDebugProps() const { + return { + debugStringConvertibleItem("attributedString", attributedString_, "")}; +} +#endif + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h new file mode 100644 index 0000000000..15e3705735 --- /dev/null +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +class ParagraphLocalData; + +using SharedParagraphLocalData = std::shared_ptr; + +/* + * LocalData for component. + * Represents what to render and how to render. + */ +class ParagraphLocalData : public LocalData { + public: + /* + * All content of component represented as an `AttributedString`. + */ + AttributedString getAttributedString() const; + void setAttributedString(AttributedString attributedString); + + /* + * `TextLayoutManager` provides a connection to platform-specific + * text rendering infrastructure which is capable to render the + * `AttributedString`. + */ + SharedTextLayoutManager getTextLayoutManager() const; + void setTextLayoutManager(SharedTextLayoutManager textLayoutManager); + +#ifdef ANDROID + folly::dynamic getDynamic() const override; +#endif + +#pragma mark - DebugStringConvertible + +#if RN_DEBUG_STRING_CONVERTIBLE + std::string getDebugName() const override; + SharedDebugStringConvertibleList getDebugProps() const override; +#endif + + private: + AttributedString attributedString_; + SharedTextLayoutManager textLayoutManager_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp index da79a25a1a..d8135cd845 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp @@ -15,8 +15,8 @@ namespace facebook { namespace react { static ParagraphAttributes convertRawProp( - RawProps const &rawProps, - ParagraphAttributes const &defaultParagraphAttributes) { + const RawProps &rawProps, + const ParagraphAttributes &defaultParagraphAttributes) { auto paragraphAttributes = ParagraphAttributes{}; paragraphAttributes.maximumNumberOfLines = convertRawProp( @@ -44,8 +44,8 @@ static ParagraphAttributes convertRawProp( } ParagraphProps::ParagraphProps( - ParagraphProps const &sourceProps, - RawProps const &rawProps) + const ParagraphProps &sourceProps, + const RawProps &rawProps) : ViewProps(sourceProps, rawProps), BaseTextProps(sourceProps, rawProps), paragraphAttributes( diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h index c796eef638..1e1ca67e15 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h @@ -26,7 +26,7 @@ namespace react { class ParagraphProps : public ViewProps, public BaseTextProps { public: ParagraphProps() = default; - ParagraphProps(ParagraphProps const &sourceProps, RawProps const &rawProps); + ParagraphProps(const ParagraphProps &sourceProps, const RawProps &rawProps); #pragma mark - Props @@ -34,12 +34,12 @@ class ParagraphProps : public ViewProps, public BaseTextProps { * Contains all prop values that affect visual representation of the * paragraph. */ - ParagraphAttributes const paragraphAttributes{}; + const ParagraphAttributes paragraphAttributes{}; /* * Defines can the text be selected (and copied) or not. */ - bool const isSelectable{}; + const bool isSelectable{}; #pragma mark - DebugStringConvertible diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp index ec7f4af6be..028652ca5c 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp @@ -6,13 +6,13 @@ */ #include "ParagraphShadowNode.h" +#include "ParagraphLocalData.h" #include "ParagraphMeasurementCache.h" -#include "ParagraphState.h" namespace facebook { namespace react { -char const ParagraphComponentName[] = "Paragraph"; +const char ParagraphComponentName[] = "Paragraph"; AttributedString ParagraphShadowNode::getAttributedString() const { if (!cachedAttributedString_.has_value()) { @@ -33,21 +33,26 @@ void ParagraphShadowNode::setTextLayoutManager( } void ParagraphShadowNode::setMeasureCache( - ParagraphMeasurementCache const *cache) { + const ParagraphMeasurementCache *cache) { ensureUnsealed(); measureCache_ = cache; } -void ParagraphShadowNode::updateStateIfNeeded() { +void ParagraphShadowNode::updateLocalDataIfNeeded() { ensureUnsealed(); auto attributedString = getAttributedString(); - auto const &state = getStateData(); - if (state.attributedString == attributedString) { + auto currentLocalData = + std::static_pointer_cast(getLocalData()); + if (currentLocalData && + currentLocalData->getAttributedString() == attributedString) { return; } - setStateData(ParagraphState{attributedString, textLayoutManager_}); + auto localData = std::make_shared(); + localData->setAttributedString(std::move(attributedString)); + localData->setTextLayoutManager(textLayoutManager_); + setLocalData(localData); } #pragma mark - LayoutableShadowNode @@ -59,16 +64,15 @@ Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const { return {0, 0}; } - ParagraphAttributes const paragraphAttributes = + const ParagraphAttributes paragraphAttributes = getProps()->paragraphAttributes; // Cache results of this function so we don't need to call measure() // repeatedly. if (measureCache_) { return measureCache_->get( - ParagraphMeasurementCacheKey{ - attributedString, paragraphAttributes, layoutConstraints}, - [&](ParagraphMeasurementCacheKey const &key) { + ParagraphMeasurementCacheKey{attributedString, paragraphAttributes, layoutConstraints}, + [&](const ParagraphMeasurementCacheKey &key) { return textLayoutManager_->measure( attributedString, paragraphAttributes, layoutConstraints); }); @@ -79,7 +83,7 @@ Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const { } void ParagraphShadowNode::layout(LayoutContext layoutContext) { - updateStateIfNeeded(); + updateLocalDataIfNeeded(); ConcreteViewShadowNode::layout(layoutContext); } diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h index dd738f169c..9d03af4a3a 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -21,7 +20,7 @@ namespace facebook { namespace react { -extern char const ParagraphComponentName[]; +extern const char ParagraphComponentName[]; using ParagraphEventEmitter = ViewEventEmitter; @@ -33,8 +32,7 @@ using ParagraphEventEmitter = ViewEventEmitter; class ParagraphShadowNode : public ConcreteViewShadowNode< ParagraphComponentName, ParagraphProps, - ParagraphEventEmitter, - ParagraphState>, + ParagraphEventEmitter>, public BaseTextShadowNode { public: using ConcreteViewShadowNode::ConcreteViewShadowNode; @@ -47,7 +45,7 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< /* * Associates a shared TextLayoutManager with the node. * `ParagraphShadowNode` uses the manager to measure text content - * and construct `ParagraphState` objects. + * and construct `ParagraphLocalData` objects. */ void setTextLayoutManager(SharedTextLayoutManager textLayoutManager); @@ -58,7 +56,7 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< * By design, the ParagraphComponentDescriptor outlives all * shadow nodes, so it's safe for this to be a raw pointer. */ - void setMeasureCache(ParagraphMeasurementCache const *cache); + void setMeasureCache(const ParagraphMeasurementCache *cache); #pragma mark - LayoutableShadowNode @@ -67,13 +65,13 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< private: /* - * Creates a `State` object (with `AttributedText` and + * Creates a `LocalData` object (with `AttributedText` and * `TextLayoutManager`) if needed. */ - void updateStateIfNeeded(); + void updateLocalDataIfNeeded(); SharedTextLayoutManager textLayoutManager_; - ParagraphMeasurementCache const *measureCache_; + const ParagraphMeasurementCache *measureCache_; /* * Cached attributed string that represents the content of the subtree started diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphState.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphState.cpp deleted file mode 100644 index 89a7c442c1..0000000000 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphState.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "ParagraphState.h" - -#include -#include - -namespace facebook { -namespace react { - -#ifdef ANDROID -folly::dynamic ParagraphState::getDynamic() const { - return toDynamic(*this); -} -#endif - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphState.h b/ReactCommon/fabric/components/text/paragraph/ParagraphState.h deleted file mode 100644 index e5ae4be756..0000000000 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphState.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -#ifdef ANDROID -#include -#endif - -namespace facebook { -namespace react { - -/* - * State for component. - * Represents what to render and how to render. - */ -class ParagraphState final { - public: - /* - * All content of component represented as an `AttributedString`. - */ - AttributedString attributedString; - - /* - * `TextLayoutManager` provides a connection to platform-specific - * text rendering infrastructure which is capable to render the - * `AttributedString`. - */ - SharedTextLayoutManager layoutManager; - -#ifdef ANDROID - ParagraphState( - AttributedString const &attributedString, - SharedTextLayoutManager const &layoutManager) - : attributedString(attributedString), layoutManager(layoutManager) {} - ParagraphState() = default; - ParagraphState(folly::dynamic const &data) { - assert(false && "Not supported"); - }; - folly::dynamic getDynamic() const; -#endif -}; - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/conversions.h b/ReactCommon/fabric/components/text/paragraph/conversions.h index 12d53b1d54..dd507cefa0 100644 --- a/ReactCommon/fabric/components/text/paragraph/conversions.h +++ b/ReactCommon/fabric/components/text/paragraph/conversions.h @@ -5,18 +5,21 @@ #include #include -#include +#include namespace facebook { namespace react { #ifdef ANDROID -inline folly::dynamic toDynamic(ParagraphState const ¶graphState) { - folly::dynamic newState = folly::dynamic::object(); - newState["attributedString"] = toDynamic(paragraphState.attributedString); - newState["hash"] = newState["attributedString"]["hash"]; - return newState; + +inline folly::dynamic toDynamic(const ParagraphLocalData ¶graphLocalData) { + folly::dynamic newLocalData = folly::dynamic::object(); + newLocalData["attributedString"] = + toDynamic(paragraphLocalData.getAttributedString()); + newLocalData["hash"] = newLocalData["attributedString"]["hash"]; + return newLocalData; } + #endif } // namespace react diff --git a/ReactCommon/fabric/components/text/tests/ParagraphLocalDataTest.cpp b/ReactCommon/fabric/components/text/tests/ParagraphLocalDataTest.cpp index 48b09cc6d3..accf32c0b7 100644 --- a/ReactCommon/fabric/components/text/tests/ParagraphLocalDataTest.cpp +++ b/ReactCommon/fabric/components/text/tests/ParagraphLocalDataTest.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace facebook { @@ -21,7 +21,7 @@ namespace react { #ifdef ANDROID TEST(ParagraphLocalDataTest, testSomething) { - auto attributedString = AttributedString(); + auto attString = AttributedString(); auto fragment = AttributedString::Fragment(); fragment.string = "test"; @@ -35,10 +35,10 @@ TEST(ParagraphLocalDataTest, testSomething) { fragment.textAttributes = text; attString.prependFragment(fragment); - auto paragraphState = ParagraphState{}; - paragraphLocalData.attributedString = attributedString; + auto paragraphLocalData = ParagraphLocalData(); + paragraphLocalData.setAttributedString(attString); - auto result = toDynamic(paragraphState)["attributedString"]; + auto result = toDynamic(paragraphLocalData)["attributedString"]; assert(result["string"] == fragment.string); auto textAttribute = result["fragments"][0]["textAttributes"];