diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc | 315 |
1 files changed, 270 insertions, 45 deletions
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc index 9d8bbcdf9bd..9e6d48dfb68 100644 --- a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc +++ b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/animation/css/css_animations.h" #include "third_party/blink/renderer/core/css/active_style_sheets.h" #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" +#include "third_party/blink/renderer/core/css/css_initial_color_value.h" #include "third_party/blink/renderer/core/css/css_pending_substitution_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_test_helpers.h" @@ -38,6 +39,7 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style_property_shorthand.h" +#include "third_party/blink/renderer/core/testing/color_scheme_helper.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -54,13 +56,10 @@ class TestCascadeResolver { STACK_ALLOCATED(); public: - explicit TestCascadeResolver(Document& document, uint8_t generation = 0) - : document_(document), resolver_(CascadeFilter(), generation) {} + explicit TestCascadeResolver(uint8_t generation = 0) + : resolver_(CascadeFilter(), generation) {} bool InCycle() const { return resolver_.InCycle(); } - bool DetectCycle(String name) { - CSSPropertyRef ref(name, document_); - DCHECK(ref.IsValid()); - const CSSProperty& property = ref.GetProperty(); + bool DetectCycle(const CSSProperty& property) { return resolver_.DetectCycle(property); } wtf_size_t CycleDepth() const { return resolver_.cycle_depth_; } @@ -72,11 +71,13 @@ class TestCascadeResolver { } uint8_t GetGeneration() { return resolver_.generation_; } CascadeResolver& InnerResolver() { return resolver_; } + const CSSProperty* CurrentProperty() const { + return resolver_.CurrentProperty(); + } private: friend class TestCascadeAutoLock; - Document& document_; CascadeResolver resolver_; }; @@ -130,7 +131,7 @@ class TestCascade { void ApplySingle(const CSSProperty& property) { EnsureAtLeast(CascadeOrigin::kAuthor); cascade_.AnalyzeIfNeeded(); - TestCascadeResolver resolver(GetDocument(), ++cascade_.generation_); + TestCascadeResolver resolver(++cascade_.generation_); cascade_.LookupAndApply(property, resolver.InnerResolver()); } @@ -259,20 +260,24 @@ class TestCascadeAutoLock { STACK_ALLOCATED(); public: - TestCascadeAutoLock(const CSSPropertyName& name, + TestCascadeAutoLock(const CSSProperty& property, TestCascadeResolver& resolver) - : lock_(name, resolver.resolver_) {} + : lock_(property, resolver.resolver_) {} private: CascadeResolver::AutoLock lock_; }; -class StyleCascadeTest : public PageTestBase, - private ScopedCSSCascadeForTest, - private ScopedCSSRevertForTest { +class StyleCascadeTest + : public PageTestBase, + private ScopedCSSCascadeForTest, + private ScopedCSSRevertForTest, + private ScopedCSSMatchedPropertiesCacheDependenciesForTest { public: StyleCascadeTest() - : ScopedCSSCascadeForTest(true), ScopedCSSRevertForTest(true) {} + : ScopedCSSCascadeForTest(true), + ScopedCSSRevertForTest(true), + ScopedCSSMatchedPropertiesCacheDependenciesForTest(true) {} CSSStyleSheet* CreateSheet(const String& css_text) { auto* init = MakeGarbageCollected<CSSStyleSheetInit>(); @@ -280,8 +285,8 @@ class StyleCascadeTest : public PageTestBase, CSSStyleSheet* sheet = CSSStyleSheet::Create(GetDocument(), init, exception_state); sheet->replaceSync(css_text, exception_state); - sheet->Contents()->EnsureRuleSet(MediaQueryEvaluator(), - kRuleHasNoSpecialState); + sheet->Contents()->EnsureRuleSet( + MediaQueryEvaluator(GetDocument().GetFrame()), kRuleHasNoSpecialState); return sheet; } @@ -338,6 +343,10 @@ class StyleCascadeTest : public PageTestBase, Document* document_; AtomicString name_; }; + + CSSPropertyName PropertyName(String name) { + return *CSSPropertyName::From(GetDocument().GetExecutionContext(), name); + } }; TEST_F(StyleCascadeTest, ApplySingle) { @@ -617,21 +626,45 @@ TEST_F(StyleCascadeTest, PendingSubstitutionInLogicalShorthand) { EXPECT_EQ("10px", cascade.ComputedValue("margin-right")); } +TEST_F(StyleCascadeTest, DetectCycleByName) { + TestCascade cascade(GetDocument()); + TestCascadeResolver resolver; + + // Two different CustomProperty instances with the same name: + CustomProperty a1("--a", GetDocument()); + CustomProperty a2("--a", GetDocument()); + + { + TestCascadeAutoLock lock(a1, resolver); + EXPECT_FALSE(resolver.InCycle()); + + // This should still be detected as a cycle, even though it's not the same + // CustomProperty instance. + EXPECT_TRUE(resolver.DetectCycle(a2)); + EXPECT_TRUE(resolver.InCycle()); + } + EXPECT_FALSE(resolver.InCycle()); +} + TEST_F(StyleCascadeTest, ResolverDetectCycle) { TestCascade cascade(GetDocument()); - TestCascadeResolver resolver(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); + CustomProperty b("--b", GetDocument()); + CustomProperty c("--c", GetDocument()); { - TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver); + TestCascadeAutoLock lock(a, resolver); EXPECT_FALSE(resolver.InCycle()); { - TestCascadeAutoLock lock(CSSPropertyName("--b"), resolver); + TestCascadeAutoLock lock(b, resolver); EXPECT_FALSE(resolver.InCycle()); { - TestCascadeAutoLock lock(CSSPropertyName("--c"), resolver); + TestCascadeAutoLock lock(c, resolver); EXPECT_FALSE(resolver.InCycle()); - EXPECT_TRUE(resolver.DetectCycle("--a")); + EXPECT_TRUE(resolver.DetectCycle(a)); EXPECT_TRUE(resolver.InCycle()); } EXPECT_TRUE(resolver.InCycle()); @@ -643,19 +676,24 @@ TEST_F(StyleCascadeTest, ResolverDetectCycle) { TEST_F(StyleCascadeTest, ResolverDetectNoCycle) { TestCascade cascade(GetDocument()); - TestCascadeResolver resolver(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); + CustomProperty b("--b", GetDocument()); + CustomProperty c("--c", GetDocument()); + CustomProperty x("--x", GetDocument()); { - TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver); + TestCascadeAutoLock lock(a, resolver); EXPECT_FALSE(resolver.InCycle()); { - TestCascadeAutoLock lock(CSSPropertyName("--b"), resolver); + TestCascadeAutoLock lock(b, resolver); EXPECT_FALSE(resolver.InCycle()); { - TestCascadeAutoLock lock(CSSPropertyName("--c"), resolver); + TestCascadeAutoLock lock(c, resolver); EXPECT_FALSE(resolver.InCycle()); - EXPECT_FALSE(resolver.DetectCycle("--x")); + EXPECT_FALSE(resolver.DetectCycle(x)); EXPECT_FALSE(resolver.InCycle()); } EXPECT_FALSE(resolver.InCycle()); @@ -667,13 +705,15 @@ TEST_F(StyleCascadeTest, ResolverDetectNoCycle) { TEST_F(StyleCascadeTest, ResolverDetectCycleSelf) { TestCascade cascade(GetDocument()); - TestCascadeResolver resolver(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); { - TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver); + TestCascadeAutoLock lock(a, resolver); EXPECT_FALSE(resolver.InCycle()); - EXPECT_TRUE(resolver.DetectCycle("--a")); + EXPECT_TRUE(resolver.DetectCycle(a)); EXPECT_TRUE(resolver.InCycle()); } EXPECT_FALSE(resolver.InCycle()); @@ -683,28 +723,33 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycle) { using AutoLock = TestCascadeAutoLock; TestCascade cascade(GetDocument()); - TestCascadeResolver resolver(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); + CustomProperty b("--b", GetDocument()); + CustomProperty c("--c", GetDocument()); + CustomProperty d("--d", GetDocument()); { - AutoLock lock(CSSPropertyName("--a"), resolver); + AutoLock lock(a, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--b"), resolver); + AutoLock lock(b, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--c"), resolver); + AutoLock lock(c, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--d"), resolver); + AutoLock lock(d, resolver); EXPECT_FALSE(resolver.InCycle()); // Cycle 1 (big cycle): - EXPECT_TRUE(resolver.DetectCycle("--b")); + EXPECT_TRUE(resolver.DetectCycle(b)); EXPECT_TRUE(resolver.InCycle()); EXPECT_EQ(1u, resolver.CycleDepth()); // Cycle 2 (small cycle): - EXPECT_TRUE(resolver.DetectCycle("--c")); + EXPECT_TRUE(resolver.DetectCycle(c)); EXPECT_TRUE(resolver.InCycle()); EXPECT_EQ(1u, resolver.CycleDepth()); } @@ -720,28 +765,33 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) { using AutoLock = TestCascadeAutoLock; TestCascade cascade(GetDocument()); - TestCascadeResolver resolver(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); + CustomProperty b("--b", GetDocument()); + CustomProperty c("--c", GetDocument()); + CustomProperty d("--d", GetDocument()); { - AutoLock lock(CSSPropertyName("--a"), resolver); + AutoLock lock(a, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--b"), resolver); + AutoLock lock(b, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--c"), resolver); + AutoLock lock(c, resolver); EXPECT_FALSE(resolver.InCycle()); { - AutoLock lock(CSSPropertyName("--d"), resolver); + AutoLock lock(d, resolver); EXPECT_FALSE(resolver.InCycle()); // Cycle 1 (small cycle): - EXPECT_TRUE(resolver.DetectCycle("--c")); + EXPECT_TRUE(resolver.DetectCycle(c)); EXPECT_TRUE(resolver.InCycle()); EXPECT_EQ(2u, resolver.CycleDepth()); // Cycle 2 (big cycle): - EXPECT_TRUE(resolver.DetectCycle("--b")); + EXPECT_TRUE(resolver.DetectCycle(b)); EXPECT_TRUE(resolver.InCycle()); EXPECT_EQ(1u, resolver.CycleDepth()); } @@ -754,7 +804,7 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) { } TEST_F(StyleCascadeTest, ResolverMarkApplied) { - TestCascadeResolver resolver(GetDocument(), 2); + TestCascadeResolver resolver(2); CascadePriority priority(CascadeOrigin::kAuthor); EXPECT_EQ(0, priority.GetGeneration()); @@ -767,8 +817,36 @@ TEST_F(StyleCascadeTest, ResolverMarkApplied) { EXPECT_EQ(2, priority.GetGeneration()); } +TEST_F(StyleCascadeTest, CurrentProperty) { + using AutoLock = TestCascadeAutoLock; + + TestCascade cascade(GetDocument()); + TestCascadeResolver resolver; + + CustomProperty a("--a", GetDocument()); + CustomProperty b("--b", GetDocument()); + CustomProperty c("--c", GetDocument()); + + EXPECT_FALSE(resolver.CurrentProperty()); + { + AutoLock lock(a, resolver); + EXPECT_EQ(&a, resolver.CurrentProperty()); + { + AutoLock lock(b, resolver); + EXPECT_EQ(&b, resolver.CurrentProperty()); + { + AutoLock lock(c, resolver); + EXPECT_EQ(&c, resolver.CurrentProperty()); + } + EXPECT_EQ(&b, resolver.CurrentProperty()); + } + EXPECT_EQ(&a, resolver.CurrentProperty()); + } + EXPECT_FALSE(resolver.CurrentProperty()); +} + TEST_F(StyleCascadeTest, ResolverMarkUnapplied) { - TestCascadeResolver resolver(GetDocument(), 7); + TestCascadeResolver resolver(7); CascadePriority priority(CascadeOrigin::kAuthor); EXPECT_EQ(0, priority.GetGeneration()); @@ -2603,6 +2681,37 @@ TEST_F(StyleCascadeTest, RubyPositionSurrogateCanCascadeAsOriginal) { } } +TEST_F(StyleCascadeTest, TextOrientationPriority) { + TestCascade cascade(GetDocument()); + cascade.Add("text-orientation:upright !important"); + cascade.Add("-webkit-text-orientation:sideways"); + cascade.Apply(); + + EXPECT_EQ("upright", cascade.ComputedValue("text-orientation")); + EXPECT_EQ("upright", cascade.ComputedValue("-webkit-text-orientation")); +} + +TEST_F(StyleCascadeTest, TextOrientationRevert) { + TestCascade cascade(GetDocument()); + cascade.Add("text-orientation:upright", CascadeOrigin::kUserAgent); + cascade.Add("-webkit-text-orientation:mixed"); + cascade.Add("-webkit-text-orientation:revert"); + cascade.Apply(); + + EXPECT_EQ("upright", cascade.ComputedValue("text-orientation")); + EXPECT_EQ("upright", cascade.ComputedValue("-webkit-text-orientation")); +} + +TEST_F(StyleCascadeTest, TextOrientationLegacyKeyword) { + TestCascade cascade(GetDocument()); + cascade.Add("-webkit-text-orientation:vertical-right"); + cascade.Apply(); + + EXPECT_EQ("mixed", cascade.ComputedValue("text-orientation")); + EXPECT_EQ("vertical-right", + cascade.ComputedValue("-webkit-text-orientation")); +} + TEST_F(StyleCascadeTest, WebkitBorderImageCascadeOrder) { String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))"); String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))"); @@ -3114,4 +3223,120 @@ TEST_F(StyleCascadeTest, GetImportantSetMany) { *cascade.GetImportantSet()); } +TEST_F(StyleCascadeTest, NoDependenciesPresent) { + TestCascade cascade(GetDocument()); + cascade.Add("left:2px"); + cascade.Add("top:initial"); + cascade.Add("border:1px solid black"); + cascade.Add("--x:bar"); + cascade.Add("direction:rtl"); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_TRUE(state.Dependencies().IsEmpty()); + EXPECT_FALSE(state.HasIncomparableDependency()); +} + +TEST_F(StyleCascadeTest, ExplicitInheritanceDependencyIsDetected) { + TestCascade cascade(GetDocument()); + cascade.Add("left:inherit"); + cascade.Add("right:inherit"); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_EQ(2u, state.Dependencies().size()); + EXPECT_TRUE(state.Dependencies().Contains(PropertyName("left"))); + EXPECT_TRUE(state.Dependencies().Contains(PropertyName("right"))); + EXPECT_FALSE(state.HasIncomparableDependency()); +} + +TEST_F(StyleCascadeTest, IncomparableDependencyDetected) { + ASSERT_FALSE( + GetCSSPropertyInternalEmptyLineHeight().IsComputedValueComparable()); + + TestCascade cascade(GetDocument()); + cascade.Add("-internal-empty-line-height:inherit", CascadeOrigin::kUserAgent); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_EQ(1u, state.Dependencies().size()); + EXPECT_TRUE(state.Dependencies().Contains( + CSSPropertyName(CSSPropertyID::kInternalEmptyLineHeight))); + EXPECT_TRUE(state.HasIncomparableDependency()); +} + +TEST_F(StyleCascadeTest, CustomPropertyDependencyIsDetected) { + TestCascade cascade(GetDocument()); + cascade.Add("left:var(--x,1px)"); + cascade.Add("right:var(--x,2px)"); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_EQ(1u, state.Dependencies().size()); + EXPECT_TRUE(state.Dependencies().Contains(PropertyName("--x"))); + EXPECT_FALSE(state.HasIncomparableDependency()); +} + +TEST_F(StyleCascadeTest, NonInheritedCustomPropertyIsNoDependency) { + RegisterProperty(GetDocument(), "--x", "<length>", "0px", false); + TestCascade cascade(GetDocument()); + cascade.Add("left:var(--x,1px)"); + cascade.Add("right:var(--x,2px)"); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_EQ(0u, state.Dependencies().size()); +} + +TEST_F(StyleCascadeTest, DirectionAndWritingModeDependenciesAreDetected) { + TestCascade cascade(GetDocument()); + cascade.Add("margin-inline-start: 2px"); + cascade.Apply(); + const auto& state = cascade.State(); + EXPECT_EQ(2u, state.Dependencies().size()); + EXPECT_TRUE(state.Dependencies().Contains(PropertyName("direction"))); + EXPECT_TRUE(state.Dependencies().Contains(PropertyName("writing-mode"))); + EXPECT_FALSE(state.HasIncomparableDependency()); +} + +TEST_F(StyleCascadeTest, RootColorNotModifiedByEmptyCascade) { + TestCascade cascade(GetDocument(), GetDocument().documentElement()); + cascade.Add("color:red"); + cascade.Apply(); + + cascade.Reset(); + cascade.Add("display:block"); + cascade.Apply(); // Should not affect 'color'. + + auto style = cascade.TakeStyle(); + + style->SetInsideLink(EInsideLink::kInsideVisitedLink); + EXPECT_EQ(Color(255, 0, 0), + style->VisitedDependentColor(GetCSSPropertyColor())); + + style->SetInsideLink(EInsideLink::kNotInsideLink); + EXPECT_EQ(Color(255, 0, 0), + style->VisitedDependentColor(GetCSSPropertyColor())); +} + +TEST_F(StyleCascadeTest, InitialColor) { + ColorSchemeHelper color_scheme_helper(GetDocument()); + color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark); + + TestCascade cascade(GetDocument(), GetDocument().documentElement()); + cascade.Add("color-scheme:dark"); + + // CSSInitialColorValue is not reachable via a string, hence we must + // create the CSSPropertyValueSet that contains it manually. + auto* set = + MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLStandardMode); + set->SetProperty(CSSPropertyID::kColor, *CSSInitialColorValue::Create()); + cascade.Add(set); + + cascade.Apply(); + + auto style = cascade.TakeStyle(); + + style->SetInsideLink(EInsideLink::kInsideVisitedLink); + EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor())); + + style->SetInsideLink(EInsideLink::kNotInsideLink); + EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor())); +} + } // namespace blink |