mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:28:12 +00:00
LibWeb: Use number value from CSS Tokens
This lets us get rid of `try_parse_float()`, and simplifies the various places we were calling it before.
This commit is contained in:
parent
1d2276f0e7
commit
522faa1554
2 changed files with 46 additions and 153 deletions
|
@ -1854,79 +1854,6 @@ Optional<StyleProperty> Parser::convert_to_style_property(StyleDeclarationRule c
|
|||
}
|
||||
}
|
||||
|
||||
Optional<float> 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<StyleValue> Parser::parse_builtin_value(StyleComponentValueRule const& component_value)
|
||||
{
|
||||
if (component_value.is(Token::Type::Ident)) {
|
||||
|
@ -1975,7 +1902,7 @@ Optional<Length> Parser::parse_length(StyleComponentValueRule const& component_v
|
|||
Optional<float> 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<Length> 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 <quirky-length> 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<StyleValue> 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<StyleValue> 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<Color> 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<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());
|
||||
auto r = r_val.to_integer();
|
||||
auto g = g_val.to_integer();
|
||||
auto b = b_val.to_integer();
|
||||
if (AK::is_within_range<u8>(r) && AK::is_within_range<u8>(g) && AK::is_within_range<u8>(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<Color> 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<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);
|
||||
}
|
||||
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<u8>(r) && AK::is_within_range<u8>(g) && AK::is_within_range<u8>(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<Color> 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<double>(h), static_cast<double>(s), static_cast<double>(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<Color> 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<double>(h), static_cast<double>(s), static_cast<double>(l), static_cast<double>(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<CalculatedStyleValue::CalcValue> Parser::parse_calc_value(TokenStream<S
|
|||
auto parsed_calc_sum = parse_calc_sum(block_values);
|
||||
if (!parsed_calc_sum)
|
||||
return {};
|
||||
return (CalculatedStyleValue::CalcValue) { parsed_calc_sum.release_nonnull() };
|
||||
return CalculatedStyleValue::CalcValue { parsed_calc_sum.release_nonnull() };
|
||||
}
|
||||
|
||||
if (current_token.is(Token::Type::Number)) {
|
||||
auto try_the_number = try_parse_float(current_token.token().number_string_value());
|
||||
if (try_the_number.has_value())
|
||||
return (CalculatedStyleValue::CalcValue) { try_the_number.value() };
|
||||
return {};
|
||||
}
|
||||
if (current_token.is(Token::Type::Number))
|
||||
return CalculatedStyleValue::CalcValue { static_cast<float>(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<CalculatedStyleValue::CalcNumberValue> 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<CalculatedStyleValue::CalcProduct> Parser::parse_calc_product(TokenStream<StyleComponentValueRule>& tokens)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue