Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.587 diff -u -F^f -r1.587 common.inc --- includes/common.inc 16 Nov 2006 09:18:22 -0000 1.587 +++ includes/common.inc 21 Nov 2006 06:38:01 -0000 @@ -1292,10 +1292,12 @@ function drupal_add_link($attributes) { * An array of CSS files. */ function drupal_add_css($path = NULL, $type = 'module', $media = 'all') { - static $css = array('core' => array(), 'module' => array(), 'theme' => array()); + static $css = array(); - if (!is_null($path)) { - $css[$type][$path] = array('path' => $path, 'media' => $media); + // Create an array of CSS files for each media type first, since each type needs to be served + // to the browser differently. + if (isset($path)) { + $css[$media][$type][$path] = array('path' => $path, 'media' => $media); } return $css; @@ -1313,17 +1315,89 @@ function drupal_add_css($path = NULL, $t */ function drupal_get_css($css = NULL) { $output = ''; - if (is_null($css)) { + if (!isset($css)) { $css = drupal_add_css(); } + $directory_path = file_directory_path(); + + if (is_writable($directory_path) && variable_get('cache_css', TRUE) == TRUE) { + foreach ($css as $media => $types) { + $filename = md5(serialize($types)) .'.css'; + $path = $directory_path .'/css/'; + + if (!file_exists($path . $filename)) { + $filename = drupal_build_css_cache($types); + } + + $output .= ''. "\n"; + } + } + else { + foreach ($css as $media => $types) { + foreach ($types as $type) { + foreach ($type as $file) { + $output .= '' ."\n"; + } + } + } + } + + return $output; +} + +/** + * Aggregate and optimize CSS files, putting them in the files directory. + * + * @param $css + * An array of CSS files to aggregate and compress into one file. + * @return + * The name of the CSS file. + */ +function drupal_build_css_cache($css) { + $data = ''; + $filename = md5(serialize($css)) .'.css'; + + // Create the css/ within the files folder + file_check_directory(file_create_path('css'), FILE_CREATE_DIRECTORY); + + // Build aggregate CSS file foreach ($css as $type) { foreach ($type as $file) { - $output .= '\n"; + $contents = file_get_contents($file['path']); + // Return the path to either the module or theme where this CSS file originated from + $path = base_path() . substr($file['path'], 0, strrpos($file['path'], '/')) .'/'; + // Fix all paths within this CSS file, ignoring absolute paths and paths that go up a directory, ../ + $contents = preg_replace('/url\(([\'"]?)(?![a-z]+:)(?!\.\.\/)/i', 'url(\1'. $path . '\2', $contents); + // Fix all paths to misc/ + $data .= str_replace('url(../../misc/', 'url('. base_path() .'/misc/', $contents); } } - return $output; + // If any modules implement hook_compress_css, let them handle compressing + // the css, otherwise just strip out the whitespace, which can be done safely. + if (module_invoke_all('hook_compress_css')) { + foreach (module_implements('compress_css') as $module) { + $function = $module .'_compress_css'; + $function($contents); + } + } + else { + // Preform some safe CSS optimizations for removing white space + $data = str_replace(array(": ", "; ", "\n", "\t", "\r", ), array(':', ';', '', '', ''), $data); + } + + // Create the CSS file + file_save_data($data, file_create_path('css/') .'/'. $filename, FILE_EXISTS_REPLACE); + + return $filename; +} + +/** + * Delete all cached CSS files + */ +function drupal_flush_css_cache() { + file_scan_directory(file_create_path('css'), '.*', array('.', '..', 'CVS'), 'file_delete', TRUE); } /** Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.399 diff -u -F^f -r1.399 system.module --- modules/system/system.module 19 Nov 2006 23:51:01 -0000 1.399 +++ modules/system/system.module 21 Nov 2006 06:38:04 -0000 @@ -1118,6 +1118,8 @@ function system_settings_form_submit($fo * Menu callback; displays a listing of all themes. */ function system_themes() { + // Clear cached CSS files + drupal_flush_css_cache(); $themes = system_theme_data(); ksort($themes);