diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 498643eaa6..93b4217ffc 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1854,79 +1854,6 @@ Optional Parser::convert_to_style_property(StyleDeclarationRule c } } -Optional Parser::try_parse_float(StringView string) -{ - // FIXME: This is copied from DeprecatedCSSParser, so may not be to spec. - - const char* str = string.characters_without_null_termination(); - size_t len = string.length(); - size_t weight = 1; - int exp_val = 0; - float value = 0.0f; - float fraction = 0.0f; - bool has_sign = false; - bool is_negative = false; - bool is_fractional = false; - bool is_scientific = false; - - if (str[0] == '-') { - is_negative = true; - has_sign = true; - } - if (str[0] == '+') { - has_sign = true; - } - - for (size_t i = has_sign; i < len; i++) { - - // Looks like we're about to start working on the fractional part - if (str[i] == '.') { - is_fractional = true; - continue; - } - - if (str[i] == 'e' || str[i] == 'E') { - if (str[i + 1] == '-' || str[i + 1] == '+') - exp_val = atoi(str + i + 2); - else - exp_val = atoi(str + i + 1); - - is_scientific = true; - continue; - } - - if (str[i] < '0' || str[i] > '9' || exp_val != 0) - return {}; - - if (is_fractional) { - fraction *= 10; - fraction += str[i] - '0'; - weight *= 10; - } else { - value = value * 10; - value += str[i] - '0'; - } - } - - fraction /= weight; - value += fraction; - - if (is_scientific) { - bool divide = exp_val < 0; - if (divide) - exp_val *= -1; - - for (int i = 0; i < exp_val; i++) { - if (divide) - value /= 10; - else - value *= 10; - } - } - - return is_negative ? -value : value; -} - RefPtr Parser::parse_builtin_value(StyleComponentValueRule const& component_value) { if (component_value.is(Token::Type::Ident)) { @@ -1975,7 +1902,7 @@ Optional Parser::parse_length(StyleComponentValueRule const& component_v Optional numeric_value; if (component_value.is(Token::Type::Dimension)) { - auto length_string = component_value.token().m_value.string_view(); + numeric_value = component_value.token().dimension_value(); auto unit_string = component_value.token().m_unit.string_view(); if (unit_string.equals_ignoring_case("%")) { @@ -2013,26 +1940,21 @@ Optional Parser::parse_length(StyleComponentValueRule const& component_v } else { return {}; } - - numeric_value = try_parse_float(length_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); + numeric_value = component_value.token().percentage(); } else if (component_value.is(Token::Type::Ident) && component_value.token().ident().equals_ignoring_case("auto")) { return Length::make_auto(); } else if (component_value.is(Token::Type::Number)) { - auto value_string = component_value.token().m_value.string_view(); - if (value_string == "0") { + numeric_value = component_value.token().number_value(); + if (numeric_value == 0) { type = Length::Type::Px; - numeric_value = 0; } else if (m_context.in_quirks_mode() && property_has_quirk(m_context.current_property_id(), Quirk::UnitlessLength)) { // https://quirks.spec.whatwg.org/#quirky-length-value // FIXME: Disallow quirk when inside a CSS sub-expression (like `calc()`) // "The value must not be supported in arguments to CSS expressions other than the rect() // expression, and must not be supported in the supports() static method of the CSS interface." type = Length::Type::Px; - numeric_value = try_parse_float(value_string); } } @@ -2054,7 +1976,7 @@ RefPtr Parser::parse_length_value(StyleComponentValueRule const& com // Right now, it instead is quietly converted to an Identifier when needed. if (component_value.is(Token::Type::Dimension) || component_value.is(Token::Type::Percentage) || (component_value.is(Token::Type::Ident) && component_value.token().ident().equals_ignoring_case("auto"sv)) - || (m_context.in_quirks_mode() && component_value.is(Token::Type::Number) && component_value.token().m_value.string_view() != "0"sv)) { + || (m_context.in_quirks_mode() && property_has_quirk(m_context.current_property_id(), Quirk::UnitlessLength) && component_value.is(Token::Type::Number) && component_value.token().number_value() != 0)) { auto length = parse_length(component_value); if (length.has_value()) return LengthStyleValue::create(length.value()); @@ -2067,12 +1989,10 @@ RefPtr Parser::parse_numeric_value(StyleComponentValueRule const& co { if (component_value.is(Token::Type::Number)) { auto number = component_value.token(); - if (number.m_number_type == Token::NumberType::Integer) { + if (number.number_type() == Token::NumberType::Integer) { return NumericStyleValue::create_integer(number.to_integer()); } else { - auto float_value = try_parse_float(number.m_value.string_view()); - if (float_value.has_value()) - return NumericStyleValue::create_float(float_value.value()); + return NumericStyleValue::create_float(number.number_value()); } } @@ -2143,25 +2063,20 @@ Optional Parser::parse_color(StyleComponentValueRule const& component_val && g_val.is(Token::NumberType::Integer) && b_val.is(Token::NumberType::Integer)) { - auto maybe_r = r_val.m_value.string_view().to_uint(); - auto maybe_g = g_val.m_value.string_view().to_uint(); - auto maybe_b = b_val.m_value.string_view().to_uint(); - if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) - return Color(maybe_r.value(), maybe_g.value(), maybe_b.value()); + auto r = r_val.to_integer(); + auto g = g_val.to_integer(); + auto b = b_val.to_integer(); + if (AK::is_within_range(r) && AK::is_within_range(g) && AK::is_within_range(b)) + return Color(r, g, b); } 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); - } + u8 r = clamp(lroundf(r_val.percentage() * 2.55), 0, 255); + u8 g = clamp(lroundf(g_val.percentage() * 2.55), 0, 255); + u8 b = clamp(lroundf(b_val.percentage() * 2.55), 0, 255); + return Color(r, g, b); } } else if (function.name().equals_ignoring_case("rgba")) { if (params.size() != 4) @@ -2177,31 +2092,28 @@ Optional Parser::parse_color(StyleComponentValueRule const& component_val && b_val.is(Token::NumberType::Integer) && a_val.is(Token::Type::Number)) { - auto maybe_r = r_val.m_value.string_view().to_uint(); - auto maybe_g = g_val.m_value.string_view().to_uint(); - auto maybe_b = b_val.m_value.string_view().to_uint(); - 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); - } + auto r = r_val.to_integer(); + auto g = g_val.to_integer(); + auto b = b_val.to_integer(); + auto a = clamp(lroundf(a_val.number_value() * 255.0), 0, 255); + if (AK::is_within_range(r) && AK::is_within_range(g) && AK::is_within_range(b)) + return Color(r, g, b, 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 = r_val.percentage(); + auto g = g_val.percentage(); + auto b = b_val.percentage(); + auto a = a_val.number_value(); + + u8 r_255 = clamp(lroundf(r * 2.55), 0, 255); + u8 g_255 = clamp(lroundf(g * 2.55), 0, 255); + u8 b_255 = clamp(lroundf(b * 2.55), 0, 255); + u8 a_255 = clamp(lroundf(a * 255.0), 0, 255); + return Color(r_255, g_255, b_255, a_255); } } else if (function.name().equals_ignoring_case("hsl")) { if (params.size() != 3) @@ -2215,15 +2127,10 @@ Optional Parser::parse_color(StyleComponentValueRule const& component_val && 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(static_cast(h), static_cast(s), static_cast(l)); - } + auto h = h_val.number_value(); + auto s = s_val.percentage() / 100.0; + auto l = l_val.percentage() / 100.0; + return Color::from_hsl(h, s, l); } } else if (function.name().equals_ignoring_case("hsla")) { if (params.size() != 4) @@ -2239,17 +2146,11 @@ Optional Parser::parse_color(StyleComponentValueRule const& component_val && 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(static_cast(h), static_cast(s), static_cast(l), static_cast(a)); - } + auto h = h_val.number_value(); + auto s = s_val.percentage() / 100.0; + auto l = l_val.percentage() / 100.0; + auto a = a_val.number_value(); + return Color::from_hsla(h, s, l, a); } } return {}; @@ -3988,20 +3889,16 @@ Optional Parser::parse_calc_value(TokenStream(current_token.token().number_value()) }; if (current_token.is(Token::Type::Dimension) || current_token.is(Token::Type::Percentage)) { auto maybe_length = parse_length(current_token); if (maybe_length.has_value() && !maybe_length.value().is_undefined()) - return (CalculatedStyleValue::CalcValue) { maybe_length.value() }; + return CalculatedStyleValue::CalcValue { maybe_length.value() }; return {}; } @@ -4161,10 +4058,7 @@ Optional Parser::parse_calc_number_value( return {}; tokens.next_token(); - auto try_the_number = try_parse_float(first.token().number_string_value()); - if (!try_the_number.has_value()) - return {}; - return try_the_number.value(); + return first.token().number_value(); } OwnPtr Parser::parse_calc_product(TokenStream& tokens) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 578b2e56ac..4f028b6053 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -178,7 +178,6 @@ private: [[nodiscard]] RefPtr convert_to_rule(NonnullRefPtr); [[nodiscard]] RefPtr convert_to_declaration(NonnullRefPtr); - Optional try_parse_float(StringView string); Optional parse_color(StyleComponentValueRule const&); Optional parse_length(StyleComponentValueRule const&);