Index: third_party/WebKit/Source/core/dom/StyleEngineTest.cpp |
diff --git a/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp b/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp |
index f40e71e9c02545d88505e3122a8c3dc8e1c6da10..2eb87c3c8d3a378593b54cfe38e32c888dd43fc7 100644 |
--- a/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp |
+++ b/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp |
@@ -7,6 +7,7 @@ |
#include "core/css/StyleSheetContents.h" |
#include "core/dom/Document.h" |
#include "core/dom/NodeComputedStyle.h" |
+#include "core/dom/shadow/ShadowRootInit.h" |
#include "core/frame/FrameView.h" |
#include "core/html/HTMLElement.h" |
#include "core/html/HTMLStyleElement.h" |
@@ -26,6 +27,9 @@ protected: |
bool isDocumentStyleSheetCollectionClean() { return !styleEngine().shouldUpdateDocumentStyleSheetCollection(AnalyzedStyleUpdate); } |
+ enum RuleSetInvalidation { RuleSetInvalidationsScheduled, RuleSetInvalidationFullRecalc }; |
+ RuleSetInvalidation scheduleInvalidationsForRules(TreeScope&, const String& cssText); |
+ |
private: |
std::unique_ptr<DummyPageHolder> m_dummyPageHolder; |
}; |
@@ -35,6 +39,21 @@ void StyleEngineTest::SetUp() |
m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); |
} |
+StyleEngineTest::RuleSetInvalidation |
+StyleEngineTest::scheduleInvalidationsForRules(TreeScope& treeScope, const String& cssText) |
+{ |
+ StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr)); |
+ sheet->parseString(cssText); |
+ HeapVector<Member<const RuleSet>> ruleSets; |
+ RuleSet& ruleSet = sheet->ensureRuleSet(MediaQueryEvaluator(), RuleHasDocumentSecurityOrigin); |
+ ruleSet.compactRulesIfNeeded(); |
+ if (ruleSet.needsFullRecalcForRuleSetInvalidation()) |
+ return RuleSetInvalidationFullRecalc; |
+ ruleSets.append(&ruleSet); |
+ styleEngine().scheduleInvalidationsForRuleSets(treeScope, ruleSets); |
+ return RuleSetInvalidationsScheduled; |
+} |
+ |
TEST_F(StyleEngineTest, DocumentDirtyAfterInject) |
{ |
StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContext(document(), nullptr)); |
@@ -102,4 +121,136 @@ TEST_F(StyleEngineTest, TextToSheetCache) |
EXPECT_FALSE(sheet1->contents()->isUsedFromTextCache()); |
} |
+TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) |
+{ |
+ document().body()->setInnerHTML( |
+ "<div>" |
+ " <span></span>" |
+ " <div></div>" |
+ "</div>", ASSERT_NO_EXCEPTION); |
+ |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ unsigned beforeCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(scheduleInvalidationsForRules(document(), "span { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ unsigned afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(1u, afterCount - beforeCount); |
+ |
+ beforeCount = afterCount; |
+ EXPECT_EQ(scheduleInvalidationsForRules(document(), "body div { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(2u, afterCount - beforeCount); |
+ |
+ EXPECT_EQ(scheduleInvalidationsForRules(document(), "div * { background: green}"), RuleSetInvalidationFullRecalc); |
+} |
+ |
+TEST_F(StyleEngineTest, RuleSetInvalidationHost) |
+{ |
+ document().body()->setInnerHTML("<div id=nohost></div><div id=host></div>", ASSERT_NO_EXCEPTION); |
+ Element* host = document().getElementById("host"); |
+ ASSERT_TRUE(host); |
+ |
+ ShadowRootInit init; |
+ init.setMode("open"); |
+ ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
+ ASSERT_TRUE(shadowRoot); |
+ |
+ shadowRoot->setInnerHTML("<div></div><div></div><div></div>", ASSERT_NO_EXCEPTION); |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ unsigned beforeCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host(#nohost), #nohost { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ unsigned afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(0u, afterCount - beforeCount); |
+ |
+ beforeCount = afterCount; |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host(#host) { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(1u, afterCount - beforeCount); |
+ |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host(*) { background: green}"), RuleSetInvalidationFullRecalc); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host(*) :hover { background: green}"), RuleSetInvalidationFullRecalc); |
+} |
+ |
+TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) |
+{ |
+ document().body()->setInnerHTML( |
+ "<div id=host>" |
+ " <span slot=other class=s1></span>" |
+ " <span class=s2></span>" |
+ " <span class=s1></span>" |
+ " <span></span>" |
+ "</div>", ASSERT_NO_EXCEPTION); |
+ |
+ Element* host = document().getElementById("host"); |
+ ASSERT_TRUE(host); |
+ |
+ ShadowRootInit init; |
+ init.setMode("open"); |
+ ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
+ ASSERT_TRUE(shadowRoot); |
+ |
+ shadowRoot->setInnerHTML("<slot name=other></slot><slot></slot>", ASSERT_NO_EXCEPTION); |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ unsigned beforeCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, "::slotted(.s1) { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ unsigned afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(4u, afterCount - beforeCount); |
+ |
+ beforeCount = afterCount; |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, "::slotted(*) { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(4u, afterCount - beforeCount); |
+} |
+ |
+TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) |
+{ |
+ document().body()->setInnerHTML("<div id=host></div>", ASSERT_NO_EXCEPTION); |
+ Element* host = document().getElementById("host"); |
+ ASSERT_TRUE(host); |
+ |
+ ShadowRootInit init; |
+ init.setMode("open"); |
+ ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
+ ASSERT_TRUE(shadowRoot); |
+ |
+ shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>", ASSERT_NO_EXCEPTION); |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ unsigned beforeCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host-context(.nomatch) .a { background: green}"), RuleSetInvalidationsScheduled); |
+ document().view()->updateAllLifecyclePhases(); |
+ unsigned afterCount = styleEngine().styleForElementCount(); |
+ EXPECT_EQ(1u, afterCount - beforeCount); |
+ |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host-context(:hover) { background: green}"), RuleSetInvalidationFullRecalc); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ":host-context(#host) { background: green}"), RuleSetInvalidationFullRecalc); |
+} |
+ |
+TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) |
+{ |
+ document().body()->setInnerHTML("<div id=host></div>", ASSERT_NO_EXCEPTION); |
+ Element* host = document().getElementById("host"); |
+ ASSERT_TRUE(host); |
+ |
+ ShadowRootInit init; |
+ init.setMode("open"); |
+ ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
+ ASSERT_TRUE(shadowRoot); |
+ |
+ shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>", ASSERT_NO_EXCEPTION); |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ".a ::content span { background: green}"), RuleSetInvalidationFullRecalc); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ".a /deep/ span { background: green}"), RuleSetInvalidationFullRecalc); |
+ EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot, ".a::shadow span { background: green}"), RuleSetInvalidationFullRecalc); |
+} |
+ |
} // namespace blink |