Title: [266253] trunk
Revision
266253
Author
[email protected]
Date
2020-08-27 14:10:20 -0700 (Thu, 27 Aug 2020)

Log 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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (266252 => 266253)


--- trunk/LayoutTests/ChangeLog	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/LayoutTests/ChangeLog	2020-08-27 21:10:20 UTC (rev 266253)
@@ -1,3 +1,23 @@
+2020-08-27  Joonghun Park  <[email protected]>
+
+        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.
+
+        * 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.
+
 2020-08-27  Wenson Hsieh  <[email protected]>
 
         Occasional crashes when restoring replaced text under Editor::changeBackToReplacedString

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-040-expected.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-040-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-040-expected.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+	<head>
+		<title>CSS Reftest Reference</title>
+		<link rel="author" title="Florian Rivoal" href=""
+		<style>
+			div {
+				background-color:green;
+				height:100px;
+				width:100px;
+			}
+		</style>
+	</head>
+	<body>
+		<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-040.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-040.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-040.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Conditional Test: @supports selector() with pseudo-elements.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<link rel="author" href="" title="Mozilla">
+<link rel="help" href=""
+<link rel="match" href=""
+<style>
+  div {
+    background-color:red;
+    height:100px;
+    width:100px;
+  }
+  @supports selector(::before) {
+    div { background: green };
+  }
+</style>
+<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+<div></div>

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-041-expected.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-041-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-041-expected.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+    <head>
+        <title>CSS Reftest Reference</title>
+        <link rel="author" title="Florian Rivoal" href=""
+        <style>
+            div {
+                background-color:green;
+                height:100px;
+                width:100px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+        <div></div>
+    </body>
+</html>

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-041.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-041.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-041.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Conditional Test: @supports selector() with -webkit- unknown pseudo-elements and negation.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<link rel="author" href="" title="Mozilla">
+<link rel="help" href=""
+<link rel="match" href=""
+<style>
+  div {
+    background-color:red;
+    height:100px;
+    width:100px;
+  }
+  @supports not (selector(::-webkit-unknown-pseudo)) {
+    div { background: green };
+  }
+</style>
+<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+<div></div>

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-042-expected.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-042-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-042-expected.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+	<head>
+		<title>CSS Reftest Reference</title>
+		<link rel="author" title="Florian Rivoal" href=""
+		<style>
+			div {
+				background-color:green;
+				height:100px;
+				width:100px;
+			}
+		</style>
+	</head>
+	<body>
+		<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>

Added: trunk/LayoutTests/css3/conditional/w3c/at-supports-042.html (0 => 266253)


--- trunk/LayoutTests/css3/conditional/w3c/at-supports-042.html	                        (rev 0)
+++ trunk/LayoutTests/css3/conditional/w3c/at-supports-042.html	2020-08-27 21:10:20 UTC (rev 266253)
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Conditional Test: @supports selector() with multiple selectors doesn't work.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<link rel="author" href="" title="Mozilla">
+<link rel="help" href=""
+<link rel="match" href=""
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @supports selector(div, div) {
+    div { background: red };
+  }
+</style>
+<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+<div></div>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (266252 => 266253)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2020-08-27 21:10:20 UTC (rev 266253)
@@ -1,3 +1,18 @@
+2020-08-27  Joonghun Park  <[email protected]>
+
+        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.
+
+        * web-platform-tests/css/cssom/CSS-expected.txt:
+
 2020-08-27  Youenn Fablet  <[email protected]>
 
         Fix propagation of errors in TransformStream

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/CSS-expected.txt (266252 => 266253)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/CSS-expected.txt	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/CSS-expected.txt	2020-08-27 21:10:20 UTC (rev 266253)
@@ -2,5 +2,5 @@
 PASS CSS.escape 
 PASS CSS.supports, one argument form 
 FAIL CSS.supports, two argument form assert_equals: CSS.supports: two argument form succeeds for custom property expected true but got false
-FAIL CSS.supports, selector function assert_equals: CSS.supports: selector() function accepts a selector expected true but got false
+FAIL CSS.supports, selector function assert_equals: CSS.supports: selector() with unknown combinators expected false but got true
 

Modified: trunk/Source/WebCore/ChangeLog (266252 => 266253)


--- trunk/Source/WebCore/ChangeLog	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/ChangeLog	2020-08-27 21:10:20 UTC (rev 266253)
@@ -1,3 +1,36 @@
+2020-08-27  Joonghun Park  <[email protected]>
+
+        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.
+
+        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:
+
 2020-08-27  Simon Fraser  <[email protected]>
 
         ScrollLatchingState::previousWheelScrolledElement() is unused

Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (266252 => 266253)


--- trunk/Source/WebCore/css/CSSValueKeywords.in	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in	2020-08-27 21:10:20 UTC (rev 266253)
@@ -1451,3 +1451,7 @@
 // dynamic-range
 standard
 high
+
+// @supports selector()
+// https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
+selector
\ No newline at end of file

Modified: trunk/Source/WebCore/css/parser/CSSParserImpl.h (266252 => 266253)


--- trunk/Source/WebCore/css/parser/CSSParserImpl.h	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/css/parser/CSSParserImpl.h	2020-08-27 21:10:20 UTC (rev 266253)
@@ -93,6 +93,7 @@
     static Vector<double> parseKeyframeKeyList(const String&);
 
     bool supportsDeclaration(CSSParserTokenRange&);
+    const CSSParserContext& context() const { return m_context; }
 
     static void parseDeclarationListForInspector(const String&, const CSSParserContext&, CSSParserObserver&);
     static void parseStyleSheetForInspector(const String&, const CSSParserContext&, StyleSheetContents*, CSSParserObserver&);

Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (266252 => 266253)


--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2020-08-27 21:10:20 UTC (rev 266253)
@@ -46,6 +46,8 @@
 
     CSSSelectorList consumeComplexSelectorList(CSSParserTokenRange&);
 
+    static bool supportsComplexSelector(CSSParserTokenRange, const CSSParserContext&);
+
 private:
     CSSSelectorList consumeCompoundSelectorList(CSSParserTokenRange&);
 
@@ -71,6 +73,7 @@
     const AtomString& determineNamespace(const AtomString& prefix);
     void prependTypeSelectorIfNeeded(const AtomString& namespacePrefix, const AtomString& elementName, CSSParserSelector&);
     static std::unique_ptr<CSSParserSelector> splitCompoundAtImplicitShadowCrossingCombinator(std::unique_ptr<CSSParserSelector> compoundSelector, const CSSParserContext&);
+    static bool containsUnknownWebKitPseudoElements(const CSSSelector& complexSelector);
 
     class DisallowPseudoElementsScope;
 
@@ -135,6 +138,23 @@
     return CSSSelectorList { WTFMove(selectorList) };
 }
 
+bool CSSSelectorParser::supportsComplexSelector(CSSParserTokenRange range, const CSSParserContext& context)
+{
+    range.consumeWhitespace();
+    CSSSelectorParser parser(context, nullptr);
+
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=215635
+    // Unknown css selector combinator is not addressed correctly in |CSSSelectorParser::consumeComplexSelector|.
+    auto parserSelector = parser.consumeComplexSelector(range);
+    if (parser.m_failedParsing || !range.atEnd() || !parserSelector)
+        return false;
+
+    auto complexSelector = parserSelector->releaseSelector();
+    ASSERT(complexSelector);
+
+    return !containsUnknownWebKitPseudoElements(*complexSelector);
+}
+
 CSSSelectorList CSSSelectorParser::consumeCompoundSelectorList(CSSParserTokenRange& range)
 {
     Vector<std::unique_ptr<CSSParserSelector>> selectorList;
@@ -952,4 +972,14 @@
     return secondCompound;
 }
 
+bool CSSSelectorParser::containsUnknownWebKitPseudoElements(const CSSSelector& complexSelector)
+{
+    for (auto current = &complexSelector; current; current = current->tagHistory()) {
+        if (current->match() == CSSSelector::PseudoElement && current->pseudoElementType() == CSSSelector::PseudoElementWebKitCustom)
+            return true;
+    }
+
+    return false;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp (266252 => 266253)


--- trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp	2020-08-27 21:10:20 UTC (rev 266253)
@@ -40,13 +40,15 @@
     // but major browser vendors allow it in CSS.supports also.
     range.consumeWhitespace();
     CSSSupportsParser supportsParser(parser);
+
     auto result = supportsParser.consumeCondition(range);
     if (mode != ForWindowCSS || result != Invalid)
         return result;
+
     // window.CSS.supports requires parsing as-if the condition was wrapped in
     // parenthesis. The only productions that wouldn't have parsed above are the
     // declaration condition or the general enclosed productions.
-    return supportsParser.consumeDeclarationConditionOrGeneralEnclosed(range);
+    return supportsParser.consumeSupportsFeatureOrGeneralEnclosed(range);
 }
 
 enum ClauseType { Unresolved, Conjunction, Disjunction };
@@ -53,16 +55,18 @@
 
 CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange range)
 {
-    if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken)
-        return consumeNegation(range);
+    if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken) {
+        if (equalIgnoringASCIICase(range.peek().value(), "not"))
+            return consumeNegation(range);
+    }
 
     bool result = false;
     ClauseType clauseType = Unresolved;
-    
+
     auto previousTokenType = IdentToken;
 
     while (true) {
-        SupportsResult nextResult = consumeConditionInParenthesis(range, previousTokenType);
+        auto nextResult = consumeConditionInParenthesis(range, previousTokenType);
         if (nextResult == Invalid)
             return Invalid;
         bool nextSupported = nextResult;
@@ -82,7 +86,7 @@
         const CSSParserToken& token = range.peek();
         if (token.type() != IdentToken && token.type() != FunctionToken)
             return Invalid;
-        
+
         previousTokenType = token.type();
         
         if (clauseType == Unresolved)
@@ -101,20 +105,23 @@
 {
     ASSERT(range.peek().type() == IdentToken || range.peek().type() == FunctionToken);
     auto tokenType = range.peek().type();
-    if (!equalIgnoringASCIICase(range.peek().value(), "not"))
-        return Invalid;
+
     if (range.peek().type() == IdentToken)
         range.consumeIncludingWhitespace();
-    SupportsResult result = consumeConditionInParenthesis(range, tokenType);
+    auto result = consumeConditionInParenthesis(range, tokenType);
     range.consumeWhitespace();
     if (!range.atEnd() || result == Invalid)
         return Invalid;
+
     return result ? Unsupported : Supported;
 }
 
-CSSSupportsParser::SupportsResult CSSSupportsParser::consumeDeclarationConditionOrGeneralEnclosed(CSSParserTokenRange& range)
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeSupportsFeatureOrGeneralEnclosed(CSSParserTokenRange& range)
 {
     if (range.peek().type() == FunctionToken) {
+        if (range.peek().functionId() == CSSValueSelector)
+            return consumeSupportsSelectorFunction(range);
+
         range.consumeComponentValue();
         return Unsupported;
     }
@@ -122,17 +129,37 @@
     return range.peek().type() == IdentToken && m_parser.supportsDeclaration(range) ? Supported : Unsupported;
 }
 
-CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthesis(CSSParserTokenRange& range, CSSParserTokenType startTokenType)
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeSupportsSelectorFunction(CSSParserTokenRange& range)
 {
-    if (startTokenType == IdentToken && range.peek().type() != LeftParenthesisToken)
+    if (range.peek().type() != FunctionToken || range.peek().functionId() != CSSValueSelector)
         return Invalid;
 
-    CSSParserTokenRange innerRange = range.consumeBlock();
+    auto block = range.consumeBlock();
+    block.consumeWhitespace();
+
+    return CSSSelectorParser::supportsComplexSelector(block, m_parser.context()) ? Supported : Unsupported;
+}
+
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthesis(CSSParserTokenRange& range,  CSSParserTokenType startTokenType)
+{
+    // <supports-in-parens> = ( <supports-condition> ) | <supports-feature> | <general-enclosed>
+    if (startTokenType == IdentToken && range.peek().type() != LeftParenthesisToken) {
+        if (range.peek().type() == FunctionToken && range.peek().functionId() == CSSValueSelector)
+            return consumeSupportsSelectorFunction(range);
+
+        return Invalid;
+    }
+
+    auto innerRange = range.consumeBlock();
     innerRange.consumeWhitespace();
-    SupportsResult result = consumeCondition(innerRange);
+
+    auto result = consumeCondition(innerRange);
     if (result != Invalid)
         return result;
-    return consumeDeclarationConditionOrGeneralEnclosed(innerRange);
+
+    // <supports-feature> = <supports-selector-fn> | <supports-decl>
+    // <general-enclosed>
+    return consumeSupportsFeatureOrGeneralEnclosed(innerRange);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSSupportsParser.h (266252 => 266253)


--- trunk/Source/WebCore/css/parser/CSSSupportsParser.h	2020-08-27 21:02:09 UTC (rev 266252)
+++ trunk/Source/WebCore/css/parser/CSSSupportsParser.h	2020-08-27 21:10:20 UTC (rev 266253)
@@ -57,7 +57,10 @@
 
     SupportsResult consumeCondition(CSSParserTokenRange);
     SupportsResult consumeNegation(CSSParserTokenRange);
-    SupportsResult consumeDeclarationConditionOrGeneralEnclosed(CSSParserTokenRange&);
+    SupportsResult consumeSupportsFeatureOrGeneralEnclosed(CSSParserTokenRange&);
+    // https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
+    // <supports-seletor-fn> = selector( <complex-selector> );
+    SupportsResult consumeSupportsSelectorFunction(CSSParserTokenRange&);
 
     SupportsResult consumeConditionInParenthesis(CSSParserTokenRange&, CSSParserTokenType);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to