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

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

Issue 726503003: Single code path for updating invalidation sets. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Assertion fail, missing HostContext Created 6 years, 1 month 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/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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 // These should not appear in StyleRule selectors. 156 // These should not appear in StyleRule selectors.
157 ASSERT_NOT_REACHED(); 157 ASSERT_NOT_REACHED();
158 return false; 158 return false;
159 default: 159 default:
160 // New pseudo type added. Figure out if it needs a subtree invalidation or not. 160 // New pseudo type added. Figure out if it needs a subtree invalidation or not.
161 ASSERT_NOT_REACHED(); 161 ASSERT_NOT_REACHED();
162 return false; 162 return false;
163 } 163 }
164 } 164 }
165 165
166 static bool supportsInvalidationWithSelectorList(CSSSelector::PseudoType pseudo)
167 {
168 return pseudo == CSSSelector::PseudoAny
169 || pseudo == CSSSelector::PseudoCue
170 || pseudo == CSSSelector::PseudoHost
171 || pseudo == CSSSelector::PseudoHostContext
chrishtr 2014/11/13 23:01:11 This one is sort of unrelated to the main thrust o
rune 2014/11/14 00:04:53 This is what's described in the last section of th
172 || pseudo == CSSSelector::PseudoNot;
173 }
174
166 #endif // ENABLE(ASSERT) 175 #endif // ENABLE(ASSERT)
167 176
168 static bool requiresSubtreeInvalidation(const CSSSelector& selector) 177 static bool requiresSubtreeInvalidation(const CSSSelector& selector)
169 { 178 {
170 if (!selector.matchesPseudoElement() && selector.match() != CSSSelector::Pse udoClass) { 179 if (!selector.matchesPseudoElement() && selector.match() != CSSSelector::Pse udoClass) {
171 ASSERT(supportsInvalidation(selector.match())); 180 ASSERT(supportsInvalidation(selector.match()));
172 return false; 181 return false;
173 } 182 }
174 183
175 switch (selector.pseudoType()) { 184 switch (selector.pseudoType()) {
(...skipping 17 matching lines...) Expand all
193 , selectorIndex(selectorIndex) 202 , selectorIndex(selectorIndex)
194 , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) 203 , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
195 { 204 {
196 } 205 }
197 206
198 void RuleFeature::trace(Visitor* visitor) 207 void RuleFeature::trace(Visitor* visitor)
199 { 208 {
200 visitor->trace(rule); 209 visitor->trace(rule);
201 } 210 }
202 211
203 static bool supportsInvalidationWithSelectorList(CSSSelector::PseudoType pseudo) 212 bool RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features)
204 { 213 {
205 return pseudo == CSSSelector::PseudoAny 214 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName() != starAtom)
chrishtr 2014/11/13 23:01:11 Why this change?
rune 2014/11/14 00:04:53 It's to get the return value correct, and avoid us
206 || pseudo == CSSSelector::PseudoCue
207 || pseudo == CSSSelector::PseudoHost
208 || pseudo == CSSSelector::PseudoNot;
209 }
210
211 // This method is somewhat conservative in what it accepts.
212 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelect or(const CSSSelector& selector)
213 {
214 bool foundCombinator = false;
215 bool foundIdent = false;
216 for (const CSSSelector* component = &selector; component; component = compon ent->tagHistory()) {
217
218 if (component->match() == CSSSelector::Class || component->match() == CS SSelector::Id
219 || (component->match() == CSSSelector::Tag && component->tagQName(). localName() != starAtom)
220 || component->isAttributeSelector() || component->isCustomPseudoElem ent()) {
221 if (!foundCombinator) {
222 // We have found an invalidation set feature in the rightmost co mpound selector.
223 foundIdent = true;
224 }
225 } else if (supportsInvalidationWithSelectorList(component->pseudoType()) ) {
226 if (const CSSSelectorList* selectorList = component->selectorList()) {
227 // Features inside :not() are not added to the feature set, so c onsider it a universal selector.
228 bool foundUniversal = component->pseudoType() == CSSSelector::Ps eudoNot;
229 for (const CSSSelector* selector = selectorList->first(); select or; selector = CSSSelectorList::next(*selector)) {
230 // Find the invalidation set mode for each of the selectors in the selector list
231 // of a :not(), :host(), etc. For instance, ".x :-webkit-any (.a, .b)" yields an
232 // AddFeatures mode for both ".a" and ".b". ":-webkit-any(.a , *)" yields AddFeatures
233 // for ".a", but UseSubtreeStyleChange for "*". One sub-sele ctor without invalidation
234 // set features is sufficient to cause the selector to be a universal selector as far
235 // the invalidation set is concerned.
236 InvalidationSetMode subSelectorMode = invalidationSetModeFor Selector(*selector);
237
238 // The sub-selector contained something unskippable, fall ba ck to whole subtree
239 // recalcs in collectFeaturesFromSelector. subSelectorMode w ill return
240 // UseSubtreeStyleChange since there are no combinators insi de the selector list,
241 // so translate it to UseLocalStyleChange if a combinator ha s been seen in the
242 // outer context.
243 //
244 // FIXME: Is UseSubtreeStyleChange ever needed as input to c ollectFeaturesFromSelector?
245 // That is, are there any selectors for which we need to use SubtreeStyleChange for
246 // changing features when present in the rightmost compound selector?
247 if (subSelectorMode == UseSubtreeStyleChange)
248 return foundCombinator ? UseLocalStyleChange : UseSubtre eStyleChange;
249
250 // We found no features in the sub-selector, only skippable ones (foundIdent was
251 // false at the end of this method). That is a universal sel ector as far as the
252 // invalidation set is concerned.
253 if (subSelectorMode == UseLocalStyleChange)
254 foundUniversal = true;
255 }
256 if (!foundUniversal && !foundCombinator) {
257 // All sub-selectors contained invalidation set features and
258 // we are in the rightmost compound selector.
259 foundIdent = true;
260 }
261 }
262 } else if (requiresSubtreeInvalidation(*component)) {
263 return foundCombinator ? UseLocalStyleChange : UseSubtreeStyleChange ;
264 }
265 if (component->relation() != CSSSelector::SubSelector)
266 foundCombinator = true;
267 }
268 return foundIdent ? AddFeatures : UseLocalStyleChange;
269 }
270
271 void RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features)
272 {
273 if (selector.match() == CSSSelector::Tag)
274 features.tagName = selector.tagQName().localName(); 215 features.tagName = selector.tagQName().localName();
275 else if (selector.match() == CSSSelector::Id) 216 else if (selector.match() == CSSSelector::Id)
276 features.id = selector.value(); 217 features.id = selector.value();
277 else if (selector.match() == CSSSelector::Class) 218 else if (selector.match() == CSSSelector::Class)
278 features.classes.append(selector.value()); 219 features.classes.append(selector.value());
279 else if (selector.isAttributeSelector()) 220 else if (selector.isAttributeSelector())
280 features.attributes.append(selector.attribute().localName()); 221 features.attributes.append(selector.attribute().localName());
281 else if (selector.isCustomPseudoElement()) 222 else if (selector.isCustomPseudoElement())
282 features.customPseudoElement = true; 223 features.customPseudoElement = true;
224 else
225 return false;
226 return true;
chrishtr 2014/11/13 23:01:11 Is this code reachable?
rune 2014/11/14 00:04:53 Yes, it's the return value for all but the last el
283 } 227 }
284 228
285 RuleFeatureSet::RuleFeatureSet() 229 RuleFeatureSet::RuleFeatureSet()
286 { 230 {
287 } 231 }
288 232
289 RuleFeatureSet::~RuleFeatureSet() 233 RuleFeatureSet::~RuleFeatureSet()
290 { 234 {
291 } 235 }
292 236
(...skipping 21 matching lines...) Expand all
314 case CSSSelector::PseudoRequired: 258 case CSSSelector::PseudoRequired:
315 case CSSSelector::PseudoValid: 259 case CSSSelector::PseudoValid:
316 case CSSSelector::PseudoInvalid: 260 case CSSSelector::PseudoInvalid:
317 case CSSSelector::PseudoIndeterminate: 261 case CSSSelector::PseudoIndeterminate:
318 case CSSSelector::PseudoTarget: 262 case CSSSelector::PseudoTarget:
319 return &ensurePseudoInvalidationSet(selector.pseudoType()); 263 return &ensurePseudoInvalidationSet(selector.pseudoType());
320 default: 264 default:
321 break; 265 break;
322 } 266 }
323 } 267 }
324 return 0; 268 return nullptr;
325 } 269 }
326 270
327 // Given a selector, update the descendant invalidation sets for the features fo und 271 // Given a selector, update the descendant invalidation sets for the features fo und
328 // in the selector. The first step is to extract the features from the rightmost 272 // in the selector. The first step is to extract the features from the rightmost
329 // compound selector (extractInvalidationSetFeatures). Secondly, those features will be 273 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res
330 // added to the invalidation sets for the features found in the other compound s electors 274 // to the invalidation sets for the features found in the other compound selecto rs
331 // (addFeaturesToInvalidationSets). 275 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und
276 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the
277 // rightmost compound selector as well.
332 278
333 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const CSSSelector& selector) 279 void RuleFeatureSet::updateInvalidationSets(const CSSSelector& selector)
334 { 280 {
335 InvalidationSetMode mode = invalidationSetModeForSelector(selector);
336 if (mode != AddFeatures)
337 return mode;
338
339 InvalidationSetFeatures features; 281 InvalidationSetFeatures features;
340 if (const CSSSelector* current = extractInvalidationSetFeatures(selector, fe atures, false)) 282 auto result = extractInvalidationSetFeatures(selector, features, false);
341 addFeaturesToInvalidationSets(*current, features); 283 if (result.first) {
342 return AddFeatures; 284 features.forceSubtree = result.second == ForceSubtree;
285 addFeaturesToInvalidationSets(*result.first, features);
286 }
343 } 287 }
344 288
345 const CSSSelector* RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelec tor& selector, InvalidationSetFeatures& features, bool negated) 289 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType>
290 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated)
346 { 291 {
292 bool foundFeatures = false;
347 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 293 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
348 if (!negated) 294 if (!negated)
349 extractInvalidationSetFeature(*current, features); 295 foundFeatures |= extractInvalidationSetFeature(*current, features);
350 // Initialize the entry in the invalidation set map, if supported. 296 // Initialize the entry in the invalidation set map, if supported.
351 invalidationSetForSelector(*current); 297 if (!invalidationSetForSelector(*current)) {
352 if (supportsInvalidationWithSelectorList(current->pseudoType())) { 298 if (requiresSubtreeInvalidation(*current)) {
299 // Fall back to use subtree invalidations, even for features in the
300 // rightmost compound selector. Returning the start &selector he re
301 // will make addFeaturesToInvalidationSets start marking invalid ation
302 // sets for subtree recalc for features in the rightmost compoun d
303 // selector.
304 return std::make_pair(&selector, ForceSubtree);
305 }
353 if (const CSSSelectorList* selectorList = current->selectorList()) { 306 if (const CSSSelectorList* selectorList = current->selectorList()) {
354 for (const CSSSelector* selector = selectorList->first(); select or; selector = CSSSelectorList::next(*selector)) 307 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( )));
355 extractInvalidationSetFeatures(*selector, features, current- >pseudoType() == CSSSelector::PseudoNot); 308 const CSSSelector* subSelector = selectorList->first();
309 bool allSubSelectorsHaveFeatures = !!subSelector;
310 for (; subSelector; subSelector = CSSSelectorList::next(*subSele ctor)) {
311 auto result = extractInvalidationSetFeatures(*subSelector, f eatures, current->pseudoType() == CSSSelector::PseudoNot);
312 if (result.first) {
313 // A non-null selector return means the sub-selector con tained a
314 // selector which requiresSubtreeInvalidation(). Return the rightmost
315 // selector to mark for subtree recalcs like above.
316 return std::make_pair(&selector, ForceSubtree);
317 }
318 allSubSelectorsHaveFeatures &= result.second == UseFeatures;
319 }
320 foundFeatures |= allSubSelectorsHaveFeatures;
356 } 321 }
357 } 322 }
358 323
359 if (current->relation() == CSSSelector::SubSelector) 324 if (current->relation() == CSSSelector::SubSelector)
360 continue; 325 continue;
361 326
362 features.treeBoundaryCrossing = current->isShadowSelector(); 327 features.treeBoundaryCrossing = current->isShadowSelector();
363 features.adjacent = current->isAdjacentSelector(); 328 features.adjacent = current->isAdjacentSelector();
364 return current->tagHistory(); 329 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree);
365 } 330 }
366 return 0; 331 return std::make_pair(nullptr, ForceSubtree);
367 } 332 }
368 333
369 // Add features extracted from the rightmost compound selector to descendant inv alidation 334 // Add features extracted from the rightmost compound selector to descendant inv alidation
370 // sets for features found in other compound selectors. 335 // sets for features found in other compound selectors.
371 // 336 //
372 // Style invalidation is currently supported for descendants only, not for sibli ng subtrees. 337 // Style invalidation is currently supported for descendants only, not for sibli ng subtrees.
373 // We use wholeSubtree invalidation for features found left of adjacent combinat ors as 338 // We use wholeSubtree invalidation for features found left of adjacent combinat ors as
374 // SubtreeStyleChange will force sibling subtree recalc in 339 // SubtreeStyleChange will force sibling subtree recalc in
375 // ContainerNode::checkForChildrenAdjacentRuleChanges. 340 // ContainerNode::checkForChildrenAdjacentRuleChanges.
376 // 341 //
377 // As we encounter a descendant type of combinator, the features only need to be checked 342 // As we encounter a descendant type of combinator, the features only need to be checked
378 // against descendants in the same subtree only. features.adjacent is set to fal se, and 343 // against descendants in the same subtree only. features.adjacent is set to fal se, and
379 // we start adding features instead of calling setWholeSubtreeInvalid. 344 // we start adding features instead of calling setWholeSubtreeInvalid.
380 345
381 void RuleFeatureSet::addFeaturesToInvalidationSet(DescendantInvalidationSet& inv alidationSet, const InvalidationSetFeatures& features) 346 void RuleFeatureSet::addFeaturesToInvalidationSet(DescendantInvalidationSet& inv alidationSet, const InvalidationSetFeatures& features)
382 { 347 {
383 if (features.treeBoundaryCrossing) 348 if (features.treeBoundaryCrossing)
384 invalidationSet.setTreeBoundaryCrossing(); 349 invalidationSet.setTreeBoundaryCrossing();
385 if (features.insertionPointCrossing) 350 if (features.insertionPointCrossing)
386 invalidationSet.setInsertionPointCrossing(); 351 invalidationSet.setInsertionPointCrossing();
387 if (features.adjacent) { 352 if (features.useSubtreeInvalidation()) {
388 invalidationSet.setWholeSubtreeInvalid(); 353 invalidationSet.setWholeSubtreeInvalid();
389 return; 354 return;
390 } 355 }
391 if (!features.id.isEmpty()) 356 if (!features.id.isEmpty())
392 invalidationSet.addId(features.id); 357 invalidationSet.addId(features.id);
393 if (!features.tagName.isEmpty()) 358 if (!features.tagName.isEmpty())
394 invalidationSet.addTagName(features.tagName); 359 invalidationSet.addTagName(features.tagName);
395 for (const auto& className : features.classes) 360 for (const auto& className : features.classes)
396 invalidationSet.addClass(className); 361 invalidationSet.addClass(className);
397 for (const auto& attribute : features.attributes) 362 for (const auto& attribute : features.attributes)
(...skipping 29 matching lines...) Expand all
427 } 392 }
428 } 393 }
429 394
430 void RuleFeatureSet::addContentAttr(const AtomicString& attributeName) 395 void RuleFeatureSet::addContentAttr(const AtomicString& attributeName)
431 { 396 {
432 ensureAttributeInvalidationSet(attributeName); 397 ensureAttributeInvalidationSet(attributeName);
433 } 398 }
434 399
435 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) 400 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
436 { 401 {
402 updateInvalidationSets(ruleData.selector());
403
437 FeatureMetadata metadata; 404 FeatureMetadata metadata;
438 InvalidationSetMode mode = updateInvalidationSets(ruleData.selector()); 405 collectFeaturesFromSelector(ruleData.selector(), metadata);
439
440 collectFeaturesFromSelector(ruleData.selector(), metadata, mode);
441 m_metadata.add(metadata); 406 m_metadata.add(metadata);
442 407
443 if (metadata.foundSiblingSelector) 408 if (metadata.foundSiblingSelector)
444 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); 409 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin()));
445 if (ruleData.containsUncommonAttributeSelector()) 410 if (ruleData.containsUncommonAttributeSelector())
446 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); 411 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin()));
447 } 412 }
448 413
449 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className) 414 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className)
450 { 415 {
(...skipping 20 matching lines...) Expand all
471 } 436 }
472 437
473 DescendantInvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelect or::PseudoType pseudoType) 438 DescendantInvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelect or::PseudoType pseudoType)
474 { 439 {
475 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets .add(pseudoType, nullptr); 440 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets .add(pseudoType, nullptr);
476 if (addResult.isNewEntry) 441 if (addResult.isNewEntry)
477 addResult.storedValue->value = DescendantInvalidationSet::create(); 442 addResult.storedValue->value = DescendantInvalidationSet::create();
478 return *addResult.storedValue->value; 443 return *addResult.storedValue->value;
479 } 444 }
480 445
481 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode) 446 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata)
482 { 447 {
483 unsigned maxDirectAdjacentSelectors = 0; 448 unsigned maxDirectAdjacentSelectors = 0;
484 449
485 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 450 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
486 if (mode != AddFeatures) {
487 if (DescendantInvalidationSet* invalidationSet = invalidationSetForS elector(*current)) {
488 if (mode == UseSubtreeStyleChange)
489 invalidationSet->setWholeSubtreeInvalid();
490 }
491 }
492 if (current->pseudoType() == CSSSelector::PseudoFirstLine) 451 if (current->pseudoType() == CSSSelector::PseudoFirstLine)
493 metadata.usesFirstLineRules = true; 452 metadata.usesFirstLineRules = true;
494 if (current->isDirectAdjacentSelector()) { 453 if (current->isDirectAdjacentSelector()) {
495 maxDirectAdjacentSelectors++; 454 maxDirectAdjacentSelectors++;
496 } else if (maxDirectAdjacentSelectors) { 455 } else if (maxDirectAdjacentSelectors) {
497 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors ) 456 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors )
498 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ; 457 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ;
499 maxDirectAdjacentSelectors = 0; 458 maxDirectAdjacentSelectors = 0;
500 } 459 }
501 if (current->isSiblingSelector()) 460 if (current->isSiblingSelector())
502 metadata.foundSiblingSelector = true; 461 metadata.foundSiblingSelector = true;
503 462
504 collectFeaturesFromSelectorList(current->selectorList(), metadata, mode) ; 463 const CSSSelectorList* selectorList = current->selectorList();
464 if (!selectorList)
465 continue;
505 466
506 if (mode == UseLocalStyleChange && current->relation() != CSSSelector::S ubSelector) 467 for (const CSSSelector* selector = selectorList->first(); selector; sele ctor = CSSSelectorList::next(*selector))
507 mode = UseSubtreeStyleChange; 468 collectFeaturesFromSelector(*selector, metadata);
508 } 469 }
509 470
510 ASSERT(!maxDirectAdjacentSelectors); 471 ASSERT(!maxDirectAdjacentSelectors);
511 } 472 }
512 473
513 void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* sele ctorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
514 {
515 if (!selectorList)
516 return;
517
518 for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
519 collectFeaturesFromSelector(*selector, metadata, mode);
520 }
521
522 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) 474 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
523 { 475 {
524 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; 476 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
525 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors); 477 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors);
526 } 478 }
527 479
528 void RuleFeatureSet::FeatureMetadata::clear() 480 void RuleFeatureSet::FeatureMetadata::clear()
529 { 481 {
530 usesFirstLineRules = false; 482 usesFirstLineRules = false;
531 foundSiblingSelector = false; 483 foundSiblingSelector = false;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 visitor->trace(uncommonAttributeRules); 610 visitor->trace(uncommonAttributeRules);
659 visitor->trace(m_classInvalidationSets); 611 visitor->trace(m_classInvalidationSets);
660 visitor->trace(m_attributeInvalidationSets); 612 visitor->trace(m_attributeInvalidationSets);
661 visitor->trace(m_idInvalidationSets); 613 visitor->trace(m_idInvalidationSets);
662 visitor->trace(m_pseudoInvalidationSets); 614 visitor->trace(m_pseudoInvalidationSets);
663 visitor->trace(m_styleInvalidator); 615 visitor->trace(m_styleInvalidator);
664 #endif 616 #endif
665 } 617 }
666 618
667 } // namespace blink 619 } // namespace blink
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