LibWeb: Allow infinitely long flex lines when sizing under max-content
If the flex container is being sized under a max-content main size constraint, there is effectively infinite space available for flex items. Thus, flex lines should be allowed to be infinitely long. This is a little awkward, because the spec doesn't mention specifics about how to resolve flexible lengths during intrninsic sizing. I've marked the spec deviations with big "AD-HOC" comments.
This commit is contained in:
parent
9c74f49b1d
commit
3f9cfa144c
Notes:
sideshowbarker
2024-07-17 06:00:02 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/3f9cfa144c Pull-request: https://github.com/SerenityOS/serenity/pull/19200
3 changed files with 45 additions and 2 deletions
Tests/LibWeb/Layout
expected/flex
input/flex
Userland/Libraries/LibWeb/Layout
|
@ -0,0 +1,9 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x53.46875 [BFC] children: not-inline
|
||||
BlockContainer <body.outer> at (18,18) content-size 280.84375x17.46875 children: not-inline
|
||||
Box <div.inner> at (18,18) content-size 280.84375x17.46875 flex-container(row) [FFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (18,18) content-size 280.84375x17.46875 flex-item [BFC] children: inline
|
||||
line 0 width: 280.84375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 35, rect: [18,18 280.84375x17.46875]
|
||||
"this text should be all on one line"
|
||||
TextNode <#text>
|
|
@ -0,0 +1,12 @@
|
|||
<!doctype html><style>
|
||||
html { background: white; }
|
||||
.outer {
|
||||
width: max-content;
|
||||
padding: 10px;
|
||||
background: pink;
|
||||
}
|
||||
.inner {
|
||||
display: flex;
|
||||
background: orange;
|
||||
}
|
||||
</style><body class="outer"><div class="inner">this text should be all on one line
|
|
@ -911,6 +911,18 @@ void FlexFormattingContext::collect_flex_items_into_flex_lines()
|
|||
// https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
|
||||
void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
||||
{
|
||||
// AD-HOC: The spec tells us to use the "flex container’s inner main size" in this algorithm,
|
||||
// but that doesn't work when we're sizing under a max-content constraint.
|
||||
// In that case, there is effectively infinite size available in the main axis,
|
||||
// but the inner main size has not been assigned yet.
|
||||
// We solve this by calculating our own "available main size" here, which is essentially
|
||||
// infinity under max-content, 0 under min-content, and the inner main size otherwise.
|
||||
CSSPixels available_main_size;
|
||||
if (m_available_space_for_items->main.is_intrinsic_sizing_constraint())
|
||||
available_main_size = m_available_space_for_items->main.to_px();
|
||||
else
|
||||
available_main_size = inner_main_size(flex_container());
|
||||
|
||||
// 1. Determine the used flex factor.
|
||||
|
||||
// Sum the outer hypothetical main sizes of all items on the line.
|
||||
|
@ -927,7 +939,9 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
}
|
||||
// CSS-FLEXBOX-2: Account for gap between flex items.
|
||||
sum += main_gap() * (line.items.size() - 1);
|
||||
if (sum < inner_main_size(flex_container()))
|
||||
// AD-HOC: Note that we're using our own "available main size" explained above
|
||||
// instead of the flex container’s inner main size.
|
||||
if (sum < available_main_size)
|
||||
return FlexFactor::FlexGrowFactor;
|
||||
return FlexFactor::FlexShrinkFactor;
|
||||
}();
|
||||
|
@ -973,7 +987,10 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
}
|
||||
// CSS-FLEXBOX-2: Account for gap between flex items.
|
||||
sum += main_gap() * (line.items.size() - 1);
|
||||
return inner_main_size(flex_container()) - sum;
|
||||
|
||||
// AD-HOC: Note that we're using our own "available main size" explained above
|
||||
// instead of the flex container’s inner main size.
|
||||
return available_main_size - sum;
|
||||
};
|
||||
auto const initial_free_space = calculate_remaining_free_space();
|
||||
|
||||
|
@ -1101,6 +1118,11 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
// NOTE: Calculate the remaining free space once again here, since it's needed later when aligning items.
|
||||
line.remaining_free_space = calculate_remaining_free_space();
|
||||
|
||||
// AD-HOC: Due to the way we calculate the remaining free space, it can be infinite when sizing
|
||||
// under a max-content constraint. In that case, we can simply set it to zero here.
|
||||
if (!isfinite(line.remaining_free_space.value()))
|
||||
line.remaining_free_space = 0;
|
||||
|
||||
// 6. Set each item’s used main size to its target main size.
|
||||
for (auto& item : line.items) {
|
||||
item.main_size = item.target_main_size;
|
||||
|
|
Loading…
Add table
Reference in a new issue