From 7e12d7f8e6c7d7c439593d01173a8b12cbbef64a Mon Sep 17 00:00:00 2001 From: ota Date: Tue, 8 Jan 2019 17:24:07 +0900 Subject: [PATCH 1/4] Update: Add `arrowEmptyLine` option to `vue/multiline-html-element-content-newline` rule Close #683 --- .../multiline-html-element-content-newline.md | 35 ++++++- .../multiline-html-element-content-newline.js | 19 +++- .../multiline-html-element-content-newline.js | 96 +++++++++++++++++++ 3 files changed, 146 insertions(+), 4 deletions(-) diff --git a/docs/rules/multiline-html-element-content-newline.md b/docs/rules/multiline-html-element-content-newline.md index 9fe8d45af..5517831f3 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"], + "arrowEmptyLine": 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"]` +- `arrowEmptyLine` ... if `true`, allow empty line. If 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 +### `"arrowEmptyLine": 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..dbf246181 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, + arrowEmptyLine: false }, options) } @@ -69,6 +70,9 @@ module.exports = { items: { type: 'string' }, uniqueItems: true, additionalItems: false + }, + arrowEmptyLine: { + 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 arrowEmptyLine = options.arrowEmptyLine 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 (arrowEmptyLine) { + 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..b3c2a6327 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"> `, + // arrowEmptyLine + { + code: ` + `, + options: [{ arrowEmptyLine: true, ignoreWhenEmpty: false }] + }, + { + code: ` + `, + options: [{ arrowEmptyLine: true }] + }, + { + code: ` + `, + options: [{ arrowEmptyLine: true }] + }, // self closing ` `, - options: [{ arrowEmptyLine: true }] + options: [{ allowEmptyLine: true }] }, { code: ` @@ -107,7 +107,7 @@ tester.run('multiline-html-element-content-newline', rule, { `, - options: [{ arrowEmptyLine: true }] + options: [{ allowEmptyLine: true }] }, // self closing ` @@ -476,7 +476,7 @@ content 'Expected 1 line break before closing tag (``), but 2 line breaks found.' ] }, - // arrowEmptyLine + // allowEmptyLine { code: ` `, - options: [{ arrowEmptyLine: true, ignoreWhenEmpty: false }], + options: [{ allowEmptyLine: true, ignoreWhenEmpty: false }], output: ` `, - options: [{ arrowEmptyLine: true }], + options: [{ allowEmptyLine: true }], output: ` `, - options: [{ allowEmptyLine: true }] + options: [{ allowEmptyLines: true }] }, { code: ` @@ -107,7 +107,7 @@ tester.run('multiline-html-element-content-newline', rule, { `, - options: [{ allowEmptyLine: true }] + options: [{ allowEmptyLines: true }] }, // self closing ` @@ -476,7 +476,7 @@ content 'Expected 1 line break before closing tag (``), but 2 line breaks found.' ] }, - // allowEmptyLine + // allowEmptyLines { code: ` `, - options: [{ allowEmptyLine: true, ignoreWhenEmpty: false }], + options: [{ allowEmptyLines: true, ignoreWhenEmpty: false }], output: ` `, - options: [{ allowEmptyLine: true }], + options: [{ allowEmptyLines: true }], output: `