1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:37:35 +00:00

LibWeb: Return numeric values from Token value getters

This saves user code from having to parse the numbers, as we already did
that while Tokenizing. :^)

As a bonus, we now round extremely large integers to the closest
available value, like the spec tells us to.
This commit is contained in:
Sam Atkins 2021-11-18 11:46:27 +00:00 committed by Andreas Kling
parent f6869797a7
commit 1d2276f0e7

View file

@ -9,6 +9,7 @@
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <math.h>
namespace Web::CSS {
@ -111,10 +112,15 @@ public:
VERIFY(m_type == Type::Number);
return m_value.string_view();
}
double number_value() const
{
VERIFY(m_type == Type::Number);
return m_number_value;
}
i64 to_integer() const
{
VERIFY(m_type == Type::Number && m_number_type == NumberType::Integer);
return number_string_value().to_int<i64>().value();
return to_closest_integer(m_number_value);
}
bool is_integer_value_signed() const { return number_string_value().starts_with('-') || number_string_value().starts_with('+'); }
@ -123,16 +129,22 @@ public:
VERIFY(m_type == Type::Dimension);
return m_unit.string_view();
}
StringView dimension_value() const
double dimension_value() const
{
VERIFY(m_type == Type::Dimension);
return m_value.string_view();
return m_number_value;
}
i64 dimension_value_int() const { return to_closest_integer(dimension_value()); }
double percentage() const
{
VERIFY(m_type == Type::Percentage);
return m_number_value;
}
i64 dimension_value_int() const { return dimension_value().to_int().value(); }
NumberType number_type() const
{
VERIFY((m_type == Type::Number) || (m_type == Type::Dimension));
VERIFY((m_type == Type::Number) || (m_type == Type::Dimension) || (m_type == Type::Percentage));
return m_number_type;
}
@ -146,6 +158,15 @@ public:
Position const& end_position() const { return m_end_position; }
private:
static i64 to_closest_integer(double value)
{
// https://www.w3.org/TR/css-values-4/#numeric-types
// When a value cannot be explicitly supported due to range/precision limitations, it must be converted
// to the closest value supported by the implementation, but how the implementation defines "closest"
// is explicitly undefined as well.
return static_cast<i64>(clamp(round(value), NumericLimits<i64>::min(), NumericLimits<i64>::max()));
}
Type m_type { Type::Invalid };
StringBuilder m_value;