| Index: third_party/WebKit/Source/core/dom/Document.cpp
|
| diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
|
| index 4ba216fdc155a192f52295d013dd8ba229258402..5c68fc3d5fee8e2c06b5f31a64ede8b600c2dce1 100644
|
| --- a/third_party/WebKit/Source/core/dom/Document.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/Document.cpp
|
| @@ -2156,22 +2156,57 @@ void Document::notifyLayoutTreeOfSubtreeChanges() {
|
| }
|
|
|
| bool Document::needsLayoutTreeUpdateForNode(const Node& node) const {
|
| - if (!node.canParticipateInFlatTree())
|
| - return false;
|
| if (!needsLayoutTreeUpdate())
|
| return false;
|
| if (!node.isConnected())
|
| return false;
|
|
|
| + // Elements that are not distributed can still have a style, for example a
|
| + // <slot> can still be styled, but LayoutTreeBuilder::parent DCHECKs on
|
| + // things outside the flat tree, so we instead disable this optimization.
|
| + if (!node.canParticipateInFlatTree())
|
| + return true;
|
| +
|
| if (needsFullLayoutTreeUpdate() || node.needsStyleRecalc() ||
|
| node.needsStyleInvalidation())
|
| return true;
|
| - for (const ContainerNode* ancestor = LayoutTreeBuilderTraversal::parent(node);
|
| - ancestor; ancestor = LayoutTreeBuilderTraversal::parent(*ancestor)) {
|
| +
|
| + const ContainerNode* deepestParent = LayoutTreeBuilderTraversal::parent(node);
|
| +
|
| + // If we're not distributed anywhere we need our style recomputed always.
|
| + if (!deepestParent)
|
| + return true;
|
| +
|
| + for (const ContainerNode* ancestor = deepestParent; ancestor;
|
| + ancestor = LayoutTreeBuilderTraversal::parent(*ancestor)) {
|
| if (ancestor->needsStyleRecalc() || ancestor->needsStyleInvalidation() ||
|
| ancestor->needsAdjacentStyleRecalc())
|
| return true;
|
| }
|
| +
|
| + ShadowRoot* scope = node.containingShadowRoot();
|
| + if (!scope)
|
| + return false;
|
| +
|
| + // Traverse up the scopes from the node to the root checking for bits, we
|
| + // need to do this since the LayoutTreeBuilder::parent walk above skips all
|
| + // shadow roots.
|
| + for (const ShadowRoot* root = scope; root;
|
| + root = root->host().containingShadowRoot()) {
|
| + if (root->needsStyleRecalc() || root->needsStyleInvalidation() ||
|
| + root->needsAdjacentStyleRecalc())
|
| + return true;
|
| + }
|
| +
|
| + // Traverse from the location where we were distributed up until we hit the
|
| + // scope that owns the node itself which we checked above.
|
| + for (const ShadowRoot* root = deepestParent->containingShadowRoot();
|
| + root && root != scope; root = root->host().containingShadowRoot()) {
|
| + if (root->needsStyleRecalc() || root->needsStyleInvalidation() ||
|
| + root->needsAdjacentStyleRecalc())
|
| + return true;
|
| + }
|
| +
|
| return false;
|
| }
|
|
|
|
|