diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc index 8817356..f59b378 100644 --- a/core/includes/ajax.inc +++ b/core/includes/ajax.inc @@ -289,10 +289,10 @@ function ajax_render($commands = array()) { } // Now add a command to merge changes and additions to Drupal.settings. - $scripts = drupal_add_js(); + $scripts = _drupal_get_js(); if (!empty($scripts['settings'])) { $settings = $scripts['settings']; - array_unshift($commands, ajax_command_settings(call_user_func_array('array_merge_recursive', $settings['data']), TRUE)); + array_unshift($commands, ajax_command_settings($settings['data'], TRUE)); } // Allow modules to alter any Ajax response. diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 6abe08a..6b47170 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1937,20 +1937,25 @@ function drupal_array_merge_deep_array($arrays) { $result = array(); foreach ($arrays as $array) { - foreach ($array as $key => $value) { - // Renumber integer keys as array_merge_recursive() does. Note that PHP - // automatically converts array keys that are integer strings (e.g., '1') - // to integers. - if (is_integer($key)) { - $result[] = $value; - } - // Recurse when both values are arrays. - elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { - $result[$key] = drupal_array_merge_deep_array(array($result[$key], $value)); - } - // Otherwise, use the latter value, overriding any previous value. - else { - $result[$key] = $value; + if (!is_array($array)) { + $result[] = $array; + } + else { + foreach ($array as $key => $value) { + // Renumber integer keys as array_merge_recursive() does. Note that PHP + // automatically converts array keys that are integer strings (e.g., '1') + // to integers. + if (is_integer($key)) { + $result[] = $value; + } + // Recurse when both values are arrays. + elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { + $result[$key] = drupal_array_merge_deep_array(array($result[$key], $value)); + } + // Otherwise, use the latter value, overriding any previous value. + else { + $result[$key] = $value; + } } } } diff --git a/core/includes/common.inc b/core/includes/common.inc index 353a9b5..f9633e8 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3019,6 +3019,17 @@ function drupal_add_css($data = NULL, $options = NULL) { * @see drupal_add_css() */ function drupal_get_css($css = NULL, $skip_alter = FALSE) { + $css = _drupal_get_css($css, $skip_alter); + // Render the HTML needed to load the CSS. + $styles = array( + '#type' => 'styles', + '#items' => $css, + ); + + return drupal_render($styles); +} + +function _drupal_get_css($css = NULL, $skip_alter = FALSE) { if (!isset($css)) { $css = drupal_add_css(); } @@ -3031,18 +3042,6 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) { // Sort CSS items, so that they appear in the correct order. uasort($css, 'drupal_sort_css_js'); - // Provide the page with information about the individual CSS files used, - // information not otherwise available when CSS aggregation is enabled. The - // setting is attached later in this function, but is set here, so that CSS - // files removed below are still considered "used" and prevented from being - // added in a later AJAX request. - // Skip if no files were added to the page or jQuery.extend() will overwrite - // the Drupal.settings.ajaxPageState.css object with an empty array. - if (!empty($css)) { - // Cast the array to an object to be on the safe side even if not empty. - $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1); - } - // Remove the overridden CSS files. Later CSS files override former ones. $previous_item = array(); foreach ($css as $key => $item) { @@ -3057,16 +3056,7 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) { } } - // Render the HTML needed to load the CSS. - $styles = array( - '#type' => 'styles', - '#items' => $css, - ); - if (!empty($setting)) { - $styles['#attached']['js'][] = array('type' => 'setting', 'data' => $setting); - } - - return drupal_render($styles); + return $css; } /** @@ -4102,49 +4092,22 @@ function drupal_add_js($data = NULL, $options = NULL) { $options['weight'] += count($javascript) / 1000; 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)) { - // url() generates the prefix using hook_url_outbound_alter(). Instead of - // running the hook_url_outbound_alter() again here, extract the prefix - // from url(). - url('', array('prefix' => &$prefix)); - $javascript = array( - 'settings' => array( - 'data' => array( - array('basePath' => base_path()), - array('pathPrefix' => empty($prefix) ? '' : $prefix), - ), - 'type' => 'setting', - 'scope' => 'header', - 'group' => JS_SETTING, - 'every_page' => TRUE, - 'weight' => 0, - 'browsers' => array(), - ), - 'core/misc/drupal.js' => array( - 'data' => 'core/misc/drupal.js', - 'type' => 'file', - 'scope' => 'header', - 'group' => JS_LIBRARY, - 'every_page' => TRUE, - 'weight' => -1, - 'preprocess' => TRUE, - 'cache' => TRUE, - 'defer' => FALSE, - 'browsers' => array(), - ), - ); - // Register all required libraries. - drupal_add_library('system', 'jquery', TRUE); - drupal_add_library('system', 'jquery.once', TRUE); - drupal_add_library('system', 'html5shiv', TRUE); - } - switch ($options['type']) { case 'setting': - // All JavaScript settings are placed in the header of the page with - // the library weight so that inline scripts appear afterwards. + // Add basic structure for the settings. + if (!isset($javascript['settings']['data'])) { + $javascript += array( + 'settings' => array( + 'data' => array(), + 'type' => 'setting', + 'scope' => 'header', + 'group' => JS_SETTING, + 'every_page' => TRUE, + 'weight' => 0, + 'browsers' => array(), + ), + ); + } $javascript['settings']['data'][] = $data; break; @@ -4215,18 +4178,84 @@ function drupal_js_defaults($data = NULL) { * @return * All JavaScript code segments and includes for the scope as HTML tags. * + * @see _drupal_get_js() * @see drupal_add_js() * @see locale_js_alter() * @see drupal_js_defaults() */ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALSE) { + $items = _drupal_get_js($scope, $javascript, $skip_alter); + // Render the HTML needed to load the JavaScript. + $elements = array( + '#type' => 'scripts', + '#items' => $items, + ); + + return drupal_render($elements); +} + +/** + * Returns the structured array of javascript. + * + * @see drupal_get_js() + */ +function _drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALSE) { + // Needed for recursive call + $original_javascript = $javascript; + if (!isset($javascript)) { $javascript = drupal_add_js(); } + if (empty($javascript)) { return ''; } + // Register all required libraries. + $libraries_added = &drupal_static(__FUNCTION__, FALSE); + if (!$libraries_added) { + $libraries_added = TRUE; + + // url() generates the prefix using hook_url_outbound_alter(). Instead of + // running the hook_url_outbound_alter() again here, extract the prefix + // from url(). + url('', array('prefix' => &$prefix)); + drupal_add_js(array('basePath' => base_path()), 'setting'); + drupal_add_js(array('pathPrefix' => empty($prefix) ? '' : $prefix), 'setting'); + + // Provide the page with information about the theme that's used, so that a + // later Ajax request can be rendered using the same theme. + // @see ajax_base_page_theme() + if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE !== 'install') { + global $theme_key; + $settings['ajaxPageState'] = array( + 'theme' => $theme_key, + 'theme_token' => drupal_get_token($theme_key), + ); + drupal_add_js($settings, 'setting'); + } + + // Add drupal.js. + drupal_add_js('core/misc/drupal.js', array( + 'data' => 'core/misc/drupal.js', + 'type' => 'file', + 'scope' => 'header', + 'group' => JS_LIBRARY, + 'every_page' => TRUE, + 'weight' => -1, + 'preprocess' => TRUE, + 'cache' => TRUE, + 'defer' => FALSE, + 'browsers' => array(), + )); + + // Add required libraries. + drupal_add_library('system', 'jquery', TRUE); + drupal_add_library('system', 'jquery.once', TRUE); + drupal_add_library('system', 'html5shiv', TRUE); + return _drupal_get_js($scope, $original_javascript, $skip_alter); + } + // Allow modules to alter the JavaScript. if (!$skip_alter) { drupal_alter('js', $javascript); @@ -4243,12 +4272,6 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS // 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. - $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1); - unset($setting['ajaxPageState']['js']['settings']); - drupal_add_js($setting, 'setting'); - // If we're outputting the header scope, then this might be the final time // that drupal_get_js() is running, so add the setting to this output as well // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's @@ -4256,16 +4279,32 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS // stripped of settings, potentially in order to override how settings get // output, so in this case, do not add the setting to this output. if ($scope == 'header' && isset($items['settings'])) { + // Provide the page with information about the individual JavaScript files + // used, information not otherwise available when aggregation is enabled. + // This uses $javascript so everything is added regardless of the scope. + foreach ($javascript as $key => $item) { + $setting['ajaxPageState']['js'][$key] = 1; + } + unset($setting['ajaxPageState']['js']['settings']); + + // Provide the page with information about the individual CSS files used, + // information not otherwise available when CSS aggregation is enabled. The + // setting is attached later in this function, but is set here, so that CSS + // files removed below are still considered "used" and prevented from being + // added in a later AJAX request. + // Skip if no files were added to the page or jQuery.extend() will overwrite + // the Drupal.settings.ajaxPageState.css object with an empty array. + $css = _drupal_get_css(NULL, $skip_alter); + if (!empty($css)) { + // Cast the array to an object to be on the safe side even if not empty. + $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1); + } + $items['settings']['data'][] = $setting; + $items['settings']['data'] = drupal_array_merge_deep_array($items['settings']['data']); } - // Render the HTML needed to load the JavaScript. - $elements = array( - '#type' => 'scripts', - '#items' => $items, - ); - - return drupal_render($elements); + return $items; } /** @@ -4355,7 +4394,7 @@ function drupal_pre_render_scripts($elements) { switch ($item['type']) { case 'setting': $element['#value_prefix'] = $embed_prefix; - $element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");"; + $element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode($item['data']) . ");"; $element['#value_suffix'] = $embed_suffix; break; @@ -4423,45 +4462,47 @@ function drupal_group_js($javascript) { // new group needs to be made for it. $current_group_keys = NULL; $index = -1; - foreach ($javascript as $item) { - // The browsers for which the JavaScript item needs to be loaded is part of - // the information that determines when a new group is needed, but the order - // of keys in the array doesn't matter, and we don't want a new group if all - // that's different is that order. - ksort($item['browsers']); + if (is_array($javascript)) { + foreach ($javascript as $item) { + // The browsers for which the JavaScript item needs to be loaded is part of + // the information that determines when a new group is needed, but the order + // of keys in the array doesn't matter, and we don't want a new group if all + // that's different is that order. + ksort($item['browsers']); + + switch ($item['type']) { + case 'file': + // Group file items if their 'preprocess' flag is TRUE. + // 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_js() for details about that. + $group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['every_page'], $item['browsers']) : FALSE; + break; - switch ($item['type']) { - case 'file': - // Group file items if their 'preprocess' flag is TRUE. - // 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_js() for details about that. - $group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['every_page'], $item['browsers']) : FALSE; - break; + case 'external': + case 'setting': + case 'inline': + // Do not group external, settings, and inline items. + $group_keys = FALSE; + break; + } - case 'external': - case 'setting': - case 'inline': - // Do not group external, settings, and inline items. - $group_keys = FALSE; - break; - } + // If the group keys don't match the most recent group we're working with, + // then a new group must be made. + if ($group_keys !== $current_group_keys) { + $index++; + // Initialize the new group with the same properties as the first item + // being placed into it. The item's 'data' and 'weight' properties are + // unique to the item and should not be carried over to the group. + $groups[$index] = $item; + unset($groups[$index]['data'], $groups[$index]['weight']); + $groups[$index]['items'] = array(); + $current_group_keys = $group_keys ? $group_keys : NULL; + } - // If the group keys don't match the most recent group we're working with, - // then a new group must be made. - if ($group_keys !== $current_group_keys) { - $index++; - // Initialize the new group with the same properties as the first item - // being placed into it. The item's 'data' and 'weight' properties are - // unique to the item and should not be carried over to the group. - $groups[$index] = $item; - unset($groups[$index]['data'], $groups[$index]['weight']); - $groups[$index]['items'] = array(); - $current_group_keys = $group_keys ? $group_keys : NULL; + // Add the item to the current group. + $groups[$index]['items'][] = $item; } - - // Add the item to the current group. - $groups[$index]['items'][] = $item; } return $groups; diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 99e872e..8731446 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -101,15 +101,6 @@ function drupal_theme_initialize() { // Themes can have alter functions, so reset the drupal_alter() cache. drupal_static_reset('drupal_alter'); - - // Provide the page with information about the theme that's used, so that a - // later Ajax request can be rendered using the same theme. - // @see ajax_base_page_theme() - $setting['ajaxPageState'] = array( - 'theme' => $theme_key, - 'theme_token' => drupal_get_token($theme_key), - ); - drupal_add_js($setting, 'setting'); } /** diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 0aef8de..4d01bcc 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -279,8 +279,8 @@ function file_ajax_upload() { } $output = theme('status_messages') . drupal_render($form); - $js = drupal_add_js(); - $settings = call_user_func_array('array_merge_recursive', $js['settings']['data']); + $js = _drupal_get_js(); + $settings = $js['settings']['data']; $commands = array(); $commands[] = ajax_command_replace(NULL, $output, $settings); diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module index e2ecd19..c25cf76 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -856,7 +856,7 @@ function overlay_render_region($region) { // it. This region might not be included the next time drupal_render_page() // is called, and we do not want its JavaScript or CSS to erroneously appear // on the final rendered page. - $original_js = drupal_add_js(); + $original_js = _drupal_get_js(); $original_css = drupal_add_css(); $original_libraries = drupal_static('drupal_add_library'); $js = &drupal_static('drupal_add_js'); diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php index 540dc0e..755bca1 100644 --- a/core/modules/simpletest/drupal_web_test_case.php +++ b/core/modules/simpletest/drupal_web_test_case.php @@ -2073,7 +2073,9 @@ class DrupalWebTestCase extends DrupalTestCase { } if (isset($drupal_settings['ajaxPageState'])) { $extra_post .= '&' . urlencode('ajax_page_state[theme]') . '=' . urlencode($drupal_settings['ajaxPageState']['theme']); - $extra_post .= '&' . urlencode('ajax_page_state[theme_token]') . '=' . urlencode($drupal_settings['ajaxPageState']['theme_token']); + if (isset($drupal_settings['ajaxPageState']['theme_token'])) { + $extra_post .= '&' . urlencode('ajax_page_state[theme_token]') . '=' . urlencode($drupal_settings['ajaxPageState']['theme_token']); + } foreach ($drupal_settings['ajaxPageState']['css'] as $key => $value) { $extra_post .= '&' . urlencode("ajax_page_state[css][$key]") . '=1'; } diff --git a/core/modules/system/tests/common.test b/core/modules/system/tests/common.test index f0ac957..540767f 100644 --- a/core/modules/system/tests/common.test +++ b/core/modules/system/tests/common.test @@ -1203,6 +1203,7 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { // Reset drupal_add_js() and drupal_add_library() statics before each test. drupal_static_reset('drupal_add_js'); drupal_static_reset('drupal_add_library'); + drupal_static_reset('_drupal_get_js'); } function tearDown() { @@ -1224,23 +1225,25 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { * Test adding a JavaScript file. */ function testAddFile() { - $javascript = drupal_add_js('core/misc/collapse.js'); + drupal_add_js('core/misc/collapse.js'); + $javascript = _drupal_get_js(); $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when a file is added.')); $this->assertTrue(array_key_exists('core/misc/drupal.js', $javascript), t('Drupal.js is added when file is added.')); $this->assertTrue(array_key_exists('core/misc/html5.js', $javascript), t('html5.js is added when file is added.')); $this->assertTrue(array_key_exists('core/misc/collapse.js', $javascript), t('JavaScript files are correctly added.')); - $this->assertEqual(base_path(), $javascript['settings']['data'][0]['basePath'], t('Base path JavaScript setting is correctly set.')); + $this->assertEqual(base_path(), $javascript['settings']['data']['basePath'], t('Base path JavaScript setting is correctly set.')); url('', array('prefix' => &$prefix)); - $this->assertEqual(empty($prefix) ? '' : $prefix, $javascript['settings']['data'][1]['pathPrefix'], t('Path prefix JavaScript setting is correctly set.')); + $this->assertEqual(empty($prefix) ? '' : $prefix, $javascript['settings']['data']['pathPrefix'], t('Path prefix JavaScript setting is correctly set.')); } /** * Test adding settings. */ function testAddSetting() { - $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); - $this->assertEqual(280342800, $javascript['settings']['data'][2]['dries'], t('JavaScript setting is set correctly.')); - $this->assertEqual('rocks', $javascript['settings']['data'][2]['drupal'], t('The other JavaScript setting is set correctly.')); + drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); + $javascript = _drupal_get_js(); + $this->assertEqual(280342800, $javascript['settings']['data']['dries'], t('JavaScript setting is set correctly.')); + $this->assertEqual('rocks', $javascript['settings']['data']['drupal'], t('The other JavaScript setting is set correctly.')); } /** @@ -1256,6 +1259,7 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { * Test drupal_get_js() for JavaScript settings. */ function testHeaderSetting() { + drupal_static_reset('_drupal_get_js'); // Only the second of these two entries should appear in Drupal.settings. drupal_add_js(array('commonTest' => 'commonTestShouldNotAppear'), 'setting'); drupal_add_js(array('commonTest' => 'commonTestShouldAppear'), 'setting'); @@ -1267,7 +1271,7 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { drupal_add_js(array('commonTestArray' => array('key' => 'commonTestOldValue')), 'setting'); drupal_add_js(array('commonTestArray' => array('key' => 'commonTestNewValue')), 'setting'); - $javascript = drupal_get_js('header'); + $javascript = drupal_get_js(); $this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header returns basePath setting.')); $this->assertTrue(strpos($javascript, 'core/misc/jquery.js') > 0, t('Rendered JavaScript header includes jQuery.')); $this->assertTrue(strpos($javascript, 'pathPrefix') > 0, t('Rendered JavaScript header returns pathPrefix setting.')); @@ -1300,11 +1304,13 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { * Test adding inline scripts. */ function testAddInline() { + drupal_static_reset('_drupal_get_js'); $inline = 'jQuery(function () { });'; - $javascript = drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); + drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); + $javascript = _drupal_get_js(); $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when inline scripts are added.')); - $data = end($javascript); - $this->assertEqual($inline, $data['data'], t('Inline JavaScript is correctly added to the footer.')); + $data = drupal_get_js('footer'); + $this->assertEqual(strpos($data, $inline) > 0, t('Inline JavaScript is correctly added to the footer.')); } /** @@ -1348,7 +1354,8 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { * Test adding a JavaScript file with a different weight. */ function testDifferentWeight() { - $javascript = drupal_add_js('core/misc/collapse.js', array('weight' => 2)); + drupal_add_js('core/misc/collapse.js', array('weight' => 2)); + $javascript = _drupal_get_js(); $this->assertEqual($javascript['core/misc/collapse.js']['weight'], 2, t('Adding a JavaScript file with a different weight caches the given weight.')); } @@ -1407,6 +1414,7 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { // Now ensure that with aggregation on, one file is made for the // 'every_page' files, and one file is made for the others. drupal_static_reset('drupal_add_js'); + drupal_static_reset('_drupal_get_js'); $config = config('system.performance'); $config->set('preprocess_js', 1); $config->save(); @@ -1414,7 +1422,7 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { drupal_add_js('core/misc/authorize.js', array('every_page' => TRUE)); drupal_add_js('core/misc/autocomplete.js'); drupal_add_js('core/misc/batch.js', array('every_page' => TRUE)); - $js_items = drupal_add_js(); + $js_items = _drupal_get_js(); $javascript = drupal_get_js(); $expected = implode("\n", array( '', @@ -1627,6 +1635,16 @@ class CommonJavaScriptTestCase extends DrupalWebTestCase { $query_string = variable_get('css_js_query_string', '0'); $this->assertRaw(drupal_get_path('module', 'node') . '/node.js?' . $query_string, t('Query string was appended correctly to js.')); } + + /** + * Tests that Drupal.settings aren't added when not needed. + */ + function testPageWithoutJavascript() { + $this->drupalGet(''); + $content = $this->drupalGetContent(); + $this->assertTrue(strpos($content, 'Drupal.settings') === FALSE, t('Drupal.settings is not added to the page.')); + $this->assertTrue(strpos($content, '.js') === FALSE, t('No javascript is added to the page.')); + } } /** diff --git a/core/modules/system/tests/theme.test b/core/modules/system/tests/theme.test index c1ba08f..9681b2a 100644 --- a/core/modules/system/tests/theme.test +++ b/core/modules/system/tests/theme.test @@ -188,7 +188,7 @@ class ThemeTableUnitTest extends DrupalWebTestCase { $header = array('one', 'two', 'three'); $rows = array(array(1,2,3), array(4,5,6), array(7,8,9)); $this->content = theme('table', array('header' => $header, 'rows' => $rows)); - $js = drupal_add_js(); + $js = _drupal_get_js(); $this->assertTrue(isset($js['core/misc/tableheader.js']), t('tableheader.js was included when $sticky = TRUE.')); $this->assertRaw('sticky-enabled', t('Table has a class of sticky-enabled when $sticky = TRUE.')); drupal_static_reset('drupal_add_js'); @@ -204,7 +204,7 @@ class ThemeTableUnitTest extends DrupalWebTestCase { $caption = NULL; $colgroups = array(); $this->content = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes, 'caption' => $caption, 'colgroups' => $colgroups, 'sticky' => FALSE)); - $js = drupal_add_js(); + $js = _drupal_get_js(); $this->assertFalse(isset($js['core/misc/tableheader.js']), t('tableheader.js was not included because $sticky = FALSE.')); $this->assertNoRaw('sticky-enabled', t('Table does not have a class of sticky-enabled because $sticky = FALSE.')); drupal_static_reset('drupal_add_js');