-
-
Save emilio/812eed04fa62e1d696c7ba1f0223f16c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 665e847a61fdada67d77b7c65977c88c2d61c223 Mon Sep 17 00:00:00 2001 | |
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <ecobos@igalia.com> | |
Date: Mon, 5 Jun 2017 00:31:34 +0200 | |
Subject: [PATCH] wip | |
MIME-Version: 1.0 | |
Content-Type: text/plain; charset=UTF-8 | |
Content-Transfer-Encoding: 8bit | |
Signed-off-by: Emilio Cobos Álvarez <ecobos@igalia.com> | |
--- | |
LayoutTests/css3/supports-dom-api-expected.txt | 13 ++++++++ | |
LayoutTests/css3/supports-dom-api.html | 14 +++++++++ | |
Source/WebCore/css/parser/CSSParserTokenRange.h | 4 +++ | |
Source/WebCore/css/parser/CSSSupportsParser.cpp | 42 +++++++++++++++---------- | |
Source/WebCore/css/parser/CSSSupportsParser.h | 6 ++-- | |
5 files changed, 60 insertions(+), 19 deletions(-) | |
diff --git a/LayoutTests/css3/supports-dom-api-expected.txt b/LayoutTests/css3/supports-dom-api-expected.txt | |
index 9c9776c2f31..acc73f1b9fd 100644 | |
--- a/LayoutTests/css3/supports-dom-api-expected.txt | |
+++ b/LayoutTests/css3/supports-dom-api-expected.txt | |
@@ -4,6 +4,15 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE | |
PASS CSS.supports("display: none") is true | |
+PASS CSS.supports("display: deadbeef") is false | |
+PASS CSS.supports("(display: none) and ((display: block) or (display: inline))") is true | |
+PASS CSS.supports("(not (display: deadbeef)) and (display: block)") is true | |
+PASS CSS.supports("top: -webkit-calc(80% - 20px)") is true | |
+PASS CSS.supports("background-color: rgb(0, 128, 0)") is true | |
+PASS CSS.supports("background: url('/blah')") is true | |
+PASS CSS.supports("background: invalid('/blah')") is false | |
+PASS CSS.supports("display: none;") is false | |
+PASS CSS.supports("display: none; garbage") is false | |
PASS CSS.supports("(display: none)") is true | |
PASS CSS.supports("(display: deadbeef)") is false | |
PASS CSS.supports("not (display: deadbeef)") is true | |
@@ -19,6 +28,8 @@ PASS CSS.supports("(display: none) or (display: deadbeef) or (display: inline)") | |
PASS CSS.supports("(display: ohhai) or (display: deadbeef) or (display: rainbows)") is false | |
PASS CSS.supports("(display: none) and (display: block) or (display: inline)") is false | |
PASS CSS.supports("not (display: deadbeef) and (display: block)") is false | |
+PASS CSS.supports("(display: none) and (display: block) or (display: inline)") is false | |
+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 | |
@@ -28,7 +39,9 @@ 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)))))))") is true | |
PASS CSS.supports("(!important)") is false | |
+PASS CSS.supports("!important") is false | |
PASS CSS.supports("not not not not (display: none)") is false | |
+PASS CSS.supports("top baz bar: -webkit-calc(80% - 20px)") is false | |
PASS CSS.supports("(top: -webkit-calc(80% - 20px))") is true | |
PASS CSS.supports("(background-color: rgb(0, 128, 0))") is true | |
PASS CSS.supports("(background: url('/blah'))") is true | |
diff --git a/LayoutTests/css3/supports-dom-api.html b/LayoutTests/css3/supports-dom-api.html | |
index 4d240b57df6..be066515a60 100644 | |
--- a/LayoutTests/css3/supports-dom-api.html | |
+++ b/LayoutTests/css3/supports-dom-api.html | |
@@ -8,6 +8,16 @@ | |
description("Test window.CSS.supports()"); | |
shouldBeTrue('CSS.supports("display: none")'); | |
+ shouldBeFalse('CSS.supports("display: deadbeef")'); | |
+ shouldBeTrue('CSS.supports("(display: none) and ((display: block) or (display: inline))")'); | |
+ shouldBeTrue('CSS.supports("(not (display: deadbeef)) and (display: block)")'); | |
+ shouldBeTrue('CSS.supports("top: -webkit-calc(80% - 20px)")'); | |
+ shouldBeTrue('CSS.supports("background-color: rgb(0, 128, 0)")'); | |
+ shouldBeTrue('CSS.supports("background: url(\'/blah\')")'); | |
+ shouldBeFalse('CSS.supports("background: invalid(\'/blah\')")'); | |
+ shouldBeFalse('CSS.supports("display: none;")'); | |
+ shouldBeFalse('CSS.supports("display: none; garbage")'); | |
+ | |
shouldBeTrue('CSS.supports("(display: none)")'); | |
shouldBeFalse('CSS.supports("(display: deadbeef)")'); | |
@@ -31,6 +41,8 @@ | |
// Bad syntax. Can't mix operators without a layer of parentheses.. | |
shouldBeFalse('CSS.supports("(display: none) and (display: block) or (display: inline)")'); | |
shouldBeFalse('CSS.supports("not (display: deadbeef) and (display: block)")'); | |
+ shouldBeFalse('CSS.supports("(display: none) and (display: block) or (display: inline)")'); | |
+ shouldBeFalse('CSS.supports("not (display: deadbeef) and (display: block)")'); | |
// Mix 'n match. | |
shouldBeTrue('CSS.supports("(not (border: 1px 1px 1px 1px 1px solid #000)) and (display: block)")'); | |
@@ -44,7 +56,9 @@ | |
shouldBeTrue('CSS.supports("(display: none) or(-webkit-transition: all 1s )")'); | |
shouldBeTrue('CSS.supports("(((((((display: none)))))))")'); | |
shouldBeFalse('CSS.supports("(!important)")'); | |
+ shouldBeFalse('CSS.supports("!important")'); | |
shouldBeFalse('CSS.supports("not not not not (display: none)")'); | |
+ shouldBeFalse('CSS.supports("top baz bar: -webkit-calc(80% - 20px)")'); | |
// Functions. | |
shouldBeTrue('CSS.supports("(top: -webkit-calc(80% - 20px))")'); | |
diff --git a/Source/WebCore/css/parser/CSSParserTokenRange.h b/Source/WebCore/css/parser/CSSParserTokenRange.h | |
index 8a9dd439db5..624643b3f82 100644 | |
--- a/Source/WebCore/css/parser/CSSParserTokenRange.h | |
+++ b/Source/WebCore/css/parser/CSSParserTokenRange.h | |
@@ -85,6 +85,10 @@ public: | |
++m_first; | |
} | |
+ void consumeFully() { | |
+ m_first = m_last; | |
+ } | |
+ | |
String serialize() const; | |
const CSSParserToken* begin() const { return m_first; } | |
diff --git a/Source/WebCore/css/parser/CSSSupportsParser.cpp b/Source/WebCore/css/parser/CSSSupportsParser.cpp | |
index 8222f8bc6bb..ae99ac1d8ed 100644 | |
--- a/Source/WebCore/css/parser/CSSSupportsParser.cpp | |
+++ b/Source/WebCore/css/parser/CSSSupportsParser.cpp | |
@@ -36,32 +36,29 @@ namespace WebCore { | |
CSSSupportsParser::SupportsResult CSSSupportsParser::supportsCondition(CSSParserTokenRange range, CSSParserImpl& parser, SupportsParsingMode mode) | |
{ | |
- bool implicitParentheses = mode == ForWindowCSS; | |
// FIXME: The spec allows leading whitespace in @supports but not CSS.supports, | |
// but major browser vendors allow it in CSS.supports also. | |
range.consumeWhitespace(); | |
- auto result = CSSSupportsParser(parser).consumeCondition(range); | |
- if (!implicitParentheses || result != Invalid) | |
- return result; | |
- return range.peek().type() == IdentToken && parser.supportsDeclaration(range) ? Supported : Unsupported; | |
+ return CSSSupportsParser(parser).consumeCondition(range, mode == ForWindowCSS); | |
} | |
enum ClauseType { Unresolved, Conjunction, Disjunction }; | |
-CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange range) | |
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange& range, bool alreadyUnwrapped) | |
{ | |
- if (range.peek().type() == IdentToken || range.peek().type() == FunctionToken) | |
+ if (!alreadyUnwrapped && (range.peek().type() == IdentToken || range.peek().type() == FunctionToken)) | |
return consumeNegation(range); | |
bool result; | |
ClauseType clauseType = Unresolved; | |
- | |
+ | |
auto previousTokenType = IdentToken; | |
while (true) { | |
- SupportsResult nextResult = consumeConditionInParenthesis(range, previousTokenType); | |
+ SupportsResult nextResult = alreadyUnwrapped ? consumeUnwrappedCondition(range) : consumeConditionInParenthesis(range, previousTokenType); | |
if (nextResult == Invalid) | |
return Invalid; | |
+ alreadyUnwrapped = false; | |
bool nextSupported = nextResult; | |
if (clauseType == Unresolved) | |
result = nextSupported; | |
@@ -94,7 +91,7 @@ CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserT | |
return result ? Supported : Unsupported; | |
} | |
-CSSSupportsParser::SupportsResult CSSSupportsParser::consumeNegation(CSSParserTokenRange range) | |
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeNegation(CSSParserTokenRange& range) | |
{ | |
ASSERT(range.peek().type() == IdentToken || range.peek().type() == FunctionToken); | |
auto tokenType = range.peek().type(); | |
@@ -116,16 +113,27 @@ CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthes | |
CSSParserTokenRange innerRange = range.consumeBlock(); | |
innerRange.consumeWhitespace(); | |
- SupportsResult result = consumeCondition(innerRange); | |
- if (result != Invalid) | |
- return result; | |
- | |
- if (innerRange.peek().type() == FunctionToken) { | |
- innerRange.consumeComponentValue(); | |
+ return consumeUnwrappedCondition(innerRange); | |
+} | |
+ | |
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeUnwrappedCondition(CSSParserTokenRange& range) | |
+{ | |
+ { | |
+ CSSParserTokenRange copy = range; | |
+ SupportsResult result = consumeCondition(range); | |
+ if (result != Invalid) | |
+ return result; | |
+ range = copy; | |
+ } | |
+ | |
+ if (range.peek().type() == FunctionToken) { | |
+ range.consumeComponentValue(); | |
return Unsupported; | |
} | |
- return innerRange.peek().type() == IdentToken && m_parser.supportsDeclaration(innerRange) ? Supported : Unsupported; | |
+ bool result = range.peek().type() == IdentToken && m_parser.supportsDeclaration(range); | |
+ range.consumeFully(); | |
+ return result ? Supported : Unsupported; | |
} | |
} // namespace WebCore | |
diff --git a/Source/WebCore/css/parser/CSSSupportsParser.h b/Source/WebCore/css/parser/CSSSupportsParser.h | |
index 577ff2ccc36..ae180bf6e6d 100644 | |
--- a/Source/WebCore/css/parser/CSSSupportsParser.h | |
+++ b/Source/WebCore/css/parser/CSSSupportsParser.h | |
@@ -55,11 +55,13 @@ private: | |
CSSSupportsParser(CSSParserImpl& parser) | |
: m_parser(parser) { } | |
- SupportsResult consumeCondition(CSSParserTokenRange); | |
- SupportsResult consumeNegation(CSSParserTokenRange); | |
+ SupportsResult consumeCondition(CSSParserTokenRange&, bool allowImplicitParenthesis = false); | |
+ SupportsResult consumeNegation(CSSParserTokenRange&); | |
SupportsResult consumeConditionInParenthesis(CSSParserTokenRange&, CSSParserTokenType); | |
+ SupportsResult consumeUnwrappedCondition(CSSParserTokenRange&); | |
+ | |
CSSParserImpl& m_parser; | |
}; | |
-- | |
2.13.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment