summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt1
-rw-r--r--ctools.module81
-rw-r--r--includes/ajax.inc46
-rw-r--r--js/ajax-responder.js18
4 files changed, 116 insertions, 30 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 873ebe8..fce7e9f 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -23,6 +23,7 @@ Initial inclusion of the stylizer plugin to create user customizable styles from
#723296 by andrewlevine: Generalize more of CTools helpers so they can be used for non-CTools files.
#726320 by gordon: Allow the CTools wizard to have query strings in the wizard path.
#711664 by meclimdul: Make the 'hook' version of plugins now optional and improve code around it.
+#745468 by alevine and Scott Reynolds: Make ajax better able to know what .js/.css was already on the page.
ctools 6.x-1.3 (2010-Feb-01)
==============
diff --git a/ctools.module b/ctools.module
index 7ac338d..2cbb65f 100644
--- a/ctools.module
+++ b/ctools.module
@@ -114,10 +114,10 @@ function ctools_include($file, $module = 'ctools', $dir = 'includes') {
/**
* Provide the proper path to an image as necessary.
*
- * This helper function is used by ctools but can also be used in other
- * modules in the same way as explained in the comments of ctools_include.
+ * This helper function is used by ctools but can also be used in other
+ * modules in the same way as explained in the comments of ctools_include.
*
- * @param $image
+ * @param $image
* The base file name (with extension) of the image to be included.
* @param $module
* Optional module containing the include.
@@ -131,8 +131,8 @@ function ctools_image_path($image, $module = 'ctools', $dir = 'images') {
/**
* Include css files as necessary.
*
- * This helper function is used by ctools but can also be used in other
- * modules in the same way as explained in the comments of ctools_include.
+ * This helper function is used by ctools but can also be used in other
+ * modules in the same way as explained in the comments of ctools_include.
*
* @param $file
* The base file name to be included.
@@ -148,8 +148,8 @@ function ctools_add_css($file, $module = 'ctools', $dir = 'css') {
/**
* Include js files as necessary.
*
- * This helper function is used by ctools but can also be used in other
- * modules in the same way as explained in the comments of ctools_include.
+ * This helper function is used by ctools but can also be used in other
+ * modules in the same way as explained in the comments of ctools_include.
*
* @param $file
* The base file name to be included.
@@ -163,6 +163,18 @@ function ctools_add_js($file, $module = 'ctools', $dir = 'js') {
}
/**
+ * Simple function to add a page id to Drupal.settings.CTools.
+ */
+function ctools_add_page_id() {
+ static $page_id = NULL;
+ if (!isset($page_id)) {
+ $page_id = 'page-' . md5(mt_rand());
+ drupal_add_js(array('CTools' => array('pageId' => $page_id)), 'setting');
+ }
+ return $page_id;
+}
+
+/**
* Implement hook_init to keep our global CSS at the ready.
*/
function ctools_init() {
@@ -172,6 +184,10 @@ function ctools_init() {
ini_set('display_errors', 0);
register_shutdown_function('ctools_shutdown_handler');
}
+ else {
+ // Add a setting into the JS that identifies this page.
+ ctools_add_page_id();
+ }
}
/**
@@ -526,6 +542,57 @@ function ctools_preprocess_page(&$variables) {
}
$variables['content'] = strtr($variables['content'], $tokens);
}
+
+ // Go through all the JS files being added to the page and catalog them.
+ $js_files = array();
+ foreach (drupal_add_js() as $type => $data) {
+ if ($type != 'inline' && $type != 'setting') {
+ foreach ($data as $path => $info) {
+ $js_files[$path] = TRUE;
+ }
+ }
+ }
+
+ // Go through all CSS files that are being added to the page and catalog them.
+ $css_files = array();
+ $css = drupal_add_css();
+ 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)) {
+ $css_files[$file] = TRUE;
+ }
+ }
+ }
+ }
+
+ // Cache the cataloged JS and CSS so they can be found by an ajax request.
+ $page_id = ctools_add_page_id();
+ $expire = CACHE_TEMPORARY;
+
+ // If the page cache is enabled, respect its cache lifetime.
+ // @TODO: do this for only user_is_anonymous()?
+ if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) {
+ $expire = variable_get('cache_lifetime', 0);
+ }
+ cache_set($page_id, array('js' => $js_files, 'css' => $css_files), 'cache', $expire);
}
/**
diff --git a/includes/ajax.inc b/includes/ajax.inc
index e1eb270..c79fb3d 100644
--- a/includes/ajax.inc
+++ b/includes/ajax.inc
@@ -449,30 +449,34 @@ function ctools_ajax_command_submit($selector) {
function ctools_ajax_render($commands = array()) {
// Automatically extract any 'settings' added via drupal_add_js() and make
// them the first command.
-
$query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1);
$scripts = drupal_add_js(NULL, NULL);
+ $cached_scripts = cache_get($_POST['page_id'], 'cache')->data;
+
foreach ($scripts as $type => $data) {
switch ($type) {
case 'setting':
$settings = $data;
break;
case 'inline':
- // presently we ignore inline javascript.
+ case 'theme':
+ // Presently we ignore inline javascript.
+ // Theme JS is already added and because of admin themes, this could add
+ // improper JS to the page.
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) {
- $js_files[] = base_path() . $path . ($info['cache'] ? $query_string : '?' . time());
+ if (!isset($cached_scripts['js'][$path])) {
+ $js_files[] = base_path() . $path . ($info['cache'] ? $query_string : '?' . time());
+ }
}
}
}
-
$css = drupal_add_css();
-
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.
@@ -484,20 +488,24 @@ function ctools_ajax_render($commands = array()) {
$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)) {
- $css_files[] = array(
- 'file' => base_path() . $file . $query_string,
- 'media' => $media,
- );
+ // The theme stuff should already be added and because of admin themes,
+ // this could cause different CSS to be added.
+ if ($type != 'theme') {
+ 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) && !isset($cached_scripts['css'][$file])) {
+ $css_files[] = array(
+ 'file' => base_path() . $file . $query_string,
+ 'media' => $media,
+ );
+ }
}
}
}
diff --git a/js/ajax-responder.js b/js/ajax-responder.js
index c9016bf..a4d657d 100644
--- a/js/ajax-responder.js
+++ b/js/ajax-responder.js
@@ -13,6 +13,15 @@
Drupal.CTools.AJAX.scripts = {};
Drupal.CTools.AJAX.css = {};
+ Drupal.CTools.AJAX.getPageId = function() {
+ var page_id = '';
+ if (Drupal.settings.CTools && Drupal.settings.CTools.pageId) {
+ page_id = Drupal.settings.CTools.pageId;
+ }
+
+ return page_id;
+ }
+
/**
* Success callback for an ajax request.
*
@@ -53,7 +62,7 @@
$.ajax({
type: "POST",
url: url,
- data: { 'js': 1, 'ctools_ajax': 1 },
+ data: { 'js': 1, 'ctools_ajax': 1, 'page_id': Drupal.CTools.AJAX.getPageId() },
global: true,
success: function (data) {
Drupal.CTools.AJAX.commandCache[old_url] = data;
@@ -112,7 +121,7 @@
$.ajax({
type: "POST",
url: url,
- data: { 'js': 1, 'ctools_ajax': 1 },
+ data: { 'js': 1, 'ctools_ajax': 1, 'page_id': Drupal.CTools.AJAX.getPageId() },
global: true,
success: Drupal.CTools.AJAX.respond,
error: function(xhr) {
@@ -125,6 +134,7 @@
});
}
catch (err) {
+ console.log(err);
alert("An error occurred while attempting to process " + url);
$(this).removeClass('ctools-ajaxing');
return false;
@@ -154,7 +164,7 @@
$.ajax({
type: "POST",
url: url,
- data: { 'js': 1, 'ctools_ajax': 1 },
+ data: { 'js': 1, 'ctools_ajax': 1, 'page_id': Drupal.CTools.AJAX.getPageId() },
global: true,
success: Drupal.CTools.AJAX.respond,
error: function(xhr) {
@@ -173,7 +183,7 @@
$(form).ajaxSubmit({
type: "POST",
url: url,
- data: { 'js': 1, 'ctools_ajax': 1 },
+ data: { 'js': 1, 'ctools_ajax': 1, 'page_id': Drupal.CTools.AJAX.getPageId() },
global: true,
success: Drupal.CTools.AJAX.respond,
error: function(xhr) {