From 06c26d7d464b4dfb436216732f5f9e6ec3f85aac 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 (#1556) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1556 X-link: 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 --- enums.py | 7 ++-- java/com/facebook/yoga/YogaErrata.java | 8 ++-- javascript/src/generated/YGEnums.ts | 6 +-- yoga/YGConfig.h | 2 +- yoga/YGEnums.cpp | 4 +- yoga/YGEnums.h | 4 +- yoga/algorithm/AbsoluteLayout.cpp | 25 +++++++++--- yoga/algorithm/AbsoluteLayout.h | 4 +- yoga/algorithm/CalculateLayout.cpp | 54 ++++++++------------------ yoga/enums/Errata.h | 2 +- yoga/node/Node.cpp | 3 +- 11 files changed, 57 insertions(+), 62 deletions(-) diff --git a/enums.py b/enums.py index d5595b5e..6391ad8d 100755 --- a/enums.py +++ b/enums.py @@ -66,11 +66,12 @@ ENUMS = { # Allows main-axis flex basis to be stretched without flexGrow being # set (previously referred to as "UseLegacyStretchBehaviour") ("StretchFlexBasis", 1 << 0), - # Position: static behaves like position: relative within Yoga - ("PositionStaticBehavesLikeRelative", 1 << 1), # Positioning of absolute nodes will have various bugs related to # justification, alignment, and insets - ("AbsolutePositioning", 1 << 2), + ("AbsolutePositioning", 1 << 1), + # Absolute nodes will resolve percentages against the inner size of + # their containing node, not the padding box + ("AbsolutePercentAgainstInnerSize", 1 << 2), # Enable all incorrect behavior (preserve compatibility) ("All", 0x7FFFFFFF), # Enable all errata except for "StretchFlexBasis" (Defaults behavior diff --git a/java/com/facebook/yoga/YogaErrata.java b/java/com/facebook/yoga/YogaErrata.java index 6e74e640..e429d340 100644 --- a/java/com/facebook/yoga/YogaErrata.java +++ b/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/javascript/src/generated/YGEnums.ts b/javascript/src/generated/YGEnums.ts index 44b0a8d9..76a0f06e 100644 --- a/javascript/src/generated/YGEnums.ts +++ b/javascript/src/generated/YGEnums.ts @@ -50,8 +50,8 @@ export enum Edge { export enum Errata { None = 0, StretchFlexBasis = 1, - PositionStaticBehavesLikeRelative = 2, - AbsolutePositioning = 4, + AbsolutePositioning = 2, + AbsolutePercentAgainstInnerSize = 4, All = 2147483647, Classic = 2147483646, } @@ -161,8 +161,8 @@ const constants = { EDGE_ALL: Edge.All, ERRATA_NONE: Errata.None, ERRATA_STRETCH_FLEX_BASIS: Errata.StretchFlexBasis, - ERRATA_POSITION_STATIC_BEHAVES_LIKE_RELATIVE: Errata.PositionStaticBehavesLikeRelative, ERRATA_ABSOLUTE_POSITIONING: Errata.AbsolutePositioning, + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE: Errata.AbsolutePercentAgainstInnerSize, ERRATA_ALL: Errata.All, ERRATA_CLASSIC: Errata.Classic, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: ExperimentalFeature.WebFlexBasis, diff --git a/yoga/YGConfig.h b/yoga/YGConfig.h index b542afd6..b8da4c7c 100644 --- a/yoga/YGConfig.h +++ b/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/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index 7884be1a..acac2114 100644 --- a/yoga/YGEnums.cpp +++ b/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/yoga/YGEnums.h b/yoga/YGEnums.h index 835b7b69..5b67aa49 100644 --- a/yoga/YGEnums.h +++ b/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/yoga/algorithm/AbsoluteLayout.cpp b/yoga/algorithm/AbsoluteLayout.cpp index 8055c862..7a47c4d1 100644 --- a/yoga/algorithm/AbsoluteLayout.cpp +++ b/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/yoga/algorithm/AbsoluteLayout.h b/yoga/algorithm/AbsoluteLayout.h index 8544fa5c..3beabf9a 100644 --- a/yoga/algorithm/AbsoluteLayout.h +++ b/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/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 54e78166..2f24353e 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/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/yoga/enums/Errata.h b/yoga/enums/Errata.h index e919d541..43f1ba1a 100644 --- a/yoga/enums/Errata.h +++ b/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/yoga/node/Node.cpp b/yoga/node/Node.cpp index 642479a7..17a5be21 100644 --- a/yoga/node/Node.cpp +++ b/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)) {