diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index c77000cc0..f080372ce 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -258,6 +258,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti const options = parseOptions(context.options[0], context.options[1] || {}, defaultOptions) const sourceCode = context.getSourceCode() const offsets = new Map() + const preformattedTokens = new Set() /** * Set offset to the given tokens. @@ -301,6 +302,29 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } } + /** + * Sets preformatted tokens to the given element node. + * @param {Node} node The node to set. + * @returns {void} + */ + function setPreformattedTokens (node) { + const endToken = (node.endTag && tokenStore.getFirstToken(node.endTag)) || tokenStore.getTokenAfter(node) + + const option = { + includeComments: true, + filter: token => token != null && ( + token.type === 'HTMLText' || + token.type === 'HTMLTagOpen' || + token.type === 'HTMLEndTagOpen' || + token.type === 'HTMLComment' + ) + } + for (const token of tokenStore.getTokensBetween(node.startTag, endToken, option)) { + preformattedTokens.add(token) + } + preformattedTokens.add(endToken) + } + /** * Get the first and last tokens of the given node. * If the node is parenthesized, this gets the outermost parentheses. @@ -782,6 +806,11 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } } + // It does not validate preformatted tokens. + if (preformattedTokens.has(firstToken)) { + return + } + // Calculate the expected indents for comments. // It allows the same indent level with the previous line. const lastOffsetInfo = offsets.get(lastToken) @@ -821,6 +850,8 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti if (node.name !== 'pre') { const childTokens = node.children.map(n => tokenStore.getFirstToken(n)) setOffset(childTokens, 1, startTagToken) + } else { + setPreformattedTokens(node) } setOffset(endTagToken, 0, startTagToken) }, diff --git a/tests/lib/rules/html-indent.js b/tests/lib/rules/html-indent.js index a0613009a..e8a229699 100644 --- a/tests/lib/rules/html-indent.js +++ b/tests/lib/rules/html-indent.js @@ -281,6 +281,83 @@ tester.run('html-indent', rule, loadPatterns( ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` + }, + { + filename: 'test.vue', + code: unIndent` + + ` } ], @@ -564,13 +641,54 @@ tester.run('html-indent', rule, loadPatterns( aaa bbb ccc - + `, errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 }, - { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 }, + { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 } + ] + }, + { + filename: 'test.vue', + code: unIndent` + + `, + output: unIndent` + + `, + errors: [ + { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 }, + { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 }, + { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 4 }, + { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 5 }, + { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 6 }, + { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 7 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 8 } ] }