eslint-plugin-react-dom 1.23.3-next.8 → 1.24.0-next.0
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 +153 -166
- package/dist/index.mjs +154 -168
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var eff = require('@eslint-react/eff');
|
|
4
|
-
var
|
|
4
|
+
var JSX3 = require('@eslint-react/jsx');
|
|
5
|
+
var VAR = require('@eslint-react/var');
|
|
6
|
+
var tsPattern = require('ts-pattern');
|
|
5
7
|
var shared = require('@eslint-react/shared');
|
|
6
8
|
var types = require('@typescript-eslint/types');
|
|
7
9
|
var core = require('@eslint-react/core');
|
|
8
10
|
var AST = require('@eslint-react/ast');
|
|
9
11
|
var compareVersions = require('compare-versions');
|
|
10
|
-
var tsPattern = require('ts-pattern');
|
|
11
12
|
|
|
12
13
|
function _interopNamespace(e) {
|
|
13
14
|
if (e && e.__esModule) return e;
|
|
@@ -27,20 +28,31 @@ function _interopNamespace(e) {
|
|
|
27
28
|
return Object.freeze(n);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
var
|
|
31
|
+
var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
|
|
32
|
+
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
31
33
|
var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
|
|
32
34
|
|
|
33
35
|
// package.json
|
|
34
36
|
var name = "eslint-plugin-react-dom";
|
|
35
|
-
var version = "1.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
var version = "1.24.0-next.0";
|
|
38
|
+
function getAdditionalAttributes(name2, additionalComponents) {
|
|
39
|
+
return additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2))?.attributes ?? [];
|
|
40
|
+
}
|
|
41
|
+
function getAttributeStringValue(attributeName, element, context, additionalAttributes) {
|
|
42
|
+
const attributeConfig = additionalAttributes.findLast((attr) => attr.as === attributeName);
|
|
43
|
+
const actualAttributeName = attributeConfig?.name ?? attributeName;
|
|
44
|
+
const actualAttributeNode = JSX3__namespace.findPropInAttributes(
|
|
45
|
+
actualAttributeName,
|
|
46
|
+
context.sourceCode.getScope(element),
|
|
47
|
+
element.openingElement.attributes
|
|
42
48
|
);
|
|
49
|
+
if (actualAttributeNode === eff._) return attributeConfig?.defaultValue;
|
|
50
|
+
const actualAttributeScope = context.sourceCode.getScope(actualAttributeNode);
|
|
51
|
+
const actualAttributeValue = JSX3__namespace.getPropValue(actualAttributeNode, actualAttributeScope);
|
|
52
|
+
const actualAttributeValueResolved = VAR__namespace.toResolved(actualAttributeValue).value;
|
|
53
|
+
return tsPattern.match(actualAttributeValueResolved).with(tsPattern.P.string, eff.identity).with({ [actualAttributeName]: tsPattern.P.select(tsPattern.P.string) }, eff.identity).otherwise(() => eff._);
|
|
43
54
|
}
|
|
55
|
+
var createRule = shared.createRuleForPlugin("dom");
|
|
44
56
|
|
|
45
57
|
// src/rules/no-dangerously-set-innerhtml.ts
|
|
46
58
|
var RULE_NAME = "no-dangerously-set-innerhtml";
|
|
@@ -63,12 +75,13 @@ var no_dangerously_set_innerhtml_default = createRule({
|
|
|
63
75
|
create(context) {
|
|
64
76
|
return {
|
|
65
77
|
JSXElement(node) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
const attributes = node.openingElement.attributes;
|
|
79
|
+
const prop = JSX3__namespace.getProp("dangerouslySetInnerHTML", context.sourceCode.getScope(node), attributes);
|
|
80
|
+
if (prop === eff._) return;
|
|
81
|
+
context.report({
|
|
82
|
+
messageId: "noDangerouslySetInnerhtml",
|
|
83
|
+
node: prop
|
|
84
|
+
});
|
|
72
85
|
}
|
|
73
86
|
};
|
|
74
87
|
},
|
|
@@ -78,10 +91,6 @@ var RULE_NAME2 = "no-dangerously-set-innerhtml-with-children";
|
|
|
78
91
|
var RULE_FEATURES2 = [
|
|
79
92
|
"CHK"
|
|
80
93
|
];
|
|
81
|
-
function firstChildIsText(node) {
|
|
82
|
-
const [firstChild] = node.children;
|
|
83
|
-
return node.children.length > 0 && !eff.isNullable(firstChild) && !JSX8__namespace.isLineBreak(firstChild);
|
|
84
|
-
}
|
|
85
94
|
var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
86
95
|
meta: {
|
|
87
96
|
type: "problem",
|
|
@@ -98,22 +107,24 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
98
107
|
create(context) {
|
|
99
108
|
return {
|
|
100
109
|
JSXElement(node) {
|
|
110
|
+
const attributes = node.openingElement.attributes;
|
|
101
111
|
const initialScope = context.sourceCode.getScope(node);
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
const hasChildren = hasChildrenWithin(node) || JSX3__namespace.hasProp("children", initialScope, attributes);
|
|
113
|
+
const hasDangerouslySetInnerHTML = JSX3__namespace.hasProp("dangerouslySetInnerHTML", initialScope, attributes);
|
|
114
|
+
if (hasChildren && hasDangerouslySetInnerHTML) {
|
|
115
|
+
context.report({
|
|
116
|
+
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
117
|
+
node
|
|
118
|
+
});
|
|
107
119
|
}
|
|
108
|
-
context.report({
|
|
109
|
-
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
110
|
-
node
|
|
111
|
-
});
|
|
112
120
|
}
|
|
113
121
|
};
|
|
114
122
|
},
|
|
115
123
|
defaultOptions: []
|
|
116
124
|
});
|
|
125
|
+
function hasChildrenWithin(node) {
|
|
126
|
+
return node.children.length > 0 && node.children[0] != null && !JSX3__namespace.isLineBreak(node.children[0]);
|
|
127
|
+
}
|
|
117
128
|
var RULE_NAME3 = "no-find-dom-node";
|
|
118
129
|
var RULE_FEATURES3 = [
|
|
119
130
|
"CHK"
|
|
@@ -170,22 +181,32 @@ var no_missing_button_type_default = createRule({
|
|
|
170
181
|
},
|
|
171
182
|
name: RULE_NAME4,
|
|
172
183
|
create(context) {
|
|
184
|
+
const settings = shared.getSettingsFromContext(context);
|
|
185
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
|
|
173
186
|
return {
|
|
174
187
|
JSXElement(node) {
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return
|
|
188
|
+
const [name2, representName] = core.getElementNameAndRepresentName(
|
|
189
|
+
node.openingElement,
|
|
190
|
+
context,
|
|
191
|
+
settings.polymorphicPropName,
|
|
192
|
+
settings.additionalComponents
|
|
193
|
+
);
|
|
194
|
+
if (representName !== "button") return;
|
|
195
|
+
const getPropValue3 = (propName) => {
|
|
196
|
+
return getAttributeStringValue(
|
|
197
|
+
propName,
|
|
198
|
+
node,
|
|
199
|
+
context,
|
|
200
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
const prop = getPropValue3("type");
|
|
204
|
+
if (typeof prop !== "string") {
|
|
205
|
+
context.report({
|
|
206
|
+
messageId: "noMissingButtonType",
|
|
207
|
+
node
|
|
208
|
+
});
|
|
184
209
|
}
|
|
185
|
-
context.report({
|
|
186
|
-
messageId: "noMissingButtonType",
|
|
187
|
-
node
|
|
188
|
-
});
|
|
189
210
|
}
|
|
190
211
|
};
|
|
191
212
|
},
|
|
@@ -227,36 +248,40 @@ var no_missing_iframe_sandbox_default = createRule({
|
|
|
227
248
|
},
|
|
228
249
|
name: RULE_NAME5,
|
|
229
250
|
create(context) {
|
|
251
|
+
const settings = shared.getSettingsFromContext(context);
|
|
252
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
230
253
|
return {
|
|
231
254
|
JSXElement(node) {
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
255
|
+
const [name2, representName] = core.getElementNameAndRepresentName(
|
|
256
|
+
node.openingElement,
|
|
257
|
+
context,
|
|
258
|
+
settings.polymorphicPropName,
|
|
259
|
+
settings.additionalComponents
|
|
260
|
+
);
|
|
261
|
+
if (representName !== "iframe") return;
|
|
262
|
+
const getPropValue3 = (propName) => {
|
|
263
|
+
return getAttributeStringValue(
|
|
264
|
+
propName,
|
|
265
|
+
node,
|
|
266
|
+
context,
|
|
267
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
268
|
+
);
|
|
269
|
+
};
|
|
270
|
+
const sandboxValue = getPropValue3("sandbox");
|
|
271
|
+
if (sandboxValue === eff._) {
|
|
240
272
|
context.report({
|
|
241
273
|
messageId: "noMissingIframeSandbox",
|
|
242
274
|
node: node.openingElement
|
|
243
275
|
});
|
|
244
276
|
return;
|
|
245
277
|
}
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
);
|
|
253
|
-
if (hasValidSandbox) {
|
|
254
|
-
return;
|
|
278
|
+
const values = sandboxValue.split(" ");
|
|
279
|
+
if (!values.every((value) => validTypes.some((validType) => validType === value))) {
|
|
280
|
+
context.report({
|
|
281
|
+
messageId: "noMissingIframeSandbox",
|
|
282
|
+
node: node.openingElement
|
|
283
|
+
});
|
|
255
284
|
}
|
|
256
|
-
context.report({
|
|
257
|
-
messageId: "noMissingIframeSandbox",
|
|
258
|
-
node: prop
|
|
259
|
-
});
|
|
260
285
|
}
|
|
261
286
|
};
|
|
262
287
|
},
|
|
@@ -282,8 +307,8 @@ var no_namespace_default = createRule({
|
|
|
282
307
|
create(context) {
|
|
283
308
|
return {
|
|
284
309
|
JSXOpeningElement(node) {
|
|
285
|
-
const name2 =
|
|
286
|
-
if (
|
|
310
|
+
const name2 = JSX3__namespace.getElementName(node);
|
|
311
|
+
if (typeof name2 !== "string" || !name2.includes(":")) {
|
|
287
312
|
return;
|
|
288
313
|
}
|
|
289
314
|
context.report({
|
|
@@ -374,12 +399,11 @@ var no_script_url_default = createRule({
|
|
|
374
399
|
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier || node.value == null) {
|
|
375
400
|
return;
|
|
376
401
|
}
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
)
|
|
382
|
-
if (isJavaScript) {
|
|
402
|
+
const propScope = context.sourceCode.getScope(node);
|
|
403
|
+
const propValue = JSX3__namespace.getPropValue(node, propScope);
|
|
404
|
+
const propValueResolved = VAR__namespace.toResolved(propValue).value;
|
|
405
|
+
if (typeof propValueResolved !== "string") return;
|
|
406
|
+
if (shared.RE_JAVASCRIPT_PROTOCOL.test(propValueResolved)) {
|
|
383
407
|
context.report({
|
|
384
408
|
messageId: "noScriptUrl",
|
|
385
409
|
node: node.value
|
|
@@ -1453,7 +1477,6 @@ var RULE_FEATURES9 = [
|
|
|
1453
1477
|
];
|
|
1454
1478
|
var unsafeCombinations = [
|
|
1455
1479
|
["allow-scripts", "allow-same-origin"]
|
|
1456
|
-
// ...
|
|
1457
1480
|
];
|
|
1458
1481
|
var no_unsafe_iframe_sandbox_default = createRule({
|
|
1459
1482
|
meta: {
|
|
@@ -1469,37 +1492,34 @@ var no_unsafe_iframe_sandbox_default = createRule({
|
|
|
1469
1492
|
},
|
|
1470
1493
|
name: RULE_NAME10,
|
|
1471
1494
|
create(context) {
|
|
1495
|
+
const settings = shared.getSettingsFromContext(context);
|
|
1496
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
1472
1497
|
return {
|
|
1473
1498
|
JSXElement(node) {
|
|
1474
|
-
const
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
1480
|
-
const mbProp = JSX8__namespace.findPropInAttributes(attributes, initialScope)("sandbox");
|
|
1481
|
-
if (eff.O.isNone(mbProp)) {
|
|
1482
|
-
return;
|
|
1483
|
-
}
|
|
1484
|
-
const prop = mbProp.value;
|
|
1485
|
-
const isSafeSandboxValue = !eff.F.pipe(
|
|
1486
|
-
JSX8__namespace.getPropValue(prop, context.sourceCode.getScope(prop)),
|
|
1487
|
-
eff.O.flatMapNullable(
|
|
1488
|
-
(v) => tsPattern.match(v).with(tsPattern.P.string, eff.F.identity).with({ sandbox: tsPattern.P.string }, ({ sandbox }) => sandbox).otherwise(eff.F.constNull)
|
|
1489
|
-
),
|
|
1490
|
-
eff.O.filter(eff.isString),
|
|
1491
|
-
eff.O.map((value) => value.split(" ")),
|
|
1492
|
-
eff.O.exists(
|
|
1493
|
-
(values) => unsafeCombinations.some((combinations) => combinations.every((unsafeValue) => values.includes(unsafeValue)))
|
|
1494
|
-
)
|
|
1499
|
+
const [name2, representName] = core.getElementNameAndRepresentName(
|
|
1500
|
+
node.openingElement,
|
|
1501
|
+
context,
|
|
1502
|
+
settings.polymorphicPropName,
|
|
1503
|
+
settings.additionalComponents
|
|
1495
1504
|
);
|
|
1496
|
-
if (
|
|
1497
|
-
|
|
1505
|
+
if (representName !== "iframe") return;
|
|
1506
|
+
const getPropValue3 = (propName) => {
|
|
1507
|
+
return getAttributeStringValue(
|
|
1508
|
+
propName,
|
|
1509
|
+
node,
|
|
1510
|
+
context,
|
|
1511
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
1512
|
+
);
|
|
1513
|
+
};
|
|
1514
|
+
const sandboxValue = getPropValue3("sandbox");
|
|
1515
|
+
if (sandboxValue === eff._) return;
|
|
1516
|
+
const values = sandboxValue.split(" ");
|
|
1517
|
+
if (unsafeCombinations.some((unsafes) => unsafes.every((x) => values.includes(x)))) {
|
|
1518
|
+
context.report({
|
|
1519
|
+
messageId: "noUnsafeIframeSandbox",
|
|
1520
|
+
node: node.openingElement
|
|
1521
|
+
});
|
|
1498
1522
|
}
|
|
1499
|
-
context.report({
|
|
1500
|
-
messageId: "noUnsafeIframeSandbox",
|
|
1501
|
-
node: prop
|
|
1502
|
-
});
|
|
1503
1523
|
}
|
|
1504
1524
|
};
|
|
1505
1525
|
},
|
|
@@ -1510,9 +1530,11 @@ var RULE_FEATURES10 = [
|
|
|
1510
1530
|
"CHK"
|
|
1511
1531
|
];
|
|
1512
1532
|
function isExternalLinkLike(value) {
|
|
1533
|
+
if (value === eff._) return false;
|
|
1513
1534
|
return value.startsWith("https://") || /^(?:\w+:|\/\/)/u.test(value);
|
|
1514
1535
|
}
|
|
1515
1536
|
function isSafeRel(value) {
|
|
1537
|
+
if (value === eff._) return false;
|
|
1516
1538
|
return value === "noreferrer" || /\bnoreferrer\b/u.test(value);
|
|
1517
1539
|
}
|
|
1518
1540
|
var no_unsafe_target_blank_default = createRule({
|
|
@@ -1531,70 +1553,36 @@ var no_unsafe_target_blank_default = createRule({
|
|
|
1531
1553
|
create(context) {
|
|
1532
1554
|
const settings = shared.getSettingsFromContext(context);
|
|
1533
1555
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
|
|
1534
|
-
function getReportDescriptor(node) {
|
|
1535
|
-
const name2 = JSX8__namespace.getElementName(node.openingElement);
|
|
1536
|
-
const elementName = core.getElementRepresentName(node.openingElement, context);
|
|
1537
|
-
if (elementName !== "a" && !additionalComponents.some((c) => c.re.test(name2))) {
|
|
1538
|
-
return eff.O.none();
|
|
1539
|
-
}
|
|
1540
|
-
const { attributes } = node.openingElement;
|
|
1541
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
1542
|
-
const additionalAttributes = additionalComponents.findLast((c) => c.re.test(name2))?.attributes ?? [];
|
|
1543
|
-
const [
|
|
1544
|
-
targetPropName,
|
|
1545
|
-
targetPropDefaultValue
|
|
1546
|
-
] = findAttrInCustomAttributes("target", additionalAttributes);
|
|
1547
|
-
const targetProp = JSX8__namespace.findPropInAttributes(attributes, initialScope)(targetPropName);
|
|
1548
|
-
const targetPropValue = eff.O.isNone(targetProp) ? eff.O.fromNullable(targetPropDefaultValue) : eff.F.pipe(
|
|
1549
|
-
targetProp,
|
|
1550
|
-
eff.O.flatMap((attr) => JSX8__namespace.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1551
|
-
eff.O.flatMapNullable(
|
|
1552
|
-
(v) => tsPattern.match(v).with(tsPattern.P.string, eff.F.identity).with({ [targetPropName]: tsPattern.P.string }, (v2) => v2[targetPropName]).otherwise(eff.F.constNull)
|
|
1553
|
-
),
|
|
1554
|
-
eff.O.filter(eff.isString)
|
|
1555
|
-
);
|
|
1556
|
-
if (!eff.O.exists(targetPropValue, (t) => t === "_blank")) {
|
|
1557
|
-
return eff.O.none();
|
|
1558
|
-
}
|
|
1559
|
-
const [
|
|
1560
|
-
hrefPropName,
|
|
1561
|
-
hrefPropDefaultValue
|
|
1562
|
-
] = findAttrInCustomAttributes("href", additionalAttributes);
|
|
1563
|
-
const hrefProp = JSX8__namespace.findPropInAttributes(attributes, initialScope)(hrefPropName);
|
|
1564
|
-
const hrefPropValue = eff.O.isNone(hrefProp) ? eff.O.fromNullable(hrefPropDefaultValue) : eff.F.pipe(
|
|
1565
|
-
hrefProp,
|
|
1566
|
-
eff.O.flatMap((attr) => JSX8__namespace.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1567
|
-
eff.O.flatMapNullable(
|
|
1568
|
-
(v) => tsPattern.match(v).with(tsPattern.P.string, eff.F.identity).with({ [hrefPropName]: tsPattern.P.string }, (v2) => v2[hrefPropName]).otherwise(eff.F.constNull)
|
|
1569
|
-
),
|
|
1570
|
-
eff.O.filter(eff.isString)
|
|
1571
|
-
);
|
|
1572
|
-
if (!eff.O.exists(hrefPropValue, isExternalLinkLike)) {
|
|
1573
|
-
return eff.O.none();
|
|
1574
|
-
}
|
|
1575
|
-
const [
|
|
1576
|
-
relPropName,
|
|
1577
|
-
relPropDefaultValue
|
|
1578
|
-
] = findAttrInCustomAttributes("rel", additionalAttributes);
|
|
1579
|
-
const relProp = JSX8__namespace.findPropInAttributes(attributes, initialScope)(relPropName);
|
|
1580
|
-
const relPropValue = eff.O.isNone(relProp) ? eff.O.fromNullable(relPropDefaultValue) : eff.F.pipe(
|
|
1581
|
-
relProp,
|
|
1582
|
-
eff.O.flatMap((attr) => JSX8__namespace.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1583
|
-
eff.O.flatMapNullable(
|
|
1584
|
-
(v) => tsPattern.match(v).with(tsPattern.P.string, eff.F.identity).with({ [relPropName]: tsPattern.P.string }, (v2) => v2[relPropName]).otherwise(eff.F.constNull)
|
|
1585
|
-
),
|
|
1586
|
-
eff.O.filter(eff.isString)
|
|
1587
|
-
);
|
|
1588
|
-
if (eff.O.exists(relPropValue, isSafeRel)) {
|
|
1589
|
-
return eff.O.none();
|
|
1590
|
-
}
|
|
1591
|
-
return eff.O.some({
|
|
1592
|
-
messageId: "noUnsafeTargetBlank",
|
|
1593
|
-
node
|
|
1594
|
-
});
|
|
1595
|
-
}
|
|
1596
1556
|
return {
|
|
1597
|
-
JSXElement
|
|
1557
|
+
JSXElement(node) {
|
|
1558
|
+
const [name2, representName] = core.getElementNameAndRepresentName(
|
|
1559
|
+
node.openingElement,
|
|
1560
|
+
context,
|
|
1561
|
+
settings.polymorphicPropName,
|
|
1562
|
+
settings.additionalComponents
|
|
1563
|
+
);
|
|
1564
|
+
if (representName !== "a") return;
|
|
1565
|
+
const getPropValue3 = (propName) => {
|
|
1566
|
+
return getAttributeStringValue(
|
|
1567
|
+
propName,
|
|
1568
|
+
node,
|
|
1569
|
+
context,
|
|
1570
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
1571
|
+
);
|
|
1572
|
+
};
|
|
1573
|
+
if (getPropValue3("target") !== "_blank") {
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
if (!isExternalLinkLike(getPropValue3("href"))) {
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
if (!isSafeRel(getPropValue3("rel"))) {
|
|
1580
|
+
context.report({
|
|
1581
|
+
messageId: "noUnsafeTargetBlank",
|
|
1582
|
+
node
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1598
1586
|
};
|
|
1599
1587
|
},
|
|
1600
1588
|
defaultOptions: []
|
|
@@ -1637,7 +1625,7 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1637
1625
|
create(context) {
|
|
1638
1626
|
return {
|
|
1639
1627
|
JSXElement(node) {
|
|
1640
|
-
const elementName =
|
|
1628
|
+
const elementName = JSX3__namespace.getElementName(node.openingElement);
|
|
1641
1629
|
if (elementName.length === 0 || !voidElements.has(elementName)) {
|
|
1642
1630
|
return;
|
|
1643
1631
|
}
|
|
@@ -1652,9 +1640,8 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1652
1640
|
}
|
|
1653
1641
|
const { attributes } = node.openingElement;
|
|
1654
1642
|
const initialScope = context.sourceCode.getScope(node);
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1657
|
-
if (hasChildrenOrDangerAttr) {
|
|
1643
|
+
const hasAttribute = (name2) => JSX3__namespace.findPropInAttributes(name2, initialScope, attributes) !== eff._;
|
|
1644
|
+
if (hasAttribute("children") || hasAttribute("dangerouslySetInnerHTML")) {
|
|
1658
1645
|
context.report({
|
|
1659
1646
|
messageId: "noVoidElementsWithChildren",
|
|
1660
1647
|
node,
|
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
1
|
+
import { _, identity } from '@eslint-react/eff';
|
|
2
|
+
import * as JSX3 from '@eslint-react/jsx';
|
|
3
|
+
import * as VAR from '@eslint-react/var';
|
|
4
|
+
import { match, P } from 'ts-pattern';
|
|
5
|
+
import { createRuleForPlugin, getSettingsFromContext, RE_JAVASCRIPT_PROTOCOL } from '@eslint-react/shared';
|
|
4
6
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
5
|
-
import {
|
|
7
|
+
import { getElementNameAndRepresentName } from '@eslint-react/core';
|
|
6
8
|
import * as AST from '@eslint-react/ast';
|
|
7
9
|
import { compare } from 'compare-versions';
|
|
8
|
-
import { match, P } from 'ts-pattern';
|
|
9
10
|
|
|
10
11
|
// package.json
|
|
11
12
|
var name = "eslint-plugin-react-dom";
|
|
12
|
-
var version = "1.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
var version = "1.24.0-next.0";
|
|
14
|
+
function getAdditionalAttributes(name2, additionalComponents) {
|
|
15
|
+
return additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2))?.attributes ?? [];
|
|
16
|
+
}
|
|
17
|
+
function getAttributeStringValue(attributeName, element, context, additionalAttributes) {
|
|
18
|
+
const attributeConfig = additionalAttributes.findLast((attr) => attr.as === attributeName);
|
|
19
|
+
const actualAttributeName = attributeConfig?.name ?? attributeName;
|
|
20
|
+
const actualAttributeNode = JSX3.findPropInAttributes(
|
|
21
|
+
actualAttributeName,
|
|
22
|
+
context.sourceCode.getScope(element),
|
|
23
|
+
element.openingElement.attributes
|
|
19
24
|
);
|
|
25
|
+
if (actualAttributeNode === _) return attributeConfig?.defaultValue;
|
|
26
|
+
const actualAttributeScope = context.sourceCode.getScope(actualAttributeNode);
|
|
27
|
+
const actualAttributeValue = JSX3.getPropValue(actualAttributeNode, actualAttributeScope);
|
|
28
|
+
const actualAttributeValueResolved = VAR.toResolved(actualAttributeValue).value;
|
|
29
|
+
return match(actualAttributeValueResolved).with(P.string, identity).with({ [actualAttributeName]: P.select(P.string) }, identity).otherwise(() => _);
|
|
20
30
|
}
|
|
31
|
+
var createRule = createRuleForPlugin("dom");
|
|
21
32
|
|
|
22
33
|
// src/rules/no-dangerously-set-innerhtml.ts
|
|
23
34
|
var RULE_NAME = "no-dangerously-set-innerhtml";
|
|
@@ -40,12 +51,13 @@ var no_dangerously_set_innerhtml_default = createRule({
|
|
|
40
51
|
create(context) {
|
|
41
52
|
return {
|
|
42
53
|
JSXElement(node) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
const attributes = node.openingElement.attributes;
|
|
55
|
+
const prop = JSX3.getProp("dangerouslySetInnerHTML", context.sourceCode.getScope(node), attributes);
|
|
56
|
+
if (prop === _) return;
|
|
57
|
+
context.report({
|
|
58
|
+
messageId: "noDangerouslySetInnerhtml",
|
|
59
|
+
node: prop
|
|
60
|
+
});
|
|
49
61
|
}
|
|
50
62
|
};
|
|
51
63
|
},
|
|
@@ -55,10 +67,6 @@ var RULE_NAME2 = "no-dangerously-set-innerhtml-with-children";
|
|
|
55
67
|
var RULE_FEATURES2 = [
|
|
56
68
|
"CHK"
|
|
57
69
|
];
|
|
58
|
-
function firstChildIsText(node) {
|
|
59
|
-
const [firstChild] = node.children;
|
|
60
|
-
return node.children.length > 0 && !isNullable(firstChild) && !JSX8.isLineBreak(firstChild);
|
|
61
|
-
}
|
|
62
70
|
var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
63
71
|
meta: {
|
|
64
72
|
type: "problem",
|
|
@@ -75,22 +83,24 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
|
|
|
75
83
|
create(context) {
|
|
76
84
|
return {
|
|
77
85
|
JSXElement(node) {
|
|
86
|
+
const attributes = node.openingElement.attributes;
|
|
78
87
|
const initialScope = context.sourceCode.getScope(node);
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
const hasChildren = hasChildrenWithin(node) || JSX3.hasProp("children", initialScope, attributes);
|
|
89
|
+
const hasDangerouslySetInnerHTML = JSX3.hasProp("dangerouslySetInnerHTML", initialScope, attributes);
|
|
90
|
+
if (hasChildren && hasDangerouslySetInnerHTML) {
|
|
91
|
+
context.report({
|
|
92
|
+
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
93
|
+
node
|
|
94
|
+
});
|
|
84
95
|
}
|
|
85
|
-
context.report({
|
|
86
|
-
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
87
|
-
node
|
|
88
|
-
});
|
|
89
96
|
}
|
|
90
97
|
};
|
|
91
98
|
},
|
|
92
99
|
defaultOptions: []
|
|
93
100
|
});
|
|
101
|
+
function hasChildrenWithin(node) {
|
|
102
|
+
return node.children.length > 0 && node.children[0] != null && !JSX3.isLineBreak(node.children[0]);
|
|
103
|
+
}
|
|
94
104
|
var RULE_NAME3 = "no-find-dom-node";
|
|
95
105
|
var RULE_FEATURES3 = [
|
|
96
106
|
"CHK"
|
|
@@ -147,22 +157,32 @@ var no_missing_button_type_default = createRule({
|
|
|
147
157
|
},
|
|
148
158
|
name: RULE_NAME4,
|
|
149
159
|
create(context) {
|
|
160
|
+
const settings = getSettingsFromContext(context);
|
|
161
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
|
|
150
162
|
return {
|
|
151
163
|
JSXElement(node) {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return
|
|
164
|
+
const [name2, representName] = getElementNameAndRepresentName(
|
|
165
|
+
node.openingElement,
|
|
166
|
+
context,
|
|
167
|
+
settings.polymorphicPropName,
|
|
168
|
+
settings.additionalComponents
|
|
169
|
+
);
|
|
170
|
+
if (representName !== "button") return;
|
|
171
|
+
const getPropValue3 = (propName) => {
|
|
172
|
+
return getAttributeStringValue(
|
|
173
|
+
propName,
|
|
174
|
+
node,
|
|
175
|
+
context,
|
|
176
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
const prop = getPropValue3("type");
|
|
180
|
+
if (typeof prop !== "string") {
|
|
181
|
+
context.report({
|
|
182
|
+
messageId: "noMissingButtonType",
|
|
183
|
+
node
|
|
184
|
+
});
|
|
161
185
|
}
|
|
162
|
-
context.report({
|
|
163
|
-
messageId: "noMissingButtonType",
|
|
164
|
-
node
|
|
165
|
-
});
|
|
166
186
|
}
|
|
167
187
|
};
|
|
168
188
|
},
|
|
@@ -204,36 +224,40 @@ var no_missing_iframe_sandbox_default = createRule({
|
|
|
204
224
|
},
|
|
205
225
|
name: RULE_NAME5,
|
|
206
226
|
create(context) {
|
|
227
|
+
const settings = getSettingsFromContext(context);
|
|
228
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
207
229
|
return {
|
|
208
230
|
JSXElement(node) {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
231
|
+
const [name2, representName] = getElementNameAndRepresentName(
|
|
232
|
+
node.openingElement,
|
|
233
|
+
context,
|
|
234
|
+
settings.polymorphicPropName,
|
|
235
|
+
settings.additionalComponents
|
|
236
|
+
);
|
|
237
|
+
if (representName !== "iframe") return;
|
|
238
|
+
const getPropValue3 = (propName) => {
|
|
239
|
+
return getAttributeStringValue(
|
|
240
|
+
propName,
|
|
241
|
+
node,
|
|
242
|
+
context,
|
|
243
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
244
|
+
);
|
|
245
|
+
};
|
|
246
|
+
const sandboxValue = getPropValue3("sandbox");
|
|
247
|
+
if (sandboxValue === _) {
|
|
217
248
|
context.report({
|
|
218
249
|
messageId: "noMissingIframeSandbox",
|
|
219
250
|
node: node.openingElement
|
|
220
251
|
});
|
|
221
252
|
return;
|
|
222
253
|
}
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
);
|
|
230
|
-
if (hasValidSandbox) {
|
|
231
|
-
return;
|
|
254
|
+
const values = sandboxValue.split(" ");
|
|
255
|
+
if (!values.every((value) => validTypes.some((validType) => validType === value))) {
|
|
256
|
+
context.report({
|
|
257
|
+
messageId: "noMissingIframeSandbox",
|
|
258
|
+
node: node.openingElement
|
|
259
|
+
});
|
|
232
260
|
}
|
|
233
|
-
context.report({
|
|
234
|
-
messageId: "noMissingIframeSandbox",
|
|
235
|
-
node: prop
|
|
236
|
-
});
|
|
237
261
|
}
|
|
238
262
|
};
|
|
239
263
|
},
|
|
@@ -259,8 +283,8 @@ var no_namespace_default = createRule({
|
|
|
259
283
|
create(context) {
|
|
260
284
|
return {
|
|
261
285
|
JSXOpeningElement(node) {
|
|
262
|
-
const name2 =
|
|
263
|
-
if (
|
|
286
|
+
const name2 = JSX3.getElementName(node);
|
|
287
|
+
if (typeof name2 !== "string" || !name2.includes(":")) {
|
|
264
288
|
return;
|
|
265
289
|
}
|
|
266
290
|
context.report({
|
|
@@ -351,12 +375,11 @@ var no_script_url_default = createRule({
|
|
|
351
375
|
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier || node.value == null) {
|
|
352
376
|
return;
|
|
353
377
|
}
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
)
|
|
359
|
-
if (isJavaScript) {
|
|
378
|
+
const propScope = context.sourceCode.getScope(node);
|
|
379
|
+
const propValue = JSX3.getPropValue(node, propScope);
|
|
380
|
+
const propValueResolved = VAR.toResolved(propValue).value;
|
|
381
|
+
if (typeof propValueResolved !== "string") return;
|
|
382
|
+
if (RE_JAVASCRIPT_PROTOCOL.test(propValueResolved)) {
|
|
360
383
|
context.report({
|
|
361
384
|
messageId: "noScriptUrl",
|
|
362
385
|
node: node.value
|
|
@@ -1430,7 +1453,6 @@ var RULE_FEATURES9 = [
|
|
|
1430
1453
|
];
|
|
1431
1454
|
var unsafeCombinations = [
|
|
1432
1455
|
["allow-scripts", "allow-same-origin"]
|
|
1433
|
-
// ...
|
|
1434
1456
|
];
|
|
1435
1457
|
var no_unsafe_iframe_sandbox_default = createRule({
|
|
1436
1458
|
meta: {
|
|
@@ -1446,37 +1468,34 @@ var no_unsafe_iframe_sandbox_default = createRule({
|
|
|
1446
1468
|
},
|
|
1447
1469
|
name: RULE_NAME10,
|
|
1448
1470
|
create(context) {
|
|
1471
|
+
const settings = getSettingsFromContext(context);
|
|
1472
|
+
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
|
|
1449
1473
|
return {
|
|
1450
1474
|
JSXElement(node) {
|
|
1451
|
-
const
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
1457
|
-
const mbProp = JSX8.findPropInAttributes(attributes, initialScope)("sandbox");
|
|
1458
|
-
if (O.isNone(mbProp)) {
|
|
1459
|
-
return;
|
|
1460
|
-
}
|
|
1461
|
-
const prop = mbProp.value;
|
|
1462
|
-
const isSafeSandboxValue = !F.pipe(
|
|
1463
|
-
JSX8.getPropValue(prop, context.sourceCode.getScope(prop)),
|
|
1464
|
-
O.flatMapNullable(
|
|
1465
|
-
(v) => match(v).with(P.string, F.identity).with({ sandbox: P.string }, ({ sandbox }) => sandbox).otherwise(F.constNull)
|
|
1466
|
-
),
|
|
1467
|
-
O.filter(isString),
|
|
1468
|
-
O.map((value) => value.split(" ")),
|
|
1469
|
-
O.exists(
|
|
1470
|
-
(values) => unsafeCombinations.some((combinations) => combinations.every((unsafeValue) => values.includes(unsafeValue)))
|
|
1471
|
-
)
|
|
1475
|
+
const [name2, representName] = getElementNameAndRepresentName(
|
|
1476
|
+
node.openingElement,
|
|
1477
|
+
context,
|
|
1478
|
+
settings.polymorphicPropName,
|
|
1479
|
+
settings.additionalComponents
|
|
1472
1480
|
);
|
|
1473
|
-
if (
|
|
1474
|
-
|
|
1481
|
+
if (representName !== "iframe") return;
|
|
1482
|
+
const getPropValue3 = (propName) => {
|
|
1483
|
+
return getAttributeStringValue(
|
|
1484
|
+
propName,
|
|
1485
|
+
node,
|
|
1486
|
+
context,
|
|
1487
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
1488
|
+
);
|
|
1489
|
+
};
|
|
1490
|
+
const sandboxValue = getPropValue3("sandbox");
|
|
1491
|
+
if (sandboxValue === _) return;
|
|
1492
|
+
const values = sandboxValue.split(" ");
|
|
1493
|
+
if (unsafeCombinations.some((unsafes) => unsafes.every((x) => values.includes(x)))) {
|
|
1494
|
+
context.report({
|
|
1495
|
+
messageId: "noUnsafeIframeSandbox",
|
|
1496
|
+
node: node.openingElement
|
|
1497
|
+
});
|
|
1475
1498
|
}
|
|
1476
|
-
context.report({
|
|
1477
|
-
messageId: "noUnsafeIframeSandbox",
|
|
1478
|
-
node: prop
|
|
1479
|
-
});
|
|
1480
1499
|
}
|
|
1481
1500
|
};
|
|
1482
1501
|
},
|
|
@@ -1487,9 +1506,11 @@ var RULE_FEATURES10 = [
|
|
|
1487
1506
|
"CHK"
|
|
1488
1507
|
];
|
|
1489
1508
|
function isExternalLinkLike(value) {
|
|
1509
|
+
if (value === _) return false;
|
|
1490
1510
|
return value.startsWith("https://") || /^(?:\w+:|\/\/)/u.test(value);
|
|
1491
1511
|
}
|
|
1492
1512
|
function isSafeRel(value) {
|
|
1513
|
+
if (value === _) return false;
|
|
1493
1514
|
return value === "noreferrer" || /\bnoreferrer\b/u.test(value);
|
|
1494
1515
|
}
|
|
1495
1516
|
var no_unsafe_target_blank_default = createRule({
|
|
@@ -1508,70 +1529,36 @@ var no_unsafe_target_blank_default = createRule({
|
|
|
1508
1529
|
create(context) {
|
|
1509
1530
|
const settings = getSettingsFromContext(context);
|
|
1510
1531
|
const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
|
|
1511
|
-
function getReportDescriptor(node) {
|
|
1512
|
-
const name2 = JSX8.getElementName(node.openingElement);
|
|
1513
|
-
const elementName = getElementRepresentName(node.openingElement, context);
|
|
1514
|
-
if (elementName !== "a" && !additionalComponents.some((c) => c.re.test(name2))) {
|
|
1515
|
-
return O.none();
|
|
1516
|
-
}
|
|
1517
|
-
const { attributes } = node.openingElement;
|
|
1518
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
1519
|
-
const additionalAttributes = additionalComponents.findLast((c) => c.re.test(name2))?.attributes ?? [];
|
|
1520
|
-
const [
|
|
1521
|
-
targetPropName,
|
|
1522
|
-
targetPropDefaultValue
|
|
1523
|
-
] = findAttrInCustomAttributes("target", additionalAttributes);
|
|
1524
|
-
const targetProp = JSX8.findPropInAttributes(attributes, initialScope)(targetPropName);
|
|
1525
|
-
const targetPropValue = O.isNone(targetProp) ? O.fromNullable(targetPropDefaultValue) : F.pipe(
|
|
1526
|
-
targetProp,
|
|
1527
|
-
O.flatMap((attr) => JSX8.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1528
|
-
O.flatMapNullable(
|
|
1529
|
-
(v) => match(v).with(P.string, F.identity).with({ [targetPropName]: P.string }, (v2) => v2[targetPropName]).otherwise(F.constNull)
|
|
1530
|
-
),
|
|
1531
|
-
O.filter(isString)
|
|
1532
|
-
);
|
|
1533
|
-
if (!O.exists(targetPropValue, (t) => t === "_blank")) {
|
|
1534
|
-
return O.none();
|
|
1535
|
-
}
|
|
1536
|
-
const [
|
|
1537
|
-
hrefPropName,
|
|
1538
|
-
hrefPropDefaultValue
|
|
1539
|
-
] = findAttrInCustomAttributes("href", additionalAttributes);
|
|
1540
|
-
const hrefProp = JSX8.findPropInAttributes(attributes, initialScope)(hrefPropName);
|
|
1541
|
-
const hrefPropValue = O.isNone(hrefProp) ? O.fromNullable(hrefPropDefaultValue) : F.pipe(
|
|
1542
|
-
hrefProp,
|
|
1543
|
-
O.flatMap((attr) => JSX8.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1544
|
-
O.flatMapNullable(
|
|
1545
|
-
(v) => match(v).with(P.string, F.identity).with({ [hrefPropName]: P.string }, (v2) => v2[hrefPropName]).otherwise(F.constNull)
|
|
1546
|
-
),
|
|
1547
|
-
O.filter(isString)
|
|
1548
|
-
);
|
|
1549
|
-
if (!O.exists(hrefPropValue, isExternalLinkLike)) {
|
|
1550
|
-
return O.none();
|
|
1551
|
-
}
|
|
1552
|
-
const [
|
|
1553
|
-
relPropName,
|
|
1554
|
-
relPropDefaultValue
|
|
1555
|
-
] = findAttrInCustomAttributes("rel", additionalAttributes);
|
|
1556
|
-
const relProp = JSX8.findPropInAttributes(attributes, initialScope)(relPropName);
|
|
1557
|
-
const relPropValue = O.isNone(relProp) ? O.fromNullable(relPropDefaultValue) : F.pipe(
|
|
1558
|
-
relProp,
|
|
1559
|
-
O.flatMap((attr) => JSX8.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
1560
|
-
O.flatMapNullable(
|
|
1561
|
-
(v) => match(v).with(P.string, F.identity).with({ [relPropName]: P.string }, (v2) => v2[relPropName]).otherwise(F.constNull)
|
|
1562
|
-
),
|
|
1563
|
-
O.filter(isString)
|
|
1564
|
-
);
|
|
1565
|
-
if (O.exists(relPropValue, isSafeRel)) {
|
|
1566
|
-
return O.none();
|
|
1567
|
-
}
|
|
1568
|
-
return O.some({
|
|
1569
|
-
messageId: "noUnsafeTargetBlank",
|
|
1570
|
-
node
|
|
1571
|
-
});
|
|
1572
|
-
}
|
|
1573
1532
|
return {
|
|
1574
|
-
JSXElement
|
|
1533
|
+
JSXElement(node) {
|
|
1534
|
+
const [name2, representName] = getElementNameAndRepresentName(
|
|
1535
|
+
node.openingElement,
|
|
1536
|
+
context,
|
|
1537
|
+
settings.polymorphicPropName,
|
|
1538
|
+
settings.additionalComponents
|
|
1539
|
+
);
|
|
1540
|
+
if (representName !== "a") return;
|
|
1541
|
+
const getPropValue3 = (propName) => {
|
|
1542
|
+
return getAttributeStringValue(
|
|
1543
|
+
propName,
|
|
1544
|
+
node,
|
|
1545
|
+
context,
|
|
1546
|
+
getAdditionalAttributes(name2, additionalComponents)
|
|
1547
|
+
);
|
|
1548
|
+
};
|
|
1549
|
+
if (getPropValue3("target") !== "_blank") {
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
if (!isExternalLinkLike(getPropValue3("href"))) {
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
if (!isSafeRel(getPropValue3("rel"))) {
|
|
1556
|
+
context.report({
|
|
1557
|
+
messageId: "noUnsafeTargetBlank",
|
|
1558
|
+
node
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1575
1562
|
};
|
|
1576
1563
|
},
|
|
1577
1564
|
defaultOptions: []
|
|
@@ -1614,7 +1601,7 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1614
1601
|
create(context) {
|
|
1615
1602
|
return {
|
|
1616
1603
|
JSXElement(node) {
|
|
1617
|
-
const elementName =
|
|
1604
|
+
const elementName = JSX3.getElementName(node.openingElement);
|
|
1618
1605
|
if (elementName.length === 0 || !voidElements.has(elementName)) {
|
|
1619
1606
|
return;
|
|
1620
1607
|
}
|
|
@@ -1629,9 +1616,8 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1629
1616
|
}
|
|
1630
1617
|
const { attributes } = node.openingElement;
|
|
1631
1618
|
const initialScope = context.sourceCode.getScope(node);
|
|
1632
|
-
const
|
|
1633
|
-
|
|
1634
|
-
if (hasChildrenOrDangerAttr) {
|
|
1619
|
+
const hasAttribute = (name2) => JSX3.findPropInAttributes(name2, initialScope, attributes) !== _;
|
|
1620
|
+
if (hasAttribute("children") || hasAttribute("dangerouslySetInnerHTML")) {
|
|
1635
1621
|
context.report({
|
|
1636
1622
|
messageId: "noVoidElementsWithChildren",
|
|
1637
1623
|
node,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-dom",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0-next.0",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React DOM related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"eslint-plugin",
|
|
11
11
|
"eslint-plugin-react-dom"
|
|
12
12
|
],
|
|
13
|
-
"homepage": "https://github.com/
|
|
13
|
+
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
14
14
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/Rel1cx/eslint-react/issues"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/
|
|
19
|
+
"url": "git+https://github.com/Rel1cx/eslint-react.git",
|
|
20
20
|
"directory": "packages/plugins/eslint-plugin-react-dom"
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
@@ -47,13 +47,13 @@
|
|
|
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.
|
|
51
|
-
"@eslint-react/core": "1.
|
|
52
|
-
"@eslint-react/eff": "1.
|
|
53
|
-
"@eslint-react/jsx": "1.
|
|
54
|
-
"@eslint-react/
|
|
55
|
-
"@eslint-react/
|
|
56
|
-
"@eslint-react/
|
|
50
|
+
"@eslint-react/ast": "1.24.0-next.0",
|
|
51
|
+
"@eslint-react/core": "1.24.0-next.0",
|
|
52
|
+
"@eslint-react/eff": "1.24.0-next.0",
|
|
53
|
+
"@eslint-react/jsx": "1.24.0-next.0",
|
|
54
|
+
"@eslint-react/types": "1.24.0-next.0",
|
|
55
|
+
"@eslint-react/var": "1.24.0-next.0",
|
|
56
|
+
"@eslint-react/shared": "1.24.0-next.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/react": "^19.0.4",
|