source: imaps-frontend/node_modules/eslint-plugin-react/lib/rules/jsx-child-element-spacing.js

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

Update repo after prototype presentation

  • Property mode set to 100644
File size: 2.8 KB
RevLine 
[d565449]1'use strict';
2
3const docsUrl = require('../util/docsUrl');
4const report = require('../util/report');
5
6// This list is taken from https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements
7
8// Note: 'br' is not included because whitespace around br tags is inconsequential to the rendered output
9const INLINE_ELEMENTS = new Set([
10 'a',
11 'abbr',
12 'acronym',
13 'b',
14 'bdo',
15 'big',
16 'button',
17 'cite',
18 'code',
19 'dfn',
20 'em',
21 'i',
22 'img',
23 'input',
24 'kbd',
25 'label',
26 'map',
27 'object',
28 'q',
29 'samp',
30 'script',
31 'select',
32 'small',
33 'span',
34 'strong',
35 'sub',
36 'sup',
37 'textarea',
38 'tt',
39 'var',
40]);
41
42const messages = {
43 spacingAfterPrev: 'Ambiguous spacing after previous element {{element}}',
44 spacingBeforeNext: 'Ambiguous spacing before next element {{element}}',
45};
46
47/** @type {import('eslint').Rule.RuleModule} */
48module.exports = {
49 meta: {
50 docs: {
51 description: 'Enforce or disallow spaces inside of curly braces in JSX attributes and expressions',
52 category: 'Stylistic Issues',
53 recommended: false,
54 url: docsUrl('jsx-child-element-spacing'),
55 },
56 fixable: null,
57
58 messages,
59
60 schema: [],
61 },
62 create(context) {
63 const TEXT_FOLLOWING_ELEMENT_PATTERN = /^\s*\n\s*\S/;
64 const TEXT_PRECEDING_ELEMENT_PATTERN = /\S\s*\n\s*$/;
65
66 const elementName = (node) => (
67 node.openingElement
68 && node.openingElement.name
69 && node.openingElement.name.type === 'JSXIdentifier'
70 && node.openingElement.name.name
71 );
72
73 const isInlineElement = (node) => (
74 node.type === 'JSXElement'
75 && INLINE_ELEMENTS.has(elementName(node))
76 );
77
78 const handleJSX = (node) => {
79 let lastChild = null;
80 let child = null;
81 (node.children.concat([null])).forEach((nextChild) => {
82 if (
83 (lastChild || nextChild)
84 && (!lastChild || isInlineElement(lastChild))
85 && (child && (child.type === 'Literal' || child.type === 'JSXText'))
86 && (!nextChild || isInlineElement(nextChild))
87 && true
88 ) {
89 if (lastChild && child.value.match(TEXT_FOLLOWING_ELEMENT_PATTERN)) {
90 report(context, messages.spacingAfterPrev, 'spacingAfterPrev', {
91 node: lastChild,
92 loc: lastChild.loc.end,
93 data: {
94 element: elementName(lastChild),
95 },
96 });
97 } else if (nextChild && child.value.match(TEXT_PRECEDING_ELEMENT_PATTERN)) {
98 report(context, messages.spacingBeforeNext, 'spacingBeforeNext', {
99 node: nextChild,
100 loc: nextChild.loc.start,
101 data: {
102 element: elementName(nextChild),
103 },
104 });
105 }
106 }
107 lastChild = child;
108 child = nextChild;
109 });
110 };
111
112 return {
113 JSXElement: handleJSX,
114 JSXFragment: handleJSX,
115 };
116 },
117};
Note: See TracBrowser for help on using the repository browser.