@@ -235,11 +235,16 @@ var CSSLoaderPlugin;
235235 }
236236 CSSPlugin . prototype . load = function ( name , req , load , config ) {
237237 config = config || { } ;
238+ var myConfig = config [ 'vs/css' ] || { } ;
239+ if ( myConfig . inlineResources ) {
240+ global . inlineResources = true ;
241+ }
238242 var cssUrl = req . toUrl ( name + '.css' ) ;
239243 this . cssLoader . load ( name , cssUrl , function ( contents ) {
240244 // Contents has the CSS file contents if we are in a build
241245 if ( config . isBuild ) {
242246 CSSPlugin . BUILD_MAP [ name ] = contents ;
247+ CSSPlugin . BUILD_PATH_MAP [ name ] = cssUrl ;
243248 }
244249 load ( { } ) ;
245250 } , function ( err ) {
@@ -257,7 +262,8 @@ var CSSLoaderPlugin;
257262 global . cssPluginEntryPoints [ entryPoint ] = global . cssPluginEntryPoints [ entryPoint ] || [ ] ;
258263 global . cssPluginEntryPoints [ entryPoint ] . push ( {
259264 moduleName : moduleName ,
260- contents : CSSPlugin . BUILD_MAP [ moduleName ]
265+ contents : CSSPlugin . BUILD_MAP [ moduleName ] ,
266+ fsPath : CSSPlugin . BUILD_PATH_MAP [ moduleName ] ,
261267 } ) ;
262268 write . asModule ( pluginName + '!' + moduleName , 'define([\'vs/css!' + entryPoint + '\'], {});' ) ;
263269 } ;
@@ -270,12 +276,21 @@ var CSSLoaderPlugin;
270276 ' *--------------------------------------------------------*/'
271277 ] , entries = global . cssPluginEntryPoints [ moduleName ] ;
272278 for ( var i = 0 ; i < entries . length ; i ++ ) {
273- contents . push ( Utilities . rewriteUrls ( entries [ i ] . moduleName , moduleName , entries [ i ] . contents ) ) ;
279+ if ( global . inlineResources ) {
280+ contents . push ( Utilities . rewriteOrInlineUrls ( entries [ i ] . fsPath , entries [ i ] . moduleName , moduleName , entries [ i ] . contents ) ) ;
281+ }
282+ else {
283+ contents . push ( Utilities . rewriteUrls ( entries [ i ] . moduleName , moduleName , entries [ i ] . contents ) ) ;
284+ }
274285 }
275286 write ( fileName , contents . join ( '\r\n' ) ) ;
276287 }
277288 } ;
289+ CSSPlugin . prototype . getInlinedResources = function ( ) {
290+ return global . cssInlinedResources || [ ] ;
291+ } ;
278292 CSSPlugin . BUILD_MAP = { } ;
293+ CSSPlugin . BUILD_PATH_MAP = { } ;
279294 return CSSPlugin ;
280295 } ( ) ) ;
281296 CSSLoaderPlugin . CSSPlugin = CSSPlugin ;
@@ -381,7 +396,7 @@ var CSSLoaderPlugin;
381396 }
382397 return result + toPath ;
383398 } ;
384- Utilities . rewriteUrls = function ( originalFile , newFile , contents ) {
399+ Utilities . _replaceURL = function ( contents , replacer ) {
385400 // Use ")" as the terminator as quotes are oftentimes not used at all
386401 return contents . replace ( / u r l \( \s * ( [ ^ \) ] + ) \s * \) ? / g, function ( _ ) {
387402 var matches = [ ] ;
@@ -402,12 +417,54 @@ var CSSLoaderPlugin;
402417 url = url . substring ( 0 , url . length - 1 ) ;
403418 }
404419 if ( ! Utilities . startsWith ( url , 'data:' ) && ! Utilities . startsWith ( url , 'http://' ) && ! Utilities . startsWith ( url , 'https://' ) ) {
405- var absoluteUrl = Utilities . joinPaths ( Utilities . pathOf ( originalFile ) , url ) ;
406- url = Utilities . relativePath ( newFile , absoluteUrl ) ;
420+ url = replacer ( url ) ;
407421 }
408422 return 'url(' + url + ')' ;
409423 } ) ;
410424 } ;
425+ Utilities . rewriteUrls = function ( originalFile , newFile , contents ) {
426+ return this . _replaceURL ( contents , function ( url ) {
427+ var absoluteUrl = Utilities . joinPaths ( Utilities . pathOf ( originalFile ) , url ) ;
428+ return Utilities . relativePath ( newFile , absoluteUrl ) ;
429+ } ) ;
430+ } ;
431+ Utilities . rewriteOrInlineUrls = function ( originalFileFSPath , originalFile , newFile , contents ) {
432+ var fs = require . nodeRequire ( 'fs' ) ;
433+ var path = require . nodeRequire ( 'path' ) ;
434+ return this . _replaceURL ( contents , function ( url ) {
435+ if ( / \. ( s v g | p n g ) $ / . test ( url ) ) {
436+ var fsPath = path . join ( path . dirname ( originalFileFSPath ) , url ) ;
437+ var fileContents = fs . readFileSync ( fsPath ) ;
438+ if ( fileContents . length < 3000 ) {
439+ global . cssInlinedResources = global . cssInlinedResources || [ ] ;
440+ var normalizedFSPath = fsPath . replace ( / \\ / g, '/' ) ;
441+ if ( global . cssInlinedResources . indexOf ( normalizedFSPath ) >= 0 ) {
442+ console . warn ( 'CSS INLINING IMAGE AT ' + fsPath + ' MORE THAN ONCE. CONSIDER CONSOLIDATING CSS RULES' ) ;
443+ }
444+ global . cssInlinedResources . push ( normalizedFSPath ) ;
445+ var MIME = / \. s v g $ / . test ( url ) ? 'image/svg+xml' : 'image/png' ;
446+ var DATA = ';base64,' + fileContents . toString ( 'base64' ) ;
447+ if ( / \. s v g $ / . test ( url ) ) {
448+ // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
449+ var newText = fileContents . toString ( )
450+ . replace ( / " / g, '\'' )
451+ . replace ( / < / g, '%3C' )
452+ . replace ( / > / g, '%3E' )
453+ . replace ( / & / g, '%26' )
454+ . replace ( / # / g, '%23' )
455+ . replace ( / \s + / g, ' ' ) ;
456+ var encodedData = ',' + newText ;
457+ if ( encodedData . length < DATA . length ) {
458+ DATA = encodedData ;
459+ }
460+ }
461+ return '"data:' + MIME + DATA + '"' ;
462+ }
463+ }
464+ var absoluteUrl = Utilities . joinPaths ( Utilities . pathOf ( originalFile ) , url ) ;
465+ return Utilities . relativePath ( newFile , absoluteUrl ) ;
466+ } ) ;
467+ } ;
411468 return Utilities ;
412469 } ( ) ) ;
413470 CSSLoaderPlugin . Utilities = Utilities ;
0 commit comments