Skip to content

Commit

Permalink
Implement gap property for flexbox (#621)
Browse files Browse the repository at this point in the history
Add visual tests for flexbox gap.

Co-authored-by: Michael Ragazzon <[email protected]>
  • Loading branch information
ChrisFloofyKitsune and mikke89 authored Jun 12, 2024
1 parent 8b18a7c commit b5bf23d
Show file tree
Hide file tree
Showing 19 changed files with 740 additions and 0 deletions.
33 changes: 33 additions & 0 deletions Source/Core/Layout/FlexFormattingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ void FlexFormattingContext::Format(Vector2f& flex_resulting_content_size, Vector

const ComputedValues& computed_flex = element_flex->GetComputedValues();
const Style::FlexDirection direction = computed_flex.flex_direction();
const Style::LengthPercentage row_gap = computed_flex.row_gap();
const Style::LengthPercentage column_gap = computed_flex.column_gap();

const bool main_axis_horizontal = (direction == Style::FlexDirection::Row || direction == Style::FlexDirection::RowReverse);
const bool direction_reverse = (direction == Style::FlexDirection::RowReverse || direction == Style::FlexDirection::ColumnReverse);
Expand All @@ -257,6 +259,9 @@ void FlexFormattingContext::Format(Vector2f& flex_resulting_content_size, Vector
const float main_size_base_value = (main_available_size < 0.0f ? 0.0f : main_available_size);
const float cross_size_base_value = (cross_available_size < 0.0f ? 0.0f : cross_available_size);

const float main_gap_size = ResolveValue(main_axis_horizontal ? column_gap : row_gap, main_size_base_value);
const float cross_gap_size = ResolveValue(main_axis_horizontal ? row_gap : column_gap, cross_size_base_value);

// -- Build a list of all flex items with base size information --
const int num_flex_children = element_flex->GetNumChildren();
Vector<FlexItem> items;
Expand Down Expand Up @@ -386,6 +391,8 @@ void FlexFormattingContext::Format(Vector2f& flex_resulting_content_size, Vector
// Add item to current line.
line_items.push_back(std::move(item));
}

cursor += main_gap_size;
}

if (!line_items.empty())
Expand All @@ -397,6 +404,18 @@ void FlexFormattingContext::Format(Vector2f& flex_resulting_content_size, Vector

for (FlexLine& line : container.lines)
{
// now that items are in lines, we can add the main gap size to all but the last item
if (main_gap_size > 0.f)
{
for (size_t i = 0; i < line.items.size() - 1; i++)
{
line.items[i].hypothetical_main_size += main_gap_size;
line.items[i].flex_base_size += main_gap_size;
line.items[i].main.margin_b += main_gap_size;
line.items[i].main.sum_edges += main_gap_size;
}
}

line.accumulated_hypothetical_main_size = std::accumulate(line.items.begin(), line.items.end(), 0.0f,
[](float value, const FlexItem& item) { return value + item.hypothetical_main_size; });
}
Expand Down Expand Up @@ -624,6 +643,20 @@ void FlexFormattingContext::Format(Vector2f& flex_resulting_content_size, Vector
}
}

// Apply cross axis gaps to every item in every line except the last line.
if (cross_gap_size > 0.f)
{
for (size_t i = 0; i < container.lines.size() - 1; i++)
{
FlexLine& line = container.lines[i];
for (FlexItem& item : line.items)
{
item.cross.margin_b += cross_gap_size;
item.cross.sum_edges += cross_gap_size;
}
}
}

// -- Determine cross size (§9.4) --
// First, determine the cross size of each item, format it if necessary.
for (FlexLine& line : container.lines)
Expand Down
35 changes: 35 additions & 0 deletions Tests/Data/VisualTests/gap-001.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - horizontal</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-001-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-001-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 100px;
display: flex;
flex-direction: row;
gap: 20px;
}

section > div {
background-color: grey;
flex: 1 1 auto;
}
</style>
</head>
<body>
<p>Test passes if there is <strong>a green vertical line between boxes</strong>.</p>
<section>
<div></div>
<div></div>
<div></div>
</section>
</body>
</rml>
35 changes: 35 additions & 0 deletions Tests/Data/VisualTests/gap-002.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - vertical</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-002-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-align-3/#gaps" rel="help" title="The 'gap' property"/>
<link href="reference/gap-002-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
width: 200px;
height: 400px;
display: flex;
flex-direction: column;
gap: 20px;
}

section > div {
background-color: grey;
flex: 1 1 auto;
}
</style>
</head>
<body>
<p>Test passes if there is <strong>a green horizontal line between boxes</strong>.</p>
<section>
<div></div>
<div></div>
<div></div>
</section>
<hr/>
</body>
</rml>
37 changes: 37 additions & 0 deletions Tests/Data/VisualTests/gap-003.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - rows and columns</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-003-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-003-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 200px;
width: 400px;
display: flex;
gap: 20px;
flex-wrap: wrap;
}

section > div {
background-color: grey;
width: 190px;
}
</style>
</head>
<body>
<p>Test passes if there are <strong> green lines between boxes</strong>.</p>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</body>
</rml>
35 changes: 35 additions & 0 deletions Tests/Data/VisualTests/gap-004.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - intrinsic horizontal</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-004-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-004-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 100px;
display: inline-flex;
gap: 20px;
}

section > div {
background-color: grey;
color: white;
}
</style>
</head>
<body>
<p>Test passes if there are <strong> green lines between boxes</strong>.</p>
<section>
<div>Black Panther</div>
<div>Wonder Woman</div>
<div>Storm</div>
<div>Flash</div>
</section>
</body>
</rml>
35 changes: 35 additions & 0 deletions Tests/Data/VisualTests/gap-005.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - intrinsic vertical</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-005-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-005-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
display: inline-flex;
flex-direction: column;
gap: 20px;
}

section > div {
background-color: grey;
color: white;
}
</style>
</head>
<body>
<p>Test passes if there are <strong> green lines between boxes</strong>.</p>
<section>
<div>Black Panther</div>
<div>Wonder Woman</div>
<div>Storm</div>
<div>Flash</div>
</section>
</body>
</rml>
50 changes: 50 additions & 0 deletions Tests/Data/VisualTests/gap-006.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - wrap horizontal</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-006-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-006-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 100px;
width: 200px;
display: inline-flex;
flex-wrap: wrap;
gap: 20px;
}

section > div {
background-color: grey;
color: white;
height: 20px;
}

#bp {
width: 120px;
}

#ww {
width: 130px;
}

#s, #f {
width: 40px;
}
</style>
</head>
<body>
<p>Test passes if there are <strong> green lines between boxes</strong>.</p>
<section>
<div id="bp">Black Panther</div>
<div id="ww">Wonder Woman</div>
<div id="s">Storm</div>
<div id="f">Flash</div>
</section>
</body>
</rml>
38 changes: 38 additions & 0 deletions Tests/Data/VisualTests/gap-007.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - wrap vertical</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-007-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-007-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 100px;
width: 200px;
display: inline-flex;
flex-direction: column;
flex-wrap: wrap;
gap: 20px;
}

section > div {
background-color: grey;
color: white;
}
</style>
</head>
<body>
<p>Test passes if there are <strong> green lines between boxes</strong>.</p>
<section>
<div>Black Panther</div>
<div>Wonder Woman</div>
<div>Storm</div>
<div>Flash</div>
</section>
</body>
</rml>
40 changes: 40 additions & 0 deletions Tests/Data/VisualTests/gap-008.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<rml>
<head>
<link type="text/rcss" href="/../Tests/Data/style.rcss"/>
<title>CSS Flexbox Test: gap - row and column gap</title>
<link href="https://test.csswg.org/suites/css-align-3_dev/nightly-unstable/xhtml1/gap-008-ltr.xht" rel="source"/>
<link href="mailto:[email protected]" rel="author" title="Adam Argyle"/>
<link href="https://www.w3.org/TR/css-grid-1/#gutters" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#column-row-gap" rel="help"/>
<link href="https://www.w3.org/TR/css-align-3/#gap-legacy" rel="help"/>
<link href="reference/gap-008-ref.rml" rel="match"/>
<meta content="The 'gap' property enables putting space exclusively between items" name="assert"/>
<style>
section {
background-color: green;
height: 100px;
width: 400px;
display: flex;
gap: 40px 20px;
flex-wrap: wrap;
}

section > div {
background-color: grey;
width: 190px;
}
</style>
</head>
<body>
<p>
Test passes if there are <strong> 40px horizontal green lines and 20px vertical green lines between
boxes</strong>.
</p>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</body>
</rml>
Loading

0 comments on commit b5bf23d

Please sign in to comment.