| 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 <memory> |
| 8 #include "bindings/core/v8/V8Binding.h" |
| 7 #include "core/css/CSSRuleList.h" | 9 #include "core/css/CSSRuleList.h" |
| 8 #include "core/css/CSSStyleRule.h" | 10 #include "core/css/CSSStyleRule.h" |
| 9 #include "core/css/CSSStyleSheet.h" | 11 #include "core/css/CSSStyleSheet.h" |
| 10 #include "core/css/StyleSheetContents.h" | 12 #include "core/css/StyleSheetContents.h" |
| 11 #include "core/css/parser/CSSParserContext.h" | 13 #include "core/css/parser/CSSParserContext.h" |
| 12 #include "core/dom/Document.h" | 14 #include "core/dom/Document.h" |
| 13 #include "core/dom/NodeComputedStyle.h" | 15 #include "core/dom/NodeComputedStyle.h" |
| 14 #include "core/dom/shadow/ShadowRootInit.h" | 16 #include "core/dom/shadow/ShadowRootInit.h" |
| 15 #include "core/frame/FrameView.h" | 17 #include "core/frame/FrameView.h" |
| 16 #include "core/html/HTMLElement.h" | 18 #include "core/html/HTMLElement.h" |
| 17 #include "core/html/HTMLStyleElement.h" | 19 #include "core/html/HTMLStyleElement.h" |
| 18 #include "core/testing/DummyPageHolder.h" | 20 #include "core/testing/DummyPageHolder.h" |
| 19 #include "platform/heap/Heap.h" | 21 #include "platform/heap/Heap.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include <memory> | |
| 22 | 23 |
| 23 namespace blink { | 24 namespace blink { |
| 24 | 25 |
| 25 class StyleEngineTest : public ::testing::Test { | 26 class StyleEngineTest : public ::testing::Test { |
| 26 protected: | 27 protected: |
| 27 void SetUp() override; | 28 void SetUp() override; |
| 28 | 29 |
| 29 Document& document() { return m_dummyPageHolder->document(); } | 30 Document& document() { return m_dummyPageHolder->document(); } |
| 30 StyleEngine& styleEngine() { return document().styleEngine(); } | 31 StyleEngine& styleEngine() { return document().styleEngine(); } |
| 31 | 32 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } | 203 } |
| 203 | 204 |
| 204 TEST_F(StyleEngineTest, RuleSetInvalidationHost) { | 205 TEST_F(StyleEngineTest, RuleSetInvalidationHost) { |
| 205 document().body()->setInnerHTML("<div id=nohost></div><div id=host></div>"); | 206 document().body()->setInnerHTML("<div id=nohost></div><div id=host></div>"); |
| 206 Element* host = document().getElementById("host"); | 207 Element* host = document().getElementById("host"); |
| 207 ASSERT_TRUE(host); | 208 ASSERT_TRUE(host); |
| 208 | 209 |
| 209 ShadowRootInit init; | 210 ShadowRootInit init; |
| 210 init.setMode("open"); | 211 init.setMode("open"); |
| 211 ShadowRoot* shadowRoot = host->attachShadow( | 212 ShadowRoot* shadowRoot = host->attachShadow( |
| 212 ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); | 213 toScriptStateForMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
| 213 ASSERT_TRUE(shadowRoot); | 214 ASSERT_TRUE(shadowRoot); |
| 214 | 215 |
| 215 shadowRoot->setInnerHTML("<div></div><div></div><div></div>"); | 216 shadowRoot->setInnerHTML("<div></div><div></div><div></div>"); |
| 216 document().view()->updateAllLifecyclePhases(); | 217 document().view()->updateAllLifecyclePhases(); |
| 217 | 218 |
| 218 unsigned beforeCount = styleEngine().styleForElementCount(); | 219 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 219 EXPECT_EQ(scheduleInvalidationsForRules( | 220 EXPECT_EQ(scheduleInvalidationsForRules( |
| 220 *shadowRoot, ":host(#nohost), #nohost { background: green}"), | 221 *shadowRoot, ":host(#nohost), #nohost { background: green}"), |
| 221 RuleSetInvalidationsScheduled); | 222 RuleSetInvalidationsScheduled); |
| 222 document().view()->updateAllLifecyclePhases(); | 223 document().view()->updateAllLifecyclePhases(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 247 " <span class=s1></span>" | 248 " <span class=s1></span>" |
| 248 " <span></span>" | 249 " <span></span>" |
| 249 "</div>"); | 250 "</div>"); |
| 250 | 251 |
| 251 Element* host = document().getElementById("host"); | 252 Element* host = document().getElementById("host"); |
| 252 ASSERT_TRUE(host); | 253 ASSERT_TRUE(host); |
| 253 | 254 |
| 254 ShadowRootInit init; | 255 ShadowRootInit init; |
| 255 init.setMode("open"); | 256 init.setMode("open"); |
| 256 ShadowRoot* shadowRoot = host->attachShadow( | 257 ShadowRoot* shadowRoot = host->attachShadow( |
| 257 ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); | 258 toScriptStateForMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
| 258 ASSERT_TRUE(shadowRoot); | 259 ASSERT_TRUE(shadowRoot); |
| 259 | 260 |
| 260 shadowRoot->setInnerHTML("<slot name=other></slot><slot></slot>"); | 261 shadowRoot->setInnerHTML("<slot name=other></slot><slot></slot>"); |
| 261 document().view()->updateAllLifecyclePhases(); | 262 document().view()->updateAllLifecyclePhases(); |
| 262 | 263 |
| 263 unsigned beforeCount = styleEngine().styleForElementCount(); | 264 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 264 EXPECT_EQ(scheduleInvalidationsForRules( | 265 EXPECT_EQ(scheduleInvalidationsForRules( |
| 265 *shadowRoot, "::slotted(.s1) { background: green}"), | 266 *shadowRoot, "::slotted(.s1) { background: green}"), |
| 266 RuleSetInvalidationsScheduled); | 267 RuleSetInvalidationsScheduled); |
| 267 document().view()->updateAllLifecyclePhases(); | 268 document().view()->updateAllLifecyclePhases(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 278 } | 279 } |
| 279 | 280 |
| 280 TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) { | 281 TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) { |
| 281 document().body()->setInnerHTML("<div id=host></div>"); | 282 document().body()->setInnerHTML("<div id=host></div>"); |
| 282 Element* host = document().getElementById("host"); | 283 Element* host = document().getElementById("host"); |
| 283 ASSERT_TRUE(host); | 284 ASSERT_TRUE(host); |
| 284 | 285 |
| 285 ShadowRootInit init; | 286 ShadowRootInit init; |
| 286 init.setMode("open"); | 287 init.setMode("open"); |
| 287 ShadowRoot* shadowRoot = host->attachShadow( | 288 ShadowRoot* shadowRoot = host->attachShadow( |
| 288 ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); | 289 toScriptStateForMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
| 289 ASSERT_TRUE(shadowRoot); | 290 ASSERT_TRUE(shadowRoot); |
| 290 | 291 |
| 291 shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>"); | 292 shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>"); |
| 292 document().view()->updateAllLifecyclePhases(); | 293 document().view()->updateAllLifecyclePhases(); |
| 293 | 294 |
| 294 unsigned beforeCount = styleEngine().styleForElementCount(); | 295 unsigned beforeCount = styleEngine().styleForElementCount(); |
| 295 EXPECT_EQ(scheduleInvalidationsForRules( | 296 EXPECT_EQ(scheduleInvalidationsForRules( |
| 296 *shadowRoot, ":host-context(.nomatch) .a { background: green}"), | 297 *shadowRoot, ":host-context(.nomatch) .a { background: green}"), |
| 297 RuleSetInvalidationsScheduled); | 298 RuleSetInvalidationsScheduled); |
| 298 document().view()->updateAllLifecyclePhases(); | 299 document().view()->updateAllLifecyclePhases(); |
| 299 unsigned afterCount = styleEngine().styleForElementCount(); | 300 unsigned afterCount = styleEngine().styleForElementCount(); |
| 300 EXPECT_EQ(1u, afterCount - beforeCount); | 301 EXPECT_EQ(1u, afterCount - beforeCount); |
| 301 | 302 |
| 302 EXPECT_EQ(scheduleInvalidationsForRules( | 303 EXPECT_EQ(scheduleInvalidationsForRules( |
| 303 *shadowRoot, ":host-context(:hover) { background: green}"), | 304 *shadowRoot, ":host-context(:hover) { background: green}"), |
| 304 RuleSetInvalidationFullRecalc); | 305 RuleSetInvalidationFullRecalc); |
| 305 EXPECT_EQ(scheduleInvalidationsForRules( | 306 EXPECT_EQ(scheduleInvalidationsForRules( |
| 306 *shadowRoot, ":host-context(#host) { background: green}"), | 307 *shadowRoot, ":host-context(#host) { background: green}"), |
| 307 RuleSetInvalidationFullRecalc); | 308 RuleSetInvalidationFullRecalc); |
| 308 } | 309 } |
| 309 | 310 |
| 310 TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) { | 311 TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) { |
| 311 document().body()->setInnerHTML("<div id=host></div>"); | 312 document().body()->setInnerHTML("<div id=host></div>"); |
| 312 Element* host = document().getElementById("host"); | 313 Element* host = document().getElementById("host"); |
| 313 ASSERT_TRUE(host); | 314 ASSERT_TRUE(host); |
| 314 | 315 |
| 315 ShadowRootInit init; | 316 ShadowRootInit init; |
| 316 init.setMode("open"); | 317 init.setMode("open"); |
| 317 ShadowRoot* shadowRoot = host->attachShadow( | 318 ShadowRoot* shadowRoot = host->attachShadow( |
| 318 ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); | 319 toScriptStateForMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
| 319 ASSERT_TRUE(shadowRoot); | 320 ASSERT_TRUE(shadowRoot); |
| 320 | 321 |
| 321 shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>"); | 322 shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>"); |
| 322 document().view()->updateAllLifecyclePhases(); | 323 document().view()->updateAllLifecyclePhases(); |
| 323 | 324 |
| 324 EXPECT_EQ(scheduleInvalidationsForRules( | 325 EXPECT_EQ(scheduleInvalidationsForRules( |
| 325 *shadowRoot, ".a ::content span { background: green}"), | 326 *shadowRoot, ".a ::content span { background: green}"), |
| 326 RuleSetInvalidationFullRecalc); | 327 RuleSetInvalidationFullRecalc); |
| 327 EXPECT_EQ(scheduleInvalidationsForRules( | 328 EXPECT_EQ(scheduleInvalidationsForRules( |
| 328 *shadowRoot, ".a /deep/ span { background: green}"), | 329 *shadowRoot, ".a /deep/ span { background: green}"), |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 525 |
| 525 TEST_F(StyleEngineTest, NoScheduledRuleSetInvalidationsOnNewShadow) { | 526 TEST_F(StyleEngineTest, NoScheduledRuleSetInvalidationsOnNewShadow) { |
| 526 document().body()->setInnerHTML("<div id='host'></div>"); | 527 document().body()->setInnerHTML("<div id='host'></div>"); |
| 527 Element* host = document().getElementById("host"); | 528 Element* host = document().getElementById("host"); |
| 528 ASSERT_TRUE(host); | 529 ASSERT_TRUE(host); |
| 529 | 530 |
| 530 document().view()->updateAllLifecyclePhases(); | 531 document().view()->updateAllLifecyclePhases(); |
| 531 ShadowRootInit init; | 532 ShadowRootInit init; |
| 532 init.setMode("open"); | 533 init.setMode("open"); |
| 533 ShadowRoot* shadowRoot = host->attachShadow( | 534 ShadowRoot* shadowRoot = host->attachShadow( |
| 534 ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); | 535 toScriptStateForMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION); |
| 535 ASSERT_TRUE(shadowRoot); | 536 ASSERT_TRUE(shadowRoot); |
| 536 | 537 |
| 537 shadowRoot->setInnerHTML( | 538 shadowRoot->setInnerHTML( |
| 538 "<style>" | 539 "<style>" |
| 539 " span { color: green }" | 540 " span { color: green }" |
| 540 " t1 { color: green }" | 541 " t1 { color: green }" |
| 541 "</style>" | 542 "</style>" |
| 542 "<div id='t1'></div>" | 543 "<div id='t1'></div>" |
| 543 "<span></span>"); | 544 "<span></span>"); |
| 544 | 545 |
| 545 styleEngine().updateActiveStyle(); | 546 styleEngine().updateActiveStyle(); |
| 546 EXPECT_FALSE(document().childNeedsStyleInvalidation()); | 547 EXPECT_FALSE(document().childNeedsStyleInvalidation()); |
| 547 EXPECT_FALSE(document().needsStyleInvalidation()); | 548 EXPECT_FALSE(document().needsStyleInvalidation()); |
| 548 } | 549 } |
| 549 | 550 |
| 550 } // namespace blink | 551 } // namespace blink |
| OLD | NEW |