| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | /** * @fileoverview Define the number of attributes allows per line * @author Filipa Lacerda */'use strict'// ------------------------------------------------------------------------------// Rule Definition// ------------------------------------------------------------------------------const utils = require('../utils')module.exports = {  meta: {    docs: {      description: 'enforce the maximum number of attributes per line',      category: 'strongly-recommended',      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.7.1/docs/rules/max-attributes-per-line.md'    },    fixable: 'whitespace', // or "code" or "whitespace"    schema: [      {        type: 'object',        properties: {          singleline: {            anyOf: [              {                type: 'number',                minimum: 1              },              {                type: 'object',                properties: {                  max: {                    type: 'number',                    minimum: 1                  }                },                additionalProperties: false              }            ]          },          multiline: {            anyOf: [              {                type: 'number',                minimum: 1              },              {                type: 'object',                properties: {                  max: {                    type: 'number',                    minimum: 1                  },                  allowFirstLine: {                    type: 'boolean'                  }                },                additionalProperties: false              }            ]          }        }      }    ]  },  create: function (context) {    const configuration = parseOptions(context.options[0])    const multilineMaximum = configuration.multiline    const singlelinemMaximum = configuration.singleline    const canHaveFirstLine = configuration.allowFirstLine    return utils.defineTemplateBodyVisitor(context, {      'VStartTag' (node) {        const numberOfAttributes = node.attributes.length        if (!numberOfAttributes) return        if (utils.isSingleLine(node) && numberOfAttributes > singlelinemMaximum) {          showErrors(node.attributes.slice(singlelinemMaximum), node)        }        if (!utils.isSingleLine(node)) {          if (!canHaveFirstLine && node.attributes[0].loc.start.line === node.loc.start.line) {            showErrors([node.attributes[0]], node)          }          groupAttrsByLine(node.attributes)            .filter(attrs => attrs.length > multilineMaximum)            .forEach(attrs => showErrors(attrs.splice(multilineMaximum), node))        }      }    })    // ----------------------------------------------------------------------    // Helpers    // ----------------------------------------------------------------------    function parseOptions (options) {      const defaults = {        singleline: 1,        multiline: 1,        allowFirstLine: false      }      if (options) {        if (typeof options.singleline === 'number') {          defaults.singleline = options.singleline        } else if (options.singleline && options.singleline.max) {          defaults.singleline = options.singleline.max        }        if (options.multiline) {          if (typeof options.multiline === 'number') {            defaults.multiline = options.multiline          } else if (typeof options.multiline === 'object') {            if (options.multiline.max) {              defaults.multiline = options.multiline.max            }            if (options.multiline.allowFirstLine) {              defaults.allowFirstLine = options.multiline.allowFirstLine            }          }        }      }      return defaults    }    function showErrors (attributes, node) {      attributes.forEach((prop, i) => {        context.report({          node: prop,          loc: prop.loc,          message: 'Attribute "{{propName}}" should be on a new line.',          data: {            propName: prop.key.name          },          fix: i === 0 ? (fixer) => fixer.insertTextBefore(prop, '\n') : undefined        })      })    }    function groupAttrsByLine (attributes) {      const propsPerLine = [[attributes[0]]]      attributes.reduce((previous, current) => {        if (previous.loc.end.line === current.loc.start.line) {          propsPerLine[propsPerLine.length - 1].push(current)        } else {          propsPerLine.push([current])        }        return current      })      return propsPerLine    }  }}
 |