diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.spec.ts b/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.spec.ts
index 56e610a10b30..3bc8a4201a7f 100644
--- a/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.spec.ts
+++ b/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.spec.ts
@@ -190,6 +190,41 @@ describe('#visitElements', () => {
it('should add value to existing attribute that does not have a value', async () => {
runAddAttributeTest('', '');
});
+
+ it('should handle all forms of indentation', async () => {
+ runAddAttributeTest(
+ '',
+ '',
+ );
+ runAddAttributeTest(
+ `
+ `,
+ `
+ `,
+ );
+ runAddAttributeTest(
+ `
+ `,
+ `
+ `,
+ );
+ runAddAttributeTest(
+ `
+ `,
+ `
+ `,
+ );
+ });
});
describe('remove attribute tests', () => {
diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.ts b/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.ts
index bfccf0e8a745..481ec8432b73 100644
--- a/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.ts
+++ b/src/material/schematics/ng-generate/mdc-migration/rules/tree-traversal.ts
@@ -158,19 +158,24 @@ export function updateAttribute(
const prefix = html.slice(0, index);
const suffix = html.slice(index);
const attrText = newValue ? `${name}="${newValue}"` : `${name}`;
+ const indentation = parseIndentation(html, node);
+ return prefix + indentation + attrText + suffix;
+}
- if (node.startSourceSpan.start.line === node.startSourceSpan.end.line) {
- return `${prefix} ${attrText}${suffix}`;
- }
+function parseIndentation(html: string, node: TmplAstElement): string {
+ let whitespace = '';
+ let startOffset = node.startSourceSpan.start.offset + node.name.length + 1;
- const attr = node.attributes[0];
- if (attr) {
- const ctx = attr.sourceSpan.start.getContext(attr.sourceSpan.start.col + 1, 1)!;
- const indentation = ctx.before;
- return prefix + indentation + attrText + suffix;
- }
+ // Starting after the start source span's tagname,
+ // read and store each char until we reach a non-whitespace char.
- return prefix + attrText + suffix;
+ for (let i = startOffset; i < node.startSourceSpan.end.offset - 1; i++) {
+ if (!/\s/.test(html.charAt(i))) {
+ break;
+ }
+ whitespace += html.charAt(i);
+ }
+ return whitespace || ' ';
}
/**