react-native-tvos 0.77.0-0rc5 → 0.77.2-0
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/Components/TV/TVFocusGuideView.js +0 -1
- package/Libraries/Components/View/ViewPropTypes.d.ts +4 -2
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Core/setUpDeveloperTools.js +2 -3
- package/Libraries/Image/Image.android.js +2 -0
- package/Libraries/Image/ImageViewNativeComponent.js +3 -4
- package/Libraries/Image/RCTImageLoader.mm +9 -1
- package/Libraries/Pressability/Pressability.js +2 -2
- package/Libraries/Text/TextInput/RCTBaseTextInputView.mm +1 -1
- package/Libraries/Utilities/HMRClient.js +0 -28
- package/Libraries/Utilities/HMRClientProdShim.js +0 -1
- package/React/Base/RCTConvert.mm +3 -1
- package/React/Base/RCTVersion.m +2 -2
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +85 -31
- package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +5 -2
- package/React/Views/RCTTVView.m +5 -2
- package/React/Views/ScrollView/RCTScrollView.m +63 -26
- package/ReactAndroid/api/ReactAndroid.api +3 -0
- package/ReactAndroid/cmake-utils/ReactNative-application.cmake +13 -3
- package/ReactAndroid/gradle.properties +3 -3
- package/ReactAndroid/src/main/AndroidManifest.xml +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +8 -0
- package/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +12 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +37 -0
- package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +6 -1
- package/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DebugOverlayController.java +7 -2
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +8 -2
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +15 -8
- package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt +6 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt +15 -4
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +21 -41
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundDrawable.kt +0 -1
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt +0 -1
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +0 -1
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt +141 -158
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/Drawable.kt +17 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/LayerDrawable.kt +19 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt +0 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +22 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +10 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +36 -27
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +3 -3
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +16 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +38 -31
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +4 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputLocalData.java +13 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +12 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java +2 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +15 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +22 -4
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h +5 -0
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +51 -22
- package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +6 -0
- package/ReactCommon/react/renderer/attributedstring/TextAttributes.h +2 -0
- package/ReactCommon/react/renderer/attributedstring/conversions.h +5 -0
- package/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +12 -0
- package/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h +2 -3
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +24 -3
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +6 -46
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +4 -5
- package/gradle/libs.versions.toml +1 -1
- package/package.json +15 -12
- package/react-native.config.js +11 -21
- package/scripts/codegen/generate-artifacts-executor.js +8 -4
- package/scripts/generate-codegen-artifacts.js +6 -1
- package/sdks/hermes-engine/hermes-utils.rb +2 -2
- package/sdks/hermesc/linux64-bin/hermesc +0 -0
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +2 -2
|
@@ -410,23 +410,26 @@ public class TextLayoutManager {
|
|
|
410
410
|
if (widthYogaMeasureMode == YogaMeasureMode.EXACTLY) {
|
|
411
411
|
desiredWidth = width;
|
|
412
412
|
}
|
|
413
|
-
|
|
414
413
|
int hintWidth = (int) Math.ceil(desiredWidth);
|
|
415
|
-
|
|
414
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
415
|
+
StaticLayout.Builder builder =
|
|
416
416
|
StaticLayout.Builder.obtain(text, 0, spanLength, paint, hintWidth)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
417
|
+
.setAlignment(alignment)
|
|
418
|
+
.setLineSpacing(0.f, 1.f)
|
|
419
|
+
.setIncludePad(includeFontPadding)
|
|
420
|
+
.setBreakStrategy(textBreakStrategy)
|
|
421
|
+
.setHyphenationFrequency(hyphenationFrequency)
|
|
422
|
+
.setTextDirection(
|
|
423
|
+
isScriptRTL ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR);
|
|
424
|
+
|
|
425
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
426
|
+
builder.setUseLineSpacingFromFallbacks(true);
|
|
427
|
+
}
|
|
428
428
|
|
|
429
|
-
|
|
429
|
+
layout = builder.build();
|
|
430
|
+
} else {
|
|
431
|
+
layout = new StaticLayout(text, paint, hintWidth, alignment, 1.0f, 0.0f, includeFontPadding);
|
|
432
|
+
}
|
|
430
433
|
|
|
431
434
|
} else if (boring != null && (unconstrainedWidth || boring.width <= width)) {
|
|
432
435
|
int boringLayoutWidth = boring.width;
|
|
@@ -445,25 +448,29 @@ public class TextLayoutManager {
|
|
|
445
448
|
text, paint, boringLayoutWidth, alignment, 1.f, 0.f, boring, includeFontPadding);
|
|
446
449
|
} else {
|
|
447
450
|
// Is used for multiline, boring text and the width is known.
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
451
|
+
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
452
|
+
StaticLayout.Builder builder =
|
|
453
|
+
StaticLayout.Builder.obtain(text, 0, spanLength, paint, (int) Math.ceil(width))
|
|
454
|
+
.setAlignment(alignment)
|
|
455
|
+
.setLineSpacing(0.f, 1.f)
|
|
456
|
+
.setIncludePad(includeFontPadding)
|
|
457
|
+
.setBreakStrategy(textBreakStrategy)
|
|
458
|
+
.setHyphenationFrequency(hyphenationFrequency)
|
|
459
|
+
.setTextDirection(
|
|
460
|
+
isScriptRTL ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR);
|
|
461
|
+
|
|
462
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
463
|
+
builder.setJustificationMode(justificationMode);
|
|
464
|
+
}
|
|
461
465
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
466
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
467
|
+
builder.setUseLineSpacingFromFallbacks(true);
|
|
468
|
+
}
|
|
465
469
|
|
|
466
|
-
|
|
470
|
+
layout = builder.build();
|
|
471
|
+
} else {
|
|
472
|
+
layout = new StaticLayout(text, paint, (int) Math.ceil(width), alignment, 1.0f, 0.0f, includeFontPadding);
|
|
473
|
+
}
|
|
467
474
|
}
|
|
468
475
|
return layout;
|
|
469
476
|
}
|
|
@@ -232,7 +232,9 @@ public class ReactEditText extends AppCompatEditText {
|
|
|
232
232
|
public void onDestroyActionMode(ActionMode mode) {}
|
|
233
233
|
};
|
|
234
234
|
setCustomSelectionActionModeCallback(customActionModeCallback);
|
|
235
|
-
|
|
235
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
236
|
+
setCustomInsertionActionModeCallback(customActionModeCallback);
|
|
237
|
+
}
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
@Override
|
|
@@ -753,7 +755,7 @@ public class ReactEditText extends AppCompatEditText {
|
|
|
753
755
|
}
|
|
754
756
|
mDisableTextDiffing = false;
|
|
755
757
|
|
|
756
|
-
if (getBreakStrategy() != reactTextUpdate.getTextBreakStrategy()) {
|
|
758
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getBreakStrategy() != reactTextUpdate.getTextBreakStrategy()) {
|
|
757
759
|
setBreakStrategy(reactTextUpdate.getTextBreakStrategy());
|
|
758
760
|
}
|
|
759
761
|
|
package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputLocalData.java
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.views.textinput;
|
|
9
9
|
|
|
10
|
+
import android.annotation.TargetApi;
|
|
11
|
+
import android.graphics.text.LineBreaker;
|
|
12
|
+
import android.os.Build;
|
|
13
|
+
import android.text.Layout;
|
|
10
14
|
import android.text.SpannableStringBuilder;
|
|
11
15
|
import android.util.TypedValue;
|
|
12
16
|
import android.widget.EditText;
|
|
@@ -22,6 +26,7 @@ public final class ReactTextInputLocalData {
|
|
|
22
26
|
private final int mBreakStrategy;
|
|
23
27
|
private final CharSequence mPlaceholder;
|
|
24
28
|
|
|
29
|
+
@TargetApi(Build.VERSION_CODES.M)
|
|
25
30
|
public ReactTextInputLocalData(EditText editText) {
|
|
26
31
|
mText = new SpannableStringBuilder(editText.getText());
|
|
27
32
|
mTextSize = editText.getTextSize();
|
|
@@ -29,7 +34,11 @@ public final class ReactTextInputLocalData {
|
|
|
29
34
|
mPlaceholder = editText.getHint();
|
|
30
35
|
mMinLines = editText.getMinLines();
|
|
31
36
|
mMaxLines = editText.getMaxLines();
|
|
32
|
-
|
|
37
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
38
|
+
mBreakStrategy = editText.getBreakStrategy();
|
|
39
|
+
} else {
|
|
40
|
+
mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
|
|
41
|
+
}
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
public void apply(EditText editText) {
|
|
@@ -39,6 +48,8 @@ public final class ReactTextInputLocalData {
|
|
|
39
48
|
editText.setMaxLines(mMaxLines);
|
|
40
49
|
editText.setInputType(mInputType);
|
|
41
50
|
editText.setHint(mPlaceholder);
|
|
42
|
-
|
|
51
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
52
|
+
editText.setBreakStrategy(mBreakStrategy);
|
|
53
|
+
}
|
|
43
54
|
}
|
|
44
55
|
}
|
package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.views.textinput;
|
|
9
9
|
|
|
10
|
+
import android.annotation.TargetApi;
|
|
11
|
+
import android.os.Build;
|
|
10
12
|
import android.text.Layout;
|
|
11
13
|
import android.util.TypedValue;
|
|
12
14
|
import android.view.ViewGroup;
|
|
@@ -32,6 +34,7 @@ import com.facebook.yoga.YogaMeasureMode;
|
|
|
32
34
|
import com.facebook.yoga.YogaMeasureOutput;
|
|
33
35
|
import com.facebook.yoga.YogaNode;
|
|
34
36
|
|
|
37
|
+
@TargetApi(Build.VERSION_CODES.M)
|
|
35
38
|
@VisibleForTesting
|
|
36
39
|
public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
|
|
37
40
|
implements YogaMeasureFunction {
|
|
@@ -50,7 +53,9 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
|
|
|
50
53
|
public ReactTextInputShadowNode(
|
|
51
54
|
@Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) {
|
|
52
55
|
super(reactTextViewManagerCallback);
|
|
53
|
-
mTextBreakStrategy =
|
|
56
|
+
mTextBreakStrategy = (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
|
|
57
|
+
? Layout.BREAK_STRATEGY_SIMPLE
|
|
58
|
+
: Layout.BREAK_STRATEGY_HIGH_QUALITY;
|
|
54
59
|
|
|
55
60
|
initMeasureFunction();
|
|
56
61
|
}
|
|
@@ -112,7 +117,8 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
|
|
|
112
117
|
editText.setLines(mNumberOfLines);
|
|
113
118
|
}
|
|
114
119
|
|
|
115
|
-
if (
|
|
120
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
|
121
|
+
&& editText.getBreakStrategy() != mTextBreakStrategy) {
|
|
116
122
|
editText.setBreakStrategy(mTextBreakStrategy);
|
|
117
123
|
}
|
|
118
124
|
}
|
|
@@ -175,6 +181,10 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
|
|
|
175
181
|
|
|
176
182
|
@Override
|
|
177
183
|
public void setTextBreakStrategy(@Nullable String textBreakStrategy) {
|
|
184
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
178
188
|
if (textBreakStrategy == null || "simple".equals(textBreakStrategy)) {
|
|
179
189
|
mTextBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
|
|
180
190
|
} else if ("highQuality".equals(textBreakStrategy)) {
|
|
@@ -13,6 +13,7 @@ import android.graphics.Color;
|
|
|
13
13
|
import android.graphics.drawable.ColorDrawable;
|
|
14
14
|
import android.graphics.drawable.Drawable;
|
|
15
15
|
import android.graphics.drawable.RippleDrawable;
|
|
16
|
+
import android.os.Build;
|
|
16
17
|
import android.util.TypedValue;
|
|
17
18
|
import androidx.annotation.Nullable;
|
|
18
19
|
import com.facebook.infer.annotation.Nullsafe;
|
|
@@ -79,7 +80,7 @@ public class ReactDrawableHelper {
|
|
|
79
80
|
|
|
80
81
|
private static @Nullable Drawable setRadius(
|
|
81
82
|
ReadableMap drawableDescriptionDict, @Nullable Drawable drawable) {
|
|
82
|
-
if (drawableDescriptionDict.hasKey("rippleRadius") && drawable instanceof RippleDrawable) {
|
|
83
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && drawableDescriptionDict.hasKey("rippleRadius") && drawable instanceof RippleDrawable) {
|
|
83
84
|
RippleDrawable rippleDrawable = (RippleDrawable) drawable;
|
|
84
85
|
double rippleRadius = drawableDescriptionDict.getDouble("rippleRadius");
|
|
85
86
|
rippleDrawable.setRadius((int) PixelUtil.toPixelFromDIP(rippleRadius));
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
package com.facebook.react.views.view
|
|
9
9
|
|
|
10
10
|
import android.accessibilityservice.AccessibilityServiceInfo
|
|
11
|
+
import android.annotation.TargetApi
|
|
11
12
|
import android.content.Context
|
|
12
13
|
import android.content.pm.PackageManager
|
|
13
14
|
import android.graphics.Rect
|
|
15
|
+
import android.os.Build
|
|
14
16
|
import android.view.View
|
|
15
17
|
import android.view.ViewGroup
|
|
16
18
|
import android.view.accessibility.AccessibilityManager
|
|
@@ -82,6 +84,7 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
|
|
|
82
84
|
return view
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
|
|
85
88
|
@ReactProp(name = "accessible")
|
|
86
89
|
public open fun setAccessible(view: ReactViewGroup, accessible: Boolean) {
|
|
87
90
|
view.isFocusable = accessible
|
|
@@ -109,6 +112,17 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
|
|
|
109
112
|
|
|
110
113
|
@ReactProp(name = "hasTVPreferredFocus")
|
|
111
114
|
public open fun setTVPreferredFocus(view: ReactViewGroup, hasTVPreferredFocus: Boolean) {
|
|
115
|
+
/*
|
|
116
|
+
* React prop functions like this one gets called repeatedly on the New Architecture
|
|
117
|
+
* no matter the prop has changed or not. Contrary to others, `hasTVPreferredFocus` has
|
|
118
|
+
* a side effect, calling `requestFocus` function on the view which disrupts the user flow
|
|
119
|
+
* and should only called once when the property changes to `true.
|
|
120
|
+
* We keep a special state in the View class and run a comparison here to mitigate
|
|
121
|
+
* that problem.
|
|
122
|
+
*/
|
|
123
|
+
if (view.hasTVPreferredFocus == hasTVPreferredFocus) return;
|
|
124
|
+
view.hasTVPreferredFocus = hasTVPreferredFocus;
|
|
125
|
+
|
|
112
126
|
if (hasTVPreferredFocus) {
|
|
113
127
|
view.isFocusable = true
|
|
114
128
|
view.isFocusableInTouchMode = true
|
|
@@ -269,6 +283,7 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
|
|
|
269
283
|
BackgroundStyleApplicator.setFeedbackUnderlay(view, bg)
|
|
270
284
|
}
|
|
271
285
|
|
|
286
|
+
@TargetApi(Build.VERSION_CODES.M)
|
|
272
287
|
@ReactProp(name = "nativeForegroundAndroid")
|
|
273
288
|
public open fun setNativeForeground(view: ReactViewGroup, foreground: ReadableMap?) {
|
|
274
289
|
view.foreground =
|
|
@@ -17,8 +17,8 @@ namespace facebook::react {
|
|
|
17
17
|
constexpr struct {
|
|
18
18
|
int32_t Major = 0;
|
|
19
19
|
int32_t Minor = 77;
|
|
20
|
-
int32_t Patch =
|
|
21
|
-
std::string_view Prerelease = "
|
|
20
|
+
int32_t Patch = 2;
|
|
21
|
+
std::string_view Prerelease = "0";
|
|
22
22
|
} ReactNativeVersion;
|
|
23
23
|
|
|
24
24
|
} // namespace facebook::react
|
package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm
CHANGED
|
@@ -123,6 +123,15 @@ std::vector<ExportedMethod> parseExportedMethods(std::string moduleName, Class m
|
|
|
123
123
|
NSArray<RCTMethodArgument *> *arguments;
|
|
124
124
|
SEL objCMethodSelector = NSSelectorFromString(RCTParseMethodSignature(methodInfo->objcName, &arguments));
|
|
125
125
|
NSMethodSignature *objCMethodSignature = [moduleClass instanceMethodSignatureForSelector:objCMethodSelector];
|
|
126
|
+
if (objCMethodSignature == nullptr) {
|
|
127
|
+
RCTLogWarn(
|
|
128
|
+
@"The objective-c `%s` method signature for the JS method `%@` can not be found in the ObjecitveC definition of the %s module.\nThe `%@` JS method will not be available.",
|
|
129
|
+
methodInfo->objcName,
|
|
130
|
+
jsMethodName,
|
|
131
|
+
moduleName.c_str(),
|
|
132
|
+
jsMethodName);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
126
135
|
std::string objCMethodReturnType = [objCMethodSignature methodReturnType];
|
|
127
136
|
|
|
128
137
|
if (objCMethodSignature.numberOfArguments - 2 != [arguments count]) {
|
|
@@ -337,7 +346,7 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
337
346
|
SEL selector = selectorForType(argumentType);
|
|
338
347
|
|
|
339
348
|
if ([RCTConvert respondsToSelector:selector]) {
|
|
340
|
-
id objCArg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
|
|
349
|
+
id objCArg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
|
|
341
350
|
|
|
342
351
|
if (objCArgType == @encode(char)) {
|
|
343
352
|
char arg = RCTConvertTo<char>(selector, objCArg);
|
|
@@ -437,6 +446,15 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
437
446
|
|
|
438
447
|
if (objCArgType == @encode(id)) {
|
|
439
448
|
id arg = RCTConvertTo<id>(selector, objCArg);
|
|
449
|
+
|
|
450
|
+
// Handle the special case where there is an argument and it must be nil
|
|
451
|
+
// Without this check, the JS side will receive an object.
|
|
452
|
+
// See: discussion at
|
|
453
|
+
// https://github.com/facebook/react-native/pull/49250#issuecomment-2668465893
|
|
454
|
+
if (arg == [NSNull null]) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
440
458
|
if (arg) {
|
|
441
459
|
[retainedObjectsForInvocation addObject:arg];
|
|
442
460
|
}
|
|
@@ -491,7 +509,7 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
491
509
|
}
|
|
492
510
|
|
|
493
511
|
RCTResponseSenderBlock arg =
|
|
494
|
-
(RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
|
|
512
|
+
(RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
|
|
495
513
|
if (arg) {
|
|
496
514
|
[retainedObjectsForInvocation addObject:arg];
|
|
497
515
|
}
|
|
@@ -506,7 +524,7 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
506
524
|
}
|
|
507
525
|
|
|
508
526
|
RCTResponseSenderBlock senderBlock =
|
|
509
|
-
(RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
|
|
527
|
+
(RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
|
|
510
528
|
RCTResponseErrorBlock arg = ^(NSError *error) {
|
|
511
529
|
senderBlock(@[ RCTJSErrorFromNSError(error) ]);
|
|
512
530
|
};
|
|
@@ -536,7 +554,7 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
536
554
|
runtime, errorPrefix + "JavaScript argument must be a plain object. Got " + getType(runtime, jsiArg));
|
|
537
555
|
}
|
|
538
556
|
|
|
539
|
-
id arg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
|
|
557
|
+
id arg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
|
|
540
558
|
|
|
541
559
|
RCTManagedPointer *(*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
|
|
542
560
|
RCTManagedPointer *box = convert([RCTCxxConvert class], selector, arg);
|
|
@@ -32,6 +32,11 @@ using EventEmitterCallback = std::function<void(const std::string &, id)>;
|
|
|
32
32
|
namespace TurboModuleConvertUtils {
|
|
33
33
|
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
|
|
34
34
|
id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, std::shared_ptr<CallInvoker> jsInvoker);
|
|
35
|
+
id convertJSIValueToObjCObject(
|
|
36
|
+
jsi::Runtime &runtime,
|
|
37
|
+
const jsi::Value &value,
|
|
38
|
+
std::shared_ptr<CallInvoker> jsInvoker,
|
|
39
|
+
BOOL useNSNull);
|
|
35
40
|
} // namespace TurboModuleConvertUtils
|
|
36
41
|
|
|
37
42
|
template <>
|
|
@@ -57,7 +57,7 @@ static jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *va
|
|
|
57
57
|
|
|
58
58
|
static jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
|
|
59
59
|
{
|
|
60
|
-
return jsi::String::createFromUtf8(runtime, [value UTF8String]
|
|
60
|
+
return jsi::String::createFromUtf8(runtime, [value UTF8String] ? [value UTF8String] : "");
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
static jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
|
|
@@ -111,21 +111,27 @@ static NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::St
|
|
|
111
111
|
return [NSString stringWithUTF8String:value.utf8(runtime).c_str()];
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
static NSArray *
|
|
115
|
-
|
|
114
|
+
static NSArray *convertJSIArrayToNSArray(
|
|
115
|
+
jsi::Runtime &runtime,
|
|
116
|
+
const jsi::Array &value,
|
|
117
|
+
std::shared_ptr<CallInvoker> jsInvoker,
|
|
118
|
+
BOOL useNSNull)
|
|
116
119
|
{
|
|
117
120
|
size_t size = value.size(runtime);
|
|
118
121
|
NSMutableArray *result = [NSMutableArray new];
|
|
119
122
|
for (size_t i = 0; i < size; i++) {
|
|
120
123
|
// Insert kCFNull when it's `undefined` value to preserve the indices.
|
|
121
|
-
id convertedObject = convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker);
|
|
124
|
+
id convertedObject = convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker, useNSNull);
|
|
122
125
|
[result addObject:convertedObject ? convertedObject : (id)kCFNull];
|
|
123
126
|
}
|
|
124
127
|
return [result copy];
|
|
125
128
|
}
|
|
126
129
|
|
|
127
|
-
static NSDictionary *
|
|
128
|
-
|
|
130
|
+
static NSDictionary *convertJSIObjectToNSDictionary(
|
|
131
|
+
jsi::Runtime &runtime,
|
|
132
|
+
const jsi::Object &value,
|
|
133
|
+
std::shared_ptr<CallInvoker> jsInvoker,
|
|
134
|
+
BOOL useNSNull)
|
|
129
135
|
{
|
|
130
136
|
jsi::Array propertyNames = value.getPropertyNames(runtime);
|
|
131
137
|
size_t size = propertyNames.size(runtime);
|
|
@@ -133,7 +139,7 @@ convertJSIObjectToNSDictionary(jsi::Runtime &runtime, const jsi::Object &value,
|
|
|
133
139
|
for (size_t i = 0; i < size; i++) {
|
|
134
140
|
jsi::String name = propertyNames.getValueAtIndex(runtime, i).getString(runtime);
|
|
135
141
|
NSString *k = convertJSIStringToNSString(runtime, name);
|
|
136
|
-
id v = convertJSIValueToObjCObject(runtime, value.getProperty(runtime, name), jsInvoker);
|
|
142
|
+
id v = convertJSIValueToObjCObject(runtime, value.getProperty(runtime, name), jsInvoker, useNSNull);
|
|
137
143
|
if (v) {
|
|
138
144
|
result[k] = v;
|
|
139
145
|
}
|
|
@@ -161,9 +167,21 @@ convertJSIFunctionToCallback(jsi::Runtime &rt, jsi::Function &&function, std::sh
|
|
|
161
167
|
|
|
162
168
|
id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, std::shared_ptr<CallInvoker> jsInvoker)
|
|
163
169
|
{
|
|
164
|
-
|
|
170
|
+
return convertJSIValueToObjCObject(runtime, value, jsInvoker, NO);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
id convertJSIValueToObjCObject(
|
|
174
|
+
jsi::Runtime &runtime,
|
|
175
|
+
const jsi::Value &value,
|
|
176
|
+
std::shared_ptr<CallInvoker> jsInvoker,
|
|
177
|
+
BOOL useNSNull)
|
|
178
|
+
{
|
|
179
|
+
if (value.isUndefined() || (value.isNull() && !useNSNull)) {
|
|
165
180
|
return nil;
|
|
166
181
|
}
|
|
182
|
+
if (value.isNull() && useNSNull) {
|
|
183
|
+
return [NSNull null];
|
|
184
|
+
}
|
|
167
185
|
if (value.isBool()) {
|
|
168
186
|
return @(value.getBool());
|
|
169
187
|
}
|
|
@@ -176,12 +194,12 @@ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, s
|
|
|
176
194
|
if (value.isObject()) {
|
|
177
195
|
jsi::Object o = value.getObject(runtime);
|
|
178
196
|
if (o.isArray(runtime)) {
|
|
179
|
-
return convertJSIArrayToNSArray(runtime, o.getArray(runtime), jsInvoker);
|
|
197
|
+
return convertJSIArrayToNSArray(runtime, o.getArray(runtime), jsInvoker, useNSNull);
|
|
180
198
|
}
|
|
181
199
|
if (o.isFunction(runtime)) {
|
|
182
200
|
return convertJSIFunctionToCallback(runtime, o.getFunction(runtime), jsInvoker);
|
|
183
201
|
}
|
|
184
|
-
return convertJSIObjectToNSDictionary(runtime, o, jsInvoker);
|
|
202
|
+
return convertJSIObjectToNSDictionary(runtime, o, jsInvoker, useNSNull);
|
|
185
203
|
}
|
|
186
204
|
|
|
187
205
|
throw std::runtime_error("Unsupported jsi::Value kind");
|
|
@@ -195,7 +213,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
|
|
|
195
213
|
/**
|
|
196
214
|
* Creates JSError with current JS runtime and NSException stack trace.
|
|
197
215
|
*/
|
|
198
|
-
static jsi::JSError convertNSExceptionToJSError(
|
|
216
|
+
static jsi::JSError convertNSExceptionToJSError(
|
|
217
|
+
jsi::Runtime &runtime,
|
|
218
|
+
NSException *exception,
|
|
219
|
+
const std::string &moduleName,
|
|
220
|
+
const std::string &methodName)
|
|
199
221
|
{
|
|
200
222
|
std::string reason = [exception.reason UTF8String];
|
|
201
223
|
|
|
@@ -206,7 +228,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
|
|
|
206
228
|
cause.setProperty(
|
|
207
229
|
runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
|
|
208
230
|
|
|
209
|
-
|
|
231
|
+
std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
|
|
232
|
+
jsi::Value error = createJSRuntimeError(runtime, message);
|
|
210
233
|
error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
|
|
211
234
|
return {runtime, std::move(error)};
|
|
212
235
|
}
|
|
@@ -338,28 +361,34 @@ id ObjCTurboModule::performMethodInvocation(
|
|
|
338
361
|
}
|
|
339
362
|
|
|
340
363
|
if (isSync) {
|
|
341
|
-
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName,
|
|
364
|
+
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
|
|
342
365
|
} else {
|
|
343
|
-
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName,
|
|
366
|
+
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
|
|
344
367
|
}
|
|
345
368
|
|
|
346
369
|
@try {
|
|
347
370
|
[inv invokeWithTarget:strongModule];
|
|
348
371
|
} @catch (NSException *exception) {
|
|
349
|
-
|
|
372
|
+
if (isSync) {
|
|
373
|
+
// We can only convert NSException to JSError in sync method calls.
|
|
374
|
+
// See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
|
|
375
|
+
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
|
|
376
|
+
} else {
|
|
377
|
+
@throw exception;
|
|
378
|
+
}
|
|
350
379
|
} @finally {
|
|
351
380
|
[retainedObjectsForInvocation removeAllObjects];
|
|
352
381
|
}
|
|
353
382
|
|
|
354
383
|
if (!isSync) {
|
|
355
|
-
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName,
|
|
384
|
+
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
|
|
356
385
|
return;
|
|
357
386
|
}
|
|
358
387
|
|
|
359
388
|
void *rawResult;
|
|
360
389
|
[inv getReturnValue:&rawResult];
|
|
361
390
|
result = (__bridge id)rawResult;
|
|
362
|
-
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName,
|
|
391
|
+
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
|
|
363
392
|
};
|
|
364
393
|
|
|
365
394
|
if (isSync) {
|
|
@@ -401,23 +430,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
|
|
|
401
430
|
}
|
|
402
431
|
|
|
403
432
|
if (shouldVoidMethodsExecuteSync_) {
|
|
404
|
-
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName,
|
|
433
|
+
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
|
|
405
434
|
} else {
|
|
406
|
-
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName,
|
|
435
|
+
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
|
|
407
436
|
}
|
|
408
437
|
|
|
409
438
|
@try {
|
|
410
439
|
[inv invokeWithTarget:strongModule];
|
|
411
440
|
} @catch (NSException *exception) {
|
|
412
|
-
throw convertNSExceptionToJSError(runtime, exception);
|
|
441
|
+
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
|
|
413
442
|
} @finally {
|
|
414
443
|
[retainedObjectsForInvocation removeAllObjects];
|
|
415
444
|
}
|
|
416
445
|
|
|
417
446
|
if (shouldVoidMethodsExecuteSync_) {
|
|
418
|
-
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName,
|
|
447
|
+
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
|
|
419
448
|
} else {
|
|
420
|
-
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName,
|
|
449
|
+
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
|
|
421
450
|
}
|
|
422
451
|
|
|
423
452
|
return;
|
|
@@ -46,6 +46,9 @@ void TextAttributes::apply(TextAttributes textAttributes) {
|
|
|
46
46
|
allowFontScaling = textAttributes.allowFontScaling.has_value()
|
|
47
47
|
? textAttributes.allowFontScaling
|
|
48
48
|
: allowFontScaling;
|
|
49
|
+
maxFontSizeMultiplier = !std::isnan(textAttributes.maxFontSizeMultiplier)
|
|
50
|
+
? textAttributes.maxFontSizeMultiplier
|
|
51
|
+
: maxFontSizeMultiplier;
|
|
49
52
|
dynamicTypeRamp = textAttributes.dynamicTypeRamp.has_value()
|
|
50
53
|
? textAttributes.dynamicTypeRamp
|
|
51
54
|
: dynamicTypeRamp;
|
|
@@ -168,6 +171,7 @@ bool TextAttributes::operator==(const TextAttributes& rhs) const {
|
|
|
168
171
|
rhs.accessibilityRole,
|
|
169
172
|
rhs.role,
|
|
170
173
|
rhs.textTransform) &&
|
|
174
|
+
floatEquality(maxFontSizeMultiplier, rhs.maxFontSizeMultiplier) &&
|
|
171
175
|
floatEquality(opacity, rhs.opacity) &&
|
|
172
176
|
floatEquality(fontSize, rhs.fontSize) &&
|
|
173
177
|
floatEquality(fontSizeMultiplier, rhs.fontSizeMultiplier) &&
|
|
@@ -211,6 +215,8 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
|
|
|
211
215
|
debugStringConvertibleItem("fontStyle", fontStyle),
|
|
212
216
|
debugStringConvertibleItem("fontVariant", fontVariant),
|
|
213
217
|
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
|
|
218
|
+
debugStringConvertibleItem(
|
|
219
|
+
"maxFontSizeMultiplier", maxFontSizeMultiplier),
|
|
214
220
|
debugStringConvertibleItem("dynamicTypeRamp", dynamicTypeRamp),
|
|
215
221
|
debugStringConvertibleItem("letterSpacing", letterSpacing),
|
|
216
222
|
|
|
@@ -51,6 +51,7 @@ class TextAttributes : public DebugStringConvertible {
|
|
|
51
51
|
std::optional<FontStyle> fontStyle{};
|
|
52
52
|
std::optional<FontVariant> fontVariant{};
|
|
53
53
|
std::optional<bool> allowFontScaling{};
|
|
54
|
+
Float maxFontSizeMultiplier{std::numeric_limits<Float>::quiet_NaN()};
|
|
54
55
|
std::optional<DynamicTypeRamp> dynamicTypeRamp{};
|
|
55
56
|
Float letterSpacing{std::numeric_limits<Float>::quiet_NaN()};
|
|
56
57
|
std::optional<TextTransform> textTransform{};
|
|
@@ -117,6 +118,7 @@ struct hash<facebook::react::TextAttributes> {
|
|
|
117
118
|
textAttributes.opacity,
|
|
118
119
|
textAttributes.fontFamily,
|
|
119
120
|
textAttributes.fontSize,
|
|
121
|
+
textAttributes.maxFontSizeMultiplier,
|
|
120
122
|
textAttributes.fontSizeMultiplier,
|
|
121
123
|
textAttributes.fontWeight,
|
|
122
124
|
textAttributes.fontStyle,
|
|
@@ -910,6 +910,7 @@ constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 25;
|
|
|
910
910
|
constexpr static MapBuffer::Key TA_KEY_ROLE = 26;
|
|
911
911
|
constexpr static MapBuffer::Key TA_KEY_TEXT_TRANSFORM = 27;
|
|
912
912
|
constexpr static MapBuffer::Key TA_KEY_ALIGNMENT_VERTICAL = 28;
|
|
913
|
+
constexpr static MapBuffer::Key TA_KEY_MAX_FONT_SIZE_MULTIPLIER = 29;
|
|
913
914
|
|
|
914
915
|
// constants for ParagraphAttributes serialization
|
|
915
916
|
constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0;
|
|
@@ -1004,6 +1005,10 @@ inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) {
|
|
|
1004
1005
|
builder.putBool(
|
|
1005
1006
|
TA_KEY_ALLOW_FONT_SCALING, *textAttributes.allowFontScaling);
|
|
1006
1007
|
}
|
|
1008
|
+
if (!std::isnan(textAttributes.maxFontSizeMultiplier)) {
|
|
1009
|
+
builder.putDouble(
|
|
1010
|
+
TA_KEY_MAX_FONT_SIZE_MULTIPLIER, textAttributes.maxFontSizeMultiplier);
|
|
1011
|
+
}
|
|
1007
1012
|
if (!std::isnan(textAttributes.letterSpacing)) {
|
|
1008
1013
|
builder.putDouble(TA_KEY_LETTER_SPACING, textAttributes.letterSpacing);
|
|
1009
1014
|
}
|
|
@@ -73,6 +73,12 @@ static TextAttributes convertRawProp(
|
|
|
73
73
|
"allowFontScaling",
|
|
74
74
|
sourceTextAttributes.allowFontScaling,
|
|
75
75
|
defaultTextAttributes.allowFontScaling);
|
|
76
|
+
textAttributes.maxFontSizeMultiplier = convertRawProp(
|
|
77
|
+
context,
|
|
78
|
+
rawProps,
|
|
79
|
+
"maxFontSizeMultiplier",
|
|
80
|
+
sourceTextAttributes.maxFontSizeMultiplier,
|
|
81
|
+
defaultTextAttributes.maxFontSizeMultiplier);
|
|
76
82
|
textAttributes.dynamicTypeRamp = convertRawProp(
|
|
77
83
|
context,
|
|
78
84
|
rawProps,
|
|
@@ -266,6 +272,12 @@ void BaseTextProps::setProp(
|
|
|
266
272
|
defaults, value, textAttributes, fontVariant, "fontVariant");
|
|
267
273
|
REBUILD_FIELD_SWITCH_CASE(
|
|
268
274
|
defaults, value, textAttributes, allowFontScaling, "allowFontScaling");
|
|
275
|
+
REBUILD_FIELD_SWITCH_CASE(
|
|
276
|
+
defaults,
|
|
277
|
+
value,
|
|
278
|
+
textAttributes,
|
|
279
|
+
maxFontSizeMultiplier,
|
|
280
|
+
"maxFontSizeMultiplier");
|
|
269
281
|
REBUILD_FIELD_SWITCH_CASE(
|
|
270
282
|
defaults, value, textAttributes, letterSpacing, "letterSpacing");
|
|
271
283
|
REBUILD_FIELD_SWITCH_CASE(
|
|
@@ -208,8 +208,7 @@ inline bool operator==(
|
|
|
208
208
|
return areAttributedStringsEquivalentLayoutWise(
|
|
209
209
|
lhs.attributedString, rhs.attributedString) &&
|
|
210
210
|
lhs.paragraphAttributes == rhs.paragraphAttributes &&
|
|
211
|
-
lhs.layoutConstraints
|
|
212
|
-
rhs.layoutConstraints.maximumSize.width;
|
|
211
|
+
lhs.layoutConstraints == rhs.layoutConstraints;
|
|
213
212
|
}
|
|
214
213
|
|
|
215
214
|
inline bool operator!=(
|
|
@@ -243,7 +242,7 @@ struct hash<facebook::react::TextMeasureCacheKey> {
|
|
|
243
242
|
return facebook::react::hash_combine(
|
|
244
243
|
attributedStringHashLayoutWise(key.attributedString),
|
|
245
244
|
key.paragraphAttributes,
|
|
246
|
-
key.layoutConstraints
|
|
245
|
+
key.layoutConstraints);
|
|
247
246
|
}
|
|
248
247
|
};
|
|
249
248
|
|