OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |