Changeset 266253 in webkit


Ignore:
Timestamp:
Aug 27, 2020 2:10:20 PM (4 years ago)
Author:
jh718.park@samsung.com
Message:

Implement @supports selector().
https://bugs.webkit.org/show_bug.cgi?id=199237

Reviewed by Antti Koivisto.

This feature allows authors to test if the browser supports the tested selector syntax.
The corresponding spec is https://drafts.csswg.org/css-conditional-4/#at-supports-ext.

And unknown -webkit- pseudo elements are not supported according to the spec,
https://drafts.csswg.org/css-conditional-4/#support-definition-ext.

LayoutTests/imported/w3c:

  • web-platform-tests/css/cssom/CSS-expected.txt:

Source/WebCore:

Tests: css3/conditional/w3c/at-supports-040.html

css3/conditional/w3c/at-supports-041.html
css3/conditional/w3c/at-supports-042.html

  • css/CSSValueKeywords.in:
  • css/parser/CSSParserImpl.h:

(WebCore::CSSParserImpl::context const):

  • css/parser/CSSSelectorParser.cpp:

(WebCore::CSSSelectorParser::supportsComplexSelector):
(WebCore::CSSSelectorParser::containsUnknownWebKitPseudoElements):

  • css/parser/CSSSupportsParser.cpp:

(WebCore::CSSSupportsParser::supportsCondition):
(WebCore::CSSSupportsParser::consumeCondition):
(WebCore::CSSSupportsParser::consumeNegation):
(WebCore::CSSSupportsParser::consumeSupportsFeatureOrGeneralEnclosed):
(WebCore::CSSSupportsParser::consumeSupportsSelectorFunction):
(WebCore::CSSSupportsParser::consumeConditionInParenthesis):
(WebCore::CSSSupportsParser::consumeDeclarationConditionOrGeneralEnclosed): Deleted.

  • css/parser/CSSSupportsParser.h:

LayoutTests:

  • css3/conditional/w3c/at-supports-040-expected.html: Added.
  • css3/conditional/w3c/at-supports-040.html: Added.
  • css3/conditional/w3c/at-supports-041-expected.html: Added.
  • css3/conditional/w3c/at-supports-041.html: Added.
  • css3/conditional/w3c/at-supports-042-expected.html: Added.
  • css3/conditional/w3c/at-supports-042.html: Added.
Location:
trunk
Files:
6 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r266248 r266253  
     12020-08-27  Joonghun Park  <jh718.park@samsung.com>
     2
     3        Implement @supports selector().
     4        https://bugs.webkit.org/show_bug.cgi?id=199237
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This feature allows authors to test if the browser supports the tested selector syntax.
     9        The corresponding spec is https://drafts.csswg.org/css-conditional-4/#at-supports-ext.
     10
     11        And unknown -webkit- pseudo elements are not supported according to the spec,
     12        https://drafts.csswg.org/css-conditional-4/#support-definition-ext.
     13
     14        * css3/conditional/w3c/at-supports-040-expected.html: Added.
     15        * css3/conditional/w3c/at-supports-040.html: Added.
     16        * css3/conditional/w3c/at-supports-041-expected.html: Added.
     17        * css3/conditional/w3c/at-supports-041.html: Added.
     18        * css3/conditional/w3c/at-supports-042-expected.html: Added.
     19        * css3/conditional/w3c/at-supports-042.html: Added.
     20
    1212020-08-27  Wenson Hsieh  <wenson_hsieh@apple.com>
    222
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r266243 r266253  
     12020-08-27  Joonghun Park  <jh718.park@samsung.com>
     2
     3        Implement @supports selector().
     4        https://bugs.webkit.org/show_bug.cgi?id=199237
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This feature allows authors to test if the browser supports the tested selector syntax.
     9        The corresponding spec is https://drafts.csswg.org/css-conditional-4/#at-supports-ext.
     10
     11        And unknown -webkit- pseudo elements are not supported according to the spec,
     12        https://drafts.csswg.org/css-conditional-4/#support-definition-ext.
     13
     14        * web-platform-tests/css/cssom/CSS-expected.txt:
     15
    1162020-08-27  Youenn Fablet  <youenn@apple.com>
    217
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/CSS-expected.txt

    r264522 r266253  
    33PASS CSS.supports, one argument form
    44FAIL CSS.supports, two argument form assert_equals: CSS.supports: two argument form succeeds for custom property expected true but got false
    5 FAIL CSS.supports, selector function assert_equals: CSS.supports: selector() function accepts a selector expected true but got false
     5FAIL CSS.supports, selector function assert_equals: CSS.supports: selector() with unknown combinators expected false but got true
    66
  • trunk/Source/WebCore/ChangeLog

    r266252 r266253  
     12020-08-27  Joonghun Park  <jh718.park@samsung.com>
     2
     3        Implement @supports selector().
     4        https://bugs.webkit.org/show_bug.cgi?id=199237
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This feature allows authors to test if the browser supports the tested selector syntax.
     9        The corresponding spec is https://drafts.csswg.org/css-conditional-4/#at-supports-ext.
     10
     11        And unknown -webkit- pseudo elements are not supported according to the spec,
     12        https://drafts.csswg.org/css-conditional-4/#support-definition-ext.
     13
     14        Tests: css3/conditional/w3c/at-supports-040.html
     15               css3/conditional/w3c/at-supports-041.html
     16               css3/conditional/w3c/at-supports-042.html
     17
     18        * css/CSSValueKeywords.in:
     19        * css/parser/CSSParserImpl.h:
     20        (WebCore::CSSParserImpl::context const):
     21        * css/parser/CSSSelectorParser.cpp:
     22        (WebCore::CSSSelectorParser::supportsComplexSelector):
     23        (WebCore::CSSSelectorParser::containsUnknownWebKitPseudoElements):
     24        * css/parser/CSSSupportsParser.cpp:
     25        (WebCore::CSSSupportsParser::supportsCondition):
     26        (WebCore::CSSSupportsParser::consumeCondition):
     27        (WebCore::CSSSupportsParser::consumeNegation):
     28        (WebCore::CSSSupportsParser::consumeSupportsFeatureOrGeneralEnclosed):
     29        (WebCore::CSSSupportsParser::consumeSupportsSelectorFunction):
     30        (WebCore::CSSSupportsParser::consumeConditionInParenthesis):
     31        (WebCore::CSSSupportsParser::consumeDeclarationConditionOrGeneralEnclosed): Deleted.
     32        * css/parser/CSSSupportsParser.h:
     33
    1342020-08-27  Simon Fraser  <simon.fraser@apple.com>
    235
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r263255 r266253  
    14521452standard
    14531453high
     1454
     1455// @supports selector()
     1456// https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
     1457selector
  • trunk/Source/WebCore/css/parser/CSSParserImpl.h

    r263771 r266253  
    9494
    9595    bool supportsDeclaration(CSSParserTokenRange&);
     96    const CSSParserContext& context() const { return m_context; }
    9697
    9798    static void parseDeclarationListForInspector(const String&, const CSSParserContext&, CSSParserObserver&);
  • trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp

    r262695 r266253  
    4747    CSSSelectorList consumeComplexSelectorList(CSSParserTokenRange&);
    4848
     49    static bool supportsComplexSelector(CSSParserTokenRange, const CSSParserContext&);
     50
    4951private:
    5052    CSSSelectorList consumeCompoundSelectorList(CSSParserTokenRange&);
     
    7274    void prependTypeSelectorIfNeeded(const AtomString& namespacePrefix, const AtomString& elementName, CSSParserSelector&);
    7375    static std::unique_ptr<CSSParserSelector> splitCompoundAtImplicitShadowCrossingCombinator(std::unique_ptr<CSSParserSelector> compoundSelector, const CSSParserContext&);
     76    static bool containsUnknownWebKitPseudoElements(const CSSSelector& complexSelector);
    7477
    7578    class DisallowPseudoElementsScope;
     
    134137        return { };
    135138    return CSSSelectorList { WTFMove(selectorList) };
     139}
     140
     141bool CSSSelectorParser::supportsComplexSelector(CSSParserTokenRange range, const CSSParserContext& context)
     142{
     143    range.consumeWhitespace();
     144    CSSSelectorParser parser(context, nullptr);
     145
     146    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=215635
     147    // Unknown css selector combinator is not addressed correctly in |CSSSelectorParser::consumeComplexSelector|.
     148    auto parserSelector = parser.consumeComplexSelector(range);
     149    if (parser.m_failedParsing || !range.atEnd() || !parserSelector)
     150        return false;
     151
     152    auto complexSelector = parserSelector->releaseSelector();
     153    ASSERT(complexSelector);
     154
     155    return !containsUnknownWebKitPseudoElements(*complexSelector);
    136156}
    137157
     
    953973}
    954974
     975bool CSSSelectorParser::containsUnknownWebKitPseudoElements(const CSSSelector& complexSelector)
     976{
     977    for (auto current = &complexSelector; current; current = current->tagHistory()) {
     978        if (current->match() == CSSSelector::PseudoElement && current->pseudoElementType() == CSSSelector::PseudoElementWebKitCustom)
     979            return true;
     980    }
     981
     982    return false;
     983}
     984
    955985} // namespace WebCore
  • trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp

    r255036 r266253  
    4141    range.consumeWhitespace();
    4242    CSSSupportsParser supportsParser(parser);
     43
    4344    auto result = supportsParser.consumeCondition(range);
    4445    if (mode != ForWindowCSS || result != Invalid)
    4546        return result;
     47
    4648    // window.CSS.supports requires parsing as-if the condition was wrapped in
    4749    // parenthesis. The only productions that wouldn't have parsed above are the
    4850    // declaration condition or the general enclosed productions.
    49     return supportsParser.consumeDeclarationConditionOrGeneralEnclosed(range);
     51    return supportsParser.consumeSupportsFeatureOrGeneralEnclosed(range);
    5052}
    5153
     
    5456CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange range)
    5557{
    56     if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken)
    57         return consumeNegation(range);
     58    if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken) {
     59        if (equalIgnoringASCIICase(range.peek().value(), "not"))
     60            return consumeNegation(range);
     61    }
    5862
    5963    bool result = false;
    6064    ClauseType clauseType = Unresolved;
    61    
     65
    6266    auto previousTokenType = IdentToken;
    6367
    6468    while (true) {
    65         SupportsResult nextResult = consumeConditionInParenthesis(range, previousTokenType);
     69        auto nextResult = consumeConditionInParenthesis(range, previousTokenType);
    6670        if (nextResult == Invalid)
    6771            return Invalid;
     
    8387        if (token.type() != IdentToken && token.type() != FunctionToken)
    8488            return Invalid;
    85        
     89
    8690        previousTokenType = token.type();
    8791       
     
    102106    ASSERT(range.peek().type() == IdentToken || range.peek().type() == FunctionToken);
    103107    auto tokenType = range.peek().type();
    104     if (!equalIgnoringASCIICase(range.peek().value(), "not"))
    105         return Invalid;
     108
    106109    if (range.peek().type() == IdentToken)
    107110        range.consumeIncludingWhitespace();
    108     SupportsResult result = consumeConditionInParenthesis(range, tokenType);
     111    auto result = consumeConditionInParenthesis(range, tokenType);
    109112    range.consumeWhitespace();
    110113    if (!range.atEnd() || result == Invalid)
    111114        return Invalid;
     115
    112116    return result ? Unsupported : Supported;
    113117}
    114118
    115 CSSSupportsParser::SupportsResult CSSSupportsParser::consumeDeclarationConditionOrGeneralEnclosed(CSSParserTokenRange& range)
     119CSSSupportsParser::SupportsResult CSSSupportsParser::consumeSupportsFeatureOrGeneralEnclosed(CSSParserTokenRange& range)
    116120{
    117121    if (range.peek().type() == FunctionToken) {
     122        if (range.peek().functionId() == CSSValueSelector)
     123            return consumeSupportsSelectorFunction(range);
     124
    118125        range.consumeComponentValue();
    119126        return Unsupported;
     
    123130}
    124131
    125 CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthesis(CSSParserTokenRange& range, CSSParserTokenType startTokenType)
     132CSSSupportsParser::SupportsResult CSSSupportsParser::consumeSupportsSelectorFunction(CSSParserTokenRange& range)
    126133{
    127     if (startTokenType == IdentToken && range.peek().type() != LeftParenthesisToken)
     134    if (range.peek().type() != FunctionToken || range.peek().functionId() != CSSValueSelector)
    128135        return Invalid;
    129136
    130     CSSParserTokenRange innerRange = range.consumeBlock();
     137    auto block = range.consumeBlock();
     138    block.consumeWhitespace();
     139
     140    return CSSSelectorParser::supportsComplexSelector(block, m_parser.context()) ? Supported : Unsupported;
     141}
     142
     143CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthesis(CSSParserTokenRange& range,  CSSParserTokenType startTokenType)
     144{
     145    // <supports-in-parens> = ( <supports-condition> ) | <supports-feature> | <general-enclosed>
     146    if (startTokenType == IdentToken && range.peek().type() != LeftParenthesisToken) {
     147        if (range.peek().type() == FunctionToken && range.peek().functionId() == CSSValueSelector)
     148            return consumeSupportsSelectorFunction(range);
     149
     150        return Invalid;
     151    }
     152
     153    auto innerRange = range.consumeBlock();
    131154    innerRange.consumeWhitespace();
    132     SupportsResult result = consumeCondition(innerRange);
     155
     156    auto result = consumeCondition(innerRange);
    133157    if (result != Invalid)
    134158        return result;
    135     return consumeDeclarationConditionOrGeneralEnclosed(innerRange);
     159
     160    // <supports-feature> = <supports-selector-fn> | <supports-decl>
     161    // <general-enclosed>
     162    return consumeSupportsFeatureOrGeneralEnclosed(innerRange);
    136163}
    137164
  • trunk/Source/WebCore/css/parser/CSSSupportsParser.h

    r217844 r266253  
    5858    SupportsResult consumeCondition(CSSParserTokenRange);
    5959    SupportsResult consumeNegation(CSSParserTokenRange);
    60     SupportsResult consumeDeclarationConditionOrGeneralEnclosed(CSSParserTokenRange&);
     60    SupportsResult consumeSupportsFeatureOrGeneralEnclosed(CSSParserTokenRange&);
     61    // https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
     62    // <supports-seletor-fn> = selector( <complex-selector> );
     63    SupportsResult consumeSupportsSelectorFunction(CSSParserTokenRange&);
    6164
    6265    SupportsResult consumeConditionInParenthesis(CSSParserTokenRange&, CSSParserTokenType);
Note: See TracChangeset for help on using the changeset viewer.