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);