@@ -19,13 +19,15 @@ public function handle(GenerateEarlyHints $event)
19
19
$ excludeKeywords = array_filter (config ('http3earlyhints.exclude_keywords ' , []));
20
20
$ headers = $ this ->fetchLinkableNodes ($ event ->response )
21
21
->flatMap (function ($ element ) {
22
- [$ src , $ href , $ data , $ rel , $ type ] = $ element ;
22
+ [$ src , $ href , $ data , $ rel , $ type, $ crossorigin , $ as , $ fetchpriority , $ integrity , $ referrerpolicy , $ imagesizes , $ imagesrcset ] = $ element ;
23
23
$ rel = $ type === 'module ' ? 'modulepreload ' : $ rel ;
24
24
25
+ $ attributes = array_filter (@compact ('crossorigin ' , 'as ' , 'fetchpriority ' , 'integrity ' , 'referrerpolicy ' , 'imagesizes ' , 'imagesrcset ' ));
26
+
25
27
return [
26
- $ this ->buildLinkHeader ($ src ?? '' , $ rel ?? null ),
27
- $ this ->buildLinkHeader ($ href ?? '' , $ rel ?? null ),
28
- $ this ->buildLinkHeader ($ data ?? '' , $ rel ?? null ),
28
+ $ this ->buildLinkHeader ($ href ?? '' , $ rel ?? null , $ attributes ),
29
+ $ this ->buildLinkHeader ($ src ?? '' , $ rel ?? null , $ attributes ),
30
+ $ this ->buildLinkHeader ($ data ?? '' , $ rel ?? null , $ attributes ),
29
31
];
30
32
})
31
33
->filter (function (?Link $ value ) use ($ excludeKeywords ) {
@@ -60,13 +62,16 @@ protected function fetchLinkableNodes(Response $response): Collection
60
62
{
61
63
$ crawler = $ this ->getCrawler ($ response );
62
64
63
- return collect ($ crawler ->filter ('link:not([rel*="icon"]):not([rel="canonical"]):not([rel="manifest"]):not([rel="alternate"]), script[src]:not([defer]):not([async]), *:not(picture)>img[src]:not([loading="lazy"]), object[data] ' )->extract (['src ' , 'href ' , 'data ' , 'rel ' , 'type ' ]));
65
+ return collect (
66
+ $ crawler ->filter ('link:not([rel*="icon"]):not([rel="canonical"]):not([rel="manifest"]):not([rel="alternate"]), script[src]:not([defer]):not([async]), *:not(picture)>img[src]:not([loading="lazy"]), object[data] ' )
67
+ ->extract (['src ' , 'href ' , 'data ' , 'rel ' , 'type ' , 'crossorigin ' , 'as ' , 'fetchpriority ' , 'integrity ' , 'referrerpolicy ' , 'imagesizes ' , 'imagesrcset ' ])
68
+ );
64
69
}
65
70
66
71
/**
67
72
* Build out header string based on asset extension.
68
73
*/
69
- private function buildLinkHeader (string $ url , ?string $ rel = 'preload ' ): ?Link
74
+ private function buildLinkHeader (string $ url , ?string $ rel = 'preload ' , ? array $ attributes = [] ): ?Link
70
75
{
71
76
$ linkTypeMap = [
72
77
'.CSS ' => 'style ' ,
@@ -102,12 +107,18 @@ private function buildLinkHeader(string $url, ?string $rel = 'preload'): ?Link
102
107
103
108
$ link = new Link ($ rel , $ url );
104
109
110
+ foreach ($ attributes as $ key => $ value ) {
111
+ $ link = $ link ->withAttribute ($ key , $ value );
112
+ }
113
+
105
114
if ($ rel === 'preconnect ' && $ url ) {
106
115
return $ link ;
107
116
}
108
117
109
- $ link = $ link ->withAttribute ('as ' , $ type ?? 'fetch ' );
110
- if ($ type === 'font ' ) {
118
+ if (empty ($ attributes ['as ' ])) {
119
+ $ link = $ link ->withAttribute ('as ' , $ type ?? 'fetch ' );
120
+ }
121
+ if ($ type === 'font ' && empty ($ attributes ['crossorigin ' ])) {
111
122
$ link = $ link ->withAttribute ('crossorigin ' , true );
112
123
}
113
124
0 commit comments