From 816a95e66f81a25e93f02dbe422316e336e682e7 Mon Sep 17 00:00:00 2001
From: msonnabaum <msonnabaum@75278.no-reply.drupal.org>
Date: Fri, 18 May 2012 22:31:16 +0200
Subject: [PATCH] Issue #1530740 by dawehner, msonnabaum: Fixed views cache
 adds all CSS/JS on hits unnecessarily.

---
 plugins/views_plugin_cache.inc | 26 ++++----------
 tests/views_cache.test         | 63 ++++++++++++++++++++++++++++++++++
 tests/views_cache.test.css     |  5 +++
 tests/views_cache.test.js      |  5 +++
 tests/views_test.module        | 11 ++++++
 5 files changed, 90 insertions(+), 20 deletions(-)
 create mode 100644 tests/views_cache.test.css
 create mode 100644 tests/views_cache.test.js

diff --git a/plugins/views_plugin_cache.inc b/plugins/views_plugin_cache.inc
index 151fd92e25b0..fb8500f9080b 100644
--- a/plugins/views_plugin_cache.inc
+++ b/plugins/views_plugin_cache.inc
@@ -201,32 +201,18 @@ function gather_headers() {
 
     // Slightly less simple for CSS:
     $css = drupal_add_css();
-    $start = isset($this->storage['css']) ? $this->storage['css'] : array();
-    $this->storage['css'] = array();
+    $css_start = isset($this->storage['css']) ? $this->storage['css'] : array();
+    $this->storage['css'] = array_diff_assoc($css, $css_start);
 
-    foreach ($css as $file => $data) {
-      if (!isset($this->storage['css'][$file])) {
-        $this->storage['css'][$file] = $data;
-      }
-    }
-
-    // Get javascript after views renders
+    // Get javascript after/before views renders.
     $js = drupal_add_js();
-
-    // Get javascript before views renders.
-    $start = isset($this->storage['js']) ? $this->storage['js'] : array();
-    $this->storage['js'] = array();
-
+    $js_start = isset($this->storage['js']) ? $this->storage['js'] : array();
     // If there are any differences between the old and the new javascript then
     // store them to be added later.
-    if ($diff = array_diff_assoc($js, $start)) {
-      $this->storage['js'] = $diff;
-    }
+    $this->storage['js'] = array_diff_assoc($js, $js_start);
 
     // Special case the settings key and get the difference of the data.
-    if ($settings_diff = array_diff_assoc($js['settings']['data'], $start['settings']['data'])) {
-      $this->storage['js']['settings'] = $settings_diff;
-    }
+    $this->storage['js']['settings'] = array_diff_assoc($js['settings']['data'], $js_start['settings']['data']);
   }
 
   /**
diff --git a/tests/views_cache.test b/tests/views_cache.test
index e03cbf2c2b93..5f3076e6de7a 100644
--- a/tests/views_cache.test
+++ b/tests/views_cache.test
@@ -148,4 +148,67 @@ class ViewsCacheTest extends ViewsSqlTest {
     // Verify the result.
     $this->assertEqual(6, count($view->result), t('The number of returned rows match.'));
   }
+
+  /**
+   * Tests css/js storage and restoring mechanism.
+   */
+  function testHeaderStorage() {
+    // Create a view with output caching enabled.
+    // Some hook_views_pre_render in views_test.module adds the test css/js file.
+    // so they should be added to the css/js storage.
+    $view = $this->getBasicView();
+    $view->init_display();
+    $view->name = 'test_cache_header_storage';
+    $view->display_handler->override_option('cache', array(
+      'type' => 'time',
+      'output_lifespan' => '3600',
+    ));
+    // @todo The cache plugin expects settings['data'] to be set.
+    // Maybe the cache plugin should be changed.
+    drupal_add_js('setting', array('example' => ''));
+
+    $view->preview();
+    $view->destroy();
+    unset($view->pre_render_called);
+    drupal_static_reset('drupal_add_css');
+    drupal_static_reset('drupal_add_js');
+
+    $view->init_display();
+    $view->preview();
+    $css = drupal_add_css();
+    $css_path = drupal_get_path('module', 'views_test') . '/views_cache.test.css';
+    $js_path = drupal_get_path('module', 'views_test') . '/views_cache.test.js';
+    $js = drupal_add_js();
+
+    $this->assertTrue(isset($css[$css_path]), 'Make sure the css is added for cached views.');
+    $this->assertTrue(isset($js[$js_path]), 'Make sure the js is added for cached views.');
+    $this->assertFalse(!empty($view->pre_render_called), 'Make sure hook_views_pre_render is not called for the cached view.');
+    $view->destroy();
+
+    // Now add some css/jss before running the view.
+    // Make sure that this css is not added when running the cached view.
+    $view->name = 'test_cache_header_storage_2';
+
+    $system_css_path = drupal_get_path('module', 'system') . '/system.maintenance.css';
+    drupal_add_css($system_css_path);
+    $system_js_path = drupal_get_path('module', 'system') . '/system.cron.js';
+    drupal_add_js($system_js_path);
+
+    $view->init_display();
+    $view->preview();
+    $view->destroy();
+    drupal_static_reset('drupal_add_css');
+    drupal_static_reset('drupal_add_js');
+
+    $view->init_display();
+    $view->preview();
+
+    $css = drupal_add_css();
+    $js = drupal_add_js();
+
+    $this->assertFalse(isset($css[$system_css_path]), 'Make sure that unrelated css is not added.');
+    $this->assertFalse(isset($js[$system_js_path]), 'Make sure that unrelated js is not added.');
+
+  }
+
 }
diff --git a/tests/views_cache.test.css b/tests/views_cache.test.css
new file mode 100644
index 000000000000..8dd17c148f59
--- /dev/null
+++ b/tests/views_cache.test.css
@@ -0,0 +1,5 @@
+/**
+ * @file
+ * Just a placeholder file for the test.
+ * @see ViewsCacheTest::testHeaderStorage
+ */
diff --git a/tests/views_cache.test.js b/tests/views_cache.test.js
new file mode 100644
index 000000000000..8dd17c148f59
--- /dev/null
+++ b/tests/views_cache.test.js
@@ -0,0 +1,5 @@
+/**
+ * @file
+ * Just a placeholder file for the test.
+ * @see ViewsCacheTest::testHeaderStorage
+ */
diff --git a/tests/views_test.module b/tests/views_test.module
index 8f8afbe89901..f6026b8bc52f 100644
--- a/tests/views_test.module
+++ b/tests/views_test.module
@@ -48,3 +48,14 @@ function views_test_test_static_access_callback($access) {
 function views_test_test_dynamic_access_callback($access, $argument1, $argument2) {
   return $access && $argument1 == variable_get('test_dynamic_access_argument1', NULL) && $argument2 == variable_get('test_dynamic_access_argument2', NULL);
 }
+
+/**
+ * Implements hook_views_pre_render().
+ */
+function views_test_views_pre_render(&$view) {
+  if ($view->name == 'test_cache_header_storage') {
+    drupal_add_js(drupal_get_path('module', 'views_test') . '/views_cache.test.js');
+    drupal_add_css(drupal_get_path('module', 'views_test') . '/views_cache.test.css');
+    $view->pre_render_called = TRUE;
+  }
+}
-- 
GitLab