1111
1212use Symfony \Component \Asset \Packages ;
1313use Symfony \Component \DependencyInjection \ServiceLocator ;
14+ use Symfony \Contracts \EventDispatcher \EventDispatcherInterface ;
1415use Symfony \Contracts \Service \ResetInterface ;
16+ use Symfony \WebpackEncoreBundle \Event \RenderAssetTagEvent ;
1517
1618/**
1719 * @final
1820 */
1921class TagRenderer implements ResetInterface
2022{
2123 private $ entrypointLookupCollection ;
22-
2324 private $ packages ;
24-
2525 private $ defaultAttributes ;
26+ private $ defaultScriptAttributes ;
27+ private $ defaultLinkAttributes ;
28+ private $ eventDispatcher ;
2629
2730 private $ renderedFiles = [];
2831
2932 public function __construct (
3033 $ entrypointLookupCollection ,
3134 Packages $ packages ,
32- array $ defaultAttributes = []
35+ array $ defaultAttributes = [],
36+ array $ defaultScriptAttributes = [],
37+ array $ defaultLinkAttributes = [],
38+ EventDispatcherInterface $ eventDispatcher = null
3339 ) {
3440 if ($ entrypointLookupCollection instanceof EntrypointLookupInterface) {
3541 @trigger_error (sprintf ('The "$entrypointLookupCollection" argument in method "%s()" must be an instance of EntrypointLookupCollection. ' , __METHOD__ ), E_USER_DEPRECATED );
@@ -47,24 +53,39 @@ public function __construct(
4753
4854 $ this ->packages = $ packages ;
4955 $ this ->defaultAttributes = $ defaultAttributes ;
56+ $ this ->defaultScriptAttributes = $ defaultScriptAttributes ;
57+ $ this ->defaultLinkAttributes = $ defaultLinkAttributes ;
58+ $ this ->eventDispatcher = $ eventDispatcher ;
5059
5160 $ this ->reset ();
5261 }
5362
54- public function renderWebpackScriptTags (string $ entryName , string $ packageName = null , string $ entrypointName = ' _default ' ): string
63+ public function renderWebpackScriptTags (string $ entryName , string $ packageName = null , string $ entrypointName = null , array $ extraAttributes = [] ): string
5564 {
65+ $ entrypointName = $ entrypointName ?: '_default ' ;
5666 $ scriptTags = [];
5767 $ entryPointLookup = $ this ->getEntrypointLookup ($ entrypointName );
5868 $ integrityHashes = ($ entryPointLookup instanceof IntegrityDataProviderInterface) ? $ entryPointLookup ->getIntegrityData () : [];
5969
6070 foreach ($ entryPointLookup ->getJavaScriptFiles ($ entryName ) as $ filename ) {
61- $ attributes = $ this -> defaultAttributes ;
71+ $ attributes = [] ;
6272 $ attributes ['src ' ] = $ this ->getAssetPath ($ filename , $ packageName );
73+ $ attributes = array_merge ($ attributes , $ this ->defaultAttributes , $ this ->defaultScriptAttributes , $ extraAttributes );
6374
6475 if (isset ($ integrityHashes [$ filename ])) {
6576 $ attributes ['integrity ' ] = $ integrityHashes [$ filename ];
6677 }
6778
79+ $ event = new RenderAssetTagEvent (
80+ RenderAssetTagEvent::TYPE_SCRIPT ,
81+ $ attributes ['src ' ],
82+ $ attributes
83+ );
84+ if (null !== $ this ->eventDispatcher ) {
85+ $ event = $ this ->eventDispatcher ->dispatch ($ event );
86+ }
87+ $ attributes = $ event ->getAttributes ();
88+
6889 $ scriptTags [] = sprintf (
6990 '<script %s></script> ' ,
7091 $ this ->convertArrayToAttributes ($ attributes )
@@ -76,21 +97,33 @@ public function renderWebpackScriptTags(string $entryName, string $packageName =
7697 return implode ('' , $ scriptTags );
7798 }
7899
79- public function renderWebpackLinkTags (string $ entryName , string $ packageName = null , string $ entrypointName = ' _default ' ): string
100+ public function renderWebpackLinkTags (string $ entryName , string $ packageName = null , string $ entrypointName = null , array $ extraAttributes = [] ): string
80101 {
102+ $ entrypointName = $ entrypointName ?: '_default ' ;
81103 $ scriptTags = [];
82104 $ entryPointLookup = $ this ->getEntrypointLookup ($ entrypointName );
83105 $ integrityHashes = ($ entryPointLookup instanceof IntegrityDataProviderInterface) ? $ entryPointLookup ->getIntegrityData () : [];
84106
85107 foreach ($ entryPointLookup ->getCssFiles ($ entryName ) as $ filename ) {
86- $ attributes = $ this -> defaultAttributes ;
108+ $ attributes = [] ;
87109 $ attributes ['rel ' ] = 'stylesheet ' ;
88110 $ attributes ['href ' ] = $ this ->getAssetPath ($ filename , $ packageName );
111+ $ attributes = array_merge ($ attributes , $ this ->defaultAttributes , $ this ->defaultLinkAttributes , $ extraAttributes );
89112
90113 if (isset ($ integrityHashes [$ filename ])) {
91114 $ attributes ['integrity ' ] = $ integrityHashes [$ filename ];
92115 }
93116
117+ $ event = new RenderAssetTagEvent (
118+ RenderAssetTagEvent::TYPE_LINK ,
119+ $ attributes ['href ' ],
120+ $ attributes
121+ );
122+ if (null !== $ this ->eventDispatcher ) {
123+ $ this ->eventDispatcher ->dispatch ($ event );
124+ }
125+ $ attributes = $ event ->getAttributes ();
126+
94127 $ scriptTags [] = sprintf (
95128 '<link %s> ' ,
96129 $ this ->convertArrayToAttributes ($ attributes )
@@ -146,6 +179,10 @@ private function convertArrayToAttributes(array $attributesMap): string
146179 {
147180 return implode (' ' , array_map (
148181 function ($ key , $ value ) {
182+ // allows for things like defer: true to only render "defer"
183+ if ($ value === true ) {
184+ return $ key ;
185+ }
149186 return sprintf ('%s="%s" ' , $ key , htmlentities ($ value ));
150187 },
151188 array_keys ($ attributesMap ),
0 commit comments