Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/ContainerNode.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
| index c84626d91ccac8d02a52fa3d09eb7c94405555da..1a3e229a1735ec79870d4707836d791a27679877 100644 |
| --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
| +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
| @@ -588,7 +588,7 @@ void ContainerNode::removeChildren(SubtreeModificationAction action) |
| } |
| } |
| - ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenChangeSourceAPI}; |
| + ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, nullptr, ChildrenChangeSourceAPI}; |
| childrenChanged(change); |
| } |
| @@ -1216,7 +1216,7 @@ void ContainerNode::recalcChildStyle(StyleRecalcChange change) |
| } |
| } |
| -void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Node* nodeBeforeChange, Node* nodeAfterChange) |
| +void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Node* changedNode, Node* nodeBeforeChange, Node* nodeAfterChange) |
| { |
| if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || getStyleChangeType() >= SubtreeStyleChange) |
| return; |
| @@ -1229,7 +1229,7 @@ void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod |
| // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to. |
| // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids |
| // here. recalcStyle will then force a walk of the children when it sees that this has happened. |
| - if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndirectAdjacentRules()) && nodeAfterChange) |
| + if ((childrenAffectedByForwardPositionalRules() && nodeAfterChange) |
| || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { |
| setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
|
esprehn
2016/06/29 04:52:08
We need to figure out how to kill all of these Sub
rune
2016/06/29 07:44:21
crbug.com/624277
|
| return; |
| @@ -1278,13 +1278,27 @@ void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod |
| lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
| } |
| - // The + selector. We need to invalidate the first element following the change. It is the only possible element |
| - // that could be affected by this DOM change. |
| - if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { |
| - Element* elementAfterChange = nodeAfterChange->isElementNode() ? toElement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); |
| - for (unsigned i = document().styleEngine().maxDirectAdjacentSelectors(); i && elementAfterChange; --i, elementAfterChange = ElementTraversal::nextSibling(*elementAfterChange)) |
| - elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
| - } |
| + // For ~ and + combinators, succeeding siblings may need style invalidation |
| + // after an element is inserted or removed. |
| + |
| + if (!nodeAfterChange) |
| + return; |
| + if (changeType != SiblingElementRemoved && changeType != SiblingElementInserted) |
| + return; |
| + if (!childrenAffectedByIndirectAdjacentRules() && !childrenAffectedByDirectAdjacentRules()) |
| + return; |
| + |
| + Element* elementAfterChange = nodeAfterChange->isElementNode() ? toElement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); |
| + if (!elementAfterChange) |
| + return; |
| + Element* elementBeforeChange = nullptr; |
| + if (nodeBeforeChange) |
| + elementBeforeChange = nodeBeforeChange->isElementNode() ? toElement(nodeBeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); |
| + |
| + if (changeType == SiblingElementInserted) |
| + document().styleEngine().scheduleInvalidationsForInsertedSibling(elementBeforeChange, *toElement(changedNode)); |
| + else |
| + document().styleEngine().scheduleInvalidationsForRemovedSibling(elementBeforeChange, *toElement(changedNode), *elementAfterChange); |
| } |
| void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement) |