Changeset 279271 in webkit


Ignore:
Timestamp:
Jun 25, 2021 1:59:13 AM (13 months ago)
Author:
svillar@igalia.com
Message:

[css-flexbox] Do not clamp flex base size with {min|max}-{height|width}
https://bugs.webkit.org/show_bug.cgi?id=225590

Reviewed by Alan Bujtas.

Source/WebCore:

When computing flex base size we should not clamp it with neither min-{height|width}
nor max-{height|width}. That would be done later and will be called the hypothetical
main size.

For most of the cases we were already doing it, however there are some particular cases
in which we have to call the generic layout code which does clamp the sizes using min
and max sizes. In order to make those code paths work, we reset the min|max values to
their initial ones (so they effectively become inactive) and then we set the original
values back after computing the base size.

  • rendering/RenderFlexibleBox.cpp:

(WebCore::ScopedUnboundedBox::ScopedUnboundedBox): New scoped class that sets min|max sizes
to their initial values on instantiation and restores the original values on destruction.
(WebCore::ScopedUnboundedBox::~ScopedUnboundedBox):
(WebCore::RenderFlexibleBox::constructFlexItems): Wrap the base size computation with a
ScopedUnboundedBox.

LayoutTests:

The patch allows us to pass 3 new tests. We're adding percentage-max-height-003.html to
the list of expected failures because these changes make it fail. This is not really a
regression however because although the size of the deepest flex item was correct (and thus
allowed us to pass the test) the other sizes were completely wrong. So it's more an issue
of the test not being complete enough and passing artificially than anything else.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r279270 r279271  
     12021-06-14  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [css-flexbox] Do not clamp flex base size with {min|max}-{height|width}
     4        https://bugs.webkit.org/show_bug.cgi?id=225590
     5
     6        Reviewed by Alan Bujtas.
     7
     8        The patch allows us to pass 3 new tests. We're adding percentage-max-height-003.html to
     9        the list of expected failures because these changes make it fail. This is not really a
     10        regression however because although the size of the deepest flex item was correct (and thus
     11        allowed us to pass the test) the other sizes were completely wrong. So it's more an issue
     12        of the test not being complete enough and passing artificially than anything else.
     13
     14        * TestExpectations: Unskipped 3 tests & skipped 1.
     15
    1162021-06-25  Arcady Goldmints-Orlov  <agoldmints@igalia.com>
    217
  • trunk/LayoutTests/TestExpectations

    r279269 r279271  
    12181218webkit.org/b/136754 imported/w3c/web-platform-tests/css/css-flexbox/flexbox-safe-overflow-position-001.html [ ImageOnlyFailure ]
    12191219webkit.org/b/136754 imported/w3c/web-platform-tests/css/css-flexbox/percentage-max-height-002.html [ ImageOnlyFailure ]
     1220webkit.org/b/136754 imported/w3c/web-platform-tests/css/css-flexbox/percentage-max-height-003.html [ ImageOnlyFailure ]
    12201221webkit.org/b/210243 imported/w3c/web-platform-tests/css/css-flexbox/percentage-size-quirks-002.html [ Failure ]
    12211222webkit.org/b/136754 imported/w3c/web-platform-tests/css/css-flexbox/scrollbars-no-margin.html [ ImageOnlyFailure ]
     
    39503951webkit.org/b/209080 imported/w3c/web-platform-tests/css/css-writing-modes/vertical-alignment-srl-040.xht [ ImageOnlyFailure ]
    39513952
    3952 webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-column-012.html [ ImageOnlyFailure ]
    39533953webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-column-015.html [ ImageOnlyFailure ]
    3954 webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-row-007.html [ ImageOnlyFailure ]
    39553954webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-row-010.html [ ImageOnlyFailure ]
    39563955webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-001.html [ ImageOnlyFailure ]
     
    40244023webkit.org/b/221473 imported/w3c/web-platform-tests/css/css-flexbox/table-as-item-inflexible-in-column-2.html [ ImageOnlyFailure ]
    40254024webkit.org/b/221473 imported/w3c/web-platform-tests/css/css-flexbox/table-as-item-inflexible-in-row-2.html [ ImageOnlyFailure ]
    4026 webkit.org/b/221473 imported/w3c/web-platform-tests/css/css-flexbox/table-as-item-min-height-1.html [ ImageOnlyFailure ]
    40274025
    40284026# SVGs as flex items.
  • trunk/Source/WebCore/ChangeLog

    r279268 r279271  
     12021-06-14  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [css-flexbox] Do not clamp flex base size with {min|max}-{height|width}
     4        https://bugs.webkit.org/show_bug.cgi?id=225590
     5
     6        Reviewed by Alan Bujtas.
     7
     8        When computing flex base size we should not clamp it with neither min-{height|width}
     9        nor max-{height|width}. That would be done later and will be called the hypothetical
     10        main size.
     11
     12        For most of the cases we were already doing it, however there are some particular cases
     13        in which we have to call the generic layout code which does clamp the sizes using min
     14        and max sizes. In order to make those code paths work, we reset the min|max values to
     15        their initial ones (so they effectively become inactive) and then we set the original
     16        values back after computing the base size.
     17
     18        * rendering/RenderFlexibleBox.cpp:
     19        (WebCore::ScopedUnboundedBox::ScopedUnboundedBox): New scoped class that sets min|max sizes
     20        to their initial values on instantiation and restores the original values on destruction.
     21        (WebCore::ScopedUnboundedBox::~ScopedUnboundedBox):
     22        (WebCore::RenderFlexibleBox::constructFlexItems): Wrap the base size computation with a
     23        ScopedUnboundedBox.
     24
    1252021-06-09  Sergio Villar Senin  <svillar@igalia.com>
    226
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r279268 r279271  
    13711371}
    13721372
     1373// A scoped class that resets either min-width & max-width or min-height & max-height (depending on the
     1374// flex container main size) to their initial values on instantiation. It later resets them back to their
     1375// original values on destruction. It's used when computing the flex base sizes of flex items as "when determining
     1376// the flex base size, the item’s min and max main sizes are ignored (no clamping occurs)". See
     1377// https://drafts.csswg.org/css-flexbox/#line-sizing
     1378class ScopedUnboundedBox {
     1379WTF_MAKE_NONCOPYABLE(ScopedUnboundedBox);
     1380public:
     1381    ScopedUnboundedBox(RenderBox& box, bool mainAxisIsChildInlineAxis)
     1382        : m_box(box)
     1383        , m_isHorizontalWritingModeInParallelFlow(mainAxisIsChildInlineAxis == box.isHorizontalWritingMode())
     1384    {
     1385        m_originalMin = m_isHorizontalWritingModeInParallelFlow ? m_box.style().minWidth() : m_box.style().minHeight();
     1386        m_originalMax = m_isHorizontalWritingModeInParallelFlow ? m_box.style().maxWidth() : m_box.style().maxHeight();
     1387        if (m_isHorizontalWritingModeInParallelFlow) {
     1388            m_box.mutableStyle().setMinWidth(RenderStyle::initialMinSize());
     1389            m_box.mutableStyle().setMaxWidth(RenderStyle::initialMaxSize());
     1390            return;
     1391        }
     1392        m_box.mutableStyle().setMinHeight(RenderStyle::initialMinSize());
     1393        m_box.mutableStyle().setMaxHeight(RenderStyle::initialMaxSize());
     1394    }
     1395
     1396
     1397    ~ScopedUnboundedBox()
     1398    {
     1399        if (m_isHorizontalWritingModeInParallelFlow) {
     1400            m_box.mutableStyle().setMinWidth(WTFMove(m_originalMin));
     1401            m_box.mutableStyle().setMaxWidth(WTFMove(m_originalMax));
     1402            return;
     1403        }
     1404        m_box.mutableStyle().setMinHeight(WTFMove(m_originalMin));
     1405        m_box.mutableStyle().setMaxHeight(WTFMove(m_originalMax));
     1406    }
     1407
     1408private:
     1409    RenderBox& m_box;
     1410    bool m_isHorizontalWritingModeInParallelFlow;
     1411    Length m_originalMin;
     1412    Length m_originalMax;
     1413};
     1414
    13731415FlexItem RenderFlexibleBox::constructFlexItem(RenderBox& child, bool relayoutChildren)
    13741416{
    13751417    auto childHadLayout = child.everHadLayout();
    1376     child.clearOverridingContentSize();
    1377     if (childHasIntrinsicMainAxisSize(child)) {
    1378         // If this condition is true, then computeMainAxisExtentForChild will call
    1379         // child.intrinsicContentLogicalHeight() and child.scrollbarLogicalHeight(),
    1380         // so if the child has intrinsic min/max/preferred size, run layout on it now to make sure
    1381         // its logical height and scroll bars are up to date.
    1382         updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
    1383         // Don't resolve percentages in children. This is especially important for the min-height calculation,
    1384         // where we want percentages to be treated as auto. For flex-basis itself, this is not a problem because
    1385         // by definition we have an indefinite flex basis here and thus percentages should not resolve.
    1386         if (child.needsLayout() || !m_intrinsicSizeAlongMainAxis.contains(&child)) {
    1387             if (isHorizontalWritingMode() == child.isHorizontalWritingMode())
    1388                 child.setOverridingContainingBlockContentLogicalHeight(std::nullopt);
    1389             else
    1390                 child.setOverridingContainingBlockContentLogicalWidth(std::nullopt);
    1391             child.clearOverridingContentSize();
    1392             child.setChildNeedsLayout(MarkOnlyThis);
    1393             child.layoutIfNeeded();
    1394             cacheChildMainSize(child);
    1395             child.clearOverridingContainingBlockContentSize();
    1396         }
    1397     }
    1398    
    13991418    LayoutUnit borderAndPadding = isHorizontalFlow() ? child.horizontalBorderAndPaddingExtent() : child.verticalBorderAndPaddingExtent();
    1400     LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(child, borderAndPadding);
     1419    LayoutUnit childInnerFlexBaseSize;
     1420    {
     1421        ScopedUnboundedBox unbounded(child, mainAxisIsChildInlineAxis(child));
     1422        child.clearOverridingContentSize();
     1423        if (childHasIntrinsicMainAxisSize(child)) {
     1424            // If this condition is true, then computeMainAxisExtentForChild will call
     1425            // child.intrinsicContentLogicalHeight() and child.scrollbarLogicalHeight(),
     1426            // so if the child has intrinsic min/max/preferred size, run layout on it now to make sure
     1427            // its logical height and scroll bars are up to date.
     1428            updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
     1429            // Don't resolve percentages in children. This is especially important for the min-height calculation,
     1430            // where we want percentages to be treated as auto. For flex-basis itself, this is not a problem because
     1431            // by definition we have an indefinite flex basis here and thus percentages should not resolve.
     1432            if (child.needsLayout() || !m_intrinsicSizeAlongMainAxis.contains(&child)) {
     1433                if (isHorizontalWritingMode() == child.isHorizontalWritingMode())
     1434                    child.setOverridingContainingBlockContentLogicalHeight(std::nullopt);
     1435                else
     1436                    child.setOverridingContainingBlockContentLogicalWidth(std::nullopt);
     1437                child.clearOverridingContentSize();
     1438                child.setChildNeedsLayout(MarkOnlyThis);
     1439                child.layoutIfNeeded();
     1440                cacheChildMainSize(child);
     1441                child.clearOverridingContainingBlockContentSize();
     1442            }
     1443        }
     1444        childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(child, borderAndPadding);
     1445    }
     1446   
    14011447    LayoutUnit margin = isHorizontalFlow() ? child.horizontalMarginExtent() : child.verticalMarginExtent();
    14021448    return FlexItem(child, childInnerFlexBaseSize, borderAndPadding, margin, computeFlexItemMinMaxSizes(child), childHadLayout);
Note: See TracChangeset for help on using the changeset viewer.