From 822bf52c29729d25b2bfb31655cf773609a9283d Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Wed, 10 Jan 2024 12:35:33 -0800 Subject: [PATCH] BridgelessUIManager: Implement viewIsDescendantOf (#42209) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42209 Implement UIManager.viewIsDescendentOf Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D52449786 fbshipit-source-id: b607b29da935f468b00303ba20e3fe92db5291bd --- .../ReactNative/BridgelessUIManager.js | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js index 92bebb46db48f5..73ef30c8e45645 100644 --- a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js +++ b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js @@ -338,7 +338,53 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { ancestorReactTag: ?number, callback: (result: Array) => void, ): void => { - raiseSoftError('viewIsDescendantOf'); + if (reactTag == null) { + console.error( + `viewIsDescendantOf() noop: Cannot be called with ${String( + reactTag, + )} reactTag`, + ); + return; + } + + const FabricUIManager = nullthrows(getFabricUIManager()); + const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); + if (!shadowNode) { + console.error( + `viewIsDescendantOf() noop: Cannot find view with reactTag ${reactTag}`, + ); + return; + } + + if (ancestorReactTag == null) { + console.error( + `viewIsDescendantOf() noop: Cannot be called with ${String( + ancestorReactTag, + )} ancestorReactTag`, + ); + return; + } + + const ancestorShadowNode = + FabricUIManager.findShadowNodeByTag_DEPRECATED(ancestorReactTag); + if (!ancestorShadowNode) { + console.error( + `viewIsDescendantOf() noop: Cannot find view with ancestorReactTag ${ancestorReactTag}`, + ); + return; + } + + // Keep this in sync with ReadOnlyNode.js + const DOCUMENT_POSITION_CONTAINED_BY = 16; + + let result = FabricUIManager.compareDocumentPosition( + ancestorShadowNode, + shadowNode, + ); + + let isAncestor = (result & DOCUMENT_POSITION_CONTAINED_BY) !== 0; + + callback([isAncestor]); }, configureNextLayoutAnimation: ( config: Object,