| Index: Source/core/css/RuleFeature.cpp
|
| diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp
|
| index 69ea193992b9bec69ff3659e3801a1fd1dbc4775..b4d4bc3dbc210b307cbc7482f5c5e7b17bcf96dd 100644
|
| --- a/Source/core/css/RuleFeature.cpp
|
| +++ b/Source/core/css/RuleFeature.cpp
|
| @@ -41,27 +41,37 @@
|
|
|
| namespace blink {
|
|
|
| -static bool isSkippableComponentForInvalidation(const CSSSelector& selector)
|
| -{
|
| - if (selector.match() == CSSSelector::Tag) {
|
| - ASSERT(selector.tagQName().localName() == starAtom);
|
| +#if ENABLE(ASSERT)
|
| +
|
| +static bool supportsInvalidation(CSSSelector::Match match)
|
| +{
|
| + switch (match) {
|
| + case CSSSelector::Tag:
|
| + case CSSSelector::Id:
|
| + case CSSSelector::Class:
|
| + case CSSSelector::AttributeExact:
|
| + case CSSSelector::AttributeSet:
|
| + case CSSSelector::AttributeHyphen:
|
| + case CSSSelector::AttributeList:
|
| + case CSSSelector::AttributeContain:
|
| + case CSSSelector::AttributeBegin:
|
| + case CSSSelector::AttributeEnd:
|
| return true;
|
| - }
|
| - if (selector.match() == CSSSelector::PseudoElement) {
|
| - switch (selector.pseudoType()) {
|
| - case CSSSelector::PseudoBefore:
|
| - case CSSSelector::PseudoAfter:
|
| - case CSSSelector::PseudoBackdrop:
|
| - case CSSSelector::PseudoShadow:
|
| - return true;
|
| - default:
|
| - ASSERT(!selector.isCustomPseudoElement());
|
| - return false;
|
| - }
|
| - }
|
| - if (selector.match() != CSSSelector::PseudoClass)
|
| + case CSSSelector::Unknown:
|
| + case CSSSelector::PagePseudoClass:
|
| + // These should not appear in StyleRule selectors.
|
| + ASSERT_NOT_REACHED();
|
| return false;
|
| - switch (selector.pseudoType()) {
|
| + default:
|
| + // New match type added. Figure out if it needs a subtree invalidation or not.
|
| + ASSERT_NOT_REACHED();
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +static bool supportsInvalidation(CSSSelector::PseudoType type)
|
| +{
|
| + switch (type) {
|
| case CSSSelector::PseudoEmpty:
|
| case CSSSelector::PseudoFirstChild:
|
| case CSSSelector::PseudoFirstOfType:
|
| @@ -75,6 +85,7 @@ static bool isSkippableComponentForInvalidation(const CSSSelector& selector)
|
| case CSSSelector::PseudoNthLastOfType:
|
| case CSSSelector::PseudoLink:
|
| case CSSSelector::PseudoVisited:
|
| + case CSSSelector::PseudoAny:
|
| case CSSSelector::PseudoAnyLink:
|
| case CSSSelector::PseudoHover:
|
| case CSSSelector::PseudoDrag:
|
| @@ -92,15 +103,89 @@ static bool isSkippableComponentForInvalidation(const CSSSelector& selector)
|
| case CSSSelector::PseudoInvalid:
|
| case CSSSelector::PseudoIndeterminate:
|
| case CSSSelector::PseudoTarget:
|
| + case CSSSelector::PseudoBefore:
|
| + case CSSSelector::PseudoAfter:
|
| + case CSSSelector::PseudoBackdrop:
|
| case CSSSelector::PseudoLang:
|
| + case CSSSelector::PseudoNot:
|
| case CSSSelector::PseudoRoot:
|
| case CSSSelector::PseudoScope:
|
| case CSSSelector::PseudoInRange:
|
| case CSSSelector::PseudoOutOfRange:
|
| case CSSSelector::PseudoUnresolved:
|
| + case CSSSelector::PseudoHost:
|
| + case CSSSelector::PseudoShadow:
|
| case CSSSelector::PseudoListBox:
|
| return true;
|
| + case CSSSelector::PseudoNotParsed:
|
| + case CSSSelector::PseudoUnknown:
|
| + case CSSSelector::PseudoLeftPage:
|
| + case CSSSelector::PseudoRightPage:
|
| + case CSSSelector::PseudoFirstPage:
|
| + // These should not appear in StyleRule selectors.
|
| + ASSERT_NOT_REACHED();
|
| + return false;
|
| + default:
|
| + // New pseudo type added. Figure out if it needs a subtree invalidation or not.
|
| + ASSERT_NOT_REACHED();
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +#endif // ENABLE(ASSERT)
|
| +
|
| +static bool requiresSubtreeInvalidation(const CSSSelector& selector)
|
| +{
|
| + if (!selector.matchesPseudoElement() && selector.match() != CSSSelector::PseudoClass) {
|
| + ASSERT(supportsInvalidation(selector.match()));
|
| + return false;
|
| + }
|
| +
|
| + switch (selector.pseudoType()) {
|
| + case CSSSelector::PseudoFirstLine:
|
| + case CSSSelector::PseudoFirstLetter:
|
| + case CSSSelector::PseudoAutofill:
|
| + case CSSSelector::PseudoFullPageMedia:
|
| + case CSSSelector::PseudoResizer:
|
| + case CSSSelector::PseudoScrollbar:
|
| + case CSSSelector::PseudoScrollbarBack:
|
| + case CSSSelector::PseudoScrollbarButton:
|
| + case CSSSelector::PseudoScrollbarCorner:
|
| + case CSSSelector::PseudoScrollbarForward:
|
| + case CSSSelector::PseudoScrollbarThumb:
|
| + case CSSSelector::PseudoScrollbarTrack:
|
| + case CSSSelector::PseudoScrollbarTrackPiece:
|
| + case CSSSelector::PseudoWindowInactive:
|
| + case CSSSelector::PseudoCornerPresent:
|
| + case CSSSelector::PseudoDecrement:
|
| + case CSSSelector::PseudoIncrement:
|
| + case CSSSelector::PseudoHorizontal:
|
| + case CSSSelector::PseudoVertical:
|
| + case CSSSelector::PseudoStart:
|
| + case CSSSelector::PseudoEnd:
|
| + case CSSSelector::PseudoDoubleButton:
|
| + case CSSSelector::PseudoSingleButton:
|
| + case CSSSelector::PseudoNoButton:
|
| + case CSSSelector::PseudoSelection:
|
| + case CSSSelector::PseudoFullScreen:
|
| + case CSSSelector::PseudoFullScreenDocument:
|
| + case CSSSelector::PseudoFullScreenAncestor:
|
| + case CSSSelector::PseudoUserAgentCustomElement:
|
| + case CSSSelector::PseudoWebKitCustomElement:
|
| + case CSSSelector::PseudoCue:
|
| + case CSSSelector::PseudoFutureCue:
|
| + case CSSSelector::PseudoPastCue:
|
| + case CSSSelector::PseudoContent:
|
| + case CSSSelector::PseudoSpatialNavigationFocus:
|
| + // FIXME: Most pseudo classes/elements above can be supported and moved
|
| + // to assertSupportedPseudo(). Move on a case-by-case basis. If they
|
| + // require subtree invalidation, document why.
|
| + case CSSSelector::PseudoHostContext:
|
| + // :host-context matches a shadow host, yet the simple selectors inside
|
| + // :host-context matches an ancestor of the shadow host.
|
| + return true;
|
| default:
|
| + ASSERT(supportsInvalidation(selector.pseudoType()));
|
| return false;
|
| }
|
| }
|
| @@ -170,7 +255,7 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelect
|
| foundIdent = true;
|
| }
|
| }
|
| - } else if (!isSkippableComponentForInvalidation(*component)) {
|
| + } else if (requiresSubtreeInvalidation(*component)) {
|
| return foundCombinator ? UseLocalStyleChange : UseSubtreeStyleChange;
|
| }
|
| if (component->relation() != CSSSelector::SubSelector)
|
|
|