eslint-plugin-react-dom 1.24.0-next.0 → 1.24.0-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +165 -107
- package/dist/index.mjs +164 -106
- package/package.json +12 -13
package/dist/index.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var JSX3 = require('@eslint-react/jsx');
|
|
5
|
-
var VAR = require('@eslint-react/var');
|
|
6
|
-
var tsPattern = require('ts-pattern');
|
|
3
|
+
var JSX = require('@eslint-react/jsx');
|
|
7
4
|
var shared = require('@eslint-react/shared');
|
|
5
|
+
var VAR = require('@eslint-react/var');
|
|
8
6
|
var types = require('@typescript-eslint/types');
|
|
9
|
-
var core = require('@eslint-react/core');
|
|
10
7
|
var AST = require('@eslint-react/ast');
|
|
11
8
|
var compareVersions = require('compare-versions');
|
|
12
9
|
|
|
@@ -28,31 +25,41 @@ function _interopNamespace(e) {
|
|
|
28
25
|
return Object.freeze(n);
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
var
|
|
28
|
+
var JSX__namespace = /*#__PURE__*/_interopNamespace(JSX);
|
|
32
29
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
33
30
|
var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
|
|
34
31
|
|
|
35
32
|
// package.json
|
|
36
33
|
var name = "eslint-plugin-react-dom";
|
|
37
|
-
var version = "1.24.0-next.
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
var version = "1.24.0-next.11";
|
|
35
|
+
var createRule = shared.createRuleForPlugin("dom");
|
|
36
|
+
|
|
37
|
+
// src/utils/find-custom-component.ts
|
|
38
|
+
function findCustomComponent(name2, components) {
|
|
39
|
+
return components.findLast((c) => c.name === name2 || c.re.test(name2));
|
|
40
|
+
}
|
|
41
|
+
function findCustomComponentProp(name2, props) {
|
|
42
|
+
return props.findLast((a) => a.as === name2);
|
|
40
43
|
}
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
function getElementNameOnJsxAndDom(node, context, polymorphicPropName, additionalComponents = []) {
|
|
45
|
+
const name2 = JSX__namespace.getElementName(node);
|
|
46
|
+
if (name2 === name2.toLowerCase()) return [name2, name2];
|
|
47
|
+
const component = additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2));
|
|
48
|
+
if (component != null) return [name2, component.as];
|
|
49
|
+
if (polymorphicPropName == null) return [name2, name2];
|
|
50
|
+
const initialScope = context.sourceCode.getScope(node);
|
|
51
|
+
const attributeNode = JSX__namespace.getAttributeNode(
|
|
52
|
+
polymorphicPropName,
|
|
53
|
+
initialScope,
|
|
54
|
+
node.attributes
|
|
48
55
|
);
|
|
49
|
-
if (
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
if (attributeNode == null) return [name2, name2];
|
|
57
|
+
const polymorphicPropValue = VAR__namespace.toResolved(JSX__namespace.getAttributeStaticValue(attributeNode, initialScope)).value;
|
|
58
|
+
if (typeof polymorphicPropValue === "string") {
|
|
59
|
+
return [name2, polymorphicPropValue];
|
|
60
|
+
}
|
|
61
|
+
return [name2, name2];
|
|
54
62
|
}
|
|
55
|
-
var createRule = shared.createRuleForPlugin("dom");
|
|
56
63
|
|
|
57
64
|
// src/rules/no-dangerously-set-innerhtml.ts
|
|
58
65
|
var RULE_NAME = "no-dangerously-set-innerhtml";
|
|
@@ -73,14 +80,19 @@ var no_dangerously_set_innerhtml_default = createRule({
|
|
|
73
80
|
},
|
|
74
81
|
name: RULE_NAME,
|
|
75
82
|
create(context) {
|
|
83
|
+
if (!context.sourceCode.text.includes("dangerouslySetInnerHTML")) return {};
|
|
76
84
|
return {
|
|
77
85
|
JSXElement(node) {
|
|
78
86
|
const attributes = node.openingElement.attributes;
|
|
79
|
-
const
|
|
80
|
-
|
|
87
|
+
const attribute = JSX__namespace.getAttributeNode(
|
|
88
|
+
"dangerouslySetInnerHTML",
|
|
89
|
+
context.sourceCode.getScope(node),
|
|
90
|
+
attributes
|
|
91
|
+
);
|
|
92
|
+
if (attribute == null) return;
|
|
81
93
|
context.report({
|
|
82
94
|
messageId: "noDangerouslySetInnerhtml",
|
|
83
|
-
node:
|
|
95
|
+
node: attribute
|
|
84
96
|
});
|
|
85
97
|
}
|
|
86
98
|
};
|
|
@@ -105,13 +117,13 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
105
117
|
},
|
|
106
118
|
name: RULE_NAME2,
|
|
107
119
|
create(context) {
|
|
120
|
+
if (!context.sourceCode.text.includes("dangerouslySetInnerHTML")) return {};
|
|
108
121
|
return {
|
|
109
122
|
JSXElement(node) {
|
|
110
123
|
const attributes = node.openingElement.attributes;
|
|
111
124
|
const initialScope = context.sourceCode.getScope(node);
|
|
112
|
-
const hasChildren = hasChildrenWithin(node) ||
|
|
113
|
-
|
|
114
|
-
if (hasChildren && hasDangerouslySetInnerHTML) {
|
|
125
|
+
const hasChildren = hasChildrenWithin(node) || JSX__namespace.hasAttribute("children", initialScope, attributes);
|
|
126
|
+
if (hasChildren && JSX__namespace.hasAttribute("dangerouslySetInnerHTML", initialScope, attributes)) {
|
|
115
127
|
context.report({
|
|
116
128
|
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
117
129
|
node
|
|
@@ -123,7 +135,7 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
123
135
|
defaultOptions: []
|
|
124
136
|
});
|
|
125
137
|
function hasChildrenWithin(node) {
|
|
126
|
-
return node.children.length > 0 && node.children[0] != null && !
|
|
138
|
+
return node.children.length > 0 && node.children[0] != null && !JSX__namespace.isLineBreak(node.children[0]);
|
|
127
139
|
}
|
|
128
140
|
var RULE_NAME3 = "no-find-dom-node";
|
|
129
141
|
var RULE_FEATURES3 = [
|
|
@@ -143,6 +155,7 @@ var no_find_dom_node_default = createRule({
|
|
|
143
155
|
},
|
|
144
156
|
name: RULE_NAME3,
|
|
145
157
|
create(context) {
|
|
158
|
+
if (!context.sourceCode.text.includes("findDOMNode")) return {};
|
|
146
159
|
return {
|
|
147
160
|
CallExpression(node) {
|
|
148
161
|
const { callee } = node;
|
|
@@ -182,26 +195,39 @@ var no_missing_button_type_default = createRule({
|
|
|
182
195
|
name: RULE_NAME4,
|
|
183
196
|
create(context) {
|
|
184
197
|
const settings = shared.getSettingsFromContext(context);
|
|
198
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
185
199
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
|
|
186
200
|
return {
|
|
187
201
|
JSXElement(node) {
|
|
188
|
-
const [
|
|
202
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
189
203
|
node.openingElement,
|
|
190
204
|
context,
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
polymorphicPropName,
|
|
206
|
+
additionalComponents
|
|
193
207
|
);
|
|
194
|
-
if (
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (
|
|
208
|
+
if (elementNameOnDom !== "button") return;
|
|
209
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
210
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
211
|
+
const customComponentProp = findCustomComponentProp("type", customComponent?.attributes ?? []);
|
|
212
|
+
const propNameOnJsx = customComponentProp?.name ?? "type";
|
|
213
|
+
const attributeNode = JSX__namespace.getAttributeNode(
|
|
214
|
+
propNameOnJsx,
|
|
215
|
+
elementScope,
|
|
216
|
+
node.openingElement.attributes
|
|
217
|
+
);
|
|
218
|
+
if (attributeNode != null) {
|
|
219
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
220
|
+
const attributeStaticValue = JSX__namespace.getAttributeStaticValue(attributeNode, attributeScope);
|
|
221
|
+
const attributeStringValue = JSX__namespace.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
222
|
+
if (typeof attributeStringValue !== "string") {
|
|
223
|
+
context.report({
|
|
224
|
+
messageId: "noMissingButtonType",
|
|
225
|
+
node: attributeNode
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (typeof customComponentProp?.defaultValue !== "string") {
|
|
205
231
|
context.report({
|
|
206
232
|
messageId: "noMissingButtonType",
|
|
207
233
|
node
|
|
@@ -234,6 +260,9 @@ var validTypes = [
|
|
|
234
260
|
"allow-top-navigation-by-user-activation",
|
|
235
261
|
"allow-top-navigation-to-custom-protocols"
|
|
236
262
|
];
|
|
263
|
+
function hasValidSandBox(value) {
|
|
264
|
+
return typeof value === "string" && value.split(" ").every((value2) => validTypes.some((valid) => valid === value2));
|
|
265
|
+
}
|
|
237
266
|
var no_missing_iframe_sandbox_default = createRule({
|
|
238
267
|
meta: {
|
|
239
268
|
type: "problem",
|
|
@@ -249,37 +278,41 @@ var no_missing_iframe_sandbox_default = createRule({
|
|
|
249
278
|
name: RULE_NAME5,
|
|
250
279
|
create(context) {
|
|
251
280
|
const settings = shared.getSettingsFromContext(context);
|
|
281
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
252
282
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
253
283
|
return {
|
|
254
284
|
JSXElement(node) {
|
|
255
|
-
const [
|
|
285
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
256
286
|
node.openingElement,
|
|
257
287
|
context,
|
|
258
|
-
|
|
259
|
-
|
|
288
|
+
polymorphicPropName,
|
|
289
|
+
additionalComponents
|
|
260
290
|
);
|
|
261
|
-
if (
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (
|
|
291
|
+
if (elementNameOnDom !== "iframe") return;
|
|
292
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
293
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
294
|
+
const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
|
|
295
|
+
const propNameOnJsx = customComponentProp?.name ?? "sandbox";
|
|
296
|
+
const attributeNode = JSX__namespace.getAttributeNode(
|
|
297
|
+
propNameOnJsx,
|
|
298
|
+
elementScope,
|
|
299
|
+
node.openingElement.attributes
|
|
300
|
+
);
|
|
301
|
+
if (attributeNode != null) {
|
|
302
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
303
|
+
const attributeStaticValue = JSX__namespace.getAttributeStaticValue(attributeNode, attributeScope);
|
|
304
|
+
const attributeStringValue = JSX__namespace.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
305
|
+
if (hasValidSandBox(attributeStringValue)) return;
|
|
272
306
|
context.report({
|
|
273
307
|
messageId: "noMissingIframeSandbox",
|
|
274
|
-
node:
|
|
308
|
+
node: attributeNode
|
|
275
309
|
});
|
|
276
310
|
return;
|
|
277
311
|
}
|
|
278
|
-
|
|
279
|
-
if (!values.every((value) => validTypes.some((validType) => validType === value))) {
|
|
312
|
+
if (!hasValidSandBox(customComponentProp?.defaultValue)) {
|
|
280
313
|
context.report({
|
|
281
314
|
messageId: "noMissingIframeSandbox",
|
|
282
|
-
node
|
|
315
|
+
node
|
|
283
316
|
});
|
|
284
317
|
}
|
|
285
318
|
}
|
|
@@ -307,7 +340,7 @@ var no_namespace_default = createRule({
|
|
|
307
340
|
create(context) {
|
|
308
341
|
return {
|
|
309
342
|
JSXOpeningElement(node) {
|
|
310
|
-
const name2 =
|
|
343
|
+
const name2 = JSX__namespace.getElementName(node);
|
|
311
344
|
if (typeof name2 !== "string" || !name2.includes(":")) {
|
|
312
345
|
return;
|
|
313
346
|
}
|
|
@@ -399,11 +432,11 @@ var no_script_url_default = createRule({
|
|
|
399
432
|
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier || node.value == null) {
|
|
400
433
|
return;
|
|
401
434
|
}
|
|
402
|
-
const
|
|
403
|
-
const
|
|
404
|
-
const
|
|
405
|
-
if (typeof
|
|
406
|
-
if (shared.RE_JAVASCRIPT_PROTOCOL.test(
|
|
435
|
+
const attributeScope = context.sourceCode.getScope(node);
|
|
436
|
+
const attributeValue = JSX__namespace.getAttributeStaticValue(node, attributeScope);
|
|
437
|
+
const attributeValueResolved = VAR__namespace.toResolved(attributeValue).value;
|
|
438
|
+
if (typeof attributeValueResolved !== "string") return;
|
|
439
|
+
if (shared.RE_JAVASCRIPT_PROTOCOL.test(attributeValueResolved)) {
|
|
407
440
|
context.report({
|
|
408
441
|
messageId: "noScriptUrl",
|
|
409
442
|
node: node.value
|
|
@@ -1475,9 +1508,15 @@ var RULE_NAME10 = "no-unsafe-iframe-sandbox";
|
|
|
1475
1508
|
var RULE_FEATURES9 = [
|
|
1476
1509
|
"CHK"
|
|
1477
1510
|
];
|
|
1478
|
-
var
|
|
1511
|
+
var unsafeSandboxValues = [
|
|
1479
1512
|
["allow-scripts", "allow-same-origin"]
|
|
1480
1513
|
];
|
|
1514
|
+
function hasNoneOrSafeSandbox(value) {
|
|
1515
|
+
if (value == null) return true;
|
|
1516
|
+
return !unsafeSandboxValues.some((values) => {
|
|
1517
|
+
return values.every((v) => value.includes(v));
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1481
1520
|
var no_unsafe_iframe_sandbox_default = createRule({
|
|
1482
1521
|
meta: {
|
|
1483
1522
|
type: "problem",
|
|
@@ -1493,31 +1532,41 @@ var no_unsafe_iframe_sandbox_default = createRule({
|
|
|
1493
1532
|
name: RULE_NAME10,
|
|
1494
1533
|
create(context) {
|
|
1495
1534
|
const settings = shared.getSettingsFromContext(context);
|
|
1535
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
1496
1536
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
1497
1537
|
return {
|
|
1498
1538
|
JSXElement(node) {
|
|
1499
|
-
const [
|
|
1539
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
1500
1540
|
node.openingElement,
|
|
1501
1541
|
context,
|
|
1502
|
-
|
|
1503
|
-
|
|
1542
|
+
polymorphicPropName,
|
|
1543
|
+
additionalComponents
|
|
1504
1544
|
);
|
|
1505
|
-
if (
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
if (
|
|
1516
|
-
|
|
1517
|
-
|
|
1545
|
+
if (elementNameOnDom !== "iframe") return;
|
|
1546
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
1547
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
1548
|
+
const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
|
|
1549
|
+
const propNameOnJsx = customComponentProp?.name ?? "sandbox";
|
|
1550
|
+
const attributeNode = JSX__namespace.getAttributeNode(
|
|
1551
|
+
propNameOnJsx,
|
|
1552
|
+
elementScope,
|
|
1553
|
+
node.openingElement.attributes
|
|
1554
|
+
);
|
|
1555
|
+
if (attributeNode != null) {
|
|
1556
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
1557
|
+
const attributeStaticValue = JSX__namespace.getAttributeStaticValue(attributeNode, attributeScope);
|
|
1558
|
+
const attributeStringValue = JSX__namespace.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
1559
|
+
if (hasNoneOrSafeSandbox(attributeStringValue)) return;
|
|
1560
|
+
context.report({
|
|
1561
|
+
messageId: "noUnsafeIframeSandbox",
|
|
1562
|
+
node: attributeNode
|
|
1563
|
+
});
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
if (!hasNoneOrSafeSandbox(customComponentProp?.defaultValue)) {
|
|
1518
1567
|
context.report({
|
|
1519
1568
|
messageId: "noUnsafeIframeSandbox",
|
|
1520
|
-
node
|
|
1569
|
+
node
|
|
1521
1570
|
});
|
|
1522
1571
|
}
|
|
1523
1572
|
}
|
|
@@ -1530,11 +1579,11 @@ var RULE_FEATURES10 = [
|
|
|
1530
1579
|
"CHK"
|
|
1531
1580
|
];
|
|
1532
1581
|
function isExternalLinkLike(value) {
|
|
1533
|
-
if (value
|
|
1582
|
+
if (value == null) return false;
|
|
1534
1583
|
return value.startsWith("https://") || /^(?:\w+:|\/\/)/u.test(value);
|
|
1535
1584
|
}
|
|
1536
1585
|
function isSafeRel(value) {
|
|
1537
|
-
if (value
|
|
1586
|
+
if (value == null) return false;
|
|
1538
1587
|
return value === "noreferrer" || /\bnoreferrer\b/u.test(value);
|
|
1539
1588
|
}
|
|
1540
1589
|
var no_unsafe_target_blank_default = createRule({
|
|
@@ -1552,36 +1601,45 @@ var no_unsafe_target_blank_default = createRule({
|
|
|
1552
1601
|
name: RULE_NAME11,
|
|
1553
1602
|
create(context) {
|
|
1554
1603
|
const settings = shared.getSettingsFromContext(context);
|
|
1604
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
1555
1605
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
|
|
1556
1606
|
return {
|
|
1557
1607
|
JSXElement(node) {
|
|
1558
|
-
const [
|
|
1608
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
1559
1609
|
node.openingElement,
|
|
1560
1610
|
context,
|
|
1561
|
-
|
|
1562
|
-
|
|
1611
|
+
polymorphicPropName,
|
|
1612
|
+
additionalComponents
|
|
1563
1613
|
);
|
|
1564
|
-
if (
|
|
1565
|
-
const
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1614
|
+
if (elementNameOnDom !== "a") return;
|
|
1615
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
1616
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
1617
|
+
const getAttributeValue = (name2) => {
|
|
1618
|
+
const customComponentProp = findCustomComponentProp(name2, customComponent?.attributes ?? []);
|
|
1619
|
+
const propNameOnJsx = customComponentProp?.name ?? name2;
|
|
1620
|
+
const attributeNode = JSX__namespace.getAttributeNode(
|
|
1621
|
+
propNameOnJsx,
|
|
1622
|
+
elementScope,
|
|
1623
|
+
node.openingElement.attributes
|
|
1571
1624
|
);
|
|
1625
|
+
if (attributeNode == null) return customComponentProp?.defaultValue;
|
|
1626
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
1627
|
+
const attributeStaticValue = JSX__namespace.getAttributeStaticValue(attributeNode, attributeScope);
|
|
1628
|
+
return JSX__namespace.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
1572
1629
|
};
|
|
1573
|
-
if (
|
|
1630
|
+
if (getAttributeValue("target") !== "_blank") {
|
|
1574
1631
|
return;
|
|
1575
1632
|
}
|
|
1576
|
-
if (!isExternalLinkLike(
|
|
1633
|
+
if (!isExternalLinkLike(getAttributeValue("href"))) {
|
|
1577
1634
|
return;
|
|
1578
1635
|
}
|
|
1579
|
-
if (
|
|
1580
|
-
|
|
1581
|
-
messageId: "noUnsafeTargetBlank",
|
|
1582
|
-
node
|
|
1583
|
-
});
|
|
1636
|
+
if (isSafeRel(getAttributeValue("rel"))) {
|
|
1637
|
+
return;
|
|
1584
1638
|
}
|
|
1639
|
+
context.report({
|
|
1640
|
+
messageId: "noUnsafeTargetBlank",
|
|
1641
|
+
node
|
|
1642
|
+
});
|
|
1585
1643
|
}
|
|
1586
1644
|
};
|
|
1587
1645
|
},
|
|
@@ -1625,7 +1683,7 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1625
1683
|
create(context) {
|
|
1626
1684
|
return {
|
|
1627
1685
|
JSXElement(node) {
|
|
1628
|
-
const elementName =
|
|
1686
|
+
const elementName = JSX__namespace.getElementName(node.openingElement);
|
|
1629
1687
|
if (elementName.length === 0 || !voidElements.has(elementName)) {
|
|
1630
1688
|
return;
|
|
1631
1689
|
}
|
|
@@ -1640,8 +1698,8 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1640
1698
|
}
|
|
1641
1699
|
const { attributes } = node.openingElement;
|
|
1642
1700
|
const initialScope = context.sourceCode.getScope(node);
|
|
1643
|
-
const
|
|
1644
|
-
if (
|
|
1701
|
+
const hasAttribute3 = (name2) => JSX__namespace.hasAttribute(name2, initialScope, attributes);
|
|
1702
|
+
if (hasAttribute3("children") || hasAttribute3("dangerouslySetInnerHTML")) {
|
|
1645
1703
|
context.report({
|
|
1646
1704
|
messageId: "noVoidElementsWithChildren",
|
|
1647
1705
|
node,
|
package/dist/index.mjs
CHANGED
|
@@ -1,34 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as JSX3 from '@eslint-react/jsx';
|
|
3
|
-
import * as VAR from '@eslint-react/var';
|
|
4
|
-
import { match, P } from 'ts-pattern';
|
|
1
|
+
import * as JSX from '@eslint-react/jsx';
|
|
5
2
|
import { createRuleForPlugin, getSettingsFromContext, RE_JAVASCRIPT_PROTOCOL } from '@eslint-react/shared';
|
|
3
|
+
import * as VAR from '@eslint-react/var';
|
|
6
4
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
7
|
-
import { getElementNameAndRepresentName } from '@eslint-react/core';
|
|
8
5
|
import * as AST from '@eslint-react/ast';
|
|
9
6
|
import { compare } from 'compare-versions';
|
|
10
7
|
|
|
11
8
|
// package.json
|
|
12
9
|
var name = "eslint-plugin-react-dom";
|
|
13
|
-
var version = "1.24.0-next.
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
var version = "1.24.0-next.11";
|
|
11
|
+
var createRule = createRuleForPlugin("dom");
|
|
12
|
+
|
|
13
|
+
// src/utils/find-custom-component.ts
|
|
14
|
+
function findCustomComponent(name2, components) {
|
|
15
|
+
return components.findLast((c) => c.name === name2 || c.re.test(name2));
|
|
16
|
+
}
|
|
17
|
+
function findCustomComponentProp(name2, props) {
|
|
18
|
+
return props.findLast((a) => a.as === name2);
|
|
16
19
|
}
|
|
17
|
-
function
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
function getElementNameOnJsxAndDom(node, context, polymorphicPropName, additionalComponents = []) {
|
|
21
|
+
const name2 = JSX.getElementName(node);
|
|
22
|
+
if (name2 === name2.toLowerCase()) return [name2, name2];
|
|
23
|
+
const component = additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2));
|
|
24
|
+
if (component != null) return [name2, component.as];
|
|
25
|
+
if (polymorphicPropName == null) return [name2, name2];
|
|
26
|
+
const initialScope = context.sourceCode.getScope(node);
|
|
27
|
+
const attributeNode = JSX.getAttributeNode(
|
|
28
|
+
polymorphicPropName,
|
|
29
|
+
initialScope,
|
|
30
|
+
node.attributes
|
|
24
31
|
);
|
|
25
|
-
if (
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
if (attributeNode == null) return [name2, name2];
|
|
33
|
+
const polymorphicPropValue = VAR.toResolved(JSX.getAttributeStaticValue(attributeNode, initialScope)).value;
|
|
34
|
+
if (typeof polymorphicPropValue === "string") {
|
|
35
|
+
return [name2, polymorphicPropValue];
|
|
36
|
+
}
|
|
37
|
+
return [name2, name2];
|
|
30
38
|
}
|
|
31
|
-
var createRule = createRuleForPlugin("dom");
|
|
32
39
|
|
|
33
40
|
// src/rules/no-dangerously-set-innerhtml.ts
|
|
34
41
|
var RULE_NAME = "no-dangerously-set-innerhtml";
|
|
@@ -49,14 +56,19 @@ var no_dangerously_set_innerhtml_default = createRule({
|
|
|
49
56
|
},
|
|
50
57
|
name: RULE_NAME,
|
|
51
58
|
create(context) {
|
|
59
|
+
if (!context.sourceCode.text.includes("dangerouslySetInnerHTML")) return {};
|
|
52
60
|
return {
|
|
53
61
|
JSXElement(node) {
|
|
54
62
|
const attributes = node.openingElement.attributes;
|
|
55
|
-
const
|
|
56
|
-
|
|
63
|
+
const attribute = JSX.getAttributeNode(
|
|
64
|
+
"dangerouslySetInnerHTML",
|
|
65
|
+
context.sourceCode.getScope(node),
|
|
66
|
+
attributes
|
|
67
|
+
);
|
|
68
|
+
if (attribute == null) return;
|
|
57
69
|
context.report({
|
|
58
70
|
messageId: "noDangerouslySetInnerhtml",
|
|
59
|
-
node:
|
|
71
|
+
node: attribute
|
|
60
72
|
});
|
|
61
73
|
}
|
|
62
74
|
};
|
|
@@ -81,13 +93,13 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
81
93
|
},
|
|
82
94
|
name: RULE_NAME2,
|
|
83
95
|
create(context) {
|
|
96
|
+
if (!context.sourceCode.text.includes("dangerouslySetInnerHTML")) return {};
|
|
84
97
|
return {
|
|
85
98
|
JSXElement(node) {
|
|
86
99
|
const attributes = node.openingElement.attributes;
|
|
87
100
|
const initialScope = context.sourceCode.getScope(node);
|
|
88
|
-
const hasChildren = hasChildrenWithin(node) ||
|
|
89
|
-
|
|
90
|
-
if (hasChildren && hasDangerouslySetInnerHTML) {
|
|
101
|
+
const hasChildren = hasChildrenWithin(node) || JSX.hasAttribute("children", initialScope, attributes);
|
|
102
|
+
if (hasChildren && JSX.hasAttribute("dangerouslySetInnerHTML", initialScope, attributes)) {
|
|
91
103
|
context.report({
|
|
92
104
|
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
93
105
|
node
|
|
@@ -99,7 +111,7 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
99
111
|
defaultOptions: []
|
|
100
112
|
});
|
|
101
113
|
function hasChildrenWithin(node) {
|
|
102
|
-
return node.children.length > 0 && node.children[0] != null && !
|
|
114
|
+
return node.children.length > 0 && node.children[0] != null && !JSX.isLineBreak(node.children[0]);
|
|
103
115
|
}
|
|
104
116
|
var RULE_NAME3 = "no-find-dom-node";
|
|
105
117
|
var RULE_FEATURES3 = [
|
|
@@ -119,6 +131,7 @@ var no_find_dom_node_default = createRule({
|
|
|
119
131
|
},
|
|
120
132
|
name: RULE_NAME3,
|
|
121
133
|
create(context) {
|
|
134
|
+
if (!context.sourceCode.text.includes("findDOMNode")) return {};
|
|
122
135
|
return {
|
|
123
136
|
CallExpression(node) {
|
|
124
137
|
const { callee } = node;
|
|
@@ -158,26 +171,39 @@ var no_missing_button_type_default = createRule({
|
|
|
158
171
|
name: RULE_NAME4,
|
|
159
172
|
create(context) {
|
|
160
173
|
const settings = getSettingsFromContext(context);
|
|
174
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
161
175
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
|
|
162
176
|
return {
|
|
163
177
|
JSXElement(node) {
|
|
164
|
-
const [
|
|
178
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
165
179
|
node.openingElement,
|
|
166
180
|
context,
|
|
167
|
-
|
|
168
|
-
|
|
181
|
+
polymorphicPropName,
|
|
182
|
+
additionalComponents
|
|
169
183
|
);
|
|
170
|
-
if (
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (
|
|
184
|
+
if (elementNameOnDom !== "button") return;
|
|
185
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
186
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
187
|
+
const customComponentProp = findCustomComponentProp("type", customComponent?.attributes ?? []);
|
|
188
|
+
const propNameOnJsx = customComponentProp?.name ?? "type";
|
|
189
|
+
const attributeNode = JSX.getAttributeNode(
|
|
190
|
+
propNameOnJsx,
|
|
191
|
+
elementScope,
|
|
192
|
+
node.openingElement.attributes
|
|
193
|
+
);
|
|
194
|
+
if (attributeNode != null) {
|
|
195
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
196
|
+
const attributeStaticValue = JSX.getAttributeStaticValue(attributeNode, attributeScope);
|
|
197
|
+
const attributeStringValue = JSX.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
198
|
+
if (typeof attributeStringValue !== "string") {
|
|
199
|
+
context.report({
|
|
200
|
+
messageId: "noMissingButtonType",
|
|
201
|
+
node: attributeNode
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (typeof customComponentProp?.defaultValue !== "string") {
|
|
181
207
|
context.report({
|
|
182
208
|
messageId: "noMissingButtonType",
|
|
183
209
|
node
|
|
@@ -210,6 +236,9 @@ var validTypes = [
|
|
|
210
236
|
"allow-top-navigation-by-user-activation",
|
|
211
237
|
"allow-top-navigation-to-custom-protocols"
|
|
212
238
|
];
|
|
239
|
+
function hasValidSandBox(value) {
|
|
240
|
+
return typeof value === "string" && value.split(" ").every((value2) => validTypes.some((valid) => valid === value2));
|
|
241
|
+
}
|
|
213
242
|
var no_missing_iframe_sandbox_default = createRule({
|
|
214
243
|
meta: {
|
|
215
244
|
type: "problem",
|
|
@@ -225,37 +254,41 @@ var no_missing_iframe_sandbox_default = createRule({
|
|
|
225
254
|
name: RULE_NAME5,
|
|
226
255
|
create(context) {
|
|
227
256
|
const settings = getSettingsFromContext(context);
|
|
257
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
228
258
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
229
259
|
return {
|
|
230
260
|
JSXElement(node) {
|
|
231
|
-
const [
|
|
261
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
232
262
|
node.openingElement,
|
|
233
263
|
context,
|
|
234
|
-
|
|
235
|
-
|
|
264
|
+
polymorphicPropName,
|
|
265
|
+
additionalComponents
|
|
236
266
|
);
|
|
237
|
-
if (
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if (
|
|
267
|
+
if (elementNameOnDom !== "iframe") return;
|
|
268
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
269
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
270
|
+
const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
|
|
271
|
+
const propNameOnJsx = customComponentProp?.name ?? "sandbox";
|
|
272
|
+
const attributeNode = JSX.getAttributeNode(
|
|
273
|
+
propNameOnJsx,
|
|
274
|
+
elementScope,
|
|
275
|
+
node.openingElement.attributes
|
|
276
|
+
);
|
|
277
|
+
if (attributeNode != null) {
|
|
278
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
279
|
+
const attributeStaticValue = JSX.getAttributeStaticValue(attributeNode, attributeScope);
|
|
280
|
+
const attributeStringValue = JSX.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
281
|
+
if (hasValidSandBox(attributeStringValue)) return;
|
|
248
282
|
context.report({
|
|
249
283
|
messageId: "noMissingIframeSandbox",
|
|
250
|
-
node:
|
|
284
|
+
node: attributeNode
|
|
251
285
|
});
|
|
252
286
|
return;
|
|
253
287
|
}
|
|
254
|
-
|
|
255
|
-
if (!values.every((value) => validTypes.some((validType) => validType === value))) {
|
|
288
|
+
if (!hasValidSandBox(customComponentProp?.defaultValue)) {
|
|
256
289
|
context.report({
|
|
257
290
|
messageId: "noMissingIframeSandbox",
|
|
258
|
-
node
|
|
291
|
+
node
|
|
259
292
|
});
|
|
260
293
|
}
|
|
261
294
|
}
|
|
@@ -283,7 +316,7 @@ var no_namespace_default = createRule({
|
|
|
283
316
|
create(context) {
|
|
284
317
|
return {
|
|
285
318
|
JSXOpeningElement(node) {
|
|
286
|
-
const name2 =
|
|
319
|
+
const name2 = JSX.getElementName(node);
|
|
287
320
|
if (typeof name2 !== "string" || !name2.includes(":")) {
|
|
288
321
|
return;
|
|
289
322
|
}
|
|
@@ -375,11 +408,11 @@ var no_script_url_default = createRule({
|
|
|
375
408
|
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier || node.value == null) {
|
|
376
409
|
return;
|
|
377
410
|
}
|
|
378
|
-
const
|
|
379
|
-
const
|
|
380
|
-
const
|
|
381
|
-
if (typeof
|
|
382
|
-
if (RE_JAVASCRIPT_PROTOCOL.test(
|
|
411
|
+
const attributeScope = context.sourceCode.getScope(node);
|
|
412
|
+
const attributeValue = JSX.getAttributeStaticValue(node, attributeScope);
|
|
413
|
+
const attributeValueResolved = VAR.toResolved(attributeValue).value;
|
|
414
|
+
if (typeof attributeValueResolved !== "string") return;
|
|
415
|
+
if (RE_JAVASCRIPT_PROTOCOL.test(attributeValueResolved)) {
|
|
383
416
|
context.report({
|
|
384
417
|
messageId: "noScriptUrl",
|
|
385
418
|
node: node.value
|
|
@@ -1451,9 +1484,15 @@ var RULE_NAME10 = "no-unsafe-iframe-sandbox";
|
|
|
1451
1484
|
var RULE_FEATURES9 = [
|
|
1452
1485
|
"CHK"
|
|
1453
1486
|
];
|
|
1454
|
-
var
|
|
1487
|
+
var unsafeSandboxValues = [
|
|
1455
1488
|
["allow-scripts", "allow-same-origin"]
|
|
1456
1489
|
];
|
|
1490
|
+
function hasNoneOrSafeSandbox(value) {
|
|
1491
|
+
if (value == null) return true;
|
|
1492
|
+
return !unsafeSandboxValues.some((values) => {
|
|
1493
|
+
return values.every((v) => value.includes(v));
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1457
1496
|
var no_unsafe_iframe_sandbox_default = createRule({
|
|
1458
1497
|
meta: {
|
|
1459
1498
|
type: "problem",
|
|
@@ -1469,31 +1508,41 @@ var no_unsafe_iframe_sandbox_default = createRule({
|
|
|
1469
1508
|
name: RULE_NAME10,
|
|
1470
1509
|
create(context) {
|
|
1471
1510
|
const settings = getSettingsFromContext(context);
|
|
1511
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
1472
1512
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
1473
1513
|
return {
|
|
1474
1514
|
JSXElement(node) {
|
|
1475
|
-
const [
|
|
1515
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
1476
1516
|
node.openingElement,
|
|
1477
1517
|
context,
|
|
1478
|
-
|
|
1479
|
-
|
|
1518
|
+
polymorphicPropName,
|
|
1519
|
+
additionalComponents
|
|
1480
1520
|
);
|
|
1481
|
-
if (
|
|
1482
|
-
const
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
if (
|
|
1492
|
-
|
|
1493
|
-
|
|
1521
|
+
if (elementNameOnDom !== "iframe") return;
|
|
1522
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
1523
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
1524
|
+
const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
|
|
1525
|
+
const propNameOnJsx = customComponentProp?.name ?? "sandbox";
|
|
1526
|
+
const attributeNode = JSX.getAttributeNode(
|
|
1527
|
+
propNameOnJsx,
|
|
1528
|
+
elementScope,
|
|
1529
|
+
node.openingElement.attributes
|
|
1530
|
+
);
|
|
1531
|
+
if (attributeNode != null) {
|
|
1532
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
1533
|
+
const attributeStaticValue = JSX.getAttributeStaticValue(attributeNode, attributeScope);
|
|
1534
|
+
const attributeStringValue = JSX.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
1535
|
+
if (hasNoneOrSafeSandbox(attributeStringValue)) return;
|
|
1536
|
+
context.report({
|
|
1537
|
+
messageId: "noUnsafeIframeSandbox",
|
|
1538
|
+
node: attributeNode
|
|
1539
|
+
});
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
if (!hasNoneOrSafeSandbox(customComponentProp?.defaultValue)) {
|
|
1494
1543
|
context.report({
|
|
1495
1544
|
messageId: "noUnsafeIframeSandbox",
|
|
1496
|
-
node
|
|
1545
|
+
node
|
|
1497
1546
|
});
|
|
1498
1547
|
}
|
|
1499
1548
|
}
|
|
@@ -1506,11 +1555,11 @@ var RULE_FEATURES10 = [
|
|
|
1506
1555
|
"CHK"
|
|
1507
1556
|
];
|
|
1508
1557
|
function isExternalLinkLike(value) {
|
|
1509
|
-
if (value
|
|
1558
|
+
if (value == null) return false;
|
|
1510
1559
|
return value.startsWith("https://") || /^(?:\w+:|\/\/)/u.test(value);
|
|
1511
1560
|
}
|
|
1512
1561
|
function isSafeRel(value) {
|
|
1513
|
-
if (value
|
|
1562
|
+
if (value == null) return false;
|
|
1514
1563
|
return value === "noreferrer" || /\bnoreferrer\b/u.test(value);
|
|
1515
1564
|
}
|
|
1516
1565
|
var no_unsafe_target_blank_default = createRule({
|
|
@@ -1528,36 +1577,45 @@ var no_unsafe_target_blank_default = createRule({
|
|
|
1528
1577
|
name: RULE_NAME11,
|
|
1529
1578
|
create(context) {
|
|
1530
1579
|
const settings = getSettingsFromContext(context);
|
|
1580
|
+
const polymorphicPropName = settings.polymorphicPropName;
|
|
1531
1581
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
|
|
1532
1582
|
return {
|
|
1533
1583
|
JSXElement(node) {
|
|
1534
|
-
const [
|
|
1584
|
+
const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
|
|
1535
1585
|
node.openingElement,
|
|
1536
1586
|
context,
|
|
1537
|
-
|
|
1538
|
-
|
|
1587
|
+
polymorphicPropName,
|
|
1588
|
+
additionalComponents
|
|
1539
1589
|
);
|
|
1540
|
-
if (
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1590
|
+
if (elementNameOnDom !== "a") return;
|
|
1591
|
+
const elementScope = context.sourceCode.getScope(node);
|
|
1592
|
+
const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
|
|
1593
|
+
const getAttributeValue = (name2) => {
|
|
1594
|
+
const customComponentProp = findCustomComponentProp(name2, customComponent?.attributes ?? []);
|
|
1595
|
+
const propNameOnJsx = customComponentProp?.name ?? name2;
|
|
1596
|
+
const attributeNode = JSX.getAttributeNode(
|
|
1597
|
+
propNameOnJsx,
|
|
1598
|
+
elementScope,
|
|
1599
|
+
node.openingElement.attributes
|
|
1547
1600
|
);
|
|
1601
|
+
if (attributeNode == null) return customComponentProp?.defaultValue;
|
|
1602
|
+
const attributeScope = context.sourceCode.getScope(attributeNode);
|
|
1603
|
+
const attributeStaticValue = JSX.getAttributeStaticValue(attributeNode, attributeScope);
|
|
1604
|
+
return JSX.toResolvedAttributeValue(propNameOnJsx, attributeStaticValue);
|
|
1548
1605
|
};
|
|
1549
|
-
if (
|
|
1606
|
+
if (getAttributeValue("target") !== "_blank") {
|
|
1550
1607
|
return;
|
|
1551
1608
|
}
|
|
1552
|
-
if (!isExternalLinkLike(
|
|
1609
|
+
if (!isExternalLinkLike(getAttributeValue("href"))) {
|
|
1553
1610
|
return;
|
|
1554
1611
|
}
|
|
1555
|
-
if (
|
|
1556
|
-
|
|
1557
|
-
messageId: "noUnsafeTargetBlank",
|
|
1558
|
-
node
|
|
1559
|
-
});
|
|
1612
|
+
if (isSafeRel(getAttributeValue("rel"))) {
|
|
1613
|
+
return;
|
|
1560
1614
|
}
|
|
1615
|
+
context.report({
|
|
1616
|
+
messageId: "noUnsafeTargetBlank",
|
|
1617
|
+
node
|
|
1618
|
+
});
|
|
1561
1619
|
}
|
|
1562
1620
|
};
|
|
1563
1621
|
},
|
|
@@ -1601,7 +1659,7 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1601
1659
|
create(context) {
|
|
1602
1660
|
return {
|
|
1603
1661
|
JSXElement(node) {
|
|
1604
|
-
const elementName =
|
|
1662
|
+
const elementName = JSX.getElementName(node.openingElement);
|
|
1605
1663
|
if (elementName.length === 0 || !voidElements.has(elementName)) {
|
|
1606
1664
|
return;
|
|
1607
1665
|
}
|
|
@@ -1616,8 +1674,8 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1616
1674
|
}
|
|
1617
1675
|
const { attributes } = node.openingElement;
|
|
1618
1676
|
const initialScope = context.sourceCode.getScope(node);
|
|
1619
|
-
const
|
|
1620
|
-
if (
|
|
1677
|
+
const hasAttribute3 = (name2) => JSX.hasAttribute(name2, initialScope, attributes);
|
|
1678
|
+
if (hasAttribute3("children") || hasAttribute3("dangerouslySetInnerHTML")) {
|
|
1621
1679
|
context.report({
|
|
1622
1680
|
messageId: "noVoidElementsWithChildren",
|
|
1623
1681
|
node,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-dom",
|
|
3
|
-
"version": "1.24.0-next.
|
|
3
|
+
"version": "1.24.0-next.11",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React DOM related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -41,23 +41,22 @@
|
|
|
41
41
|
"./package.json"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@typescript-eslint/scope-manager": "^8.
|
|
45
|
-
"@typescript-eslint/types": "^8.
|
|
46
|
-
"@typescript-eslint/utils": "^8.
|
|
44
|
+
"@typescript-eslint/scope-manager": "^8.20.0",
|
|
45
|
+
"@typescript-eslint/types": "^8.20.0",
|
|
46
|
+
"@typescript-eslint/utils": "^8.20.0",
|
|
47
47
|
"compare-versions": "^6.1.1",
|
|
48
48
|
"string-ts": "^2.2.0",
|
|
49
49
|
"ts-pattern": "^5.6.0",
|
|
50
|
-
"@eslint-react/ast": "1.24.0-next.
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/
|
|
55
|
-
"@eslint-react/
|
|
56
|
-
"@eslint-react/shared": "1.24.0-next.0"
|
|
50
|
+
"@eslint-react/ast": "1.24.0-next.11",
|
|
51
|
+
"@eslint-react/eff": "1.24.0-next.11",
|
|
52
|
+
"@eslint-react/jsx": "1.24.0-next.11",
|
|
53
|
+
"@eslint-react/var": "1.24.0-next.11",
|
|
54
|
+
"@eslint-react/core": "1.24.0-next.11",
|
|
55
|
+
"@eslint-react/shared": "1.24.0-next.11"
|
|
57
56
|
},
|
|
58
57
|
"devDependencies": {
|
|
59
|
-
"@types/react": "^19.0.
|
|
60
|
-
"@types/react-dom": "^19.0.
|
|
58
|
+
"@types/react": "^19.0.7",
|
|
59
|
+
"@types/react-dom": "^19.0.3",
|
|
61
60
|
"tsup": "^8.3.5",
|
|
62
61
|
"@workspace/configs": "0.0.0"
|
|
63
62
|
},
|