You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/** * @fileoverview Require or prevent a new line after jsx elements and expressions. * @author Johnny Zabala * @author Joseph Stiles */
'use strict';
const docsUrl = require('../util/docsUrl');
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
module.exports = { meta: { docs: { description: 'Require or prevent a new line after jsx elements and expressions.', category: 'Stylistic Issues', recommended: false, url: docsUrl('jsx-newline') }, fixable: 'code',
messages: { require: 'JSX element should start in a new line', prevent: 'JSX element should not start in a new line' }, schema: [ { type: 'object', properties: { prevent: { default: false, type: 'boolean' } }, additionalProperties: false } ] }, create(context) { const jsxElementParents = new Set(); const sourceCode = context.getSourceCode(); return { 'Program:exit'() { jsxElementParents.forEach((parent) => { parent.children.forEach((element, index, elements) => { if (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer') { const firstAdjacentSibling = elements[index + 1]; const secondAdjacentSibling = elements[index + 2];
const hasSibling = firstAdjacentSibling && secondAdjacentSibling && (firstAdjacentSibling.type === 'Literal' || firstAdjacentSibling.type === 'JSXText');
if (!hasSibling) return;
// Check adjacent sibling has the proper amount of newlines
const isWithoutNewLine = !/\n\s*\n/.test(firstAdjacentSibling.value);
const prevent = !!(context.options[0] || {}).prevent;
if (isWithoutNewLine === prevent) return;
const messageId = prevent ? 'prevent' : 'require';
const regex = prevent ? /(\n\n)(?!.*\1)/g : /(\n)(?!.*\1)/g;
const replacement = prevent ? '\n' : '\n\n';
context.report({ node: secondAdjacentSibling, messageId, fix(fixer) { return fixer.replaceText( firstAdjacentSibling, // double or remove the last newline
sourceCode.getText(firstAdjacentSibling) .replace(regex, replacement) ); } }); } }); }); }, ':matches(JSXElement, JSXFragment) > :matches(JSXElement, JSXExpressionContainer)': (node) => { jsxElementParents.add(node.parent); } }; } };
|