diff --git a/packages/core/schematics/test/routerlink_empty_expr_migration_spec.ts b/packages/core/schematics/test/routerlink_empty_expr_migration_spec.ts
index f4184bbf6d8..be2f78a3078 100644
--- a/packages/core/schematics/test/routerlink_empty_expr_migration_spec.ts
+++ b/packages/core/schematics/test/routerlink_empty_expr_migration_spec.ts
@@ -76,7 +76,7 @@ describe('routerlink emptyExpr assignment migration', () => {
await runMigration();
expect(warnOutput.length).toBe(1);
- expect(warnOutput[0]).toMatch(/^⮑ {3}index.ts@5:25/);
+ expect(warnOutput[0]).toMatch(/^⮑ {3}index\.ts@5:25/);
const content = tree.readContent('/index.ts');
expect(content).toContain(`
`);
@@ -101,7 +101,7 @@ describe('routerlink emptyExpr assignment migration', () => {
await runMigration();
expect(warnOutput.length).toBe(1);
- expect(warnOutput).toMatch(/^⮑ {3}tmpl.html@3:20/);
+ expect(warnOutput).toMatch(/^⮑ {3}tmpl\.html@3:20/);
const content = tree.readContent('/tmpl.html');
expect(content).toContain(``);
@@ -215,9 +215,30 @@ describe('routerlink emptyExpr assignment migration', () => {
await runMigration();
expect(warnOutput.length).toBe(1);
- expect(warnOutput[0]).toMatch(/^⮑ {3}index.ts@4:35/);
+ expect(warnOutput[0]).toMatch(/^⮑ {3}index\.ts@4:35/);
const content = tree.readContent('/index.ts');
expect(content).toContain(`\r\n{{1}}\r\n
`);
});
+
+ it('should work for files that use CRLF line endings before routerLink bindings', async () => {
+ writeFile(
+ '/index.ts',
+ `
+ import {Component} from '@angular/core';
+
+ @Component({` +
+ 'template: `' +
+ '\r\n\r\n\r\n{{1}}
`' +
+ `})
+ export class MyComp {}
+ `);
+
+ await runMigration();
+ expect(warnOutput.length).toBe(1);
+ expect(warnOutput[0]).toMatch(/^⮑ {3}index\.ts@7:6/);
+
+ const content = tree.readContent('/index.ts');
+ expect(content).toContain(`\r\n\r\n\r\n{{1}}
`);
+ });
});
diff --git a/packages/core/schematics/utils/ng_component_template.ts b/packages/core/schematics/utils/ng_component_template.ts
index cc84653e3da..8c2c5c34217 100644
--- a/packages/core/schematics/utils/ng_component_template.ts
+++ b/packages/core/schematics/utils/ng_component_template.ts
@@ -97,16 +97,24 @@ export class NgComponentTemplateVisitor {
if (propertyName === 'template' && ts.isStringLiteralLike(property.initializer)) {
// Need to add an offset of one to the start because the template quotes are
// not part of the template content.
- const templateStartIdx = property.initializer.getStart() + 1;
+ // The `getText()` method gives us the original raw text.
+ // We could have used the `text` property, but if the template is defined as a backtick
+ // string then the `text` property contains a "cooked" version of the string. Such cooked
+ // strings will have converted CRLF characters to only LF. This messes up string
+ // replacements in template migrations.
+ // The raw text returned by `getText()` includes the enclosing quotes so we change the
+ // `content` and `start` values accordingly.
+ const content = property.initializer.getText().slice(1, -1);
+ const start = property.initializer.getStart() + 1;
const filePath = resolve(sourceFileName);
this.resolvedTemplates.push({
filePath: filePath,
container: node,
- content: property.initializer.text,
+ content,
inline: true,
- start: templateStartIdx,
+ start: start,
getCharacterAndLineOfPosition: pos =>
- ts.getLineAndCharacterOfPosition(sourceFile, pos + templateStartIdx)
+ ts.getLineAndCharacterOfPosition(sourceFile, pos + start)
});
}
if (propertyName === 'templateUrl' && ts.isStringLiteralLike(property.initializer)) {