mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
LibWeb: Implement distributing space to tracks beyond limits in GFC
Implements "Distribute space beyond limits" step from: https://www.w3.org/TR/css-grid-2/#distribute-extra-space
This commit is contained in:
parent
e3ade95d24
commit
20edbb70f8
Notes:
sideshowbarker
2024-07-16 22:17:03 +09:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/SerenityOS/serenity/commit/20edbb70f8 Pull-request: https://github.com/SerenityOS/serenity/pull/19550
9
Tests/LibWeb/Layout/expected/grid/grow-beyond-limits.txt
Normal file
9
Tests/LibWeb/Layout/expected/grid/grow-beyond-limits.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x33.46875 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
|
||||
Box <div.container> at (8,8) content-size 784x17.46875 [GFC] children: not-inline
|
||||
BlockContainer <div.item> at (8,8) content-size 28.6875x17.46875 [BFC] children: inline
|
||||
line 0 width: 28.6875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 3, rect: [8,8 28.6875x17.46875]
|
||||
"one"
|
||||
TextNode <#text>
|
10
Tests/LibWeb/Layout/input/grid/grow-beyond-limits.html
Normal file
10
Tests/LibWeb/Layout/input/grid/grow-beyond-limits.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html><style>
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(min-content, 0px);
|
||||
}
|
||||
|
||||
.item {
|
||||
background-color: aquamarine;
|
||||
}
|
||||
</style><div class="container"><div class="item">one</div></div>
|
|
@ -783,8 +783,10 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(AvailableSpace const&
|
|||
}
|
||||
|
||||
template<typename Match>
|
||||
void GridFormattingContext::distribute_extra_space_across_spanned_tracks_base_size(CSSPixels item_size_contribution, Vector<GridTrack&>& spanned_tracks, Match matcher)
|
||||
void GridFormattingContext::distribute_extra_space_across_spanned_tracks_base_size(GridDimension dimension, CSSPixels item_size_contribution, SpaceDistributionPhase phase, Vector<GridTrack&>& spanned_tracks, Match matcher)
|
||||
{
|
||||
auto& available_size = dimension == GridDimension::Column ? m_available_space->width : m_available_space->height;
|
||||
|
||||
Vector<GridTrack&> affected_tracks;
|
||||
for (auto& track : spanned_tracks) {
|
||||
if (matcher(track))
|
||||
|
@ -830,7 +832,31 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_base_si
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: 3. Distribute space beyond limits
|
||||
// 3. Distribute space beyond limits
|
||||
if (extra_space > 0) {
|
||||
Vector<GridTrack&> tracks_to_grow_beyond_limits;
|
||||
|
||||
// If space remains after all tracks are frozen, unfreeze and continue to
|
||||
// distribute space to the item-incurred increase of...
|
||||
if (phase == SpaceDistributionPhase::AccommodateMinimumContribution || phase == SpaceDistributionPhase::AccommodateMinContentContribution) {
|
||||
// when accommodating minimum contributions or accommodating min-content contributions: any affected track
|
||||
// that happens to also have an intrinsic max track sizing function
|
||||
for (auto& track : affected_tracks) {
|
||||
if (track.max_track_sizing_function.is_intrinsic(available_size))
|
||||
tracks_to_grow_beyond_limits.append(track);
|
||||
}
|
||||
|
||||
// if there are no such tracks, then all affected tracks.
|
||||
if (tracks_to_grow_beyond_limits.size() == 0)
|
||||
tracks_to_grow_beyond_limits = affected_tracks;
|
||||
}
|
||||
// FIXME: when accommodating max-content contributions: any affected track that happens to also have a
|
||||
// max-content max track sizing function; if there are no such tracks, then all affected tracks.
|
||||
|
||||
CSSPixels increase_per_track = extra_space / affected_tracks.size();
|
||||
for (auto& track : affected_tracks)
|
||||
track.item_incurred_increase += increase_per_track;
|
||||
}
|
||||
|
||||
// 4. For each affected track, if the track’s item-incurred increase is larger than the track’s planned increase
|
||||
// set the track’s planned increase to that value.
|
||||
|
@ -935,7 +961,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
|
|||
return calculate_limited_min_content_contribution(item, dimension);
|
||||
return calculate_minimum_contribution(item, dimension);
|
||||
}();
|
||||
distribute_extra_space_across_spanned_tracks_base_size(item_size_contribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
distribute_extra_space_across_spanned_tracks_base_size(dimension, item_size_contribution, SpaceDistributionPhase::AccommodateMinimumContribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
return track.min_track_sizing_function.is_intrinsic(available_size);
|
||||
});
|
||||
for (auto& track : spanned_tracks) {
|
||||
|
@ -947,7 +973,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
|
|||
// sizing function of min-content or max-content by distributing extra space as needed to account for
|
||||
// these items' min-content contributions.
|
||||
auto item_min_content_contribution = calculate_min_content_contribution(item, dimension);
|
||||
distribute_extra_space_across_spanned_tracks_base_size(item_min_content_contribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
distribute_extra_space_across_spanned_tracks_base_size(dimension, item_min_content_contribution, SpaceDistributionPhase::AccommodateMinContentContribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
return track.min_track_sizing_function.is_min_content() || track.min_track_sizing_function.is_max_content();
|
||||
});
|
||||
for (auto& track : spanned_tracks) {
|
||||
|
@ -960,7 +986,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
|
|||
// distributing extra space as needed to account for these items' limited max-content contributions.
|
||||
if (available_size.is_max_content()) {
|
||||
auto item_limited_max_content_contribution = calculate_limited_max_content_contribution(item, dimension);
|
||||
distribute_extra_space_across_spanned_tracks_base_size(item_limited_max_content_contribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
distribute_extra_space_across_spanned_tracks_base_size(dimension, item_limited_max_content_contribution, SpaceDistributionPhase::AccommodateMaxContentContribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
return track.min_track_sizing_function.is_auto(available_size) || track.min_track_sizing_function.is_max_content();
|
||||
});
|
||||
for (auto& track : spanned_tracks) {
|
||||
|
@ -1030,9 +1056,10 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
|
|||
// 1. For intrinsic minimums: First increase the base size of tracks with an intrinsic min track sizing
|
||||
// function by distributing extra space as needed to accommodate these items’ minimum contributions.
|
||||
auto item_minimum_contribution = automatic_minimum_size(item, dimension);
|
||||
distribute_extra_space_across_spanned_tracks_base_size(item_minimum_contribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
return track.min_track_sizing_function.is_flexible_length();
|
||||
});
|
||||
distribute_extra_space_across_spanned_tracks_base_size(dimension,
|
||||
item_minimum_contribution, SpaceDistributionPhase::AccommodateMinimumContribution, spanned_tracks, [&](GridTrack const& track) {
|
||||
return track.min_track_sizing_function.is_flexible_length();
|
||||
});
|
||||
|
||||
for (auto& track : spanned_tracks) {
|
||||
track.base_size += track.planned_increase;
|
||||
|
@ -1074,6 +1101,8 @@ void GridFormattingContext::maximize_tracks(AvailableSpace const& available_spac
|
|||
while (free_space_px > 0) {
|
||||
auto free_space_to_distribute_per_track = free_space_px / tracks.size();
|
||||
for (auto& track : tracks) {
|
||||
if (track.base_size_frozen)
|
||||
continue;
|
||||
VERIFY(isfinite(track.growth_limit.to_double()));
|
||||
track.base_size = min(track.growth_limit, track.base_size + free_space_to_distribute_per_track);
|
||||
}
|
||||
|
|
|
@ -242,8 +242,14 @@ private:
|
|||
|
||||
void collapse_auto_fit_tracks_if_needed(GridDimension const);
|
||||
|
||||
enum class SpaceDistributionPhase {
|
||||
AccommodateMinimumContribution,
|
||||
AccommodateMinContentContribution,
|
||||
AccommodateMaxContentContribution
|
||||
};
|
||||
|
||||
template<typename Match>
|
||||
void distribute_extra_space_across_spanned_tracks_base_size(CSSPixels item_size_contribution, Vector<GridTrack&>& spanned_tracks, Match matcher);
|
||||
void distribute_extra_space_across_spanned_tracks_base_size(GridDimension dimension, CSSPixels item_size_contribution, SpaceDistributionPhase phase, Vector<GridTrack&>& spanned_tracks, Match matcher);
|
||||
|
||||
template<typename Match>
|
||||
void distribute_extra_space_across_spanned_tracks_growth_limit(CSSPixels item_size_contribution, Vector<GridTrack&>& spanned_tracks, Match matcher);
|
||||
|
|
Loading…
Reference in a new issue