2018-02-14 13:54:00 -05:00
/ * *
* @license
* Copyright Google Inc . All Rights Reserved .
*
* Use of this source code is governed by an MIT - style license that can be
* found in the LICENSE file at https : //angular.io/license
* /
2018-12-13 18:51:47 -05:00
import { AttributeMarker } from '@angular/compiler/src/core' ;
2018-10-05 17:12:13 -04:00
import { setup } from '@angular/compiler/test/aot/test_util' ;
2018-10-18 13:08:51 -04:00
2018-11-29 19:21:16 -05:00
import { DEFAULT_INTERPOLATION_CONFIG , InterpolationConfig } from '../../../compiler/src/compiler' ;
2018-10-18 13:08:51 -04:00
import { decimalDigest } from '../../../compiler/src/i18n/digest' ;
import { extractMessages } from '../../../compiler/src/i18n/extractor_merger' ;
import { HtmlParser } from '../../../compiler/src/ml_parser/html_parser' ;
2018-02-14 13:54:00 -05:00
import { compile , expectEmit } from './mock_compile' ;
2018-10-18 13:08:51 -04:00
const angularFiles = setup ( {
compileAngular : false ,
compileFakeCore : true ,
compileAnimations : false ,
} ) ;
const htmlParser = new HtmlParser ( ) ;
2019-07-31 05:52:38 -04:00
// TODO: update translation extraction RegExp to support `$localize` tags.
2019-02-25 15:42:50 -05:00
const EXTRACT_GENERATED_TRANSLATIONS_REGEXP =
/const\s*(.*?)\s*=\s*goog\.getMsg\("(.*?)",?\s*(.*?)\)/g ;
2018-10-18 13:08:51 -04:00
const diff = ( a : Set < string > , b : Set < string > ) : Set < string > = >
new Set ( [ . . . Array . from ( a ) ] . filter ( x = > ! b . has ( x ) ) ) ;
2019-06-14 06:19:09 -04:00
const extract = ( from : string , regex : any , transformFn : ( match : any [ ] , state : Set < any > ) = > any ) = > {
const result = new Set < any > ( ) ;
let item ;
while ( ( item = regex . exec ( from ) ) !== null ) {
result . add ( transformFn ( item , result ) ) ;
}
return result ;
} ;
2018-11-16 12:57:23 -05:00
2018-10-18 13:08:51 -04:00
// verify that we extracted all the necessary translations
// and their ids match the ones extracted via 'ng xi18n'
2018-11-29 19:21:16 -05:00
const verifyTranslationIds =
( source : string , output : string , exceptions = { } ,
interpolationConfig : InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG ) = > {
2019-02-08 17:10:19 -05:00
const parseResult =
htmlParser . parse ( source , 'path:://to/template' , { tokenizeExpansionForms : true } ) ;
2018-11-29 19:21:16 -05:00
const extractedIdToMsg = new Map < string , any > ( ) ;
const extractedIds = new Set < string > ( ) ;
const generatedIds = new Set < string > ( ) ;
const msgs = extractMessages ( parseResult . rootNodes , interpolationConfig , [ ] , { } ) ;
msgs . messages . forEach ( msg = > {
const id = msg . id || decimalDigest ( msg ) ;
extractedIds . add ( id ) ;
extractedIdToMsg . set ( id , msg ) ;
} ) ;
const regexp = /const\s*MSG_EXTERNAL_(.+?)\s*=\s*goog\.getMsg/g ;
const ids = extract ( output , regexp , v = > v [ 1 ] ) ;
ids . forEach ( id = > { generatedIds . add ( id . split ( '$$' ) [ 0 ] ) ; } ) ;
const delta = diff ( extractedIds , generatedIds ) ;
if ( delta . size ) {
// check if we have ids in exception list
const outstanding = diff ( delta , new Set ( Object . keys ( exceptions ) ) ) ;
if ( outstanding . size ) {
throw new Error ( `
2018-10-18 13:08:51 -04:00
Extracted and generated IDs don ' t match , delta :
$ { JSON . stringify ( Array . from ( delta ) ) }
` );
2018-11-29 19:21:16 -05:00
}
}
return true ;
} ;
2018-10-18 13:08:51 -04:00
// verify that placeholders in translation string match
// placeholders object defined as goog.getMsg function argument
const verifyPlaceholdersIntegrity = ( output : string ) = > {
2019-04-11 05:17:49 -04:00
const extractTranslations = ( from : string ) = > {
2019-02-25 15:42:50 -05:00
return extract ( from , EXTRACT_GENERATED_TRANSLATIONS_REGEXP , v = > [ v [ 2 ] , v [ 3 ] ] ) ;
2018-10-18 13:08:51 -04:00
} ;
const extractPlaceholdersFromBody = ( body : string ) = > {
const regex = /{\$(.*?)}/g ;
return extract ( body , regex , v = > v [ 1 ] ) ;
} ;
const extractPlaceholdersFromArgs = ( args : string ) = > {
const regex = /\s+"(.+?)":\s*".*?"/g ;
return extract ( args , regex , v = > v [ 1 ] ) ;
} ;
2019-04-11 05:17:49 -04:00
const translations = extractTranslations ( output ) ;
2018-10-18 13:08:51 -04:00
translations . forEach ( ( translation ) = > {
const bodyPhs = extractPlaceholdersFromBody ( translation [ 0 ] ) ;
const argsPhs = extractPlaceholdersFromArgs ( translation [ 1 ] ) ;
if ( bodyPhs . size !== argsPhs . size || diff ( bodyPhs , argsPhs ) . size ) {
return false ;
}
} ) ;
return true ;
} ;
2019-02-25 15:42:50 -05:00
const verifyUniqueConsts = ( output : string ) = > {
extract (
output , EXTRACT_GENERATED_TRANSLATIONS_REGEXP ,
( current : string [ ] , state : Set < any > ) : string = > {
const key = current [ 1 ] ;
if ( state . has ( key ) ) {
throw new Error ( ` Duplicate const ${ key } found in generated output! ` ) ;
}
return key ;
} ) ;
return true ;
} ;
2019-11-15 11:25:59 -05:00
/ * *
* Escape the template string for being placed inside a backtick string literal .
*
* * "\" would erroneously indicate a control character
* * "`" and "${" strings would erroneously indicate the end of a message part
* /
const escapeTemplate = ( template : string ) = >
template . replace ( /\\/g , '\\\\' ) . replace ( /`/g , '\\`' ) . replace ( /\$\{/g , '$\\{' ) ;
2018-10-18 13:08:51 -04:00
const getAppFilesWithTemplate = ( template : string , args : any = { } ) = > ( {
app : {
'spec.ts' : `
import { Component , NgModule } from '@angular/core' ;
@Component ( {
selector : 'my-component' ,
$ { args . preserveWhitespaces ? 'preserveWhitespaces: true,' : '' }
2018-11-29 19:21:16 -05:00
$ { args . interpolation ? 'interpolation: ' + JSON . stringify ( args . interpolation ) + ', ' : '' }
2019-11-15 11:25:59 -05:00
template : \ ` ${ escapeTemplate ( template ) } \`
2018-10-18 13:08:51 -04:00
} )
export class MyComponent { }
@NgModule ( { declarations : [ MyComponent ] } )
export class MyModule { }
`
}
} ) ;
2018-11-16 12:57:23 -05:00
const maybePrint = ( output : string , verbose : boolean ) = > {
if ( ! verbose ) return ;
// tslint:disable-next-line
console . log ( `
2018-10-18 13:08:51 -04:00
=== === === = Generated output : === === === =
2018-11-16 12:57:23 -05:00
$ { output }
2018-10-18 13:08:51 -04:00
=== === === === === === === === === === === === ===
2018-11-16 12:57:23 -05:00
` );
} ;
const verify = ( input : string , output : string , extra : any = { } ) : void = > {
const files = getAppFilesWithTemplate ( input , extra . inputArgs ) ;
const opts = ( i18nUseExternalIds : boolean ) = >
( { i18nUseExternalIds , . . . ( extra . compilerOptions || { } ) } ) ;
// invoke with file-based prefix translation names
2019-01-11 20:23:51 -05:00
if ( ! extra . skipPathBasedCheck ) {
const result = compile ( files , angularFiles , opts ( false ) ) ;
maybePrint ( result . source , extra . verbose ) ;
expect ( verifyPlaceholdersIntegrity ( result . source ) ) . toBe ( true ) ;
2019-02-25 15:42:50 -05:00
expect ( verifyUniqueConsts ( result . source ) ) . toBe ( true ) ;
2019-01-11 20:23:51 -05:00
expectEmit ( result . source , output , 'Incorrect template' ) ;
}
2018-11-16 12:57:23 -05:00
// invoke with translation names based on external ids
2019-01-11 20:23:51 -05:00
if ( ! extra . skipIdBasedCheck ) {
const result = compile ( files , angularFiles , opts ( true ) ) ;
maybePrint ( result . source , extra . verbose ) ;
const interpolationConfig = extra . inputArgs && extra . inputArgs . interpolation ?
InterpolationConfig . fromArray ( extra . inputArgs . interpolation ) :
undefined ;
expect ( verifyTranslationIds ( input , result . source , extra . exceptions , interpolationConfig ) )
. toBe ( true ) ;
expect ( verifyPlaceholdersIntegrity ( result . source ) ) . toBe ( true ) ;
2019-02-25 15:42:50 -05:00
expect ( verifyUniqueConsts ( result . source ) ) . toBe ( true ) ;
2019-01-11 20:23:51 -05:00
expectEmit ( result . source , output , 'Incorrect template' ) ;
}
2018-10-18 13:08:51 -04:00
} ;
2019-09-04 11:27:29 -04:00
describe ( 'i18n support in the template compiler' , ( ) = > {
2018-02-14 13:54:00 -05:00
2018-10-12 17:34:38 -04:00
describe ( 'element attributes' , ( ) = > {
2019-10-02 13:17:56 -04:00
it ( 'should add the meaning and description as JsDoc comments and metadata blocks' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n = "meaningA|descA@@idA" > Content A < / div >
< div i18n - title = "meaningB|descB@@idB" title = "Title B" > Content B < / div >
2019-09-13 07:46:05 -04:00
< div i18n - title = "meaningC|" title = "Title C" > Content C < / div >
2018-10-18 13:08:51 -04:00
< div i18n - title = "meaningD|descD" title = "Title D" > Content D < / div >
< div i18n - title = "meaningE@@idE" title = "Title E" > Content E < / div >
< div i18n - title = "@@idF" title = "Title F" > Content F < / div >
2019-11-15 11:25:59 -05:00
< div i18n - title = "[BACKUP_$\{MESSAGE}_ID:idH]\`desc@@idG" title = "Title G" > Content G < / div >
< div i18n = "Some text \\' [BACKUP_MESSAGE_ID: xxx]" > Content H < / div >
2018-10-18 13:08:51 -04:00
` ;
2018-02-14 13:54:00 -05:00
2019-07-30 13:02:17 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc descA
* @meaning meaningA
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_idA $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Content A" ) ;
$I18N_0 $ = $MSG_EXTERNAL_idA $ $APP_SPEC_TS_1 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-09-13 07:46:05 -04:00
$I18N_0 $ = $localize \ ` :meaningA|descA@@idA:Content A \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc descB
* @meaning meaningB
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_idB $ $APP_SPEC_TS_4 $ = goog . getMsg ( "Title B" ) ;
$I18N_3 $ = $MSG_EXTERNAL_idB $ $APP_SPEC_TS_4 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-09-13 07:46:05 -04:00
$I18N_3 $ = $localize \ ` :meaningB|descB@@idB:Title B \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c5 $ = [ "title" , $I18N_3 $ ] ;
var $I18N_7 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
2019-09-13 07:46:05 -04:00
* @meaning meaningC
2019-04-11 05:17:49 -04:00
* /
2019-09-13 07:46:05 -04:00
const $MSG_EXTERNAL_6435899732746131543 $ $APP_SPEC_TS_8 $ = goog . getMsg ( "Title C" ) ;
$I18N_7 $ = $MSG_EXTERNAL_6435899732746131543 $ $APP_SPEC_TS_8 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_7 $ = $localize \ ` :meaningC|:Title C \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c9 $ = [ "title" , $I18N_7 $ ] ;
var $I18N_11 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc descD
* @meaning meaningD
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_5200291527729162531 $ $APP_SPEC_TS_12 $ = goog . getMsg ( "Title D" ) ;
$I18N_11 $ = $MSG_EXTERNAL_5200291527729162531 $ $APP_SPEC_TS_12 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_11 $ = $localize \ ` :meaningD|descD:Title D \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c13 $ = [ "title" , $I18N_11 $ ] ;
var $I18N_15 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc meaningE
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_idE $ $APP_SPEC_TS_16 $ = goog . getMsg ( "Title E" ) ;
$I18N_15 $ = $MSG_EXTERNAL_idE $ $APP_SPEC_TS_16 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-09-13 07:46:05 -04:00
$I18N_15 $ = $localize \ ` :meaningE@@idE:Title E \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c17 $ = [ "title" , $I18N_15 $ ] ;
var $I18N_19 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_idF $ $APP_SPEC_TS_20 $ = goog . getMsg ( "Title F" ) ;
$I18N_19 $ = $MSG_EXTERNAL_idF $ $APP_SPEC_TS_20 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-09-13 07:46:05 -04:00
$I18N_19 $ = $localize \ ` :@@idF:Title F \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c21 $ = [ "title" , $I18N_19 $ ] ;
var $I18N_23 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
2019-11-15 11:25:59 -05:00
* @desc [ BACKUP_ $ ` +
String . raw ` {MESSAGE}_ID:idH] ` +
'`' + String . raw ` desc
2019-04-11 05:17:49 -04:00
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_idG $ $APP_SPEC_TS_24 $ = goog . getMsg ( "Title G" ) ;
$I18N_23 $ = $MSG_EXTERNAL_idG $ $APP_SPEC_TS_24 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-11-15 11:25:59 -05:00
$I18N_23 $ = $localize \ ` :[BACKUP_ $ \ {MESSAGE}_ID \ :idH] \\ \` desc@@idG:Title G \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c25 $ = [ "title" , $I18N_23 $ ] ;
2019-11-15 11:25:59 -05:00
var $I18N_20 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-11-15 11:25:59 -05:00
/ * *
* @desc Some text \ ' [ BACKUP_MESSAGE_ID : xxx ]
* /
const $MSG_EXTERNAL_idG $ $APP_SPEC_TS_21 $ = goog . getMsg ( "Content H" ) ;
$I18N_20 $ = $MSG_EXTERNAL_idG $ $APP_SPEC_TS_21 $ ;
}
else {
$I18N_20 $ = $localize \ ` :Some text \\ ' [BACKUP_MESSAGE_ID \ : xxx]:Content H \` ;
}
2018-10-05 17:12:13 -04:00
…
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 2 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 3 , $_c5 $ ) ;
$r3 $ . ɵ ɵ text ( 4 , "Content B" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 5 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 6 , $_c9 $ ) ;
$r3 $ . ɵ ɵ text ( 7 , "Content C" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 8 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 9 , $_c13 $ ) ;
$r3 $ . ɵ ɵ text ( 10 , "Content D" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 11 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 12 , $_c17 $ ) ;
$r3 $ . ɵ ɵ text ( 13 , "Content E" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 14 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 15 , $_c21 $ ) ;
$r3 $ . ɵ ɵ text ( 16 , "Content F" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 17 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 18 , $_c25 $ ) ;
$r3 $ . ɵ ɵ text ( 19 , "Content G" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-11-15 11:25:59 -05:00
$r3 $ . ɵ ɵ elementStart ( 20 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 21 , $I18N_20 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
2018-02-14 13:54:00 -05:00
}
2018-03-22 18:03:06 -04:00
` ;
2018-02-14 13:54:00 -05:00
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-02-14 13:54:00 -05:00
} ) ;
2018-10-05 17:12:13 -04:00
2020-02-26 01:59:34 -05:00
it ( 'should support i18n attributes on explicit <ng-template> elements' , ( ) = > {
const input = `
< ng - template i18n - title title = "Hello" > < / n g - t e m p l a t e >
` ;
// TODO (FW-1942): update the code to avoid adding `title` attribute in plain form
// into the `consts` array on Component def.
const output = String . raw `
var $I18N_0 $ ;
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
const $MSG_EXTERNAL_6616505470450179563 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Hello" ) ;
$I18N_0 $ = $MSG_EXTERNAL_6616505470450179563 $ $APP_SPEC_TS_1 $ ;
}
else {
$I18N_0 $ = $localize \ ` Hello \` ;
}
const $_c2 $ = [ "title" , $I18N_0 $ ] ;
…
consts : [ [ "title" , "Hello" ] ] ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ template ( 0 , MyComponent_ng_template_0_Template , 0 , 0 , "ng-template" , 0 ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c2 $ ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should support i18n attributes on explicit <ng-template> with structural directives' ,
( ) = > {
const input = `
< ng - template * ngIf = "visible" i18n - title title = "Hello" > Test < / n g - t e m p l a t e >
` ;
// TODO (FW-1942): update the code to avoid adding `title` attribute in plain form
// into the `consts` array on Component def.
const output = String . raw `
var $I18N_0 $ ;
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
const $MSG_EXTERNAL_6616505470450179563 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Hello" ) ;
$I18N_0 $ = $MSG_EXTERNAL_6616505470450179563 $ $APP_SPEC_TS_1 $ ;
}
else {
$I18N_0 $ = $localize \ ` Hello \` ;
}
const $_c2 $ = [ "title" , $I18N_0 $ ] ;
function MyComponent_0_ng_template_0_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ text ( 0 , "Test" ) ;
}
}
function MyComponent_0_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ template ( 0 , MyComponent_0_ng_template_0_Template , 1 , 0 , "ng-template" , 1 ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c2 $ ) ;
}
}
…
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] , [ "title" , "Hello" ] ] ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ template ( 0 , MyComponent_0_Template , 2 , 0 , undefined , 0 ) ;
}
if ( rf & 2 ) {
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should not create translations for empty attributes' , ( ) = > {
const input = `
< div id = "static" i18n - title = "m|d" title > < / div >
` ;
const output = `
…
2019-09-23 14:08:51 -04:00
consts : [ [ "id" , "static" , "title" , "" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 0 , "div" , 0 ) ;
2018-10-18 13:08:51 -04:00
}
2018-02-14 13:54:00 -05:00
}
2018-10-18 13:08:51 -04:00
` ;
verify ( input , output ) ;
} ) ;
2019-07-09 21:08:33 -04:00
it ( 'should not create translations for bound attributes' , ( ) = > {
const input = `
< div
[ title ] = "title" i18n - title
[ attr . label ] = "label" i18n - attr . label >
< / div >
` ;
const output = `
…
2019-09-23 14:08:51 -04:00
consts : [ [ 3 , "title" ] ] ,
2019-07-09 21:08:33 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 0 , "div" , 0 ) ;
2019-07-09 21:08:33 -04:00
}
if ( rf & 2 ) {
$r3 $ . ɵ ɵ property ( "title" , ctx . title ) ;
$r3 $ . ɵ ɵ attribute ( "label" , ctx . label ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should translate static attributes' , ( ) = > {
const input = `
< div id = "static" i18n - title = "m|d" title = "introduction" > < / div >
` ;
2018-02-14 13:54:00 -05:00
2019-07-30 13:02:17 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_8809028065680254561 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "introduction" ) ;
$I18N_1 $ = $MSG_EXTERNAL_8809028065680254561 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` :m|d:introduction \` ;
2019-04-11 05:17:49 -04:00
}
const $_c1 $ = [ "title" , $I18N_1 $ ] ;
2018-10-05 17:12:13 -04:00
…
2019-09-23 14:08:51 -04:00
consts : [ [ "id" , "static" , $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
2018-02-14 13:54:00 -05:00
}
2018-10-05 17:12:13 -04:00
` ;
2018-02-14 13:54:00 -05:00
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-05 17:12:13 -04:00
} ) ;
2018-10-05 17:12:13 -04:00
it ( 'should support interpolation' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div id = "dynamic-1"
i18n - title = "m|d" title = "intro {{ valueA | uppercase }}"
i18n - aria - label = "m1|d1" aria - label = "{{ valueB }}"
i18n - aria - roledescription aria - roledescription = "static text"
> < / div >
< div id = "dynamic-2"
i18n - title = "m2|d2" title = "{{ valueA }} and {{ valueB }} and again {{ valueA + valueB }}"
i18n - aria - roledescription aria - roledescription = "{{ valueC }}"
> < / div >
` ;
2018-10-05 17:12:13 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_5526535577705876535 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "static text" ) ;
$I18N_1 $ = $MSG_EXTERNAL_5526535577705876535 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` static text \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_8977039798304050198 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "intro {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_2 $ = $MSG_EXTERNAL_8977039798304050198 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` :m|d:intro $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d1
* @meaning m1
* /
const $MSG_EXTERNAL_7432761130955693041 $ $APP_SPEC_TS_3 $ = goog . getMsg ( "{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_3 $ = $MSG_EXTERNAL_7432761130955693041 $ $APP_SPEC_TS_3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` :m1|d1: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-11-16 12:57:23 -05:00
const $_c1 $ = [
2019-04-11 05:17:49 -04:00
"aria-roledescription" , $I18N_1 $ ,
"title" , $I18N_2 $ ,
"aria-label" , $I18N_3 $
2018-11-16 12:57:23 -05:00
] ;
2019-04-11 05:17:49 -04:00
var $I18N_6 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d2
* @meaning m2
* /
const $MSG_EXTERNAL_7566208596013750546 $ $APP_SPEC_TS_6 $ = goog . getMsg ( "{$interpolation} and {$interpolation_1} and again {$interpolation_2}" , {
"interpolation" : "\uFFFD0\uFFFD" , "interpolation_1" : "\uFFFD1\uFFFD" , "interpolation_2" : "\uFFFD2\uFFFD"
} ) ;
$I18N_6 $ = $MSG_EXTERNAL_7566208596013750546 $ $APP_SPEC_TS_6 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_6 $ = $localize \ ` :m2|d2: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: and $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: and again $ ` +
String . raw ` {" \ uFFFD2 \ uFFFD"}:INTERPOLATION_2: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_7 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_6639222533406278123 $ $APP_SPEC_TS_7 $ = goog . getMsg ( "{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_7 $ = $MSG_EXTERNAL_6639222533406278123 $ $APP_SPEC_TS_7 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_7 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-04 18:56:47 -05:00
const $_c3 $ = [
2019-04-11 05:17:49 -04:00
"title" , $I18N_6 $ ,
"aria-roledescription" , $I18N_7 $
2018-12-04 18:56:47 -05:00
] ;
2018-10-05 17:12:13 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 5 ,
2018-11-28 20:31:21 -05:00
vars : 8 ,
2019-09-23 14:08:51 -04:00
consts : [ [ "id" , "dynamic-1" , $ { AttributeMarker . I18n } , "aria-roledescription" , "title" , "aria-label" ] , [ "id" , "dynamic-2" , $ { AttributeMarker . I18n } , "title" , "aria-roledescription" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 2 , $_c1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 3 , "div" , 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 4 , $_c3 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 6 , ctx . valueA ) ) ( ctx . valueB ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 3 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueA ) ( ctx . valueB ) ( ctx . valueA + ctx . valueB ) ( ctx . valueC ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 4 ) ;
2018-10-05 17:12:13 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-05 17:12:13 -04:00
} ) ;
2018-11-29 19:21:16 -05:00
it ( 'should support interpolation with custom interpolation config' , ( ) = > {
const input = `
< div i18n - title = "m|d" title = "intro {% valueA | uppercase %}" > < / div >
` ;
const output = String . raw `
2019-04-11 19:51:27 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_8977039798304050198 $ = goog . getMsg ( "intro {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_1 $ = $MSG_EXTERNAL_8977039798304050198 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` :m|d:intro $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c3 $ = [ "title" , $I18N_1 $ ] ;
2018-11-29 19:21:16 -05:00
…
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-11-29 19:21:16 -05:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 2 , $_c3 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-11-29 19:21:16 -05:00
}
if ( rf & 2 ) {
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 1 , ctx . valueA ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2018-11-29 19:21:16 -05:00
}
}
` ;
verify ( input , output , { inputArgs : { interpolation : [ '{%' , '%}' ] } } ) ;
} ) ;
2018-10-05 17:12:13 -04:00
it ( 'should correctly bind to context in nested template' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div * ngFor = "let outer of items" >
2018-12-26 20:36:26 -05:00
< div i18n - title = "m|d" title = "different scope {{ outer | uppercase }}" > < / div >
2018-10-18 13:08:51 -04:00
< / div >
` ;
2018-10-05 17:12:13 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_8538466649243975456 $ $APP_SPEC_TS__1 $ = goog . getMsg ( "different scope {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_8538466649243975456 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` :m|d:different scope $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c2 $ = [ "title" , $I18N_1 $ ] ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_0_Template ( rf , ctx ) {
2018-10-05 17:12:13 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 1 , "div" , 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 2 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 3 , $_c2 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
const $outer_r1 $ = ctx . $implicit ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 2 , 1 , $outer_r1 $ ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 3 ) ;
2018-10-05 17:12:13 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 1 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngFor" , "ngForOf" ] , [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_div_0_Template , 4 , 3 , "div" , 0 ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngForOf" , ctx . items ) ;
2018-10-05 17:12:13 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-05 17:12:13 -04:00
} ) ;
2019-08-24 17:02:30 -04:00
it ( 'should support complex expressions in interpolation' , ( ) = > {
const input = `
< div i18n - title title = "{{valueA.getRawValue()?.getTitle()}} title" > < / div >
` ;
const output = String . raw `
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-24 17:02:30 -04:00
const $MSG_EXTERNAL_3462388422673575127 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "{$interpolation} title" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_3462388422673575127 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: title \` ;
2019-08-24 17:02:30 -04:00
}
const $_c3 $ = [ "title" , $I18N_1 $ ] ;
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2019-08-24 17:02:30 -04:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . I18n } , "title" ] ] ,
2019-08-24 17:02:30 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-08-24 17:02:30 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c3 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
}
if ( rf & 2 ) {
var $tmp_0_0 $ = null ;
const $currVal_0 $ = ( $tmp_0_0 $ = ctx . valueA . getRawValue ( ) ) == null ? null : $tmp_0_0 $ . getTitle ( ) ;
$r3 $ . ɵ ɵ i18nExp ( $currVal_0 $ ) ;
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-05 17:12:13 -04:00
it ( 'should support interpolation' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div id = "dynamic-1"
i18n - title = "m|d" title = "intro {{ valueA | uppercase }}"
i18n - aria - label = "m1|d1" aria - label = "{{ valueB }}"
i18n - aria - roledescription aria - roledescription = "static text"
> < / div >
< div id = "dynamic-2"
i18n - title = "m2|d2" title = "{{ valueA }} and {{ valueB }} and again {{ valueA + valueB }}"
i18n - aria - roledescription aria - roledescription = "{{ valueC }}"
> < / div >
` ;
2018-10-05 17:12:13 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_5526535577705876535 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "static text" ) ;
$I18N_1 $ = $MSG_EXTERNAL_5526535577705876535 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` static text \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_8977039798304050198 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "intro {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_2 $ = $MSG_EXTERNAL_8977039798304050198 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` :m|d:intro $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d1
* @meaning m1
* /
const $MSG_EXTERNAL_7432761130955693041 $ $APP_SPEC_TS_3 $ = goog . getMsg ( "{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_3 $ = $MSG_EXTERNAL_7432761130955693041 $ $APP_SPEC_TS_3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` :m1|d1: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-11-16 12:57:23 -05:00
const $_c1 $ = [
2019-04-11 05:17:49 -04:00
"aria-roledescription" , $I18N_1 $ ,
"title" , $I18N_2 $ ,
"aria-label" , $I18N_3 $
2018-11-16 12:57:23 -05:00
] ;
2019-04-11 05:17:49 -04:00
var $I18N_6 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d2
* @meaning m2
* /
const $MSG_EXTERNAL_7566208596013750546 $ $APP_SPEC_TS_6 $ = goog . getMsg ( "{$interpolation} and {$interpolation_1} and again {$interpolation_2}" , {
"interpolation" : "\uFFFD0\uFFFD" , "interpolation_1" : "\uFFFD1\uFFFD" , "interpolation_2" : "\uFFFD2\uFFFD"
} ) ;
$I18N_6 $ = $MSG_EXTERNAL_7566208596013750546 $ $APP_SPEC_TS_6 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_6 $ = $localize \ ` :m2|d2: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: and $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: and again $ ` +
String . raw ` {" \ uFFFD2 \ uFFFD"}:INTERPOLATION_2: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_7 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_6639222533406278123 $ $APP_SPEC_TS_7 $ = goog . getMsg ( "{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_7 $ = $MSG_EXTERNAL_6639222533406278123 $ $APP_SPEC_TS_7 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_7 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-04 18:56:47 -05:00
const $_c3 $ = [
2019-04-11 05:17:49 -04:00
"title" , $I18N_6 $ ,
"aria-roledescription" , $I18N_7 $
2018-12-04 18:56:47 -05:00
] ;
2018-10-05 17:12:13 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 5 ,
2018-11-28 20:31:21 -05:00
vars : 8 ,
2019-09-23 14:08:51 -04:00
consts : [ [
"id" , "dynamic-1" ,
$ { AttributeMarker . I18n } , "aria-roledescription" , "title" , "aria-label"
] , [ "id" , "dynamic-2" , $ { AttributeMarker . I18n } , "title" , "aria-roledescription" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 2 , $_c1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 3 , "div" , 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 4 , $_c3 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 6 , ctx . valueA ) ) ( ctx . valueB ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 3 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueA ) ( ctx . valueB ) ( ctx . valueA + ctx . valueB ) ( ctx . valueC ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 4 ) ;
2018-10-05 17:12:13 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-05 17:12:13 -04:00
} ) ;
it ( 'should correctly bind to context in nested template' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div * ngFor = "let outer of items" >
2018-12-26 20:36:26 -05:00
< div i18n - title = "m|d" title = "different scope {{ outer | uppercase }}" > < / div >
2018-10-18 13:08:51 -04:00
< / div >
` ;
2018-10-05 17:12:13 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 19:51:27 -04:00
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_8538466649243975456 $ $APP_SPEC_TS__3 $ = goog . getMsg ( "different scope {$interpolation}" , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_2 $ = $MSG_EXTERNAL_8538466649243975456 $ $APP_SPEC_TS__3 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` :m|d:different scope $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c4 $ = [ "title" , $I18N_2 $ ] ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_0_Template ( rf , ctx ) {
2018-10-05 17:12:13 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 1 , "div" , 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 2 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nAttributes ( 3 , $_c4 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
const $outer_r1 $ = ctx . $implicit ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 2 , 1 , $outer_r1 $ ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 3 ) ;
2018-10-05 17:12:13 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 1 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngFor" , "ngForOf" ] , [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-05 17:12:13 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_div_0_Template , 4 , 3 , "div" , 0 ) ;
2018-10-05 17:12:13 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngForOf" , ctx . items ) ;
2018-10-05 17:12:13 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
} ) ;
it ( 'should work correctly when placed on i18n root node' , ( ) = > {
const input = `
< div i18n i18n - title = "m|d" title = "Element title" > Some content < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
/ * *
* @desc d
* @meaning m
* /
const $MSG_EXTERNAL_7727043314656808423 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "Element title" ) ;
$I18N_0 $ = $MSG_EXTERNAL_7727043314656808423 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` :m|d:Element title \` ;
2019-04-11 05:17:49 -04:00
}
const $_c1 $ = [ "title" , $I18N_0 $ ] ;
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4969674997806975147 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "Some content" ) ;
$I18N_2 $ = $MSG_EXTERNAL_4969674997806975147 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` Some content \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c1 $ ) ;
$r3 $ . ɵ ɵ i18n ( 2 , $I18N_2 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
2018-02-14 13:54:00 -05:00
} ) ;
2019-01-11 20:23:51 -05:00
2019-04-11 05:17:49 -04:00
it ( 'should sanitize ids and generate proper var names' , ( ) = > {
2019-01-11 20:23:51 -05:00
const input = `
< div i18n = "@@ID.WITH.INVALID.CHARS.2" i18n - title = "@@ID.WITH.INVALID.CHARS" title = "Element title" >
Some content
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Element title" ) ;
$I18N_0 $ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS $ $APP_SPEC_TS_1 $ ;
}
else {
2019-09-13 07:46:05 -04:00
$I18N_0 $ = $localize \ ` :@@ID.WITH.INVALID.CHARS:Element title \` ;
2019-04-11 05:17:49 -04:00
}
const $_c1 $ = [ "title" , $I18N_0 $ ] ;
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2 $ $APP_SPEC_TS_4 $ = goog . getMsg ( " Some content " ) ;
$I18N_2 $ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2 $ $APP_SPEC_TS_4 $ ;
}
else {
2019-09-13 07:46:05 -04:00
$I18N_2 $ = $localize \ ` :@@ID.WITH.INVALID.CHARS.2: Some content \` ;
2019-04-11 05:17:49 -04:00
}
2019-01-11 20:23:51 -05:00
…
` ;
const exceptions = {
'ID.WITH.INVALID.CHARS' : 'Verify const name generation only' ,
'ID.WITH.INVALID.CHARS.2' : 'Verify const name generation only'
} ;
verify ( input , output , { exceptions , skipPathBasedCheck : true } ) ;
} ) ;
2018-02-14 13:54:00 -05:00
} ) ;
2018-10-12 17:34:38 -04:00
describe ( 'nested nodes' , ( ) = > {
it ( 'should not produce instructions for empty content' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n > < / div >
< div i18n > < / div >
< div i18n >
< / div >
` ;
2018-02-14 13:54:00 -05:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ element ( 0 , "div" ) ;
$r3 $ . ɵ ɵ element ( 1 , "div" ) ;
$r3 $ . ɵ ɵ element ( 2 , "div" ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
const exceptions = {
'6524085439495453930' : 'No translation is produced for empty content (whitespaces)' ,
'814405839137385666' : 'No translation is produced for empty content (line breaks)'
} ;
verify ( input , output , { exceptions } ) ;
2018-10-12 17:34:38 -04:00
} ) ;
2019-09-04 11:27:29 -04:00
it ( 'should ignore HTML comments within translated text' , ( ) = > {
const input = `
< div i18n > Some <!-- comments -- > text < / div >
` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-09-13 07:46:05 -04:00
const $MSG_APP_SPEC_TS_1 $ = goog . getMsg ( "Some text" ) ;
$I18N_0 $ = $MSG_APP_SPEC_TS_1 $ ;
2019-09-04 11:27:29 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Some text \` ;
2019-09-04 11:27:29 -04:00
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should properly escape quotes in content' , ( ) = > {
const input = `
2019-11-26 09:03:19 -05:00
< div i18n > Some text 'with single quotes' , "with double quotes" , \ ` with backticks \` and without quotes.</div>
2018-10-18 13:08:51 -04:00
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-11-26 09:03:19 -05:00
const $MSG_EXTERNAL_4924931801512133405 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "Some text 'with single quotes', \"with double quotes\" , ` +
'`with backticks`' + String . raw ` and without quotes.");
2019-04-11 05:17:49 -04:00
$I18N_0 $ = $MSG_EXTERNAL_4924931801512133405 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-11-26 09:03:19 -05:00
$I18N_0 $ = $localize \ ` Some text 'with single quotes', "with double quotes", \\ \` with backticks \\ \` and without quotes. \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
` ;
verify ( input , output ) ;
} ) ;
2018-10-12 17:34:38 -04:00
2019-11-26 09:03:19 -05:00
it ( 'should handle interpolations wrapped in backticks' , ( ) = > {
const input = '<div i18n>`{{ count }}`</div>' ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-11-26 09:03:19 -05:00
const $MSG_APP_SPEC_TS_1 $ = goog . getMsg ( " ` +
'`{$interpolation}`' + String . raw ` ", { "interpolation": " \ uFFFD0 \ uFFFD" });
$I18N_0 $ = $MSG_APP_SPEC_TS_1 $ ;
}
else {
$I18N_0 $ = $localize \ ` \\ \` $ ` +
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \\ \` \` ;
} ` ;
verify ( input , output ) ;
} ) ;
2018-10-12 17:34:38 -04:00
it ( 'should handle i18n attributes with plain-text content' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n > My i18n block # 1 < / div >
< div > My non - i18n block # 1 < / div >
< div i18n > My i18n block # 2 < / div >
< div > My non - i18n block # 2 < / div >
< div i18n > My i18n block # 3 < / div >
` ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "My i18n block #1" ) ;
$I18N_0 $ = $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block #1 \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_2413150872298537152 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "My i18n block #2" ) ;
$I18N_1 $ = $MSG_EXTERNAL_2413150872298537152 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` My i18n block #2 \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_5023003143537152794 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "My i18n block #3" ) ;
$I18N_2 $ = $MSG_EXTERNAL_5023003143537152794 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` My i18n block #3 \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-12 17:34:38 -04:00
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 2 , "div" ) ;
$r3 $ . ɵ ɵ text ( 3 , "My non-i18n block #1" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 4 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 5 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 6 , "div" ) ;
$r3 $ . ɵ ɵ text ( 7 , "My non-i18n block #2" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 8 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 9 , $I18N_2 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-12 17:34:38 -04:00
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should support named interpolations' , ( ) = > {
const input = `
2019-07-08 20:37:26 -04:00
< div i18n >
Named interpolation : { { valueA // i18n(ph="PH_A") }}
Named interpolation with spaces : { { valueB // i18n(ph="PH B") }}
< / div >
2018-10-18 13:08:51 -04:00
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_7597881511811528589 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " Named interpolation: {$phA} Named interpolation with spaces: {$phB} " , {
"phA" : "\uFFFD0\uFFFD" ,
"phB" : "\uFFFD1\uFFFD"
2019-04-11 05:17:49 -04:00
} ) ;
2019-07-08 20:37:26 -04:00
$I18N_0 $ = $MSG_EXTERNAL_7597881511811528589 $ $APP_SPEC_TS_0 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Named interpolation: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:PH_A: Named interpolation with spaces: $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:PH_B: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2019-07-08 20:37:26 -04:00
vars : 2 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-07-08 20:37:26 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueA ) ( ctx . valueB ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
2018-10-12 17:34:38 -04:00
}
2018-10-18 13:08:51 -04:00
` ;
verify ( input , output ) ;
} ) ;
2018-10-12 17:34:38 -04:00
2018-11-29 19:21:16 -05:00
it ( 'should support interpolation with custom interpolation config' , ( ) = > {
const input = `
< div i18n > { % valueA % } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_6749967533321674787 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_6749967533321674787 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-11-29 19:21:16 -05:00
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-11-29 19:21:16 -05:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueA ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-11-29 19:21:16 -05:00
}
}
` ;
verify ( input , output , { inputArgs : { interpolation : [ '{%' , '%}' ] } } ) ;
} ) ;
2019-02-25 18:26:10 -05:00
it ( 'should support interpolations with complex expressions' , ( ) = > {
const input = `
< div i18n >
{ { valueA | async } }
{ { valueA ? . a ? . b } }
2019-08-24 17:02:30 -04:00
{ { valueA . getRawValue ( ) ? . getTitle ( ) } }
2019-02-25 18:26:10 -05:00
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-09-13 07:46:05 -04:00
const $MSG_APP_SPEC_TS_1 $ $APP_SPEC_TS_1 $ = goog . getMsg ( " {$interpolation} {$interpolation_1} {$interpolation_2} " , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD" ,
2019-08-24 17:02:30 -04:00
"interpolation_1" : "\uFFFD1\uFFFD" ,
"interpolation_2" : "\uFFFD2\uFFFD"
2019-04-11 05:17:49 -04:00
} ) ;
2019-09-13 07:46:05 -04:00
$I18N_0 $ = $MSG_APP_SPEC_TS_1 $ $APP_SPEC_TS_1 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: $ ` +
String . raw ` {" \ uFFFD2 \ uFFFD"}:INTERPOLATION_2: \` ;
2019-04-11 05:17:49 -04:00
}
2019-02-25 18:26:10 -05:00
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ pipe ( 2 , "async" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-02-25 18:26:10 -05:00
}
if ( rf & 2 ) {
2019-08-24 17:02:30 -04:00
var $tmp_2_0 $ = null ;
const $currVal_2 $ = ( $tmp_2_0 $ = ctx . valueA . getRawValue ( ) ) == null ? null : $tmp_2_0 $ . getTitle ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-08-24 17:02:30 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 2 , 3 , ctx . valueA ) ) ( ctx . valueA == null ? null : ctx . valueA . a == null ? null : ctx . valueA . a . b ) ( $currVal_2 $ ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2019-02-25 18:26:10 -05:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should handle i18n attributes with bindings in content' , ( ) = > {
const input = `
< div i18n > My i18n block # { { one } } < / div >
< div i18n > My i18n block # { { two | uppercase } } < / div >
< div i18n > My i18n block # { { three + four + five } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_572579892698764378 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "My i18n block #{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_572579892698764378 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_609623417156596326 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "My i18n block #{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_609623417156596326 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` My i18n block # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_3998119318957372120 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "My i18n block #{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_2 $ = $MSG_EXTERNAL_3998119318957372120 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` My i18n block # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-12 17:34:38 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 7 ,
2018-11-28 20:31:21 -05:00
vars : 5 ,
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 2 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 3 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ pipe ( 4 , "uppercase" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 5 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 6 , $I18N_2 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . one ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 3 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 4 , 3 , ctx . two ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 3 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . three + ctx . four + ctx . five ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 6 ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-12 17:34:38 -04:00
} ) ;
it ( 'should handle i18n attributes with bindings and nested elements in content' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n >
My i18n block # { { one } }
< span > Plain text in nested element < / span >
< / div >
< div i18n >
My i18n block # { { two | uppercase } }
< div >
< div >
< span >
More bindings in more nested element : { { nestedInBlockTwo } }
< / span >
< / div >
< / div >
< / div >
` ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7905233330103651696 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " My i18n block #{$interpolation} {$startTagSpan}Plain text in nested element{$closeTagSpan}" , {
"interpolation" : "\uFFFD0\uFFFD" ,
"startTagSpan" : "\uFFFD#2\uFFFD" ,
"closeTagSpan" : "\uFFFD/#2\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_7905233330103651696 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_TAG_SPAN:Plain text in nested element $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_5788821996131681377 $ $APP_SPEC_TS_1 $ = goog . getMsg ( " My i18n block #{$interpolation} {$startTagDiv}{$startTagDiv}{$startTagSpan} More bindings in more nested element: {$interpolation_1} {$closeTagSpan}{$closeTagDiv}{$closeTagDiv}" , {
"interpolation" : "\uFFFD0\uFFFD" ,
"startTagDiv" : "[\uFFFD#6\uFFFD|\uFFFD#7\uFFFD]" ,
"startTagSpan" : "\uFFFD#8\uFFFD" ,
"interpolation_1" : "\uFFFD1\uFFFD" ,
"closeTagSpan" : "\uFFFD/#8\uFFFD" ,
"closeTagDiv" : "[\uFFFD/#7\uFFFD|\uFFFD/#6\uFFFD]"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_5788821996131681377 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` My i18n block # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {"[ \ uFFFD#6 \ uFFFD| \ uFFFD#7 \ uFFFD]"}:START_TAG_DIV: $ ` +
String . raw ` {"[ \ uFFFD#6 \ uFFFD| \ uFFFD#7 \ uFFFD]"}:START_TAG_DIV: $ ` + String . raw
` {" \ uFFFD#8 \ uFFFD"}:START_TAG_SPAN: More bindings in more nested element: $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: $ ` +
String . raw ` {" \ uFFFD/#8 \ uFFFD"}:CLOSE_TAG_SPAN: $ ` +
String . raw ` {"[ \ uFFFD/#7 \ uFFFD| \ uFFFD/#6 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
String . raw ` {"[ \ uFFFD/#7 \ uFFFD| \ uFFFD/#6 \ uFFFD]"}:CLOSE_TAG_DIV: \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ ) ;
2018-10-12 17:34:38 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 9 ,
2018-11-28 20:31:21 -05:00
vars : 5 ,
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ element ( 2 , "span" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 3 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 4 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ pipe ( 5 , "uppercase" ) ;
$r3 $ . ɵ ɵ elementStart ( 6 , "div" ) ;
$r3 $ . ɵ ɵ elementStart ( 7 , "div" ) ;
$r3 $ . ɵ ɵ element ( 8 , "span" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . one ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 6 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 5 , 3 , ctx . two ) ) ( ctx . nestedInBlockTwo ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 4 ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-12 17:34:38 -04:00
} ) ;
it ( 'should handle i18n attributes with bindings in content and element attributes' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n >
My i18n block # 1 with value : { { valueA } }
< span i18n - title title = "Span title {{ valueB }} and {{ valueC }}" >
Plain text in nested element ( block # 1 )
< / span >
< / div >
< div i18n >
My i18n block # 2 with value { { valueD | uppercase } }
< span i18n - title title = "Span title {{ valueE }}" >
Plain text in nested element ( block # 2 )
< / span >
< / div >
` ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 19:51:27 -04:00
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_4782264005467235841 $ $APP_SPEC_TS_3 $ = goog . getMsg ( "Span title {$interpolation} and {$interpolation_1}" , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD" ,
"interpolation_1" : "\uFFFD1\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_2 $ = $MSG_EXTERNAL_4782264005467235841 $ $APP_SPEC_TS_3 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` Span title $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: and $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c4 $ = [ "title" , $I18N_2 $ ] ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_4446430594603971069 $ $APP_SPEC_TS_5 $ = goog . getMsg ( " My i18n block #1 with value: {$interpolation} {$startTagSpan} Plain text in nested element (block #1) {$closeTagSpan}" , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD" ,
"startTagSpan" : "\uFFFD#2\uFFFD" ,
"closeTagSpan" : "\uFFFD/#2\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_0 $ = $MSG_EXTERNAL_4446430594603971069 $ $APP_SPEC_TS_5 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block #1 with value: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` + String . raw
` {" \ uFFFD#2 \ uFFFD"}:START_TAG_SPAN: Plain text in nested element (block #1) $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
var $I18N_7 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_2719594642740200058 $ $APP_SPEC_TS_8 $ = goog . getMsg ( "Span title {$interpolation}" , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_7 $ = $MSG_EXTERNAL_2719594642740200058 $ $APP_SPEC_TS_8 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_7 $ = $localize \ ` Span title $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c9 $ = [ "title" , $I18N_7 $ ] ;
var $I18N_6 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 19:51:27 -04:00
const $MSG_EXTERNAL_2778714953278357902 $ $APP_SPEC_TS_10 $ = goog . getMsg ( " My i18n block #2 with value {$interpolation} {$startTagSpan} Plain text in nested element (block #2) {$closeTagSpan}" , {
2019-04-11 05:17:49 -04:00
"interpolation" : "\uFFFD0\uFFFD" ,
"startTagSpan" : "\uFFFD#7\uFFFD" ,
"closeTagSpan" : "\uFFFD/#7\uFFFD"
} ) ;
2019-04-11 19:51:27 -04:00
$I18N_6 $ = $MSG_EXTERNAL_2778714953278357902 $ $APP_SPEC_TS_10 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_6 $ = $localize \ ` My i18n block #2 with value $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` + String . raw
` {" \ uFFFD#7 \ uFFFD"}:START_TAG_SPAN: Plain text in nested element (block #2) $ ` +
String . raw ` {" \ uFFFD/#7 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-12 17:34:38 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 9 ,
2018-11-28 20:31:21 -05:00
vars : 7 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 2 , "span" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 3 , $_c4 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementStart ( 4 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 5 , $I18N_6 $ ) ;
$r3 $ . ɵ ɵ pipe ( 6 , "uppercase" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 7 , "span" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 8 , $_c9 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueB ) ( ctx . valueC ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 3 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueA ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 4 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . valueE ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 8 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 6 , 5 , ctx . valueD ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 5 ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-12 17:34:38 -04:00
} ) ;
it ( 'should handle i18n attributes in nested templates' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div >
Some content
< div * ngIf = "visible" >
< div i18n >
Some other content { { valueA } }
< div >
More nested levels with bindings { { valueB | uppercase } }
< / div >
< / div >
< / div >
< / div >
` ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7679414751795588050 $ $APP_SPEC_TS__1 $ = goog . getMsg ( " Some other content {$interpolation} {$startTagDiv} More nested levels with bindings {$interpolation_1} {$closeTagDiv}" , {
"interpolation" : "\uFFFD0\uFFFD" ,
"startTagDiv" : "\uFFFD#3\uFFFD" ,
"interpolation_1" : "\uFFFD1\uFFFD" ,
"closeTagDiv" : "\uFFFD/#3\uFFFD"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_7679414751795588050 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Some other content $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {" \ uFFFD#3 \ uFFFD"}:START_TAG_DIV: More nested levels with bindings $ ` +
String . raw ` {" \ uFFFD1 \ uFFFD"}:INTERPOLATION_1: $ ` +
String . raw ` {" \ uFFFD/#3 \ uFFFD"}:CLOSE_TAG_DIV: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-12 17:34:38 -04:00
…
2018-12-19 15:17:38 -05:00
function MyComponent_div_2_Template ( rf , ctx ) {
2018-10-12 17:34:38 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ elementStart ( 1 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 2 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ element ( 3 , "div" ) ;
$r3 $ . ɵ ɵ pipe ( 4 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 4 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . valueA ) ( $r3 $ . ɵ ɵ pipeBind1 ( 4 , 2 , $ctx_r0 $ . valueB ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2018-10-12 17:34:38 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ text ( 1 , " Some content " ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 2 , MyComponent_div_2_Template , 5 , 4 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
2018-10-12 17:34:38 -04:00
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should ignore i18n attributes on self-closing tags' , ( ) = > {
const input = `
< img src = "logo.png" i18n / >
< img src = "logo.png" i18n * ngIf = "visible" / >
< img src = "logo.png" i18n * ngIf = "visible" i18n - title title = "App logo #{{ id }}" / >
` ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
const output = String . raw `
2018-12-19 15:17:38 -05:00
function MyComponent_img_1_Template ( rf , ctx ) {
2018-11-16 12:57:23 -05:00
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 0 , "img" , 0 ) ;
2018-11-16 12:57:23 -05:00
}
}
2019-04-11 05:17:49 -04:00
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_2367729185105559721 $ $APP_SPEC_TS__2 $ = goog . getMsg ( "App logo #{$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_2 $ = $MSG_EXTERNAL_2367729185105559721 $ $APP_SPEC_TS__2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` App logo # $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2019-04-11 19:51:27 -04:00
const $_c4 $ = [ "title" , $I18N_2 $ ] ;
2018-12-19 15:17:38 -05:00
function MyComponent_img_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "img" , 3 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nAttributes ( 1 , $_c4 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r1 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r1 $ . id ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
2018-10-12 17:34:38 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2019-09-23 14:08:51 -04:00
consts : [ [ "src" , "logo.png" ] , [ "src" , "logo.png" , $ { AttributeMarker . Template } , "ngIf" ] , [ "src" , "logo.png" , $ { AttributeMarker . Bindings } , "title" , $ { AttributeMarker . Template } , "ngIf" ] , [ "src" , "logo.png" , $ { AttributeMarker . I18n } , "title" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 0 , "img" , 0 ) ;
$r3 $ . ɵ ɵ template ( 1 , MyComponent_img_1_Template , 1 , 0 , "img" , 1 ) ;
$r3 $ . ɵ ɵ template ( 2 , MyComponent_img_2_Template , 2 , 1 , "img" , 2 ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-12 17:34:38 -04:00
2018-10-18 13:08:51 -04:00
it ( 'should handle i18n context in nested templates' , ( ) = > {
const input = `
< div i18n >
Some content
< div * ngIf = "visible" >
Some other content { { valueA } }
< div >
More nested levels with bindings { { valueB | uppercase } }
< div * ngIf = "exists" >
Content inside sub - template { { valueC } }
< div >
Bottom level element { { valueD } }
< / div >
< / div >
< / div >
< / div >
< div * ngIf = "!visible" >
Some other content { { valueE + valueF } }
< div >
More nested levels with bindings { { valueG | uppercase } }
< / div >
< / div >
< / div >
` ;
const output = String . raw `
2018-12-19 15:17:38 -05:00
function MyComponent_div_2_div_4_Template ( rf , ctx ) {
2018-10-12 17:34:38 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 2 ) ;
$r3 $ . ɵ ɵ elementStart ( 1 , "div" ) ;
$r3 $ . ɵ ɵ element ( 2 , "div" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r2 $ = $r3 $ . ɵ ɵ nextContext ( 2 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r2 $ . valueC ) ( $ctx_r2 $ . valueD ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-12 17:34:38 -04:00
}
}
2018-12-19 15:17:38 -05:00
function MyComponent_div_2_Template ( rf , ctx ) {
2018-10-12 17:34:38 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ elementStart ( 1 , "div" ) ;
$r3 $ . ɵ ɵ elementStart ( 2 , "div" ) ;
$r3 $ . ɵ ɵ pipe ( 3 , "uppercase" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 4 , MyComponent_div_2_div_4_Template , 3 , 2 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 4 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , $ctx_r0 $ . exists ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . valueA ) ( $r3 $ . ɵ ɵ pipeBind1 ( 3 , 3 , $ctx_r0 $ . valueB ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-12 17:34:38 -04:00
}
}
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_1221890473527419724 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " Some content {$startTagDiv_2} Some other content {$interpolation} {$startTagDiv} More nested levels with bindings {$interpolation_1} {$startTagDiv_1} Content inside sub-template {$interpolation_2} {$startTagDiv} Bottom level element {$interpolation_3} {$closeTagDiv}{$closeTagDiv}{$closeTagDiv}{$closeTagDiv}{$startTagDiv_3} Some other content {$interpolation_4} {$startTagDiv} More nested levels with bindings {$interpolation_5} {$closeTagDiv}{$closeTagDiv}" , {
"startTagDiv_2" : "\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD" ,
"closeTagDiv" : "[\uFFFD/#2:2\uFFFD|\uFFFD/#1:2\uFFFD\uFFFD/*4:2\uFFFD|\uFFFD/#2:1\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD|\uFFFD/#2:3\uFFFD|\uFFFD/#1:3\uFFFD\uFFFD/*3:3\uFFFD]" ,
"startTagDiv_3" : "\uFFFD*3:3\uFFFD\uFFFD#1:3\uFFFD" ,
"interpolation" : "\uFFFD0:1\uFFFD" ,
"startTagDiv" : "[\uFFFD#2:1\uFFFD|\uFFFD#2:2\uFFFD|\uFFFD#2:3\uFFFD]" ,
"interpolation_1" : "\uFFFD1:1\uFFFD" ,
"startTagDiv_1" : "\uFFFD*4:2\uFFFD\uFFFD#1:2\uFFFD" ,
"interpolation_2" : "\uFFFD0:2\uFFFD" ,
"interpolation_3" : "\uFFFD1:2\uFFFD" ,
"interpolation_4" : "\uFFFD0:3\uFFFD" ,
"interpolation_5" : "\uFFFD1:3\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_1221890473527419724 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Some content $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {" \ uFFFD*2:1 \ uFFFD \ uFFFD#1:1 \ uFFFD"}:START_TAG_DIV_2: Some other content $ ` +
String . raw ` {" \ uFFFD0:1 \ uFFFD"}:INTERPOLATION: $ ` + String . raw
` {"[ \ uFFFD#2:1 \ uFFFD| \ uFFFD#2:2 \ uFFFD| \ uFFFD#2:3 \ uFFFD]"}:START_TAG_DIV: More nested levels with bindings $ ` +
String . raw ` {" \ uFFFD1:1 \ uFFFD"}:INTERPOLATION_1: $ ` + String . raw
` {" \ uFFFD*4:2 \ uFFFD \ uFFFD#1:2 \ uFFFD"}:START_TAG_DIV_1: Content inside sub-template $ ` +
String . raw ` {" \ uFFFD0:2 \ uFFFD"}:INTERPOLATION_2: $ ` + String . raw
` {"[ \ uFFFD#2:1 \ uFFFD| \ uFFFD#2:2 \ uFFFD| \ uFFFD#2:3 \ uFFFD]"}:START_TAG_DIV: Bottom level element $ ` +
String . raw ` {" \ uFFFD1:2 \ uFFFD"}:INTERPOLATION_3: $ ` + String . raw
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {" \ uFFFD*3:3 \ uFFFD \ uFFFD#1:3 \ uFFFD"}:START_TAG_DIV_3: Some other content $ ` +
String . raw ` {" \ uFFFD0:3 \ uFFFD"}:INTERPOLATION_4: $ ` + String . raw
` {"[ \ uFFFD#2:1 \ uFFFD| \ uFFFD#2:2 \ uFFFD| \ uFFFD#2:3 \ uFFFD]"}:START_TAG_DIV: More nested levels with bindings $ ` +
String . raw ` {" \ uFFFD1:3 \ uFFFD"}:INTERPOLATION_5: $ ` + String . raw
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/#2:2 \ uFFFD| \ uFFFD/#1:2 \ uFFFD \ uFFFD/*4:2 \ uFFFD| \ uFFFD/#2:1 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD| \ uFFFD/#2:3 \ uFFFD| \ uFFFD/#1:3 \ uFFFD \ uFFFD/*3:3 \ uFFFD]"}:CLOSE_TAG_DIV: \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_3_Template ( rf , ctx ) {
2018-10-12 17:34:38 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 3 ) ;
$r3 $ . ɵ ɵ elementStart ( 1 , "div" ) ;
$r3 $ . ɵ ɵ element ( 2 , "div" ) ;
$r3 $ . ɵ ɵ pipe ( 3 , "uppercase" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r1 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 3 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r1 $ . valueE + $ctx_r1 $ . valueF ) ( $r3 $ . ɵ ɵ pipeBind1 ( 3 , 2 , $ctx_r1 $ . valueG ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-12 17:34:38 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 4 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-12 17:34:38 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 2 , MyComponent_div_2_Template , 5 , 5 , "div" , 0 ) ;
$r3 $ . ɵ ɵ template ( 3 , MyComponent_div_3_Template , 4 , 4 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-12 17:34:38 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ! ctx . visible ) ;
2018-10-12 17:34:38 -04:00
}
}
` ;
2018-02-14 13:54:00 -05:00
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
} ) ;
it ( 'should handle i18n attribute with directives' , ( ) = > {
const input = `
< div i18n * ngIf = "visible" > Some other content < span > { { valueA } } < / span > < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_119975189388320493 $ $APP_SPEC_TS__1 $ = goog . getMsg ( "Some other content {$startTagSpan}{$interpolation}{$closeTagSpan}" , {
"startTagSpan" : "\uFFFD#2\uFFFD" ,
"interpolation" : "\uFFFD0\uFFFD" ,
"closeTagSpan" : "\uFFFD/#2\uFFFD"
} ) ;
$I18N_1 $ = $MSG_EXTERNAL_119975189388320493 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Some other content $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_TAG_SPAN: $ ` +
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2018-12-19 15:17:38 -05:00
function MyComponent_div_0_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ element ( 2 , "span" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . valueA ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 1 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_div_0_Template , 3 , 1 , "div" , 0 ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
2018-02-14 13:54:00 -05:00
} ) ;
2019-03-07 17:24:54 -05:00
it ( 'should generate event listeners instructions before i18n ones' , ( ) = > {
const input = `
< div i18n ( click ) = " onClick ( ) " > Hello < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_APP_SPEC_TS_2 $ = goog . getMsg ( "Hello" ) ;
$I18N_1 $ = $MSG_APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Hello \` ;
2019-04-11 05:17:49 -04:00
}
2019-03-07 17:24:54 -05:00
…
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Bindings } , "click" ] ] ,
2019-03-07 17:24:54 -05:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 0 ) ;
2020-02-01 07:19:31 -05:00
$r3 $ . ɵ ɵ listener ( "click" , function MyComponent_Template_div_click_0_listener() { return ctx . onClick ( ) ; } ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-03-07 17:24:54 -05:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-02-14 13:54:00 -05:00
} ) ;
2018-10-18 13:08:51 -04:00
describe ( 'self-closing i18n instructions' , ( ) = > {
it ( 'should be generated with text-only content' , ( ) = > {
const input = `
< div i18n > My i18n block # 1 < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "My i18n block #1" ) ;
$I18N_0 $ = $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block #1 \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
2018-02-14 13:54:00 -05:00
}
2018-10-18 13:08:51 -04:00
` ;
verify ( input , output ) ;
} ) ;
it ( 'should be generated for ICU-only i18n blocks' , ( ) = > {
const input = `
< div i18n > { age , select , 10 { ten } 20 { twenty } other { other } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
2018-02-14 13:54:00 -05:00
2018-10-18 13:08:51 -04:00
verify ( input , output ) ;
} ) ;
it ( 'should be generated within <ng-container> and <ng-template> blocks' , ( ) = > {
const input = `
< ng - template i18n > My i18n block # 1 < / n g - t e m p l a t e >
< ng - container i18n > My i18n block # 2 < / n g - c o n t a i n e r >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_2413150872298537152 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "My i18n block #2" ) ;
$I18N_0 $ = $MSG_EXTERNAL_2413150872298537152 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` My i18n block #2 \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS__1 $ = goog . getMsg ( "My i18n block #1" ) ;
$I18N_1 $ = $MSG_EXTERNAL_4890179241114413722 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` My i18n block #1 \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_0_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_1 $ ) ;
2018-10-18 13:08:51 -04:00
}
}
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_ng_template_0_Template , 1 , 0 , "ng-template" ) ;
$r3 $ . ɵ ɵ elementContainerStart ( 1 ) ;
$r3 $ . ɵ ɵ i18n ( 2 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-11-28 14:34:24 -05:00
it ( 'should not be generated in case we have styling instructions' , ( ) = > {
const input = `
< span i18n class = "myClass" > Text # 1 < / span >
< span i18n style = "padding: 10px;" > Text # 2 < / span >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_5295701706185791735 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Text #1" ) ;
$I18N_1 $ = $MSG_EXTERNAL_5295701706185791735 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Text #1 \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4722270221386399294 $ $APP_SPEC_TS_3 $ = goog . getMsg ( "Text #2" ) ;
$I18N_3 $ = $MSG_EXTERNAL_4722270221386399294 $ $APP_SPEC_TS_3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` Text #2 \` ;
2019-04-11 05:17:49 -04:00
}
2018-11-28 14:34:24 -05:00
…
2019-09-23 14:08:51 -04:00
decls : 4 ,
2018-11-28 14:34:24 -05:00
vars : 0 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Classes } , "myClass" ] , [ $ { AttributeMarker . Styles } , "padding" , "10px" ] ] ,
2018-11-28 14:34:24 -05:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "span" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_1 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 2 , "span" , 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 3 , $I18N_3 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-11-28 14:34:24 -05:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
} ) ;
describe ( 'ng-container and ng-template' , ( ) = > {
it ( 'should handle single translation message using <ng-container>' , ( ) = > {
const input = `
< ng - container i18n > Some content : { { valueA | uppercase } } < / n g - c o n t a i n e r >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_355394464191978948 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "Some content: {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_355394464191978948 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Some content: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 3 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementContainerStart ( 0 ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ pipe ( 2 , "uppercase" ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 2 , 1 , ctx . valueA ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle single translation message using <ng-template>' , ( ) = > {
const input = `
< ng - template i18n > Some content : { { valueA | uppercase } } < / n g - t e m p l a t e >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_355394464191978948 $ $APP_SPEC_TS__0 $ = goog . getMsg ( "Some content: {$interpolation}" , {
"interpolation" : "\uFFFD0\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_355394464191978948 $ $APP_SPEC_TS__0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Some content: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_0_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
2018-10-18 13:08:51 -04:00
} if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 1 , $ctx_r0 $ . valueA ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 1 ,
2018-11-28 20:31:21 -05:00
vars : 0 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_ng_template_0_Template , 2 , 3 , "ng-template" ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-12-26 20:36:26 -05:00
it ( 'should be able to act as child elements inside i18n block' , ( ) = > {
2018-10-18 13:08:51 -04:00
const input = `
< div i18n >
< ng - template > Template content : { { valueA | uppercase } } < / n g - t e m p l a t e >
< ng - container > Container content : { { valueB | uppercase } } < / n g - c o n t a i n e r >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_702706566400598764 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{$startTagNgTemplate}Template content: {$interpolation}{$closeTagNgTemplate}{$startTagNgContainer}Container content: {$interpolation_1}{$closeTagNgContainer}" , {
"startTagNgTemplate" : "\uFFFD*2:1\uFFFD" ,
"closeTagNgTemplate" : "\uFFFD/*2:1\uFFFD" ,
"startTagNgContainer" : "\uFFFD#3\uFFFD" ,
"interpolation_1" : "\uFFFD0\uFFFD" ,
"closeTagNgContainer" : "\uFFFD/#3\uFFFD" ,
"interpolation" : "\uFFFD0:1\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_702706566400598764 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD*2:1 \ uFFFD"}:START_TAG_NG_TEMPLATE:Template content: $ ` +
String . raw ` {" \ uFFFD0:1 \ uFFFD"}:INTERPOLATION: $ ` +
String . raw ` {" \ uFFFD/*2:1 \ uFFFD"}:CLOSE_TAG_NG_TEMPLATE: $ ` +
String . raw ` {" \ uFFFD#3 \ uFFFD"}:START_TAG_NG_CONTAINER:Container content: $ ` +
String . raw ` {" \ uFFFD0 \ uFFFD"}:INTERPOLATION_1: $ ` +
String . raw ` {" \ uFFFD/#3 \ uFFFD"}:CLOSE_TAG_NG_CONTAINER: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 1 , $ctx_r0 $ . valueA ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 5 ,
2018-11-28 20:31:21 -05:00
vars : 3 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ template ( 2 , MyComponent_ng_template_2_Template , 2 , 3 , "ng-template" ) ;
2019-07-07 10:35:58 -04:00
$r3 $ . ɵ ɵ elementContainer ( 3 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ pipe ( 4 , "uppercase" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 4 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 4 , 1 , ctx . valueB ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle ICUs outside of translatable sections' , ( ) = > {
const input = `
< ng - template > { gender , select , male { male } female { female } other { other } } < / n g - t e m p l a t e >
< ng - container > { age , select , 10 { ten } 20 { twenty } other { other } } < / n g - c o n t a i n e r >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS__1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_1 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_0_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_1 $ ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_ng_template_0_Template , 1 , 1 , "ng-template" ) ;
$r3 $ . ɵ ɵ elementContainerStart ( 1 ) ;
$r3 $ . ɵ ɵ i18n ( 2 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should correctly propagate i18n context through nested templates' , ( ) = > {
const input = `
< div i18n >
< ng - template >
Template A : { { valueA | uppercase } }
< ng - template >
Template B : { { valueB } }
< ng - template >
Template C : { { valueC } }
< / n g - t e m p l a t e >
< / n g - t e m p l a t e >
< / n g - t e m p l a t e >
< / div >
` ;
const output = String . raw `
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_2_ng_template_2_ng_template_1_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_0 $ , 3 ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r2 $ = $r3 $ . ɵ ɵ nextContext ( 3 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r2 $ . valueC ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_2_ng_template_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 2 ) ;
$r3 $ . ɵ ɵ template ( 1 , MyComponent_ng_template_2_ng_template_2_ng_template_1_Template , 1 , 1 , "ng-template" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r1 $ = $r3 $ . ɵ ɵ nextContext ( 2 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r1 $ . valueB ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_2051477021417799640 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{$startTagNgTemplate} Template A: {$interpolation} {$startTagNgTemplate} Template B: {$interpolation_1} {$startTagNgTemplate} Template C: {$interpolation_2} {$closeTagNgTemplate}{$closeTagNgTemplate}{$closeTagNgTemplate}" , {
"startTagNgTemplate" : "[\uFFFD*2:1\uFFFD|\uFFFD*2:2\uFFFD|\uFFFD*1:3\uFFFD]" ,
"closeTagNgTemplate" : "[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]" ,
"interpolation" : "\uFFFD0:1\uFFFD" ,
"interpolation_1" : "\uFFFD0:2\uFFFD" ,
"interpolation_2" : "\uFFFD0:3\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_2051477021417799640 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD*2:1 \ uFFFD| \ uFFFD*2:2 \ uFFFD| \ uFFFD*1:3 \ uFFFD]"}:START_TAG_NG_TEMPLATE: Template A: $ ` +
String . raw ` {" \ uFFFD0:1 \ uFFFD"}:INTERPOLATION: $ ` + String . raw
` {"[ \ uFFFD*2:1 \ uFFFD| \ uFFFD*2:2 \ uFFFD| \ uFFFD*1:3 \ uFFFD]"}:START_TAG_NG_TEMPLATE: Template B: $ ` +
String . raw ` {" \ uFFFD0:2 \ uFFFD"}:INTERPOLATION_1: $ ` + String . raw
` {"[ \ uFFFD*2:1 \ uFFFD| \ uFFFD*2:2 \ uFFFD| \ uFFFD*1:3 \ uFFFD]"}:START_TAG_NG_TEMPLATE: Template C: $ ` +
String . raw ` {" \ uFFFD0:3 \ uFFFD"}:INTERPOLATION_2: $ ` + String . raw
` {"[ \ uFFFD/*1:3 \ uFFFD| \ uFFFD/*2:2 \ uFFFD| \ uFFFD/*2:1 \ uFFFD]"}:CLOSE_TAG_NG_TEMPLATE: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/*1:3 \ uFFFD| \ uFFFD/*2:2 \ uFFFD| \ uFFFD/*2:1 \ uFFFD]"}:CLOSE_TAG_NG_TEMPLATE: $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {"[ \ uFFFD/*1:3 \ uFFFD| \ uFFFD/*2:2 \ uFFFD| \ uFFFD/*2:1 \ uFFFD]"}:CLOSE_TAG_NG_TEMPLATE: \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ pipe ( 1 , "uppercase" ) ;
$r3 $ . ɵ ɵ template ( 2 , MyComponent_ng_template_2_ng_template_2_Template , 2 , 1 , "ng-template" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $r3 $ . ɵ ɵ pipeBind1 ( 1 , 1 , $ctx_r0 $ . valueA ) ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 0 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ template ( 2 , MyComponent_ng_template_2_Template , 3 , 3 , "ng-template" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should work with ICUs' , ( ) = > {
const input = `
< ng - container i18n > { gender , select , male { male } female { female } other { other } } < / n g - c o n t a i n e r >
< ng - template i18n > { age , select , 10 { ten } 20 { twenty } other { other } } < / n g - t e m p l a t e >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS__1 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}}" ) ;
$I18N_1 $ = $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS__1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_1 $ ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementContainerStart ( 0 ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
$r3 $ . ɵ ɵ template ( 2 , MyComponent_ng_template_2_Template , 1 , 1 , "ng-template" ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle self-closing tags as content' , ( ) = > {
const input = `
< ng - container i18n >
2018-11-16 12:57:23 -05:00
< img src = "logo.png" title = "Logo" / > is my logo # 1
2018-10-18 13:08:51 -04:00
< / n g - c o n t a i n e r >
< ng - template i18n >
2018-11-16 12:57:23 -05:00
< img src = "logo.png" title = "Logo" / > is my logo # 2
2018-10-18 13:08:51 -04:00
< / n g - t e m p l a t e >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4891196282781544695 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{$tagImg} is my logo #1 " , {
"tagImg" : "\uFFFD#2\uFFFD\uFFFD/#2\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_4891196282781544695 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#2 \ uFFFD \ uFFFD/#2 \ uFFFD"}:TAG_IMG: is my logo #1 \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_461986953980355147 $ $APP_SPEC_TS__2 $ = goog . getMsg ( "{$tagImg} is my logo #2 " , {
"tagImg" : "\uFFFD#1\uFFFD\uFFFD/#1\uFFFD"
} ) ;
$I18N_2 $ = $MSG_EXTERNAL_461986953980355147 $ $APP_SPEC_TS__2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#1 \ uFFFD \ uFFFD/#1 \ uFFFD"}:TAG_IMG: is my logo #2 \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_ng_template_3_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_2 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 1 , "img" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
consts : [ [ "src" , "logo.png" , "title" , "Logo" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementContainerStart ( 0 ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ element ( 2 , "img" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
$r3 $ . ɵ ɵ template ( 3 , MyComponent_ng_template_3_Template , 2 , 0 , "ng-template" ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2019-02-25 15:42:50 -05:00
it ( 'should not emit duplicate i18n consts for nested <ng-container>s' , ( ) = > {
const input = `
< ng - template i18n >
Root content
< ng - container * ngIf = "visible" >
Nested content
< / n g - c o n t a i n e r >
< / n g - t e m p l a t e >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8537814667662432133 $ $APP_SPEC_TS__0 $ = goog . getMsg ( " Root content {$startTagNgContainer} Nested content {$closeTagNgContainer}" , {
"startTagNgContainer" : "\uFFFD*1:1\uFFFD\uFFFD#1:1\uFFFD" ,
"closeTagNgContainer" : "\uFFFD/#1:1\uFFFD\uFFFD/*1:1\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_8537814667662432133 $ $APP_SPEC_TS__0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Root content $ ` +
2019-07-30 13:02:17 -04:00
String . raw
2019-09-06 07:26:48 -04:00
` {" \ uFFFD*1:1 \ uFFFD \ uFFFD#1:1 \ uFFFD"}:START_TAG_NG_CONTAINER: Nested content $ ` +
String . raw ` {" \ uFFFD/#1:1 \ uFFFD \ uFFFD/*1:1 \ uFFFD"}:CLOSE_TAG_NG_CONTAINER: \` ;
2019-04-11 05:17:49 -04:00
}
2019-02-25 15:42:50 -05:00
…
` ;
verify ( input , output ) ;
} ) ;
it ( 'should not emit duplicate i18n consts for elements with the same content' , ( ) = > {
const input = `
< div i18n > Test < / div >
< div i18n > Test < / div >
` ;
2019-10-02 13:17:56 -04:00
// TODO(FW-635): currently we generate unique consts for each i18n block even though it
// might contain the same content. This should be optimized by translation statements caching,
// that can be implemented in the future within FW-635.
2019-02-25 15:42:50 -05:00
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_6563391987554512024 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "Test" ) ;
$I18N_0 $ = $MSG_EXTERNAL_6563391987554512024 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Test \` ;
2019-04-11 05:17:49 -04:00
}
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_6563391987554512024 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "Test" ) ;
$I18N_1 $ = $MSG_EXTERNAL_6563391987554512024 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Test \` ;
2019-04-11 05:17:49 -04:00
}
2019-02-25 15:42:50 -05:00
…
` ;
verify ( input , output ) ;
} ) ;
2019-07-07 10:35:58 -04:00
it ( 'should generate a self-closing container instruction for ng-container inside i18n' , ( ) = > {
const input = `
< div i18n >
Hello < ng - container > there < / n g - c o n t a i n e r >
< / div >
` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-07 10:35:58 -04:00
const $MSG_APP_SPEC_TS_1 $ = goog . getMsg ( " Hello {$startTagNgContainer}there{$closeTagNgContainer}" , { "startTagNgContainer" : "\uFFFD#2\uFFFD" , "closeTagNgContainer" : "\uFFFD/#2\uFFFD" } ) ;
$I18N_0 $ = $MSG_APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Hello $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_TAG_NG_CONTAINER:there $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_TAG_NG_CONTAINER: \` ;
2019-07-07 10:35:58 -04:00
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2019-07-07 10:35:58 -04:00
vars : 0 ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , I18N_0 ) ;
$r3 $ . ɵ ɵ elementContainer ( 2 ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should not generate a self-closing container instruction for ng-container with non-text content inside i18n' ,
( ) = > {
const input = `
< div i18n >
Hello < ng - container > there < strong > ! < / strong > < / n g - c o n t a i n e r >
< / div >
` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-07 10:35:58 -04:00
const $MSG_APP_SPEC_TS_1 $ = goog . getMsg ( " Hello {$startTagNgContainer}there {$startTagStrong}!{$closeTagStrong}{$closeTagNgContainer}" , { "startTagNgContainer" : "\uFFFD#2\uFFFD" , "startTagStrong" : "\uFFFD#3\uFFFD" , "closeTagStrong" : "\uFFFD/#3\uFFFD" , "closeTagNgContainer" : "\uFFFD/#2\uFFFD" } ) ;
$I18N_0 $ = $MSG_APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` Hello $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_TAG_NG_CONTAINER:there $ ` +
String . raw ` {" \ uFFFD#3 \ uFFFD"}:START_TAG_STRONG:! $ ` +
String . raw ` {" \ uFFFD/#3 \ uFFFD"}:CLOSE_TAG_STRONG: $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_TAG_NG_CONTAINER: \` ;
2019-07-07 10:35:58 -04:00
}
…
2019-09-23 14:08:51 -04:00
decls : 4 ,
2019-07-07 10:35:58 -04:00
vars : 0 ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , I18N_0 ) ;
$r3 $ . ɵ ɵ elementContainerStart ( 2 ) ;
$r3 $ . ɵ ɵ element ( 3 , "strong" ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2019-09-11 17:00:59 -04:00
// Note: applying structural directives to <ng-template> is typically user error, but it is
// technically allowed, so we need to support it.
it ( 'should handle structural directives' , ( ) = > {
const input = `
< ng - template * ngIf = "someFlag" i18n > Content A < / n g - t e m p l a t e >
< ng - container * ngIf = "someFlag" i18n > Content B < / n g - c o n t a i n e r >
` ;
const output = String . raw `
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-09-11 17:00:59 -04:00
const $MSG_EXTERNAL_3308216566145348998 $ $APP_SPEC_TS___2 $ = goog . getMsg ( "Content A" ) ;
$I18N_1 $ = $MSG_EXTERNAL_3308216566145348998 $ $APP_SPEC_TS___2 $ ;
} else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` Content A \` ;
2019-09-11 17:00:59 -04:00
}
function MyComponent_0_ng_template_0_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_1 $ ) ;
}
}
function MyComponent_0_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ template ( 0 , MyComponent_0_ng_template_0_Template , 1 , 0 , "ng-template" ) ;
}
}
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-09-11 17:00:59 -04:00
const $MSG_EXTERNAL_8349021389088127654 $ $APP_SPEC_TS__4 $ = goog . getMsg ( "Content B" ) ;
$I18N_3 $ = $MSG_EXTERNAL_8349021389088127654 $ $APP_SPEC_TS__4 $ ;
} else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` Content B \` ;
2019-09-11 17:00:59 -04:00
}
function MyComponent_ng_container_1_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ elementContainerStart ( 0 ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_3 $ ) ;
$r3 $ . ɵ ɵ elementContainerEnd ( ) ;
}
}
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2019-09-11 17:00:59 -04:00
vars : 2 ,
2019-09-23 14:08:51 -04:00
consts : [ [ 4 , "ngIf" ] ] ,
2019-09-11 17:00:59 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 0 , MyComponent_0_Template , 1 , 0 , undefined , 0 ) ;
$r3 $ . ɵ ɵ template ( 1 , MyComponent_ng_container_1_Template , 2 , 0 , "ng-container" , 0 ) ;
2019-09-11 17:00:59 -04:00
}
if ( rf & 2 ) {
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . someFlag ) ;
$r3 $ . ɵ ɵ advance ( 1 ) ;
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . someFlag ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
} ) ;
describe ( 'whitespace preserving mode' , ( ) = > {
it ( 'should keep inner content of i18n block as is' , ( ) = > {
const input = `
< div i18n >
Some text
< span > Text inside span < / span >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_963542717423364282 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "\n Some text\n {$startTagSpan}Text inside span{$closeTagSpan}\n " , {
"startTagSpan" : "\uFFFD#3\uFFFD" ,
"closeTagSpan" : "\uFFFD/#3\uFFFD"
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_963542717423364282 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-01 19:44:50 -04:00
$I18N_0 $ = $localize \ `
Some text
$ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD#3 \ uFFFD"}:START_TAG_SPAN:Text inside span $ ` +
2019-10-01 19:44:50 -04:00
String . raw ` {" \ uFFFD/#3 \ uFFFD"}:CLOSE_TAG_SPAN:
\ ` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ text ( 0 , "\n " ) ;
$r3 $ . ɵ ɵ elementStart ( 1 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 2 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ element ( 3 , "span" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ text ( 4 , "\n " ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output , { inputArgs : { preserveWhitespaces : true } } ) ;
} ) ;
} ) ;
describe ( 'icu logic' , ( ) = > {
it ( 'should handle single icus' , ( ) = > {
const input = `
< div i18n > { gender , select , male { male } female { female } other { other } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should properly escape quotes in content' , ( ) = > {
const input = `
< div i18n > { gender , select , single { 'single quotes' } double { "double quotes" } other { other } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_4166854826696768832 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, single {'single quotes'} double {\"double quotes\"} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_4166854826696768832 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, single {'single quotes'} double {"double quotes"} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-10-18 13:08:51 -04:00
` ;
verify ( input , output ) ;
} ) ;
2019-01-13 19:56:00 -05:00
it ( 'should support ICU-only templates' , ( ) = > {
const input = `
{ age , select , 10 { ten } 20 { twenty } other { other } }
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2019-04-11 05:17:49 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-01-13 19:56:00 -05:00
…
2019-09-23 14:08:51 -04:00
decls : 1 ,
2019-01-13 19:56:00 -05:00
vars : 1 ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18n ( 0 , $I18N_0 $ ) ;
2019-01-13 19:56:00 -05:00
}
if ( rf & 2 ) {
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2019-01-13 19:56:00 -05:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should generate i18n instructions for icus generated outside of i18n blocks' , ( ) = > {
const input = `
< div > { gender , select , male { male } female { female } other { other } } < / div >
< div * ngIf = "visible" title = "icu only" >
{ age , select , 10 { ten } 20 { twenty } other { other } }
< / div >
< div * ngIf = "available" title = "icu and text" >
You have { count , select , 0 { no emails } 1 { one email } other { { { count } } emails } } .
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS__3 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}}" ) ;
$I18N_3 $ = $MSG_EXTERNAL_8806993169187953163 $ $APP_SPEC_TS__3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_3 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_3 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 2 ) ;
2019-08-24 17:02:30 -04:00
$r3 $ . ɵ ɵ text ( 1 , " " ) ;
2019-08-02 07:42:04 -04:00
$r3 $ . ɵ ɵ i18n ( 2 , $I18N_3 $ ) ;
2019-08-24 17:02:30 -04:00
$r3 $ . ɵ ɵ text ( 3 , " " ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . age ) ;
2019-08-02 07:42:04 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2018-10-18 13:08:51 -04:00
}
}
2019-04-11 05:17:49 -04:00
var $I18N_5 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_1922743304863699161 $ $APP_SPEC_TS__5 $ = goog . getMsg ( "{VAR_SELECT, select, 0 {no emails} 1 {one email} other {{INTERPOLATION} emails}}" ) ;
2019-04-11 05:17:49 -04:00
$I18N_5 $ = $MSG_EXTERNAL_1922743304863699161 $ $APP_SPEC_TS__5 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_5 $ = $localize \ ` {VAR_SELECT, select, 0 {no emails} 1 {one email} other {{INTERPOLATION} emails}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_5 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_5 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"INTERPOLATION" : "\uFFFD1\uFFFD"
2018-11-16 12:57:23 -05:00
} ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_3_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" , 3 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ text ( 1 , " You have " ) ;
$r3 $ . ɵ ɵ i18n ( 2 , $I18N_5 $ ) ;
$r3 $ . ɵ ɵ text ( 3 , ". " ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r1 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r1 $ . count ) ( $ctx_r1 $ . count ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 2 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 4 ,
2018-11-28 20:31:21 -05:00
vars : 3 ,
2019-09-23 14:08:51 -04:00
consts : [ [ "title" , "icu only" , $ { AttributeMarker . Template } , "ngIf" ] , [ "title" , "icu and text" , $ { AttributeMarker . Template } , "ngIf" ] , [ "title" , "icu only" ] , [ "title" , "icu and text" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 2 , MyComponent_div_2_Template , 4 , 1 , "div" , 0 ) ;
$r3 $ . ɵ ɵ template ( 3 , MyComponent_div_3_Template , 4 , 2 , "div" , 1 ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . available ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-11-29 19:21:16 -05:00
it ( 'should support interpolation with custom interpolation config' , ( ) = > {
const input = `
< div i18n > { age , select , 10 { ten } 20 { twenty } other { { % other % } } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_2949673783721159566 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} other {{INTERPOLATION}}}" ) ;
2019-04-11 05:17:49 -04:00
$I18N_0 $ = $MSG_EXTERNAL_2949673783721159566 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} other {{INTERPOLATION}}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"INTERPOLATION" : "\uFFFD1\uFFFD"
2018-11-29 19:21:16 -05:00
} ) ;
…
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-11-29 19:21:16 -05:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . age ) ( ctx . other ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-11-29 19:21:16 -05:00
}
}
` ;
2019-05-09 14:47:25 -04:00
2018-11-29 19:21:16 -05:00
verify ( input , output , { inputArgs : { interpolation : [ '{%' , '%}' ] } } ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should handle icus with html' , ( ) = > {
const input = `
< div i18n >
{ gender , select , male { male - < b > male < / b > } female { female < b > female < / b > } other { < div class = "other" > < i > other < / i > < / div > } }
< b > Other content < / b >
< div class = "other" > < i > Another content < / i > < / div >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_2417296354340576868 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male - {START_BOLD_TEXT}male{CLOSE_BOLD_TEXT}} female {female {START_BOLD_TEXT}female{CLOSE_BOLD_TEXT}} other {{START_TAG_DIV}{START_ITALIC_TEXT}other{CLOSE_ITALIC_TEXT}{CLOSE_TAG_DIV}}}" ) ;
2019-04-11 05:17:49 -04:00
$I18N_1 $ = $MSG_EXTERNAL_2417296354340576868 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male - {START_BOLD_TEXT}male{CLOSE_BOLD_TEXT}} female {female {START_BOLD_TEXT}female{CLOSE_BOLD_TEXT}} other {{START_TAG_DIV}{START_ITALIC_TEXT}other{CLOSE_ITALIC_TEXT}{CLOSE_TAG_DIV}}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"START_BOLD_TEXT" : "<b>" ,
"CLOSE_BOLD_TEXT" : "</b>" ,
"START_ITALIC_TEXT" : "<i>" ,
"CLOSE_ITALIC_TEXT" : "</i>" ,
"START_TAG_DIV" : "<div class=\"other\">" ,
"CLOSE_TAG_DIV" : "</div>"
2018-11-16 12:57:23 -05:00
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_EXTERNAL_5791551881115084301 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " {$icu} {$startBoldText}Other content{$closeBoldText}{$startTagDiv}{$startItalicText}Another content{$closeItalicText}{$closeTagDiv}" , {
2019-04-11 05:17:49 -04:00
"startBoldText" : "\uFFFD#2\uFFFD" ,
"closeBoldText" : "\uFFFD/#2\uFFFD" ,
"startTagDiv" : "\uFFFD#3\uFFFD" ,
"startItalicText" : "\uFFFD#4\uFFFD" ,
"closeItalicText" : "\uFFFD/#4\uFFFD" ,
"closeTagDiv" : "\uFFFD/#3\uFFFD" ,
2019-05-21 15:59:53 -04:00
"icu" : $I18N_1 $
2019-04-11 05:17:49 -04:00
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_5791551881115084301 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` { $ I18N_1 $ }:ICU: $ ` +
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_BOLD_TEXT:Other content $ ` +
String . raw ` {" \ uFFFD/#2 \ uFFFD"}:CLOSE_BOLD_TEXT: $ ` +
String . raw ` {" \ uFFFD#3 \ uFFFD"}:START_TAG_DIV: $ ` +
String . raw ` {" \ uFFFD#4 \ uFFFD"}:START_ITALIC_TEXT:Another content $ ` +
String . raw ` {" \ uFFFD/#4 \ uFFFD"}:CLOSE_ITALIC_TEXT: $ ` +
String . raw ` {" \ uFFFD/#3 \ uFFFD"}:CLOSE_TAG_DIV: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 5 ,
2018-11-28 20:31:21 -05:00
vars : 1 ,
2019-09-23 14:08:51 -04:00
consts : [ [ 1 , "other" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ element ( 2 , "b" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ elementStart ( 3 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ element ( 4 , "i" ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 4 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle icus with expressions' , ( ) = > {
const input = `
< div i18n > { gender , select , male { male of age : { { ageA + ageB + ageC } } } female { female } other { other } } < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_6879461626778511059 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, male {male of age: {INTERPOLATION}} female {female} other {other}}" ) ;
2019-04-11 05:17:49 -04:00
$I18N_0 $ = $MSG_EXTERNAL_6879461626778511059 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, male {male of age: {INTERPOLATION}} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"INTERPOLATION" : "\uFFFD1\uFFFD"
2018-11-16 12:57:23 -05:00
} ) ;
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ( ctx . ageA + ctx . ageB + ctx . ageC ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle multiple icus in one block' , ( ) = > {
const input = `
< div i18n >
{ gender , select , male { male } female { female } other { other } }
{ age , select , 10 { ten } 20 { twenty } 30 { thirty } other { other } }
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_1 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7068143081688428291 $ $APP_SPEC_TS_2 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}}" ) ;
$I18N_2 $ = $MSG_EXTERNAL_7068143081688428291 $ $APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_2 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_2 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD1\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_EXTERNAL_2967249209167308918 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " {$icu} {$icu_1} " , {
2019-04-11 05:17:49 -04:00
"icu" : $I18N_1 $ ,
"icu_1" : $I18N_2 $
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_2967249209167308918 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` { $ I18N_1 $ }:ICU: $ ` + String . raw ` { $ I18N_2 $ }:ICU_1: \` ;
2019-04-11 05:17:49 -04:00
}
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ( ctx . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle multiple icus that share same placeholder' , ( ) = > {
const input = `
< div i18n >
{ gender , select , male { male } female { female } other { other } }
< div >
{ gender , select , male { male } female { female } other { other } }
< / div >
< div * ngIf = "visible" >
{ gender , select , male { male } female { female } other { other } }
< / div >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_1 $ = $MSG_APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_2 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_APP_SPEC_TS_2 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_2 $ = $MSG_APP_SPEC_TS_2 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_2 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_2 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_2 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD1\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_4 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_APP_SPEC_TS__4 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_4 $ = $MSG_APP_SPEC_TS__4 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_4 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_4 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_4 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0:1\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_APP_SPEC_TS_0 $ = goog . getMsg ( " {$icu} {$startTagDiv} {$icu} {$closeTagDiv}{$startTagDiv_1} {$icu} {$closeTagDiv}" , {
2019-04-11 05:17:49 -04:00
"startTagDiv" : "\uFFFD#2\uFFFD" ,
"closeTagDiv" : "[\uFFFD/#2\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*3:1\uFFFD]" ,
"startTagDiv_1" : "\uFFFD*3:1\uFFFD\uFFFD#1:1\uFFFD" ,
"icu" : "\uFFFDI18N_EXP_ICU\uFFFD"
} ) ;
$I18N_0 $ = $MSG_APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFDI18N_EXP_ICU \ uFFFD"}:ICU: $ ` +
String . raw ` {" \ uFFFD#2 \ uFFFD"}:START_TAG_DIV: $ ` +
String . raw ` {" \ uFFFDI18N_EXP_ICU \ uFFFD"}:ICU: $ ` + String . raw
` {"[ \ uFFFD/#2 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*3:1 \ uFFFD]"}:CLOSE_TAG_DIV: $ ` +
String . raw ` {" \ uFFFD*3:1 \ uFFFD \ uFFFD#1:1 \ uFFFD"}:START_TAG_DIV_1: $ ` +
String . raw ` {" \ uFFFDI18N_EXP_ICU \ uFFFD"}:ICU: $ ` + String . raw
` {"[ \ uFFFD/#2 \ uFFFD| \ uFFFD/#1:1 \ uFFFD \ uFFFD/*3:1 \ uFFFD]"}:CLOSE_TAG_DIV: \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2019-04-11 05:17:49 -04:00
"ICU" : [ $I18N_1 $ , $I18N_2 $ , $I18N_4 $ ]
2018-10-18 13:08:51 -04:00
} ) ;
2018-12-19 15:17:38 -05:00
function MyComponent_div_3_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ element ( 1 , "div" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 4 ,
2018-11-28 20:31:21 -05:00
vars : 3 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ element ( 2 , "div" ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 3 , MyComponent_div_3_Template , 2 , 1 , "div" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 3 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . visible ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
2018-11-16 12:57:23 -05:00
// TODO(akushnir): this use-case is currently supported with
// file-based prefix for translation const names. Translation statements
// caching is required to support this use-case (FW-635) with id-based consts.
verify ( input , output , { skipIdBasedCheck : true } ) ;
2018-10-18 13:08:51 -04:00
} ) ;
it ( 'should handle nested icus' , ( ) = > {
const input = `
< div i18n >
{ gender , select ,
male { male of age : { age , select , 10 { ten } 20 { twenty } 30 { thirty } other { other } } }
female { female }
other { other }
}
< / div >
` ;
const output = String . raw `
2019-08-02 07:42:04 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_343563413083115114 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT_1, select, male {male of age: {VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}}} female {female} other {other}}" ) ;
2019-08-02 07:42:04 -04:00
$I18N_1 $ = $MSG_EXTERNAL_343563413083115114 $ $APP_SPEC_TS_0 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT_1, select, male {male of age: {VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}}} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-08-02 07:42:04 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-10-18 13:08:51 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"VAR_SELECT_1" : "\uFFFD1\uFFFD"
} ) ;
2019-08-02 07:42:04 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_EXTERNAL_3052001905251380936 $ $APP_SPEC_TS_3 $ = goog . getMsg ( " {$icu} " , { "icu" : $I18N_1 $ } ) ;
$I18N_0 $ = $MSG_EXTERNAL_3052001905251380936 $ $APP_SPEC_TS_3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` { $ I18N_1 $ }:ICU: \` ;
2019-08-02 07:42:04 -04:00
} …
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . age ) ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
const exceptions = {
'3052001905251380936' : 'Wrapper message generated by "ng xi18n" around ICU: " {$ICU} "'
} ;
2018-12-04 23:54:42 -05:00
verify ( input , output , { exceptions } ) ;
2018-10-18 13:08:51 -04:00
} ) ;
2019-07-11 14:59:22 -04:00
it ( 'nested with interpolations in "other" blocks' , ( ) = > {
const input = `
< div i18n > { count , plural ,
= 0 { zero }
= 2 { { { count } } { name , select ,
cat { cats }
dog { dogs }
other { animals } } ! }
other { other - { { count } } }
} < / div >
` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-11 14:59:22 -04:00
const $MSG_EXTERNAL_6870293071705078389 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_PLURAL, plural, =0 {zero} =2 {{INTERPOLATION} {VAR_SELECT, select, cat {cats} dog {dogs} other {animals}} !} other {other - {INTERPOLATION}}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_6870293071705078389 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_PLURAL, plural, =0 {zero} =2 {{INTERPOLATION} {VAR_SELECT, select, cat {cats} dog {dogs} other {animals}} !} other {other - {INTERPOLATION}}} \` ;
2019-07-11 14:59:22 -04:00
}
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"VAR_PLURAL" : "\uFFFD1\uFFFD" ,
"INTERPOLATION" : "\uFFFD2\uFFFD"
} ) ;
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2019-07-11 14:59:22 -04:00
vars : 3 ,
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-07-11 14:59:22 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . name ) ( ctx . count ) ( ctx . count ) ;
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
}
}
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
it ( 'should handle icus in different contexts' , ( ) = > {
const input = `
< div i18n >
{ gender , select , male { male } female { female } other { other } }
< span * ngIf = "ageVisible" >
{ age , select , 10 { ten } 20 { twenty } 30 { thirty } other { other } }
< / span >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male} female {female} other {other}}" ) ;
$I18N_1 $ = $MSG_EXTERNAL_7842238767399919809 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male} female {female} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-04-11 05:17:49 -04:00
const $MSG_EXTERNAL_7068143081688428291 $ $APP_SPEC_TS__3 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}}" ) ;
$I18N_3 $ = $MSG_EXTERNAL_7068143081688428291 $ $APP_SPEC_TS__3 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_3 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_3 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_3 $ , {
2018-11-16 12:57:23 -05:00
"VAR_SELECT" : "\uFFFD0:1\uFFFD"
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_EXTERNAL_1194472282609532229 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " {$icu} {$startTagSpan} {$icu_1} {$closeTagSpan}" , {
2019-04-11 05:17:49 -04:00
"startTagSpan" : "\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD" ,
"closeTagSpan" : "\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD" ,
"icu" : $I18N_1 $ ,
"icu_1" : $I18N_3 $
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_1194472282609532229 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` { $ I18N_1 $ }:ICU: $ ` +
String . raw ` {" \ uFFFD*2:1 \ uFFFD \ uFFFD#1:1 \ uFFFD"}:START_TAG_SPAN: $ ` +
String . raw ` { $ I18N_3 $ }:ICU_1: $ ` +
String . raw ` {" \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_span_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ element ( 1 , "span" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 2 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 2 , MyComponent_span_2_Template , 2 , 1 , "span" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . ageVisible ) ;
2019-06-17 11:07:44 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle icus with interpolations' , ( ) = > {
const input = `
< div i18n >
{ gender , select , male { male { { weight } } } female { female { { height } } } other { other } }
< span * ngIf = "ageVisible" >
{ age , select , 10 { ten } 20 { twenty } 30 { thirty } other { other : { { otherAge } } } }
< / span >
< / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_1 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_7825031864601787094 $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, male {male {INTERPOLATION}} female {female {INTERPOLATION_1}} other {other}}" ) ;
2019-04-11 05:17:49 -04:00
$I18N_1 $ = $MSG_EXTERNAL_7825031864601787094 $ $APP_SPEC_TS_1 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_1 $ = $localize \ ` {VAR_SELECT, select, male {male {INTERPOLATION}} female {female {INTERPOLATION_1}} other {other}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_1 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_1 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"INTERPOLATION" : "\uFFFD1\uFFFD" ,
"INTERPOLATION_1" : "\uFFFD2\uFFFD"
2018-11-16 12:57:23 -05:00
} ) ;
2019-09-23 14:08:51 -04:00
var $I18N_3 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_2310343208266678305 $ $APP_SPEC_TS__3 $ = goog . getMsg ( "{VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other: {INTERPOLATION}}}" ) ;
2019-09-23 14:08:51 -04:00
$I18N_3 $ = $MSG_EXTERNAL_2310343208266678305 $ $APP_SPEC_TS__3 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_4 $ = $localize \ ` {VAR_SELECT, select, 10 {ten} 20 {twenty} 30 {thirty} other {other: {INTERPOLATION}}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-09-23 14:08:51 -04:00
$I18N_3 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_3 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0:1\uFFFD" ,
"INTERPOLATION" : "\uFFFD1:1\uFFFD"
2018-11-16 12:57:23 -05:00
} ) ;
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-08-02 07:42:04 -04:00
const $MSG_EXTERNAL_7186042105600518133 $ $APP_SPEC_TS_0 $ = goog . getMsg ( " {$icu} {$startTagSpan} {$icu_1} {$closeTagSpan}" , {
2019-04-11 05:17:49 -04:00
"startTagSpan" : "\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD" ,
"closeTagSpan" : "\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD" ,
"icu" : $I18N_1 $ ,
2019-09-23 14:08:51 -04:00
"icu_1" : $I18N_3 $
2019-04-11 05:17:49 -04:00
} ) ;
$I18N_0 $ = $MSG_EXTERNAL_7186042105600518133 $ $APP_SPEC_TS_0 $ ;
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {I18N_1}:ICU: $ ` +
String . raw ` {" \ uFFFD*2:1 \ uFFFD \ uFFFD#1:1 \ uFFFD"}:START_TAG_SPAN: $ ` +
2019-09-23 14:08:51 -04:00
String . raw ` {I18N_3}:ICU_1: $ ` +
2019-09-06 07:26:48 -04:00
String . raw ` {" \ uFFFD/#1:1 \ uFFFD \ uFFFD/*2:1 \ uFFFD"}:CLOSE_TAG_SPAN: \` ;
2019-04-11 05:17:49 -04:00
}
2018-12-19 15:17:38 -05:00
function MyComponent_span_2_Template ( rf , ctx ) {
2018-10-18 13:08:51 -04:00
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nStart ( 0 , $I18N_0 $ , 1 ) ;
$r3 $ . ɵ ɵ element ( 1 , "span" ) ;
$r3 $ . ɵ ɵ i18nEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-05-17 21:49:21 -04:00
const $ctx_r0 $ = $r3 $ . ɵ ɵ nextContext ( ) ;
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( $ctx_r0 $ . age ) ( $ctx_r0 $ . otherAge ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 0 ) ;
2018-10-18 13:08:51 -04:00
}
}
…
2019-09-23 14:08:51 -04:00
decls : 3 ,
2018-11-28 20:31:21 -05:00
vars : 4 ,
2019-09-23 14:08:51 -04:00
consts : [ [ $ { AttributeMarker . Template } , "ngIf" ] ] ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18nStart ( 1 , $I18N_0 $ ) ;
2019-09-23 14:08:51 -04:00
$r3 $ . ɵ ɵ template ( 2 , MyComponent_span_2_Template , 2 , 2 , "span" , 0 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nEnd ( ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-09-06 17:43:16 -04:00
$r3 $ . ɵ ɵ advance ( 2 ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ property ( "ngIf" , ctx . ageVisible ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ( ctx . weight ) ( ctx . height ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
it ( 'should handle icus with named interpolations' , ( ) = > {
const input = `
< div i18n > {
gender ,
select ,
male { male { { weight // i18n(ph="PH_A") }}}
female { female { { height // i18n(ph="PH_B") }}}
2019-07-08 20:37:26 -04:00
other { other { { age // i18n(ph="PH WITH SPACES") }}}
2018-10-18 13:08:51 -04:00
} < / div >
` ;
const output = String . raw `
2019-04-11 05:17:49 -04:00
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-07-08 20:37:26 -04:00
const $MSG_EXTERNAL_6318060397235942326 $ $APP_SPEC_TS_0 $ = goog . getMsg ( "{VAR_SELECT, select, male {male {PH_A}} female {female {PH_B}} other {other {PH_WITH_SPACES}}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_6318060397235942326 $ $APP_SPEC_TS_0 $ ;
2019-04-11 05:17:49 -04:00
}
else {
2019-10-02 13:17:56 -04:00
$I18N_0 $ = $localize \ ` {VAR_SELECT, select, male {male {PH_A}} female {female {PH_B}} other {other {PH_WITH_SPACES}}} \` ;
2019-04-11 05:17:49 -04:00
}
2019-05-17 21:49:21 -04:00
$I18N_0 $ = $r3 $ . ɵ ɵ i18nPostprocess ( $I18N_0 $ , {
2019-07-08 20:37:26 -04:00
"VAR_SELECT" : "\uFFFD0\uFFFD" ,
"PH_A" : "\uFFFD1\uFFFD" ,
"PH_B" : "\uFFFD2\uFFFD" ,
"PH_WITH_SPACES" : "\uFFFD3\uFFFD"
2018-11-16 12:57:23 -05:00
} ) ;
2018-10-18 13:08:51 -04:00
…
2019-09-23 14:08:51 -04:00
decls : 2 ,
2018-11-28 20:31:21 -05:00
vars : 4 ,
2018-10-18 13:08:51 -04:00
template : function MyComponent_Template ( rf , ctx ) {
if ( rf & 1 ) {
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ elementStart ( 0 , "div" ) ;
$r3 $ . ɵ ɵ i18n ( 1 , $I18N_0 $ ) ;
$r3 $ . ɵ ɵ elementEnd ( ) ;
2018-10-18 13:08:51 -04:00
}
if ( rf & 2 ) {
2019-12-16 14:55:50 -05:00
$r3 $ . ɵ ɵ advance ( 1 ) ;
2019-06-25 11:14:07 -04:00
$r3 $ . ɵ ɵ i18nExp ( ctx . gender ) ( ctx . weight ) ( ctx . height ) ( ctx . age ) ;
2019-05-17 21:49:21 -04:00
$r3 $ . ɵ ɵ i18nApply ( 1 ) ;
2018-10-18 13:08:51 -04:00
}
}
` ;
verify ( input , output ) ;
} ) ;
2019-10-15 18:54:14 -04:00
it ( 'should attach metadata in case an ICU represents the whole message' , ( ) = > {
const input = `
< div i18n = "meaningA|descA@@idA" > { count , select , 1 { one } other { more than one } } < / div >
` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 06:58:10 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) {
2019-10-15 18:54:14 -04:00
/ * *
* @desc descA
* @meaning meaningA
* /
const $MSG_EXTERNAL_idA $ $APP_SPEC_TS_1 $ = goog . getMsg ( "{VAR_SELECT, select, 1 {one} other {more than one}}" ) ;
$I18N_0 $ = $MSG_EXTERNAL_idA $ $APP_SPEC_TS_1 $ ;
}
else {
$I18N_0 $ = $localize \ ` :meaningA|descA@@idA:{VAR_SELECT, select, 1 {one} other {more than one}} \` ;
}
$I18N_0 $ = i0 . ɵ ɵ i18nPostprocess ( $I18N_0 $ , { "VAR_SELECT" : "\uFFFD0\uFFFD" } ) ;
` ;
verify ( input , output ) ;
} ) ;
2018-10-18 13:08:51 -04:00
} ) ;
2019-12-03 03:36:38 -05:00
describe ( '$localize legacy message ids' , ( ) = > {
it ( 'should add legacy message ids if `enableI18nLegacyMessageIdFormat` is true' , ( ) = > {
const input = ` <div i18n>Some Message</div> ` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 20:07:09 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) { … }
2019-12-03 03:36:38 -05:00
else {
$I18N_0 $ = $localize \ ` :␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message \` ;
}
…
` ;
verify ( input , output , { compilerOptions : { enableI18nLegacyMessageIdFormat : true } } ) ;
} ) ;
it ( 'should add legacy message ids if `enableI18nLegacyMessageIdFormat` is undefined' , ( ) = > {
const input = ` <div i18n>Some Message</div> ` ;
const output = String . raw `
var $I18N_0 $ ;
2019-12-03 20:07:09 -05:00
if ( typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode ) { … }
2019-12-03 03:36:38 -05:00
else {
$I18N_0 $ = $localize \ ` :␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message \` ;
}
…
` ;
verify ( input , output , { compilerOptions : { enableI18nLegacyMessageIdFormat : undefined } } ) ;
} ) ;
} ) ;
2018-10-18 13:08:51 -04:00
describe ( 'errors' , ( ) = > {
2019-08-03 15:24:48 -04:00
const verifyNestedSectionsError = ( errorThrown : any , expectedErrorText : string ) = > {
expect ( errorThrown . ngParseErrors . length ) . toBe ( 1 ) ;
const msg = errorThrown . ngParseErrors [ 0 ] . toString ( ) ;
expect ( msg ) . toContain (
'Cannot mark an element as translatable inside of a translatable section. Please remove the nested i18n marker.' ) ;
expect ( msg ) . toContain ( expectedErrorText ) ;
expect ( msg ) . toMatch ( /app\/spec\.ts\@\d+\:\d+/ ) ;
} ;
2018-10-18 13:08:51 -04:00
it ( 'should throw on nested i18n sections' , ( ) = > {
const files = getAppFilesWithTemplate ( `
2019-08-03 15:24:48 -04:00
< div i18n >
< div i18n > Some content < / div >
< / div >
` );
try {
compile ( files , angularFiles ) ;
} catch ( error ) {
verifyNestedSectionsError ( error , '[ERROR ->]<div i18n>Some content</div>' ) ;
}
} ) ;
it ( 'should throw on nested i18n sections with tags in between' , ( ) = > {
const files = getAppFilesWithTemplate ( `
< div i18n >
< div >
< div i18n > Some content < / div >
< / div >
< / div >
2018-10-18 13:08:51 -04:00
` );
2019-08-03 15:24:48 -04:00
try {
compile ( files , angularFiles ) ;
} catch ( error ) {
verifyNestedSectionsError ( error , '[ERROR ->]<div i18n>Some content</div>' ) ;
}
2018-02-14 13:54:00 -05:00
} ) ;
2019-08-03 15:24:48 -04:00
it ( 'should throw on nested i18n sections represented with <ng-container>s' , ( ) = > {
const files = getAppFilesWithTemplate ( `
< ng - container i18n >
< div >
< ng - container i18n > Some content < / n g - c o n t a i n e r >
< / div >
< / n g - c o n t a i n e r >
` );
try {
compile ( files , angularFiles ) ;
} catch ( error ) {
verifyNestedSectionsError (
error , '[ERROR ->]<ng-container i18n>Some content</ng-container>' ) ;
}
} ) ;
2018-02-14 13:54:00 -05:00
} ) ;
} ) ;