big_pipe.module 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. /**
  3. * @file
  4. * Adds BigPipe no-JS detection.
  5. */
  6. use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
  7. use Drupal\Core\Routing\RouteMatchInterface;
  8. use Drupal\Core\Url;
  9. /**
  10. * Implements hook_help().
  11. */
  12. function big_pipe_help($route_name, RouteMatchInterface $route_match) {
  13. switch ($route_name) {
  14. case 'help.page.big_pipe':
  15. $output = '<h3>' . t('About') . '</h3>';
  16. $output .= '<p>' . t('The BigPipe module sends pages with dynamic content in a way that allows browsers to show them much faster. For more information, see the <a href=":big_pipe-documentation">online documentation for the BigPipe module</a>.', [':big_pipe-documentation' => 'https://www.drupal.org/documentation/modules/big_pipe']) . '</p>';
  17. $output .= '<h3>' . t('Uses') . '</h3>';
  18. $output .= '<dl>';
  19. $output .= '<dt>' . t('Speeding up your site') . '</dt>';
  20. $output .= '<dd>' . t('The module requires no configuration. Every part of the page contains metadata that allows BigPipe to figure this out on its own.') . '</dd>';
  21. $output .= '</dl>';
  22. return $output;
  23. }
  24. }
  25. /**
  26. * Implements hook_page_attachments().
  27. *
  28. * @see \Drupal\big_pipe\Controller\BigPipeController::setNoJsCookie()
  29. */
  30. function big_pipe_page_attachments(array &$page) {
  31. // Routes that don't use BigPipe also don't need no-JS detection.
  32. if (\Drupal::routeMatch()->getRouteObject()->getOption('_no_big_pipe')) {
  33. return;
  34. }
  35. $request = \Drupal::request();
  36. // BigPipe is only used when there is an actual session, so only add the no-JS
  37. // detection when there actually is a session.
  38. // @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy.
  39. $session_exists = \Drupal::service('session_configuration')->hasSession($request);
  40. $page['#cache']['contexts'][] = 'session.exists';
  41. // Only do the no-JS detection while we don't know if there's no JS support:
  42. // avoid endless redirect loops.
  43. $has_big_pipe_nojs_cookie = $request->cookies->has(BigPipeStrategy::NOJS_COOKIE);
  44. $page['#cache']['contexts'][] = 'cookies:' . BigPipeStrategy::NOJS_COOKIE;
  45. if ($session_exists) {
  46. if (!$has_big_pipe_nojs_cookie) {
  47. // Let server set the BigPipe no-JS cookie.
  48. $page['#attached']['html_head'][] = [
  49. [
  50. // Redirect through a 'Refresh' meta tag if JavaScript is disabled.
  51. '#tag' => 'meta',
  52. '#noscript' => TRUE,
  53. '#attributes' => [
  54. 'http-equiv' => 'Refresh',
  55. 'content' => '0; URL=' . Url::fromRoute('big_pipe.nojs', [], ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
  56. ],
  57. ],
  58. 'big_pipe_detect_nojs',
  59. ];
  60. }
  61. else {
  62. // Let client delete the BigPipe no-JS cookie.
  63. $page['#attached']['html_head'][] = [
  64. [
  65. '#tag' => 'script',
  66. '#value' => 'document.cookie = "' . BigPipeStrategy::NOJS_COOKIE . '=1; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"',
  67. ],
  68. 'big_pipe_detect_js',
  69. ];
  70. }
  71. }
  72. }