diff --git a/Examples/UIExplorer/TextExample.android.js b/Examples/UIExplorer/TextExample.android.js
index 0d7efa1d5..4d1f61b4f 100644
--- a/Examples/UIExplorer/TextExample.android.js
+++ b/Examples/UIExplorer/TextExample.android.js
@@ -215,6 +215,23 @@ var TextExample = React.createClass({
Move fast and be bold
+
+
+ Solid underline
+
+
+ None textDecoration
+
+
+ Solid line-through
+
+
+ Both underline and line-through
+
+
+ Mixed text with underline and line-through text nodes
+
+
console.log('1st')}>
(Normal text,
diff --git a/Libraries/Text/TextStylePropTypes.js b/Libraries/Text/TextStylePropTypes.js
index 9c4668174..2f67fb73e 100644
--- a/Libraries/Text/TextStylePropTypes.js
+++ b/Libraries/Text/TextStylePropTypes.js
@@ -52,9 +52,6 @@ var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), {
textAlignVertical: ReactPropTypes.oneOf(
['auto' /*default*/, 'top', 'bottom', 'center']
),
- /**
- * @platform ios
- */
textDecorationLine: ReactPropTypes.oneOf(
['none' /*default*/, 'underline', 'line-through', 'underline line-through']
),
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java
index 3cef8895a..38160e477 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java
@@ -71,6 +71,7 @@ public class ViewProps {
public static final String RESIZE_MODE = "resizeMode";
public static final String TEXT_ALIGN = "textAlign";
public static final String TEXT_ALIGN_VERTICAL = "textAlignVertical";
+ public static final String TEXT_DECORATION_LINE = "textDecorationLine";
public static final String BORDER_WIDTH = "borderWidth";
public static final String BORDER_LEFT_WIDTH = "borderLeftWidth";
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
index 36996a1f8..657695284 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
@@ -25,6 +25,8 @@ import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
+import android.text.style.StrikethroughSpan;
+import android.text.style.UnderlineSpan;
import android.widget.TextView;
import com.facebook.csslayout.CSSConstants;
@@ -146,6 +148,12 @@ public class ReactTextShadowNode extends LayoutShadowNode {
textCSSNode.mFontFamily,
textCSSNode.getThemedContext().getAssets())));
}
+ if (textCSSNode.mIsUnderlineTextDecorationSet) {
+ ops.add(new SetSpanOperation(start, end, new UnderlineSpan()));
+ }
+ if (textCSSNode.mIsLineThroughTextDecorationSet) {
+ ops.add(new SetSpanOperation(start, end, new StrikethroughSpan()));
+ }
if (textCSSNode.mTextShadowOffsetDx != 0 || textCSSNode.mTextShadowOffsetDy != 0) {
ops.add(new SetSpanOperation(
start,
@@ -287,6 +295,9 @@ public class ReactTextShadowNode extends LayoutShadowNode {
private float mTextShadowRadius = 1;
private int mTextShadowColor = DEFAULT_TEXT_SHADOW_COLOR;
+ private boolean mIsUnderlineTextDecorationSet = false;
+ private boolean mIsLineThroughTextDecorationSet = false;
+
/**
* mFontStyle can be {@link Typeface#NORMAL} or {@link Typeface#ITALIC}.
* mFontWeight can be {@link Typeface#NORMAL} or {@link Typeface#BOLD}.
@@ -428,6 +439,22 @@ public class ReactTextShadowNode extends LayoutShadowNode {
}
}
+ @ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
+ public void setTextDecorationLine(@Nullable String textDecorationLineString) {
+ mIsUnderlineTextDecorationSet = false;
+ mIsLineThroughTextDecorationSet = false;
+ if (textDecorationLineString != null) {
+ for (String textDecorationLineSubString : textDecorationLineString.split(" ")) {
+ if ("underline".equals(textDecorationLineSubString)) {
+ mIsUnderlineTextDecorationSet = true;
+ } else if ("line-through".equals(textDecorationLineSubString)) {
+ mIsLineThroughTextDecorationSet = true;
+ }
+ }
+ }
+ markUpdated();
+ }
+
@ReactProp(name = PROP_SHADOW_OFFSET)
public void setTextShadowOffset(ReadableMap offsetMap) {
if (offsetMap == null) {
diff --git a/ReactAndroid/src/test/java/com/facebook/react/views/text/ReactTextTest.java b/ReactAndroid/src/test/java/com/facebook/react/views/text/ReactTextTest.java
index 68734c4a5..257f77a89 100644
--- a/ReactAndroid/src/test/java/com/facebook/react/views/text/ReactTextTest.java
+++ b/ReactAndroid/src/test/java/com/facebook/react/views/text/ReactTextTest.java
@@ -22,6 +22,8 @@ import android.os.Build;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
+import android.text.style.StrikethroughSpan;
+import android.text.style.UnderlineSpan;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.widget.TextView;
@@ -279,6 +281,60 @@ public class ReactTextTest {
assertThat(customStyleSpan.getWeight() & Typeface.BOLD).isNotZero();
}
+ @Test
+ public void testTextDecorationLineUnderlineApplied() {
+ UIManagerModule uiManager = getUIManagerModule();
+
+ ReactRootView rootView = createText(
+ uiManager,
+ JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "underline"),
+ JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text"));
+
+ TextView textView = (TextView) rootView.getChildAt(0);
+ Spanned text = (Spanned) textView.getText();
+ UnderlineSpan underlineSpan = getSingleSpan(textView, UnderlineSpan.class);
+ StrikethroughSpan[] strikeThroughSpans =
+ text.getSpans(0, text.length(), StrikethroughSpan.class);
+ assertThat(underlineSpan instanceof UnderlineSpan).isTrue();
+ assertThat(strikeThroughSpans).hasSize(0);
+ }
+
+ @Test
+ public void testTextDecorationLineLineThroughApplied() {
+ UIManagerModule uiManager = getUIManagerModule();
+
+ ReactRootView rootView = createText(
+ uiManager,
+ JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "line-through"),
+ JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text"));
+
+ TextView textView = (TextView) rootView.getChildAt(0);
+ Spanned text = (Spanned) textView.getText();
+ UnderlineSpan[] underlineSpans =
+ text.getSpans(0, text.length(), UnderlineSpan.class);
+ StrikethroughSpan strikeThroughSpan =
+ getSingleSpan(textView, StrikethroughSpan.class);
+ assertThat(underlineSpans).hasSize(0);
+ assertThat(strikeThroughSpan instanceof StrikethroughSpan).isTrue();
+ }
+
+ @Test
+ public void testTextDecorationLineUnderlineLineThroughApplied() {
+ UIManagerModule uiManager = getUIManagerModule();
+
+ ReactRootView rootView = createText(
+ uiManager,
+ JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "underline line-through"),
+ JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text"));
+
+ UnderlineSpan underlineSpan =
+ getSingleSpan((TextView) rootView.getChildAt(0), UnderlineSpan.class);
+ StrikethroughSpan strikeThroughSpan =
+ getSingleSpan((TextView) rootView.getChildAt(0), StrikethroughSpan.class);
+ assertThat(underlineSpan instanceof UnderlineSpan).isTrue();
+ assertThat(strikeThroughSpan instanceof StrikethroughSpan).isTrue();
+ }
+
@Test
public void testBackgroundColorStyleApplied() {
UIManagerModule uiManager = getUIManagerModule();