8.5.x big_pipe.module big_pipe_page_attachments(array &$page)
8.1.x big_pipe.module big_pipe_page_attachments(array &$page)
8.2.x big_pipe.module big_pipe_page_attachments(array &$page)
8.3.x big_pipe.module big_pipe_page_attachments(array &$page)
8.4.x big_pipe.module big_pipe_page_attachments(array &$page)
8.6.x big_pipe.module big_pipe_page_attachments(array &$page)

Implements hook_page_attachments().

See also

\Drupal\big_pipe\Controller\BigPipeController::setNoJsCookie()

File

core/modules/big_pipe/big_pipe.module, line 35
Adds BigPipe no-JS detection.

Code

function big_pipe_page_attachments(array &$page) {

  // Routes that don't use BigPipe also don't need no-JS detection.
  if (\Drupal::routeMatch()
    ->getRouteObject()
    ->getOption('_no_big_pipe')) {
    return;
  }
  $request = \Drupal::request();

  // BigPipe is only used when there is an actual session, so only add the no-JS
  // detection when there actually is a session.
  // @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy.
  $session_exists = \Drupal::service('session_configuration')
    ->hasSession($request);
  $page['#cache']['contexts'][] = 'session.exists';

  // Only do the no-JS detection while we don't know if there's no JS support:
  // avoid endless redirect loops.
  $has_big_pipe_nojs_cookie = $request->cookies
    ->has(BigPipeStrategy::NOJS_COOKIE);
  $page['#cache']['contexts'][] = 'cookies:' . BigPipeStrategy::NOJS_COOKIE;
  if ($session_exists) {
    if (!$has_big_pipe_nojs_cookie) {

      // Let server set the BigPipe no-JS cookie.
      $page['#attached']['html_head'][] = [
        [
          // Redirect through a 'Refresh' meta tag if JavaScript is disabled.
          '#tag' => 'meta',
          '#noscript' => TRUE,
          '#attributes' => [
            'http-equiv' => 'Refresh',
            // @todo: Switch to Url::fromRoute() once https://www.drupal.org/node/2589967 is resolved.
            'content' => '0; URL=' . Url::fromUri('internal:/big_pipe/no-js', [
              'query' => \Drupal::service('redirect.destination')
                ->getAsArray(),
            ])
              ->toString(),
          ],
        ],
        'big_pipe_detect_nojs',
      ];
    }
    else {

      // Let client delete the BigPipe no-JS cookie.
      $page['#attached']['html_head'][] = [
        [
          '#tag' => 'script',
          '#value' => 'document.cookie = "' . BigPipeStrategy::NOJS_COOKIE . '=1; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"',
        ],
        'big_pipe_detect_js',
      ];
    }
  }
}