f9525a1519be42dda92ec00c459152d077ded20d
[yaffs-website] / web / modules / contrib / http2_server_push / src / Asset / JsCollectionRenderer.php
1 <?php
2
3 namespace Drupal\http2_server_push\Asset;
4
5 use Drupal\Core\Asset\AssetCollectionRendererInterface;
6 use Symfony\Component\HttpFoundation\RequestStack;
7
8 /**
9  * Decorates the JS collection renderer service, adds Server Push.
10  *
11  * @see \Drupal\Core\Asset\JsCollectionRenderer
12  * @see \Drupal\http2_server_push\Render\HtmlResponseAttachmentsProcessor
13  */
14 class JsCollectionRenderer implements AssetCollectionRendererInterface {
15
16   use AssetHtmlTagRenderElementTrait;
17
18   /**
19    * The decorated JS collection renderer.
20    *
21    * @var \Drupal\Core\Asset\AssetCollectionRendererInterface
22    */
23   protected $jsCollectionRenderer;
24
25   /**
26    * The request stack.
27    *
28    * @var \Symfony\Component\HttpFoundation\RequestStack
29    */
30   protected $requestStack;
31
32   /**
33    * Constructs a JsCollectionRenderer.
34    *
35    * @param \Drupal\Core\Asset\AssetCollectionRendererInterface $js_collection_renderer
36    *   The decorated JS collection renderer.
37    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
38    *   The request stack.
39    */
40   public function __construct(AssetCollectionRendererInterface $js_collection_renderer, RequestStack $request_stack) {
41     $this->jsCollectionRenderer = $js_collection_renderer;
42     $this->requestStack = $request_stack;
43   }
44
45   /**
46    * {@inheritdoc}
47    */
48   public function render(array $js_assets) {
49     $elements = $this->jsCollectionRenderer->render($js_assets);
50
51     $request = $this->requestStack->getCurrentRequest();
52     $link_headers = $request->attributes->get('http2_server_push_link_headers', []);
53     foreach ($elements as &$element) {
54       if (!static::isScript($element)) {
55         continue;
56       }
57
58       // Locally served JS files that are sent to all browsers can be pushed.
59       if (isset($element['#attributes']['src']) && static::hasRootRelativeUrl($element, 'src') && static::isUnconditional($element)) {
60         $link_header_value = '<' . $element['#attributes']['src'] . '>; rel=preload; as=script';
61         $link_headers[] = $link_header_value;
62
63         // @todo When this is moved into Drupal core, consider allowing bubbling
64         // of bubbleable metadata from the return value of
65         // \Drupal\Core\Render\HtmlResponseAttachmentsProcessor::processAssetLibraries
66         // so this line of code can work, which would mean we would no longer
67         // need to use request attributes. (The problem is that a key assumption
68         // is that rendering set of asset libraries to HTML that loads CSS/JS,
69         // no further attachment bubbling happens. That's a fine assumption, but
70         // this module is the first and sole exception.)
71         //$element['#attached']['http_header'][] = ['Link', $link_header_value];
72       }
73     }
74     $request->attributes->set('http2_server_push_link_headers', $link_headers);
75     return $elements;
76   }
77
78 }