Skip to content

Commit 406049b

Browse files
crisbetoAndrewKushnir
authored andcommitted
fix(compiler): generate i18n instructions for blocks (#52958)
Adds support for generating i18n instructions inside of blocks. Fixes #52540. Fixes #52767. PR Close #52958
1 parent 5fb707f commit 406049b

File tree

16 files changed

+947
-38
lines changed

16 files changed

+947
-38
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/****************************************************************************************************
2+
* PARTIAL FILE: conditional.js
3+
****************************************************************************************************/
4+
import { Component } from '@angular/core';
5+
import * as i0 from "@angular/core";
6+
export class MyApp {
7+
constructor() {
8+
this.count = 0;
9+
}
10+
}
11+
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
12+
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
13+
<div i18n>
14+
Content:
15+
@if (count === 0) {
16+
before<span>zero</span>after
17+
} @else if (count === 1) {
18+
before<div>one</div>after
19+
} @else {
20+
before<button>otherwise</button>after
21+
}!
22+
23+
@if (count === 7) {
24+
before<span>seven</span>after
25+
}
26+
</div>
27+
`, isInline: true });
28+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
29+
type: Component,
30+
args: [{
31+
template: `
32+
<div i18n>
33+
Content:
34+
@if (count === 0) {
35+
before<span>zero</span>after
36+
} @else if (count === 1) {
37+
before<div>one</div>after
38+
} @else {
39+
before<button>otherwise</button>after
40+
}!
41+
42+
@if (count === 7) {
43+
before<span>seven</span>after
44+
}
45+
</div>
46+
`
47+
}]
48+
}] });
49+
50+
/****************************************************************************************************
51+
* PARTIAL FILE: conditional.d.ts
52+
****************************************************************************************************/
53+
import * as i0 from "@angular/core";
54+
export declare class MyApp {
55+
count: number;
56+
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
57+
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
58+
}
59+
60+
/****************************************************************************************************
61+
* PARTIAL FILE: switch.js
62+
****************************************************************************************************/
63+
import { Component } from '@angular/core';
64+
import * as i0 from "@angular/core";
65+
export class MyApp {
66+
constructor() {
67+
this.count = 0;
68+
}
69+
}
70+
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
71+
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
72+
<div i18n>
73+
Content:
74+
@switch (count) {
75+
@case (0) {before<span>zero</span>after}
76+
@case (1) {before<div>one</div>after}
77+
@default {before<button>otherwise</button>after}
78+
}
79+
</div>
80+
`, isInline: true });
81+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
82+
type: Component,
83+
args: [{
84+
template: `
85+
<div i18n>
86+
Content:
87+
@switch (count) {
88+
@case (0) {before<span>zero</span>after}
89+
@case (1) {before<div>one</div>after}
90+
@default {before<button>otherwise</button>after}
91+
}
92+
</div>
93+
`
94+
}]
95+
}] });
96+
97+
/****************************************************************************************************
98+
* PARTIAL FILE: switch.d.ts
99+
****************************************************************************************************/
100+
import * as i0 from "@angular/core";
101+
export declare class MyApp {
102+
count: number;
103+
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
104+
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
105+
}
106+
107+
/****************************************************************************************************
108+
* PARTIAL FILE: for.js
109+
****************************************************************************************************/
110+
import { Component } from '@angular/core';
111+
import * as i0 from "@angular/core";
112+
export class MyApp {
113+
constructor() {
114+
this.items = [1, 2, 3];
115+
}
116+
}
117+
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
118+
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
119+
<div i18n>
120+
Content:
121+
@for (item of items; track item) {
122+
before<span>middle</span>after
123+
} @empty {
124+
before<div>empty</div>after
125+
}!
126+
</div>
127+
`, isInline: true });
128+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
129+
type: Component,
130+
args: [{
131+
template: `
132+
<div i18n>
133+
Content:
134+
@for (item of items; track item) {
135+
before<span>middle</span>after
136+
} @empty {
137+
before<div>empty</div>after
138+
}!
139+
</div>
140+
`
141+
}]
142+
}] });
143+
144+
/****************************************************************************************************
145+
* PARTIAL FILE: for.d.ts
146+
****************************************************************************************************/
147+
import * as i0 from "@angular/core";
148+
export declare class MyApp {
149+
items: number[];
150+
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
151+
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
152+
}
153+
154+
/****************************************************************************************************
155+
* PARTIAL FILE: defer.js
156+
****************************************************************************************************/
157+
import { Component } from '@angular/core';
158+
import * as i0 from "@angular/core";
159+
export class MyApp {
160+
constructor() {
161+
this.isLoaded = false;
162+
}
163+
}
164+
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
165+
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
166+
<div i18n>
167+
Content:
168+
@defer (when isLoaded) {
169+
before<span>middle</span>after
170+
} @placeholder {
171+
before<div>placeholder</div>after
172+
} @loading {
173+
before<button>loading</button>after
174+
} @error {
175+
before<h1>error</h1>after
176+
}
177+
</div>
178+
`, isInline: true });
179+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
180+
type: Component,
181+
args: [{
182+
template: `
183+
<div i18n>
184+
Content:
185+
@defer (when isLoaded) {
186+
before<span>middle</span>after
187+
} @placeholder {
188+
before<div>placeholder</div>after
189+
} @loading {
190+
before<button>loading</button>after
191+
} @error {
192+
before<h1>error</h1>after
193+
}
194+
</div>
195+
`
196+
}]
197+
}] });
198+
199+
/****************************************************************************************************
200+
* PARTIAL FILE: defer.d.ts
201+
****************************************************************************************************/
202+
import * as i0 from "@angular/core";
203+
export declare class MyApp {
204+
isLoaded: boolean;
205+
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
206+
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
207+
}
208+
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"$schema": "../../test_case_schema.json",
3+
"cases": [
4+
{
5+
"description": "should support @if blocks",
6+
"skipForTemplatePipeline": true,
7+
"inputFiles": [
8+
"conditional.ts"
9+
],
10+
"expectations": [
11+
{
12+
"files": [
13+
{
14+
"generated": "conditional.js",
15+
"expected": "conditional_template.js"
16+
}
17+
],
18+
"extraChecks": [
19+
"verifyPlaceholdersIntegrity",
20+
"verifyUniqueConsts"
21+
]
22+
}
23+
]
24+
},
25+
{
26+
"description": "should support @switch blocks",
27+
"skipForTemplatePipeline": true,
28+
"inputFiles": [
29+
"switch.ts"
30+
],
31+
"expectations": [
32+
{
33+
"files": [
34+
{
35+
"generated": "switch.js",
36+
"expected": "switch_template.js"
37+
}
38+
],
39+
"extraChecks": [
40+
"verifyPlaceholdersIntegrity",
41+
"verifyUniqueConsts"
42+
]
43+
}
44+
]
45+
},
46+
{
47+
"description": "should support @for blocks",
48+
"skipForTemplatePipeline": true,
49+
"inputFiles": [
50+
"for.ts"
51+
],
52+
"expectations": [
53+
{
54+
"files": [
55+
{
56+
"generated": "for.js",
57+
"expected": "for_template.js"
58+
}
59+
],
60+
"extraChecks": [
61+
"verifyPlaceholdersIntegrity",
62+
"verifyUniqueConsts"
63+
]
64+
}
65+
]
66+
},
67+
{
68+
"description": "should support @defer blocks",
69+
"skipForTemplatePipeline": true,
70+
"inputFiles": [
71+
"defer.ts"
72+
],
73+
"expectations": [
74+
{
75+
"files": [
76+
{
77+
"generated": "defer.js",
78+
"expected": "defer_template.js"
79+
}
80+
],
81+
"extraChecks": [
82+
"verifyPlaceholdersIntegrity",
83+
"verifyUniqueConsts"
84+
]
85+
}
86+
]
87+
}
88+
]
89+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
template: `
5+
<div i18n>
6+
Content:
7+
@if (count === 0) {
8+
before<span>zero</span>after
9+
} @else if (count === 1) {
10+
before<div>one</div>after
11+
} @else {
12+
before<button>otherwise</button>after
13+
}!
14+
15+
@if (count === 7) {
16+
before<span>seven</span>after
17+
}
18+
</div>
19+
`
20+
})
21+
export class MyApp {
22+
count = 0;
23+
}

0 commit comments

Comments
 (0)