Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.809 diff -u -r1.809 common.inc --- includes/common.inc 15 Oct 2008 16:05:51 -0000 1.809 +++ includes/common.inc 17 Oct 2008 02:36:27 -0000 @@ -1731,55 +1731,82 @@ * file added to the list, if exists in the same directory. This CSS file * should contain overrides for properties which should be reversed or * otherwise different in a right-to-left display. - * @param $type - * (optional) The type of stylesheet that is being added. Types are: module - * or theme. - * @param $media - * (optional) The media type for the stylesheet, e.g., all, print, screen. - * @param $preprocess - * (optional) Should this CSS file be aggregated and compressed if this - * feature has been turned on under the performance section? - * - * What does this actually mean? - * CSS preprocessing is the process of aggregating a bunch of separate CSS - * files into one file that is then compressed by removing all extraneous - * white space. - * - * The reason for merging the CSS files is outlined quite thoroughly here: - * http://www.die.net/musings/page_load_time/ - * "Load fewer external objects. Due to request overhead, one bigger file - * just loads faster than two smaller ones half its size." - * - * However, you should *not* preprocess every file as this can lead to - * redundant caches. You should set $preprocess = FALSE when: - * - * - Your styles are only used rarely on the site. This could be a special - * admin page, the homepage, or a handful of pages that does not represent - * the majority of the pages on your site. - * - * Typical candidates for caching are for example styles for nodes across - * the site, or used in the theme. + * @param $options + * (optional) A string defining the type of CSS that is being added in the + * $path parameter ('module' or 'theme'), or an associative array of + * additional options, with the following keys: + * - 'type' + * The type of stylesheet that is being added. Types are: module or + * theme. + * - 'media' + * The media type for the stylesheet, e.g., all, print, screen. + * - 'preprocess': + * Should this CSS file be aggregated and compressed if this feature has + * been turned on under the performance section? + * + * What does this actually mean? + * CSS preprocessing is the process of aggregating a bunch of separate CSS + * files into one file that is then compressed by removing all extraneous + * white space. + * + * The reason for merging the CSS files is outlined quite thoroughly here: + * http://www.die.net/musings/page_load_time/ + * "Load fewer external objects. Due to request overhead, one bigger file + * just loads faster than two smaller ones half its size." + * + * However, you should *not* preprocess every file as this can lead to + * redundant caches. You should set $preprocess = FALSE when your styles + * are only used rarely on the site. This could be a special admin page, + * the homepage, or a handful of pages that does not represent the + * majority of the pages on your site. + * + * Typical candidates for caching are for example styles for nodes across + * the site, or used in the theme. + * @param $reset + * (optional) Resets the currently loaded cascading stylesheets. * @return * An array of CSS files. */ -function drupal_add_css($path = NULL, $type = 'module', $media = 'all', $preprocess = TRUE) { +function drupal_add_css($path = NULL, $options = NULL, $reset = FALSE) { static $css = array(); global $language; + // Request made to reset the CSS added so far. + if ($reset) { + $css = array(); + } + // 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)) { + // Construct the options, taking the defaults into consideration. + if (isset($options)) { + if (!is_array($options)) { + $options = array('type' => $options); + } + } + else { + $options = array(); + } + $options += array( + 'type' => 'module', + 'media' => 'all', + 'preprocess' => TRUE + ); + $media = $options['media']; + $type = $options['type']; + // This check is necessary to ensure proper cascading of styles and is faster than an asort(). if (!isset($css[$media])) { $css[$media] = array('module' => array(), 'theme' => array()); } - $css[$media][$type][$path] = $preprocess; + $css[$media][$type][$path] = $options['preprocess']; // If the current language is RTL, add the CSS file with RTL overrides. if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $rtl_path = str_replace('.css', '-rtl.css', $path); if (file_exists($rtl_path)) { - $css[$media][$type][$rtl_path] = $preprocess; + $css[$media][$type][$rtl_path] = $options['preprocess']; } } } Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.189 diff -u -r1.189 locale.inc --- includes/locale.inc 12 Oct 2008 04:30:05 -0000 1.189 +++ includes/locale.inc 17 Oct 2008 02:36:27 -0000 @@ -2215,7 +2215,7 @@ */ function _locale_translate_language_list($translation, $limit_language) { // Add CSS - drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css', array('preprocess' => FALSE)); $languages = language_list(); unset($languages['en']); Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.439 diff -u -r1.439 theme.inc --- includes/theme.inc 16 Oct 2008 13:50:21 -0000 1.439 +++ includes/theme.inc 17 Oct 2008 02:36:28 -0000 @@ -133,7 +133,7 @@ // And now add the stylesheets properly foreach ($final_stylesheets as $media => $stylesheets) { foreach ($stylesheets as $stylesheet) { - drupal_add_css($stylesheet, 'theme', $media); + drupal_add_css($stylesheet, array('type' => 'theme', 'media' => $media)); } } Index: modules/simpletest/simpletest.module =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v retrieving revision 1.21 diff -u -r1.21 simpletest.module --- modules/simpletest/simpletest.module 15 Oct 2008 14:17:27 -0000 1.21 +++ modules/simpletest/simpletest.module 17 Oct 2008 02:36:28 -0000 @@ -199,7 +199,7 @@ } function theme_simpletest_test_table($table) { - drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css', 'module'); + drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css'); drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', 'module'); // Create header for test selection table. Index: modules/openid/openid.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.pages.inc,v retrieving revision 1.10 diff -u -r1.10 openid.pages.inc --- modules/openid/openid.pages.inc 13 Oct 2008 00:33:03 -0000 1.10 +++ modules/openid/openid.pages.inc 17 Oct 2008 02:36:28 -0000 @@ -29,7 +29,7 @@ */ function openid_user_identities($account) { drupal_set_title($account->name); - drupal_add_css(drupal_get_path('module', 'openid') . '/openid.css', 'module'); + drupal_add_css(drupal_get_path('module', 'openid') . '/openid.css'); // Check to see if we got a response $result = openid_complete(); Index: modules/openid/openid.module =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.module,v retrieving revision 1.31 diff -u -r1.31 openid.module --- modules/openid/openid.module 12 Oct 2008 04:30:06 -0000 1.31 +++ modules/openid/openid.module 17 Oct 2008 02:36:28 -0000 @@ -75,7 +75,7 @@ */ function openid_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'user_login_block' || $form_id == 'user_login') { - drupal_add_css(drupal_get_path('module', 'openid') . '/openid.css', 'module'); + drupal_add_css(drupal_get_path('module', 'openid') . '/openid.css'); drupal_add_js(drupal_get_path('module', 'openid') . '/openid.js'); if (!empty($form_state['post']['openid_identifier'])) { $form['name']['#required'] = FALSE; Index: modules/help/help.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/help/help.admin.inc,v retrieving revision 1.6 diff -u -r1.6 help.admin.inc --- modules/help/help.admin.inc 14 Apr 2008 17:48:37 -0000 1.6 +++ modules/help/help.admin.inc 17 Oct 2008 02:36:28 -0000 @@ -11,7 +11,7 @@ */ function help_main() { // Add CSS - drupal_add_css(drupal_get_path('module', 'help') . '/help.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'help') . '/help.css', array('preprocess' => FALSE)); $output = '

' . t('Help topics') . '

' . t('Help is available on the following items:') . '

' . help_links_as_list(); return $output; } Index: modules/dblog/dblog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/dblog/dblog.module,v retrieving revision 1.28 diff -u -r1.28 dblog.module --- modules/dblog/dblog.module 6 Oct 2008 11:30:11 -0000 1.28 +++ modules/dblog/dblog.module 17 Oct 2008 02:36:28 -0000 @@ -83,7 +83,7 @@ function dblog_init() { if (arg(0) == 'admin' && arg(1) == 'reports') { // Add the CSS for this module - drupal_add_css(drupal_get_path('module', 'dblog') . '/dblog.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'dblog') . '/dblog.css', array('preprocess' => FALSE)); } } Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.270 diff -u -r1.270 search.module --- modules/search/search.module 12 Oct 2008 19:00:56 -0000 1.270 +++ modules/search/search.module 17 Oct 2008 02:36:28 -0000 @@ -1031,7 +1031,7 @@ function search_form(&$form_state, $action = '', $keys = '', $type = NULL, $prompt = NULL) { // Add CSS - drupal_add_css(drupal_get_path('module', 'search') . '/search.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'search') . '/search.css', array('preprocess' => FALSE)); if (!$action) { $action = url('search/' . $type); Index: modules/tracker/tracker.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/tracker/tracker.pages.inc,v retrieving revision 1.11 diff -u -r1.11 tracker.pages.inc --- modules/tracker/tracker.pages.inc 13 Oct 2008 00:33:05 -0000 1.11 +++ modules/tracker/tracker.pages.inc 17 Oct 2008 02:36:28 -0000 @@ -12,7 +12,7 @@ */ function tracker_page($account = NULL, $set_title = FALSE) { // Add CSS - drupal_add_css(drupal_get_path('module', 'tracker') . '/tracker.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'tracker') . '/tracker.css', array('preprocess' => FALSE)); if ($account) { if ($set_title) { Index: modules/simpletest/tests/common.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v retrieving revision 1.8 diff -u -r1.8 common.test --- modules/simpletest/tests/common.test 15 Oct 2008 16:05:51 -0000 1.8 +++ modules/simpletest/tests/common.test 17 Oct 2008 02:36:28 -0000 @@ -115,6 +115,56 @@ } /** + * Test the Drupal CSS system. + */ +class CascadingStylesheetsTestCase extends DrupalWebTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('Cascading Stylesheets'), + 'description' => t("Tests adding various cascading stylesheets to the page."), + 'group' => t('System') + ); + } + + /** + * Implementation of setUp(). + */ + function setUp() { + parent::setUp(); + // Reset drupal_add_css() before each test. + drupal_add_css(NULL, NULL, TRUE); + } + + /** + * Check default stylesheets as empty. + */ + function testDefault() { + $this->assertEqual(array(), drupal_add_css(), t('Default CSS is empty.')); + } + + /** + * Tests adding a file stylesheet. + */ + function testAddFile() { + $simpletestcss = drupal_get_path('module', 'simpletest') . '/simpletest.css'; + $css = drupal_add_css($simpletestcss); + $this->assertEqual($css['all']['module'][$simpletestcss], TRUE, t('Adding a CSS file caches it properly.')); + } + + /** + * Tests rendering the stylesheets. + */ + function testRenderFile() { + $simpletestcss = drupal_get_path('module', 'simpletest') . '/simpletest.css'; + drupal_add_css($simpletestcss); + $this->assertTrue(strpos(drupal_get_css(), $simpletestcss) > 0, t('Rendered CSS includes the added stylesheet.')); + } +} + +/** * Test drupal_http_request(). */ class DrupalHTTPRequestTestCase extends DrupalWebTestCase { Index: modules/color/color.module =================================================================== RCS file: /cvs/drupal/drupal/modules/color/color.module,v retrieving revision 1.48 diff -u -r1.48 color.module --- modules/color/color.module 9 Oct 2008 00:02:28 -0000 1.48 +++ modules/color/color.module 17 Oct 2008 02:36:28 -0000 @@ -153,11 +153,11 @@ $info = color_get_info($theme); // Add Farbtastic color picker. - drupal_add_css('misc/farbtastic/farbtastic.css', 'module', 'all', FALSE); + drupal_add_css('misc/farbtastic/farbtastic.css', array('preprocess' => FALSE)); drupal_add_js('misc/farbtastic/farbtastic.js'); // Add custom CSS and JS. - drupal_add_css($base . '/color.css', 'module', 'all', FALSE); + drupal_add_css($base . '/color.css', array('preprocess' => FALSE)); drupal_add_js($base . '/color.js'); drupal_add_js(array('color' => array( 'reference' => color_get_palette($theme, TRUE) Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.632 diff -u -r1.632 system.module --- modules/system/system.module 14 Oct 2008 20:44:57 -0000 1.632 +++ modules/system/system.module 17 Oct 2008 02:36:28 -0000 @@ -706,13 +706,13 @@ if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) { global $custom_theme; $custom_theme = variable_get('admin_theme', '0'); - drupal_add_css(drupal_get_path('module', 'system') . '/admin.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') . '/admin.css'); } // Add the CSS for this module. - drupal_add_css(drupal_get_path('module', 'system') . '/defaults.css', 'module'); - drupal_add_css(drupal_get_path('module', 'system') . '/system.css', 'module'); - drupal_add_css(drupal_get_path('module', 'system') . '/system-menus.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') . '/defaults.css'); + drupal_add_css(drupal_get_path('module', 'system') . '/system.css'); + drupal_add_css(drupal_get_path('module', 'system') . '/system-menus.css'); } /** Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.928 diff -u -r1.928 user.module --- modules/user/user.module 12 Oct 2008 04:30:09 -0000 1.928 +++ modules/user/user.module 17 Oct 2008 02:36:28 -0000 @@ -1120,7 +1120,7 @@ } function user_init() { - drupal_add_css(drupal_get_path('module', 'user') . '/user.css', 'module'); + drupal_add_css(drupal_get_path('module', 'user') . '/user.css'); } function user_uid_optional_load($arg) { Index: modules/block/block.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v retrieving revision 1.22 diff -u -r1.22 block.admin.inc --- modules/block/block.admin.inc 13 Oct 2008 00:33:01 -0000 1.22 +++ modules/block/block.admin.inc 17 Oct 2008 02:36:28 -0000 @@ -28,7 +28,7 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { global $theme_key, $custom_theme; - drupal_add_css(drupal_get_path('module', 'block') . '/block.css', 'module', 'all', FALSE); + drupal_add_css(drupal_get_path('module', 'block') . '/block.css', array('preprocess' => FALSE)); // If non-default theme configuration has been selected, set the custom theme. $custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');