source: imaps-frontend/node_modules/eslint-plugin-react/lib/rules/jsx-newline.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/**
2 * @fileoverview Require or prevent a new line after jsx elements and expressions.
3 * @author Johnny Zabala
4 * @author Joseph Stiles
5 */
6
7'use strict';
8
9const docsUrl = require('../util/docsUrl');
10const getText = require('../util/eslint').getText;
11const report = require('../util/report');
12
13// ------------------------------------------------------------------------------
14// Rule Definition
15// ------------------------------------------------------------------------------
16
17const messages = {
18 require: 'JSX element should start in a new line',
19 prevent: 'JSX element should not start in a new line',
20 allowMultilines: 'Multiline JSX elements should start in a new line',
21};
22
23function isMultilined(node) {
24 return node && node.loc.start.line !== node.loc.end.line;
25}
26
27/** @type {import('eslint').Rule.RuleModule} */
28module.exports = {
29 meta: {
30 docs: {
31 description: 'Require or prevent a new line after jsx elements and expressions.',
32 category: 'Stylistic Issues',
33 recommended: false,
34 url: docsUrl('jsx-newline'),
35 },
36 fixable: 'code',
37
38 messages,
39 schema: [
40 {
41 type: 'object',
42 properties: {
43 prevent: {
44 default: false,
45 type: 'boolean',
46 },
47 allowMultilines: {
48 default: false,
49 type: 'boolean',
50 },
51 },
52 additionalProperties: false,
53 if: {
54 properties: {
55 allowMultilines: {
56 const: true,
57 },
58 },
59 },
60 then: {
61 properties: {
62 prevent: {
63 const: true,
64 },
65 },
66 required: [
67 'prevent',
68 ],
69 },
70 },
71 ],
72 },
73 create(context) {
74 const jsxElementParents = new Set();
75
76 function isBlockCommentInCurlyBraces(element) {
77 const elementRawValue = getText(context, element);
78 return /^\s*{\/\*/.test(elementRawValue);
79 }
80
81 function isNonBlockComment(element) {
82 return !isBlockCommentInCurlyBraces(element) && (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer');
83 }
84
85 return {
86 'Program:exit'() {
87 jsxElementParents.forEach((parent) => {
88 parent.children.forEach((element, index, elements) => {
89 if (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer') {
90 const configuration = context.options[0] || {};
91 const prevent = configuration.prevent || false;
92 const allowMultilines = configuration.allowMultilines || false;
93
94 const firstAdjacentSibling = elements[index + 1];
95 const secondAdjacentSibling = elements[index + 2];
96
97 const hasSibling = firstAdjacentSibling
98 && secondAdjacentSibling
99 && (firstAdjacentSibling.type === 'Literal' || firstAdjacentSibling.type === 'JSXText');
100
101 if (!hasSibling) return;
102
103 // Check adjacent sibling has the proper amount of newlines
104 const isWithoutNewLine = !/\n\s*\n/.test(firstAdjacentSibling.value);
105
106 if (isBlockCommentInCurlyBraces(element)) return;
107 if (
108 allowMultilines
109 && (
110 isMultilined(element)
111 || isMultilined(elements.slice(index + 2).find(isNonBlockComment))
112 )
113 ) {
114 if (!isWithoutNewLine) return;
115
116 const regex = /(\n)(?!.*\1)/g;
117 const replacement = '\n\n';
118 const messageId = 'allowMultilines';
119
120 report(context, messages[messageId], messageId, {
121 node: secondAdjacentSibling,
122 fix(fixer) {
123 return fixer.replaceText(
124 firstAdjacentSibling,
125 getText(context, firstAdjacentSibling).replace(regex, replacement)
126 );
127 },
128 });
129
130 return;
131 }
132
133 if (isWithoutNewLine === prevent) return;
134
135 const messageId = prevent
136 ? 'prevent'
137 : 'require';
138
139 const regex = prevent
140 ? /(\n\n)(?!.*\1)/g
141 : /(\n)(?!.*\1)/g;
142
143 const replacement = prevent
144 ? '\n'
145 : '\n\n';
146
147 report(context, messages[messageId], messageId, {
148 node: secondAdjacentSibling,
149 fix(fixer) {
150 return fixer.replaceText(
151 firstAdjacentSibling,
152 // double or remove the last newline
153 getText(context, firstAdjacentSibling).replace(regex, replacement)
154 );
155 },
156 });
157 }
158 });
159 });
160 },
161 ':matches(JSXElement, JSXFragment) > :matches(JSXElement, JSXExpressionContainer)': (node) => {
162 jsxElementParents.add(node.parent);
163 },
164 };
165 },
166};
Note: See TracBrowser for help on using the repository browser.