Commit d1d3ce0b authored by Dries's avatar Dries

- Patch #315797 by mfer, Rob Loach, et al: rework the parameter of drupal_add_js.

parent e83bf94b
......@@ -84,7 +84,7 @@ function _batch_progress_page_js() {
// 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', 'core', 'header', FALSE, FALSE);
drupal_add_js('misc/progress.js', array('type' => 'core', 'cache' => FALSE));
$url = url($batch['url'], array('query' => array('id' => $batch['id'])));
$js_setting = array(
......@@ -95,7 +95,7 @@ function _batch_progress_page_js() {
),
);
drupal_add_js($js_setting, 'setting');
drupal_add_js('misc/batch.js', 'core', 'header', FALSE, FALSE);
drupal_add_js('misc/batch.js', array('type' => 'core', 'cache' => FALSE));
$output = '<div id="progress"></div>';
return $output;
......
......@@ -2046,57 +2046,100 @@ function drupal_clear_css_cache() {
* settings are required by some modules to function properly. The settings
* will be accessible at Drupal.settings.
*
* Examples:
* @code
* 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')
* );
* @endcode
*
* @param $data
* (optional) If given, the value depends on the $type parameter:
* (optional) If given, the value depends on the $options parameter:
* - 'core', 'module' or 'theme': Path to the file relative to base_path().
* - 'inline': The JavaScript code that should be placed in the given scope.
* - 'setting': An array with configuration options as associative array. The
* array is directly placed in Drupal.settings. You might want to wrap your
* actual configuration settings in another variable to prevent the pollution
* of the Drupal.settings namespace.
* @param $type
* (optional) The type of JavaScript that should be added to the page. Allowed
* values are 'core', 'module', 'theme', 'inline' and 'setting'. You
* can, however, specify any value. It is treated as a reference to a JavaScript
* file. Defaults to 'module'.
* @param $scope
* (optional) The location in which you want to place the script. Possible
* values are 'header' and 'footer' by default. If your theme implements
* different locations, however, you can also use these.
* @param $defer
* (optional) If set to TRUE, the defer attribute is set on the <script> tag.
* Defaults to FALSE. This parameter is not used with $type == 'setting'.
* @param $cache
* (optional) If set to FALSE, the JavaScript file is loaded anew on every page
* call, that means, it is not cached. Defaults to TRUE. Used only when $type
* references a JavaScript file.
* @param $preprocess
* (optional) Should this JS file be aggregated if this
* feature has been turned on under the performance section?
* @param $options
* (optional) A string defining the type of JavaScript that is being added
* in the $data parameter ('core', 'module', 'theme', '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'.
* - scope
* The location in which you want to place the script. Possible
* values are 'header' and 'footer'. If your theme implements different
* locations, however, you can also use these. Defaults to 'header'.
* - defer
* If set to TRUE, the defer attribute is set on the <script> tag.
* Defaults to FALSE. This parameter is not used with 'type' => 'setting'.
* - cache
* If set to FALSE, the JavaScript file is loaded anew on every page
* call, that means, it is not cached. Used only when type references
* a JavaScript file. Defaults to TRUE.
* - preprocess
* Aggregate the JavaScript if the JavaScript optimization setting has
* been toggled in admin/settings/performance. Defaults to TRUE.
* @param $reset
* (optional) Resets the currently loaded JavaScript.
* @return
* If the first parameter is NULL, the JavaScript array that has been built so
* far for $scope is returned. If the first three parameters are NULL,
* an array with all scopes is returned.
* The contructed array of JavaScript files.
* @see drupal_get_js()
*/
function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE, $preprocess = TRUE) {
function drupal_add_js($data = NULL, $options = NULL, $reset = FALSE) {
static $javascript = array();
if (isset($data)) {
// 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['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(),
$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(),
)
);
}
......@@ -2113,22 +2156,15 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
$javascript[$scope][$type][] = $data;
break;
case 'inline':
$javascript[$scope][$type][] = array('code' => $data, 'defer' => $defer);
$javascript[$scope][$type][] = array('code' => $data, 'defer' => $options['defer']);
break;
default:
// If cache is FALSE, don't preprocess the JS file.
$javascript[$scope][$type][$data] = array('cache' => $cache, 'defer' => $defer, 'preprocess' => (!$cache ? FALSE : $preprocess));
$javascript[$scope][$type][$data] = $options;
}
}
if (isset($scope)) {
if (isset($javascript[$scope])) {
return $javascript[$scope];
}
else {
return array();
}
return isset($javascript[$scope]) ? $javascript[$scope] : array();
}
else {
return $javascript;
......@@ -2151,6 +2187,7 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
* 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')) {
......@@ -2158,7 +2195,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL) {
}
if (!isset($javascript)) {
$javascript = drupal_add_js(NULL, NULL, $scope);
$javascript = drupal_add_js(NULL, array('scope' => $scope));
}
if (empty($javascript)) {
......
......@@ -518,10 +518,8 @@ function locale_update_js_files() {
$dir = file_create_path(variable_get('locale_js_directory', 'languages'));
$parsed = variable_get('javascript_parsed', array());
// The first three parameters are NULL in order to get an array with all
// scopes. This is necessary to prevent recreation of JS translation files
// when new files are added for example in the footer.
$javascript = drupal_add_js(NULL, NULL, NULL);
// Get an array of all the JavaScript added so far.
$javascript = drupal_add_js();
$files = $new_files = FALSE;
foreach ($javascript as $scope) {
......
......@@ -252,6 +252,109 @@ class DrupalSetContentTestCase extends DrupalWebTestCase {
}
}
/**
* Tests for the JavaScript system.
*/
class JavaScriptTestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('JavaScript'),
'description' => t("Tests the JavaScript system."),
'group' => t('System')
);
}
/**
* Implementation of setUp().
*/
function setUp() {
// Reset drupal_add_js() before each test.
drupal_add_js(NULL, NULL, TRUE);
}
/**
* 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.'));
}
/**
* 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.'));
}
/**
* Test drupal_get_js() for JavaScript settings.
*/
function testHeaderSetting() {
drupal_add_js(array('testSetting' => 'testValue'), 'setting');
$javascript = drupal_get_js('header');
$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.'));
}
/**
* 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.'));
}
/**
* 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.'));
}
/**
* Test drupal_get_js() 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.'));
}
/**
* Test drupal_add_js() sets preproccess to false when cache is set to false.
*/
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.'));
}
}
/**
* Tests Drupal error and exception handlers.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment