Skip to content

Commit

Permalink
Added support for textDecorationLine style prop on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
Charca committed Apr 9, 2016
1 parent 58db9f3 commit 011c026
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 3 deletions.
17 changes: 17 additions & 0 deletions Examples/UIExplorer/TextExample.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@ var TextExample = React.createClass({
Move fast and be bold
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Text Decoration">
<Text style={{textDecorationLine: 'underline'}}>
Solid underline
</Text>
<Text style={{textDecorationLine: 'none'}}>
None textDecoration
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'solid'}}>
Solid line-through
</Text>
<Text style={{textDecorationLine: 'underline line-through'}}>
Both underline and line-through
</Text>
<Text>
Mixed text with <Text style={{textDecorationLine: 'underline'}}>underline</Text> and <Text style={{textDecorationLine: 'line-through'}}>line-through</Text> text nodes
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Nested">
<Text onPress={() => console.log('1st')}>
(Normal text,
Expand Down
3 changes: 0 additions & 3 deletions Libraries/Text/TextStylePropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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']
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
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;
Expand Down Expand Up @@ -147,6 +149,12 @@ private static void buildSpannedFromTextCSSNode(
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,
Expand Down Expand Up @@ -293,6 +301,9 @@ private static int parseNumericFontWeight(String fontWeightString) {
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}.
Expand Down Expand Up @@ -434,6 +445,22 @@ public void setFontStyle(@Nullable String fontStyleString) {
}
}

@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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
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;
Expand Down Expand Up @@ -279,6 +281,51 @@ public void testFontFamilyBoldItalicStyleApplied() {
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"));

UnderlineSpan underlineSpan =
getSingleSpan((TextView) rootView.getChildAt(0), UnderlineSpan.class);
assertThat(underlineSpan instanceof UnderlineSpan).isTrue();
}

@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"));

StrikethroughSpan strikeThroughSpan =
getSingleSpan((TextView) rootView.getChildAt(0), StrikethroughSpan.class);
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();
Expand Down

0 comments on commit 011c026

Please sign in to comment.