mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 03:57:44 +00:00
LibWeb: Define if identifier represent area or line during layout [GFC]
This fixes regression introduced in
c03e025a32
by assuming that it is
possible to determine whether identifier stands for line or area
during parsing.
This commit is contained in:
parent
5d7e73adfe
commit
b66f65dc9e
10 changed files with 104 additions and 145 deletions
|
@ -17,13 +17,15 @@ String GridTrackPlacement::to_string() const
|
|||
[&](Auto const&) {
|
||||
builder.append("auto"sv);
|
||||
},
|
||||
[&](Area const& area) {
|
||||
builder.append(area.name);
|
||||
},
|
||||
[&](Line const& line) {
|
||||
builder.appendff("{}", line.value);
|
||||
if (line.name.has_value())
|
||||
builder.appendff(" {}", line.name.value());
|
||||
[&](AreaOrLine const& area_or_line) {
|
||||
if (area_or_line.line_number.has_value() && area_or_line.name.has_value()) {
|
||||
builder.appendff("{} {}", *area_or_line.line_number, *area_or_line.name);
|
||||
} else if (area_or_line.line_number.has_value()) {
|
||||
builder.appendff("{}", *area_or_line.line_number);
|
||||
}
|
||||
if (area_or_line.name.has_value()) {
|
||||
builder.appendff("{}", *area_or_line.name);
|
||||
}
|
||||
},
|
||||
[&](Span const& span) {
|
||||
builder.appendff("span {}", span.value);
|
||||
|
|
|
@ -18,14 +18,9 @@ public:
|
|||
return GridTrackPlacement();
|
||||
}
|
||||
|
||||
static GridTrackPlacement make_area(String name)
|
||||
static GridTrackPlacement make_line(Optional<int> line_number, Optional<String> name)
|
||||
{
|
||||
return GridTrackPlacement(Area { .name = name });
|
||||
}
|
||||
|
||||
static GridTrackPlacement make_line(int value, Optional<String> name)
|
||||
{
|
||||
return GridTrackPlacement(Line { .value = value, .name = name });
|
||||
return GridTrackPlacement(AreaOrLine { .line_number = line_number, .name = name });
|
||||
}
|
||||
|
||||
static GridTrackPlacement make_span(int value)
|
||||
|
@ -34,21 +29,25 @@ public:
|
|||
}
|
||||
|
||||
bool is_auto() const { return m_value.has<Auto>(); }
|
||||
bool is_area() const { return m_value.has<Area>(); }
|
||||
bool is_line() const { return m_value.has<Line>(); }
|
||||
bool is_span() const { return m_value.has<Span>(); }
|
||||
bool is_area_or_line() const { return m_value.has<AreaOrLine>(); }
|
||||
|
||||
bool is_auto_positioned() const { return is_auto() || is_span(); }
|
||||
bool is_positioned() const { return !is_auto_positioned(); }
|
||||
|
||||
bool has_line_name() const
|
||||
bool has_identifier() const
|
||||
{
|
||||
return is_line() && m_value.get<Line>().name.has_value();
|
||||
return is_area_or_line() && m_value.get<AreaOrLine>().name.has_value();
|
||||
}
|
||||
|
||||
String area_name() const { return m_value.get<Area>().name; }
|
||||
String line_name() const { return m_value.get<Line>().name.value(); }
|
||||
int line_number() const { return m_value.get<Line>().value; }
|
||||
bool has_line_number() const
|
||||
{
|
||||
return is_area_or_line() && m_value.get<AreaOrLine>().line_number.has_value();
|
||||
}
|
||||
|
||||
String identifier() const { return *m_value.get<AreaOrLine>().name; }
|
||||
|
||||
int line_number() const { return *m_value.get<AreaOrLine>().line_number; }
|
||||
int span() const { return m_value.get<Span>().value; }
|
||||
|
||||
String to_string() const;
|
||||
|
@ -60,15 +59,10 @@ private:
|
|||
bool operator==(Auto const&) const = default;
|
||||
};
|
||||
|
||||
struct Area {
|
||||
String name;
|
||||
bool operator==(Area const& other) const = default;
|
||||
};
|
||||
|
||||
struct Line {
|
||||
int value;
|
||||
struct AreaOrLine {
|
||||
Optional<int> line_number;
|
||||
Optional<String> name;
|
||||
bool operator==(Line const& other) const = default;
|
||||
bool operator==(AreaOrLine const& other) const = default;
|
||||
};
|
||||
|
||||
struct Span {
|
||||
|
@ -78,14 +72,12 @@ private:
|
|||
|
||||
GridTrackPlacement()
|
||||
: m_value(Auto {}) {};
|
||||
GridTrackPlacement(Area value)
|
||||
: m_value(value) {};
|
||||
GridTrackPlacement(Line value)
|
||||
GridTrackPlacement(AreaOrLine value)
|
||||
: m_value(value) {};
|
||||
GridTrackPlacement(Span value)
|
||||
: m_value(value) {};
|
||||
|
||||
Variant<Auto, Area, Line, Span> m_value;
|
||||
Variant<Auto, AreaOrLine, Span> m_value;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -5371,7 +5371,7 @@ RefPtr<StyleValue> Parser::parse_grid_track_placement(Vector<ComponentValue> con
|
|||
if (is_identifier(current_token)) {
|
||||
auto maybe_string = String::from_utf8(current_token.ident());
|
||||
if (!maybe_string.is_error())
|
||||
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_area(maybe_string.value()));
|
||||
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line({}, maybe_string.value()));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -136,13 +136,13 @@ void GridFormattingContext::place_item_with_row_and_column_position(Box const& c
|
|||
|
||||
int row_start = 0, row_end = 0, column_start = 0, column_end = 0;
|
||||
|
||||
if (grid_row_start.is_line())
|
||||
if (grid_row_start.has_line_number())
|
||||
row_start = child_box.computed_values().grid_row_start().line_number() - 1;
|
||||
if (grid_row_end.is_line())
|
||||
if (grid_row_end.has_line_number())
|
||||
row_end = child_box.computed_values().grid_row_end().line_number() - 1;
|
||||
if (grid_column_start.is_line())
|
||||
if (grid_column_start.has_line_number())
|
||||
column_start = child_box.computed_values().grid_column_start().line_number() - 1;
|
||||
if (grid_column_end.is_line())
|
||||
if (grid_column_end.has_line_number())
|
||||
column_end = child_box.computed_values().grid_column_end().line_number() - 1;
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#line-placement
|
||||
|
@ -174,15 +174,15 @@ void GridFormattingContext::place_item_with_row_and_column_position(Box const& c
|
|||
// grid-column-start line.
|
||||
size_t row_span = 1;
|
||||
size_t column_span = 1;
|
||||
if (grid_row_start.is_line() && grid_row_end.is_span())
|
||||
if (grid_row_start.has_line_number() && grid_row_end.is_span())
|
||||
row_span = grid_row_end.span();
|
||||
if (grid_column_start.is_line() && grid_column_end.is_span())
|
||||
if (grid_column_start.has_line_number() && grid_column_end.is_span())
|
||||
column_span = grid_column_end.span();
|
||||
if (grid_row_end.is_line() && child_box.computed_values().grid_row_start().is_span()) {
|
||||
if (grid_row_end.has_line_number() && child_box.computed_values().grid_row_start().is_span()) {
|
||||
row_span = grid_row_start.span();
|
||||
row_start = row_end - row_span;
|
||||
}
|
||||
if (grid_column_end.is_line() && grid_column_start.is_span()) {
|
||||
if (grid_column_end.has_line_number() && grid_column_start.is_span()) {
|
||||
column_span = grid_column_start.span();
|
||||
column_start = column_end - column_span;
|
||||
}
|
||||
|
@ -200,54 +200,39 @@ void GridFormattingContext::place_item_with_row_and_column_position(Box const& c
|
|||
// https://www.w3.org/TR/css-grid-2/#common-uses-named-lines
|
||||
// 8.1.3. Named Lines and Spans
|
||||
// Instead of counting lines by number, lines can be referenced by their line name:
|
||||
if (grid_column_end.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_end.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_column_end.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_end.identifier()); maybe_grid_area.has_value())
|
||||
column_end = maybe_grid_area->column_end;
|
||||
else
|
||||
column_end = 1;
|
||||
column_start = column_end - 1;
|
||||
} else if (grid_column_end.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_column_end.line_name(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_column_end.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
column_end = line_name_index;
|
||||
else
|
||||
column_end = 1;
|
||||
column_start = column_end - 1;
|
||||
}
|
||||
|
||||
if (grid_column_start.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_start.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_column_start.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_start.identifier()); maybe_grid_area.has_value())
|
||||
column_start = maybe_grid_area->column_start;
|
||||
else
|
||||
column_start = 0;
|
||||
}
|
||||
if (grid_column_start.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_column_start.line_name(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_column_start.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
column_start = line_name_index;
|
||||
else
|
||||
column_start = 0;
|
||||
}
|
||||
|
||||
if (grid_row_end.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_end.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_row_end.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_end.identifier()); maybe_grid_area.has_value())
|
||||
row_end = maybe_grid_area->row_end;
|
||||
else
|
||||
row_end = 1;
|
||||
row_start = row_end - 1;
|
||||
} else if (grid_row_end.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_row_end.line_name(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_row_end.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
row_end = line_name_index;
|
||||
else
|
||||
row_end = 1;
|
||||
row_start = row_end - 1;
|
||||
}
|
||||
|
||||
if (grid_row_start.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_start.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_row_start.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_start.identifier()); maybe_grid_area.has_value())
|
||||
row_start = maybe_grid_area->row_start;
|
||||
else
|
||||
row_start = 0;
|
||||
} else if (grid_row_start.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_row_start.line_name(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_row_start.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
row_start = line_name_index;
|
||||
else
|
||||
row_start = 0;
|
||||
|
@ -301,9 +286,9 @@ void GridFormattingContext::place_item_with_row_position(Box const& child_box)
|
|||
|
||||
int row_start = 0, row_end = 0;
|
||||
|
||||
if (grid_row_start.is_line())
|
||||
if (grid_row_start.has_line_number())
|
||||
row_start = grid_row_start.line_number() - 1;
|
||||
if (grid_row_end.is_line())
|
||||
if (grid_row_end.has_line_number())
|
||||
row_end = grid_row_end.line_number() - 1;
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#line-placement
|
||||
|
@ -332,9 +317,9 @@ void GridFormattingContext::place_item_with_row_position(Box const& child_box)
|
|||
// grid-column-end: span 2 indicates the second grid line in the endward direction from the
|
||||
// grid-column-start line.
|
||||
size_t row_span = 1;
|
||||
if (grid_row_start.is_line() && grid_row_end.is_span())
|
||||
if (grid_row_start.has_line_number() && grid_row_end.is_span())
|
||||
row_span = grid_row_end.span();
|
||||
if (grid_row_end.is_line() && grid_row_start.is_span()) {
|
||||
if (grid_row_end.has_line_number() && grid_row_start.is_span()) {
|
||||
row_span = grid_row_start.span();
|
||||
row_start = row_end - row_span;
|
||||
// FIXME: Remove me once have implemented spans overflowing into negative indexes, e.g., grid-row: span 2 / 1
|
||||
|
@ -355,27 +340,20 @@ void GridFormattingContext::place_item_with_row_position(Box const& child_box)
|
|||
// https://www.w3.org/TR/css-grid-2/#common-uses-named-lines
|
||||
// 8.1.3. Named Lines and Spans
|
||||
// Instead of counting lines by number, lines can be referenced by their line name:
|
||||
if (grid_row_end.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_end.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_row_end.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_end.identifier()); maybe_grid_area.has_value())
|
||||
row_end = maybe_grid_area->row_end;
|
||||
else
|
||||
row_end = 1;
|
||||
row_start = row_end - 1;
|
||||
} else if (grid_row_end.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_row_end.line_name(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_row_end.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
row_end = line_name_index - 1;
|
||||
else
|
||||
row_end = 1;
|
||||
row_start = row_end - 1;
|
||||
}
|
||||
|
||||
if (grid_row_start.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_start.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_row_start.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_row_start.identifier()); maybe_grid_area.has_value())
|
||||
row_start = maybe_grid_area->row_start;
|
||||
else
|
||||
row_start = 0;
|
||||
} else if (grid_row_start.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_row_start.line_name(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_row_start.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
|
||||
row_start = line_name_index;
|
||||
else
|
||||
row_start = 0;
|
||||
|
@ -436,15 +414,15 @@ void GridFormattingContext::place_item_with_column_position(Box const& child_box
|
|||
auto const& grid_column_end = child_box.computed_values().grid_column_end();
|
||||
|
||||
int column_start = 0;
|
||||
if (grid_column_start.is_line() && grid_column_start.line_number() > 0) {
|
||||
if (grid_column_start.has_line_number() && grid_column_start.line_number() > 0) {
|
||||
column_start = grid_column_start.line_number() - 1;
|
||||
} else if (grid_column_start.is_line()) {
|
||||
} else if (grid_column_start.has_line_number()) {
|
||||
// NOTE: Negative indexes count from the end side of the explicit grid
|
||||
column_start = m_explicit_columns_line_count + grid_column_start.line_number();
|
||||
}
|
||||
|
||||
int column_end = 0;
|
||||
if (grid_column_end.is_line())
|
||||
if (grid_column_end.has_line_number())
|
||||
column_end = grid_column_end.line_number() - 1;
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#line-placement
|
||||
|
@ -474,9 +452,9 @@ void GridFormattingContext::place_item_with_column_position(Box const& child_box
|
|||
// grid-column-start line.
|
||||
size_t column_span = 1;
|
||||
size_t row_span = grid_row_start.is_span() ? grid_row_start.span() : 1;
|
||||
if (grid_column_start.is_line() && grid_column_end.is_span())
|
||||
if (grid_column_start.has_line_number() && grid_column_end.is_span())
|
||||
column_span = grid_column_end.span();
|
||||
if (grid_column_end.is_line() && grid_column_start.is_span()) {
|
||||
if (grid_column_end.has_line_number() && grid_column_start.is_span()) {
|
||||
column_span = grid_column_start.span();
|
||||
column_start = column_end - column_span;
|
||||
// FIXME: Remove me once have implemented spans overflowing into negative indexes, e.g., grid-column: span 2 / 1
|
||||
|
@ -500,31 +478,24 @@ void GridFormattingContext::place_item_with_column_position(Box const& child_box
|
|||
// https://www.w3.org/TR/css-grid-2/#common-uses-named-lines
|
||||
// 8.1.3. Named Lines and Spans
|
||||
// Instead of counting lines by number, lines can be referenced by their line name:
|
||||
if (grid_column_end.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_end.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_column_end.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_end.identifier()); maybe_grid_area.has_value())
|
||||
column_end = maybe_grid_area->column_end;
|
||||
else
|
||||
column_end = 1;
|
||||
column_start = column_end - 1;
|
||||
} else if (grid_column_end.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_column_end.line_name(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_column_end.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
column_end = line_name_index;
|
||||
else
|
||||
column_end = 1;
|
||||
column_start = column_end - 1;
|
||||
}
|
||||
|
||||
if (grid_column_start.is_area()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_start.area_name()); maybe_grid_area.has_value())
|
||||
if (grid_column_start.has_identifier()) {
|
||||
if (auto maybe_grid_area = m_grid_areas.get(grid_column_start.identifier()); maybe_grid_area.has_value())
|
||||
column_start = maybe_grid_area->column_start;
|
||||
else
|
||||
column_start = 0;
|
||||
}
|
||||
if (grid_column_start.has_line_name()) {
|
||||
if (auto line_name_index = get_line_index_by_line_name(grid_column_start.line_name(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
|
||||
else if (auto line_name_index = get_line_index_by_line_name(grid_column_start.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1) {
|
||||
column_start = line_name_index;
|
||||
else
|
||||
} else {
|
||||
column_start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are multiple lines of the same name, they effectively establish a named set of grid
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue