Skip to content
Permalink
Browse files
@supports should not work if "not", "or", or "and" isn't follow by a …
…space

https://bugs.webkit.org/show_bug.cgi?id=137568

Reviewed by Dean Jackson.

Match the behaviors of spec, Gecko, and Blink by rejecting "not", "or", or "and" not followed by a space:
https://drafts.csswg.org/css-conditional-3/#typedef-supports-decl

* LayoutTests/TestExpectations: Removed failing expectations from now passing tests.
* LayoutTests/css3/supports-dom-api.html:
* LayoutTests/css3/supports-expected.txt:
* LayoutTests/css3/supports.html:
* Source/WebCore/css/parser/CSSSupportsParser.cpp:
(WebCore::CSSSupportsParser::consumeCondition):
(WebCore::CSSSupportsParser::consumeNegation):

Canonical link: https://commits.webkit.org/253194@main
  • Loading branch information
rniwa committed Aug 7, 2022
1 parent c42eefc commit dcf7924cd7cf05120372b2e4645316c473fd9e56
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 25 deletions.
@@ -1837,15 +1837,10 @@ imported/w3c/web-platform-tests/html/semantics/embedded-content/the-object-eleme
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-video-element/intrinsicsize/intrinsicsize-without-unsized-media.tentative.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-video-element/video-poster-shown-preload-auto.html [ Skip ]

# @supports W3C Failures
webkit.org/b/137568 imported/w3c/web-platform-tests/css/css-conditional/at-supports-014.html [ ImageOnlyFailure ]
webkit.org/b/216003 imported/w3c/web-platform-tests/css/css-conditional/at-supports-043.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/at-supports-046.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/at-supports-namespace-001.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/at-supports-namespace-002.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/css-supports-036.xht [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/css-supports-038.xht [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-conditional/css-supports-039.xht [ ImageOnlyFailure ]

transitions/svg-text-shadow-transition.html [ Failure ]
webkit.org/b/137883 transitions/background-transitions.html [ Failure Pass ]
@@ -33,10 +33,10 @@ PASS CSS.supports("not (display: deadbeef) and (display: block)") is false
PASS CSS.supports("(not (border: 1px 1px 1px 1px 1px solid #000)) and (display: block)") is true
PASS CSS.supports("(display: block !important) and ((display: inline) or (display: deadbeef))") is true
PASS CSS.supports("not ((not (display: block)) or ((display: none) and (deadbeef: 1px)))") is true
PASS CSS.supports("not( display: deadbeef)") is true
PASS CSS.supports("not( display: deadbeef)") is false
PASS CSS.supports("(display: none)and ( -webkit-transition: all 1s )") is true
PASS CSS.supports("(display: none)or(-webkit-transition: all 1s)") is true
PASS CSS.supports("(display: none) or(-webkit-transition: all 1s )") is true
PASS CSS.supports("(display: none)or(-webkit-transition: all 1s)") is false
PASS CSS.supports("(display: none) or(-webkit-transition: all 1s )") is false
PASS CSS.supports("(((((((display: none)))))))") is true
PASS CSS.supports("(!important)") is false
PASS CSS.supports("!important") is false
@@ -50,10 +50,10 @@
shouldBeTrue('CSS.supports("not ((not (display: block)) or ((display: none) and (deadbeef: 1px)))")');

// Whitespace/Syntax.
shouldBeTrue('CSS.supports("not( display: deadbeef)")');
shouldBeFalse('CSS.supports("not( display: deadbeef)")');
shouldBeTrue('CSS.supports("(display: none)and ( -webkit-transition: all 1s )")');
shouldBeTrue('CSS.supports("(display: none)or(-webkit-transition: all 1s)")');
shouldBeTrue('CSS.supports("(display: none) or(-webkit-transition: all 1s )")');
shouldBeFalse('CSS.supports("(display: none)or(-webkit-transition: all 1s)")');
shouldBeFalse('CSS.supports("(display: none) or(-webkit-transition: all 1s )")');
shouldBeTrue('CSS.supports("(((((((display: none)))))))")');
shouldBeFalse('CSS.supports("(!important)")');
shouldBeFalse('CSS.supports("!important")');
@@ -25,10 +25,10 @@ PASS getComputedStyle(document.getElementById('t18')).content is "\"UNTOUCHED\""
PASS getComputedStyle(document.getElementById('t19')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t20')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t21')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t22')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t22')).content is "\"UNTOUCHED\""
PASS getComputedStyle(document.getElementById('t23')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t24')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t25')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t24')).content is "\"UNTOUCHED\""
PASS getComputedStyle(document.getElementById('t25')).content is "\"UNTOUCHED\""
PASS getComputedStyle(document.getElementById('t26')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t27')).content is "\"APPLIED\""
PASS getComputedStyle(document.getElementById('t28')).content is "\"UNTOUCHED\""
@@ -86,19 +86,19 @@

/* Whitespace/Syntax */
@supports not( display: deadbeef) {
#t22 { content: "APPLIED" }
#t22 { content: "FAIL" }
}

@supports (display: none)and ( -webkit-transition: all 1s ) {
#t23 { content: "APPLIED" }
}

@supports (display: none)or(-webkit-transition: all 1s) {
#t24 { content: "APPLIED" }
#t24 { content: "FAIL" }
}

@supports (display: none) or(-webkit-transition: all 1s ) {
#t25 { content: "APPLIED" }
#t25 { content: "FAIL" }
}

@supports (((((((display: none))))))) {
@@ -231,7 +231,7 @@
<script>
description("Test the @supports rule.");
var numTests = 45;
var untouchedTests = [1, 3, 5, 8, 12, 13, 14, 18, 28, 29, 34, 36, 43, 44]; // Tests whose content shouldn't change from the UNTOUCHED default.
var untouchedTests = [1, 3, 5, 8, 12, 13, 14, 18, 22, 24, 25, 28, 29, 34, 36, 43, 44]; // Tests whose content shouldn't change from the UNTOUCHED default.

var container = document.getElementById("test_container");
for (var i=0; i < numTests; i++) {
@@ -56,7 +56,7 @@ enum ClauseType { Unresolved, Conjunction, Disjunction };

CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange range)
{
if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken) {
if (range.peek().type() == IdentToken) {
if (equalLettersIgnoringASCIICase(range.peek().value(), "not"_s))
return consumeNegation(range);
}
@@ -85,30 +85,35 @@ CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserT
break;

const CSSParserToken& token = range.peek();
if (token.type() != IdentToken && token.type() != FunctionToken)
if (token.type() != IdentToken)
return Invalid;

previousTokenType = token.type();

if (clauseType == Unresolved)
clauseType = token.value().length() == 3 ? Conjunction : Disjunction;
if ((clauseType == Conjunction && !equalLettersIgnoringASCIICase(token.value(), "and"_s))
|| (clauseType == Disjunction && !equalLettersIgnoringASCIICase(token.value(), "or"_s)))
return Invalid;

if (token.type() == IdentToken)
range.consumeIncludingWhitespace();
range.consume();
if (range.peek().type() != WhitespaceToken)
return Invalid;
range.consumeWhitespace();
}
return result ? Supported : Unsupported;
}

CSSSupportsParser::SupportsResult CSSSupportsParser::consumeNegation(CSSParserTokenRange range)
{
ASSERT(range.peek().type() == IdentToken || range.peek().type() == FunctionToken);
ASSERT(range.peek().type() == IdentToken);
auto tokenType = range.peek().type();

if (range.peek().type() == IdentToken)
range.consumeIncludingWhitespace();
range.consume();
if (range.peek().type() != WhitespaceToken)
return Invalid;
range.consumeWhitespace();
auto result = consumeConditionInParenthesis(range, tokenType);
range.consumeWhitespace();
if (!range.atEnd() || result == Invalid)

0 comments on commit dcf7924

Please sign in to comment.