OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/dom/StyleEngine.h" | 5 #include "core/dom/StyleEngine.h" |
6 | 6 |
7 #include "core/css/StyleSheetContents.h" | 7 #include "core/css/StyleSheetContents.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/NodeComputedStyle.h" | 9 #include "core/dom/NodeComputedStyle.h" |
| 10 #include "core/dom/shadow/ShadowRootInit.h" |
10 #include "core/frame/FrameView.h" | 11 #include "core/frame/FrameView.h" |
11 #include "core/html/HTMLElement.h" | 12 #include "core/html/HTMLElement.h" |
12 #include "core/html/HTMLStyleElement.h" | 13 #include "core/html/HTMLStyleElement.h" |
13 #include "core/testing/DummyPageHolder.h" | 14 #include "core/testing/DummyPageHolder.h" |
14 #include "platform/heap/Heap.h" | 15 #include "platform/heap/Heap.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 #include <memory> | 17 #include <memory> |
17 | 18 |
18 namespace blink { | 19 namespace blink { |
19 | 20 |
20 class StyleEngineTest : public ::testing::Test { | 21 class StyleEngineTest : public ::testing::Test { |
21 protected: | 22 protected: |
22 void SetUp() override; | 23 void SetUp() override; |
23 | 24 |
24 Document& document() { return m_dummyPageHolder->document(); } | 25 Document& document() { return m_dummyPageHolder->document(); } |
25 StyleEngine& styleEngine() { return document().styleEngine(); } | 26 StyleEngine& styleEngine() { return document().styleEngine(); } |
26 | 27 |
27 bool isDocumentStyleSheetCollectionClean() { return !styleEngine().shouldUpd
ateDocumentStyleSheetCollection(AnalyzedStyleUpdate); } | 28 bool isDocumentStyleSheetCollectionClean() { return !styleEngine().shouldUpd
ateDocumentStyleSheetCollection(AnalyzedStyleUpdate); } |
28 | 29 |
| 30 void scheduleInvalidationsForRules(TreeScope&, const String& cssText); |
| 31 |
29 private: | 32 private: |
30 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; | 33 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; |
31 }; | 34 }; |
32 | 35 |
33 void StyleEngineTest::SetUp() | 36 void StyleEngineTest::SetUp() |
34 { | 37 { |
35 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); | 38 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); |
36 } | 39 } |
37 | 40 |
| 41 void StyleEngineTest::scheduleInvalidationsForRules(TreeScope& treeScope, const
String& cssText) |
| 42 { |
| 43 StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(HTML
StandardMode, nullptr)); |
| 44 sheet->parseString(cssText); |
| 45 HeapVector<Member<const RuleSet>> ruleSets; |
| 46 RuleSet& ruleSet = sheet->ensureRuleSet(MediaQueryEvaluator(), RuleHasDocume
ntSecurityOrigin); |
| 47 ruleSet.compactRulesIfNeeded(); |
| 48 ruleSets.append(&ruleSet); |
| 49 styleEngine().scheduleInvalidationsForRuleSets(treeScope, ruleSets); |
| 50 } |
| 51 |
38 TEST_F(StyleEngineTest, DocumentDirtyAfterInject) | 52 TEST_F(StyleEngineTest, DocumentDirtyAfterInject) |
39 { | 53 { |
40 StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContex
t(document(), nullptr)); | 54 StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContex
t(document(), nullptr)); |
41 parsedSheet->parseString("div {}"); | 55 parsedSheet->parseString("div {}"); |
42 styleEngine().injectAuthorSheet(parsedSheet); | 56 styleEngine().injectAuthorSheet(parsedSheet); |
43 document().view()->updateAllLifecyclePhases(); | 57 document().view()->updateAllLifecyclePhases(); |
44 | 58 |
45 EXPECT_TRUE(isDocumentStyleSheetCollectionClean()); | 59 EXPECT_TRUE(isDocumentStyleSheetCollectionClean()); |
46 } | 60 } |
47 | 61 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 // Garbage collection should clear the weak reference in the StyleSheetConte
nts cache. | 109 // Garbage collection should clear the weak reference in the StyleSheetConte
nts cache. |
96 ThreadState::current()-> collectAllGarbage(); | 110 ThreadState::current()-> collectAllGarbage(); |
97 | 111 |
98 element = HTMLStyleElement::create(document(), false); | 112 element = HTMLStyleElement::create(document(), false); |
99 sheet1 = styleEngine().createSheet(element, sheetText, minPos, context); | 113 sheet1 = styleEngine().createSheet(element, sheetText, minPos, context); |
100 | 114 |
101 // Check that we did not use a cached StyleSheetContents after the garbage c
ollection. | 115 // Check that we did not use a cached StyleSheetContents after the garbage c
ollection. |
102 EXPECT_FALSE(sheet1->contents()->isUsedFromTextCache()); | 116 EXPECT_FALSE(sheet1->contents()->isUsedFromTextCache()); |
103 } | 117 } |
104 | 118 |
| 119 TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) |
| 120 { |
| 121 document().body()->setInnerHTML( |
| 122 "<div>" |
| 123 " <span></span>" |
| 124 " <div></div>" |
| 125 "</div>", ASSERT_NO_EXCEPTION); |
| 126 |
| 127 document().view()->updateAllLifecyclePhases(); |
| 128 |
| 129 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 130 |
| 131 scheduleInvalidationsForRules(document(), "span { background: green}"); |
| 132 document().view()->updateAllLifecyclePhases(); |
| 133 |
| 134 unsigned afterCount = styleEngine().styleForElementCount(); |
| 135 |
| 136 EXPECT_EQ(1u, afterCount - beforeCount); |
| 137 |
| 138 beforeCount = afterCount; |
| 139 scheduleInvalidationsForRules(document(), "body div { background: green}"); |
| 140 document().view()->updateAllLifecyclePhases(); |
| 141 |
| 142 afterCount = styleEngine().styleForElementCount(); |
| 143 |
| 144 EXPECT_EQ(2u, afterCount - beforeCount); |
| 145 } |
| 146 |
| 147 TEST_F(StyleEngineTest, RuleSetInvalidationHost) |
| 148 { |
| 149 document().body()->setInnerHTML("<div id=nohost></div><div id=host></div>",
ASSERT_NO_EXCEPTION); |
| 150 Element* host = document().getElementById("host"); |
| 151 ASSERT_TRUE(host); |
| 152 |
| 153 ShadowRootInit init; |
| 154 init.setMode("open"); |
| 155 ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(docume
nt().frame()), init, ASSERT_NO_EXCEPTION); |
| 156 ASSERT_TRUE(shadowRoot); |
| 157 |
| 158 shadowRoot->setInnerHTML("<div></div><div></div><div></div>", ASSERT_NO_EXCE
PTION); |
| 159 document().view()->updateAllLifecyclePhases(); |
| 160 |
| 161 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 162 scheduleInvalidationsForRules(*shadowRoot, ":host(#nohost), #nohost { backgr
ound: green}"); |
| 163 document().view()->updateAllLifecyclePhases(); |
| 164 unsigned afterCount = styleEngine().styleForElementCount(); |
| 165 EXPECT_EQ(0u, afterCount - beforeCount); |
| 166 |
| 167 beforeCount = afterCount; |
| 168 scheduleInvalidationsForRules(*shadowRoot, ":host(#host) { background: green
}"); |
| 169 document().view()->updateAllLifecyclePhases(); |
| 170 afterCount = styleEngine().styleForElementCount(); |
| 171 EXPECT_EQ(1u, afterCount - beforeCount); |
| 172 } |
| 173 |
| 174 TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) |
| 175 { |
| 176 document().body()->setInnerHTML( |
| 177 "<div id=host>" |
| 178 " <span slot=other class=s1></span>" |
| 179 " <span class=s2></span>" |
| 180 " <span class=s1></span>" |
| 181 " <span></span>" |
| 182 "</div>", ASSERT_NO_EXCEPTION); |
| 183 |
| 184 Element* host = document().getElementById("host"); |
| 185 ASSERT_TRUE(host); |
| 186 |
| 187 ShadowRootInit init; |
| 188 init.setMode("open"); |
| 189 ShadowRoot* shadowRoot = host->attachShadow(ScriptState::forMainWorld(docume
nt().frame()), init, ASSERT_NO_EXCEPTION); |
| 190 ASSERT_TRUE(shadowRoot); |
| 191 |
| 192 shadowRoot->setInnerHTML("<slot name=other></slot><slot></slot>", ASSERT_NO_
EXCEPTION); |
| 193 document().view()->updateAllLifecyclePhases(); |
| 194 |
| 195 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 196 scheduleInvalidationsForRules(*shadowRoot, "::slotted(.s1) { background: gre
en}"); |
| 197 document().view()->updateAllLifecyclePhases(); |
| 198 unsigned afterCount = styleEngine().styleForElementCount(); |
| 199 EXPECT_EQ(2u, afterCount - beforeCount); |
| 200 } |
| 201 |
105 } // namespace blink | 202 } // namespace blink |
OLD | NEW |