react-native 0.76.6 → 0.76.8
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/AppDelegate/RCTAppDelegate.mm +0 -5
- package/Libraries/AppDelegate/RCTAppSetupUtils.mm +3 -1
- package/Libraries/AppDelegate/RCTRootViewFactory.mm +2 -3
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Image/RCTImageLoader.mm +9 -1
- package/Libraries/Network/FormData.js +11 -3
- package/Libraries/Utilities/Appearance.js +3 -1
- package/React/Base/RCTVersion.m +1 -1
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +2 -5
- package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
- package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
- package/ReactAndroid/api/ReactAndroid.api +3 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/HMRClient.java +4 -1
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +13 -8
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +15 -8
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +16 -2
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +9 -0
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +24 -13
- package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +5 -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/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/cli.js +11 -2
- package/gradle/libs.versions.toml +1 -1
- package/package.json +8 -8
- package/react-native.config.js +24 -23
- 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
|
@@ -81,11 +81,6 @@
|
|
|
81
81
|
[_window makeKeyAndVisible];
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
- (void)applicationDidEnterBackground:(UIApplication *)application
|
|
85
|
-
{
|
|
86
|
-
// Noop
|
|
87
|
-
}
|
|
88
|
-
|
|
89
84
|
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
|
90
85
|
{
|
|
91
86
|
[NSException raise:@"RCTBridgeDelegate::sourceURLForBridge not implemented"
|
|
@@ -53,7 +53,9 @@ RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary
|
|
|
53
53
|
id<RCTSurfaceProtocol> surface = [[RCTFabricSurface alloc] initWithBridge:bridge
|
|
54
54
|
moduleName:moduleName
|
|
55
55
|
initialProperties:initialProperties];
|
|
56
|
-
|
|
56
|
+
UIView *rootView = [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
|
|
57
|
+
[surface start];
|
|
58
|
+
return rootView;
|
|
57
59
|
}
|
|
58
60
|
return [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
|
|
59
61
|
}
|
|
@@ -159,9 +159,8 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
|
|
|
159
159
|
|
|
160
160
|
RCTFabricSurface *surface = [self.reactHost createSurfaceWithModuleName:moduleName initialProperties:initProps];
|
|
161
161
|
|
|
162
|
-
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView =
|
|
163
|
-
initWithSurface:surface
|
|
164
|
-
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
|
|
162
|
+
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView =
|
|
163
|
+
[[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
|
|
165
164
|
|
|
166
165
|
surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor];
|
|
167
166
|
if (self->_configuration.customizeRootView != nil) {
|
|
@@ -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
|
-
|
|
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];
|
|
@@ -28,6 +28,15 @@ type FormDataPart =
|
|
|
28
28
|
...
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Encode a FormData filename compliant with RFC 2183
|
|
33
|
+
*
|
|
34
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#directives
|
|
35
|
+
*/
|
|
36
|
+
function encodeFilename(filename: string): string {
|
|
37
|
+
return encodeURIComponent(filename.replace(/\//g, '_'));
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
/**
|
|
32
41
|
* Polyfill for XMLHttpRequest2 FormData API, allowing multipart POST requests
|
|
33
42
|
* with mixed data (string, native files) to be submitted via XMLHttpRequest.
|
|
@@ -82,9 +91,8 @@ class FormData {
|
|
|
82
91
|
// content type (cf. web Blob interface.)
|
|
83
92
|
if (typeof value === 'object' && !Array.isArray(value) && value) {
|
|
84
93
|
if (typeof value.name === 'string') {
|
|
85
|
-
headers['content-disposition'] +=
|
|
86
|
-
value.name
|
|
87
|
-
}"; filename*=utf-8''${encodeURI(value.name)}`;
|
|
94
|
+
headers['content-disposition'] +=
|
|
95
|
+
`; filename="${encodeFilename(value.name)}"`;
|
|
88
96
|
}
|
|
89
97
|
if (typeof value.type === 'string') {
|
|
90
98
|
headers['content-type'] = value.type;
|
|
@@ -105,7 +105,9 @@ export function setColorScheme(colorScheme: ?ColorSchemeName): void {
|
|
|
105
105
|
const {NativeAppearance} = state;
|
|
106
106
|
if (NativeAppearance != null) {
|
|
107
107
|
NativeAppearance.setColorScheme(colorScheme ?? 'unspecified');
|
|
108
|
-
state.appearance = {
|
|
108
|
+
state.appearance = {
|
|
109
|
+
colorScheme: toColorScheme(NativeAppearance.getColorScheme()),
|
|
110
|
+
};
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -53,11 +53,8 @@ static RCTRootViewSizeFlexibility convertToRootViewSizeFlexibility(RCTSurfaceSiz
|
|
|
53
53
|
|
|
54
54
|
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface
|
|
55
55
|
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
[surface start];
|
|
59
|
-
}
|
|
60
|
-
return self;
|
|
56
|
+
return [super initWithSurface:surface
|
|
57
|
+
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
|
|
61
58
|
}
|
|
62
59
|
|
|
63
60
|
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
|
@@ -99,11 +99,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
|
99
99
|
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
|
100
100
|
[_backedTextInputView.defaultTextAttributes mutableCopy];
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
|
|
104
|
-
eventEmitterWrapper.eventEmitter = _eventEmitter;
|
|
105
|
-
defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
|
|
106
|
-
#endif
|
|
102
|
+
defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
|
|
107
103
|
|
|
108
104
|
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
|
109
105
|
}
|
|
@@ -263,10 +259,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
|
263
259
|
if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
|
|
264
260
|
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
|
265
261
|
RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
|
|
266
|
-
#if !TARGET_OS_MACCATALYST
|
|
267
262
|
defaultAttributes[RCTAttributedStringEventEmitterKey] =
|
|
268
263
|
_backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
|
|
269
|
-
#endif
|
|
270
264
|
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
|
271
265
|
}
|
|
272
266
|
|
|
@@ -142,6 +142,7 @@ using namespace facebook::react;
|
|
|
142
142
|
|
|
143
143
|
if (!_view) {
|
|
144
144
|
_view = [[RCTSurfaceView alloc] initWithSurface:(RCTSurface *)self];
|
|
145
|
+
[self _updateLayoutContext];
|
|
145
146
|
_touchHandler = [RCTSurfaceTouchHandler new];
|
|
146
147
|
[_touchHandler attachToView:_view];
|
|
147
148
|
}
|
|
@@ -2248,7 +2248,7 @@ public abstract interface class com/facebook/react/devsupport/HMRClient : com/fa
|
|
|
2248
2248
|
public abstract fun disable ()V
|
|
2249
2249
|
public abstract fun enable ()V
|
|
2250
2250
|
public abstract fun registerBundle (Ljava/lang/String;)V
|
|
2251
|
-
public abstract fun setup (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;
|
|
2251
|
+
public abstract fun setup (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZLjava/lang/String;)V
|
|
2252
2252
|
}
|
|
2253
2253
|
|
|
2254
2254
|
public final class com/facebook/react/devsupport/InspectorFlags {
|
|
@@ -7859,6 +7859,7 @@ public class com/facebook/react/views/text/TextAttributeProps {
|
|
|
7859
7859
|
public static final field TA_KEY_LETTER_SPACING S
|
|
7860
7860
|
public static final field TA_KEY_LINE_BREAK_STRATEGY S
|
|
7861
7861
|
public static final field TA_KEY_LINE_HEIGHT S
|
|
7862
|
+
public static final field TA_KEY_MAX_FONT_SIZE_MULTIPLIER S
|
|
7862
7863
|
public static final field TA_KEY_OPACITY S
|
|
7863
7864
|
public static final field TA_KEY_ROLE S
|
|
7864
7865
|
public static final field TA_KEY_TEXT_DECORATION_COLOR S
|
|
@@ -7891,6 +7892,7 @@ public class com/facebook/react/views/text/TextAttributeProps {
|
|
|
7891
7892
|
protected field mLetterSpacingInput F
|
|
7892
7893
|
protected field mLineHeight F
|
|
7893
7894
|
protected field mLineHeightInput F
|
|
7895
|
+
protected field mMaxFontSizeMultiplier F
|
|
7894
7896
|
protected field mNumberOfLines I
|
|
7895
7897
|
protected field mOpacity F
|
|
7896
7898
|
protected field mRole Lcom/facebook/react/uimanager/ReactAccessibilityDelegate$Role;
|
|
@@ -696,10 +696,12 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
|
|
|
696
696
|
URL sourceUrl = new URL(getSourceUrl());
|
|
697
697
|
String path = sourceUrl.getPath().substring(1); // strip initial slash in path
|
|
698
698
|
String host = sourceUrl.getHost();
|
|
699
|
+
String scheme = sourceUrl.getProtocol();
|
|
699
700
|
int port = sourceUrl.getPort() != -1 ? sourceUrl.getPort() : sourceUrl.getDefaultPort();
|
|
700
701
|
mCurrentContext
|
|
701
702
|
.getJSModule(HMRClient.class)
|
|
702
|
-
.setup(
|
|
703
|
+
.setup(
|
|
704
|
+
"android", path, host, port, mDevSettings.isHotModuleReplacementEnabled(), scheme);
|
|
703
705
|
} catch (MalformedURLException e) {
|
|
704
706
|
showNewJavaError(e.getMessage(), e);
|
|
705
707
|
}
|
|
@@ -26,8 +26,11 @@ public interface HMRClient extends JavaScriptModule {
|
|
|
26
26
|
* @param host The host that the HMRClient should communicate with.
|
|
27
27
|
* @param port The port that the HMRClient should communicate with on the host.
|
|
28
28
|
* @param isEnabled Whether HMR is enabled initially.
|
|
29
|
+
* @param scheme The protocol that the HMRClient should communicate with on the host (defaults to
|
|
30
|
+
* http).
|
|
29
31
|
*/
|
|
30
|
-
void setup(
|
|
32
|
+
void setup(
|
|
33
|
+
String platform, String bundleEntry, String host, int port, boolean isEnabled, String scheme);
|
|
31
34
|
|
|
32
35
|
/** Registers an additional JS bundle with HMRClient. */
|
|
33
36
|
void registerBundle(String bundleUrl);
|
|
@@ -172,7 +172,7 @@ public class FabricUIManager
|
|
|
172
172
|
private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
|
|
173
173
|
|
|
174
174
|
private boolean mMountNotificationScheduled = false;
|
|
175
|
-
private
|
|
175
|
+
private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
|
|
176
176
|
|
|
177
177
|
@ThreadConfined(UI)
|
|
178
178
|
@NonNull
|
|
@@ -1257,12 +1257,15 @@ public class FabricUIManager
|
|
|
1257
1257
|
|
|
1258
1258
|
// Collect surface IDs for all the mount items
|
|
1259
1259
|
for (MountItem mountItem : mountItems) {
|
|
1260
|
-
if (mountItem != null
|
|
1261
|
-
|
|
1260
|
+
if (mountItem != null
|
|
1261
|
+
&& !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
|
|
1262
|
+
mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
|
|
1262
1263
|
}
|
|
1263
1264
|
}
|
|
1264
1265
|
|
|
1265
|
-
if (!mMountNotificationScheduled && !
|
|
1266
|
+
if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
|
|
1267
|
+
mMountNotificationScheduled = true;
|
|
1268
|
+
|
|
1266
1269
|
// Notify mount when the effects are visible and prevent mount hooks to
|
|
1267
1270
|
// delay paint.
|
|
1268
1271
|
UiThreadUtil.getUiThreadHandler()
|
|
@@ -1272,17 +1275,19 @@ public class FabricUIManager
|
|
|
1272
1275
|
public void run() {
|
|
1273
1276
|
mMountNotificationScheduled = false;
|
|
1274
1277
|
|
|
1278
|
+
// Create a copy in case mount hooks trigger more mutations
|
|
1279
|
+
final List<Integer> surfaceIdsToReportMount =
|
|
1280
|
+
mSurfaceIdsWithPendingMountNotification;
|
|
1281
|
+
mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
|
|
1282
|
+
|
|
1275
1283
|
final @Nullable Binding binding = mBinding;
|
|
1276
1284
|
if (binding == null || mDestroyed) {
|
|
1277
|
-
mMountedSurfaceIds.clear();
|
|
1278
1285
|
return;
|
|
1279
1286
|
}
|
|
1280
1287
|
|
|
1281
|
-
for (int surfaceId :
|
|
1288
|
+
for (int surfaceId : surfaceIdsToReportMount) {
|
|
1282
1289
|
binding.reportMount(surfaceId);
|
|
1283
1290
|
}
|
|
1284
|
-
|
|
1285
|
-
mMountedSurfaceIds.clear();
|
|
1286
1291
|
}
|
|
1287
1292
|
});
|
|
1288
1293
|
}
|
|
@@ -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
|
|
334
|
-
|
|
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
|
|
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
|
-
|
|
434
|
+
SurfaceMountingManager smm = getSurfaceMountingManager(surfaceId, reactTag);
|
|
438
435
|
if (smm == null) {
|
|
439
|
-
|
|
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
|
}
|
|
@@ -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
|
-
|
|
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;
|
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]) {
|
|
@@ -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)
|
|
@@ -195,7 +195,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
|
|
|
195
195
|
/**
|
|
196
196
|
* Creates JSError with current JS runtime and NSException stack trace.
|
|
197
197
|
*/
|
|
198
|
-
static jsi::JSError convertNSExceptionToJSError(
|
|
198
|
+
static jsi::JSError convertNSExceptionToJSError(
|
|
199
|
+
jsi::Runtime &runtime,
|
|
200
|
+
NSException *exception,
|
|
201
|
+
const std::string &moduleName,
|
|
202
|
+
const std::string &methodName)
|
|
199
203
|
{
|
|
200
204
|
std::string reason = [exception.reason UTF8String];
|
|
201
205
|
|
|
@@ -206,7 +210,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
|
|
|
206
210
|
cause.setProperty(
|
|
207
211
|
runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
|
|
208
212
|
|
|
209
|
-
|
|
213
|
+
std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
|
|
214
|
+
jsi::Value error = createJSRuntimeError(runtime, message);
|
|
210
215
|
error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
|
|
211
216
|
return {runtime, std::move(error)};
|
|
212
217
|
}
|
|
@@ -338,28 +343,34 @@ id ObjCTurboModule::performMethodInvocation(
|
|
|
338
343
|
}
|
|
339
344
|
|
|
340
345
|
if (isSync) {
|
|
341
|
-
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName,
|
|
346
|
+
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
|
|
342
347
|
} else {
|
|
343
|
-
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName,
|
|
348
|
+
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
|
|
344
349
|
}
|
|
345
350
|
|
|
346
351
|
@try {
|
|
347
352
|
[inv invokeWithTarget:strongModule];
|
|
348
353
|
} @catch (NSException *exception) {
|
|
349
|
-
|
|
354
|
+
if (isSync) {
|
|
355
|
+
// We can only convert NSException to JSError in sync method calls.
|
|
356
|
+
// See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
|
|
357
|
+
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
|
|
358
|
+
} else {
|
|
359
|
+
@throw exception;
|
|
360
|
+
}
|
|
350
361
|
} @finally {
|
|
351
362
|
[retainedObjectsForInvocation removeAllObjects];
|
|
352
363
|
}
|
|
353
364
|
|
|
354
365
|
if (!isSync) {
|
|
355
|
-
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName,
|
|
366
|
+
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
|
|
356
367
|
return;
|
|
357
368
|
}
|
|
358
369
|
|
|
359
370
|
void *rawResult;
|
|
360
371
|
[inv getReturnValue:&rawResult];
|
|
361
372
|
result = (__bridge id)rawResult;
|
|
362
|
-
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName,
|
|
373
|
+
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
|
|
363
374
|
};
|
|
364
375
|
|
|
365
376
|
if (isSync) {
|
|
@@ -401,23 +412,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
|
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
if (shouldVoidMethodsExecuteSync_) {
|
|
404
|
-
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName,
|
|
415
|
+
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
|
|
405
416
|
} else {
|
|
406
|
-
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName,
|
|
417
|
+
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
|
|
407
418
|
}
|
|
408
419
|
|
|
409
420
|
@try {
|
|
410
421
|
[inv invokeWithTarget:strongModule];
|
|
411
422
|
} @catch (NSException *exception) {
|
|
412
|
-
throw convertNSExceptionToJSError(runtime, exception);
|
|
423
|
+
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
|
|
413
424
|
} @finally {
|
|
414
425
|
[retainedObjectsForInvocation removeAllObjects];
|
|
415
426
|
}
|
|
416
427
|
|
|
417
428
|
if (shouldVoidMethodsExecuteSync_) {
|
|
418
|
-
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName,
|
|
429
|
+
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
|
|
419
430
|
} else {
|
|
420
|
-
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName,
|
|
431
|
+
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
|
|
421
432
|
}
|
|
422
433
|
|
|
423
434
|
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) &&
|
|
@@ -213,6 +217,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
|
|
|
213
217
|
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
|
|
214
218
|
debugStringConvertibleItem("dynamicTypeRamp", dynamicTypeRamp),
|
|
215
219
|
debugStringConvertibleItem("letterSpacing", letterSpacing),
|
|
220
|
+
debugStringConvertibleItem("maxFontSizeMultiplier", maxFontSizeMultiplier),
|
|
216
221
|
|
|
217
222
|
// Paragraph Styles
|
|
218
223
|
debugStringConvertibleItem("lineHeight", lineHeight),
|
|
@@ -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,
|
|
@@ -909,6 +909,7 @@ constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 25;
|
|
|
909
909
|
constexpr static MapBuffer::Key TA_KEY_ROLE = 26;
|
|
910
910
|
constexpr static MapBuffer::Key TA_KEY_TEXT_TRANSFORM = 27;
|
|
911
911
|
constexpr static MapBuffer::Key TA_KEY_ALIGNMENT_VERTICAL = 28;
|
|
912
|
+
constexpr static MapBuffer::Key TA_KEY_MAX_FONT_SIZE_MULTIPLIER = 29;
|
|
912
913
|
|
|
913
914
|
// constants for ParagraphAttributes serialization
|
|
914
915
|
constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0;
|
|
@@ -1003,6 +1004,10 @@ inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) {
|
|
|
1003
1004
|
builder.putBool(
|
|
1004
1005
|
TA_KEY_ALLOW_FONT_SCALING, *textAttributes.allowFontScaling);
|
|
1005
1006
|
}
|
|
1007
|
+
if (!std::isnan(textAttributes.maxFontSizeMultiplier)) {
|
|
1008
|
+
builder.putDouble(
|
|
1009
|
+
TA_KEY_MAX_FONT_SIZE_MULTIPLIER, textAttributes.maxFontSizeMultiplier);
|
|
1010
|
+
}
|
|
1006
1011
|
if (!std::isnan(textAttributes.letterSpacing)) {
|
|
1007
1012
|
builder.putDouble(TA_KEY_LETTER_SPACING, textAttributes.letterSpacing);
|
|
1008
1013
|
}
|
|
@@ -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(
|
|
@@ -52,8 +52,29 @@ BOOL RCTIsAttributedStringEffectivelySame(
|
|
|
52
52
|
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
|
53
53
|
const facebook::react::TextAttributes &baseTextAttributes);
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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);
|
|
@@ -135,6 +96,7 @@ inline static CGFloat RCTBaseSizeForDynamicTypeRamp(const DynamicTypeRamp &dynam
|
|
|
135
96
|
inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
|
|
136
97
|
{
|
|
137
98
|
if (textAttributes.allowFontScaling.value_or(true)) {
|
|
99
|
+
CGFloat fontSizeMultiplier = !isnan(textAttributes.fontSizeMultiplier) ? textAttributes.fontSizeMultiplier : 1.0;
|
|
138
100
|
if (textAttributes.dynamicTypeRamp.has_value()) {
|
|
139
101
|
DynamicTypeRamp dynamicTypeRamp = textAttributes.dynamicTypeRamp.value();
|
|
140
102
|
UIFontMetrics *fontMetrics =
|
|
@@ -142,10 +104,11 @@ inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const Tex
|
|
|
142
104
|
// Using a specific font size reduces rounding errors from -scaledValueForValue:
|
|
143
105
|
CGFloat requestedSize =
|
|
144
106
|
isnan(textAttributes.fontSize) ? RCTBaseSizeForDynamicTypeRamp(dynamicTypeRamp) : textAttributes.fontSize;
|
|
145
|
-
|
|
146
|
-
} else {
|
|
147
|
-
return textAttributes.fontSizeMultiplier;
|
|
107
|
+
fontSizeMultiplier = [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
|
|
148
108
|
}
|
|
109
|
+
CGFloat maxFontSizeMultiplier =
|
|
110
|
+
!isnan(textAttributes.maxFontSizeMultiplier) ? textAttributes.maxFontSizeMultiplier : 0.0;
|
|
111
|
+
return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
|
|
149
112
|
} else {
|
|
150
113
|
return 1.0;
|
|
151
114
|
}
|
|
@@ -403,10 +366,8 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
|
|
|
403
366
|
{
|
|
404
367
|
auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
|
|
405
368
|
|
|
406
|
-
#if !TARGET_OS_MACCATALYST
|
|
407
369
|
if (fragment.parentShadowView.componentHandle) {
|
|
408
|
-
|
|
409
|
-
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
|
|
370
|
+
auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
|
|
410
371
|
|
|
411
372
|
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
|
|
412
373
|
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
|
|
@@ -414,7 +375,6 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
|
|
|
414
375
|
[nsAttributedStringFragment addAttributes:additionalTextAttributes
|
|
415
376
|
range:NSMakeRange(0, nsAttributedStringFragment.length)];
|
|
416
377
|
}
|
|
417
|
-
#endif
|
|
418
378
|
|
|
419
379
|
return nsAttributedStringFragment;
|
|
420
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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;
|
package/cli.js
CHANGED
|
@@ -23,6 +23,15 @@ const deprecated = () => {
|
|
|
23
23
|
);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
function findCommunityCli(startDir = process.cwd()) {
|
|
27
|
+
// With isolated node_modules (eg pnpm), we won't be able to find
|
|
28
|
+
// `@react-native-community/cli` starting from the `react-native` directory.
|
|
29
|
+
// Instead, we should use the project root, which we assume to be the cwd.
|
|
30
|
+
const options = {paths: [startDir]};
|
|
31
|
+
const rncli = require.resolve('@react-native-community/cli', options);
|
|
32
|
+
return require(rncli);
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
function isMissingCliDependency(error) {
|
|
27
36
|
return (
|
|
28
37
|
error.code === 'MODULE_NOT_FOUND' &&
|
|
@@ -217,7 +226,7 @@ async function main() {
|
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
try {
|
|
220
|
-
return
|
|
229
|
+
return findCommunityCli().run(name);
|
|
221
230
|
} catch (e) {
|
|
222
231
|
if (isMissingCliDependency(e)) {
|
|
223
232
|
warnWithExplicitDependency();
|
|
@@ -231,7 +240,7 @@ if (require.main === module) {
|
|
|
231
240
|
main();
|
|
232
241
|
} else {
|
|
233
242
|
try {
|
|
234
|
-
cli =
|
|
243
|
+
cli = findCommunityCli();
|
|
235
244
|
} catch (e) {
|
|
236
245
|
// We silence @react-native-community/cli missing as it is no
|
|
237
246
|
// longer a dependency
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native",
|
|
3
|
-
"version": "0.76.
|
|
3
|
+
"version": "0.76.8",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -109,13 +109,13 @@
|
|
|
109
109
|
},
|
|
110
110
|
"dependencies": {
|
|
111
111
|
"@jest/create-cache-key-function": "^29.6.3",
|
|
112
|
-
"@react-native/assets-registry": "0.76.
|
|
113
|
-
"@react-native/codegen": "0.76.
|
|
114
|
-
"@react-native/community-cli-plugin": "0.76.
|
|
115
|
-
"@react-native/gradle-plugin": "0.76.
|
|
116
|
-
"@react-native/js-polyfills": "0.76.
|
|
117
|
-
"@react-native/normalize-colors": "0.76.
|
|
118
|
-
"@react-native/virtualized-lists": "0.76.
|
|
112
|
+
"@react-native/assets-registry": "0.76.8",
|
|
113
|
+
"@react-native/codegen": "0.76.8",
|
|
114
|
+
"@react-native/community-cli-plugin": "0.76.8",
|
|
115
|
+
"@react-native/gradle-plugin": "0.76.8",
|
|
116
|
+
"@react-native/js-polyfills": "0.76.8",
|
|
117
|
+
"@react-native/normalize-colors": "0.76.8",
|
|
118
|
+
"@react-native/virtualized-lists": "0.76.8",
|
|
119
119
|
"abort-controller": "^3.0.0",
|
|
120
120
|
"anser": "^1.4.9",
|
|
121
121
|
"ansi-regex": "^5.0.0",
|
package/react-native.config.js
CHANGED
|
@@ -20,9 +20,24 @@
|
|
|
20
20
|
|
|
21
21
|
const verbose = process.env.DEBUG && process.env.DEBUG.includes('react-native');
|
|
22
22
|
|
|
23
|
+
function findCommunityPlatformPackage(spec, startDir = process.cwd()) {
|
|
24
|
+
// In monorepos, we cannot make any assumptions on where
|
|
25
|
+
// `@react-native-community/*` gets installed. The safest way to find it
|
|
26
|
+
// (barring adding an optional peer dependency) is to start from the project
|
|
27
|
+
// root.
|
|
28
|
+
//
|
|
29
|
+
// Note that we're assuming that the current working directory is the project
|
|
30
|
+
// root. This is also what `@react-native-community/cli` assumes (see
|
|
31
|
+
// https://github.com/react-native-community/cli/blob/14.x/packages/cli-tools/src/findProjectRoot.ts).
|
|
32
|
+
const main = require.resolve(spec, {paths: [startDir]});
|
|
33
|
+
return require(main);
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
let android;
|
|
24
37
|
try {
|
|
25
|
-
android =
|
|
38
|
+
android = findCommunityPlatformPackage(
|
|
39
|
+
'@react-native-community/cli-platform-android',
|
|
40
|
+
);
|
|
26
41
|
} catch {
|
|
27
42
|
if (verbose) {
|
|
28
43
|
console.warn(
|
|
@@ -33,7 +48,9 @@ try {
|
|
|
33
48
|
|
|
34
49
|
let ios;
|
|
35
50
|
try {
|
|
36
|
-
ios =
|
|
51
|
+
ios = findCommunityPlatformPackage(
|
|
52
|
+
'@react-native-community/cli-platform-ios',
|
|
53
|
+
);
|
|
37
54
|
} catch {
|
|
38
55
|
if (verbose) {
|
|
39
56
|
console.warn(
|
|
@@ -44,27 +61,11 @@ try {
|
|
|
44
61
|
|
|
45
62
|
const commands = [];
|
|
46
63
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
}
|
|
64
|
+
const {
|
|
65
|
+
bundleCommand,
|
|
66
|
+
startCommand,
|
|
67
|
+
} = require('@react-native/community-cli-plugin');
|
|
68
|
+
commands.push(bundleCommand, startCommand);
|
|
68
69
|
|
|
69
70
|
const codegenCommand = {
|
|
70
71
|
name: 'codegen',
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|