.../Core/Ajax/AjaxResponseAttachmentsProcessor.php | 19 +++++++++---------- .../Render/HtmlResponseAttachmentsProcessor.php | 22 ++++++---------------- core/modules/big_pipe/src/Render/BigPipe.php | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php index 80bc7f9..7d36b51 100644 --- a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php @@ -105,19 +105,16 @@ public function __construct(AssetResolverInterface $asset_resolver, ConfigFactor /** * {@inheritdoc} */ - public function processAttachments(AttachmentsInterface $response, $ajax_page_state = NULL) { + public function processAttachments(AttachmentsInterface $response) { // @todo Convert to assertion once https://www.drupal.org/node/2408013 lands if (!$response instanceof AjaxResponse) { throw new \InvalidArgumentException('\Drupal\Core\Ajax\AjaxResponse instance expected.'); } - if ($response->getContent() == '{}') { - if (!isset($ajax_page_state)) { - $request = $this->requestStack->getCurrentRequest(); - $ajax_page_state = $request->request->get('ajax_page_state'); - } + $request = $this->requestStack->getCurrentRequest(); - $response->setData($this->buildAttachmentsCommands($response, $ajax_page_state)); + if ($response->getContent() == '{}') { + $response->setData($this->buildAttachmentsCommands($response, $request)); } return $response; @@ -128,13 +125,15 @@ public function processAttachments(AttachmentsInterface $response, $ajax_page_st * * @param \Drupal\Core\Ajax\AjaxResponse $response * The AJAX response to update. - * @param array $ajax_page_state - * The current ajax page state. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object that the AJAX is responding to. * * @return array * An array of commands ready to be returned as JSON. */ - protected function buildAttachmentsCommands(AjaxResponse $response, array $ajax_page_state = NULL) { + protected function buildAttachmentsCommands(AjaxResponse $response, Request $request) { + $ajax_page_state = $request->request->get('ajax_page_state'); + // Aggregate CSS/JS if necessary, but only during normal site operation. $optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess'); $optimize_js = !defined('MAINTENANCE_MODE') && $this->config->get('js.preprocess'); diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php index 93251b5..d77ce4d 100644 --- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php @@ -156,13 +156,7 @@ public function processAttachments(AttachmentsInterface $response) { $attachment_placeholders = $attached['html_response_attachment_placeholders']; unset($attached['html_response_attachment_placeholders']); - // Take Ajax page state into account, to allow for something like Turbolinks - // to be implemented without altering core. - // @see https://github.com/rails/turbolinks/ - // @todo https://www.drupal.org/node/2497115 - Below line is broken due to ->request. - $ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state'); - - $variables = $this->processAssetLibraries($attached, $attachment_placeholders, $ajax_page_state); + $variables = $this->processAssetLibraries($attached, $attachment_placeholders); // Since we can only replace content in the HTML head section if there's a // placeholder for it, we can safely avoid processing the render array if @@ -266,8 +260,6 @@ protected function renderPlaceholders(HtmlResponse $response) { * The attachments to process. * @param array $placeholders * The placeholders that exist in the response. - * @param array $ajax_page_state - * (optional) The ajax page state of the page. * * @return array * An array keyed by asset type, with keys: @@ -275,10 +267,14 @@ protected function renderPlaceholders(HtmlResponse $response) { * - scripts * - scripts_bottom */ - public function processAssetLibraries(array $attached, array $placeholders, array $ajax_page_state = NULL) { + protected function processAssetLibraries(array $attached, array $placeholders) { $all_attached = ['#attached' => $attached]; $assets = AttachedAssets::createFromRenderArray($all_attached); + // Take Ajax page state into account, to allow for something like Turbolinks + // to be implemented without altering core. + // @see https://github.com/rails/turbolinks/ + $ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state'); $assets->setAlreadyLoadedLibraries(isset($ajax_page_state) ? explode(',', $ajax_page_state['libraries']) : []); $variables = []; @@ -295,13 +291,7 @@ public function processAssetLibraries(array $attached, array $placeholders, arra // Optimize JS if necessary, but only during normal site operation. $optimize_js = !defined('MAINTENANCE_MODE') && !\Drupal::state()->get('system.maintenance_mode') && $this->config->get('js.preprocess'); list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, $optimize_js); - } - - if (isset($placeholders['scripts'])) { $variables['scripts'] = $this->jsCollectionRenderer->render($js_assets_header); - } - - if (isset($placeholders['scripts_bottom'])) { $variables['scripts_bottom'] = $this->jsCollectionRenderer->render($js_assets_footer); } diff --git a/core/modules/big_pipe/src/Render/BigPipe.php b/core/modules/big_pipe/src/Render/BigPipe.php index d374d0f..78c758c 100644 --- a/core/modules/big_pipe/src/Render/BigPipe.php +++ b/core/modules/big_pipe/src/Render/BigPipe.php @@ -12,6 +12,12 @@ use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Render\AttachmentsResponseProcessorInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\HttpKernel\KernelEvents; /** * A class that allows sending the main content first, then replace @@ -173,7 +179,17 @@ public function sendContent($content, $attachments, array $placeholders) { $response->addCommand(new ReplaceCommand(sprintf('[data-big-pipe-selector="%s"]', $placeholder), $elements['#markup'])); $response->setAttachments($elements['#attached']); - $this->ajaxResponseAttachmentsProcessor->processAttachments($response, $this->ajaxPageState); + // @todo Clean up. + $request_stack = \Drupal::service('request_stack'); + $master_request = $request_stack->getMasterRequest(); + $request = Request::create($master_request->getUri(), $master_request->getMethod(), $master_request->query->all(), $master_request->cookies->all(), array(), $master_request->server->all()); + $request->headers->set('Accept', 'application/json'); + $request->request->set('ajax_page_state', $this->ajaxPageState); + $request_stack->push($request); + $event = new FilterResponseEvent(\Drupal::service('http_kernel.basic'), $request, HttpKernelInterface::SUB_REQUEST, $response); + \Drupal::service('event_dispatcher')->dispatch(KernelEvents::RESPONSE, $event); + $response = $event->getResponse(); + $request_stack->pop(); // @todo Filter response. $json = $response->getContent();