From 663df57c6206105f8228ee3c57c46235837f6a4b Mon Sep 17 00:00:00 2001 From: Swordsman-Inaction Date: Tue, 23 May 2017 10:54:39 -0700 Subject: [PATCH] Add viewIsDescendantOf for UIManager on Android Summary: Add the ability for UIManager to check if a node is an ancestor of anther one on Android like #7876 did on iOS Closes https://github.com/facebook/react-native/pull/13129 Differential Revision: D4938319 Pulled By: hramos fbshipit-source-id: abe20779be2142a1ea9ac46f52d8cd8609236419 --- .../react/uimanager/ReactShadowNode.java | 17 +++++++++++++++++ .../react/uimanager/UIImplementation.java | 16 ++++++++++++++++ .../react/uimanager/UIManagerModule.java | 11 +++++++++++ 3 files changed, 44 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java index 3c8d92369..a3ce58bf3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -452,6 +452,23 @@ public class ReactShadowNode { return mTotalNativeChildren; } + public boolean isDescendantOf(ReactShadowNode ancestorNode) { + ReactShadowNode parentNode = getParent(); + + boolean isDescendant = false; + + while (parentNode != null) { + if (parentNode == ancestorNode) { + isDescendant = true; + break; + } else { + parentNode = parentNode.getParent(); + } + } + + return isDescendant; + } + /** * Returns the offset within the native children owned by all layout-only nodes in the subtree * rooted at this node for the given child. Put another way, this returns the number of native diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java index ab6e6f2aa..6fc29266f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -469,6 +469,22 @@ public class UIImplementation { mOperationsQueue.enqueueFindTargetForTouch(reactTag, targetX, targetY, callback); } + /** + * Check if the first shadow node is the descendant of the second shadow node + */ + public void viewIsDescendantOf( + final int reactTag, + final int ancestorReactTag, + final Callback callback) { + ReactShadowNode node = mShadowNodeRegistry.getNode(reactTag); + ReactShadowNode ancestorNode = mShadowNodeRegistry.getNode(ancestorReactTag); + if (node == null || ancestorNode == null) { + callback.invoke(false); + return; + } + callback.invoke(node.isDescendantOf(ancestorNode)); + } + /** * Determines the location on screen, width, and height of the given view relative to the root * view and returns the values via an async callback. diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index c9074438f..e173b0795 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -412,6 +412,17 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements callback); } + /** + * Check if the first shadow node is the descendant of the second shadow node + */ + @ReactMethod + public void viewIsDescendantOf( + final int reactTag, + final int ancestorReactTag, + final Callback callback) { + mUIImplementation.viewIsDescendantOf(reactTag, ancestorReactTag, callback); + } + /** * Registers a new Animation that can then be added to a View using {@link #addAnimation}. */