forked from angular-eslint/angular-eslint
/
no-positive-tabindex.ts
59 lines (55 loc) · 1.89 KB
/
no-positive-tabindex.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type {
ParseSourceSpan,
TmplAstBoundAttribute,
TmplAstTextAttribute,
} from '@angular-eslint/bundled-angular-compiler';
import { getTemplateParserServices } from '@angular-eslint/utils';
import { createESLintRule } from '../utils/create-eslint-rule';
import { getDomElements } from '../utils/get-dom-elements';
import { toPattern } from '../utils/to-pattern';
type Options = [];
export type MessageIds = 'noPositiveTabindex' | 'suggestNonNegativeTabindex';
export const RULE_NAME = 'no-positive-tabindex';
export default createESLintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Ensures that the `tabindex` attribute is not positive',
recommended: false,
},
hasSuggestions: true,
schema: [],
messages: {
noPositiveTabindex: 'The `tabindex` attribute should not be positive',
suggestNonNegativeTabindex: 'Use `tabindex="{{tabindex}}"`',
},
},
defaultOptions: [],
create(context) {
const parserServices = getTemplateParserServices(context);
const elementNamePattern = toPattern([...getDomElements()]);
return {
[`Element$1[name=${elementNamePattern}] > BoundAttribute[name="tabindex"][value.ast.value>0], TextAttribute[name="tabindex"][value>0]`]({
valueSpan,
}: (TmplAstBoundAttribute | TmplAstTextAttribute) & {
valueSpan: ParseSourceSpan;
}) {
const loc = parserServices.convertNodeSourceSpanToLoc(valueSpan);
context.report({
loc,
messageId: 'noPositiveTabindex',
suggest: ['-1', '0'].map((tabindex) => ({
messageId: 'suggestNonNegativeTabindex',
fix: (fixer) =>
fixer.replaceTextRange(
[valueSpan.start.offset, valueSpan.end.offset],
tabindex,
),
data: { tabindex },
})),
});
},
};
},
});