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

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

Issue 1565263003: Implement CSS parser part for ::slotted pseudo element (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed comments in PS6. Created 4 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
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 "core/css/parser/CSSSelectorParser.h" 5 #include "core/css/parser/CSSSelectorParser.h"
6 6
7 #include "core/css/CSSSelectorList.h" 7 #include "core/css/CSSSelectorList.h"
8 #include "core/css/StyleSheetContents.h" 8 #include "core/css/StyleSheetContents.h"
9 #include "core/frame/UseCounter.h" 9 #include "core/frame/UseCounter.h"
10 #include "platform/RuntimeEnabledFeatures.h" 10 #include "platform/RuntimeEnabledFeatures.h"
11 11
12 namespace blink { 12 namespace blink {
13 13
14 static void recordSelectorStats(const CSSParserContext& context, const CSSSelect orList& selectorList) 14 static void recordSelectorStats(const CSSParserContext& context, const CSSSelect orList& selectorList)
15 { 15 {
16 if (!context.useCounter()) 16 if (!context.useCounter())
17 return; 17 return;
18 18
19 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) { 19 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
20 for (const CSSSelector* current = selector; current ; current = current- >tagHistory()) { 20 for (const CSSSelector* current = selector; current ; current = current- >tagHistory()) {
21 UseCounter::Feature feature = UseCounter::NumberOfFeatures; 21 UseCounter::Feature feature = UseCounter::NumberOfFeatures;
22 switch (current->pseudoType()) { 22 switch (current->pseudoType()) {
23 case CSSSelector::PseudoUnresolved: 23 case CSSSelector::PseudoUnresolved:
24 feature = UseCounter::CSSSelectorPseudoUnresolved; 24 feature = UseCounter::CSSSelectorPseudoUnresolved;
25 break; 25 break;
26 case CSSSelector::PseudoSlotted:
27 feature = UseCounter::CSSSelectorPseudoSlotted;
28 break;
26 case CSSSelector::PseudoContent: 29 case CSSSelector::PseudoContent:
27 feature = UseCounter::CSSSelectorPseudoContent; 30 feature = UseCounter::CSSSelectorPseudoContent;
28 break; 31 break;
29 case CSSSelector::PseudoHost: 32 case CSSSelector::PseudoHost:
30 feature = UseCounter::CSSSelectorPseudoHost; 33 feature = UseCounter::CSSSelectorPseudoHost;
31 break; 34 break;
32 case CSSSelector::PseudoHostContext: 35 case CSSSelector::PseudoHostContext:
33 feature = UseCounter::CSSSelectorPseudoHostContext; 36 feature = UseCounter::CSSSelectorPseudoHostContext;
34 break; 37 break;
35 case CSSSelector::PseudoFullScreenAncestor: 38 case CSSSelector::PseudoFullScreenAncestor:
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 { 467 {
465 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock); 468 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock);
466 block.consumeWhitespace(); 469 block.consumeWhitespace();
467 if (!innerSelector || !innerSelector->isSimple() || !block.atEnd()) 470 if (!innerSelector || !innerSelector->isSimple() || !block.atEnd())
468 return nullptr; 471 return nullptr;
469 Vector<OwnPtr<CSSParserSelector>> selectorVector; 472 Vector<OwnPtr<CSSParserSelector>> selectorVector;
470 selectorVector.append(innerSelector.release()); 473 selectorVector.append(innerSelector.release());
471 selector->adoptSelectorVector(selectorVector); 474 selector->adoptSelectorVector(selectorVector);
472 return selector.release(); 475 return selector.release();
473 } 476 }
477 case CSSSelector::PseudoSlotted:
478 {
479 DisallowPseudoElementsScope scope(this);
480
481 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock);
482 block.consumeWhitespace();
483 if (!innerSelector || !block.atEnd() || !RuntimeEnabledFeatures::sha dowDOMV1Enabled())
484 return nullptr;
485 Vector<OwnPtr<CSSParserSelector>> selectorVector;
486 selectorVector.append(innerSelector.release());
487 selector->adoptSelectorVector(selectorVector);
488 return selector.release();
489 }
474 case CSSSelector::PseudoLang: 490 case CSSSelector::PseudoLang:
475 { 491 {
476 // FIXME: CSS Selectors Level 4 allows :lang(*-foo) 492 // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
477 const CSSParserToken& ident = block.consumeIncludingWhitespace(); 493 const CSSParserToken& ident = block.consumeIncludingWhitespace();
478 if (ident.type() != IdentToken || !block.atEnd()) 494 if (ident.type() != IdentToken || !block.atEnd())
479 return nullptr; 495 return nullptr;
480 selector->setArgument(ident.value()); 496 selector->setArgument(ident.value());
481 return selector.release(); 497 return selector.release();
482 } 498 }
483 case CSSSelector::PseudoNthChild: 499 case CSSSelector::PseudoNthChild:
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 673
658 const AtomicString& CSSSelectorParser::determineNamespace(const AtomicString& pr efix) 674 const AtomicString& CSSSelectorParser::determineNamespace(const AtomicString& pr efix)
659 { 675 {
660 if (!m_styleSheet) 676 if (!m_styleSheet)
661 return defaultNamespace(); 677 return defaultNamespace();
662 return m_styleSheet->determineNamespace(prefix); 678 return m_styleSheet->determineNamespace(prefix);
663 } 679 }
664 680
665 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector) 681 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector)
666 { 682 {
667 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->needsImplicitShadowCrossingCombinatorForMatching()) 683 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->needsImplicitShadowCrossingCombinatorForMatching() && compoundSelector->pse udoType() != CSSSelector::PseudoSlotted)
668 return; 684 return;
669 685
670 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName; 686 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName;
671 AtomicString namespaceURI = determineNamespace(namespacePrefix); 687 AtomicString namespaceURI = determineNamespace(namespacePrefix);
672 if (namespaceURI.isNull()) { 688 if (namespaceURI.isNull()) {
673 m_failedParsing = true; 689 m_failedParsing = true;
674 return; 690 return;
675 } 691 }
676 QualifiedName tag = QualifiedName(namespacePrefix, determinedElementName, na mespaceURI); 692 QualifiedName tag = QualifiedName(namespacePrefix, determinedElementName, na mespaceURI);
677 693
678 // *:host/*:host-context never matches, so we can't discard the *, 694 // *:host/*:host-context never matches, so we can't discard the *,
679 // otherwise we can't tell the difference between *:host and just :host. 695 // otherwise we can't tell the difference between *:host and just :host.
680 // 696 //
681 // Also, selectors where we use a ShadowPseudo combinator between the 697 // Also, selectors where we use a ShadowPseudo combinator between the
682 // element and the pseudo element for matching (custom pseudo elements, 698 // element and the pseudo element for matching (custom pseudo elements,
683 // ::cue, ::shadow), we need a universal selector to set the combinator 699 // ::cue, ::shadow), we need a universal selector to set the combinator
684 // (relation) on in the cases where there are no simple selectors preceding 700 // (relation) on in the cases where there are no simple selectors preceding
685 // the pseudo element. 701 // the pseudo element.
686 if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoun dSelector->needsImplicitShadowCrossingCombinatorForMatching()) 702 if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoun dSelector->needsImplicitShadowCrossingCombinatorForMatching() || compoundSelecto r->pseudoType() == CSSSelector::PseudoSlotted)
687 compoundSelector->prependTagSelector(tag, elementName.isNull()); 703 compoundSelector->prependTagSelector(tag, elementName.isNull());
688 } 704 }
689 705
690 PassOwnPtr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(Pas sOwnPtr<CSSParserSelector> compoundSelector, PassOwnPtr<CSSParserSelector> simpl eSelector) 706 PassOwnPtr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(Pas sOwnPtr<CSSParserSelector> compoundSelector, PassOwnPtr<CSSParserSelector> simpl eSelector)
691 { 707 {
692 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ; 708 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ;
693 return compoundSelector; 709 return compoundSelector;
694 } 710 }
695 711
696 PassOwnPtr<CSSParserSelector> CSSSelectorParser::splitCompoundAtImplicitShadowCr ossingCombinator(PassOwnPtr<CSSParserSelector> compoundSelector) 712 PassOwnPtr<CSSParserSelector> CSSSelectorParser::splitCompoundAtImplicitShadowCr ossingCombinator(PassOwnPtr<CSSParserSelector> compoundSelector)
697 { 713 {
698 // The tagHistory is a linked list that stores combinator separated compound selectors 714 // The tagHistory is a linked list that stores combinator separated compound selectors
699 // from right-to-left. Yet, within a single compound selector, stores the si mple selectors 715 // from right-to-left. Yet, within a single compound selector, stores the si mple selectors
700 // from left-to-right. 716 // from left-to-right.
701 // 717 //
702 // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each ele ment in the 718 // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each ele ment in the
703 // list stored with an associated relation (combinator or SubSelector). 719 // list stored with an associated relation (combinator or SubSelector).
704 // 720 //
705 // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator 721 // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator
706 // to their left, which really makes for a new compound selector, yet it's c onsumed by 722 // to their left, which really makes for a new compound selector, yet it's c onsumed by
707 // the selector parser as a single compound selector. 723 // the selector parser as a single compound selector.
708 // 724 //
709 // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input , #x ] 725 // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input , #x ]
710 726 //
727 // Likewise, ::slotted() pseudo element has an implicit ShadowSlot combinato r to its left
728 // for finding matching slot element in other TreeScope.
729 //
730 // Example: slot[name=foo]::slotted(div) -> [ ::slotted(div), slot, [name=fo o] ]
711 CSSParserSelector* splitAfter = compoundSelector.get(); 731 CSSParserSelector* splitAfter = compoundSelector.get();
712 732
713 while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitS hadowCrossingCombinatorForMatching()) 733 while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitS hadowCrossingCombinatorForMatching() && splitAfter->tagHistory()->pseudoType() ! = CSSSelector::PseudoSlotted)
rune 2016/01/19 09:16:09 You may move the PseudoSlotted into needsImplicitS
kochi 2016/01/19 11:09:12 Done.
714 splitAfter = splitAfter->tagHistory(); 734 splitAfter = splitAfter->tagHistory();
715 735
716 if (!splitAfter || !splitAfter->tagHistory()) 736 if (!splitAfter || !splitAfter->tagHistory())
717 return compoundSelector; 737 return compoundSelector;
718 738
719 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); 739 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory();
720 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector ); 740 secondCompound->appendTagHistory(secondCompound->pseudoType() == CSSSelector ::PseudoSlotted ? CSSSelector::ShadowSlot : CSSSelector::ShadowPseudo, compoundS elector);
721 return secondCompound.release(); 741 return secondCompound.release();
722 } 742 }
723 743
724 } // namespace blink 744 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/SelectorFilter.cpp ('k') | third_party/WebKit/Source/core/frame/UseCounter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698