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 || ' '; } /**