From 8e56109515a5638d661ab6ca5d73f541d65b2e15 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Sun, 5 Jan 2025 09:51:58 +1100 Subject: [PATCH] LibWeb/CSS: Implement the light-dark color function --- Libraries/LibWeb/CMakeLists.txt | 1 + Libraries/LibWeb/CSS/Parser/Parser.cpp | 37 ++++++++++ Libraries/LibWeb/CSS/Parser/Parser.h | 1 + .../LibWeb/CSS/StyleValues/CSSColorValue.h | 1 + .../LibWeb/CSS/StyleValues/CSSLightDark.cpp | 37 ++++++++++ .../LibWeb/CSS/StyleValues/CSSLightDark.h | 43 +++++++++++ .../css-color/light-dark-currentcolor.html | 16 ++++ .../Screenshot/expected/color-scheme-ref.html | 10 +++ .../Screenshot/images/color-scheme-ref.png | Bin 0 -> 23319 bytes .../LibWeb/Screenshot/input/color-scheme.html | 69 ++++++++++++++++++ .../css/css-color/light-dark-basic.txt | 7 ++ .../light-dark-currentcolor-in-color.txt | 6 ++ .../css/css-color/light-dark-basic.html | 26 +++++++ .../light-dark-currentcolor-in-color.html | 21 ++++++ 14 files changed, 275 insertions(+) create mode 100644 Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp create mode 100644 Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h create mode 100644 Tests/LibWeb/Ref/input/wpt-import/css/css-color/light-dark-currentcolor.html create mode 100644 Tests/LibWeb/Screenshot/expected/color-scheme-ref.html create mode 100644 Tests/LibWeb/Screenshot/images/color-scheme-ref.png create mode 100644 Tests/LibWeb/Screenshot/input/color-scheme.html create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-basic.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-currentcolor-in-color.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-basic.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-currentcolor-in-color.html diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 899c3eb2590..fe8e5c4eaca 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -138,6 +138,7 @@ set(SOURCES CSS/StyleValues/CSSKeywordValue.cpp CSS/StyleValues/CSSLabLike.cpp CSS/StyleValues/CSSLCHLike.cpp + CSS/StyleValues/CSSLightDark.cpp CSS/StyleValues/CSSRGB.cpp CSS/StyleValues/DisplayStyleValue.cpp CSS/StyleValues/EasingStyleValue.cpp diff --git a/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Libraries/LibWeb/CSS/Parser/Parser.cpp index a6ba66a60a1..72ef47d08a9 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -3491,6 +3492,40 @@ RefPtr Parser::parse_color_function(TokenStream& alpha.release_nonnull()); } +// https://drafts.csswg.org/css-color-5/#funcdef-light-dark +RefPtr Parser::parse_light_dark_color_value(TokenStream& outer_tokens) +{ + auto transaction = outer_tokens.begin_transaction(); + + outer_tokens.discard_whitespace(); + auto const& function_token = outer_tokens.consume_a_token(); + if (!function_token.is_function("light-dark"sv)) + return {}; + + auto inner_tokens = TokenStream { function_token.function().value }; + + inner_tokens.discard_whitespace(); + auto light = parse_color_value(inner_tokens); + if (!light) + return {}; + + inner_tokens.discard_whitespace(); + if (!inner_tokens.consume_a_token().is(Token::Type::Comma)) + return {}; + + inner_tokens.discard_whitespace(); + auto dark = parse_color_value(inner_tokens); + if (!dark) + return {}; + + inner_tokens.discard_whitespace(); + if (inner_tokens.has_next_token()) + return {}; + + transaction.commit(); + return CSSLightDark::create(light.release_nonnull(), dark.release_nonnull()); +} + // https://www.w3.org/TR/css-color-4/#color-syntax RefPtr Parser::parse_color_value(TokenStream& tokens) { @@ -3522,6 +3557,8 @@ RefPtr Parser::parse_color_value(TokenStream& tok return oklab; if (auto oklch = parse_oklch_color_value(tokens)) return oklch; + if (auto light_dark = parse_light_dark_color_value(tokens)) + return light_dark; auto transaction = tokens.begin_transaction(); tokens.discard_whitespace(); diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index e9901d32212..f3821349c07 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -291,6 +291,7 @@ private: RefPtr parse_lch_color_value(TokenStream&); RefPtr parse_oklch_color_value(TokenStream&); RefPtr parse_color_function(TokenStream&); + RefPtr parse_light_dark_color_value(TokenStream&); RefPtr parse_color_value(TokenStream&); RefPtr parse_color_scheme_value(TokenStream&); RefPtr parse_counter_value(TokenStream&); diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h index 225a4e8fb4d..39ddf3e2df4 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h @@ -39,6 +39,7 @@ public: Rec2020, XYZD50, XYZD65, + LightDark, // This is used by CSSLightDark for light-dark(..., ...). }; ColorType color_type() const { return m_color_type; } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp new file mode 100644 index 00000000000..ed171eef8d4 --- /dev/null +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025, Ladybird contributors + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "CSSLightDark.h" +#include + +namespace Web::CSS { + +Color CSSLightDark::to_color(Optional node) const +{ + if (node.has_value() && node.value().computed_values().color_scheme() == PreferredColorScheme::Dark) + return m_properties.dark->to_color(node); + + return m_properties.light->to_color(node); +} + +bool CSSLightDark::equals(CSSStyleValue const& other) const +{ + if (type() != other.type()) + return false; + auto const& other_color = other.as_color(); + if (color_type() != other_color.color_type()) + return false; + auto const& other_light_dark = verify_cast(other_color); + return m_properties == other_light_dark.m_properties; +} + +String CSSLightDark::to_string(SerializationMode mode) const +{ + // FIXME: We don't have enough information to determine the computed value here. + return MUST(String::formatted("light-dark({}, {})", m_properties.light->to_string(mode), m_properties.dark->to_string(mode))); +} + +} diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h new file mode 100644 index 00000000000..4d2bd6d94da --- /dev/null +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, Ladybird contributors + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::CSS { + +// https://drafts.csswg.org/css-color-5/#funcdef-light-dark +class CSSLightDark final : public CSSColorValue { +public: + virtual ~CSSLightDark() override = default; + + static ValueComparingNonnullRefPtr create(ValueComparingNonnullRefPtr light, ValueComparingNonnullRefPtr dark) + { + return AK::adopt_ref(*new (nothrow) CSSLightDark(move(light), move(dark))); + } + + virtual bool equals(CSSStyleValue const&) const override; + virtual Color to_color(Optional) const override; + virtual String to_string(SerializationMode) const override; + +private: + CSSLightDark(ValueComparingNonnullRefPtr light, ValueComparingNonnullRefPtr dark) + : CSSColorValue(CSSColorValue::ColorType::LightDark) + , m_properties { .light = move(light), .dark = move(dark) } + { + } + + struct Properties { + ValueComparingNonnullRefPtr light; + ValueComparingNonnullRefPtr dark; + bool operator==(Properties const&) const = default; + }; + + Properties m_properties; +}; + +} // Web::CSS diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-color/light-dark-currentcolor.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-color/light-dark-currentcolor.html new file mode 100644 index 00000000000..9b4928d803f --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-color/light-dark-currentcolor.html @@ -0,0 +1,16 @@ + + +CurrentColor can be used inside light-dark + + + + +

Test passes if there is a filled green square.

+
diff --git a/Tests/LibWeb/Screenshot/expected/color-scheme-ref.html b/Tests/LibWeb/Screenshot/expected/color-scheme-ref.html new file mode 100644 index 00000000000..4208be37a46 --- /dev/null +++ b/Tests/LibWeb/Screenshot/expected/color-scheme-ref.html @@ -0,0 +1,10 @@ + + diff --git a/Tests/LibWeb/Screenshot/images/color-scheme-ref.png b/Tests/LibWeb/Screenshot/images/color-scheme-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..283645ae512ffe76b01392857e6adfa8f7038ef7 GIT binary patch literal 23319 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 nFegLk;rdZqVe?y5kDNdCpWkNI + +
+
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
+
+
+
+
+
+
+
+
light-dark(red,green)
+
+
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
a
+
+
+
+
+
+
+
+
+
light-dark(red,green)
+
+
diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-basic.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-basic.txt new file mode 100644 index 00000000000..4876a2739e5 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-basic.txt @@ -0,0 +1,7 @@ +Harness status: OK + +Found 2 tests + +2 Pass +Pass light-dark(white, black) +Pass light-dark(light-dark(white, red), red) \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-currentcolor-in-color.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-currentcolor-in-color.txt new file mode 100644 index 00000000000..53efa25abbd --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/light-dark-currentcolor-in-color.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Fail +Fail curentColor in light-dark() refers to parent color \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-basic.html b/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-basic.html new file mode 100644 index 00000000000..8cb3abfbb94 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-basic.html @@ -0,0 +1,26 @@ + +light-dark() color-scheme propagation + + + + +
+
+
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-currentcolor-in-color.html b/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-currentcolor-in-color.html new file mode 100644 index 00000000000..b48d2132221 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-color/light-dark-currentcolor-in-color.html @@ -0,0 +1,21 @@ + + +CurrentColor can be used inside light-dark for the color property + + + + +
+
Text should be green
+
+