@office-iss/react-native-win32 0.74.4 → 0.75.0-preview.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 (206) hide show
  1. package/.flowconfig +9 -4
  2. package/CHANGELOG.json +554 -51
  3. package/CHANGELOG.md +165 -30
  4. package/Libraries/Animated/AnimatedImplementation.js +2 -0
  5. package/Libraries/Animated/NativeAnimatedHelper.js +4 -0
  6. package/Libraries/Animated/NativeAnimatedHelper.win32.js +4 -0
  7. package/Libraries/Animated/createAnimatedComponent.js +10 -4
  8. package/Libraries/Animated/useAnimatedProps.js +56 -28
  9. package/Libraries/BatchedBridge/MessageQueue.js +1 -0
  10. package/Libraries/Components/Button.js +10 -5
  11. package/Libraries/Components/Button.win32.js +1 -0
  12. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +11 -2
  13. package/Libraries/Components/Pressable/Pressable.js +13 -6
  14. package/Libraries/Components/Pressable/Pressable.win32.js +13 -6
  15. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +4 -0
  16. package/Libraries/Components/ScrollView/ScrollView.js +109 -29
  17. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +6 -0
  18. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +13 -1
  19. package/Libraries/Components/StatusBar/StatusBar.js +1 -21
  20. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -15
  21. package/Libraries/Components/TextInput/InputAccessoryView.js +10 -1
  22. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +0 -12
  23. package/Libraries/Components/TextInput/TextInput.d.ts +0 -19
  24. package/Libraries/Components/TextInput/TextInput.js +14 -70
  25. package/Libraries/Components/TextInput/TextInput.win32.js +15 -72
  26. package/Libraries/Components/Touchable/Touchable.js +2 -2
  27. package/Libraries/Components/Touchable/TouchableHighlight.d.ts +4 -10
  28. package/Libraries/Components/Touchable/TouchableHighlight.js +3 -1
  29. package/Libraries/Components/Touchable/TouchableOpacity.d.ts +4 -32
  30. package/Libraries/Components/Touchable/TouchableOpacity.js +3 -1
  31. package/Libraries/Components/Touchable/TouchableWithoutFeedback.d.ts +8 -0
  32. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +117 -111
  33. package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -0
  34. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  35. package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +1 -0
  36. package/Libraries/Components/View/View.js +0 -11
  37. package/Libraries/Components/View/View.win32.js +0 -11
  38. package/Libraries/Components/View/ViewAccessibility.js +4 -4
  39. package/Libraries/Components/View/ViewAccessibility.win32.js +6 -6
  40. package/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
  41. package/Libraries/Components/View/ViewPropTypes.js +7 -0
  42. package/Libraries/Components/View/ViewPropTypes.win32.js +7 -0
  43. package/Libraries/Core/Devtools/loadBundleFromServer.js +3 -3
  44. package/Libraries/Core/Devtools/loadBundleFromServer.win32.js +153 -0
  45. package/Libraries/Core/Devtools/parseErrorStack.js +5 -5
  46. package/Libraries/Core/Devtools/parseHermesStack.js +22 -16
  47. package/Libraries/Core/ErrorHandlers.js +116 -0
  48. package/Libraries/Core/ExceptionsManager.js +2 -2
  49. package/Libraries/Core/ReactNativeVersion.js +3 -3
  50. package/Libraries/Core/setUpDeveloperTools.js +3 -1
  51. package/Libraries/Core/setUpPerformance.js +6 -4
  52. package/Libraries/Core/setUpReactDevTools.js +70 -10
  53. package/Libraries/Core/setUpTimers.js +50 -31
  54. package/Libraries/Debugging/DebuggingOverlayRegistry.js +1 -1
  55. package/Libraries/Image/Image.android.js +23 -13
  56. package/Libraries/Image/Image.d.ts +14 -15
  57. package/Libraries/Image/Image.ios.js +21 -11
  58. package/Libraries/Image/Image.win32.js +5 -3
  59. package/Libraries/Image/ImageProps.js +16 -5
  60. package/Libraries/Image/ImageTypes.flow.js +7 -2
  61. package/Libraries/Image/ImageUtils.js +1 -0
  62. package/Libraries/Image/ImageViewNativeComponent.js +2 -1
  63. package/Libraries/Inspector/ElementBox.js +6 -3
  64. package/Libraries/Inspector/ElementProperties.js +1 -1
  65. package/Libraries/Interaction/TouchHistoryMath.js +4 -4
  66. package/Libraries/IntersectionObserver/IntersectionObserverManager.js +6 -26
  67. package/Libraries/JSInspector/NetworkAgent.js +1 -1
  68. package/Libraries/LogBox/Data/LogBoxData.js +39 -29
  69. package/Libraries/LogBox/Data/LogBoxLog.js +114 -2
  70. package/Libraries/LogBox/Data/parseLogBoxLog.js +168 -53
  71. package/Libraries/LogBox/LogBox.js +29 -12
  72. package/Libraries/LogBox/LogBoxNotificationContainer.js +4 -0
  73. package/Libraries/LogBox/UI/LogBoxInspector.js +8 -70
  74. package/Libraries/LogBox/UI/LogBoxInspectorBody.js +87 -0
  75. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +6 -42
  76. package/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js +58 -0
  77. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +5 -66
  78. package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +8 -52
  79. package/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js +76 -0
  80. package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.js +8 -5
  81. package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.win32.js +8 -5
  82. package/Libraries/LogBox/UI/LogBoxNotification.js +13 -152
  83. package/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js +63 -0
  84. package/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js +67 -0
  85. package/Libraries/LogBox/UI/LogBoxNotificationMessage.js +57 -0
  86. package/Libraries/NativeComponent/BaseViewConfig.android.js +5 -0
  87. package/Libraries/NativeComponent/BaseViewConfig.ios.js +5 -0
  88. package/Libraries/NativeComponent/BaseViewConfig.win32.js +5 -0
  89. package/Libraries/NativeComponent/NativeComponentRegistry.js +12 -5
  90. package/Libraries/NativeComponent/StaticViewConfigValidator.js +3 -0
  91. package/Libraries/Network/XMLHttpRequest.js +5 -1
  92. package/Libraries/NewAppScreen/components/LearnMoreLinks.js +3 -3
  93. package/Libraries/Pressability/Pressability.js +3 -51
  94. package/Libraries/Pressability/Pressability.win32.js +3 -51
  95. package/Libraries/ReactNative/AppContainer-dev.js +3 -2
  96. package/Libraries/ReactNative/AppContainer-prod.js +2 -1
  97. package/Libraries/ReactNative/AppContainer.js +2 -0
  98. package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
  99. package/Libraries/ReactNative/AppRegistry.js +10 -4
  100. package/Libraries/ReactNative/BridgelessUIManager.js +1 -21
  101. package/Libraries/ReactNative/FabricUIManager.js +0 -51
  102. package/Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps.js +1 -0
  103. package/Libraries/ReactNative/RendererImplementation.js +20 -2
  104. package/Libraries/ReactNative/UIManager.d.ts +0 -21
  105. package/Libraries/ReactNative/UIManagerProperties.js +0 -3
  106. package/Libraries/ReactNative/__mocks__/FabricUIManager.js +5 -341
  107. package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -8
  108. package/Libraries/ReactNative/renderApplication.js +3 -0
  109. package/Libraries/Renderer/implementations/ReactFabric-dev.js +15682 -27088
  110. package/Libraries/Renderer/implementations/ReactFabric-prod.js +5082 -4381
  111. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +3480 -2571
  112. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +15943 -27543
  113. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +5303 -4606
  114. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +3450 -2572
  115. package/Libraries/Renderer/shims/ReactFabric.js +2 -2
  116. package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -2
  117. package/Libraries/Renderer/shims/ReactNative.js +2 -3
  118. package/Libraries/Renderer/shims/ReactNativeTypes.js +24 -3
  119. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -2
  120. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -2
  121. package/Libraries/Share/Share.d.ts +16 -10
  122. package/Libraries/Share/Share.js +14 -15
  123. package/Libraries/StyleSheet/StyleSheet.d.ts +1 -1
  124. package/Libraries/StyleSheet/StyleSheet.js +3 -10
  125. package/Libraries/StyleSheet/StyleSheet.win32.js +3 -10
  126. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +21 -21
  127. package/Libraries/StyleSheet/StyleSheetTypes.js +24 -18
  128. package/Libraries/StyleSheet/flattenStyle.js +1 -0
  129. package/Libraries/StyleSheet/processFilter.js +132 -0
  130. package/Libraries/StyleSheet/processTransform.js +18 -3
  131. package/Libraries/Text/Text.js +151 -128
  132. package/Libraries/Text/Text.win32.js +163 -138
  133. package/Libraries/Text/TextNativeComponent.js +5 -4
  134. package/Libraries/Text/TextNativeComponent.win32.js +5 -4
  135. package/Libraries/Text/TextProps.js +6 -6
  136. package/Libraries/Text/TextProps.win32.js +6 -6
  137. package/Libraries/TurboModule/TurboModuleRegistry.js +2 -1
  138. package/Libraries/Types/CodegenTypes.js +3 -0
  139. package/Libraries/Utilities/{LoadingView.android.js → DevLoadingView.js} +33 -11
  140. package/Libraries/Utilities/Dimensions.js +1 -0
  141. package/Libraries/Utilities/Dimensions.win32.js +1 -0
  142. package/Libraries/Utilities/HMRClient.js +36 -8
  143. package/Libraries/Utilities/HMRClientProdShim.js +1 -0
  144. package/Libraries/Utilities/Platform.android.js +4 -4
  145. package/Libraries/Utilities/RCTLog.js +1 -0
  146. package/Libraries/Utilities/ReactNativeTestTools.js +12 -24
  147. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +11 -6
  148. package/Libraries/__tests__/ButtonWin32-test.js +7 -6
  149. package/Libraries/promiseRejectionTrackingOptions.js +1 -0
  150. package/jest/mockComponent.js +7 -0
  151. package/jest/renderer.js +25 -14
  152. package/jest/setup.js +19 -13
  153. package/jest.config.js +2 -1
  154. package/overrides.json +30 -29
  155. package/package.json +27 -25
  156. package/rn-get-polyfills.js +1 -0
  157. package/src/private/core/composeStyles.js +27 -0
  158. package/src/private/featureflags/ReactNativeFeatureFlags.js +93 -33
  159. package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +23 -4
  160. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +56 -0
  161. package/src/private/fusebox/setUpFuseboxReactDevToolsDispatcher.js +108 -0
  162. package/src/private/specs/modules/NativeBlobModule.js +4 -2
  163. package/src/private/specs/modules/NativeDevSettings.js +1 -0
  164. package/src/private/specs/modules/NativePushNotificationManagerIOS.js +0 -4
  165. package/src/private/specs/modules/NativeUIManager.js +0 -7
  166. package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +24 -24
  167. package/src/private/webapis/dom/nodes/ReactNativeElement.js +11 -14
  168. package/src/private/webapis/dom/nodes/ReadOnlyCharacterData.js +2 -3
  169. package/src/private/webapis/dom/nodes/ReadOnlyElement.js +24 -54
  170. package/src/private/webapis/dom/nodes/ReadOnlyNode.js +5 -13
  171. package/src/private/webapis/dom/nodes/specs/NativeDOM.js +468 -0
  172. package/src/private/webapis/dom/nodes/specs/__mocks__/NativeDOMMock.js +413 -0
  173. package/src/private/webapis/dom/oldstylecollections/DOMRectList.js +4 -4
  174. package/src/private/webapis/dom/oldstylecollections/HTMLCollection.js +4 -4
  175. package/src/private/webapis/dom/oldstylecollections/NodeList.js +5 -5
  176. package/src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks.js +34 -0
  177. package/src/private/webapis/microtasks/specs/NativeMicrotasks.js +21 -0
  178. package/src/private/webapis/performance/EventCounts.js +1 -1
  179. package/src/private/webapis/performance/MemoryInfo.js +9 -9
  180. package/src/private/webapis/performance/Performance.js +10 -56
  181. package/src/private/webapis/performance/PerformanceObserver.js +30 -22
  182. package/src/private/webapis/performance/RawPerformanceEntry.js +2 -7
  183. package/src/private/webapis/performance/ReactNativeStartupTiming.js +18 -18
  184. package/src/private/webapis/performance/UserTiming.js +63 -0
  185. package/src/private/webapis/performance/{NativePerformance.js → specs/NativePerformance.js} +3 -2
  186. package/src/private/webapis/performance/{NativePerformanceObserver.js → specs/NativePerformanceObserver.js} +2 -2
  187. package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformance.js +1 -1
  188. package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformanceObserver.js +3 -4
  189. package/src-win/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
  190. package/types/modules/globals.d.ts +4 -0
  191. package/Libraries/Components/ScrollView/ScrollView.win32.js +0 -1915
  192. package/Libraries/NativeModules/specs/NativeAnimationsDebugModule.js +0 -13
  193. package/Libraries/Utilities/LoadingView.ios.js +0 -50
  194. package/Libraries/Utilities/LoadingView.js +0 -16
  195. package/jest/ReactNativeInternalFeatureFlagsMock.js +0 -13
  196. package/src/private/featureflags/NativeReactNativeFeatureFlags.js +0 -44
  197. package/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js +0 -92
  198. package/src/private/specs/modules/NativeAnimationsDebugModule.js +0 -20
  199. package/src/private/webapis/dom/oldstylecollections/__tests__/DOMRectList-test.js +0 -85
  200. package/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js +0 -80
  201. package/src/private/webapis/dom/oldstylecollections/__tests__/NodeList-test.js +0 -161
  202. package/src/private/webapis/performance/__tests__/EventCounts-test.js +0 -116
  203. package/src/private/webapis/performance/__tests__/NativePerformanceMock-test.js +0 -82
  204. package/src/private/webapis/performance/__tests__/NativePerformanceObserverMock-test.js +0 -108
  205. package/src/private/webapis/performance/__tests__/Performance-test.js +0 -117
  206. package/src/private/webapis/performance/__tests__/PerformanceObserver-test.js +0 -208
@@ -10,12 +10,52 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ import type {Domain} from '../../src/private/fusebox/setUpFuseboxReactDevToolsDispatcher';
14
+
13
15
  if (__DEV__) {
14
- let isWebSocketOpen = false;
15
- let ws = null;
16
+ // Register dispatcher on global, which can be used later by Chrome DevTools frontend
17
+ require('../../src/private/fusebox/setUpFuseboxReactDevToolsDispatcher');
16
18
 
19
+ // Install hook before React is loaded.
17
20
  const reactDevTools = require('react-devtools-core');
18
- const connectToDevTools = () => {
21
+ // This should be defined in DEV, otherwise error is expected.
22
+ const fuseboxReactDevToolsDispatcher =
23
+ global.__FUSEBOX_REACT_DEVTOOLS_DISPATCHER__;
24
+ const reactDevToolsFuseboxGlobalBindingName =
25
+ fuseboxReactDevToolsDispatcher.BINDING_NAME;
26
+
27
+ const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
28
+ const devToolsSettingsManager = require('../DevToolsSettings/DevToolsSettingsManager');
29
+ const resolveRNStyle = require('../StyleSheet/flattenStyle');
30
+
31
+ let disconnect = null;
32
+ function disconnectBackendFromReactDevToolsInFuseboxIfNeeded() {
33
+ if (disconnect != null) {
34
+ disconnect();
35
+ disconnect = null;
36
+ }
37
+ }
38
+
39
+ function connectToReactDevToolsInFusebox(domain: Domain) {
40
+ disconnect = reactDevTools.connectWithCustomMessagingProtocol({
41
+ onSubscribe: listener => {
42
+ domain.onMessage.addEventListener(listener);
43
+ },
44
+ onUnsubscribe: listener => {
45
+ domain.onMessage.removeEventListener(listener);
46
+ },
47
+ onMessage: (event, payload) => {
48
+ domain.sendMessage({event, payload});
49
+ },
50
+ settingsManager: devToolsSettingsManager,
51
+ nativeStyleEditorValidAttributes: Object.keys(ReactNativeStyleAttributes),
52
+ resolveRNStyle,
53
+ });
54
+ }
55
+
56
+ let isWebSocketOpen = false;
57
+ let ws = null;
58
+ function connectToWSBasedReactDevToolsFrontend() {
19
59
  if (ws !== null && isWebSocketOpen) {
20
60
  // If the DevTools backend is already connected, don't recreate the WebSocket.
21
61
  // This would break the connection.
@@ -61,12 +101,9 @@ if (__DEV__) {
61
101
  isWebSocketOpen = true;
62
102
  });
63
103
 
64
- const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
65
- const devToolsSettingsManager = require('../DevToolsSettings/DevToolsSettingsManager');
66
-
67
104
  reactDevTools.connectToDevTools({
68
105
  isAppActive,
69
- resolveRNStyle: require('../StyleSheet/flattenStyle'),
106
+ resolveRNStyle,
70
107
  nativeStyleEditorValidAttributes: Object.keys(
71
108
  ReactNativeStyleAttributes,
72
109
  ),
@@ -74,9 +111,32 @@ if (__DEV__) {
74
111
  devToolsSettingsManager,
75
112
  });
76
113
  }
77
- };
114
+ }
115
+
116
+ // 1. If React DevTools has already been opened and initialized in Fusebox, bindings survive reloads
117
+ if (global[reactDevToolsFuseboxGlobalBindingName] != null) {
118
+ disconnectBackendFromReactDevToolsInFuseboxIfNeeded();
119
+ const domain =
120
+ fuseboxReactDevToolsDispatcher.initializeDomain('react-devtools');
121
+ connectToReactDevToolsInFusebox(domain);
122
+ }
123
+
124
+ // 2. If React DevTools panel in Fusebox was opened for the first time after the runtime has been created
125
+ // 2. OR if React DevTools frontend was re-initialized: Chrome DevTools was closed and then re-opened
126
+ global.__FUSEBOX_REACT_DEVTOOLS_DISPATCHER__.onDomainInitialization.addEventListener(
127
+ (domain: Domain) => {
128
+ if (domain.name === 'react-devtools') {
129
+ disconnectBackendFromReactDevToolsInFuseboxIfNeeded();
130
+ connectToReactDevToolsInFusebox(domain);
131
+ }
132
+ },
133
+ );
78
134
 
135
+ // 3. Fallback to attempting to connect WS-based RDT frontend
79
136
  const RCTNativeAppEventEmitter = require('../EventEmitter/RCTNativeAppEventEmitter');
80
- RCTNativeAppEventEmitter.addListener('RCTDevMenuShown', connectToDevTools);
81
- connectToDevTools(); // Try connecting once on load
137
+ RCTNativeAppEventEmitter.addListener(
138
+ 'RCTDevMenuShown',
139
+ connectToWSBasedReactDevToolsFrontend,
140
+ );
141
+ connectToWSBasedReactDevToolsFrontend(); // Try connecting once on load
82
142
  }
@@ -10,7 +10,9 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- const {isNativeFunction} = require('../Utilities/FeatureDetection');
13
+ const ReactNativeFeatureFlags = require('../../src/private/featureflags/ReactNativeFeatureFlags');
14
+ const NativeReactNativeFeatureFlags =
15
+ require('../../src/private/featureflags/specs/NativeReactNativeFeatureFlags').default;
14
16
  const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
15
17
 
16
18
  if (__DEV__) {
@@ -19,14 +21,6 @@ if (__DEV__) {
19
21
  }
20
22
  }
21
23
 
22
- // Currently, Hermes `Promise` is implemented via Internal Bytecode.
23
- const hasHermesPromiseQueuedToJSVM =
24
- global.HermesInternal?.hasPromise?.() === true &&
25
- global.HermesInternal?.useEngineQueue?.() === true;
26
-
27
- const hasNativePromise = isNativeFunction(Promise);
28
- const hasPromiseQueuedToJSVM = hasNativePromise || hasHermesPromiseQueuedToJSVM;
29
-
30
24
  // In bridgeless mode, timers are host functions installed from cpp.
31
25
  if (global.RN$Bridgeless !== true) {
32
26
  /**
@@ -54,15 +48,49 @@ if (global.RN$Bridgeless !== true) {
54
48
  defineLazyTimer('cancelAnimationFrame');
55
49
  defineLazyTimer('requestIdleCallback');
56
50
  defineLazyTimer('cancelIdleCallback');
51
+ } else if (
52
+ // TODO remove this condition when bridgeless == modern scheduler everywhere.
53
+ NativeReactNativeFeatureFlags != null &&
54
+ // eslint-disable-next-line react-hooks/rules-of-hooks -- false positive due to `use` prefix
55
+ ReactNativeFeatureFlags.useModernRuntimeScheduler()
56
+ ) {
57
+ polyfillGlobal(
58
+ 'requestIdleCallback',
59
+ () =>
60
+ require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
61
+ .default.requestIdleCallback,
62
+ );
63
+
64
+ polyfillGlobal(
65
+ 'cancelIdleCallback',
66
+ () =>
67
+ require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
68
+ .default.cancelIdleCallback,
69
+ );
57
70
  }
58
71
 
59
- /**
60
- * Set up immediate APIs, which is required to use the same microtask queue
61
- * as the Promise.
62
- */
63
- if (hasPromiseQueuedToJSVM) {
64
- // When promise queues to the JSVM microtasks queue, we shim the immediate
65
- // APIs via `queueMicrotask` to maintain the backward compatibility.
72
+ // We need to check if the native module is available before accessing the
73
+ // feature flag, because otherwise the API would throw an error in the legacy
74
+ // architecture in OSS, where the native module isn't available.
75
+ if (
76
+ NativeReactNativeFeatureFlags != null &&
77
+ ReactNativeFeatureFlags.enableMicrotasks()
78
+ ) {
79
+ // This is the flag that tells React to use `queueMicrotask` to batch state
80
+ // updates, instead of using the scheduler to schedule a regular task.
81
+ // We use a global variable because we don't currently have any other
82
+ // mechanism to pass feature flags from RN to React in OSS.
83
+ global.RN$enableMicrotasksInReact = true;
84
+
85
+ polyfillGlobal(
86
+ 'queueMicrotask',
87
+ () =>
88
+ require('../../src/private/webapis/microtasks/specs/NativeMicrotasks')
89
+ .default.queueMicrotask,
90
+ );
91
+
92
+ // We shim the immediate APIs via `queueMicrotask` to maintain the backward
93
+ // compatibility.
66
94
  polyfillGlobal(
67
95
  'setImmediate',
68
96
  () => require('./Timers/immediateShim').setImmediate,
@@ -72,6 +100,12 @@ if (hasPromiseQueuedToJSVM) {
72
100
  () => require('./Timers/immediateShim').clearImmediate,
73
101
  );
74
102
  } else {
103
+ // Polyfill it with promise (regardless it's polyfilled or native) otherwise.
104
+ polyfillGlobal(
105
+ 'queueMicrotask',
106
+ () => require('./Timers/queueMicrotask.js').default,
107
+ );
108
+
75
109
  // When promise was polyfilled hence is queued to the RN microtask queue,
76
110
  // we polyfill the immediate APIs as aliases to the ReactNativeMicrotask APIs.
77
111
  // Note that in bridgeless mode, immediate APIs are installed from cpp.
@@ -86,18 +120,3 @@ if (hasPromiseQueuedToJSVM) {
86
120
  );
87
121
  }
88
122
  }
89
-
90
- /**
91
- * Set up the microtask queueing API, which is required to use the same
92
- * microtask queue as the Promise.
93
- */
94
- if (hasHermesPromiseQueuedToJSVM) {
95
- // Fast path for Hermes.
96
- polyfillGlobal('queueMicrotask', () => global.HermesInternal?.enqueueJob);
97
- } else {
98
- // Polyfill it with promise (regardless it's polyfilled or native) otherwise.
99
- polyfillGlobal(
100
- 'queueMicrotask',
101
- () => require('./Timers/queueMicrotask.js').default,
102
- );
103
- }
@@ -62,9 +62,9 @@ class DebuggingOverlayRegistry {
62
62
  constructor() {
63
63
  if (reactDevToolsHook?.reactDevtoolsAgent != null) {
64
64
  this.#onReactDevToolsAgentAttached(reactDevToolsHook.reactDevtoolsAgent);
65
- return;
66
65
  }
67
66
 
67
+ // There could be cases when frontend is disconnected and then connected again for the same React Native runtime.
68
68
  reactDevToolsHook?.on?.(
69
69
  'react-devtools',
70
70
  this.#onReactDevToolsAgentAttached,
@@ -23,7 +23,9 @@ import {
23
23
  import {getImageSourcesFromImageProps} from './ImageSourceUtils';
24
24
  import {convertObjectFitToResizeMode} from './ImageUtils';
25
25
  import ImageViewNativeComponent from './ImageViewNativeComponent';
26
- import NativeImageLoaderAndroid from './NativeImageLoaderAndroid';
26
+ import NativeImageLoaderAndroid, {
27
+ type ImageSize,
28
+ } from './NativeImageLoaderAndroid';
27
29
  import resolveAssetSource from './resolveAssetSource';
28
30
  import TextInlineImageNativeComponent from './TextInlineImageNativeComponent';
29
31
  import * as React from 'react';
@@ -40,13 +42,15 @@ function generateRequestId() {
40
42
  */
41
43
  function getSize(
42
44
  url: string,
43
- success: (width: number, height: number) => void,
45
+ success?: (width: number, height: number) => void,
44
46
  failure?: (error: mixed) => void,
45
- ): void {
46
- NativeImageLoaderAndroid.getSize(url)
47
- .then(function (sizes) {
48
- success(sizes.width, sizes.height);
49
- })
47
+ ): void | Promise<ImageSize> {
48
+ const promise = NativeImageLoaderAndroid.getSize(url);
49
+ if (typeof success !== 'function') {
50
+ return promise;
51
+ }
52
+ promise
53
+ .then(sizes => success(sizes.width, sizes.height))
50
54
  .catch(
51
55
  failure ||
52
56
  function () {
@@ -64,13 +68,15 @@ function getSize(
64
68
  function getSizeWithHeaders(
65
69
  url: string,
66
70
  headers: {[string]: string, ...},
67
- success: (width: number, height: number) => void,
71
+ success?: (width: number, height: number) => void,
68
72
  failure?: (error: mixed) => void,
69
- ): void {
70
- NativeImageLoaderAndroid.getSizeWithHeaders(url, headers)
71
- .then(function (sizes) {
72
- success(sizes.width, sizes.height);
73
- })
73
+ ): void | Promise<ImageSize> {
74
+ const promise = NativeImageLoaderAndroid.getSizeWithHeaders(url, headers);
75
+ if (typeof success !== 'function') {
76
+ return promise;
77
+ }
78
+ promise
79
+ .then(sizes => success(sizes.width, sizes.height))
74
80
  .catch(
75
81
  failure ||
76
82
  function () {
@@ -171,7 +177,11 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
171
177
  ...restProps,
172
178
  style,
173
179
  shouldNotifyLoadEvents: !!(onLoadStart || onLoad || onLoadEnd || onError),
180
+ // Both iOS and C++ sides expect to have "source" prop, whereas on Android it's "src"
181
+ // (for historical reasons). So in the latter case we populate both "src" and "source",
182
+ // in order to have a better alignment between platforms in the future.
174
183
  src: sources,
184
+ source: sources,
175
185
  /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
176
186
  * when making Flow check .android.js files. */
177
187
  headers: (source?.[0]?.headers || source?.headers: ?{[string]: string}),
@@ -325,20 +325,31 @@ export interface ImageProps extends ImagePropsBase {
325
325
  style?: StyleProp<ImageStyle> | undefined;
326
326
  }
327
327
 
328
+ export interface ImageSize {
329
+ width: number;
330
+ height: number;
331
+ }
332
+
328
333
  declare class ImageComponent extends React.Component<ImageProps> {}
329
334
  declare const ImageBase: Constructor<NativeMethods> & typeof ImageComponent;
330
335
  export class Image extends ImageBase {
336
+ static getSize(uri: string): Promise<ImageSize>;
331
337
  static getSize(
332
338
  uri: string,
333
339
  success: (width: number, height: number) => void,
334
340
  failure?: (error: any) => void,
335
- ): any;
341
+ ): void;
342
+
343
+ static getSizeWithHeaders(
344
+ uri: string,
345
+ headers: {[index: string]: string},
346
+ ): Promise<ImageSize>;
336
347
  static getSizeWithHeaders(
337
348
  uri: string,
338
349
  headers: {[index: string]: string},
339
350
  success: (width: number, height: number) => void,
340
351
  failure?: (error: any) => void,
341
- ): any;
352
+ ): void;
342
353
  static prefetch(url: string): Promise<boolean>;
343
354
  static prefetchWithMetadata(
344
355
  url: string,
@@ -368,16 +379,4 @@ export interface ImageBackgroundProps extends ImagePropsBase {
368
379
  declare class ImageBackgroundComponent extends React.Component<ImageBackgroundProps> {}
369
380
  declare const ImageBackgroundBase: Constructor<NativeMethods> &
370
381
  typeof ImageBackgroundComponent;
371
- export class ImageBackground extends ImageBackgroundBase {
372
- resizeMode: ImageResizeMode;
373
- getSize(
374
- uri: string,
375
- success: (width: number, height: number) => void,
376
- failure: (error: any) => void,
377
- ): any;
378
- prefetch(url: string): any;
379
- abortPrefetch?(requestId: number): void;
380
- queryCache?(
381
- urls: string[],
382
- ): Promise<{[url: string]: 'memory' | 'disk' | 'disk/memory'}>;
383
- }
382
+ export class ImageBackground extends ImageBackgroundBase {}
@@ -11,6 +11,7 @@
11
11
  import type {ImageStyle, ImageStyleProp} from '../StyleSheet/StyleSheet';
12
12
  import type {RootTag} from '../Types/RootTagTypes';
13
13
  import type {AbstractImageIOS, ImageIOS} from './ImageTypes.flow';
14
+ import type {ImageSize} from './NativeImageLoaderAndroid';
14
15
 
15
16
  import {createRootTag} from '../ReactNative/RootTag';
16
17
  import flattenStyle from '../StyleSheet/flattenStyle';
@@ -29,15 +30,22 @@ import * as React from 'react';
29
30
 
30
31
  function getSize(
31
32
  uri: string,
32
- success: (width: number, height: number) => void,
33
+ success?: (width: number, height: number) => void,
33
34
  failure?: (error: mixed) => void,
34
- ): void {
35
- NativeImageLoaderIOS.getSize(uri)
36
- .then(([width, height]) => success(width, height))
35
+ ): void | Promise<ImageSize> {
36
+ const promise = NativeImageLoaderIOS.getSize(uri).then(([width, height]) => ({
37
+ width,
38
+ height,
39
+ }));
40
+ if (typeof success !== 'function') {
41
+ return promise;
42
+ }
43
+ promise
44
+ .then(sizes => success(sizes.width, sizes.height))
37
45
  .catch(
38
46
  failure ||
39
47
  function () {
40
- console.warn('Failed to get size for image ' + uri);
48
+ console.warn('Failed to get size for image: ' + uri);
41
49
  },
42
50
  );
43
51
  }
@@ -45,13 +53,15 @@ function getSize(
45
53
  function getSizeWithHeaders(
46
54
  uri: string,
47
55
  headers: {[string]: string, ...},
48
- success: (width: number, height: number) => void,
56
+ success?: (width: number, height: number) => void,
49
57
  failure?: (error: mixed) => void,
50
- ): void {
51
- NativeImageLoaderIOS.getSizeWithHeaders(uri, headers)
52
- .then(function (sizes) {
53
- success(sizes.width, sizes.height);
54
- })
58
+ ): void | Promise<ImageSize> {
59
+ const promise = NativeImageLoaderIOS.getSizeWithHeaders(uri, headers);
60
+ if (typeof success !== 'function') {
61
+ return promise;
62
+ }
63
+ promise
64
+ .then(sizes => success(sizes.width, sizes.height))
55
65
  .catch(
56
66
  failure ||
57
67
  function () {
@@ -34,7 +34,7 @@ import * as React from 'react';
34
34
 
35
35
  function getSize(
36
36
  uri: string,
37
- success: (width: number, height: number) => void,
37
+ success?: (width: number, height: number) => void,
38
38
  // $FlowFixMe[unclear-type]
39
39
  failure?: (error: any) => void,
40
40
  ) {
@@ -45,7 +45,7 @@ function getSize(
45
45
  .catch(
46
46
  failure ||
47
47
  function () {
48
- console.warn('Failed to get size for image ' + uri);
48
+ console.warn('Failed to get size for image: ' + uri);
49
49
  },
50
50
  );
51
51
  */
@@ -55,6 +55,7 @@ function getSize(
55
55
  (width: number, height: number, err?: string) => {
56
56
  // $FlowFixMe[sketchy-null-string]
57
57
  if (!err) {
58
+ // $FlowFixMe[not-a-function]
58
59
  success(width, height);
59
60
  } else {
60
61
  if (failure) {
@@ -71,12 +72,13 @@ function getSize(
71
72
  function getSizeWithHeaders(
72
73
  uri: string,
73
74
  headers: {[string]: string, ...},
74
- success: (width: number, height: number) => void,
75
+ success?: (width: number, height: number) => void,
75
76
  failure?: (error: mixed) => void,
76
77
  // $FlowFixMe[unclear-type]
77
78
  ): any {
78
79
  return NativeImageLoaderWin32.getSizeWithHeaders(uri, headers)
79
80
  .then(function (sizes) {
81
+ // $FlowFixMe[not-a-function]
80
82
  success(sizes.width, sizes.height);
81
83
  })
82
84
  .catch(
@@ -59,6 +59,22 @@ type AndroidImageProps = $ReadOnly<{|
59
59
  loadingIndicatorSource?: ?(number | $ReadOnly<{|uri: string|}>),
60
60
  progressiveRenderingEnabled?: ?boolean,
61
61
  fadeDuration?: ?number,
62
+
63
+ /**
64
+ * The mechanism that should be used to resize the image when the image's
65
+ * dimensions differ from the image view's dimensions. Defaults to `'auto'`.
66
+ * See https://reactnative.dev/docs/image#resizemethod-android
67
+ */
68
+ resizeMethod?: ?('auto' | 'resize' | 'scale'),
69
+
70
+ /**
71
+ * When the `resizeMethod` is set to `resize`, the destination dimensions are
72
+ * multiplied by this value. The `scale` method is used to perform the
73
+ * remainder of the resize.
74
+ * This is used to produce higher quality images when resizing to small dimensions.
75
+ * Defaults to 1.0.
76
+ */
77
+ resizeMultiplier?: ?number,
62
78
  |}>;
63
79
 
64
80
  export type ImageProps = {|
@@ -183,11 +199,6 @@ export type ImageProps = {|
183
199
  */
184
200
  onLoadStart?: ?() => void,
185
201
 
186
- /**
187
- * See https://reactnative.dev/docs/image#resizemethod
188
- */
189
- resizeMethod?: ?('auto' | 'resize' | 'scale'),
190
-
191
202
  /**
192
203
  * The image source (either a remote URL or a local file resource).
193
204
  *
@@ -18,12 +18,17 @@ import typeof TextInlineImageNativeComponent from './TextInlineImageNativeCompon
18
18
  import * as React from 'react';
19
19
 
20
20
  type ImageComponentStaticsIOS = $ReadOnly<{
21
- getSize: (
21
+ getSize(uri: string): Promise<{width: number, height: number}>,
22
+ getSize(
22
23
  uri: string,
23
24
  success: (width: number, height: number) => void,
24
25
  failure?: (error: mixed) => void,
25
- ) => void,
26
+ ): void,
26
27
 
28
+ getSizeWithHeaders(
29
+ uri: string,
30
+ headers: {[string]: string, ...},
31
+ ): Promise<{width: number, height: number}>,
27
32
  getSizeWithHeaders(
28
33
  uri: string,
29
34
  headers: {[string]: string, ...},
@@ -17,5 +17,6 @@ export function convertObjectFitToResizeMode(objectFit: string): ResizeMode {
17
17
  fill: 'stretch',
18
18
  'scale-down': 'contain',
19
19
  };
20
+ // $FlowFixMe[invalid-computed-prop]
20
21
  return objectFitMap[objectFit];
21
22
  }
@@ -82,13 +82,14 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
82
82
  validAttributes: {
83
83
  blurRadius: true,
84
84
  internal_analyticTag: true,
85
+ resizeMethod: true,
85
86
  resizeMode: true,
87
+ resizeMultiplier: true,
86
88
  tintColor: {
87
89
  process: require('../StyleSheet/processColor').default,
88
90
  },
89
91
  borderBottomLeftRadius: true,
90
92
  borderTopLeftRadius: true,
91
- resizeMethod: true,
92
93
  src: true,
93
94
  // NOTE: New Architecture expects this to be called `source`,
94
95
  // regardless of the platform, therefore propagate it as well.
@@ -20,10 +20,9 @@ const React = require('react');
20
20
 
21
21
  class ElementBox extends React.Component<$FlowFixMeProps> {
22
22
  render(): React.Node {
23
- // $FlowFixMe[underconstrained-implicit-instantiation]
24
23
  const style = flattenStyle(this.props.style) || {};
25
- let margin = resolveBoxStyle('margin', style);
26
- let padding = resolveBoxStyle('padding', style);
24
+ let margin: ?$ReadOnly<Style> = resolveBoxStyle('margin', style);
25
+ let padding: ?$ReadOnly<Style> = resolveBoxStyle('padding', style);
27
26
 
28
27
  const frameStyle = {...this.props.frame};
29
28
  const contentStyle: {width: number, height: number} = {
@@ -122,13 +121,17 @@ function resolveSizeInPlace(
122
121
  direction: string,
123
122
  dimension: string,
124
123
  ) {
124
+ // $FlowFixMe[invalid-computed-prop]
125
125
  if (style[direction] !== null && typeof style[direction] === 'string') {
126
126
  if (style[direction].indexOf('%') !== -1) {
127
127
  // $FlowFixMe[prop-missing]
128
128
  style[direction] =
129
+ // $FlowFixMe[invalid-computed-prop]
129
130
  (parseFloat(style[direction]) / 100.0) *
131
+ // $FlowFixMe[invalid-computed-prop]
130
132
  Dimensions.get('window')[dimension];
131
133
  }
134
+ // $FlowFixMe[invalid-computed-prop]
132
135
  if (style[direction] === 'auto') {
133
136
  // Ignore auto sizing in frame drawing due to complexity of correctly rendering this
134
137
  // $FlowFixMe[prop-missing]
@@ -71,7 +71,7 @@ class ElementProperties extends React.Component<Props> {
71
71
  <View style={styles.col}>
72
72
  <StyleInspector style={style} />
73
73
  </View>
74
- {<BoxInspector style={style} frame={this.props.frame} />}
74
+ <BoxInspector style={style} frame={this.props.frame} />
75
75
  </View>
76
76
  </View>
77
77
  </TouchableWithoutFeedback>
@@ -48,10 +48,10 @@ const TouchHistoryMath = {
48
48
  ofCurrent && isXAxis
49
49
  ? oneTouchData.currentPageX
50
50
  : ofCurrent && !isXAxis
51
- ? oneTouchData.currentPageY
52
- : !ofCurrent && isXAxis
53
- ? oneTouchData.previousPageX
54
- : oneTouchData.previousPageY;
51
+ ? oneTouchData.currentPageY
52
+ : !ofCurrent && isXAxis
53
+ ? oneTouchData.previousPageX
54
+ : oneTouchData.previousPageY;
55
55
  count = 1;
56
56
  }
57
57
  } else {
@@ -67,19 +67,11 @@ function setTargetForInstanceHandle(
67
67
  instanceHandleToTargetMap.set(key, target);
68
68
  }
69
69
 
70
- function unsetTargetForInstanceHandle(instanceHandle: mixed): void {
71
- // $FlowExpectedError[incompatible-type] instanceHandle is typed as mixed but we know it's an object and we need it to be to use it as a key in a WeakMap.
72
- const key: interface {} = instanceHandle;
73
- instanceHandleToTargetMap.delete(key);
74
- }
75
-
76
70
  // The mapping between ReactNativeElement and their corresponding shadow node
77
71
  // also needs to be kept here because React removes the link when unmounting.
78
- // We also keep the instance handle so we don't have to retrieve it again
79
- // from the target to unobserve.
80
- const targetToShadowNodeAndInstanceHandleMap: WeakMap<
72
+ const targetToShadowNodeMap: WeakMap<
81
73
  ReactNativeElement,
82
- [ReturnType<typeof getShadowNode>, mixed],
74
+ ReturnType<typeof getShadowNode>,
83
75
  > = new WeakMap();
84
76
 
85
77
  /**
@@ -163,12 +155,8 @@ export function observe({
163
155
  // access it even after the instance handle has been unmounted.
164
156
  setTargetForInstanceHandle(instanceHandle, target);
165
157
 
166
- // Same for the mapping between the target and its shadow node
167
- // and instance handle.
168
- targetToShadowNodeAndInstanceHandleMap.set(target, [
169
- targetShadowNode,
170
- instanceHandle,
171
- ]);
158
+ // Same for the mapping between the target and its shadow node.
159
+ targetToShadowNodeMap.set(target, targetShadowNode);
172
160
 
173
161
  if (!isConnected) {
174
162
  NativeIntersectionObserver.connect(notifyIntersectionObservers);
@@ -201,26 +189,18 @@ export function unobserve(
201
189
  return;
202
190
  }
203
191
 
204
- const targetShadowNodeAndInstanceHandle =
205
- targetToShadowNodeAndInstanceHandleMap.get(target);
206
- if (targetShadowNodeAndInstanceHandle == null) {
192
+ const targetShadowNode = targetToShadowNodeMap.get(target);
193
+ if (targetShadowNode == null) {
207
194
  console.error(
208
195
  'IntersectionObserverManager: could not find registration data for target',
209
196
  );
210
197
  return;
211
198
  }
212
199
 
213
- const [targetShadowNode, instanceHandle] = targetShadowNodeAndInstanceHandle;
214
-
215
200
  NativeIntersectionObserver.unobserve(
216
201
  intersectionObserverId,
217
202
  targetShadowNode,
218
203
  );
219
-
220
- // We can guarantee we won't receive any more entries for this target,
221
- // so we don't need to keep the mappings anymore.
222
- unsetTargetForInstanceHandle(instanceHandle);
223
- targetToShadowNodeAndInstanceHandleMap.delete(target);
224
204
  }
225
205
 
226
206
  /**
@@ -232,7 +232,7 @@ class Interceptor {
232
232
  const event: LoadingFinishedEvent = {
233
233
  requestId: String(id),
234
234
  timestamp: JSInspector.getTimestamp(),
235
- encodedDataLength: encodedDataLength,
235
+ encodedDataLength,
236
236
  };
237
237
  this._agent.sendEvent('loadingFinished', event);
238
238
  }