/** * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes. * @author ryym */ 'use strict'; const docsUrl = require('../util/docsUrl'); // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: 'Disallow or enforce spaces around equal signs in JSX attributes', category: 'Stylistic Issues', recommended: false, url: docsUrl('jsx-equals-spacing') }, fixable: 'code', messages: { noSpaceBefore: 'There should be no space before \'=\'', noSpaceAfter: 'There should be no space after \'=\'', needSpaceBefore: 'A space is required before \'=\'', needSpaceAfter: 'A space is required after \'=\'' }, schema: [{ enum: ['always', 'never'] }] }, create(context) { const config = context.options[0]; /** * Determines a given attribute node has an equal sign. * @param {ASTNode} attrNode - The attribute node. * @returns {boolean} Whether or not the attriute node has an equal sign. */ function hasEqual(attrNode) { return attrNode.type !== 'JSXSpreadAttribute' && attrNode.value !== null; } // -------------------------------------------------------------------------- // Public // -------------------------------------------------------------------------- return { JSXOpeningElement(node) { node.attributes.forEach((attrNode) => { if (!hasEqual(attrNode)) { return; } const sourceCode = context.getSourceCode(); const equalToken = sourceCode.getTokenAfter(attrNode.name); const spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken); const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value); switch (config) { default: case 'never': if (spacedBefore) { context.report({ node: attrNode, loc: equalToken.loc.start, messageId: 'noSpaceBefore', fix(fixer) { return fixer.removeRange([attrNode.name.range[1], equalToken.range[0]]); } }); } if (spacedAfter) { context.report({ node: attrNode, loc: equalToken.loc.start, messageId: 'noSpaceAfter', fix(fixer) { return fixer.removeRange([equalToken.range[1], attrNode.value.range[0]]); } }); } break; case 'always': if (!spacedBefore) { context.report({ node: attrNode, loc: equalToken.loc.start, messageId: 'needSpaceBefore', fix(fixer) { return fixer.insertTextBefore(equalToken, ' '); } }); } if (!spacedAfter) { context.report({ node: attrNode, loc: equalToken.loc.start, messageId: 'needSpaceAfter', fix(fixer) { return fixer.insertTextAfter(equalToken, ' '); } }); } break; } }); } }; } };