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

Side by Side Diff: Source/core/css/invalidation/StyleInvalidationTreeWalk.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: Move code around. 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
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/StyleInvalidationTreeWalk.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 StyleInvalidationTreeWalk::computeStyleInvalidation(Document& document, Rul eFeatureSet* featureSet)
20 {
21 if (Element* documentElement = document.documentElement()) {
22 if (documentElement->childNeedsStyleInvalidation())
23 StyleInvalidationTreeWalk(featureSet).invalidateStyle(documentElemen t);
24 }
25 document.clearChildNeedsStyleInvalidation();
26 document.clearNeedsStyleInvalidation();
27 featureSet->m_pendingInvalidationMap.clear();
28 }
29
30 StyleInvalidationTreeWalk::StyleInvalidationTreeWalk(const RuleFeatureSet* featu reSet)
31 : m_featureSet(featureSet)
32 {
33 }
34
35 void StyleInvalidationTreeWalk::RecursionData::pushInvalidationSet(const Descend antInvalidationSet& invalidationSet)
36 {
37 invalidationSet.getClasses(m_invalidationClasses);
38 m_foundInvalidationSet = true;
39 }
40
41 bool StyleInvalidationTreeWalk::RecursionData::matchesCurrentInvalidationSets(El ement* element)
esprehn 2014/03/19 22:09:04 This should be a method on the InvalidationSet its
chrishtr 2014/03/19 22:49:39 The problem with that is that this code operates o
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 StyleInvalidationTreeWalk::checkInvalidationSetsAgainstElement(Element* ele ment)
esprehn 2014/03/19 22:09:04 invalidateOwnStyle. These should match recalcStyl
chrishtr 2014/03/19 22:49:39 This method does not do a full invalidation. We do
56 {
57 bool thisElementNeedsStyleRecalc = false;
58 if (element->needsStyleInvalidation()) {
59 if (RuleFeatureSet::InvalidationList* invalidationList = m_featureSet->m _pendingInvalidationMap.get(element)) {
esprehn 2014/03/19 22:09:04 You should expose getters, don't reach into the me
chrishtr 2014/03/19 22:49:39 Done.
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 StyleInvalidationTreeWalk::invalidateStyleForChildren(Element* element)
esprehn 2014/03/19 22:09:04 invalidateChildrenStyle
chrishtr 2014/03/19 22:49:39 Done.
81 {
82 bool someChildrenNeedStyleRecalc = false;
83 for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->ol derShadowRoot()) {
84 for (Element* child = ElementTraversal::firstWithin(*root); child; child = ElementTraversal::nextSibling(*child)) {
85 bool childRecalced = invalidateStyle(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 = invalidateStyle(child);
93 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalc ed;
94 }
95 return someChildrenNeedStyleRecalc;
96 }
97
98 bool StyleInvalidationTreeWalk::invalidateStyle(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->childNeedsStyleInvali dation()) {
108 someChildrenNeedStyleRecalc = invalidateStyleForChildren(element);
109 }
esprehn 2014/03/19 22:09:04 extra braces
chrishtr 2014/03/19 22:49:39 Done.
110
111 if (thisElementNeedsStyleRecalc) {
112 element->setNeedsStyleRecalc(LocalStyleChange);
113 } else if (m_recursionData.foundInvalidationSet() && someChildrenNeedStyleRe calc) {
114 // Clone the RenderStyle in order to preserve correct style sharing, if possible. Otherwise recalc style.
115 if (RenderObject* renderer = element->renderer()) {
116 ASSERT(renderer->style());
117 renderer->setStyleInternal(RenderStyle::clone(renderer->style()));
118 } else {
119 element->setNeedsStyleRecalc(LocalStyleChange);
120 }
121 }
122
123 element->clearChildNeedsStyleInvalidation();
124 element->clearNeedsStyleInvalidation();
125
126 return thisElementNeedsStyleRecalc;
127 }
128
129 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698