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

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: rebase, fix layout test. 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 { 495 {
493 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock); 496 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock);
494 block.consumeWhitespace(); 497 block.consumeWhitespace();
495 if (!innerSelector || !innerSelector->isSimple() || !block.atEnd()) 498 if (!innerSelector || !innerSelector->isSimple() || !block.atEnd())
496 return nullptr; 499 return nullptr;
497 Vector<OwnPtr<CSSParserSelector>> selectorVector; 500 Vector<OwnPtr<CSSParserSelector>> selectorVector;
498 selectorVector.append(innerSelector.release()); 501 selectorVector.append(innerSelector.release());
499 selector->adoptSelectorVector(selectorVector); 502 selector->adoptSelectorVector(selectorVector);
500 return selector.release(); 503 return selector.release();
501 } 504 }
505 case CSSSelector::PseudoSlotted:
506 {
507 DisallowPseudoElementsScope scope(this);
508
509 OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(bl ock);
510 block.consumeWhitespace();
511 if (!innerSelector || !block.atEnd() || !RuntimeEnabledFeatures::sha dowDOMV1Enabled())
512 return nullptr;
513 Vector<OwnPtr<CSSParserSelector>> selectorVector;
514 selectorVector.append(innerSelector.release());
515 selector->adoptSelectorVector(selectorVector);
516 return selector.release();
517 }
502 case CSSSelector::PseudoLang: 518 case CSSSelector::PseudoLang:
503 { 519 {
504 // FIXME: CSS Selectors Level 4 allows :lang(*-foo) 520 // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
505 const CSSParserToken& ident = block.consumeIncludingWhitespace(); 521 const CSSParserToken& ident = block.consumeIncludingWhitespace();
506 if (ident.type() != IdentToken || !block.atEnd()) 522 if (ident.type() != IdentToken || !block.atEnd())
507 return nullptr; 523 return nullptr;
508 selector->setArgument(ident.value()); 524 selector->setArgument(ident.value());
509 return selector.release(); 525 return selector.release();
510 } 526 }
511 case CSSSelector::PseudoNthChild: 527 case CSSSelector::PseudoNthChild:
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 701
686 const AtomicString& CSSSelectorParser::determineNamespace(const AtomicString& pr efix) 702 const AtomicString& CSSSelectorParser::determineNamespace(const AtomicString& pr efix)
687 { 703 {
688 if (!m_styleSheet) 704 if (!m_styleSheet)
689 return defaultNamespace(); 705 return defaultNamespace();
690 return m_styleSheet->determineNamespace(prefix); 706 return m_styleSheet->determineNamespace(prefix);
691 } 707 }
692 708
693 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector) 709 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector)
694 { 710 {
695 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->needsImplicitShadowCrossingCombinatorForMatching()) 711 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->needsImplicitShadowCombinatorForMatching())
696 return; 712 return;
697 713
698 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName; 714 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName;
699 AtomicString namespaceURI = determineNamespace(namespacePrefix); 715 AtomicString namespaceURI = determineNamespace(namespacePrefix);
700 if (namespaceURI.isNull()) { 716 if (namespaceURI.isNull()) {
701 m_failedParsing = true; 717 m_failedParsing = true;
702 return; 718 return;
703 } 719 }
704 QualifiedName tag = QualifiedName(namespacePrefix, determinedElementName, na mespaceURI); 720 QualifiedName tag = QualifiedName(namespacePrefix, determinedElementName, na mespaceURI);
705 721
706 // *:host/*:host-context never matches, so we can't discard the *, 722 // *:host/*:host-context never matches, so we can't discard the *,
707 // otherwise we can't tell the difference between *:host and just :host. 723 // otherwise we can't tell the difference between *:host and just :host.
708 // 724 //
709 // Also, selectors where we use a ShadowPseudo combinator between the 725 // Also, selectors where we use a ShadowPseudo combinator between the
710 // element and the pseudo element for matching (custom pseudo elements, 726 // element and the pseudo element for matching (custom pseudo elements,
711 // ::cue, ::shadow), we need a universal selector to set the combinator 727 // ::cue, ::shadow), we need a universal selector to set the combinator
712 // (relation) on in the cases where there are no simple selectors preceding 728 // (relation) on in the cases where there are no simple selectors preceding
713 // the pseudo element. 729 // the pseudo element.
714 if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoun dSelector->needsImplicitShadowCrossingCombinatorForMatching()) 730 if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoun dSelector->needsImplicitShadowCombinatorForMatching())
715 compoundSelector->prependTagSelector(tag, elementName.isNull()); 731 compoundSelector->prependTagSelector(tag, elementName.isNull());
716 } 732 }
717 733
718 PassOwnPtr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(Pas sOwnPtr<CSSParserSelector> compoundSelector, PassOwnPtr<CSSParserSelector> simpl eSelector) 734 PassOwnPtr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(Pas sOwnPtr<CSSParserSelector> compoundSelector, PassOwnPtr<CSSParserSelector> simpl eSelector)
719 { 735 {
720 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ; 736 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ;
721 return compoundSelector; 737 return compoundSelector;
722 } 738 }
723 739
724 PassOwnPtr<CSSParserSelector> CSSSelectorParser::splitCompoundAtImplicitShadowCr ossingCombinator(PassOwnPtr<CSSParserSelector> compoundSelector) 740 PassOwnPtr<CSSParserSelector> CSSSelectorParser::splitCompoundAtImplicitShadowCr ossingCombinator(PassOwnPtr<CSSParserSelector> compoundSelector)
725 { 741 {
726 // The tagHistory is a linked list that stores combinator separated compound selectors 742 // The tagHistory is a linked list that stores combinator separated compound selectors
727 // from right-to-left. Yet, within a single compound selector, stores the si mple selectors 743 // from right-to-left. Yet, within a single compound selector, stores the si mple selectors
728 // from left-to-right. 744 // from left-to-right.
729 // 745 //
730 // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each ele ment in the 746 // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each ele ment in the
731 // list stored with an associated relation (combinator or SubSelector). 747 // list stored with an associated relation (combinator or SubSelector).
732 // 748 //
733 // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator 749 // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator
734 // to their left, which really makes for a new compound selector, yet it's c onsumed by 750 // to their left, which really makes for a new compound selector, yet it's c onsumed by
735 // the selector parser as a single compound selector. 751 // the selector parser as a single compound selector.
736 // 752 //
737 // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input , #x ] 753 // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input , #x ]
738 754 //
755 // Likewise, ::slotted() pseudo element has an implicit ShadowSlot combinato r to its left
756 // for finding matching slot element in other TreeScope.
757 //
758 // Example: slot[name=foo]::slotted(div) -> [ ::slotted(div), slot, [name=fo o] ]
739 CSSParserSelector* splitAfter = compoundSelector.get(); 759 CSSParserSelector* splitAfter = compoundSelector.get();
740 760
741 while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitS hadowCrossingCombinatorForMatching()) 761 while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitS hadowCombinatorForMatching())
742 splitAfter = splitAfter->tagHistory(); 762 splitAfter = splitAfter->tagHistory();
743 763
744 if (!splitAfter || !splitAfter->tagHistory()) 764 if (!splitAfter || !splitAfter->tagHistory())
745 return compoundSelector; 765 return compoundSelector;
746 766
747 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); 767 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory();
748 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector ); 768 secondCompound->appendTagHistory(secondCompound->pseudoType() == CSSSelector ::PseudoSlotted ? CSSSelector::ShadowSlot : CSSSelector::ShadowPseudo, compoundS elector);
749 return secondCompound.release(); 769 return secondCompound.release();
750 } 770 }
751 771
752 } // namespace blink 772 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/parser/CSSParserSelector.h ('k') | third_party/WebKit/Source/core/frame/UseCounter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698