From 10e0aec62fbdac7287aae74afd07ec54274dd6be Mon Sep 17 00:00:00 2001 From: Andy Street Date: Mon, 14 Nov 2016 07:09:43 -0800 Subject: [PATCH] Update ReactShadowNode to not add CSSNode children if parent has measure defined Summary: See inline comment for rationale Reviewed By: emilsjolander Differential Revision: D4154168 fbshipit-source-id: 6d428d4e9f4a68c88bb994ded88c817bee744563 --- .../react/uimanager/ReactShadowNode.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) 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 581182060..fe9c11c04 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -142,7 +142,11 @@ public class ReactShadowNode { mChildren.add(i, child); child.mParent = this; - mCSSNode.addChildAt(child.mCSSNode, i); + // If a CSS node has measure defined, the layout algorithm will not visit its children. Even + // more, it asserts that you don't add children to nodes with measure functions. + if (!mCSSNode.isMeasureDefined()) { + mCSSNode.addChildAt(child.mCSSNode, i); + } markUpdated(); int increase = child.mIsLayoutOnly ? child.mTotalNativeChildren : 1; @@ -159,7 +163,9 @@ public class ReactShadowNode { ReactShadowNode removed = mChildren.remove(i); removed.mParent = null; - mCSSNode.removeChildAt(i); + if (!mCSSNode.isMeasureDefined()) { + mCSSNode.removeChildAt(i); + } markUpdated(); int decrease = removed.mIsLayoutOnly ? removed.mTotalNativeChildren : 1; @@ -191,7 +197,9 @@ public class ReactShadowNode { int decrease = 0; for (int i = getChildCount() - 1; i >= 0; i--) { - mCSSNode.removeChildAt(i); + if (!mCSSNode.isMeasureDefined()) { + mCSSNode.removeChildAt(i); + } ReactShadowNode toRemove = getChildAt(i); toRemove.mParent = null; decrease += toRemove.mIsLayoutOnly ? toRemove.mTotalNativeChildren : 1; @@ -633,6 +641,12 @@ public class ReactShadowNode { } public void setMeasureFunction(CSSNodeAPI.MeasureFunction measureFunction) { + if ((measureFunction == null ^ mCSSNode.isMeasureDefined()) && + getChildCount() != 0) { + throw new RuntimeException( + "Since a node with a measure function does not add any native CSSLayout children, it's " + + "not safe to transition to/from having a measure function unless a node has no children"); + } mCSSNode.setMeasureFunction(measureFunction); }