From 4a0327953990d5a5ea55967219568e53d986f541 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 13 Jul 2021 16:50:58 +0100 Subject: [PATCH] LibWeb: Add CSS ValueListStyleValue As the new CSS parser tokenizes its input, we can no longer easily rely on a StringStyleValue for multi-value properties. (eg, border) ValueListStyleValue lets us wrap all of the ComponentValues that the Parser produced for one declaration, as a single StyleValue, to then be parsed into StyleValues by the StyleResolver. Originally, I wanted it to be a list of StyleValues, but several properties use syntax that makes use of non-StyleValue tokens, eg: ```css /* Syntax using a / */ font: 12px/14px sans-serif; /* Multiple values separated by commas */ background: url(catdog.png), url(another-image.jpg), blue; ``` Passing the ComponentValue tokens themselves means that all that information is carried over. The alternative might be to create a StyleValue subclass for each property and parse them fully inside the Parser. (eg, `FontStyleValue`) I decided against `ListStyleValue` as a name, to avoid confusion with list styles. It's not ideal, but names are hard. --- Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 22 ++++++++++++++++++++ Userland/Libraries/LibWeb/CSS/StyleValue.h | 20 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 7d85f56227..551ed1f53b 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -1,11 +1,14 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include +#include #include #include #include @@ -169,4 +172,23 @@ void ImageStyleValue::resource_did_load() m_document->browsing_context()->set_needs_display({}); } +ValueListStyleValue::ValueListStyleValue(Vector&& values) + : StyleValue(Type::ValueList) + , m_values(move(values)) +{ +} + +String ValueListStyleValue::to_string() const +{ + StringBuilder builder; + builder.appendff("List[{}](", m_values.size()); + for (auto& value : m_values) { + builder.append(value.to_debug_string()); + builder.append(","); + } + + builder.append(")"); + return builder.to_string(); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index c03c926a43..8f7e0fc06b 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -1,12 +1,14 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen + * Copyright (c) 2021, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once +#include #include #include #include @@ -16,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -219,6 +222,7 @@ public: Position, CustomProperty, Numeric, + ValueList, }; Type type() const { return m_type; } @@ -233,6 +237,7 @@ public: bool is_position() const { return type() == Type::Position; } bool is_custom_property() const { return type() == Type::CustomProperty; } bool is_numeric() const { return type() == Type::Numeric; } + bool is_value_list() const { return type() == Type::ValueList; } virtual String to_string() const = 0; virtual Length to_length() const { return Length::make_auto(); } @@ -460,6 +465,21 @@ private: RefPtr m_bitmap; }; +class ValueListStyleValue final : public StyleValue { +public: + static NonnullRefPtr create(Vector&& values) { return adopt_ref(*new ValueListStyleValue(move(values))); } + virtual ~ValueListStyleValue() override { } + + virtual String to_string() const override; + + Vector const& values() const { return m_values; } + +private: + ValueListStyleValue(Vector&&); + + Vector m_values; +}; + inline CSS::ValueID StyleValue::to_identifier() const { if (is_identifier())