mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-24 19:28:48 +00:00
LibWeb: Improve grid area calculation for abspos items in GFC
- Add support for placement of abspos items into track formed by last line and padding edge of grid container - Correctly handle auto-positioned abspos items by placing them between padding edges of grid container Fixes crashing on https://wpt.live/css/css-grid/abspos/positioned-grid-descendants-001.html
This commit is contained in:
parent
32c467cc0e
commit
0dec2dc21c
Notes:
github-actions[bot]
2024-10-11 07:09:38 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 0dec2dc21c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1722
10 changed files with 473 additions and 85 deletions
|
@ -0,0 +1,50 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x286 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x270 children: not-inline
|
||||
Box <div.grid-container> at (58,58) content-size 170x170 positioned [GFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,58) content-size 50x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,58 6.34375x17] baseline: 13.296875
|
||||
"1"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,58) content-size 100x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,58 8.8125x17] baseline: 13.296875
|
||||
"2"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,128) content-size 50x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,128 9.09375x17] baseline: 13.296875
|
||||
"3"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,128) content-size 100x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,128 7.75x17] baseline: 13.296875
|
||||
"4"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.abspos-box> at (228,228) content-size 50x50 positioned [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,278) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x286]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x270]
|
||||
PaintableBox (Box<DIV>.grid-container) [8,8 270x270]
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,58 50x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,58 100x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,128 50x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,128 100x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.abspos-box) [228,228 50x50]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,278 784x0]
|
|
@ -0,0 +1,50 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x286 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x270 children: not-inline
|
||||
Box <div.grid-container> at (58,58) content-size 170x170 positioned [GFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,58) content-size 50x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,58 6.34375x17] baseline: 13.296875
|
||||
"1"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,58) content-size 100x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,58 8.8125x17] baseline: 13.296875
|
||||
"2"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,128) content-size 50x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,128 9.09375x17] baseline: 13.296875
|
||||
"3"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,128) content-size 100x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,128 7.75x17] baseline: 13.296875
|
||||
"4"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.abspos-box> at (8,228) content-size 270x50 positioned [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,278) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x286]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x270]
|
||||
PaintableBox (Box<DIV>.grid-container) [8,8 270x270]
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,58 50x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,58 100x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,128 50x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,128 100x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.abspos-box) [8,228 270x50]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,278 784x0]
|
|
@ -0,0 +1,50 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x286 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x270 children: not-inline
|
||||
Box <div.grid-container> at (58,58) content-size 170x170 positioned [GFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,58) content-size 50x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,58 6.34375x17] baseline: 13.296875
|
||||
"1"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,58) content-size 100x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,58 8.8125x17] baseline: 13.296875
|
||||
"2"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,128) content-size 50x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,128 9.09375x17] baseline: 13.296875
|
||||
"3"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,128) content-size 100x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,128 7.75x17] baseline: 13.296875
|
||||
"4"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.abspos-box> at (8,8) content-size 270x270 positioned [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,278) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x286]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x270]
|
||||
PaintableBox (Box<DIV>.grid-container) [8,8 270x270]
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,58 50x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,58 100x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,128 50x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,128 100x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.abspos-box) [8,8 270x270]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,278 784x0]
|
|
@ -0,0 +1,50 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x286 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x270 children: not-inline
|
||||
Box <div.grid-container> at (58,58) content-size 170x170 positioned [GFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,58) content-size 50x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,58 6.34375x17] baseline: 13.296875
|
||||
"1"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,58) content-size 100x50 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,58 8.8125x17] baseline: 13.296875
|
||||
"2"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (58,128) content-size 50x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [58,128 9.09375x17] baseline: 13.296875
|
||||
"3"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.grid-item> at (128,128) content-size 100x100 [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [128,128 7.75x17] baseline: 13.296875
|
||||
"4"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.abspos-box> at (228,8) content-size 50x270 positioned [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,278) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x286]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x270]
|
||||
PaintableBox (Box<DIV>.grid-container) [8,8 270x270]
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,58 50x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,58 100x50]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [58,128 50x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.grid-item) [128,128 100x100]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.abspos-box) [228,8 50x270]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,278 784x0]
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 100px;
|
||||
grid-template-rows: 50px 100px;
|
||||
position: relative;
|
||||
background-color: #ccc;
|
||||
padding: 50px;
|
||||
gap: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
.grid-item {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: red;
|
||||
grid-row: 3;
|
||||
grid-column: 3;
|
||||
}
|
||||
</style>
|
||||
<div class="grid-container">
|
||||
<div class="grid-item">1</div>
|
||||
<div class="grid-item">2</div>
|
||||
<div class="grid-item">3</div>
|
||||
<div class="grid-item">4</div>
|
||||
<div class="abspos-box"></div>
|
||||
</div>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 100px;
|
||||
grid-template-rows: 50px 100px;
|
||||
position: relative;
|
||||
background-color: #ccc;
|
||||
padding: 50px;
|
||||
gap: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
.grid-item {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: red;
|
||||
grid-row: 3;
|
||||
}
|
||||
</style>
|
||||
<div class="grid-container">
|
||||
<div class="grid-item">1</div>
|
||||
<div class="grid-item">2</div>
|
||||
<div class="grid-item">3</div>
|
||||
<div class="grid-item">4</div>
|
||||
<div class="abspos-box"></div>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 100px;
|
||||
grid-template-rows: 50px 100px;
|
||||
position: relative;
|
||||
background-color: #ccc;
|
||||
padding: 50px;
|
||||
gap: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
.grid-item {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
<div class="grid-container">
|
||||
<div class="grid-item">1</div>
|
||||
<div class="grid-item">2</div>
|
||||
<div class="grid-item">3</div>
|
||||
<div class="grid-item">4</div>
|
||||
<div class="abspos-box"></div>
|
||||
</div>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 100px;
|
||||
grid-template-rows: 50px 100px;
|
||||
position: relative;
|
||||
background-color: #ccc;
|
||||
padding: 50px;
|
||||
gap: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
.grid-item {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: red;
|
||||
grid-column: 3;
|
||||
}
|
||||
</style>
|
||||
<div class="grid-container">
|
||||
<div class="grid-item">1</div>
|
||||
<div class="grid-item">2</div>
|
||||
<div class="grid-item">3</div>
|
||||
<div class="grid-item">4</div>
|
||||
<div class="abspos-box"></div>
|
||||
</div>
|
|
@ -464,7 +464,7 @@ void GridFormattingContext::place_item_with_no_declared_position(Box const& chil
|
|||
|
||||
void GridFormattingContext::record_grid_placement(GridItem grid_item)
|
||||
{
|
||||
m_occupation_grid.set_occupied(grid_item.column, grid_item.column + grid_item.column_span, grid_item.row, grid_item.row + grid_item.row_span);
|
||||
m_occupation_grid.set_occupied(grid_item.column.value(), grid_item.column.value() + grid_item.column_span.value(), grid_item.row.value(), grid_item.row.value() + grid_item.row_span.value());
|
||||
m_grid_items.append(grid_item);
|
||||
}
|
||||
|
||||
|
@ -1445,8 +1445,8 @@ void GridFormattingContext::place_grid_items()
|
|||
|
||||
// NOTE: When final implicit grid sizes are known, we can offset their positions so leftmost grid track has 0 index.
|
||||
for (auto& item : m_grid_items) {
|
||||
item.row = item.row - m_occupation_grid.min_row_index();
|
||||
item.column = item.column - m_occupation_grid.min_column_index();
|
||||
item.row = item.row.value() - m_occupation_grid.min_row_index();
|
||||
item.column = item.column.value() - m_occupation_grid.min_column_index();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1833,73 +1833,121 @@ void GridFormattingContext::collapse_auto_fit_tracks_if_needed(GridDimension con
|
|||
|
||||
CSSPixelRect GridFormattingContext::get_grid_area_rect(GridItem const& grid_item) const
|
||||
{
|
||||
auto resolved_row_span = grid_item.row_span * 2;
|
||||
if (grid_item.gap_adjusted_row() + resolved_row_span > m_grid_rows_and_gaps.size())
|
||||
resolved_row_span = m_grid_rows_and_gaps.size() - grid_item.gap_adjusted_row();
|
||||
CSSPixelRect area_rect;
|
||||
|
||||
auto resolved_column_span = grid_item.column_span * 2;
|
||||
if (grid_item.gap_adjusted_column() + resolved_column_span > m_grid_columns_and_gaps.size())
|
||||
resolved_column_span = m_grid_columns_and_gaps.size() - grid_item.gap_adjusted_column();
|
||||
auto place_into_track = [&](GridDimension const dimension) {
|
||||
auto const& tracks_and_gaps = dimension == GridDimension::Column ? m_grid_columns_and_gaps : m_grid_rows_and_gaps;
|
||||
|
||||
int row_start = grid_item.gap_adjusted_row();
|
||||
int row_end = row_start + resolved_row_span;
|
||||
int column_start = grid_item.gap_adjusted_column();
|
||||
int column_end = column_start + resolved_column_span;
|
||||
auto resolved_span = grid_item.span(dimension) * 2;
|
||||
auto gap_adjusted_position = grid_item.gap_adjusted_position(dimension);
|
||||
if (gap_adjusted_position + resolved_span > tracks_and_gaps.size()) {
|
||||
resolved_span = tracks_and_gaps.size() - gap_adjusted_position;
|
||||
}
|
||||
|
||||
auto grid_container_width = m_available_space->width.to_px_or_zero();
|
||||
CSSPixels sum_base_size_of_columns_and_gaps = 0;
|
||||
CSSPixels sum_base_size_of_columns = 0;
|
||||
for (auto const& col_track : m_grid_columns_and_gaps) {
|
||||
if (!col_track.is_gap)
|
||||
sum_base_size_of_columns += col_track.base_size;
|
||||
sum_base_size_of_columns_and_gaps += col_track.base_size;
|
||||
}
|
||||
auto const& justify_content = grid_container().computed_values().justify_content();
|
||||
int start = gap_adjusted_position;
|
||||
int end = start + resolved_span;
|
||||
VERIFY(start <= end);
|
||||
|
||||
CSSPixels x_start = 0;
|
||||
CSSPixels x_end = 0;
|
||||
if (justify_content == CSS::JustifyContent::Center || justify_content == CSS::JustifyContent::SpaceAround || justify_content == CSS::JustifyContent::SpaceEvenly) {
|
||||
auto free_space = grid_container_width - sum_base_size_of_columns_and_gaps;
|
||||
free_space = max(free_space, 0);
|
||||
x_start = free_space / 2;
|
||||
x_end = free_space / 2;
|
||||
} else if (justify_content == CSS::JustifyContent::End || justify_content == CSS::JustifyContent::Right) {
|
||||
auto free_space = grid_container_width - sum_base_size_of_columns_and_gaps;
|
||||
x_start = free_space;
|
||||
x_end = free_space;
|
||||
auto grid_container_size = dimension == GridDimension::Column ? m_available_space->width : m_available_space->height;
|
||||
|
||||
CSSPixels sum_of_base_sizes_including_gaps = 0;
|
||||
for (auto const& track : tracks_and_gaps) {
|
||||
sum_of_base_sizes_including_gaps += track.base_size;
|
||||
}
|
||||
|
||||
Alignment alignment;
|
||||
if (dimension == GridDimension::Column) {
|
||||
alignment = to_alignment(grid_container().computed_values().justify_content());
|
||||
} else {
|
||||
alignment = to_alignment(grid_container().computed_values().align_content());
|
||||
}
|
||||
CSSPixels start_offset = 0;
|
||||
CSSPixels end_offset = 0;
|
||||
if (alignment == Alignment::Center || alignment == Alignment::SpaceAround || alignment == Alignment::SpaceEvenly) {
|
||||
auto free_space = grid_container_size.to_px_or_zero() - sum_of_base_sizes_including_gaps;
|
||||
free_space = max(free_space, 0);
|
||||
start_offset = free_space / 2;
|
||||
end_offset = free_space / 2;
|
||||
} else if (alignment == Alignment::End) {
|
||||
auto free_space = grid_container_size.to_px_or_zero() - sum_of_base_sizes_including_gaps;
|
||||
start_offset = free_space;
|
||||
end_offset = free_space;
|
||||
}
|
||||
|
||||
for (int i = 0; i < min(start, tracks_and_gaps.size()); i++)
|
||||
start_offset += tracks_and_gaps[i].base_size;
|
||||
for (int i = 0; i < min(end, tracks_and_gaps.size()); i++) {
|
||||
end_offset += tracks_and_gaps[i].base_size;
|
||||
}
|
||||
|
||||
if (dimension == GridDimension::Column) {
|
||||
area_rect.set_x(start_offset);
|
||||
area_rect.set_width(end_offset - start_offset);
|
||||
} else {
|
||||
area_rect.set_y(start_offset);
|
||||
area_rect.set_height(end_offset - start_offset);
|
||||
}
|
||||
};
|
||||
|
||||
auto place_into_track_formed_by_last_line_and_grid_container_padding_edge = [&](GridDimension const dimension) {
|
||||
VERIFY(grid_item.box->is_absolutely_positioned());
|
||||
auto const& tracks_and_gaps = dimension == GridDimension::Column ? m_grid_columns_and_gaps : m_grid_rows_and_gaps;
|
||||
auto const& grid_container_state = m_state.get(grid_container());
|
||||
CSSPixels offset = 0;
|
||||
for (auto const& row_track : tracks_and_gaps) {
|
||||
offset += row_track.base_size;
|
||||
}
|
||||
CSSPixels size = dimension == GridDimension::Column ? grid_container_state.padding_right : grid_container_state.padding_bottom;
|
||||
if (dimension == GridDimension::Column) {
|
||||
area_rect.set_x(offset);
|
||||
area_rect.set_width(size);
|
||||
} else {
|
||||
area_rect.set_y(offset);
|
||||
area_rect.set_height(size);
|
||||
}
|
||||
};
|
||||
|
||||
if (grid_item.row.has_value()) {
|
||||
if (grid_item.row == (int)m_grid_rows.size()) {
|
||||
place_into_track_formed_by_last_line_and_grid_container_padding_edge(GridDimension::Row);
|
||||
} else {
|
||||
place_into_track(GridDimension::Row);
|
||||
}
|
||||
} else {
|
||||
// https://www.w3.org/TR/css-grid-2/#abspos-items
|
||||
// Instead of auto-placement, an auto value for a grid-placement property contributes a special line to the placement whose position
|
||||
// is that of the corresponding padding edge of the grid container (the padding edge of the scrollable area, if the grid container
|
||||
// overflows). These lines become the first and last lines (0th and -0th) of the augmented grid used for positioning absolutely-positioned items.
|
||||
CSSPixels height = 0;
|
||||
for (auto const& row_track : m_grid_rows_and_gaps) {
|
||||
height += row_track.base_size;
|
||||
}
|
||||
auto const& grid_container_state = m_state.get(grid_container());
|
||||
height += grid_container_state.padding_top;
|
||||
height += grid_container_state.padding_bottom;
|
||||
area_rect.set_height(height);
|
||||
area_rect.set_y(-grid_container_state.padding_top);
|
||||
}
|
||||
|
||||
auto grid_container_height = m_available_space->height.to_px_or_zero();
|
||||
CSSPixels sum_base_size_of_rows_and_gaps = 0;
|
||||
for (auto const& row_track : m_grid_rows_and_gaps) {
|
||||
sum_base_size_of_rows_and_gaps += row_track.base_size;
|
||||
}
|
||||
auto const& align_content = grid_container().computed_values().align_content();
|
||||
|
||||
CSSPixels y_start = 0;
|
||||
CSSPixels y_end = 0;
|
||||
if (align_content == CSS::AlignContent::Center || align_content == CSS::AlignContent::SpaceAround || align_content == CSS::AlignContent::SpaceEvenly) {
|
||||
auto free_space = grid_container_height - sum_base_size_of_rows_and_gaps;
|
||||
free_space = max(free_space, 0);
|
||||
y_start = free_space / 2;
|
||||
y_end = free_space / 2;
|
||||
} else if (align_content == CSS::AlignContent::End || align_content == CSS::AlignContent::FlexEnd) {
|
||||
auto free_space = grid_container_height - sum_base_size_of_rows_and_gaps;
|
||||
y_start = free_space;
|
||||
y_end = free_space;
|
||||
if (grid_item.column.has_value()) {
|
||||
if (grid_item.column == (int)m_grid_columns.size()) {
|
||||
place_into_track_formed_by_last_line_and_grid_container_padding_edge(GridDimension::Column);
|
||||
} else {
|
||||
place_into_track(GridDimension::Column);
|
||||
}
|
||||
} else {
|
||||
CSSPixels width = 0;
|
||||
for (auto const& col_track : m_grid_columns_and_gaps) {
|
||||
width += col_track.base_size;
|
||||
}
|
||||
auto const& grid_container_state = m_state.get(grid_container());
|
||||
width += grid_container_state.padding_left;
|
||||
width += grid_container_state.padding_right;
|
||||
area_rect.set_width(width);
|
||||
area_rect.set_x(-grid_container_state.padding_left);
|
||||
}
|
||||
|
||||
for (int i = 0; i < column_start; i++)
|
||||
x_start += m_grid_columns_and_gaps[i].base_size;
|
||||
for (int i = 0; i < column_end; i++)
|
||||
x_end += m_grid_columns_and_gaps[i].base_size;
|
||||
for (int i = 0; i < row_start; i++)
|
||||
y_start += m_grid_rows_and_gaps[i].base_size;
|
||||
for (int i = 0; i < row_end; i++) {
|
||||
y_end += m_grid_rows_and_gaps[i].base_size;
|
||||
}
|
||||
|
||||
return { x_start, y_start, x_end - x_start, y_end - y_start };
|
||||
return area_rect;
|
||||
}
|
||||
|
||||
void GridFormattingContext::run(AvailableSpace const& available_space)
|
||||
|
@ -2037,17 +2085,21 @@ void GridFormattingContext::layout_absolutely_positioned_element(Box const& box)
|
|||
auto& box_state = m_state.get_mutable(box);
|
||||
auto const& computed_values = box.computed_values();
|
||||
|
||||
auto is_auto_positioned = is_auto_positioned_track(computed_values.grid_row_start(), computed_values.grid_row_end()) || is_auto_positioned_track(computed_values.grid_column_start(), computed_values.grid_column_end());
|
||||
auto is_auto_row = is_auto_positioned_track(computed_values.grid_row_start(), computed_values.grid_row_end());
|
||||
auto is_auto_column = is_auto_positioned_track(computed_values.grid_column_start(), computed_values.grid_column_end());
|
||||
|
||||
auto row_placement_position = resolve_grid_position(box, GridDimension::Row);
|
||||
auto column_placement_position = resolve_grid_position(box, GridDimension::Column);
|
||||
GridItem item { box, {}, {}, {}, {} };
|
||||
if (!is_auto_row) {
|
||||
auto row_placement_position = resolve_grid_position(box, GridDimension::Row);
|
||||
item.row = row_placement_position.start;
|
||||
item.row_span = row_placement_position.span;
|
||||
}
|
||||
if (!is_auto_column) {
|
||||
auto column_placement_position = resolve_grid_position(box, GridDimension::Column);
|
||||
item.column = column_placement_position.start;
|
||||
item.column_span = column_placement_position.span;
|
||||
}
|
||||
|
||||
auto row_start = row_placement_position.start;
|
||||
auto row_span = row_placement_position.span;
|
||||
auto column_start = column_placement_position.start;
|
||||
auto column_span = column_placement_position.span;
|
||||
|
||||
GridItem item { box, row_start, row_span, column_start, column_span };
|
||||
auto grid_area_rect = get_grid_area_rect(item);
|
||||
auto available_width = AvailableSize::make_definite(grid_area_rect.width());
|
||||
auto available_height = AvailableSize::make_definite(grid_area_rect.height());
|
||||
|
@ -2136,12 +2188,6 @@ void GridFormattingContext::layout_absolutely_positioned_element(Box const& box)
|
|||
used_offset.set_x(grid_area_rect.x() + box_state.inset_left + box_state.margin_box_left());
|
||||
used_offset.set_y(grid_area_rect.y() + box_state.inset_top + box_state.margin_box_top());
|
||||
|
||||
// NOTE: Absolutely positioned boxes with auto-placement are relative to the *padding edge* of the containing block.
|
||||
if (is_auto_positioned) {
|
||||
auto const& containing_block_state = m_state.get_mutable(*box.containing_block());
|
||||
used_offset.translate_by(-containing_block_state.padding_left, -containing_block_state.padding_top);
|
||||
}
|
||||
|
||||
box_state.set_content_offset(used_offset);
|
||||
|
||||
if (independent_formatting_context)
|
||||
|
@ -2291,12 +2337,12 @@ bool OccupationGrid::is_occupied(int column_index, int row_index) const
|
|||
|
||||
int GridItem::gap_adjusted_row() const
|
||||
{
|
||||
return row * 2;
|
||||
return row.value() * 2;
|
||||
}
|
||||
|
||||
int GridItem::gap_adjusted_column() const
|
||||
{
|
||||
return column * 2;
|
||||
return column.value() * 2;
|
||||
}
|
||||
|
||||
CSSPixels GridFormattingContext::calculate_grid_container_maximum_size(GridDimension const dimension) const
|
||||
|
|
|
@ -37,19 +37,20 @@ struct GridPosition {
|
|||
struct GridItem {
|
||||
JS::NonnullGCPtr<Box const> box;
|
||||
|
||||
int row;
|
||||
size_t row_span;
|
||||
int column;
|
||||
size_t column_span;
|
||||
// Position and span are empty if the item is auto-placed which could only be the case for abspos items
|
||||
Optional<int> row;
|
||||
Optional<size_t> row_span;
|
||||
Optional<int> column;
|
||||
Optional<size_t> column_span;
|
||||
|
||||
[[nodiscard]] size_t span(GridDimension const dimension) const
|
||||
{
|
||||
return dimension == GridDimension::Column ? column_span : row_span;
|
||||
return dimension == GridDimension::Column ? column_span.value() : row_span.value();
|
||||
}
|
||||
|
||||
[[nodiscard]] int raw_position(GridDimension const dimension) const
|
||||
{
|
||||
return dimension == GridDimension::Column ? column : row;
|
||||
return dimension == GridDimension::Column ? column.value() : row.value();
|
||||
}
|
||||
|
||||
[[nodiscard]] CSSPixels add_margin_box_sizes(CSSPixels content_size, GridDimension dimension, LayoutState const& state) const
|
||||
|
@ -60,6 +61,11 @@ struct GridItem {
|
|||
return box_state.margin_box_top() + content_size + box_state.margin_box_bottom();
|
||||
}
|
||||
|
||||
[[nodiscard]] int gap_adjusted_position(GridDimension const dimension) const
|
||||
{
|
||||
return dimension == GridDimension::Column ? gap_adjusted_column() : gap_adjusted_row();
|
||||
}
|
||||
|
||||
[[nodiscard]] int gap_adjusted_row() const;
|
||||
[[nodiscard]] int gap_adjusted_column() const;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue