From 62efff8ab8e05d27da24e50d1751660138a8ac76 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 26 Feb 2018 09:03:55 -0800 Subject: [PATCH] Implement cloning for all ReactShadowNodes Reviewed By: achen1 Differential Revision: D7063509 fbshipit-source-id: 90df8a3d2e6f2a4efa13f5eb0337b191b690bf8f --- .../react/uimanager/LayoutShadowNode.java | 23 ++++++++++++- .../views/modal/ModalHostShadowNode.java | 11 +++++++ .../progressbar/ProgressBarShadowNode.java | 22 +++++++++++-- .../views/slider/ReactSliderManager.java | 17 ++++++++++ .../views/switchview/ReactSwitchManager.java | 17 ++++++++++ .../views/text/ReactBaseTextShadowNode.java | 33 +++++++++++++++++++ .../views/text/ReactRawTextShadowNode.java | 14 ++++++++ .../text/ReactTextInlineImageShadowNode.java | 7 ++++ .../react/views/text/ReactTextShadowNode.java | 16 +++++++++ .../text/ReactVirtualTextShadowNode.java | 11 +++++++ ...coBasedReactTextInlineImageShadowNode.java | 16 +++++++++ .../textinput/ReactTextInputShadowNode.java | 18 ++++++++++ 12 files changed, 201 insertions(+), 4 deletions(-) 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 ea83f81ab..b941c2167 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java @@ -37,6 +37,13 @@ public class LayoutShadowNode extends ReactShadowNodeImpl { float value; YogaUnit unit; + private MutableYogaValue() { } + + private MutableYogaValue(MutableYogaValue mutableYogaValue) { + this.value = mutableYogaValue.value; + this.unit = mutableYogaValue.unit; + } + void setFromDynamic(Dynamic dynamic) { if (dynamic.isNull()) { unit = YogaUnit.UNDEFINED; @@ -59,7 +66,21 @@ public class LayoutShadowNode extends ReactShadowNodeImpl { } } - private final MutableYogaValue mTempYogaValue = new MutableYogaValue(); + private final MutableYogaValue mTempYogaValue; + + public LayoutShadowNode() { + mTempYogaValue = new MutableYogaValue(); + } + + protected LayoutShadowNode(LayoutShadowNode node) { + super(node); + mTempYogaValue = new MutableYogaValue(node.mTempYogaValue); + } + + @Override + public LayoutShadowNode mutableCopy() { + return new LayoutShadowNode(this); + } @ReactProp(name = ViewProps.WIDTH) public void setWidth(Dynamic width) { 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 98c5f0db6..5e429ac67 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 @@ -21,6 +21,17 @@ import com.facebook.react.uimanager.ReactShadowNodeImpl; */ class ModalHostShadowNode extends LayoutShadowNode { + public ModalHostShadowNode() {} + + private ModalHostShadowNode(ModalHostShadowNode node) { + super(node); + } + + @Override + public ModalHostShadowNode mutableCopy() { + return new ModalHostShadowNode(this); + } + /** * We need to set the styleWidth and styleHeight of the one child (represented by the * within the in Modal.js. This needs to fill the entire window. diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java index 7975f67fb..5e44b6213 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java @@ -33,14 +33,30 @@ public class ProgressBarShadowNode extends LayoutShadowNode implements YogaMeasu private String mStyle = ReactProgressBarViewManager.DEFAULT_STYLE; - private final SparseIntArray mHeight = new SparseIntArray(); - private final SparseIntArray mWidth = new SparseIntArray(); - private final Set mMeasured = new HashSet<>(); + private final SparseIntArray mHeight; + private final SparseIntArray mWidth; + private final Set mMeasured; public ProgressBarShadowNode() { + mHeight = new SparseIntArray(); + mWidth = new SparseIntArray(); + mMeasured = new HashSet<>(); setMeasureFunction(this); } + public ProgressBarShadowNode(ProgressBarShadowNode node) { + super(node); + mWidth = node.mWidth.clone(); + mHeight = node.mHeight.clone(); + mMeasured = new HashSet<>(node.mMeasured); + setMeasureFunction(this); + } + + @Override + public ProgressBarShadowNode mutableCopy() { + return new ProgressBarShadowNode(this); + } + public @Nullable String getStyle() { return mStyle; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java index 3c5547606..9ab464ad0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java @@ -48,9 +48,26 @@ public class ReactSliderManager extends SimpleViewManager { private boolean mMeasured; private ReactSliderShadowNode() { + initMeasureFunction(); + } + + private ReactSliderShadowNode(ReactSliderShadowNode node) { + super(node); + mWidth = node.mWidth; + mHeight = node.mHeight; + mMeasured = node.mMeasured; + initMeasureFunction(); + } + + private void initMeasureFunction() { setMeasureFunction(this); } + @Override + public ReactSliderShadowNode mutableCopy() { + return new ReactSliderShadowNode(this); + } + @Override public long measure( YogaNode node, diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java index 1bec8c428..62a3ad3f4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java @@ -40,9 +40,26 @@ public class ReactSwitchManager extends SimpleViewManager { private boolean mMeasured; private ReactSwitchShadowNode() { + initMeasureFunction(); + } + + private ReactSwitchShadowNode(ReactSwitchShadowNode node) { + super(node); + mWidth = node.mWidth; + mHeight = node.mHeight; + mMeasured = node.mMeasured; + initMeasureFunction(); + } + + private void initMeasureFunction() { setMeasureFunction(this); } + @Override + public ReactSwitchShadowNode mutableCopy() { + return new ReactSwitchShadowNode(this); + } + @Override public long measure( YogaNode node, diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index 0be8fa626..9b73869b1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -280,6 +280,39 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode { protected boolean mContainsImages = false; protected float mHeightOfTallestInlineImage = Float.NaN; + public ReactBaseTextShadowNode() {} + + public ReactBaseTextShadowNode(ReactBaseTextShadowNode node) { + super(node); + mLineHeight = node.mLineHeight; + mIsColorSet = node.mIsColorSet; + mAllowFontScaling = node.mAllowFontScaling; + mColor = node.mColor; + mIsBackgroundColorSet = node.mIsBackgroundColorSet; + mBackgroundColor = node.mBackgroundColor; + + mNumberOfLines = node.mNumberOfLines; + mFontSize = node.mFontSize; + mFontSizeInput = node.mFontSizeInput; + mLineHeightInput = node.mLineHeightInput; + mTextAlign = node.mTextAlign; + mTextBreakStrategy = node.mTextBreakStrategy; + + mTextShadowOffsetDx = node.mTextShadowOffsetDx; + mTextShadowOffsetDy = node.mTextShadowOffsetDy; + mTextShadowRadius = node.mTextShadowRadius; + mTextShadowColor = node.mTextShadowColor; + + mIsUnderlineTextDecorationSet = node.mIsUnderlineTextDecorationSet; + mIsLineThroughTextDecorationSet = node.mIsLineThroughTextDecorationSet; + mIncludeFontPadding = node.mIncludeFontPadding; + mFontStyle = node.mFontStyle; + mFontWeight = node.mFontWeight; + mFontFamily = node.mFontFamily; + mContainsImages = node.mContainsImages; + mHeightOfTallestInlineImage = node.mHeightOfTallestInlineImage; + } + // Returns a line height which takes into account the requested line height // and the height of the inline images. public float getEffectiveLineHeight() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java index 6bc7cc93d..a37fab61a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java @@ -22,6 +22,18 @@ public class ReactRawTextShadowNode extends ReactShadowNodeImpl { private @Nullable String mText = null; + public ReactRawTextShadowNode() { } + + private ReactRawTextShadowNode(ReactRawTextShadowNode node) { + super(node); + this.mText = node.mText; + } + + @Override + public ReactShadowNodeImpl mutableCopy() { + return new ReactRawTextShadowNode(this); + } + @ReactProp(name = PROP_TEXT) public void setText(@Nullable String text) { mText = text; @@ -36,4 +48,6 @@ public class ReactRawTextShadowNode extends ReactShadowNodeImpl { public boolean isVirtual() { return true; } + + } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java index 7f63093b3..637767cb8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java @@ -20,4 +20,11 @@ public abstract class ReactTextInlineImageShadowNode extends LayoutShadowNode { * place of this node. */ public abstract TextInlineImageSpan buildInlineImageSpan(); + + public ReactTextInlineImageShadowNode() {} + + protected ReactTextInlineImageShadowNode(ReactTextInlineImageShadowNode node) { + super(node); + } + } 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 35e182489..72e044ee8 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 @@ -17,6 +17,7 @@ import android.text.TextPaint; import android.view.Gravity; import android.widget.TextView; import com.facebook.infer.annotation.Assertions; +import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.Spacing; import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.yoga.YogaConstants; @@ -137,11 +138,26 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode { }; public ReactTextShadowNode() { + initMeasureFunction(); + } + + private ReactTextShadowNode(ReactTextShadowNode node) { + super(node); + this.mPreparedSpannableText = node.mPreparedSpannableText; + initMeasureFunction(); + } + + private void initMeasureFunction() { if (!isVirtual()) { setMeasureFunction(mTextMeasureFunction); } } + @Override + public LayoutShadowNode mutableCopy() { + return new ReactTextShadowNode(this); + } + // Return text alignment according to LTR or RTL style private int getTextAlign() { int textAlign = mTextAlign; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java index 734549aeb..6506e9697 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java @@ -11,4 +11,15 @@ public class ReactVirtualTextShadowNode extends ReactBaseTextShadowNode { public boolean isVirtual() { return true; } + + public ReactVirtualTextShadowNode() { } + + private ReactVirtualTextShadowNode(ReactVirtualTextShadowNode node) { + super(node); + } + + @Override + public ReactVirtualTextShadowNode mutableCopy() { + return new ReactVirtualTextShadowNode(this); + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java index e069c8f5c..56298de90 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java @@ -7,6 +7,7 @@ package com.facebook.react.views.text.frescosupport; +import com.facebook.react.uimanager.LayoutShadowNode; import javax.annotation.Nullable; import java.util.Locale; @@ -48,6 +49,21 @@ public class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineIm mCallerContext = callerContext; } + private FrescoBasedReactTextInlineImageShadowNode(FrescoBasedReactTextInlineImageShadowNode node) { + super(node); + mHeaders = node.mHeaders; // mHeaders is immutable + mWidth = node.mWidth; + mHeight = node.mHeight; + mDraweeControllerBuilder = node.mDraweeControllerBuilder; + mCallerContext = node.mCallerContext; + mUri = node.mUri; + } + + @Override + public FrescoBasedReactTextInlineImageShadowNode mutableCopy() { + return new FrescoBasedReactTextInlineImageShadowNode(this); + } + @ReactProp(name = "src") public void setSource(@Nullable ReadableArray sources) { final String source = diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java index cdc1d1196..375c02a62 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java @@ -14,6 +14,7 @@ import android.widget.EditText; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.common.annotations.VisibleForTesting; +import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.Spacing; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIViewOperationQueue; @@ -47,6 +48,23 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode setMeasureFunction(this); } + private ReactTextInputShadowNode(ReactTextInputShadowNode node) { + super(node); + mMostRecentEventCount = node.mMostRecentEventCount; + mText = node.mText; + mLocalData = node.mLocalData; + setMeasureFunction(this); + ThemedReactContext themedContext = getThemedContext(); + if (themedContext != null) { + setThemedContext(themedContext); + } + } + + @Override + public ReactTextInputShadowNode mutableCopy() { + return new ReactTextInputShadowNode(this); + } + @Override public void setThemedContext(ThemedReactContext themedContext) { super.setThemedContext(themedContext);