@office-iss/react-native-win32 0.0.0-canary.260 → 0.0.0-canary.262

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 (51) hide show
  1. package/.flowconfig +4 -3
  2. package/CHANGELOG.json +37 -1
  3. package/CHANGELOG.md +21 -4
  4. package/Libraries/Animated/nodes/AnimatedObject.js +2 -5
  5. package/Libraries/Animated/nodes/AnimatedProps.js +2 -0
  6. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +0 -3
  7. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +0 -3
  8. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -3
  9. package/Libraries/Components/TextInput/TextInput.js +20 -24
  10. package/Libraries/Components/TextInput/TextInput.win32.js +20 -24
  11. package/Libraries/Components/View/ViewNativeComponent.js +0 -7
  12. package/Libraries/Core/ReactNativeVersion.js +1 -1
  13. package/Libraries/Image/ImageViewNativeComponent.js +0 -3
  14. package/Libraries/Lists/SectionListModern.js +2 -2
  15. package/Libraries/LogBox/Data/LogBoxData.js +8 -14
  16. package/Libraries/Modal/Modal.js +0 -1
  17. package/Libraries/NativeComponent/BaseViewConfig.android.js +6 -0
  18. package/Libraries/NativeComponent/NativeComponentRegistry.js +13 -20
  19. package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -21
  20. package/Libraries/ReactNative/RendererImplementation.js +2 -2
  21. package/Libraries/Renderer/shims/ReactNativeTypes.js +9 -4
  22. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +3 -3
  23. package/Libraries/StyleSheet/StyleSheetTypes.js +1 -1
  24. package/Libraries/StyleSheet/processBackgroundImage.js +137 -39
  25. package/Libraries/StyleSheet/processBoxShadow.js +1 -1
  26. package/Libraries/StyleSheet/processFilter.js +9 -5
  27. package/Libraries/Text/Text.win32.js +1 -1
  28. package/Libraries/Text/TextNativeComponent.js +0 -6
  29. package/Libraries/Text/TextNativeComponent.win32.js +0 -6
  30. package/Libraries/Utilities/Appearance.js +108 -84
  31. package/Libraries/Utilities/DevLoadingView.js +2 -4
  32. package/Libraries/Utilities/HMRClient.js +1 -1
  33. package/Libraries/Utilities/createPerformanceLogger.js +0 -9
  34. package/Libraries/Utilities/stringifyViewConfig.js +22 -0
  35. package/Libraries/Utilities/useColorScheme.js +3 -3
  36. package/Libraries/promiseRejectionTrackingOptions.js +1 -1
  37. package/index.js +1 -1
  38. package/index.win32.js +1 -1
  39. package/jest/setup.js +0 -4
  40. package/overrides.json +5 -5
  41. package/package.json +13 -13
  42. package/src/private/featureflags/ReactNativeFeatureFlags.js +27 -6
  43. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +5 -2
  44. package/src/private/fusebox/FuseboxSessionObserver.js +42 -0
  45. package/src/private/specs/modules/NativeAppearance.js +3 -3
  46. package/src/private/webapis/intersectionobserver/IntersectionObserver.js +4 -2
  47. package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +9 -9
  48. package/src/private/webapis/mutationobserver/MutationObserver.js +4 -2
  49. package/src/private/webapis/mutationobserver/MutationObserverManager.js +19 -10
  50. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +0 -135
  51. package/src/private/specs/modules/NativeDebuggerSessionObserver.js +0 -23
package/jest/setup.js CHANGED
@@ -392,10 +392,6 @@ jest
392
392
  .mock('../Libraries/ReactNative/requireNativeComponent', () => {
393
393
  return jest.requireActual('./mockNativeComponent');
394
394
  })
395
- .mock(
396
- '../Libraries/Utilities/verifyComponentAttributeEquivalence',
397
- () => function () {},
398
- )
399
395
  .mock('../Libraries/Vibration/Vibration', () => ({
400
396
  vibrate: jest.fn(),
401
397
  cancel: jest.fn(),
package/overrides.json CHANGED
@@ -7,19 +7,19 @@
7
7
  "**/__snapshots__/**",
8
8
  "src-win/rntypes/**"
9
9
  ],
10
- "baseVersion": "0.76.0-nightly-20240816-17017d2b8",
10
+ "baseVersion": "0.76.0-nightly-20240901-305b4357e",
11
11
  "overrides": [
12
12
  {
13
13
  "type": "derived",
14
14
  "file": ".flowconfig",
15
15
  "baseFile": ".flowconfig",
16
- "baseHash": "3d94d14740956b3455abfbdff5e043212d04974b"
16
+ "baseHash": "67b097833fd6733db6c64c57fbcb2efb3e9b51c5"
17
17
  },
18
18
  {
19
19
  "type": "derived",
20
20
  "file": "src-win/index.win32.js",
21
21
  "baseFile": "packages/react-native/index.js",
22
- "baseHash": "dc1e45b643d33d868da60fa27da2cbda0231b7f3"
22
+ "baseHash": "da5d9e79c8c14c56ba00f73c8514c06e6fffe8ed"
23
23
  },
24
24
  {
25
25
  "type": "platform",
@@ -116,7 +116,7 @@
116
116
  "type": "derived",
117
117
  "file": "src-win/Libraries/Components/TextInput/TextInput.win32.js",
118
118
  "baseFile": "packages/react-native/Libraries/Components/TextInput/TextInput.js",
119
- "baseHash": "259941a60002c5a2a4166a39404d099f0472941e"
119
+ "baseHash": "494c1159a38de1b57d3889a4dabdc3708204ad4d"
120
120
  },
121
121
  {
122
122
  "type": "patch",
@@ -445,7 +445,7 @@
445
445
  "type": "derived",
446
446
  "file": "src-win/Libraries/Text/TextNativeComponent.win32.js",
447
447
  "baseFile": "packages/react-native/Libraries/Text/TextNativeComponent.js",
448
- "baseHash": "dcb764530f8a6529152d9791597865034e2c36ae",
448
+ "baseHash": "642b6fc1c5b5802e3612f39c2ae0135b149a65f8",
449
449
  "issue": 7074
450
450
  },
451
451
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@office-iss/react-native-win32",
3
- "version": "0.0.0-canary.260",
3
+ "version": "0.0.0-canary.262",
4
4
  "description": "Implementation of react native on top of Office's Win32 platform.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,13 +30,13 @@
30
30
  "@react-native-community/cli-platform-android": "14.0.0",
31
31
  "@react-native-community/cli-platform-ios": "14.0.0",
32
32
  "@react-native/assets": "1.0.0",
33
- "@react-native/assets-registry": "0.76.0-nightly-20240816-17017d2b8",
34
- "@react-native/codegen": "0.76.0-nightly-20240816-17017d2b8",
35
- "@react-native/community-cli-plugin": "0.76.0-nightly-20240816-17017d2b8",
36
- "@react-native/gradle-plugin": "0.76.0-nightly-20240816-17017d2b8",
37
- "@react-native/js-polyfills": "0.76.0-nightly-20240816-17017d2b8",
38
- "@react-native/normalize-colors": "0.76.0-nightly-20240816-17017d2b8",
39
- "@react-native/virtualized-lists": "0.76.0-nightly-20240816-17017d2b8",
33
+ "@react-native/assets-registry": "0.76.0-nightly-20240901-305b4357e",
34
+ "@react-native/codegen": "0.76.0-nightly-20240901-305b4357e",
35
+ "@react-native/community-cli-plugin": "0.76.0-nightly-20240901-305b4357e",
36
+ "@react-native/gradle-plugin": "0.76.0-nightly-20240901-305b4357e",
37
+ "@react-native/js-polyfills": "0.76.0-nightly-20240901-305b4357e",
38
+ "@react-native/normalize-colors": "0.76.0-nightly-20240901-305b4357e",
39
+ "@react-native/virtualized-lists": "0.76.0-nightly-20240901-305b4357e",
40
40
  "abort-controller": "^3.0.0",
41
41
  "anser": "^1.4.9",
42
42
  "ansi-regex": "^5.0.0",
@@ -50,8 +50,8 @@
50
50
  "jest-environment-node": "^29.6.3",
51
51
  "jsc-android": "^250231.0.0",
52
52
  "memoize-one": "^5.0.0",
53
- "metro-runtime": "^0.80.3",
54
- "metro-source-map": "^0.80.3",
53
+ "metro-runtime": "^0.80.10",
54
+ "metro-source-map": "^0.80.10",
55
55
  "mkdirp": "^0.5.1",
56
56
  "nullthrows": "^1.1.1",
57
57
  "pretty-format": "^26.5.2",
@@ -82,19 +82,19 @@
82
82
  "@types/prop-types": "15.7.1",
83
83
  "@types/react": "^18.2.6",
84
84
  "eslint": "^8.19.0",
85
- "flow-bin": "^0.241.0",
85
+ "flow-bin": "^0.245.0",
86
86
  "jscodeshift": "^0.14.0",
87
87
  "just-scripts": "^1.3.3",
88
88
  "prettier": "2.8.8",
89
89
  "react": "19.0.0-rc-fb9a90fa48-20240614",
90
- "react-native": "0.76.0-nightly-20240816-17017d2b8",
90
+ "react-native": "0.76.0-nightly-20240901-305b4357e",
91
91
  "react-native-platform-override": "^1.9.45",
92
92
  "typescript": "5.0.4"
93
93
  },
94
94
  "peerDependencies": {
95
95
  "@types/react": "^18.2.6",
96
96
  "react": "^19.0.0-rc-fb9a90fa48-20240614",
97
- "react-native": "0.76.0-nightly-20240816-17017d2b8"
97
+ "react-native": "0.76.0-nightly-20240901-305b4357e"
98
98
  },
99
99
  "beachball": {
100
100
  "defaultNpmTag": "canary",
@@ -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<<fb7a3dcf7b3e5001e45f808fb4410376>>
7
+ * @generated SignedSource<<3693bce1a6719ef03c1c3148230771b4>>
8
8
  * @flow strict-local
9
9
  */
10
10
 
@@ -30,6 +30,7 @@ export type ReactNativeFeatureFlagsJsOnly = {
30
30
  animatedShouldDebounceQueueFlush: Getter<boolean>,
31
31
  animatedShouldUseSingleOp: Getter<boolean>,
32
32
  enableAccessToHostTreeInFabric: Getter<boolean>,
33
+ enableOptimisedVirtualizedCells: Getter<boolean>,
33
34
  isLayoutAnimationEnabled: Getter<boolean>,
34
35
  shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean>,
35
36
  shouldUseAnimatedObjectForTransform: Getter<boolean>,
@@ -48,7 +49,6 @@ export type ReactNativeFeatureFlags = {
48
49
  commonTestFlag: Getter<boolean>,
49
50
  allowRecursiveCommitsWithSynchronousMountOnAndroid: Getter<boolean>,
50
51
  batchRenderingUpdatesInEventLoop: Getter<boolean>,
51
- changeOrderOfMountingInstructionsOnAndroid: Getter<boolean>,
52
52
  completeReactInstanceCreationOnBgThreadOnAndroid: Getter<boolean>,
53
53
  destroyFabricSurfacesInReactInstanceManager: Getter<boolean>,
54
54
  enableAlignItemsBaselineOnFabricIOS: Getter<boolean>,
@@ -60,6 +60,8 @@ export type ReactNativeFeatureFlags = {
60
60
  enableFabricLogs: Getter<boolean>,
61
61
  enableFabricRendererExclusively: Getter<boolean>,
62
62
  enableGranularShadowTreeStateReconciliation: Getter<boolean>,
63
+ enableIOSViewClipToPaddingBox: Getter<boolean>,
64
+ enableLayoutAnimationsOnIOS: Getter<boolean>,
63
65
  enableLongTaskAPI: Getter<boolean>,
64
66
  enableMicrotasks: Getter<boolean>,
65
67
  enablePropsUpdateReconciliationAndroid: Getter<boolean>,
@@ -72,6 +74,7 @@ export type ReactNativeFeatureFlags = {
72
74
  fixIncorrectScrollViewStateUpdateOnAndroid: Getter<boolean>,
73
75
  fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean>,
74
76
  fixMissedFabricStateUpdatesOnAndroid: Getter<boolean>,
77
+ fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter<boolean>,
75
78
  forceBatchingMountItemsOnAndroid: Getter<boolean>,
76
79
  fuseboxEnabledDebug: Getter<boolean>,
77
80
  fuseboxEnabledRelease: Getter<boolean>,
@@ -86,6 +89,7 @@ export type ReactNativeFeatureFlags = {
86
89
  useNativeViewConfigsInBridgelessMode: Getter<boolean>,
87
90
  useNewReactImageViewBackgroundDrawing: Getter<boolean>,
88
91
  useOptimisedViewPreallocationOnAndroid: Getter<boolean>,
92
+ useOptimizedEventBatchingOnAndroid: Getter<boolean>,
89
93
  useRuntimeShadowNodeReferenceUpdate: Getter<boolean>,
90
94
  useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean>,
91
95
  useStateAlignmentMechanism: Getter<boolean>,
@@ -112,6 +116,11 @@ export const animatedShouldUseSingleOp: Getter<boolean> = createJavaScriptFlagGe
112
116
  */
113
117
  export const enableAccessToHostTreeInFabric: Getter<boolean> = createJavaScriptFlagGetter('enableAccessToHostTreeInFabric', false);
114
118
 
119
+ /**
120
+ * Removing unnecessary rerenders Virtualized cells after any rerenders of Virualized list. Works with strict=true option
121
+ */
122
+ export const enableOptimisedVirtualizedCells: Getter<boolean> = createJavaScriptFlagGetter('enableOptimisedVirtualizedCells', false);
123
+
115
124
  /**
116
125
  * Function used to enable / disabled Layout Animations in React Native.
117
126
  */
@@ -169,10 +178,6 @@ export const allowRecursiveCommitsWithSynchronousMountOnAndroid: Getter<boolean>
169
178
  * When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
170
179
  */
171
180
  export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false);
172
- /**
173
- * When enabled, insert of views on Android will be moved from the beginning of the IntBufferBatchMountItem to be after layout updates.
174
- */
175
- export const changeOrderOfMountingInstructionsOnAndroid: Getter<boolean> = createNativeFlagGetter('changeOrderOfMountingInstructionsOnAndroid', false);
176
181
  /**
177
182
  * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android
178
183
  */
@@ -217,6 +222,14 @@ export const enableFabricRendererExclusively: Getter<boolean> = createNativeFlag
217
222
  * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing.
218
223
  */
219
224
  export const enableGranularShadowTreeStateReconciliation: Getter<boolean> = createNativeFlagGetter('enableGranularShadowTreeStateReconciliation', false);
225
+ /**
226
+ * iOS Views will clip to their padding box vs border box
227
+ */
228
+ export const enableIOSViewClipToPaddingBox: Getter<boolean> = createNativeFlagGetter('enableIOSViewClipToPaddingBox', false);
229
+ /**
230
+ * When enabled, LayoutAnimations API will animate state changes on iOS.
231
+ */
232
+ export const enableLayoutAnimationsOnIOS: Getter<boolean> = createNativeFlagGetter('enableLayoutAnimationsOnIOS', true);
220
233
  /**
221
234
  * Enables the reporting of long tasks through `PerformanceObserver`. Only works if the event loop is enabled.
222
235
  */
@@ -265,6 +278,10 @@ export const fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean> =
265
278
  * Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.
266
279
  */
267
280
  export const fixMissedFabricStateUpdatesOnAndroid: Getter<boolean> = createNativeFlagGetter('fixMissedFabricStateUpdatesOnAndroid', false);
281
+ /**
282
+ * Fixes a limitation on Android where the mounting coordinator would report there are no pending transactions but some of them were actually not processed due to the use of the push model.
283
+ */
284
+ export const fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter<boolean> = createNativeFlagGetter('fixMountingCoordinatorReportedPendingTransactionsOnAndroid', false);
268
285
  /**
269
286
  * Forces the mounting layer on Android to always batch mount items instead of dispatching them immediately. This might fix some crashes related to synchronous state updates, where some views dispatch state updates during mount.
270
287
  */
@@ -321,6 +338,10 @@ export const useNewReactImageViewBackgroundDrawing: Getter<boolean> = createNati
321
338
  * Moves more of the work in view preallocation to the main thread to free up JS thread.
322
339
  */
323
340
  export const useOptimisedViewPreallocationOnAndroid: Getter<boolean> = createNativeFlagGetter('useOptimisedViewPreallocationOnAndroid', false);
341
+ /**
342
+ * Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback.
343
+ */
344
+ export const useOptimizedEventBatchingOnAndroid: Getter<boolean> = createNativeFlagGetter('useOptimizedEventBatchingOnAndroid', false);
324
345
  /**
325
346
  * When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree.
326
347
  */
@@ -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<<9728234e0662758c72ba79b3cffbd4e5>>
7
+ * @generated SignedSource<<6d4aa48dfdd3b78ac5f0f8e70eb3895f>>
8
8
  * @flow strict-local
9
9
  */
10
10
 
@@ -26,7 +26,6 @@ export interface Spec extends TurboModule {
26
26
  +commonTestFlag?: () => boolean;
27
27
  +allowRecursiveCommitsWithSynchronousMountOnAndroid?: () => boolean;
28
28
  +batchRenderingUpdatesInEventLoop?: () => boolean;
29
- +changeOrderOfMountingInstructionsOnAndroid?: () => boolean;
30
29
  +completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean;
31
30
  +destroyFabricSurfacesInReactInstanceManager?: () => boolean;
32
31
  +enableAlignItemsBaselineOnFabricIOS?: () => boolean;
@@ -38,6 +37,8 @@ export interface Spec extends TurboModule {
38
37
  +enableFabricLogs?: () => boolean;
39
38
  +enableFabricRendererExclusively?: () => boolean;
40
39
  +enableGranularShadowTreeStateReconciliation?: () => boolean;
40
+ +enableIOSViewClipToPaddingBox?: () => boolean;
41
+ +enableLayoutAnimationsOnIOS?: () => boolean;
41
42
  +enableLongTaskAPI?: () => boolean;
42
43
  +enableMicrotasks?: () => boolean;
43
44
  +enablePropsUpdateReconciliationAndroid?: () => boolean;
@@ -50,6 +51,7 @@ export interface Spec extends TurboModule {
50
51
  +fixIncorrectScrollViewStateUpdateOnAndroid?: () => boolean;
51
52
  +fixMappingOfEventPrioritiesBetweenFabricAndReact?: () => boolean;
52
53
  +fixMissedFabricStateUpdatesOnAndroid?: () => boolean;
54
+ +fixMountingCoordinatorReportedPendingTransactionsOnAndroid?: () => boolean;
53
55
  +forceBatchingMountItemsOnAndroid?: () => boolean;
54
56
  +fuseboxEnabledDebug?: () => boolean;
55
57
  +fuseboxEnabledRelease?: () => boolean;
@@ -64,6 +66,7 @@ export interface Spec extends TurboModule {
64
66
  +useNativeViewConfigsInBridgelessMode?: () => boolean;
65
67
  +useNewReactImageViewBackgroundDrawing?: () => boolean;
66
68
  +useOptimisedViewPreallocationOnAndroid?: () => boolean;
69
+ +useOptimizedEventBatchingOnAndroid?: () => boolean;
67
70
  +useRuntimeShadowNodeReferenceUpdate?: () => boolean;
68
71
  +useRuntimeShadowNodeReferenceUpdateOnLayout?: () => boolean;
69
72
  +useStateAlignmentMechanism?: () => boolean;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ class FuseboxSessionObserver {
13
+ #hasNativeSupport: boolean;
14
+
15
+ constructor() {
16
+ this.#hasNativeSupport = global.hasOwnProperty(
17
+ '__DEBUGGER_SESSION_OBSERVER__',
18
+ );
19
+ }
20
+
21
+ hasActiveSession(): boolean {
22
+ if (!this.#hasNativeSupport) {
23
+ return false;
24
+ }
25
+
26
+ return global.__DEBUGGER_SESSION_OBSERVER__.hasActiveSession;
27
+ }
28
+
29
+ subscribe(callback: (status: boolean) => void): () => void {
30
+ if (!this.#hasNativeSupport) {
31
+ return () => {};
32
+ }
33
+
34
+ global.__DEBUGGER_SESSION_OBSERVER__.subscribers.add(callback);
35
+ return () => {
36
+ global.__DEBUGGER_SESSION_OBSERVER__.subscribers.delete(callback);
37
+ };
38
+ }
39
+ }
40
+
41
+ const observerInstance: FuseboxSessionObserver = new FuseboxSessionObserver();
42
+ export default observerInstance;
@@ -14,19 +14,19 @@ import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboMod
14
14
 
15
15
  export type ColorSchemeName = 'light' | 'dark';
16
16
 
17
- export type AppearancePreferences = {|
17
+ export type AppearancePreferences = {
18
18
  // TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
19
19
  // types.
20
20
  /* 'light' | 'dark' */
21
21
  colorScheme?: ?string,
22
- |};
22
+ };
23
23
 
24
24
  export interface Spec extends TurboModule {
25
25
  // TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
26
26
  // types.
27
27
  /* 'light' | 'dark' */
28
28
  +getColorScheme: () => ?string;
29
- +setColorScheme?: (colorScheme: string) => void;
29
+ +setColorScheme: (colorScheme: string) => void;
30
30
 
31
31
  // RCTEventEmitter
32
32
  +addListener: (eventName: string) => void;
@@ -141,12 +141,14 @@ export default class IntersectionObserver {
141
141
  return;
142
142
  }
143
143
 
144
- IntersectionObserverManager.observe({
144
+ const didStartObserving = IntersectionObserverManager.observe({
145
145
  intersectionObserverId: this._getOrCreateIntersectionObserverId(),
146
146
  target,
147
147
  });
148
148
 
149
- this._observationTargets.add(target);
149
+ if (didStartObserving) {
150
+ this._observationTargets.add(target);
151
+ }
150
152
  }
151
153
 
152
154
  /**
@@ -116,10 +116,10 @@ export function observe({
116
116
  }: {
117
117
  intersectionObserverId: IntersectionObserverId,
118
118
  target: ReactNativeElement,
119
- }): void {
119
+ }): boolean {
120
120
  if (NativeIntersectionObserver == null) {
121
121
  warnNoNativeIntersectionObserver();
122
- return;
122
+ return false;
123
123
  }
124
124
 
125
125
  const registeredObserver = registeredIntersectionObservers.get(
@@ -129,15 +129,13 @@ export function observe({
129
129
  console.error(
130
130
  `IntersectionObserverManager: could not start observing target because IntersectionObserver with ID ${intersectionObserverId} was not registered.`,
131
131
  );
132
- return;
132
+ return false;
133
133
  }
134
134
 
135
135
  const targetShadowNode = getShadowNode(target);
136
136
  if (targetShadowNode == null) {
137
- console.error(
138
- 'IntersectionObserverManager: could not find reference to host node from target',
139
- );
140
- return;
137
+ // The target is disconnected. We can't observe it anymore.
138
+ return false;
141
139
  }
142
140
 
143
141
  const instanceHandle = getInstanceHandle(target);
@@ -145,7 +143,7 @@ export function observe({
145
143
  console.error(
146
144
  'IntersectionObserverManager: could not find reference to instance handle from target',
147
145
  );
148
- return;
146
+ return false;
149
147
  }
150
148
 
151
149
  // Store the mapping between the instance handle and the target so we can
@@ -160,11 +158,13 @@ export function observe({
160
158
  isConnected = true;
161
159
  }
162
160
 
163
- return NativeIntersectionObserver.observe({
161
+ NativeIntersectionObserver.observe({
164
162
  intersectionObserverId,
165
163
  targetShadowNode,
166
164
  thresholds: registeredObserver.observer.thresholds,
167
165
  });
166
+
167
+ return true;
168
168
  }
169
169
 
170
170
  export function unobserve(
@@ -121,13 +121,15 @@ export default class MutationObserver {
121
121
  MutationObserverManager.unobserve(mutationObserverId, target);
122
122
  }
123
123
 
124
- MutationObserverManager.observe({
124
+ const didStartObserving = MutationObserverManager.observe({
125
125
  mutationObserverId,
126
126
  target,
127
127
  subtree: Boolean(options?.subtree),
128
128
  });
129
129
 
130
- this._observationTargets.add(target);
130
+ if (didStartObserving) {
131
+ this._observationTargets.add(target);
132
+ }
131
133
  }
132
134
 
133
135
  _unobserve(target: ReactNativeElement): void {
@@ -43,6 +43,13 @@ const registeredMutationObservers: Map<
43
43
  $ReadOnly<{observer: MutationObserver, callback: MutationObserverCallback}>,
44
44
  > = new Map();
45
45
 
46
+ // The mapping between ReactNativeElement and their corresponding shadow node
47
+ // needs to be kept here because React removes the link when unmounting.
48
+ const targetToShadowNodeMap: WeakMap<
49
+ ReactNativeElement,
50
+ ReturnType<typeof getShadowNode>,
51
+ > = new WeakMap();
52
+
46
53
  /**
47
54
  * Registers the given mutation observer and returns a unique ID for it,
48
55
  * which is required to start observing targets.
@@ -85,10 +92,10 @@ export function observe({
85
92
  mutationObserverId: MutationObserverId,
86
93
  target: ReactNativeElement,
87
94
  subtree: boolean,
88
- }): void {
95
+ }): boolean {
89
96
  if (NativeMutationObserver == null) {
90
97
  warnNoNativeMutationObserver();
91
- return;
98
+ return false;
92
99
  }
93
100
 
94
101
  const registeredObserver =
@@ -97,17 +104,17 @@ export function observe({
97
104
  console.error(
98
105
  `MutationObserverManager: could not start observing target because MutationObserver with ID ${mutationObserverId} was not registered.`,
99
106
  );
100
- return;
107
+ return false;
101
108
  }
102
109
 
103
110
  const targetShadowNode = getShadowNode(target);
104
111
  if (targetShadowNode == null) {
105
- console.error(
106
- 'MutationObserverManager: could not find reference to host node from target',
107
- );
108
- return;
112
+ // The target is disconnected. We can't observe it anymore.
113
+ return false;
109
114
  }
110
115
 
116
+ targetToShadowNodeMap.set(target, targetShadowNode);
117
+
111
118
  if (!isConnected) {
112
119
  NativeMutationObserver.connect(
113
120
  notifyMutationObservers,
@@ -121,11 +128,13 @@ export function observe({
121
128
  isConnected = true;
122
129
  }
123
130
 
124
- return NativeMutationObserver.observe({
131
+ NativeMutationObserver.observe({
125
132
  mutationObserverId,
126
133
  targetShadowNode,
127
134
  subtree,
128
135
  });
136
+
137
+ return true;
129
138
  }
130
139
 
131
140
  export function unobserve(
@@ -146,10 +155,10 @@ export function unobserve(
146
155
  return;
147
156
  }
148
157
 
149
- const targetShadowNode = getShadowNode(target);
158
+ const targetShadowNode = targetToShadowNodeMap.get(target);
150
159
  if (targetShadowNode == null) {
151
160
  console.error(
152
- 'MutationObserverManager: could not find reference to host node from target',
161
+ 'MutationObserverManager: could not find registration data for target',
153
162
  );
154
163
  return;
155
164
  }
@@ -1,135 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @flow
9
- */
10
-
11
- import PlatformBaseViewConfig from '../NativeComponent/PlatformBaseViewConfig';
12
- import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
13
-
14
- const IGNORED_KEYS = ['transform', 'hitSlop'];
15
-
16
- /**
17
- * The purpose of this function is to validate that the view config that
18
- * native exposes for a given view manager is the same as the view config
19
- * that is specified for that view manager in JS.
20
- *
21
- * In order to improve perf, we want to avoid calling into native to get
22
- * the view config when each view manager is used. To do this, we are moving
23
- * the configs to JS. In the future we will use these JS based view configs
24
- * to codegen the view manager on native to ensure they stay in sync without
25
- * this runtime check.
26
- *
27
- * If this function fails, that likely means a change was made to the native
28
- * view manager without updating the JS config as well. Ideally you can make
29
- * that direct change to the JS config. If you don't know what the differences
30
- * are, the best approach I've found is to create a view that prints
31
- * the return value of getNativeComponentAttributes, and then copying that
32
- * text and pasting it back into JS:
33
- * <Text selectable={true}>{JSON.stringify(getNativeComponentAttributes('RCTView'))}</Text>
34
- *
35
- * This is meant to be a stopgap until the time comes when we only have a
36
- * single source of truth. I wonder if this message will still be here two
37
- * years from now...
38
- */
39
- export default function verifyComponentAttributeEquivalence(
40
- nativeViewConfig: ViewConfig,
41
- staticViewConfig: ViewConfig,
42
- ) {
43
- for (const prop of [
44
- 'validAttributes',
45
- 'bubblingEventTypes',
46
- 'directEventTypes',
47
- ]) {
48
- const diff = Object.keys(
49
- lefthandObjectDiff(nativeViewConfig[prop], staticViewConfig[prop]),
50
- );
51
-
52
- if (diff.length > 0) {
53
- const name =
54
- staticViewConfig.uiViewClassName ?? nativeViewConfig.uiViewClassName;
55
- console.error(
56
- `'${name}' has a view config that does not match native. ` +
57
- `'${prop}' is missing: ${diff.join(', ')}`,
58
- );
59
- }
60
- }
61
- }
62
-
63
- // Return the different key-value pairs of the right object, by iterating through the keys in the left object
64
- // Note it won't return a difference where a key is missing in the left but exists the right.
65
- function lefthandObjectDiff(leftObj: Object, rightObj: Object): Object {
66
- const differentKeys: {[string]: any | {...}} = {};
67
-
68
- function compare(leftItem: any, rightItem: any, key: string) {
69
- if (typeof leftItem !== typeof rightItem && leftItem != null) {
70
- differentKeys[key] = rightItem;
71
- return;
72
- }
73
-
74
- if (typeof leftItem === 'object') {
75
- const objDiff = lefthandObjectDiff(leftItem, rightItem);
76
- if (Object.keys(objDiff).length > 1) {
77
- differentKeys[key] = objDiff;
78
- }
79
- return;
80
- }
81
-
82
- if (leftItem !== rightItem) {
83
- differentKeys[key] = rightItem;
84
- return;
85
- }
86
- }
87
-
88
- for (const key in leftObj) {
89
- if (IGNORED_KEYS.includes(key)) {
90
- continue;
91
- }
92
-
93
- if (!rightObj) {
94
- differentKeys[key] = {};
95
- } else if (leftObj.hasOwnProperty(key)) {
96
- compare(leftObj[key], rightObj[key], key);
97
- }
98
- }
99
-
100
- return differentKeys;
101
- }
102
-
103
- export function getConfigWithoutViewProps(
104
- viewConfig: ViewConfig,
105
- propName: string,
106
- ): {...} {
107
- // $FlowFixMe[invalid-computed-prop]
108
- if (!viewConfig[propName]) {
109
- return {};
110
- }
111
-
112
- return (
113
- Object.keys(viewConfig[propName])
114
- // $FlowFixMe[invalid-computed-prop]
115
- .filter(prop => !PlatformBaseViewConfig[propName][prop])
116
- .reduce<{[string]: any}>((obj, prop) => {
117
- // $FlowFixMe[invalid-computed-prop]
118
- obj[prop] = viewConfig[propName][prop];
119
- return obj;
120
- }, {})
121
- );
122
- }
123
-
124
- export function stringifyViewConfig(viewConfig: any): string {
125
- return JSON.stringify(
126
- viewConfig,
127
- (key, val) => {
128
- if (typeof val === 'function') {
129
- return `ƒ ${val.name}`;
130
- }
131
- return val;
132
- },
133
- 2,
134
- );
135
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict
8
- * @format
9
- * @oncall react_native
10
- */
11
-
12
- import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport';
13
-
14
- import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry';
15
-
16
- export interface Spec extends TurboModule {
17
- +hasActiveSession: () => boolean;
18
- +subscribe: (callback: (hasActiveSession: boolean) => void) => () => void;
19
- }
20
-
21
- export default (TurboModuleRegistry.get<Spec>(
22
- 'NativeDebuggerSessionObserverCxx',
23
- ): ?Spec);