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

Side by Side Diff: Source/core/css/RuleFeature.cpp

Issue 199373003: Use LocalStyleChange for classes in rightmost compound selector. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/css/RuleFeature.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved.
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 case CSSSelector::PseudoUnresolved: 93 case CSSSelector::PseudoUnresolved:
94 return true; 94 return true;
95 default: 95 default:
96 return false; 96 return false;
97 } 97 }
98 ASSERT_NOT_REACHED(); 98 ASSERT_NOT_REACHED();
99 return false; 99 return false;
100 } 100 }
101 101
102 // This method is somewhat conservative in what it accepts. 102 // This method is somewhat conservative in what it accepts.
103 static bool supportsClassDescendantInvalidation(const CSSSelector& selector) 103 RuleFeatureSet::InvalidationMode RuleFeatureSet::supportsClassDescendantInvalida tion(const CSSSelector& selector)
104 { 104 {
105 bool foundDescendantRelation = false; 105 bool foundDescendantRelation = false;
106 bool foundIdent = false; 106 bool foundIdent = false;
107 for (const CSSSelector* component = &selector; component; component = compon ent->tagHistory()) { 107 for (const CSSSelector* component = &selector; component; component = compon ent->tagHistory()) {
108 108
109 // FIXME: We should allow pseudo elements, but we need to change how the y hook 109 // FIXME: We should allow pseudo elements, but we need to change how the y hook
110 // into recalcStyle by moving them to recalcOwnStyle instead of recalcCh ildStyle. 110 // into recalcStyle by moving them to recalcOwnStyle instead of recalcCh ildStyle.
111 111
112 // FIXME: next up: Tag and Id. 112 // FIXME: next up: Tag and Id.
113 if (component->m_match == CSSSelector::Class) { 113 if (component->m_match == CSSSelector::Class) {
114 if (!foundDescendantRelation) 114 if (!foundDescendantRelation)
115 foundIdent = true; 115 foundIdent = true;
116 } else if (!isSkippableComponentForInvalidation(*component)) { 116 } else if (!isSkippableComponentForInvalidation(*component)) {
117 return false; 117 return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeSty leChange;
118 } 118 }
119 // FIXME: We can probably support ShadowAll and ShadowDeep. 119 // FIXME: We can probably support ShadowAll and ShadowDeep.
120 switch (component->relation()) { 120 switch (component->relation()) {
121 case CSSSelector::Descendant: 121 case CSSSelector::Descendant:
122 case CSSSelector::Child: 122 case CSSSelector::Child:
123 foundDescendantRelation = true; 123 foundDescendantRelation = true;
124 // Fall through! 124 // Fall through!
125 case CSSSelector::SubSelector: 125 case CSSSelector::SubSelector:
126 continue; 126 continue;
127 default: 127 default:
128 return false; 128 return UseLocalStyleChange;
129 } 129 }
130 } 130 }
131 return foundIdent; 131 return foundIdent ? UseInvalidationSets : UseLocalStyleChange;
132 } 132 }
133 133
134 void extractClassIdOrTag(const CSSSelector& selector, Vector<AtomicString>& clas ses, AtomicString& id, AtomicString& tagName) 134 void extractClassIdOrTag(const CSSSelector& selector, Vector<AtomicString>& clas ses, AtomicString& id, AtomicString& tagName)
135 { 135 {
136 if (selector.m_match == CSSSelector::Tag) 136 if (selector.m_match == CSSSelector::Tag)
137 tagName = selector.tagQName().localName(); 137 tagName = selector.tagQName().localName();
138 else if (selector.m_match == CSSSelector::Id) 138 else if (selector.m_match == CSSSelector::Id)
139 id = selector.value(); 139 id = selector.value();
140 else if (selector.m_match == CSSSelector::Class) 140 else if (selector.m_match == CSSSelector::Class)
141 classes.append(selector.value()); 141 classes.append(selector.value());
142 } 142 }
143 143
144 RuleFeatureSet::RuleFeatureSet() 144 RuleFeatureSet::RuleFeatureSet()
145 : m_targetedStyleRecalcEnabled(RuntimeEnabledFeatures::targetedStyleRecalcEn abled()) 145 : m_targetedStyleRecalcEnabled(RuntimeEnabledFeatures::targetedStyleRecalcEn abled())
146 { 146 {
147 } 147 }
148 148
149 bool RuleFeatureSet::updateClassInvalidationSets(const CSSSelector& selector) 149 RuleFeatureSet::InvalidationMode RuleFeatureSet::updateClassInvalidationSets(con st CSSSelector& selector)
150 { 150 {
151 if (!supportsClassDescendantInvalidation(selector)) 151 InvalidationMode mode = supportsClassDescendantInvalidation(selector);
152 return false; 152 if (mode != UseInvalidationSets)
153 return mode;
153 154
154 Vector<AtomicString> classes; 155 Vector<AtomicString> classes;
155 AtomicString id; 156 AtomicString id;
156 AtomicString tagName; 157 AtomicString tagName;
157 158
158 const CSSSelector* lastSelector = &selector; 159 const CSSSelector* lastSelector = &selector;
159 for (; lastSelector; lastSelector = lastSelector->tagHistory()) { 160 for (; lastSelector; lastSelector = lastSelector->tagHistory()) {
160 extractClassIdOrTag(*lastSelector, classes, id, tagName); 161 extractClassIdOrTag(*lastSelector, classes, id, tagName);
161 if (lastSelector->m_match == CSSSelector::Class) 162 if (lastSelector->m_match == CSSSelector::Class)
162 ensureClassInvalidationSet(lastSelector->value()); 163 ensureClassInvalidationSet(lastSelector->value());
163 if (lastSelector->relation() != CSSSelector::SubSelector) 164 if (lastSelector->relation() != CSSSelector::SubSelector)
164 break; 165 break;
165 } 166 }
166 167
167 if (!lastSelector) 168 if (!lastSelector)
168 return true; 169 return UseInvalidationSets;
169 170
170 for (const CSSSelector* current = lastSelector->tagHistory(); current; curre nt = current->tagHistory()) { 171 for (const CSSSelector* current = lastSelector->tagHistory(); current; curre nt = current->tagHistory()) {
171 if (current->m_match == CSSSelector::Class) { 172 if (current->m_match == CSSSelector::Class) {
172 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); 173 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value());
173 if (!id.isEmpty()) 174 if (!id.isEmpty())
174 invalidationSet.addId(id); 175 invalidationSet.addId(id);
175 if (!tagName.isEmpty()) 176 if (!tagName.isEmpty())
176 invalidationSet.addTagName(tagName); 177 invalidationSet.addTagName(tagName);
177 for (Vector<AtomicString>::const_iterator it = classes.begin(); it ! = classes.end(); ++it) { 178 for (Vector<AtomicString>::const_iterator it = classes.begin(); it ! = classes.end(); ++it) {
178 invalidationSet.addClass(*it); 179 invalidationSet.addClass(*it);
179 } 180 }
180 } 181 }
181 } 182 }
182 return true; 183 return UseInvalidationSets;
183 } 184 }
184 185
185 void RuleFeatureSet::addAttributeInASelector(const AtomicString& attributeName) 186 void RuleFeatureSet::addAttributeInASelector(const AtomicString& attributeName)
186 { 187 {
187 m_metadata.attrsInRules.add(attributeName); 188 m_metadata.attrsInRules.add(attributeName);
188 } 189 }
189 190
190 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) 191 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
191 { 192 {
192 FeatureMetadata metadata; 193 FeatureMetadata metadata;
193 bool selectorUsesClassInvalidationSet = false; 194 InvalidationMode mode = UseSubtreeStyleChange;
194 if (m_targetedStyleRecalcEnabled) 195 if (m_targetedStyleRecalcEnabled)
195 selectorUsesClassInvalidationSet = updateClassInvalidationSets(ruleData. selector()); 196 mode = updateClassInvalidationSets(ruleData.selector());
196 197
197 SelectorFeatureCollectionMode collectionMode; 198 collectFeaturesFromSelector(ruleData.selector(), metadata, mode);
198 if (selectorUsesClassInvalidationSet)
199 collectionMode = DontProcessClasses;
200 else
201 collectionMode = ProcessClasses;
202 collectFeaturesFromSelector(ruleData.selector(), metadata, collectionMode);
203 m_metadata.add(metadata); 199 m_metadata.add(metadata);
204 200
205 if (metadata.foundSiblingSelector) 201 if (metadata.foundSiblingSelector)
206 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); 202 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin()));
207 if (ruleData.containsUncommonAttributeSelector()) 203 if (ruleData.containsUncommonAttributeSelector())
208 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); 204 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin()));
209 } 205 }
210 206
211 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className) 207 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className)
212 { 208 {
213 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr); 209 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr);
214 if (addResult.isNewEntry) 210 if (addResult.isNewEntry)
215 addResult.storedValue->value = DescendantInvalidationSet::create(); 211 addResult.storedValue->value = DescendantInvalidationSet::create();
216 return *addResult.storedValue->value; 212 return *addResult.storedValue->value;
217 } 213 }
218 214
219 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector) 215 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
220 { 216 {
221 collectFeaturesFromSelector(selector, m_metadata, ProcessClasses); 217 collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange);
222 } 218 }
223 219
224 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMode collectio nMode) 220 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata, InvalidationMode mode)
225 { 221 {
226 unsigned maxDirectAdjacentSelectors = 0; 222 unsigned maxDirectAdjacentSelectors = 0;
227 223
228 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 224 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
229 if (current->m_match == CSSSelector::Id) { 225 if (current->m_match == CSSSelector::Id) {
230 metadata.idsInRules.add(current->value()); 226 metadata.idsInRules.add(current->value());
231 } else if (current->m_match == CSSSelector::Class && collectionMode == P rocessClasses) { 227 } else if (current->m_match == CSSSelector::Class && mode != UseInvalida tionSets) {
esprehn 2014/03/13 23:28:13 This is confusing since you're saying "mode is not
rune 2014/03/14 13:01:19 Renamed now.
232 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); 228 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value());
233 invalidationSet.setWholeSubtreeInvalid(); 229 if (mode == UseSubtreeStyleChange)
230 invalidationSet.setWholeSubtreeInvalid();
234 } else if (current->isAttributeSelector()) { 231 } else if (current->isAttributeSelector()) {
235 metadata.attrsInRules.add(current->attribute().localName()); 232 metadata.attrsInRules.add(current->attribute().localName());
236 } 233 }
237 if (current->pseudoType() == CSSSelector::PseudoFirstLine) 234 if (current->pseudoType() == CSSSelector::PseudoFirstLine)
238 metadata.usesFirstLineRules = true; 235 metadata.usesFirstLineRules = true;
239 if (current->isDirectAdjacentSelector()) { 236 if (current->isDirectAdjacentSelector()) {
240 maxDirectAdjacentSelectors++; 237 maxDirectAdjacentSelectors++;
241 } else if (maxDirectAdjacentSelectors) { 238 } else if (maxDirectAdjacentSelectors) {
242 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors ) 239 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors )
243 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ; 240 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ;
244 maxDirectAdjacentSelectors = 0; 241 maxDirectAdjacentSelectors = 0;
245 } 242 }
246 if (current->isSiblingSelector()) 243 if (current->isSiblingSelector())
247 metadata.foundSiblingSelector = true; 244 metadata.foundSiblingSelector = true;
248 245
249 collectFeaturesFromSelectorList(current->selectorList(), metadata, colle ctionMode); 246 collectFeaturesFromSelectorList(current->selectorList(), metadata, mode) ;
247
248 if (mode == UseLocalStyleChange && current->relation() != CSSSelector::S ubSelector)
249 mode = UseSubtreeStyleChange;
250 } 250 }
251 251
252 ASSERT(!maxDirectAdjacentSelectors); 252 ASSERT(!maxDirectAdjacentSelectors);
253 } 253 }
254 254
255 void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* sele ctorList, RuleFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMo de collectionMode) 255 void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* sele ctorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationMode mode)
256 { 256 {
257 if (!selectorList) 257 if (!selectorList)
258 return; 258 return;
259 259
260 for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) 260 for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
261 collectFeaturesFromSelector(*selector, metadata, collectionMode); 261 collectFeaturesFromSelector(*selector, metadata, mode);
262 } 262 }
263 263
264 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) 264 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
265 { 265 {
266 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; 266 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
267 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors); 267 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors);
268 268
269 HashSet<AtomicString>::const_iterator end = other.idsInRules.end(); 269 HashSet<AtomicString>::const_iterator end = other.idsInRules.end();
270 for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it) 270 for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it)
271 idsInRules.add(*it); 271 idsInRules.add(*it);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 444 }
445 445
446 invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize); 446 invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize);
447 element->clearChildNeedsStyleInvalidation(); 447 element->clearChildNeedsStyleInvalidation();
448 element->clearNeedsStyleInvalidation(); 448 element->clearNeedsStyleInvalidation();
449 449
450 return thisElementNeedsStyleRecalc; 450 return thisElementNeedsStyleRecalc;
451 } 451 }
452 452
453 } // namespace WebCore 453 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/css/RuleFeature.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698