Chromium Code Reviews| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |