Correct parenthesis-matching inside of :not(). (Bug 586070) r=bzbarsky a2.0=bsmedberg
authorL. David Baron <dbaron@dbaron.org>
Sun, 15 Aug 2010 08:42:29 -0400
changeset 50630 521694df26c46b5be05a2481ff13426a796053dd
parent 50629 45984c1823316fb6347476b06f87c5a49fcdb45e
child 50631 4d25cd8808e523a208ef4376ef24660f18ee650f
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs586070
milestone2.0b4pre
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
Correct parenthesis-matching inside of :not(). (Bug 586070) r=bzbarsky a2.0=bsmedberg
layout/style/nsCSSParser.cpp
layout/style/test/test_unclosed_parentheses.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3218,21 +3218,23 @@ CSSParserImpl::ParseNegatedSimpleSelecto
     parsingStatus = ParseAttributeSelector(aDataMask, *newSel);
   }
   else {
     // then it should be a type element or universal selector
     parsingStatus = ParseTypeOrUniversalSelector(aDataMask, *newSel, PR_TRUE);
   }
   if (eSelectorParsingStatus_Error == parsingStatus) {
     REPORT_UNEXPECTED_TOKEN(PENegationBadInner);
+    SkipUntil(')');
     return parsingStatus;
   }
   // close the parenthesis
   if (!ExpectSymbol(')', PR_TRUE)) {
     REPORT_UNEXPECTED_TOKEN(PENegationNoClose);
+    SkipUntil(')');
     return eSelectorParsingStatus_Error;
   }
 
   NS_ASSERTION(newSel->mNameSpace == kNameSpaceID_Unknown ||
                (!newSel->mIDList && !newSel->mClassList &&
                 !newSel->mPseudoClassList && !newSel->mAttrList),
                "Need to fix the serialization code to deal with this");
 
--- a/layout/style/test/test_unclosed_parentheses.html
+++ b/layout/style/test/test_unclosed_parentheses.html
@@ -132,27 +132,52 @@ var declarations = [
   "border-top-width: -moz-calc(2em +",
   "border-top-width: -moz-calc(2em + ",
   "border-top-width: -moz-calc(2em *",
   "border-top-width: -moz-calc(2em * ",
   "border-top-width: -moz-calc((2em)",
   "border-top-width: -moz-calc((2em) ",
 ];
 
+var selectors = [
+  ":not(",
+  ":not( ",
+  ":not(-",
+  ":not(- ",
+  ":not(>",
+  ":not(> ",
+  ":not(div p",
+  ":not(div p ",
+  ":not(div >",
+  ":not(div > ",
+];
+
 var textNode = document.createTextNode("");
 document.getElementById("style").appendChild(textNode);
 var cs = getComputedStyle(document.getElementById("display"), "");
 
 for (var i = 0; i < declarations.length; ++i) {
   var sheet = "@namespace html url(http://www.w3.org/1999/xhtml);\n" +
               "#display { color: green; " + declarations[i] +
               " x x x x x x x ; color: red; ) ; z-index: " + (i + 1) + " }";
   textNode.data = sheet;
   is(cs.color, "rgb(0, 128, 0)",
      "color for declaration '" + declarations[i] + "'");
   is(cs.zIndex, i+1,
      "z-index for declaration '" + declarations[i] + "'");
 }
 
+for (var i = 0; i < selectors.length; ++i) {
+  var sheet = "@namespace html url(http://www.w3.org/1999/xhtml);\n" +
+              "#display { color: green } " +
+              selectors[i] + " x x x x x x x , #display { color: red } #display { color: red } ) , #display { color: red } " +
+              "#display { z-index: " + (i + 1) + " }";
+  textNode.data = sheet;
+  is(cs.color, "rgb(0, 128, 0)",
+     "color for selector '" + selectors[i] + "'");
+  is(cs.zIndex, i+1,
+     "z-index for selector '" + selectors[i] + "'");
+}
+
 </script>
 </pre>
 </body>
 </html>