fix(ivy): template compiler should render correct $localize placeholder names (#32509)

The `goog.getMsg()` function requires placeholder names to be camelCased.

This is not the case for `$localize`. Here placeholder names need
match what is serialized to translation files.

Specifically such placeholder names keep their casing but have all characters
that are not in `a-z`, `A-Z`, `0-9` and `_` converted to `_`.

PR Close #32509
This commit is contained in:
Pete Bacon Darwin 2019-09-06 12:26:48 +01:00 committed by Matias Niemelä
parent 9166baf709
commit ea6a2e9f25
7 changed files with 1344 additions and 1279 deletions

View File

@ -417,7 +417,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`intro $` + $I18N_2$ = $localize \`intro $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
var $I18N_3$; var $I18N_3$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -432,7 +432,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_3$ = $localize \`$` + $I18N_3$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c1$ = [ const $_c1$ = [
"aria-roledescription", $I18N_1$, "aria-roledescription", $I18N_1$,
@ -453,9 +453,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_6$ = $localize \`$` + $I18N_6$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: and $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: and $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: and again $` + String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1: and again $` +
String.raw `{"\uFFFD2\uFFFD"}:interpolation_2:\`; String.raw `{"\uFFFD2\uFFFD"}:INTERPOLATION_2:\`;
} }
var $I18N_7$; var $I18N_7$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -466,7 +466,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_7$ = $localize \`$` + $I18N_7$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c3$ = [ const $_c3$ = [
"title", $I18N_6$, "title", $I18N_6$,
@ -518,7 +518,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \`intro $` + $I18N_1$ = $localize \`intro $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c3$ = ["title", $I18N_1$]; const $_c3$ = ["title", $I18N_1$];
@ -561,7 +561,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \`different scope $` + $I18N_1$ = $localize \`different scope $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c2$ = ["title", $I18N_1$]; const $_c2$ = ["title", $I18N_1$];
function MyComponent_div_0_Template(rf, ctx) { function MyComponent_div_0_Template(rf, ctx) {
@ -612,7 +612,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \`$` + $I18N_1$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: title\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: title\`;
} }
const $_c3$ = ["title", $I18N_1$]; const $_c3$ = ["title", $I18N_1$];
@ -675,7 +675,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`intro $` + $I18N_2$ = $localize \`intro $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
var $I18N_3$; var $I18N_3$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -690,7 +690,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_3$ = $localize \`$` + $I18N_3$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c1$ = [ const $_c1$ = [
"aria-roledescription", $I18N_1$, "aria-roledescription", $I18N_1$,
@ -711,9 +711,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_6$ = $localize \`$` + $I18N_6$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: and $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: and $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: and again $` + String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1: and again $` +
String.raw `{"\uFFFD2\uFFFD"}:interpolation_2:\`; String.raw `{"\uFFFD2\uFFFD"}:INTERPOLATION_2:\`;
} }
var $I18N_7$; var $I18N_7$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -724,7 +724,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_7$ = $localize \`$` + $I18N_7$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c3$ = [ const $_c3$ = [
"title", $I18N_6$, "title", $I18N_6$,
@ -779,7 +779,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`different scope $` + $I18N_2$ = $localize \`different scope $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c4$ = ["title", $I18N_2$]; const $_c4$ = ["title", $I18N_2$];
function MyComponent_div_0_Template(rf, ctx) { function MyComponent_div_0_Template(rf, ctx) {
@ -1033,8 +1033,8 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` Named interpolation: $` + $I18N_0$ = $localize \` Named interpolation: $` +
String.raw `{"\uFFFD0\uFFFD"}:phA: Named interpolation with spaces: $` + String.raw `{"\uFFFD0\uFFFD"}:PH_A: Named interpolation with spaces: $` +
String.raw `{"\uFFFD1\uFFFD"}:phB: \`; String.raw `{"\uFFFD1\uFFFD"}:PH_B: \`;
} }
consts: 2, consts: 2,
@ -1071,7 +1071,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`$` + $I18N_0$ = $localize \`$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
template: function MyComponent_Template(rf, ctx) { template: function MyComponent_Template(rf, ctx) {
@ -1111,9 +1111,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: $` + String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1: $` +
String.raw `{"\uFFFD2\uFFFD"}:interpolation_2: \`; String.raw `{"\uFFFD2\uFFFD"}:INTERPOLATION_2: \`;
} }
template: function MyComponent_Template(rf, ctx) { template: function MyComponent_Template(rf, ctx) {
@ -1152,7 +1152,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`My i18n block #$` + $I18N_0$ = $localize \`My i18n block #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
var $I18N_1$; var $I18N_1$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -1163,7 +1163,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \`My i18n block #$` + $I18N_1$ = $localize \`My i18n block #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
var $I18N_2$; var $I18N_2$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -1174,7 +1174,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`My i18n block #$` + $I18N_2$ = $localize \`My i18n block #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
consts: 7, consts: 7,
@ -1239,9 +1239,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` My i18n block #$` + $I18N_0$ = $localize \` My i18n block #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` +
String.raw `{"\uFFFD#2\uFFFD"}:startTagSpan:Plain text in nested element$` + String.raw `{"\uFFFD#2\uFFFD"}:START_TAG_SPAN:Plain text in nested element$` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
var $I18N_1$; var $I18N_1$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -1257,14 +1257,14 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \` My i18n block #$` + $I18N_1$ = $localize \` My i18n block #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` +
String.raw `{"[\uFFFD#6\uFFFD|\uFFFD#7\uFFFD]"}:startTagDiv:$` + String.raw `{"[\uFFFD#6\uFFFD|\uFFFD#7\uFFFD]"}:START_TAG_DIV:$` +
String.raw `{"[\uFFFD#6\uFFFD|\uFFFD#7\uFFFD]"}:startTagDiv:$` + String.raw String.raw `{"[\uFFFD#6\uFFFD|\uFFFD#7\uFFFD]"}:START_TAG_DIV:$` + String.raw
`{"\uFFFD#8\uFFFD"}:startTagSpan: More bindings in more nested element: $` + `{"\uFFFD#8\uFFFD"}:START_TAG_SPAN: More bindings in more nested element: $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: $` + String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1: $` +
String.raw `{"\uFFFD/#8\uFFFD"}:closeTagSpan:$` + String.raw `{"\uFFFD/#8\uFFFD"}:CLOSE_TAG_SPAN:$` +
String.raw `{"[\uFFFD/#7\uFFFD|\uFFFD/#6\uFFFD]"}:closeTagDiv:$` + String.raw `{"[\uFFFD/#7\uFFFD|\uFFFD/#6\uFFFD]"}:CLOSE_TAG_DIV:$` +
String.raw `{"[\uFFFD/#7\uFFFD|\uFFFD/#6\uFFFD]"}:closeTagDiv:\`; String.raw `{"[\uFFFD/#7\uFFFD|\uFFFD/#6\uFFFD]"}:CLOSE_TAG_DIV:\`;
} }
$I18N_1$ = $r3$.ɵɵi18nPostprocess($I18N_1$); $I18N_1$ = $r3$.ɵɵi18nPostprocess($I18N_1$);
@ -1330,8 +1330,8 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`Span title $` + $I18N_2$ = $localize \`Span title $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: and $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: and $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1:\`; String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1:\`;
} }
const $_c4$ = ["title", $I18N_2$]; const $_c4$ = ["title", $I18N_2$];
var $I18N_0$; var $I18N_0$;
@ -1345,9 +1345,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` My i18n block #1 with value: $` + $I18N_0$ = $localize \` My i18n block #1 with value: $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` + String.raw
`{"\uFFFD#2\uFFFD"}:startTagSpan: Plain text in nested element (block #1) $` + `{"\uFFFD#2\uFFFD"}:START_TAG_SPAN: Plain text in nested element (block #1) $` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
var $I18N_7$; var $I18N_7$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -1358,7 +1358,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_7$ = $localize \`Span title $` + $I18N_7$ = $localize \`Span title $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c9$ = ["title", $I18N_7$]; const $_c9$ = ["title", $I18N_7$];
var $I18N_6$; var $I18N_6$;
@ -1372,9 +1372,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_6$ = $localize \` My i18n block #2 with value $` + $I18N_6$ = $localize \` My i18n block #2 with value $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` + String.raw
`{"\uFFFD#7\uFFFD"}:startTagSpan: Plain text in nested element (block #2) $` + `{"\uFFFD#7\uFFFD"}:START_TAG_SPAN: Plain text in nested element (block #2) $` +
String.raw `{"\uFFFD/#7\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#7\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
consts: 9, consts: 9,
@ -1444,10 +1444,10 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \` Some other content $` + $I18N_1$ = $localize \` Some other content $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION: $` +
String.raw `{"\uFFFD#3\uFFFD"}:startTagDiv: More nested levels with bindings $` + String.raw `{"\uFFFD#3\uFFFD"}:START_TAG_DIV: More nested levels with bindings $` +
String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: $` + String.raw `{"\uFFFD1\uFFFD"}:INTERPOLATION_1: $` +
String.raw `{"\uFFFD/#3\uFFFD"}:closeTagDiv:\`; String.raw `{"\uFFFD/#3\uFFFD"}:CLOSE_TAG_DIV:\`;
} }
function MyComponent_div_2_Template(rf, ctx) { function MyComponent_div_2_Template(rf, ctx) {
@ -1514,7 +1514,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`App logo #$` + $I18N_2$ = $localize \`App logo #$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
const $_c4$ = ["title", $I18N_2$]; const $_c4$ = ["title", $I18N_2$];
function MyComponent_img_2_Template(rf, ctx) { function MyComponent_img_2_Template(rf, ctx) {
@ -1630,29 +1630,29 @@ describe('i18n support in the template compiler', () => {
else { else {
$I18N_0$ = $localize \` Some content $` + $I18N_0$ = $localize \` Some content $` +
String.raw String.raw
`{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:startTagDiv_2: Some other content $` + `{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:START_TAG_DIV_2: Some other content $` +
String.raw `{"\uFFFD0:1\uFFFD"}:interpolation: $` + String.raw String.raw `{"\uFFFD0:1\uFFFD"}:INTERPOLATION: $` + String.raw
`{"[\uFFFD#2:1\uFFFD|\uFFFD#2:2\uFFFD|\uFFFD#2:3\uFFFD]"}:startTagDiv: More nested levels with bindings $` + `{"[\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 String.raw `{"\uFFFD1:1\uFFFD"}:INTERPOLATION_1: $` + String.raw
`{"\uFFFD*4:2\uFFFD\uFFFD#1:2\uFFFD"}:startTagDiv_1: Content inside sub-template $` + `{"\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 String.raw `{"\uFFFD0:2\uFFFD"}:INTERPOLATION_2: $` + String.raw
`{"[\uFFFD#2:1\uFFFD|\uFFFD#2:2\uFFFD|\uFFFD#2:3\uFFFD]"}:startTagDiv: Bottom level element $` + `{"[\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 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]"}: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]"}:CLOSE_TAG_DIV:$` +
String.raw 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]"}: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]"}:CLOSE_TAG_DIV:$` +
String.raw 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]"}: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]"}:CLOSE_TAG_DIV:$` +
String.raw 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]"}: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]"}:CLOSE_TAG_DIV:$` +
String.raw String.raw
`{"\uFFFD*3:3\uFFFD\uFFFD#1:3\uFFFD"}:startTagDiv_3: Some other content $` + `{"\uFFFD*3:3\uFFFD\uFFFD#1:3\uFFFD"}:START_TAG_DIV_3: Some other content $` +
String.raw `{"\uFFFD0:3\uFFFD"}:interpolation_4: $` + String.raw String.raw `{"\uFFFD0:3\uFFFD"}:INTERPOLATION_4: $` + String.raw
`{"[\uFFFD#2:1\uFFFD|\uFFFD#2:2\uFFFD|\uFFFD#2:3\uFFFD]"}:startTagDiv: More nested levels with bindings $` + `{"[\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 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]"}: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]"}:CLOSE_TAG_DIV:$` +
String.raw 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]"}: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]"}:CLOSE_TAG_DIV:\`;
} }
$I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$); $I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$);
function MyComponent_div_3_Template(rf, ctx) { function MyComponent_div_3_Template(rf, ctx) {
@ -1712,9 +1712,9 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_1$ = $localize \`Some other content $` + $I18N_1$ = $localize \`Some other content $` +
String.raw `{"\uFFFD#2\uFFFD"}:startTagSpan:$` + String.raw `{"\uFFFD#2\uFFFD"}:START_TAG_SPAN:$` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:$` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:$` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
function MyComponent_div_0_Template(rf, ctx) { function MyComponent_div_0_Template(rf, ctx) {
@ -1945,7 +1945,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`Some content: $` + $I18N_0$ = $localize \`Some content: $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
consts: 3, consts: 3,
@ -1983,7 +1983,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`Some content: $` + $I18N_0$ = $localize \`Some content: $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation:\`; String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION:\`;
} }
function MyComponent_ng_template_0_Template(rf, ctx) { function MyComponent_ng_template_0_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
@ -2031,12 +2031,12 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`$` + $I18N_0$ = $localize \`$` +
String.raw `{"\uFFFD*2:1\uFFFD"}:startTagNgTemplate:Template content: $` + String.raw `{"\uFFFD*2:1\uFFFD"}:START_TAG_NG_TEMPLATE:Template content: $` +
String.raw `{"\uFFFD0:1\uFFFD"}:interpolation:$` + String.raw `{"\uFFFD0:1\uFFFD"}:INTERPOLATION:$` +
String.raw `{"\uFFFD/*2:1\uFFFD"}:closeTagNgTemplate:$` + String.raw `{"\uFFFD/*2:1\uFFFD"}:CLOSE_TAG_NG_TEMPLATE:$` +
String.raw `{"\uFFFD#3\uFFFD"}:startTagNgContainer:Container content: $` + String.raw `{"\uFFFD#3\uFFFD"}:START_TAG_NG_CONTAINER:Container content: $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation_1:$` + String.raw `{"\uFFFD0\uFFFD"}:INTERPOLATION_1:$` +
String.raw `{"\uFFFD/#3\uFFFD"}:closeTagNgContainer:\`; String.raw `{"\uFFFD/#3\uFFFD"}:CLOSE_TAG_NG_CONTAINER:\`;
} }
function MyComponent_ng_template_2_Template(rf, ctx) { function MyComponent_ng_template_2_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
@ -2185,17 +2185,17 @@ describe('i18n support in the template compiler', () => {
else { else {
$I18N_0$ = $localize \`$` + $I18N_0$ = $localize \`$` +
String.raw String.raw
`{"[\uFFFD*2:1\uFFFD|\uFFFD*2:2\uFFFD|\uFFFD*1:3\uFFFD]"}:startTagNgTemplate: Template A: $` + `{"[\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 String.raw `{"\uFFFD0:1\uFFFD"}:INTERPOLATION: $` + String.raw
`{"[\uFFFD*2:1\uFFFD|\uFFFD*2:2\uFFFD|\uFFFD*1:3\uFFFD]"}:startTagNgTemplate: Template B: $` + `{"[\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 String.raw `{"\uFFFD0:2\uFFFD"}:INTERPOLATION_1: $` + String.raw
`{"[\uFFFD*2:1\uFFFD|\uFFFD*2:2\uFFFD|\uFFFD*1:3\uFFFD]"}:startTagNgTemplate: Template C: $` + `{"[\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 String.raw `{"\uFFFD0:3\uFFFD"}:INTERPOLATION_2: $` + String.raw
`{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:closeTagNgTemplate:$` + `{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:CLOSE_TAG_NG_TEMPLATE:$` +
String.raw String.raw
`{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:closeTagNgTemplate:$` + `{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:CLOSE_TAG_NG_TEMPLATE:$` +
String.raw String.raw
`{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:closeTagNgTemplate:\`; `{"[\uFFFD/*1:3\uFFFD|\uFFFD/*2:2\uFFFD|\uFFFD/*2:1\uFFFD]"}:CLOSE_TAG_NG_TEMPLATE:\`;
} }
$I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$); $I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$);
function MyComponent_ng_template_2_Template(rf, ctx) { function MyComponent_ng_template_2_Template(rf, ctx) {
@ -2309,7 +2309,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`$` + $I18N_0$ = $localize \`$` +
String.raw `{"\uFFFD#2\uFFFD\uFFFD/#2\uFFFD"}:tagImg: is my logo #1 \`; String.raw `{"\uFFFD#2\uFFFD\uFFFD/#2\uFFFD"}:TAG_IMG: is my logo #1 \`;
} }
var $I18N_2$; var $I18N_2$;
if (ngI18nClosureMode) { if (ngI18nClosureMode) {
@ -2320,7 +2320,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_2$ = $localize \`$` + $I18N_2$ = $localize \`$` +
String.raw `{"\uFFFD#1\uFFFD\uFFFD/#1\uFFFD"}:tagImg: is my logo #2 \`; String.raw `{"\uFFFD#1\uFFFD\uFFFD/#1\uFFFD"}:TAG_IMG: is my logo #2 \`;
} }
function MyComponent_ng_template_3_Template(rf, ctx) { function MyComponent_ng_template_3_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
@ -2367,8 +2367,8 @@ describe('i18n support in the template compiler', () => {
else { else {
$I18N_0$ = $localize \` Root content $` + $I18N_0$ = $localize \` Root content $` +
String.raw String.raw
`{"\uFFFD*1:1\uFFFD\uFFFD#1:1\uFFFD"}:startTagNgContainer: Nested content $` + `{"\uFFFD*1:1\uFFFD\uFFFD#1:1\uFFFD"}:START_TAG_NG_CONTAINER: Nested content $` +
String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*1:1\uFFFD"}:closeTagNgContainer:\`; String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*1:1\uFFFD"}:CLOSE_TAG_NG_CONTAINER:\`;
} }
`; `;
@ -2423,8 +2423,8 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` Hello $` + $I18N_0$ = $localize \` Hello $` +
String.raw `{"\uFFFD#2\uFFFD"}:startTagNgContainer:there$` + String.raw `{"\uFFFD#2\uFFFD"}:START_TAG_NG_CONTAINER:there$` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeTagNgContainer:\`; String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_TAG_NG_CONTAINER:\`;
} }
consts: 3, consts: 3,
@ -2459,10 +2459,10 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` Hello $` + $I18N_0$ = $localize \` Hello $` +
String.raw `{"\uFFFD#2\uFFFD"}:startTagNgContainer:there $` + String.raw `{"\uFFFD#2\uFFFD"}:START_TAG_NG_CONTAINER:there $` +
String.raw `{"\uFFFD#3\uFFFD"}:startTagStrong:!$` + String.raw `{"\uFFFD#3\uFFFD"}:START_TAG_STRONG:!$` +
String.raw `{"\uFFFD/#3\uFFFD"}:closeTagStrong:$` + String.raw `{"\uFFFD/#3\uFFFD"}:CLOSE_TAG_STRONG:$` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeTagNgContainer:\`; String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_TAG_NG_CONTAINER:\`;
} }
consts: 4, consts: 4,
@ -2505,8 +2505,8 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \`\n Some text\n $` + $I18N_0$ = $localize \`\n Some text\n $` +
String.raw `{"\uFFFD#3\uFFFD"}:startTagSpan:Text inside span$` + String.raw `{"\uFFFD#3\uFFFD"}:START_TAG_SPAN:Text inside span$` +
String.raw `{"\uFFFD/#3\uFFFD"}:closeTagSpan:\n \`; String.raw `{"\uFFFD/#3\uFFFD"}:CLOSE_TAG_SPAN:\n \`;
} }
template: function MyComponent_Template(rf, ctx) { template: function MyComponent_Template(rf, ctx) {
@ -2805,13 +2805,13 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{$I18N_1$}:icu: $` + String.raw `{$I18N_1$}:ICU: $` +
String.raw `{"\uFFFD#2\uFFFD"}:startBoldText:Other content$` + String.raw `{"\uFFFD#2\uFFFD"}:START_BOLD_TEXT:Other content$` +
String.raw `{"\uFFFD/#2\uFFFD"}:closeBoldText:$` + String.raw `{"\uFFFD/#2\uFFFD"}:CLOSE_BOLD_TEXT:$` +
String.raw `{"\uFFFD#3\uFFFD"}:startTagDiv:$` + String.raw `{"\uFFFD#3\uFFFD"}:START_TAG_DIV:$` +
String.raw `{"\uFFFD#4\uFFFD"}:startItalicText:Another content$` + String.raw `{"\uFFFD#4\uFFFD"}:START_ITALIC_TEXT:Another content$` +
String.raw `{"\uFFFD/#4\uFFFD"}:closeItalicText:$` + String.raw `{"\uFFFD/#4\uFFFD"}:CLOSE_ITALIC_TEXT:$` +
String.raw `{"\uFFFD/#3\uFFFD"}:closeTagDiv:\`; String.raw `{"\uFFFD/#3\uFFFD"}:CLOSE_TAG_DIV:\`;
} }
consts: 5, consts: 5,
@ -2917,7 +2917,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{$I18N_1$}:icu: $` + String.raw `{$I18N_2$}:icu_1: \`; String.raw `{$I18N_1$}:ICU: $` + String.raw `{$I18N_2$}:ICU_1: \`;
} }
consts: 2, consts: 2,
@ -2999,13 +2999,13 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:icu: $` + String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:ICU: $` +
String.raw `{"\uFFFD#2\uFFFD"}:startTagDiv: $` + String.raw `{"\uFFFD#2\uFFFD"}:START_TAG_DIV: $` +
String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:icu: $` + String.raw String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:ICU: $` + String.raw
`{"[\uFFFD/#2\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*3:1\uFFFD]"}:closeTagDiv:$` + `{"[\uFFFD/#2\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*3:1\uFFFD]"}:CLOSE_TAG_DIV:$` +
String.raw `{"\uFFFD*3:1\uFFFD\uFFFD#1:1\uFFFD"}:startTagDiv_1: $` + String.raw `{"\uFFFD*3:1\uFFFD\uFFFD#1:1\uFFFD"}:START_TAG_DIV_1: $` +
String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:icu: $` + String.raw String.raw `{"\uFFFDI18N_EXP_ICU\uFFFD"}:ICU: $` + String.raw
`{"[\uFFFD/#2\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*3:1\uFFFD]"}:closeTagDiv:\`; `{"[\uFFFD/#2\uFFFD|\uFFFD/#1:1\uFFFD\uFFFD/*3:1\uFFFD]"}:CLOSE_TAG_DIV:\`;
} }
$I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$, { $I18N_0$ = $r3$.ɵɵi18nPostprocess($I18N_0$, {
"ICU": [$I18N_1$, $I18N_2$, $I18N_4$] "ICU": [$I18N_1$, $I18N_2$, $I18N_4$]
@ -3080,7 +3080,7 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{$I18N_1$}:icu: \`; String.raw `{$I18N_1$}:ICU: \`;
} }
consts: 2, consts: 2,
vars: 2, vars: 2,
@ -3196,10 +3196,10 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{$I18N_1$}:icu: $` + String.raw `{$I18N_1$}:ICU: $` +
String.raw `{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:startTagSpan: $` + String.raw `{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:START_TAG_SPAN: $` +
String.raw `{$I18N_3$}:icu_1: $` + String.raw `{$I18N_3$}:ICU_1: $` +
String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
function MyComponent_span_2_Template(rf, ctx) { function MyComponent_span_2_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
@ -3285,10 +3285,10 @@ describe('i18n support in the template compiler', () => {
} }
else { else {
$I18N_0$ = $localize \` $` + $I18N_0$ = $localize \` $` +
String.raw `{I18N_1}:icu: $` + String.raw `{I18N_1}:ICU: $` +
String.raw `{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:startTagSpan: $` + String.raw `{"\uFFFD*2:1\uFFFD\uFFFD#1:1\uFFFD"}:START_TAG_SPAN: $` +
String.raw `{I18N_4}:icu_1: $` + String.raw `{I18N_4}:ICU_1: $` +
String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD"}:closeTagSpan:\`; String.raw `{"\uFFFD/#1:1\uFFFD\uFFFD/*2:1\uFFFD"}:CLOSE_TAG_SPAN:\`;
} }
function MyComponent_span_2_Template(rf, ctx) { function MyComponent_span_2_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {

View File

@ -9,7 +9,6 @@ import * as i18n from '../../../i18n/i18n_ast';
import * as o from '../../../output/output_ast'; import * as o from '../../../output/output_ast';
import {serializeIcuNode} from './icu_serializer'; import {serializeIcuNode} from './icu_serializer';
import {i18nMetaToDocStmt, metaFromI18nMessage} from './meta';
import {formatI18nPlaceholderName} from './util'; import {formatI18nPlaceholderName} from './util';
export function createLocalizeStatements( export function createLocalizeStatements(
@ -37,7 +36,7 @@ class MessagePiece {
} }
class LiteralPiece extends MessagePiece {} class LiteralPiece extends MessagePiece {}
class PlaceholderPiece extends MessagePiece { class PlaceholderPiece extends MessagePiece {
constructor(name: string) { super(formatI18nPlaceholderName(name)); } constructor(name: string) { super(formatI18nPlaceholderName(name, /* useCamelCase */ false)); }
} }
/** /**

View File

@ -2021,13 +2021,15 @@ export function getTranslationDeclStmts(
message: i18n.Message, variable: o.ReadVarExpr, closureVar: o.ReadVarExpr, message: i18n.Message, variable: o.ReadVarExpr, closureVar: o.ReadVarExpr,
params: {[name: string]: o.Expression} = {}, params: {[name: string]: o.Expression} = {},
transformFn?: (raw: o.ReadVarExpr) => o.Expression): o.Statement[] { transformFn?: (raw: o.ReadVarExpr) => o.Expression): o.Statement[] {
const formattedParams = i18nFormatPlaceholderNames(params, /* useCamelCase */ true);
const statements: o.Statement[] = [ const statements: o.Statement[] = [
declareI18nVariable(variable), declareI18nVariable(variable),
o.ifStmt( o.ifStmt(
o.variable(NG_I18N_CLOSURE_MODE), o.variable(NG_I18N_CLOSURE_MODE),
createGoogleGetMsgStatements(variable, message, closureVar, formattedParams), createGoogleGetMsgStatements(
createLocalizeStatements(variable, message, formattedParams)), variable, message, closureVar,
i18nFormatPlaceholderNames(params, /* useCamelCase */ true)),
createLocalizeStatements(
variable, message, i18nFormatPlaceholderNames(params, /* useCamelCase */ false))),
]; ];
if (transformFn) { if (transformFn) {

View File

@ -232,6 +232,11 @@ describe('serializeI18nMessageForGetMsg', () => {
.toEqual('Some text {$interpolation} and {$interpolation_1}'); .toEqual('Some text {$interpolation} and {$interpolation_1}');
}); });
it('should serialize interpolation with named placeholder for `GetMsg()`', () => {
expect(serialize('{{ valueB + valueC // i18n(ph="PLACEHOLDER NAME") }}'))
.toEqual('{$placeholderName}');
});
it('should serialize content with HTML tags for `GetMsg()`', () => { it('should serialize content with HTML tags for `GetMsg()`', () => {
expect(serialize('A <span>B<div>C</div></span> D')) expect(serialize('A <span>B<div>C</div></span> D'))
.toEqual('A {$startTagSpan}B{$startTagDiv}C{$closeTagDiv}{$closeTagSpan} D'); .toEqual('A {$startTagSpan}B{$startTagDiv}C{$closeTagDiv}{$closeTagSpan} D');
@ -277,14 +282,14 @@ describe('serializeI18nMessageForLocalize', () => {
it('should serialize text with interpolation for `$localize()`', () => { it('should serialize text with interpolation for `$localize()`', () => {
expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }} done')).toEqual({ expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }} done')).toEqual({
messageParts: ['Some text ', ' and ', ' done'], messageParts: ['Some text ', ' and ', ' done'],
placeHolders: ['interpolation', 'interpolation_1'] placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
}); });
}); });
it('should serialize text with interpolation at start for `$localize()`', () => { it('should serialize text with interpolation at start for `$localize()`', () => {
expect(serialize('{{ valueA }} and {{ valueB + valueC }} done')).toEqual({ expect(serialize('{{ valueA }} and {{ valueB + valueC }} done')).toEqual({
messageParts: ['', ' and ', ' done'], messageParts: ['', ' and ', ' done'],
placeHolders: ['interpolation', 'interpolation_1'] placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
}); });
}); });
@ -292,21 +297,27 @@ describe('serializeI18nMessageForLocalize', () => {
it('should serialize text with interpolation at end for `$localize()`', () => { it('should serialize text with interpolation at end for `$localize()`', () => {
expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }}')).toEqual({ expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }}')).toEqual({
messageParts: ['Some text ', ' and ', ''], messageParts: ['Some text ', ' and ', ''],
placeHolders: ['interpolation', 'interpolation_1'] placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
}); });
}); });
it('should serialize only interpolation for `$localize()`', () => { it('should serialize only interpolation for `$localize()`', () => {
expect(serialize('{{ valueB + valueC }}')) expect(serialize('{{ valueB + valueC }}'))
.toEqual({messageParts: ['', ''], placeHolders: ['interpolation']}); .toEqual({messageParts: ['', ''], placeHolders: ['INTERPOLATION']});
});
it('should serialize interpolation with named placeholder for `$localize()`', () => {
expect(serialize('{{ valueB + valueC // i18n(ph="PLACEHOLDER NAME") }}'))
.toEqual({messageParts: ['', ''], placeHolders: ['PLACEHOLDER_NAME']});
}); });
it('should serialize content with HTML tags for `$localize()`', () => { it('should serialize content with HTML tags for `$localize()`', () => {
expect(serialize('A <span>B<div>C</div></span> D')).toEqual({ expect(serialize('A <span>B<div>C</div></span> D')).toEqual({
messageParts: ['A ', 'B', 'C', '', ' D'], messageParts: ['A ', 'B', 'C', '', ' D'],
placeHolders: ['startTagSpan', 'startTagDiv', 'closeTagDiv', 'closeTagSpan'] placeHolders: ['START_TAG_SPAN', 'START_TAG_DIV', 'CLOSE_TAG_DIV', 'CLOSE_TAG_SPAN']
}); });
}); });
@ -346,7 +357,7 @@ describe('serializeI18nMessageForLocalize', () => {
'{gender, select, male {male} female {female} other {other}}<div>{gender, select, male {male} female {female} other {other}}</div>')) '{gender, select, male {male} female {female} other {other}}<div>{gender, select, male {male} female {female} other {other}}</div>'))
.toEqual({ .toEqual({
messageParts: ['', '', '', '', ''], messageParts: ['', '', '', '', ''],
placeHolders: ['icu', 'startTagDiv', 'icu', 'closeTagDiv'] placeHolders: ['ICU', 'START_TAG_DIV', 'ICU', 'CLOSE_TAG_DIV']
}); });
}); });
}); });

File diff suppressed because it is too large Load Diff

View File

@ -20,10 +20,10 @@ describe('ViewContainerRef', () => {
const TRANSLATIONS: any = { const TRANSLATIONS: any = {
'Bar': 'o', 'Bar': 'o',
'{$startTagBefore}{$closeTagBefore}{$startTagDiv}{$startTagInside}{$closeTagInside}{$closeTagDiv}{$startTagAfter}{$closeTagAfter}': '{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}{$START_TAG_DIV}{$START_TAG_INSIDE}{$CLOSE_TAG_INSIDE}{$CLOSE_TAG_DIV}{$START_TAG_AFTER}{$CLOSE_TAG_AFTER}':
'F{$startTagDiv}{$closeTagDiv}o', 'F{$START_TAG_DIV}{$CLOSE_TAG_DIV}o',
'{$startTagBefore}{$closeTagBefore}{$startTagDiv}{$startTagIn}{$closeTagIn}{$closeTagDiv}{$startTagAfter}{$closeTagAfter}': '{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}{$START_TAG_DIV}{$START_TAG_IN}{$CLOSE_TAG_IN}{$CLOSE_TAG_DIV}{$START_TAG_AFTER}{$CLOSE_TAG_AFTER}':
'{$startTagDiv}{$closeTagDiv}{$startTagBefore}{$closeTagBefore}' '{$START_TAG_DIV}{$CLOSE_TAG_DIV}{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}'
}; };
/** /**

View File

@ -10,12 +10,12 @@ import {loadTranslations} from '@angular/localize/run_time';
export const translations = { export const translations = {
'What needs to be done?': `Qu'y a-t-il à faire ?`, 'What needs to be done?': `Qu'y a-t-il à faire ?`,
'{$startHeadingLevel1}todos{$closeHeadingLevel1}{$tagInput}': '{$START_HEADING_LEVEL1}todos{$CLOSE_HEADING_LEVEL1}{$TAG_INPUT}':
'{$startHeadingLevel1}liste de tâches{$closeHeadingLevel1}{$tagInput}', '{$START_HEADING_LEVEL1}liste de tâches{$CLOSE_HEADING_LEVEL1}{$TAG_INPUT}',
'{VAR_PLURAL, plural, =1 {item left} other {items left}}': '{VAR_PLURAL, plural, =1 {item left} other {items left}}':
'{VAR_PLURAL, plural, =1 {tâche restante} other {tâches restantes}}', '{VAR_PLURAL, plural, =1 {tâche restante} other {tâches restantes}}',
'{$startTagStrong}{$interpolation}{$closeTagStrong}{$icu}': '{$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG}{$ICU}':
'{$startTagStrong}{$interpolation}{$closeTagStrong} {$icu}', '{$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG} {$ICU}',
' Clear completed ': ' Effacer terminés ', ' Clear completed ': ' Effacer terminés ',
'Demonstrate Components': 'Démontrer les components', 'Demonstrate Components': 'Démontrer les components',
'Demonstrate Structural Directives': 'Démontrer les directives structurelles', 'Demonstrate Structural Directives': 'Démontrer les directives structurelles',