diff --git a/lib/rules/block-indentation.js b/lib/rules/block-indentation.js index da6def14c9..d5fb5f0be1 100644 --- a/lib/rules/block-indentation.js +++ b/lib/rules/block-indentation.js @@ -192,18 +192,14 @@ module.exports = class BlockIndentation extends Rule { this.seen = new Set(); return { - Template(node) { - if (this.mode === 'fix') { - if ( - node.body[0] && - node.body[0].type === 'TextNode' && - !removeWhitespaceEnd(node.body[0].chars) - ) { - // We need to remove the text node in this case - node.body.shift(); - } - } - return node; + Template: { + enter(node) { + this.template = node; + return node; + }, + exit() { + this.template = null; + }, }, BlockStatement(node) { @@ -281,7 +277,7 @@ module.exports = class BlockIndentation extends Rule { } // Process all the child with the path to access the child from the current node - if (sourceBeforeFix !== this.sourceEdited) { + if (sourceBeforeFix !== this.sourceEdited && this.sourceEdited) { fixedNode = this.fixLine( this.sourceEdited.split('\n'), 0, @@ -302,20 +298,30 @@ module.exports = class BlockIndentation extends Rule { return node; } + const indexOfNodeInTemplate = this.template.body.indexOf(node); + const isDirectChildOfTemplate = indexOfNodeInTemplate !== -1; let startColumn = node.loc.start.column; let startLine = node.loc.start.line; + const shouldValidate = startLine === 1 || isDirectChildOfTemplate; - if (startLine === 1 && startColumn !== 0) { + if (shouldValidate && startColumn !== 0) { if (this.mode === 'fix') { - // If we are in a child (path set) we want to edit directly the source and not the source of the node - const elementSource = path - ? this.sourceEdited || this.source.join('') - : sourceForLoc(this.sourceEdited || this.source, { - end: node.loc.end, - start: { line: node.loc.start.line, column: 0 }, - }); - const fixedNode = this.fixLine(elementSource.split('\n'), 0, startColumn, 0, path); - return fixedNode; + if (isDirectChildOfTemplate) { + const previousNode = this.template.body[indexOfNodeInTemplate - 1]; + if (previousNode.type === 'TextNode') { + previousNode.chars = removeWhitespaceEnd(previousNode.chars); + } + } else { + // If we are in a child (path set) we want to edit directly the source and not the source of the node + const elementSource = path + ? this.sourceEdited || this.source.join('') + : sourceForLoc(this.sourceEdited || this.source, { + end: node.loc.end, + start: { line: node.loc.start.line, column: 0 }, + }); + const fixedNode = this.fixLine(elementSource.split('\n'), 0, startColumn, 0, path); + return fixedNode; + } } else { let isElementNode = node && node.type === 'ElementNode'; let displayName = isElementNode ? node.tag : node.path.original; diff --git a/test/unit/rules/block-indentation-test.js b/test/unit/rules/block-indentation-test.js index 5297f6dabc..dbffd22345 100644 --- a/test/unit/rules/block-indentation-test.js +++ b/test/unit/rules/block-indentation-test.js @@ -26,7 +26,7 @@ generateRuleTests({ ' ', '{{/if}}', ].join('\n'), - '\n {{#each cats as |dog|}}\n {{/each}}', + '\n{{#each cats as |dog|}}\n{{/each}}', '

Stuff

', '
\n

Stuff Here

\n
', '{{#if isMorning}}\n' + @@ -227,17 +227,30 @@ generateRuleTests({ '{{/if}}', ].join('\n'), }, - ], + ].filter((value, index) => index >= 0), bad: [ { // start and end must be the same indentation template: '\n {{#each cats as |dog|}}\n {{/each}}', - fixedTemplate: '\n {{#each cats as |dog|}}\n {{/each}}', + fixedTemplate: '\n{{#each cats as |dog|}}\n{{/each}}', verifyResults(results) { expect(results).toMatchInlineSnapshot(` Array [ + Object { + "column": 2, + "endColumn": 17, + "endLine": 3, + "filePath": "layout.hbs", + "isFixable": true, + "line": 2, + "message": "Incorrect indentation for \`{{#each}}\` beginning at L2:C2. Expected \`{{#each}}\` to be at an indentation of 0, but was found at 2.", + "rule": "block-indentation", + "severity": 2, + "source": "{{#each cats as |dog|}} + {{/each}}", + }, Object { "column": 17, "endColumn": 17, @@ -1182,5 +1195,29 @@ generateRuleTests({ `); }, }, + { + template: '
\n
\n \n ', + fixedTemplate: '
\n
\n\n', + + verifyResults(results) { + expect(results).toMatchInlineSnapshot(` + Array [ + Object { + "column": 2, + "endColumn": 9, + "endLine": 4, + "filePath": "layout.hbs", + "isFixable": true, + "line": 3, + "message": "Incorrect indentation for \`\` beginning at L3:C2. Expected \`\` to be at an indentation of 0, but was found at 2.", + "rule": "block-indentation", + "severity": 2, + "source": " + ", + }, + ] + `); + }, + }, ], });