diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java index 6e74e64008bd11..e429d3408409cc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java @@ -12,8 +12,8 @@ public enum YogaErrata { NONE(0), STRETCH_FLEX_BASIS(1), - POSITION_STATIC_BEHAVES_LIKE_RELATIVE(2), - ABSOLUTE_POSITIONING(4), + ABSOLUTE_POSITIONING(2), + ABSOLUTE_PERCENT_AGAINST_INNER_SIZE(4), ALL(2147483647), CLASSIC(2147483646); @@ -31,8 +31,8 @@ public static YogaErrata fromInt(int value) { switch (value) { case 0: return NONE; case 1: return STRETCH_FLEX_BASIS; - case 2: return POSITION_STATIC_BEHAVES_LIKE_RELATIVE; - case 4: return ABSOLUTE_POSITIONING; + case 2: return ABSOLUTE_POSITIONING; + case 4: return ABSOLUTE_PERCENT_AGAINST_INNER_SIZE; case 2147483647: return ALL; case 2147483646: return CLASSIC; default: throw new IllegalArgumentException("Unknown enum value: " + value); diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGConfig.h b/packages/react-native/ReactCommon/yoga/yoga/YGConfig.h index b542afd6ebb89b..b8da4c7c0c7259 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGConfig.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGConfig.h @@ -81,7 +81,7 @@ YG_EXPORT float YGConfigGetPointScaleFactor(YGConfigConstRef config); * * By deafult Yoga will prioritize W3C conformance. `Errata` may be set to ask * Yoga to produce specific incorrect behaviors. E.g. `YGConfigSetErrata(config, - * YGErrataPositionStaticBehavesLikeRelative)`. + * YGErrataStretchFlexBasis)`. * * YGErrata is a bitmask, and multiple errata may be set at once. Predfined * constants exist for convenience: diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index 7884be1a6999ba..acac21148f7e2b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -95,10 +95,10 @@ const char* YGErrataToString(const YGErrata value) { return "none"; case YGErrataStretchFlexBasis: return "stretch-flex-basis"; - case YGErrataPositionStaticBehavesLikeRelative: - return "position-static-behaves-like-relative"; case YGErrataAbsolutePositioning: return "absolute-positioning"; + case YGErrataAbsolutePercentAgainstInnerSize: + return "absolute-percent-against-inner-size"; case YGErrataAll: return "all"; case YGErrataClassic: diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 835b7b697b189e..5b67aa49205f7e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -56,8 +56,8 @@ YG_ENUM_DECL( YGErrata, YGErrataNone = 0, YGErrataStretchFlexBasis = 1, - YGErrataPositionStaticBehavesLikeRelative = 2, - YGErrataAbsolutePositioning = 4, + YGErrataAbsolutePositioning = 2, + YGErrataAbsolutePercentAgainstInnerSize = 4, YGErrataAll = 2147483647, YGErrataClassic = 2147483646) YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp index 8055c86252ae47..7a47c4d18e1db4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp @@ -462,7 +462,9 @@ void layoutAbsoluteDescendants( uint32_t currentDepth, uint32_t generationCount, float currentNodeMainOffsetFromContainingBlock, - float currentNodeCrossOffsetFromContainingBlock) { + float currentNodeCrossOffsetFromContainingBlock, + float containingNodeAvailableInnerWidth, + float containingNodeAvailableInnerHeight) { const FlexDirection mainAxis = resolveDirection( currentNode->getStyle().flexDirection(), currentNodeDirection); const FlexDirection crossAxis = @@ -471,14 +473,23 @@ void layoutAbsoluteDescendants( if (child->getStyle().display() == Display::None) { continue; } else if (child->getStyle().positionType() == PositionType::Absolute) { + const bool absoluteErrata = + currentNode->hasErrata(Errata::AbsolutePercentAgainstInnerSize); + const float containingBlockWidth = absoluteErrata + ? containingNodeAvailableInnerWidth + : containingNode->getLayout().measuredDimension(Dimension::Width) - + containingNode->getBorderForAxis(FlexDirection::Row); + const float containingBlockHeight = absoluteErrata + ? containingNodeAvailableInnerHeight + : containingNode->getLayout().measuredDimension(Dimension::Height) - + containingNode->getBorderForAxis(FlexDirection::Column); + layoutAbsoluteChild( containingNode, currentNode, child, - containingNode->getLayout().measuredDimension(Dimension::Width) - - containingNode->getBorderForAxis(FlexDirection::Row), - containingNode->getLayout().measuredDimension(Dimension::Height) - - containingNode->getBorderForAxis(FlexDirection::Column), + containingBlockWidth, + containingBlockHeight, widthSizingMode, currentNodeDirection, layoutMarkerData, @@ -534,7 +545,9 @@ void layoutAbsoluteDescendants( currentDepth + 1, generationCount, childMainOffsetFromContainingBlock, - childCrossOffsetFromContainingBlock); + childCrossOffsetFromContainingBlock, + containingNodeAvailableInnerWidth, + containingNodeAvailableInnerHeight); } } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.h index 8544fa5c567e59..3beabf9a4a0a17 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.h @@ -33,6 +33,8 @@ void layoutAbsoluteDescendants( uint32_t currentDepth, uint32_t generationCount, float currentNodeMainOffsetFromContainingBlock, - float currentNodeCrossOffsetFromContainingBlock); + float currentNodeCrossOffsetFromContainingBlock, + float containingNodeAvailableInnerWidth, + float containingNodeAvailableInnerHeight); } // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 54e781668d53e2..2f24353ee39978 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -2026,41 +2026,22 @@ static void calculateLayoutImpl( if (performLayout) { // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN - if (!node->hasErrata(Errata::PositionStaticBehavesLikeRelative)) { - // Let the containing block layout its absolute descendants. By definition - // the containing block will not be static unless we are at the root. - if (node->getStyle().positionType() != PositionType::Static || - node->alwaysFormsContainingBlock() || depth == 1) { - layoutAbsoluteDescendants( - node, - node, - isMainAxisRow ? sizingModeMainDim : sizingModeCrossDim, - direction, - layoutMarkerData, - depth, - generationCount, - 0.0f, - 0.0f); - } - } else { - for (auto child : node->getChildren()) { - if (child->getStyle().display() == Display::None || - child->getStyle().positionType() != PositionType::Absolute) { - continue; - } - - layoutAbsoluteChild( - node, - node, - child, - availableInnerWidth, - availableInnerHeight, - isMainAxisRow ? sizingModeMainDim : sizingModeCrossDim, - direction, - layoutMarkerData, - depth, - generationCount); - } + // Let the containing block layout its absolute descendants. By definition + // the containing block will not be static unless we are at the root. + if (node->getStyle().positionType() != PositionType::Static || + node->alwaysFormsContainingBlock() || depth == 1) { + layoutAbsoluteDescendants( + node, + node, + isMainAxisRow ? sizingModeMainDim : sizingModeCrossDim, + direction, + layoutMarkerData, + depth, + generationCount, + 0.0f, + 0.0f, + availableInnerWidth, + availableInnerHeight); } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN @@ -2074,8 +2055,7 @@ static void calculateLayoutImpl( // cannot guarantee that their positions are set when their parents are // done with layout. if (child->getStyle().display() == Display::None || - (!node->hasErrata(Errata::PositionStaticBehavesLikeRelative) && - child->getStyle().positionType() == PositionType::Absolute)) { + child->getStyle().positionType() == PositionType::Absolute) { continue; } if (needsMainTrailingPos) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h index e919d541c3da88..43f1ba1a989314 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h @@ -18,8 +18,8 @@ namespace facebook::yoga { enum class Errata : uint32_t { None = YGErrataNone, StretchFlexBasis = YGErrataStretchFlexBasis, - PositionStaticBehavesLikeRelative = YGErrataPositionStaticBehavesLikeRelative, AbsolutePositioning = YGErrataAbsolutePositioning, + AbsolutePercentAgainstInnerSize = YGErrataAbsolutePercentAgainstInnerSize, All = YGErrataAll, Classic = YGErrataClassic, }; diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 642479a7aaf3a9..17a5be21c5b185 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -519,8 +519,7 @@ float Node::relativePosition( FlexDirection axis, Direction direction, float axisSize) const { - if (style_.positionType() == PositionType::Static && - !hasErrata(Errata::PositionStaticBehavesLikeRelative)) { + if (style_.positionType() == PositionType::Static) { return 0; } if (isInlineStartPositionDefined(axis, direction)) {