From 56b9b990de1fbe6ee78a5116e404259e849a07a7 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Thu, 18 Jan 2024 21:22:05 -0800 Subject: [PATCH] Remove static-behaves-like-relative errata (#42315) Summary: X-link: https://github.com/facebook/yoga/pull/1556 Pull Request resolved: https://github.com/facebook/react-native/pull/42315 Since we aim to ship static to all users of yoga (not just XPR), we need to remove the errata that is gating most of the features. This should be a non breaking change. To ensure that, I added a new errata which, if on, will use the inner size of the containing node as the containing block. This is how it has been for a while and resolving this is risky and time consuming so for the time being we will stick with that. Reviewed By: NickGerleman Differential Revision: D52706161 fbshipit-source-id: 30a93f29cb0d97b20b2947eaa21f36cdc78c4961 --- .../java/com/facebook/yoga/YogaErrata.java | 8 +-- .../ReactCommon/yoga/yoga/YGConfig.h | 2 +- .../ReactCommon/yoga/yoga/YGEnums.cpp | 4 +- .../ReactCommon/yoga/yoga/YGEnums.h | 4 +- .../yoga/yoga/algorithm/AbsoluteLayout.cpp | 25 ++++++--- .../yoga/yoga/algorithm/AbsoluteLayout.h | 4 +- .../yoga/yoga/algorithm/CalculateLayout.cpp | 54 ++++++------------- .../ReactCommon/yoga/yoga/enums/Errata.h | 2 +- .../ReactCommon/yoga/yoga/node/Node.cpp | 3 +- 9 files changed, 50 insertions(+), 56 deletions(-) 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 6e74e64008b..e429d340840 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 @@ package com.facebook.yoga; 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 enum YogaErrata { 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 b542afd6ebb..b8da4c7c0c7 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 7884be1a699..acac21148f7 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 835b7b697b1..5b67aa49205 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 8055c86252a..7a47c4d18e1 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 8544fa5c567..3beabf9a4a0 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 54e781668d5..2f24353ee39 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 e919d541c3d..43f1ba1a989 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 642479a7aaf..17a5be21c5b 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)) {