Index: modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css,v
retrieving revision 1.2
diff -u -r1.2 css_input_without_import.css.optimized.css
--- modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css	10 Nov 2009 17:27:53 -0000	1.2
+++ modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css	30 Nov 2009 17:01:53 -0000
@@ -1,11 +1,4 @@
-
-
-
-
-
-body{margin:0;padding:0;background:#edf5fa;font:76%/170% Verdana,sans-serif;color:#494949;}.this .is .a .test{font:1em/100% Verdana,sans-serif;color:#494949;}
-
-.this
+body{margin:0;padding:0;background:#edf5fa;font:76%/170% Verdana,sans-serif;color:#494949}.this .is .a .test{font:1em/100% Verdana,sans-serif;color:#494949}.this
 .is
 .a
-.test{font:1em/100% Verdana,sans-serif;color:#494949;}textarea,select{font:1em/160% Verdana,sans-serif;color:#494949;}
\ No newline at end of file
+.test{font:1em/100% Verdana,sans-serif;color:#494949}textarea,select{font:1em/160% Verdana,sans-serif;color:#494949}
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.92
diff -u -r1.92 common.test
--- modules/simpletest/tests/common.test	21 Nov 2009 14:35:05 -0000	1.92
+++ modules/simpletest/tests/common.test	30 Nov 2009 17:01:53 -0000
@@ -587,7 +587,7 @@
    */
   function testRenderInlineFullPage() {
     $css = 'body { font-size: 254px; }';
-    $expected = 'font-size:254px;';
+    $expected = 'font-size:254px';
 
     // Create a node, using the PHP filter that tests drupal_add_css().
     $settings = array(
@@ -768,6 +768,7 @@
     // - Optimized expected content: name.css.optimized.css
     $testfiles = array(
       'css_input_without_import.css',
+      'hacks.css'
     );
     $path = drupal_get_path('module', 'simpletest') . '/files/css_test_files';
     foreach ($testfiles as $file) {
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1052
diff -u -r1.1052 common.inc
--- includes/common.inc	26 Nov 2009 05:54:48 -0000	1.1052
+++ includes/common.inc	30 Nov 2009 17:01:53 -0000
@@ -3069,7 +3069,7 @@
  * which on normal pages is up through the preprocess step of theme('html').
  * Adding a link will overwrite a prior link with the exact same 'rel' and
  * 'href' attributes.
- * 
+ *
  * @param $attributes
  *   Associative array of element attributes including 'href' and 'rel'.
  * @param $header
@@ -3472,14 +3472,69 @@
 
   if ($optimize) {
     // Perform some safe CSS optimizations.
-    $contents = preg_replace('{
-      (?<=\\\\\*/)([^/\*]+/\*)([^\*/]+\*/)  # Add a backslash also at the end ie-mac hack comment, so the next pass will not touch it.
-                                            # The added backshlash does not affect the effectiveness of the hack.
-      }x', '\1\\\\\2', $contents);    
-    $contents = preg_replace('<
-      \s*([@{}:;,]|\)\s|\s\()\s* |          # Remove whitespace around separators, but keep space around parentheses.
-      /\*[^*\\\\]*\*+([^/*][^*]*\*+)*/ |    # Remove comments that are not CSS hacks.
-      >x', '\1', $contents);
+
+    // Unify all (line)breaks to make the next regular expression easier.
+    $contents = str_replace(array('\r\n', '\f', '\r'), '\n', $contents);
+
+    // Find all strings and comments in the stylesheet and the chunks in between.
+    // The regular expressions for strings and comments are modified versions of
+    // the ones found here: http://www.w3.org/TR/CSS21/syndata.html#tokenization.
+    $chunks = preg_split('@
+      ("(?:[^\n\\\\"]|\\\\(?i:\n|[0-9a-f]{1,6}[\040\n\t]?|[^\n0-9a-f]))*")|
+      (\'(?:[^\n\\\\\']|\\\\(?i:\n|[0-9a-f]{1,6}[\040\n\t]?|[^\n0-9a-f]))*\')|
+      (?:\s*(/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)\s*) # Already eat all whitespace
+                                                 # around comments.
+      @x', $contents, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+
+    $contents = '';
+    $keep_comment = FALSE;
+    // Iterate over all the chunks and rebuild contents.
+    foreach ($chunks as $i => $chunk) {
+      $start = substr($chunk, 0, 2);
+      $end = substr($chunk, -2);
+
+      // Process comments.
+      if ($start == '/*' && $end == '*/') {
+        // Keep IE-mac hack start comment
+        if (substr($chunk, -3) == '\*/') {
+          // Use an empty comment as this won't hurt the hack.
+          $contents .= '/*\*/';
+          $keep_comment = TRUE;
+        }
+        // Keep comment in output if $keep_comment is TRUE.
+        elseif ($keep_comment) {
+          $contents .= $chunk;
+          $keep_comment = FALSE;
+        }
+        // Keep comments that come right before or after ">" or ":" characters
+        // as those are probably hacks:
+        // http://www.webdevout.net/css-hacks#in_css-selectors.
+        elseif ((isset($chunks[$i-1]) && in_array(substr($chunks[$i-1], -1), array('>', ':'))) ||
+                (isset($chunks[$i+1]) && in_array($chunks[$i+1]{0}, array('>', ':')))) {
+          $contents .= '/**/';
+          continue;
+        }
+      }
+      // Process strings.
+      elseif (($start{0} == '"' && $end{0} == '"') ||
+              ($start{0} == "'" && $end{0} == "'")) {
+        $contents .= $chunk;
+      }
+      // Proces anything else.
+      else {
+        $contents .= preg_replace('<
+          ;\s*(})\s* |               # Remove unnecessary last ";" from rulesets.
+          (:first-(?:letter|line)\s)\s*({)\s* |
+                                     # Leave at least 1 space between the
+                                     # first-letter and first-line pseudo elements
+                                     # and "{" (http://www.crankygeek.com/ie6pebug/).
+          \s*([@{}:;,]|\)\s|\s\()\s* # Remove whitespace around separators, but
+                                     # keep space around parentheses.
+          >x', '\1\2\3\4', $chunk);
+      }
+    }
+
+    $contents = trim($contents) . "\n";
   }
 
   // Replaces @import commands with the actual stylesheet content.
Index: modules/simpletest/files/css_test_files/hacks.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/hacks.css
diff -N modules/simpletest/files/css_test_files/hacks.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/hacks.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,107 @@
+
+/**
+ * Test file containing all kinds of css hacks which should be kept in an
+ * aggregate stylesheet.
+ *
+ * http://centricle.com/ref/css/filters/ 
+ */
+
+/**
+ * IE5/Mac Band Pass Filter
+ * http://www.stopdesign.com/examples/ie5mac-bpf/
+ */
+/* Feed to IE-mac \*//*/
+@import "ie5mac.css";
+/* End feed to IE-mac */
+
+/**
+ * Commented Backslash MacIE5 CSS Hack
+ * http://www.sam-i-am.com/work/sandbox/css/mac_ie5_hack.html 
+ */
+/* Hides from IE-mac \*/
+* html .clearfix {
+  height: 1%;
+}
+.clearfix {
+  display: block;
+}
+/* End hide from IE-mac */
+
+/**
+ * Caio's Hack 
+ * http://centricle.com/ref/css/filters/tests/caio/
+ */
+/*/ Hide from nav4 */
+.clearfix {
+  display: inline-block;
+}
+/* End hide from nav4 */
+
+/**
+ * Fabrice's Inversion
+ * http://archivist.incutio.com/viewlist/css-discuss/5967
+ */
+/*/ Feed to nav *//*/
+.clearfix {
+  display: block;
+}
+/* End feed to nav4 */
+
+/**
+ * http://code.google.com/p/minify/source/browse/trunk/min_unit_tests/_test_files/css/hacks.css
+ * Hide properties from various IE/win
+ */
+div {
+    width: 140px;
+    width/* */:/**/100px;
+    width: /**/100px;
+}
+
+/**
+ * http://www.webdevout.net/css-hacks#in_css-selectors
+ */
+html>/**/body {}
+
+@media screen {
+    /* for IE 5.x-6, hidden from IE 5 Mac */ /*\*/
+    * html div#page {
+        height: 1%;
+    }
+    /**/ /* end hidden from IE 5 Mac */
+}
+
+/**
+ * http://wellstyled.com/css-underscore-hack.html
+ * http://centricle.com/ref/css/filters/tests/asterisk/
+ */
+foo { /* filters for IE */
+    _height : 20px;
+    *height : 15px;
+}
+
+/**
+ * Tantek's box model hack
+ * http://www.tantek.com/CSS/Examples/boxmodelhack.html 
+ */
+div {
+  width:400px;
+  voice-family: "\"}\"";
+  voice-family:inherit;
+  width:300px;
+}
+
+/**
+ * Tantek's midpass hack
+ * http://tantek.com/CSS/Examples/midpass.html 
+ */
+@media tty {
+  i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";}
+}/* */
+
+/**
+ * Leave at least 1 space between these pseudo elements and "{" for IE6
+ * http://www.crankygeek.com/ie6pebug/ 
+ */
+p:first-letter  {color:red;}
+p:first-line   {color:red;}
+
Index: modules/simpletest/files/css_test_files/hacks.css.optimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/hacks.css.optimized.css
diff -N modules/simpletest/files/css_test_files/hacks.css.optimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/hacks.css.optimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,3 @@
+/*\*//*/
+@import "ie5mac.css";
+/* End feed to IE-mac *//*\*/* html .clearfix{height:1%}.clearfix{display:block}/* End hide from IE-mac */.clearfix{display:inline-block}div{width:140px;width/**/:/**/100px;width:/**/100px}html>/**/body{}@media screen{/*\*/* html div#page{height:1%}/**/}foo{_height:20px;*height:15px}div{width:400px;voice-family:"\"}\"";voice-family:inherit;width:300px}@media tty{i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*"}}p:first-letter {color:red}p:first-line {color:red}
Index: modules/simpletest/files/css_test_files/hacks.css.unoptimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/hacks.css.unoptimized.css
diff -N modules/simpletest/files/css_test_files/hacks.css.unoptimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/hacks.css.unoptimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,107 @@
+
+/**
+ * Test file containing all kinds of css hacks which should be kept in an
+ * aggregate stylesheet.
+ *
+ * http://centricle.com/ref/css/filters/ 
+ */
+
+/**
+ * IE5/Mac Band Pass Filter
+ * http://www.stopdesign.com/examples/ie5mac-bpf/
+ */
+/* Feed to IE-mac \*//*/
+@import "ie5mac.css";
+/* End feed to IE-mac */
+
+/**
+ * Commented Backslash MacIE5 CSS Hack
+ * http://www.sam-i-am.com/work/sandbox/css/mac_ie5_hack.html 
+ */
+/* Hides from IE-mac \*/
+* html .clearfix {
+  height: 1%;
+}
+.clearfix {
+  display: block;
+}
+/* End hide from IE-mac */
+
+/**
+ * Caio's Hack 
+ * http://centricle.com/ref/css/filters/tests/caio/
+ */
+/*/ Hide from nav4 */
+.clearfix {
+  display: inline-block;
+}
+/* End hide from nav4 */
+
+/**
+ * Fabrice's Inversion
+ * http://archivist.incutio.com/viewlist/css-discuss/5967
+ */
+/*/ Feed to nav *//*/
+.clearfix {
+  display: block;
+}
+/* End feed to nav4 */
+
+/**
+ * http://code.google.com/p/minify/source/browse/trunk/min_unit_tests/_test_files/css/hacks.css
+ * Hide properties from various IE/win
+ */
+div {
+    width: 140px;
+    width/* */:/**/100px;
+    width: /**/100px;
+}
+
+/**
+ * http://www.webdevout.net/css-hacks#in_css-selectors
+ */
+html>/**/body {}
+
+@media screen {
+    /* for IE 5.x-6, hidden from IE 5 Mac */ /*\*/
+    * html div#page {
+        height: 1%;
+    }
+    /**/ /* end hidden from IE 5 Mac */
+}
+
+/**
+ * http://wellstyled.com/css-underscore-hack.html
+ * http://centricle.com/ref/css/filters/tests/asterisk/
+ */
+foo { /* filters for IE */
+    _height : 20px;
+    *height : 15px;
+}
+
+/**
+ * Tantek's box model hack
+ * http://www.tantek.com/CSS/Examples/boxmodelhack.html 
+ */
+div {
+  width:400px;
+  voice-family: "\"}\"";
+  voice-family:inherit;
+  width:300px;
+}
+
+/**
+ * Tantek's midpass hack
+ * http://tantek.com/CSS/Examples/midpass.html 
+ */
+@media tty {
+  i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";}
+}/* */
+
+/**
+ * Leave at least 1 space between these pseudo elements and "{" for IE6
+ * http://www.crankygeek.com/ie6pebug/ 
+ */
+p:first-letter  {color:red;}
+p:first-line   {color:red;}
+
