Index: Source/core/css/parser/CSSSelectorParser.cpp |
diff --git a/Source/core/css/parser/CSSSelectorParser.cpp b/Source/core/css/parser/CSSSelectorParser.cpp |
index 8b735232bc03b72a064caf3d74e0e5cce0bddc4d..5e7e1cb4591a3465d65f837f81fc85a7a364bbb8 100644 |
--- a/Source/core/css/parser/CSSSelectorParser.cpp |
+++ b/Source/core/css/parser/CSSSelectorParser.cpp |
@@ -50,6 +50,25 @@ void CSSSelectorParser::consumeComplexSelectorList(CSSSelectorList& output) |
output.adoptSelectorVector(selectorList); |
} |
+void CSSSelectorParser::consumeCompoundSelectorList(CSSSelectorList& output) |
+{ |
+ Vector<OwnPtr<CSSParserSelector> > selectorList; |
+ OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(); |
+ if (!selector) |
+ return; |
+ selectorList.append(selector.release()); |
+ while (!m_tokenRange.atEnd() && m_tokenRange.peek().type() == CommaToken) { |
+ m_tokenRange.consumeIncludingWhitespaceAndComments(); |
+ selector = consumeCompoundSelector(); |
+ if (!selector) |
+ return; |
+ selectorList.append(selector.release()); |
+ } |
+ |
+ if (!m_failedParsing) |
+ output.adoptSelectorVector(selectorList); |
+} |
+ |
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector() |
{ |
OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(); |
@@ -240,7 +259,62 @@ PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeAttribute() |
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumePseudo() |
{ |
- // FIXME: Implement pseudo-element and pseudo-class parsing |
+ ASSERT(m_tokenRange.peek().type() == ColonToken); |
+ m_tokenRange.consumeIncludingComments(); |
+ |
+ int colons = 1; |
+ if (m_tokenRange.peek().type() == ColonToken) { |
+ m_tokenRange.consumeIncludingComments(); |
+ colons++; |
+ } |
+ |
+ const CSSParserToken& token = m_tokenRange.consumeIncludingComments(); |
+ if (token.type() != IdentToken && token.type() != FunctionToken) |
+ return nullptr; |
+ m_tokenRange.consumeWhitespaceAndComments(); |
+ |
+ OwnPtr<CSSParserSelector> selector = CSSParserSelector::create(); |
+ selector->setMatch(colons == 1 ? CSSSelector::PseudoClass : CSSSelector::PseudoElement); |
+ selector->setValue(AtomicString(token.value().lower())); |
+ |
+ if (token.type() == IdentToken) { |
+ if (selector->pseudoType() == CSSSelector::PseudoUnknown) |
+ return nullptr; |
+ return selector.release(); |
+ } |
+ |
+ if ((colons == 1 |
+ && (equalIgnoringCase(token.value(), "host") |
+ || equalIgnoringCase(token.value(), "host-context") |
+ || equalIgnoringCase(token.value(), "-webkit-any"))) |
+ || (colons == 2 && equalIgnoringCase(token.value(), "cue"))) { |
+ |
+ CSSSelectorList* selectorList = new CSSSelectorList(); |
+ consumeCompoundSelectorList(*selectorList); |
+ if (!selectorList->isValid() || (!m_tokenRange.atEnd() && m_tokenRange.consumeIncludingComments().type() != RightParenthesisToken)) |
alancutter (OOO until 2018)
2014/12/29 02:53:01
consumeCompoundSelectorList does not consume trail
Timothy Loh
2015/01/05 05:24:51
Updated consumeCompoundSelectorList to consume tra
|
+ return nullptr; |
+ |
+ selector->setSelectorList(adoptPtr(selectorList)); |
+ selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached? |
+ ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown); |
+ return selector.release(); |
+ } |
+ |
+ if (colons == 1 && equalIgnoringCase(token.value(), "not")) { |
+ OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(); |
+ if (!innerSelector || !innerSelector->isSimple()) |
+ return nullptr; |
+ Vector<OwnPtr<CSSParserSelector> > selectorVector; |
+ selectorVector.append(innerSelector.release()); |
+ selector->adoptSelectorVector(selectorVector); |
+ if (!m_tokenRange.atEnd() && m_tokenRange.consumeIncludingComments().type() != RightParenthesisToken) |
alancutter (OOO until 2018)
2014/12/29 02:53:01
consumeCompoundSelector does not consume trailing
|
+ return nullptr; |
+ return selector.release(); |
+ } |
+ |
+ // FIXME: Support :nth-*(<an+b>) |
+ // FIXME: Support :lang(<ident>) |
+ |
return nullptr; |
} |