Commit 913382f3 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Don't always force recalc for getComputedStyle in shadow trees.

We used to force clean style and layout tree getComputedStyle queries to
elements inside shadow trees. This was because the traversal in
Document::NeedsLayoutTreeUpdateForNode() skipped slots and shadow roots.
Now that slots are included in the flat tree, we can simply add checks
for shadow roots walking up the flat tree.

TEST=fast/dom/shadow/sibling-rules-under-shadow-root.html

Bug: 704421
Change-Id: Iee46f326ea96c0a4fad3e09b7784cf86d1dcdc85
Reviewed-on: https://chromium-review.googlesource.com/950042
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542386}
parent 4ee6ee15
......@@ -1674,6 +1674,7 @@ jumbo_source_set("unit_tests") {
"css/ActiveStyleSheetsTest.cpp",
"css/AffectedByPseudoTest.cpp",
"css/CSSCalculationValueTest.cpp",
"css/CSSComputedStyleDeclarationTest.cpp",
"css/CSSFontFaceSourceTest.cpp",
"css/CSSGradientValueTest.cpp",
"css/CSSPageRuleTest.cpp",
......
......@@ -361,10 +361,7 @@ const CSSValue* CSSComputedStyleDeclaration::GetPropertyCSSValue(
LayoutObject* layout_object = StyledLayoutObject();
const ComputedStyle* style = ComputeComputedStyle();
// TODO(futhark@chromium.org): IsInShadowTree() should not be necessary here.
// See http://crbug.com/704421
if (property_class.IsLayoutDependent(style, layout_object) ||
styled_node->IsInShadowTree()) {
if (property_class.IsLayoutDependent(style, layout_object)) {
document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(styled_node);
styled_node = StyledNode();
style = ComputeComputedStyle();
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/ShadowRoot.h"
#include "core/html/HTMLElement.h"
#include "core/testing/PageTestBase.h"
namespace blink {
class CSSComputedStyleDeclarationTest : public PageTestBase {};
TEST_F(CSSComputedStyleDeclarationTest, CleanAncestorsNoRecalc) {
GetDocument().body()->SetInnerHTMLFromString(R"HTML(
<div id=dirty></div>
<div>
<div id=target style='color:green'></div>
</div>
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FALSE(GetDocument().NeedsLayoutTreeUpdate());
GetDocument().getElementById("dirty")->setAttribute("style", "color:pink");
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
Element* target = GetDocument().getElementById("target");
CSSComputedStyleDeclaration* computed =
CSSComputedStyleDeclaration::Create(target);
EXPECT_STREQ("rgb(0, 128, 0)",
computed->GetPropertyValue(CSSPropertyColor).Utf8().data());
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
}
TEST_F(CSSComputedStyleDeclarationTest, CleanShadowAncestorsNoRecalc) {
GetDocument().body()->SetInnerHTMLFromString(R"HTML(
<div id=dirty></div>
<div id=host></div>
)HTML");
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
shadow_root.SetInnerHTMLFromString(R"HTML(
<div id=target style='color:green'></div>
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FALSE(GetDocument().NeedsLayoutTreeUpdate());
GetDocument().getElementById("dirty")->setAttribute("style", "color:pink");
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
Element* target = shadow_root.getElementById("target");
CSSComputedStyleDeclaration* computed =
CSSComputedStyleDeclaration::Create(target);
EXPECT_STREQ("rgb(0, 128, 0)",
computed->GetPropertyValue(CSSPropertyColor).Utf8().data());
EXPECT_EQ(RuntimeEnabledFeatures::SlotInFlatTreeEnabled(),
GetDocument().NeedsLayoutTreeUpdate());
}
} // namespace blink
......@@ -2301,9 +2301,16 @@ bool Document::NeedsLayoutTreeUpdateForNode(const Node& node) const {
return true;
for (const ContainerNode* ancestor = LayoutTreeBuilderTraversal::Parent(node);
ancestor; ancestor = LayoutTreeBuilderTraversal::Parent(*ancestor)) {
if (ShadowRoot* root = ancestor->GetShadowRoot()) {
if (root->NeedsStyleRecalc() || root->NeedsStyleInvalidation() ||
root->NeedsAdjacentStyleRecalc()) {
return true;
}
}
if (ancestor->NeedsStyleRecalc() || ancestor->NeedsStyleInvalidation() ||
ancestor->NeedsAdjacentStyleRecalc())
ancestor->NeedsAdjacentStyleRecalc()) {
return true;
}
}
return false;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment