Back out 6d1c0e678b61 (Bug 689319) because of test failures
authorMatt Brubeck <mbrubeck@mozilla.com>
Fri, 30 Sep 2011 14:11:24 -0700
changeset 77938 c59e1d1d8615b5ebfcd29772171670bf55e4f8e1
parent 77937 746002692d9302bcee68c3365978fbf178fc1041
child 77939 54b59144ace116a4e35a4723e6fa13f4475f4048
push id21257
push usermak77@bonardo.net
push dateSat, 01 Oct 2011 09:11:07 +0000
treeherdermozilla-central@164fd1bbd06f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs689319
milestone10.0a1
backs out6d1c0e678b613589b601606da0552513d71b9d4c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 6d1c0e678b61 (Bug 689319) because of test failures
layout/style/nsCSSParser.cpp
layout/style/nsCSSStyleSheet.cpp
layout/style/nsIMediaList.h
layout/style/test/test_media_queries.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -336,17 +336,17 @@ protected:
                       bool aInsideBraces = false);
   bool ParseAtRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseCharsetRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseImportRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseURLOrString(nsString& aURL);
   bool GatherMedia(nsMediaList* aMedia,
                      bool aInAtRule);
   bool ParseMediaQuery(bool aInAtRule, nsMediaQuery **aQuery,
-                         bool *aHitStop);
+                         bool *aParsedSomething, bool *aHitStop);
   bool ParseMediaQueryExpression(nsMediaQuery* aQuery);
   void ProcessImport(const nsString& aURLSpec,
                      nsMediaList* aMedia,
                      RuleAppendFunc aAppendFunc,
                      void* aProcessData);
   bool ParseGroupRule(css::GroupRule* aRule, RuleAppendFunc aAppendFunc,
                         void* aProcessData);
   bool ParseMediaRule(RuleAppendFunc aAppendFunc, void* aProcessData);
@@ -1172,18 +1172,23 @@ CSSParserImpl::ParseMediaList(const nsSu
   // http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors
   // which wouldn't work for media queries since they remove all but the
   // first word.  However, they're changed in
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/section-document.html#media2
   // (as of 2008-05-29) which says that the media attribute just points
   // to a media query.  (The main substative difference is the relative
   // precedence of commas and paretheses.)
 
-  GatherMedia(aMediaList, false); // can only fail on low-level error (OOM)
-
+  if (!GatherMedia(aMediaList, PR_FALSE)) {
+    aMediaList->Clear();
+    aMediaList->SetNonEmpty(); // don't match anything
+    if (!mHTMLMediaMode) {
+      OUTPUT_ERROR();
+    }
+  }
   nsresult rv = mScanner.GetLowLevelError();
   CLEAR_ERROR();
   ReleaseScanner();
   mHTMLMediaMode = PR_FALSE;
 
   return rv;
 }
 
@@ -1617,19 +1622,21 @@ CSSParserImpl::ParseURLOrString(nsString
   }
   UngetToken();
   return PR_FALSE;
 }
 
 bool
 CSSParserImpl::ParseMediaQuery(bool aInAtRule,
                                nsMediaQuery **aQuery,
+                               bool *aParsedSomething,
                                bool *aHitStop)
 {
   *aQuery = nsnull;
+  *aParsedSomething = PR_FALSE;
   *aHitStop = PR_FALSE;
 
   // "If the comma-separated list is the empty list it is assumed to
   // specify the media query 'all'."  (css3-mediaqueries, section
   // "Media Queries")
   if (!GetToken(PR_TRUE)) {
     *aHitStop = PR_TRUE;
     // expected termination by EOF
@@ -1644,18 +1651,19 @@ CSSParserImpl::ParseMediaQuery(bool aInA
   if (eCSSToken_Symbol == mToken.mType && aInAtRule &&
       (mToken.mSymbol == ';' || mToken.mSymbol == '{')) {
     *aHitStop = PR_TRUE;
     UngetToken();
     return PR_TRUE;
   }
   UngetToken();
 
-  nsMediaQuery* query = new nsMediaQuery;
-  *aQuery = query;
+  *aParsedSomething = PR_TRUE;
+
+  nsAutoPtr<nsMediaQuery> query(new nsMediaQuery);
   if (!query) {
     mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
     return PR_FALSE;
   }
 
   if (ExpectSymbol('(', PR_TRUE)) {
     // we got an expression without a media type
     UngetToken(); // so ParseMediaQueryExpression can handle it
@@ -1722,52 +1730,52 @@ CSSParserImpl::ParseMediaQuery(bool aInA
       UngetToken();
       return PR_FALSE;
     }
     if (!ParseMediaQueryExpression(query)) {
       OUTPUT_ERROR();
       query->SetHadUnknownExpression();
     }
   }
+  *aQuery = query.forget();
   return PR_TRUE;
 }
 
 // Returns false only when there is a low-level error in the scanner
 // (out-of-memory).
 bool
 CSSParserImpl::GatherMedia(nsMediaList* aMedia,
                            bool aInAtRule)
 {
   for (;;) {
     nsAutoPtr<nsMediaQuery> query;
-    bool hitStop;
+    bool parsedSomething, hitStop;
     if (!ParseMediaQuery(aInAtRule, getter_Transfers(query),
-                         &hitStop)) {
+                         &parsedSomething, &hitStop)) {
       NS_ASSERTION(!hitStop, "should return true when hit stop");
-      OUTPUT_ERROR();
       if (NS_FAILED(mScanner.GetLowLevelError())) {
         return PR_FALSE;
       }
-      if (query) {
-        query->SetHadUnknownExpression();
-      }
       if (aInAtRule) {
         const PRUnichar stopChars[] =
           { PRUnichar(','), PRUnichar('{'), PRUnichar(';'), PRUnichar(0) };
         SkipUntilOneOf(stopChars);
       } else {
         SkipUntil(',');
       }
       // Rely on SkipUntilOneOf leaving mToken around as the last token read.
       if (mToken.mType == eCSSToken_Symbol && aInAtRule &&
           (mToken.mSymbol == '{' || mToken.mSymbol == ';')) {
         UngetToken();
         hitStop = PR_TRUE;
       }
     }
+    if (parsedSomething) {
+      aMedia->SetNonEmpty();
+    }
     if (query) {
       nsresult rv = aMedia->AppendQuery(query);
       if (NS_FAILED(rv)) {
         mScanner.SetLowLevelError(rv);
         return PR_FALSE;
       }
     }
     if (hitStop) {
--- a/layout/style/nsCSSStyleSheet.cpp
+++ b/layout/style/nsCSSStyleSheet.cpp
@@ -537,29 +537,34 @@ NS_INTERFACE_MAP_BEGIN(nsMediaList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MediaList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsMediaList)
 NS_IMPL_RELEASE(nsMediaList)
 
 
 nsMediaList::nsMediaList()
-  : mStyleSheet(nsnull)
+  : mIsEmpty(PR_TRUE)
+  , mStyleSheet(nsnull)
 {
 }
 
 nsMediaList::~nsMediaList()
 {
 }
 
 nsresult
 nsMediaList::GetText(nsAString& aMediaText)
 {
   aMediaText.Truncate();
 
+  if (mArray.Length() == 0 && !mIsEmpty) {
+    aMediaText.AppendLiteral("not all");
+  }
+
   for (PRInt32 i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     nsMediaQuery* query = mArray[i];
     NS_ENSURE_TRUE(query, NS_ERROR_FAILURE);
 
     query->AppendToString(aMediaText);
 
     if (i + 1 < i_end) {
       aMediaText.AppendLiteral(", ");
@@ -591,17 +596,17 @@ bool
 nsMediaList::Matches(nsPresContext* aPresContext,
                      nsMediaQueryResultCacheKey* aKey)
 {
   for (PRInt32 i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     if (mArray[i]->Matches(aPresContext, aKey)) {
       return PR_TRUE;
     }
   }
-  return mArray.IsEmpty();
+  return mIsEmpty;
 }
 
 nsresult
 nsMediaList::SetStyleSheet(nsCSSStyleSheet *aSheet)
 {
   NS_ASSERTION(aSheet == mStyleSheet || !aSheet || !mStyleSheet,
                "multiple style sheets competing for one media list");
   mStyleSheet = aSheet;
@@ -614,16 +619,17 @@ nsMediaList::Clone(nsMediaList** aResult
   nsRefPtr<nsMediaList> result = new nsMediaList();
   if (!result || !result->mArray.AppendElements(mArray.Length()))
     return NS_ERROR_OUT_OF_MEMORY;
   for (PRInt32 i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     if (!(result->mArray[i] = mArray[i]->Clone())) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
+  result->mIsEmpty = mIsEmpty;
   NS_ADDREF(*aResult = result);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMediaList::GetMediaText(nsAString& aMediaText)
 {
   return GetText(aMediaText);
--- a/layout/style/nsIMediaList.h
+++ b/layout/style/nsIMediaList.h
@@ -200,23 +200,28 @@ public:
     aQuery.forget();
     return NS_OK;
   }
 
   nsresult Clone(nsMediaList** aResult);
 
   PRInt32 Count() { return mArray.Length(); }
   nsMediaQuery* MediumAt(PRInt32 aIndex) { return mArray[aIndex]; }
-  void Clear() { mArray.Clear(); }
+  void Clear() { mArray.Clear(); mIsEmpty = PR_TRUE; }
+  // a media list with no items may not represent the lack of a media
+  // list; it could represent the empty string or something with parser
+  // errors, which means that the media list should never match
+  void SetNonEmpty() { mIsEmpty = PR_FALSE; }
 
 protected:
   ~nsMediaList();
 
   nsresult Delete(const nsAString & aOldMedium);
   nsresult Append(const nsAString & aOldMedium);
 
   nsTArray<nsAutoPtr<nsMediaQuery> > mArray;
+  bool mIsEmpty;
   // not refcounted; sheet will let us know when it goes away
   // mStyleSheet is the sheet that needs to be dirtied when this medialist
   // changes
   nsCSSStyleSheet*         mStyleSheet;
 };
 #endif /* !defined(nsIMediaList_h_) */
--- a/layout/style/test/test_media_queries.html
+++ b/layout/style/test/test_media_queries.html
@@ -74,17 +74,17 @@ function run() {
   document.getElementsByTagName("head")[0]
     .appendChild(parse_test_style_element);
 
   function query_is_parseable(q) {
     parse_test_style_text.data = "@media screen, " + q + " {}";
     var sheet = parse_test_style_element.sheet; // XXX yikes, not live!
     if (sheet.cssRules.length == 1 &&
         sheet.cssRules[0].type == CSSRule.MEDIA_RULE)
-      return sheet.cssRules[0].media.mediaText != "screen, not all";
+      return sheet.cssRules[0].media.mediaText != "screen";
     ok(false, "unexpected result testing whether query " + q +
               " is parseable");
     return true; // doesn't matter, we already failed
   }
 
   function query_should_be_parseable(q) {
     ok(query_is_parseable(q), "query " + q + " should be parseable");
     test_serialization(q, false, false);