Chromium Code Reviews| Index: third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp |
| diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp |
| index c3a608af70adb86015c653645640c1edcc8eca00..0d649eba4f44ab3c4321bd95a252d9553f8a7263 100644 |
| --- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp |
| +++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp |
| @@ -130,31 +130,59 @@ CSSSelectorList CSSSelectorParser::consumeCompoundSelectorList(CSSParserTokenRan |
| return CSSSelectorList::adoptSelectorVector(selectorList); |
| } |
| +namespace { |
| + |
| +enum CompoundSelectorFlags { |
| + HasPseudoElementForRightmostCompound = 1 << 1, |
|
Timothy Loh
2016/01/19 04:59:27
Shouldn't we start counting from 1 << 0?
rune
2016/01/19 08:41:51
Done.
|
| + HasContentPseudoElement = 1 << 2 |
| +}; |
| + |
| +unsigned extractCompoundFlags(const CSSParserSelector& simpleSelector, CSSParserMode parserMode) |
| +{ |
| + if (simpleSelector.match() != CSSSelector::PseudoElement) |
| + return 0; |
| + if (simpleSelector.pseudoType() == CSSSelector::PseudoContent) |
| + return HasContentPseudoElement; |
| + if (simpleSelector.pseudoType() == CSSSelector::PseudoShadow) |
| + return 0; |
| + // TODO(rune@opera.com): crbug.com/578131 |
| + // The UASheetMode check is a work-around to allow this selector in mediaControls(New).css: |
| + // input[type="range" i]::-webkit-media-slider-container > div { |
| + if (parserMode == UASheetMode && simpleSelector.pseudoType() == CSSSelector::PseudoWebKitCustomElement) |
| + return 0; |
| + return HasPseudoElementForRightmostCompound; |
| +} |
| + |
| +} // namespace |
| + |
| PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector(CSSParserTokenRange& range) |
| { |
| OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(range); |
| if (!selector) |
| return nullptr; |
| - bool previousCompoundHasContentPseudo = false; |
| - for (CSSParserSelector* simple = selector.get(); simple && !previousCompoundHasContentPseudo; simple = simple->tagHistory()) |
| - previousCompoundHasContentPseudo = simple->pseudoType() == CSSSelector::PseudoContent; |
| + unsigned previousCompoundFlags = 0; |
| + |
| + for (CSSParserSelector* simple = selector.get(); simple && !previousCompoundFlags; simple = simple->tagHistory()) |
| + previousCompoundFlags |= extractCompoundFlags(*simple, m_context.mode()); |
| while (CSSSelector::Relation combinator = consumeCombinator(range)) { |
| OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector(range); |
| if (!nextSelector) |
| return combinator == CSSSelector::Descendant ? selector.release() : nullptr; |
| + if (previousCompoundFlags & HasPseudoElementForRightmostCompound) |
| + return nullptr; |
| CSSParserSelector* end = nextSelector.get(); |
| - bool compoundHasContentPseudo = end->pseudoType() == CSSSelector::PseudoContent; |
| + unsigned compoundFlags = extractCompoundFlags(*end, m_context.mode()); |
| while (end->tagHistory()) { |
| end = end->tagHistory(); |
| - compoundHasContentPseudo |= end->pseudoType() == CSSSelector::PseudoContent; |
| + compoundFlags |= extractCompoundFlags(*end, m_context.mode()); |
| } |
| end->setRelation(combinator); |
| - if (previousCompoundHasContentPseudo) |
| + if (previousCompoundFlags & HasContentPseudoElement) |
| end->setRelationIsAffectedByPseudoContent(); |
| - previousCompoundHasContentPseudo = compoundHasContentPseudo; |
| + previousCompoundFlags = compoundFlags; |
| end->setTagHistory(selector.release()); |
| selector = nextSelector.release(); |