react-native-tvos 0.85.2-0 → 0.85.3-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/Libraries/Components/ScrollView/ScrollView.d.ts +1 -1
  2. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  3. package/Libraries/Components/TV/TVViewPropTypes.js +9 -0
  4. package/Libraries/Components/View/View.js +7 -3
  5. package/Libraries/Core/ReactNativeVersion.js +2 -2
  6. package/Libraries/NativeComponent/TVViewConfig.js +1 -0
  7. package/Libraries/Utilities/HMRClient.js +28 -1
  8. package/README.md +13 -1
  9. package/React/Base/RCTVersion.m +2 -2
  10. package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
  11. package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
  12. package/React/CoreModules/RCTRedBox+Internal.h +42 -0
  13. package/React/CoreModules/RCTRedBox.mm +30 -471
  14. package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
  15. package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
  16. package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
  17. package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
  18. package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
  19. package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
  20. package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
  21. package/React/CoreModules/RCTRedBoxController.mm +447 -0
  22. package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
  23. package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
  24. package/React/CoreModules/React-CoreModules.podspec +1 -0
  25. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  26. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  27. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
  28. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +35 -15
  29. package/ReactAndroid/gradle.properties +1 -1
  30. package/ReactAndroid/hermes-engine/build.gradle.kts +17 -0
  31. package/ReactAndroid/publish.gradle +20 -46
  32. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +1 -1
  34. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +127 -26
  35. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
  36. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
  37. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
  38. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +11 -1
  39. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
  40. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
  41. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  42. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +2 -2
  43. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +50 -10
  44. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +14 -4
  45. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +14 -4
  46. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +46 -6
  47. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt +1 -0
  48. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +5 -0
  49. package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
  50. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  51. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  52. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
  53. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
  54. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +14 -0
  55. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +18 -4
  56. package/ReactCommon/React-Fabric.podspec +6 -0
  57. package/ReactCommon/cxxreact/ReactNativeVersion.h +3 -3
  58. package/ReactCommon/jsinspector-modern/HostAgent.cpp +36 -0
  59. package/ReactCommon/jsinspector-modern/HostTarget.cpp +7 -1
  60. package/ReactCommon/jsinspector-modern/HostTarget.h +25 -0
  61. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +1 -1
  62. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +4 -4
  63. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  64. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  65. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  66. package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
  67. package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
  68. package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
  69. package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
  70. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +12 -0
  71. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +3 -2
  72. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  73. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -1
  74. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +1 -1
  75. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  76. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  77. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  78. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +7 -3
  79. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +52 -29
  80. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +6 -6
  81. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  82. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  83. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +12 -5
  84. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +3 -1
  85. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +42 -0
  86. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  87. package/ReactCommon/react/debug/CMakeLists.txt +2 -1
  88. package/ReactCommon/react/debug/React-debug.podspec +7 -1
  89. package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
  90. package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
  91. package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
  92. package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
  93. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
  94. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
  95. package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
  96. package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
  97. package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
  98. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
  99. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
  100. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +135 -45
  101. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
  102. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +21 -1
  103. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
  104. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
  105. package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
  106. package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
  107. package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
  108. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
  109. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
  110. package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
  111. package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
  112. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  113. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  114. package/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +7 -0
  115. package/ReactCommon/react/renderer/components/view/BaseViewProps.h +1 -0
  116. package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +18 -0
  117. package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.h +1 -0
  118. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  119. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  120. package/package.json +11 -11
  121. package/scripts/cocoapods/utils.rb +1 -0
  122. package/scripts/react_native_pods.rb +1 -0
  123. package/scripts/replace-rncore-version.js +72 -15
  124. package/src/private/featureflags/ReactNativeFeatureFlags.js +26 -1
  125. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
  126. package/src/private/setup/setUpDefaultReactNativeEnvironment.js +6 -0
  127. package/types/public/ReactNativeTVTypes.d.ts +9 -0
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<669708c311abe9ffc8f7783219e2baad>>
7
+ * @generated SignedSource<<499aedb10bae64c096e7ad2e096bdd1f>>
8
8
  */
9
9
 
10
10
  /**
@@ -65,6 +65,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
65
65
  private var enableLayoutAnimationsOnIOSCache: Boolean? = null
66
66
  private var enableMainQueueCoordinatorOnIOSCache: Boolean? = null
67
67
  private var enableModuleArgumentNSNullConversionIOSCache: Boolean? = null
68
+ private var enableMutationObserverByDefaultCache: Boolean? = null
68
69
  private var enableNativeCSSParsingCache: Boolean? = null
69
70
  private var enableNetworkEventReportingCache: Boolean? = null
70
71
  private var enablePreparedTextLayoutCache: Boolean? = null
@@ -83,13 +84,17 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
83
84
  private var fixTextClippingAndroid15useBoundsForWidthCache: Boolean? = null
84
85
  private var fuseboxAssertSingleHostStateCache: Boolean? = null
85
86
  private var fuseboxEnabledReleaseCache: Boolean? = null
87
+ private var fuseboxFrameRecordingEnabledCache: Boolean? = null
86
88
  private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
89
+ private var fuseboxScreenshotCaptureEnabledCache: Boolean? = null
87
90
  private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
88
91
  private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
89
92
  private var perfIssuesEnabledCache: Boolean? = null
90
93
  private var perfMonitorV2EnabledCache: Boolean? = null
91
94
  private var preparedTextCacheSizeCache: Double? = null
92
95
  private var preventShadowTreeCommitExhaustionCache: Boolean? = null
96
+ private var redBoxV2AndroidCache: Boolean? = null
97
+ private var redBoxV2IOSCache: Boolean? = null
93
98
  private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
94
99
  private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null
95
100
  private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null
@@ -520,6 +525,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
520
525
  return cached
521
526
  }
522
527
 
528
+ override fun enableMutationObserverByDefault(): Boolean {
529
+ var cached = enableMutationObserverByDefaultCache
530
+ if (cached == null) {
531
+ cached = currentProvider.enableMutationObserverByDefault()
532
+ accessedFeatureFlags.add("enableMutationObserverByDefault")
533
+ enableMutationObserverByDefaultCache = cached
534
+ }
535
+ return cached
536
+ }
537
+
523
538
  override fun enableNativeCSSParsing(): Boolean {
524
539
  var cached = enableNativeCSSParsingCache
525
540
  if (cached == null) {
@@ -700,6 +715,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
700
715
  return cached
701
716
  }
702
717
 
718
+ override fun fuseboxFrameRecordingEnabled(): Boolean {
719
+ var cached = fuseboxFrameRecordingEnabledCache
720
+ if (cached == null) {
721
+ cached = currentProvider.fuseboxFrameRecordingEnabled()
722
+ accessedFeatureFlags.add("fuseboxFrameRecordingEnabled")
723
+ fuseboxFrameRecordingEnabledCache = cached
724
+ }
725
+ return cached
726
+ }
727
+
703
728
  override fun fuseboxNetworkInspectionEnabled(): Boolean {
704
729
  var cached = fuseboxNetworkInspectionEnabledCache
705
730
  if (cached == null) {
@@ -710,6 +735,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
710
735
  return cached
711
736
  }
712
737
 
738
+ override fun fuseboxScreenshotCaptureEnabled(): Boolean {
739
+ var cached = fuseboxScreenshotCaptureEnabledCache
740
+ if (cached == null) {
741
+ cached = currentProvider.fuseboxScreenshotCaptureEnabled()
742
+ accessedFeatureFlags.add("fuseboxScreenshotCaptureEnabled")
743
+ fuseboxScreenshotCaptureEnabledCache = cached
744
+ }
745
+ return cached
746
+ }
747
+
713
748
  override fun hideOffscreenVirtualViewsOnIOS(): Boolean {
714
749
  var cached = hideOffscreenVirtualViewsOnIOSCache
715
750
  if (cached == null) {
@@ -770,6 +805,26 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
770
805
  return cached
771
806
  }
772
807
 
808
+ override fun redBoxV2Android(): Boolean {
809
+ var cached = redBoxV2AndroidCache
810
+ if (cached == null) {
811
+ cached = currentProvider.redBoxV2Android()
812
+ accessedFeatureFlags.add("redBoxV2Android")
813
+ redBoxV2AndroidCache = cached
814
+ }
815
+ return cached
816
+ }
817
+
818
+ override fun redBoxV2IOS(): Boolean {
819
+ var cached = redBoxV2IOSCache
820
+ if (cached == null) {
821
+ cached = currentProvider.redBoxV2IOS()
822
+ accessedFeatureFlags.add("redBoxV2IOS")
823
+ redBoxV2IOSCache = cached
824
+ }
825
+ return cached
826
+ }
827
+
773
828
  override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean {
774
829
  var cached = shouldPressibilityUseW3CPointerEventsForHoverCache
775
830
  if (cached == null) {
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<db06b64a8d1b9ab99b368fea41185d62>>
7
+ * @generated SignedSource<<4ed94743d9eafd0be32bb04471a18fc6>>
8
8
  */
9
9
 
10
10
  /**
@@ -105,6 +105,8 @@ public interface ReactNativeFeatureFlagsProvider {
105
105
 
106
106
  @DoNotStrip public fun enableModuleArgumentNSNullConversionIOS(): Boolean
107
107
 
108
+ @DoNotStrip public fun enableMutationObserverByDefault(): Boolean
109
+
108
110
  @DoNotStrip public fun enableNativeCSSParsing(): Boolean
109
111
 
110
112
  @DoNotStrip public fun enableNetworkEventReporting(): Boolean
@@ -141,8 +143,12 @@ public interface ReactNativeFeatureFlagsProvider {
141
143
 
142
144
  @DoNotStrip public fun fuseboxEnabledRelease(): Boolean
143
145
 
146
+ @DoNotStrip public fun fuseboxFrameRecordingEnabled(): Boolean
147
+
144
148
  @DoNotStrip public fun fuseboxNetworkInspectionEnabled(): Boolean
145
149
 
150
+ @DoNotStrip public fun fuseboxScreenshotCaptureEnabled(): Boolean
151
+
146
152
  @DoNotStrip public fun hideOffscreenVirtualViewsOnIOS(): Boolean
147
153
 
148
154
  @DoNotStrip public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean
@@ -155,6 +161,10 @@ public interface ReactNativeFeatureFlagsProvider {
155
161
 
156
162
  @DoNotStrip public fun preventShadowTreeCommitExhaustion(): Boolean
157
163
 
164
+ @DoNotStrip public fun redBoxV2Android(): Boolean
165
+
166
+ @DoNotStrip public fun redBoxV2IOS(): Boolean
167
+
158
168
  @DoNotStrip public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
159
169
 
160
170
  @DoNotStrip public fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean
@@ -23,6 +23,45 @@ public object PerformanceTracer {
23
23
  SoLoader.loadLibrary("react_performancetracerjni")
24
24
  }
25
25
 
26
+ public fun <T> trace(name: String, block: () -> T): T {
27
+ return trace(name, null /* track */, null /* trackGroup */, null /* color */, block)
28
+ }
29
+
30
+ public fun <T> trace(name: String, track: String, block: () -> T): T {
31
+ return trace(name, track, null /* trackGroup */, null /* color */, block)
32
+ }
33
+
34
+ public fun <T> trace(name: String, track: String, trackGroup: String, block: () -> T): T {
35
+ return trace(name, track, trackGroup, null /* color */, block)
36
+ }
37
+
38
+ public fun <T> trace(
39
+ name: String,
40
+ track: String?,
41
+ trackGroup: String?,
42
+ color: String?,
43
+ block: () -> T,
44
+ ): T {
45
+ if (!isTracing()) {
46
+ return block()
47
+ }
48
+
49
+ val startTimeNanos = java.lang.System.nanoTime()
50
+ try {
51
+ return block()
52
+ } finally {
53
+ val endTimeNanos = java.lang.System.nanoTime()
54
+ reportTimeStamp(
55
+ name,
56
+ startTimeNanos,
57
+ endTimeNanos,
58
+ track,
59
+ trackGroup,
60
+ color,
61
+ )
62
+ }
63
+ }
64
+
26
65
  /** Callback interface for tracing state changes. */
27
66
  @DoNotStrip
28
67
  public interface TracingStateCallback {
@@ -14,7 +14,7 @@ public object ReactNativeVersion {
14
14
  public val VERSION: Map<String, Any?> = mapOf(
15
15
  "major" to 0,
16
16
  "minor" to 85,
17
- "patch" to 2,
18
- "prerelease" to "0"
17
+ "patch" to 3,
18
+ "prerelease" to "1"
19
19
  )
20
20
  }
@@ -12,6 +12,7 @@ import android.content.Context
12
12
  import android.content.Intent
13
13
  import android.nfc.NfcAdapter
14
14
  import android.os.Bundle
15
+ import androidx.core.graphics.createBitmap
15
16
  import com.facebook.common.logging.FLog
16
17
  import com.facebook.infer.annotation.Assertions
17
18
  import com.facebook.infer.annotation.ThreadConfined
@@ -447,6 +448,43 @@ public class ReactHostImpl(
447
448
  InspectorNetworkHelper.loadNetworkResource(url, listener)
448
449
  }
449
450
 
451
+ @DoNotStrip
452
+ private fun captureScreenshot(format: String, quality: Int): String? {
453
+ val activity = currentActivity ?: return null
454
+ val window = activity.window ?: return null
455
+ val decorView = window.decorView.rootView
456
+
457
+ val width = decorView.width
458
+ val height = decorView.height
459
+ if (width <= 0 || height <= 0) {
460
+ return null
461
+ }
462
+
463
+ val bitmap = createBitmap(width, height)
464
+ val canvas = android.graphics.Canvas(bitmap)
465
+ decorView.draw(canvas)
466
+
467
+ val outputStream = java.io.ByteArrayOutputStream()
468
+ val compressFormat =
469
+ when (format) {
470
+ "jpeg" -> android.graphics.Bitmap.CompressFormat.JPEG
471
+ "webp" ->
472
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
473
+ android.graphics.Bitmap.CompressFormat.WEBP_LOSSY
474
+ } else {
475
+ @Suppress("DEPRECATION") android.graphics.Bitmap.CompressFormat.WEBP
476
+ }
477
+ else -> android.graphics.Bitmap.CompressFormat.PNG
478
+ }
479
+ val compressQuality = if (quality in 0..100) quality else 80
480
+
481
+ bitmap.compress(compressFormat, compressQuality, outputStream)
482
+ bitmap.recycle()
483
+
484
+ val bytes = outputStream.toByteArray()
485
+ return android.util.Base64.encodeToString(bytes, android.util.Base64.NO_WRAP)
486
+ }
487
+
450
488
  /**
451
489
  * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until
452
490
  * reload is finished, before destroying.
@@ -1565,16 +1603,18 @@ public class ReactHostImpl(
1565
1603
  when (state) {
1566
1604
  TracingState.ENABLED_IN_BACKGROUND_MODE,
1567
1605
  TracingState.ENABLED_IN_CDP_MODE -> {
1568
- val observer =
1569
- FrameTimingsObserver(
1570
- _screenshotsEnabled,
1571
- { frameTimingsSequence ->
1572
- inspectorTarget.recordFrameTimings(frameTimingsSequence)
1573
- },
1574
- )
1575
- observer.setCurrentWindow(currentActivity?.window)
1576
- observer.start()
1577
- frameTimingsObserver = observer
1606
+ if (InspectorFlags.getFrameRecordingEnabled()) {
1607
+ val observer =
1608
+ FrameTimingsObserver(
1609
+ _screenshotsEnabled,
1610
+ { frameTimingsSequence ->
1611
+ inspectorTarget.recordFrameTimings(frameTimingsSequence)
1612
+ },
1613
+ )
1614
+ observer.setCurrentWindow(currentActivity?.window)
1615
+ observer.start()
1616
+ frameTimingsObserver = observer
1617
+ }
1578
1618
  }
1579
1619
  TracingState.DISABLED -> {
1580
1620
  frameTimingsObserver?.stop()
@@ -586,29 +586,39 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
586
586
  }
587
587
 
588
588
  /**
589
- * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign.
590
- * Returns true if snap scrolling was performed, false otherwise.
589
+ * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign
590
+ * or scrollSnapOffset. Returns true if snap scrolling was performed, false otherwise.
591
591
  */
592
592
  private boolean tryScrollSnapToChild(View focused) {
593
593
  if (mSnapToAlignment != SNAP_ALIGNMENT_ITEM) {
594
594
  return false;
595
595
  }
596
596
 
597
- kotlin.Pair<View, String> result = ReactScrollViewHelper.findScrollSnapAlign(focused, this);
597
+ kotlin.Triple<View, String, Integer> result =
598
+ ReactScrollViewHelper.findScrollSnap(focused, this);
598
599
  if (result == null) {
599
600
  return false;
600
601
  }
601
602
 
602
603
  View snapTarget = result.getFirst();
603
604
  String alignment = result.getSecond();
605
+ Integer snapOffset = result.getThird();
604
606
 
605
607
  Rect rect = new Rect();
606
608
  snapTarget.getDrawingRect(rect);
607
609
  offsetDescendantRectToMyCoords(snapTarget, rect);
608
610
 
609
- int viewportWidth = getWidth() - getPaddingLeft() - getPaddingRight();
610
611
  int maxScrollX = Math.max(0, computeHorizontalScrollRange() - getWidth());
611
612
 
613
+ if (snapOffset != null) {
614
+ int targetOffset = ReactScrollViewHelper.computeScrollSnapTargetForOffset(
615
+ rect.left, snapOffset, mSnapInterval, maxScrollX);
616
+ reactSmoothScrollTo(targetOffset, getScrollY());
617
+ return true;
618
+ }
619
+
620
+ int viewportWidth = getWidth() - getPaddingLeft() - getPaddingRight();
621
+
612
622
  Integer targetOffset = ReactScrollViewHelper.computeScrollSnapOffset(
613
623
  rect.left, rect.right, viewportWidth, alignment, mSnapInterval, mSnapToItemPadding, maxScrollX);
614
624
  if (targetOffset == null) {
@@ -519,29 +519,39 @@ public class ReactScrollView extends ScrollView
519
519
  }
520
520
 
521
521
  /**
522
- * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign.
523
- * Returns true if snap scrolling was performed, false otherwise.
522
+ * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign
523
+ * or scrollSnapOffset. Returns true if snap scrolling was performed, false otherwise.
524
524
  */
525
525
  private boolean tryScrollSnapToChild(View focused) {
526
526
  if (mSnapToAlignment != SNAP_ALIGNMENT_ITEM) {
527
527
  return false;
528
528
  }
529
529
 
530
- kotlin.Pair<View, String> result = ReactScrollViewHelper.findScrollSnapAlign(focused, this);
530
+ kotlin.Triple<View, String, Integer> result =
531
+ ReactScrollViewHelper.findScrollSnap(focused, this);
531
532
  if (result == null) {
532
533
  return false;
533
534
  }
534
535
 
535
536
  View snapTarget = result.getFirst();
536
537
  String alignment = result.getSecond();
538
+ Integer snapOffset = result.getThird();
537
539
 
538
540
  Rect rect = new Rect();
539
541
  snapTarget.getDrawingRect(rect);
540
542
  offsetDescendantRectToMyCoords(snapTarget, rect);
541
543
 
542
- int viewportHeight = getHeight() - getPaddingTop() - getPaddingBottom();
543
544
  int maxScrollY = getMaxScrollY();
544
545
 
546
+ if (snapOffset != null) {
547
+ int targetOffset = ReactScrollViewHelper.computeScrollSnapTargetForOffset(
548
+ rect.top, snapOffset, mSnapInterval, maxScrollY);
549
+ reactSmoothScrollTo(getScrollX(), targetOffset);
550
+ return true;
551
+ }
552
+
553
+ int viewportHeight = getHeight() - getPaddingTop() - getPaddingBottom();
554
+
545
555
  Integer targetOffset = ReactScrollViewHelper.computeScrollSnapOffset(
546
556
  rect.top, rect.bottom, viewportHeight, alignment, mSnapInterval, mSnapToItemPadding, maxScrollY);
547
557
  if (targetOffset == null) {
@@ -569,27 +569,67 @@ public object ReactScrollViewHelper {
569
569
 
570
570
  /**
571
571
  * Walks up the view hierarchy from the focused view to find a ReactViewGroup with
572
- * scrollSnapAlign set. Returns a Pair of (snapTarget, alignment) or null if not found.
572
+ * either scrollSnapAlign or scrollSnapOffset set. Returns a Triple of (snapTarget,
573
+ * alignment, offsetPx) or null if neither marker was found. Exactly one of
574
+ * alignment/offsetPx is non-null on return.
575
+ *
576
+ * Walk is inner→outer, latest marker wins. On a single view declaring both,
577
+ * scrollSnapOffset wins as the more specific config.
573
578
  *
574
579
  * Shared by [ReactScrollView] and [ReactHorizontalScrollView].
575
580
  */
576
581
  @JvmStatic
577
- public fun findScrollSnapAlign(focused: View, scrollView: ViewGroup): Pair<View, String>? {
582
+ public fun findScrollSnap(focused: View, scrollView: ViewGroup): Triple<View, String?, Int?>? {
578
583
  var view: View? = focused
579
584
  var snapTarget: View? = null
580
585
  var alignment: String? = null
586
+ var offset: Int? = null
581
587
  while (view != null && view !== scrollView) {
582
588
  if (view is ReactViewGroup) {
583
- val snap = view.scrollSnapAlign
584
- if (snap != null) {
585
- alignment = snap
589
+ val o = view.scrollSnapOffset
590
+ val a = view.scrollSnapAlign
591
+ if (o != null) {
592
+ offset = o
593
+ alignment = null
594
+ snapTarget = view
595
+ } else if (a != null) {
596
+ alignment = a
597
+ offset = null
586
598
  snapTarget = view
587
599
  }
588
600
  }
589
601
  val parent = view.parent
590
602
  view = if (parent is View) parent else null
591
603
  }
592
- return if (alignment != null && snapTarget != null) Pair(snapTarget, alignment) else null
604
+ return if (snapTarget != null && (alignment != null || offset != null))
605
+ Triple(snapTarget, alignment, offset) else null
606
+ }
607
+
608
+ /**
609
+ * Computes the target scroll offset for the per-item scrollSnapOffset path:
610
+ * land the snap target's leading edge at `snapOffset` pixels from the viewport origin.
611
+ *
612
+ * Returns the clamped target offset.
613
+ *
614
+ * Shared by [ReactScrollView] and [ReactHorizontalScrollView].
615
+ *
616
+ * @param focusedStart the start coordinate of the snap target in scroll view coordinates
617
+ * @param snapOffset the per-item pixel offset from the viewport origin
618
+ * @param snapInterval the snap interval (0 if not set)
619
+ * @param maxScrollOffset the maximum scroll offset for clamping
620
+ */
621
+ @JvmStatic
622
+ public fun computeScrollSnapTargetForOffset(
623
+ focusedStart: Int,
624
+ snapOffset: Int,
625
+ snapInterval: Int,
626
+ maxScrollOffset: Int,
627
+ ): Int {
628
+ var targetOffset = focusedStart - snapOffset
629
+ if (snapInterval > 0) {
630
+ targetOffset = (Math.floor(targetOffset.toDouble() / snapInterval) * snapInterval).toInt()
631
+ }
632
+ return Math.max(0, Math.min(targetOffset, maxScrollOffset))
593
633
  }
594
634
 
595
635
  /**
@@ -174,6 +174,7 @@ public open class ReactViewGroup public constructor(context: Context?) :
174
174
  private var onInterceptTouchEventListener: OnInterceptTouchEventListener? = null
175
175
  private var needsOffscreenAlphaCompositing = false
176
176
  public var scrollSnapAlign: String? = null
177
+ public var scrollSnapOffset: Int? = null
177
178
  private var backfaceOpacity = 0f
178
179
  private var backfaceVisible = false
179
180
  private var childrenRemovedWhileTransitioning: MutableSet<Int>? = null
@@ -195,6 +195,11 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
195
195
  view.scrollSnapAlign = value
196
196
  }
197
197
 
198
+ @ReactProp(name = "scrollSnapOffset", defaultFloat = Float.NaN)
199
+ public open fun setScrollSnapOffset(view: ReactViewGroup, value: Float) {
200
+ view.scrollSnapOffset = if (value.isNaN()) null else value.dpToPx().toInt()
201
+ }
202
+
198
203
  @ReactProp(name = ViewProps.BACKGROUND_IMAGE, customType = "BackgroundImage")
199
204
  public open fun setBackgroundImage(view: ReactViewGroup, backgroundImage: ReadableArray?) {
200
205
  if (ViewUtil.getUIManagerType(view) == UIManagerType.FABRIC) {
@@ -117,6 +117,7 @@ add_react_common_subdir(react/renderer/components/safeareaview)
117
117
  add_react_common_subdir(react/renderer/leakchecker)
118
118
  add_react_common_subdir(react/renderer/observers/events)
119
119
  add_react_common_subdir(react/renderer/observers/intersection)
120
+ add_react_common_subdir(react/renderer/observers/mutation)
120
121
  add_react_common_subdir(react/renderer/textlayoutmanager)
121
122
  add_react_common_subdir(react/utils)
122
123
  add_react_common_subdir(react/bridging)
@@ -128,6 +129,7 @@ add_react_common_subdir(react/nativemodule/featureflags)
128
129
  add_react_common_subdir(react/nativemodule/microtasks)
129
130
  add_react_common_subdir(react/nativemodule/idlecallbacks)
130
131
  add_react_common_subdir(react/nativemodule/intersectionobserver)
132
+ add_react_common_subdir(react/nativemodule/mutationobserver)
131
133
  add_react_common_subdir(react/nativemodule/webperformance)
132
134
  add_react_common_subdir(react/networking)
133
135
  add_react_common_subdir(jserrorhandler)
@@ -197,6 +199,7 @@ add_library(reactnative
197
199
  $<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
198
200
  $<TARGET_OBJECTS:react_nativemodule_intersectionobserver>
199
201
  $<TARGET_OBJECTS:react_nativemodule_microtasks>
202
+ $<TARGET_OBJECTS:react_nativemodule_mutationobserver>
200
203
  $<TARGET_OBJECTS:react_nativemodule_webperformance>
201
204
  $<TARGET_OBJECTS:react_networking>
202
205
  $<TARGET_OBJECTS:react_newarchdefaults>
@@ -219,6 +222,7 @@ add_library(reactnative
219
222
  $<TARGET_OBJECTS:react_renderer_mounting>
220
223
  $<TARGET_OBJECTS:react_renderer_observers_events>
221
224
  $<TARGET_OBJECTS:react_renderer_observers_intersection>
225
+ $<TARGET_OBJECTS:react_renderer_observers_mutation>
222
226
  $<TARGET_OBJECTS:react_renderer_runtimescheduler>
223
227
  $<TARGET_OBJECTS:react_renderer_scheduler>
224
228
  $<TARGET_OBJECTS:react_renderer_telemetry>
@@ -292,6 +296,7 @@ target_include_directories(reactnative
292
296
  $<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
293
297
  $<TARGET_PROPERTY:react_nativemodule_intersectionobserver,INTERFACE_INCLUDE_DIRECTORIES>
294
298
  $<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
299
+ $<TARGET_PROPERTY:react_nativemodule_mutationobserver,INTERFACE_INCLUDE_DIRECTORIES>
295
300
  $<TARGET_PROPERTY:react_nativemodule_webperformance,INTERFACE_INCLUDE_DIRECTORIES>
296
301
  $<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
297
302
  $<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
@@ -315,6 +320,8 @@ target_include_directories(reactnative
315
320
  $<TARGET_PROPERTY:react_renderer_mapbuffer,INTERFACE_INCLUDE_DIRECTORIES>
316
321
  $<TARGET_PROPERTY:react_renderer_mounting,INTERFACE_INCLUDE_DIRECTORIES>
317
322
  $<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>
318
325
  $<TARGET_PROPERTY:react_renderer_runtimescheduler,INTERFACE_INCLUDE_DIRECTORIES>
319
326
  $<TARGET_PROPERTY:react_renderer_scheduler,INTERFACE_INCLUDE_DIRECTORIES>
320
327
  $<TARGET_PROPERTY:react_renderer_telemetry,INTERFACE_INCLUDE_DIRECTORIES>
@@ -11,6 +11,12 @@
11
11
 
12
12
  namespace facebook::react::jsinspector_modern {
13
13
 
14
+ bool JInspectorFlags::getScreenshotCaptureEnabled(
15
+ jni::alias_ref<jclass> /*unused*/) {
16
+ auto& inspectorFlags = InspectorFlags::getInstance();
17
+ return inspectorFlags.getScreenshotCaptureEnabled();
18
+ }
19
+
14
20
  bool JInspectorFlags::getFuseboxEnabled(jni::alias_ref<jclass> /*unused*/) {
15
21
  auto& inspectorFlags = InspectorFlags::getInstance();
16
22
  return inspectorFlags.getFuseboxEnabled();
@@ -21,7 +27,18 @@ bool JInspectorFlags::getIsProfilingBuild(jni::alias_ref<jclass> /*unused*/) {
21
27
  return inspectorFlags.getIsProfilingBuild();
22
28
  }
23
29
 
30
+ bool JInspectorFlags::getFrameRecordingEnabled(
31
+ jni::alias_ref<jclass> /*unused*/) {
32
+ auto& inspectorFlags = InspectorFlags::getInstance();
33
+ return inspectorFlags.getFrameRecordingEnabled();
34
+ }
35
+
24
36
  void JInspectorFlags::registerNatives() {
37
+ javaClassLocal()->registerNatives({
38
+ makeNativeMethod(
39
+ "getScreenshotCaptureEnabled",
40
+ JInspectorFlags::getScreenshotCaptureEnabled),
41
+ });
25
42
  javaClassLocal()->registerNatives({
26
43
  makeNativeMethod("getFuseboxEnabled", JInspectorFlags::getFuseboxEnabled),
27
44
  });
@@ -29,6 +46,11 @@ void JInspectorFlags::registerNatives() {
29
46
  makeNativeMethod(
30
47
  "getIsProfilingBuild", JInspectorFlags::getIsProfilingBuild),
31
48
  });
49
+ javaClassLocal()->registerNatives({
50
+ makeNativeMethod(
51
+ "getFrameRecordingEnabled",
52
+ JInspectorFlags::getFrameRecordingEnabled),
53
+ });
32
54
  }
33
55
 
34
56
  } // namespace facebook::react::jsinspector_modern
@@ -18,8 +18,10 @@ class JInspectorFlags : public jni::JavaClass<JInspectorFlags> {
18
18
  public:
19
19
  static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/InspectorFlags;";
20
20
 
21
+ static bool getScreenshotCaptureEnabled(jni::alias_ref<jclass> /*unused*/);
21
22
  static bool getFuseboxEnabled(jni::alias_ref<jclass> /*unused*/);
22
23
  static bool getIsProfilingBuild(jni::alias_ref<jclass> /*unused*/);
24
+ static bool getFrameRecordingEnabled(jni::alias_ref<jclass> /*unused*/);
23
25
 
24
26
  static void registerNatives();
25
27