summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
diff options
context:
space:
mode:
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.cc315
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