Index: includes/ajax.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/ajax.inc,v retrieving revision 1.34 diff -u -p -r1.34 ajax.inc --- includes/ajax.inc 4 Oct 2010 17:46:00 -0000 1.34 +++ includes/ajax.inc 4 Oct 2010 19:46:49 -0000 @@ -565,7 +565,7 @@ function ajax_process_form($element, &$f // Attach JavaScript settings to the element. if (isset($element['#ajax']['event'])) { $element['#attached']['library'][] = array('system', 'form'); - $element['#attached']['js']['misc/ajax.js'] = array('weight' => JS_LIBRARY + 2); + $element['#attached']['js']['misc/ajax.js'] = array('group' => JS_LIBRARY, 'weight' => 2); $settings = $element['#ajax']; Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1232 diff -u -p -r1.1232 common.inc --- includes/common.inc 4 Oct 2010 17:46:00 -0000 1.1232 +++ includes/common.inc 4 Oct 2010 19:46:50 -0000 @@ -56,33 +56,33 @@ define('SAVED_UPDATED', 2); define('SAVED_DELETED', 3); /** - * The default weight of system CSS files added to the page. + * The default group for system CSS files added to the page. */ define('CSS_SYSTEM', -100); /** - * The default weight of CSS files added to the page. + * The default group for module CSS files added to the page. */ define('CSS_DEFAULT', 0); /** - * The default weight of theme CSS files added to the page. + * The default group for theme CSS files added to the page. */ define('CSS_THEME', 100); /** - * The weight of JavaScript libraries, settings or jQuery plugins being - * added to the page. + * The default group for JavaScript libraries, settings or jQuery plugins added + * to the page. */ define('JS_LIBRARY', -100); /** - * The default weight of JavaScript being added to the page. + * The default group for module JavaScript code added to the page. */ define('JS_DEFAULT', 0); /** - * The weight of theme JavaScript code being added to the page. + * The default group for theme JavaScript code added to the page. */ define('JS_THEME', 100); @@ -2734,19 +2734,50 @@ function drupal_add_html_head_link($attr * 'modules/node/node.css' is 'node.css'. If the external library "node.js" * ships with a 'node.css', then a different, unique basename would be * 'node.js.css'. - * - 'weight': The weight of the stylesheet specifies the order in which the - * CSS will appear when presented on the page. Available constants are: + * - 'group': A number identifying the group in which to add the stylesheet. + * Available constants are: * - CSS_SYSTEM: Any system-layer CSS. * - CSS_DEFAULT: Any module-layer CSS. * - CSS_THEME: Any theme-layer CSS. - * If you need to embed a CSS file before any other module's stylesheets, - * for example, you would use CSS_DEFAULT - 1. Note that inline CSS is - * simply appended to the end of the specified scope (region), so they - * always come last. + * The group number serves as a weight: the markup for loading a stylesheet + * within a lower weight group is output to the page before the markup for + * loading a stylesheet within a higher weight group, so CSS within higher + * weight groups take precendence over CSS within lower weight groups. + * - 'every_page': For optimal front-end performance when aggregation is + * enabled, this should be set to TRUE if the stylesheet is present on every + * page of the website for users for whom it is present at all. This + * defaults to FALSE. It is set to TRUE for stylesheets added via module and + * theme .info files. Modules that add stylesheets within hook_init() + * implementations, or from other code that ensures that the stylesheet is + * added to all website pages, should also set this flag to TRUE. All + * stylesheets within the same group that have the 'every_page' flag set to + * TRUE and do not have 'preprocess' set to FALSE are aggregated together + * into a single aggregate file, and that aggregate file can be reused + * across a user's entire site visit, leading to faster navigation between + * pages. However, stylesheets that are only needed on pages less frequently + * visited, can be added by code that only runs for those particular pages, + * and that code should not set the 'every_page' flag. This minimizes the + * size of the aggregate file that the user needs to download when first + * visiting the website. Stylesheets without the 'every_page' flag are + * aggregated into a separate aggregate file. This other aggregate file is + * likely to change from page to page, and each new aggregate file needs to + * be downloaded when first encountered, so it should be kept relatively + * small by ensuring that most commonly needed stylesheets are added to + * every page. + * - 'weight': The weight of the stylesheet specifies the order in which the + * CSS will appear relative to other stylesheets with the same group and + * 'every_page' flag. The exact ordering of stylesheets is as follows: + * - First by group. + * - Then by the 'every_page' flag, with TRUE coming before FALSE. + * - Then by weight. + * - Then by the order in which the CSS was added. For example, all else + * being the same, a stylesheet added by a call to drupal_add_css() that + * happened later in the page request gets added to the page after one for + * which drupal_add_css() happened earlier in the page request. * - 'media': The media type for the stylesheet, e.g., all, print, screen. * Defaults to 'all'. * - 'preprocess': If TRUE and CSS aggregation/compression is enabled, the - * styles will be aggregated and compressed. Defaults to FALSE. + * styles will be aggregated and compressed. Defaults to TRUE. * - 'browsers': An array containing information specifying which browsers * should load the CSS item. See drupal_pre_render_conditional_comments() * for details. @@ -2772,9 +2803,11 @@ function drupal_add_css($data = NULL, $o if (isset($data)) { $options += array( 'type' => 'file', - 'weight' => CSS_DEFAULT, + 'group' => CSS_DEFAULT, + 'weight' => 0, + 'every_page' => FALSE, 'media' => 'all', - 'preprocess' => FALSE, + 'preprocess' => TRUE, 'data' => $data, 'browsers' => array(), ); @@ -2783,6 +2816,11 @@ function drupal_add_css($data = NULL, $o '!IE' => TRUE, ); + // Files with a query string cannot be preprocessed. + if ($options['type'] === 'file' && $options['preprocess'] && strpos($options['data'], '?') !== FALSE) { + $options['preprocess'] = FALSE; + } + // Always add a tiny value to the weight, to conserve the insertion order. $options['weight'] += count($css) / 1000; @@ -2839,8 +2877,8 @@ function drupal_get_css($css = NULL, $sk drupal_alter('css', $css); } - // Sort CSS items according to their weights. - uasort($css, 'drupal_sort_weight'); + // Sort CSS items, so that they appear in the correct order. + uasort($css, 'drupal_sort_css_js'); // Remove the overridden CSS files. Later CSS files override former ones. $previous_item = array(); @@ -2871,6 +2909,46 @@ function drupal_get_css($css = NULL, $sk } /** + * Function used by uasort to sort the array structures returned by drupal_add_css() and drupal_add_js(). + * + * This sort order helps optimize front-end performance while providing modules + * and themes with the necessary control for ordering the CSS and JavaScript + * appearing on a page. + */ +function drupal_sort_css_js($a, $b) { + // First order by group, so that, for example, all items in the CSS_SYSTEM + // group appear before items in the CSS_DEFAULT_GROUP, which appear before + // all items in the CSS_THEME group. Modules may create additional groups by + // defining their own constants. + if ($a['group'] < $b['group']) { + return -1; + } + elseif ($a['group'] > $b['group']) { + return 1; + } + // Within a group, order all infrequently needed, page-specific files after + // common files needed throughout the website. Separating this way allows for + // the aggregate file generated for all of the common files to be reused + // across a site visit without being cut by a page using a less common file. + elseif ($a['every_page'] && !$b['every_page']) { + return -1; + } + elseif (!$a['every_page'] && $b['every_page']) { + return 1; + } + // Finally, order by weight. + elseif ($a['weight'] < $b['weight']) { + return -1; + } + elseif ($a['weight'] > $b['weight']) { + return 1; + } + else { + return 0; + } +} + +/** * Default callback to group CSS items. * * This function arranges the CSS items that are in the #items property of the @@ -2933,7 +3011,10 @@ function drupal_group_css($css) { switch ($item['type']) { case 'file': // Group file items if their 'preprocess' flag is TRUE. - $group_keys = $item['preprocess'] ? array($item['type'], $item['media'], $item['browsers']) : FALSE; + // Help ensure maximum reuse of aggregate files by only grouping + // together items that share the same 'group' value and 'every_page' + // flag. See drupal_add_css() for details about that. + $group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['every_page'], $item['media'], $item['browsers']) : FALSE; break; case 'inline': // Always group inline items. @@ -3683,27 +3764,63 @@ function drupal_region_class($region) { * - scope: The location in which you want to place the script. Possible * values are 'header' or 'footer'. If your theme implements different * regions, you can also use these. Defaults to 'header'. - * - weight: A number defining the order in which the JavaScript is added to - * the page. In some cases, the order in which the JavaScript is presented - * on the page is very important. jQuery, for example, must be added to - * the page before any jQuery code is run, so jquery.js uses a weight of - * JS_LIBRARY - 20, jquery.once.js (a library drupal.js depends on) uses - * a weight of JS_LIBRARY - 19, drupal.js uses a weight of JS_LIBRARY - 1, - * and all following scripts depending on jQuery and Drupal behaviors are - * simply added using the default weight of JS_DEFAULT. Available constants - * are: + * - 'group': A number identifying the group in which to add the JavaScript. + * Available constants are: * - JS_LIBRARY: Any libraries, settings, or jQuery plugins. * - JS_DEFAULT: Any module-layer JavaScript. * - JS_THEME: Any theme-layer JavaScript. - * If you need to invoke a JavaScript file before any other module's - * JavaScript, for example, you would use JS_DEFAULT - 1. + * The group number serves as a weight: JavaScript within a lower weight + * group is presented on the page before JavaScript within a higher weight + * group. + * - 'every_page': For optimal front-end performance when aggregation is + * enabled, this should be set to TRUE if the JavaScript is present on every + * page of the website for users for whom it is present at all. This + * defaults to FALSE. It is set to TRUE for JavaScript files that are added + * via module and theme .info files. Modules that add JavaScript within + * hook_init() implementations, or from other code that ensures that the + * JavaScript is added to all website pages, should also set this flag to + * TRUE. All JavaScript files within the same group and that have the + * 'every_page' flag set to TRUE and do not have 'preprocess' set to FALSE + * are aggregated together into a single aggregate file, and that aggregate + * file can be reused across a user's entire site visit, leading to faster + * navigation between pages. However, JavaScript that is only needed on + * pages less frequently visited, can be added by code that only runs for + * those particular pages, and that code should not set the 'every_page' + * flag. This minimizes the size of the aggregate file that the user needs + * to download when first visiting the website. JavaScript without the + * 'every_page' flag is aggregated into a separate aggregate file. This + * other aggregate file is likely to change from page to page, and each new + * aggregate file needs to be downloaded when first encountered, so it + * should be kept relatively small by ensuring that most commonly needed + * JavaScript is added to every page. + * - weight: A number defining the order in which the JavaScript is added to + * the page relative to other JavaScript with the same 'scope', 'group', + * and 'every_page' value. In some cases, the order in which the JavaScript + * is presented on the page is very important. jQuery, for example, must be + * added to the page before any jQuery code is run, so jquery.js uses the + * JS_LIBRARY group and a weight of -20, jquery.once.js (a library drupal.js + * depends on) uses the JS_LIBRARY group and a weight of -19, drupal.js uses + * the JS_LIBRARY group and a weight of -1, other libraries use the + * JS_LIBRARY group and a weight of 0 or higher, and all other scripts use + * one of the other group constants. The exact ordering of JavaScript is as + * follows: + * - First by scope, with 'header' first, 'footer' last, and any other + * scopes provided by a custom theme coming in between, as determined by + * the theme. + * - Then by group. + * - Then by the 'every_page' flag, with TRUE coming before FALSE. + * - Then by weight. + * - Then by the order in which the JavaScript was added. For example, all + * else being the same, JavaScript added by a call to drupal_add_js() that + * happened later in the page request gets added to the page after one for + * which drupal_add_js() happened earlier in the page request. * - defer: If set to TRUE, the defer attribute is set on the <script> * tag. Defaults to FALSE. * - cache: If set to FALSE, the JavaScript file is loaded anew on every page * call; in other words, it is not cached. Used only when 'type' references * a JavaScript file. Defaults to TRUE. * - preprocess: If TRUE and JavaScript aggregation is enabled, the script - * file will be aggregated. Defaults to FALSE. + * file will be aggregated. Defaults to TRUE. * * @return * The current array of JavaScript files, settings, and in-line code, @@ -3744,21 +3861,25 @@ function drupal_add_js($data = NULL, $op ), 'type' => 'setting', 'scope' => 'header', - 'weight' => JS_LIBRARY, + 'group' => JS_LIBRARY, + 'every_page' => TRUE, + 'weight' => 0, ), 'misc/drupal.js' => array( 'data' => 'misc/drupal.js', 'type' => 'file', 'scope' => 'header', - 'weight' => JS_LIBRARY - 1, + 'group' => JS_LIBRARY, + 'every_page' => TRUE, + 'weight' => -1, + 'preprocess' => TRUE, 'cache' => TRUE, 'defer' => FALSE, - 'preprocess' => TRUE, ), ); // Register all required libraries. - drupal_add_library('system', 'jquery'); - drupal_add_library('system', 'once'); + drupal_add_library('system', 'jquery', TRUE); + drupal_add_library('system', 'once', TRUE); } switch ($options['type']) { @@ -3792,11 +3913,13 @@ function drupal_add_js($data = NULL, $op function drupal_js_defaults($data = NULL) { return array( 'type' => 'file', - 'weight' => JS_DEFAULT, + 'group' => JS_DEFAULT, + 'every_page' => FALSE, + 'weight' => 0, 'scope' => 'header', 'cache' => TRUE, 'defer' => FALSE, - 'preprocess' => FALSE, + 'preprocess' => TRUE, 'version' => NULL, 'data' => $data, ); @@ -3880,8 +4003,8 @@ function drupal_get_js($scope = 'header' // third-party code might require the use of a different query string. $js_version_string = variable_get('drupal_js_version_query_string', 'v='); - // Sort the JavaScript by weight so that it appears in the correct order. - uasort($items, 'drupal_sort_weight'); + // Sort the JavaScript so that it appears in the correct order. + uasort($items, 'drupal_sort_css_js'); // Provide the page with information about the individual JavaScript files // used, information not otherwise available when aggregation is enabled. @@ -3942,8 +4065,13 @@ function drupal_get_js($scope = 'header' } else { // By increasing the index for each aggregated file, we maintain - // the relative ordering of JS by weight. - $key = 'aggregate' . $index; + // the relative ordering of JS by weight. We also set the key such + // that groups are split by items sharing the same 'group' value and + // 'every_page' flag. While this potentially results in more aggregate + // files, it helps make each one more reusable across a site visit, + // leading to better front-end performance of a website as a whole. + // See drupal_add_js() for details. + $key = 'aggregate_' . $item['group'] . '_' . $item['every_page'] . '_' . $index; $processed[$key] = ''; $files[$key][$item['data']] = $item; } @@ -4007,9 +4135,9 @@ function drupal_get_js($scope = 'header' * * @param $elements * The structured array describing the data being rendered. - * @param $weight - * The default weight of JavaScript and CSS being added. This is only applied - * to the stylesheets and JavaScript items that don't have an explicit weight + * @param $group + * The default group of JavaScript and CSS being added. This is only applied + * to the stylesheets and JavaScript items that don't have an explicit group * assigned to them. * @param $dependency_check * When TRUE, will exit if a given library's dependencies are missing. When @@ -4025,7 +4153,7 @@ function drupal_get_js($scope = 'header' * @see drupal_add_css() * @see drupal_render() */ -function drupal_process_attached($elements, $weight = JS_DEFAULT, $dependency_check = FALSE) { +function drupal_process_attached($elements, $group = JS_DEFAULT, $dependency_check = FALSE, $every_page = NULL) { // Add defaults to the special attached structures that should be processed differently. $elements['#attached'] += array( 'library' => array(), @@ -4036,7 +4164,7 @@ function drupal_process_attached($elemen // Add the libraries first. $success = TRUE; foreach ($elements['#attached']['library'] as $library) { - if (drupal_add_library($library[0], $library[1]) === FALSE) { + if (drupal_add_library($library[0], $library[1], $every_page) === FALSE) { $success = FALSE; // Exit if the dependency is missing. if ($dependency_check) { @@ -4063,9 +4191,13 @@ function drupal_process_attached($elemen $data = $options['data']; unset($options['data']); } - // Apply the default weight if the weight isn't explicitly given. - if (!isset($options['weight'])) { - $options['weight'] = $weight; + // Apply the default group if it isn't explicitly given. + if (!isset($options['group'])) { + $options['group'] = $group; + } + // Set the every_page flag if one was passed. + if (isset($every_page)) { + $options['every_page'] = $every_page; } call_user_func('drupal_add_' . $type, $data, $options); } @@ -4212,7 +4344,7 @@ function drupal_process_attached($elemen * @see form_example_states_form() */ function drupal_process_states(&$elements) { - $elements['#attached']['js']['misc/states.js'] = array('weight' => JS_LIBRARY + 1); + $elements['#attached']['js']['misc/states.js'] = array('group' => JS_LIBRARY, 'weight' => 1); $elements['#attached']['js'][] = array( 'type' => 'setting', 'data' => array('states' => array('#' . $elements['#id'] => $elements['#states'])), @@ -4241,7 +4373,7 @@ function drupal_process_states(&$element * @see hook_library() * @see hook_library_alter() */ -function drupal_add_library($module, $name) { +function drupal_add_library($module, $name, $every_page = NULL) { $added = &drupal_static(__FUNCTION__, array()); // Only process the library if it exists and it was not added already. @@ -4253,7 +4385,7 @@ function drupal_add_library($module, $na 'js' => $library['js'], 'css' => $library['css'], ); - $added[$module][$name] = drupal_process_attached($elements, JS_LIBRARY, TRUE); + $added[$module][$name] = drupal_process_attached($elements, JS_LIBRARY, TRUE, $every_page); } else { // Requested library does not exist. @@ -4434,8 +4566,8 @@ function drupal_add_tabledrag($table_id, // Add the table drag JavaScript to the page before the module JavaScript // to ensure that table drag behaviors are registered before any module // uses it. - drupal_add_js('misc/jquery.cookie.js', array('weight' => JS_DEFAULT - 2)); - drupal_add_js('misc/tabledrag.js', array('weight' => JS_DEFAULT - 1)); + drupal_add_js('misc/jquery.cookie.js', array('weight' => -2)); + drupal_add_js('misc/tabledrag.js', array('weight' => -1)); $js_added = TRUE; } Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.500 diff -u -p -r1.500 form.inc --- includes/form.inc 4 Oct 2010 18:00:45 -0000 1.500 +++ includes/form.inc 4 Oct 2010 19:46:51 -0000 @@ -3061,7 +3061,7 @@ function form_process_fieldset(&$element } // Contains form element summary functionalities. - $element['#attached']['js']['misc/form.js'] = array('weight' => JS_LIBRARY + 1); + $element['#attached']['js']['misc/form.js'] = array('group' => JS_LIBRARY, 'weight' => 1); // The .form-wrapper class is required for #states to treat fieldsets like // containers. Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.617 diff -u -p -r1.617 theme.inc --- includes/theme.inc 4 Oct 2010 17:46:00 -0000 1.617 +++ includes/theme.inc 4 Oct 2010 19:46:52 -0000 @@ -173,7 +173,7 @@ function _drupal_theme_initialize($theme // And now add the stylesheets properly foreach ($final_stylesheets as $media => $stylesheets) { foreach ($stylesheets as $stylesheet) { - drupal_add_css($stylesheet, array('weight' => CSS_THEME, 'media' => $media, 'preprocess' => TRUE)); + drupal_add_css($stylesheet, array('group' => CSS_THEME, 'every_page' => TRUE, 'media' => $media)); } } @@ -198,7 +198,7 @@ function _drupal_theme_initialize($theme // Add scripts used by this theme. foreach ($final_scripts as $script) { - drupal_add_js($script, array('weight' => JS_THEME, 'preprocess' => TRUE)); + drupal_add_js($script, array('group' => JS_THEME, 'every_page' => TRUE)); } $theme_engine = NULL; Index: modules/color/color.module =================================================================== RCS file: /cvs/drupal/drupal/modules/color/color.module,v retrieving revision 1.91 diff -u -p -r1.91 color.module --- modules/color/color.module 22 Sep 2010 03:24:09 -0000 1.91 +++ modules/color/color.module 4 Oct 2010 19:46:54 -0000 @@ -247,7 +247,7 @@ function theme_color_scheme_form($variab $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js'; // Add the JS at a weight below color.js. - drupal_add_js($preview_js_path, array('weight' => JS_DEFAULT - 1)); + drupal_add_js($preview_js_path, array('weight' => -1)); $output = ''; $output .= '
'; Index: modules/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.300 diff -u -p -r1.300 locale.module --- modules/locale/locale.module 1 Oct 2010 15:24:18 -0000 1.300 +++ modules/locale/locale.module 4 Oct 2010 19:46:58 -0000 @@ -905,7 +905,7 @@ function locale_library_alter(&$librarie global $language; if ($module == 'system' && isset($libraries['system']['ui.datepicker'])) { $datepicker = drupal_get_path('module', 'locale') . '/locale.datepicker.js'; - $libraries['system']['ui.datepicker']['js'][$datepicker] = array('weight' => JS_THEME); + $libraries['system']['ui.datepicker']['js'][$datepicker] = array('group' => JS_THEME); $libraries['system']['ui.datepicker']['js'][] = array( 'data' => array( 'jqueryuidatepicker' => array( Index: modules/simpletest/tests/common.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v retrieving revision 1.127 diff -u -p -r1.127 common.test --- modules/simpletest/tests/common.test 19 Sep 2010 18:10:41 -0000 1.127 +++ modules/simpletest/tests/common.test 4 Oct 2010 19:47:02 -0000 @@ -655,7 +655,7 @@ class CascadingStylesheetsTestCase exten function testRenderInlinePreprocess() { $css = 'body { padding: 0px; }'; $css_preprocessed = ''; - drupal_add_css($css, array('type' => 'inline', 'preprocess' => TRUE)); + drupal_add_css($css, array('type' => 'inline')); $styles = drupal_get_css(); $this->assertEqual(trim($styles), $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.')); } @@ -665,7 +665,7 @@ class CascadingStylesheetsTestCase exten */ function testRenderInlineNoPreprocess() { $css = 'body { padding: 0px; }'; - drupal_add_css($css, array('type' => 'inline')); + drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE)); $styles = drupal_get_css(); $this->assertTrue(strpos($styles, $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.')); } @@ -675,7 +675,9 @@ class CascadingStylesheetsTestCase exten */ function testRenderInlineFullPage() { $css = 'body { font-size: 254px; }'; - $expected = $css; + // Inline CSS is minified unless 'preprocess' => FALSE is passed as a + // drupal_add_css() option. + $expected = 'body{font-size:254px;}'; // Create a node, using the PHP filter that tests drupal_add_css(). $php_format_id = db_query_range('SELECT format FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField(); @@ -706,9 +708,9 @@ class CascadingStylesheetsTestCase exten drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css'); // A few system CSS files, ordered in a strange way. $system_path = drupal_get_path('module', 'system'); - drupal_add_css($system_path . '/system.menus.css', array('weight' => CSS_SYSTEM)); - drupal_add_css($system_path . '/system.base.css', array('weight' => CSS_SYSTEM - 10)); - drupal_add_css($system_path . '/system.theme.css', array('weight' => CSS_SYSTEM)); + drupal_add_css($system_path . '/system.menus.css', array('group' => CSS_SYSTEM)); + drupal_add_css($system_path . '/system.base.css', array('group' => CSS_SYSTEM, 'weight' => -10)); + drupal_add_css($system_path . '/system.theme.css', array('group' => CSS_SYSTEM)); $expected = array( $system_path . '/system.base.css', @@ -1242,11 +1244,19 @@ class JavaScriptTestCase extends DrupalW } /** + * Test adding a JavaScript file with a different group. + */ + function testDifferentGroup() { + $javascript = drupal_add_js('misc/collapse.js', array('group' => JS_THEME)); + $this->assertEqual($javascript['misc/collapse.js']['group'], JS_THEME, t('Adding a JavaScript file with a different group caches the given group.')); + } + + /** * Test adding a JavaScript file with a different weight. */ function testDifferentWeight() { - $javascript = drupal_add_js('misc/collapse.js', array('weight' => JS_THEME)); - $this->assertEqual($javascript['misc/collapse.js']['weight'], JS_THEME, t('Adding a JavaScript file with a different weight caches the given weight.')); + $javascript = drupal_add_js('misc/collapse.js', array('weight' => 2)); + $this->assertEqual($javascript['misc/collapse.js']['weight'], 2, t('Adding a JavaScript file with a different weight caches the given weight.')); } /** @@ -1295,7 +1305,10 @@ class JavaScriptTestCase extends DrupalW * Test rendering the JavaScript with a file's weight above jQuery's. */ function testRenderDifferentWeight() { - drupal_add_js('misc/collapse.js', array('weight' => JS_LIBRARY - 21)); + // JavaScript files are sorted first by group, then by the 'every_page' + // flag, then by weight (see drupal_sort_css_js()), so to test the effect of + // weight, we need the other two options to be the same. + drupal_add_js('misc/collapse.js', array('group' => JS_LIBRARY, 'every_page' => TRUE, 'weight' => -21)); $javascript = drupal_get_js(); $this->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), t('Rendering a JavaScript file above jQuery.')); } @@ -1308,7 +1321,7 @@ class JavaScriptTestCase extends DrupalW function testAlter() { // Add both tableselect.js and simpletest.js, with a larger weight on SimpleTest. drupal_add_js('misc/tableselect.js'); - drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => JS_THEME)); + drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => 9999)); // Render the JavaScript, testing if simpletest.js was altered to be before // tableselect.js. See simpletest_js_alter() to see where this alteration Index: modules/simpletest/tests/system.base.css =================================================================== RCS file: modules/simpletest/tests/system.base.css diff -N modules/simpletest/tests/system.base.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/tests/system.base.css 4 Oct 2010 19:47:03 -0000 @@ -0,0 +1,7 @@ +/* $Id: system.base.css $ */ + +/** + * This file is for testing CSS file override in + * CascadingStylesheetsTestCase::testRenderOverride(). + * No contents are necessary. + */ Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.972 diff -u -p -r1.972 system.module --- modules/system/system.module 4 Oct 2010 18:00:46 -0000 1.972 +++ modules/system/system.module 4 Oct 2010 19:47:07 -0000 @@ -1066,7 +1066,7 @@ function system_library() { 'website' => 'http://jquery.com', 'version' => '1.4.2', 'js' => array( - 'misc/jquery.js' => array('weight' => JS_LIBRARY - 20, 'preprocess' => TRUE), + 'misc/jquery.js' => array('group' => JS_LIBRARY, 'weight' => -20), ), ); @@ -1076,7 +1076,7 @@ function system_library() { 'website' => 'http://plugins.jquery.com/project/once', 'version' => '1.2', 'js' => array( - 'misc/jquery.once.js' => array('weight' => JS_LIBRARY - 19, 'preprocess' => TRUE), + 'misc/jquery.once.js' => array('group' => JS_LIBRARY, 'weight' => -19), ), ); @@ -1142,7 +1142,7 @@ function system_library() { 'website' => 'http://jqueryui.com', 'version' => '1.8', 'js' => array( - 'misc/ui/jquery.ui.core.min.js' => array('weight' => JS_LIBRARY - 11), + 'misc/ui/jquery.ui.core.min.js' => array('group' => JS_LIBRARY, 'weight' => -11), ), 'css' => array( 'misc/ui/jquery.ui.core.css' => array(), @@ -1359,7 +1359,7 @@ function system_library() { 'website' => 'http://docs.jquery.com/UI/Widget', 'version' => '1.8', 'js' => array( - 'misc/ui/jquery.ui.widget.min.js' => array('weight' => JS_LIBRARY - 10), + 'misc/ui/jquery.ui.widget.min.js' => array('group' => JS_LIBRARY, 'weight' => -10), ), 'dependencies' => array( array('system', 'ui'), @@ -1370,7 +1370,7 @@ function system_library() { 'website' => 'http://jqueryui.com/demos/effect/', 'version' => '1.8', 'js' => array( - 'misc/ui/jquery.effects.core.min.js' => array('weight' => JS_LIBRARY - 9), + 'misc/ui/jquery.effects.core.min.js' => array('group' => JS_LIBRARY, 'weight' => -9), ), ); $libraries['effects.blind'] = array( @@ -1819,14 +1819,15 @@ function _system_filetransfer_backend_fo */ function system_init() { $path = drupal_get_path('module', 'system'); - // Add the CSS for this module. - drupal_add_css($path . '/system.base.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); + // Add the CSS for this module. These aren't in system.info, because they + // need to be in the CSS_SYSTEM group rather than the CSS_DEFAULT group. + drupal_add_css($path . '/system.base.css', array('group' => CSS_SYSTEM, 'every_page' => TRUE)); if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit' || arg(2) == 'delete'))) { - drupal_add_css($path . '/system.admin.css', array('weight' => CSS_SYSTEM)); + drupal_add_css($path . '/system.admin.css', array('group' => CSS_SYSTEM)); } - drupal_add_css($path . '/system.menus.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); - drupal_add_css($path . '/system.messages.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); - drupal_add_css($path . '/system.theme.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); + drupal_add_css($path . '/system.menus.css', array('group' => CSS_SYSTEM, 'every_page' => TRUE)); + drupal_add_css($path . '/system.messages.css', array('group' => CSS_SYSTEM, 'every_page' => TRUE)); + drupal_add_css($path . '/system.theme.css', array('group' => CSS_SYSTEM, 'every_page' => TRUE)); // Ignore slave database servers for this request. // @@ -1862,13 +1863,13 @@ function system_add_module_assets() { if (!empty($info['stylesheets'])) { foreach ($info['stylesheets'] as $media => $stylesheets) { foreach ($stylesheets as $stylesheet) { - drupal_add_css($stylesheet, array('media' => $media, 'preprocess' => TRUE)); + drupal_add_css($stylesheet, array('every_page' => TRUE, 'media' => $media)); } } } if (!empty($info['scripts'])) { foreach ($info['scripts'] as $script) { - drupal_add_js($script, array('preprocess' => TRUE)); + drupal_add_js($script, array('every_page' => TRUE)); } } } Index: modules/toolbar/toolbar.module =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v retrieving revision 1.45 diff -u -p -r1.45 toolbar.module --- modules/toolbar/toolbar.module 20 Sep 2010 02:43:18 -0000 1.45 +++ modules/toolbar/toolbar.module 4 Oct 2010 19:47:08 -0000 @@ -188,7 +188,7 @@ function toolbar_view() { '#attached'=> array( 'js' => array( $module_path . '/toolbar.js', - array('data' => 'misc/jquery.cookie.js', 'weight' => JS_LIBRARY + 2), + array('data' => 'misc/jquery.cookie.js', 'group' => JS_LIBRARY, 'weight' => 2), array( 'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'), 'type' => 'setting' Index: themes/bartik/template.php =================================================================== RCS file: /cvs/drupal/drupal/themes/bartik/template.php,v retrieving revision 1.5 diff -u -p -r1.5 template.php --- themes/bartik/template.php 1 Sep 2010 02:13:58 -0000 1.5 +++ themes/bartik/template.php 4 Oct 2010 19:47:09 -0000 @@ -23,8 +23,8 @@ function bartik_preprocess_html(&$variab } // Add conditional stylesheets for IE - drupal_add_css(path_to_theme() . '/css/ie.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 7', '!IE' => FALSE))); - drupal_add_css(path_to_theme() . '/css/ie6.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'IE 6', '!IE' => FALSE))); + drupal_add_css(path_to_theme() . '/css/ie.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 7', '!IE' => FALSE), 'preprocess' => FALSE)); + drupal_add_css(path_to_theme() . '/css/ie6.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'IE 6', '!IE' => FALSE), 'preprocess' => FALSE)); } /** Index: themes/garland/template.php =================================================================== RCS file: /cvs/drupal/drupal/themes/garland/template.php,v retrieving revision 1.41 diff -u -p -r1.41 template.php --- themes/garland/template.php 30 Jul 2010 02:47:28 -0000 1.41 +++ themes/garland/template.php 4 Oct 2010 19:47:10 -0000 @@ -42,7 +42,7 @@ function garland_preprocess_html(&$vars) $vars['classes_array'][] = 'fluid-width'; } // Add conditional CSS for IE6. - drupal_add_css(path_to_theme() . '/fix-ie.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE))); + drupal_add_css(path_to_theme() . '/fix-ie.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE), 'preprocess' => FALSE)); } /** Index: themes/seven/template.php =================================================================== RCS file: /cvs/drupal/drupal/themes/seven/template.php,v retrieving revision 1.23 diff -u -p -r1.23 template.php --- themes/seven/template.php 3 Oct 2010 02:46:12 -0000 1.23 +++ themes/seven/template.php 4 Oct 2010 19:47:10 -0000 @@ -18,9 +18,9 @@ function seven_preprocess_maintenance_pa */ function seven_preprocess_html(&$vars) { // Add conditional CSS for IE8 and below. - drupal_add_css(path_to_theme() . '/ie.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE))); + drupal_add_css(path_to_theme() . '/ie.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE), 'preprocess' => FALSE)); // Add conditional CSS for IE6. - drupal_add_css(path_to_theme() . '/ie6.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE))); + drupal_add_css(path_to_theme() . '/ie6.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE), 'preprocess' => FALSE)); } /**