Skip to content

Commit

Permalink
Add errata "PercentAbsoluteOmitsPadding"
Browse files Browse the repository at this point in the history
Summary:
This change default-enables a bugfix to Yoga's handling of absolute-positioned children sized using percentages. Yoga previously measured percentage of the box without padding, where the W3C spec, and browser behavior verified by test, use the padding box instead. See facebook#850 for more details of the backing issue.

I have so far left this behind a `YGExperimentalFeature`, because it will change the dimensions of existing views which use absolute percentages with parent padding.

This change moves it from a `YGExperimentalFeature` to `YGErrata`. This means the conformant path is enabled by default, but users of `YGErrataClassic` and `YGErrataAll` will stay on the previous behavior.

Right now the name is `PercentAbsoluteOmitsPadding` as something that tries to explain the issue in lay-terms and be a little less long than the old one, but I am open to other ideas.

I also fixed a reversal of `height` and `width` in one place compared to the original PR, and enabled a significantly more edge-casey fix without the errata.

Differential Revision: D45763574

fbshipit-source-id: 00471f861dc6022a3f3f4842b90b6a4237b0917d
  • Loading branch information
NickGerleman authored and facebook-github-bot committed May 11, 2023
1 parent 76144b5 commit 7c4ec48
Show file tree
Hide file tree
Showing 88 changed files with 271 additions and 2,475 deletions.
1 change: 1 addition & 0 deletions csharp/Facebook.Yoga/YogaErrata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum YogaErrata
{
None = 0,
StretchFlexBasis = 1,
PercentAbsoluteOmitsPadding = 2,
All = 2147483647,
Classic = 2147483646,
}
Expand Down
97 changes: 49 additions & 48 deletions csharp/tests/Facebook.Yoga/YGAbsolutePositionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public class YGAbsolutePositionTest
public void Test_absolute_layout_width_height_start_top()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 100;
Expand Down Expand Up @@ -64,8 +62,6 @@ public void Test_absolute_layout_width_height_start_top()
public void Test_absolute_layout_width_height_end_bottom()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 100;
Expand Down Expand Up @@ -109,8 +105,6 @@ public void Test_absolute_layout_width_height_end_bottom()
public void Test_absolute_layout_start_top_end_bottom()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 100;
Expand Down Expand Up @@ -154,8 +148,6 @@ public void Test_absolute_layout_start_top_end_bottom()
public void Test_absolute_layout_width_height_start_top_end_bottom()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 100;
Expand Down Expand Up @@ -201,8 +193,6 @@ public void Test_absolute_layout_width_height_start_top_end_bottom()
public void Test_do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
Expand Down Expand Up @@ -261,8 +251,6 @@ public void Test_do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_
public void Test_absolute_layout_within_border()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.MarginLeft = 10;
Expand Down Expand Up @@ -380,8 +368,6 @@ public void Test_absolute_layout_within_border()
public void Test_absolute_layout_align_items_and_justify_content_center()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -426,8 +412,6 @@ public void Test_absolute_layout_align_items_and_justify_content_center()
public void Test_absolute_layout_align_items_and_justify_content_flex_end()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.FlexEnd;
Expand Down Expand Up @@ -472,8 +456,6 @@ public void Test_absolute_layout_align_items_and_justify_content_flex_end()
public void Test_absolute_layout_justify_content_center()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -517,8 +499,6 @@ public void Test_absolute_layout_justify_content_center()
public void Test_absolute_layout_align_items_center()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.AlignItems = YogaAlign.Center;
Expand Down Expand Up @@ -562,8 +542,6 @@ public void Test_absolute_layout_align_items_center()
public void Test_absolute_layout_align_items_center_on_child_only()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.FlexGrow = 1;
Expand Down Expand Up @@ -607,8 +585,6 @@ public void Test_absolute_layout_align_items_center_on_child_only()
public void Test_absolute_layout_align_items_and_justify_content_center_and_top_position()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -654,8 +630,6 @@ public void Test_absolute_layout_align_items_and_justify_content_center_and_top_
public void Test_absolute_layout_align_items_and_justify_content_center_and_bottom_position()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -701,8 +675,6 @@ public void Test_absolute_layout_align_items_and_justify_content_center_and_bott
public void Test_absolute_layout_align_items_and_justify_content_center_and_left_position()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -748,8 +720,6 @@ public void Test_absolute_layout_align_items_and_justify_content_center_and_left
public void Test_absolute_layout_align_items_and_justify_content_center_and_right_position()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down Expand Up @@ -795,8 +765,6 @@ public void Test_absolute_layout_align_items_and_justify_content_center_and_righ
public void Test_position_root_with_rtl_should_position_withoutdirection()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Left = 72;
Expand All @@ -823,8 +791,6 @@ public void Test_position_root_with_rtl_should_position_withoutdirection()
public void Test_absolute_layout_percentage_bottom_based_on_parent_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 100;
Expand Down Expand Up @@ -901,8 +867,6 @@ public void Test_absolute_layout_percentage_bottom_based_on_parent_height()
public void Test_absolute_layout_in_wrap_reverse_column_container()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Wrap = YogaWrap.WrapReverse;
Expand Down Expand Up @@ -945,8 +909,6 @@ public void Test_absolute_layout_in_wrap_reverse_column_container()
public void Test_absolute_layout_in_wrap_reverse_row_container()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
Expand Down Expand Up @@ -990,8 +952,6 @@ public void Test_absolute_layout_in_wrap_reverse_row_container()
public void Test_absolute_layout_in_wrap_reverse_column_container_flex_end()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Wrap = YogaWrap.WrapReverse;
Expand Down Expand Up @@ -1035,8 +995,6 @@ public void Test_absolute_layout_in_wrap_reverse_column_container_flex_end()
public void Test_absolute_layout_in_wrap_reverse_row_container_flex_end()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
Expand Down Expand Up @@ -1081,8 +1039,6 @@ public void Test_absolute_layout_in_wrap_reverse_row_container_flex_end()
public void Test_percent_absolute_position_infinite_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.Width = 300;
Expand Down Expand Up @@ -1135,12 +1091,59 @@ public void Test_percent_absolute_position_infinite_height()
Assert.AreEqual(0f, root_child1.LayoutHeight);
}

[Test]
public void Test_percent_absolute_trailing_position_with_margin()
{
YogaConfig config = new YogaConfig();

YogaNode root = new YogaNode(config);
root.PaddingTop = 10;
root.BorderTopWidth = 10;
root.Width = 100;
root.Height = 100;

YogaNode root_child0 = new YogaNode(config);
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Right = 2;
root_child0.Bottom = 5;
root_child0.MarginLeft = 8;
root_child0.MarginTop = 2;
root_child0.MarginRight = 4;
root_child0.MarginBottom = 6;
root_child0.Width = 100;
root_child0.Height = 50.Percent();
root.Insert(0, root_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();

Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);

Assert.AreEqual(-6f, root_child0.LayoutX);
Assert.AreEqual(39f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);

root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();

Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);

Assert.AreEqual(-6f, root_child0.LayoutX);
Assert.AreEqual(39f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
}

[Test]
public void Test_absolute_layout_percentage_height_based_on_padded_parent()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.PaddingTop = 10;
Expand Down Expand Up @@ -1184,8 +1187,6 @@ public void Test_absolute_layout_percentage_height_based_on_padded_parent()
public void Test_absolute_layout_percentage_height_based_on_padded_parent_and_align_items_center()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true);
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.FixAbsoluteTrailingColumnMargin, true);

YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
Expand Down
Loading

0 comments on commit 7c4ec48

Please sign in to comment.