Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: Source/core/css/invalidation/StyleInvalidator.cpp

Issue 204873003: Factor the style invalidation tree walk out of RuleFeatureSet, and make it generic. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added explicit. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/css/invalidation/StyleInvalidator.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 // Copyright 2014 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "config.h"
7
8 #include "core/css/invalidation/StyleInvalidator.h"
9
10 #include "core/dom/Document.h"
11 #include "core/dom/Element.h"
12 #include "core/dom/ElementTraversal.h"
13 #include "core/dom/shadow/ElementShadow.h"
14 #include "core/dom/shadow/ShadowRoot.h"
15 #include "core/rendering/RenderObject.h"
16
17 namespace WebCore {
18
19 void StyleInvalidator::invalidate()
20 {
21 if (Element* documentElement = m_document.documentElement()) {
22 if (documentElement->childNeedsStyleInvalidation())
23 invalidate(*documentElement);
24 }
25 m_document.clearChildNeedsStyleInvalidation();
26 m_document.clearNeedsStyleInvalidation();
27 m_pendingInvalidationMap.clear();
28 }
29
30 StyleInvalidator::StyleInvalidator(Document& document)
31 : m_document(document)
32 , m_pendingInvalidationMap(document.styleResolver()->ruleFeatureSet().pendin gInvalidationMap())
33 { }
34
35 void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvali dationSet& invalidationSet)
36 {
37 invalidationSet.getClasses(m_invalidationClasses);
38 m_foundInvalidationSet = true;
39 }
40
41 bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSets(Element& el ement)
42 {
43 if (!element.hasClass())
44 return false;
45
46 const SpaceSplitString& classNames = element.classNames();
47 for (Vector<AtomicString>::const_iterator it = m_invalidationClasses.begin() ; it != m_invalidationClasses.end(); ++it) {
48 if (classNames.contains(*it))
49 return true;
50 }
51
52 return false;
53 }
54
55 bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element& element)
56 {
57 bool thisElementNeedsStyleRecalc = false;
58 if (element.needsStyleInvalidation()) {
59 if (RuleFeatureSet::InvalidationList* invalidationList = m_pendingInvali dationMap.get(&element)) {
60 // FIXME: it's really only necessary to clone the render style for t his element, not full style recalc.
61 thisElementNeedsStyleRecalc = true;
62 for (RuleFeatureSet::InvalidationList::const_iterator it = invalidat ionList->begin(); it != invalidationList->end(); ++it) {
63 m_recursionData.pushInvalidationSet(**it);
64 if ((*it)->wholeSubtreeInvalid()) {
65 element.setNeedsStyleRecalc(SubtreeStyleChange);
66 // Even though we have set needsStyleRecalc on the whole sub tree, we need to keep walking over the subtree
67 // in order to clear the invalidation dirty bits on all elem ents.
68 // FIXME: we can optimize this by having a dedicated functio n that just traverses the tree and removes the dirty bits,
69 // without checking classes etc.
70 break;
71 }
72 }
73 }
74 }
75 if (!thisElementNeedsStyleRecalc)
76 thisElementNeedsStyleRecalc = m_recursionData.matchesCurrentInvalidation Sets(element);
77 return thisElementNeedsStyleRecalc;
78 }
79
80 bool StyleInvalidator::invalidateChildren(Element& element)
81 {
82 bool someChildrenNeedStyleRecalc = false;
83 for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->old erShadowRoot()) {
84 for (Element* child = ElementTraversal::firstWithin(*root); child; child = ElementTraversal::nextSibling(*child)) {
85 bool childRecalced = invalidate(*child);
86 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRe calced;
87 }
88 root->clearChildNeedsStyleInvalidation();
89 root->clearNeedsStyleInvalidation();
90 }
91 for (Element* child = ElementTraversal::firstWithin(element); child; child = ElementTraversal::nextSibling(*child)) {
92 bool childRecalced = invalidate(*child);
93 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalc ed;
94 }
95 return someChildrenNeedStyleRecalc;
96 }
97
98 bool StyleInvalidator::invalidate(Element& element)
99 {
100 RecursionCheckpoint checkpoint(&m_recursionData);
101
102 bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(eleme nt);
103
104 bool someChildrenNeedStyleRecalc = false;
105 // foundInvalidationSet() will be true if we are in a subtree of a node with a DescendantInvalidationSet on it.
106 // We need to check all nodes in the subtree of such a node.
107 if (m_recursionData.foundInvalidationSet() || element.childNeedsStyleInvalid ation())
108 someChildrenNeedStyleRecalc = invalidateChildren(element);
109
110 if (thisElementNeedsStyleRecalc) {
111 element.setNeedsStyleRecalc(LocalStyleChange);
112 } else if (m_recursionData.foundInvalidationSet() && someChildrenNeedStyleRe calc) {
113 // Clone the RenderStyle in order to preserve correct style sharing, if possible. Otherwise recalc style.
114 if (RenderObject* renderer = element.renderer()) {
115 ASSERT(renderer->style());
116 renderer->setStyleInternal(RenderStyle::clone(renderer->style()));
117 } else {
118 element.setNeedsStyleRecalc(LocalStyleChange);
119 }
120 }
121
122 element.clearChildNeedsStyleInvalidation();
123 element.clearNeedsStyleInvalidation();
124
125 return thisElementNeedsStyleRecalc;
126 }
127
128 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/css/invalidation/StyleInvalidator.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698