LibWeb: Resolve percentage padding and margins for grid items in GFC

Adds a second pass to resolve percentage paddings and margins of grid
items after track sizes are known. If resolving percentage paddings
or margins affects tracks sizes then second pass to re-resolve track
sizes might also be needed but I cannot come up with an example to
reproduce that so we can leave it to improve in the future :)
This commit is contained in:
Aliaksandr Kalenik 2023-06-08 02:49:30 +03:00 committed by Andreas Kling
parent 775742b35d
commit 1c979e0ed7
Notes: sideshowbarker 2024-07-16 21:39:23 +09:00
4 changed files with 68 additions and 18 deletions

View file

@ -0,0 +1,10 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
BlockContainer <div> at (8,8) content-size 784x17.46875 children: not-inline
Box <div.grid> at (8,8) content-size 784x17.46875 [GFC] children: not-inline
BlockContainer <div.item> at (243.2,8) content-size 313.6x17.46875 [BFC] children: inline
line 0 width: 121.0625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 16, rect: [243.2,8 121.0625x17.46875]
"A filthy t-shirt"
TextNode <#text>

View file

@ -0,0 +1,12 @@
<style>
.grid {
display: grid;
background-color: lightgreen;
}
.item {
background-color: lightpink;
margin: 0 20%;
padding: 0 10%;
}
</style><div><div class="grid"><div class="item">A filthy t-shirt

View file

@ -1418,6 +1418,38 @@ void GridFormattingContext::resolve_grid_item_heights()
}
}
void GridFormattingContext::resolve_items_box_metrics(GridDimension const dimension)
{
for (auto& item : m_grid_items) {
auto& box_state = m_state.get_mutable(item.box());
auto& computed_values = item.box().computed_values();
if (dimension == GridDimension::Column) {
CSSPixels containing_block_width = containing_block_size_for_item(item, GridDimension::Column);
box_state.padding_right = computed_values.padding().right().to_px(grid_container(), containing_block_width);
box_state.padding_left = computed_values.padding().left().to_px(grid_container(), containing_block_width);
box_state.margin_right = computed_values.margin().right().to_px(grid_container(), containing_block_width);
box_state.margin_left = computed_values.margin().left().to_px(grid_container(), containing_block_width);
box_state.border_right = computed_values.border_right().width;
box_state.border_left = computed_values.border_left().width;
} else {
CSSPixels containing_block_height = containing_block_size_for_item(item, GridDimension::Row);
box_state.padding_top = computed_values.padding().top().to_px(grid_container(), containing_block_height);
box_state.padding_bottom = computed_values.padding().bottom().to_px(grid_container(), containing_block_height);
box_state.margin_top = computed_values.margin().top().to_px(grid_container(), containing_block_height);
box_state.margin_bottom = computed_values.margin().bottom().to_px(grid_container(), containing_block_height);
box_state.border_top = computed_values.border_top().width;
box_state.border_bottom = computed_values.border_bottom().width;
}
}
}
void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const& available_space)
{
m_available_space = available_space;
@ -1447,34 +1479,28 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
box_state.set_indefinite_content_width();
if (!computed_values.height().is_length())
box_state.set_indefinite_content_height();
// NOTE: It is ok to use 0 containing block size to resolve paddings on the first pass when grid areas sizes
// are not known yet.
// FIXME: Do second pass of tracks layout to resolve percentage paddings
box_state.padding_top = computed_values.padding().top().to_px(grid_container(), 0);
box_state.padding_right = computed_values.padding().right().to_px(grid_container(), 0);
box_state.padding_bottom = computed_values.padding().bottom().to_px(grid_container(), 0);
box_state.padding_left = computed_values.padding().left().to_px(grid_container(), 0);
box_state.margin_top = computed_values.margin().top().to_px(grid_container(), 0);
box_state.margin_right = computed_values.margin().right().to_px(grid_container(), 0);
box_state.margin_bottom = computed_values.margin().bottom().to_px(grid_container(), 0);
box_state.margin_left = computed_values.margin().left().to_px(grid_container(), 0);
box_state.border_top = computed_values.border_top().width;
box_state.border_right = computed_values.border_right().width;
box_state.border_bottom = computed_values.border_bottom().width;
box_state.border_left = computed_values.border_left().width;
}
// Do the first pass of resolving grid items box metrics to compute values that are independent of a track width
resolve_items_box_metrics(GridDimension::Column);
run_track_sizing(available_space, GridDimension::Column);
// Do the second pass of resolving box metrics to compute values that depend on a track width
resolve_items_box_metrics(GridDimension::Column);
// Once the sizes of column tracks, which determine the widths of the grid areas forming the containing blocks
// for grid items, ara calculated, it becomes possible to determine the final widths of the grid items.
resolve_grid_item_widths();
// Do the first pass of resolving grid items box metrics to compute values that are independent of a track height
resolve_items_box_metrics(GridDimension::Row);
run_track_sizing(available_space, GridDimension::Row);
// Do the second pass of resolving box metrics to compute values that depend on a track height
resolve_items_box_metrics(GridDimension::Row);
resolve_grid_item_heights();
determine_grid_container_height();

View file

@ -124,6 +124,8 @@ public:
Box const& grid_container() const { return context_box(); }
private:
void resolve_items_box_metrics(GridDimension const dimension);
CSSPixels m_automatic_content_height { 0 };
bool is_auto_positioned_row(CSS::GridTrackPlacement const&, CSS::GridTrackPlacement const&) const;
bool is_auto_positioned_column(CSS::GridTrackPlacement const&, CSS::GridTrackPlacement const&) const;