diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2021-11-18 11:46:27 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-19 22:35:05 +0100 |
commit | 1d2276f0e70b95470b20430ccecc6b8d6d6c8101 (patch) | |
tree | 14c5f1cc33b5e4096579aa5effd1ea41623ebc23 /Userland | |
parent | f6869797a7a56de4db4d9d8a06bfffe6ca520d81 (diff) | |
download | serenity-1d2276f0e70b95470b20430ccecc6b8d6d6c8101.zip |
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.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Token.h | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Token.h b/Userland/Libraries/LibWeb/CSS/Parser/Token.h index b7e2a96480..dcb5bca35d 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Token.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Token.h @@ -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; |