diff --git a/docs/rules/multiline-html-element-content-newline.md b/docs/rules/multiline-html-element-content-newline.md index 9fe8d45af..1004c1ee1 100644 --- a/docs/rules/multiline-html-element-content-newline.md +++ b/docs/rules/multiline-html-element-content-newline.md @@ -78,7 +78,8 @@ This rule enforces a line break before and after the contents of a multiline ele { "vue/multiline-html-element-content-newline": ["error", { "ignoreWhenEmpty": true, - "ignores": ["pre", "textarea"] + "ignores": ["pre", "textarea"], + "allowEmptyLines": false }] } ``` @@ -87,6 +88,8 @@ This rule enforces a line break before and after the contents of a multiline ele default `true` - `ignores` ... the configuration for element names to ignore line breaks style. default `["pre", "textarea"]` +- `allowEmptyLines` ... if `true`, it allows empty lines around content. If you want to disallow multiple empty lines, use [no-multiple-empty-lines] in combination. + default `false` ### `"ignores": ["VueComponent", "pre", "textarea"]` @@ -109,6 +112,36 @@ This rule enforces a line break before and after the contents of a multiline ele +### `"allowEmptyLines": true` + + + +```vue + +``` + + + +## :books: Further reading + +- [no-multiple-empty-lines] + +[no-multiple-empty-lines]: https://eslint.org/docs/rules/no-multiple-empty-lines + ## :mag: Implementation - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/multiline-html-element-content-newline.js) diff --git a/lib/rules/multiline-html-element-content-newline.js b/lib/rules/multiline-html-element-content-newline.js index b92841b84..8e900b6ec 100644 --- a/lib/rules/multiline-html-element-content-newline.js +++ b/lib/rules/multiline-html-element-content-newline.js @@ -22,7 +22,8 @@ function isMultilineElement (element) { function parseOptions (options) { return Object.assign({ ignores: ['pre', 'textarea'], - ignoreWhenEmpty: true + ignoreWhenEmpty: true, + allowEmptyLines: false }, options) } @@ -69,6 +70,9 @@ module.exports = { items: { type: 'string' }, uniqueItems: true, additionalItems: false + }, + allowEmptyLines: { + type: 'boolean' } }, additionalProperties: false @@ -83,6 +87,7 @@ module.exports = { const options = parseOptions(context.options[0]) const ignores = options.ignores const ignoreWhenEmpty = options.ignoreWhenEmpty + const allowEmptyLines = options.allowEmptyLines const template = context.parserServices.getTemplateBodyTokenStore && context.parserServices.getTemplateBodyTokenStore() const sourceCode = context.getSourceCode() @@ -94,6 +99,14 @@ module.exports = { ignores.includes(casing.kebabCase(node.rawName)) } + function isInvalidLineBreaks (lineBreaks) { + if (allowEmptyLines) { + return lineBreaks === 0 + } else { + return lineBreaks !== 1 + } + } + return utils.defineTemplateBodyVisitor(context, { 'VElement' (node) { if (inIgnoreElement) { @@ -127,7 +140,7 @@ module.exports = { const beforeLineBreaks = contentFirst.loc.start.line - node.startTag.loc.end.line const afterLineBreaks = node.endTag.loc.start.line - contentLast.loc.end.line - if (beforeLineBreaks !== 1) { + if (isInvalidLineBreaks(beforeLineBreaks)) { context.report({ node: template.getLastToken(node.startTag), loc: { @@ -150,7 +163,7 @@ module.exports = { return } - if (afterLineBreaks !== 1) { + if (isInvalidLineBreaks(afterLineBreaks)) { context.report({ node: template.getFirstToken(node.endTag), loc: { diff --git a/tests/lib/rules/multiline-html-element-content-newline.js b/tests/lib/rules/multiline-html-element-content-newline.js index b1eaa64c4..8f2f707bd 100644 --- a/tests/lib/rules/multiline-html-element-content-newline.js +++ b/tests/lib/rules/multiline-html-element-content-newline.js @@ -72,6 +72,43 @@ tester.run('multiline-html-element-content-newline', rule, { class="panel"> `, + // allowEmptyLines + { + code: ` + `, + options: [{ allowEmptyLines: true, ignoreWhenEmpty: false }] + }, + { + code: ` + `, + options: [{ allowEmptyLines: true }] + }, + { + code: ` + `, + options: [{ allowEmptyLines: true }] + }, // self closing `