From 7a94709cd2f7a47af8c336fccf3f656bbfeb65bf Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Sun, 27 Oct 2024 19:49:25 -0400 Subject: [PATCH] LibWeb/CSS: Factorize the parsing code for lch-like color functions --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 93 +++++++++++-------- Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 + 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index b748ba425d4..c749dc4b39f 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3337,6 +3337,54 @@ RefPtr Parser::parse_oklab_color_value(TokenStream, 4>> Parser::parse_lch_like_color_value(TokenStream& outer_tokens, StringView function_name) +{ + // This helper is designed to be compatible with lch and oklch and parses a function with a form like: + // f() = f( [ | | none] + // [ | | none] + // [ | none] + // [ / [ | none] ]? ) + + auto transaction = outer_tokens.begin_transaction(); + outer_tokens.discard_whitespace(); + + auto const& function_token = outer_tokens.consume_a_token(); + if (!function_token.is_function(function_name)) + return OptionalNone {}; + + auto inner_tokens = TokenStream { function_token.function().value }; + inner_tokens.discard_whitespace(); + + auto l = parse_number_percentage_value(inner_tokens); + if (!l) + return OptionalNone {}; + inner_tokens.discard_whitespace(); + + auto c = parse_number_percentage_value(inner_tokens); + if (!c) + return OptionalNone {}; + inner_tokens.discard_whitespace(); + + auto h = parse_hue_value(inner_tokens); + if (!h) + return OptionalNone {}; + inner_tokens.discard_whitespace(); + + RefPtr alpha; + if (inner_tokens.has_next_token()) { + alpha = parse_solidus_and_alpha_value(inner_tokens); + if (!alpha || inner_tokens.has_next_token()) + return OptionalNone {}; + } + + if (!alpha) + alpha = NumberStyleValue::create(1); + + transaction.commit(); + + return Array { move(l), move(c), move(h), move(alpha) }; +} + // https://www.w3.org/TR/css-color-4/#funcdef-oklch RefPtr Parser::parse_oklch_color_value(TokenStream& outer_tokens) { @@ -3345,47 +3393,16 @@ RefPtr Parser::parse_oklch_color_value(TokenStream | none] // [ / [ | none] ]? ) - auto transaction = outer_tokens.begin_transaction(); - outer_tokens.discard_whitespace(); - - auto& function_token = outer_tokens.consume_a_token(); - if (!function_token.is_function("oklch"sv)) + auto maybe_color_values = parse_lch_like_color_value(outer_tokens, "oklch"sv); + if (!maybe_color_values.has_value()) return {}; - RefPtr l; - RefPtr c; - RefPtr h; - RefPtr alpha; + auto& color_values = *maybe_color_values; - auto inner_tokens = TokenStream { function_token.function().value }; - inner_tokens.discard_whitespace(); - - l = parse_number_percentage_value(inner_tokens); - if (!l) - return {}; - inner_tokens.discard_whitespace(); - - c = parse_number_percentage_value(inner_tokens); - if (!c) - return {}; - inner_tokens.discard_whitespace(); - - h = parse_hue_value(inner_tokens); - if (!h) - return {}; - inner_tokens.discard_whitespace(); - - if (inner_tokens.has_next_token()) { - alpha = parse_solidus_and_alpha_value(inner_tokens); - if (!alpha || inner_tokens.has_next_token()) - return {}; - } - - if (!alpha) - alpha = NumberStyleValue::create(1); - - transaction.commit(); - return CSSOKLCH::create(l.release_nonnull(), c.release_nonnull(), h.release_nonnull(), alpha.release_nonnull()); + return CSSOKLCH::create(color_values[0].release_nonnull(), + color_values[1].release_nonnull(), + color_values[2].release_nonnull(), + color_values[3].release_nonnull()); } // https://www.w3.org/TR/css-color-4/#funcdef-color diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index a12d176fc4b..5a9c4f483a2 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -253,6 +253,7 @@ private: Optional, 4>> parse_lab_like_color_value(TokenStream&, StringView); RefPtr parse_lab_color_value(TokenStream&); RefPtr parse_oklab_color_value(TokenStream&); + Optional, 4>> parse_lch_like_color_value(TokenStream&, StringView); RefPtr parse_oklch_color_value(TokenStream&); RefPtr parse_color_function(TokenStream&); RefPtr parse_color_value(TokenStream&);