Changeset 207854 in webkit


Ignore:
Timestamp:
Oct 25, 2016 4:21:03 PM (7 years ago)
Author:
hyatt@apple.com
Message:

[CSS Parser] Improvements to selector parsing
https://bugs.webkit.org/show_bug.cgi?id=163964

Reviewed by Zalan Bujtas.

  • css/CSSSelector.cpp:

(WebCore::CSSSelector::setAttribute):
(WebCore::CSSSelector::setNth):

  • css/CSSSelector.h:

(WebCore::CSSSelector::setAttributeValueMatchingIsCaseInsensitive):

  • css/StyleSheetContents.cpp:

(WebCore::StyleSheetContents::StyleSheetContents):
(WebCore::StyleSheetContents::parserAppendRule):
(WebCore::StyleSheetContents::ruleAt):
(WebCore::StyleSheetContents::ruleCount):
(WebCore::StyleSheetContents::clearRules):
(WebCore::StyleSheetContents::wrapperInsertRule):
(WebCore::StyleSheetContents::wrapperDeleteRule):

  • css/StyleSheetContents.h:
  • css/parser/CSSParser.cpp:

(WebCore::CSSParserContext::CSSParserContext):
(WebCore::CSSParser::parseSelector):

  • css/parser/CSSParserValues.h:

(WebCore::CSSParserSelector::setAttribute):
(WebCore::CSSParserSelector::setArgument):
(WebCore::CSSParserSelector::setNth):

  • css/parser/CSSSelectorParser.cpp:

(WebCore::consumeLangArgumentList):
(WebCore::CSSSelectorParser::consumeCompoundSelector):
(WebCore::CSSSelectorParser::consumeAttribute):
(WebCore::isPseudoClassFunction):
(WebCore::isPseudoElementFunction):
(WebCore::CSSSelectorParser::consumePseudo):
(WebCore::CSSSelectorParser::consumeCombinator):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207853 r207854  
     12016-10-25  Dave Hyatt  <hyatt@apple.com>
     2
     3        [CSS Parser] Improvements to selector parsing
     4        https://bugs.webkit.org/show_bug.cgi?id=163964
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        * css/CSSSelector.cpp:
     9        (WebCore::CSSSelector::setAttribute):
     10        (WebCore::CSSSelector::setNth):
     11        * css/CSSSelector.h:
     12        (WebCore::CSSSelector::setAttributeValueMatchingIsCaseInsensitive):
     13        * css/StyleSheetContents.cpp:
     14        (WebCore::StyleSheetContents::StyleSheetContents):
     15        (WebCore::StyleSheetContents::parserAppendRule):
     16        (WebCore::StyleSheetContents::ruleAt):
     17        (WebCore::StyleSheetContents::ruleCount):
     18        (WebCore::StyleSheetContents::clearRules):
     19        (WebCore::StyleSheetContents::wrapperInsertRule):
     20        (WebCore::StyleSheetContents::wrapperDeleteRule):
     21        * css/StyleSheetContents.h:
     22        * css/parser/CSSParser.cpp:
     23        (WebCore::CSSParserContext::CSSParserContext):
     24        (WebCore::CSSParser::parseSelector):
     25        * css/parser/CSSParserValues.h:
     26        (WebCore::CSSParserSelector::setAttribute):
     27        (WebCore::CSSParserSelector::setArgument):
     28        (WebCore::CSSParserSelector::setNth):
     29        * css/parser/CSSSelectorParser.cpp:
     30        (WebCore::consumeLangArgumentList):
     31        (WebCore::CSSSelectorParser::consumeCompoundSelector):
     32        (WebCore::CSSSelectorParser::consumeAttribute):
     33        (WebCore::isPseudoClassFunction):
     34        (WebCore::isPseudoElementFunction):
     35        (WebCore::CSSSelectorParser::consumePseudo):
     36        (WebCore::CSSSelectorParser::consumeCombinator):
     37
    1382016-10-25  Beth Dakin  <bdakin@apple.com>
    239
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r207536 r207854  
    764764}
    765765
     766void CSSSelector::setAttribute(const QualifiedName& value, bool convertToLowercase, AttributeMatchType matchType)
     767{
     768    createRareData();
     769    m_data.m_rareData->m_attribute = value;
     770    m_data.m_rareData->m_attributeCanonicalLocalName = convertToLowercase ? value.localName().convertToASCIILowercase() : value.localName();
     771    m_caseInsensitiveAttributeValueMatching = matchType == CaseInsensitive;
     772}
     773   
    766774void CSSSelector::setArgument(const AtomicString& value)
    767775{
     
    782790}
    783791
     792void CSSSelector::setNth(int a, int b)
     793{
     794    createRareData();
     795    m_parsedNth = true; // FIXME-NEWPARSER: Can remove this parsed boolean once old parser is gone.
     796    m_data.m_rareData->m_a = a;
     797    m_data.m_rareData->m_b = b;
     798}
     799   
     800// FIXME-NEWPARSER: All the code to parse nth-child stuff can be removed when
     801// the new parser is enabled.
    784802bool CSSSelector::parseNth() const
    785803{
  • trunk/Source/WebCore/css/CSSSelector.h

    r207536 r207854  
    245245
    246246        void setValue(const AtomicString&);
    247         void setAttribute(const QualifiedName&, bool isCaseInsensitive);
     247       
     248        // FIXME-NEWPARSER: These two methods can go away once the old parser is gone.
     249        void setAttribute(const QualifiedName&, bool);
     250        void setAttributeValueMatchingIsCaseInsensitive(bool);
     251        void setAttribute(const QualifiedName&, bool convertToLowercase, AttributeMatchType);
     252        void setNth(int a, int b);
    248253        void setArgument(const AtomicString&);
    249         void setAttributeValueMatchingIsCaseInsensitive(bool);
    250254        void setLangArgumentList(std::unique_ptr<Vector<AtomicString>>);
    251255        void setSelectorList(std::unique_ptr<CSSSelectorList>);
     
    586590    m_caseInsensitiveAttributeValueMatching = isCaseInsensitive;
    587591}
    588 
     592   
    589593inline bool CSSSelector::attributeValueMatchingIsCaseInsensitive() const
    590594{
  • trunk/Source/WebCore/css/StyleSheetContents.cpp

    r207767 r207854  
    8181    , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
    8282    , m_importRules(o.m_importRules.size())
     83    , m_namespaceRules(o.m_namespaceRules.size())
    8384    , m_childRules(o.m_childRules.size())
    8485    , m_namespaces(o.m_namespaces)
     
    143144    }
    144145
     146    if (is<StyleRuleNamespace>(rule)) {
     147        // Parser enforces that @namespace rules come before all rules other than
     148        // import/charset rules
     149        ASSERT(m_childRules.isEmpty());
     150        StyleRuleNamespace& namespaceRule = downcast<StyleRuleNamespace>(rule.get());
     151        parserAddNamespace(namespaceRule.prefix(), namespaceRule.uri());
     152        m_namespaceRules.append(downcast<StyleRuleNamespace>(rule.ptr()));
     153        return;
     154    }
     155
    145156    if (is<StyleRuleMedia>(rule))
    146157        reportMediaQueryWarningIfNeeded(singleOwnerDocument(), downcast<StyleRuleMedia>(rule.get()).mediaQueries());
     
    165176
    166177    childVectorIndex -= m_importRules.size();
     178   
     179    if (childVectorIndex < m_namespaceRules.size())
     180        return m_namespaceRules[childVectorIndex].get();
     181   
     182    childVectorIndex -= m_namespaceRules.size();
     183   
    167184    return m_childRules[childVectorIndex].get();
    168185}
     
    172189    unsigned result = 0;
    173190    result += m_importRules.size();
     191    result += m_namespaceRules.size();
    174192    result += m_childRules.size();
    175193    return result;
     
    188206    }
    189207    m_importRules.clear();
     208    m_namespaceRules.clear();
    190209    m_childRules.clear();
    191210    clearCharsetRule();
     
    222241    childVectorIndex -= m_importRules.size();
    223242
     243   
     244    if (childVectorIndex < m_namespaceRules.size() || (childVectorIndex == m_namespaceRules.size() && rule->isNamespaceRule())) {
     245        // Inserting non-namespace rules other than import rule before @namespace is
     246        // not allowed.
     247        if (!is<StyleRuleNamespace>(rule))
     248            return false;
     249        // Inserting @namespace rule when rules other than import/namespace/charset
     250        // are present is not allowed.
     251        if (!m_childRules.isEmpty())
     252            return false;
     253       
     254        StyleRuleNamespace& namespaceRule = downcast<StyleRuleNamespace>(rule.get());
     255        m_namespaceRules.insert(index, downcast<StyleRuleNamespace>(rule.ptr()));
     256       
     257        // For now to be compatible with IE and Firefox if a namespace rule with the same
     258        // prefix is added, it overwrites previous ones.
     259        // FIXME: The eventual correct behavior would be to ensure that the last value in
     260        // the list wins.
     261        parserAddNamespace(namespaceRule.prefix(), namespaceRule.uri());
     262        return true;
     263    }
     264    if (is<StyleRuleNamespace>(rule))
     265        return false;
     266    childVectorIndex -= m_namespaceRules.size();
     267
    224268    // If the number of selectors would overflow RuleData, we drop the operation.
    225269    if (is<StyleRule>(rule) && downcast<StyleRule>(rule.get()).selectorList().componentCount() > RuleData::maximumSelectorComponentCount)
     
    242286    }
    243287    childVectorIndex -= m_importRules.size();
     288
     289    if (childVectorIndex < m_namespaceRules.size()) {
     290        if (!m_childRules.isEmpty())
     291            return;
     292        m_namespaceRules.remove(childVectorIndex);
     293        return;
     294    }
     295    childVectorIndex -= m_namespaceRules.size();
    244296
    245297    m_childRules.remove(childVectorIndex);
  • trunk/Source/WebCore/css/StyleSheetContents.h

    r207767 r207854  
    4242class StyleRuleBase;
    4343class StyleRuleImport;
     44class StyleRuleNamespace;
    4445
    4546class StyleSheetContents final : public RefCounted<StyleSheetContents> {
     
    105106    const Vector<RefPtr<StyleRuleBase>>& childRules() const { return m_childRules; }
    106107    const Vector<RefPtr<StyleRuleImport>>& importRules() const { return m_importRules; }
     108    const Vector<RefPtr<StyleRuleNamespace>>& namespaceRules() const { return m_namespaceRules; }
    107109
    108110    void notifyLoadedSheet(const CachedCSSStyleSheet*);
     
    155157    String m_encodingFromCharsetRule;
    156158    Vector<RefPtr<StyleRuleImport>> m_importRules;
     159    Vector<RefPtr<StyleRuleNamespace>> m_namespaceRules;
    157160    Vector<RefPtr<StyleRuleBase>> m_childRules;
    158161    typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
  • trunk/Source/WebCore/css/parser/CSSParser.cpp

    r207757 r207854  
    6565#include "CSSRevertValue.h"
    6666#include "CSSSelector.h"
     67#include "CSSSelectorParser.h"
    6768#include "CSSShadowValue.h"
    6869#include "CSSStyleSheet.h"
    6970#include "CSSTimingFunctionValue.h"
     71#include "CSSTokenizer.h"
    7072#include "CSSUnicodeRangeValue.h"
    7173#include "CSSUnsetValue.h"
     
    14121414void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
    14131415{
     1416    if (m_context.useNewParser && m_context.mode != UASheetMode) {
     1417        CSSTokenizer::Scope scope(string);
     1418        selectorList = CSSSelectorParser::parseSelector(scope.tokenRange(), m_context, nullptr);
     1419        return;
     1420    }
     1421
    14141422    m_selectorListForParseSelector = &selectorList;
    1415 
     1423   
    14161424    setupParser("@-webkit-selector{", string, "}");
    14171425
  • trunk/Source/WebCore/css/parser/CSSParserValues.cpp

    r207790 r207854  
    411411    m_selector->setLangArgumentList(WTFMove(argumentList));
    412412}
    413    
     413
     414void CSSParserSelector::setLangArgumentList(std::unique_ptr<Vector<AtomicString>> argumentList)
     415{
     416    ASSERT_WITH_MESSAGE(!argumentList->isEmpty(), "No CSS Selector takes an empty argument list.");
     417    m_selector->setLangArgumentList(WTFMove(argumentList));
     418}
     419
    414420void CSSParserSelector::setSelectorList(std::unique_ptr<CSSSelectorList> selectorList)
    415421{
  • trunk/Source/WebCore/css/parser/CSSParserValues.h

    r207790 r207854  
    223223
    224224    void setValue(const AtomicString& value) { m_selector->setValue(value); }
     225   
     226    // FIXME-NEWPARSER: These two methods can go away once old parser is gone.
    225227    void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); }
     228    void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
     229   
     230    void setAttribute(const QualifiedName& value, bool convertToLowercase, CSSSelector::AttributeMatchType type) { m_selector->setAttribute(value, convertToLowercase, type); }
     231   
    226232    void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
    227     void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
     233    void setNth(int a, int b) { m_selector->setNth(a, b); }
    228234    void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
    229235    void setRelation(CSSSelector::RelationType value) { m_selector->setRelation(value); }
     
    236242    void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
    237243    void setLangArgumentList(const Vector<CSSParserString>& stringVector);
     244    void setLangArgumentList(std::unique_ptr<Vector<AtomicString>>);
    238245    void setSelectorList(std::unique_ptr<CSSSelectorList>);
    239246
  • trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp

    r207790 r207854  
    101101}
    102102
     103static bool consumeLangArgumentList(std::unique_ptr<Vector<AtomicString>>& argumentList, CSSParserTokenRange& range)
     104{
     105    const CSSParserToken& ident = range.consumeIncludingWhitespace();
     106    if (ident.type() != IdentToken && ident.type() != StringToken)
     107        return false;
     108    StringView string = ident.value();
     109    if (string.startsWith("--"))
     110        return false;
     111    argumentList->append(string.toAtomicString());
     112    while (!range.atEnd() && range.peek().type() == CommaToken) {
     113        range.consumeIncludingWhitespace();
     114        const CSSParserToken& ident = range.consumeIncludingWhitespace();
     115        if (ident.type() != IdentToken && ident.type() != StringToken)
     116            return false;
     117        StringView string = ident.value();
     118        if (string.startsWith("--"))
     119            return false;
     120        argumentList->append(string.toAtomicString());
     121    }
     122    return range.atEnd();
     123}
     124
    103125namespace {
    104126
     
    258280            compoundPseudoElement = compoundSelector->pseudoElementType();
    259281    }
    260     if (m_context.isHTMLDocument)
    261         elementName = elementName.convertToASCIILowercase();
    262282
    263283    while (std::unique_ptr<CSSParserSelector> simpleSelector = consumeSimpleSelector(range)) {
     
    401421    block.consumeWhitespace();
    402422
    403     if (m_context.isHTMLDocument)
    404         attributeName = attributeName.convertToASCIILowercase();
    405 
    406423    AtomicString namespaceURI = determineNamespace(namespacePrefix);
    407424    if (namespaceURI.isNull())
     
    415432
    416433    if (block.atEnd()) {
    417         selector->setAttribute(qualifiedName, CSSSelector::CaseSensitive);
     434        selector->setAttribute(qualifiedName, m_context.isHTMLDocument, CSSSelector::CaseSensitive);
    418435        selector->setMatch(CSSSelector::Set);
    419436        return selector;
     
    426443        return nullptr;
    427444    selector->setValue(attributeValue.value().toAtomicString());
    428     selector->setAttribute(qualifiedName, consumeAttributeFlags(block));
     445   
     446    selector->setAttribute(qualifiedName, m_context.isHTMLDocument, consumeAttributeFlags(block));
    429447
    430448    if (!block.atEnd())
    431449        return nullptr;
    432450    return selector;
     451}
     452
     453static bool isPseudoClassFunction(CSSSelector::PseudoClassType pseudoClassType)
     454{
     455    switch (pseudoClassType) {
     456    case CSSSelector::PseudoClassNot:
     457    case CSSSelector::PseudoClassMatches:
     458    case CSSSelector::PseudoClassNthChild:
     459    case CSSSelector::PseudoClassNthLastChild:
     460    case CSSSelector::PseudoClassNthOfType:
     461    case CSSSelector::PseudoClassNthLastOfType:
     462    case CSSSelector::PseudoClassLang:
     463    case CSSSelector::PseudoClassAny:
     464    case CSSSelector::PseudoClassHost:
     465#if ENABLE_CSS_SELECTORS_LEVEL4
     466    case CSSSelector::PseudoClassDir:
     467    case CSSSelector::PseudoClassRole:
     468#endif
     469        return true;
     470    default:
     471        break;
     472    }
     473    return false;
     474}
     475   
     476static bool isPseudoElementFunction(CSSSelector::PseudoElementType pseudoElementType)
     477{
     478    switch (pseudoElementType) {
     479    case CSSSelector::PseudoElementCue:
     480    case CSSSelector::PseudoElementSlotted:
     481        return true;
     482    default:
     483        break;
     484    }
     485    return false;
    433486}
    434487
     
    460513    if (token.type() == IdentToken) {
    461514        range.consume();
    462         if ((selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementUnknown) || (selector->match() == CSSSelector::PseudoClass && selector->pseudoClassType() == CSSSelector::PseudoClassUnknown))
     515        if ((selector->match() == CSSSelector::PseudoElement && (selector->pseudoElementType() == CSSSelector::PseudoElementUnknown || isPseudoElementFunction(selector->pseudoElementType())))
     516            || (selector->match() == CSSSelector::PseudoClass && (selector->pseudoClassType() == CSSSelector::PseudoClassUnknown || isPseudoClassFunction(selector->pseudoClassType()))))
    463517            return nullptr;
    464518        return selector;
     
    470524        return nullptr;
    471525
    472     switch (selector->pseudoClassType()) {
    473     case CSSSelector::PseudoClassNot: {
    474         std::unique_ptr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
    475         block.consumeWhitespace();
    476         if (!innerSelector || !block.atEnd())
    477             return nullptr;
    478         Vector<std::unique_ptr<CSSParserSelector>> selectorVector;
    479         selectorVector.append(WTFMove(innerSelector));
    480         selector->adoptSelectorVector(selectorVector);
    481         return selector;
    482     }
    483     case CSSSelector::PseudoClassNthChild:
    484     case CSSSelector::PseudoClassNthLastChild:
    485     case CSSSelector::PseudoClassNthOfType:
    486     case CSSSelector::PseudoClassNthLastOfType: {
    487         std::pair<int, int> ab;
    488         if (!consumeANPlusB(block, ab))
    489             return nullptr;
    490         block.consumeWhitespace();
    491         if (!block.atEnd())
    492             return nullptr;
    493         selector->setArgument(AtomicString::number(ab.first * ab.second));
    494         return selector;
    495     }
    496     case CSSSelector::PseudoClassLang: {
    497         // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
    498         const CSSParserToken& ident = block.consumeIncludingWhitespace();
    499         if (ident.type() != IdentToken || !block.atEnd())
    500             return nullptr;
    501         selector->setArgument(ident.value().toAtomicString());
    502         return selector;
    503     }
    504     // FIXME-NEWPARSER: Support :host-context
    505     case CSSSelector::PseudoClassAny:
    506     case CSSSelector::PseudoClassHost: {
    507         DisallowPseudoElementsScope scope(this);
    508         std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
    509         *selectorList = consumeCompoundSelectorList(block);
    510         if (!selectorList->isValid() || !block.atEnd())
    511             return nullptr;
    512         selector->setSelectorList(WTFMove(selectorList));
    513         return selector;
    514     }
    515     default:
    516         break;
    517     }
    518 
    519     switch (selector->pseudoElementType()) {
    520     case CSSSelector::PseudoElementCue: {
    521         DisallowPseudoElementsScope scope(this);
    522         std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
    523         *selectorList = consumeCompoundSelectorList(block);
    524         if (!selectorList->isValid() || !block.atEnd())
    525             return nullptr;
    526         selector->setSelectorList(WTFMove(selectorList));
    527         return selector;
    528     }
    529     case CSSSelector::PseudoElementSlotted: {
    530         DisallowPseudoElementsScope scope(this);
    531 
    532         std::unique_ptr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
    533         block.consumeWhitespace();
    534         if (!innerSelector || !block.atEnd())
    535             return nullptr;
    536         Vector<std::unique_ptr<CSSParserSelector>> selectorVector;
    537         selectorVector.append(WTFMove(innerSelector));
    538         selector->adoptSelectorVector(selectorVector);
    539         return selector;
    540     }
    541     default:
    542         break;
     526    if (selector->match() == CSSSelector::PseudoClass) {
     527        switch (selector->pseudoClassType()) {
     528        case CSSSelector::PseudoClassNot: {
     529            DisallowPseudoElementsScope scope(this);
     530            std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
     531            *selectorList = consumeComplexSelectorList(block);
     532            if (!selectorList->componentCount() || !block.atEnd())
     533                return nullptr;
     534            selector->setSelectorList(WTFMove(selectorList));
     535            return selector;
     536        }
     537        case CSSSelector::PseudoClassNthChild:
     538        case CSSSelector::PseudoClassNthLastChild:
     539        case CSSSelector::PseudoClassNthOfType:
     540        case CSSSelector::PseudoClassNthLastOfType: {
     541            std::pair<int, int> ab;
     542            if (!consumeANPlusB(block, ab))
     543                return nullptr;
     544            block.consumeWhitespace();
     545            if (!block.atEnd()) {
     546                if (block.peek().type() != IdentToken)
     547                    return nullptr;
     548                const CSSParserToken& ident = block.consume();
     549                if (!equalIgnoringASCIICase(ident.value(), "of"))
     550                    return nullptr;
     551                DisallowPseudoElementsScope scope(this);
     552                block.consumeWhitespace();
     553                std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
     554                *selectorList = consumeComplexSelectorList(block);
     555                if (!selectorList->componentCount() || !block.atEnd())
     556                    return nullptr;
     557                selector->setSelectorList(WTFMove(selectorList));
     558            }
     559            selector->setNth(ab.first, ab.second);
     560            return selector;
     561        }
     562        case CSSSelector::PseudoClassLang: {
     563            // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
     564            auto argumentList = std::make_unique<Vector<AtomicString>>();
     565            if (!consumeLangArgumentList(argumentList, block))
     566                return nullptr;
     567            selector->setLangArgumentList(WTFMove(argumentList));
     568            return selector;
     569        }
     570        case CSSSelector::PseudoClassMatches: {
     571            std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
     572            *selectorList = consumeComplexSelectorList(block);
     573            if (!selectorList->componentCount() || !block.atEnd())
     574                return nullptr;
     575            selector->setSelectorList(WTFMove(selectorList));
     576            return selector;
     577        }
     578        // FIXME-NEWPARSER: Support :host-context
     579        case CSSSelector::PseudoClassAny:
     580        case CSSSelector::PseudoClassHost: {
     581            DisallowPseudoElementsScope scope(this);
     582            std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
     583            *selectorList = consumeCompoundSelectorList(block);
     584            if (!selectorList->componentCount() || !block.atEnd())
     585                return nullptr;
     586            selector->setSelectorList(WTFMove(selectorList));
     587            return selector;
     588        }
     589#if ENABLE_CSS_SELECTORS_LEVEL4
     590        case CSSSelector::PseudoClassDir:
     591        case CSSSelector::PseudoClassRole: {
     592            const CSSParserToken& ident = block.consumeIncludingWhitespace();
     593            if (ident.type() != IdentToken)
     594                return nullptr;
     595            selector->setArgument(ident.value().toAtomicString());
     596            return selector;
     597        }
     598#endif
     599        default:
     600            break;
     601        }
     602
     603    }
     604   
     605    if (selector->match() == CSSSelector::PseudoElement) {
     606        switch (selector->pseudoElementType()) {
     607        case CSSSelector::PseudoElementCue: {
     608            DisallowPseudoElementsScope scope(this);
     609            std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
     610            *selectorList = consumeCompoundSelectorList(block);
     611            if (!selectorList->isValid() || !block.atEnd())
     612                return nullptr;
     613            selector->setSelectorList(WTFMove(selectorList));
     614            return selector;
     615        }
     616        case CSSSelector::PseudoElementSlotted: {
     617            DisallowPseudoElementsScope scope(this);
     618
     619            std::unique_ptr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
     620            block.consumeWhitespace();
     621            if (!innerSelector || !block.atEnd())
     622                return nullptr;
     623            Vector<std::unique_ptr<CSSParserSelector>> selectorVector;
     624            selectorVector.append(WTFMove(innerSelector));
     625            selector->adoptSelectorVector(selectorVector);
     626            return selector;
     627        }
     628        default:
     629            break;
     630        }
    543631    }
    544632
     
    565653        if (delimiter == '~')
    566654            return CSSSelector::IndirectAdjacent;
     655#if ENABLE_CSS_SELECTORS_LEVEL4
     656        // FIXME-NEWPARSER: Need to set that this was a >> so serialization is correct
     657        if (delimiter == '>' && range.peek().type() == DelimiterToken && range.peek().delimiter() == '>') {
     658            range.consumeIncludingWhitespace();
     659            return CSSSelector::Descendant;
     660        }
     661#endif
    567662        return CSSSelector::Child;
    568663    }
Note: See TracChangeset for help on using the changeset viewer.