react-native 0.78.0 → 0.78.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm +7 -0
  2. package/Libraries/AppDelegate/RCTReactNativeFactory.mm +24 -0
  3. package/Libraries/AppDelegate/RCTRootViewFactory.h +18 -0
  4. package/Libraries/AppDelegate/RCTRootViewFactory.mm +16 -0
  5. package/Libraries/Components/TextInput/TextInput.js +3 -3
  6. package/Libraries/Core/ReactNativeVersion.js +1 -1
  7. package/Libraries/Image/Image.android.js +2 -0
  8. package/Libraries/Image/ImageViewNativeComponent.js +3 -4
  9. package/Libraries/Network/RCTDataRequestHandler.mm +17 -3
  10. package/Libraries/Network/RCTFileRequestHandler.mm +17 -3
  11. package/React/Base/RCTVersion.m +1 -1
  12. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
  13. package/ReactAndroid/gradle.properties +1 -1
  14. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +13 -8
  15. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  16. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt +12 -11
  17. package/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt +1 -1
  18. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +0 -3
  19. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  20. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +9 -0
  21. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +24 -13
  22. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +24 -3
  23. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +1 -43
  24. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +4 -5
  25. package/package.json +10 -10
  26. package/react-native.config.js +5 -21
  27. package/sdks/hermesc/osx-bin/hermes +0 -0
  28. package/sdks/hermesc/osx-bin/hermesc +0 -0
  29. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  30. package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
  31. package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
  32. package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
@@ -118,4 +118,11 @@
118
118
  return nullptr;
119
119
  }
120
120
 
121
+ - (void)loadSourceForBridge:(RCTBridge *)bridge
122
+ onProgress:(RCTSourceLoadProgressBlock)onProgress
123
+ onComplete:(RCTSourceLoadBlock)loadCallback
124
+ {
125
+ [RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
126
+ }
127
+
121
128
  @end
@@ -156,6 +156,15 @@ using namespace facebook::react;
156
156
  return RCTAppSetupDefaultModuleFromClass(moduleClass, self.delegate.dependencyProvider);
157
157
  }
158
158
 
159
+ - (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
160
+ {
161
+ if ([_delegate respondsToSelector:@selector(extraModulesForBridge:)]) {
162
+ return [_delegate extraModulesForBridge:bridge];
163
+ }
164
+
165
+ return @[];
166
+ }
167
+
159
168
  #pragma mark - RCTComponentViewFactoryComponentProvider
160
169
 
161
170
  - (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
@@ -228,6 +237,21 @@ using namespace facebook::react;
228
237
  };
229
238
  }
230
239
 
240
+ if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:onProgress:onComplete:)]) {
241
+ configuration.loadSourceForBridgeWithProgress =
242
+ ^(RCTBridge *_Nonnull bridge,
243
+ RCTSourceLoadProgressBlock _Nonnull onProgress,
244
+ RCTSourceLoadBlock _Nonnull loadCallback) {
245
+ [weakSelf.delegate loadSourceForBridge:bridge onProgress:onProgress onComplete:loadCallback];
246
+ };
247
+ }
248
+
249
+ if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
250
+ configuration.loadSourceForBridge = ^(RCTBridge *_Nonnull bridge, RCTSourceLoadBlock _Nonnull loadCallback) {
251
+ [weakSelf.delegate loadSourceForBridge:bridge withBlock:loadCallback];
252
+ };
253
+ }
254
+
231
255
  return [[RCTRootViewFactory alloc] initWithTurboModuleDelegate:self hostDelegate:self configuration:configuration];
232
256
  }
233
257
 
@@ -31,6 +31,11 @@ typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
31
31
  typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
32
32
  typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
33
33
  typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
34
+ typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
35
+ RCTBridge *bridge,
36
+ RCTSourceLoadProgressBlock onProgress,
37
+ RCTSourceLoadBlock loadCallback);
38
+ typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
34
39
 
35
40
  #pragma mark - RCTRootViewFactory Configuration
36
41
  @interface RCTRootViewFactoryConfiguration : NSObject
@@ -145,6 +150,19 @@ typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *modu
145
150
  */
146
151
  @property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
147
152
 
153
+ /**
154
+ * The bridge will automatically attempt to load the JS source code from the
155
+ * location specified by the `sourceURLForBridge:` method, however, if you want
156
+ * to handle loading the JS yourself, you can do so by setting this property.
157
+ */
158
+ @property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
159
+
160
+ /**
161
+ * Similar to loadSourceForBridgeWithProgress but without progress
162
+ * reporting.
163
+ */
164
+ @property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
165
+
148
166
  @end
149
167
 
150
168
  #pragma mark - RCTRootViewFactory
@@ -302,6 +302,22 @@
302
302
  return NO;
303
303
  }
304
304
 
305
+ - (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback
306
+ {
307
+ if (_configuration.loadSourceForBridge != nil) {
308
+ _configuration.loadSourceForBridge(bridge, loadCallback);
309
+ }
310
+ }
311
+
312
+ - (void)loadSourceForBridge:(RCTBridge *)bridge
313
+ onProgress:(RCTSourceLoadProgressBlock)onProgress
314
+ onComplete:(RCTSourceLoadBlock)loadCallback
315
+ {
316
+ if (_configuration.loadSourceForBridgeWithProgress != nil) {
317
+ _configuration.loadSourceForBridgeWithProgress(bridge, onProgress, loadCallback);
318
+ }
319
+ }
320
+
305
321
  - (NSURL *)bundleURL
306
322
  {
307
323
  return self->_configuration.bundleURLBlock();
@@ -1019,7 +1019,7 @@ function useTextInputStateSynchronization_STATE({
1019
1019
  mostRecentEventCount: number,
1020
1020
  selection: ?Selection,
1021
1021
  inputRef: React.RefObject<null | HostInstance>,
1022
- text: string,
1022
+ text?: string,
1023
1023
  viewCommands: ViewCommands,
1024
1024
  }): {
1025
1025
  setLastNativeText: string => void,
@@ -1100,7 +1100,7 @@ function useTextInputStateSynchronization_REFS({
1100
1100
  mostRecentEventCount: number,
1101
1101
  selection: ?Selection,
1102
1102
  inputRef: React.RefObject<null | HostInstance>,
1103
- text: string,
1103
+ text?: string,
1104
1104
  viewCommands: ViewCommands,
1105
1105
  }): {
1106
1106
  setLastNativeText: string => void,
@@ -1314,7 +1314,7 @@ function InternalTextInput(props: Props): React.Node {
1314
1314
  ? props.value
1315
1315
  : typeof props.defaultValue === 'string'
1316
1316
  ? props.defaultValue
1317
- : '';
1317
+ : undefined;
1318
1318
 
1319
1319
  const viewCommands =
1320
1320
  AndroidTextInputCommands ||
@@ -16,7 +16,7 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 78,
19
- patch: 0,
19
+ patch: 2,
20
20
  prerelease: null,
21
21
  };
22
22
 
@@ -133,6 +133,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
133
133
  width: undefined,
134
134
  height: undefined,
135
135
  };
136
+ const defaultSource = resolveAssetSource(props.defaultSource);
136
137
  const loadingIndicatorSource = resolveAssetSource(
137
138
  props.loadingIndicatorSource,
138
139
  );
@@ -178,6 +179,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
178
179
  /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
179
180
  * when making Flow check .android.js files. */
180
181
  headers: (source?.[0]?.headers || source?.headers: ?{[string]: string}),
182
+ defaultSource: defaultSource ? defaultSource.uri : null,
181
183
  loadingIndicatorSrc: loadingIndicatorSource
182
184
  ? loadingIndicatorSource.uri
183
185
  : null,
@@ -21,6 +21,7 @@ import type {
21
21
  } from '../StyleSheet/StyleSheet';
22
22
  import type {ResolvedAssetSource} from './AssetSourceResolver';
23
23
  import type {ImageProps} from './ImageProps';
24
+ import type {ImageSource} from './ImageSource';
24
25
 
25
26
  import * as NativeComponentRegistry from '../NativeComponent/NativeComponentRegistry';
26
27
  import {ConditionallyIgnoredEventHandlers} from '../NativeComponent/ViewConfigIgnore';
@@ -42,7 +43,7 @@ type Props = $ReadOnly<{
42
43
  | ?ResolvedAssetSource
43
44
  | ?$ReadOnlyArray<?$ReadOnly<{uri?: ?string, ...}>>,
44
45
  headers?: ?{[string]: string},
45
- defaultSrc?: ?string,
46
+ defaultSource?: ?ImageSource | ?string,
46
47
  loadingIndicatorSrc?: ?string,
47
48
  }>;
48
49
 
@@ -82,9 +83,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
82
83
  },
83
84
  validAttributes: {
84
85
  blurRadius: true,
85
- defaultSource: {
86
- process: require('./resolveAssetSource'),
87
- },
86
+ defaultSource: true,
88
87
  internal_analyticTag: true,
89
88
  resizeMethod: true,
90
89
  resizeMode: true,
@@ -8,6 +8,8 @@
8
8
  #import <React/RCTDataRequestHandler.h>
9
9
  #import <ReactCommon/RCTTurboModule.h>
10
10
 
11
+ #import <mutex>
12
+
11
13
  #import "RCTNetworkPlugins.h"
12
14
 
13
15
  @interface RCTDataRequestHandler () <RCTTurboModule>
@@ -15,14 +17,22 @@
15
17
 
16
18
  @implementation RCTDataRequestHandler {
17
19
  NSOperationQueue *_queue;
20
+ std::mutex _operationHandlerMutexLock;
18
21
  }
19
22
 
20
23
  RCT_EXPORT_MODULE()
21
24
 
22
25
  - (void)invalidate
23
26
  {
24
- [_queue cancelAllOperations];
25
- _queue = nil;
27
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
28
+ if (_queue) {
29
+ for (NSOperation *operation in _queue.operations) {
30
+ if (!operation.isCancelled && !operation.isFinished) {
31
+ [operation cancel];
32
+ }
33
+ }
34
+ _queue = nil;
35
+ }
26
36
  }
27
37
 
28
38
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -32,6 +42,7 @@ RCT_EXPORT_MODULE()
32
42
 
33
43
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
34
44
  {
45
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
35
46
  // Lazy setup
36
47
  if (!_queue) {
37
48
  _queue = [NSOperationQueue new];
@@ -69,7 +80,10 @@ RCT_EXPORT_MODULE()
69
80
 
70
81
  - (void)cancelRequest:(NSOperation *)op
71
82
  {
72
- [op cancel];
83
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
84
+ if (!op.isCancelled && !op.isFinished) {
85
+ [op cancel];
86
+ }
73
87
  }
74
88
 
75
89
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -7,6 +7,8 @@
7
7
 
8
8
  #import <React/RCTFileRequestHandler.h>
9
9
 
10
+ #import <mutex>
11
+
10
12
  #import <MobileCoreServices/MobileCoreServices.h>
11
13
 
12
14
  #import <React/RCTUtils.h>
@@ -19,14 +21,22 @@
19
21
 
20
22
  @implementation RCTFileRequestHandler {
21
23
  NSOperationQueue *_fileQueue;
24
+ std::mutex _operationHandlerMutexLock;
22
25
  }
23
26
 
24
27
  RCT_EXPORT_MODULE()
25
28
 
26
29
  - (void)invalidate
27
30
  {
28
- [_fileQueue cancelAllOperations];
29
- _fileQueue = nil;
31
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
32
+ if (_fileQueue) {
33
+ for (NSOperation *operation in _fileQueue.operations) {
34
+ if (!operation.isCancelled && !operation.isFinished) {
35
+ [operation cancel];
36
+ }
37
+ }
38
+ _fileQueue = nil;
39
+ }
30
40
  }
31
41
 
32
42
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -36,6 +46,7 @@ RCT_EXPORT_MODULE()
36
46
 
37
47
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
38
48
  {
49
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
39
50
  // Lazy setup
40
51
  if (!_fileQueue) {
41
52
  _fileQueue = [NSOperationQueue new];
@@ -83,7 +94,10 @@ RCT_EXPORT_MODULE()
83
94
 
84
95
  - (void)cancelRequest:(NSOperation *)op
85
96
  {
86
- [op cancel];
97
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
98
+ if (!op.isCancelled && !op.isFinished) {
99
+ [op cancel];
100
+ }
87
101
  }
88
102
 
89
103
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -23,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(78),
26
- RCTVersionPatch: @(0),
26
+ RCTVersionPatch: @(2),
27
27
  RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
@@ -101,11 +101,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
101
101
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
102
102
  [_backedTextInputView.defaultTextAttributes mutableCopy];
103
103
 
104
- #if !TARGET_OS_MACCATALYST
105
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
106
- eventEmitterWrapper.eventEmitter = _eventEmitter;
107
- defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
108
- #endif
104
+ defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
109
105
 
110
106
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
111
107
  }
@@ -266,10 +262,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
266
262
  if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
267
263
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
268
264
  RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
269
- #if !TARGET_OS_MACCATALYST
270
265
  defaultAttributes[RCTAttributedStringEventEmitterKey] =
271
266
  _backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
272
- #endif
273
267
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
274
268
  }
275
269
 
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.78.0
1
+ VERSION_NAME=0.78.2
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
 
4
4
  android.useAndroidX=true
@@ -173,7 +173,7 @@ public class FabricUIManager
173
173
  private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
174
174
 
175
175
  private boolean mMountNotificationScheduled = false;
176
- private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
176
+ private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
177
177
 
178
178
  @ThreadConfined(UI)
179
179
  @NonNull
@@ -1250,12 +1250,15 @@ public class FabricUIManager
1250
1250
 
1251
1251
  // Collect surface IDs for all the mount items
1252
1252
  for (MountItem mountItem : mountItems) {
1253
- if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
1254
- mMountedSurfaceIds.add(mountItem.getSurfaceId());
1253
+ if (mountItem != null
1254
+ && !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
1255
+ mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
1255
1256
  }
1256
1257
  }
1257
1258
 
1258
- if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
1259
+ if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
1260
+ mMountNotificationScheduled = true;
1261
+
1259
1262
  // Notify mount when the effects are visible and prevent mount hooks to
1260
1263
  // delay paint.
1261
1264
  UiThreadUtil.getUiThreadHandler()
@@ -1265,17 +1268,19 @@ public class FabricUIManager
1265
1268
  public void run() {
1266
1269
  mMountNotificationScheduled = false;
1267
1270
 
1271
+ // Create a copy in case mount hooks trigger more mutations
1272
+ final List<Integer> surfaceIdsToReportMount =
1273
+ mSurfaceIdsWithPendingMountNotification;
1274
+ mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
1275
+
1268
1276
  final @Nullable FabricUIManagerBinding binding = mBinding;
1269
1277
  if (binding == null || mDestroyed) {
1270
- mMountedSurfaceIds.clear();
1271
1278
  return;
1272
1279
  }
1273
1280
 
1274
- for (int surfaceId : mMountedSurfaceIds) {
1281
+ for (int surfaceId : surfaceIdsToReportMount) {
1275
1282
  binding.reportMount(surfaceId);
1276
1283
  }
1277
-
1278
- mMountedSurfaceIds.clear();
1279
1284
  }
1280
1285
  });
1281
1286
  }
@@ -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", 78,
20
- "patch", 0,
20
+ "patch", 2,
21
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
 
@@ -198,17 +199,17 @@ internal class CompositeBackgroundDrawable(
198
199
 
199
200
  computedBorderRadius?.let {
200
201
  pathForOutline.addRoundRect(
201
- RectF(bounds),
202
- 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),
211
- Path.Direction.CW)
202
+ RectF(bounds),
203
+ floatArrayOf(
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()),
212
+ Path.Direction.CW)
212
213
  }
213
214
 
214
215
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -124,7 +124,7 @@ public constructor(
124
124
  }
125
125
  }
126
126
 
127
- @ReactProp(name = "defaultSource", customType = "ImageSource")
127
+ @ReactProp(name = "defaultSource")
128
128
  public fun setDefaultSource(view: ReactImageView, source: String?) {
129
129
  view.setDefaultSource(source)
130
130
  }
@@ -588,9 +588,6 @@ public class ReactViewGroup extends ViewGroup
588
588
  UiThreadUtil.assertOnUiThread();
589
589
  checkViewClippingTag(child, Boolean.TRUE);
590
590
  if (!customDrawOrderDisabled()) {
591
- if (indexOfChild(child) == -1) {
592
- return;
593
- }
594
591
  getDrawingOrderHelper().handleRemoveView(child);
595
592
  setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
596
593
  } else {
@@ -17,7 +17,7 @@ namespace facebook::react {
17
17
  constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 78;
20
- int32_t Patch = 0;
20
+ int32_t Patch = 2;
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)
@@ -203,7 +203,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
203
203
  /**
204
204
  * Creates JSError with current JS runtime and NSException stack trace.
205
205
  */
206
- static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
206
+ static jsi::JSError convertNSExceptionToJSError(
207
+ jsi::Runtime &runtime,
208
+ NSException *exception,
209
+ const std::string &moduleName,
210
+ const std::string &methodName)
207
211
  {
208
212
  std::string reason = [exception.reason UTF8String];
209
213
 
@@ -214,7 +218,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
214
218
  cause.setProperty(
215
219
  runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
216
220
 
217
- jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
221
+ std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
222
+ jsi::Value error = createJSRuntimeError(runtime, message);
218
223
  error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
219
224
  return {runtime, std::move(error)};
220
225
  }
@@ -346,28 +351,34 @@ id ObjCTurboModule::performMethodInvocation(
346
351
  }
347
352
 
348
353
  if (isSync) {
349
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
354
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
350
355
  } else {
351
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
356
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
352
357
  }
353
358
 
354
359
  @try {
355
360
  [inv invokeWithTarget:strongModule];
356
361
  } @catch (NSException *exception) {
357
- throw convertNSExceptionToJSError(runtime, exception);
362
+ if (isSync) {
363
+ // We can only convert NSException to JSError in sync method calls.
364
+ // See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
365
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
366
+ } else {
367
+ @throw exception;
368
+ }
358
369
  } @finally {
359
370
  [retainedObjectsForInvocation removeAllObjects];
360
371
  }
361
372
 
362
373
  if (!isSync) {
363
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
374
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
364
375
  return;
365
376
  }
366
377
 
367
378
  void *rawResult;
368
379
  [inv getReturnValue:&rawResult];
369
380
  result = (__bridge id)rawResult;
370
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
381
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
371
382
  };
372
383
 
373
384
  if (isSync) {
@@ -409,23 +420,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
409
420
  }
410
421
 
411
422
  if (shouldVoidMethodsExecuteSync_) {
412
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
423
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
413
424
  } else {
414
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
425
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
415
426
  }
416
427
 
417
428
  @try {
418
429
  [inv invokeWithTarget:strongModule];
419
430
  } @catch (NSException *exception) {
420
- throw convertNSExceptionToJSError(runtime, exception);
431
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
421
432
  } @finally {
422
433
  [retainedObjectsForInvocation removeAllObjects];
423
434
  }
424
435
 
425
436
  if (shouldVoidMethodsExecuteSync_) {
426
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
437
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
427
438
  } else {
428
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
439
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
429
440
  }
430
441
 
431
442
  return;
@@ -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);
@@ -409,10 +370,8 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
409
370
  {
410
371
  auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
411
372
 
412
- #if !TARGET_OS_MACCATALYST
413
373
  if (fragment.parentShadowView.componentHandle) {
414
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
415
- eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
374
+ auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
416
375
 
417
376
  NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
418
377
  @{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
@@ -420,7 +379,6 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
420
379
  [nsAttributedStringFragment addAttributes:additionalTextAttributes
421
380
  range:NSMakeRange(0, nsAttributedStringFragment.length)];
422
381
  }
423
- #endif
424
382
 
425
383
  return nsAttributedStringFragment;
426
384
  }
@@ -268,11 +268,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
268
268
  // after (fraction == 1.0) the last character, then the attribute is valid.
269
269
  if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
270
270
  (fraction < 1 || characterIndex < textStorage.length - 1)) {
271
- RCTWeakEventEmitterWrapper *eventEmitterWrapper =
272
- (RCTWeakEventEmitterWrapper *)[textStorage attribute:RCTAttributedStringEventEmitterKey
273
- atIndex:characterIndex
274
- effectiveRange:NULL];
275
- return eventEmitterWrapper.eventEmitter;
271
+ NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
272
+ atIndex:characterIndex
273
+ effectiveRange:NULL];
274
+ return RCTUnwrapEventEmitter(eventEmitterWrapper);
276
275
  }
277
276
 
278
277
  return nil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.78.0",
3
+ "version": "0.78.2",
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.78.0",
112
- "@react-native/codegen": "0.78.0",
113
- "@react-native/community-cli-plugin": "0.78.0",
114
- "@react-native/gradle-plugin": "0.78.0",
115
- "@react-native/js-polyfills": "0.78.0",
116
- "@react-native/normalize-colors": "0.78.0",
117
- "@react-native/virtualized-lists": "0.78.0",
111
+ "@react-native/assets-registry": "0.78.2",
112
+ "@react-native/codegen": "0.78.2",
113
+ "@react-native/community-cli-plugin": "0.78.2",
114
+ "@react-native/gradle-plugin": "0.78.2",
115
+ "@react-native/js-polyfills": "0.78.2",
116
+ "@react-native/normalize-colors": "0.78.2",
117
+ "@react-native/virtualized-lists": "0.78.2",
118
118
  "abort-controller": "^3.0.0",
119
119
  "anser": "^1.4.9",
120
120
  "ansi-regex": "^5.0.0",
@@ -129,8 +129,8 @@
129
129
  "invariant": "^2.2.4",
130
130
  "jest-environment-node": "^29.6.3",
131
131
  "memoize-one": "^5.0.0",
132
- "metro-runtime": "^0.81.0",
133
- "metro-source-map": "^0.81.0",
132
+ "metro-runtime": "^0.81.3",
133
+ "metro-source-map": "^0.81.3",
134
134
  "nullthrows": "^1.1.1",
135
135
  "pretty-format": "^29.7.0",
136
136
  "promise": "^8.3.0",
@@ -44,27 +44,11 @@ try {
44
44
 
45
45
  const commands = [];
46
46
 
47
- try {
48
- const {
49
- bundleCommand,
50
- startCommand,
51
- } = require('@react-native/community-cli-plugin');
52
- commands.push(bundleCommand, startCommand);
53
- } catch (e) {
54
- const known =
55
- e.code === 'MODULE_NOT_FOUND' &&
56
- e.message.includes('@react-native-community/cli-server-api');
57
-
58
- if (!known) {
59
- throw e;
60
- }
61
-
62
- if (verbose) {
63
- console.warn(
64
- '@react-native-community/cli-server-api not found, the react-native.config.js may be unusable.',
65
- );
66
- }
67
- }
47
+ const {
48
+ bundleCommand,
49
+ startCommand,
50
+ } = require('@react-native/community-cli-plugin');
51
+ commands.push(bundleCommand, startCommand);
68
52
 
69
53
  const codegenCommand = {
70
54
  name: 'codegen',
Binary file
Binary file
Binary file
Binary file