diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index b0b233fc393..00d52171c66 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -4403,6 +4403,74 @@ RefPtr Parser::parse_border_radius_shorthand_value(TokenStream Parser::parse_columns_value(TokenStream& tokens) +{ + if (tokens.remaining_token_count() > 2) + return nullptr; + + RefPtr column_count; + RefPtr column_width; + + Vector remaining_longhands { PropertyID::ColumnCount, PropertyID::ColumnWidth }; + int found_autos = 0; + + auto transaction = tokens.begin_transaction(); + while (tokens.has_next_token()) { + auto property_and_value = parse_css_value_for_properties(remaining_longhands, tokens); + if (!property_and_value.has_value()) + return nullptr; + auto& value = property_and_value->style_value; + + // since the values can be in either order, we want to skip over autos + if (value->has_auto()) { + found_autos++; + continue; + } + + remove_property(remaining_longhands, property_and_value->property); + + switch (property_and_value->property) { + case PropertyID::ColumnCount: { + VERIFY(!column_count); + column_count = value.release_nonnull(); + continue; + } + case PropertyID::ColumnWidth: { + VERIFY(!column_width); + column_width = value.release_nonnull(); + continue; + } + default: + VERIFY_NOT_REACHED(); + } + } + + if (found_autos > 2) + return nullptr; + + if (found_autos == 2) { + column_count = CSSKeywordValue::create(Keyword::Auto); + column_width = CSSKeywordValue::create(Keyword::Auto); + } + + if (found_autos == 1) { + if (!column_count) + column_count = CSSKeywordValue::create(Keyword::Auto); + if (!column_width) + column_width = CSSKeywordValue::create(Keyword::Auto); + } + + if (!column_count) + column_count = property_initial_value(m_context.realm(), PropertyID::ColumnCount); + if (!column_width) + column_width = property_initial_value(m_context.realm(), PropertyID::ColumnWidth); + + transaction.commit(); + return ShorthandStyleValue::create(PropertyID::Columns, + { PropertyID::ColumnCount, PropertyID::ColumnWidth }, + { column_count.release_nonnull(), column_width.release_nonnull() }); +} + RefPtr Parser::parse_shadow_value(TokenStream& tokens, AllowInsetKeyword allow_inset_keyword) { // "none" @@ -7193,6 +7261,10 @@ Parser::ParseErrorOr> Parser::parse_css_value(Prope if (auto parsed_value = parse_shadow_value(tokens, AllowInsetKeyword::Yes); parsed_value && !tokens.has_next_token()) return parsed_value.release_nonnull(); return ParseError::SyntaxError; + case PropertyID::Columns: + if (auto parsed_value = parse_columns_value(tokens); parsed_value && !tokens.has_next_token()) + return parsed_value.release_nonnull(); + return ParseError::SyntaxError; case PropertyID::Content: if (auto parsed_value = parse_content_value(tokens); parsed_value && !tokens.has_next_token()) return parsed_value.release_nonnull(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index e1e45fb183b..323074160b0 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -288,6 +288,7 @@ private: RefPtr parse_border_value(PropertyID, TokenStream&); RefPtr parse_border_radius_value(TokenStream&); RefPtr parse_border_radius_shorthand_value(TokenStream&); + RefPtr parse_columns_value(TokenStream&); RefPtr parse_content_value(TokenStream&); RefPtr parse_counter_increment_value(TokenStream&); RefPtr parse_counter_reset_value(TokenStream&); diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json index de8fb7e4121..390ce102f4a 100644 --- a/Userland/Libraries/LibWeb/CSS/Properties.json +++ b/Userland/Libraries/LibWeb/CSS/Properties.json @@ -979,6 +979,14 @@ "auto" ] }, + "columns": { + "inherited": false, + "initial": "auto auto", + "longhands": [ + "column-width", + "column-count" + ] + }, "content": { "animation-type": "discrete", "inherited": false, diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp index 14ecd25ec29..5c22ba6f219 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp @@ -93,6 +93,19 @@ String ShorthandStyleValue::to_string() const bottom_right.vertical_radius().to_string(), bottom_left.vertical_radius().to_string())); } + case PropertyID::Columns: { + auto column_width = longhand(PropertyID::ColumnWidth)->to_string(); + auto column_count = longhand(PropertyID::ColumnCount)->to_string(); + + if (column_width == column_count) + return column_width; + if (column_width.equals_ignoring_ascii_case("auto"sv)) + return column_count; + if (column_count.equals_ignoring_ascii_case("auto"sv)) + return column_width; + + return MUST(String::formatted("{} {}", column_width, column_count)); + } case PropertyID::Flex: return MUST(String::formatted("{} {} {}", longhand(PropertyID::FlexGrow)->to_string(), longhand(PropertyID::FlexShrink)->to_string(), longhand(PropertyID::FlexBasis)->to_string())); case PropertyID::FlexFlow: