react-native 0.77.0-rc.7 → 0.77.1

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 (26) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +2 -2
  2. package/Libraries/Core/setUpDeveloperTools.js +2 -3
  3. package/Libraries/Image/RCTImageLoader.mm +9 -1
  4. package/Libraries/Utilities/HMRClient.js +0 -28
  5. package/Libraries/Utilities/HMRClientProdShim.js +0 -1
  6. package/React/Base/RCTVersion.m +2 -2
  7. package/ReactAndroid/api/ReactAndroid.api +2 -0
  8. package/ReactAndroid/gradle.properties +1 -1
  9. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +15 -8
  10. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
  11. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt +9 -8
  12. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +16 -2
  13. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  14. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +13 -4
  15. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h +5 -0
  16. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +27 -9
  17. package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +6 -0
  18. package/ReactCommon/react/renderer/attributedstring/TextAttributes.h +2 -0
  19. package/ReactCommon/react/renderer/attributedstring/conversions.h +5 -0
  20. package/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +12 -0
  21. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +5 -3
  22. package/package.json +8 -8
  23. package/sdks/hermesc/linux64-bin/hermesc +0 -0
  24. package/sdks/hermesc/osx-bin/hermes +0 -0
  25. package/sdks/hermesc/osx-bin/hermesc +0 -0
  26. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
@@ -16,8 +16,8 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 77,
19
- patch: 0,
20
- prerelease: 'rc.7',
19
+ patch: 1,
20
+ prerelease: null,
21
21
  };
22
22
 
23
23
  module.exports = {version};
@@ -42,9 +42,8 @@ if (__DEV__) {
42
42
  if (!Platform.isTesting) {
43
43
  const HMRClient = require('../Utilities/HMRClient');
44
44
 
45
- if (global.__FUSEBOX_HAS_FULL_CONSOLE_SUPPORT__) {
46
- HMRClient.unstable_notifyFuseboxConsoleEnabled();
47
- } else if (console._isPolyfilled) {
45
+ // TODO(T214991636): Remove legacy Metro log forwarding
46
+ if (console._isPolyfilled) {
48
47
  // We assume full control over the console and send JavaScript logs to Metro.
49
48
  [
50
49
  'trace',
@@ -477,7 +477,15 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image, CGSize size, CGFloat scal
477
477
 
478
478
  // Add missing png extension
479
479
  if (request.URL.fileURL && request.URL.pathExtension.length == 0) {
480
- mutableRequest.URL = [request.URL URLByAppendingPathExtension:@"png"];
480
+ // Check if there exists a file with that url on disk already
481
+ // This should fix issue https://github.com/facebook/react-native/issues/46870
482
+ if ([[NSFileManager defaultManager] fileExistsAtPath:request.URL.path]) {
483
+ mutableRequest.URL = request.URL;
484
+ } else {
485
+ // This is the default behavior in case there is no file on disk with no extension.
486
+ // We assume that the extension is `png`.
487
+ mutableRequest.URL = [request.URL URLByAppendingPathExtension:@"png"];
488
+ }
481
489
  }
482
490
  if (_redirectDelegate != nil) {
483
491
  mutableRequest.URL = [_redirectDelegate redirectAssetsURL:mutableRequest.URL];
@@ -26,7 +26,6 @@ let hmrUnavailableReason: string | null = null;
26
26
  let currentCompileErrorMessage: string | null = null;
27
27
  let didConnect: boolean = false;
28
28
  let pendingLogs: Array<[LogLevel, $ReadOnlyArray<mixed>]> = [];
29
- let pendingFuseboxConsoleNotification = false;
30
29
 
31
30
  type LogLevel =
32
31
  | 'trace'
@@ -52,7 +51,6 @@ export type HMRClientNativeInterface = {|
52
51
  isEnabled: boolean,
53
52
  scheme?: string,
54
53
  ): void,
55
- unstable_notifyFuseboxConsoleEnabled(): void,
56
54
  |};
57
55
 
58
56
  /**
@@ -142,29 +140,6 @@ const HMRClient: HMRClientNativeInterface = {
142
140
  }
143
141
  },
144
142
 
145
- unstable_notifyFuseboxConsoleEnabled() {
146
- if (!hmrClient) {
147
- pendingFuseboxConsoleNotification = true;
148
- return;
149
- }
150
- hmrClient.send(
151
- JSON.stringify({
152
- type: 'log',
153
- level: 'info',
154
- data: [
155
- '\n' +
156
- '\u001B[7m' +
157
- ' \u001B[1m💡 JavaScript logs have moved!\u001B[22m They can now be ' +
158
- 'viewed in React Native DevTools. Tip: Type \u001B[1mj\u001B[22m in ' +
159
- 'the terminal to open (requires Google Chrome or Microsoft Edge).' +
160
- '\u001B[27m' +
161
- '\n',
162
- ],
163
- }),
164
- );
165
- pendingFuseboxConsoleNotification = false;
166
- },
167
-
168
143
  // Called once by the bridge on startup, even if Fast Refresh is off.
169
144
  // It creates the HMR client but doesn't actually set up the socket yet.
170
145
  setup(
@@ -341,9 +316,6 @@ function flushEarlyLogs(client: MetroHMRClient) {
341
316
  pendingLogs.forEach(([level, data]) => {
342
317
  HMRClient.log(level, data);
343
318
  });
344
- if (pendingFuseboxConsoleNotification) {
345
- HMRClient.unstable_notifyFuseboxConsoleEnabled();
346
- }
347
319
  } finally {
348
320
  pendingLogs.length = 0;
349
321
  }
@@ -25,7 +25,6 @@ const HMRClientProdShim: HMRClientNativeInterface = {
25
25
  disable() {},
26
26
  registerBundle() {},
27
27
  log() {},
28
- unstable_notifyFuseboxConsoleEnabled() {},
29
28
  };
30
29
 
31
30
  module.exports = HMRClientProdShim;
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(77),
26
- RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"rc.7",
26
+ RCTVersionPatch: @(1),
27
+ RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -7443,6 +7443,7 @@ public class com/facebook/react/views/text/TextAttributeProps {
7443
7443
  public static final field TA_KEY_LETTER_SPACING S
7444
7444
  public static final field TA_KEY_LINE_BREAK_STRATEGY S
7445
7445
  public static final field TA_KEY_LINE_HEIGHT S
7446
+ public static final field TA_KEY_MAX_FONT_SIZE_MULTIPLIER S
7446
7447
  public static final field TA_KEY_OPACITY S
7447
7448
  public static final field TA_KEY_ROLE S
7448
7449
  public static final field TA_KEY_TEXT_DECORATION_COLOR S
@@ -7475,6 +7476,7 @@ public class com/facebook/react/views/text/TextAttributeProps {
7475
7476
  protected field mLetterSpacingInput F
7476
7477
  protected field mLineHeight F
7477
7478
  protected field mLineHeightInput F
7479
+ protected field mMaxFontSizeMultiplier F
7478
7480
  protected field mNumberOfLines I
7479
7481
  protected field mOpacity F
7480
7482
  protected field mRole Lcom/facebook/react/uimanager/ReactAccessibilityDelegate$Role;
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.77.0-rc.7
1
+ VERSION_NAME=0.77.1
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
 
4
4
  android.useAndroidX=true
@@ -330,14 +330,11 @@ public class MountingManager {
330
330
  @AnyThread
331
331
  @ThreadConfined(ANY)
332
332
  public @Nullable EventEmitterWrapper getEventEmitter(int surfaceId, int reactTag) {
333
- SurfaceMountingManager surfaceMountingManager =
334
- (surfaceId == ViewUtil.NO_SURFACE_ID
335
- ? getSurfaceManagerForView(reactTag)
336
- : getSurfaceManager(surfaceId));
337
- if (surfaceMountingManager == null) {
333
+ SurfaceMountingManager smm = getSurfaceMountingManager(surfaceId, reactTag);
334
+ if (smm == null) {
338
335
  return null;
339
336
  }
340
- return surfaceMountingManager.getEventEmitter(reactTag);
337
+ return smm.getEventEmitter(reactTag);
341
338
  }
342
339
 
343
340
  /**
@@ -434,11 +431,21 @@ public class MountingManager {
434
431
  boolean canCoalesceEvent,
435
432
  @Nullable WritableMap params,
436
433
  @EventCategoryDef int eventCategory) {
437
- @Nullable SurfaceMountingManager smm = getSurfaceManager(surfaceId);
434
+ SurfaceMountingManager smm = getSurfaceMountingManager(surfaceId, reactTag);
438
435
  if (smm == null) {
439
- // Cannot queue event without valid surface mountng manager. Do nothing here.
436
+ FLog.d(
437
+ TAG,
438
+ "Cannot queue event without valid surface mounting manager for tag: %d, surfaceId: %d",
439
+ reactTag,
440
+ surfaceId);
440
441
  return;
441
442
  }
442
443
  smm.enqueuePendingEvent(reactTag, eventName, canCoalesceEvent, params, eventCategory);
443
444
  }
445
+
446
+ private @Nullable SurfaceMountingManager getSurfaceMountingManager(int surfaceId, int reactTag) {
447
+ return (surfaceId == ViewUtil.NO_SURFACE_ID
448
+ ? getSurfaceManagerForView(reactTag)
449
+ : getSurfaceManager(surfaceId));
450
+ }
444
451
  }
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
17
17
  public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
18
18
  "major", 0,
19
19
  "minor", 77,
20
- "patch", 0,
21
- "prerelease", "rc.7");
20
+ "patch", 1,
21
+ "prerelease", null);
22
22
  }
@@ -16,6 +16,7 @@ import android.graphics.drawable.LayerDrawable
16
16
  import android.os.Build
17
17
  import com.facebook.react.common.annotations.UnstableReactNativeAPI
18
18
  import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
19
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
19
20
  import com.facebook.react.uimanager.style.BorderInsets
20
21
  import com.facebook.react.uimanager.style.BorderRadiusStyle
21
22
 
@@ -200,14 +201,14 @@ internal class CompositeBackgroundDrawable(
200
201
  pathForOutline.addRoundRect(
201
202
  RectF(bounds),
202
203
  floatArrayOf(
203
- it.topLeft.horizontal + (computedBorderInsets?.left ?: 0f),
204
- it.topLeft.vertical + (computedBorderInsets?.top ?: 0f),
205
- it.topRight.horizontal + (computedBorderInsets?.right ?: 0f),
206
- it.topRight.vertical + (computedBorderInsets?.top ?: 0f),
207
- it.bottomRight.horizontal + (computedBorderInsets?.right ?: 0f),
208
- it.bottomRight.vertical + (computedBorderInsets?.bottom ?: 0f),
209
- it.bottomLeft.horizontal + (computedBorderInsets?.left ?: 0f),
210
- it.bottomLeft.vertical) + (computedBorderInsets?.bottom ?: 0f),
204
+ (it.topLeft.horizontal + (computedBorderInsets?.left ?: 0f)).dpToPx(),
205
+ (it.topLeft.vertical + (computedBorderInsets?.top ?: 0f)).dpToPx(),
206
+ (it.topRight.horizontal + (computedBorderInsets?.right ?: 0f)).dpToPx(),
207
+ (it.topRight.vertical + (computedBorderInsets?.top ?: 0f)).dpToPx(),
208
+ (it.bottomRight.horizontal + (computedBorderInsets?.right ?: 0f)).dpToPx(),
209
+ (it.bottomRight.vertical + (computedBorderInsets?.bottom ?: 0f)).dpToPx(),
210
+ (it.bottomLeft.horizontal + (computedBorderInsets?.left ?: 0f)).dpToPx(),
211
+ (it.bottomLeft.vertical + (computedBorderInsets?.bottom ?: 0f)).dpToPx()),
211
212
  Path.Direction.CW)
212
213
  }
213
214
 
@@ -61,6 +61,7 @@ public class TextAttributeProps {
61
61
  public static final short TA_KEY_LINE_BREAK_STRATEGY = 25;
62
62
  public static final short TA_KEY_ROLE = 26;
63
63
  public static final short TA_KEY_TEXT_TRANSFORM = 27;
64
+ public static final short TA_KEY_MAX_FONT_SIZE_MULTIPLIER = 29;
64
65
 
65
66
  public static final int UNSET = -1;
66
67
 
@@ -81,6 +82,7 @@ public class TextAttributeProps {
81
82
  protected float mLineHeight = Float.NaN;
82
83
  protected boolean mIsColorSet = false;
83
84
  protected boolean mAllowFontScaling = true;
85
+ protected float mMaxFontSizeMultiplier = Float.NaN;
84
86
  protected int mColor;
85
87
  protected boolean mIsBackgroundColorSet = false;
86
88
  protected int mBackgroundColor;
@@ -227,6 +229,9 @@ public class TextAttributeProps {
227
229
  case TA_KEY_TEXT_TRANSFORM:
228
230
  result.setTextTransform(entry.getStringValue());
229
231
  break;
232
+ case TA_KEY_MAX_FONT_SIZE_MULTIPLIER:
233
+ result.setMaxFontSizeMultiplier((float) entry.getDoubleValue());
234
+ break;
230
235
  }
231
236
  }
232
237
 
@@ -243,6 +248,8 @@ public class TextAttributeProps {
243
248
  result.setLineHeight(getFloatProp(props, ViewProps.LINE_HEIGHT, ReactConstants.UNSET));
244
249
  result.setLetterSpacing(getFloatProp(props, ViewProps.LETTER_SPACING, Float.NaN));
245
250
  result.setAllowFontScaling(getBooleanProp(props, ViewProps.ALLOW_FONT_SCALING, true));
251
+ result.setMaxFontSizeMultiplier(
252
+ getFloatProp(props, ViewProps.MAX_FONT_SIZE_MULTIPLIER, Float.NaN));
246
253
  result.setFontSize(getFloatProp(props, ViewProps.FONT_SIZE, ReactConstants.UNSET));
247
254
  result.setColor(props.hasKey(ViewProps.COLOR) ? props.getInt(ViewProps.COLOR, 0) : null);
248
255
  result.setColor(
@@ -411,7 +418,14 @@ public class TextAttributeProps {
411
418
  mAllowFontScaling = allowFontScaling;
412
419
  setFontSize(mFontSizeInput);
413
420
  setLineHeight(mLineHeightInput);
414
- setLetterSpacing(mLetterSpacingInput);
421
+ }
422
+ }
423
+
424
+ private void setMaxFontSizeMultiplier(float maxFontSizeMultiplier) {
425
+ if (maxFontSizeMultiplier != mMaxFontSizeMultiplier) {
426
+ mMaxFontSizeMultiplier = maxFontSizeMultiplier;
427
+ setFontSize(mFontSizeInput);
428
+ setLineHeight(mLineHeightInput);
415
429
  }
416
430
  }
417
431
 
@@ -420,7 +434,7 @@ public class TextAttributeProps {
420
434
  if (fontSize != ReactConstants.UNSET) {
421
435
  fontSize =
422
436
  mAllowFontScaling
423
- ? (float) Math.ceil(PixelUtil.toPixelFromSP(fontSize))
437
+ ? (float) Math.ceil(PixelUtil.toPixelFromSP(fontSize, mMaxFontSizeMultiplier))
424
438
  : (float) Math.ceil(PixelUtil.toPixelFromDIP(fontSize));
425
439
  }
426
440
  mFontSize = (int) fontSize;
@@ -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 = 0;
21
- std::string_view Prerelease = "rc.7";
20
+ int32_t Patch = 1;
21
+ std::string_view Prerelease = "";
22
22
  } ReactNativeVersion;
23
23
 
24
24
  } // namespace facebook::react
@@ -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);
@@ -491,7 +500,7 @@ void ObjCInteropTurboModule::setInvocationArg(
491
500
  }
492
501
 
493
502
  RCTResponseSenderBlock arg =
494
- (RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
503
+ (RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
495
504
  if (arg) {
496
505
  [retainedObjectsForInvocation addObject:arg];
497
506
  }
@@ -506,7 +515,7 @@ void ObjCInteropTurboModule::setInvocationArg(
506
515
  }
507
516
 
508
517
  RCTResponseSenderBlock senderBlock =
509
- (RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
518
+ (RCTResponseSenderBlock)TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
510
519
  RCTResponseErrorBlock arg = ^(NSError *error) {
511
520
  senderBlock(@[ RCTJSErrorFromNSError(error) ]);
512
521
  };
@@ -536,7 +545,7 @@ void ObjCInteropTurboModule::setInvocationArg(
536
545
  runtime, errorPrefix + "JavaScript argument must be a plain object. Got " + getType(runtime, jsiArg));
537
546
  }
538
547
 
539
- id arg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_);
548
+ id arg = TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsiArg, jsInvoker_, YES);
540
549
 
541
550
  RCTManagedPointer *(*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
542
551
  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 <>
@@ -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
- convertJSIArrayToNSArray(jsi::Runtime &runtime, const jsi::Array &value, std::shared_ptr<CallInvoker> jsInvoker)
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
- convertJSIObjectToNSDictionary(jsi::Runtime &runtime, const jsi::Object &value, std::shared_ptr<CallInvoker> jsInvoker)
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
- if (value.isUndefined() || value.isNull()) {
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");
@@ -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(
@@ -135,6 +135,7 @@ inline static CGFloat RCTBaseSizeForDynamicTypeRamp(const DynamicTypeRamp &dynam
135
135
  inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
136
136
  {
137
137
  if (textAttributes.allowFontScaling.value_or(true)) {
138
+ CGFloat fontSizeMultiplier = !isnan(textAttributes.fontSizeMultiplier) ? textAttributes.fontSizeMultiplier : 1.0;
138
139
  if (textAttributes.dynamicTypeRamp.has_value()) {
139
140
  DynamicTypeRamp dynamicTypeRamp = textAttributes.dynamicTypeRamp.value();
140
141
  UIFontMetrics *fontMetrics =
@@ -142,10 +143,11 @@ inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const Tex
142
143
  // Using a specific font size reduces rounding errors from -scaledValueForValue:
143
144
  CGFloat requestedSize =
144
145
  isnan(textAttributes.fontSize) ? RCTBaseSizeForDynamicTypeRamp(dynamicTypeRamp) : textAttributes.fontSize;
145
- return [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
146
- } else {
147
- return textAttributes.fontSizeMultiplier;
146
+ fontSizeMultiplier = [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
148
147
  }
148
+ CGFloat maxFontSizeMultiplier =
149
+ !isnan(textAttributes.maxFontSizeMultiplier) ? textAttributes.maxFontSizeMultiplier : 0.0;
150
+ return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
149
151
  } else {
150
152
  return 1.0;
151
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.77.0-rc.7",
3
+ "version": "0.77.1",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -108,13 +108,13 @@
108
108
  },
109
109
  "dependencies": {
110
110
  "@jest/create-cache-key-function": "^29.6.3",
111
- "@react-native/assets-registry": "0.77.0-rc.7",
112
- "@react-native/codegen": "0.77.0-rc.7",
113
- "@react-native/community-cli-plugin": "0.77.0-rc.7",
114
- "@react-native/gradle-plugin": "0.77.0-rc.7",
115
- "@react-native/js-polyfills": "0.77.0-rc.7",
116
- "@react-native/normalize-colors": "0.77.0-rc.7",
117
- "@react-native/virtualized-lists": "0.77.0-rc.7",
111
+ "@react-native/assets-registry": "0.77.1",
112
+ "@react-native/codegen": "0.77.1",
113
+ "@react-native/community-cli-plugin": "0.77.1",
114
+ "@react-native/gradle-plugin": "0.77.1",
115
+ "@react-native/js-polyfills": "0.77.1",
116
+ "@react-native/normalize-colors": "0.77.1",
117
+ "@react-native/virtualized-lists": "0.77.1",
118
118
  "abort-controller": "^3.0.0",
119
119
  "anser": "^1.4.9",
120
120
  "ansi-regex": "^5.0.0",
Binary file
Binary file
Binary file
Binary file