Skip to content

Commit 2d7594f

Browse files
committed
feat[Fabric/Paper]: support getIsOneInstanceAncestorOfAnother api method
1 parent 87cb0bf commit 2d7594f

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

packages/react-native-renderer/src/ReactFabric.js

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
dispatchCommand,
4040
sendAccessibilityEvent,
4141
getNodeFromInternalInstanceHandle,
42+
isChildPublicInstance,
4243
} from './ReactNativePublicCompat';
4344
import {getPublicInstanceFromInternalInstanceHandle} from './ReactFiberConfigFabric';
4445

@@ -128,6 +129,8 @@ export {
128129
// instance handles we use to dispatch events. This provides a way to access
129130
// the public instances we created from them (potentially created lazily).
130131
getPublicInstanceFromInternalInstanceHandle,
132+
// DEV-only:
133+
isChildPublicInstance,
131134
};
132135

133136
injectIntoDevTools({

packages/react-native-renderer/src/ReactNativePublicCompat.js

+49
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99

1010
import type {Node, HostComponent} from './ReactNativeTypes';
11+
import type {PublicInstance as FabricPublicInstance} from './ReactFiberConfigFabric';
12+
import type {PublicInstance as PaperPublicInstance} from './ReactFiberConfigNative';
1113
import type {ElementRef, ElementType} from 'react';
1214

1315
// Modules provided by RN:
@@ -16,15 +18,19 @@ import {
1618
legacySendAccessibilityEvent,
1719
getNodeFromPublicInstance,
1820
getNativeTagFromPublicInstance,
21+
getInternalInstanceHandleFromPublicInstance,
1922
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
2023

2124
import {
2225
findHostInstance,
2326
findHostInstanceWithWarning,
2427
} from 'react-reconciler/src/ReactFiberReconciler';
28+
import {doesFiberContain} from 'react-reconciler/src/ReactFiberTreeReflection';
2529
import ReactSharedInternals from 'shared/ReactSharedInternals';
2630
import getComponentNameFromType from 'shared/getComponentNameFromType';
2731

32+
import ReactNativeFiberHostComponent from './ReactNativeFiberHostComponent';
33+
2834
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
2935

3036
export function findHostInstance_DEPRECATED<TElementType: ElementType>(
@@ -218,3 +224,46 @@ export function getNodeFromInternalInstanceHandle(
218224
internalInstanceHandle.stateNode.node
219225
);
220226
}
227+
228+
// Remove this once Paper is no longer supported and DOM Node API are enabled by default in RN.
229+
export function isChildPublicInstance(
230+
parentInstance: FabricPublicInstance | PaperPublicInstance,
231+
childInstance: FabricPublicInstance | PaperPublicInstance,
232+
): boolean {
233+
if (__DEV__) {
234+
const parentInternalInstanceHandle =
235+
// $FlowExpectedError[incompatible-call] Prioritizing early return for Fabric case, without explicitly checking with instanceof to make Flow happy.
236+
getInternalInstanceHandleFromPublicInstance(parentInstance);
237+
const childInternalInstanceHandle =
238+
// $FlowExpectedError[incompatible-call] Prioritizing early return for Fabric case, without explicitly checking with instanceof to make Flow happy.
239+
getInternalInstanceHandleFromPublicInstance(childInstance);
240+
241+
// Fabric
242+
if (
243+
parentInternalInstanceHandle != null &&
244+
childInternalInstanceHandle != null
245+
) {
246+
return doesFiberContain(
247+
parentInternalInstanceHandle,
248+
childInternalInstanceHandle,
249+
);
250+
}
251+
252+
// Paper
253+
if (
254+
parentInstance instanceof ReactNativeFiberHostComponent &&
255+
childInstance instanceof ReactNativeFiberHostComponent
256+
) {
257+
return doesFiberContain(
258+
parentInstance._internalFiberInstanceHandleDEV,
259+
childInstance._internalFiberInstanceHandleDEV,
260+
);
261+
}
262+
263+
return false;
264+
} else {
265+
throw new Error(
266+
'isChildPublicInstance() is not available in production.',
267+
);
268+
}
269+
}

packages/react-native-renderer/src/ReactNativeRenderer.js

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
findNodeHandle,
4545
dispatchCommand,
4646
sendAccessibilityEvent,
47+
isChildPublicInstance,
4748
} from './ReactNativePublicCompat';
4849

4950
// $FlowFixMe[missing-local-annot]
@@ -137,6 +138,8 @@ export {
137138
// This export is typically undefined in production builds.
138139
// See the "enableGetInspectorDataForInstanceInProduction" flag.
139140
getInspectorDataForInstance,
141+
// DEV-only:
142+
isChildPublicInstance,
140143
};
141144

142145
injectIntoDevTools({

scripts/flow/react-native-host-hooks.js

+3
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'
159159
declare export function createPublicTextInstance(
160160
internalInstanceHandle: mixed,
161161
): PublicTextInstance;
162+
declare export function getInternalInstanceHandleFromPublicInstance(
163+
publicInstance: PublicInstance,
164+
): ?Object;
162165
}
163166

164167
declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore' {

0 commit comments

Comments
 (0)