mirror of
https://github.com/status-im/react-native.git
synced 2025-01-14 11:34:23 +00:00
Added support for textDecorationLine style prop on Android
Summary:As suggested by kmagiera in #3819, I've implemented `textDecorationLine` style for Android in `ReactTextShadowNode` using span operations so we can support nested Text components. ![Demo](http://c.hlp.sc/022k2l033p0n/Image%202016-01-03%20at%2011.17.15%20PM.png) Closes https://github.com/facebook/react-native/pull/5105 Differential Revision: D3167756 Pulled By: andreicoman11 fb-gh-sync-id: 122701a53d50f47f89b49e1f343c97db5fa2323d fbshipit-source-id: 122701a53d50f47f89b49e1f343c97db5fa2323d
This commit is contained in:
parent
eac617d6ee
commit
2039be9d32
@ -215,6 +215,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,
|
||||
|
@ -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']
|
||||
),
|
||||
|
@ -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";
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user