LibWeb: Improve grid-template-area parsing and serialization

This commit is contained in:
Gingeh 2024-11-15 16:16:03 +11:00 committed by Sam Atkins
commit 0afd7f166a
Notes: github-actions[bot] 2024-12-02 16:20:49 +00:00
13 changed files with 274 additions and 62 deletions

View file

@ -22,6 +22,7 @@
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/CSSStyleValue.h>
#include <LibWeb/CSS/CalculatedOr.h>
#include <LibWeb/CSS/CharacterTypes.h>
#include <LibWeb/CSS/EdgeRect.h>
#include <LibWeb/CSS/MediaList.h>
#include <LibWeb/CSS/Parser/Parser.h>
@ -7804,20 +7805,60 @@ RefPtr<CSSStyleValue> Parser::parse_grid_shorthand_value(TokenStream<ComponentVa
RefPtr<CSSStyleValue> Parser::parse_grid_template_areas_value(TokenStream<ComponentValue>& tokens)
{
// none | <string>+
Vector<Vector<String>> grid_area_rows;
if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None))
return GridTemplateAreaStyleValue::create(move(grid_area_rows));
return GridTemplateAreaStyleValue::create({});
auto is_full_stop = [](u32 code_point) {
return code_point == '.';
};
auto consume_while = [](Utf8CodePointIterator& code_points, AK::Function<bool(u32)> predicate) {
StringBuilder builder;
while (!code_points.done() && predicate(*code_points)) {
builder.append_code_point(*code_points);
++code_points;
}
return MUST(builder.to_string());
};
Vector<Vector<String>> grid_area_rows;
Optional<size_t> column_count;
auto transaction = tokens.begin_transaction();
while (tokens.has_next_token() && tokens.next_token().is(Token::Type::String)) {
Vector<String> grid_area_columns;
auto const parts = MUST(tokens.consume_a_token().token().string().to_string().split(' '));
for (auto& part : parts) {
grid_area_columns.append(part);
auto string = tokens.consume_a_token().token().string().code_points();
auto code_points = string.begin();
while (!code_points.done()) {
if (is_whitespace(*code_points)) {
consume_while(code_points, is_whitespace);
} else if (is_full_stop(*code_points)) {
consume_while(code_points, *is_full_stop);
grid_area_columns.append("."_string);
} else if (is_ident_code_point(*code_points)) {
auto token = consume_while(code_points, is_ident_code_point);
grid_area_columns.append(move(token));
} else {
return nullptr;
}
}
if (grid_area_columns.is_empty())
return nullptr;
if (column_count.has_value()) {
if (grid_area_columns.size() != column_count)
return nullptr;
} else {
column_count = grid_area_columns.size();
}
grid_area_rows.append(move(grid_area_columns));
}
// FIXME: If a named grid area spans multiple grid cells, but those cells do not form a single filled-in rectangle, the declaration is invalid.
transaction.commit();
return GridTemplateAreaStyleValue::create(grid_area_rows);
}

View file

@ -8,6 +8,7 @@
*/
#include "GridTemplateAreaStyleValue.h"
#include <LibWeb/CSS/Serialize.h>
namespace Web::CSS {
@ -23,13 +24,15 @@ String GridTemplateAreaStyleValue::to_string() const
StringBuilder builder;
for (size_t y = 0; y < m_grid_template_area.size(); ++y) {
if (y != 0)
builder.append(' ');
StringBuilder row_builder;
for (size_t x = 0; x < m_grid_template_area[y].size(); ++x) {
builder.appendff("{}", m_grid_template_area[y][x]);
if (x < m_grid_template_area[y].size() - 1)
builder.append(" "sv);
if (x != 0)
row_builder.append(' ');
row_builder.appendff("{}", m_grid_template_area[y][x]);
}
if (y < m_grid_template_area.size() - 1)
builder.append(", "sv);
serialize_a_string(builder, row_builder.string_view());
}
return MUST(builder.to_string());
}