Introducing `ReactShadowNode.isYogaLeafNode()`

Summary:
We have to have a way to explicitly enforce the fact that some nodes cannot have Yoga child nodes.
Previously we relied on `isMeasureDefined()`, which is actually special case (so it does not cover all possible cases).

Reviewed By: AaaChiuuu

Differential Revision: D5647855

fbshipit-source-id: 59591be61ef62c61eb98748d44bb28b878f713fc
This commit is contained in:
Valentin Shergin 2017-09-06 17:08:30 -07:00 committed by Facebook Github Bot
parent c3038d7210
commit 35cac3bf1b
1 changed files with 17 additions and 3 deletions

View File

@ -119,6 +119,16 @@ public class ReactShadowNode {
return false; return false;
} }
/**
* Nodes that return {@code true} will not manage (and and remove) child Yoga nodes.
* For example {@link ReactTextInputShadowNode} or {@link ReactTextShadowNode} have child nodes,
* which do not want Yoga to lay out, so in the eyes of Yoga it is a leaf node.
* Override this method in subclass to enforce this requirement.
*/
public boolean isYogaLeafNode() {
return isMeasureDefined();
}
public final String getViewClass() { public final String getViewClass() {
return Assertions.assertNotNull(mViewClassName); return Assertions.assertNotNull(mViewClassName);
} }
@ -172,7 +182,7 @@ public class ReactShadowNode {
// If a CSS node has measure defined, the layout algorithm will not visit its children. Even // 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. // more, it asserts that you don't add children to nodes with measure functions.
if (mYogaNode != null && !mYogaNode.isMeasureDefined()) { if (mYogaNode != null && !isYogaLeafNode()) {
YogaNode childYogaNode = child.mYogaNode; YogaNode childYogaNode = child.mYogaNode;
if (childYogaNode == null) { if (childYogaNode == null) {
throw new RuntimeException( throw new RuntimeException(
@ -198,7 +208,7 @@ public class ReactShadowNode {
ReactShadowNode removed = mChildren.remove(i); ReactShadowNode removed = mChildren.remove(i);
removed.mParent = null; removed.mParent = null;
if (mYogaNode != null && !mYogaNode.isMeasureDefined()) { if (mYogaNode != null && !isYogaLeafNode()) {
mYogaNode.removeChildAt(i); mYogaNode.removeChildAt(i);
} }
markUpdated(); markUpdated();
@ -232,7 +242,7 @@ public class ReactShadowNode {
int decrease = 0; int decrease = 0;
for (int i = getChildCount() - 1; i >= 0; i--) { for (int i = getChildCount() - 1; i >= 0; i--) {
if (mYogaNode != null && !mYogaNode.isMeasureDefined()) { if (mYogaNode != null && !isYogaLeafNode()) {
mYogaNode.removeChildAt(i); mYogaNode.removeChildAt(i);
} }
ReactShadowNode toRemove = getChildAt(i); ReactShadowNode toRemove = getChildAt(i);
@ -797,6 +807,10 @@ public class ReactShadowNode {
mYogaNode.setMeasureFunction(measureFunction); mYogaNode.setMeasureFunction(measureFunction);
} }
public boolean isMeasureDefined() {
return mYogaNode.isMeasureDefined();
}
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();