@@ -83,7 +83,7 @@ const PLUGIN_NAME: string = 'localization';
8383
8484const PLACEHOLDER_PREFIX : string = Constants . STRING_PLACEHOLDER_PREFIX ;
8585const PLACEHOLDER_REGEX : RegExp = new RegExp (
86- `${ PLACEHOLDER_PREFIX } (\\+(?: [^+]){2,})? \\+_(\\d+)` ,
86+ `${ PLACEHOLDER_PREFIX } (\\+[^+]+) \\+_(\\d+)` ,
8787 'g'
8888) ;
8989
@@ -301,7 +301,6 @@ export class LocalizationPlugin implements Webpack.Plugin {
301301 const localizedChunkAssets : ILocaleElementMap = { } ;
302302 let alreadyProcessedAFileInThisChunk : boolean = false ;
303303 for ( const chunkFileName of chunk . files ) {
304- debugger ;
305304 if (
306305 chunkFileName . indexOf ( this . _localeNamePlaceholder . value ) !== - 1 && // Ensure this is expected to be localized
307306 chunkFileName . endsWith ( '.js' ) && // Ensure this is a JS file
@@ -441,7 +440,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
441440 ) : Map < string , IProcessAssetResult > {
442441 const assetSource : string = asset . source ( ) ;
443442
444- const getJsonpFn : ( ) => ( ( locale : string ) => string ) = ( ) => {
443+ const getJsonpFn : ( ) => ( ( locale : string , chunkIdToken : string | undefined ) => string ) = ( ) => {
445444 const idsWithStrings : Set < string > = new Set < string > ( ) ;
446445 const idsWithoutStrings : Set < string > = new Set < string > ( ) ;
447446
@@ -474,8 +473,8 @@ export class LocalizationPlugin implements Webpack.Plugin {
474473 chunkMapping [ idWithoutStrings ] = 1 ;
475474 }
476475
477- return ( locale : string ) => {
478- return `(${ JSON . stringify ( [ locale , this . _noStringsLocaleName ] ) } )[${ JSON . stringify ( chunkMapping ) } [chunkId ]]` ;
476+ return ( locale : string , chunkIdToken : string ) => {
477+ return `(${ JSON . stringify ( [ locale , this . _noStringsLocaleName ] ) } )[${ JSON . stringify ( chunkMapping ) } [${ chunkIdToken } ]]` ;
479478 }
480479 }
481480 } ;
@@ -519,7 +518,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
519518 private _processString (
520519 source : string ,
521520 initialSize : number ,
522- jsonpFunction : ( ( locale : string ) => string ) | undefined = undefined
521+ jsonpFunction : ( ( locale : string , token : string | undefined ) => string ) | undefined = undefined
523522 ) : IProcessStringResultSet {
524523 if ( ! jsonpFunction ) {
525524 jsonpFunction = ( ) => { throw new Error ( 'JSONP placeholder replacement is unsupported in this context' ) } ;
@@ -545,8 +544,9 @@ export class LocalizationPlugin implements Webpack.Plugin {
545544
546545 interface IDynamicReconstructionElement extends IReconstructionElement {
547546 kind : 'dynamic' ;
548- valueFn : ( locale : string ) => string ;
547+ valueFn : ( locale : string , token : string | undefined ) => string ;
549548 size : number ;
549+ token ?: string ;
550550 }
551551
552552 const issues : string [ ] = [ ] ;
@@ -561,7 +561,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
561561 } ;
562562 reconstructionSeries . push ( staticElement ) ;
563563
564- const [ placeholder , capturedQuotemark , placeholderSerialNumber ] = regexResult ;
564+ const [ placeholder , capturedToken , placeholderSerialNumber ] = regexResult ;
565565
566566 let localizedReconstructionElement : IReconstructionElement ;
567567 if ( placeholderSerialNumber === this . _localeNamePlaceholder . suffix ) {
@@ -575,7 +575,8 @@ export class LocalizationPlugin implements Webpack.Plugin {
575575 const dynamicElement : IDynamicReconstructionElement = {
576576 kind : 'dynamic' ,
577577 valueFn : jsonpFunction ,
578- size : placeholder . length
578+ size : placeholder . length ,
579+ token : capturedToken . substr ( 1 )
579580 } ;
580581 localizedReconstructionElement = dynamicElement ;
581582 } else {
@@ -588,7 +589,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
588589 } ;
589590 localizedReconstructionElement = brokenLocalizedElement ;
590591 } else {
591- const quotemark : string = capturedQuotemark . substr ( 1 , ( capturedQuotemark . length - 1 ) / 2 ) ;
592+ const quotemark : string = capturedToken . substr ( 1 , ( capturedToken . length - 1 ) / 2 ) ;
592593 const localizedElement : ILocalizedReconstructionElement = {
593594 kind : 'localized' ,
594595 values : values ,
@@ -655,7 +656,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
655656
656657 case 'dynamic' : {
657658 const dynamicElement : IDynamicReconstructionElement = element as IDynamicReconstructionElement ;
658- const newValue : string = dynamicElement . valueFn ( locale ) ;
659+ const newValue : string = dynamicElement . valueFn ( locale , dynamicElement . token ) ;
659660 reconstruction . push ( newValue ) ;
660661 sizeDiff += ( newValue . length - dynamicElement . size ) ;
661662 break ;
@@ -720,7 +721,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
720721 this . _localeNamePlaceholder = this . _getPlaceholderString ( ) ;
721722
722723 // Create a special placeholder for the [locale] token in the JSONP script src function
723- this . _jsonpScriptNameLocalePlaceholder = this . _getPlaceholderString ( ) ;
724+ this . _jsonpScriptNameLocalePlaceholder = this . _getPlaceholderString ( 'chunkId' ) ;
724725
725726 // START options.localizedData.passthroughLocale
726727 if ( this . _options . localizedData . passthroughLocale ) {
@@ -851,10 +852,17 @@ export class LocalizationPlugin implements Webpack.Plugin {
851852 return errors ;
852853 }
853854
854- private _getPlaceholderString ( ) : IStringPlaceholder {
855+ /**
856+ * @param token - Use this as a value that may be escaped or minified.
857+ */
858+ private _getPlaceholderString ( token : string = '""' ) : IStringPlaceholder {
859+ if ( token . match ( / \+ / ) ) {
860+ throw new Error ( 'The token may not contain a + symbol.' )
861+ }
862+
855863 const suffix : string = ( this . _stringPlaceholderCounter ++ ) . toString ( ) ;
856864 return {
857- value : `${ Constants . STRING_PLACEHOLDER_PREFIX } +"" +_${ suffix } ` ,
865+ value : `${ Constants . STRING_PLACEHOLDER_PREFIX } +${ token } +_${ suffix } ` ,
858866 suffix : suffix
859867 } ;
860868 }
0 commit comments