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

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

Issue 1317533002: Sibling invalidation sets (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: review feedback Created 5 years, 3 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
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 19 matching lines...) Expand all
30 #include "core/css/RuleFeature.h" 30 #include "core/css/RuleFeature.h"
31 31
32 #include "core/HTMLNames.h" 32 #include "core/HTMLNames.h"
33 #include "core/css/CSSFunctionValue.h" 33 #include "core/css/CSSFunctionValue.h"
34 #include "core/css/CSSSelector.h" 34 #include "core/css/CSSSelector.h"
35 #include "core/css/CSSSelectorList.h" 35 #include "core/css/CSSSelectorList.h"
36 #include "core/css/CSSValueList.h" 36 #include "core/css/CSSValueList.h"
37 #include "core/css/RuleSet.h" 37 #include "core/css/RuleSet.h"
38 #include "core/css/StylePropertySet.h" 38 #include "core/css/StylePropertySet.h"
39 #include "core/css/StyleRule.h" 39 #include "core/css/StyleRule.h"
40 #include "core/css/invalidation/InvalidationLists.h"
40 #include "core/css/invalidation/InvalidationSet.h" 41 #include "core/css/invalidation/InvalidationSet.h"
41 #include "core/dom/Element.h" 42 #include "core/dom/Element.h"
42 #include "core/dom/Node.h" 43 #include "core/dom/Node.h"
43 #include "core/inspector/InspectorTraceEvents.h" 44 #include "core/inspector/InspectorTraceEvents.h"
44 #include "wtf/BitVector.h" 45 #include "wtf/BitVector.h"
45 46
46 namespace blink { 47 namespace blink {
47 48
48 #if ENABLE(ASSERT) 49 #if ENABLE(ASSERT)
49 50
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 232 }
232 233
233 RuleFeatureSet::RuleFeatureSet() 234 RuleFeatureSet::RuleFeatureSet()
234 { 235 {
235 } 236 }
236 237
237 RuleFeatureSet::~RuleFeatureSet() 238 RuleFeatureSet::~RuleFeatureSet()
238 { 239 {
239 } 240 }
240 241
241 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector) 242 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector, InvalidationType type)
242 { 243 {
243 if (selector.match() == CSSSelector::Class) 244 if (selector.match() == CSSSelector::Class)
244 return &ensureClassInvalidationSet(selector.value()); 245 return &ensureClassInvalidationSet(selector.value(), type);
245 if (selector.isAttributeSelector()) 246 if (selector.isAttributeSelector())
246 return &ensureAttributeInvalidationSet(selector.attribute().localName()) ; 247 return &ensureAttributeInvalidationSet(selector.attribute().localName(), type);
247 if (selector.match() == CSSSelector::Id) 248 if (selector.match() == CSSSelector::Id)
248 return &ensureIdInvalidationSet(selector.value()); 249 return &ensureIdInvalidationSet(selector.value(), type);
249 if (selector.match() == CSSSelector::PseudoClass) { 250 if (selector.match() == CSSSelector::PseudoClass) {
250 switch (selector.pseudoType()) { 251 switch (selector.pseudoType()) {
251 case CSSSelector::PseudoEmpty: 252 case CSSSelector::PseudoEmpty:
252 case CSSSelector::PseudoLink: 253 case CSSSelector::PseudoLink:
253 case CSSSelector::PseudoVisited: 254 case CSSSelector::PseudoVisited:
254 case CSSSelector::PseudoAnyLink: 255 case CSSSelector::PseudoAnyLink:
255 case CSSSelector::PseudoAutofill: 256 case CSSSelector::PseudoAutofill:
256 case CSSSelector::PseudoHover: 257 case CSSSelector::PseudoHover:
257 case CSSSelector::PseudoFocus: 258 case CSSSelector::PseudoFocus:
258 case CSSSelector::PseudoActive: 259 case CSSSelector::PseudoActive:
259 case CSSSelector::PseudoChecked: 260 case CSSSelector::PseudoChecked:
260 case CSSSelector::PseudoEnabled: 261 case CSSSelector::PseudoEnabled:
261 case CSSSelector::PseudoDisabled: 262 case CSSSelector::PseudoDisabled:
262 case CSSSelector::PseudoOptional: 263 case CSSSelector::PseudoOptional:
263 case CSSSelector::PseudoPlaceholderShown: 264 case CSSSelector::PseudoPlaceholderShown:
264 case CSSSelector::PseudoRequired: 265 case CSSSelector::PseudoRequired:
265 case CSSSelector::PseudoValid: 266 case CSSSelector::PseudoValid:
266 case CSSSelector::PseudoInvalid: 267 case CSSSelector::PseudoInvalid:
267 case CSSSelector::PseudoIndeterminate: 268 case CSSSelector::PseudoIndeterminate:
268 case CSSSelector::PseudoTarget: 269 case CSSSelector::PseudoTarget:
269 return &ensurePseudoInvalidationSet(selector.pseudoType()); 270 return &ensurePseudoInvalidationSet(selector.pseudoType(), type);
270 default: 271 default:
271 break; 272 break;
272 } 273 }
273 } 274 }
274 return nullptr; 275 return nullptr;
275 } 276 }
276 277
277 // Given a rule, update the descendant invalidation sets for the features found 278 // Given a rule, update the descendant invalidation sets for the features found
278 // in its selector. The first step is to extract the features from the rightmost 279 // in its selector. The first step is to extract the features from the rightmost
279 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res 280 // compound selector (extractInvalidationSetFeatures).
280 // to the invalidation sets for the features found in the other compound selecto rs 281 // If we find a feature in the right-most compound selector that requires a
281 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und 282 // subtree recalc, we addFeaturesToInvalidationSets for the rightmost compound
282 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the 283 // selector as well.
283 // rightmost compound selector as well. 284 // Finally, add those features to the invalidation sets for the features found
285 // in the other compound selectors (addFeaturesToInvalidationSets).
284 286
285 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) 287 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData)
286 { 288 {
287 InvalidationSetFeatures features; 289 InvalidationSetFeatures features;
288 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); 290 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false);
289 if (result.first) {
290 features.forceSubtree = result.second == ForceSubtree;
291 addFeaturesToInvalidationSets(*result.first, features);
292 }
293 291
294 // If any ::before and ::after rules specify 'content: attr(...)', we 292 // If any ::before and ::after rules specify 'content: attr(...)', we
295 // need to create invalidation sets for those attributes. 293 // need to create invalidation sets for those attributes.
296 if (features.hasBeforeOrAfter) 294 if (features.hasBeforeOrAfter)
297 updateInvalidationSetsForContentAttribute(ruleData); 295 updateInvalidationSetsForContentAttribute(ruleData);
296
297 if (result.first) {
298 features.forceSubtree = result.second == ForceSubtree;
299 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features);
300 }
298 } 301 }
299 302
300 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) 303 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData)
301 { 304 {
302 const StylePropertySet& propertySet = ruleData.rule()->properties(); 305 const StylePropertySet& propertySet = ruleData.rule()->properties();
303 306
304 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); 307 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent);
305 308
306 if (propertyIndex == -1) 309 if (propertyIndex == -1)
307 return; 310 return;
308 311
309 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex); 312 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex);
310 CSSValue* contentValue = contentProperty.value(); 313 CSSValue* contentValue = contentProperty.value();
311 314
312 if (!contentValue->isValueList()) 315 if (!contentValue->isValueList())
313 return; 316 return;
314 317
315 for (auto& item : toCSSValueList(*contentValue)) { 318 for (auto& item : toCSSValueList(*contentValue)) {
316 if (!item->isFunctionValue()) 319 if (!item->isFunctionValue())
317 continue; 320 continue;
318 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); 321 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get());
319 if (functionValue->functionType() != CSSValueAttr) 322 if (functionValue->functionType() != CSSValueAttr)
320 continue; 323 continue;
321 ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(function Value->item(0))->getStringValue())); 324 ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(function Value->item(0))->getStringValue()), InvalidateDescendants).setAppliesDirectly();
322 } 325 }
323 } 326 }
324 327
325 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> 328 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType>
326 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated) 329 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated)
327 { 330 {
328 bool foundFeatures = false; 331 bool foundFeatures = false;
329 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 332 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
330 if (!negated) 333 if (!negated)
331 foundFeatures |= extractInvalidationSetFeature(*current, features); 334 foundFeatures |= extractInvalidationSetFeature(*current, features);
332 // Initialize the entry in the invalidation set map, if supported. 335 // Initialize the entry in the invalidation set map, if supported.
333 if (!invalidationSetForSelector(*current)) { 336 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) {
337 invalidationSet->setAppliesDirectly();
338 } else {
334 if (requiresSubtreeInvalidation(*current)) { 339 if (requiresSubtreeInvalidation(*current)) {
335 // Fall back to use subtree invalidations, even for features in the 340 // Fall back to use subtree invalidations, even for features in the
336 // rightmost compound selector. Returning the start &selector he re 341 // rightmost compound selector. Returning the start &selector he re
337 // will make addFeaturesToInvalidationSets start marking invalid ation 342 // will make addFeaturesToInvalidationSets start marking invalid ation
338 // sets for subtree recalc for features in the rightmost compoun d 343 // sets for subtree recalc for features in the rightmost compoun d
339 // selector. 344 // selector.
340 return std::make_pair(&selector, ForceSubtree); 345 return std::make_pair(&selector, ForceSubtree);
341 } 346 }
342 if (const CSSSelectorList* selectorList = current->selectorList()) { 347 if (const CSSSelectorList* selectorList = current->selectorList()) {
343 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); 348 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( )));
(...skipping 11 matching lines...) Expand all
355 } 360 }
356 foundFeatures |= allSubSelectorsHaveFeatures; 361 foundFeatures |= allSubSelectorsHaveFeatures;
357 } 362 }
358 } 363 }
359 364
360 if (current->relation() == CSSSelector::SubSelector) 365 if (current->relation() == CSSSelector::SubSelector)
361 continue; 366 continue;
362 367
363 features.treeBoundaryCrossing = current->isShadowSelector(); 368 features.treeBoundaryCrossing = current->isShadowSelector();
364 features.adjacent = current->isAdjacentSelector(); 369 features.adjacent = current->isAdjacentSelector();
370 if (current->relation() == CSSSelector::DirectAdjacent)
371 features.maxDirectAdjacentSelectors = 1;
365 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); 372 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree);
366 } 373 }
367 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); 374 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree);
368 } 375 }
369 376
370 // Add features extracted from the rightmost compound selector to descendant inv alidation 377 // Add features extracted from the rightmost compound selector to descendant inv alidation
371 // sets for features found in other compound selectors. 378 // sets for features found in other compound selectors.
372 // 379 //
373 // Style invalidation is currently supported for descendants only, not for sibli ng subtrees. 380 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees.
374 // We use wholeSubtree invalidation for features found left of adjacent combinat ors as
375 // SubtreeStyleChange will force sibling subtree recalc in
376 // ContainerNode::checkForChildrenAdjacentRuleChanges.
377 // 381 //
378 // As we encounter a descendant type of combinator, the features only need to be checked 382 // As we encounter a descendant type of combinator, the features only need to be checked
379 // against descendants in the same subtree only. features.adjacent is set to fal se, and 383 // against descendants in the same subtree only. features.adjacent is set to fal se, and
380 // we start adding features instead of calling setWholeSubtreeInvalid. 384 // we start adding features to the descendant invalidation set.
381 385
382 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features) 386 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features)
383 { 387 {
388 invalidationSet.updateMaxDirectAdjacentSelectors(features.maxDirectAdjacentS electors);
389
384 if (features.treeBoundaryCrossing) 390 if (features.treeBoundaryCrossing)
385 invalidationSet.setTreeBoundaryCrossing(); 391 invalidationSet.setTreeBoundaryCrossing();
386 if (features.insertionPointCrossing) 392 if (features.insertionPointCrossing)
387 invalidationSet.setInsertionPointCrossing(); 393 invalidationSet.setInsertionPointCrossing();
388 if (features.useSubtreeInvalidation()) { 394 if (features.forceSubtree) {
389 invalidationSet.setWholeSubtreeInvalid(); 395 invalidationSet.setWholeSubtreeInvalid();
390 return; 396 return;
391 } 397 }
392 if (!features.id.isEmpty()) 398 if (!features.id.isEmpty())
393 invalidationSet.addId(features.id); 399 invalidationSet.addId(features.id);
394 if (!features.tagName.isEmpty()) 400 if (!features.tagName.isEmpty())
395 invalidationSet.addTagName(features.tagName); 401 invalidationSet.addTagName(features.tagName);
396 for (const auto& className : features.classes) 402 for (const auto& className : features.classes)
397 invalidationSet.addClass(className); 403 invalidationSet.addClass(className);
398 for (const auto& attribute : features.attributes) 404 for (const auto& attribute : features.attributes)
399 invalidationSet.addAttribute(attribute); 405 invalidationSet.addAttribute(attribute);
400 if (features.customPseudoElement) 406 if (features.customPseudoElement)
401 invalidationSet.setCustomPseudoInvalid(); 407 invalidationSet.setCustomPseudoInvalid();
402 } 408 }
403 409
404 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, InvalidationSetFeatures& features) 410 // selector is the selector immediately to the left of the rightmost selector.
411 // siblingFeatures is null if selector is not immediately to the left of a sibli ng combinator.
412 // descendantFeatures has the features of the rightmost selector.
413 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea tures)
405 { 414 {
406 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 415 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator.
407 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt)) { 416 InvalidationSetFeatures localFeatures;
408 addFeaturesToInvalidationSet(*invalidationSet, features); 417
418 for (const CSSSelector* current = selector; current; current = current->tagH istory()) {
419 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants;
420 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) {
421 if (siblingFeatures) {
422 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ;
423 if (siblingFeatures == &descendantFeatures)
424 invalidationSet->setAppliesDirectly();
425 else
426 addFeaturesToInvalidationSet(invalidationSet->ensureDescenda ntInvalidationSet(), descendantFeatures);
427 } else {
428 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s);
429 }
409 } else { 430 } else {
410 if (current->isTreeBoundaryCrossing()) 431 if (current->isTreeBoundaryCrossing())
411 features.treeBoundaryCrossing = true; 432 descendantFeatures.treeBoundaryCrossing = true;
412 if (current->isInsertionPointCrossing()) 433 if (current->isInsertionPointCrossing())
413 features.insertionPointCrossing = true; 434 descendantFeatures.insertionPointCrossing = true;
414 if (const CSSSelectorList* selectorList = current->selectorList()) { 435 if (const CSSSelectorList* selectorList = current->selectorList()) {
415 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); 436 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( )));
416 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) 437 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector))
417 addFeaturesToInvalidationSets(*subSelector, features); 438 addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures);
418 } 439 }
419 } 440 }
420 441
421 if (current->relation() == CSSSelector::SubSelector) 442 if (current->relation() == CSSSelector::SubSelector)
422 continue; 443 continue;
423 444
424 if (current->isShadowSelector()) 445 if (current->isShadowSelector())
425 features.treeBoundaryCrossing = true; 446 descendantFeatures.treeBoundaryCrossing = true;
426 447
427 features.adjacent = current->isAdjacentSelector(); 448 if (!current->isAdjacentSelector()) {
449 selector = current->tagHistory();
450 siblingFeatures = nullptr;
451 continue;
452 }
453
454 if (siblingFeatures) {
455 if (siblingFeatures->maxDirectAdjacentSelectors != std::numeric_limi ts<unsigned>::max()) {
456 if (current->relation() == CSSSelector::DirectAdjacent)
457 siblingFeatures->maxDirectAdjacentSelectors++;
458 else
459 siblingFeatures->maxDirectAdjacentSelectors = std::numeric_l imits<unsigned>::max();
460 }
461 } else {
462 localFeatures = InvalidationSetFeatures();
463 auto result = extractInvalidationSetFeatures(*selector, localFeature s, false);
464 ASSERT(result.first);
465 localFeatures.forceSubtree = result.second == ForceSubtree;
466
467 siblingFeatures = &localFeatures;
468 }
428 } 469 }
429 } 470 }
430 471
431 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) 472 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
432 { 473 {
433 updateInvalidationSets(ruleData); 474 updateInvalidationSets(ruleData);
434 475
435 FeatureMetadata metadata; 476 FeatureMetadata metadata;
436 collectFeaturesFromSelector(ruleData.selector(), metadata); 477 collectFeaturesFromSelector(ruleData.selector(), metadata);
437 m_metadata.add(metadata); 478 m_metadata.add(metadata);
438 479
439 if (metadata.foundSiblingSelector) 480 if (metadata.foundSiblingSelector)
440 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); 481 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin()));
441 if (ruleData.containsUncommonAttributeSelector()) 482 if (ruleData.containsUncommonAttributeSelector())
442 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); 483 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin()));
443 } 484 }
444 485
445 InvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className)
446 {
447 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr);
448 if (addResult.isNewEntry)
449 addResult.storedValue->value = InvalidationSet::create();
450 return *addResult.storedValue->value;
451 }
452
453 InvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const AtomicStri ng& attributeName)
454 {
455 InvalidationSetMap::AddResult addResult = m_attributeInvalidationSets.add(at tributeName, nullptr);
456 if (addResult.isNewEntry)
457 addResult.storedValue->value = InvalidationSet::create();
458 return *addResult.storedValue->value;
459 }
460
461 InvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id)
462 {
463 InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullp tr);
464 if (addResult.isNewEntry)
465 addResult.storedValue->value = InvalidationSet::create();
466 return *addResult.storedValue->value;
467 }
468
469 InvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::Pseudo Type pseudoType)
470 {
471 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets .add(pseudoType, nullptr);
472 if (addResult.isNewEntry)
473 addResult.storedValue->value = InvalidationSet::create();
474 return *addResult.storedValue->value;
475 }
476
477 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata) 486 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata)
478 { 487 {
479 unsigned maxDirectAdjacentSelectors = 0; 488 unsigned maxDirectAdjacentSelectors = 0;
480 489
481 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 490 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
482 if (current->pseudoType() == CSSSelector::PseudoFirstLine) 491 if (current->pseudoType() == CSSSelector::PseudoFirstLine)
483 metadata.usesFirstLineRules = true; 492 metadata.usesFirstLineRules = true;
484 if (current->pseudoType() == CSSSelector::PseudoWindowInactive) 493 if (current->pseudoType() == CSSSelector::PseudoWindowInactive)
485 metadata.usesWindowInactiveSelector = true; 494 metadata.usesWindowInactiveSelector = true;
486 if (current->relation() == CSSSelector::DirectAdjacent) { 495 if (current->relation() == CSSSelector::DirectAdjacent) {
(...skipping 28 matching lines...) Expand all
515 void RuleFeatureSet::FeatureMetadata::clear() 524 void RuleFeatureSet::FeatureMetadata::clear()
516 { 525 {
517 usesFirstLineRules = false; 526 usesFirstLineRules = false;
518 usesWindowInactiveSelector = false; 527 usesWindowInactiveSelector = false;
519 foundSiblingSelector = false; 528 foundSiblingSelector = false;
520 maxDirectAdjacentSelectors = 0; 529 maxDirectAdjacentSelectors = 0;
521 } 530 }
522 531
523 void RuleFeatureSet::add(const RuleFeatureSet& other) 532 void RuleFeatureSet::add(const RuleFeatureSet& other)
524 { 533 {
525 for (const auto& invalidationSet : other.m_classInvalidationSets) 534 for (const auto& entry : other.m_classInvalidationSets)
526 ensureClassInvalidationSet(invalidationSet.key).combine(*invalidationSet .value); 535 ensureClassInvalidationData(entry.key).combine(*entry.value);
527 for (const auto& invalidationSet : other.m_attributeInvalidationSets) 536 for (const auto& entry : other.m_attributeInvalidationSets)
528 ensureAttributeInvalidationSet(invalidationSet.key).combine(*invalidatio nSet.value); 537 ensureAttributeInvalidationData(entry.key).combine(*entry.value);
529 for (const auto& invalidationSet : other.m_idInvalidationSets) 538 for (const auto& entry : other.m_idInvalidationSets)
530 ensureIdInvalidationSet(invalidationSet.key).combine(*invalidationSet.va lue); 539 ensureIdInvalidationData(entry.key).combine(*entry.value);
531 for (const auto& invalidationSet : other.m_pseudoInvalidationSets) 540 for (const auto& entry : other.m_pseudoInvalidationSets)
532 ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(invalid ationSet.key)).combine(*invalidationSet.value); 541 ensurePseudoInvalidationData(static_cast<CSSSelector::PseudoType>(entry. key)).combine(*entry.value);
533 542
534 m_metadata.add(other.m_metadata); 543 m_metadata.add(other.m_metadata);
535 544
536 siblingRules.appendVector(other.siblingRules); 545 siblingRules.appendVector(other.siblingRules);
537 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); 546 uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
538 } 547 }
539 548
540 void RuleFeatureSet::clear() 549 void RuleFeatureSet::clear()
541 { 550 {
542 siblingRules.clear(); 551 siblingRules.clear();
543 uncommonAttributeRules.clear(); 552 uncommonAttributeRules.clear();
544 m_metadata.clear(); 553 m_metadata.clear();
545 m_classInvalidationSets.clear(); 554 m_classInvalidationSets.clear();
546 m_attributeInvalidationSets.clear(); 555 m_attributeInvalidationSets.clear();
547 m_idInvalidationSets.clear(); 556 m_idInvalidationSets.clear();
548 } 557 }
549 558
550 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationSetVector& inva lidationSets, Element& element, const AtomicString& className) const 559 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationLists& invalida tionLists, Element& element, const AtomicString& className) const
551 { 560 {
552 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_classInvalidatio nSets.get(className)) { 561 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_classInvalidat ionSets.get(className)) {
553 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, classChange , className); 562 if (invalidationData->descendants()) {
554 invalidationSets.append(invalidationSet); 563 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), classChange, className);
564 invalidationLists.descendants().append(invalidationData->descendants ());
565 }
566 if (invalidationData->siblings()) {
567 if (element.parentElement())
568 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), classChange, className);
569 invalidationLists.siblings().append(invalidationData->siblings());
570 }
555 } 571 }
556 } 572 }
557 573
558 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationSetVector& invalid ationSets, Element& element, const AtomicString& id) const 574 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio nLists, Element& element, const AtomicString& id) const
559 { 575 {
560 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_idInvalidationSe ts.get(id)) { 576 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_idInvalidation Sets.get(id)) {
561 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, idChange, i d); 577 if (invalidationData->descendants()) {
562 invalidationSets.append(invalidationSet); 578 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), idChange, id);
579 invalidationLists.descendants().append(invalidationData->descendants ());
580 }
581 if (invalidationData->siblings()) {
582 if (element.parentElement())
583 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), idChange, id);
584 invalidationLists.siblings().append(invalidationData->siblings());
585 }
563 } 586 }
564 } 587 }
565 588
566 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationSetVector& invalidationSets, Element& element, const QualifiedName& attributeName) const 589 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva lidationLists, Element& element, const QualifiedName& attributeName) const
567 { 590 {
568 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_attributeInvalid ationSets.get(attributeName.localName())) { 591 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_attributeInval idationSets.get(attributeName.localName())) {
569 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, attributeCh ange, attributeName); 592 if (invalidationData->descendants()) {
570 invalidationSets.append(invalidationSet); 593 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), attributeChange, attributeName);
594 invalidationLists.descendants().append(invalidationData->descendants ());
595 }
596 if (invalidationData->siblings()) {
597 if (element.parentElement())
598 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), attributeChange, attributeName);
599 invalidationLists.siblings().append(invalidationData->siblings());
600 }
571 } 601 }
572 } 602 }
573 603
574 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationSetVector & invalidationSets, Element& element, CSSSelector::PseudoType pseudo) const 604 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in validationLists, Element& element, CSSSelector::PseudoType pseudo) const
575 { 605 {
576 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_pseudoInvalidati onSets.get(pseudo)) { 606 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_pseudoInvalida tionSets.get(pseudo)) {
577 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, pseudoChang e, pseudo); 607 if (invalidationData->descendants()) {
578 invalidationSets.append(invalidationSet); 608 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), pseudoChange, pseudo);
609 invalidationLists.descendants().append(invalidationData->descendants ());
610 }
611 if (invalidationData->siblings()) {
612 if (element.parentElement())
613 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), pseudoChange, pseudo);
614 invalidationLists.siblings().append(invalidationData->siblings());
615 }
579 } 616 }
580 } 617 }
581 618
582 DEFINE_TRACE(RuleFeatureSet) 619 DEFINE_TRACE(RuleFeatureSet)
583 { 620 {
584 #if ENABLE(OILPAN) 621 #if ENABLE(OILPAN)
585 visitor->trace(siblingRules); 622 visitor->trace(siblingRules);
586 visitor->trace(uncommonAttributeRules); 623 visitor->trace(uncommonAttributeRules);
587 visitor->trace(m_classInvalidationSets); 624 visitor->trace(m_classInvalidationSets);
588 visitor->trace(m_attributeInvalidationSets); 625 visitor->trace(m_attributeInvalidationSets);
589 visitor->trace(m_idInvalidationSets); 626 visitor->trace(m_idInvalidationSets);
590 visitor->trace(m_pseudoInvalidationSets); 627 visitor->trace(m_pseudoInvalidationSets);
591 #endif 628 #endif
592 } 629 }
593 630
594 } // namespace blink 631 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698