/** * @author Yosuke Ota * See LICENSE file in root directory for full license. */ 'use strict' const utils = require('../utils') // https://github.com/vuejs/vue-next/blob/64e2f4643602c5980361e66674141e61ba60ef70/packages/compiler-core/src/parse.ts#L405 const SPECIAL_TEMPLATE_DIRECTIVES = new Set([ 'if', 'else', 'else-if', 'for', 'slot' ]) /** * @param {VAttribute | VDirective} attr */ function getKeyName(attr) { if (attr.directive) { if (attr.key.name.name !== 'bind') { // no v-bind return null } if ( !attr.key.argument || attr.key.argument.type === 'VExpressionContainer' ) { // unknown return null } return attr.key.argument.name } return attr.key.name } /** * @param {VAttribute | VDirective} attr */ function isFragmentTemplateAttribute(attr) { if (attr.directive) { const directiveName = attr.key.name.name if (SPECIAL_TEMPLATE_DIRECTIVES.has(directiveName)) { return true } if (directiveName === 'slot-scope') { // `slot-scope` is deprecated in Vue.js 2.6 return true } if (directiveName === 'scope') { // `scope` is deprecated in Vue.js 2.5 return true } } const keyName = getKeyName(attr) if (keyName === 'slot') { // `slot` is deprecated in Vue.js 2.6 return true } return false } module.exports = { meta: { type: 'problem', docs: { description: 'disallow useless attribute on `