Skip to content

Commit b2d7378

Browse files
authored
prefer-dom-node-dataset: Fix edge cases (#2171)
1 parent 61234af commit b2d7378

7 files changed

+86
-8
lines changed

rules/ast/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626
isCallExpression,
2727
isCallOrNewExpression,
2828
isEmptyNode: require('./is-empty-node.js'),
29+
isExpressionStatement: require('./is-expression-statement.js'),
2930
isFunction: require('./is-function.js'),
3031
isMemberExpression: require('./is-member-expression.js'),
3132
isMethodCall: require('./is-method-call.js'),

rules/ast/is-expression-statement.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
function isExpressionStatement(node) {
4+
return node.type === 'ExpressionStatement'
5+
|| (
6+
node.type === 'ChainExpression'
7+
&& node.parent.type === 'ExpressionStatement'
8+
);
9+
}
10+
11+
module.exports = isExpressionStatement;

rules/prefer-dom-node-dataset.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
'use strict';
22
const {isIdentifierName} = require('@babel/helper-validator-identifier');
3-
const {escapeString, hasOptionalChainElement} = require('./utils/index.js');
4-
const {isMethodCall, isStringLiteral} = require('./ast/index.js');
3+
const {
4+
escapeString,
5+
hasOptionalChainElement,
6+
isValueNotUsable,
7+
} = require('./utils/index.js');
8+
const {isMethodCall, isStringLiteral, isExpressionStatement} = require('./ast/index.js');
59

610
const MESSAGE_ID = 'prefer-dom-node-dataset';
711
const messages = {
@@ -19,6 +23,15 @@ function getFix(callExpression, context) {
1923
return;
2024
}
2125

26+
// `element.setAttribute(…)` returns `undefined`, but `AssignmentExpression` returns value of RHS
27+
if (method === 'setAttribute' && !isValueNotUsable(callExpression)) {
28+
return;
29+
}
30+
31+
if (method === 'removeAttribute' && !isExpressionStatement(callExpression.parent)) {
32+
return;
33+
}
34+
2235
return fixer => {
2336
const [nameNode] = callExpression.arguments;
2437
const name = dashToCamelCase(nameNode.value.toLowerCase().slice(5));

rules/utils/is-value-not-usable.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
'use strict';
22

3-
module.exports = node =>
4-
node.parent.type === 'ExpressionStatement'
5-
|| (
6-
node.parent.type === 'ChainExpression'
7-
&& node.parent.parent.type === 'ExpressionStatement'
8-
);
3+
const {isExpressionStatement} = require('../ast/index.js');
4+
5+
module.exports = node => isExpressionStatement(node.parent);

test/prefer-dom-node-dataset.mjs

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ test.snapshot({
5454
'element.setAttribute("DATA-Foo-bar", "🦄");',
5555
// Not fixable
5656
'optional?.element.setAttribute("data-unicorn", "🦄");',
57+
'console.log(element.setAttribute("data-unicorn", "🦄"))',
5758
],
5859
});
5960

@@ -104,6 +105,7 @@ test.snapshot({
104105
'element.querySelector("#selector").removeAttribute("data-AllowAccess");',
105106
'element.removeAttribute("data-");',
106107
'optional?.element.removeAttribute("data-unicorn");',
108+
'element.removeAttribute("data-unicorn")?.property',
107109
],
108110
});
109111

@@ -156,6 +158,7 @@ test.snapshot({
156158
'element.hasAttribute("data-foo");',
157159
'element.querySelector("#selector").hasAttribute("data-AllowAccess");',
158160
'optional?.element.hasAttribute("data-unicorn");',
161+
'element.hasAttribute("data-unicorn").toString()',
159162
],
160163
});
161164

@@ -204,5 +207,6 @@ test.snapshot({
204207
'element.getAttribute("data-foo");',
205208
'element.querySelector("#selector").getAttribute("data-AllowAccess");',
206209
'optional?.element.getAttribute("data-unicorn");',
210+
'element.getAttribute("data-unicorn").toString()',
207211
],
208212
});

test/snapshots/prefer-dom-node-dataset.mjs.md

+52
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ Generated by [AVA](https://avajs.dev).
279279
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`setAttribute(…)\`.␊
280280
`
281281

282+
## Invalid #18
283+
1 | console.log(element.setAttribute("data-unicorn", "🦄"))
284+
285+
> Error 1/1
286+
287+
`␊
288+
> 1 | console.log(element.setAttribute("data-unicorn", "🦄"))␊
289+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`setAttribute(…)\`.␊
290+
`
291+
282292
## Invalid #1
283293
1 | element.removeAttribute(
284294
2 | "data-foo", // comment
@@ -525,6 +535,16 @@ Generated by [AVA](https://avajs.dev).
525535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`removeAttribute(…)\`.␊
526536
`
527537

538+
## Invalid #16
539+
1 | element.removeAttribute("data-unicorn")?.property
540+
541+
> Error 1/1
542+
543+
`␊
544+
> 1 | element.removeAttribute("data-unicorn")?.property␊
545+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`removeAttribute(…)\`.␊
546+
`
547+
528548
## Invalid #1
529549
1 | element.hasAttribute(
530550
2 | "data-foo", // comment
@@ -755,6 +775,22 @@ Generated by [AVA](https://avajs.dev).
755775
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`hasAttribute(…)\`.␊
756776
`
757777

778+
## Invalid #15
779+
1 | element.hasAttribute("data-unicorn").toString()
780+
781+
> Output
782+
783+
`␊
784+
1 | Object.hasOwn(element.dataset, "unicorn").toString()␊
785+
`
786+
787+
> Error 1/1
788+
789+
`␊
790+
> 1 | element.hasAttribute("data-unicorn").toString()␊
791+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`hasAttribute(…)\`.␊
792+
`
793+
758794
## Invalid #1
759795
1 | element.getAttribute(
760796
2 | "data-foo", // comment
@@ -984,3 +1020,19 @@ Generated by [AVA](https://avajs.dev).
9841020
> 1 | optional?.element.getAttribute("data-unicorn");␊
9851021
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`getAttribute(…)\`.␊
9861022
`
1023+
1024+
## Invalid #15
1025+
1 | element.getAttribute("data-unicorn").toString()
1026+
1027+
> Output
1028+
1029+
`␊
1030+
1 | element.dataset.unicorn.toString()␊
1031+
`
1032+
1033+
> Error 1/1
1034+
1035+
`␊
1036+
> 1 | element.getAttribute("data-unicorn").toString()␊
1037+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer \`.dataset\` over \`getAttribute(…)\`.␊
1038+
`
185 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)