Chromium Code Reviews| Index: Source/core/css/RuleFeature.cpp |
| diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
| index 69ea193992b9bec69ff3659e3801a1fd1dbc4775..e187d37eda96116e06d96f7cf4b20171dbf546f9 100644 |
| --- a/Source/core/css/RuleFeature.cpp |
| +++ b/Source/core/css/RuleFeature.cpp |
| @@ -41,27 +41,35 @@ |
| namespace blink { |
| -static bool isSkippableComponentForInvalidation(const CSSSelector& selector) |
| -{ |
| - if (selector.match() == CSSSelector::Tag) { |
| - ASSERT(selector.tagQName().localName() == starAtom); |
| - 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; |
| - } |
| +static void assertSupportedMatch(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: |
| + break; |
| + case CSSSelector::Unknown: |
| + case CSSSelector::PagePseudoClass: |
| + // These should not appear in StyleRule selectors. |
| + ASSERT_NOT_REACHED(); |
| + break; |
| + default: |
| + // New match type added. Figure out if it needs a subtree invalidation or not. |
| + ASSERT_NOT_REACHED(); |
| + break; |
| } |
| - if (selector.match() != CSSSelector::PseudoClass) |
| - return false; |
| - switch (selector.pseudoType()) { |
| +} |
| + |
| +static void assertSupportedPseudo(CSSSelector::PseudoType type) |
|
esprehn
2014/10/15 17:55:23
supports what? This name is too generic.
rune
2014/10/15 20:43:31
I used the name you proposed in the ASSERT comment
|
| +{ |
| + switch (type) { |
| case CSSSelector::PseudoEmpty: |
| case CSSSelector::PseudoFirstChild: |
| case CSSSelector::PseudoFirstOfType: |
| @@ -75,6 +83,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 +101,93 @@ 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: |
| + break; |
| + 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(); |
| + break; |
| + default: |
| + // New pseudo type added. Figure out if it needs a subtree invalidation or not. |
| + ASSERT_NOT_REACHED(); |
| + break; |
| + } |
| +} |
| + |
| +static bool requiresSubtreeInvalidation(const CSSSelector& selector) |
| +{ |
| + if (!selector.matchesPseudoElement() && selector.match() != CSSSelector::PseudoClass) { |
| + assertSupportedMatch(selector.match()); |
| + return false; |
| + } |
| + |
| + switch (selector.pseudoType()) { |
| + 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::PseudoFirstLine: |
| + // :first-line pseudo can apply to elements arbitrarily deep down in the |
| + // DOM from its container given an arbitrary number of block descendants |
| + // with no inline flow content in between. |
| + case CSSSelector::PseudoFirstLetter: |
|
esprehn
2014/10/15 17:55:23
I don't think this is true (or for first-line). Th
rune
2014/10/15 20:43:31
It currently breaks fast/dynamic/first-letter-disp
|
| + // :first-letter pseudo elements can be arbitrarily deep down in the |
| + // DOM from its container given an arbitrary number of block descendants |
| + // with no text content in between. |
| + 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: |
| + assertSupportedPseudo(selector.pseudoType()); |
|
esprehn
2014/10/15 17:55:23
I'd rather you made these methods return booleans
rune
2014/10/15 20:43:30
Done.
I've kept the ASSERT_NOT_REACHED(), though.
|
| return false; |
| } |
| } |
| @@ -170,7 +257,7 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelect |
| foundIdent = true; |
| } |
| } |
| - } else if (!isSkippableComponentForInvalidation(*component)) { |
| + } else if (requiresSubtreeInvalidation(*component)) { |
| return foundCombinator ? UseLocalStyleChange : UseSubtreeStyleChange; |
| } |
| if (component->relation() != CSSSelector::SubSelector) |