summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2021-11-18 11:46:27 +0000
committerAndreas Kling <kling@serenityos.org>2021-11-19 22:35:05 +0100
commit1d2276f0e70b95470b20430ccecc6b8d6d6c8101 (patch)
tree14c5f1cc33b5e4096579aa5effd1ea41623ebc23 /Userland
parentf6869797a7a56de4db4d9d8a06bfffe6ca520d81 (diff)
downloadserenity-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.h31
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;