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	24 Nov 2009 13:27:35 -0000
@@ -768,6 +768,8 @@
     // - Optimized expected content: name.css.optimized.css
     $testfiles = array(
       'css_input_without_import.css',
+      'css_input_with_import.css',
+      'css_input_with_nested_import.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.1051
diff -u -r1.1051 common.inc
--- includes/common.inc	21 Nov 2009 00:43:42 -0000	1.1051
+++ includes/common.inc	24 Nov 2009 13:27:35 -0000
@@ -3309,7 +3311,7 @@
         break;
       case 'inline':
         // Include inline stylesheets.
-        $inline_css .= drupal_load_stylesheet_content($item['data'], $item['preprocess']);
+        $inline_css .= drupal_load_stylesheet_content($item['data'], $item['preprocess'], FALSE);
         break;
       case 'external':
         // Preprocessing for external CSS files is ignored.
@@ -3334,6 +3336,13 @@
   }
   // Enclose the inline CSS with the style tag if required.
   if (!empty($inline_css)) {
+    // Per the W3C specification at http://www.w3.org/TR/REC-CSS2/cascade.html#at-import,
+    // @import rules must proceed any other style, so we move those to the top.
+    $regexp = '/@import[^;]+;/i';
+    preg_match_all($regexp, $inline_css, $matches);
+    $inline_css = preg_replace($regexp, '', $inline_css);
+    $inline_css = implode('', $matches[0]) . $inline_css;
+
     $element = $css_element;
     $element['#tag'] = 'style';
     $element['#value'] = $inline_css;
@@ -3356,22 +3365,16 @@
  *   The name of the CSS file.
  */
 function drupal_build_css_cache($css, $filename) {
-  $data = '';
-
   // Create the css/ within the files folder.
   $csspath = 'public://css';
   file_prepare_directory($csspath, FILE_CREATE_DIRECTORY);
   if (!file_exists($csspath . '/' . $filename)) {
+    $data = '';
     // Build aggregate CSS file.
     foreach ($css as $stylesheet) {
       // Only 'file' stylesheets can be aggregated.
       if ($stylesheet['type'] == 'file') {
-        $contents = drupal_load_stylesheet($stylesheet['data'], TRUE);
-        // Return the path to where this CSS file originated from.
-        $base = base_path() . dirname($stylesheet['data']) . '/';
-        _drupal_build_css_path(NULL, $base);
-        // Prefix all paths within this CSS file, ignoring external and absolute paths.
-        $data .= preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $contents);
+        $data .= drupal_load_stylesheet($stylesheet['data'], TRUE, TRUE);
       }
     }
 
@@ -3389,25 +3392,45 @@
 }
 
 /**
- * Helper function for drupal_build_css_cache().
+ * Helper function for drupal_load_stylesheet().
  *
  * This function will prefix all paths within a CSS file.
+ *
+ * @see drupal_load_stylesheet()
+ * @see drupal_load_stylesheet_contents()
  */
 function _drupal_build_css_path($matches, $base = NULL) {
-  $_base = &drupal_static(__FUNCTION__);
+  // $_base does not use drupal_static as it is set by $base.
+  static $_base;
   // Store base path for preg_replace_callback.
   if (isset($base)) {
     $_base = $base;
   }
 
-  // Prefix with base and remove '../' segments where possible.
-  $path = $_base . $matches[1];
-  $last = '';
-  while ($path != $last) {
-    $last = $path;
-    $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
+  if (is_array($matches)) {
+    // Prefix with base.
+    if (!empty($_base)) {
+      $path = base_path() . $_base . '/' . $matches[1];
+    }
+    else {
+      $path = base_path() . $matches[1];
+    }
+
+    // Replace '/./' segments for '/'.
+    $path = str_replace('/./', '/', $path);
+
+    // Remove '../' segments where possible.
+    $last = '';
+    while ($path != $last) {
+      $last = $path;
+      $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
+    }
+
+    return 'url(' . $path . ')';
+  }
+  else {
+    return $_base;
   }
-  return 'url(' . $path . ')';
 }
 
 /**
@@ -3425,10 +3448,12 @@
  *   Name of the stylesheet to be processed.
  * @param $optimize
  *   Defines if CSS contents should be compressed or not.
+ * @param $flatten
+ *   Defines if @import commands should be replaced with the actual stylesheet content.
  * @return
  *   Contents of the stylesheet, including any resolved @import commands.
  */
-function drupal_load_stylesheet($file, $optimize = NULL) {
+function drupal_load_stylesheet($file, $optimize = NULL, $flatten = TRUE) {
   // $_optimize does not use drupal_static as it is set by $optimize.
   static $_optimize;
   // Store optimization parameter for preg_replace_callback with nested @import loops.
@@ -3441,15 +3466,19 @@
     // Load the local CSS stylesheet.
     $contents = file_get_contents($file);
 
-    // Change to the current stylesheet's directory.
-    $cwd = getcwd();
-    chdir(dirname($file));
+    $temp = _drupal_build_css_path(NULL);
+    // Inform _drupal_build_css_path() where this CSS file originated from.
+    _drupal_build_css_path(NULL, dirname($file));
 
     // Process the stylesheet.
-    $contents = drupal_load_stylesheet_content($contents, $_optimize);
+    $contents = drupal_load_stylesheet_content($contents, $_optimize, $flatten);
 
-    // Change back directory.
-    chdir($cwd);
+    // Restore _drupal_build_css_path().
+    _drupal_build_css_path(NULL, $temp);
+  }
+  else {
+    // Return an @import command when file doesn't seem to exist.
+    $contents = '@import url(' . $file . ');';
   }
 
   return $contents;
@@ -3466,7 +3495,7 @@
  * @return
  *   Contents of the stylesheet including the imported stylesheets.
  */
-function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
+function drupal_load_stylesheet_content($contents, $optimize = FALSE, $flatten = TRUE) {
   // Remove multiple charset declarations for standards compliance (and fixing Safari problems).
   $contents = preg_replace('/^@charset\s+[\'"](\S*)\b[\'"];/i', '', $contents);
 
@@ -3475,31 +3504,37 @@
     $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);    
+      }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);
   }
 
-  // Replaces @import commands with the actual stylesheet content.
-  // This happens recursively but omits external files.
-  $contents = preg_replace_callback('/@import\s*(?:url\()?[\'"]?(?![a-z]+:)([^\'"\()]+)[\'"]?\)?;/', '_drupal_load_stylesheet', $contents);
+  // Normalize @import commands so they all contain the url() function.
+  $contents = preg_replace('/@import\s*(?:url\(\s*)?[\'"]?([^\'"\()]+)[\'"]?\s*\)?;/', '@import url(\1);', $contents);
+
+  // Normalize all paths within this CSS file, ignoring external and absolute paths.
+  $contents = preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $contents);
+
+  if ($flatten) {
+    // Replaces @import commands with the actual stylesheet content.
+    // This happens recursively but omits external files.
+    $contents = preg_replace_callback('/@import url\((\/[^\)]+\.css)\)?;/', '_drupal_load_stylesheet', $contents);
+  }
+
   return $contents;
 }
 
 /**
- * Loads stylesheets recursively and returns contents with corrected paths.
+ * Helper function for drupal_load_stylesheet_content().
  *
- * This function is used for recursive loading of stylesheets and
- * returns the stylesheet content with all url() paths corrected.
+ * This function is used for recursive loading of stylesheets.
  */
 function _drupal_load_stylesheet($matches) {
-  $filename = $matches[1];
-  // Load the imported stylesheet and replace @import commands in there as well.
-  $file = drupal_load_stylesheet($filename);
-  // Alter all url() paths, but not external.
-  return preg_replace('/url\(([\'"]?)(?![a-z]+:)([^\'")]+)[\'"]?\)?;/i', 'url(\1' . dirname($filename) . '/', $file);
+  // Strip base URL path to get a correct internal file path.
+  $filename = substr($matches[1], strlen(base_path()));
+  return drupal_load_stylesheet($filename);
 }
 
 /**
Index: modules/simpletest/files/css_test_files/css_input_with_import.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_import.css
diff -N modules/simpletest/files/css_test_files/css_input_with_import.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_import.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,13 @@
+@import "css_input_without_import.css";
+
+/**
+ * @file Basic css that use import
+ */
+
+
+body {
+  margin: 0;
+  background-image: url(../image-1.png);
+  font: 76%/170% Verdana, sans-serif;
+  color: #494949;
+}
Index: modules/simpletest/files/css_test_files/css_input_with_nested_import.unoptimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_nested_import.unoptimized.css
diff -N modules/simpletest/files/css_test_files/css_input_with_nested_import.unoptimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_nested_import.unoptimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,51 @@
+/* $Id: css_input_without_import.css.unoptimized.css,v 1.2 2009/11/10 17:27:53 webchick Exp $ */
+
+/**
+ * @file Basic css that does not use import
+ */
+
+
+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;
+}
+
+/**
+ * CSS spec says that all whitespace is valid whitespace, so this selector should be just as
+ * good as the one above.
+ */
+
+.this
+.is
+.a
+.test {
+font: 1em/100% Verdana, sans-serif;
+color: #494949;
+}
+
+textarea, select {
+  font: 1em/160% Verdana, sans-serif;
+  color: #494949;
+}
+
+
+
+/**
+ * @file Basic css that use import
+ */
+
+
+body {
+  margin: 0;
+  background-image: url(/modules/simpletest/files/image-1.png);
+  font: 76%/170% Verdana, sans-serif;
+  color: #494949;
+}
Index: modules/simpletest/files/css_test_files/css_input_with_nested_import.optimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_nested_import.optimized.css
diff -N modules/simpletest/files/css_test_files/css_input_with_nested_import.optimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_nested_import.optimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,16 @@
+
+
+
+
+
+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;}
+
+
+
+
+body {margin: 0;background-image: url(/modules/simpletest/files/image-1.png);font:76%/170% Verdana, sans-serif;color: #494949;}
Index: modules/simpletest/files/css_test_files/css_input_with_nested_import.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_nested_import.css
diff -N modules/simpletest/files/css_test_files/css_input_with_nested_import.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_nested_import.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1 @@
+@import "css_input_with_import.css";
\ No newline at end of file
Index: modules/simpletest/files/css_test_files/css_input_with_import.optimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_import.optimized.css
diff -N modules/simpletest/files/css_test_files/css_input_with_import.optimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_import.optimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,16 @@
+
+
+
+
+
+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;}
+
+
+
+
+body {margin: 0;background-image: url(/modules/simpletest/files/image-1.png);font:76%/170% Verdana, sans-serif;color: #494949;}
Index: modules/simpletest/files/css_test_files/css_input_with_import.unoptimized.css
===================================================================
RCS file: modules/simpletest/files/css_test_files/css_input_with_import.unoptimized.css
diff -N modules/simpletest/files/css_test_files/css_input_with_import.unoptimized.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/files/css_test_files/css_input_with_import.unoptimized.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,51 @@
+/* $Id$ */
+
+/**
+ * @file Basic css that does not use import
+ */
+
+
+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;
+}
+
+/**
+ * CSS spec says that all whitespace is valid whitespace, so this selector should be just as
+ * good as the one above.
+ */
+
+.this
+.is
+.a
+.test {
+font: 1em/100% Verdana, sans-serif;
+color: #494949;
+}
+
+textarea, select {
+  font: 1em/160% Verdana, sans-serif;
+  color: #494949;
+}
+
+
+
+/**
+ * @file Basic css that use import
+ */
+
+
+body {
+  margin: 0;
+  background-image: url(/modules/simpletest/files/image-1.png);
+  font: 76%/170% Verdana, sans-serif;
+  color: #494949;
+}
