Skip to content

Commit

Permalink
fix(compiler): generate i18n instructions for blocks (#52958)
Browse files Browse the repository at this point in the history
Adds support for generating i18n instructions inside of blocks.

Fixes #52540.
Fixes #52767.

PR Close #52958
  • Loading branch information
crisbeto authored and AndrewKushnir committed Nov 20, 2023
1 parent f01b718 commit 291deac
Show file tree
Hide file tree
Showing 16 changed files with 947 additions and 38 deletions.
@@ -0,0 +1,208 @@
/****************************************************************************************************
* PARTIAL FILE: conditional.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.count = 0;
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
<div i18n>
Content:
@if (count === 0) {
before<span>zero</span>after
} @else if (count === 1) {
before<div>one</div>after
} @else {
before<button>otherwise</button>after
}!
@if (count === 7) {
before<span>seven</span>after
}
</div>
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
<div i18n>
Content:
@if (count === 0) {
before<span>zero</span>after
} @else if (count === 1) {
before<div>one</div>after
} @else {
before<button>otherwise</button>after
}!
@if (count === 7) {
before<span>seven</span>after
}
</div>
`
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: conditional.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
count: number;
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

/****************************************************************************************************
* PARTIAL FILE: switch.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.count = 0;
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
<div i18n>
Content:
@switch (count) {
@case (0) {before<span>zero</span>after}
@case (1) {before<div>one</div>after}
@default {before<button>otherwise</button>after}
}
</div>
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
<div i18n>
Content:
@switch (count) {
@case (0) {before<span>zero</span>after}
@case (1) {before<div>one</div>after}
@default {before<button>otherwise</button>after}
}
</div>
`
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: switch.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
count: number;
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

/****************************************************************************************************
* PARTIAL FILE: for.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.items = [1, 2, 3];
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
<div i18n>
Content:
@for (item of items; track item) {
before<span>middle</span>after
} @empty {
before<div>empty</div>after
}!
</div>
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
<div i18n>
Content:
@for (item of items; track item) {
before<span>middle</span>after
} @empty {
before<div>empty</div>after
}!
</div>
`
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: for.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
items: number[];
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

/****************************************************************************************************
* PARTIAL FILE: defer.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.isLoaded = false;
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
<div i18n>
Content:
@defer (when isLoaded) {
before<span>middle</span>after
} @placeholder {
before<div>placeholder</div>after
} @loading {
before<button>loading</button>after
} @error {
before<h1>error</h1>after
}
</div>
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
<div i18n>
Content:
@defer (when isLoaded) {
before<span>middle</span>after
} @placeholder {
before<div>placeholder</div>after
} @loading {
before<button>loading</button>after
} @error {
before<h1>error</h1>after
}
</div>
`
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: defer.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
isLoaded: boolean;
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

@@ -0,0 +1,89 @@
{
"$schema": "../../test_case_schema.json",
"cases": [
{
"description": "should support @if blocks",
"skipForTemplatePipeline": true,
"inputFiles": [
"conditional.ts"
],
"expectations": [
{
"files": [
{
"generated": "conditional.js",
"expected": "conditional_template.js"
}
],
"extraChecks": [
"verifyPlaceholdersIntegrity",
"verifyUniqueConsts"
]
}
]
},
{
"description": "should support @switch blocks",
"skipForTemplatePipeline": true,
"inputFiles": [
"switch.ts"
],
"expectations": [
{
"files": [
{
"generated": "switch.js",
"expected": "switch_template.js"
}
],
"extraChecks": [
"verifyPlaceholdersIntegrity",
"verifyUniqueConsts"
]
}
]
},
{
"description": "should support @for blocks",
"skipForTemplatePipeline": true,
"inputFiles": [
"for.ts"
],
"expectations": [
{
"files": [
{
"generated": "for.js",
"expected": "for_template.js"
}
],
"extraChecks": [
"verifyPlaceholdersIntegrity",
"verifyUniqueConsts"
]
}
]
},
{
"description": "should support @defer blocks",
"skipForTemplatePipeline": true,
"inputFiles": [
"defer.ts"
],
"expectations": [
{
"files": [
{
"generated": "defer.js",
"expected": "defer_template.js"
}
],
"extraChecks": [
"verifyPlaceholdersIntegrity",
"verifyUniqueConsts"
]
}
]
}
]
}
@@ -0,0 +1,23 @@
import {Component} from '@angular/core';

@Component({
template: `
<div i18n>
Content:
@if (count === 0) {
before<span>zero</span>after
} @else if (count === 1) {
before<div>one</div>after
} @else {
before<button>otherwise</button>after
}!
@if (count === 7) {
before<span>seven</span>after
}
</div>
`
})
export class MyApp {
count = 0;
}

0 comments on commit 291deac

Please sign in to comment.