@@ -83,58 +83,74 @@ class CspHtmlWebpackPlugin {
8383 . join ( '; ' ) ;
8484 }
8585
86+ /**
87+ * Processes HtmlWebpackPlugin's html data adding the CSP defined
88+ * @param htmlPluginData
89+ * @param compileCb
90+ */
91+ processCsp ( htmlPluginData , compileCb ) {
92+ const $ = cheerio . load ( htmlPluginData . html , {
93+ decodeEntities : false
94+ } ) ;
95+
96+ // if not enabled, remove the empty tag
97+ if ( ! this . isEnabled ( htmlPluginData ) ) {
98+ $ ( 'meta[http-equiv="Content-Security-Policy"]' ) . remove ( ) ;
99+
100+ // eslint-disable-next-line no-param-reassign
101+ htmlPluginData . html = $ . html ( ) ;
102+
103+ return compileCb ( null , htmlPluginData ) ;
104+ }
105+
106+ const policyObj = JSON . parse ( JSON . stringify ( this . policy ) ) ;
107+
108+ const inlineSrc = $ ( 'script:not([src])' )
109+ . map ( ( i , element ) => this . hash ( $ ( element ) . html ( ) ) )
110+ . get ( ) ;
111+ const inlineStyle = $ ( 'style:not([href])' )
112+ . map ( ( i , element ) => this . hash ( $ ( element ) . html ( ) ) )
113+ . get ( ) ;
114+
115+ // Wrapped in flatten([]) to handle both when policy is a string and an array
116+ policyObj [ 'script-src' ] = flatten ( [ policyObj [ 'script-src' ] ] ) . concat (
117+ inlineSrc
118+ ) ;
119+ policyObj [ 'style-src' ] = flatten ( [ policyObj [ 'style-src' ] ] ) . concat (
120+ inlineStyle
121+ ) ;
122+
123+ $ ( 'meta[http-equiv="Content-Security-Policy"]' ) . attr (
124+ 'content' ,
125+ this . buildPolicy ( policyObj )
126+ ) ;
127+
128+ // eslint-disable-next-line no-param-reassign
129+ htmlPluginData . html = $ . html ( ) ;
130+
131+ return compileCb ( null , htmlPluginData ) ;
132+ }
133+
86134 /**
87135 * Hooks into webpack to collect assets and hash them, build the policy, and add it into our HTML template
88136 * @param compiler
89137 */
90138 apply ( compiler ) {
91- compiler . plugin ( 'compilation' , compilation => {
92- compilation . plugin (
93- 'html-webpack-plugin-after-html-processing' ,
94- ( htmlPluginData , compileCb ) => {
95- const $ = cheerio . load ( htmlPluginData . html , {
96- decodeEntities : false
97- } ) ;
98-
99- // if not enabled, remove the empty tag
100- if ( ! this . isEnabled ( htmlPluginData ) ) {
101- $ ( 'meta[http-equiv="Content-Security-Policy"]' ) . remove ( ) ;
102-
103- // eslint-disable-next-line no-param-reassign
104- htmlPluginData . html = $ . html ( ) ;
105-
106- return compileCb ( null , htmlPluginData ) ;
107- }
108-
109- const policyObj = JSON . parse ( JSON . stringify ( this . policy ) ) ;
110-
111- const inlineSrc = $ ( 'script:not([src])' )
112- . map ( ( i , element ) => this . hash ( $ ( element ) . html ( ) ) )
113- . get ( ) ;
114- const inlineStyle = $ ( 'style:not([href])' )
115- . map ( ( i , element ) => this . hash ( $ ( element ) . html ( ) ) )
116- . get ( ) ;
117-
118- // Wrapped in flatten([]) to handle both when policy is a string and an array
119- policyObj [ 'script-src' ] = flatten ( [ policyObj [ 'script-src' ] ] ) . concat (
120- inlineSrc
121- ) ;
122- policyObj [ 'style-src' ] = flatten ( [ policyObj [ 'style-src' ] ] ) . concat (
123- inlineStyle
124- ) ;
125-
126- $ ( 'meta[http-equiv="Content-Security-Policy"]' ) . attr (
127- 'content' ,
128- this . buildPolicy ( policyObj )
129- ) ;
130-
131- // eslint-disable-next-line no-param-reassign
132- htmlPluginData . html = $ . html ( ) ;
133-
134- return compileCb ( null , htmlPluginData ) ;
135- }
136- ) ;
137- } ) ;
139+ if ( compiler . hooks ) {
140+ compiler . hooks . compilation . tap ( 'CspHtmlWebpackPlugin' , compilation => {
141+ compilation . hooks . htmlWebpackPluginAfterHtmlProcessing . tapAsync (
142+ 'CspHtmlWebpackPlugin' ,
143+ this . processCsp . bind ( this )
144+ ) ;
145+ } ) ;
146+ } else {
147+ compiler . plugin ( 'compilation' , compilation => {
148+ compilation . plugin (
149+ 'html-webpack-plugin-after-html-processing' ,
150+ this . processCsp . bind ( this )
151+ ) ;
152+ } ) ;
153+ }
138154 }
139155}
140156
0 commit comments