diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp index 6553dfc49e..2b197e043c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp @@ -284,7 +284,7 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value) auto type_args = type_parts.size() > 1 ? type_parts[1] : ""sv; if (type_name == "color") { property_generator.append(R"~~~( - if (style_value.is_color()) + if (style_value.has_color()) return true; )~~~"); } else if (type_name == "image") { @@ -295,7 +295,7 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value) } else if (type_name == "length" || type_name == "percentage") { // FIXME: Handle lengths and percentages separately property_generator.append(R"~~~( - if (style_value.is_length() || style_value.is_calculated()) + if (style_value.has_length() || style_value.is_calculated()) return true; )~~~"); } else if (type_name == "number" || type_name == "integer") { @@ -309,14 +309,14 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value) max_value = type_args.substring_view(comma_index + 1, type_args.length() - comma_index - 2); } property_generator.append(R"~~~( - if (style_value.is_numeric())~~~"); + if (style_value.has_number())~~~"); if (!min_value.is_empty()) { property_generator.set("minvalue", min_value); - property_generator.append(" && (style_value.as_number() >= (float)@minvalue@)"); + property_generator.append(" && (style_value.to_number() >= (float)@minvalue@)"); } if (!max_value.is_empty()) { property_generator.set("maxvalue", max_value); - property_generator.append(" && (style_value.as_number() <= (float)@maxvalue@)"); + property_generator.append(" && (style_value.to_number() <= (float)@maxvalue@)"); } property_generator.append(R"~~~() return true; diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index a06f40af8d..6338ca22f8 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -268,7 +268,7 @@ Optional StyleProperties::z_index() const return {}; auto& value = maybe_value.value(); - if (value->is_auto()) + if (value->has_auto()) return 0; if (value->is_numeric()) return static_cast(static_cast(*value).value()); @@ -339,7 +339,7 @@ Optional StyleProperties::flex_basis() const if (value.value()->is_identifier() && value.value()->to_identifier() == CSS::ValueID::Content) return { { CSS::FlexBasis::Content, {} } }; - if (value.value()->is_auto()) + if (value.value()->has_auto()) return { { CSS::FlexBasis::Auto, {} } }; if (value.value()->is_length()) diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 5ec38b9866..7e48f460f1 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -26,14 +26,158 @@ StyleValue::~StyleValue() { } -bool StyleValue::is_color() const +BackgroundStyleValue const& StyleValue::as_background() const { - if (type() == Type::Color) - return true; - if (type() != Type::Identifier) - return false; + VERIFY(is_background()); + return static_cast(*this); +} - switch (to_identifier()) { +BackgroundRepeatStyleValue const& StyleValue::as_background_repeat() const +{ + VERIFY(is_background_repeat()); + return static_cast(*this); +} + +BorderStyleValue const& StyleValue::as_border() const +{ + VERIFY(is_border()); + return static_cast(*this); +} + +BorderRadiusStyleValue const& StyleValue::as_border_radius() const +{ + VERIFY(is_border_radius()); + return static_cast(*this); +} + +BoxShadowStyleValue const& StyleValue::as_box_shadow() const +{ + VERIFY(is_box_shadow()); + return static_cast(*this); +} + +CalculatedStyleValue const& StyleValue::as_calculated() const +{ + VERIFY(is_calculated()); + return static_cast(*this); +} + +ColorStyleValue const& StyleValue::as_color() const +{ + VERIFY(is_color()); + return static_cast(*this); +} + +CustomStyleValue const& StyleValue::as_custom_property() const +{ + VERIFY(is_custom_property()); + return static_cast(*this); +} + +FlexStyleValue const& StyleValue::as_flex() const +{ + VERIFY(is_flex()); + return static_cast(*this); +} + +FlexFlowStyleValue const& StyleValue::as_flex_flow() const +{ + VERIFY(is_flex_flow()); + return static_cast(*this); +} + +FontStyleValue const& StyleValue::as_font() const +{ + VERIFY(is_font()); + return static_cast(*this); +} + +IdentifierStyleValue const& StyleValue::as_identifier() const +{ + VERIFY(is_identifier()); + return static_cast(*this); +} + +ImageStyleValue const& StyleValue::as_image() const +{ + VERIFY(is_image()); + return static_cast(*this); +} + +InheritStyleValue const& StyleValue::as_inherit() const +{ + VERIFY(is_inherit()); + return static_cast(*this); +} + +InitialStyleValue const& StyleValue::as_initial() const +{ + VERIFY(is_initial()); + return static_cast(*this); +} + +LengthStyleValue const& StyleValue::as_length() const +{ + VERIFY(is_length()); + return static_cast(*this); +} + +ListStyleStyleValue const& StyleValue::as_list_style() const +{ + VERIFY(is_list_style()); + return static_cast(*this); +} + +NumericStyleValue const& StyleValue::as_numeric() const +{ + VERIFY(is_numeric()); + return static_cast(*this); +} + +OverflowStyleValue const& StyleValue::as_overflow() const +{ + VERIFY(is_overflow()); + return static_cast(*this); +} + +StringStyleValue const& StyleValue::as_string() const +{ + VERIFY(is_string()); + return static_cast(*this); +} + +TextDecorationStyleValue const& StyleValue::as_text_decoration() const +{ + VERIFY(is_text_decoration()); + return static_cast(*this); +} + +TransformationStyleValue const& StyleValue::as_transformation() const +{ + VERIFY(is_transformation()); + return static_cast(*this); +} + +UnsetStyleValue const& StyleValue::as_unset() const +{ + VERIFY(is_unset()); + return static_cast(*this); +} + +StyleValueList const& StyleValue::as_value_list() const +{ + VERIFY(is_value_list()); + return static_cast(*this); +} + +String IdentifierStyleValue::to_string() const +{ + return CSS::string_from_value_id(m_id); +} + +bool IdentifierStyleValue::has_color() const +{ + switch (m_id) { case ValueID::Currentcolor: case ValueID::LibwebLink: case ValueID::LibwebPaletteActiveLink: @@ -92,21 +236,8 @@ bool StyleValue::is_color() const case ValueID::LibwebPaletteWindowText: return true; default: - break; + return false; } - - return false; -} - -float StyleValue::as_number() const -{ - VERIFY(is_numeric()); - return static_cast(*this).value(); -} - -String IdentifierStyleValue::to_string() const -{ - return CSS::string_from_value_id(m_id); } Color IdentifierStyleValue::to_color(Layout::NodeWithStyle const& node) const @@ -255,5 +386,4 @@ void ImageStyleValue::resource_did_load() if (m_document->browsing_context()) m_document->browsing_context()->set_needs_display({}); } - } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 8a2b78c6aa..9433e8df86 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -269,11 +269,11 @@ public: bool is_flex() const { return type() == Type::Flex; } bool is_flex_flow() const { return type() == Type::FlexFlow; } bool is_font() const { return type() == Type::Font; } - bool is_identifier() const { return type() == Type::Identifier || is_auto(); } + bool is_identifier() const { return type() == Type::Identifier; } bool is_image() const { return type() == Type::Image; } bool is_inherit() const { return type() == Type::Inherit; } bool is_initial() const { return type() == Type::Initial; } - virtual bool is_length() const { return type() == Type::Length; } + bool is_length() const { return type() == Type::Length; } bool is_list_style() const { return type() == Type::ListStyle; } bool is_numeric() const { return type() == Type::Numeric; } bool is_overflow() const { return type() == Type::Overflow; } @@ -285,21 +285,67 @@ public: bool is_builtin() const { return is_inherit() || is_initial() || is_unset(); } - bool is_builtin_or_dynamic() const - { - return is_builtin() || is_custom_property() || is_calculated(); - } + BackgroundRepeatStyleValue const& as_background_repeat() const; + BackgroundStyleValue const& as_background() const; + BorderRadiusStyleValue const& as_border_radius() const; + BorderStyleValue const& as_border() const; + BoxShadowStyleValue const& as_box_shadow() const; + CalculatedStyleValue const& as_calculated() const; + ColorStyleValue const& as_color() const; + CustomStyleValue const& as_custom_property() const; + FlexFlowStyleValue const& as_flex_flow() const; + FlexStyleValue const& as_flex() const; + FontStyleValue const& as_font() const; + IdentifierStyleValue const& as_identifier() const; + ImageStyleValue const& as_image() const; + InheritStyleValue const& as_inherit() const; + InitialStyleValue const& as_initial() const; + LengthStyleValue const& as_length() const; + ListStyleStyleValue const& as_list_style() const; + NumericStyleValue const& as_numeric() const; + OverflowStyleValue const& as_overflow() const; + StringStyleValue const& as_string() const; + TextDecorationStyleValue const& as_text_decoration() const; + TransformationStyleValue const& as_transformation() const; + UnsetStyleValue const& as_unset() const; + StyleValueList const& as_value_list() const; - float as_number() const; + BackgroundRepeatStyleValue& as_background_repeat() { return const_cast(const_cast(*this).as_background_repeat()); } + BackgroundStyleValue& as_background() { return const_cast(const_cast(*this).as_background()); } + BorderRadiusStyleValue& as_border_radius() { return const_cast(const_cast(*this).as_border_radius()); } + BorderStyleValue& as_border() { return const_cast(const_cast(*this).as_border()); } + BoxShadowStyleValue& as_box_shadow() { return const_cast(const_cast(*this).as_box_shadow()); } + CalculatedStyleValue& as_calculated() { return const_cast(const_cast(*this).as_calculated()); } + ColorStyleValue& as_color() { return const_cast(const_cast(*this).as_color()); } + CustomStyleValue& as_custom_property() { return const_cast(const_cast(*this).as_custom_property()); } + FlexFlowStyleValue& as_flex_flow() { return const_cast(const_cast(*this).as_flex_flow()); } + FlexStyleValue& as_flex() { return const_cast(const_cast(*this).as_flex()); } + FontStyleValue& as_font() { return const_cast(const_cast(*this).as_font()); } + IdentifierStyleValue& as_identifier() { return const_cast(const_cast(*this).as_identifier()); } + ImageStyleValue& as_image() { return const_cast(const_cast(*this).as_image()); } + InheritStyleValue& as_inherit() { return const_cast(const_cast(*this).as_inherit()); } + InitialStyleValue& as_initial() { return const_cast(const_cast(*this).as_initial()); } + LengthStyleValue& as_length() { return const_cast(const_cast(*this).as_length()); } + ListStyleStyleValue& as_list_style() { return const_cast(const_cast(*this).as_list_style()); } + NumericStyleValue& as_numeric() { return const_cast(const_cast(*this).as_numeric()); } + OverflowStyleValue& as_overflow() { return const_cast(const_cast(*this).as_overflow()); } + StringStyleValue& as_string() { return const_cast(const_cast(*this).as_string()); } + TextDecorationStyleValue& as_text_decoration() { return const_cast(const_cast(*this).as_text_decoration()); } + TransformationStyleValue& as_transformation() { return const_cast(const_cast(*this).as_transformation()); } + UnsetStyleValue& as_unset() { return const_cast(const_cast(*this).as_unset()); } + StyleValueList& as_value_list() { return const_cast(const_cast(*this).as_value_list()); } - virtual String to_string() const = 0; - virtual Length to_length() const { return {}; } + virtual bool has_auto() const { return false; } + virtual bool has_color() const { return false; } + virtual bool has_identifier() const { return false; } + virtual bool has_length() const { return false; } + virtual bool has_number() const { return false; } virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; } - - CSS::ValueID to_identifier() const; - - virtual bool is_auto() const { return false; } + virtual CSS::ValueID to_identifier() const { return ValueID::Invalid; } + virtual Length to_length() const { return {}; } + virtual float to_number() const { return {}; } + virtual String to_string() const = 0; bool operator==(const StyleValue& other) const { return equals(other); } bool operator!=(const StyleValue& other) const { return !(*this == other); } @@ -621,8 +667,9 @@ public: virtual ~ColorStyleValue() override { } Color color() const { return m_color; } - String to_string() const override { return m_color.to_string(); } - Color to_color(Layout::NodeWithStyle const&) const override { return m_color; } + virtual String to_string() const override { return m_color.to_string(); } + virtual bool has_color() const override { return true; } + virtual Color to_color(Layout::NodeWithStyle const&) const override { return m_color; } virtual bool equals(const StyleValue& other) const override { @@ -806,8 +853,12 @@ public: CSS::ValueID id() const { return m_id; } - virtual String to_string() const override; + virtual bool has_auto() const override { return m_id == ValueID::Auto; } + virtual bool has_identifier() const override { return true; } + virtual CSS::ValueID to_identifier() const override { return m_id; } + virtual bool has_color() const override; virtual Color to_color(Layout::NodeWithStyle const& node) const override; + virtual String to_string() const override; virtual bool equals(const StyleValue& other) const override { @@ -892,13 +943,13 @@ public: } virtual ~LengthStyleValue() override { } + Length const& length() const { return m_length; } + + virtual bool has_auto() const override { return m_length.is_auto(); } + virtual bool has_length() const override { return true; } virtual String to_string() const override { return m_length.to_string(); } virtual Length to_length() const override { return m_length; } - const Length& length() const { return m_length; } - - virtual bool is_auto() const override { return m_length.is_auto(); } - virtual bool equals(const StyleValue& other) const override { if (type() != other.type()) @@ -960,10 +1011,15 @@ public: return adopt_ref(*new NumericStyleValue(value)); } - virtual bool is_length() const override { return m_value == 0; } + virtual bool has_length() const override { return m_value == 0; } virtual Length to_length() const override { return Length(0, Length::Type::Px); } + virtual bool has_number() const override { return true; } + virtual float to_number() const override { return m_value; } + float value() const { return m_value; } + // FIXME: Store integer values separately + i64 int_value() const { return roundf(m_value); } String to_string() const override { return String::formatted("{}", m_value); } virtual bool equals(StyleValue const& other) const override @@ -1143,12 +1199,4 @@ private: NonnullRefPtrVector m_values; }; -inline CSS::ValueID StyleValue::to_identifier() const -{ - if (type() == Type::Identifier) - return static_cast(*this).id(); - if (is_auto()) - return CSS::ValueID::Auto; - return CSS::ValueID::Invalid; -} } diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 6cf15246f3..45635fd526 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -28,8 +28,33 @@ class Selector; class StyleProperties; class StyleResolver; class StyleSheet; -class StyleValue; enum class Display; + +class StyleValue; +class BackgroundRepeatStyleValue; +class BackgroundStyleValue; +class BorderRadiusStyleValue; +class BorderStyleValue; +class BoxShadowStyleValue; +class CalculatedStyleValue; +class ColorStyleValue; +class CustomStyleValue; +class FlexFlowStyleValue; +class FlexStyleValue; +class FontStyleValue; +class IdentifierStyleValue; +class ImageStyleValue; +class InheritStyleValue; +class InitialStyleValue; +class LengthStyleValue; +class ListStyleStyleValue; +class NumericStyleValue; +class OverflowStyleValue; +class StringStyleValue; +class TextDecorationStyleValue; +class TransformationStyleValue; +class UnsetStyleValue; +class StyleValueList; } namespace Web::DOM { diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index d054ac96c3..47bd8f4db6 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -329,13 +329,13 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) if (computed_values.opacity() == 0) m_visible = false; - if (auto width = specified_style.property(CSS::PropertyID::Width); width.has_value() && !width.value()->is_auto()) + if (auto width = specified_style.property(CSS::PropertyID::Width); width.has_value() && !width.value()->has_auto()) m_has_definite_width = true; computed_values.set_width(specified_style.length_or_fallback(CSS::PropertyID::Width, {})); computed_values.set_min_width(specified_style.length_or_fallback(CSS::PropertyID::MinWidth, {})); computed_values.set_max_width(specified_style.length_or_fallback(CSS::PropertyID::MaxWidth, {})); - if (auto height = specified_style.property(CSS::PropertyID::Height); height.has_value() && !height.value()->is_auto()) + if (auto height = specified_style.property(CSS::PropertyID::Height); height.has_value() && !height.value()->has_auto()) m_has_definite_height = true; computed_values.set_height(specified_style.length_or_fallback(CSS::PropertyID::Height, {})); computed_values.set_min_height(specified_style.length_or_fallback(CSS::PropertyID::MinHeight, {}));