@html-eslint/eslint-plugin 0.41.0-alpha.0 → 0.42.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/lib/configs/recommended.js +1 -0
- package/lib/data/entities.json +2299 -0
- package/lib/rules/index.js +8 -0
- package/lib/rules/lowercase.js +8 -5
- package/lib/rules/max-element-depth.js +1 -1
- package/lib/rules/no-aria-hidden-on-focusable.js +118 -0
- package/lib/rules/no-duplicate-in-head.js +191 -0
- package/lib/rules/no-empty-headings.js +122 -0
- package/lib/rules/no-extra-spacing-text.js +1 -1
- package/lib/rules/no-invalid-entity.js +108 -0
- package/lib/rules/require-img-alt.js +36 -13
- package/package.json +6 -6
- package/types/configs/recommended.d.ts +1 -0
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
- package/types/rules/lowercase.d.ts.map +1 -1
- package/types/rules/no-aria-hidden-on-focusable.d.ts +8 -0
- package/types/rules/no-aria-hidden-on-focusable.d.ts.map +1 -0
- package/types/rules/no-duplicate-in-head.d.ts +11 -0
- package/types/rules/no-duplicate-in-head.d.ts.map +1 -0
- package/types/rules/no-empty-headings.d.ts +9 -0
- package/types/rules/no-empty-headings.d.ts.map +1 -0
- package/types/rules/no-invalid-entity.d.ts +13 -0
- package/types/rules/no-invalid-entity.d.ts.map +1 -0
- package/types/rules/require-img-alt.d.ts.map +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
3
|
*
|
|
4
4
|
* @typedef {Object} Option
|
|
5
|
-
* @property {string[]} [
|
|
5
|
+
* @property {string[]} [substitute]
|
|
6
6
|
*
|
|
7
7
|
* @typedef { import("../types").RuleModule<[Option]> } RuleModule
|
|
8
8
|
*/
|
|
@@ -13,6 +13,7 @@ const { getRuleUrl } = require("./utils/rule");
|
|
|
13
13
|
|
|
14
14
|
const MESSAGE_IDS = {
|
|
15
15
|
MISSING_ALT: "missingAlt",
|
|
16
|
+
INSERT_ALT: "insertAlt",
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -20,7 +21,7 @@ const MESSAGE_IDS = {
|
|
|
20
21
|
*/
|
|
21
22
|
module.exports = {
|
|
22
23
|
meta: {
|
|
23
|
-
type: "
|
|
24
|
+
type: "suggestion",
|
|
24
25
|
|
|
25
26
|
docs: {
|
|
26
27
|
description: "Require `alt` attribute at `<img>` tag",
|
|
@@ -30,6 +31,7 @@ module.exports = {
|
|
|
30
31
|
},
|
|
31
32
|
|
|
32
33
|
fixable: null,
|
|
34
|
+
hasSuggestions: true,
|
|
33
35
|
schema: [
|
|
34
36
|
{
|
|
35
37
|
type: "object",
|
|
@@ -45,6 +47,7 @@ module.exports = {
|
|
|
45
47
|
],
|
|
46
48
|
messages: {
|
|
47
49
|
[MESSAGE_IDS.MISSING_ALT]: "Missing `alt` attribute at `<img>` tag",
|
|
50
|
+
[MESSAGE_IDS.INSERT_ALT]: 'Insert `alt=""` at `<img>` tag',
|
|
48
51
|
},
|
|
49
52
|
},
|
|
50
53
|
|
|
@@ -60,13 +63,27 @@ module.exports = {
|
|
|
60
63
|
if (node.name !== "img") {
|
|
61
64
|
return;
|
|
62
65
|
}
|
|
63
|
-
|
|
66
|
+
|
|
67
|
+
const hasAlt = hasValidAltOrSubstitute(node, substitute);
|
|
68
|
+
const hasSubstituteOption = substitute.length > 0;
|
|
69
|
+
|
|
70
|
+
if (!hasAlt) {
|
|
64
71
|
context.report({
|
|
65
72
|
loc: {
|
|
66
73
|
start: node.openStart.loc.start,
|
|
67
74
|
end: node.openEnd.loc.end,
|
|
68
75
|
},
|
|
69
76
|
messageId: MESSAGE_IDS.MISSING_ALT,
|
|
77
|
+
suggest: hasSubstituteOption
|
|
78
|
+
? null
|
|
79
|
+
: [
|
|
80
|
+
{
|
|
81
|
+
messageId: MESSAGE_IDS.INSERT_ALT,
|
|
82
|
+
fix(fixer) {
|
|
83
|
+
return fixer.insertTextBefore(node.openEnd, ' alt=""');
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
],
|
|
70
87
|
});
|
|
71
88
|
}
|
|
72
89
|
},
|
|
@@ -77,16 +94,22 @@ module.exports = {
|
|
|
77
94
|
/**
|
|
78
95
|
* @param {Tag} node
|
|
79
96
|
* @param {string[]} substitute
|
|
80
|
-
* @returns
|
|
97
|
+
* @returns {boolean}
|
|
81
98
|
*/
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
99
|
+
function hasValidAltOrSubstitute(node, substitute) {
|
|
100
|
+
let hasAnyAlt = false;
|
|
101
|
+
|
|
102
|
+
for (const attr of node.attributes) {
|
|
103
|
+
if (attr.key && attr.key.value) {
|
|
104
|
+
const isAltAttr = attr.key.value === "alt";
|
|
105
|
+
const isSubstituteAttr = substitute.includes(attr.key.value);
|
|
106
|
+
|
|
107
|
+
if (isAltAttr || isSubstituteAttr) {
|
|
108
|
+
hasAnyAlt = true;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
89
111
|
}
|
|
90
|
-
|
|
91
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return hasAnyAlt;
|
|
92
115
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@html-eslint/eslint-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "ESLint plugin for HTML",
|
|
6
6
|
"author": "yeonjuan",
|
|
@@ -40,16 +40,16 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@eslint/plugin-kit": "^0.3.1",
|
|
43
|
-
"@html-eslint/parser": "^0.
|
|
44
|
-
"@html-eslint/template-parser": "^0.
|
|
45
|
-
"@html-eslint/template-syntax-parser": "^0.
|
|
43
|
+
"@html-eslint/parser": "^0.42.0",
|
|
44
|
+
"@html-eslint/template-parser": "^0.42.0",
|
|
45
|
+
"@html-eslint/template-syntax-parser": "^0.42.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"eslint": "^8.0.0 || ^9.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@eslint/core": "^0.14.0",
|
|
52
|
-
"@html-eslint/types": "^0.
|
|
52
|
+
"@html-eslint/types": "^0.42.0",
|
|
53
53
|
"@types/estree": "^0.0.47",
|
|
54
54
|
"es-html-parser": "0.2.0",
|
|
55
55
|
"eslint": "^9.27.0",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "30e536dad0fef8ea04b8ef383024f203a3f2655f"
|
|
63
63
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export declare let configs: {
|
|
|
29
29
|
"@html-eslint/require-closing-tags": "error";
|
|
30
30
|
"@html-eslint/no-duplicate-attrs": "error";
|
|
31
31
|
"@html-eslint/use-baseline": "error";
|
|
32
|
+
"@html-eslint/no-duplicate-in-head": "error";
|
|
32
33
|
};
|
|
33
34
|
};
|
|
34
35
|
"flat/recommended": {
|
|
@@ -58,6 +59,7 @@ export declare let configs: {
|
|
|
58
59
|
"@html-eslint/require-closing-tags": "error";
|
|
59
60
|
"@html-eslint/no-duplicate-attrs": "error";
|
|
60
61
|
"@html-eslint/use-baseline": "error";
|
|
62
|
+
"@html-eslint/no-duplicate-in-head": "error";
|
|
61
63
|
};
|
|
62
64
|
};
|
|
63
65
|
};
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";;4BAO2B,QAAQ
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";;4BAO2B,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgB3B,4BAA4B;qCAAjB,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lowercase.d.ts","sourceRoot":"","sources":["../../lib/rules/lowercase.js"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"lowercase.d.ts","sourceRoot":"","sources":["../../lib/rules/lowercase.js"],"names":[],"mappings":";;;wBAkBU,UAAU;;WAjBN,OAAO,oBAAoB,EAAE,GAAG;gBAChC,OAAO,oBAAoB,EAAE,QAAQ;iBACrC,OAAO,oBAAoB,EAAE,SAAS;kBACtC,OAAO,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare namespace _exports {
|
|
2
|
+
export { RuleModule, Tag };
|
|
3
|
+
}
|
|
4
|
+
declare const _exports: RuleModule;
|
|
5
|
+
export = _exports;
|
|
6
|
+
type RuleModule = import("../types").RuleModule<[]>;
|
|
7
|
+
type Tag = import("@html-eslint/types").Tag;
|
|
8
|
+
//# sourceMappingURL=no-aria-hidden-on-focusable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-aria-hidden-on-focusable.d.ts","sourceRoot":"","sources":["../../lib/rules/no-aria-hidden-on-focusable.js"],"names":[],"mappings":";;;wBA8BU,UAAU;;kBA7BN,OAAO,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;WACjC,OAAO,oBAAoB,EAAE,GAAG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare namespace _exports {
|
|
2
|
+
export { Tag, StyleTag, ScriptTag, AttributeValue, RuleModule };
|
|
3
|
+
}
|
|
4
|
+
declare const _exports: RuleModule;
|
|
5
|
+
export = _exports;
|
|
6
|
+
type Tag = import("@html-eslint/types").Tag;
|
|
7
|
+
type StyleTag = import("@html-eslint/types").StyleTag;
|
|
8
|
+
type ScriptTag = import("@html-eslint/types").ScriptTag;
|
|
9
|
+
type AttributeValue = import("@html-eslint/types").AttributeValue;
|
|
10
|
+
type RuleModule = import("../types").RuleModule<[]>;
|
|
11
|
+
//# sourceMappingURL=no-duplicate-in-head.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-duplicate-in-head.d.ts","sourceRoot":"","sources":["../../lib/rules/no-duplicate-in-head.js"],"names":[],"mappings":";;;wBAgEU,UAAU;;WA/DN,OAAO,oBAAoB,EAAE,GAAG;gBAChC,OAAO,oBAAoB,EAAE,QAAQ;iBACrC,OAAO,oBAAoB,EAAE,SAAS;sBACtC,OAAO,oBAAoB,EAAE,cAAc;kBAC3C,OAAO,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare namespace _exports {
|
|
2
|
+
export { RuleModule, Tag, Text };
|
|
3
|
+
}
|
|
4
|
+
declare const _exports: RuleModule;
|
|
5
|
+
export = _exports;
|
|
6
|
+
type RuleModule = import("../types").RuleModule<[]>;
|
|
7
|
+
type Tag = import("@html-eslint/types").Tag;
|
|
8
|
+
type Text = import("@html-eslint/types").Text;
|
|
9
|
+
//# sourceMappingURL=no-empty-headings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-empty-headings.d.ts","sourceRoot":"","sources":["../../lib/rules/no-empty-headings.js"],"names":[],"mappings":";;;wBA0EU,UAAU;;kBAzEN,OAAO,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;WACjC,OAAO,oBAAoB,EAAE,GAAG;YAChC,OAAO,oBAAoB,EAAE,IAAI"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare namespace _exports {
|
|
2
|
+
export { RuleModule, SuggestionReportDescriptor, Text, EntityData };
|
|
3
|
+
}
|
|
4
|
+
declare const _exports: RuleModule;
|
|
5
|
+
export = _exports;
|
|
6
|
+
type RuleModule = import("../types").RuleModule<[]>;
|
|
7
|
+
type SuggestionReportDescriptor = import("../types").SuggestionReportDescriptor;
|
|
8
|
+
type Text = import("@html-eslint/types").Text;
|
|
9
|
+
type EntityData = {
|
|
10
|
+
codepoints: number[];
|
|
11
|
+
characters: string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=no-invalid-entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-invalid-entity.d.ts","sourceRoot":"","sources":["../../lib/rules/no-invalid-entity.js"],"names":[],"mappings":";;;wBAyBU,UAAU;;kBAxBN,OAAO,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;kCACjC,OAAO,UAAU,EAAE,0BAA0B;YAC7C,OAAO,oBAAoB,EAAE,IAAI;;gBAMjC,MAAM,EAAE;gBACR,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-img-alt.d.ts","sourceRoot":"","sources":["../../lib/rules/require-img-alt.js"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"require-img-alt.d.ts","sourceRoot":"","sources":["../../lib/rules/require-img-alt.js"],"names":[],"mappings":";;;wBAmBU,UAAU;;WAlBN,OAAO,oBAAoB,EAAE,GAAG;;;;kBAKhC,OAAO,UAAU,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC"}
|