From dcead6f5ebec4f4df1c27b641954d2f8ba5a9edb Mon Sep 17 00:00:00 2001 From: FalseHonesty Date: Mon, 29 May 2023 16:34:53 -0400 Subject: [PATCH] LibWeb: Add support for parsing place-content shorthand CSS property --- .../place-content-shorthand-property.txt | 9 ++++ .../place-content-shorthand-property.html | 9 ++++ Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 27 ++++++++++++ Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 + Userland/Libraries/LibWeb/CSS/Properties.json | 8 ++++ .../Libraries/LibWeb/CSS/StyleComputer.cpp | 14 +++++++ Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 7 ++++ Userland/Libraries/LibWeb/CSS/StyleValue.h | 4 ++ .../StyleValues/PlaceContentStyleValue.cpp | 16 +++++++ .../CSS/StyleValues/PlaceContentStyleValue.h | 42 +++++++++++++++++++ Userland/Libraries/LibWeb/Forward.h | 1 + 12 files changed, 139 insertions(+) create mode 100644 Tests/LibWeb/Layout/expected/place-content-shorthand-property.txt create mode 100644 Tests/LibWeb/Layout/input/place-content-shorthand-property.html create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.h diff --git a/Tests/LibWeb/Layout/expected/place-content-shorthand-property.txt b/Tests/LibWeb/Layout/expected/place-content-shorthand-property.txt new file mode 100644 index 0000000000..6be17aa7bd --- /dev/null +++ b/Tests/LibWeb/Layout/expected/place-content-shorthand-property.txt @@ -0,0 +1,9 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x37.46875 [BFC] children: not-inline + BlockContainer at (10,10) content-size 780x19.46875 children: not-inline + Box at (11,11) content-size 800x17.46875 flex-container(row) [FFC] children: not-inline + BlockContainer <(anonymous)> at (392.210937,11) content-size 37.578125x17.46875 flex-item [BFC] children: inline + line 0 width: 37.578125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 4, rect: [392.210937,11 37.578125x17.46875] + "Text" + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/place-content-shorthand-property.html b/Tests/LibWeb/Layout/input/place-content-shorthand-property.html new file mode 100644 index 0000000000..e50d4bdb82 --- /dev/null +++ b/Tests/LibWeb/Layout/input/place-content-shorthand-property.html @@ -0,0 +1,9 @@ +
Text \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 41ff064808..e5a66521b2 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -101,6 +101,7 @@ set(SOURCES CSS/StyleValues/ListStyleStyleValue.cpp CSS/StyleValues/NumericStyleValue.cpp CSS/StyleValues/OverflowStyleValue.cpp + CSS/StyleValues/PlaceContentStyleValue.cpp CSS/StyleValues/PositionStyleValue.cpp CSS/StyleValues/RadialGradientStyleValue.cpp CSS/StyleValues/RectStyleValue.cpp diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 902babeda0..9a43ea5d34 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -6105,6 +6106,28 @@ ErrorOr> Parser::parse_overflow_value(Vector return nullptr; } +ErrorOr> Parser::parse_place_content_value(Vector const& component_values) +{ + if (component_values.size() > 2) + return nullptr; + + auto tokens = TokenStream { component_values }; + auto maybe_align_content_value = TRY(parse_css_value_for_property(PropertyID::AlignContent, tokens)); + if (!maybe_align_content_value) + return nullptr; + + if (component_values.size() == 1) { + if (!property_accepts_identifier(PropertyID::JustifyContent, maybe_align_content_value->to_identifier())) + return nullptr; + return PlaceContentStyleValue::create(*maybe_align_content_value, *maybe_align_content_value); + } + + auto maybe_justify_content_value = TRY(parse_css_value_for_property(PropertyID::JustifyContent, tokens)); + if (!maybe_justify_content_value) + return nullptr; + return PlaceContentStyleValue::create(maybe_align_content_value.release_nonnull(), maybe_justify_content_value.release_nonnull()); +} + ErrorOr> Parser::parse_text_decoration_value(Vector const& component_values) { RefPtr decoration_line; @@ -7227,6 +7250,10 @@ Parser::ParseErrorOr> Parser::parse_css_value(Property if (auto parsed_value = FIXME_TRY(parse_overflow_value(component_values))) return parsed_value.release_nonnull(); return ParseError::SyntaxError; + case PropertyID::PlaceContent: + if (auto parsed_value = FIXME_TRY(parse_place_content_value(component_values))) + return parsed_value.release_nonnull(); + return ParseError::SyntaxError; case PropertyID::TextDecoration: if (auto parsed_value = FIXME_TRY(parse_text_decoration_value(component_values))) return parsed_value.release_nonnull(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 6943ab0e0a..51cf8cd7a0 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -317,6 +317,7 @@ private: ErrorOr> parse_font_family_value(TokenStream&); ErrorOr> parse_list_style_value(Vector const&); ErrorOr> parse_overflow_value(Vector const&); + ErrorOr> parse_place_content_value(Vector const&); enum class AllowInsetKeyword { No, Yes, diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json index effb79a88e..03a5558263 100644 --- a/Userland/Libraries/LibWeb/CSS/Properties.json +++ b/Userland/Libraries/LibWeb/CSS/Properties.json @@ -1543,6 +1543,14 @@ "unitless-length" ] }, + "place-content": { + "inherited": false, + "initial": "normal", + "longhands": [ + "align-content", + "justify-content" + ] + }, "pointer-events": { "affects-layout": false, "inherited": true, diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 0fc12fb9dd..6e7372af67 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -343,6 +344,19 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope return; } + if (property_id == CSS::PropertyID::PlaceContent) { + if (value.is_place_content()) { + auto const& place_content = value.as_place_content(); + style.set_property(CSS::PropertyID::AlignContent, place_content.align_content()); + style.set_property(CSS::PropertyID::JustifyContent, place_content.justify_content()); + return; + } + + style.set_property(CSS::PropertyID::AlignContent, value); + style.set_property(CSS::PropertyID::JustifyContent, value); + return; + } + if (property_id == CSS::PropertyID::Border) { set_property_expanding_shorthands(style, CSS::PropertyID::BorderTop, value, document, declaration); set_property_expanding_shorthands(style, CSS::PropertyID::BorderRight, value, document, declaration); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 6a1bd6b180..8aaa8a357b 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -295,6 +296,12 @@ PercentageStyleValue const& StyleValue::as_percentage() const return static_cast(*this); } +PlaceContentStyleValue const& StyleValue::as_place_content() const +{ + VERIFY(is_place_content()); + return static_cast(*this); +} + PositionStyleValue const& StyleValue::as_position() const { VERIFY(is_position()); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 9fe07caa69..20465076ba 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -123,6 +123,7 @@ public: Numeric, Overflow, Percentage, + PlaceContent, Position, RadialGradient, Rect, @@ -177,6 +178,7 @@ public: bool is_numeric() const { return type() == Type::Numeric; } bool is_overflow() const { return type() == Type::Overflow; } bool is_percentage() const { return type() == Type::Percentage; } + bool is_place_content() const { return type() == Type::PlaceContent; } bool is_position() const { return type() == Type::Position; } bool is_radial_gradient() const { return type() == Type::RadialGradient; } bool is_rect() const { return type() == Type::Rect; } @@ -230,6 +232,7 @@ public: NumericStyleValue const& as_numeric() const; OverflowStyleValue const& as_overflow() const; PercentageStyleValue const& as_percentage() const; + PlaceContentStyleValue const& as_place_content() const; PositionStyleValue const& as_position() const; RadialGradientStyleValue const& as_radial_gradient() const; RectStyleValue const& as_rect() const; @@ -280,6 +283,7 @@ public: NumericStyleValue& as_numeric() { return const_cast(const_cast(*this).as_numeric()); } OverflowStyleValue& as_overflow() { return const_cast(const_cast(*this).as_overflow()); } PercentageStyleValue& as_percentage() { return const_cast(const_cast(*this).as_percentage()); } + PlaceContentStyleValue& as_place_content() { return const_cast(const_cast(*this).as_place_content()); } PositionStyleValue& as_position() { return const_cast(const_cast(*this).as_position()); } RadialGradientStyleValue& as_radial_gradient() { return const_cast(const_cast(*this).as_radial_gradient()); } RectStyleValue& as_rect() { return const_cast(const_cast(*this).as_rect()); } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.cpp new file mode 100644 index 0000000000..32d19ce176 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Hunter Salyer + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "PlaceContentStyleValue.h" + +namespace Web::CSS { + +ErrorOr PlaceContentStyleValue::to_string() const +{ + return String::formatted("{} {}", TRY(m_properties.align_content->to_string()), TRY(m_properties.justify_content->to_string())); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.h new file mode 100644 index 0000000000..67fc27e636 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/PlaceContentStyleValue.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Hunter Salyer + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::CSS { + +class PlaceContentStyleValue final : public StyleValueWithDefaultOperators { +public: + static ErrorOr> create(ValueComparingNonnullRefPtr align_content, ValueComparingNonnullRefPtr justify_content) + { + return adopt_nonnull_ref_or_enomem(new (nothrow) PlaceContentStyleValue(move(align_content), move(justify_content))); + } + virtual ~PlaceContentStyleValue() override = default; + + ValueComparingNonnullRefPtr align_content() const { return m_properties.align_content; } + ValueComparingNonnullRefPtr justify_content() const { return m_properties.justify_content; } + + virtual ErrorOr to_string() const override; + + bool properties_equal(PlaceContentStyleValue const& other) const { return m_properties == other.m_properties; }; + +private: + PlaceContentStyleValue(ValueComparingNonnullRefPtr align_content, ValueComparingNonnullRefPtr justify_content) + : StyleValueWithDefaultOperators(Type::PlaceContent) + , m_properties { .align_content = move(align_content), .justify_content = move(justify_content) } + { + } + + struct Properties { + ValueComparingNonnullRefPtr align_content; + ValueComparingNonnullRefPtr justify_content; + bool operator==(Properties const&) const = default; + } m_properties; +}; + +} diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index d47b0ab8b7..1e0650c113 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -135,6 +135,7 @@ class OverflowStyleValue; class Percentage; class PercentageOrCalculated; class PercentageStyleValue; +class PlaceContentStyleValue; class PositionStyleValue; class PropertyOwningCSSStyleDeclaration; class RadialGradientStyleValue;