diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h index c6513462cf9..e82fd18295e 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h @@ -41,6 +41,7 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< static ShadowNodeTraits BaseTraits() { auto traits = ConcreteViewShadowNode::BaseTraits(); traits.set(ShadowNodeTraits::Trait::LeafYogaNode); + return traits; } diff --git a/ReactCommon/fabric/components/text/text/TextShadowNode.h b/ReactCommon/fabric/components/text/text/TextShadowNode.h index c6824e55ce8..8841e73d89e 100644 --- a/ReactCommon/fabric/components/text/text/TextShadowNode.h +++ b/ReactCommon/fabric/components/text/text/TextShadowNode.h @@ -26,6 +26,17 @@ class TextShadowNode : public ConcreteShadowNode< TextEventEmitter>, public BaseTextShadowNode { public: + static ShadowNodeTraits BaseTraits() { + auto traits = ConcreteShadowNode::BaseTraits(); + +#ifdef ANDROID + traits.set(ShadowNodeTraits::Trait::FormsView); + traits.set(ShadowNodeTraits::Trait::FormsStackingContext); +#endif + + return traits; + } + using ConcreteShadowNode::ConcreteShadowNode; }; diff --git a/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h b/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h index fbe6d32dcad..8ae629b3dcd 100644 --- a/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h +++ b/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h @@ -59,6 +59,8 @@ class ConcreteViewShadowNode : public ConcreteShadowNode< static ShadowNodeTraits BaseTraits() { auto traits = BaseShadowNode::BaseTraits(); traits.set(ShadowNodeTraits::Trait::ViewKind); + traits.set(ShadowNodeTraits::Trait::FormsStackingContext); + traits.set(ShadowNodeTraits::Trait::FormsView); return traits; } diff --git a/ReactCommon/fabric/components/view/ViewShadowNode.cpp b/ReactCommon/fabric/components/view/ViewShadowNode.cpp index 3dd1cb622da..d00b4e3be8e 100644 --- a/ReactCommon/fabric/components/view/ViewShadowNode.cpp +++ b/ReactCommon/fabric/components/view/ViewShadowNode.cpp @@ -33,5 +33,58 @@ bool ViewShadowNode::isLayoutOnly() const { getLayoutMetrics().borderWidth == EdgeInsets{}; } +ViewShadowNode::ViewShadowNode( + ShadowNodeFragment const &fragment, + ShadowNodeFamily::Shared const &family, + ShadowNodeTraits traits) + : ConcreteViewShadowNode(fragment, family, traits) { + updateTraits(); +} + +ViewShadowNode::ViewShadowNode( + ShadowNode const &sourceShadowNode, + ShadowNodeFragment const &fragment) + : ConcreteViewShadowNode(sourceShadowNode, fragment) { + updateTraits(); +} + +static bool isColorMeaningful(SharedColor const &color) { + if (!color) { + return false; + } + + return colorComponentsFromColor(color).alpha > 0; +} + +void ViewShadowNode::updateTraits() { + auto &viewProps = static_cast(*props_); + + bool formsStackingContext = !viewProps.collapsable || + viewProps.pointerEvents == PointerEventsMode::None || + !viewProps.nativeId.empty() || viewProps.accessible || + viewProps.opacity != 1.0 || viewProps.transform != Transform{} || + viewProps.zIndex != 0 || viewProps.getClipsContentToBounds() || + viewProps.yogaStyle.positionType() == YGPositionTypeAbsolute; + + bool formsView = isColorMeaningful(viewProps.backgroundColor) || + isColorMeaningful(viewProps.foregroundColor) || + isColorMeaningful(viewProps.shadowColor) || + !(viewProps.yogaStyle.border() == YGStyle::Edges{}); + + formsView = formsView || formsStackingContext; + + if (formsView) { + traits_.set(ShadowNodeTraits::Trait::FormsView); + } else { + traits_.unset(ShadowNodeTraits::Trait::FormsView); + } + + if (formsStackingContext) { + traits_.set(ShadowNodeTraits::Trait::FormsStackingContext); + } else { + traits_.unset(ShadowNodeTraits::Trait::FormsStackingContext); + } +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/view/ViewShadowNode.h b/ReactCommon/fabric/components/view/ViewShadowNode.h index daffb630fd9..f29b6760bd3 100644 --- a/ReactCommon/fabric/components/view/ViewShadowNode.h +++ b/ReactCommon/fabric/components/view/ViewShadowNode.h @@ -23,9 +23,19 @@ class ViewShadowNode final : public ConcreteViewShadowNode< ViewProps, ViewEventEmitter> { public: - using ConcreteViewShadowNode::ConcreteViewShadowNode; + ViewShadowNode( + ShadowNodeFragment const &fragment, + ShadowNodeFamily::Shared const &family, + ShadowNodeTraits traits); + + ViewShadowNode( + ShadowNode const &sourceShadowNode, + ShadowNodeFragment const &fragment); bool isLayoutOnly() const; + + private: + void updateTraits(); }; } // namespace react diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.h b/ReactCommon/fabric/core/shadownode/ShadowNode.h index 66d2c6ce218..cb3b265a1e1 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.h @@ -207,6 +207,7 @@ class ShadowNode : public Sealable, public DebugStringConvertible { */ ShadowNodeFamily::Shared family_; + protected: /* * Traits associated with the particular `ShadowNode` class and an instance of * that class. diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeTraits.h b/ReactCommon/fabric/core/shadownode/ShadowNodeTraits.h index 46ad563d712..607d308e96d 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeTraits.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeTraits.h @@ -57,6 +57,14 @@ class ShadowNodeTraits { // Inherits `LayoutableShadowNode` and calls `measure()`. HasMeasure = 1 << 11, + // Indicates that the `ShadowNode` must form a stacking context (a level + // of the hierarchy; `ShadowView`s formed by descendants the node will be + // descendants of a `ShadowView` formed by the node). + FormsStackingContext = 1 << 13, + + // Indicates that the node must form a `ShadowView`. + FormsView = 1 << 14, + // Internal to `ShadowNode`; do not use it outside. // Indicates that `children` list is shared between nodes and need // to be cloned before the first mutation.