diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index ee33a8467aab94..144084327fb9d0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<99da5cf948e469e385bd70b4c59cd764>> + * @generated SignedSource<> */ /** @@ -101,16 +101,16 @@ public object ReactNativeFeatureFlags { public fun enableFabricRenderer(): Boolean = accessor.enableFabricRenderer() /** - * Synchronise the view command dispatching with mounting of new transaction + * This feature flag enables a fix for reparenting fix in differentiator */ @JvmStatic - public fun enableFixForViewCommandRace(): Boolean = accessor.enableFixForViewCommandRace() + public fun enableFixForParentTagDuringReparenting(): Boolean = accessor.enableFixForParentTagDuringReparenting() /** - * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. + * Enables font scale changes updating layout for measurable nodes. */ @JvmStatic - public fun enableGranularShadowTreeStateReconciliation(): Boolean = accessor.enableGranularShadowTreeStateReconciliation() + public fun enableFontScaleChangesUpdatingLayout(): Boolean = accessor.enableFontScaleChangesUpdatingLayout() /** * iOS Views will clip to their padding box vs border box diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index f16e6b88855156..4fd8c37f9a2e83 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5e1d8c0e728715d4110b6d1d156357c5>> + * @generated SignedSource<> */ /** @@ -32,8 +32,8 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null - private var enableFixForViewCommandRaceCache: Boolean? = null - private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null + private var enableFixForParentTagDuringReparentingCache: Boolean? = null + private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null @@ -175,20 +175,20 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun enableFixForViewCommandRace(): Boolean { - var cached = enableFixForViewCommandRaceCache + override fun enableFixForParentTagDuringReparenting(): Boolean { + var cached = enableFixForParentTagDuringReparentingCache if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableFixForViewCommandRace() - enableFixForViewCommandRaceCache = cached + cached = ReactNativeFeatureFlagsCxxInterop.enableFixForParentTagDuringReparenting() + enableFixForParentTagDuringReparentingCache = cached } return cached } - override fun enableGranularShadowTreeStateReconciliation(): Boolean { - var cached = enableGranularShadowTreeStateReconciliationCache + override fun enableFontScaleChangesUpdatingLayout(): Boolean { + var cached = enableFontScaleChangesUpdatingLayoutCache if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableGranularShadowTreeStateReconciliation() - enableGranularShadowTreeStateReconciliationCache = cached + cached = ReactNativeFeatureFlagsCxxInterop.enableFontScaleChangesUpdatingLayout() + enableFontScaleChangesUpdatingLayoutCache = cached } return cached } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index cd57aa387902ea..e0f765432bbcbc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -52,9 +52,9 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableFabricRenderer(): Boolean - @DoNotStrip @JvmStatic public external fun enableFixForViewCommandRace(): Boolean + @DoNotStrip @JvmStatic public external fun enableFixForParentTagDuringReparenting(): Boolean - @DoNotStrip @JvmStatic public external fun enableGranularShadowTreeStateReconciliation(): Boolean + @DoNotStrip @JvmStatic public external fun enableFontScaleChangesUpdatingLayout(): Boolean @DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 63660d779fac0a..bba7f129e411c9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<11d93a900862ed8ce98f90f9af2de47b>> + * @generated SignedSource<> */ /** @@ -47,9 +47,9 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableFabricRenderer(): Boolean = false - override fun enableFixForViewCommandRace(): Boolean = false + override fun enableFixForParentTagDuringReparenting(): Boolean = false - override fun enableGranularShadowTreeStateReconciliation(): Boolean = false + override fun enableFontScaleChangesUpdatingLayout(): Boolean = false override fun enableIOSViewClipToPaddingBox(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 7c22c3bdd3d0dd..54bb1ff056e9c3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0614fa80cbc66806fa45aef70f34e2d7>> + * @generated SignedSource<> */ /** @@ -36,8 +36,8 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null - private var enableFixForViewCommandRaceCache: Boolean? = null - private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null + private var enableFixForParentTagDuringReparentingCache: Boolean? = null + private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null @@ -191,22 +191,22 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableFixForViewCommandRace(): Boolean { - var cached = enableFixForViewCommandRaceCache + override fun enableFixForParentTagDuringReparenting(): Boolean { + var cached = enableFixForParentTagDuringReparentingCache if (cached == null) { - cached = currentProvider.enableFixForViewCommandRace() - accessedFeatureFlags.add("enableFixForViewCommandRace") - enableFixForViewCommandRaceCache = cached + cached = currentProvider.enableFixForParentTagDuringReparenting() + accessedFeatureFlags.add("enableFixForParentTagDuringReparenting") + enableFixForParentTagDuringReparentingCache = cached } return cached } - override fun enableGranularShadowTreeStateReconciliation(): Boolean { - var cached = enableGranularShadowTreeStateReconciliationCache + override fun enableFontScaleChangesUpdatingLayout(): Boolean { + var cached = enableFontScaleChangesUpdatingLayoutCache if (cached == null) { - cached = currentProvider.enableGranularShadowTreeStateReconciliation() - accessedFeatureFlags.add("enableGranularShadowTreeStateReconciliation") - enableGranularShadowTreeStateReconciliationCache = cached + cached = currentProvider.enableFontScaleChangesUpdatingLayout() + accessedFeatureFlags.add("enableFontScaleChangesUpdatingLayout") + enableFontScaleChangesUpdatingLayoutCache = cached } return cached } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 31c4f90f10b730..ecf28a4af5b199 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5f4ff90382b2d69df401535cb33e64c5>> + * @generated SignedSource<<76da11369c2f7b8955a154a63af374a3>> */ /** @@ -47,9 +47,9 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableFabricRenderer(): Boolean - @DoNotStrip public fun enableFixForViewCommandRace(): Boolean + @DoNotStrip public fun enableFixForParentTagDuringReparenting(): Boolean - @DoNotStrip public fun enableGranularShadowTreeStateReconciliation(): Boolean + @DoNotStrip public fun enableFontScaleChangesUpdatingLayout(): Boolean @DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 1ede11bdd9ed6a..fdb9bc8b3a7a12 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<28069af1f34c79e9907c85697a291c0e>> + * @generated SignedSource<> */ /** @@ -111,15 +111,15 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool enableFixForViewCommandRace() override { + bool enableFixForParentTagDuringReparenting() override { static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableFixForViewCommandRace"); + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableFixForParentTagDuringReparenting"); return method(javaProvider_); } - bool enableGranularShadowTreeStateReconciliation() override { + bool enableFontScaleChangesUpdatingLayout() override { static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableGranularShadowTreeStateReconciliation"); + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableFontScaleChangesUpdatingLayout"); return method(javaProvider_); } @@ -379,14 +379,14 @@ bool JReactNativeFeatureFlagsCxxInterop::enableFabricRenderer( return ReactNativeFeatureFlags::enableFabricRenderer(); } -bool JReactNativeFeatureFlagsCxxInterop::enableFixForViewCommandRace( +bool JReactNativeFeatureFlagsCxxInterop::enableFixForParentTagDuringReparenting( facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableFixForViewCommandRace(); + return ReactNativeFeatureFlags::enableFixForParentTagDuringReparenting(); } -bool JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconciliation( +bool JReactNativeFeatureFlagsCxxInterop::enableFontScaleChangesUpdatingLayout( facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); + return ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout(); } bool JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox( @@ -617,11 +617,11 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { "enableFabricRenderer", JReactNativeFeatureFlagsCxxInterop::enableFabricRenderer), makeNativeMethod( - "enableFixForViewCommandRace", - JReactNativeFeatureFlagsCxxInterop::enableFixForViewCommandRace), + "enableFixForParentTagDuringReparenting", + JReactNativeFeatureFlagsCxxInterop::enableFixForParentTagDuringReparenting), makeNativeMethod( - "enableGranularShadowTreeStateReconciliation", - JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconciliation), + "enableFontScaleChangesUpdatingLayout", + JReactNativeFeatureFlagsCxxInterop::enableFontScaleChangesUpdatingLayout), makeNativeMethod( "enableIOSViewClipToPaddingBox", JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 665dd08e57343d..08a7e66c0df57d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<763d595784bdf31a852ebf2a492a1393>> + * @generated SignedSource<> */ /** @@ -66,10 +66,10 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableFabricRenderer( facebook::jni::alias_ref); - static bool enableFixForViewCommandRace( + static bool enableFixForParentTagDuringReparenting( facebook::jni::alias_ref); - static bool enableGranularShadowTreeStateReconciliation( + static bool enableFontScaleChangesUpdatingLayout( facebook::jni::alias_ref); static bool enableIOSViewClipToPaddingBox( diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 811d4fef5a177c..a216d18723ba68 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<511c1667fab247b77d771a7a26e87b46>> + * @generated SignedSource<<5ee10cdf8f5e3695ce4f73373291935e>> */ /** @@ -74,12 +74,12 @@ bool ReactNativeFeatureFlags::enableFabricRenderer() { return getAccessor().enableFabricRenderer(); } -bool ReactNativeFeatureFlags::enableFixForViewCommandRace() { - return getAccessor().enableFixForViewCommandRace(); +bool ReactNativeFeatureFlags::enableFixForParentTagDuringReparenting() { + return getAccessor().enableFixForParentTagDuringReparenting(); } -bool ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation() { - return getAccessor().enableGranularShadowTreeStateReconciliation(); +bool ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout() { + return getAccessor().enableFontScaleChangesUpdatingLayout(); } bool ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox() { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index f082b18249f424..6864d37a1af2e1 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<19cfd8b41dd429c83a5e0f0df514d1d1>> + * @generated SignedSource<> */ /** @@ -100,14 +100,14 @@ class ReactNativeFeatureFlags { RN_EXPORT static bool enableFabricRenderer(); /** - * Synchronise the view command dispatching with mounting of new transaction + * This feature flag enables a fix for reparenting fix in differentiator */ - RN_EXPORT static bool enableFixForViewCommandRace(); + RN_EXPORT static bool enableFixForParentTagDuringReparenting(); /** - * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. + * Enables font scale changes updating layout for measurable nodes. */ - RN_EXPORT static bool enableGranularShadowTreeStateReconciliation(); + RN_EXPORT static bool enableFontScaleChangesUpdatingLayout(); /** * iOS Views will clip to their padding box vs border box diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index c8ef7996747ccf..52d4f68d6c958b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<4c18c271811129f1e1411fc2666aeb38>> */ /** @@ -245,8 +245,8 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableFixForViewCommandRace() { - auto flagValue = enableFixForViewCommandRace_.load(); +bool ReactNativeFeatureFlagsAccessor::enableFixForParentTagDuringReparenting() { + auto flagValue = enableFixForParentTagDuringReparenting_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -254,17 +254,17 @@ bool ReactNativeFeatureFlagsAccessor::enableFixForViewCommandRace() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableFixForViewCommandRace"); + markFlagAsAccessed(12, "enableFixForParentTagDuringReparenting"); - flagValue = currentProvider_->enableFixForViewCommandRace(); - enableFixForViewCommandRace_ = flagValue; + flagValue = currentProvider_->enableFixForParentTagDuringReparenting(); + enableFixForParentTagDuringReparenting_ = flagValue; } return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliation() { - auto flagValue = enableGranularShadowTreeStateReconciliation_.load(); +bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { + auto flagValue = enableFontScaleChangesUpdatingLayout_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -272,10 +272,10 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableGranularShadowTreeStateReconciliation"); + markFlagAsAccessed(13, "enableFontScaleChangesUpdatingLayout"); - flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation(); - enableGranularShadowTreeStateReconciliation_ = flagValue; + flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); + enableFontScaleChangesUpdatingLayout_ = flagValue; } return flagValue.value(); @@ -308,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(15, "enableJSRuntimeGCOnMemoryPressureOnIOS"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -353,8 +353,8 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { - auto flagValue = enableLongTaskAPI_.load(); +bool ReactNativeFeatureFlagsAccessor::enableMainQueueModulesOnIOS() { + auto flagValue = enableMainQueueModulesOnIOS_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -362,10 +362,28 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableLongTaskAPI"); + markFlagAsAccessed(18, "enableMainQueueModulesOnIOS"); - flagValue = currentProvider_->enableLongTaskAPI(); - enableLongTaskAPI_ = flagValue; + flagValue = currentProvider_->enableMainQueueModulesOnIOS(); + enableMainQueueModulesOnIOS_ = flagValue; + } + + return flagValue.value(); +} + +bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { + auto flagValue = enableNativeCSSParsing_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(19, "enableNativeCSSParsing"); + + flagValue = currentProvider_->enableNativeCSSParsing(); + enableNativeCSSParsing_ = flagValue; } return flagValue.value(); @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableSynchronousStateUpdates"); + markFlagAsAccessed(22, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableUIConsistency"); + markFlagAsAccessed(23, "enableViewCulling"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableViewRecycling"); + markFlagAsAccessed(24, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "excludeYogaFromRawProps"); + markFlagAsAccessed(25, "enableViewRecyclingForText"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorEmittingUpdatesWithWrongP // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "fixDifferentiatorEmittingUpdatesWithWrongParentTag"); + markFlagAsAccessed(26, "enableViewRecyclingForView"); flagValue = currentProvider_->fixDifferentiatorEmittingUpdatesWithWrongParentTag(); fixDifferentiatorEmittingUpdatesWithWrongParentTag_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(27, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "fuseboxEnabledRelease"); + markFlagAsAccessed(28, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -587,8 +605,8 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueAndroid() { - auto flagValue = initEagerTurboModulesOnNativeModulesQueueAndroid_.load(); +bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { + auto flagValue = fuseboxNetworkInspectionEnabled_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -596,17 +614,17 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(29, "fuseboxNetworkInspectionEnabled"); - flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); - initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; + flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); + fuseboxNetworkInspectionEnabled_ = flagValue; } return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { - auto flagValue = lazyAnimationCallbacks_.load(); +bool ReactNativeFeatureFlagsAccessor::removeTurboModuleManagerDelegateMutex() { + auto flagValue = removeTurboModuleManagerDelegateMutex_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -614,17 +632,17 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "lazyAnimationCallbacks"); + markFlagAsAccessed(30, "removeTurboModuleManagerDelegateMutex"); - flagValue = currentProvider_->lazyAnimationCallbacks(); - lazyAnimationCallbacks_ = flagValue; + flagValue = currentProvider_->removeTurboModuleManagerDelegateMutex(); + removeTurboModuleManagerDelegateMutex_ = flagValue; } return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { - auto flagValue = loadVectorDrawablesOnImages_.load(); +bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid() { + auto flagValue = traceTurboModulePromiseRejectionsOnAndroid_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -632,17 +650,17 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(31, "traceTurboModulePromiseRejectionsOnAndroid"); - flagValue = currentProvider_->loadVectorDrawablesOnImages(); - loadVectorDrawablesOnImages_ = flagValue; + flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); + traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; } return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid() { - auto flagValue = traceTurboModulePromiseRejectionsOnAndroid_.load(); +bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit() { + auto flagValue = updateRuntimeShadowNodeReferencesOnCommit_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -650,10 +668,10 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(32, "updateRuntimeShadowNodeReferencesOnCommit"); - flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); - traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; + flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); + updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; } return flagValue.value(); @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(33, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -677,6 +695,24 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() { + auto flagValue = useEditTextStockAndroidFocusBehavior_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(34, "useEditTextStockAndroidFocusBehavior"); + + flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior(); + useEditTextStockAndroidFocusBehavior_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { auto flagValue = useFabricInterop_.load(); @@ -686,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "useFabricInterop"); + markFlagAsAccessed(35, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -722,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(36, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -758,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(37, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -776,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useRawPropsJsiValue"); + markFlagAsAccessed(38, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -812,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "useShadowNodeStateOnClone"); + markFlagAsAccessed(39, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -830,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "useTurboModuleInterop"); + markFlagAsAccessed(40, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -848,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "useTurboModules"); + markFlagAsAccessed(41, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 1d453a762d518a..41045733ad9724 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2a6cbfd5de86a5bb840f1fc5f47c51a6>> + * @generated SignedSource<<4338d98b457f8f70a9f8bbe8ab245ce8>> */ /** @@ -44,8 +44,8 @@ class ReactNativeFeatureFlagsAccessor { bool enableEventEmitterRetentionDuringGesturesOnAndroid(); bool enableFabricLogs(); bool enableFabricRenderer(); - bool enableFixForViewCommandRace(); - bool enableGranularShadowTreeStateReconciliation(); + bool enableFixForParentTagDuringReparenting(); + bool enableFontScaleChangesUpdatingLayout(); bool enableIOSViewClipToPaddingBox(); bool enableImagePrefetchingAndroid(); bool enableLayoutAnimationsOnAndroid(); @@ -89,7 +89,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 46> accessedFeatureFlags_; + std::array, 42> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; @@ -103,8 +103,8 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableEventEmitterRetentionDuringGesturesOnAndroid_; std::atomic> enableFabricLogs_; std::atomic> enableFabricRenderer_; - std::atomic> enableFixForViewCommandRace_; - std::atomic> enableGranularShadowTreeStateReconciliation_; + std::atomic> enableFixForParentTagDuringReparenting_; + std::atomic> enableFontScaleChangesUpdatingLayout_; std::atomic> enableIOSViewClipToPaddingBox_; std::atomic> enableImagePrefetchingAndroid_; std::atomic> enableLayoutAnimationsOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e2d9217689afd5..0df3986f058758 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<830cdd4b394262ee65abc63a54833674>> + * @generated SignedSource<<2eb8786fbcf716f02200770bba667f48>> */ /** @@ -75,11 +75,11 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool enableFixForViewCommandRace() override { + bool enableFixForParentTagDuringReparenting() override { return false; } - bool enableGranularShadowTreeStateReconciliation() override { + bool enableFontScaleChangesUpdatingLayout() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 9e436f6ecd0b18..a72a1cd2a4d1e9 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<627094b444d8b7a513d7190272848a9e>> + * @generated SignedSource<<74978e3a2abd1ec238127003e33b51bd>> */ /** @@ -153,22 +153,22 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableFabricRenderer(); } - bool enableFixForViewCommandRace() override { - auto value = values_["enableFixForViewCommandRace"]; + bool enableFixForParentTagDuringReparenting() override { + auto value = values_["enableFixForParentTagDuringReparenting"]; if (!value.isNull()) { return value.getBool(); } - return ReactNativeFeatureFlagsDefaults::enableFixForViewCommandRace(); + return ReactNativeFeatureFlagsDefaults::enableFixForParentTagDuringReparenting(); } - bool enableGranularShadowTreeStateReconciliation() override { - auto value = values_["enableGranularShadowTreeStateReconciliation"]; + bool enableFontScaleChangesUpdatingLayout() override { + auto value = values_["enableFontScaleChangesUpdatingLayout"]; if (!value.isNull()) { return value.getBool(); } - return ReactNativeFeatureFlagsDefaults::enableGranularShadowTreeStateReconciliation(); + return ReactNativeFeatureFlagsDefaults::enableFontScaleChangesUpdatingLayout(); } bool enableIOSViewClipToPaddingBox() override { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index e7f1ceaf8e6e67..38f0a3aea6d010 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<190bad7388fb33884eebca0fed4ad61f>> + * @generated SignedSource<<49c3003d551dc87d22811c92ad16a76c>> */ /** @@ -37,8 +37,8 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableEventEmitterRetentionDuringGesturesOnAndroid() = 0; virtual bool enableFabricLogs() = 0; virtual bool enableFabricRenderer() = 0; - virtual bool enableFixForViewCommandRace() = 0; - virtual bool enableGranularShadowTreeStateReconciliation() = 0; + virtual bool enableFixForParentTagDuringReparenting() = 0; + virtual bool enableFontScaleChangesUpdatingLayout() = 0; virtual bool enableIOSViewClipToPaddingBox() = 0; virtual bool enableImagePrefetchingAndroid() = 0; virtual bool enableLayoutAnimationsOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index f2ea23f46d83f3..5fe466caa0a115 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2911cd67b3a434c7d3610740befac4f9>> + * @generated SignedSource<<48fbc60de3ca7d6e9c106f451fd0683c>> */ /** @@ -104,14 +104,14 @@ bool NativeReactNativeFeatureFlags::enableFabricRenderer( return ReactNativeFeatureFlags::enableFabricRenderer(); } -bool NativeReactNativeFeatureFlags::enableFixForViewCommandRace( +bool NativeReactNativeFeatureFlags::enableFixForParentTagDuringReparenting( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableFixForViewCommandRace(); + return ReactNativeFeatureFlags::enableFixForParentTagDuringReparenting(); } -bool NativeReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation( +bool NativeReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); + return ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout(); } bool NativeReactNativeFeatureFlags::enableIOSViewClipToPaddingBox( diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index e6260245a1e94e..1c0f4ef53b2b30 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9df551425337f50b9bb8837684bbbba0>> + * @generated SignedSource<<5bd90040747e90e28f36243cf6c473d0>> */ /** @@ -61,9 +61,9 @@ class NativeReactNativeFeatureFlags bool enableFabricRenderer(jsi::Runtime& runtime); - bool enableFixForViewCommandRace(jsi::Runtime& runtime); + bool enableFixForParentTagDuringReparenting(jsi::Runtime& runtime); - bool enableGranularShadowTreeStateReconciliation(jsi::Runtime& runtime); + bool enableFontScaleChangesUpdatingLayout(jsi::Runtime& runtime); bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp index f38e0fa7109a34..fc6933e6e27942 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -961,20 +961,31 @@ static void calculateShadowViewMutationsFlattener( // Flatten parent, unflatten child else { // Unflatten old list into new tree + // TODO(T217775046): Find a test case for this branch of view + // flattening + culling. + auto parentTagForUpdateWhenFlattened = + ReactNativeFeatureFlags:: + enableFixForParentTagDuringReparenting() + ? parentTagForUpdate + : oldTreeNodePair.shadowView.tag; calculateShadowViewMutationsFlattener( scope, - ReparentMode::Unflatten, + /* reparentMode */ ReparentMode::Unflatten, mutationContainer, + /* parentTag */ (reparentMode == ReparentMode::Flatten ? parentTag : newTreeNodePair.shadowView.tag), - unvisitedRecursiveChildPairs, - newTreeNodePair, + /* unvisitedOtherNodes */ unvisitedRecursiveChildPairs, + /* node */ newTreeNodePair, + /* parentTagForUpdate */ (reparentMode == ReparentMode::Flatten - ? oldTreeNodePair.shadowView.tag + ? parentTagForUpdateWhenFlattened : parentTag), - subVisitedNewMap, - subVisitedOldMap); + /* parentSubVisitedOtherNewNodes */ subVisitedNewMap, + /* parentSubVisitedOtherOldNodes */ subVisitedOldMap, + /* oldCullingContext */ adjustedOldCullingContext, + /* newCullingContext */ adjustedNewCullingContext); // If old nodes were not visited, we know that we can delete them // now. They will be removed from the hierarchy by the outermost diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/OrderIndexTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/OrderIndexTest.cpp index 170b275f655444..b724f7316f0dfd 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/OrderIndexTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/OrderIndexTest.cpp @@ -5,11 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -#include #include #include +#include +#include #include #include #include @@ -23,9 +24,24 @@ namespace facebook::react { -class OrderIndexTest : public ::testing::Test { +class OrderIndexTestFeatureFlags : public ReactNativeFeatureFlagsDefaults { + public: + explicit OrderIndexTestFeatureFlags( + bool enableFixForParentTagDuringReparenting) + : enableFixForParentTagDuringReparenting_( + enableFixForParentTagDuringReparenting) {} + + bool enableFixForParentTagDuringReparenting() override { + return enableFixForParentTagDuringReparenting_; + } + + private: + bool enableFixForParentTagDuringReparenting_; +}; + +class OrderIndexTest : public testing::TestWithParam { protected: - ComponentBuilder builder_; + std::unique_ptr builder_; std::shared_ptr rootShadowNode_; std::shared_ptr nodeA_; std::shared_ptr nodeB_; @@ -35,7 +51,13 @@ class OrderIndexTest : public ::testing::Test { std::shared_ptr currentRootShadowNode_; StubViewTree currentStubViewTree_; - OrderIndexTest() : builder_(simpleComponentBuilder()) { + void SetUp() override { + ReactNativeFeatureFlags::dangerouslyReset(); + ReactNativeFeatureFlags::override( + std::make_unique(GetParam())); + + builder_ = std::make_unique(simpleComponentBuilder()); + auto element = Element() .reference(rootShadowNode_) .tag(1) @@ -46,7 +68,7 @@ class OrderIndexTest : public ::testing::Test { Element().tag(5).reference(nodeD_), }); - builder_.build(element); + builder_->build(element); mutateViewShadowNodeProps_(nodeA_, [](ViewProps& props) { auto& yogaStyle = props.yogaStyle; @@ -75,6 +97,10 @@ class OrderIndexTest : public ::testing::Test { buildStubViewTreeWithoutUsingDifferentiator(*currentRootShadowNode_); } + void TearDown() override { + ReactNativeFeatureFlags::dangerouslyReset(); + } + void mutateViewShadowNodeProps_( const std::shared_ptr& node, std::function callback) { @@ -101,7 +127,7 @@ class OrderIndexTest : public ::testing::Test { } }; -TEST_F(OrderIndexTest, defaultOrderIsDocumentOrder) { +TEST_P(OrderIndexTest, defaultOrderIsDocumentOrder) { testViewTree_([this](const StubViewTree& viewTree) { EXPECT_EQ(viewTree.size(), 5); EXPECT_EQ(viewTree.getRootStubView().children.size(), 4); @@ -113,7 +139,7 @@ TEST_F(OrderIndexTest, defaultOrderIsDocumentOrder) { }); } -TEST_F(OrderIndexTest, basicZIndex) { +TEST_P(OrderIndexTest, basicZIndex) { mutateViewShadowNodeProps_( nodeA_, [](ViewProps& props) { props.zIndex = 5; }); mutateViewShadowNodeProps_( @@ -134,7 +160,7 @@ TEST_F(OrderIndexTest, basicZIndex) { }); } -TEST_F(OrderIndexTest, negativeZIndex) { +TEST_P(OrderIndexTest, negativeZIndex) { mutateViewShadowNodeProps_( nodeA_, [](ViewProps& props) { props.zIndex = 5; }); mutateViewShadowNodeProps_( @@ -155,7 +181,7 @@ TEST_F(OrderIndexTest, negativeZIndex) { }); } -TEST_F(OrderIndexTest, zeroZIndex) { +TEST_P(OrderIndexTest, zeroZIndex) { mutateViewShadowNodeProps_( nodeC_, [](ViewProps& props) { props.zIndex = 0; }); mutateViewShadowNodeProps_( @@ -172,7 +198,7 @@ TEST_F(OrderIndexTest, zeroZIndex) { }); } -TEST_F(OrderIndexTest, staticBehindNonStatic) { +TEST_P(OrderIndexTest, staticBehindNonStatic) { mutateViewShadowNodeProps_(nodeB_, [](ViewProps& props) { auto& yogaStyle = props.yogaStyle; yogaStyle.setPositionType(yoga::PositionType::Static); @@ -195,7 +221,7 @@ TEST_F(OrderIndexTest, staticBehindNonStatic) { }); } -TEST_F(OrderIndexTest, zIndexStaticBehindNonStatic) { +TEST_P(OrderIndexTest, zIndexStaticBehindNonStatic) { mutateViewShadowNodeProps_( nodeB_, [](ViewProps& props) { props.zIndex = 5; }); mutateViewShadowNodeProps_( @@ -217,7 +243,7 @@ TEST_F(OrderIndexTest, zIndexStaticBehindNonStatic) { }); } -TEST_F(OrderIndexTest, staticDoesNotGetZIndex) { +TEST_P(OrderIndexTest, staticDoesNotGetZIndex) { mutateViewShadowNodeProps_(nodeB_, [](ViewProps& props) { auto& yogaStyle = props.yogaStyle; yogaStyle.setPositionType(yoga::PositionType::Static); @@ -241,4 +267,10 @@ TEST_F(OrderIndexTest, staticDoesNotGetZIndex) { EXPECT_EQ(viewTree.getRootStubView().children.at(3)->tag, nodeC_->getTag()); }); } + +INSTANTIATE_TEST_SUITE_P( + enableFixForParentTagDuringReparenting, + OrderIndexTest, + testing::Values(false, true)); + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp index be86af67be5d1f..a0032620da8d41 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include #include @@ -325,8 +327,34 @@ static void testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( } // namespace facebook::react using namespace facebook::react; +class ShadowTreeLifecycleFeatureFlags : public ReactNativeFeatureFlagsDefaults { + public: + explicit ShadowTreeLifecycleFeatureFlags( + bool enableFixForParentTagDuringReparenting) + : enableFixForParentTagDuringReparenting_( + enableFixForParentTagDuringReparenting) {} + + bool enableFixForParentTagDuringReparenting() override { + return enableFixForParentTagDuringReparenting_; + } -TEST( + private: + bool enableFixForParentTagDuringReparenting_; +}; + +class ShadowTreeLifecycleTest : public testing::TestWithParam { + protected: + void SetUp() override { + ReactNativeFeatureFlags::override( + std::make_unique(GetParam())); + } + + void TearDown() override { + ReactNativeFeatureFlags::dangerouslyReset(); + } +}; + +TEST_P( ShadowTreeLifecycleTest, stableBiggerTreeFewerIterationsOptimizedMovesFlattener) { testShadowNodeTreeLifeCycle( @@ -336,7 +364,7 @@ TEST( /* stages */ 32); } -TEST( +TEST_P( ShadowTreeLifecycleTest, stableBiggerTreeFewerIterationsOptimizedMovesFlattener2) { testShadowNodeTreeLifeCycle( @@ -346,7 +374,7 @@ TEST( /* stages */ 32); } -TEST( +TEST_P( ShadowTreeLifecycleTest, stableSmallerTreeMoreIterationsOptimizedMovesFlattener) { testShadowNodeTreeLifeCycle( @@ -356,7 +384,7 @@ TEST( /* stages */ 32); } -TEST( +TEST_P( ShadowTreeLifecycleTest, unstableSmallerTreeFewerIterationsExtensiveFlatteningUnflattening) { testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( @@ -366,7 +394,7 @@ TEST( /* stages */ 32); } -TEST( +TEST_P( ShadowTreeLifecycleTest, unstableBiggerTreeFewerIterationsExtensiveFlatteningUnflattening) { testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( @@ -376,7 +404,7 @@ TEST( /* stages */ 32); } -TEST( +TEST_P( ShadowTreeLifecycleTest, unstableSmallerTreeMoreIterationsExtensiveFlatteningUnflattening) { testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( @@ -413,3 +441,8 @@ TEST( // /* stages */ 32); // } // } + +INSTANTIATE_TEST_SUITE_P( + enableFixForParentTagDuringReparenting, + ShadowTreeLifecycleTest, + testing::Values(false, true)); diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StackingContextTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StackingContextTest.cpp index dd7d74a5245816..c727b168164542 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StackingContextTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StackingContextTest.cpp @@ -5,11 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -#include #include #include +#include +#include #include #include #include @@ -24,9 +25,24 @@ namespace facebook::react { -class StackingContextTest : public ::testing::Test { +class StackingContextTestFeatureFlags : public ReactNativeFeatureFlagsDefaults { + public: + explicit StackingContextTestFeatureFlags( + bool enableFixForParentTagDuringReparenting) + : enableFixForParentTagDuringReparenting_( + enableFixForParentTagDuringReparenting) {} + + bool enableFixForParentTagDuringReparenting() override { + return enableFixForParentTagDuringReparenting_; + } + + private: + bool enableFixForParentTagDuringReparenting_; +}; + +class StackingContextTest : public ::testing::TestWithParam { protected: - ComponentBuilder builder_; + std::unique_ptr builder_; std::shared_ptr rootShadowNode_; std::shared_ptr nodeA_; std::shared_ptr nodeAA_; @@ -41,7 +57,10 @@ class StackingContextTest : public ::testing::Test { std::shared_ptr currentRootShadowNode_; StubViewTree currentStubViewTree_; - StackingContextTest() : builder_(simpleComponentBuilder()) { + void SetUp() override { + ReactNativeFeatureFlags::override( + std::make_unique(GetParam())); + // ┌────────────── (Root) ──────────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ // │ ┃ ┃ │ @@ -144,7 +163,8 @@ class StackingContextTest : public ::testing::Test { }); // clang-format on - builder_.build(element); + builder_ = std::make_unique(simpleComponentBuilder()); + builder_->build(element); currentRootShadowNode_ = rootShadowNode_; currentRootShadowNode_->layoutIfNeeded(); @@ -152,6 +172,10 @@ class StackingContextTest : public ::testing::Test { buildStubViewTreeWithoutUsingDifferentiator(*currentRootShadowNode_); } + void TearDown() override { + ReactNativeFeatureFlags::dangerouslyReset(); + } + void mutateViewShadowNodeProps_( const std::shared_ptr& node, std::function callback) { @@ -179,7 +203,7 @@ class StackingContextTest : public ::testing::Test { } }; -TEST_F(StackingContextTest, defaultPropsMakeEverythingFlattened) { +TEST_P(StackingContextTest, defaultPropsMakeEverythingFlattened) { testViewTree_([](const StubViewTree& viewTree) { // 1 view in total. EXPECT_EQ(viewTree.size(), 1); @@ -189,7 +213,7 @@ TEST_F(StackingContextTest, defaultPropsMakeEverythingFlattened) { }); } -TEST_F(StackingContextTest, mostPropsDoNotForceViewsToMaterialize) { +TEST_P(StackingContextTest, mostPropsDoNotForceViewsToMaterialize) { // ┌────────────── (Root) ──────────────┐ ┌────────── (Root) ───────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ │ // │ ┃ ┃ │ │ │ @@ -292,7 +316,7 @@ TEST_F(StackingContextTest, mostPropsDoNotForceViewsToMaterialize) { }); } -TEST_F(StackingContextTest, somePropsForceViewsToMaterialize1) { +TEST_P(StackingContextTest, somePropsForceViewsToMaterialize1) { // ┌────────────── (Root) ──────────────┐ ┌─────────── (Root) ──────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ ┏━ AA (tag: 3) ━━━━━━━━━━━┓ │ // │ ┃ ┃ │ │ ┃ #FormsView ┃ │ @@ -376,7 +400,7 @@ TEST_F(StackingContextTest, somePropsForceViewsToMaterialize1) { }); } -TEST_F(StackingContextTest, somePropsForceViewsToMaterialize2) { +TEST_P(StackingContextTest, somePropsForceViewsToMaterialize2) { // ┌────────────── (Root) ──────────────┐ ┌─────────── (Root) ──────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ ┏━ A (tag: 2) ━━━━━━━━━━━━┓ │ // │ ┃ backgroundColor: black; ┃ │ │ ┃ #FormsView ┃ │ @@ -478,7 +502,7 @@ TEST_F(StackingContextTest, somePropsForceViewsToMaterialize2) { }); } -TEST_F(StackingContextTest, nonCollapsableChildren) { +TEST_P(StackingContextTest, nonCollapsableChildren) { // ┌────────────── (Root) ──────────────┐ ┌─────────── (Root) ──────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ ┏━ BBA (tag: 7) ━━━━━━━━━━┓ │ // │ ┃ ┃ │ │ ┃ ┃ │ @@ -555,7 +579,7 @@ TEST_F(StackingContextTest, nonCollapsableChildren) { }); } -TEST_F(StackingContextTest, nonCollapsableChildrenMixed) { +TEST_P(StackingContextTest, nonCollapsableChildrenMixed) { // ┌────────────── (Root) ──────────────┐ ┌─────────── (Root) ──────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ ┏━ BA (tag: 5) ━━ ━━━━━━━━┓ │ // │ ┃ ┃ │ │ ┃ ┃ │ @@ -648,7 +672,7 @@ TEST_F(StackingContextTest, nonCollapsableChildrenMixed) { }); } -TEST_F(StackingContextTest, zIndexAndFlattenedNodes) { +TEST_P(StackingContextTest, zIndexAndFlattenedNodes) { // ┌────────────── (Root) ──────────────┐ ┌────────── (Root) ───────────┐ // │ ┏━ A (tag: 2) ━━━━━━━━━━━━━━━━━━━┓ │ │ ┏━ BD (tag: 10) ━━━━━━━━━━┓ │ // │ ┃ ┃ │ │ ┃ #FormsView ┃ │ @@ -971,4 +995,9 @@ TEST_F(StackingContextTest, zIndexAndFlattenedNodes) { }); } +INSTANTIATE_TEST_SUITE_P( + enableFixForParentTagDuringReparenting, + StackingContextTest, + testing::Values(false, true)); + } // namespace facebook::react diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 0f89c327757dd0..91935af4c13a30 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -159,26 +159,29 @@ const definitions: FeatureFlagDefinitions = { expectedReleaseValue: true, purpose: 'release', }, + ossReleaseStage: 'canary', }, - enableFixForViewCommandRace: { + enableFixForParentTagDuringReparenting: { defaultValue: false, metadata: { - dateAdded: '2024-11-14', + dateAdded: '2025-04-22', description: - 'Synchronise the view command dispatching with mounting of new transaction', + 'This feature flag enables a fix for reparenting fix in differentiator', expectedReleaseValue: true, purpose: 'experimentation', }, + ossReleaseStage: 'none', }, - enableGranularShadowTreeStateReconciliation: { + enableFontScaleChangesUpdatingLayout: { defaultValue: false, metadata: { - dateAdded: '2024-05-01', + dateAdded: '2025-04-07', description: - 'When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing.', + 'Enables font scale changes updating layout for measurable nodes.', expectedReleaseValue: true, purpose: 'experimentation', }, + ossReleaseStage: 'none', }, enableIOSViewClipToPaddingBox: { defaultValue: false, @@ -627,6 +630,7 @@ const definitions: FeatureFlagDefinitions = { expectedReleaseValue: true, purpose: 'experimentation', }, + ossReleaseStage: 'none', }, useInsertionEffectsForAnimations: { defaultValue: true, diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index bb94ccf140b231..69e4a32f1896c1 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<63601ec83ade8f3774d185ebacf4c792>> + * @generated SignedSource<<95280f033ae8492b6fdf610d0d94fff6>> * @flow strict */ @@ -63,8 +63,8 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableEventEmitterRetentionDuringGesturesOnAndroid: Getter, enableFabricLogs: Getter, enableFabricRenderer: Getter, - enableFixForViewCommandRace: Getter, - enableGranularShadowTreeStateReconciliation: Getter, + enableFixForParentTagDuringReparenting: Getter, + enableFontScaleChangesUpdatingLayout: Getter, enableIOSViewClipToPaddingBox: Getter, enableImagePrefetchingAndroid: Getter, enableLayoutAnimationsOnAndroid: Getter, @@ -237,13 +237,13 @@ export const enableFabricLogs: Getter = createNativeFlagGetter('enableF */ export const enableFabricRenderer: Getter = createNativeFlagGetter('enableFabricRenderer', false); /** - * Synchronise the view command dispatching with mounting of new transaction + * This feature flag enables a fix for reparenting fix in differentiator */ -export const enableFixForViewCommandRace: Getter = createNativeFlagGetter('enableFixForViewCommandRace', false); +export const enableFixForParentTagDuringReparenting: Getter = createNativeFlagGetter('enableFixForParentTagDuringReparenting', false); /** - * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. + * Enables font scale changes updating layout for measurable nodes. */ -export const enableGranularShadowTreeStateReconciliation: Getter = createNativeFlagGetter('enableGranularShadowTreeStateReconciliation', false); +export const enableFontScaleChangesUpdatingLayout: Getter = createNativeFlagGetter('enableFontScaleChangesUpdatingLayout', false); /** * iOS Views will clip to their padding box vs border box */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 03e8d13530798f..ef50e6a5c4fa4c 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<7526f36924ba650136380fa0fbd2ee60>> * @flow strict */ @@ -36,8 +36,8 @@ export interface Spec extends TurboModule { +enableEventEmitterRetentionDuringGesturesOnAndroid?: () => boolean; +enableFabricLogs?: () => boolean; +enableFabricRenderer?: () => boolean; - +enableFixForViewCommandRace?: () => boolean; - +enableGranularShadowTreeStateReconciliation?: () => boolean; + +enableFixForParentTagDuringReparenting?: () => boolean; + +enableFontScaleChangesUpdatingLayout?: () => boolean; +enableIOSViewClipToPaddingBox?: () => boolean; +enableImagePrefetchingAndroid?: () => boolean; +enableLayoutAnimationsOnAndroid?: () => boolean; diff --git a/packages/react-native/src/private/renderer/mounting/__tests__/Mounting-itest.js b/packages/react-native/src/private/renderer/mounting/__tests__/Mounting-itest.js new file mode 100644 index 00000000000000..924a9314edfc00 --- /dev/null +++ b/packages/react-native/src/private/renderer/mounting/__tests__/Mounting-itest.js @@ -0,0 +1,294 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + * @fantom_flags enableFixForParentTagDuringReparenting:true + */ + +import 'react-native/Libraries/Core/InitializeCore'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {View} from 'react-native'; + +describe('ViewFlattening', () => { + /** + * Test reordering of views with the same parent: + * + * For instance: + * A -> [B,C,D] ==> A -> [D,B,C] + * + * In the V1 of diffing this would produce 3 removes and 3 inserts, but with + * some cleverness we can reduce this to 1 remove and 1 insert. + */ + test('reordering', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "View", nativeID: "A"}', + 'Create {type: "View", nativeID: "B"}', + 'Create {type: "View", nativeID: "C"}', + 'Create {type: "View", nativeID: "D"}', + 'Insert {type: "View", parentNativeID: "A", index: 0, nativeID: "B"}', + 'Insert {type: "View", parentNativeID: "A", index: 1, nativeID: "C"}', + 'Insert {type: "View", parentNativeID: "A", index: 2, nativeID: "D"}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "A"}', + ]); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Remove {type: "View", parentNativeID: "A", index: 2, nativeID: "D"}', + 'Insert {type: "View", parentNativeID: "A", index: 0, nativeID: "D"}', + ]); + }); + + /** + * Test reparenting mutation instruction generation. + * We cannot practically handle all possible use-cases here. + */ + test('view reparenting', () => { + const root = Fantom.createRoot(); + + // Root -> G* -> H -> I -> J -> A* [nodes with * are _not_ flattened] + Fantom.runTask(() => { + root.render( + + + + + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "View", nativeID: "G"}', + 'Create {type: "View", nativeID: "A"}', + 'Insert {type: "View", parentNativeID: "G", index: 0, nativeID: "A"}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "G"}', + ]); + + // Root -> G* -> H* -> I -> J -> A* [nodes with * are _not_ flattened] + // Force an update with A with new props + Fantom.runTask(() => { + root.render( + + + + + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "A"}', + 'Remove {type: "View", parentNativeID: "G", index: 0, nativeID: "A"}', + 'Create {type: "View", nativeID: "H"}', + 'Insert {type: "View", parentNativeID: "G", index: 0, nativeID: "H"}', + 'Insert {type: "View", parentNativeID: "H", index: 0, nativeID: "A"}', + ]); + + // The view is reparented 1 level down with a different sibling + // Root -> G* -> H* -> I* -> J -> [B*, A*] [nodes with * are _not_ flattened] + Fantom.runTask(() => { + root.render( + + + + + + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + + + + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Remove {type: "View", parentNativeID: "H", index: 0, nativeID: "A"}', + 'Create {type: "View", nativeID: "I"}', + 'Create {type: "View", nativeID: "B"}', + 'Insert {type: "View", parentNativeID: "H", index: 0, nativeID: "I"}', + 'Insert {type: "View", parentNativeID: "I", index: 0, nativeID: "B"}', + 'Insert {type: "View", parentNativeID: "I", index: 1, nativeID: "A"}', + ]); + + // The view is reparented 1 level further down with its order with the sibling + // swapped + // Root -> G* -> H* -> I* -> J* -> [A*, B*] [nodes with * are _not_ flattened] + Fantom.runTask(() => { + root.render( + + + + + + + + + + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + + + + + + + + + + , + ); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Remove {type: "View", parentNativeID: "I", index: 1, nativeID: "A"}', + 'Remove {type: "View", parentNativeID: "I", index: 0, nativeID: "B"}', + 'Create {type: "View", nativeID: "J"}', + 'Insert {type: "View", parentNativeID: "I", index: 0, nativeID: "J"}', + 'Insert {type: "View", parentNativeID: "J", index: 0, nativeID: "A"}', + 'Insert {type: "View", parentNativeID: "J", index: 1, nativeID: "B"}', + ]); + }); +}); + +test('parent-child switching from unflattened-flattened to flattened-unflattened', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + // force view to be flattened. + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (root), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); +});