Skip to content

Commit 28fb4a2

Browse files
Add feature flag to enable experimental MutationObserver (#55919) (#56600)
Summary: Pull Request resolved: #56600 This picks #55919 into 0.85-stable, as we'll be testing this feature in apps using 0.85. Changelog: [Internal] - Not needed. It's gated behind a feature flag that's disabled by default. Test Plan: Tested e2e on Android and iOS using RN Tester. Everything compiles correctly. Reviewed By: Abbondanzo, sammy-SC, javache Differential Revision: D95223862 fbshipit-source-id: e19dd163e5f7fecd9ef28b79be61455f0993a3c4 Co-authored-by: Rubén Norte <rubennorte@meta.com>
1 parent 7fc99bc commit 28fb4a2

30 files changed

Lines changed: 290 additions & 67 deletions

packages/react-native/Package.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,13 @@ let reactIntersectionObserverNativeModule = RNTarget(
344344
dependencies: [.reactNativeDependencies, .reactCxxReact, .reactFabric, .reactTurboModuleBridging, .reactTurboModuleCore, .reactGraphics, .reactGraphicsApple, .reactRuntimeScheduler, .yoga]
345345
)
346346

347+
/// React-mutationobservernativemodule.podspec
348+
let reactMutationObserverNativeModule = RNTarget(
349+
name: .reactMutationObserverNativeModule,
350+
path: "ReactCommon/react/nativemodule/mutationobserver",
351+
dependencies: [.reactNativeDependencies, .reactCxxReact, .reactFabric, .reactTurboModuleBridging, .reactTurboModuleCore, .yoga]
352+
)
353+
347354
/// React-featureflagnativemodule.podspec
348355
let reactFeatureflagsNativemodule = RNTarget(
349356
name: .reactFeatureflagsNativemodule,
@@ -460,7 +467,7 @@ let reactFabric = RNTarget(
460467
"components/root/tests",
461468
],
462469
dependencies: [.reactNativeDependencies, .reactJsiExecutor, .rctTypesafety, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .reactRendererDebug, .reactGraphics, .yoga],
463-
sources: ["animated", "animationbackend", "animations", "attributedstring", "core", "componentregistry", "componentregistry/native", "components/root", "components/view", "components/view/platform/cxx", "components/scrollview", "components/scrollview/platform/cxx", "components/scrollview/platform/ios", "components/legacyviewmanagerinterop", "components/legacyviewmanagerinterop/platform/ios", "dom", "scheduler", "mounting", "observers/events", "observers/intersection", "telemetry", "consistency", "leakchecker", "uimanager", "uimanager/consistency"]
470+
sources: ["animated", "animationbackend", "animations", "attributedstring", "core", "componentregistry", "componentregistry/native", "components/root", "components/view", "components/view/platform/cxx", "components/scrollview", "components/scrollview/platform/cxx", "components/scrollview/platform/ios", "components/legacyviewmanagerinterop", "components/legacyviewmanagerinterop/platform/ios", "dom", "scheduler", "mounting", "observers/events", "observers/intersection", "observers/mutation", "telemetry", "consistency", "leakchecker", "uimanager", "uimanager/consistency"]
464471
)
465472

466473
let reactFabricInputAccessory = RNTarget(
@@ -696,6 +703,7 @@ let targets = [
696703
reactIdleCallbacksNativeModule,
697704
reactWebPerformanceNativeModule,
698705
reactIntersectionObserverNativeModule,
706+
reactMutationObserverNativeModule,
699707
reactFeatureflagsNativemodule,
700708
reactNativeModuleDom,
701709
reactAppDelegate,
@@ -884,6 +892,7 @@ extension String {
884892
static let reactIdleCallbacksNativeModule = "React-idlecallbacksnativemodule"
885893
static let reactWebPerformanceNativeModule = "React-webperformancenativemodule"
886894
static let reactIntersectionObserverNativeModule = "React-intersectionobservernativemodule"
895+
static let reactMutationObserverNativeModule = "React-mutationobservernativemodule"
887896
static let reactFeatureflagsNativemodule = "React-featureflagsnativemodule"
888897
static let reactNativeModuleDom = "React-domnativemodule"
889898
static let reactAppDelegate = "React-RCTAppDelegate"

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b522f15f814b0aa1c39fb4ca3c774b4f>>
7+
* @generated SignedSource<<bf97f4c89920b390b07c209c2252a1d4>>
88
*/
99

1010
/**
@@ -276,6 +276,12 @@ public object ReactNativeFeatureFlags {
276276
@JvmStatic
277277
public fun enableModuleArgumentNSNullConversionIOS(): Boolean = accessor.enableModuleArgumentNSNullConversionIOS()
278278

279+
/**
280+
* Enables the MutationObserver Web API in React Native.
281+
*/
282+
@JvmStatic
283+
public fun enableMutationObserverByDefault(): Boolean = accessor.enableMutationObserverByDefault()
284+
279285
/**
280286
* Parse CSS strings using the Fabric CSS parser instead of ViewConfig processing
281287
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d7427d54488f99fa4958904723582e2d>>
7+
* @generated SignedSource<<1b02cb83f56785dfa3ce35f1d818f0cb>>
88
*/
99

1010
/**
@@ -61,6 +61,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
6161
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
6262
private var enableMainQueueCoordinatorOnIOSCache: Boolean? = null
6363
private var enableModuleArgumentNSNullConversionIOSCache: Boolean? = null
64+
private var enableMutationObserverByDefaultCache: Boolean? = null
6465
private var enableNativeCSSParsingCache: Boolean? = null
6566
private var enableNetworkEventReportingCache: Boolean? = null
6667
private var enablePreparedTextLayoutCache: Boolean? = null
@@ -477,6 +478,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
477478
return cached
478479
}
479480

481+
override fun enableMutationObserverByDefault(): Boolean {
482+
var cached = enableMutationObserverByDefaultCache
483+
if (cached == null) {
484+
cached = ReactNativeFeatureFlagsCxxInterop.enableMutationObserverByDefault()
485+
enableMutationObserverByDefaultCache = cached
486+
}
487+
return cached
488+
}
489+
480490
override fun enableNativeCSSParsing(): Boolean {
481491
var cached = enableNativeCSSParsingCache
482492
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<a6e60b15f983227515dd59449a7018dc>>
7+
* @generated SignedSource<<a408eecf4c99f58239e2a7b9b8189888>>
88
*/
99

1010
/**
@@ -110,6 +110,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
110110

111111
@DoNotStrip @JvmStatic public external fun enableModuleArgumentNSNullConversionIOS(): Boolean
112112

113+
@DoNotStrip @JvmStatic public external fun enableMutationObserverByDefault(): Boolean
114+
113115
@DoNotStrip @JvmStatic public external fun enableNativeCSSParsing(): Boolean
114116

115117
@DoNotStrip @JvmStatic public external fun enableNetworkEventReporting(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<9c0f3543f620cbed7dc0646e804e99c6>>
7+
* @generated SignedSource<<8c191a23b3930615bf4c08e6223b9192>>
88
*/
99

1010
/**
@@ -105,6 +105,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
105105

106106
override fun enableModuleArgumentNSNullConversionIOS(): Boolean = false
107107

108+
override fun enableMutationObserverByDefault(): Boolean = false
109+
108110
override fun enableNativeCSSParsing(): Boolean = false
109111

110112
override fun enableNetworkEventReporting(): Boolean = true

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<1a04fbbdeb04ad45889eb36e871a5307>>
7+
* @generated SignedSource<<71f813e0b1bec88221d53572aaa7b989>>
88
*/
99

1010
/**
@@ -65,6 +65,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
6565
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
6666
private var enableMainQueueCoordinatorOnIOSCache: Boolean? = null
6767
private var enableModuleArgumentNSNullConversionIOSCache: Boolean? = null
68+
private var enableMutationObserverByDefaultCache: Boolean? = null
6869
private var enableNativeCSSParsingCache: Boolean? = null
6970
private var enableNetworkEventReportingCache: Boolean? = null
7071
private var enablePreparedTextLayoutCache: Boolean? = null
@@ -522,6 +523,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
522523
return cached
523524
}
524525

526+
override fun enableMutationObserverByDefault(): Boolean {
527+
var cached = enableMutationObserverByDefaultCache
528+
if (cached == null) {
529+
cached = currentProvider.enableMutationObserverByDefault()
530+
accessedFeatureFlags.add("enableMutationObserverByDefault")
531+
enableMutationObserverByDefaultCache = cached
532+
}
533+
return cached
534+
}
535+
525536
override fun enableNativeCSSParsing(): Boolean {
526537
var cached = enableNativeCSSParsingCache
527538
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b6fd49c63c29d8883cce1a91d8f21523>>
7+
* @generated SignedSource<<6f4f023705715564d2e8694791d26f3d>>
88
*/
99

1010
/**
@@ -105,6 +105,8 @@ public interface ReactNativeFeatureFlagsProvider {
105105

106106
@DoNotStrip public fun enableModuleArgumentNSNullConversionIOS(): Boolean
107107

108+
@DoNotStrip public fun enableMutationObserverByDefault(): Boolean
109+
108110
@DoNotStrip public fun enableNativeCSSParsing(): Boolean
109111

110112
@DoNotStrip public fun enableNetworkEventReporting(): Boolean

packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ add_react_common_subdir(react/renderer/components/safeareaview)
117117
add_react_common_subdir(react/renderer/leakchecker)
118118
add_react_common_subdir(react/renderer/observers/events)
119119
add_react_common_subdir(react/renderer/observers/intersection)
120+
add_react_common_subdir(react/renderer/observers/mutation)
120121
add_react_common_subdir(react/renderer/textlayoutmanager)
121122
add_react_common_subdir(react/utils)
122123
add_react_common_subdir(react/bridging)
@@ -128,6 +129,7 @@ add_react_common_subdir(react/nativemodule/featureflags)
128129
add_react_common_subdir(react/nativemodule/microtasks)
129130
add_react_common_subdir(react/nativemodule/idlecallbacks)
130131
add_react_common_subdir(react/nativemodule/intersectionobserver)
132+
add_react_common_subdir(react/nativemodule/mutationobserver)
131133
add_react_common_subdir(react/nativemodule/webperformance)
132134
add_react_common_subdir(react/networking)
133135
add_react_common_subdir(jserrorhandler)
@@ -197,6 +199,7 @@ add_library(reactnative
197199
$<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
198200
$<TARGET_OBJECTS:react_nativemodule_intersectionobserver>
199201
$<TARGET_OBJECTS:react_nativemodule_microtasks>
202+
$<TARGET_OBJECTS:react_nativemodule_mutationobserver>
200203
$<TARGET_OBJECTS:react_nativemodule_webperformance>
201204
$<TARGET_OBJECTS:react_networking>
202205
$<TARGET_OBJECTS:react_newarchdefaults>
@@ -219,6 +222,7 @@ add_library(reactnative
219222
$<TARGET_OBJECTS:react_renderer_mounting>
220223
$<TARGET_OBJECTS:react_renderer_observers_events>
221224
$<TARGET_OBJECTS:react_renderer_observers_intersection>
225+
$<TARGET_OBJECTS:react_renderer_observers_mutation>
222226
$<TARGET_OBJECTS:react_renderer_runtimescheduler>
223227
$<TARGET_OBJECTS:react_renderer_scheduler>
224228
$<TARGET_OBJECTS:react_renderer_telemetry>
@@ -292,6 +296,7 @@ target_include_directories(reactnative
292296
$<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
293297
$<TARGET_PROPERTY:react_nativemodule_intersectionobserver,INTERFACE_INCLUDE_DIRECTORIES>
294298
$<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
299+
$<TARGET_PROPERTY:react_nativemodule_mutationobserver,INTERFACE_INCLUDE_DIRECTORIES>
295300
$<TARGET_PROPERTY:react_nativemodule_webperformance,INTERFACE_INCLUDE_DIRECTORIES>
296301
$<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
297302
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
@@ -315,6 +320,8 @@ target_include_directories(reactnative
315320
$<TARGET_PROPERTY:react_renderer_mapbuffer,INTERFACE_INCLUDE_DIRECTORIES>
316321
$<TARGET_PROPERTY:react_renderer_mounting,INTERFACE_INCLUDE_DIRECTORIES>
317322
$<TARGET_PROPERTY:react_renderer_observers_events,INTERFACE_INCLUDE_DIRECTORIES>
323+
$<TARGET_PROPERTY:react_renderer_observers_intersection,INTERFACE_INCLUDE_DIRECTORIES>
324+
$<TARGET_PROPERTY:react_renderer_observers_mutation,INTERFACE_INCLUDE_DIRECTORIES>
318325
$<TARGET_PROPERTY:react_renderer_runtimescheduler,INTERFACE_INCLUDE_DIRECTORIES>
319326
$<TARGET_PROPERTY:react_renderer_scheduler,INTERFACE_INCLUDE_DIRECTORIES>
320327
$<TARGET_PROPERTY:react_renderer_telemetry,INTERFACE_INCLUDE_DIRECTORIES>

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d7b3c513adfc1a5f1d29f0e481282a96>>
7+
* @generated SignedSource<<629e0071deb87fcfc23fec013025012c>>
88
*/
99

1010
/**
@@ -285,6 +285,12 @@ class ReactNativeFeatureFlagsJavaProvider
285285
return method(javaProvider_);
286286
}
287287

288+
bool enableMutationObserverByDefault() override {
289+
static const auto method =
290+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableMutationObserverByDefault");
291+
return method(javaProvider_);
292+
}
293+
288294
bool enableNativeCSSParsing() override {
289295
static const auto method =
290296
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableNativeCSSParsing");
@@ -770,6 +776,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableModuleArgumentNSNullConversionIOS
770776
return ReactNativeFeatureFlags::enableModuleArgumentNSNullConversionIOS();
771777
}
772778

779+
bool JReactNativeFeatureFlagsCxxInterop::enableMutationObserverByDefault(
780+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
781+
return ReactNativeFeatureFlags::enableMutationObserverByDefault();
782+
}
783+
773784
bool JReactNativeFeatureFlagsCxxInterop::enableNativeCSSParsing(
774785
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
775786
return ReactNativeFeatureFlags::enableNativeCSSParsing();
@@ -1154,6 +1165,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
11541165
makeNativeMethod(
11551166
"enableModuleArgumentNSNullConversionIOS",
11561167
JReactNativeFeatureFlagsCxxInterop::enableModuleArgumentNSNullConversionIOS),
1168+
makeNativeMethod(
1169+
"enableMutationObserverByDefault",
1170+
JReactNativeFeatureFlagsCxxInterop::enableMutationObserverByDefault),
11571171
makeNativeMethod(
11581172
"enableNativeCSSParsing",
11591173
JReactNativeFeatureFlagsCxxInterop::enableNativeCSSParsing),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<9a0ad2e34163e0efed56ca1662d68c35>>
7+
* @generated SignedSource<<4b7da9ad83796b0df3d4df89326a647c>>
88
*/
99

1010
/**
@@ -153,6 +153,9 @@ class JReactNativeFeatureFlagsCxxInterop
153153
static bool enableModuleArgumentNSNullConversionIOS(
154154
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
155155

156+
static bool enableMutationObserverByDefault(
157+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
158+
156159
static bool enableNativeCSSParsing(
157160
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
158161

0 commit comments

Comments
 (0)