diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java index ae5828323..e8d043136 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java @@ -29,27 +29,32 @@ public class LayoutShadowNode extends ReactShadowNode { @ReactProp(name = ViewProps.MIN_WIDTH, defaultFloat = CSSConstants.UNDEFINED) public void setMinWidth(float minWidth) { - setStyleMinWidth(CSSConstants.isUndefined(minWidth) ? minWidth : PixelUtil.toPixelFromDIP(minWidth)); + setStyleMinWidth( + CSSConstants.isUndefined(minWidth) ? minWidth : PixelUtil.toPixelFromDIP(minWidth)); } @ReactProp(name = ViewProps.MAX_WIDTH, defaultFloat = CSSConstants.UNDEFINED) public void setMaxWidth(float maxWidth) { - setStyleMaxWidth(CSSConstants.isUndefined(maxWidth) ? maxWidth : PixelUtil.toPixelFromDIP(maxWidth)); + setStyleMaxWidth( + CSSConstants.isUndefined(maxWidth) ? maxWidth : PixelUtil.toPixelFromDIP(maxWidth)); } @ReactProp(name = ViewProps.HEIGHT, defaultFloat = CSSConstants.UNDEFINED) public void setHeight(float height) { - setStyleHeight(CSSConstants.isUndefined(height) ? height : PixelUtil.toPixelFromDIP(height)); + setStyleHeight( + CSSConstants.isUndefined(height) ? height : PixelUtil.toPixelFromDIP(height)); } @ReactProp(name = ViewProps.MIN_HEIGHT, defaultFloat = CSSConstants.UNDEFINED) public void setMinHeight(float minHeight) { - setStyleMinHeight(CSSConstants.isUndefined(minHeight) ? minHeight : PixelUtil.toPixelFromDIP(minHeight)); + setStyleMinHeight( + CSSConstants.isUndefined(minHeight) ? minHeight : PixelUtil.toPixelFromDIP(minHeight)); } @ReactProp(name = ViewProps.MAX_HEIGHT, defaultFloat = CSSConstants.UNDEFINED) public void setMaxHeight(float maxHeight) { - setStyleMaxHeight(CSSConstants.isUndefined(maxHeight) ? maxHeight : PixelUtil.toPixelFromDIP(maxHeight)); + setStyleMaxHeight( + CSSConstants.isUndefined(maxHeight) ? maxHeight : PixelUtil.toPixelFromDIP(maxHeight)); } @ReactProp(name = ViewProps.FLEX, defaultFloat = 0f) @@ -81,7 +86,8 @@ public class LayoutShadowNode extends ReactShadowNode { @ReactProp(name = ViewProps.FLEX_WRAP) public void setFlexWrap(@Nullable String flexWrap) { - setWrap(flexWrap == null ? CSSWrap.NOWRAP : CSSWrap.valueOf(flexWrap.toUpperCase(Locale.US))); + setFlexWrap( + flexWrap == null ? CSSWrap.NOWRAP : CSSWrap.valueOf(flexWrap.toUpperCase(Locale.US))); } @ReactProp(name = ViewProps.ALIGN_SELF) 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 520ced417..581182060 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -13,8 +13,17 @@ import javax.annotation.Nullable; import java.util.ArrayList; +import com.facebook.csslayout.CSSAlign; import com.facebook.csslayout.CSSConstants; +import com.facebook.csslayout.CSSDirection; +import com.facebook.csslayout.CSSFlexDirection; +import com.facebook.csslayout.CSSJustify; +import com.facebook.csslayout.CSSLayoutContext; +import com.facebook.csslayout.CSSNodeAPI; import com.facebook.csslayout.CSSNodeDEPRECATED; +import com.facebook.csslayout.CSSOverflow; +import com.facebook.csslayout.CSSPositionType; +import com.facebook.csslayout.CSSWrap; import com.facebook.csslayout.Spacing; import com.facebook.infer.annotation.Assertions; import com.facebook.react.uimanager.annotations.ReactPropertyHolder; @@ -43,7 +52,7 @@ import com.facebook.react.uimanager.annotations.ReactPropertyHolder; * information. */ @ReactPropertyHolder -public class ReactShadowNode extends CSSNodeDEPRECATED { +public class ReactShadowNode { private int mReactTag; private @Nullable String mViewClassName; @@ -51,6 +60,8 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { private @Nullable ThemedReactContext mThemedContext; private boolean mShouldNotifyOnLayout; private boolean mNodeUpdated = true; + private @Nullable ArrayList mChildren; + private @Nullable ReactShadowNode mParent; // layout-only nodes private boolean mIsLayoutOnly; @@ -63,6 +74,7 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { private float mAbsoluteBottom; private final Spacing mDefaultPadding = new Spacing(0); private final Spacing mPadding = new Spacing(CSSConstants.UNDEFINED); + private final CSSNodeDEPRECATED mCSSNode = new CSSNodeDEPRECATED(); /** * Nodes that return {@code true} will be treated as "virtual" nodes. That is, nodes that are not @@ -88,7 +100,7 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { } public final boolean hasUpdates() { - return mNodeUpdated || hasNewLayout() || isDirty(); + return mNodeUpdated || hasNewLayout() || mCSSNode.isDirty(); } public final void markUpdateSeen() { @@ -109,74 +121,45 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { } } - public boolean hasUnseenUpdates() { + public final boolean hasUnseenUpdates() { return mNodeUpdated; } - @Override public void dirty() { if (!isVirtual()) { - super.dirty(); + mCSSNode.dirty(); } } - public void setDefaultPadding(int spacingType, float padding) { - mDefaultPadding.set(spacingType, padding); - updatePadding(); - } - - @Override - public void setPadding(int spacingType, float padding) { - mPadding.set(spacingType, padding); - updatePadding(); - } - - private void updatePadding() { - for (int spacingType = Spacing.LEFT; spacingType <= Spacing.ALL; spacingType++) { - if (spacingType == Spacing.LEFT || - spacingType == Spacing.RIGHT || - spacingType == Spacing.START || - spacingType == Spacing.END) { - if (CSSConstants.isUndefined(mPadding.getRaw(spacingType)) && - CSSConstants.isUndefined(mPadding.getRaw(Spacing.HORIZONTAL)) && - CSSConstants.isUndefined(mPadding.getRaw(Spacing.ALL))) { - super.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); - } else { - super.setPadding(spacingType, mPadding.getRaw(spacingType)); - } - } else if (spacingType == Spacing.TOP || spacingType == Spacing.BOTTOM) { - if (CSSConstants.isUndefined(mPadding.getRaw(spacingType)) && - CSSConstants.isUndefined(mPadding.getRaw(Spacing.VERTICAL)) && - CSSConstants.isUndefined(mPadding.getRaw(Spacing.ALL))) { - super.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); - } else { - super.setPadding(spacingType, mPadding.getRaw(spacingType)); - } - } else { - if (CSSConstants.isUndefined(mPadding.getRaw(spacingType))) { - super.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); - } else { - super.setPadding(spacingType, mPadding.getRaw(spacingType)); - } - } + public void addChildAt(ReactShadowNode child, int i) { + if (child.mParent != null) { + throw new IllegalViewOperationException( + "Tried to add child that already has a parent! Remove it from its parent first."); } - } + if (mChildren == null) { + mChildren = new ArrayList(4); + } + mChildren.add(i, child); + child.mParent = this; - @Override - public void addChildAt(CSSNodeDEPRECATED child, int i) { - super.addChildAt(child, i); + mCSSNode.addChildAt(child.mCSSNode, i); markUpdated(); - ReactShadowNode node = (ReactShadowNode) child; - int increase = node.mIsLayoutOnly ? node.mTotalNativeChildren : 1; + int increase = child.mIsLayoutOnly ? child.mTotalNativeChildren : 1; mTotalNativeChildren += increase; updateNativeChildrenCountInParent(increase); } - @Override public ReactShadowNode removeChildAt(int i) { - ReactShadowNode removed = (ReactShadowNode) super.removeChildAt(i); + if (mChildren == null) { + throw new ArrayIndexOutOfBoundsException( + "Index " + i + " out of bounds: node has no children"); + } + ReactShadowNode removed = mChildren.remove(i); + removed.mParent = null; + + mCSSNode.removeChildAt(i); markUpdated(); int decrease = removed.mIsLayoutOnly ? removed.mTotalNativeChildren : 1; @@ -185,12 +168,35 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { return removed; } + public final int getChildCount() { + return mChildren == null ? 0 : mChildren.size(); + } + + public final ReactShadowNode getChildAt(int i) { + if (mChildren == null) { + throw new ArrayIndexOutOfBoundsException( + "Index " + i + " out of bounds: node has no children"); + } + return mChildren.get(i); + } + + public final int indexOf(ReactShadowNode child) { + return mChildren == null ? -1 : mChildren.indexOf(child); + } + public void removeAllChildren() { + if (getChildCount() == 0) { + return; + } + int decrease = 0; for (int i = getChildCount() - 1; i >= 0; i--) { - ReactShadowNode removed = (ReactShadowNode) super.removeChildAt(i); - decrease += removed.mIsLayoutOnly ? removed.mTotalNativeChildren : 1; + mCSSNode.removeChildAt(i); + ReactShadowNode toRemove = getChildAt(i); + toRemove.mParent = null; + decrease += toRemove.mIsLayoutOnly ? toRemove.mTotalNativeChildren : 1; } + Assertions.assertNotNull(mChildren).clear(); markUpdated(); mTotalNativeChildren -= decrease; @@ -294,14 +300,8 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { mViewClassName = viewClassName; } - @Override - public final ReactShadowNode getChildAt(int i) { - return (ReactShadowNode) super.getChildAt(i); - } - - @Override public final @Nullable ReactShadowNode getParent() { - return (ReactShadowNode) super.getParent(); + return mParent; } /** @@ -309,7 +309,7 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { * never change during the lifetime of a {@link ReactShadowNode} instance, but different instances * can have different contexts; don't cache any calculations based on theme values globally. */ - public ThemedReactContext getThemedContext() { + public final ThemedReactContext getThemedContext() { return Assertions.assertNotNull(mThemedContext); } @@ -317,19 +317,27 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { mThemedContext = themedContext; } - public void setShouldNotifyOnLayout(boolean shouldNotifyOnLayout) { - mShouldNotifyOnLayout = shouldNotifyOnLayout; + public final boolean shouldNotifyOnLayout() { + return mShouldNotifyOnLayout; } - public boolean shouldNotifyOnLayout() { - return mShouldNotifyOnLayout; + public void calculateLayout(CSSLayoutContext layoutContext) { + mCSSNode.calculateLayout(layoutContext); + } + + public final boolean hasNewLayout() { + return mCSSNode.hasNewLayout(); + } + + public final void markLayoutSeen() { + mCSSNode.markLayoutSeen(); } /** * Adds a child that the native view hierarchy will have at this index in the native view * corresponding to this node. */ - public void addNativeChildAt(ReactShadowNode child, int nativeIndex) { + public final void addNativeChildAt(ReactShadowNode child, int nativeIndex) { Assertions.assertCondition(!mIsLayoutOnly); Assertions.assertCondition(!child.mIsLayoutOnly); @@ -341,14 +349,14 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { child.mNativeParent = this; } - public ReactShadowNode removeNativeChildAt(int i) { + public final ReactShadowNode removeNativeChildAt(int i) { Assertions.assertNotNull(mNativeChildren); ReactShadowNode removed = mNativeChildren.remove(i); removed.mNativeParent = null; return removed; } - public void removeAllNativeChildren() { + public final void removeAllNativeChildren() { if (mNativeChildren != null) { for (int i = mNativeChildren.size() - 1; i >= 0; i--) { mNativeChildren.get(i).mNativeParent = null; @@ -357,16 +365,16 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { } } - public int getNativeChildCount() { + public final int getNativeChildCount() { return mNativeChildren == null ? 0 : mNativeChildren.size(); } - public int indexOfNativeChild(ReactShadowNode nativeChild) { + public final int indexOfNativeChild(ReactShadowNode nativeChild) { Assertions.assertNotNull(mNativeChildren); return mNativeChildren.indexOf(nativeChild); } - public @Nullable ReactShadowNode getNativeParent() { + public final @Nullable ReactShadowNode getNativeParent() { return mNativeParent; } @@ -374,18 +382,18 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { * Sets whether this node only contributes to the layout of its children without doing any * drawing or functionality itself. */ - public void setIsLayoutOnly(boolean isLayoutOnly) { + public final void setIsLayoutOnly(boolean isLayoutOnly) { Assertions.assertCondition(getParent() == null, "Must remove from no opt parent first"); Assertions.assertCondition(mNativeParent == null, "Must remove from native parent first"); Assertions.assertCondition(getNativeChildCount() == 0, "Must remove all native children first"); mIsLayoutOnly = isLayoutOnly; } - public boolean isLayoutOnly() { + public final boolean isLayoutOnly() { return mIsLayoutOnly; } - public int getTotalNativeChildren() { + public final int getTotalNativeChildren() { return mTotalNativeChildren; } @@ -418,7 +426,7 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { * getNativeOffsetForChild(Node 3) => 4 * getNativeOffsetForChild(Node 4) => 6 */ - public int getNativeOffsetForChild(ReactShadowNode child) { + public final int getNativeOffsetForChild(ReactShadowNode child) { int index = 0; boolean found = false; for (int i = 0; i < getChildCount(); i++) { @@ -435,6 +443,22 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { return index; } + public final float getLayoutX() { + return mCSSNode.getLayoutX(); + } + + public final float getLayoutY() { + return mCSSNode.getLayoutY(); + } + + public final float getLayoutWidth() { + return mCSSNode.getLayoutWidth(); + } + + public final float getLayoutHeight() { + return mCSSNode.getLayoutHeight(); + } + /** * @return the x position of the corresponding view on the screen, rounded to pixels */ @@ -462,4 +486,158 @@ public class ReactShadowNode extends CSSNodeDEPRECATED { public int getScreenHeight() { return Math.round(mAbsoluteBottom - mAbsoluteTop); } + + public final CSSDirection getLayoutDirection() { + return mCSSNode.getLayoutDirection(); + } + + public void setLayoutDirection(CSSDirection direction) { + mCSSNode.setDirection(direction); + } + + public final float getStyleWidth() { + return mCSSNode.getStyleWidth(); + } + + public void setStyleWidth(float widthPx) { + mCSSNode.setStyleWidth(widthPx); + } + + public void setStyleMinWidth(float widthPx) { + mCSSNode.setStyleMinWidth(widthPx); + } + + public void setStyleMaxWidth(float widthPx) { + mCSSNode.setStyleMaxWidth(widthPx); + } + + public final float getStyleHeight() { + return mCSSNode.getStyleHeight(); + } + + public void setStyleHeight(float heightPx) { + mCSSNode.setStyleHeight(heightPx); + } + + public void setStyleMinHeight(float widthPx) { + mCSSNode.setStyleMinHeight(widthPx); + } + + public void setStyleMaxHeight(float widthPx) { + mCSSNode.setStyleMaxHeight(widthPx); + } + + public void setFlex(float flex) { + mCSSNode.setFlex(flex); + } + + public void setFlexGrow(float flexGrow) { + mCSSNode.setFlexGrow(flexGrow); + } + + public void setFlexShrink(float flexShrink) { + mCSSNode.setFlexShrink(flexShrink); + } + + public void setFlexBasis(float flexBasis) { + mCSSNode.setFlexBasis(flexBasis); + } + + public void setFlexDirection(CSSFlexDirection flexDirection) { + mCSSNode.setFlexDirection(flexDirection); + } + + public void setFlexWrap(CSSWrap wrap) { + mCSSNode.setWrap(wrap); + } + + public void setAlignSelf(CSSAlign alignSelf) { + mCSSNode.setAlignSelf(alignSelf); + } + + public void setAlignItems(CSSAlign alignItems) { + mCSSNode.setAlignItems(alignItems); + } + + public void setJustifyContent(CSSJustify justifyContent) { + mCSSNode.setJustifyContent(justifyContent); + } + + public void setOverflow(CSSOverflow overflow) { + mCSSNode.setOverflow(overflow); + } + + public void setMargin(int spacingType, float margin) { + mCSSNode.setMargin(spacingType, margin); + } + + public final float getPadding(int spacingType) { + return mCSSNode.getPadding(spacingType); + } + + public void setDefaultPadding(int spacingType, float padding) { + mDefaultPadding.set(spacingType, padding); + updatePadding(); + } + + public void setPadding(int spacingType, float padding) { + mPadding.set(spacingType, padding); + updatePadding(); + } + + private void updatePadding() { + for (int spacingType = Spacing.LEFT; spacingType <= Spacing.ALL; spacingType++) { + if (spacingType == Spacing.LEFT || + spacingType == Spacing.RIGHT || + spacingType == Spacing.START || + spacingType == Spacing.END) { + if (CSSConstants.isUndefined(mPadding.getRaw(spacingType)) && + CSSConstants.isUndefined(mPadding.getRaw(Spacing.HORIZONTAL)) && + CSSConstants.isUndefined(mPadding.getRaw(Spacing.ALL))) { + mCSSNode.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); + } else { + mCSSNode.setPadding(spacingType, mPadding.getRaw(spacingType)); + } + } else if (spacingType == Spacing.TOP || spacingType == Spacing.BOTTOM) { + if (CSSConstants.isUndefined(mPadding.getRaw(spacingType)) && + CSSConstants.isUndefined(mPadding.getRaw(Spacing.VERTICAL)) && + CSSConstants.isUndefined(mPadding.getRaw(Spacing.ALL))) { + mCSSNode.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); + } else { + mCSSNode.setPadding(spacingType, mPadding.getRaw(spacingType)); + } + } else { + if (CSSConstants.isUndefined(mPadding.getRaw(spacingType))) { + mCSSNode.setPadding(spacingType, mDefaultPadding.getRaw(spacingType)); + } else { + mCSSNode.setPadding(spacingType, mPadding.getRaw(spacingType)); + } + } + } + } + + public void setBorder(int spacingType, float borderWidth) { + mCSSNode.setBorder(spacingType, borderWidth); + } + + public void setPosition(int spacingType, float position) { + mCSSNode.setPosition(spacingType, position); + } + + public void setPositionType(CSSPositionType positionType) { + mCSSNode.setPositionType(positionType); + } + + public void setShouldNotifyOnLayout(boolean shouldNotifyOnLayout) { + mShouldNotifyOnLayout = shouldNotifyOnLayout; + } + + public void setMeasureFunction(CSSNodeAPI.MeasureFunction measureFunction) { + mCSSNode.setMeasureFunction(measureFunction); + } + + @Override + public String toString() { + return mCSSNode.toString(); + } } 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 d43391eed..aa0089069 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -86,7 +86,7 @@ public class UIImplementation { ReactShadowNode rootCSSNode = new ReactShadowNode(); I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance(); if (sharedI18nUtilInstance.isRTL(mReactContext)) { - rootCSSNode.setDirection(CSSDirection.RTL); + rootCSSNode.setLayoutDirection(CSSDirection.RTL); } rootCSSNode.setViewClassName("Root"); return rootCSSNode; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java index b6b310c48..52f3c2251 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java @@ -11,8 +11,8 @@ package com.facebook.react.views.modal; import android.graphics.Point; -import com.facebook.csslayout.CSSNodeDEPRECATED; import com.facebook.react.uimanager.LayoutShadowNode; +import com.facebook.react.uimanager.ReactShadowNode; /** * We implement the Modal by using an Android Dialog. That will fill the entire window of the @@ -29,7 +29,7 @@ class ModalHostShadowNode extends LayoutShadowNode { * within the in Modal.js. This needs to fill the entire window. */ @Override - public void addChildAt(CSSNodeDEPRECATED child, int i) { + public void addChildAt(ReactShadowNode child, int i) { super.addChildAt(child, i); Point modalSize = ModalHostHelper.getModalHostSize(getThemedContext()); child.setStyleWidth(modalSize.x); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 47809ea45..95b19e815 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -33,7 +33,6 @@ import android.widget.TextView; import com.facebook.csslayout.CSSDirection; import com.facebook.csslayout.CSSConstants; import com.facebook.csslayout.CSSMeasureMode; -import com.facebook.csslayout.CSSNodeDEPRECATED; import com.facebook.csslayout.CSSNodeAPI; import com.facebook.csslayout.MeasureOutput; import com.facebook.csslayout.Spacing; @@ -43,6 +42,7 @@ import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.LayoutShadowNode; +import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.UIViewOperationQueue; @@ -105,15 +105,15 @@ public class ReactTextShadowNode extends LayoutShadowNode { } private static void buildSpannedFromTextCSSNode( - ReactTextShadowNode textCSSNode, + ReactTextShadowNode textShadowNode, SpannableStringBuilder sb, List ops) { int start = sb.length(); - if (textCSSNode.mText != null) { - sb.append(textCSSNode.mText); + if (textShadowNode.mText != null) { + sb.append(textShadowNode.mText); } - for (int i = 0, length = textCSSNode.getChildCount(); i < length; i++) { - CSSNodeDEPRECATED child = textCSSNode.getChildAt(i); + for (int i = 0, length = textShadowNode.getChildCount(); i < length; i++) { + ReactShadowNode child = textShadowNode.getChildAt(i); if (child instanceof ReactTextShadowNode) { buildSpannedFromTextCSSNode((ReactTextShadowNode) child, sb, ops); } else if (child instanceof ReactTextInlineImageShadowNode) { @@ -129,57 +129,57 @@ public class ReactTextShadowNode extends LayoutShadowNode { throw new IllegalViewOperationException("Unexpected view type nested under text node: " + child.getClass()); } - ((ReactShadowNode) child).markUpdateSeen(); + child.markUpdateSeen(); } int end = sb.length(); if (end >= start) { - if (textCSSNode.mIsColorSet) { - ops.add(new SetSpanOperation(start, end, new ForegroundColorSpan(textCSSNode.mColor))); + if (textShadowNode.mIsColorSet) { + ops.add(new SetSpanOperation(start, end, new ForegroundColorSpan(textShadowNode.mColor))); } - if (textCSSNode.mIsBackgroundColorSet) { + if (textShadowNode.mIsBackgroundColorSet) { ops.add(new SetSpanOperation( start, end, - new BackgroundColorSpan(textCSSNode.mBackgroundColor))); + new BackgroundColorSpan(textShadowNode.mBackgroundColor))); } - if (textCSSNode.mFontSize != UNSET) { - ops.add(new SetSpanOperation(start, end, new AbsoluteSizeSpan(textCSSNode.mFontSize))); + if (textShadowNode.mFontSize != UNSET) { + ops.add(new SetSpanOperation(start, end, new AbsoluteSizeSpan(textShadowNode.mFontSize))); } - if (textCSSNode.mFontStyle != UNSET || - textCSSNode.mFontWeight != UNSET || - textCSSNode.mFontFamily != null) { + if (textShadowNode.mFontStyle != UNSET || + textShadowNode.mFontWeight != UNSET || + textShadowNode.mFontFamily != null) { ops.add(new SetSpanOperation( start, end, new CustomStyleSpan( - textCSSNode.mFontStyle, - textCSSNode.mFontWeight, - textCSSNode.mFontFamily, - textCSSNode.getThemedContext().getAssets()))); + textShadowNode.mFontStyle, + textShadowNode.mFontWeight, + textShadowNode.mFontFamily, + textShadowNode.getThemedContext().getAssets()))); } - if (textCSSNode.mIsUnderlineTextDecorationSet) { + if (textShadowNode.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new UnderlineSpan())); } - if (textCSSNode.mIsLineThroughTextDecorationSet) { + if (textShadowNode.mIsLineThroughTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new StrikethroughSpan())); } - if (textCSSNode.mTextShadowOffsetDx != 0 || textCSSNode.mTextShadowOffsetDy != 0) { + if (textShadowNode.mTextShadowOffsetDx != 0 || textShadowNode.mTextShadowOffsetDy != 0) { ops.add(new SetSpanOperation( start, end, new ShadowStyleSpan( - textCSSNode.mTextShadowOffsetDx, - textCSSNode.mTextShadowOffsetDy, - textCSSNode.mTextShadowRadius, - textCSSNode.mTextShadowColor))); + textShadowNode.mTextShadowOffsetDx, + textShadowNode.mTextShadowOffsetDy, + textShadowNode.mTextShadowRadius, + textShadowNode.mTextShadowColor))); } - if (!Float.isNaN(textCSSNode.getEffectiveLineHeight())) { + if (!Float.isNaN(textShadowNode.getEffectiveLineHeight())) { ops.add(new SetSpanOperation( start, end, - new CustomLineHeightSpan(textCSSNode.getEffectiveLineHeight()))); + new CustomLineHeightSpan(textShadowNode.getEffectiveLineHeight()))); } - ops.add(new SetSpanOperation(start, end, new ReactTagSpan(textCSSNode.getReactTag()))); + ops.add(new SetSpanOperation(start, end, new ReactTagSpan(textShadowNode.getReactTag()))); } } @@ -218,7 +218,7 @@ public class ReactTextShadowNode extends LayoutShadowNode { return sb; } - private static final CSSNodeAPI.MeasureFunction TEXT_MEASURE_FUNCTION = + private final CSSNodeAPI.MeasureFunction mTextMeasureFunction = new CSSNodeAPI.MeasureFunction() { @Override public long measure( @@ -228,11 +228,10 @@ public class ReactTextShadowNode extends LayoutShadowNode { float height, CSSMeasureMode heightMode) { // TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic) - ReactTextShadowNode reactCSSNode = (ReactTextShadowNode) node; TextPaint textPaint = sTextPaintInstance; Layout layout; Spanned text = Assertions.assertNotNull( - reactCSSNode.mPreparedSpannableText, + mPreparedSpannableText, "Spannable element has not been prepared in onBeforeLayout"); BoringLayout.Metrics boring = BoringLayout.isBoring(text, textPaint); float desiredWidth = boring == null ? @@ -278,11 +277,11 @@ public class ReactTextShadowNode extends LayoutShadowNode { true); } - if (reactCSSNode.mNumberOfLines != UNSET && - reactCSSNode.mNumberOfLines < layout.getLineCount()) { + if (mNumberOfLines != UNSET && + mNumberOfLines < layout.getLineCount()) { return MeasureOutput.make( layout.getWidth(), - layout.getLineBottom(reactCSSNode.mNumberOfLines - 1)); + layout.getLineBottom(mNumberOfLines - 1)); } else { return MeasureOutput.make(layout.getWidth(), layout.getHeight()); } @@ -356,7 +355,7 @@ public class ReactTextShadowNode extends LayoutShadowNode { public ReactTextShadowNode(boolean isVirtual) { mIsVirtual = isVirtual; if (!isVirtual) { - setMeasureFunction(TEXT_MEASURE_FUNCTION); + setMeasureFunction(mTextMeasureFunction); } }