Bug 1338486: Support implied parentheses in CSS.supports; r?dholbert draft
authorManish Goregaokar <manishearth@gmail.com>
Sun, 04 Jun 2017 03:45:05 -0700
changeset 588746 1dfe3ec2f02553ee6bc547bbfb16a51b3c9ee974
parent 588345 87c745019518b1d6cd782534f2553721e5735657
child 631664 c639aec43f82588458465be1854f733eb7fb8a0f
push id62140
push userbmo:manishearth@gmail.com
push dateSun, 04 Jun 2017 10:45:58 +0000
reviewersdholbert
bugs1338486
milestone55.0a1
Bug 1338486: Support implied parentheses in CSS.supports; r?dholbert MozReview-Commit-ID: CUo371Hvj4T
layout/style/CSS.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSParser.h
layout/style/test/stylo-failures.md
layout/style/test/test_css_supports.html
--- a/layout/style/CSS.cpp
+++ b/layout/style/CSS.cpp
@@ -88,17 +88,18 @@ CSS::Supports(const GlobalObject& aGloba
 
   if (info.mStyleBackendType == StyleBackendType::Servo) {
     NS_ConvertUTF16toUTF8 cond(aCondition);
     return Servo_CSSSupports(&cond);
   }
 
   nsCSSParser parser;
   return parser.EvaluateSupportsCondition(aCondition, info.mDocURI,
-                                          info.mBaseURI, info.mPrincipal);
+                                          info.mBaseURI, info.mPrincipal,
+                                          /* impliedParentheses */ true);
 }
 
 /* static */ void
 CSS::Escape(const GlobalObject& aGlobal,
             const nsAString& aIdent,
             nsAString& aReturn)
 {
   nsStyleUtil::AppendEscapedCSSIdent(aIdent, aReturn);
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -258,17 +258,18 @@ public:
                                    const nsAString& aValue,
                                    nsIURI* aDocURL,
                                    nsIURI* aBaseURL,
                                    nsIPrincipal* aDocPrincipal);
 
   bool EvaluateSupportsCondition(const nsAString& aCondition,
                                  nsIURI* aDocURL,
                                  nsIURI* aBaseURL,
-                                 nsIPrincipal* aDocPrincipal);
+                                 nsIPrincipal* aDocPrincipal,
+                                 bool impliedParentheses = false);
 
   already_AddRefed<nsIAtom> ParseCounterStyleName(const nsAString& aBuffer,
                                                   nsIURI* aURL);
 
   bool ParseCounterDescriptor(nsCSSCounterDesc aDescID,
                               const nsAString& aBuffer,
                               nsIURI* aSheetURL,
                               nsIURI* aBaseURL,
@@ -2409,25 +2410,33 @@ CSSParserImpl::EvaluateSupportsDeclarati
 
   return parsedOK;
 }
 
 bool
 CSSParserImpl::EvaluateSupportsCondition(const nsAString& aDeclaration,
                                          nsIURI* aDocURL,
                                          nsIURI* aBaseURL,
-                                         nsIPrincipal* aDocPrincipal)
+                                         nsIPrincipal* aDocPrincipal,
+                                         bool impliedParentheses)
 {
   nsCSSScanner scanner(aDeclaration, 0);
   css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aDocURL);
   InitScanner(scanner, reporter, aDocURL, aBaseURL, aDocPrincipal);
   nsAutoSuppressErrors suppressErrors(this);
 
   bool conditionMet;
-  bool parsedOK = ParseSupportsCondition(conditionMet) && !GetToken(true);
+  bool parsedOK;
+
+  if (impliedParentheses) {
+    parsedOK = ParseSupportsConditionInParensInsideParens(conditionMet) && !GetToken(true);
+  } else {
+    parsedOK = ParseSupportsCondition(conditionMet) && !GetToken(true);
+  }
+  
 
   CLEAR_ERROR();
   ReleaseScanner();
 
   return parsedOK && conditionMet;
 }
 
 bool
@@ -18163,20 +18172,22 @@ nsCSSParser::EvaluateSupportsDeclaration
     EvaluateSupportsDeclaration(aProperty, aValue, aDocURL, aBaseURL,
                                 aDocPrincipal);
 }
 
 bool
 nsCSSParser::EvaluateSupportsCondition(const nsAString& aCondition,
                                        nsIURI* aDocURL,
                                        nsIURI* aBaseURL,
-                                       nsIPrincipal* aDocPrincipal)
+                                       nsIPrincipal* aDocPrincipal,
+                                         bool impliedParentheses)
 {
   return static_cast<CSSParserImpl*>(mImpl)->
-    EvaluateSupportsCondition(aCondition, aDocURL, aBaseURL, aDocPrincipal);
+    EvaluateSupportsCondition(aCondition, aDocURL, aBaseURL,
+                              aDocPrincipal, impliedParentheses);
 }
 
 bool
 nsCSSParser::EnumerateVariableReferences(const nsAString& aPropertyValue,
                                          VariableEnumFunc aFunc,
                                          void* aData)
 {
   return static_cast<CSSParserImpl*>(mImpl)->
--- a/layout/style/nsCSSParser.h
+++ b/layout/style/nsCSSParser.h
@@ -247,21 +247,26 @@ public:
                                    const nsAString& aValue,
                                    nsIURI* aDocURL,
                                    nsIURI* aBaseURL,
                                    nsIPrincipal* aDocPrincipal);
 
   /**
    * Parse an @supports condition and returns the result of evaluating the
    * condition.
+   *
+   * The one-argument CSS.supports() allows for providing a parentheses-less
+   * @supports condition, i.e. the parentheses are "implied". In such a case,
+   * impliedParentheses can be set to true.
    */
   bool EvaluateSupportsCondition(const nsAString& aCondition,
                                  nsIURI* aDocURL,
                                  nsIURI* aBaseURL,
-                                 nsIPrincipal* aDocPrincipal);
+                                 nsIPrincipal* aDocPrincipal,
+                                 bool impliedParentheses = false);
 
   typedef void (*VariableEnumFunc)(const nsAString&, void*);
 
   /**
    * Parses aPropertyValue as a property value and calls aFunc for each
    * variable reference that is found.  Returns false if there was
    * a syntax error in the use of variable references.
    */
--- a/layout/style/test/stylo-failures.md
+++ b/layout/style/test/stylo-failures.md
@@ -110,17 +110,17 @@ to mochitest command.
     * test_selectors.html `:dir` [11]
 * Quirks mode support
   * test_hover_quirk.html: hover quirks bug 1355724 [6]
 * Unit should be preserved after parsing servo/servo#15346
   * test_units_time.html [1]
 * getComputedStyle style doesn't contain custom properties bug 1336891
   * test_variable_serialization_computed.html [35]
   * test_variables.html `custom property name` [2]
-* test_css_supports.html: issues around @supports syntax servo/servo#15482 [8]
+* test_css_supports.html: issues around @supports syntax servo/servo#15482 [7]
 * test_author_specified_style.html: support serializing color as author specified bug 1348165 [27]
 * browser_newtab_share_rule_processors.js: agent style sheet sharing [1]
 * :visited support (bug 1328509)
   * test_visited_reftests.html `selector-descendant-2.xhtml` [2]
   * ... `selector-child-2.xhtml` [2]
   * ... `color-on-bullets-1.html` [2]
   * ... `inherit-keyword-1.xhtml` [2]
   * ... `mathml-links.html` [2]
--- a/layout/style/test/test_css_supports.html
+++ b/layout/style/test/test_css_supports.html
@@ -17,16 +17,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 779917 **/
 
 function runTest()
 {
   var passingConditions = [
+    "color: green",
     "(color: green)",
     "((color: green))",
     "(color: green !important)",
     "(color: rainbow) or (color: green)",
     "(color: green) or (color: rainbow)",
     "(color: green) and (color: blue)",
     "(color: rainbow) or (color: iridescent) or (color: green)",
     "(color: red) and (color: green) and (color: blue)",
@@ -64,17 +65,16 @@ function runTest()
     "not (color: rainbow) and not (color: iridescent)",
     "not (color: rainbow) or (color: green)",
     "(not (color: rainbow) or (color: green))",
     "(unknown: green)",
     "not ({ something @with (unbalanced brackets })",
     "(color: green) or an-extension(that is [unbalanced)",
     "not(unknown: unknown)",
     "(color: green) or(color: blue)",
-    "color: green",
     "(color: green;)",
     "(font-family: 'Helvetica\n",
     "(font-family: 'Helvetica\n')",
     "()",
     ""
   ];
 
   var passingDeclarations = [