Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement margin-trim for flexbox.
https://bugs.webkit.org/show_bug.cgi?id=249208
rdar://103285847

Reviewed by Alan Baradlay.

Adds support for the margin-trim property on flexbox containers.
Depending on the values that are set for this property, it will trim
the corresponding edges of the flex items that are adjacent to those
edges of the container.

In order to achieve this, a new data structure, m_marginTrimItems, was
added to RenderFlexibleBox. This structure simply holds the items that
are trimmed according to their location in the flexbox.

The first step of this algorithm is to trim the edges of the first and
last child of the flexbox. This is done so that
RenderFlexibleBox::computeIntrinsicLogicalWidths does not incorrectly
take these margins into consideration when computing the width of the
flexbox under a min/max content constraint.

In order to figure out which items are actually being trimmed, we cannot
perform any trimming until the flex lines are created. As the lines
get created in FlexLayoutAlgorithm::computeNextFlexLine, we can trim the
main axis margins of the first and last items. This will require not
only updating the object's MarginBox but also the main axis sizing
information of the flex item itself. In order to do this, we need to
make FlexItem's mainAxisMargin mutable.

After the line has been constructed, we can trim the cross axis margins
of the items if the line is either the first line or last line of the
flexbox.

* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-end-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-end-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-start-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-start-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-block-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-block-multiline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-block-multiline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-grow-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-grow.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-inline-multiline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-inline-multiline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-orthogonal-item-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-orthogonal-item.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-shrink-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-column-shrink.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-end-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-end-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-start-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-start-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-trimmed-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-inline-trimmed-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-block-multiline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-block-multiline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-grow-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-grow.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-inline-multiline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-inline-multiline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-orthogonal-item-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-orthogonal-item.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-shrink-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-shrink.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-trim-all-margins-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-trim-all-margins.html: Added.
* LayoutTests/platform/mac/imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-template-expected.txt: Added.
* Source/WebCore/rendering/FlexibleBoxAlgorithm.cpp:
(WebCore::FlexLayoutAlgorithm::FlexLayoutAlgorithm):
(WebCore::FlexLayoutAlgorithm::canFitItemWithTrimmedMarginEnd const):
(WebCore::FlexLayoutAlgorithm::removeMarginEndFromFlexSizes const):
(WebCore::FlexLayoutAlgorithm::computeNextFlexLine):
* Source/WebCore/rendering/FlexibleBoxAlgorithm.h:
(WebCore::FlexLayoutAlgorithm::isMultiline const):
* Source/WebCore/rendering/RenderBlock.cpp:
(WebCore::RenderBlock::marginIntrinsicLogicalWidthForChild const):
* Source/WebCore/rendering/RenderBox.cpp:
(WebCore::RenderBox::computeLogicalWidthInFragment const):
(WebCore::RenderBox::fillAvailableMeasure const):
(WebCore::RenderBox::computeOrTrimInlineMargin const):
(WebCore::RenderBox::computeInlineDirectionMargins const):
* Source/WebCore/rendering/RenderBox.h:
* Source/WebCore/rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::layoutBlock):
(WebCore::RenderFlexibleBox::initializeMarginTrimState):
(WebCore::RenderFlexibleBox::shouldTrimChildMargin const):
(WebCore::RenderFlexibleBox::shouldTrimMainAxisMarginStart const):
(WebCore::RenderFlexibleBox::shouldTrimMainAxisMarginEnd const):
(WebCore::RenderFlexibleBox::shouldTrimCrossAxisMarginStart const):
(WebCore::RenderFlexibleBox::shouldTrimCrossAxisMarginEnd const):
(WebCore::RenderFlexibleBox::trimMainAxisMarginStart):
(WebCore::RenderFlexibleBox::trimMainAxisMarginEnd):
(WebCore::RenderFlexibleBox::trimCrossAxisMarginStart):
(WebCore::RenderFlexibleBox::trimCrossAxisMarginEnd):
(WebCore::RenderFlexibleBox::layoutFlexItems):
* Source/WebCore/rendering/RenderFlexibleBox.h:

Canonical link: https://commits.webkit.org/258563@main
  • Loading branch information
sgill26 authored and Sammy Gill committed Jan 6, 2023
1 parent 1273df2 commit 0efe67f
Show file tree
Hide file tree
Showing 42 changed files with 1,201 additions and 30 deletions.
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-end-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<meta name="assert" content="block-end should only trim margin block end of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
margin-block-start: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-end-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="flex-block-end-trimmed-only-ref.html">
<meta name="assert" content="block-end should trim only margin block end of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
margin-trim: block-end;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
margin-block: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-start-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<meta name="assert" content="block-start should trim only margin block start of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
margin-block-end: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-start-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="flex-block-start-trimmed-only-ref.html">
<meta name="assert" content="block-start should trim only margin block start of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
margin-trim: block-start;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
margin-block: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<meta name="assert" content="block should trim only block margins of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-block-trimmed-only</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="flex-block-trimmed-only-ref.html">
<meta name="assert" content="block should trim only block margins of flex items">
<style>
flexbox {
display: flex;
width: min-content;
border: 1px black solid;
margin-trim: block;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline: 10px;
margin-block: 10px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-column-block-multiline</title>
<meta name="assert" content="block-start should be trimmed for items at the start of the flex line and block-end should be trimmed for items at the end of the flex line">
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<div style="width:100px; height: 100px; background-color: green;"></div>
</body>
</html>
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-column-block-multiline</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<meta name="assert" content="block-start should be trimmed for items at the start of the flex line and block-end should be trimmed for items at the end of the flex line">
<style>
flexbox {
display: flex;
width: 100px;
height: 100px;
flex-wrap: wrap;
flex-direction: column;
margin-trim: block;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
}
item:nth-child(odd) {
margin-block-start: 25px;
}
item:nth-child(even) {
margin-block-end: 25px;
}
</style>
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<flexbox>
<item></item>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-grow-002</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<meta name="assert" content="items should grow to take up the space made available by trimming margins">
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<div style="width:100px; height: 100px; background-color: green;"></div>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-grow-002</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<meta name="assert" content="items should grow to take up the space made available by trimming margins">
<style>
flexbox {
display: flex;
width: 100px;
height: 100px;
flex-direction: column;
margin-trim: block;
}
item {
display: block;
width: 100px;
height: 50px;
margin-block: 25px;
flex: 1 0 auto;
background-color: green;
}
</style>
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<flexbox>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-column-inline-multiline</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<meta name="assert" content="inline-start should be trimmed for all items on the first flex line and inline-end should be trimmed for all items on the last flex line">
<style>
flexbox {
display: flex;
width: 60px;
height: 100px;
flex-direction: column;
flex-wrap: wrap;
gap: 0px 30px;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-column-inline-multiline</title>
<link rel="author" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-flex">
<link rel="match" href="flex-column-inline-multiline-ref.html">
<meta name="assert" content="inline-start should be trimmed for all items on the first flex line and inline-end should be trimmed for all items on the last flex line">
<style>
flexbox {
display: flex;
width: min-content;
height: 100px;
flex-direction: column;
flex-wrap: wrap;
margin-trim: inline;
}
item {
display: block;
background-color: green;
width: 50px;
height: 50px;
margin-inline-start: 10px;
margin-inline-end: 20px;
}
</style>
</head>
<body>
<flexbox>
<item></item>
<item></item>
<item></item>
<item></item>
</flexbox>
</body>
</html>
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: flex-orthogonal-item-002</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<meta name="assert" content="orthogonal items have correct margins trimmed according to the flexbox's writing mode">
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<div style="width:100px; height: 100px; background-color: green;"></div>
</body>
</html>

0 comments on commit 0efe67f

Please sign in to comment.