Index: third_party/WebKit/Source/core/dom/StyleEngine.cpp |
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
index b7cccd69a0808c85471a3698915ce9c4f613368e..6a0b92239da42b36fdf75464c5f48252344e4d82 100644 |
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
@@ -37,6 +37,7 @@ |
#include "core/css/resolver/ScopedStyleResolver.h" |
#include "core/dom/DocumentStyleSheetCollector.h" |
#include "core/dom/Element.h" |
+#include "core/dom/ElementTraversal.h" |
#include "core/dom/ProcessingInstruction.h" |
#include "core/dom/ShadowTreeStyleSheetCollection.h" |
#include "core/dom/StyleChangeReason.h" |
@@ -690,6 +691,56 @@ void StyleEngine::pseudoStateChangedForElement(CSSSelector::PseudoType pseudoTyp |
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); |
} |
+void StyleEngine::scheduleSiblingInvalidationsForElement(Element& element, Element& schedulingElement, unsigned minDirectAdjacent, bool invalidateSchedulingElement) |
+{ |
+ InvalidationLists invalidationLists; |
+ |
+ RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet(); |
+ |
+ if (element.hasID()) |
+ ruleFeatureSet.collectSiblingInvalidationSetForId(invalidationLists, element, element.idForStyleResolution(), minDirectAdjacent); |
+ |
+ if (element.hasClass()) { |
+ const SpaceSplitString& classNames = element.classNames(); |
+ for (size_t i = 0; i < classNames.size(); i++) |
+ ruleFeatureSet.collectSiblingInvalidationSetForClass(invalidationLists, element, classNames[i], minDirectAdjacent); |
+ } |
+ |
+ for (const Attribute& attribute : element.attributes()) |
+ ruleFeatureSet.collectSiblingInvalidationSetForAttribute(invalidationLists, element, attribute.name(), minDirectAdjacent); |
+ |
+ ruleFeatureSet.collectUniversalSiblingInvalidationSet(invalidationLists, minDirectAdjacent); |
+ |
+ m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, schedulingElement); |
+ if (invalidateSchedulingElement) |
+ m_styleInvalidator.scheduleDescendantsFromSiblingSets(schedulingElement, invalidationLists.siblings); |
+} |
+ |
+void StyleEngine::scheduleInvalidationsForInsertedSibling(Element* beforeElement, Element& insertedElement) |
+{ |
+ unsigned affectedSiblings = insertedElement.parentNode()->childrenAffectedByIndirectAdjacentRules() ? UINT_MAX : m_maxDirectAdjacentSelectors; |
+ |
+ scheduleSiblingInvalidationsForElement(insertedElement, insertedElement, 1, false); |
+ |
+ Element* schedulingElement = &insertedElement; |
+ for (unsigned i = 1; beforeElement && i <= affectedSiblings; i++, beforeElement = ElementTraversal::previousSibling(*(schedulingElement = beforeElement))) |
+ scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingElement, i, false); |
+} |
+ |
+void StyleEngine::scheduleInvalidationsForRemovedSibling(Element* beforeElement, Element& removedElement, Element& afterElement) |
+{ |
+ unsigned affectedSiblings = afterElement.parentNode()->childrenAffectedByIndirectAdjacentRules() ? UINT_MAX : m_maxDirectAdjacentSelectors; |
+ |
+ Element* schedulingElement = beforeElement; |
+ if (!schedulingElement) |
+ schedulingElement = &afterElement; |
+ |
+ scheduleSiblingInvalidationsForElement(removedElement, *schedulingElement, 1, schedulingElement == &afterElement); |
+ |
+ for (unsigned i = 2; beforeElement && i <= affectedSiblings; i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) |
+ scheduleSiblingInvalidationsForElement(*beforeElement, *beforeElement, i, false); |
+} |
+ |
void StyleEngine::setStatsEnabled(bool enabled) |
{ |
if (!enabled) { |
@@ -702,6 +753,24 @@ void StyleEngine::setStatsEnabled(bool enabled) |
m_styleResolverStats->reset(); |
} |
+void StyleEngine::willRemoveChild(Node& child) |
+{ |
+ if (!child.needsStyleInvalidation()) |
+ return; |
+ if (!child.isElementNode()) |
+ return; |
+ if (!child.inShadowIncludingDocument()) |
+ return; |
+ |
+ Element* elementTo = ElementTraversal::previousSibling(child); |
+ bool invalidateElementTo = !elementTo; |
+ if (!elementTo) |
+ elementTo = ElementTraversal::nextSibling(child); |
+ if (!elementTo) |
+ return; |
+ styleInvalidator().rescheduleSiblingInvalidationSetsForRemovedElement(toElement(child), *elementTo, invalidateElementTo); |
+} |
+ |
void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name) |
{ |
if (!m_preferredStylesheetSetName.isEmpty()) |