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
This commit is contained in:
Joe Vilches
2024-01-18 21:22:05 -08:00
committed by Facebook GitHub Bot
parent f69a1a43e5
commit 06c26d7d46
11 changed files with 57 additions and 62 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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,

View File

@@ -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:

View File

@@ -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:

View File

@@ -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)

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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,
};

View File

@@ -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)) {