Chromium Code Reviews| 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) { |