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 db587b430b914da1dccc41d3b4bb4ab662bf1d91..5a8234f78c6d62ba9174299af32983936c7e7d88 100644 |
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
@@ -46,6 +46,7 @@ |
#include "core/frame/Settings.h" |
#include "core/html/HTMLIFrameElement.h" |
#include "core/html/HTMLLinkElement.h" |
+#include "core/html/HTMLSlotElement.h" |
#include "core/html/imports/HTMLImportsController.h" |
#include "core/inspector/InspectorInstrumentation.h" |
#include "core/page/Page.h" |
@@ -759,6 +760,73 @@ void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) |
m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, nthParent); |
} |
+void StyleEngine::scheduleRuleSetInvalidationsForElement(Element& element, const HeapVector<Member<const RuleSet>>& ruleSets) |
+{ |
+ AtomicString id; |
+ const SpaceSplitString* classNames = nullptr; |
+ bool typeSelectorMatch = false; |
+ |
+ if (element.hasID()) |
+ id = element.idForStyleResolution(); |
+ if (element.hasClass()) |
+ classNames = &element.classNames(); |
+ |
+ InvalidationLists invalidationLists; |
+ for (const auto& ruleSet : ruleSets) { |
+ if (!id.isNull()) |
+ ruleSet->features().collectInvalidationSetsForId(invalidationLists, element, id); |
+ if (classNames) { |
+ unsigned classNameCount = classNames->size(); |
+ for (size_t i = 0; i < classNameCount; i++) |
+ ruleSet->features().collectInvalidationSetsForClass(invalidationLists, element, (*classNames)[i]); |
+ } |
+ for (const Attribute& attribute : element.attributes()) |
+ ruleSet->features().collectInvalidationSetsForAttribute(invalidationLists, element, attribute.name()); |
+ |
+ if (element.needsStyleRecalc()) |
+ continue; |
+ |
+ if (!typeSelectorMatch && ruleSet->tagRules(element.localNameForSelectorMatching())) { |
+ typeSelectorMatch = true; |
+ element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange)); |
Eric Willigers
2016/09/13 01:22:03
element.needsStyleRecalc() becomes true, so typeSe
rune
2016/09/13 13:13:53
The needsStyleRecalc() is actually wrong, since it
|
+ } |
+ } |
+ m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); |
+} |
+ |
+void StyleEngine::scheduleInvalidationsForRuleSets(TreeScope& treeScope, const HeapVector<Member<const RuleSet>>& ruleSets) |
+{ |
+#if DCHECK_IS_ON() |
+ // Full scope recalcs should be handled while collecting the ruleSets before |
+ // calling this method. |
+ for (auto ruleSet : ruleSets) |
+ DCHECK(!ruleSet->features().needsFullRecalcForRuleSetInvalidation()); |
+#endif // DCHECK_IS_ON() |
+ |
+ if (treeScope.rootNode().isShadowRoot()) { |
+ Element& host = toShadowRoot(treeScope.rootNode()).host(); |
+ scheduleRuleSetInvalidationsForElement(host, ruleSets); |
+ if (host.getStyleChangeType() >= SubtreeStyleChange) |
+ return; |
+ } |
+ |
+ Node* stayWithin = &treeScope.rootNode(); |
+ Element* element = ElementTraversal::firstChild(*stayWithin); |
+ while (element) { |
+ scheduleRuleSetInvalidationsForElement(*element, ruleSets); |
+ if (isHTMLSlotElement(element)) { |
+ for (auto& node : toHTMLSlotElement(element)->getDistributedNodes()) { |
+ if (node->isElementNode()) |
+ scheduleRuleSetInvalidationsForElement(*toElement(node), ruleSets); |
+ } |
+ } |
+ if (element->getStyleChangeType() < SubtreeStyleChange) |
+ element = ElementTraversal::next(*element, stayWithin); |
+ else |
+ element = ElementTraversal::nextSkippingChildren(*element, stayWithin); |
+ } |
+} |
+ |
void StyleEngine::setStatsEnabled(bool enabled) |
{ |
if (!enabled) { |