react-native 0.72.0-rc.0 → 0.72.0-rc.2

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.
Files changed (71) hide show
  1. package/Libraries/Components/View/ReactNativeStyleAttributes.js +0 -7
  2. package/Libraries/Core/ReactNativeVersion.js +1 -1
  3. package/Libraries/Core/ReactNativeVersionCheck.js +5 -1
  4. package/Libraries/NativeComponent/BaseViewConfig.android.js +0 -8
  5. package/Libraries/NativeComponent/BaseViewConfig.ios.js +0 -8
  6. package/Libraries/ReactNative/UIManager.js +27 -1
  7. package/Libraries/Renderer/implementations/ReactFabric-dev.js +26 -3
  8. package/Libraries/Renderer/implementations/ReactFabric-prod.js +13 -1
  9. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +13 -1
  10. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +0 -7
  11. package/Libraries/StyleSheet/StyleSheetTypes.js +0 -74
  12. package/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +3 -3
  13. package/React/Base/RCTVersion.m +1 -1
  14. package/React/CoreModules/RCTDevMenu.mm +3 -3
  15. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropCoordinatorAdapter.mm +1 -1
  16. package/ReactAndroid/gradle.properties +1 -1
  17. package/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +40 -1
  18. package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +22 -7
  19. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +10 -0
  20. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +29 -0
  21. package/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java +25 -2
  22. package/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java +56 -0
  23. package/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +11 -0
  24. package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt +1 -0
  25. package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt +4 -0
  26. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +26 -8
  27. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +21 -0
  28. package/ReactAndroid/src/main/java/com/facebook/react/fabric/interop/InteropEvent.java +41 -0
  29. package/ReactAndroid/src/main/java/com/facebook/react/fabric/interop/InteropEventEmitter.java +65 -0
  30. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +9 -0
  31. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  32. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java +1 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +32 -0
  34. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java +19 -0
  35. package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLetterSpacingSpan.java +4 -0
  36. package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +4 -0
  37. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java +1 -5
  38. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +190 -134
  39. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +23 -10
  40. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java +5 -0
  41. package/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +3 -0
  42. package/ReactCommon/React-rncore.podspec +12 -4
  43. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  44. package/ReactCommon/react/config/ReactNativeConfig.cpp +3 -0
  45. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h +4 -1
  46. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm +49 -2
  47. package/ReactCommon/react/renderer/components/text/ParagraphLayoutManager.cpp +30 -5
  48. package/ReactCommon/react/renderer/components/text/ParagraphLayoutManager.h +12 -0
  49. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +0 -21
  50. package/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +0 -49
  51. package/ReactCommon/react/renderer/components/view/YogaStylableProps.h +0 -9
  52. package/ReactCommon/react/renderer/core/CoreFeatures.cpp +1 -0
  53. package/ReactCommon/react/renderer/core/CoreFeatures.h +5 -0
  54. package/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp +5 -1
  55. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +112 -83
  56. package/build.gradle.kts +17 -0
  57. package/gradle.properties +1 -0
  58. package/package.json +8 -8
  59. package/scripts/cocoapods/__tests__/codegen_utils-test.rb +9 -1
  60. package/scripts/cocoapods/__tests__/jsengine-test.rb +6 -2
  61. package/scripts/cocoapods/__tests__/test_utils/podSpy.rb +2 -1
  62. package/scripts/cocoapods/codegen_utils.rb +1 -1
  63. package/scripts/cocoapods/jsengine.rb +6 -1
  64. package/sdks/hermesc/linux64-bin/hermesc +0 -0
  65. package/sdks/hermesc/osx-bin/hermesc +0 -0
  66. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  67. package/settings.gradle.kts +30 -0
  68. package/template/android/app/build.gradle +7 -2
  69. package/template/metro.config.js +7 -13
  70. package/template/package.json +5 -3
  71. package/types/index.d.ts +4 -0
@@ -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.List;
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 (!mIsSettingTextFromCacheUpdate && mSelectionWatcher != null && hasFocus()) {
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, reactTextUpdate.mContainsMultipleFragments);
588
-
589
- // Mitigation for https://github.com/facebook/react-native/issues/35936 (S318090)
590
- stripAttributeEquivalentSpans(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(false);
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,58 +674,170 @@ public class ReactEditText extends AppCompatEditText
653
674
  spannableStringBuilder.setSpan(span, spanStart, spanEnd, spanFlags);
654
675
  }
655
676
  }
677
+ }
656
678
 
657
- // In Fabric only, apply necessary styles to entire span
658
- // If the Spannable was constructed from multiple fragments, we don't apply any spans that could
659
- // impact the whole Spannable, because that would override "local" styles per-fragment
660
- if (!skipAddSpansForMeasurements) {
661
- addSpansForMeasurement(getText());
662
- }
679
+ // TODO: Replace with Predicate<T> and lambdas once Java 8 builds in OSS
680
+ interface SpanPredicate<T> {
681
+ boolean test(T span);
663
682
  }
664
683
 
665
- private void stripAttributeEquivalentSpans(SpannableStringBuilder sb) {
666
- // We have already set a font size on the EditText itself. We can safely remove sizing spans
667
- // which are the same as the set font size, and not otherwise overlapped.
668
- final int effectiveFontSize = mTextAttributes.getEffectiveFontSize();
669
- ReactAbsoluteSizeSpan[] spans = sb.getSpans(0, sb.length(), ReactAbsoluteSizeSpan.class);
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
+ });
670
699
 
671
- outerLoop:
672
- for (ReactAbsoluteSizeSpan span : spans) {
673
- ReactAbsoluteSizeSpan[] overlappingSpans =
674
- sb.getSpans(sb.getSpanStart(span), sb.getSpanEnd(span), ReactAbsoluteSizeSpan.class);
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
+ });
675
709
 
676
- for (ReactAbsoluteSizeSpan overlappingSpan : overlappingSpans) {
677
- if (span.getSize() != effectiveFontSize) {
678
- continue outerLoop;
679
- }
680
- }
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
+ });
681
729
 
682
- sb.removeSpan(span);
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
+ });
683
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
+ });
684
764
  }
685
765
 
686
- private void unstripAttributeEquivalentSpans(
687
- SpannableStringBuilder workingText, Spannable originalText) {
688
- // We must add spans back for Fabric to be able to measure, at lower precedence than any
689
- // existing spans. Remove all spans, add the attributes, then re-add the spans over
690
- workingText.append(originalText);
766
+ private <T> void stripSpansOfKind(
767
+ SpannableStringBuilder sb, Class<T> clazz, SpanPredicate<T> shouldStrip) {
768
+ T[] spans = sb.getSpans(0, sb.length(), clazz);
691
769
 
692
- for (Object span : workingText.getSpans(0, workingText.length(), Object.class)) {
693
- workingText.removeSpan(span);
770
+ for (T span : spans) {
771
+ if (shouldStrip.test(span)) {
772
+ sb.removeSpan(span);
773
+ }
694
774
  }
775
+ }
776
+
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;
695
787
 
696
788
  workingText.setSpan(
697
789
  new ReactAbsoluteSizeSpan(mTextAttributes.getEffectiveFontSize()),
698
790
  0,
699
791
  workingText.length(),
700
- Spanned.SPAN_INCLUSIVE_INCLUSIVE);
792
+ spanFlags);
793
+
794
+ workingText.setSpan(
795
+ new ReactForegroundColorSpan(getCurrentTextColor()), 0, workingText.length(), spanFlags);
701
796
 
702
- for (Object span : originalText.getSpans(0, originalText.length(), Object.class)) {
797
+ int backgroundColor = mReactBackgroundManager.getBackgroundColor();
798
+ if (backgroundColor != Color.TRANSPARENT) {
703
799
  workingText.setSpan(
704
- span,
705
- originalText.getSpanStart(span),
706
- originalText.getSpanEnd(span),
707
- originalText.getSpanFlags(span));
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);
819
+ }
820
+ }
821
+
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);
708
841
  }
709
842
  }
710
843
 
@@ -724,73 +857,6 @@ public class ReactEditText extends AppCompatEditText
724
857
  return true;
725
858
  }
726
859
 
727
- // This is hacked in for Fabric. When we delete non-Fabric code, we might be able to simplify or
728
- // clean this up a bit.
729
- private void addSpansForMeasurement(Spannable spannable) {
730
- if (!mFabricViewStateManager.hasStateWrapper()) {
731
- return;
732
- }
733
-
734
- boolean originalDisableTextDiffing = mDisableTextDiffing;
735
- mDisableTextDiffing = true;
736
-
737
- int start = 0;
738
- int end = spannable.length();
739
-
740
- // Remove duplicate spans we might add here
741
- Object[] spans = spannable.getSpans(0, length(), Object.class);
742
- for (Object span : spans) {
743
- int spanFlags = spannable.getSpanFlags(span);
744
- boolean isInclusive =
745
- (spanFlags & Spanned.SPAN_INCLUSIVE_INCLUSIVE) == Spanned.SPAN_INCLUSIVE_INCLUSIVE
746
- || (spanFlags & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) == Spanned.SPAN_INCLUSIVE_EXCLUSIVE;
747
- if (isInclusive
748
- && span instanceof ReactSpan
749
- && spannable.getSpanStart(span) == start
750
- && spannable.getSpanEnd(span) == end) {
751
- spannable.removeSpan(span);
752
- }
753
- }
754
-
755
- List<TextLayoutManager.SetSpanOperation> ops = new ArrayList<>();
756
-
757
- if (!Float.isNaN(mTextAttributes.getLetterSpacing())) {
758
- ops.add(
759
- new TextLayoutManager.SetSpanOperation(
760
- start, end, new CustomLetterSpacingSpan(mTextAttributes.getLetterSpacing())));
761
- }
762
- ops.add(
763
- new TextLayoutManager.SetSpanOperation(
764
- start, end, new ReactAbsoluteSizeSpan((int) mTextAttributes.getEffectiveFontSize())));
765
- if (mFontStyle != UNSET || mFontWeight != UNSET || mFontFamily != null) {
766
- ops.add(
767
- new TextLayoutManager.SetSpanOperation(
768
- start,
769
- end,
770
- new CustomStyleSpan(
771
- mFontStyle,
772
- mFontWeight,
773
- null, // TODO: do we need to support FontFeatureSettings / fontVariant?
774
- mFontFamily,
775
- getReactContext(ReactEditText.this).getAssets())));
776
- }
777
- if (!Float.isNaN(mTextAttributes.getEffectiveLineHeight())) {
778
- ops.add(
779
- new TextLayoutManager.SetSpanOperation(
780
- start, end, new CustomLineHeightSpan(mTextAttributes.getEffectiveLineHeight())));
781
- }
782
-
783
- int priority = 0;
784
- for (TextLayoutManager.SetSpanOperation op : ops) {
785
- // Actual order of calling {@code execute} does NOT matter,
786
- // but the {@code priority} DOES matter.
787
- op.execute(spannable, priority);
788
- priority++;
789
- }
790
-
791
- mDisableTextDiffing = originalDisableTextDiffing;
792
- }
793
-
794
860
  protected boolean showSoftKeyboard() {
795
861
  return mInputMethodManager.showSoftInput(this, 0);
796
862
  }
@@ -1060,7 +1126,9 @@ public class ReactEditText extends AppCompatEditText
1060
1126
 
1061
1127
  float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
1062
1128
  if (!Float.isNaN(effectiveLetterSpacing)) {
1063
- setLetterSpacing(effectiveLetterSpacing);
1129
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
1130
+ setLetterSpacing(effectiveLetterSpacing);
1131
+ }
1064
1132
  }
1065
1133
  }
1066
1134
 
@@ -1075,7 +1143,7 @@ public class ReactEditText extends AppCompatEditText
1075
1143
  * TextLayoutManager.java with some very minor modifications. There's some duplication between
1076
1144
  * here and TextLayoutManager, so there might be an opportunity for refactor.
1077
1145
  */
1078
- private void updateCachedSpannable(boolean resetStyles) {
1146
+ private void updateCachedSpannable() {
1079
1147
  // Noops in non-Fabric
1080
1148
  if (mFabricViewStateManager == null || !mFabricViewStateManager.hasStateWrapper()) {
1081
1149
  return;
@@ -1085,12 +1153,6 @@ public class ReactEditText extends AppCompatEditText
1085
1153
  return;
1086
1154
  }
1087
1155
 
1088
- if (resetStyles) {
1089
- mIsSettingTextFromCacheUpdate = true;
1090
- addSpansForMeasurement(getText());
1091
- mIsSettingTextFromCacheUpdate = false;
1092
- }
1093
-
1094
1156
  Editable currentText = getText();
1095
1157
  boolean haveText = currentText != null && currentText.length() > 0;
1096
1158
 
@@ -1132,8 +1194,7 @@ public class ReactEditText extends AppCompatEditText
1132
1194
  // ...
1133
1195
  // - android.app.Activity.dispatchKeyEvent (Activity.java:3447)
1134
1196
  try {
1135
- Spannable text = (Spannable) currentText.subSequence(0, currentText.length());
1136
- unstripAttributeEquivalentSpans(sb, text);
1197
+ sb.append(currentText.subSequence(0, currentText.length()));
1137
1198
  } catch (IndexOutOfBoundsException e) {
1138
1199
  ReactSoftExceptionLogger.logSoftException(TAG, e);
1139
1200
  }
@@ -1149,11 +1210,9 @@ public class ReactEditText extends AppCompatEditText
1149
1210
  // Measure something so we have correct height, even if there's no string.
1150
1211
  sb.append("I");
1151
1212
  }
1152
-
1153
- // Make sure that all text styles are applied when we're measurable the hint or "blank" text
1154
- addSpansForMeasurement(sb);
1155
1213
  }
1156
1214
 
1215
+ addSpansFromStyleAttributes(sb);
1157
1216
  TextLayoutManager.setCachedSpannabledForTag(getId(), sb);
1158
1217
  }
1159
1218
 
@@ -1168,7 +1227,7 @@ public class ReactEditText extends AppCompatEditText
1168
1227
  private class TextWatcherDelegator implements TextWatcher {
1169
1228
  @Override
1170
1229
  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
1171
- if (!mIsSettingTextFromCacheUpdate && !mIsSettingTextFromJS && mListeners != null) {
1230
+ if (!mIsSettingTextFromJS && mListeners != null) {
1172
1231
  for (TextWatcher listener : mListeners) {
1173
1232
  listener.beforeTextChanged(s, start, count, after);
1174
1233
  }
@@ -1182,23 +1241,20 @@ public class ReactEditText extends AppCompatEditText
1182
1241
  TAG, "onTextChanged[" + getId() + "]: " + s + " " + start + " " + before + " " + count);
1183
1242
  }
1184
1243
 
1185
- if (!mIsSettingTextFromCacheUpdate) {
1186
- if (!mIsSettingTextFromJS && mListeners != null) {
1187
- for (TextWatcher listener : mListeners) {
1188
- listener.onTextChanged(s, start, before, count);
1189
- }
1244
+ if (!mIsSettingTextFromJS && mListeners != null) {
1245
+ for (TextWatcher listener : mListeners) {
1246
+ listener.onTextChanged(s, start, before, count);
1190
1247
  }
1191
-
1192
- updateCachedSpannable(
1193
- !mIsSettingTextFromJS && !mIsSettingTextFromState && start == 0 && before == 0);
1194
1248
  }
1195
1249
 
1250
+ updateCachedSpannable();
1251
+
1196
1252
  onContentSizeChange();
1197
1253
  }
1198
1254
 
1199
1255
  @Override
1200
1256
  public void afterTextChanged(Editable s) {
1201
- if (!mIsSettingTextFromCacheUpdate && !mIsSettingTextFromJS && mListeners != null) {
1257
+ if (!mIsSettingTextFromJS && mListeners != null) {
1202
1258
  for (TextWatcher listener : mListeners) {
1203
1259
  listener.afterTextChanged(s);
1204
1260
  }
@@ -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;
@@ -68,6 +69,7 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
68
69
  import com.facebook.react.views.text.ReactBaseTextShadowNode;
69
70
  import com.facebook.react.views.text.ReactTextUpdate;
70
71
  import com.facebook.react.views.text.ReactTextViewManagerCallback;
72
+ import com.facebook.react.views.text.ReactTypefaceUtils;
71
73
  import com.facebook.react.views.text.TextAttributeProps;
72
74
  import com.facebook.react.views.text.TextInlineImageSpan;
73
75
  import com.facebook.react.views.text.TextLayoutManager;
@@ -412,6 +414,11 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
412
414
  view.setFontStyle(fontStyle);
413
415
  }
414
416
 
417
+ @ReactProp(name = ViewProps.FONT_VARIANT)
418
+ public void setFontVariant(ReactEditText view, @Nullable ReadableArray fontVariant) {
419
+ view.setFontFeatureSettings(ReactTypefaceUtils.parseFontVariant(fontVariant));
420
+ }
421
+
415
422
  @ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true)
416
423
  public void setIncludeFontPadding(ReactEditText view, boolean includepad) {
417
424
  view.setIncludeFontPadding(includepad);
@@ -935,6 +942,20 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
935
942
  view.setAutoFocus(autoFocus);
936
943
  }
937
944
 
945
+ @ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
946
+ public void setTextDecorationLine(ReactEditText view, @Nullable String textDecorationLineString) {
947
+ view.setPaintFlags(
948
+ view.getPaintFlags() & ~(Paint.STRIKE_THRU_TEXT_FLAG | Paint.UNDERLINE_TEXT_FLAG));
949
+
950
+ for (String token : textDecorationLineString.split(" ")) {
951
+ if (token.equals("underline")) {
952
+ view.setPaintFlags(view.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
953
+ } else if (token.equals("line-through")) {
954
+ view.setPaintFlags(view.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
955
+ }
956
+ }
957
+ }
958
+
938
959
  @ReactPropGroup(
939
960
  names = {
940
961
  ViewProps.BORDER_WIDTH,
@@ -1329,9 +1350,6 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
1329
1350
  TextLayoutManager.getOrCreateSpannableForText(
1330
1351
  view.getContext(), attributedString, mReactTextViewManagerCallback);
1331
1352
 
1332
- boolean containsMultipleFragments =
1333
- attributedString.getArray("fragments").toArrayList().size() > 1;
1334
-
1335
1353
  int textBreakStrategy =
1336
1354
  TextAttributeProps.getTextBreakStrategy(
1337
1355
  paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY));
@@ -1344,8 +1362,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
1344
1362
  TextAttributeProps.getTextAlignment(
1345
1363
  props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
1346
1364
  textBreakStrategy,
1347
- TextAttributeProps.getJustificationMode(props, currentJustificationMode),
1348
- containsMultipleFragments);
1365
+ TextAttributeProps.getJustificationMode(props, currentJustificationMode));
1349
1366
  }
1350
1367
 
1351
1368
  public Object getReactTextUpdate(ReactEditText view, ReactStylesDiffMap props, MapBuffer state) {
@@ -1366,9 +1383,6 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
1366
1383
  TextLayoutManagerMapBuffer.getOrCreateSpannableForText(
1367
1384
  view.getContext(), attributedString, mReactTextViewManagerCallback);
1368
1385
 
1369
- boolean containsMultipleFragments =
1370
- attributedString.getMapBuffer(TextLayoutManagerMapBuffer.AS_KEY_FRAGMENTS).getCount() > 1;
1371
-
1372
1386
  int textBreakStrategy =
1373
1387
  TextAttributeProps.getTextBreakStrategy(
1374
1388
  paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
@@ -1381,7 +1395,6 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
1381
1395
  TextAttributeProps.getTextAlignment(
1382
1396
  props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
1383
1397
  textBreakStrategy,
1384
- TextAttributeProps.getJustificationMode(props, currentJustificationMode),
1385
- containsMultipleFragments);
1398
+ TextAttributeProps.getJustificationMode(props, currentJustificationMode));
1386
1399
  }
1387
1400
  }
@@ -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
  }
@@ -429,6 +429,9 @@ void Binding::installFabricUIManager(
429
429
  "CalculateTransformedFramesEnabled",
430
430
  getFeatureFlagValue("calculateTransformedFramesEnabled"));
431
431
 
432
+ CoreFeatures::cacheLastTextMeasurement =
433
+ getFeatureFlagValue("enableTextMeasureCachePerShadowNode");
434
+
432
435
  // Props setter pattern feature
433
436
  CoreFeatures::enablePropIteratorSetter =
434
437
  getFeatureFlagValue("enableCppPropsIteratorSetter");
@@ -16,7 +16,15 @@ else
16
16
  source[:tag] = "v#{version}"
17
17
  end
18
18
 
19
- react_native_path = ".."
19
+ # We are using two different paths for react native because of the way how js_srcs_dir and output_dir options are used
20
+ # output_dir option usage was introduced in https://github.com/facebook/react-native/pull/36210
21
+ # React-rncore.podspec is the only podspec in the project that uses this option
22
+ # We should rethink this approach in T148704916
23
+
24
+ # Relative path to react native from iOS project root (e.g. <ios-project-root>/../node_modules/react-native)
25
+ react_native_dependency_path = ENV['REACT_NATIVE_PATH']
26
+ # Relative path to react native from current podspec
27
+ react_native_sources_path = '..'
20
28
 
21
29
  Pod::Spec.new do |s|
22
30
  s.name = "React-rncore"
@@ -33,10 +41,10 @@ Pod::Spec.new do |s|
33
41
 
34
42
 
35
43
  use_react_native_codegen!(s, {
36
- :react_native_path => react_native_path,
37
- :js_srcs_dir => "#{react_native_path}/Libraries",
44
+ :react_native_path => react_native_sources_path,
45
+ :js_srcs_dir => "#{react_native_sources_path}/Libraries",
38
46
  :library_name => "rncore",
39
47
  :library_type => "components",
40
- :output_dir => "#{react_native_path}/react-native/ReactCommon"
48
+ :output_dir => "#{react_native_dependency_path}/ReactCommon"
41
49
  })
42
50
  end
@@ -18,7 +18,7 @@ constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 72;
20
20
  int32_t Patch = 0;
21
- std::string_view Prerelease = "rc.0";
21
+ std::string_view Prerelease = "rc.2";
22
22
  } ReactNativeVersion;
23
23
 
24
24
  } // namespace facebook::react
@@ -24,6 +24,9 @@ bool EmptyReactNativeConfig::getBool(const std::string &param) const {
24
24
  if (param == "react_fabric:enabled_layout_animations_ios") {
25
25
  return true;
26
26
  }
27
+ if (param == "react_fabric:enable_nstextstorage_caching") {
28
+ return true;
29
+ }
27
30
  return false;
28
31
  }
29
32
 
@@ -33,7 +33,10 @@ typedef void (^InterceptorBlock)(std::string eventName, folly::dynamic event);
33
33
 
34
34
  - (NSString *)componentViewName;
35
35
 
36
- - (void)handleCommand:(NSString *)commandName args:(NSArray *)args reactTag:(NSInteger)tag;
36
+ - (void)handleCommand:(NSString *)commandName
37
+ args:(NSArray *)args
38
+ reactTag:(NSInteger)tag
39
+ paperView:(UIView *)paperView;
37
40
 
38
41
  @end
39
42