Skip to content
Permalink
Browse files
Do not consider min/max sizes when computing width as flex base size.
https://bugs.webkit.org/show_bug.cgi?id=244394
rdar://99193252

Reviewed by Alan Bujtas.

According to the CSS flexbox spec, when we compute the base size for
flex items, we want to ignore the min and max main sizes of the item.
This is because these values will be used to compute the hypothetical
main size instead, The hypothetical main size will be computed using
the base size and clamping it in between the min and max main sizes.
This patch focuses specifically on the case when the main size is in
the inline axis (i.e. logical width).

In order to accomplish this, we need to keep track of when we are
computing base sizes in the flex algorithm. The m_isComputingBaseSizes
member will keep track of this and will be set/unset using the
SetForScope class. Then, whenever we compute the width of an item, we
will check to see if it is a flex item and if it is currently being
computed as a flex base size.

A little more work may be required to add the same type of logic to the
block axis. When attempting to do this in an initial implementation,
other test cases that started failing. It seems like that will require
an additional patch.

Spec: https://www.w3.org/TR/css-flexbox-1/#algo-main-item

* LayoutTests/TestExpectations:
* Source/WebCore/rendering/RenderBox.cpp:
(WebCore::RenderBox::computeReplacedLogicalWidthRespectingMinMaxWidth const):
(WebCore::RenderBox::shouldIgnoreMinMaxSizes const):
* Source/WebCore/rendering/RenderBox.h:
* Source/WebCore/rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::computeFlexBaseSizeForChild):
* Source/WebCore/rendering/RenderFlexibleBox.h:
(WebCore::RenderFlexibleBox::isComputingBaseSizes const):
* Source/WebCore/rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::computePreferredLogicalWidths):

Canonical link: https://commits.webkit.org/255002@main
  • Loading branch information
sgill26 authored and rreno committed Sep 29, 2022
1 parent 94fb9bb commit e093fe3f0975f00d1299770a0145d7d73a60219d
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 3 deletions.
@@ -4384,7 +4384,6 @@ webkit.org/b/209080 imported/w3c/web-platform-tests/css/css-writing-modes/vertic

webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-column-012.html [ ImageOnlyFailure ]
webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-column-015.html [ ImageOnlyFailure ]
webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-row-007.html [ ImageOnlyFailure ]
webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-row-010.html [ ImageOnlyFailure ]
webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-005.html [ ImageOnlyFailure ]

@@ -3388,6 +3388,9 @@ LayoutUnit RenderBox::computeReplacedLogicalWidth(ShouldComputePreferred shouldC

LayoutUnit RenderBox::computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit logicalWidth, ShouldComputePreferred shouldComputePreferred) const
{
if (shouldIgnoreMinMaxSizes())
return logicalWidth;

auto& logicalMinWidth = style().logicalMinWidth();
auto& logicalMaxWidth = style().logicalMaxWidth();
bool useLogicalWidthForMinWidth = (shouldComputePreferred == ComputePreferred && logicalMinWidth.isPercentOrCalculated()) || logicalMinWidth.isUndefined();
@@ -5547,4 +5550,9 @@ LayoutUnit RenderBox::intrinsicLogicalWidth() const
return style().isHorizontalWritingMode() ? intrinsicSize().width() : intrinsicSize().height();
}

bool RenderBox::shouldIgnoreMinMaxSizes() const
{
return isFlexItem() && downcast<RenderFlexibleBox>(parent())->isComputingFlexBaseSizes();
}

} // namespace WebCore
@@ -665,6 +665,8 @@ override;

bool shouldComputeLogicalHeightFromAspectRatio() const;

bool shouldIgnoreMinMaxSizes() const;

protected:
RenderBox(Element&, RenderStyle&&, BaseTypeFlags);
RenderBox(Document&, RenderStyle&&, BaseTypeFlags);
@@ -1100,6 +1100,7 @@ LayoutUnit RenderFlexibleBox::computeFlexBaseSizeForChild(RenderBox& child, Layo
ScopedFlexBasisAsChildMainSize scoped(child, flexBasis.isContent() ? Length(LengthType::MaxContent) : flexBasis, mainAxisIsChildInlineAxis(child));

maybeCacheChildMainIntrinsicSize(child, relayoutChildren);
SetForScope<bool> computingBaseSizesScope(m_isComputingFlexBaseSizes, true);

// 9.2.3 A.
if (childMainSizeIsDefinite(child, flexBasis))
@@ -92,6 +92,8 @@ class RenderFlexibleBox : public RenderBlock {

bool shouldApplyMinBlockSizeAutoForChild(const RenderBox&) const;

bool isComputingFlexBaseSizes() const { return m_isComputingFlexBaseSizes; }

protected:
void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;

@@ -234,6 +236,7 @@ class RenderFlexibleBox : public RenderBlock {
SizeDefiniteness m_hasDefiniteHeight { SizeDefiniteness::Unknown };
bool m_inLayout { false };
bool m_shouldResetChildLogicalHeightBeforeLayout { false };
bool m_isComputingFlexBaseSizes { false };
};

} // namespace WebCore
@@ -671,16 +671,17 @@ void RenderReplaced::computePreferredLogicalWidths()
else
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);

bool ignoreMinMaxSizes = shouldIgnoreMinMaxSizes();
const RenderStyle& styleToUse = style();
if (styleToUse.logicalWidth().isPercentOrCalculated() || styleToUse.logicalMaxWidth().isPercentOrCalculated())
m_minPreferredLogicalWidth = 0;

if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
if (!ignoreMinMaxSizes && styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth()));
m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth()));
}

if (styleToUse.logicalMaxWidth().isFixed()) {
if (!ignoreMinMaxSizes && styleToUse.logicalMaxWidth().isFixed()) {
m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth()));
m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth()));
}

0 comments on commit e093fe3

Please sign in to comment.