UNPKG

3.55 kBJavaScriptView Raw
1const { fixingNodes } = require('./es-beautifier-common.js');
2
3const create = (context) => {
4 const option = context.options[0] || {
5 allowSingleLine: true,
6 maxLenInSingleLine: 80,
7 };
8 const allowSingleLine = option.allowSingleLine;
9 const maxLen = option.maxLenInSingleLine;
10 const indentStr = option.indentStr || ' ';
11
12 const sourceCode = context.getSourceCode();
13
14 const enterJSXElement = (node) => {
15 if (allowSingleLine &&
16 node.loc.start.line === node.loc.end.line &&
17 (!maxLen || sourceCode.lines[node.loc.end.line - 1].length < maxLen)) {
18 // we accept one line
19 return;
20 }
21
22 let parent = node.parent;
23 while (parent && parent.loc.start.line === node.loc.start.line) {
24 if (fixingNodes.has(parent)) {
25 // we ignore this time as we are still in the process
26 return;
27 }
28 parent = parent.parent;
29 }
30
31 if (node.children.length) {
32 const src = sourceCode.getText(node, node.loc.start.column);
33 const currIndent = src.substring(0, node.loc.start.column).match(/(\s*)$/)[1];
34 if (node.children[0].type === 'Literal') {
35 const literal = node.children[0];
36 const headingSpaces = literal.value.match(/^(\s*)/)[1];
37 const expectedHeading = `\n${currIndent}${indentStr}`;
38 if (headingSpaces !== expectedHeading) {
39 const range = [
40 literal.range[0],
41 literal.range[0] + headingSpaces.length,
42 ];
43 context.report({
44 node,
45 message: 'Literal in JSX Element should be on a separate line.',
46 loc: node.loc.start,
47 fix: fixer => fixer.replaceTextRange(range, expectedHeading),
48 });
49 }
50 }
51 if (node.children[node.children.length - 1].type === 'Literal') {
52 const literal = node.children[node.children.length - 1];
53 const tailingSpaces = literal.value.match(/(\s*)$/)[1];
54 const expectedTailing = `\n${currIndent}`;
55 if (tailingSpaces !== expectedTailing) {
56 const range = [
57 literal.range[1] - tailingSpaces.length,
58 literal.range[1],
59 ];
60 context.report({
61 node,
62 message: 'Literal in JSX Element should be on a separate line.',
63 loc: node.loc.start,
64 fix: fixer => fixer.replaceTextRange(range, expectedTailing),
65 });
66 }
67 }
68 if (node.children[0].type === 'JSXExpressionContainer') {
69 context.report({
70 node,
71 message: 'Literal in JSX Element should be on a separate line.',
72 loc: node.loc.start,
73 fix: fixer => fixer.insertTextBefore(node.children[0], '\n'),
74 });
75 }
76 if (node.children[node.children.length - 1].type === 'JSXExpressionContainer') {
77 context.report({
78 node,
79 message: 'Literal in JSX Element should be on a separate line.',
80 loc: node.loc.start,
81 fix: fixer => fixer.insertTextBefore(node.closingElement, '\n'),
82 });
83 }
84 }
85 };
86
87 return {
88 JSXElement: enterJSXElement,
89 };
90};
91
92module.exports = {
93 meta: {
94 docs: {
95 description: 'enforce literals in elements on separte lines in JSX',
96 category: 'Stylistic Issues',
97 },
98 fixable: 'whitespace',
99 schema: [{
100 type: 'object',
101 properties: {
102 allowSingleLine: { type: 'boolean' },
103 maxLenInSingleLine: { type: 'integer' },
104 indentStr: { type: 'string' },
105 },
106 additionalProperties: false,
107 }],
108 },
109 create,
110};