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
This commit is contained in:
Rob Hogan
2021-10-18 02:16:03 -07:00
committed by Facebook GitHub Bot
parent f1b5fe1d3e
commit 61755aced1
8 changed files with 58 additions and 179 deletions
@@ -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));
@@ -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),
@@ -61,8 +61,7 @@ class TextAttributes : public DebugStringConvertible {
// Decoration
SharedColor textDecorationColor{};
better::optional<TextDecorationLineType> textDecorationLineType{};
better::optional<TextDecorationLineStyle> textDecorationLineStyle{};
better::optional<TextDecorationLinePattern> textDecorationLinePattern{};
better::optional<TextDecorationStyle> textDecorationStyle{};
// Shadow
// TODO: Use `Point` type instead of `Size` for `textShadowOffset` attribute.
@@ -124,8 +123,7 @@ struct hash<facebook::react::TextAttributes> {
textAttributes.baseWritingDirection,
textAttributes.textDecorationColor,
textAttributes.textDecorationLineType,
textAttributes.textDecorationLineStyle,
textAttributes.textDecorationLinePattern,
textAttributes.textDecorationStyle,
textAttributes.textShadowOffset,
textAttributes.textShadowRadius,
textAttributes.textShadowColor,
@@ -475,94 +475,45 @@ inline std::string toString(
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
TextDecorationLineStyle &result) {
react_native_assert(value.hasType<std::string>());
if (value.hasType<std::string>()) {
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<std::string>());
if (value.hasType<std::string>()) {
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(
@@ -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<facebook::react::WritingDirection> {
};
template <>
struct hash<facebook::react::TextDecorationLinePattern> {
size_t operator()(const facebook::react::TextDecorationLinePattern &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLineStyle> {
size_t operator()(const facebook::react::TextDecorationLineStyle &v) const {
struct hash<facebook::react::TextDecorationStyle> {
size_t operator()(const facebook::react::TextDecorationStyle &v) const {
return hash<int>()(static_cast<int>(v));
}
};
@@ -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(
@@ -171,9 +171,8 @@ NSDictionary<NSAttributedStringKey, id> *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);
@@ -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)