react-native 0.77.1 → 0.77.3

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 (55) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Image/Image.android.js +2 -0
  3. package/Libraries/Image/ImageViewNativeComponent.js +3 -4
  4. package/Libraries/Network/RCTDataRequestHandler.mm +17 -3
  5. package/Libraries/Network/RCTFileRequestHandler.mm +17 -3
  6. package/React/Base/RCTVersion.m +1 -1
  7. package/React/DevSupport/RCTPausedInDebuggerOverlayController.mm +3 -5
  8. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +18 -4
  9. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +1 -4
  10. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +22 -3
  11. package/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +1 -1
  12. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
  13. package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
  14. package/ReactAndroid/gradle.properties +1 -1
  15. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +2 -2
  16. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +21 -10
  17. package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt +3 -16
  18. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  19. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt +13 -0
  20. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +0 -3
  21. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +2 -2
  22. package/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt +1 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +39 -0
  24. package/ReactCommon/React-FabricComponents.podspec +1 -1
  25. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  26. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +9 -0
  27. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +24 -13
  28. package/ReactCommon/react/renderer/components/modal/CMakeLists.txt +4 -1
  29. package/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h +3 -2
  30. package/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +4 -12
  31. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h +2 -2
  32. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.mm +1 -1
  33. package/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h +38 -0
  34. package/ReactCommon/react/renderer/components/modal/platform/android/ModalHostViewUtils.cpp +18 -0
  35. package/ReactCommon/react/renderer/components/modal/platform/cxx/ModalHostViewUtils.cpp +17 -0
  36. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp +33 -0
  37. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h +17 -0
  38. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp +3 -2
  39. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +2 -1
  40. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +24 -3
  41. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +1 -43
  42. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +4 -5
  43. package/ReactCommon/react/runtime/TimerManager.cpp +6 -4
  44. package/ReactCommon/react/runtime/TimerManager.h +3 -1
  45. package/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +9 -5
  46. package/package.json +10 -10
  47. package/react-native.config.js +11 -21
  48. package/scripts/codegen/generate-artifacts-executor.js +8 -4
  49. package/scripts/generate-codegen-artifacts.js +6 -1
  50. package/sdks/hermesc/osx-bin/hermes +0 -0
  51. package/sdks/hermesc/osx-bin/hermesc +0 -0
  52. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  53. package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
  54. package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
  55. package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
@@ -17,7 +17,7 @@ namespace facebook::react {
17
17
  constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 77;
20
- int32_t Patch = 1;
20
+ int32_t Patch = 3;
21
21
  std::string_view Prerelease = "";
22
22
  } ReactNativeVersion;
23
23
 
@@ -446,6 +446,15 @@ void ObjCInteropTurboModule::setInvocationArg(
446
446
 
447
447
  if (objCArgType == @encode(id)) {
448
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
+
449
458
  if (arg) {
450
459
  [retainedObjectsForInvocation addObject:arg];
451
460
  }
@@ -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)
@@ -213,7 +213,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
213
213
  /**
214
214
  * Creates JSError with current JS runtime and NSException stack trace.
215
215
  */
216
- static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
216
+ static jsi::JSError convertNSExceptionToJSError(
217
+ jsi::Runtime &runtime,
218
+ NSException *exception,
219
+ const std::string &moduleName,
220
+ const std::string &methodName)
217
221
  {
218
222
  std::string reason = [exception.reason UTF8String];
219
223
 
@@ -224,7 +228,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
224
228
  cause.setProperty(
225
229
  runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
226
230
 
227
- jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
231
+ std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
232
+ jsi::Value error = createJSRuntimeError(runtime, message);
228
233
  error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
229
234
  return {runtime, std::move(error)};
230
235
  }
@@ -356,28 +361,34 @@ id ObjCTurboModule::performMethodInvocation(
356
361
  }
357
362
 
358
363
  if (isSync) {
359
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
364
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
360
365
  } else {
361
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
366
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
362
367
  }
363
368
 
364
369
  @try {
365
370
  [inv invokeWithTarget:strongModule];
366
371
  } @catch (NSException *exception) {
367
- throw convertNSExceptionToJSError(runtime, exception);
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
+ }
368
379
  } @finally {
369
380
  [retainedObjectsForInvocation removeAllObjects];
370
381
  }
371
382
 
372
383
  if (!isSync) {
373
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
384
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
374
385
  return;
375
386
  }
376
387
 
377
388
  void *rawResult;
378
389
  [inv getReturnValue:&rawResult];
379
390
  result = (__bridge id)rawResult;
380
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
391
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
381
392
  };
382
393
 
383
394
  if (isSync) {
@@ -419,23 +430,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
419
430
  }
420
431
 
421
432
  if (shouldVoidMethodsExecuteSync_) {
422
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
433
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
423
434
  } else {
424
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
435
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
425
436
  }
426
437
 
427
438
  @try {
428
439
  [inv invokeWithTarget:strongModule];
429
440
  } @catch (NSException *exception) {
430
- throw convertNSExceptionToJSError(runtime, exception);
441
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
431
442
  } @finally {
432
443
  [retainedObjectsForInvocation removeAllObjects];
433
444
  }
434
445
 
435
446
  if (shouldVoidMethodsExecuteSync_) {
436
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
447
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
437
448
  } else {
438
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
449
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
439
450
  }
440
451
 
441
452
  return;
@@ -14,7 +14,10 @@ add_compile_options(
14
14
  -Wpedantic
15
15
  -DLOG_TAG=\"Fabric\")
16
16
 
17
- file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS *.cpp)
17
+ file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS
18
+ *.cpp
19
+ platform/android/*.cpp)
20
+
18
21
  add_library(rrc_modal STATIC ${rrc_modal_SRC})
19
22
 
20
23
  target_include_directories(rrc_modal PUBLIC ${REACT_COMMON_DIR})
@@ -30,8 +30,9 @@ class ModalHostViewComponentDescriptor final
30
30
  *shadowNode.getState())
31
31
  .getData();
32
32
 
33
- layoutableShadowNode.setSize(
34
- Size{stateData.screenSize.width, stateData.screenSize.height});
33
+ layoutableShadowNode.setSize(Size{
34
+ .width = stateData.screenSize.width,
35
+ .height = stateData.screenSize.height});
35
36
  layoutableShadowNode.setPositionType(YGPositionTypeAbsolute);
36
37
 
37
38
  ConcreteComponentDescriptor::adopt(shadowNode);
@@ -9,15 +9,12 @@
9
9
 
10
10
  #include <react/renderer/core/graphicsConversions.h>
11
11
  #include <react/renderer/graphics/Float.h>
12
+ #include "ModalHostViewUtils.h"
12
13
 
13
14
  #ifdef ANDROID
14
15
  #include <folly/dynamic.h>
15
16
  #endif
16
17
 
17
- #if defined(__APPLE__) && TARGET_OS_IOS
18
- #include "ModalHostViewUtils.h"
19
- #endif
20
-
21
18
  namespace facebook::react {
22
19
 
23
20
  /*
@@ -27,12 +24,7 @@ class ModalHostViewState final {
27
24
  public:
28
25
  using Shared = std::shared_ptr<const ModalHostViewState>;
29
26
 
30
- #if defined(__APPLE__) && TARGET_OS_IOS
31
- ModalHostViewState() : screenSize(RCTModalHostViewScreenSize()) {
32
- #else
33
- ModalHostViewState(){
34
- #endif
35
- };
27
+ ModalHostViewState() : screenSize(ModalHostViewScreenSize()) {}
36
28
  ModalHostViewState(Size screenSize_) : screenSize(screenSize_){};
37
29
 
38
30
  #ifdef ANDROID
@@ -40,8 +32,8 @@ class ModalHostViewState final {
40
32
  const ModalHostViewState& previousState,
41
33
  folly::dynamic data)
42
34
  : screenSize(Size{
43
- (Float)data["screenWidth"].getDouble(),
44
- (Float)data["screenHeight"].getDouble()}){};
35
+ .width = (Float)data["screenWidth"].getDouble(),
36
+ .height = (Float)data["screenHeight"].getDouble()}){};
45
37
  #endif
46
38
 
47
39
  const Size screenSize{};
@@ -7,10 +7,10 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include <react/renderer/core/graphicsConversions.h>
10
+ #include <react/renderer/graphics/Size.h>
11
11
 
12
12
  namespace facebook::react {
13
13
 
14
- Size RCTModalHostViewScreenSize(void);
14
+ Size ModalHostViewScreenSize(void);
15
15
 
16
16
  } // namespace facebook::react
@@ -11,7 +11,7 @@
11
11
 
12
12
  namespace facebook::react {
13
13
 
14
- Size RCTModalHostViewScreenSize(void)
14
+ Size ModalHostViewScreenSize(void)
15
15
  {
16
16
  CGSize screenSize = RCTScreenSize();
17
17
  return {screenSize.width, screenSize.height};
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <react/renderer/graphics/Size.h>
12
+
13
+ namespace facebook::react {
14
+
15
+ class JReactModalHostView
16
+ : public facebook::jni::JavaClass<JReactModalHostView> {
17
+ public:
18
+ static auto constexpr kJavaDescriptor =
19
+ "Lcom/facebook/react/views/modal/ReactModalHostView;";
20
+
21
+ static Size getDisplayMetrics() {
22
+ static auto method =
23
+ JReactModalHostView::javaClassStatic()->getStaticMethod<jlong()>(
24
+ "getScreenDisplayMetricsWithoutInsets");
25
+ auto result = method(javaClassStatic());
26
+
27
+ // Inspired from yogaMeassureToSize from conversions.h
28
+ int32_t wBits = 0xFFFFFFFF & (result >> 32);
29
+ int32_t hBits = 0xFFFFFFFF & result;
30
+
31
+ auto* measuredWidth = reinterpret_cast<float*>(&wBits);
32
+ auto* measuredHeight = reinterpret_cast<float*>(&hBits);
33
+
34
+ return Size{.width = *measuredWidth, .height = *measuredHeight};
35
+ }
36
+ };
37
+
38
+ } // namespace facebook::react
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <react/renderer/components/modal/ModalHostViewUtils.h>
9
+ #include <react/renderer/graphics/Size.h>
10
+ #include "JReactModalHostView.h"
11
+
12
+ namespace facebook::react {
13
+
14
+ Size ModalHostViewScreenSize() {
15
+ return JReactModalHostView::getDisplayMetrics();
16
+ }
17
+
18
+ } // namespace facebook::react
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <react/renderer/components/modal/ModalHostViewUtils.h>
9
+ #include <react/renderer/graphics/Size.h>
10
+
11
+ namespace facebook::react {
12
+
13
+ Size ModalHostViewScreenSize() {
14
+ return Size{0, 0};
15
+ }
16
+
17
+ } // namespace facebook::react
@@ -76,6 +76,39 @@ EventPayloadType ScrollEvent::getType() const {
76
76
  return EventPayloadType::ScrollEvent;
77
77
  }
78
78
 
79
+ jsi::Value ScrollEndDragEvent::asJSIValue(jsi::Runtime& runtime) const {
80
+ auto payload = ScrollEvent::asJSIValue(runtime).asObject(runtime);
81
+
82
+ {
83
+ auto targetContentOffsetObj = jsi::Object(runtime);
84
+ targetContentOffsetObj.setProperty(runtime, "x", targetContentOffset.x);
85
+ targetContentOffsetObj.setProperty(runtime, "y", targetContentOffset.y);
86
+ payload.setProperty(runtime, "targetContentOffset", targetContentOffsetObj);
87
+ }
88
+
89
+ {
90
+ auto velocityObj = jsi::Object(runtime);
91
+ velocityObj.setProperty(runtime, "x", velocity.x);
92
+ velocityObj.setProperty(runtime, "y", velocity.y);
93
+ payload.setProperty(runtime, "velocity", velocityObj);
94
+ }
95
+
96
+ return payload;
97
+ }
98
+
99
+ folly::dynamic ScrollEndDragEvent::asDynamic() const {
100
+ auto metrics = ScrollEvent::asDynamic();
101
+
102
+ auto targetContentOffsetObj = folly::dynamic::object(
103
+ "x", targetContentOffset.x)("y", targetContentOffset.y);
104
+ metrics["targetContentOffset"] = std::move(targetContentOffsetObj);
105
+
106
+ auto velocityObj = folly::dynamic::object("x", velocity.x)("y", velocity.y);
107
+ metrics["velocity"] = std::move(velocityObj);
108
+
109
+ return metrics;
110
+ };
111
+
79
112
  #if RN_DEBUG_STRING_CONVERTIBLE
80
113
 
81
114
  std::string getDebugName(const ScrollEvent& /*scrollEvent*/) {
@@ -37,6 +37,23 @@ struct ScrollEvent : public EventPayload {
37
37
  EventPayloadType getType() const override;
38
38
  };
39
39
 
40
+ struct ScrollEndDragEvent : public ScrollEvent {
41
+ Point targetContentOffset;
42
+ Point velocity;
43
+
44
+ ScrollEndDragEvent() = default;
45
+
46
+ ScrollEndDragEvent(const ScrollEvent& scrollEvent)
47
+ : ScrollEvent(scrollEvent), targetContentOffset({}), velocity({}) {}
48
+
49
+ folly::dynamic asDynamic() const;
50
+
51
+ /*
52
+ * EventPayload implementations
53
+ */
54
+ jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
55
+ };
56
+
40
57
  #if RN_DEBUG_STRING_CONVERTIBLE
41
58
 
42
59
  std::string getDebugName(const ScrollEvent& scrollEvent);
@@ -25,8 +25,9 @@ void ScrollViewEventEmitter::onScrollBeginDrag(
25
25
  }
26
26
 
27
27
  void ScrollViewEventEmitter::onScrollEndDrag(
28
- const ScrollEvent& scrollEvent) const {
29
- dispatchScrollViewEvent("scrollEndDrag", scrollEvent);
28
+ const ScrollEndDragEvent& scrollEvent) const {
29
+ dispatchEvent(
30
+ "scrollEndDrag", std::make_shared<ScrollEndDragEvent>(scrollEvent));
30
31
  }
31
32
 
32
33
  void ScrollViewEventEmitter::onMomentumScrollBegin(
@@ -21,10 +21,11 @@ class ScrollViewEventEmitter : public ViewEventEmitter {
21
21
  using ViewEventEmitter::ViewEventEmitter;
22
22
 
23
23
  using Metrics = ScrollEvent;
24
+ using EndDragMetrics = ScrollEndDragEvent;
24
25
 
25
26
  void onScroll(const ScrollEvent& scrollEvent) const;
26
27
  void onScrollBeginDrag(const ScrollEvent& scrollEvent) const;
27
- void onScrollEndDrag(const ScrollEvent& scrollEvent) const;
28
+ void onScrollEndDrag(const ScrollEndDragEvent& scrollEvent) const;
28
29
  void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const;
29
30
  void onMomentumScrollEnd(const ScrollEvent& scrollEvent) const;
30
31
  void onScrollToTop(const ScrollEvent& scrollEvent) const;
@@ -52,8 +52,29 @@ BOOL RCTIsAttributedStringEffectivelySame(
52
52
  NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
53
53
  const facebook::react::TextAttributes &baseTextAttributes);
54
54
 
55
- @interface RCTWeakEventEmitterWrapper : NSObject
56
- @property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
57
- @end
55
+ static inline NSData *RCTWrapEventEmitter(const facebook::react::SharedEventEmitter &eventEmitter)
56
+ {
57
+ auto eventEmitterPtr = new std::weak_ptr<const facebook::react::EventEmitter>(eventEmitter);
58
+ return [[NSData alloc] initWithBytesNoCopy:eventEmitterPtr
59
+ length:sizeof(eventEmitterPtr)
60
+ deallocator:^(void *ptrToDelete, NSUInteger) {
61
+ delete (std::weak_ptr<facebook::react::EventEmitter> *)ptrToDelete;
62
+ }];
63
+ }
64
+
65
+ static inline facebook::react::SharedEventEmitter RCTUnwrapEventEmitter(NSData *data)
66
+ {
67
+ if (data.length == 0) {
68
+ return nullptr;
69
+ }
70
+
71
+ auto weakPtr = dynamic_cast<std::weak_ptr<const facebook::react::EventEmitter> *>(
72
+ (std::weak_ptr<const facebook::react::EventEmitter> *)data.bytes);
73
+ if (weakPtr) {
74
+ return weakPtr->lock();
75
+ }
76
+
77
+ return nullptr;
78
+ }
58
79
 
59
80
  NS_ASSUME_NONNULL_END
@@ -16,45 +16,6 @@
16
16
 
17
17
  using namespace facebook::react;
18
18
 
19
- @implementation RCTWeakEventEmitterWrapper {
20
- std::weak_ptr<const EventEmitter> _weakEventEmitter;
21
- }
22
-
23
- - (void)setEventEmitter:(SharedEventEmitter)eventEmitter
24
- {
25
- _weakEventEmitter = eventEmitter;
26
- }
27
-
28
- - (SharedEventEmitter)eventEmitter
29
- {
30
- return _weakEventEmitter.lock();
31
- }
32
-
33
- - (void)dealloc
34
- {
35
- _weakEventEmitter.reset();
36
- }
37
-
38
- - (BOOL)isEqual:(id)object
39
- {
40
- // We consider the underlying EventEmitter as the identity
41
- if (![object isKindOfClass:[self class]]) {
42
- return NO;
43
- }
44
-
45
- auto thisEventEmitter = [self eventEmitter];
46
- auto otherEventEmitter = [((RCTWeakEventEmitterWrapper *)object) eventEmitter];
47
- return thisEventEmitter == otherEventEmitter;
48
- }
49
-
50
- - (NSUInteger)hash
51
- {
52
- // We consider the underlying EventEmitter as the identity
53
- return (NSUInteger)_weakEventEmitter.lock().get();
54
- }
55
-
56
- @end
57
-
58
19
  inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
59
20
  {
60
21
  assert(fontWeight > 50);
@@ -405,10 +366,8 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
405
366
  {
406
367
  auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
407
368
 
408
- #if !TARGET_OS_MACCATALYST
409
369
  if (fragment.parentShadowView.componentHandle) {
410
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
411
- eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
370
+ auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
412
371
 
413
372
  NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
414
373
  @{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
@@ -416,7 +375,6 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
416
375
  [nsAttributedStringFragment addAttributes:additionalTextAttributes
417
376
  range:NSMakeRange(0, nsAttributedStringFragment.length)];
418
377
  }
419
- #endif
420
378
 
421
379
  return nsAttributedStringFragment;
422
380
  }
@@ -280,11 +280,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
280
280
  // after (fraction == 1.0) the last character, then the attribute is valid.
281
281
  if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
282
282
  (fraction < 1 || characterIndex < textStorage.length - 1)) {
283
- RCTWeakEventEmitterWrapper *eventEmitterWrapper =
284
- (RCTWeakEventEmitterWrapper *)[textStorage attribute:RCTAttributedStringEventEmitterKey
285
- atIndex:characterIndex
286
- effectiveRange:NULL];
287
- return eventEmitterWrapper.eventEmitter;
283
+ NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
284
+ atIndex:characterIndex
285
+ effectiveRange:NULL];
286
+ return RCTUnwrapEventEmitter(eventEmitterWrapper);
288
287
  }
289
288
 
290
289
  return nil;
@@ -300,8 +300,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
300
300
  }
301
301
 
302
302
  if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
303
- // Do not throw any error to match web spec
304
- return timerIndex_++;
303
+ // Do not throw any error to match web spec; instead return 0, an
304
+ // invalid timer id
305
+ return 0;
305
306
  }
306
307
 
307
308
  auto callback = args[0].getObject(rt).getFunction(rt);
@@ -358,8 +359,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
358
359
  }
359
360
 
360
361
  if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
361
- throw jsi::JSError(
362
- rt, "The first argument to setInterval must be a function.");
362
+ // Do not throw any error to match web spec; instead return 0, an
363
+ // invalid timer id
364
+ return 0;
363
365
  }
364
366
  auto callback = args[0].getObject(rt).getFunction(rt);
365
367
  auto delay = count > 1
@@ -93,7 +93,9 @@ class TimerManager {
93
93
 
94
94
  // Each timeout that is registered on this queue gets a sequential id. This
95
95
  // is the global count from which those are assigned.
96
- TimerHandle timerIndex_{0};
96
+ // As per WHATWG HTML 8.6.1 (Timers) ids must be greater than zero, i.e. start
97
+ // at 1
98
+ TimerHandle timerIndex_{1};
97
99
 
98
100
  // The React Native microtask queue is used to back public APIs including
99
101
  // `queueMicrotask`, `clearImmediate`, and `setImmediate` (which is used by
@@ -266,7 +266,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithoutDelay) {
266
266
  EXPECT_CALL(
267
267
  *mockRegistry_,
268
268
  createTimer(_, 0)); // If delay is not provided, it should use 0
269
- eval("setTimeout(() => {});");
269
+ auto val = eval("setTimeout(() => {});");
270
+ expectNoError();
271
+ EXPECT_EQ(val.asNumber(), 1); // First timer id should start at 1
270
272
  }
271
273
 
272
274
  TEST_F(ReactInstanceTest, testSetTimeoutWithPassThroughArgs) {
@@ -298,8 +300,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithInvalidArgs) {
298
300
  getErrorMessage("setTimeout();"),
299
301
  "setTimeout must be called with at least one argument (the function to call).");
300
302
 
301
- eval("setTimeout('invalid');");
303
+ auto val = eval("setTimeout('invalid')");
302
304
  expectNoError();
305
+ EXPECT_EQ(val.asNumber(), 0);
303
306
 
304
307
  eval("setTimeout(() => {}, 'invalid');");
305
308
  expectNoError();
@@ -416,9 +419,10 @@ TEST_F(ReactInstanceTest, testSetIntervalWithInvalidArgs) {
416
419
  EXPECT_EQ(
417
420
  getErrorMessage("setInterval();"),
418
421
  "setInterval must be called with at least one argument (the function to call).");
419
- EXPECT_EQ(
420
- getErrorMessage("setInterval('invalid', 100);"),
421
- "The first argument to setInterval must be a function.");
422
+
423
+ auto val = eval("setInterval('invalid', 100)");
424
+ expectNoError();
425
+ EXPECT_EQ(val.asNumber(), 0);
422
426
  }
423
427
 
424
428
  TEST_F(ReactInstanceTest, testClearInterval) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.77.1",
3
+ "version": "0.77.3",
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.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",
111
+ "@react-native/assets-registry": "0.77.3",
112
+ "@react-native/codegen": "0.77.3",
113
+ "@react-native/community-cli-plugin": "0.77.3",
114
+ "@react-native/gradle-plugin": "0.77.3",
115
+ "@react-native/js-polyfills": "0.77.3",
116
+ "@react-native/normalize-colors": "0.77.3",
117
+ "@react-native/virtualized-lists": "0.77.3",
118
118
  "abort-controller": "^3.0.0",
119
119
  "anser": "^1.4.9",
120
120
  "ansi-regex": "^5.0.0",
@@ -130,8 +130,8 @@
130
130
  "jest-environment-node": "^29.6.3",
131
131
  "jsc-android": "^250231.0.0",
132
132
  "memoize-one": "^5.0.0",
133
- "metro-runtime": "^0.81.0",
134
- "metro-source-map": "^0.81.0",
133
+ "metro-runtime": "^0.81.5",
134
+ "metro-source-map": "^0.81.5",
135
135
  "nullthrows": "^1.1.1",
136
136
  "pretty-format": "^29.7.0",
137
137
  "promise": "^8.3.0",