From c052457498a8650cef6b027ce52b7f21cd0182e2 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 11 Nov 2021 11:47:31 +0000 Subject: [PATCH] LibWeb: Bring BackgroundStyleValue::to_string() to spec This now outputs valid CSS representing the background, instead of confusing debug info. We can't guarantee that all the longhands have the same number of values, since while that's always the case when parsing, we also create BackgroundStyleValues when producing the resolved style, which just combines the longhands together. --- Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 60 ++++++++++++++++++++ Userland/Libraries/LibWeb/CSS/StyleValue.h | 30 +++++----- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index ee582d08e0..b95b767807 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -181,6 +181,66 @@ StyleValueList const& StyleValue::as_value_list() const return static_cast(*this); } +BackgroundStyleValue::BackgroundStyleValue( + NonnullRefPtr color, + NonnullRefPtr image, + NonnullRefPtr position, + NonnullRefPtr size, + NonnullRefPtr repeat, + NonnullRefPtr attachment, + NonnullRefPtr origin, + NonnullRefPtr clip) + : StyleValue(Type::Background) + , m_color(color) + , m_image(image) + , m_position(position) + , m_size(size) + , m_repeat(repeat) + , m_attachment(attachment) + , m_origin(origin) + , m_clip(clip) +{ + auto layer_count = [](auto style_value) -> size_t { + if (style_value->is_value_list()) + return style_value->as_value_list().size(); + else + return 1; + }; + + m_layer_count = max(layer_count(m_image), layer_count(m_position)); + m_layer_count = max(m_layer_count, layer_count(m_size)); + m_layer_count = max(m_layer_count, layer_count(m_repeat)); + m_layer_count = max(m_layer_count, layer_count(m_attachment)); + m_layer_count = max(m_layer_count, layer_count(m_origin)); + m_layer_count = max(m_layer_count, layer_count(m_clip)); + + VERIFY(!m_color->is_value_list()); +} + +String BackgroundStyleValue::to_string() const +{ + if (m_layer_count == 1) { + return String::formatted("{} {} {} {} {} {} {} {}", m_color->to_string(), m_image->to_string(), m_position->to_string(), m_size->to_string(), m_repeat->to_string(), m_attachment->to_string(), m_origin->to_string(), m_clip->to_string()); + } + + auto get_layer_value_string = [](NonnullRefPtr const& style_value, size_t index) { + if (style_value->is_value_list()) + return style_value->as_value_list().value_at(index, true)->to_string(); + return style_value->to_string(); + }; + + StringBuilder builder; + for (size_t i = 0; i < m_layer_count; i++) { + if (i) + builder.append(", "); + if (i == m_layer_count - 1) + builder.appendff("{} ", m_color->to_string()); + builder.appendff("{} {} {} {} {} {} {}", get_layer_value_string(m_image, i), get_layer_value_string(m_position, i), get_layer_value_string(m_size, i), get_layer_value_string(m_repeat, i), get_layer_value_string(m_attachment, i), get_layer_value_string(m_origin, i), get_layer_value_string(m_clip, i)); + } + + return builder.to_string(); +} + String IdentifierStyleValue::to_string() const { return CSS::string_from_value_id(m_id); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index faab372d81..45e4a4c875 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -408,6 +408,8 @@ public: } virtual ~BackgroundStyleValue() override { } + size_t layer_count() const { return m_layer_count; } + NonnullRefPtr attachment() const { return m_attachment; } NonnullRefPtr clip() const { return m_clip; } NonnullRefPtr color() const { return m_color; } @@ -417,10 +419,7 @@ public: NonnullRefPtr repeat() const { return m_repeat; } NonnullRefPtr size() const { return m_size; } - virtual String to_string() const override - { - return String::formatted("{} {} {} {} {} {} {} {}", m_color->to_string(), m_image->to_string(), m_position->to_string(), m_size->to_string(), m_repeat->to_string(), m_attachment->to_string(), m_origin->to_string(), m_clip->to_string()); - } + virtual String to_string() const override; private: BackgroundStyleValue( @@ -431,18 +430,8 @@ private: NonnullRefPtr repeat, NonnullRefPtr attachment, NonnullRefPtr origin, - NonnullRefPtr clip) - : StyleValue(Type::Background) - , m_color(color) - , m_image(image) - , m_position(position) - , m_size(size) - , m_repeat(repeat) - , m_attachment(attachment) - , m_origin(origin) - , m_clip(clip) - { - } + NonnullRefPtr clip); + NonnullRefPtr m_color; NonnullRefPtr m_image; NonnullRefPtr m_position; @@ -451,6 +440,8 @@ private: NonnullRefPtr m_attachment; NonnullRefPtr m_origin; NonnullRefPtr m_clip; + + size_t m_layer_count; }; class PositionStyleValue final : public StyleValue { @@ -1321,7 +1312,14 @@ class StyleValueList final : public StyleValue { public: static NonnullRefPtr create(NonnullRefPtrVector&& values) { return adopt_ref(*new StyleValueList(move(values))); } + size_t size() const { return m_values.size(); } NonnullRefPtrVector const& values() const { return m_values; } + NonnullRefPtr value_at(size_t i, bool allow_loop) const + { + if (allow_loop) + return m_values[i % size()]; + return m_values[i]; + } virtual String to_string() const {