UNPKG

eslint-plugin-san

Version:

Official ESLint plugin for San

117 lines (103 loc) 3.64 kB
/** * @author Toru Nagashima * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ 'use strict'; /* eslint-disable */ // ------------------------------------------------------------------------------ // Requirements // ------------------------------------------------------------------------------ const utils = require('../utils'); // ------------------------------------------------------------------------------ // Helpers // ------------------------------------------------------------------------------ /** * Get the name of the given attribute node. * @param {VAttribute | VDirective} attribute The attribute node to get. * @returns {string | null} The name of the attribute. */ function getName(attribute) { if (!attribute.directive) { return attribute.key.name; } if (attribute.key.name.name === 'bind') { return ( (attribute.key.argument && attribute.key.argument.type === 'VIdentifier' && attribute.key.argument.name) || null ); } return null; } // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { type: 'problem', docs: { description: 'disallow duplication of attributes', categories: ['essential'], url: 'https://ecomfe.github.io/eslint-plugin-san/rules/no-duplicate-attributes.html' }, fixable: null, schema: [ { type: 'object', properties: { allowCoexistClass: { type: 'boolean' }, allowCoexistStyle: { type: 'boolean' } } } ] }, /** @param {RuleContext} context */ create(context) { const options = context.options[0] || {}; const allowCoexistStyle = options.allowCoexistStyle !== false; const allowCoexistClass = options.allowCoexistClass !== false; /** @type {Set<string>} */ const directiveNames = new Set(); /** @type {Set<string>} */ const attributeNames = new Set(); /** * @param {string} name * @param {boolean} isDirective */ function isDuplicate(name, isDirective) { if ((allowCoexistStyle && name === 'style') || (allowCoexistClass && name === 'class')) { return isDirective ? directiveNames.has(name) : attributeNames.has(name); } return directiveNames.has(name) || attributeNames.has(name); } return utils.defineTemplateBodyVisitor(context, { VStartTag() { directiveNames.clear(); attributeNames.clear(); }, VAttribute(node) { const name = getName(node); if (name == null) { return; } if (isDuplicate(name, node.directive)) { context.report({ node, loc: node.loc, message: "Duplicate attribute '{{name}}'.", data: {name} }); } if (node.directive) { directiveNames.add(name); } else { attributeNames.add(name); } } }); } };