From 9f0be636f8b7c12f5505e0c098fd07ba41b7b27c Mon Sep 17 00:00:00 2001 From: Jessica Janiuk Date: Mon, 27 Nov 2023 10:21:25 -0500 Subject: [PATCH] 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 --- .../control-flow-migration/util.ts | 11 ++++-- .../test/control_flow_migration_spec.ts | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/core/schematics/ng-generate/control-flow-migration/util.ts b/packages/core/schematics/ng-generate/control-flow-migration/util.ts index b701fdb46ef8d7..7071c8597b27ca 100644 --- a/packages/core/schematics/ng-generate/control-flow-migration/util.ts +++ b/packages/core/schematics/ng-generate/control-flow-migration/util.ts @@ -302,8 +302,14 @@ export function getTemplates(template: string): Map { } function wrapIntoI18nContainer(i18nAttr: Attribute, content: string) { + const {start, middle, end} = generatei18nContainer(i18nAttr, content); + return `${start}${middle}${end}`; +} + +function generatei18nContainer( + i18nAttr: Attribute, middle: string): {start: string, middle: string, end: string} { const i18n = i18nAttr.value === '' ? 'i18n' : `i18n="${i18nAttr.value}"`; - return `${content}`; + return {start: ``, middle, end: ``}; } /** @@ -431,8 +437,7 @@ export function getMainBlock(etm: ElementToMigrate, tmpl: string, offset: number } else if (isI18nTemplate(etm, i18nAttr)) { const childStart = etm.el.children[0].sourceSpan.start.offset - offset; const childEnd = etm.el.children[etm.el.children.length - 1].sourceSpan.end.offset - offset; - const middle = wrapIntoI18nContainer(i18nAttr!, tmpl.slice(childStart, childEnd)); - return {start: '', middle, end: ''}; + return generatei18nContainer(i18nAttr!, tmpl.slice(childStart, childEnd)); } const attrStart = etm.attr.keySpan!.start.offset - 1 - offset; diff --git a/packages/core/schematics/test/control_flow_migration_spec.ts b/packages/core/schematics/test/control_flow_migration_spec.ts index 72a7bad92260c2..ef8738780667af 100644 --- a/packages/core/schematics/test/control_flow_migration_spec.ts +++ b/packages/core/schematics/test/control_flow_migration_spec.ts @@ -620,6 +620,45 @@ describe('control flow migration', () => { ].join('\n')); }); + it('should migrate an NgIfElse case with ng-templates with multiple i18n attributes', + async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + show = false; + } + `); + + writeFile('/comp.html', [ + ``, + ` Foo`, + ``, + ` Bar `, + `Bam`, + ].join('\n')); + + await runMigration(); + const content = tree.readContent('/comp.html'); + + expect(content).toBe([ + `@if (false) {`, + ` `, + ` Foo`, + ` `, + `} @else {`, + ` Bar `, + `}`, + `@if (true) {`, + ` Bam`, + `}`, + ].join('\n')); + }); + it('should migrate an if else case', async () => { writeFile('/comp.ts', ` import {Component} from '@angular/core';