Commit 67076176 authored by alexpott's avatar alexpott

Issue #2647916 by Lendude, Wim Leers, dawehner: Views ajax modals stop working...

Issue #2647916 by Lendude, Wim Leers, dawehner: Views ajax modals stop working in certain scenarios: due to JS settings caching, AJAX responses may set wrong ajaxPageState.libraries, causing problems for subsequent AJAX requests/responses
parent 97b2c764
......@@ -214,7 +214,7 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize) {
// hook_library_info_alter(). Additionally add the current language to
// support translation of JavaScript files via hook_js_alter().
$libraries_to_load = $this->getLibrariesToLoad($assets);
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load) . serialize($assets->getLibraries())) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
if ($cached = $this->cache->get($cid)) {
list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;
......
......@@ -655,15 +655,6 @@ function system_js_settings_build(&$settings, AttachedAssetsInterface $assets) {
// @see \Drupal\Core\Theme\AjaxBasePageNegotiator
$theme_key = \Drupal::theme()->getActiveTheme()->getName();
$settings['ajaxPageState']['theme'] = $theme_key;
// Provide the page with information about the individual asset libraries
// used, information not otherwise available when aggregation is enabled.
$minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_merge(
$assets->getLibraries(),
$assets->getAlreadyLoadedLibraries()
));
sort($minimal_libraries);
$settings['ajaxPageState']['libraries'] = implode(',', $minimal_libraries);
}
}
......@@ -715,7 +706,7 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
$settings['pluralDelimiter'] = LOCALE_PLURAL_DELIMITER;
}
// Add the theme token to ajaxPageState, ensuring the database is available
// before doing so.
// before doing so. Also add the loaded libraries to ajaxPageState.
/** @var \Drupal\Core\Asset\LibraryDependencyResolver $library_dependency_resolver */
$library_dependency_resolver = \Drupal::service('library.dependency_resolver');
if (isset($settings['ajaxPageState']) || in_array('core/drupal.ajax', $library_dependency_resolver->getLibrariesWithDependencies($assets->getAlreadyLoadedLibraries()))) {
......@@ -729,6 +720,14 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
->get($active_theme_key);
}
}
// Provide the page with information about the individual asset libraries
// used, information not otherwise available when aggregation is enabled.
$minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_merge(
$assets->getLibraries(),
$assets->getAlreadyLoadedLibraries()
));
sort($minimal_libraries);
$settings['ajaxPageState']['libraries'] = implode(',', $minimal_libraries);
}
}
......
<?php
namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler;
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Tests the contextual filter handler UI.
*
* @group views
*/
class ContextualFilterTest extends JavascriptTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_field_body'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
ViewTestData::createTestViews(get_class($this), ['views_test_config']);
// Disable automatic live preview to make the sequence of calls clearer.
\Drupal::configFactory()->getEditable('views.settings')->set('ui.show.advanced_column', TRUE)->save();
$account = $this->drupalCreateUser(['administer views']);
$this->drupalLogin($account);
}
/**
* Test adding a contextual filter handler through the UI.
*/
public function testAddContextualFilterUI() {
$web_assert = $this->assertSession();
$this->drupalGet('/admin/structure/views/view/test_field_body');
$web_assert->assertWaitOnAjaxRequest();
$page = $this->getSession()->getPage();
$page->clickLink('views-add-argument');
$web_assert->assertWaitOnAjaxRequest();
$page->checkField('name[node_field_data.nid]');
$add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
$add_button->click();
$web_assert->assertWaitOnAjaxRequest();
$page->fillField('options[default_action]', 'default');
$page->selectFieldOption('options[default_argument_type]', 'node');
$add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
$add_button->click();
$web_assert->assertWaitOnAjaxRequest();
$page->pressButton('edit-actions-submit');
$web_assert->assertWaitOnAjaxRequest();
$page->clickLink('Content: ID');
// Check that the dialog opens.
$web_assert->assertWaitOnAjaxRequest();
$page->pressButton('Close');
}
}
......@@ -5,11 +5,11 @@
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
/**
* Tests that AJAX responses use the current theme.
* Tests AJAX responses.
*
* @group Ajax
*/
class AjaxThemeTest extends JavascriptTestBase {
class AjaxTest extends JavascriptTestBase {
/**
* {@inheritdoc}
......@@ -42,4 +42,44 @@ public function testAjaxWithAdminRoute() {
$assert->pageTextNotContains('Current theme: seven');
}
/**
* Test that AJAX loaded libraries are not retained between requests.
*
* @see https://www.drupal.org/node/2647916
*/
public function testDrupalSettingsCachingRegression() {
$this->drupalGet('ajax-test/dialog');
$assert = $this->assertSession();
$session = $this->getSession();
// Insert a fake library into the already loaded library settings.
$fake_library = 'fakeLibrary/fakeLibrary';
$session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
// Test that the fake library is set.
$this->assertContains($fake_library, $libraries);
// Click on the AJAX link.
$this->clickLink('Link 8 (ajax)');
$assert->assertWaitOnAjaxRequest();
// Test that the fake library is still set after the AJAX call.
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
$this->assertContains($fake_library, $libraries);
// Reload the page, this should reset the loaded libraries and remove the
// fake library.
$this->drupalGet('ajax-test/dialog');
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
$this->assertNotContains($fake_library, $libraries);
// Click on the AJAX link again, and the libraries should still not contain
// the fake library.
$this->clickLink('Link 8 (ajax)');
$assert->assertWaitOnAjaxRequest();
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
$this->assertNotContains($fake_library, $libraries);
}
}
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