Bug 773296 - Part 12: Record whether we are parsing an @supports condition. r=dbaron
authorCameron McCormack <cam@mcc.id.au>
Thu, 12 Dec 2013 13:09:42 +1100
changeset 160106 88fd50578a763adeaefbf1214e3e4c5cf75598ac
parent 160105 246d623b5259994d18d02abb5321182ea42ce514
child 160107 27256a46adbbec1f866c38502a426bd80bc40f1d
push id3938
push usercbook@mozilla.com
push dateThu, 12 Dec 2013 15:09:56 +0000
treeherderfx-team@0cf1107e2791 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs773296
milestone29.0a1
Bug 773296 - Part 12: Record whether we are parsing an @supports condition. r=dbaron This stores on the nsCSSParser whether we are somewhere in the middle of parsing an @supports condition. Because @supports condition parsing uses the scanner recording function (to save its conditionText), and variable reference containing values also need it, we can't do both at once. Luckily, if we're parsing an @supports condition, we don't really need to store the token stream text; we only need to know if it was valid, and we don't need its actual value later. So we use this flag later to see if we can skip turning on scanner recording while parsing variable reference containing values.
layout/style/nsCSSParser.cpp
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -823,16 +823,21 @@ protected:
   // True for parsing media lists for HTML attributes, where we have to
   // ignore CSS comments.
   bool mHTMLMediaMode : 1;
 
   // This flag is set when parsing a non-box shorthand; it's used to not apply
   // some quirks during shorthand parsing
   bool          mParsingCompoundProperty : 1;
 
+  // True if we are in the middle of parsing an @supports condition.
+  // This is used to avoid recording the input stream when variable references
+  // are encountered in a property declaration in the @supports condition.
+  bool mInSupportsCondition : 1;
+
   // True if we are somewhere within a @supports rule whose condition is
   // false.
   bool mInFailingSupportsRule : 1;
 
   // True if we will suppress all parse errors (except unexpected EOFs).
   // This is used to prevent errors for declarations inside a failing
   // @supports rule.
   bool mSuppressErrors : 1;
@@ -901,16 +906,17 @@ CSSParserImpl::CSSParserImpl()
     mHavePushBack(false),
     mNavQuirkMode(false),
     mHashlessColorQuirk(false),
     mUnitlessLengthQuirk(false),
     mUnsafeRulesEnabled(false),
     mViewportUnitsEnabled(true),
     mHTMLMediaMode(false),
     mParsingCompoundProperty(false),
+    mInSupportsCondition(false),
     mInFailingSupportsRule(false),
     mSuppressErrors(false),
     mNextFree(nullptr)
 {
 }
 
 CSSParserImpl::~CSSParserImpl()
 {
@@ -3335,41 +3341,48 @@ CSSParserImpl::ParseSupportsRule(RuleApp
 
 // supports_condition
 //   : supports_condition_in_parens supports_condition_terms
 //   | supports_condition_negation
 //   ;
 bool
 CSSParserImpl::ParseSupportsCondition(bool& aConditionMet)
 {
+  mInSupportsCondition = true;
+
   if (!GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PESupportsConditionStartEOF2);
     return false;
   }
 
   UngetToken();
 
   mScanner->ClearSeenBadToken();
 
   if (mToken.IsSymbol('(') ||
       mToken.mType == eCSSToken_Function ||
       mToken.mType == eCSSToken_URL ||
       mToken.mType == eCSSToken_Bad_URL) {
-    return ParseSupportsConditionInParens(aConditionMet) &&
-           ParseSupportsConditionTerms(aConditionMet) &&
-           !mScanner->SeenBadToken();
+    bool result = ParseSupportsConditionInParens(aConditionMet) &&
+                  ParseSupportsConditionTerms(aConditionMet) &&
+                  !mScanner->SeenBadToken();
+    mInSupportsCondition = false;
+    return result;
   }
 
   if (mToken.mType == eCSSToken_Ident &&
       mToken.mIdent.LowerCaseEqualsLiteral("not")) {
-    return ParseSupportsConditionNegation(aConditionMet) &&
-           !mScanner->SeenBadToken();
+    bool result = ParseSupportsConditionNegation(aConditionMet) &&
+                  !mScanner->SeenBadToken();
+    mInSupportsCondition = false;
+    return result;
   }
 
   REPORT_UNEXPECTED_TOKEN(PESupportsConditionExpectedStart);
+  mInSupportsCondition = false;
   return false;
 }
 
 // supports_condition_negation
 //   : 'not' S+ supports_condition_in_parens
 //   ;
 bool
 CSSParserImpl::ParseSupportsConditionNegation(bool& aConditionMet)