From 644facd19d659ad30edb63a0e0882c7ff17296cc Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 21 May 2024 11:25:57 -0700 Subject: [PATCH] Make dimension units case insensitive (#44639) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44639 https://www.w3.org/TR/css-values-4/#dimensions > Like keywords, unit identifiers are ASCII case-insensitive. Changelog: [Internal] Reviewed By: joevilches Differential Revision: D57620806 fbshipit-source-id: 26946ed4031f379888651c08b1b0895ac701a320 --- .../ReactCommon/react/renderer/css/CSSAngleUnit.h | 2 +- .../ReactCommon/react/renderer/css/CSSKeywords.h | 11 +---------- .../ReactCommon/react/renderer/css/CSSLengthUnit.h | 2 +- .../react/renderer/css/tests/CSSValueParserTest.cpp | 9 +++++++++ .../react-native/ReactCommon/react/utils/fnv1a.h | 13 +++++++++++++ 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSAngleUnit.h b/packages/react-native/ReactCommon/react/renderer/css/CSSAngleUnit.h index 1261fcef660..4e2255f180c 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/CSSAngleUnit.h +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSAngleUnit.h @@ -31,7 +31,7 @@ enum class CSSAngleUnit : uint8_t { * Parses a unit from a dimension token into a CSS angle unit. */ constexpr std::optional parseCSSAngleUnit(std::string_view unit) { - switch (fnv1a(unit)) { + switch (fnv1aLowercase(unit)) { case fnv1a("deg"): return CSSAngleUnit::Deg; case fnv1a("grad"): diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSKeywords.h b/packages/react-native/ReactCommon/react/renderer/css/CSSKeywords.h index ef2fb4fa286..f2e3b779b3b 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/CSSKeywords.h +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSKeywords.h @@ -175,16 +175,7 @@ CSS_DEFINE_KEYWORD_CONEPTS(WrapReverse) */ template constexpr std::optional parseCSSKeyword(std::string_view ident) { - struct LowerCaseTransform { - constexpr char operator()(char c) const { - if (c >= 'A' && c <= 'Z') { - return c + static_cast('a' - 'A'); - } - return c; - } - }; - - switch (fnv1a(ident)) { + switch (fnv1aLowercase(ident)) { case fnv1a("absolute"): if constexpr (detail::hasAbsolute) { return KeywordT::Absolute; diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSLengthUnit.h b/packages/react-native/ReactCommon/react/renderer/css/CSSLengthUnit.h index dea830d6727..b09199832a8 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/CSSLengthUnit.h +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSLengthUnit.h @@ -70,7 +70,7 @@ enum class CSSLengthUnit : uint8_t { */ constexpr std::optional parseCSSLengthUnit( std::string_view unit) { - switch (fnv1a(unit)) { + switch (fnv1aLowercase(unit)) { case fnv1a("cap"): return CSSLengthUnit::Cap; case fnv1a("ch"): diff --git a/packages/react-native/ReactCommon/react/renderer/css/tests/CSSValueParserTest.cpp b/packages/react-native/ReactCommon/react/renderer/css/tests/CSSValueParserTest.cpp index 473ed1bb6a6..67e32665fb6 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/tests/CSSValueParserTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/css/tests/CSSValueParserTest.cpp @@ -59,6 +59,11 @@ TEST(CSSValueParser, length_values) { EXPECT_EQ(pxValue.getLength().value, 20.0f); EXPECT_EQ(pxValue.getLength().unit, CSSLengthUnit::Px); + auto capsValue = parseCSSValue("50PX"); + EXPECT_EQ(capsValue.type(), CSSValueType::Length); + EXPECT_EQ(capsValue.getLength().value, 50.0f); + EXPECT_EQ(capsValue.getLength().unit, CSSLengthUnit::Px); + auto cmValue = parseCSSValue("453cm"); EXPECT_EQ(cmValue.type(), CSSValueType::Length); EXPECT_EQ(cmValue.getLength().value, 453.0f); @@ -258,6 +263,10 @@ TEST(CSSValueParser, angle_values) { EXPECT_EQ(degreeValue.type(), CSSValueType::Angle); EXPECT_EQ(degreeValue.getAngle().degrees, 10.0f); + auto spongebobCaseValue = parseCSSValue("20dEg"); + EXPECT_EQ(spongebobCaseValue.type(), CSSValueType::Angle); + EXPECT_EQ(spongebobCaseValue.getAngle().degrees, 20.0f); + auto radianValue = parseCSSValue("10rad"); EXPECT_EQ(radianValue.type(), CSSValueType::Angle); EXPECT_NEAR(radianValue.getAngle().degrees, 572.958f, 0.001f); diff --git a/packages/react-native/ReactCommon/react/utils/fnv1a.h b/packages/react-native/ReactCommon/react/utils/fnv1a.h index 4f6bf4a16ec..2acdeb3113b 100644 --- a/packages/react-native/ReactCommon/react/utils/fnv1a.h +++ b/packages/react-native/ReactCommon/react/utils/fnv1a.h @@ -38,4 +38,17 @@ constexpr uint32_t fnv1a(std::string_view string) noexcept { return hash; } +constexpr uint32_t fnv1aLowercase(std::string_view string) { + struct LowerCaseTransform { + constexpr char operator()(char c) const { + if (c >= 'A' && c <= 'Z') { + return c + static_cast('a' - 'A'); + } + return c; + } + }; + + return fnv1a(string); +} + } // namespace facebook::react