diff --git a/includes/ajax.inc b/includes/ajax.inc index bd590aa66046489955ecc2ad999b1a6866654cc0..1760aac5cc84f49e42c2e040dc35c562386363e0 100644 --- a/includes/ajax.inc +++ b/includes/ajax.inc @@ -565,7 +565,7 @@ function ajax_process_form($element, &$form_state) { // 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']; diff --git a/includes/common.inc b/includes/common.inc index 0cddf5de075321b8be349e1e89a85a73c171024c..824e32751f3c08e752604c80976f046928d7316a 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -56,33 +56,33 @@ 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($attributes, $header = FALSE) { * '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, $options = NULL) { 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, $options = NULL) { '!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, $skip_alter = FALSE) { 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(); @@ -2870,6 +2908,46 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) { return drupal_render($styles); } +/** + * 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. * @@ -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, $options = NULL) { ), '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, $options = NULL) { 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', $javascript = NULL, $skip_alter = FALS // 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', $javascript = NULL, $skip_alter = FALS } 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', $javascript = NULL, $skip_alter = FALS * * @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', $javascript = NULL, $skip_alter = FALS * @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($elements, $weight = JS_DEFAULT, $dependency_ch // 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($elements, $weight = JS_DEFAULT, $dependency_ch $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($elements, $weight = JS_DEFAULT, $dependency_ch * @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(&$elements) { * @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, $name) { '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, $action, $relationship, $group, $subgro // 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; } diff --git a/includes/form.inc b/includes/form.inc index 3d468391c455b36de4882c968c82db46d80828ac..2610c99021db0bfeaf34532a2dcc4a5a924e78e1 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -3061,7 +3061,7 @@ function form_process_fieldset(&$element, &$form_state) { } // 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. diff --git a/includes/theme.inc b/includes/theme.inc index 4ccbcbf2c25608d83c11a4b6734f9e77797a7110..e042d5d2a64abb3e868532edd26e7f506cfa1189 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -173,7 +173,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb // 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, $base_theme = array(), $registry_callb // 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; diff --git a/modules/color/color.module b/modules/color/color.module index a9d8980903a44af4b7c5aa38d525cef51037fc4f..d94cadc3374cf44c674ccad8e09f89ecf3cfbf47 100644 --- a/modules/color/color.module +++ b/modules/color/color.module @@ -247,7 +247,7 @@ function theme_color_scheme_form($variables) { $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 .= '<div class="color-form clearfix">'; diff --git a/modules/locale/locale.module b/modules/locale/locale.module index 6233f7c0eb9347254ec1f42ce2ee680c6ec09091..92147aa8a58e000c167c6e1c64cde39c8668659d 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -880,7 +880,7 @@ function locale_library_alter(&$libraries, $module) { 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( diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index 97cea80e53919a68ea1bb910b1866ce178a237e0..43f4b5cc105d1debc40e2f83f96eed26b5846c1f 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -655,7 +655,7 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase { function testRenderInlinePreprocess() { $css = 'body { padding: 0px; }'; $css_preprocessed = '<style type="text/css" media="all">' . drupal_load_stylesheet_content($css, TRUE) . '</style>'; - 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 extends DrupalWebTestCase { */ 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 extends DrupalWebTestCase { */ 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 extends DrupalWebTestCase { 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', @@ -1241,12 +1243,20 @@ class JavaScriptTestCase extends DrupalWebTestCase { $this->assertFalse($javascript['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); } + /** + * 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 DrupalWebTestCase { * 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 DrupalWebTestCase { 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 diff --git a/modules/system/system.module b/modules/system/system.module index 08d2010ccd89c1e7b34af44ab1c9f5bf39c7bc39..ce9cdf6d30b7c353a5d9011d06166b0e35b05810 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -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_form_common() { */ 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)); } } } diff --git a/modules/toolbar/toolbar.module b/modules/toolbar/toolbar.module index ebbdb34c15b385a7e96df28e879130be2f531b34..af39ac41b126da7b3378a7fcc4432e738be2b53d 100644 --- a/modules/toolbar/toolbar.module +++ b/modules/toolbar/toolbar.module @@ -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' diff --git a/themes/bartik/template.php b/themes/bartik/template.php index 9132a9f0e6b2e5750ff6e8371ce76ac5329d4839..acc04a0f21db1357f59484f995fc8252a5a70acc 100644 --- a/themes/bartik/template.php +++ b/themes/bartik/template.php @@ -23,8 +23,8 @@ function bartik_preprocess_html(&$variables) { } // 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)); } /** diff --git a/themes/garland/template.php b/themes/garland/template.php index ecd14a47e9cb24cdd35166e2282bcb0546fc2539..020eb5f8da9d816d799c51961cad73adeb9aef40 100644 --- a/themes/garland/template.php +++ b/themes/garland/template.php @@ -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)); } /** diff --git a/themes/seven/template.php b/themes/seven/template.php index e87868c727eff78cd5f223c32ab501cae722407b..78d41f1689a39b62810e9bd3db6be3c137a78aea 100644 --- a/themes/seven/template.php +++ b/themes/seven/template.php @@ -18,9 +18,9 @@ function seven_preprocess_maintenance_page(&$vars) { */ 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)); } /**