See #843 - fixes an edge case in attribute tidying.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Sat, 17 Dec 2016 11:15:53 +0000 (12:15 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sat, 17 Dec 2016 11:15:53 +0000 (12:15 +0100)
Why:

* We should treat single and double quotes properly as in tokenizer.

lib/optimizer/tidy-rules.js
test/optimizer/basic-test.js

index 684666b..745b4d4 100644 (file)
@@ -48,7 +48,9 @@ function removeWhitespace(value) {
   var isNewLineWin;
   var isEscaped;
   var wasEscaped;
-  var isQuote;
+  var isQuoted;
+  var isSingleQuoted;
+  var isDoubleQuoted;
   var isAttribute;
   var isRelation;
   var isWhitespace;
@@ -62,43 +64,50 @@ function removeWhitespace(value) {
 
     isNewLineNix = character == Marker.NEW_LINE_NIX;
     isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.NEW_LINE_WIN;
+    isQuoted = isSingleQuoted || isDoubleQuoted;
     isRelation = !isEscaped && RELATION_PATTERN.test(character);
     isWhitespace = WHITESPACE_PATTERN.test(character);
 
-    if (wasEscaped && isQuote && isNewLineWin) {
+    if (wasEscaped && isQuoted && isNewLineWin) {
       // swallow escaped new windows lines in comments
       stripped.pop();
       stripped.pop();
-    } else if (isEscaped && isQuote && isNewLineNix) {
+    } else if (isEscaped && isQuoted && isNewLineNix) {
       // swallow escaped new *nix lines in comments
       stripped.pop();
     } else if (isEscaped) {
       stripped.push(character);
-    } else if (character == Marker.OPEN_SQUARE_BRACKET && !isQuote) {
+    } else if (character == Marker.OPEN_SQUARE_BRACKET && !isQuoted) {
       stripped.push(character);
       isAttribute = true;
-    } else if (character == Marker.CLOSE_SQUARE_BRACKET && !isQuote) {
+    } else if (character == Marker.CLOSE_SQUARE_BRACKET && !isQuoted) {
       stripped.push(character);
       isAttribute = false;
-    } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuote) {
+    } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuoted) {
       stripped.push(character);
       roundBracketLevel++;
-    } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuote) {
+    } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuoted) {
       stripped.push(character);
       roundBracketLevel--;
-    } else if ((character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) && !isQuote) {
+    } else if (character == Marker.SINGLE_QUOTE && !isQuoted) {
       stripped.push(character);
-      isQuote = true;
-    } else if (character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) {
+      isSingleQuoted = true;
+    } else if (character == Marker.DOUBLE_QUOTE && !isQuoted) {
+      stripped.push(character);
+      isDoubleQuoted = true;
+    } else if (character == Marker.SINGLE_QUOTE && isQuoted) {
+      stripped.push(character);
+      isSingleQuoted = false;
+    } else if (character == Marker.DOUBLE_QUOTE && isQuoted) {
       stripped.push(character);
-      isQuote = false;
+      isDoubleQuoted = false;
     } else if (isWhitespace && wasRelation) {
       continue;
-    } else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuote) {
+    } else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuoted) {
       // skip space
-    } else if (isWhitespace && wasWhitespace && !isQuote) {
+    } else if (isWhitespace && wasWhitespace && !isQuoted) {
       // skip extra space
-    } else if ((isNewLineWin || isNewLineNix) && (isAttribute || roundBracketLevel > 0) && isQuote) {
+    } else if ((isNewLineWin || isNewLineNix) && (isAttribute || roundBracketLevel > 0) && isQuoted) {
       // skip newline
     } else if (isRelation && wasWhitespace) {
       stripped.pop();
index 5393ee9..1f4931a 100644 (file)
@@ -92,6 +92,10 @@ vows.describe('simple optimizations')
       'escaped characters': [
         '.a\\+\\+b{color:red}',
         '.a\\+\\+b{color:red}'
+      ],
+      'quotes #1': [
+        '.a[title="a b c\'s d e f"]{color:red}',
+        '.a[title="a b c\'s d e f"]{color:red}'
       ]
     }, { advanced: false })
   )