From 61755aced131d5625da38ca0ae19efc6ebdc0205 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Mon, 18 Oct 2021 02:14:33 -0700 Subject: [PATCH] Merge textDecoration(LineStyle|LinePattern) into textDecorationStyle Summary: The [first implementation of `TextAttributes` in Fabric](https://github.com/facebook/react-native/commit/62576bcb7832e08c6fd9f9482285882c37a2ece5) included two separate props instead of `textDecorationStyle`: `textDecorationLineStyle` (single, double, ...) and `textDecorationLinePattern` (dot, dash, dotdash, ...). These two props were implemented in C++ and iOS but never supported in JS. Pre-Fabric (and CSS) on the other hand use a single prop `textDecorationStyle: 'solid' | 'double' | 'dotted' | 'dashed'`. This diff implements this same API in Fabric, and removes the unused `textDecorationLineStyle` and `textDecorationLinePattern` props. Changelog: [iOS][Fixed] - Implement `textDecorationStyle` on iOS and remove unused `textDecorationLineStyle` and `textDecorationLinePattern` from Fabric. Reviewed By: dmitryrykun Differential Revision: D31617598 fbshipit-source-id: f5173e7ecdd31aafa0e5f0e50137eefa0505e007 --- .../react/views/text/TextAttributeProps.java | 7 +- .../attributedstring/TextAttributes.cpp | 21 +--- .../attributedstring/TextAttributes.h | 6 +- .../renderer/attributedstring/conversions.h | 118 +++++------------- .../renderer/attributedstring/primitives.h | 21 +--- .../components/text/BaseTextProps.cpp | 14 +-- .../platform/ios/RCTAttributedTextUtils.mm | 5 +- .../ios/RCTTextPrimitivesConversions.h | 45 ++----- 8 files changed, 58 insertions(+), 179 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java index 6c93d200e85..7c4419c68ee 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java @@ -47,8 +47,7 @@ public class TextAttributeProps { public static final short TA_KEY_BEST_WRITING_DIRECTION = 13; public static final short TA_KEY_TEXT_DECORATION_COLOR = 14; public static final short TA_KEY_TEXT_DECORATION_LINE = 15; - public static final short TA_KEY_TEXT_DECORATION_LINE_STYLE = 16; - public static final short TA_KEY_TEXT_DECORATION_LINE_PATTERN = 17; + public static final short TA_KEY_TEXT_DECORATION_STYLE = 16; public static final short TA_KEY_TEXT_SHADOW_RAIDUS = 18; public static final short TA_KEY_TEXT_SHADOW_COLOR = 19; public static final short TA_KEY_IS_HIGHLIGHTED = 20; @@ -192,9 +191,7 @@ public class TextAttributeProps { case TA_KEY_TEXT_DECORATION_LINE: result.setTextDecorationLine(entry.getString()); break; - case TA_KEY_TEXT_DECORATION_LINE_STYLE: - break; - case TA_KEY_TEXT_DECORATION_LINE_PATTERN: + case TA_KEY_TEXT_DECORATION_STYLE: break; case TA_KEY_TEXT_SHADOW_RAIDUS: result.setTextShadowRadius(entry.getInt(1)); diff --git a/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp b/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp index 9aaea5aec5a..8c014d5a443 100644 --- a/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +++ b/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp @@ -71,13 +71,9 @@ void TextAttributes::apply(TextAttributes textAttributes) { textDecorationLineType = textAttributes.textDecorationLineType.hasValue() ? textAttributes.textDecorationLineType : textDecorationLineType; - textDecorationLineStyle = textAttributes.textDecorationLineStyle.hasValue() - ? textAttributes.textDecorationLineStyle - : textDecorationLineStyle; - textDecorationLinePattern = - textAttributes.textDecorationLinePattern.hasValue() - ? textAttributes.textDecorationLinePattern - : textDecorationLinePattern; + textDecorationStyle = textAttributes.textDecorationStyle.hasValue() + ? textAttributes.textDecorationStyle + : textDecorationStyle; // Shadow textShadowOffset = textAttributes.textShadowOffset.hasValue() @@ -117,8 +113,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const { baseWritingDirection, textDecorationColor, textDecorationLineType, - textDecorationLineStyle, - textDecorationLinePattern, + textDecorationStyle, textShadowOffset, textShadowColor, isHighlighted, @@ -137,8 +132,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const { rhs.baseWritingDirection, rhs.textDecorationColor, rhs.textDecorationLineType, - rhs.textDecorationLineStyle, - rhs.textDecorationLinePattern, + rhs.textDecorationStyle, rhs.textShadowOffset, rhs.textShadowColor, rhs.isHighlighted, @@ -199,10 +193,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const { debugStringConvertibleItem("textDecorationColor", textDecorationColor), debugStringConvertibleItem( "textDecorationLineType", textDecorationLineType), - debugStringConvertibleItem( - "textDecorationLineStyle", textDecorationLineStyle), - debugStringConvertibleItem( - "textDecorationLinePattern", textDecorationLinePattern), + debugStringConvertibleItem("textDecorationStyle", textDecorationStyle), // Shadow debugStringConvertibleItem("textShadowOffset", textShadowOffset), diff --git a/ReactCommon/react/renderer/attributedstring/TextAttributes.h b/ReactCommon/react/renderer/attributedstring/TextAttributes.h index b7f07b962da..56c30652179 100644 --- a/ReactCommon/react/renderer/attributedstring/TextAttributes.h +++ b/ReactCommon/react/renderer/attributedstring/TextAttributes.h @@ -61,8 +61,7 @@ class TextAttributes : public DebugStringConvertible { // Decoration SharedColor textDecorationColor{}; better::optional textDecorationLineType{}; - better::optional textDecorationLineStyle{}; - better::optional textDecorationLinePattern{}; + better::optional textDecorationStyle{}; // Shadow // TODO: Use `Point` type instead of `Size` for `textShadowOffset` attribute. @@ -124,8 +123,7 @@ struct hash { textAttributes.baseWritingDirection, textAttributes.textDecorationColor, textAttributes.textDecorationLineType, - textAttributes.textDecorationLineStyle, - textAttributes.textDecorationLinePattern, + textAttributes.textDecorationStyle, textAttributes.textShadowOffset, textAttributes.textShadowRadius, textAttributes.textShadowColor, diff --git a/ReactCommon/react/renderer/attributedstring/conversions.h b/ReactCommon/react/renderer/attributedstring/conversions.h index 56ab6bdef94..576b8f008bb 100644 --- a/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/ReactCommon/react/renderer/attributedstring/conversions.h @@ -475,94 +475,45 @@ inline std::string toString( inline void fromRawValue( const PropsParserContext &context, const RawValue &value, - TextDecorationLineStyle &result) { - react_native_assert(value.hasType()); - if (value.hasType()) { - auto string = (std::string)value; - if (string == "single") { - result = TextDecorationLineStyle::Single; - } else if (string == "thick") { - result = TextDecorationLineStyle::Thick; - } else if (string == "double") { - result = TextDecorationLineStyle::Double; - } else { - LOG(ERROR) << "Unsupported TextDecorationLineStyle value: " << string; - react_native_assert(false); - // sane default for prod - result = TextDecorationLineStyle::Single; - } - return; - } - - LOG(ERROR) << "Unsupported TextDecorationLineStyle type"; - // sane default for prod - result = TextDecorationLineStyle::Single; -} - -inline std::string toString( - const TextDecorationLineStyle &textDecorationLineStyle) { - switch (textDecorationLineStyle) { - case TextDecorationLineStyle::Single: - return "single"; - case TextDecorationLineStyle::Thick: - return "thick"; - case TextDecorationLineStyle::Double: - return "double"; - } - - LOG(ERROR) << "Unsupported TextDecorationLineStyle value"; - react_native_assert(false); - // sane default for prod - return "single"; -} - -inline void fromRawValue( - const PropsParserContext &context, - const RawValue &value, - TextDecorationLinePattern &result) { + TextDecorationStyle &result) { react_native_assert(value.hasType()); if (value.hasType()) { auto string = (std::string)value; if (string == "solid") { - result = TextDecorationLinePattern::Solid; - } else if (string == "dot") { - result = TextDecorationLinePattern::Dot; - } else if (string == "dash") { - result = TextDecorationLinePattern::Dash; - } else if (string == "dash-dot") { - result = TextDecorationLinePattern::DashDot; - } else if (string == "dash-dot-dot") { - result = TextDecorationLinePattern::DashDotDot; + result = TextDecorationStyle::Solid; + } else if (string == "double") { + result = TextDecorationStyle::Double; + } else if (string == "dotted") { + result = TextDecorationStyle::Dotted; + } else if (string == "dashed") { + result = TextDecorationStyle::Dashed; } else { - LOG(ERROR) << "Unsupported TextDecorationLinePattern value: " << string; + LOG(ERROR) << "Unsupported TextDecorationStyle value: " << string; react_native_assert(false); // sane default for prod - result = TextDecorationLinePattern::Solid; + result = TextDecorationStyle::Solid; } return; } - LOG(ERROR) << "Unsupported TextDecorationLineStyle type"; + LOG(ERROR) << "Unsupported TextDecorationStyle type"; // sane default for prod - result = TextDecorationLinePattern::Solid; + result = TextDecorationStyle::Solid; } -inline std::string toString( - const TextDecorationLinePattern &textDecorationLinePattern) { - switch (textDecorationLinePattern) { - case TextDecorationLinePattern::Solid: +inline std::string toString(const TextDecorationStyle &textDecorationStyle) { + switch (textDecorationStyle) { + case TextDecorationStyle::Solid: return "solid"; - case TextDecorationLinePattern::Dot: - return "dot"; - case TextDecorationLinePattern::Dash: - return "dash"; - case TextDecorationLinePattern::DashDot: - return "dash-dot"; - case TextDecorationLinePattern::DashDotDot: - return "dash-dot-dot"; + case TextDecorationStyle::Double: + return "double"; + case TextDecorationStyle::Dotted: + return "dotted"; + case TextDecorationStyle::Dashed: + return "dashed"; } - LOG(ERROR) << "Unsupported TextDecorationLinePattern value"; + LOG(ERROR) << "Unsupported TextDecorationStyle value"; react_native_assert(false); // sane default for prod return "solid"; @@ -931,15 +882,9 @@ inline folly::dynamic toDynamic(const TextAttributes &textAttributes) { _textAttributes( "textDecorationLine", toString(*textAttributes.textDecorationLineType)); } - if (textAttributes.textDecorationLineStyle.has_value()) { + if (textAttributes.textDecorationStyle.has_value()) { _textAttributes( - "textDecorationLineStyle", - toString(*textAttributes.textDecorationLineStyle)); - } - if (textAttributes.textDecorationLinePattern.has_value()) { - _textAttributes( - "textDecorationLinePattern", - toString(*textAttributes.textDecorationLinePattern)); + "textDecorationStyle", toString(*textAttributes.textDecorationStyle)); } // Shadow // textShadowOffset = textAttributes.textShadowOffset.has_value() ? @@ -1030,8 +975,7 @@ constexpr static Key TA_KEY_ALIGNMENT = 12; constexpr static Key TA_KEY_BEST_WRITING_DIRECTION = 13; constexpr static Key TA_KEY_TEXT_DECORATION_COLOR = 14; constexpr static Key TA_KEY_TEXT_DECORATION_LINE = 15; -constexpr static Key TA_KEY_TEXT_DECORATION_LINE_STYLE = 16; -constexpr static Key TA_KEY_TEXT_DECORATION_LINE_PATTERN = 17; +constexpr static Key TA_KEY_TEXT_DECORATION_STYLE = 16; constexpr static Key TA_KEY_TEXT_SHADOW_RAIDUS = 18; constexpr static Key TA_KEY_TEXT_SHADOW_COLOR = 19; constexpr static Key TA_KEY_IS_HIGHLIGHTED = 20; @@ -1150,16 +1094,12 @@ inline MapBuffer toMapBuffer(const TextAttributes &textAttributes) { TA_KEY_TEXT_DECORATION_LINE, toString(*textAttributes.textDecorationLineType)); } - if (textAttributes.textDecorationLineStyle.has_value()) { + if (textAttributes.textDecorationStyle.has_value()) { builder.putString( - TA_KEY_TEXT_DECORATION_LINE_STYLE, - toString(*textAttributes.textDecorationLineStyle)); - } - if (textAttributes.textDecorationLinePattern.has_value()) { - builder.putString( - TA_KEY_TEXT_DECORATION_LINE_PATTERN, - toString(*textAttributes.textDecorationLinePattern)); + TA_KEY_TEXT_DECORATION_STYLE, + toString(*textAttributes.textDecorationStyle)); } + // Shadow if (!std::isnan(textAttributes.textShadowRadius)) { builder.putDouble( diff --git a/ReactCommon/react/renderer/attributedstring/primitives.h b/ReactCommon/react/renderer/attributedstring/primitives.h index d4be5236613..ebf4616f5e6 100644 --- a/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/ReactCommon/react/renderer/attributedstring/primitives.h @@ -81,15 +81,7 @@ enum class TextDecorationLineType { UnderlineStrikethrough }; -enum class TextDecorationLineStyle { Single, Thick, Double }; - -enum class TextDecorationLinePattern { - Solid, - Dot, - Dash, - DashDot, - DashDotDot, -}; +enum class TextDecorationStyle { Solid, Double, Dotted, Dashed }; enum class AccessibilityRole { None, @@ -176,15 +168,8 @@ struct hash { }; template <> -struct hash { - size_t operator()(const facebook::react::TextDecorationLinePattern &v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextDecorationLineStyle &v) const { +struct hash { + size_t operator()(const facebook::react::TextDecorationStyle &v) const { return hash()(static_cast(v)); } }; diff --git a/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index d8079cf4b81..73590497435 100644 --- a/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -131,18 +131,12 @@ static TextAttributes convertRawProp( "textDecorationLine", sourceTextAttributes.textDecorationLineType, defaultTextAttributes.textDecorationLineType); - textAttributes.textDecorationLineStyle = convertRawProp( + textAttributes.textDecorationStyle = convertRawProp( context, rawProps, - "textDecorationLineStyle", - sourceTextAttributes.textDecorationLineStyle, - defaultTextAttributes.textDecorationLineStyle); - textAttributes.textDecorationLinePattern = convertRawProp( - context, - rawProps, - "textDecorationLinePattern", - sourceTextAttributes.textDecorationLinePattern, - defaultTextAttributes.textDecorationLinePattern); + "textDecorationStyle", + sourceTextAttributes.textDecorationStyle, + defaultTextAttributes.textDecorationStyle); // Shadow textAttributes.textShadowOffset = convertRawProp( diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm index 7e63b2df90b..11ef92858ec 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm @@ -171,9 +171,8 @@ NSDictionary *RCTNSTextAttributesFromTextAttributes(T if (textAttributes.textDecorationLineType.value_or(TextDecorationLineType::None) != TextDecorationLineType::None) { auto textDecorationLineType = textAttributes.textDecorationLineType.value(); - NSUnderlineStyle style = RCTNSUnderlineStyleFromStyleAndPattern( - textAttributes.textDecorationLineStyle.value_or(TextDecorationLineStyle::Single), - textAttributes.textDecorationLinePattern.value_or(TextDecorationLinePattern::Solid)); + NSUnderlineStyle style = RCTNSUnderlineStyleFromTextDecorationStyle( + textAttributes.textDecorationStyle.value_or(TextDecorationStyle::Solid)); UIColor *textDecorationColor = RCTUIColorFromSharedColor(textAttributes.textDecorationColor); diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextPrimitivesConversions.h b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextPrimitivesConversions.h index c78daec7b7a..9788d8ebb00 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextPrimitivesConversions.h +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextPrimitivesConversions.h @@ -57,43 +57,18 @@ inline static RCTFontVariant RCTFontVariantFromFontVariant(FontVariant fontVaria return (RCTFontVariant)fontVariant; } -inline static NSUnderlineStyle RCTNSUnderlineStyleFromStyleAndPattern( - TextDecorationLineStyle textDecorationLineStyle, - TextDecorationLinePattern textDecorationLinePattern) +inline static NSUnderlineStyle RCTNSUnderlineStyleFromTextDecorationStyle(TextDecorationStyle textDecorationStyle) { - NSUnderlineStyle style = NSUnderlineStyleNone; - - switch (textDecorationLineStyle) { - case TextDecorationLineStyle::Single: - style = NSUnderlineStyle(style | NSUnderlineStyleSingle); - break; - case TextDecorationLineStyle::Thick: - style = NSUnderlineStyle(style | NSUnderlineStyleThick); - break; - case TextDecorationLineStyle::Double: - style = NSUnderlineStyle(style | NSUnderlineStyleDouble); - break; + switch (textDecorationStyle) { + case TextDecorationStyle::Solid: + return NSUnderlineStyleSingle; + case TextDecorationStyle::Double: + return NSUnderlineStyleDouble; + case TextDecorationStyle::Dashed: + return NSUnderlinePatternDash | NSUnderlineStyleSingle; + case TextDecorationStyle::Dotted: + return NSUnderlinePatternDot | NSUnderlineStyleSingle; } - - switch (textDecorationLinePattern) { - case TextDecorationLinePattern::Solid: - style = NSUnderlineStyle(style | NSUnderlinePatternSolid); - break; - case TextDecorationLinePattern::Dash: - style = NSUnderlineStyle(style | NSUnderlinePatternDash); - break; - case TextDecorationLinePattern::Dot: - style = NSUnderlineStyle(style | NSUnderlinePatternDot); - break; - case TextDecorationLinePattern::DashDot: - style = NSUnderlineStyle(style | NSUnderlinePatternDashDot); - break; - case TextDecorationLinePattern::DashDotDot: - style = NSUnderlineStyle(style | NSUnderlinePatternDashDotDot); - break; - } - - return style; } inline static UIColor *RCTUIColorFromSharedColor(const SharedColor &sharedColor)