From 5e3da93f1a3bdcd1d0127305f770904e411328f4 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 6 Jun 2023 15:42:43 +0100 Subject: [PATCH] LibWeb: Add RatioStyleValue and parsing --- .../LibWeb/GenerateCSSPropertyID.cpp | 5 ++- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 13 +++++++ Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 + Userland/Libraries/LibWeb/CSS/Ratio.h | 19 ++++++++- Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 7 ++++ Userland/Libraries/LibWeb/CSS/StyleValue.h | 4 ++ .../LibWeb/CSS/StyleValues/RatioStyleValue.h | 39 +++++++++++++++++++ Userland/Libraries/LibWeb/Forward.h | 2 + 8 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/RatioStyleValue.h diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp index bab6ed06c98..b0f554a5c43 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp @@ -20,7 +20,7 @@ void generate_bounds_checking_function(JsonObject& properties, SourceGenerator& static bool type_name_is_enum(StringView type_name) { - return !AK::first_is_one_of(type_name, "angle"sv, "color"sv, "custom-ident"sv, "frequency"sv, "image"sv, "integer"sv, "length"sv, "number"sv, "percentage"sv, "rect"sv, "resolution"sv, "string"sv, "time"sv, "url"sv); + return !AK::first_is_one_of(type_name, "angle"sv, "color"sv, "custom-ident"sv, "frequency"sv, "image"sv, "integer"sv, "length"sv, "number"sv, "percentage"sv, "ratio"sv, "rect"sv, "resolution"sv, "string"sv, "time"sv, "url"sv); } ErrorOr serenity_main(Main::Arguments arguments) @@ -167,6 +167,7 @@ enum class ValueType { Paint, Percentage, Position, + Ratio, Rect, Resolution, String, @@ -612,6 +613,8 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type) property_generator.appendln(" case ValueType::Number:"); } else if (type_name == "percentage") { property_generator.appendln(" case ValueType::Percentage:"); + } else if (type_name == "ratio") { + property_generator.appendln(" case ValueType::Ratio:"); } else if (type_name == "rect") { property_generator.appendln(" case ValueType::Rect:"); } else if (type_name == "resolution") { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 7cf0f5cf0cb..d8b4c2c8212 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -4387,6 +4388,13 @@ ErrorOr> Parser::parse_color_value(ComponentValue const& comp return nullptr; } +ErrorOr> Parser::parse_ratio_value(TokenStream& tokens) +{ + if (auto ratio = parse_ratio(tokens); ratio.has_value()) + return RatioStyleValue::create(ratio.release_value()); + return nullptr; +} + ErrorOr> Parser::parse_string_value(ComponentValue const& component_value) { if (component_value.is(Token::Type::String)) @@ -7626,6 +7634,11 @@ ErrorOr Parser::parse_css_value_for_properties(Readonl } } + if (auto property = any_property_accepts_type(property_ids, ValueType::Ratio); property.has_value()) { + if (auto maybe_ratio = TRY(parse_ratio_value(tokens))) + return PropertyAndValue { *property, maybe_ratio }; + } + auto property_accepting_integer = any_property_accepts_type(property_ids, ValueType::Integer); auto property_accepting_number = any_property_accepts_type(property_ids, ValueType::Number); bool property_accepts_numeric = property_accepting_integer.has_value() || property_accepting_number.has_value(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index a72b0c976b1..d099ba44939 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -299,6 +299,7 @@ private: ErrorOr> parse_identifier_value(ComponentValue const&); ErrorOr> parse_color_value(ComponentValue const&); ErrorOr> parse_rect_value(ComponentValue const&); + ErrorOr> parse_ratio_value(TokenStream&); ErrorOr> parse_string_value(ComponentValue const&); ErrorOr> parse_image_value(ComponentValue const&); template diff --git a/Userland/Libraries/LibWeb/CSS/Ratio.h b/Userland/Libraries/LibWeb/CSS/Ratio.h index 2ee7098359f..1f3af802784 100644 --- a/Userland/Libraries/LibWeb/CSS/Ratio.h +++ b/Userland/Libraries/LibWeb/CSS/Ratio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022-2023, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -19,6 +19,23 @@ public: ErrorOr to_string() const; + bool operator==(Ratio const& other) const + { + return value() == other.value(); + } + + int operator<=>(Ratio const& other) const + { + auto this_value = value(); + auto other_value = other.value(); + + if (this_value < other_value) + return -1; + if (this_value > other_value) + return 1; + return 0; + } + private: float m_first_value { 0 }; float m_second_value { 1 }; diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index f67c7008bc6..95e783ab6fd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -321,6 +322,12 @@ RadialGradientStyleValue const& StyleValue::as_radial_gradient() const return static_cast(*this); } +RatioStyleValue const& StyleValue::as_ratio() const +{ + VERIFY(is_ratio()); + return static_cast(*this); +} + RectStyleValue const& StyleValue::as_rect() const { VERIFY(is_rect()); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index dae517ba76d..df94f2c5536 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -127,6 +127,7 @@ public: PlaceContent, Position, RadialGradient, + Ratio, Rect, Resolution, Shadow, @@ -183,6 +184,7 @@ public: 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_ratio() const { return type() == Type::Ratio; } bool is_rect() const { return type() == Type::Rect; } bool is_resolution() const { return type() == Type::Resolution; } bool is_shadow() const { return type() == Type::Shadow; } @@ -238,6 +240,7 @@ public: PlaceContentStyleValue const& as_place_content() const; PositionStyleValue const& as_position() const; RadialGradientStyleValue const& as_radial_gradient() const; + RatioStyleValue const& as_ratio() const; RectStyleValue const& as_rect() const; ResolutionStyleValue const& as_resolution() const; ShadowStyleValue const& as_shadow() const; @@ -290,6 +293,7 @@ public: 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()); } + RatioStyleValue& as_ratio() { return const_cast(const_cast(*this).as_ratio()); } RectStyleValue& as_rect() { return const_cast(const_cast(*this).as_rect()); } ResolutionStyleValue& as_resolution() { return const_cast(const_cast(*this).as_resolution()); } ShadowStyleValue& as_shadow() { return const_cast(const_cast(*this).as_shadow()); } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/RatioStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/RatioStyleValue.h new file mode 100644 index 00000000000..99eff85e19d --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/RatioStyleValue.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::CSS { + +class RatioStyleValue final : public StyleValueWithDefaultOperators { +public: + static ErrorOr> create(Ratio ratio) + { + return adopt_nonnull_ref_or_enomem(new (nothrow) RatioStyleValue(move(ratio))); + } + virtual ~RatioStyleValue() override = default; + + Ratio const& ratio() const { return m_ratio; } + Ratio& ratio() { return m_ratio; } + + virtual ErrorOr to_string() const override { return m_ratio.to_string(); } + + bool properties_equal(RatioStyleValue const& other) const { return m_ratio == other.m_ratio; } + +private: + RatioStyleValue(Ratio&& ratio) + : StyleValueWithDefaultOperators(Type::Ratio) + , m_ratio(ratio) + { + } + + Ratio m_ratio; +}; + +} diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index d15b6456fd7..89b27f77019 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -140,6 +140,8 @@ class PlaceContentStyleValue; class PositionStyleValue; class PropertyOwningCSSStyleDeclaration; class RadialGradientStyleValue; +class Ratio; +class RatioStyleValue; class RectStyleValue; class Resolution; class ResolutionStyleValue;