| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h" |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/renderer/core/css/css_color_value.h" |
| #include "third_party/blink/renderer/core/css/css_identifier_value.h" |
| #include "third_party/blink/renderer/core/css/css_value_list.h" |
| #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" |
| |
| namespace blink { |
| |
| TEST(CSSParserFastPathsTest, ParseKeyword) { |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kFloat, "left", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| CSSIdentifierValue* identifier_value = To<CSSIdentifierValue>(value); |
| EXPECT_EQ(CSSValueID::kLeft, identifier_value->GetValueID()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kFloat, "foo", |
| kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseCSSWideKeywords) { |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kMarginTop, "inherit", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsInheritedValue()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMarginRight, |
| "InHeriT", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsInheritedValue()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMarginBottom, |
| "initial", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsInitialValue()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMarginLeft, |
| "IniTiaL", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsInitialValue()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMarginTop, |
| "unset", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsUnsetValue()); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMarginLeft, |
| "unsEt", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsUnsetValue()); |
| // Fast path doesn't handle short hands. |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kMargin, "initial", |
| kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseRevert) { |
| // Revert enabled, IsKeywordPropertyID=false |
| { |
| DCHECK(!CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID::kMarginTop)); |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kMarginTop, "revert", kHTMLStandardMode); |
| ASSERT_TRUE(value); |
| EXPECT_TRUE(value->IsRevertValue()); |
| } |
| |
| // Revert enabled, IsKeywordPropertyID=true |
| { |
| DCHECK(CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID::kDirection)); |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kDirection, "revert", kHTMLStandardMode); |
| ASSERT_TRUE(value); |
| EXPECT_TRUE(value->IsRevertValue()); |
| } |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseTransform) { |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kTransform, "translate(5.5px, 5px)", kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| ASSERT_TRUE(value->IsValueList()); |
| ASSERT_EQ("translate(5.5px, 5px)", value->CssText()); |
| |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kTransform, |
| "translate3d(5px, 5px, 10.1px)", |
| kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| ASSERT_TRUE(value->IsValueList()); |
| ASSERT_EQ("translate3d(5px, 5px, 10.1px)", value->CssText()); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseComplexTransform) { |
| // Random whitespace is on purpose. |
| static const char* kComplexTransform = |
| "translateX(5px) " |
| "translateZ(20.5px) " |
| "translateY(10px) " |
| "scale3d(0.5, 1, 0.7) " |
| "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) "; |
| static const char* kComplexTransformNormalized = |
| "translateX(5px) " |
| "translateZ(20.5px) " |
| "translateY(10px) " |
| "scale3d(0.5, 1, 0.7) " |
| "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)"; |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kTransform, kComplexTransform, kHTMLStandardMode); |
| ASSERT_NE(nullptr, value); |
| ASSERT_TRUE(value->IsValueList()); |
| ASSERT_EQ(kComplexTransformNormalized, value->CssText()); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseTransformNotFastPath) { |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kTransform, "rotateX(1deg)", kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| value = CSSParserFastPaths::MaybeParseValue(CSSPropertyID::kTransform, |
| "translateZ(1px) rotateX(1deg)", |
| kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseInvalidTransform) { |
| CSSValue* value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kTransform, "rotateX(1deg", kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| value = CSSParserFastPaths::MaybeParseValue( |
| CSSPropertyID::kTransform, "translateZ(1px) (1px, 1px) rotateX(1deg", |
| kHTMLStandardMode); |
| ASSERT_EQ(nullptr, value); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseColorWithLargeAlpha) { |
| CSSValue* value = CSSParserFastPaths::ParseColor("rgba(0,0,0,1893205797.13)", |
| kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseColorWithNewSyntax) { |
| CSSValue* value = |
| CSSParserFastPaths::ParseColor("rgba(0 0 0)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("rgba(0 0 0 / 1)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("rgba(0, 0, 0, 1)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("RGBA(0 0 0 / 1)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("RGB(0 0 0 / 1)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("rgba(0 0 0 0)", kHTMLStandardMode); |
| EXPECT_EQ(nullptr, value); |
| |
| value = CSSParserFastPaths::ParseColor("rgba(0, 0 0 1)", kHTMLStandardMode); |
| EXPECT_EQ(nullptr, value); |
| |
| value = |
| CSSParserFastPaths::ParseColor("rgba(0, 0, 0 / 1)", kHTMLStandardMode); |
| EXPECT_EQ(nullptr, value); |
| |
| value = CSSParserFastPaths::ParseColor("rgba(0 0 0, 1)", kHTMLStandardMode); |
| EXPECT_EQ(nullptr, value); |
| } |
| |
| TEST(CSSParserFastPathsTest, ParseColorWithDecimal) { |
| CSSValue* value = CSSParserFastPaths::ParseColor("rgba(0.0, 0.0, 0.0, 1.0)", |
| kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = |
| CSSParserFastPaths::ParseColor("rgb(0.0, 0.0, 0.0)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = |
| CSSParserFastPaths::ParseColor("rgb(0.0 , 0.0,0.0)", kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value()); |
| |
| value = CSSParserFastPaths::ParseColor("rgb(254.5, 254.5, 254.5)", |
| kHTMLStandardMode); |
| EXPECT_NE(nullptr, value); |
| EXPECT_TRUE(value->IsColorValue()); |
| EXPECT_EQ(Color::kWhite, To<cssvalue::CSSColorValue>(*value).Value()); |
| } |
| |
| TEST(CSSParserFastPathsTest, IsValidKeywordPropertyAndValueOverflowClip) { |
| { |
| ScopedOverflowClipForTest overflow_clip_feature_enabler(false); |
| EXPECT_FALSE(CSSParserFastPaths::IsValidKeywordPropertyAndValue( |
| CSSPropertyID::kOverflowX, CSSValueID::kClip, |
| CSSParserMode::kHTMLStandardMode)); |
| } |
| { |
| ScopedOverflowClipForTest overflow_clip_feature_enabler(true); |
| EXPECT_TRUE(CSSParserFastPaths::IsValidKeywordPropertyAndValue( |
| CSSPropertyID::kOverflowX, CSSValueID::kClip, |
| CSSParserMode::kHTMLStandardMode)); |
| } |
| } |
| |
| } // namespace blink |