diff options
author | Sam Atkins <atkinssj@gmail.com> | 2021-07-28 14:10:03 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-31 00:18:11 +0200 |
commit | 697bffa3bd988e94fe10659dfeaf604c48071d4b (patch) | |
tree | 189d5e5e40365fe6bb532b21a6ba53c86635de73 /Userland/Libraries/LibWeb | |
parent | 1b72766e4eeffa6d19b77e9c7c7bd6cff2951bb8 (diff) | |
download | serenity-697bffa3bd988e94fe10659dfeaf604c48071d4b.zip |
LibWeb: Convert CSS parse_{color,length}() lambdas into methods
This lets us get the Length and Color values directly, without having to
create a StyleValue object and then throw it away again, when parsing
the box-shadow property in the next commit.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 428 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 2 |
2 files changed, 217 insertions, 213 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 0a00a88a7b..4641a5b7a0 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1414,74 +1414,75 @@ RefPtr<StyleValue> Parser::parse_keyword_or_custom_value(ParsingContext const&, return {}; } -RefPtr<StyleValue> Parser::parse_length_value(ParsingContext const& context, StyleComponentValueRule const& component_value) +Optional<Length> Parser::parse_length(ParsingContext const& context, StyleComponentValueRule const& component_value) { - auto parse_length = [&]() -> Optional<Length> { - Length::Type type = Length::Type::Undefined; - Optional<float> numeric_value; - - if (component_value.is(Token::Type::Dimension)) { - auto length_string = component_value.token().m_value.string_view(); - auto unit_string = component_value.token().m_unit.string_view(); - - if (unit_string.equals_ignoring_case("%")) { - type = Length::Type::Percentage; - } else if (unit_string.equals_ignoring_case("px")) { - type = Length::Type::Px; - } else if (unit_string.equals_ignoring_case("pt")) { - type = Length::Type::Pt; - } else if (unit_string.equals_ignoring_case("pc")) { - type = Length::Type::Pc; - } else if (unit_string.equals_ignoring_case("mm")) { - type = Length::Type::Mm; - } else if (unit_string.equals_ignoring_case("rem")) { - type = Length::Type::Rem; - } else if (unit_string.equals_ignoring_case("em")) { - type = Length::Type::Em; - } else if (unit_string.equals_ignoring_case("ex")) { - type = Length::Type::Ex; - } else if (unit_string.equals_ignoring_case("vw")) { - type = Length::Type::Vw; - } else if (unit_string.equals_ignoring_case("vh")) { - type = Length::Type::Vh; - } else if (unit_string.equals_ignoring_case("vmax")) { - type = Length::Type::Vmax; - } else if (unit_string.equals_ignoring_case("vmin")) { - type = Length::Type::Vmin; - } else if (unit_string.equals_ignoring_case("cm")) { - type = Length::Type::Cm; - } else if (unit_string.equals_ignoring_case("in")) { - type = Length::Type::In; - } else if (unit_string.equals_ignoring_case("Q")) { - type = Length::Type::Q; - } else if (context.in_quirks_mode()) { - type = Length::Type::Px; - } + Length::Type type = Length::Type::Undefined; + Optional<float> numeric_value; - numeric_value = try_parse_float(length_string); - } else if (component_value.is(Token::Type::Number)) { - auto value_string = component_value.token().m_value.string_view(); - if (value_string == "0") { - type = Length::Type::Px; - numeric_value = 0; - } else if (context.in_quirks_mode()) { - type = Length::Type::Px; - numeric_value = try_parse_float(value_string); - } - } else if (component_value.is(Token::Type::Percentage)) { + if (component_value.is(Token::Type::Dimension)) { + auto length_string = component_value.token().m_value.string_view(); + auto unit_string = component_value.token().m_unit.string_view(); + + if (unit_string.equals_ignoring_case("%")) { type = Length::Type::Percentage; - auto value_string = component_value.token().m_value.string_view(); + } else if (unit_string.equals_ignoring_case("px")) { + type = Length::Type::Px; + } else if (unit_string.equals_ignoring_case("pt")) { + type = Length::Type::Pt; + } else if (unit_string.equals_ignoring_case("pc")) { + type = Length::Type::Pc; + } else if (unit_string.equals_ignoring_case("mm")) { + type = Length::Type::Mm; + } else if (unit_string.equals_ignoring_case("rem")) { + type = Length::Type::Rem; + } else if (unit_string.equals_ignoring_case("em")) { + type = Length::Type::Em; + } else if (unit_string.equals_ignoring_case("ex")) { + type = Length::Type::Ex; + } else if (unit_string.equals_ignoring_case("vw")) { + type = Length::Type::Vw; + } else if (unit_string.equals_ignoring_case("vh")) { + type = Length::Type::Vh; + } else if (unit_string.equals_ignoring_case("vmax")) { + type = Length::Type::Vmax; + } else if (unit_string.equals_ignoring_case("vmin")) { + type = Length::Type::Vmin; + } else if (unit_string.equals_ignoring_case("cm")) { + type = Length::Type::Cm; + } else if (unit_string.equals_ignoring_case("in")) { + type = Length::Type::In; + } else if (unit_string.equals_ignoring_case("Q")) { + type = Length::Type::Q; + } else if (context.in_quirks_mode()) { + type = Length::Type::Px; + } + + numeric_value = try_parse_float(length_string); + } else if (component_value.is(Token::Type::Number)) { + auto value_string = component_value.token().m_value.string_view(); + if (value_string == "0") { + type = Length::Type::Px; + numeric_value = 0; + } else if (context.in_quirks_mode()) { + type = Length::Type::Px; numeric_value = try_parse_float(value_string); } + } else if (component_value.is(Token::Type::Percentage)) { + type = Length::Type::Percentage; + auto value_string = component_value.token().m_value.string_view(); + numeric_value = try_parse_float(value_string); + } - if (!numeric_value.has_value()) - return {}; + if (!numeric_value.has_value()) + return {}; - return Length(numeric_value.value(), type); - }; + return Length(numeric_value.value(), type); +} +RefPtr<StyleValue> Parser::parse_length_value(ParsingContext const& context, StyleComponentValueRule const& component_value) +{ if (component_value.is(Token::Type::Dimension) || component_value.is(Token::Type::Number) || component_value.is(Token::Type::Percentage)) { - auto length = parse_length(); + auto length = parse_length(context, component_value); if (length.has_value()) return LengthStyleValue::create(length.value()); } @@ -1516,178 +1517,179 @@ RefPtr<StyleValue> Parser::parse_identifier_value(ParsingContext const&, StyleCo return {}; } -RefPtr<StyleValue> Parser::parse_color_value(ParsingContext const&, StyleComponentValueRule const& component_value) +Optional<Color> Parser::parse_color(ParsingContext const&, StyleComponentValueRule const& component_value) { // https://www.w3.org/TR/css-color-3/ - auto parse_css_color = [&]() -> Optional<Color> { - if (component_value.is(Token::Type::Ident)) { - auto ident = component_value.token().ident(); - if (ident.equals_ignoring_case("transparent")) - return Color::from_rgba(0x00000000); - - auto color = Color::from_string(ident.to_string().to_lowercase()); - if (color.has_value()) - return color; - - } else if (component_value.is(Token::Type::Hash)) { - // FIXME: Read it directly - auto color = Color::from_string(String::formatted("#{}", component_value.token().m_value.to_string().to_lowercase())); - if (color.has_value()) - return color; - - } else if (component_value.is_function()) { - auto& function = component_value.function(); - auto& values = function.values(); - - Vector<Token> params; - for (size_t i = 0; i < values.size(); ++i) { - auto& value = values.at(i); - if (value.is(Token::Type::Whitespace)) - continue; + if (component_value.is(Token::Type::Ident)) { + auto ident = component_value.token().ident(); + if (ident.equals_ignoring_case("transparent")) + return Color::from_rgba(0x00000000); + + auto color = Color::from_string(ident.to_string().to_lowercase()); + if (color.has_value()) + return color; + + } else if (component_value.is(Token::Type::Hash)) { + // FIXME: Read it directly + auto color = Color::from_string(String::formatted("#{}", component_value.token().m_value.to_string().to_lowercase())); + if (color.has_value()) + return color; + + } else if (component_value.is_function()) { + auto& function = component_value.function(); + auto& values = function.values(); + + Vector<Token> params; + for (size_t i = 0; i < values.size(); ++i) { + auto& value = values.at(i); + if (value.is(Token::Type::Whitespace)) + continue; + + if (value.is(Token::Type::Percentage) || value.is(Token::Type::Number)) { + params.append(value.token()); + // Eat following comma and whitespace + while ((i + 1) < values.size()) { + auto& next = values.at(i + 1); + if (next.is(Token::Type::Whitespace)) + i++; + else if (next.is(Token::Type::Comma)) + break; - if (value.is(Token::Type::Percentage) || value.is(Token::Type::Number)) { - params.append(value.token()); - // Eat following comma and whitespace - while ((i + 1) < values.size()) { - auto& next = values.at(i + 1); - if (next.is(Token::Type::Whitespace)) - i++; - else if (next.is(Token::Type::Comma)) - break; - - return {}; - } + return {}; } } + } - if (function.name().equals_ignoring_case("rgb")) { - if (params.size() != 3) - return {}; + if (function.name().equals_ignoring_case("rgb")) { + if (params.size() != 3) + return {}; - auto r_val = params[0]; - auto g_val = params[1]; - auto b_val = params[2]; - - if (r_val.is(Token::NumberType::Integer) - && g_val.is(Token::NumberType::Integer) - && b_val.is(Token::NumberType::Integer)) { - - auto maybe_r = r_val.m_value.string_view().to_uint<u8>(); - auto maybe_g = g_val.m_value.string_view().to_uint<u8>(); - auto maybe_b = b_val.m_value.string_view().to_uint<u8>(); - if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) - return Color(maybe_r.value(), maybe_g.value(), maybe_b.value()); - - } else if (r_val.is(Token::Type::Percentage) - && g_val.is(Token::Type::Percentage) - && b_val.is(Token::Type::Percentage)) { - - auto maybe_r = try_parse_float(r_val.m_value.string_view()); - auto maybe_g = try_parse_float(g_val.m_value.string_view()); - auto maybe_b = try_parse_float(b_val.m_value.string_view()); - if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) { - u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255); - u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255); - u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255); - return Color(r, g, b); - } + auto r_val = params[0]; + auto g_val = params[1]; + auto b_val = params[2]; + + if (r_val.is(Token::NumberType::Integer) + && g_val.is(Token::NumberType::Integer) + && b_val.is(Token::NumberType::Integer)) { + + auto maybe_r = r_val.m_value.string_view().to_uint<u8>(); + auto maybe_g = g_val.m_value.string_view().to_uint<u8>(); + auto maybe_b = b_val.m_value.string_view().to_uint<u8>(); + if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) + return Color(maybe_r.value(), maybe_g.value(), maybe_b.value()); + + } else if (r_val.is(Token::Type::Percentage) + && g_val.is(Token::Type::Percentage) + && b_val.is(Token::Type::Percentage)) { + + auto maybe_r = try_parse_float(r_val.m_value.string_view()); + auto maybe_g = try_parse_float(g_val.m_value.string_view()); + auto maybe_b = try_parse_float(b_val.m_value.string_view()); + if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) { + u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255); + u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255); + u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255); + return Color(r, g, b); } - } else if (function.name().equals_ignoring_case("rgba")) { - if (params.size() != 4) - return {}; + } + } else if (function.name().equals_ignoring_case("rgba")) { + if (params.size() != 4) + return {}; - auto r_val = params[0]; - auto g_val = params[1]; - auto b_val = params[2]; - auto a_val = params[3]; - - if (r_val.is(Token::NumberType::Integer) - && g_val.is(Token::NumberType::Integer) - && b_val.is(Token::NumberType::Integer) - && a_val.is(Token::Type::Number)) { - - auto maybe_r = r_val.m_value.string_view().to_uint<u8>(); - auto maybe_g = g_val.m_value.string_view().to_uint<u8>(); - auto maybe_b = b_val.m_value.string_view().to_uint<u8>(); - auto maybe_a = try_parse_float(a_val.m_value.string_view()); - if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) { - u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255); - return Color(maybe_r.value(), maybe_g.value(), maybe_b.value(), a); - } - - } else if (r_val.is(Token::Type::Percentage) - && g_val.is(Token::Type::Percentage) - && b_val.is(Token::Type::Percentage) - && a_val.is(Token::Type::Number)) { - - auto maybe_r = try_parse_float(r_val.m_value.string_view()); - auto maybe_g = try_parse_float(g_val.m_value.string_view()); - auto maybe_b = try_parse_float(b_val.m_value.string_view()); - auto maybe_a = try_parse_float(a_val.m_value.string_view()); - if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) { - u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255); - u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255); - u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255); - u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255); - return Color(r, g, b, a); - } + auto r_val = params[0]; + auto g_val = params[1]; + auto b_val = params[2]; + auto a_val = params[3]; + + if (r_val.is(Token::NumberType::Integer) + && g_val.is(Token::NumberType::Integer) + && b_val.is(Token::NumberType::Integer) + && a_val.is(Token::Type::Number)) { + + auto maybe_r = r_val.m_value.string_view().to_uint<u8>(); + auto maybe_g = g_val.m_value.string_view().to_uint<u8>(); + auto maybe_b = b_val.m_value.string_view().to_uint<u8>(); + auto maybe_a = try_parse_float(a_val.m_value.string_view()); + if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) { + u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255); + return Color(maybe_r.value(), maybe_g.value(), maybe_b.value(), a); } - } else if (function.name().equals_ignoring_case("hsl")) { - if (params.size() != 3) - return {}; - auto h_val = params[0]; - auto s_val = params[1]; - auto l_val = params[2]; - - if (h_val.is(Token::Type::Number) - && s_val.is(Token::Type::Percentage) - && l_val.is(Token::Type::Percentage)) { - - auto maybe_h = try_parse_float(h_val.m_value.string_view()); - auto maybe_s = try_parse_float(s_val.m_value.string_view()); - auto maybe_l = try_parse_float(l_val.m_value.string_view()); - if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value()) { - float h = maybe_h.value(); - float s = maybe_s.value() / 100.0f; - float l = maybe_l.value() / 100.0f; - return Color::from_hsl(h, s, l); - } + } else if (r_val.is(Token::Type::Percentage) + && g_val.is(Token::Type::Percentage) + && b_val.is(Token::Type::Percentage) + && a_val.is(Token::Type::Number)) { + + auto maybe_r = try_parse_float(r_val.m_value.string_view()); + auto maybe_g = try_parse_float(g_val.m_value.string_view()); + auto maybe_b = try_parse_float(b_val.m_value.string_view()); + auto maybe_a = try_parse_float(a_val.m_value.string_view()); + if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) { + u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255); + u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255); + u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255); + u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255); + return Color(r, g, b, a); } - } else if (function.name().equals_ignoring_case("hsla")) { - if (params.size() != 4) - return {}; + } + } else if (function.name().equals_ignoring_case("hsl")) { + if (params.size() != 3) + return {}; - auto h_val = params[0]; - auto s_val = params[1]; - auto l_val = params[2]; - auto a_val = params[3]; - - if (h_val.is(Token::Type::Number) - && s_val.is(Token::Type::Percentage) - && l_val.is(Token::Type::Percentage) - && a_val.is(Token::Type::Number)) { - - auto maybe_h = try_parse_float(h_val.m_value.string_view()); - auto maybe_s = try_parse_float(s_val.m_value.string_view()); - auto maybe_l = try_parse_float(l_val.m_value.string_view()); - auto maybe_a = try_parse_float(a_val.m_value.string_view()); - if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value() && maybe_a.has_value()) { - float h = maybe_h.value(); - float s = maybe_s.value() / 100.0f; - float l = maybe_l.value() / 100.0f; - float a = maybe_a.value(); - return Color::from_hsla(h, s, l, a); - } + auto h_val = params[0]; + auto s_val = params[1]; + auto l_val = params[2]; + + if (h_val.is(Token::Type::Number) + && s_val.is(Token::Type::Percentage) + && l_val.is(Token::Type::Percentage)) { + + auto maybe_h = try_parse_float(h_val.m_value.string_view()); + auto maybe_s = try_parse_float(s_val.m_value.string_view()); + auto maybe_l = try_parse_float(l_val.m_value.string_view()); + if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value()) { + float h = maybe_h.value(); + float s = maybe_s.value() / 100.0f; + float l = maybe_l.value() / 100.0f; + return Color::from_hsl(h, s, l); } } - return {}; - } + } else if (function.name().equals_ignoring_case("hsla")) { + if (params.size() != 4) + return {}; + auto h_val = params[0]; + auto s_val = params[1]; + auto l_val = params[2]; + auto a_val = params[3]; + + if (h_val.is(Token::Type::Number) + && s_val.is(Token::Type::Percentage) + && l_val.is(Token::Type::Percentage) + && a_val.is(Token::Type::Number)) { + + auto maybe_h = try_parse_float(h_val.m_value.string_view()); + auto maybe_s = try_parse_float(s_val.m_value.string_view()); + auto maybe_l = try_parse_float(l_val.m_value.string_view()); + auto maybe_a = try_parse_float(a_val.m_value.string_view()); + if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value() && maybe_a.has_value()) { + float h = maybe_h.value(); + float s = maybe_s.value() / 100.0f; + float l = maybe_l.value() / 100.0f; + float a = maybe_a.value(); + return Color::from_hsla(h, s, l, a); + } + } + } return {}; - }; + } - auto color = parse_css_color(); + return {}; +} + +RefPtr<StyleValue> Parser::parse_color_value(ParsingContext const& context, StyleComponentValueRule const& component_value) +{ + auto color = parse_color(context, component_value); if (color.has_value()) return ColorStyleValue::create(color.value()); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 165da97c5e..cbbb236c08 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -165,6 +165,8 @@ private: [[nodiscard]] Optional<StyleProperty> convert_to_style_property(StyleDeclarationRule&); static Optional<float> try_parse_float(StringView string); + static Optional<Color> parse_color(ParsingContext const&, StyleComponentValueRule const&); + static Optional<Length> parse_length(ParsingContext const&, StyleComponentValueRule const&); static Optional<URL> parse_url_function(ParsingContext const&, StyleComponentValueRule const&); static RefPtr<StyleValue> parse_keyword_or_custom_value(ParsingContext const&, StyleComponentValueRule const&); |