Issue #2506369 by catch, dawehner, Wim Leers: Cache CSS/JS asset resolving
parent
d305a8efaa
commit
5d3a761e61
|
@ -1318,7 +1318,7 @@ services:
|
|||
arguments: ['@library.discovery']
|
||||
asset.resolver:
|
||||
class: Drupal\Core\Asset\AssetResolver
|
||||
arguments: ['@library.discovery', '@library.dependency_resolver', '@module_handler', '@theme.manager']
|
||||
arguments: ['@library.discovery', '@library.dependency_resolver', '@module_handler', '@theme.manager', '@language_manager', '@cache.data']
|
||||
info_parser:
|
||||
class: Drupal\Core\Extension\InfoParser
|
||||
twig:
|
||||
|
|
|
@ -175,7 +175,7 @@ class AjaxResponse extends JsonResponse {
|
|||
// Resolve the attached libraries into asset collections.
|
||||
$assets = new AttachedAssets();
|
||||
$assets->setLibraries(isset($this->attachments['library']) ? $this->attachments['library'] : [])
|
||||
->setAlreadyLoadedLibraries(isset($ajax_page_state) ? explode(',', $ajax_page_state['libraries']) : [])
|
||||
->setAlreadyLoadedLibraries(isset($ajax_page_state['libraries']) ? explode(',', $ajax_page_state['libraries']) : [])
|
||||
->setSettings(isset($this->attachments['drupalSettings']) ? $this->attachments['drupalSettings'] : []);
|
||||
$asset_resolver = \Drupal::service('asset.resolver');
|
||||
$css_assets = $asset_resolver->getCssAssets($assets, $optimize_css);
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
|
||||
namespace Drupal\Core\Asset;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Theme\ThemeManagerInterface;
|
||||
|
||||
/**
|
||||
|
@ -43,6 +46,20 @@ class AssetResolver implements AssetResolverInterface {
|
|||
*/
|
||||
protected $themeManager;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* The cache backend.
|
||||
*
|
||||
* @var \Drupal\Core\Cache\CacheBackendInterface
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructs a new AssetResolver instance.
|
||||
*
|
||||
|
@ -54,12 +71,18 @@ class AssetResolver implements AssetResolverInterface {
|
|||
* The module handler.
|
||||
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
|
||||
* The theme manager.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
|
||||
* The cache backend.
|
||||
*/
|
||||
public function __construct(LibraryDiscoveryInterface $library_discovery, LibraryDependencyResolverInterface $library_dependency_resolver, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
|
||||
public function __construct(LibraryDiscoveryInterface $library_discovery, LibraryDependencyResolverInterface $library_dependency_resolver, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, LanguageManagerInterface $language_manager, CacheBackendInterface $cache) {
|
||||
$this->libraryDiscovery = $library_discovery;
|
||||
$this->libraryDependencyResolver = $library_dependency_resolver;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->themeManager = $theme_manager;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,6 +115,12 @@ class AssetResolver implements AssetResolverInterface {
|
|||
*/
|
||||
public function getCssAssets(AttachedAssetsInterface $assets, $optimize) {
|
||||
$theme_info = $this->themeManager->getActiveTheme();
|
||||
// Add the theme name to the cache key since themes may implement
|
||||
// hook_css_alter().
|
||||
$cid = 'css:' . $theme_info->getName() . ':' . Crypt::hashBase64(serialize($assets)) . (int) $optimize;
|
||||
if ($cached = $this->cache->get($cid)) {
|
||||
return $cached->data;
|
||||
}
|
||||
|
||||
$css = [];
|
||||
$default_options = [
|
||||
|
@ -149,6 +178,7 @@ class AssetResolver implements AssetResolverInterface {
|
|||
if ($optimize) {
|
||||
$css = \Drupal::service('asset.css.collection_optimizer')->optimize($css);
|
||||
}
|
||||
$this->cache->set($cid, $css, CacheBackendInterface::CACHE_PERMANENT, ['library_info']);
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
@ -180,10 +210,6 @@ class AssetResolver implements AssetResolverInterface {
|
|||
// Attached settings win over settings in libraries.
|
||||
$settings = NestedArray::mergeDeepArray([$settings, $assets->getSettings()], TRUE);
|
||||
|
||||
// Allow modules and themes to alter the JavaScript settings.
|
||||
$this->moduleHandler->alter('js_settings', $settings, $assets);
|
||||
$this->themeManager->alter('js_settings', $settings, $assets);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
@ -191,115 +217,142 @@ class AssetResolver implements AssetResolverInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getJsAssets(AttachedAssetsInterface $assets, $optimize) {
|
||||
$javascript = [];
|
||||
$default_options = [
|
||||
'type' => 'file',
|
||||
'group' => JS_DEFAULT,
|
||||
'every_page' => FALSE,
|
||||
'weight' => 0,
|
||||
'cache' => TRUE,
|
||||
'preprocess' => TRUE,
|
||||
'attributes' => [],
|
||||
'version' => NULL,
|
||||
'browsers' => [],
|
||||
];
|
||||
$theme_info = $this->themeManager->getActiveTheme();
|
||||
// Add the theme name to the cache key since themes may implement
|
||||
// hook_js_alter(). Additionally add the current language to support
|
||||
// translation of JavaScript files.
|
||||
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($assets));
|
||||
|
||||
$libraries_to_load = $this->getLibrariesToLoad($assets);
|
||||
|
||||
// Collect all libraries that contain JS assets and are in the header.
|
||||
$header_js_libraries = [];
|
||||
foreach ($libraries_to_load as $library) {
|
||||
list($extension, $name) = explode('/', $library, 2);
|
||||
$definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
|
||||
if (isset($definition['js']) && !empty($definition['header'])) {
|
||||
$header_js_libraries[] = $library;
|
||||
}
|
||||
if ($cached = $this->cache->get($cid)) {
|
||||
list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;
|
||||
}
|
||||
// The current list of header JS libraries are only those libraries that are
|
||||
// in the header, but their dependencies must also be loaded for them to
|
||||
// function correctly, so update the list with those.
|
||||
$header_js_libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($header_js_libraries);
|
||||
else {
|
||||
$javascript = [];
|
||||
$default_options = [
|
||||
'type' => 'file',
|
||||
'group' => JS_DEFAULT,
|
||||
'every_page' => FALSE,
|
||||
'weight' => 0,
|
||||
'cache' => TRUE,
|
||||
'preprocess' => TRUE,
|
||||
'attributes' => [],
|
||||
'version' => NULL,
|
||||
'browsers' => [],
|
||||
];
|
||||
|
||||
foreach ($libraries_to_load as $library) {
|
||||
list($extension, $name) = explode('/', $library, 2);
|
||||
$definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
|
||||
if (isset($definition['js'])) {
|
||||
foreach ($definition['js'] as $options) {
|
||||
$options += $default_options;
|
||||
$libraries_to_load = $this->getLibrariesToLoad($assets);
|
||||
|
||||
// 'scope' is a calculated option, based on which libraries are marked
|
||||
// to be loaded from the header (see above).
|
||||
$options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer';
|
||||
|
||||
// Preprocess can only be set if caching is enabled and no attributes
|
||||
// are set.
|
||||
$options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE;
|
||||
|
||||
// Always add a tiny value to the weight, to conserve the insertion
|
||||
// order.
|
||||
$options['weight'] += count($javascript) / 1000;
|
||||
|
||||
// Local and external files must keep their name as the associative
|
||||
// key so the same JavaScript file is not added twice.
|
||||
$javascript[$options['data']] = $options;
|
||||
// Collect all libraries that contain JS assets and are in the header.
|
||||
$header_js_libraries = [];
|
||||
foreach ($libraries_to_load as $library) {
|
||||
list($extension, $name) = explode('/', $library, 2);
|
||||
$definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
|
||||
if (isset($definition['js']) && !empty($definition['header'])) {
|
||||
$header_js_libraries[] = $library;
|
||||
}
|
||||
}
|
||||
}
|
||||
// The current list of header JS libraries are only those libraries that
|
||||
// are in the header, but their dependencies must also be loaded for them
|
||||
// to function correctly, so update the list with those.
|
||||
$header_js_libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($header_js_libraries);
|
||||
|
||||
// Allow modules and themes to alter the JavaScript assets.
|
||||
$this->moduleHandler->alter('js', $javascript, $assets);
|
||||
$this->themeManager->alter('js', $javascript, $assets);
|
||||
foreach ($libraries_to_load as $library) {
|
||||
list($extension, $name) = explode('/', $library, 2);
|
||||
$definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
|
||||
if (isset($definition['js'])) {
|
||||
foreach ($definition['js'] as $options) {
|
||||
$options += $default_options;
|
||||
|
||||
// Sort JavaScript assets, so that they appear in the correct order.
|
||||
uasort($javascript, 'static::sort');
|
||||
// 'scope' is a calculated option, based on which libraries are
|
||||
// marked to be loaded from the header (see above).
|
||||
$options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer';
|
||||
|
||||
// Prepare the return value: filter JavaScript assets per scope.
|
||||
$js_assets_header = [];
|
||||
$js_assets_footer = [];
|
||||
foreach ($javascript as $key => $item) {
|
||||
if ($item['scope'] == 'header') {
|
||||
$js_assets_header[$key] = $item;
|
||||
}
|
||||
elseif ($item['scope'] == 'footer') {
|
||||
$js_assets_footer[$key] = $item;
|
||||
}
|
||||
}
|
||||
// Preprocess can only be set if caching is enabled and no
|
||||
// attributes are set.
|
||||
$options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE;
|
||||
|
||||
if ($optimize) {
|
||||
$collection_optimizer = \Drupal::service('asset.js.collection_optimizer');
|
||||
$js_assets_header = $collection_optimizer->optimize($js_assets_header);
|
||||
$js_assets_footer = $collection_optimizer->optimize($js_assets_footer);
|
||||
}
|
||||
// Always add a tiny value to the weight, to conserve the insertion
|
||||
// order.
|
||||
$options['weight'] += count($javascript) / 1000;
|
||||
|
||||
// If the core/drupalSettings library is being loaded or is already loaded,
|
||||
// get the JavaScript settings assets, and convert them into a single
|
||||
// "regular" JavaScript asset.
|
||||
$libraries_to_load = $this->getLibrariesToLoad($assets);
|
||||
$settings_needed = in_array('core/drupalSettings', $libraries_to_load) || in_array('core/drupalSettings', $this->libraryDependencyResolver->getLibrariesWithDependencies($assets->getAlreadyLoadedLibraries()));
|
||||
$settings_have_changed = count($libraries_to_load) > 0 || count($assets->getSettings()) > 0;
|
||||
if ($settings_needed && $settings_have_changed) {
|
||||
$settings = $this->getJsSettingsAssets($assets);
|
||||
if (!empty($settings)) {
|
||||
$settings_as_inline_javascript = [
|
||||
'type' => 'setting',
|
||||
'group' => JS_SETTING,
|
||||
'every_page' => TRUE,
|
||||
'weight' => 0,
|
||||
'browsers' => [],
|
||||
'data' => $settings,
|
||||
];
|
||||
$settings_js_asset = ['drupalSettings' => $settings_as_inline_javascript];
|
||||
// Prepend to the list of JS assets, to render it first. Preferably in
|
||||
// the footer, but in the header if necessary.
|
||||
if (in_array('core/drupalSettings', $header_js_libraries)) {
|
||||
$js_assets_header = $settings_js_asset + $js_assets_header;
|
||||
}
|
||||
else {
|
||||
$js_assets_footer = $settings_js_asset + $js_assets_footer;
|
||||
// Local and external files must keep their name as the associative
|
||||
// key so the same JavaScript file is not added twice.
|
||||
$javascript[$options['data']] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow modules and themes to alter the JavaScript assets.
|
||||
$this->moduleHandler->alter('js', $javascript, $assets);
|
||||
$this->themeManager->alter('js', $javascript, $assets);
|
||||
|
||||
// Sort JavaScript assets, so that they appear in the correct order.
|
||||
uasort($javascript, 'static::sort');
|
||||
|
||||
// Prepare the return value: filter JavaScript assets per scope.
|
||||
$js_assets_header = [];
|
||||
$js_assets_footer = [];
|
||||
foreach ($javascript as $key => $item) {
|
||||
if ($item['scope'] == 'header') {
|
||||
$js_assets_header[$key] = $item;
|
||||
}
|
||||
elseif ($item['scope'] == 'footer') {
|
||||
$js_assets_footer[$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($optimize) {
|
||||
$collection_optimizer = \Drupal::service('asset.js.collection_optimizer');
|
||||
$js_assets_header = $collection_optimizer->optimize($js_assets_header);
|
||||
$js_assets_footer = $collection_optimizer->optimize($js_assets_footer);
|
||||
}
|
||||
|
||||
// If the core/drupalSettings library is being loaded or is already
|
||||
// loaded, get the JavaScript settings assets, and convert them into a
|
||||
// single "regular" JavaScript asset.
|
||||
$libraries_to_load = $this->getLibrariesToLoad($assets);
|
||||
$settings_required = in_array('core/drupalSettings', $libraries_to_load) || in_array('core/drupalSettings', $this->libraryDependencyResolver->getLibrariesWithDependencies($assets->getAlreadyLoadedLibraries()));
|
||||
$settings_have_changed = count($libraries_to_load) > 0 || count($assets->getSettings()) > 0;
|
||||
|
||||
// Initialize settings to FALSE since they are not needed by default. This
|
||||
// distinguishes between an empty array which must still allow
|
||||
// hook_js_settings_alter() to be run.
|
||||
$settings = FALSE;
|
||||
if ($settings_required && $settings_have_changed) {
|
||||
$settings = $this->getJsSettingsAssets($assets);
|
||||
// Allow modules to add cached JavaScript settings.
|
||||
foreach ($this->moduleHandler->getImplementations('js_settings_build') as $module) {
|
||||
$function = $module . '_' . 'js_settings_build';
|
||||
$function($settings, $assets);
|
||||
}
|
||||
}
|
||||
$settings_in_header = in_array('core/drupalSettings', $header_js_libraries);
|
||||
$this->cache->set($cid, [$js_assets_header, $js_assets_footer, $settings, $settings_in_header], CacheBackendInterface::CACHE_PERMANENT, ['library_info']);
|
||||
}
|
||||
|
||||
|
||||
if ($settings !== FALSE) {
|
||||
// Allow modules and themes to alter the JavaScript settings.
|
||||
$this->moduleHandler->alter('js_settings', $settings, $assets);
|
||||
$this->themeManager->alter('js_settings', $settings, $assets);
|
||||
$settings_as_inline_javascript = [
|
||||
'type' => 'setting',
|
||||
'group' => JS_SETTING,
|
||||
'every_page' => TRUE,
|
||||
'weight' => 0,
|
||||
'browsers' => [],
|
||||
'data' => $settings,
|
||||
];
|
||||
$settings_js_asset = ['drupalSettings' => $settings_as_inline_javascript];
|
||||
// Prepend to the list of JS assets, to render it first. Preferably in
|
||||
// the footer, but in the header if necessary.
|
||||
if ($settings_in_header) {
|
||||
$js_assets_header = $settings_js_asset + $js_assets_header;
|
||||
}
|
||||
else {
|
||||
$js_assets_footer = $settings_js_asset + $js_assets_footer;
|
||||
}
|
||||
}
|
||||
return [
|
||||
$js_assets_header,
|
||||
$js_assets_footer,
|
||||
|
|
|
@ -825,6 +825,27 @@ function hook_library_info_build() {
|
|||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the JavaScript settings (drupalSettings).
|
||||
*
|
||||
* @param array &$settings
|
||||
* An array of all JavaScript settings (drupalSettings) being presented on the
|
||||
* page.
|
||||
* @param \Drupal\Core\Asset\AttachedAssetsInterface $assets
|
||||
* The assets attached to the current response.
|
||||
*
|
||||
* @see \Drupal\Core\Asset\AssetResolver
|
||||
*
|
||||
* The results of this hook are cached, however modules may use
|
||||
* hook_js_settings_alter() to dynamically alter settings.
|
||||
*/
|
||||
function hook_js_settings_build(array &$settings, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
|
||||
// Manipulate settings.
|
||||
if (isset($settings['dialog'])) {
|
||||
$settings['dialog']['autoResize'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary alterations to the JavaScript settings (drupalSettings).
|
||||
*
|
||||
|
|
|
@ -158,7 +158,7 @@ class CKEditorLoadingTest extends WebTestBase {
|
|||
// Editor.module's JS present. Note: ckeditor/drupal.ckeditor depends on
|
||||
// editor/drupal.editor, hence presence of the former implies presence of
|
||||
// the latter.
|
||||
isset($settings['ajaxPageState']) && in_array('ckeditor/drupal.ckeditor', explode(',', $settings['ajaxPageState']['libraries'])),
|
||||
isset($settings['ajaxPageState']['libraries']) && in_array('ckeditor/drupal.ckeditor', explode(',', $settings['ajaxPageState']['libraries'])),
|
||||
// Body field.
|
||||
$this->xpath('//textarea[@id="edit-body-0-value"]'),
|
||||
// Format selector.
|
||||
|
|
|
@ -130,7 +130,7 @@ class CommentCSSTest extends CommentTestBase {
|
|||
if ($case['comment_status'] == CommentInterface::PUBLISHED || $case['user'] == 'admin') {
|
||||
$this->assertIdentical(1, count($this->xpath('//*[contains(@class, "comment")]/*[@data-comment-timestamp="' . $comment->getChangedTime() . '"]')), 'data-comment-timestamp attribute is set on comment');
|
||||
$expectedJS = ($case['user'] !== 'anonymous');
|
||||
$this->assertIdentical($expectedJS, isset($settings['ajaxPageState']) && in_array('comment/drupal.comment-new-indicator', explode(',', $settings['ajaxPageState']['libraries'])), 'drupal.comment-new-indicator library is present.');
|
||||
$this->assertIdentical($expectedJS, isset($settings['ajaxPageState']['libraries']) && in_array('comment/drupal.comment-new-indicator', explode(',', $settings['ajaxPageState']['libraries'])), 'drupal.comment-new-indicator library is present.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2053,9 +2053,13 @@ abstract class WebTestBase extends TestBase {
|
|||
protected function getAjaxPageStatePostData() {
|
||||
$post = array();
|
||||
$drupal_settings = $this->drupalSettings;
|
||||
if (isset($drupal_settings['ajaxPageState'])) {
|
||||
if (isset($drupal_settings['ajaxPageState']['theme'])) {
|
||||
$post['ajax_page_state[theme]'] = $drupal_settings['ajaxPageState']['theme'];
|
||||
}
|
||||
if (isset($drupal_settings['ajaxPageState']['theme_token'])) {
|
||||
$post['ajax_page_state[theme_token]'] = $drupal_settings['ajaxPageState']['theme_token'];
|
||||
}
|
||||
if (isset($drupal_settings['ajaxPageState']['libraries'])) {
|
||||
$post['ajax_page_state[libraries]'] = $drupal_settings['ajaxPageState']['libraries'];
|
||||
}
|
||||
return $post;
|
||||
|
|
|
@ -606,10 +606,46 @@ function system_page_attachments(array &$page) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_js_settings_build().
|
||||
*
|
||||
* Sets values for the core/drupal.ajax library, which just depends on the
|
||||
* active theme but no other request-dependent values.
|
||||
*/
|
||||
function system_js_settings_build(&$settings, AttachedAssetsInterface $assets) {
|
||||
// Generate the values for the core/drupal.ajax library.
|
||||
// We need to send ajaxPageState settings for core/drupal.ajax if:
|
||||
// - ajaxPageState is being loaded in this Response, in which case it will
|
||||
// already exist at $settings['ajaxPageState'] (because the core/drupal.ajax
|
||||
// library definition specifies a placeholder 'ajaxPageState' setting).
|
||||
// - core/drupal.ajax already has been loaded and hence this is an AJAX
|
||||
// Response in which we must send the list of extra asset libraries that are
|
||||
// being added in this AJAX Response.
|
||||
/** @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()))) {
|
||||
// Provide the page with information about the theme that's used, so that
|
||||
// a later AJAX request can be rendered using the same theme.
|
||||
// @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_js_settings_alter().
|
||||
*
|
||||
* Sets values for the core/drupalSettings and core/drupal.ajax libraries.
|
||||
* Sets values which depend on the current request, like core/drupalSettings
|
||||
* as well as theme_token ajax state.
|
||||
*/
|
||||
function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
|
||||
// url() generates the script and prefix using hook_url_outbound_alter().
|
||||
|
@ -647,36 +683,15 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
|
|||
if (!isset($settings['pluralDelimiter'])) {
|
||||
$settings['pluralDelimiter'] = LOCALE_PLURAL_DELIMITER;
|
||||
}
|
||||
|
||||
// Now generate the values for the core/drupal.ajax library.
|
||||
// We need to send ajaxPageState settings for core/drupal.ajax if:
|
||||
// - ajaxPageState is being loaded in this Response, in which case it will
|
||||
// already exist at $settings['ajaxPageState'] (because the core/drupal.ajax
|
||||
// library definition specifies a placeholder 'ajaxPageState' setting).
|
||||
// - core/drupal.ajax already has been loaded and hence this is an AJAX
|
||||
// Response in which we must send the list of extra asset libraries that are
|
||||
// being added in this AJAX Response.
|
||||
// Add the theme token to ajaxPageState, ensuring the database is available
|
||||
// before doing so.
|
||||
/** @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()))) {
|
||||
// Provide the page with information about the theme that's used, so that
|
||||
// a later AJAX request can be rendered using the same theme.
|
||||
// @see \Drupal\Core\Theme\AjaxBasePageNegotiator
|
||||
$theme_key = \Drupal::theme()->getActiveTheme()->getName();
|
||||
$settings['ajaxPageState']['theme'] = $theme_key;
|
||||
// Checks that the DB is available before filling theme_token.
|
||||
if (!defined('MAINTENANCE_MODE')) {
|
||||
$settings['ajaxPageState']['theme_token'] = \Drupal::csrfToken()->get($theme_key);
|
||||
$settings['ajaxPageState']['theme_token'] = \Drupal::csrfToken()
|
||||
->get(\Drupal::theme()->getActiveTheme()->getName());
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue