Index: modules/color/color.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/color/color.module,v
retrieving revision 1.29
diff -u -p -r1.29 color.module
--- modules/color/color.module	6 Dec 2007 09:58:30 -0000	1.29
+++ modules/color/color.module	9 Dec 2007 21:15:17 -0000
@@ -8,7 +8,7 @@ function color_help($path, $arg) {
   switch ($path) {
     case 'admin/help#color':
       $output = '<p>'. t('Color module allows a site administrator to quickly and easily change the color scheme of the entire site. In order for color module to work however, a theme must be specifically designed to use the color changing features. The default theme, Garland, (as well as its fixed width counterpart, Minnelli) was designed to take advantage of these features. With color module, you can easily change the color of links, backgrounds, text, and more depending on which color module enabled theme you are using. Color module requires your <a href="@url">file download method</a> to be set to public.', array('@url' => url('admin/settings/file-system'))) .'</p>';
-      $output .= '<p>'. t("It is important to remember that color module saves a modified copy of the theme's style.css file in the files directory, and includes it after the theme's original style.css. This means that if you make any manual changes to your theme's style.css file, you must save your color settings again, even if they haven't changed. This causes the color module generated version of style.css in the files directory to be recreated using the new version of the original file.") .'</p>';
+      $output .= '<p>'. t("It is important to remember that color module saves a modified copy of the theme's specified stylesheet in the files directory. This means that if you make any manual changes to your theme's stylesheet, you must save your color settings again, even if they haven't changed. This causes the color module generated version of the stylesheet in the files directory to be recreated using the new version of the original file.") .'</p>';
       return $output;
   }
 }
@@ -58,12 +58,45 @@ function color_form_alter(&$form, $form_
  * Callback for the theme to alter the resources used.
  */
 function _color_page_alter(&$vars) {
-  global $theme_key;
+  global $language, $theme_key;
 
-  // Override stylesheet
-  $path = variable_get('color_'. $theme_key .'_stylesheet', NULL);
-  if ($path) {
-    $vars['css']['all']['theme'][$path] = TRUE;
+  // Override stylesheets.
+  $color_paths = variable_get('color_'. $theme_key .'_stylesheets', array());
+  if (!empty($color_paths)) {
+    // Loop over themes CSS files and try to rebuild CSS array with rewritten
+    // stylesheets. Additional keep the orginal order for CSS cascading intact.
+    $new_theme_css = array();
+
+    foreach ($vars['css']['all']['theme'] as $old_path => $old_preprocess) {
+      // Add the non-colored stylesheet as we cannot use if/else in following loop.
+      $new_theme_css[$old_path] = $old_preprocess;
+
+      // Loop over the path array with recolored CSS files to find matching paths that
+      // could replace the non-recolored paths. The list of configured files could be
+      // different from the [theme].info file or the files added by drupal_add_css().
+      foreach ($color_paths as $color_path) {
+        // Color module currently requires unique file names to be used,
+        // what allows to compare different filepaths.
+        if (basename($old_path) == basename($color_path)) {
+          // Pull out the non-colored and replace with rewritten stylesheet.
+          unset($new_theme_css[$old_path]);
+          $new_theme_css[$color_path] = $old_preprocess;
+
+          // If the current language is RTL and the CSS file had an RTL variant,
+          // pull out the non-colored and replace with rewritten RTL stylesheet.
+          if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
+            $rtl_old_path = str_replace('.css', '-rtl.css', $old_path);
+            $rtl_color_path = str_replace('.css', '-rtl.css', $color_path);
+            if (file_exists($rtl_color_path)) {
+              unset($new_theme_css[$rtl_old_path]);
+              $new_theme_css[$rtl_color_path] = $old_preprocess;
+            }
+          }
+          break;
+        }
+      }
+    }
+    $vars['css']['all']['theme'] = $new_theme_css;
     $vars['styles'] = drupal_get_css($vars['css']);
   }
 
@@ -243,7 +276,7 @@ function color_scheme_form_submit($form,
   if (implode(',', color_get_palette($theme, true)) == implode(',', $palette)
     || $form_state['values']['op'] == t('Reset to defaults')) {
     variable_del('color_'. $theme .'_palette');
-    variable_del('color_'. $theme .'_stylesheet');
+    variable_del('color_'. $theme .'_stylesheets');
     variable_del('color_'. $theme .'_logo');
     variable_del('color_'. $theme .'_files');
     variable_del('color_'. $theme .'_screenshot');
@@ -260,12 +293,10 @@ function color_scheme_form_submit($form,
   $paths['target'] = $paths['target'] .'/';
   $paths['id'] = $id;
   $paths['source'] = drupal_get_path('theme', $theme) .'/';
-  $paths['stylesheet'] = $paths['target'] .'style.css';
   $paths['files'] = $paths['map'] = array();
 
-  // Save palette and stylesheet location
+  // Save palette and logo location
   variable_set('color_'. $theme .'_palette', $palette);
-  variable_set('color_'. $theme .'_stylesheet', $paths['stylesheet']);
   variable_set('color_'. $theme .'_logo', $paths['target'] .'logo.png');
 
   // Copy over neutral images
@@ -280,20 +311,63 @@ function color_scheme_form_submit($form,
   // Render new images
   _color_render_images($theme, $info, $paths, $palette);
 
-  // Rewrite stylesheet
-  _color_rewrite_stylesheet($theme, $info, $paths, $palette);
+  // Rewrite theme stylesheets
+  $css = array();
+  foreach ($info['css'] as $file) {
+    if (file_exists($paths['source'] . $file)) {
+      // Aggregate @imports recursively for each configured top level CSS file 
+      // without optimisations. Aggregate and compress optimisations will be 
+      // handled by drupal_build_css_cache() only.
+      $style = drupal_load_stylesheet($paths['source'] . $file, FALSE);
+
+      // Return the path to where this CSS file originated from, stripping
+      // off the name of the file at the end of the path.
+      $base = base_path() . dirname($paths['source'] . $file) .'/';
+      _drupal_build_css_path(NULL, $base);
+
+      // Prefix all paths within this CSS file, ignoring absolute paths.
+      $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
+
+      // Rewrite stylesheet with new colors.
+      $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
+      $base_file = basename($file);
+      $css[] = $paths['target'] . $base_file;
+      _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
+
+      $rtl_file = str_replace('.css', '-rtl.css', $file);
+      if (file_exists($paths['source'] . $rtl_file)) {
+        // Aggregate @imports recursively for each top level RTL CSS file
+        // without optimisations. Aggregate and compress optimisations will be 
+        // handled by drupal_build_css_cache() only.
+        $style = drupal_load_stylesheet($paths['source'] . $rtl_file, FALSE);
+
+        // Return the path to where this CSS file originated from, stripping
+        // off the name of the file at the end of the path.
+        $base = base_path() . dirname($paths['source'] . $file) .'/';
+        _drupal_build_css_path(NULL, $base);
+
+        // Prefix all paths within this CSS file, ignoring absolute paths.
+        $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
+
+        // Rewrite stylesheet with new colors.
+        $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
+        $base_file = basename($rtl_file);
+        $css[] = $paths['target'] . $base_file;
+        _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
+      }
+    }
+  }
 
-  // Maintain list of files
+  // Maintain list of files.
+  variable_set('color_'. $theme .'_stylesheets', $css);
   variable_set('color_'. $theme .'_files', $paths['files']);
 }
 
 /**
  * Rewrite the stylesheet to match the colors in the palette.
  */
-function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette) {
-  // Load stylesheet
+function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
   $themes = list_themes();
-  $style = file_get_contents($themes[$theme]->stylesheets['all']['style.css']);
 
   // Prepare color conversion table
   $conversion = $palette;
@@ -304,13 +378,9 @@ function _color_rewrite_stylesheet($them
   $default = color_get_palette($theme, true);
 
   // Split off the "Don't touch" section of the stylesheet.
-  list($style, $fixed) = explode("Color Module: Don't touch", $style);
-
-  // Look for @import commands and insert the referenced stylesheets.
-  $cwd = getcwd();
-  chdir(drupal_get_path('theme', $theme));
-  $style = preg_replace_callback('/@import\s*["\']([^"\']+)["\'];/', '_color_import_stylesheet', $style);
-  chdir($cwd);
+  if (strpos("Color Module: Don't touch", $style) !== FALSE) {
+    list($style, $fixed) = explode("Color Module: Don't touch", $style);
+  }
 
   // Find all colors in the stylesheet and the chunks in between.
   $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);
@@ -351,28 +421,31 @@ function _color_rewrite_stylesheet($them
     $is_color = !$is_color;
   }
   // Append fixed colors segment
-  $output .= $fixed;
+  if (isset($fixed)) {
+    $output .= $fixed;
+  }
 
   // Replace paths to images
   foreach ($paths['map'] as $before => $after) {
+    $before = base_path() . $paths['source'] . $before;
+    $before = preg_replace('`(^|/)(?!../)([^/]+)/../`', '$1', $before);
     $output = str_replace($before, $after, $output);
   }
 
-  // Write new stylesheet
-  $file = fopen($paths['stylesheet'], 'w+');
-  fwrite($file, $output);
-  fclose($file);
-  $paths['files'][] = $paths['stylesheet'];
-
-  // Set standard file permissions for webserver-generated files
-  @chmod($paths['stylesheet'], 0664);
+  return $output;
 }
 
 /**
- * Helper function for _color_rewrite_stylesheet.
+ * Save the rewritten stylesheet to disk.
  */
-function _color_import_stylesheet($matches) {
-  return preg_replace('/url\(([\'"]?)(?![a-z]+:)/i', 'url(\1'. dirname($matches[1]) .'/', file_get_contents($matches[1]));
+function _color_save_stylesheet($file, $style, &$paths) {
+
+  // Write new stylesheet.
+  file_save_data($style, $file, FILE_EXISTS_REPLACE);
+  $paths['files'][] = $file;
+
+  // Set standard file permissions for webserver-generated files.
+  @chmod($file, 0664);
 }
 
 /**
Index: themes/garland/color/color.inc
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/color/color.inc,v
retrieving revision 1.3
diff -u -p -r1.3 color.inc
--- themes/garland/color/color.inc	2 Oct 2007 16:31:50 -0000	1.3
+++ themes/garland/color/color.inc	9 Dec 2007 21:15:17 -0000
@@ -30,6 +30,11 @@ $info = array(
     'images/menu-leaf.gif',
   ),
 
+  // CSS files (excluding @import) to rewrite with new color scheme
+  'css' => array(
+    'style.css',
+  ),
+
   // Coordinates of gradient (x, y, width, height)
   'gradient' => array(0, 37, 760, 121),
 
Index: themes/garland/minnelli/color/color.inc
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/minnelli/color/color.inc,v
retrieving revision 1.3
diff -u -p -r1.3 color.inc
--- themes/garland/minnelli/color/color.inc	2 Oct 2007 16:33:09 -0000	1.3
+++ themes/garland/minnelli/color/color.inc	9 Dec 2007 21:15:18 -0000
@@ -30,6 +30,11 @@ $info = array(
     '../images/menu-leaf.gif',
   ),
 
+  // CSS files (excluding @import) to rewrite with new color scheme
+  'css' => array(
+    '../style.css',
+  ),
+
   // Coordinates of gradient (x, y, width, height)
   'gradient' => array(0, 37, 760, 121),
 
