@@ -143,8 +143,15 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
143143 } ) ;
144144 } )
145145 . then ( function ( html ) {
146- // Add the stylesheets, scripts and so on to the resulting html
147- return self . postProcessHtml ( html , assets ) ;
146+ // Prepare script and link tags
147+ var assetTags = self . generateAssetTags ( assets ) ;
148+ var pluginArgs = { head : assetTags . head , body : assetTags . body , plugin : self , chunks : chunks , outputName : self . childCompilationOutputName } ;
149+ // Allow plugins to change the assetTag definitions
150+ return applyPluginsAsyncWaterfall ( 'html-webpack-plugin-alter-asset-tags' , pluginArgs )
151+ . then ( function ( ) {
152+ // Add the stylesheets, scripts and so on to the resulting html
153+ return self . postProcessHtml ( html , assets , { body : pluginArgs . body , head : pluginArgs . head } ) ;
154+ } ) ;
148155 } )
149156 // Allow plugins to change the html after assets are injected
150157 . then ( function ( html ) {
@@ -259,7 +266,7 @@ HtmlWebpackPlugin.prototype.executeTemplate = function (templateFunction, chunks
259266 *
260267 * Returns a promise
261268 */
262- HtmlWebpackPlugin . prototype . postProcessHtml = function ( html , assets ) {
269+ HtmlWebpackPlugin . prototype . postProcessHtml = function ( html , assets , assetTags ) {
263270 var self = this ;
264271 if ( typeof html !== 'string' ) {
265272 return Promise . reject ( 'Expected html to be a string but got ' + JSON . stringify ( html ) ) ;
@@ -268,7 +275,7 @@ HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets) {
268275 // Inject
269276 . then ( function ( ) {
270277 if ( self . options . inject ) {
271- return self . injectAssetsIntoHtml ( html , assets ) ;
278+ return self . injectAssetsIntoHtml ( html , assets , assetTags ) ;
272279 } else {
273280 return html ;
274281 }
@@ -449,27 +456,45 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function (compilation, chu
449456/**
450457 * Injects the assets into the given html string
451458 */
452- HtmlWebpackPlugin . prototype . injectAssetsIntoHtml = function ( html , assets ) {
459+ HtmlWebpackPlugin . prototype . generateAssetTags = function ( assets ) {
453460 // Turn script files into script tags
454461 var scripts = assets . js . map ( function ( scriptPath ) {
455- return '<script type="text/javascript" src="' + scriptPath + '"></script>' ;
462+ return {
463+ tagName : 'script' ,
464+ closeTag : true ,
465+ attributes : {
466+ type : 'text/javascript' ,
467+ src : scriptPath
468+ }
469+ } ;
456470 } ) ;
457471 // Make tags self-closing in case of xhtml
458- var xhtml = this . options . xhtml ? '/' : '' ;
472+ var selfClosingTag = ! ! this . options . xhtml ;
459473 // Turn css files into link tags
460474 var styles = assets . css . map ( function ( stylePath ) {
461- return '<link href="' + stylePath + '" rel="stylesheet"' + xhtml + '>' ;
475+ return {
476+ tagName : 'link' ,
477+ selfClosingTag : selfClosingTag ,
478+ attributes : {
479+ href : stylePath ,
480+ rel : 'stylesheet'
481+ }
482+ } ;
462483 } ) ;
463- // Injections
464- var htmlRegExp = / ( < h t m l [ ^ > ] * > ) / i;
484+ // Injection targets
465485 var head = [ ] ;
466- var headRegExp = / ( < \/ h e a d > ) / i;
467486 var body = [ ] ;
468- var bodyRegExp = / ( < \/ b o d y > ) / i;
469487
470488 // If there is a favicon present, add it to the head
471489 if ( assets . favicon ) {
472- head . push ( '<link rel="shortcut icon" href="' + assets . favicon + '"' + xhtml + '>' ) ;
490+ head . push ( {
491+ tagName : 'link' ,
492+ selfClosingTag : selfClosingTag ,
493+ attributes : {
494+ rel : 'shortcut icon' ,
495+ href : assets . favicon
496+ }
497+ } ) ;
473498 }
474499 // Add styles to the head
475500 head = head . concat ( styles ) ;
@@ -479,6 +504,18 @@ HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets) {
479504 } else {
480505 body = body . concat ( scripts ) ;
481506 }
507+ return { head : head , body : body } ;
508+ } ;
509+
510+ /**
511+ * Injects the assets into the given html string
512+ */
513+ HtmlWebpackPlugin . prototype . injectAssetsIntoHtml = function ( html , assets , assetTags ) {
514+ var htmlRegExp = / ( < h t m l [ ^ > ] * > ) / i;
515+ var headRegExp = / ( < \/ h e a d > ) / i;
516+ var bodyRegExp = / ( < \/ b o d y > ) / i;
517+ var body = assetTags . body . map ( this . createHtmlTag ) ;
518+ var head = assetTags . head . map ( this . createHtmlTag ) ;
482519
483520 if ( body . length ) {
484521 if ( bodyRegExp . test ( html ) ) {
@@ -533,6 +570,18 @@ HtmlWebpackPlugin.prototype.appendHash = function (url, hash) {
533570 return url + ( url . indexOf ( '?' ) === - 1 ? '?' : '&' ) + hash ;
534571} ;
535572
573+ /**
574+ * Turn a tag definition into a html string
575+ */
576+ HtmlWebpackPlugin . prototype . createHtmlTag = function ( tagDefinition ) {
577+ var attributes = Object . keys ( tagDefinition . attributes || { } ) . map ( function ( attributeName ) {
578+ return attributeName + '="' + tagDefinition . attributes [ attributeName ] + '"' ;
579+ } ) ;
580+ return '<' + [ tagDefinition . tagName ] . concat ( attributes ) . join ( ' ' ) + ( tagDefinition . selfClosingTag ? '/' : '' ) + '>' +
581+ ( tagDefinition . innerHTML || '' ) +
582+ ( tagDefinition . closeTag ? '</' + tagDefinition . tagName + '>' : '' ) ;
583+ } ;
584+
536585/**
537586 * Helper to return the absolute template path with a fallback loader
538587 */
0 commit comments