Skip to content

Commit ba6d7fe

Browse files
fix(migrations): fixes CF migration i18n ng-template offsets (#53212)
This addresses an issue where multiple ng-templates are present with i18n attributes. The offsets would be incorrectly accounted for when being replaced with an ng-container. fixes: #53149 PR Close #53212
1 parent 0fcef65 commit ba6d7fe

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

packages/core/schematics/ng-generate/control-flow-migration/util.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,14 @@ export function getTemplates(template: string): Map<string, Template> {
302302
}
303303

304304
function wrapIntoI18nContainer(i18nAttr: Attribute, content: string) {
305+
const {start, middle, end} = generatei18nContainer(i18nAttr, content);
306+
return `${start}${middle}${end}`;
307+
}
308+
309+
function generatei18nContainer(
310+
i18nAttr: Attribute, middle: string): {start: string, middle: string, end: string} {
305311
const i18n = i18nAttr.value === '' ? 'i18n' : `i18n="${i18nAttr.value}"`;
306-
return `<ng-container ${i18n}>${content}</ng-container>`;
312+
return {start: `<ng-container ${i18n}>`, middle, end: `</ng-container>`};
307313
}
308314

309315
/**
@@ -431,8 +437,7 @@ export function getMainBlock(etm: ElementToMigrate, tmpl: string, offset: number
431437
} else if (isI18nTemplate(etm, i18nAttr)) {
432438
const childStart = etm.el.children[0].sourceSpan.start.offset - offset;
433439
const childEnd = etm.el.children[etm.el.children.length - 1].sourceSpan.end.offset - offset;
434-
const middle = wrapIntoI18nContainer(i18nAttr!, tmpl.slice(childStart, childEnd));
435-
return {start: '', middle, end: ''};
440+
return generatei18nContainer(i18nAttr!, tmpl.slice(childStart, childEnd));
436441
}
437442

438443
const attrStart = etm.attr.keySpan!.start.offset - 1 - offset;

packages/core/schematics/test/control_flow_migration_spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,45 @@ describe('control flow migration', () => {
620620
].join('\n'));
621621
});
622622

623+
it('should migrate an NgIfElse case with ng-templates with multiple i18n attributes',
624+
async () => {
625+
writeFile('/comp.ts', `
626+
import {Component} from '@angular/core';
627+
import {NgIf} from '@angular/common';
628+
629+
@Component({
630+
templateUrl: './comp.html'
631+
})
632+
class Comp {
633+
show = false;
634+
}
635+
`);
636+
637+
writeFile('/comp.html', [
638+
`<ng-template *ngIf="false; else barTempl" i18n="@@foo">`,
639+
` Foo`,
640+
`</ng-template>`,
641+
`<ng-template i18n="@@bar" #barTempl> Bar </ng-template>`,
642+
`<a *ngIf="true" i18n="@@bam">Bam</a>`,
643+
].join('\n'));
644+
645+
await runMigration();
646+
const content = tree.readContent('/comp.html');
647+
648+
expect(content).toBe([
649+
`@if (false) {`,
650+
` <ng-container i18n="@@foo">`,
651+
` Foo`,
652+
` </ng-container>`,
653+
`} @else {`,
654+
` <ng-container i18n="@@bar"> Bar </ng-container>`,
655+
`}`,
656+
`@if (true) {`,
657+
` <a i18n="@@bam">Bam</a>`,
658+
`}`,
659+
].join('\n'));
660+
});
661+
623662
it('should migrate an if else case', async () => {
624663
writeFile('/comp.ts', `
625664
import {Component} from '@angular/core';

0 commit comments

Comments
 (0)