Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: Source/core/css/parser/CSSSelectorParser.cpp

Issue 792763003: CSS Parser: Implement selector parsing (pseudo-classes/elements) [3/3] (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@selector2
Patch Set: rebase & handle trailing whitespace Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/css/parser/CSSSelectorParser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/css/parser/CSSSelectorParser.h" 6 #include "core/css/parser/CSSSelectorParser.h"
7 7
8 #include "core/css/CSSSelectorList.h" 8 #include "core/css/CSSSelectorList.h"
9 #include "core/css/StyleSheetContents.h" 9 #include "core/css/StyleSheetContents.h"
10 #include "platform/RuntimeEnabledFeatures.h" 10 #include "platform/RuntimeEnabledFeatures.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 selector = consumeComplexSelector(); 43 selector = consumeComplexSelector();
44 if (!selector) 44 if (!selector)
45 return; 45 return;
46 selectorList.append(selector.release()); 46 selectorList.append(selector.release());
47 } 47 }
48 48
49 if (!m_failedParsing) 49 if (!m_failedParsing)
50 output.adoptSelectorVector(selectorList); 50 output.adoptSelectorVector(selectorList);
51 } 51 }
52 52
53 void CSSSelectorParser::consumeCompoundSelectorList(CSSSelectorList& output)
54 {
55 Vector<OwnPtr<CSSParserSelector> > selectorList;
56 OwnPtr<CSSParserSelector> selector = consumeCompoundSelector();
57 if (!selector)
58 return;
59 selectorList.append(selector.release());
60 while (!m_tokenRange.atEnd() && m_tokenRange.peek().type() == CommaToken) {
61 m_tokenRange.consumeIncludingWhitespaceAndComments();
62 selector = consumeCompoundSelector();
63 if (!selector)
64 return;
65 selectorList.append(selector.release());
66 }
67
68 m_tokenRange.consumeWhitespaceAndComments();
69
70 if (!m_failedParsing)
71 output.adoptSelectorVector(selectorList);
72 }
73
53 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector() 74 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector()
54 { 75 {
55 OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(); 76 OwnPtr<CSSParserSelector> selector = consumeCompoundSelector();
56 if (!selector) 77 if (!selector)
57 return nullptr; 78 return nullptr;
58 while (CSSSelector::Relation combinator = consumeCombinator()) { 79 while (CSSSelector::Relation combinator = consumeCombinator()) {
59 OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector(); 80 OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector();
60 if (!nextSelector) 81 if (!nextSelector)
61 return combinator == CSSSelector::Descendant ? selector.release() : nullptr; 82 return combinator == CSSSelector::Descendant ? selector.release() : nullptr;
62 CSSParserSelector* end = nextSelector.get(); 83 CSSParserSelector* end = nextSelector.get();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 selector->setAttribute(qualifiedName, consumeAttributeFlags()); 254 selector->setAttribute(qualifiedName, consumeAttributeFlags());
234 255
235 if (!m_tokenRange.atEnd() && m_tokenRange.consumeIncludingComments().type() != RightBracketToken) 256 if (!m_tokenRange.atEnd() && m_tokenRange.consumeIncludingComments().type() != RightBracketToken)
236 return nullptr; 257 return nullptr;
237 258
238 return selector.release(); 259 return selector.release();
239 } 260 }
240 261
241 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumePseudo() 262 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumePseudo()
242 { 263 {
243 // FIXME: Implement pseudo-element and pseudo-class parsing 264 ASSERT(m_tokenRange.peek().type() == ColonToken);
265 m_tokenRange.consumeIncludingComments();
266
267 int colons = 1;
268 if (m_tokenRange.peek().type() == ColonToken) {
269 m_tokenRange.consumeIncludingComments();
270 colons++;
271 }
272
273 const CSSParserToken& token = m_tokenRange.consumeIncludingComments();
274 if (token.type() != IdentToken && token.type() != FunctionToken)
275 return nullptr;
276 m_tokenRange.consumeWhitespaceAndComments();
277
278 OwnPtr<CSSParserSelector> selector = CSSParserSelector::create();
279 selector->setMatch(colons == 1 ? CSSSelector::PseudoClass : CSSSelector::Pse udoElement);
280 selector->setValue(AtomicString(token.value().lower()));
281
282 if (token.type() == IdentToken) {
283 if (selector->pseudoType() == CSSSelector::PseudoUnknown)
284 return nullptr;
285 return selector.release();
286 }
287
288 if ((colons == 1
289 && (equalIgnoringCase(token.value(), "host")
290 || equalIgnoringCase(token.value(), "host-context")
291 || equalIgnoringCase(token.value(), "-webkit-any")))
292 || (colons == 2 && equalIgnoringCase(token.value(), "cue"))) {
293
294 CSSSelectorList* selectorList = new CSSSelectorList();
295 consumeCompoundSelectorList(*selectorList);
296 if (!selectorList->isValid() || (!m_tokenRange.atEnd() && m_tokenRange.c onsumeIncludingComments().type() != RightParenthesisToken))
297 return nullptr;
298
299 selector->setSelectorList(adoptPtr(selectorList));
300 selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached?
301 ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown);
302 return selector.release();
303 }
304
305 if (colons == 1 && equalIgnoringCase(token.value(), "not")) {
306 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector();
307 if (!innerSelector || !innerSelector->isSimple())
308 return nullptr;
309 Vector<OwnPtr<CSSParserSelector> > selectorVector;
310 selectorVector.append(innerSelector.release());
311 selector->adoptSelectorVector(selectorVector);
312 if (!m_tokenRange.atEnd() && m_tokenRange.consumeIncludingComments().typ e() != RightParenthesisToken)
313 return nullptr;
314 return selector.release();
315 }
316
317 // FIXME: Support :nth-*(<an+b>)
318 // FIXME: Support :lang(<ident>)
319
244 return nullptr; 320 return nullptr;
245 } 321 }
246 322
247 CSSSelector::Relation CSSSelectorParser::consumeCombinator() 323 CSSSelector::Relation CSSSelectorParser::consumeCombinator()
248 { 324 {
249 CSSSelector::Relation fallbackResult = CSSSelector::SubSelector; 325 CSSSelector::Relation fallbackResult = CSSSelector::SubSelector;
250 while (m_tokenRange.peek().type() == WhitespaceToken || m_tokenRange.peek(). type() == CommentToken) { 326 while (m_tokenRange.peek().type() == WhitespaceToken || m_tokenRange.peek(). type() == CommentToken) {
251 if (m_tokenRange.consume().type() == WhitespaceToken) 327 if (m_tokenRange.consume().type() == WhitespaceToken)
252 fallbackResult = CSSSelector::Descendant; 328 fallbackResult = CSSSelector::Descendant;
253 } 329 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 486 }
411 if (specifiers->isContentPseudoElement()) { 487 if (specifiers->isContentPseudoElement()) {
412 specifiers->insertTagHistory(CSSSelector::SubSelector, newSpecifier, CSS Selector::SubSelector); 488 specifiers->insertTagHistory(CSSSelector::SubSelector, newSpecifier, CSS Selector::SubSelector);
413 return specifiers; 489 return specifiers;
414 } 490 }
415 specifiers->appendTagHistory(CSSSelector::SubSelector, newSpecifier); 491 specifiers->appendTagHistory(CSSSelector::SubSelector, newSpecifier);
416 return specifiers; 492 return specifiers;
417 } 493 }
418 494
419 } // namespace blink 495 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/css/parser/CSSSelectorParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698