react-native 0.71.6 → 0.71.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/React/Base/RCTVersion.m +1 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLetterSpacingSpan.java +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java +1 -5
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +9 -7
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java +13 -5
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +15 -15
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +204 -117
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +33 -17
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java +5 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/package.json +1 -1
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/template/package.json +1 -1
package/React/Base/RCTVersion.m
CHANGED
package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLetterSpacingSpan.java
CHANGED
|
@@ -37,6 +37,10 @@ public class CustomLetterSpacingSpan extends MetricAffectingSpan implements Reac
|
|
|
37
37
|
apply(paint);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
public float getSpacing() {
|
|
41
|
+
return mLetterSpacing;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
private void apply(TextPaint paint) {
|
|
41
45
|
if (!Float.isNaN(mLetterSpacing)) {
|
|
42
46
|
paint.setLetterSpacing(mLetterSpacing);
|
|
@@ -71,6 +71,10 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {
|
|
|
71
71
|
return mFontFamily;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
public @Nullable String getFontFeatureSettings() {
|
|
75
|
+
return mFeatureSettings;
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
private static void apply(
|
|
75
79
|
Paint paint,
|
|
76
80
|
int style,
|
|
@@ -31,8 +31,6 @@ public class ReactTextUpdate {
|
|
|
31
31
|
private final int mSelectionEnd;
|
|
32
32
|
private final int mJustificationMode;
|
|
33
33
|
|
|
34
|
-
public boolean mContainsMultipleFragments;
|
|
35
|
-
|
|
36
34
|
/**
|
|
37
35
|
* @deprecated Use a non-deprecated constructor for ReactTextUpdate instead. This one remains
|
|
38
36
|
* because it's being used by a unit test that isn't currently open source.
|
|
@@ -142,13 +140,11 @@ public class ReactTextUpdate {
|
|
|
142
140
|
int jsEventCounter,
|
|
143
141
|
int textAlign,
|
|
144
142
|
int textBreakStrategy,
|
|
145
|
-
int justificationMode
|
|
146
|
-
boolean containsMultipleFragments) {
|
|
143
|
+
int justificationMode) {
|
|
147
144
|
|
|
148
145
|
ReactTextUpdate reactTextUpdate =
|
|
149
146
|
new ReactTextUpdate(
|
|
150
147
|
text, jsEventCounter, false, textAlign, textBreakStrategy, justificationMode);
|
|
151
|
-
reactTextUpdate.mContainsMultipleFragments = containsMultipleFragments;
|
|
152
148
|
return reactTextUpdate;
|
|
153
149
|
}
|
|
154
150
|
|
|
@@ -54,7 +54,6 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
|
|
54
54
|
private boolean mContainsImages;
|
|
55
55
|
private final int mDefaultGravityHorizontal;
|
|
56
56
|
private final int mDefaultGravityVertical;
|
|
57
|
-
private int mTextAlign;
|
|
58
57
|
private int mNumberOfLines;
|
|
59
58
|
private TextUtils.TruncateAt mEllipsizeLocation;
|
|
60
59
|
private boolean mAdjustsFontSizeToFit;
|
|
@@ -69,8 +68,7 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
|
|
69
68
|
super(context);
|
|
70
69
|
|
|
71
70
|
// Get these defaults only during the constructor - these should never be set otherwise
|
|
72
|
-
mDefaultGravityHorizontal =
|
|
73
|
-
getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
|
71
|
+
mDefaultGravityHorizontal = getGravityHorizontal();
|
|
74
72
|
mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
|
|
75
73
|
|
|
76
74
|
initView();
|
|
@@ -89,10 +87,10 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
|
|
89
87
|
|
|
90
88
|
mReactBackgroundManager = new ReactViewBackgroundManager(this);
|
|
91
89
|
|
|
92
|
-
mTextAlign = Gravity.NO_GRAVITY;
|
|
93
90
|
mNumberOfLines = ViewDefaults.NUMBER_OF_LINES;
|
|
94
91
|
mAdjustsFontSizeToFit = false;
|
|
95
92
|
mLinkifyMaskType = 0;
|
|
93
|
+
mNotifyOnInlineViewLayout = false;
|
|
96
94
|
mTextIsSelectable = false;
|
|
97
95
|
mEllipsizeLocation = TextUtils.TruncateAt.END;
|
|
98
96
|
|
|
@@ -392,10 +390,9 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
|
|
392
390
|
}
|
|
393
391
|
|
|
394
392
|
int nextTextAlign = update.getTextAlign();
|
|
395
|
-
if (
|
|
396
|
-
|
|
393
|
+
if (nextTextAlign != getGravityHorizontal()) {
|
|
394
|
+
setGravityHorizontal(nextTextAlign);
|
|
397
395
|
}
|
|
398
|
-
setGravityHorizontal(mTextAlign);
|
|
399
396
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
400
397
|
if (getBreakStrategy() != update.getTextBreakStrategy()) {
|
|
401
398
|
setBreakStrategy(update.getTextBreakStrategy());
|
|
@@ -552,6 +549,11 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
|
|
552
549
|
return false;
|
|
553
550
|
}
|
|
554
551
|
|
|
552
|
+
/* package */ int getGravityHorizontal() {
|
|
553
|
+
return getGravity()
|
|
554
|
+
& (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
|
555
|
+
}
|
|
556
|
+
|
|
555
557
|
/* package */ void setGravityHorizontal(int gravityHorizontal) {
|
|
556
558
|
if (gravityHorizontal == 0) {
|
|
557
559
|
gravityHorizontal = mDefaultGravityHorizontal;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
package com.facebook.react.views.text;
|
|
9
9
|
|
|
10
10
|
import android.content.Context;
|
|
11
|
+
import android.os.Build;
|
|
11
12
|
import android.text.Spannable;
|
|
12
13
|
import androidx.annotation.NonNull;
|
|
13
14
|
import androidx.annotation.Nullable;
|
|
@@ -23,6 +24,7 @@ import com.facebook.react.uimanager.ReactAccessibilityDelegate;
|
|
|
23
24
|
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
|
24
25
|
import com.facebook.react.uimanager.StateWrapper;
|
|
25
26
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
27
|
+
import com.facebook.react.uimanager.ViewProps;
|
|
26
28
|
import com.facebook.yoga.YogaMeasureMode;
|
|
27
29
|
import java.util.HashMap;
|
|
28
30
|
import java.util.Map;
|
|
@@ -148,15 +150,19 @@ public class ReactTextViewManager
|
|
|
148
150
|
view.setSpanned(spanned);
|
|
149
151
|
|
|
150
152
|
int textBreakStrategy =
|
|
151
|
-
TextAttributeProps.getTextBreakStrategy(
|
|
153
|
+
TextAttributeProps.getTextBreakStrategy(
|
|
154
|
+
paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY));
|
|
155
|
+
int currentJustificationMode =
|
|
156
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
|
152
157
|
|
|
153
158
|
return new ReactTextUpdate(
|
|
154
159
|
spanned,
|
|
155
160
|
state.hasKey("mostRecentEventCount") ? state.getInt("mostRecentEventCount") : -1,
|
|
156
161
|
false, // TODO add this into local Data
|
|
157
|
-
TextAttributeProps.getTextAlignment(
|
|
162
|
+
TextAttributeProps.getTextAlignment(
|
|
163
|
+
props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
|
|
158
164
|
textBreakStrategy,
|
|
159
|
-
TextAttributeProps.getJustificationMode(props));
|
|
165
|
+
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
|
160
166
|
}
|
|
161
167
|
|
|
162
168
|
private Object getReactTextUpdate(ReactTextView view, ReactStylesDiffMap props, MapBuffer state) {
|
|
@@ -171,15 +177,17 @@ public class ReactTextViewManager
|
|
|
171
177
|
int textBreakStrategy =
|
|
172
178
|
TextAttributeProps.getTextBreakStrategy(
|
|
173
179
|
paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
|
|
180
|
+
int currentJustificationMode =
|
|
181
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
|
174
182
|
|
|
175
183
|
return new ReactTextUpdate(
|
|
176
184
|
spanned,
|
|
177
185
|
-1, // UNUSED FOR TEXT
|
|
178
186
|
false, // TODO add this into local Data
|
|
179
187
|
TextAttributeProps.getTextAlignment(
|
|
180
|
-
props, TextLayoutManagerMapBuffer.isRTL(attributedString)),
|
|
188
|
+
props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
|
|
181
189
|
textBreakStrategy,
|
|
182
|
-
TextAttributeProps.getJustificationMode(props));
|
|
190
|
+
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
@Override
|
|
@@ -249,35 +249,35 @@ public class TextAttributeProps {
|
|
|
249
249
|
return result;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
int textAlignment;
|
|
252
|
+
public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL, int defaultValue) {
|
|
253
|
+
if (!props.hasKey(ViewProps.TEXT_ALIGN)) {
|
|
254
|
+
return defaultValue;
|
|
255
|
+
}
|
|
257
256
|
|
|
257
|
+
String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN);
|
|
258
258
|
if ("justify".equals(textAlignPropValue)) {
|
|
259
|
-
|
|
259
|
+
return Gravity.LEFT;
|
|
260
260
|
} else {
|
|
261
261
|
if (textAlignPropValue == null || "auto".equals(textAlignPropValue)) {
|
|
262
|
-
|
|
262
|
+
return Gravity.NO_GRAVITY;
|
|
263
263
|
} else if ("left".equals(textAlignPropValue)) {
|
|
264
|
-
|
|
264
|
+
return isRTL ? Gravity.RIGHT : Gravity.LEFT;
|
|
265
265
|
} else if ("right".equals(textAlignPropValue)) {
|
|
266
|
-
|
|
266
|
+
return isRTL ? Gravity.LEFT : Gravity.RIGHT;
|
|
267
267
|
} else if ("center".equals(textAlignPropValue)) {
|
|
268
|
-
|
|
268
|
+
return Gravity.CENTER_HORIZONTAL;
|
|
269
269
|
} else {
|
|
270
270
|
throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlignPropValue);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
-
return textAlignment;
|
|
274
273
|
}
|
|
275
274
|
|
|
276
|
-
public static int getJustificationMode(ReactStylesDiffMap props) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
275
|
+
public static int getJustificationMode(ReactStylesDiffMap props, int defaultValue) {
|
|
276
|
+
if (!props.hasKey(ViewProps.TEXT_ALIGN)) {
|
|
277
|
+
return defaultValue;
|
|
278
|
+
}
|
|
280
279
|
|
|
280
|
+
String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN);
|
|
281
281
|
if ("justify".equals(textAlignPropValue) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
282
282
|
return Layout.JUSTIFICATION_MODE_INTER_WORD;
|
|
283
283
|
}
|
|
@@ -11,6 +11,8 @@ import static com.facebook.react.uimanager.UIManagerHelper.getReactContext;
|
|
|
11
11
|
import static com.facebook.react.views.text.TextAttributeProps.UNSET;
|
|
12
12
|
|
|
13
13
|
import android.content.Context;
|
|
14
|
+
import android.graphics.Color;
|
|
15
|
+
import android.graphics.Paint;
|
|
14
16
|
import android.graphics.Rect;
|
|
15
17
|
import android.graphics.Typeface;
|
|
16
18
|
import android.graphics.drawable.Drawable;
|
|
@@ -50,15 +52,19 @@ import com.facebook.react.views.text.CustomLetterSpacingSpan;
|
|
|
50
52
|
import com.facebook.react.views.text.CustomLineHeightSpan;
|
|
51
53
|
import com.facebook.react.views.text.CustomStyleSpan;
|
|
52
54
|
import com.facebook.react.views.text.ReactAbsoluteSizeSpan;
|
|
55
|
+
import com.facebook.react.views.text.ReactBackgroundColorSpan;
|
|
56
|
+
import com.facebook.react.views.text.ReactForegroundColorSpan;
|
|
53
57
|
import com.facebook.react.views.text.ReactSpan;
|
|
58
|
+
import com.facebook.react.views.text.ReactStrikethroughSpan;
|
|
54
59
|
import com.facebook.react.views.text.ReactTextUpdate;
|
|
55
60
|
import com.facebook.react.views.text.ReactTypefaceUtils;
|
|
61
|
+
import com.facebook.react.views.text.ReactUnderlineSpan;
|
|
56
62
|
import com.facebook.react.views.text.TextAttributes;
|
|
57
63
|
import com.facebook.react.views.text.TextInlineImageSpan;
|
|
58
64
|
import com.facebook.react.views.text.TextLayoutManager;
|
|
59
65
|
import com.facebook.react.views.view.ReactViewBackgroundManager;
|
|
60
66
|
import java.util.ArrayList;
|
|
61
|
-
import java.util.
|
|
67
|
+
import java.util.Objects;
|
|
62
68
|
|
|
63
69
|
/**
|
|
64
70
|
* A wrapper around the EditText that lets us better control what happens when an EditText gets
|
|
@@ -82,7 +88,6 @@ public class ReactEditText extends AppCompatEditText
|
|
|
82
88
|
// *TextChanged events should be triggered. This is less expensive than removing the text
|
|
83
89
|
// listeners and adding them back again after the text change is completed.
|
|
84
90
|
protected boolean mIsSettingTextFromJS;
|
|
85
|
-
protected boolean mIsSettingTextFromCacheUpdate = false;
|
|
86
91
|
private int mDefaultGravityHorizontal;
|
|
87
92
|
private int mDefaultGravityVertical;
|
|
88
93
|
|
|
@@ -362,7 +367,7 @@ public class ReactEditText extends AppCompatEditText
|
|
|
362
367
|
}
|
|
363
368
|
|
|
364
369
|
super.onSelectionChanged(selStart, selEnd);
|
|
365
|
-
if (
|
|
370
|
+
if (mSelectionWatcher != null && hasFocus()) {
|
|
366
371
|
mSelectionWatcher.onSelectionChanged(selStart, selEnd);
|
|
367
372
|
}
|
|
368
373
|
}
|
|
@@ -512,6 +517,14 @@ public class ReactEditText extends AppCompatEditText
|
|
|
512
517
|
}
|
|
513
518
|
}
|
|
514
519
|
|
|
520
|
+
@Override
|
|
521
|
+
public void setFontFeatureSettings(String fontFeatureSettings) {
|
|
522
|
+
if (!Objects.equals(fontFeatureSettings, getFontFeatureSettings())) {
|
|
523
|
+
super.setFontFeatureSettings(fontFeatureSettings);
|
|
524
|
+
mTypefaceDirty = true;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
515
528
|
public void maybeUpdateTypeface() {
|
|
516
529
|
if (!mTypefaceDirty) {
|
|
517
530
|
return;
|
|
@@ -523,6 +536,17 @@ public class ReactEditText extends AppCompatEditText
|
|
|
523
536
|
ReactTypefaceUtils.applyStyles(
|
|
524
537
|
getTypeface(), mFontStyle, mFontWeight, mFontFamily, getContext().getAssets());
|
|
525
538
|
setTypeface(newTypeface);
|
|
539
|
+
|
|
540
|
+
// Match behavior of CustomStyleSpan and enable SUBPIXEL_TEXT_FLAG when setting anything
|
|
541
|
+
// nonstandard
|
|
542
|
+
if (mFontStyle != UNSET
|
|
543
|
+
|| mFontWeight != UNSET
|
|
544
|
+
|| mFontFamily != null
|
|
545
|
+
|| getFontFeatureSettings() != null) {
|
|
546
|
+
setPaintFlags(getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
|
547
|
+
} else {
|
|
548
|
+
setPaintFlags(getPaintFlags() & (~Paint.SUBPIXEL_TEXT_FLAG));
|
|
549
|
+
}
|
|
526
550
|
}
|
|
527
551
|
|
|
528
552
|
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
|
@@ -584,10 +608,8 @@ public class ReactEditText extends AppCompatEditText
|
|
|
584
608
|
SpannableStringBuilder spannableStringBuilder =
|
|
585
609
|
new SpannableStringBuilder(reactTextUpdate.getText());
|
|
586
610
|
|
|
587
|
-
manageSpans(spannableStringBuilder
|
|
588
|
-
|
|
589
|
-
// Mitigation for https://github.com/facebook/react-native/issues/35936 (S318090)
|
|
590
|
-
stripAbsoluteSizeSpans(spannableStringBuilder);
|
|
611
|
+
manageSpans(spannableStringBuilder);
|
|
612
|
+
stripStyleEquivalentSpans(spannableStringBuilder);
|
|
591
613
|
|
|
592
614
|
mContainsImages = reactTextUpdate.containsImages();
|
|
593
615
|
|
|
@@ -615,7 +637,7 @@ public class ReactEditText extends AppCompatEditText
|
|
|
615
637
|
}
|
|
616
638
|
|
|
617
639
|
// Update cached spans (in Fabric only).
|
|
618
|
-
updateCachedSpannable(
|
|
640
|
+
updateCachedSpannable();
|
|
619
641
|
}
|
|
620
642
|
|
|
621
643
|
/**
|
|
@@ -624,8 +646,7 @@ public class ReactEditText extends AppCompatEditText
|
|
|
624
646
|
* will adapt to the new text, hence why {@link SpannableStringBuilder#replace} never removes
|
|
625
647
|
* them.
|
|
626
648
|
*/
|
|
627
|
-
private void manageSpans(
|
|
628
|
-
SpannableStringBuilder spannableStringBuilder, boolean skipAddSpansForMeasurements) {
|
|
649
|
+
private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
|
|
629
650
|
Object[] spans = getText().getSpans(0, length(), Object.class);
|
|
630
651
|
for (int spanIdx = 0; spanIdx < spans.length; spanIdx++) {
|
|
631
652
|
Object span = spans[spanIdx];
|
|
@@ -653,33 +674,170 @@ public class ReactEditText extends AppCompatEditText
|
|
|
653
674
|
spannableStringBuilder.setSpan(span, spanStart, spanEnd, spanFlags);
|
|
654
675
|
}
|
|
655
676
|
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// TODO: Replace with Predicate<T> and lambdas once Java 8 builds in OSS
|
|
680
|
+
interface SpanPredicate<T> {
|
|
681
|
+
boolean test(T span);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Remove spans from the SpannableStringBuilder which can be represented by TextAppearance
|
|
686
|
+
* attributes on the underlying EditText. This works around instability on Samsung devices with
|
|
687
|
+
* the presence of spans https://github.com/facebook/react-native/issues/35936 (S318090)
|
|
688
|
+
*/
|
|
689
|
+
private void stripStyleEquivalentSpans(SpannableStringBuilder sb) {
|
|
690
|
+
stripSpansOfKind(
|
|
691
|
+
sb,
|
|
692
|
+
ReactAbsoluteSizeSpan.class,
|
|
693
|
+
new SpanPredicate<ReactAbsoluteSizeSpan>() {
|
|
694
|
+
@Override
|
|
695
|
+
public boolean test(ReactAbsoluteSizeSpan span) {
|
|
696
|
+
return span.getSize() == mTextAttributes.getEffectiveFontSize();
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
stripSpansOfKind(
|
|
701
|
+
sb,
|
|
702
|
+
ReactBackgroundColorSpan.class,
|
|
703
|
+
new SpanPredicate<ReactBackgroundColorSpan>() {
|
|
704
|
+
@Override
|
|
705
|
+
public boolean test(ReactBackgroundColorSpan span) {
|
|
706
|
+
return span.getBackgroundColor() == mReactBackgroundManager.getBackgroundColor();
|
|
707
|
+
}
|
|
708
|
+
});
|
|
656
709
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
710
|
+
stripSpansOfKind(
|
|
711
|
+
sb,
|
|
712
|
+
ReactForegroundColorSpan.class,
|
|
713
|
+
new SpanPredicate<ReactForegroundColorSpan>() {
|
|
714
|
+
@Override
|
|
715
|
+
public boolean test(ReactForegroundColorSpan span) {
|
|
716
|
+
return span.getForegroundColor() == getCurrentTextColor();
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
stripSpansOfKind(
|
|
721
|
+
sb,
|
|
722
|
+
ReactStrikethroughSpan.class,
|
|
723
|
+
new SpanPredicate<ReactStrikethroughSpan>() {
|
|
724
|
+
@Override
|
|
725
|
+
public boolean test(ReactStrikethroughSpan span) {
|
|
726
|
+
return (getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0;
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
stripSpansOfKind(
|
|
731
|
+
sb,
|
|
732
|
+
ReactUnderlineSpan.class,
|
|
733
|
+
new SpanPredicate<ReactUnderlineSpan>() {
|
|
734
|
+
@Override
|
|
735
|
+
public boolean test(ReactUnderlineSpan span) {
|
|
736
|
+
return (getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0;
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
741
|
+
stripSpansOfKind(
|
|
742
|
+
sb,
|
|
743
|
+
CustomLetterSpacingSpan.class,
|
|
744
|
+
new SpanPredicate<CustomLetterSpacingSpan>() {
|
|
745
|
+
@Override
|
|
746
|
+
public boolean test(CustomLetterSpacingSpan span) {
|
|
747
|
+
return span.getSpacing() == mTextAttributes.getEffectiveLetterSpacing();
|
|
748
|
+
}
|
|
749
|
+
});
|
|
662
750
|
}
|
|
751
|
+
|
|
752
|
+
stripSpansOfKind(
|
|
753
|
+
sb,
|
|
754
|
+
CustomStyleSpan.class,
|
|
755
|
+
new SpanPredicate<CustomStyleSpan>() {
|
|
756
|
+
@Override
|
|
757
|
+
public boolean test(CustomStyleSpan span) {
|
|
758
|
+
return span.getStyle() == mFontStyle
|
|
759
|
+
&& Objects.equals(span.getFontFamily(), mFontFamily)
|
|
760
|
+
&& span.getWeight() == mFontWeight
|
|
761
|
+
&& Objects.equals(span.getFontFeatureSettings(), getFontFeatureSettings());
|
|
762
|
+
}
|
|
763
|
+
});
|
|
663
764
|
}
|
|
664
765
|
|
|
665
|
-
private void
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
final int effectiveFontSize = mTextAttributes.getEffectiveFontSize();
|
|
669
|
-
ReactAbsoluteSizeSpan[] spans = sb.getSpans(0, sb.length(), ReactAbsoluteSizeSpan.class);
|
|
766
|
+
private <T> void stripSpansOfKind(
|
|
767
|
+
SpannableStringBuilder sb, Class<T> clazz, SpanPredicate<T> shouldStrip) {
|
|
768
|
+
T[] spans = sb.getSpans(0, sb.length(), clazz);
|
|
670
769
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
770
|
+
for (T span : spans) {
|
|
771
|
+
if (shouldStrip.test(span)) {
|
|
772
|
+
sb.removeSpan(span);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
675
776
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
777
|
+
/**
|
|
778
|
+
* Copy styles represented as attributes to the underlying span, for later measurement or other
|
|
779
|
+
* usage outside the ReactEditText.
|
|
780
|
+
*/
|
|
781
|
+
private void addSpansFromStyleAttributes(SpannableStringBuilder workingText) {
|
|
782
|
+
int spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
|
|
783
|
+
|
|
784
|
+
// Set all bits for SPAN_PRIORITY so that this span has the highest possible priority
|
|
785
|
+
// (least precedence). This ensures the span is behind any overlapping spans.
|
|
786
|
+
spanFlags |= Spannable.SPAN_PRIORITY;
|
|
787
|
+
|
|
788
|
+
workingText.setSpan(
|
|
789
|
+
new ReactAbsoluteSizeSpan(mTextAttributes.getEffectiveFontSize()),
|
|
790
|
+
0,
|
|
791
|
+
workingText.length(),
|
|
792
|
+
spanFlags);
|
|
793
|
+
|
|
794
|
+
workingText.setSpan(
|
|
795
|
+
new ReactForegroundColorSpan(getCurrentTextColor()), 0, workingText.length(), spanFlags);
|
|
796
|
+
|
|
797
|
+
int backgroundColor = mReactBackgroundManager.getBackgroundColor();
|
|
798
|
+
if (backgroundColor != Color.TRANSPARENT) {
|
|
799
|
+
workingText.setSpan(
|
|
800
|
+
new ReactBackgroundColorSpan(backgroundColor), 0, workingText.length(), spanFlags);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if ((getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
|
|
804
|
+
workingText.setSpan(new ReactStrikethroughSpan(), 0, workingText.length(), spanFlags);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
if ((getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0) {
|
|
808
|
+
workingText.setSpan(new ReactUnderlineSpan(), 0, workingText.length(), spanFlags);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
812
|
+
float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
|
|
813
|
+
if (!Float.isNaN(effectiveLetterSpacing)) {
|
|
814
|
+
workingText.setSpan(
|
|
815
|
+
new CustomLetterSpacingSpan(effectiveLetterSpacing),
|
|
816
|
+
0,
|
|
817
|
+
workingText.length(),
|
|
818
|
+
spanFlags);
|
|
680
819
|
}
|
|
820
|
+
}
|
|
681
821
|
|
|
682
|
-
|
|
822
|
+
if (mFontStyle != UNSET
|
|
823
|
+
|| mFontWeight != UNSET
|
|
824
|
+
|| mFontFamily != null
|
|
825
|
+
|| getFontFeatureSettings() != null) {
|
|
826
|
+
workingText.setSpan(
|
|
827
|
+
new CustomStyleSpan(
|
|
828
|
+
mFontStyle,
|
|
829
|
+
mFontWeight,
|
|
830
|
+
getFontFeatureSettings(),
|
|
831
|
+
mFontFamily,
|
|
832
|
+
getContext().getAssets()),
|
|
833
|
+
0,
|
|
834
|
+
workingText.length(),
|
|
835
|
+
spanFlags);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
float lineHeight = mTextAttributes.getEffectiveLineHeight();
|
|
839
|
+
if (!Float.isNaN(lineHeight)) {
|
|
840
|
+
workingText.setSpan(new CustomLineHeightSpan(lineHeight), 0, workingText.length(), spanFlags);
|
|
683
841
|
}
|
|
684
842
|
}
|
|
685
843
|
|
|
@@ -699,73 +857,6 @@ public class ReactEditText extends AppCompatEditText
|
|
|
699
857
|
return true;
|
|
700
858
|
}
|
|
701
859
|
|
|
702
|
-
// This is hacked in for Fabric. When we delete non-Fabric code, we might be able to simplify or
|
|
703
|
-
// clean this up a bit.
|
|
704
|
-
private void addSpansForMeasurement(Spannable spannable) {
|
|
705
|
-
if (!mFabricViewStateManager.hasStateWrapper()) {
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
boolean originalDisableTextDiffing = mDisableTextDiffing;
|
|
710
|
-
mDisableTextDiffing = true;
|
|
711
|
-
|
|
712
|
-
int start = 0;
|
|
713
|
-
int end = spannable.length();
|
|
714
|
-
|
|
715
|
-
// Remove duplicate spans we might add here
|
|
716
|
-
Object[] spans = spannable.getSpans(0, length(), Object.class);
|
|
717
|
-
for (Object span : spans) {
|
|
718
|
-
int spanFlags = spannable.getSpanFlags(span);
|
|
719
|
-
boolean isInclusive =
|
|
720
|
-
(spanFlags & Spanned.SPAN_INCLUSIVE_INCLUSIVE) == Spanned.SPAN_INCLUSIVE_INCLUSIVE
|
|
721
|
-
|| (spanFlags & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) == Spanned.SPAN_INCLUSIVE_EXCLUSIVE;
|
|
722
|
-
if (isInclusive
|
|
723
|
-
&& span instanceof ReactSpan
|
|
724
|
-
&& spannable.getSpanStart(span) == start
|
|
725
|
-
&& spannable.getSpanEnd(span) == end) {
|
|
726
|
-
spannable.removeSpan(span);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
List<TextLayoutManager.SetSpanOperation> ops = new ArrayList<>();
|
|
731
|
-
|
|
732
|
-
if (!Float.isNaN(mTextAttributes.getLetterSpacing())) {
|
|
733
|
-
ops.add(
|
|
734
|
-
new TextLayoutManager.SetSpanOperation(
|
|
735
|
-
start, end, new CustomLetterSpacingSpan(mTextAttributes.getLetterSpacing())));
|
|
736
|
-
}
|
|
737
|
-
ops.add(
|
|
738
|
-
new TextLayoutManager.SetSpanOperation(
|
|
739
|
-
start, end, new ReactAbsoluteSizeSpan((int) mTextAttributes.getEffectiveFontSize())));
|
|
740
|
-
if (mFontStyle != UNSET || mFontWeight != UNSET || mFontFamily != null) {
|
|
741
|
-
ops.add(
|
|
742
|
-
new TextLayoutManager.SetSpanOperation(
|
|
743
|
-
start,
|
|
744
|
-
end,
|
|
745
|
-
new CustomStyleSpan(
|
|
746
|
-
mFontStyle,
|
|
747
|
-
mFontWeight,
|
|
748
|
-
null, // TODO: do we need to support FontFeatureSettings / fontVariant?
|
|
749
|
-
mFontFamily,
|
|
750
|
-
getReactContext(ReactEditText.this).getAssets())));
|
|
751
|
-
}
|
|
752
|
-
if (!Float.isNaN(mTextAttributes.getEffectiveLineHeight())) {
|
|
753
|
-
ops.add(
|
|
754
|
-
new TextLayoutManager.SetSpanOperation(
|
|
755
|
-
start, end, new CustomLineHeightSpan(mTextAttributes.getEffectiveLineHeight())));
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
int priority = 0;
|
|
759
|
-
for (TextLayoutManager.SetSpanOperation op : ops) {
|
|
760
|
-
// Actual order of calling {@code execute} does NOT matter,
|
|
761
|
-
// but the {@code priority} DOES matter.
|
|
762
|
-
op.execute(spannable, priority);
|
|
763
|
-
priority++;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
mDisableTextDiffing = originalDisableTextDiffing;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
860
|
protected boolean showSoftKeyboard() {
|
|
770
861
|
return mInputMethodManager.showSoftInput(this, 0);
|
|
771
862
|
}
|
|
@@ -820,6 +911,11 @@ public class ReactEditText extends AppCompatEditText
|
|
|
820
911
|
}
|
|
821
912
|
}
|
|
822
913
|
|
|
914
|
+
/* package */ int getGravityHorizontal() {
|
|
915
|
+
return getGravity()
|
|
916
|
+
& (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
|
917
|
+
}
|
|
918
|
+
|
|
823
919
|
/* package */ void setGravityHorizontal(int gravityHorizontal) {
|
|
824
920
|
if (gravityHorizontal == 0) {
|
|
825
921
|
gravityHorizontal = mDefaultGravityHorizontal;
|
|
@@ -1030,7 +1126,9 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1030
1126
|
|
|
1031
1127
|
float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
|
|
1032
1128
|
if (!Float.isNaN(effectiveLetterSpacing)) {
|
|
1033
|
-
|
|
1129
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
1130
|
+
setLetterSpacing(effectiveLetterSpacing);
|
|
1131
|
+
}
|
|
1034
1132
|
}
|
|
1035
1133
|
}
|
|
1036
1134
|
|
|
@@ -1045,7 +1143,7 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1045
1143
|
* TextLayoutManager.java with some very minor modifications. There's some duplication between
|
|
1046
1144
|
* here and TextLayoutManager, so there might be an opportunity for refactor.
|
|
1047
1145
|
*/
|
|
1048
|
-
private void updateCachedSpannable(
|
|
1146
|
+
private void updateCachedSpannable() {
|
|
1049
1147
|
// Noops in non-Fabric
|
|
1050
1148
|
if (mFabricViewStateManager == null || !mFabricViewStateManager.hasStateWrapper()) {
|
|
1051
1149
|
return;
|
|
@@ -1055,12 +1153,6 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1055
1153
|
return;
|
|
1056
1154
|
}
|
|
1057
1155
|
|
|
1058
|
-
if (resetStyles) {
|
|
1059
|
-
mIsSettingTextFromCacheUpdate = true;
|
|
1060
|
-
addSpansForMeasurement(getText());
|
|
1061
|
-
mIsSettingTextFromCacheUpdate = false;
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
1156
|
Editable currentText = getText();
|
|
1065
1157
|
boolean haveText = currentText != null && currentText.length() > 0;
|
|
1066
1158
|
|
|
@@ -1118,11 +1210,9 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1118
1210
|
// Measure something so we have correct height, even if there's no string.
|
|
1119
1211
|
sb.append("I");
|
|
1120
1212
|
}
|
|
1121
|
-
|
|
1122
|
-
// Make sure that all text styles are applied when we're measurable the hint or "blank" text
|
|
1123
|
-
addSpansForMeasurement(sb);
|
|
1124
1213
|
}
|
|
1125
1214
|
|
|
1215
|
+
addSpansFromStyleAttributes(sb);
|
|
1126
1216
|
TextLayoutManager.setCachedSpannabledForTag(getId(), sb);
|
|
1127
1217
|
}
|
|
1128
1218
|
|
|
@@ -1137,7 +1227,7 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1137
1227
|
private class TextWatcherDelegator implements TextWatcher {
|
|
1138
1228
|
@Override
|
|
1139
1229
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
1140
|
-
if (!
|
|
1230
|
+
if (!mIsSettingTextFromJS && mListeners != null) {
|
|
1141
1231
|
for (TextWatcher listener : mListeners) {
|
|
1142
1232
|
listener.beforeTextChanged(s, start, count, after);
|
|
1143
1233
|
}
|
|
@@ -1151,23 +1241,20 @@ public class ReactEditText extends AppCompatEditText
|
|
|
1151
1241
|
TAG, "onTextChanged[" + getId() + "]: " + s + " " + start + " " + before + " " + count);
|
|
1152
1242
|
}
|
|
1153
1243
|
|
|
1154
|
-
if (!
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
listener.onTextChanged(s, start, before, count);
|
|
1158
|
-
}
|
|
1244
|
+
if (!mIsSettingTextFromJS && mListeners != null) {
|
|
1245
|
+
for (TextWatcher listener : mListeners) {
|
|
1246
|
+
listener.onTextChanged(s, start, before, count);
|
|
1159
1247
|
}
|
|
1160
|
-
|
|
1161
|
-
updateCachedSpannable(
|
|
1162
|
-
!mIsSettingTextFromJS && !mIsSettingTextFromState && start == 0 && before == 0);
|
|
1163
1248
|
}
|
|
1164
1249
|
|
|
1250
|
+
updateCachedSpannable();
|
|
1251
|
+
|
|
1165
1252
|
onContentSizeChange();
|
|
1166
1253
|
}
|
|
1167
1254
|
|
|
1168
1255
|
@Override
|
|
1169
1256
|
public void afterTextChanged(Editable s) {
|
|
1170
|
-
if (!
|
|
1257
|
+
if (!mIsSettingTextFromJS && mListeners != null) {
|
|
1171
1258
|
for (TextWatcher listener : mListeners) {
|
|
1172
1259
|
listener.afterTextChanged(s);
|
|
1173
1260
|
}
|
package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
CHANGED
|
@@ -13,6 +13,7 @@ import android.content.Context;
|
|
|
13
13
|
import android.content.res.ColorStateList;
|
|
14
14
|
import android.graphics.BlendMode;
|
|
15
15
|
import android.graphics.BlendModeColorFilter;
|
|
16
|
+
import android.graphics.Paint;
|
|
16
17
|
import android.graphics.PorterDuff;
|
|
17
18
|
import android.graphics.drawable.Drawable;
|
|
18
19
|
import android.os.Build;
|
|
@@ -67,6 +68,7 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
|
|
|
67
68
|
import com.facebook.react.views.text.ReactBaseTextShadowNode;
|
|
68
69
|
import com.facebook.react.views.text.ReactTextUpdate;
|
|
69
70
|
import com.facebook.react.views.text.ReactTextViewManagerCallback;
|
|
71
|
+
import com.facebook.react.views.text.ReactTypefaceUtils;
|
|
70
72
|
import com.facebook.react.views.text.TextAttributeProps;
|
|
71
73
|
import com.facebook.react.views.text.TextInlineImageSpan;
|
|
72
74
|
import com.facebook.react.views.text.TextLayoutManager;
|
|
@@ -404,6 +406,11 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|
|
404
406
|
view.setFontStyle(fontStyle);
|
|
405
407
|
}
|
|
406
408
|
|
|
409
|
+
@ReactProp(name = ViewProps.FONT_VARIANT)
|
|
410
|
+
public void setFontVariant(ReactEditText view, @Nullable ReadableArray fontVariant) {
|
|
411
|
+
view.setFontFeatureSettings(ReactTypefaceUtils.parseFontVariant(fontVariant));
|
|
412
|
+
}
|
|
413
|
+
|
|
407
414
|
@ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true)
|
|
408
415
|
public void setIncludeFontPadding(ReactEditText view, boolean includepad) {
|
|
409
416
|
view.setIncludeFontPadding(includepad);
|
|
@@ -925,6 +932,20 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|
|
925
932
|
view.setAutoFocus(autoFocus);
|
|
926
933
|
}
|
|
927
934
|
|
|
935
|
+
@ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
|
|
936
|
+
public void setTextDecorationLine(ReactEditText view, @Nullable String textDecorationLineString) {
|
|
937
|
+
view.setPaintFlags(
|
|
938
|
+
view.getPaintFlags() & ~(Paint.STRIKE_THRU_TEXT_FLAG | Paint.UNDERLINE_TEXT_FLAG));
|
|
939
|
+
|
|
940
|
+
for (String token : textDecorationLineString.split(" ")) {
|
|
941
|
+
if (token.equals("underline")) {
|
|
942
|
+
view.setPaintFlags(view.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
|
943
|
+
} else if (token.equals("line-through")) {
|
|
944
|
+
view.setPaintFlags(view.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
928
949
|
@ReactPropGroup(
|
|
929
950
|
names = {
|
|
930
951
|
ViewProps.BORDER_WIDTH,
|
|
@@ -1305,10 +1326,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|
|
1305
1326
|
}
|
|
1306
1327
|
|
|
1307
1328
|
ReadableNativeMap state = stateWrapper.getStateData();
|
|
1308
|
-
if (state == null) {
|
|
1309
|
-
return null;
|
|
1310
|
-
}
|
|
1311
|
-
if (!state.hasKey("attributedString")) {
|
|
1329
|
+
if (state == null || !state.hasKey("attributedString")) {
|
|
1312
1330
|
return null;
|
|
1313
1331
|
}
|
|
1314
1332
|
|
|
@@ -1322,19 +1340,19 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|
|
1322
1340
|
TextLayoutManager.getOrCreateSpannableForText(
|
|
1323
1341
|
view.getContext(), attributedString, mReactTextViewManagerCallback);
|
|
1324
1342
|
|
|
1325
|
-
boolean containsMultipleFragments =
|
|
1326
|
-
attributedString.getArray("fragments").toArrayList().size() > 1;
|
|
1327
|
-
|
|
1328
1343
|
int textBreakStrategy =
|
|
1329
|
-
TextAttributeProps.getTextBreakStrategy(
|
|
1344
|
+
TextAttributeProps.getTextBreakStrategy(
|
|
1345
|
+
paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY));
|
|
1346
|
+
int currentJustificationMode =
|
|
1347
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
|
1330
1348
|
|
|
1331
1349
|
return ReactTextUpdate.buildReactTextUpdateFromState(
|
|
1332
1350
|
spanned,
|
|
1333
1351
|
state.getInt("mostRecentEventCount"),
|
|
1334
|
-
TextAttributeProps.getTextAlignment(
|
|
1352
|
+
TextAttributeProps.getTextAlignment(
|
|
1353
|
+
props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
|
|
1335
1354
|
textBreakStrategy,
|
|
1336
|
-
TextAttributeProps.getJustificationMode(props)
|
|
1337
|
-
containsMultipleFragments);
|
|
1355
|
+
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
|
1338
1356
|
}
|
|
1339
1357
|
|
|
1340
1358
|
public Object getReactTextUpdate(ReactEditText view, ReactStylesDiffMap props, MapBuffer state) {
|
|
@@ -1355,20 +1373,18 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|
|
1355
1373
|
TextLayoutManagerMapBuffer.getOrCreateSpannableForText(
|
|
1356
1374
|
view.getContext(), attributedString, mReactTextViewManagerCallback);
|
|
1357
1375
|
|
|
1358
|
-
boolean containsMultipleFragments =
|
|
1359
|
-
attributedString.getMapBuffer(TextLayoutManagerMapBuffer.AS_KEY_FRAGMENTS).getCount() > 1;
|
|
1360
|
-
|
|
1361
1376
|
int textBreakStrategy =
|
|
1362
1377
|
TextAttributeProps.getTextBreakStrategy(
|
|
1363
1378
|
paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
|
|
1379
|
+
int currentJustificationMode =
|
|
1380
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
|
1364
1381
|
|
|
1365
1382
|
return ReactTextUpdate.buildReactTextUpdateFromState(
|
|
1366
1383
|
spanned,
|
|
1367
1384
|
state.getInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT),
|
|
1368
1385
|
TextAttributeProps.getTextAlignment(
|
|
1369
|
-
props, TextLayoutManagerMapBuffer.isRTL(attributedString)),
|
|
1386
|
+
props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
|
|
1370
1387
|
textBreakStrategy,
|
|
1371
|
-
TextAttributeProps.getJustificationMode(props)
|
|
1372
|
-
containsMultipleFragments);
|
|
1388
|
+
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
|
1373
1389
|
}
|
|
1374
1390
|
}
|
package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java
CHANGED
|
@@ -19,6 +19,7 @@ public class ReactViewBackgroundManager {
|
|
|
19
19
|
|
|
20
20
|
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
|
|
21
21
|
private View mView;
|
|
22
|
+
private int mColor = Color.TRANSPARENT;
|
|
22
23
|
|
|
23
24
|
public ReactViewBackgroundManager(View view) {
|
|
24
25
|
this.mView = view;
|
|
@@ -56,6 +57,10 @@ public class ReactViewBackgroundManager {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
public int getBackgroundColor() {
|
|
61
|
+
return mColor;
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
public void setBorderWidth(int position, float width) {
|
|
60
65
|
getOrCreateReactViewBackground().setBorderWidth(position, width);
|
|
61
66
|
}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|