async_js.module in Asynchronous JavaScript 8
Same filename and directory in other branches
Queue JavaScript files to be loaded asynchronously.
File
async_js.moduleView source
<?php
/**
* @file
* Queue JavaScript files to be loaded asynchronously.
*/
/**
* Queue scripts to be loaded asynchronously.
*
* @param string $src
* The path to the file relative to base_path().
* @param array $options
* An associative array of options for each script. The following elements
* affect asynchronous loading functionality:
* - 'type': The type of JavaScript that is to be added to the page.
* Allowed values are 'file' or 'external'. Defaults to 'file'.
* - 'async_dependencies': An indexed array of scripts which must be loaded
* before the current script. The value of each item in the array must
* correspond exactly to the $src parameter originally used to load the
* dependency.
* - 'async_callback': The name of a javascript function, or an array of them,
* in the global scope which will be run once this particular script is
* finished loading.
* - 'async_fade': An array of jQuery selectors which correspond to elements
* on the page to fadeIn after a specified timeout and in unison. The
* fadeIn effect will be applied universally to all elements defined in
* this way on a single page.
* - 'async_container': A jQuery selector which corresponds to the element on
* the page in which the script should be inserted. If left blank, the
* script will be inserted before the first script element in the document.
* - 'cache': If set to FALSE, the JavaScript file is loaded anew on every
* asynchronous request. Defaults to TRUE.
*
* @see async_js_js_alter()
*/
function async_js_add_js($src = NULL, array $options = array()) {
$javascript =& drupal_static(__FUNCTION__, array());
if (!empty($src)) {
// Set default options.
$options += array(
'type' => 'file',
'async_dependencies' => array(),
'async_callback' => array(),
'async_fade' => array(),
'async_container' => NULL,
'cache' => TRUE,
);
// Add script to queue.
$javascript[$src] = array(
'data' => $src,
) + $options;
}
return $javascript;
}
/**
* Implements hook_js_alter().
*
* @see async_js_add_js()
*/
function async_js_js_alter(&$javascript) {
// Add any scripts to be loaded asynchronously.
foreach ($javascript as $key => $script) {
if (!empty($script['async_js'])) {
async_js_add_js($script['data'], $script);
unset($javascript[$key]);
}
}
// Retrieve all scripts to be loaded asynchronously.
$async_js = async_js_add_js();
if (!empty($async_js)) {
// Process dependencies.
$async_js = _async_js_process_dependencies($async_js);
// Build file URLs.
$async_js = _async_js_build_urls($async_js);
// Initialize settings array.
$settings = array();
$javascript['settings']['data'][]['async_js'] =& $settings;
// Add settings for each script.
foreach ($async_js as $script) {
// Prep $script for JavaScript.
$script = array(
'data' => $script['data'],
// Use an array of callbacks, even if only given a string.
'callbacks' => (array) $script['async_callback'],
'fade' => $script['async_fade'],
'container' => $script['async_container'],
'dependencies' => $script['async_dependencies'],
'dependents' => $script['async_dependents'],
'queued' => FALSE,
'loaded' => FALSE,
);
// Add file to script list.
$settings['javascript'][$script['data']] = $script;
}
// Add additional settings.
$settings['timeout'] = variable_get('async_js_timeout', 1000);
$settings['finalCallback'] = variable_get('async_js_final_callback', '');
// Add our own script.
$data = drupal_get_path('module', 'async_js') . '/async_js.js';
$javascript[$data] = drupal_js_defaults($data);
}
}
/**
* Prepares script data for actual requests.
*
* @param array $scripts
* An array of scripts as returned by async_js_add_js().
*
* @see async_js_js_alter()
* @see async_js_add_js()
*/
function _async_js_build_urls(array $scripts = array()) {
// Initialize variables necessary for building the file url.
$default_query_string = variable_get('css_js_query_string', '0');
$js_version_string = variable_get('drupal_js_version_query_string', 'v=');
// Keep track of any changes we make so we can reference them later when
// dealing with dependencies and dependents.
$changes = array();
// Build the urls.
foreach ($scripts as &$script) {
if ($script['type'] != 'external') {
$old_data = $script['data'];
$query_string = empty($script['version']) ? $default_query_string : $js_version_string . $script['version'];
$query_string_separator = strpos($script['data'], '?') !== FALSE ? '&' : '?';
$script['data'] = file_create_url($script['data']) . $query_string_separator . ($script['cache'] ? $query_string : REQUEST_TIME);
$changes[$old_data] = $script['data'];
}
}
// Handle potential dependencies and dependents.
foreach ($scripts as &$script) {
// Handle potential dependencies.
if (!empty($script['async_dependencies'])) {
foreach ($script['async_dependencies'] as $key => $dependency) {
if (!empty($changes[$dependency])) {
$script['async_dependencies'][$key] = $changes[$dependency];
}
}
}
// Handle potential dependents.
if (!empty($script['async_dependents'])) {
foreach ($script['async_dependents'] as $key => $dependent) {
if (!empty($changes[$dependent])) {
$script['async_dependents'][$key] = $changes[$dependent];
}
}
}
}
return $scripts;
}
/**
* Processes script dependencies, creating corresponding dependent references.
*
* @param array $scripts
* An array of scripts as returned by async_js_add_js().
*
* @see async_js_js_alter()
* @see async_js_add_js()
*/
function _async_js_process_dependencies(array $scripts = array()) {
foreach ($scripts as $key => $script) {
// Make sure every script has an empty async_dependents array by default.
$scripts[$key]['async_dependents'] = array();
}
$scripts_copy = $scripts;
// Create corresponding dependent references.
foreach ($scripts_copy as $key => $script) {
if (!empty($script['async_dependencies'])) {
foreach ($script['async_dependencies'] as $dependency) {
if (!empty($scripts[$dependency])) {
$scripts[$dependency]['async_dependents'][] = $script['data'];
}
else {
unset($scripts[$key]);
drupal_set_message(t('The script, @script is dependent on @dependency, which does not exist on this page.', array(
'@script' => $script['data'],
'@dependency' => $dependency,
)), 'error');
}
}
}
}
return $scripts;
}
Functions
Name![]() |
Description |
---|---|
async_js_add_js | Queue scripts to be loaded asynchronously. |
async_js_js_alter | Implements hook_js_alter(). |
_async_js_build_urls | Prepares script data for actual requests. |
_async_js_process_dependencies | Processes script dependencies, creating corresponding dependent references. |