scripts.inc in Magic 7.2
Same filename and directory in other branches
A file with scripts to alter the default behavior of drupal js.
File
includes/scripts.incView source
<?php
/**
* @file
* A file with scripts to alter the default behavior of drupal js.
*/
/**
* 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.
*
* Note that hook_js_alter(&$javascript) is called during this function call
* to allow alterations of the JavaScript during its presentation. Calls to
* drupal_add_js() from hook_js_alter() will not be added to the output
* presentation. The correct way to add JavaScript during hook_js_alter()
* is to add another element to the $javascript array, deriving from
* drupal_js_defaults(). See locale_js_alter() for an example of this.
*
* @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.
* @param $skip_alter
* (optional) If set to TRUE, this function skips calling drupal_alter() on
* $javascript, useful when the calling function passes a $javascript array
* that has already been altered.
*
* @return
* All JavaScript code segments and includes for the scope as HTML tags.
*
* @see drupal_add_js()
* @see locale_js_alter()
* @see drupal_js_defaults()
*/
function magic_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALSE) {
if (!isset($javascript)) {
$javascript = drupal_add_js();
}
if (empty($javascript)) {
return '';
}
// Allow modules to alter the JavaScript.
if (!$skip_alter) {
drupal_alter('js', $javascript);
}
// Check to see if Force Header is available and set to true.
// If it is neither enabled nor set to true, change scope to footer, otherwise, keep it in the header.
// Done here because scope may change on alter. Screw Inversion of control.
$library_head = theme_get_setting('magic_library_head');
foreach ($javascript as $js_key => $js_value) {
if (!empty($js_value['force header']) && $js_value['force header']) {
$javascript[$js_key]['scope'] = 'header';
}
else {
$javascript[$js_key]['scope'] = 'footer';
}
if ($js_value['group'] == JS_LIBRARY && $library_head) {
$javascript[$js_key]['scope'] = 'header';
}
if ($js_key === 'settings') {
// We do this to ensure Drupal.settings comes after the libraries, but
// before module and theme JS.
$javascript[$js_key]['group'] = JS_SETTINGS;
if ($library_head) {
$javascript[$js_key]['scope'] = 'header';
}
}
}
// Filter out elements of the given scope.
$items = array();
foreach ($javascript as $key => $item) {
if ($item['scope'] == $scope) {
$items[$key] = $item;
}
}
// The index counter is used to keep aggregated and non-aggregated files in
// order by weight.
$index = 1;
$processed = array();
$files = array();
$preprocess_js = variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update');
// 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.
$default_query_string = variable_get('css_js_query_string', '0');
// 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<!--//--><![CDATA[//><!--\n";
$embed_suffix = "\n//--><!]]>\n";
// Since JavaScript may look for arguments in the URL and act on them, some
// 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 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']);
if (isset($items['settings'])) {
// We are already printing out the settings, we need this too.
$items['settings']['data'][] = $setting;
}
else {
// This is Drupal's default behavior.
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
// because drupal_get_js() was intentionally passed a $javascript argument
// stripped off 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'])) {
$items['settings']['data'][] = $setting;
}
// Loop through the JavaScript to construct the rendered output.
$element = array(
'#tag' => 'script',
'#value' => '',
'#attributes' => array(
'type' => 'text/javascript',
),
);
foreach ($items as $item) {
$query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
switch ($item['type']) {
case 'setting':
$js_element = $element;
$js_element['#value_prefix'] = $embed_prefix;
$js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
$js_element['#value_suffix'] = $embed_suffix;
// This is where Magic will deviate from the usual Drupal output. We
// need our settings to be after jQuery but before module JS, therefore
// we are going to treat it as a file or another inline file.
$processed[$index++] = theme('html_tag', array(
'element' => $js_element,
));
break;
case 'inline':
$js_element = $element;
if ($item['defer']) {
$js_element['#attributes']['defer'] = 'defer';
}
$js_element['#value_prefix'] = $embed_prefix;
$js_element['#value'] = $item['data'];
$js_element['#value_suffix'] = $embed_suffix;
$processed[$index++] = theme('html_tag', array(
'element' => $js_element,
));
break;
case 'file':
$js_element = $element;
if (!$item['preprocess'] || !$preprocess_js) {
if ($item['defer']) {
$js_element['#attributes']['defer'] = 'defer';
}
$query_string_separator = strpos($item['data'], '?') !== FALSE ? '&' : '?';
$js_element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
$processed[$index++] = theme('html_tag', array(
'element' => $js_element,
));
}
else {
// By increasing the index for each aggregated file, we maintain
// 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;
}
break;
case 'external':
$js_element = $element;
// Preprocessing for external JavaScript files is ignored.
if ($item['defer']) {
$js_element['#attributes']['defer'] = 'defer';
}
$js_element['#attributes']['src'] = $item['data'];
$processed[$index++] = theme('html_tag', array(
'element' => $js_element,
));
break;
}
}
// Aggregate any remaining JS files that haven't already been output.
if ($preprocess_js && count($files) > 0) {
foreach ($files as $key => $file_set) {
$uri = drupal_build_js_cache($file_set);
// Only include the file if was written successfully. Errors are logged
// using watchdog.
if ($uri) {
$preprocess_file = file_create_url($uri);
$js_element = $element;
$js_element['#attributes']['src'] = $preprocess_file;
$processed[$key] = theme('html_tag', array(
'element' => $js_element,
));
}
}
}
// 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.
return implode('', $processed);
}
Functions
Name | Description |
---|---|
magic_get_js | Returns a themed presentation of all JavaScript code for the current page. |