1 | 'use strict';
|
2 | const getDocumentationUrl = require('./utils/get-documentation-url');
|
3 | const isValidVariableName = require('./utils/is-valid-variable-name');
|
4 | const quoteString = require('./utils/quote-string');
|
5 | const methodSelector = require('./utils/method-selector');
|
6 |
|
7 | const selector = [
|
8 | methodSelector({
|
9 | name: 'setAttribute',
|
10 | length: 2
|
11 | }),
|
12 | '[arguments.0.type="Literal"]'
|
13 | ].join('');
|
14 |
|
15 | const parseNodeText = (context, argument) => context.getSourceCode().getText(argument);
|
16 |
|
17 | const dashToCamelCase = string => string.replace(/-[a-z]/g, s => s[1].toUpperCase());
|
18 |
|
19 | const fix = (context, node, fixer) => {
|
20 | let [name, value] = node.arguments;
|
21 | const calleeObject = parseNodeText(context, node.callee.object);
|
22 |
|
23 | name = dashToCamelCase(name.value.slice(5));
|
24 | value = parseNodeText(context, value);
|
25 |
|
26 | const replacement = `${calleeObject}.dataset${
|
27 | isValidVariableName(name) ?
|
28 | `.${name}` :
|
29 | `[${quoteString(name)}]`
|
30 | } = ${value}`;
|
31 |
|
32 | return fixer.replaceText(node, replacement);
|
33 | };
|
34 |
|
35 | const create = context => {
|
36 | return {
|
37 | [selector](node) {
|
38 | const name = node.arguments[0].value;
|
39 |
|
40 | if (typeof name !== 'string' || !name.startsWith('data-') || name === 'data-') {
|
41 | return;
|
42 | }
|
43 |
|
44 | context.report({
|
45 | node,
|
46 | message: 'Prefer `.dataset` over `setAttribute(…)`.',
|
47 | fix: fixer => fix(context, node, fixer)
|
48 | });
|
49 | }
|
50 | };
|
51 | };
|
52 |
|
53 | module.exports = {
|
54 | create,
|
55 | meta: {
|
56 | type: 'suggestion',
|
57 | docs: {
|
58 | url: getDocumentationUrl(__filename)
|
59 | },
|
60 | fixable: 'code'
|
61 | }
|
62 | };
|