Index: includes/batch.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/batch.inc,v retrieving revision 1.26 diff -u -r1.26 batch.inc --- includes/batch.inc 22 Oct 2008 19:39:36 -0000 1.26 +++ includes/batch.inc 30 Oct 2008 19:51:18 -0000 @@ -84,7 +84,7 @@ // error messages. Only safe strings should be passed in to batch_set(). $current_set = _batch_current_set(); drupal_set_title($current_set['title'], PASS_THROUGH); - drupal_add_js('misc/progress.js', array('type' => 'core', 'cache' => FALSE)); + drupal_add_js('misc/progress.js', array('#weight' => -16, '#cache' => FALSE)); $url = url($batch['url'], array('query' => array('id' => $batch['id']))); $js_setting = array( @@ -95,7 +95,7 @@ ), ); drupal_add_js($js_setting, 'setting'); - drupal_add_js('misc/batch.js', array('type' => 'core', 'cache' => FALSE)); + drupal_add_js('misc/batch.js', array('#weight' => -16, '#cache' => FALSE)); $output = '
'; return $output; Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.812 diff -u -r1.812 common.inc --- includes/common.inc 29 Oct 2008 10:06:06 -0000 1.812 +++ includes/common.inc 30 Oct 2008 19:51:18 -0000 @@ -1722,6 +1722,102 @@ } /** + * TODO: Doxygen + */ +function drupal_add_support_file($type = NULL, $path = NULL, $options = array(), $reset = FALSE) { + static $support_files = array(); + if ($reset) { + $support_files = array(); + } + if (!$path) { + return $support_files; + } + + $file = $options; + // Store parameters for easy reference later. + $file['#type'] = $type; + $file['#path'] = $path; + if (!isset($file['#method']) || $file['#method'] == 'file') { + // If the path is a file path use that as the key, for easier alteration. + $support_files[$type][$path] = $file; + } + else { + // If not, just use a numeric key. + $support_files[$type][] = $file; + } +} + +/** + * TODO: Doxygen + */ +function drupal_get_support_files($type, $scope = NULL) { + // Collect and process all files, if we haven't already. + if (!isset($support_files)) { + static $support_files = array(); + $support_files = module_invoke_all('support_files'); + $support_files += drupal_add_support_file(); + support_file_defaults($support_files); + + // Sort and alter + foreach ($support_files as $key => $files) { + uasort($support_files[$key], 'element_sort'); + } + drupal_alter('support_files', $support_files); + } + + // If we still don't have any files of the requested type, then nothing to do. + if (!array_key_exists($type, $support_files)) { + return; + } + + // TODO: Aggregate files + // require_once variable_get('support_file_aggregation_inc', './includes/support_file_aggregation.inc'); + // $function = 'aggregation_' . $type; + // if (function_exists($function)) { + // $function($support_files); + // } + return theme('support_files_' . $type, $support_files[$type], $scope); +} + +function support_file_defaults(&$support_files) { + foreach ($support_files as $type => $files) { + $function = 'support_file_defaults_' . $type; + if (function_exists($function)) { + $defaults = $function(); + foreach ($files as $key => $file) { + // Allow shortcut array for file paths for brevity. + if (!is_array($support_files[$type][$key])) { + $support_files[$type][$key] = array('#path' => $key); + } + // Fill in any missing values as defaults. + $support_files[$type][$key] += $defaults; + } + } + } +} + +function support_file_defaults_css() { + return array( + '#method' => 'file', + '#media' => 'all', + '#weight' => 10, + '#cache' => TRUE, + '#preprocess' => TRUE, + ); +} + +function support_file_defaults_js() { + return array( + '#method' => 'file', + '#scope' => 'header', + '#defer' => FALSE, + '#weight' => 10, + '#cache' => TRUE, + '#preprocess' => TRUE, + ); +} + +/** * Adds a CSS file to the stylesheet queue. * * @param $path @@ -1732,7 +1828,7 @@ * name, for example: system-menus.css rather than simply menus.css. Themes * can override module-supplied CSS files based on their filenames, and this * prefixing helps prevent confusing name collisions for theme developers. - * See drupal_get_css where the overrides are performed. + * See drupal_get_support_files where the overrides are performed. * * If the direction of the current language is right-to-left (Hebrew, * Arabic, etc.), the function will also look for an RTL CSS file and append @@ -1780,148 +1876,17 @@ * An array of CSS files. */ 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] = $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] = $options['preprocess']; - } - } - } - - return $css; -} - -/** - * Returns a themed representation of all stylesheets that should be attached to the page. - * - * It loads the CSS in order, with 'module' first, then 'theme' afterwards. - * This ensures proper cascading of styles so themes can easily override - * module styles through CSS selectors. - * - * Themes may replace module-defined CSS files by adding a stylesheet with the - * same filename. For example, themes/garland/system-menus.css would replace - * modules/system/system-menus.css. This allows themes to override complete - * CSS files, rather than specific selectors, when necessary. - * - * If the original CSS file is being overridden by a theme, the theme is - * responsible for supplying an accompanying RTL CSS file to replace the - * module's. - * - * @param $css - * (optional) An array of CSS files. If no array is provided, the default - * stylesheets array is used instead. - * @return - * A string of XHTML CSS tags. - */ -function drupal_get_css($css = NULL) { - $output = ''; - if (!isset($css)) { - $css = drupal_add_css(); - } - $no_module_preprocess = ''; - $no_theme_preprocess = ''; - - $preprocess_css = (variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); - $directory = file_directory_path(); - $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC); - - // A dummy query-string is added to filenames, to gain control over - // browser-caching. The string changes on every update or full cache - // flush, forcing browsers to load a new copy of the files, as the - // URL changed. - $query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1); - - foreach ($css as $media => $types) { - // If CSS preprocessing is off, we still need to output the styles. - // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones. - foreach ($types as $type => $files) { - if ($type == 'module') { - // Setup theme overrides for module styles. - $theme_styles = array(); - foreach (array_keys($css[$media]['theme']) as $theme_style) { - $theme_styles[] = basename($theme_style); - } - } - foreach ($types[$type] as $file => $preprocess) { - // If the theme supplies its own style using the name of the module style, skip its inclusion. - // This includes any RTL styles associated with its main LTR counterpart. - if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) { - // Unset the file to prevent its inclusion when CSS aggregation is enabled. - unset($types[$type][$file]); - continue; - } - // Only include the stylesheet if it exists. - if (file_exists($file)) { - if (!$preprocess || !($is_writable && $preprocess_css)) { - // If a CSS file is not to be preprocessed and it's a module CSS file, it needs to *always* appear at the *top*, - // regardless of whether preprocessing is on or off. - if (!$preprocess && $type == 'module') { - $no_module_preprocess .= '' . "\n"; - } - // If a CSS file is not to be preprocessed and it's a theme CSS file, it needs to *always* appear at the *bottom*, - // regardless of whether preprocessing is on or off. - elseif (!$preprocess && $type == 'theme') { - $no_theme_preprocess .= '' . "\n"; - } - else { - $output .= '' . "\n"; - } - } - } - } - } - - if ($is_writable && $preprocess_css) { - $filename = md5(serialize($types) . $query_string) . '.css'; - $preprocess_file = drupal_build_css_cache($types, $filename); - $output .= '' . "\n"; - } + if (is_string($options)) { + $options = array('#weight' => $options); } - - return $no_module_preprocess . $output . $no_theme_preprocess; + drupal_add_support_file('css', $path, $options); } /** * Aggregate and optimize CSS files, putting them in the files directory. * * @param $types - * An array of types of CSS files (e.g., screen, print) to aggregate and - * compress into one file. + * (depreciated) - TODO: remove and replace with weights. * @param $filename * The name of the aggregate CSS file. * @return @@ -2090,7 +2055,7 @@ * drupal_add_js('misc/collapse.js'); * drupal_add_js('misc/collapse.js', 'module'); * drupal_add_js('$(document).ready(function(){alert("Hello!");});', - * array('type' => 'inline', 'scope' => 'footer') + * array('form' => 'inline', 'scope' => 'footer') * ); * @endcode * @@ -2103,14 +2068,14 @@ * actual configuration settings in another variable to prevent the pollution * of the Drupal.settings namespace. * @param $options - * (optional) A string defining the type of JavaScript that is being added - * in the $data parameter ('core', 'module', 'theme', 'setting', 'inline'), + * (optional) A string defining the method of JavaScript insertion that is required + * in the $data parameter ('file' 'setting', 'inline'), * or an array which can have any or all of the following keys (these are * not valid with type => 'setting'): - * - type - * The type of JavaScript that should be added to the page. Allowed - * values are 'core', 'module', 'theme', 'inline' and 'setting'. Defaults - * to 'module'. + * - method + * The method by which the JavaScript should be added to the page. Allowed + * values are 'file', 'inline' and 'setting'. Defaults + * to 'file'. * - scope * The location in which you want to place the script. Possible * values are 'header' and 'footer'. If your theme implements different @@ -2129,178 +2094,12 @@ * (optional) Resets the currently loaded JavaScript. * @return * The contructed array of JavaScript files. - * @see drupal_get_js() */ function drupal_add_js($data = NULL, $options = NULL, $reset = FALSE) { - static $javascript = array(); - - // 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', - // Default to a header scope only if we're adding some data. - 'scope' => isset($data) ? 'header' : NULL, - 'cache' => TRUE, - 'defer' => FALSE, - 'preprocess' => TRUE - ); - // Preprocess can only be set if caching is enabled. - $options['preprocess'] = $options['cache'] ? $options['preprocess'] : FALSE; - $type = $options['type']; - $scope = $options['scope']; - unset($options['type'], $options['scope']); - - // Request made to reset the JavaScript added so far. - if ($reset) { - $javascript = array(); - } - - if (isset($data)) { - // Add jquery.js and drupal.js, as well as the basePath setting, the - // first time a Javascript file is added. - if (empty($javascript)) { - $javascript = array( - 'header' => array( - 'core' => array( - 'misc/jquery.js' => array('cache' => TRUE, 'defer' => FALSE, 'preprocess' => TRUE), - 'misc/drupal.js' => array('cache' => TRUE, 'defer' => FALSE, 'preprocess' => TRUE), - ), - 'module' => array(), - 'theme' => array(), - 'setting' => array( - array('basePath' => base_path()), - ), - 'inline' => array(), - ) - ); - } - - if (isset($scope) && !isset($javascript[$scope])) { - $javascript[$scope] = array('core' => array(), 'module' => array(), 'theme' => array(), 'setting' => array(), 'inline' => array()); - } - - if (isset($type) && isset($scope) && !isset($javascript[$scope][$type])) { - $javascript[$scope][$type] = array(); - } - - switch ($type) { - case 'setting': - $javascript[$scope][$type][] = $data; - break; - case 'inline': - $javascript[$scope][$type][] = array('code' => $data, 'defer' => $options['defer']); - break; - default: - $javascript[$scope][$type][$data] = $options; - } - } - - if (isset($scope)) { - return isset($javascript[$scope]) ? $javascript[$scope] : array(); - } - else { - return $javascript; + if (is_string($options)) { + $options = array('#method' => $options); } -} - -/** - * Returns a themed presentation of all JavaScript code for the current page. - * - * References to JavaScript files are placed in a certain order: first, all - * 'core' files, then all 'module' and finally all 'theme' JavaScript files - * are added to the page. Then, all settings are output, followed by 'inline' - * JavaScript code. If running update.php, all preprocessing is disabled. - * - * @param $scope - * (optional) The scope for which the JavaScript rules should be returned. - * Defaults to 'header'. - * @param $javascript - * (optional) An array with all JavaScript code. Defaults to the default - * JavaScript array for the given scope. - * @return - * All JavaScript code segments and includes for the scope as HTML tags. - * @see drupal_add_js() - */ -function drupal_get_js($scope = 'header', $javascript = NULL) { - if ((!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') && function_exists('locale_update_js_files')) { - locale_update_js_files(); - } - - if (!isset($javascript)) { - $javascript = drupal_add_js(NULL, array('scope' => $scope)); - } - - if (empty($javascript)) { - return ''; - } - - $output = ''; - $preprocessed = ''; - $no_preprocess = array('core' => '', 'module' => '', 'theme' => ''); - $files = array(); - $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); - $directory = file_directory_path(); - $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC); - - // A dummy query-string is added to filenames, to gain control over - // browser-caching. The string changes on every update or full cache - // flush, forcing browsers to load a new copy of the files, as the - // URL changed. Files that should not be cached (see drupal_add_js()) - // get REQUEST_TIME as query-string instead, to enforce reload on every - // page request. - $query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1); - - // For inline Javascript to validate as XHTML, all Javascript containing - // XHTML needs to be wrapped in CDATA. To make that backwards compatible - // with HTML 4, we need to comment out the CDATA-tag. - $embed_prefix = "\n\n"; - - foreach ($javascript as $type => $data) { - if (!$data) continue; - - switch ($type) { - case 'setting': - $output .= '\n"; - break; - case 'inline': - foreach ($data as $info) { - $output .= '\n"; - } - break; - default: - // If JS preprocessing is off, we still need to output the scripts. - // Additionally, go through any remaining scripts if JS preprocessing is on and output the non-cached ones. - foreach ($data as $path => $info) { - if (!$info['preprocess'] || !$is_writable || !$preprocess_js) { - $no_preprocess[$type] .= '\n"; - } - else { - $files[$path] = $info; - } - } - } - } - - // Aggregate any remaining JS files that haven't already been output. - if ($is_writable && $preprocess_js && count($files) > 0) { - $filename = md5(serialize($files) . $query_string) . '.js'; - $preprocess_file = drupal_build_js_cache($files, $filename); - $preprocessed .= '' . "\n"; - } - - // Keep the order of JS files consistent as some are preprocessed and others are not. - // Make sure any inline or JS setting variables appear last after libraries have loaded. - $output = $preprocessed . implode('', $no_preprocess) . $output; - - return $output; + drupal_add_support_file('js', $data, $options); } /** @@ -2413,7 +2212,7 @@ function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgroup = NULL, $source = NULL, $hidden = TRUE, $limit = 0) { static $js_added = FALSE; if (!$js_added) { - drupal_add_js('misc/tabledrag.js', 'core'); + drupal_add_js('misc/tabledrag.js', array('#weight' => -16)); $js_added = TRUE; } @@ -3133,6 +2932,12 @@ 'indentation' => array( 'arguments' => array('size' => 1), ), + 'support_files_css' => array( + 'arguments' => array('support_files' => array()), + ), + 'support_files_js' => array( + 'arguments' => array('support_files' => array()), + ), // from pager.inc 'pager' => array( 'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()), Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.299 diff -u -r1.299 form.inc --- includes/form.inc 30 Oct 2008 02:35:54 -0000 1.299 +++ includes/form.inc 30 Oct 2008 19:51:18 -0000 @@ -2153,7 +2153,6 @@ // Add teaser behavior (must come before resizable) if (!empty($element['#teaser'])) { drupal_add_js('misc/teaser.js'); - // Note: arrays are merged in drupal_get_js(). drupal_add_js(array('teaserCheckbox' => array($element['#id'] => $element['#teaser_checkbox'])), 'setting'); drupal_add_js(array('teaser' => array($element['#id'] => $element['#teaser'])), 'setting'); $class[] = 'teaser'; Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.190 diff -u -r1.190 locale.inc --- includes/locale.inc 26 Oct 2008 18:06:38 -0000 1.190 +++ includes/locale.inc 30 Oct 2008 19:51:19 -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', array('preprocess' => 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.446 diff -u -r1.446 theme.inc --- includes/theme.inc 26 Oct 2008 18:06:38 -0000 1.446 +++ includes/theme.inc 30 Oct 2008 19:51:19 -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, array('type' => 'theme', 'media' => $media)); + drupal_add_css($stylesheet, array('#weight' => '0', '#media' => $media)); } } @@ -158,7 +158,7 @@ // Add scripts used by this theme. foreach ($final_scripts as $script) { - drupal_add_js($script, 'theme'); + drupal_add_js($script, array('#weight' => '0')); } $theme_engine = NULL; @@ -1613,7 +1613,7 @@ */ function theme_closure($main = 0) { $footer = module_invoke_all('footer', $main); - return implode("\n", $footer) . drupal_get_js('footer'); + return implode("\n", $footer) . drupal_get_support_files('css', 'footer'); } /** @@ -1753,6 +1753,73 @@ } /** + * TODO: Doxygen + */ +function theme_support_files_css($support_files) { + $output = ''; + + // A dummy query-string is added to filenames, to gain control over + // browser-caching. The string changes on every update or full cache + // flush, forcing browsers to load a new copy of the files, as the + // URL changed. + $query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1); + + foreach ($support_files as $file) { + // Only include the stylesheet if it exists. + $output .= '' . "\n"; + } + return $output; +} + +/** + * TODO: Doxygen + */ +function theme_support_files_js($support_files, $scope = NULL) { + $files = ''; + $inline = ''; + $settings = ''; + + if (!$scope) { + // If no specific scope is requested. + $scope = 'header'; + } + + // A dummy query-string is added to filenames, to gain control over + // browser-caching. The string changes on every update or full cache + // flush, forcing browsers to load a new copy of the files, as the + // URL changed. Files that should not be cached (see drupal_add_js()) + // get REQUEST_TIME as query-string instead, to enforce reload on every + // page request. + $query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1); + + // For inline Javascript to validate as XHTML, all Javascript containing + // XHTML needs to be wrapped in CDATA. To make that backwards compatible + // with HTML 4, we need to comment out the CDATA-tag. + $embed_prefix = "\n\n"; + + foreach ($support_files as $item) { + // Only include the file if it is in the requested region + if ($item['#scope'] == $scope) { + switch ($item['#method']) { + case 'setting': + $settings .= '\n"; + break; + case 'inline': + $inline .= '\n"; + break; + default: + $files .= '\n"; + } + } + } + + // Settings depends on jQuery and inline code can depend on both + // included files and settings, so we add it in the appropriate order. + return $files . $settings . $inline; +} + +/** * Adds a default set of helper variables for preprocess functions and * templates. This comes in before any other preprocess function which makes * it possible to be used in default theme implementations (non-overriden @@ -1872,9 +1939,9 @@ $variables['search_box'] = (theme_get_setting('toggle_search') ? drupal_get_form('search_theme_form') : ''); $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''); $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''); - $variables['css'] = drupal_add_css(); - $variables['styles'] = drupal_get_css(); - $variables['scripts'] = drupal_get_js(); + $variables['css'] = drupal_get_support_files('css'); + $variables['styles'] = drupal_get_support_files('css'); + $variables['scripts'] = drupal_get_support_files('js'); $variables['tabs'] = theme('menu_local_tasks'); $variables['title'] = drupal_get_title(); // Closure should be filled last. Index: includes/theme.maintenance.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.maintenance.inc,v retrieving revision 1.20 diff -u -r1.20 theme.maintenance.inc --- includes/theme.maintenance.inc 26 Oct 2008 18:06:38 -0000 1.20 +++ includes/theme.maintenance.inc 30 Oct 2008 19:51:19 -0000 @@ -258,9 +258,9 @@ $variables['search_box'] = ''; $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''); $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''); - $variables['css'] = drupal_add_css(); - $variables['styles'] = drupal_get_css(); - $variables['scripts'] = drupal_get_js(); + $variables['css'] = drupal_get_support_files('css'); + $variables['styles'] = drupal_get_support_files('css'); + $variables['scripts'] = drupal_get_support_files('js'); $variables['tabs'] = ''; $variables['title'] = drupal_get_title(); $variables['closure'] = ''; Index: modules/block/block.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v retrieving revision 1.26 diff -u -r1.26 block.admin.inc --- modules/block/block.admin.inc 29 Oct 2008 10:08:51 -0000 1.26 +++ modules/block/block.admin.inc 30 Oct 2008 19:51:19 -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', array('preprocess' => 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'); Index: modules/color/color.module =================================================================== RCS file: /cvs/drupal/drupal/modules/color/color.module,v retrieving revision 1.49 diff -u -r1.49 color.module --- modules/color/color.module 26 Oct 2008 18:06:38 -0000 1.49 +++ modules/color/color.module 30 Oct 2008 19:51:19 -0000 @@ -107,7 +107,7 @@ } } $vars['css']['all']['theme'] = $new_theme_css; - $vars['styles'] = drupal_get_css($vars['css']); + $vars['styles'] = drupal_get_support_files('css'); } // Override logo. @@ -153,11 +153,11 @@ $info = color_get_info($theme); // Add Farbtastic color picker. - drupal_add_css('misc/farbtastic/farbtastic.css', array('preprocess' => 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', array('preprocess' => 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/dblog/dblog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/dblog/dblog.module,v retrieving revision 1.30 diff -u -r1.30 dblog.module --- modules/dblog/dblog.module 30 Oct 2008 09:16:01 -0000 1.30 +++ modules/dblog/dblog.module 30 Oct 2008 19:51:19 -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', array('preprocess' => FALSE)); + drupal_add_css(drupal_get_path('module', 'dblog') . '/dblog.css', array('#preprocess' => FALSE)); } } Index: modules/help/help.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/help/help.admin.inc,v retrieving revision 1.7 diff -u -r1.7 help.admin.inc --- modules/help/help.admin.inc 26 Oct 2008 18:06:38 -0000 1.7 +++ modules/help/help.admin.inc 30 Oct 2008 19:51:19 -0000 @@ -11,7 +11,7 @@ */ function help_main() { // Add CSS - drupal_add_css(drupal_get_path('module', 'help') . '/help.css', array('preprocess' => 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/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.230 diff -u -r1.230 locale.module --- modules/locale/locale.module 22 Oct 2008 19:39:36 -0000 1.230 +++ modules/locale/locale.module 30 Oct 2008 19:51:19 -0000 @@ -505,6 +505,10 @@ } /** + * Implementation of hook_support_files_alter(). + * + * Add RTL CSS overrides to the page, if neccessary and available. + * * Update JavaScript translation file, if required, and add it to the page. * * This function checks all JavaScript files currently added via drupal_add_js() @@ -512,29 +516,37 @@ * and Drupal.formatPlural() calls. Also refreshes the JavaScript translation * file if necessary, and adds it to the page. */ -function locale_update_js_files() { +function locale_support_files_alter(&$support_files) { global $language; $dir = file_create_path(variable_get('locale_js_directory', 'languages')); $parsed = variable_get('javascript_parsed', array()); - - // Get an array of all the JavaScript added so far. - $javascript = drupal_add_js(); $files = $new_files = FALSE; - foreach ($javascript as $scope) { - foreach ($scope as $type => $data) { - if ($type != 'setting' && $type != 'inline') { - foreach ($data as $filepath => $info) { - $files = TRUE; - if (!in_array($filepath, $parsed)) { - // Don't parse our own translations files. - if (substr($filepath, 0, strlen($dir)) != $dir) { - locale_inc_callback('_locale_parse_js_file', $filepath); - watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath)); - $parsed[] = $filepath; - $new_files = TRUE; - } + foreach ($support_files as $type => $files) { + foreach ($files as $key => $file) { + // CSS alterations + if ($type == 'css') { + // 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', $file['#path']); + if (file_exists($rtl_path)) { + $support_files[$type][$rtl_path] = $file; + $support_files[$type][$rtl_path]['#file'] = $rtl_path; + $support_files[$type][$rtl_path]['#weight']++; + } + } + } + // If we have a javascript file that has not been parsed already, then we need to parse it. + if ($type == 'js' && $file['#method'] != 'setting' && $file['#method'] != 'inline') { + $files = TRUE; + if (!in_array($file['#path'], $parsed)) { + // Don't parse our own translations files. + if (substr($file['#path'], 0, strlen($dir)) != $dir) { + locale_inc_callback('_locale_parse_js_file', $file['#path']); + watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $file['#path'])); + $parsed[] = $file['#path']; + $new_files = TRUE; } } } @@ -566,7 +578,9 @@ // Add the translation JavaScript file to the page. if ($files && !empty($language->javascript)) { - drupal_add_js($dir . '/' . $language->language . '_' . $language->javascript . '.js', 'core'); + $result = support_file_defaults_js(); + $result['#path'] = $dir . '/' . $language->language . '_' . $language->javascript . '.js'; + $support_files['js'][] = $result; } } Index: modules/node/node.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v retrieving revision 1.27 diff -u -r1.27 node.admin.inc --- modules/node/node.admin.inc 12 Oct 2008 04:30:06 -0000 1.27 +++ modules/node/node.admin.inc 30 Oct 2008 19:51:19 -0000 @@ -254,7 +254,7 @@ $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset')); } - drupal_add_js('misc/form.js', 'core'); + drupal_add_js('misc/form.js', array('#weight' => -16)); return $form; } Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.271 diff -u -r1.271 search.module --- modules/search/search.module 26 Oct 2008 18:06:38 -0000 1.271 +++ modules/search/search.module 30 Oct 2008 19:51:19 -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', array('preprocess' => FALSE)); + drupal_add_css(drupal_get_path('module', 'search') . '/search.css', array('#preprocess' => FALSE)); if (!$action) { $action = url('search/' . $type); Index: modules/simpletest/tests/common.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v retrieving revision 1.10 diff -u -r1.10 common.test --- modules/simpletest/tests/common.test 26 Oct 2008 18:06:39 -0000 1.10 +++ modules/simpletest/tests/common.test 30 Oct 2008 19:51:19 -0000 @@ -134,8 +134,8 @@ */ function setUp() { parent::setUp(); - // Reset drupal_add_css() before each test. - drupal_add_css(NULL, NULL, TRUE); + // Reset support files before each test. + drupal_add_support_file(NULL, NULL, NULL, TRUE); } /** @@ -150,17 +150,19 @@ */ function testAddFile() { $path = drupal_get_path('module', 'simpletest') . '/simpletest.css'; - $css = drupal_add_css($path); - $this->assertEqual($css['all']['module'][$path], TRUE, t('Adding a CSS file caches it properly.')); + drupal_add_css($path); + $support_files = drupal_add_support_file(); + $this->assertEqual($support_files['css'][$path]['#path'], $path, t('Adding a CSS file caches it properly.')); } /** * Tests rendering the stylesheets. */ function testRenderFile() { - $css = drupal_get_path('module', 'simpletest') . '/simpletest.css'; - drupal_add_css($css); - $this->assertTrue(strpos(drupal_get_css(), $css) > 0, t('Rendered CSS includes the added stylesheet.')); + $path = drupal_get_path('module', 'simpletest') . '/simpletest.css'; + drupal_add_css($path); + $css = drupal_get_support_files('css'); + $this->assertTrue(strpos($css, $path) > 0, t('Rendered CSS includes the added stylesheet.')); } } @@ -306,6 +308,11 @@ * Tests for the JavaScript system. */ class JavaScriptTestCase extends DrupalWebTestCase { + /** + * Store configured value for JavaScript preprocessing. + */ + var $preprocess_js; + /** * Implementation of getInfo(). */ @@ -316,92 +323,116 @@ 'group' => t('System') ); } - + /** * Implementation of setUp(). */ function setUp() { - // Reset drupal_add_js() before each test. - drupal_add_js(NULL, NULL, TRUE); + // Reset support files before each test. + drupal_add_support_file(NULL, NULL, NULL, TRUE); + // Disable Preprocessing + $this->preprocess_js = variable_get('preprocess_js', 0); + variable_set('preprocess_js', 0); + // Enable locale in test enviornment. + parent::setUp('locale'); } - + + /** + * Implementation of tearDown() + */ + function tearDown() { + // Restore configured value for JavaScript preprocessing. + variable_set('preprocess_js', $this->preprocess_js); + parent::tearDown(); + } + /** * Test default JavaScript is empty. */ function testDefault() { $this->assertEqual(array(), drupal_add_js(), t('Default JavaScript is empty.')); } - + /** * Test adding a JavaScript file. */ function testAddFile() { drupal_add_js('misc/collapse.js'); - $javascript = drupal_add_js(); - $this->assertTrue(array_key_exists('misc/jquery.js', $javascript['header']['core']), t('jQuery is added when a file is added.')); - $this->assertTrue(array_key_exists('misc/drupal.js', $javascript['header']['core']), t('Drupal.js is added when file is added.')); - $this->assertTrue(array_key_exists('misc/collapse.js', $javascript['header']['module']), t('JavaScript files are correctly added.')); - $this->assertEqual(base_path(), $javascript['header']['setting'][0]['basePath'], t('Base path JavaScript setting is correctly set.')); + $support_files = drupal_add_support_file(); + $this->assertEqual($support_files['js']['misc/collapse.js']['#path'], 'misc/collapse.js', t('JavaScript files are correctly added.')); } - + /** * Test adding settings. */ function testAddSetting() { drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); - $javascript = drupal_add_js(); - $this->assertEqual(280342800, $javascript['header']['setting'][1]['dries'], t('JavaScript setting is set correctly.')); - $this->assertEqual('rocks', $javascript['header']['setting'][1]['drupal'], t('The other JavaScript setting is set correctly.')); + $support_files = drupal_add_support_file(); + $this->assertEqual(280342800, $support_files['js'][0]['#path']['dries'], t('JavaScript setting is set correctly.')); + $this->assertEqual('rocks', $support_files['js'][0]['#path']['drupal'], t('The other JavaScript setting is set correctly.')); } - + /** - * Test drupal_get_js() for JavaScript settings. + * Test drupal_get_support_files() for JavaScript settings. */ function testHeaderSetting() { drupal_add_js(array('testSetting' => 'testValue'), 'setting'); - $javascript = drupal_get_js('header'); + $javascript = drupal_get_support_files('js'); $this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header returns basePath setting.')); $this->assertTrue(strpos($javascript, 'testSetting') > 0, t('Rendered JavaScript header returns custom setting.')); $this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header includes jQuery.')); + $this->assertTrue(strpos($javascript, 'misc/drupal.js') > 0, t('Rendered JavaScript header includes Drupal.js.')); } - + /** * Test to see if resetting the JavaScript empties the cache. */ function testReset() { drupal_add_js('misc/collapse.js'); - drupal_add_js(NULL, NULL, TRUE); - $this->assertEqual(array(), drupal_add_js(), t('Resetting the JavaScript correctly empties the cache.')); + drupal_add_support_file(NULL, NULL, NULL, TRUE); + $this->assertEqual(array(), drupal_add_support_file(), t('Resetting the JavaScript correctly empties the cache.')); } - + /** * Test adding inline scripts. */ function testAddInline() { $inline = '$(document).ready(function(){});'; - drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); - $javascript = drupal_add_js(); - $this->assertTrue(array_key_exists('misc/jquery.js', $javascript['header']['core']), t('jQuery is added when inline scripts are added.')); - $this->assertEqual($inline, $javascript['footer']['inline'][0]['code'], t('Inline JavaScript is correctly added to the footer.')); + drupal_add_js($inline, array('#method' => 'inline', '#scope' => 'footer')); + $support_files = drupal_add_support_file(); + $this->assertEqual($support_files['js'][0]['#path'], $inline, t('Inline JavaScript is correctly added to the footer.')); } - + /** - * Test drupal_get_js() with a footer scope. + * Test drupal_get_support_files() with a footer scope. */ function testFooterHTML() { $inline = '$(document).ready(function(){});'; - drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); - $javascript = drupal_get_js('footer'); - $this->assertTrue(strpos($javascript, $inline) > 0, t('Rendered JavaScript footer returns the inline code.')); + drupal_add_js($inline, array('#method' => 'inline', '#scope' => 'footer')); + $header_javascript = drupal_get_support_files('js'); + $footer_javascript = drupal_get_support_files('js', 'footer'); + $this->assertTrue(strpos($header_javascript, 'misc/drupal.js') > 0, t('jQuery is added when inline scripts are added.')); + $this->assertTrue(strpos($footer_javascript, $inline) > 0, t('Inline JavaScript is correctly added to the footer.')); } - + /** * Test drupal_add_js() sets preproccess to false when cache is set to false. + * TODO: Reenable when aggregation is added again. */ function testNoCache() { - drupal_add_js('misc/collapse.js', array('cache' => FALSE)); - $javascript = drupal_add_js(); - $this->assertTrue(!$javascript['header']['module']['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); +// drupal_add_js('misc/collapse.js', array('#cache' => FALSE)); +// $javascript = drupal_add_js(); +// $this->assertFalse($javascript['header'][JS_WEIGHT_DEFAULT]['file']['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); + } + + /** + * Test adding a JavaScript file with a different weight. + */ + function testDifferentWeight() { + drupal_add_js('misc/collapse.js', array('#weight' => 42)); + drupal_add_js('misc/drupal.js', array('#weight' => -42)); + $javascript = drupal_get_support_files('js'); + $this->assertTrue(strpos($javascript, 'misc/collapse.js') > strpos($javascript, 'misc/drupal.js'), t('Adding a JavaScript file with a different weight.')); } } Index: modules/system/system.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v retrieving revision 1.102 diff -u -r1.102 system.admin.inc --- modules/system/system.admin.inc 16 Oct 2008 20:23:08 -0000 1.102 +++ modules/system/system.admin.inc 30 Oct 2008 19:51:19 -0000 @@ -1736,7 +1736,7 @@ if (!variable_get('clean_url', 0)) { if (strpos(request_uri(), '?q=') !== FALSE) { - drupal_add_js(drupal_get_path('module', 'system') . '/system.js', 'module'); + drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); $form['clean_url']['#description'] .= ' ' . t('Before enabling clean URLs, you must perform a test to determine if your server is properly configured. If you are able to see this page again after clicking the "Run the clean URL test" link, the test has succeeded and the radio buttons above will be available. If instead you are directed to a "Page not found" error, you will need to change the configuration of your server. The handbook page on Clean URLs has additional troubleshooting information.', array('@handbook' => 'http://drupal.org/node/15365')) . ''; Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.634 diff -u -r1.634 system.module --- modules/system/system.module 29 Oct 2008 03:02:42 -0000 1.634 +++ modules/system/system.module 30 Oct 2008 19:51:20 -0000 @@ -713,6 +713,11 @@ 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'); + + // Add the JS for this module. + drupal_add_js('misc/jquery.js', array('#weight' => -20)); + drupal_add_js('misc/drupal.js', array('#weight' => -18)); + drupal_add_js(array('basePath' => base_path()), 'setting'); } /** @@ -2151,3 +2156,50 @@ function system_image_toolkits() { return array('gd'); } + +/** + * Implementation of hook_support_files_alter(). + */ +function system_support_files_alter(&$support_files) { + $settings = array(); + $javascript = FALSE; + foreach ($support_files as $type => $files) { + foreach ($files as $key => $file) { + // JavaScript alterations + if ($type == 'js') { + // Collect the arrays for each setting, removing the individual entries. + if ($file['#method'] == 'setting') { + $settings[] = $file['#path']; + unset($support_files[$type][$key]); + } + } + + // Remove entries pointing to non-existent files. + if ($file['#method'] == 'file' && !file_exists($file['#path'])) { + unset($support_files[$type][$key]); + } + // Pass in a more semantic '#data' element for inline elements. + if ($file['#method'] == 'inline') { + $support_files[$type][$key]['#data'] = $file['#path']; + unset($support_files[$type][$key]['#path']); + } + // Note if additional JavaScript has been added. + if ($file['#path'] != 'misc/jquery.js' && $file['#path'] != 'misc/drupal.js') { + $javascript = TRUE; + } + } + } + // Remove jQuery and Drupal JavaScript if unneccessary, as an optimization. + if (!$javascript) { + unset($support_files['js']['misc/jquery.js']); + unset($support_files['js']['misc/drupal.js']); + $settings = array(); + } + // Merge the settings arrays and readd as a single #data element. + if (!empty($settings)) { + $result = support_file_defaults_js(); + $result['#method'] = 'setting'; + $result['#data'] = call_user_func_array('array_merge_recursive', $settings); + $support_files['js'][] = $result; + } +} \ No newline at end of file Index: modules/tracker/tracker.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/tracker/tracker.pages.inc,v retrieving revision 1.12 diff -u -r1.12 tracker.pages.inc --- modules/tracker/tracker.pages.inc 26 Oct 2008 18:06:39 -0000 1.12 +++ modules/tracker/tracker.pages.inc 30 Oct 2008 19:51:20 -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', array('preprocess' => FALSE)); + drupal_add_css(drupal_get_path('module', 'tracker') . '/tracker.css', array('#preprocess' => FALSE)); if ($account) { if ($set_title) { Index: modules/user/user.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v retrieving revision 1.30 diff -u -r1.30 user.admin.inc --- modules/user/user.admin.inc 19 Oct 2008 21:19:02 -0000 1.30 +++ modules/user/user.admin.inc 30 Oct 2008 19:51:20 -0000 @@ -83,7 +83,7 @@ ); } - drupal_add_js('misc/form.js', 'core'); + drupal_add_js('misc/form.js', array('#weight' => -16)); return $form; } Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.930 diff -u -r1.930 user.module --- modules/user/user.module 26 Oct 2008 18:06:39 -0000 1.930 +++ modules/user/user.module 30 Oct 2008 19:51:20 -0000 @@ -2160,7 +2160,7 @@ global $user; // Only need to do once per page. if (!$complete) { - drupal_add_js(drupal_get_path('module', 'user') . '/user.js', 'module'); + drupal_add_js(drupal_get_path('module', 'user') . '/user.js'); drupal_add_js(array( 'password' => array( Index: themes/chameleon/chameleon.theme =================================================================== RCS file: /cvs/drupal/drupal/themes/chameleon/chameleon.theme,v retrieving revision 1.78 diff -u -r1.78 chameleon.theme --- themes/chameleon/chameleon.theme 25 Jun 2008 09:12:25 -0000 1.78 +++ themes/chameleon/chameleon.theme 30 Oct 2008 19:51:20 -0000 @@ -32,8 +32,8 @@ $output .= "\n"; $output .= " " . ($title ? strip_tags($title) . " | " . variable_get("site_name", "Drupal") : variable_get("site_name", "Drupal") . " | " . variable_get("site_slogan", "")) . "\n"; $output .= drupal_get_html_head(); - $output .= drupal_get_css(); - $output .= drupal_get_js(); + $output .= drupal_get_support_files('css'); + $output .= drupal_get_support_files('js'); $output .= ""; $output .= "\n"; $output .= "
";