@html-eslint/eslint-plugin 0.33.1 → 0.34.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/rules/id-naming-convention.js +8 -7
- package/lib/rules/lowercase.js +4 -0
- package/lib/rules/no-duplicate-attrs.js +2 -2
- package/lib/rules/sort-attrs.js +46 -18
- package/lib/rules/utils/node.js +10 -12
- package/package.json +6 -4
- package/types/rules/id-naming-convention.d.ts.map +1 -1
- package/types/rules/lowercase.d.ts.map +1 -1
- package/types/rules/sort-attrs.d.ts.map +1 -1
- package/types/rules/utils/node.d.ts +6 -5
- package/types/rules/utils/node.d.ts.map +1 -1
- /package/lib/types/{settings.ts → settings.d.ts} +0 -0
|
@@ -12,11 +12,7 @@ const {
|
|
|
12
12
|
isPascalCase,
|
|
13
13
|
isKebabCase,
|
|
14
14
|
} = require("./utils/naming");
|
|
15
|
-
const {
|
|
16
|
-
findAttr,
|
|
17
|
-
isAttributesEmpty,
|
|
18
|
-
isExpressionInTemplate,
|
|
19
|
-
} = require("./utils/node");
|
|
15
|
+
const { findAttr, isAttributesEmpty, hasTemplate } = require("./utils/node");
|
|
20
16
|
const { createVisitors } = require("./utils/visitors");
|
|
21
17
|
|
|
22
18
|
const MESSAGE_IDS = {
|
|
@@ -94,7 +90,12 @@ module.exports = {
|
|
|
94
90
|
return;
|
|
95
91
|
}
|
|
96
92
|
const idAttr = findAttr(node, "id");
|
|
97
|
-
if (
|
|
93
|
+
if (
|
|
94
|
+
idAttr &&
|
|
95
|
+
idAttr.value &&
|
|
96
|
+
!hasTemplate(idAttr.value) &&
|
|
97
|
+
!checkNaming(idAttr.value.value)
|
|
98
|
+
) {
|
|
98
99
|
context.report({
|
|
99
100
|
node: idAttr,
|
|
100
101
|
data: {
|
|
@@ -117,7 +118,7 @@ module.exports = {
|
|
|
117
118
|
if (
|
|
118
119
|
idAttr &&
|
|
119
120
|
idAttr.value &&
|
|
120
|
-
!
|
|
121
|
+
!hasTemplate(idAttr.value) &&
|
|
121
122
|
!checkNaming(idAttr.value.value)
|
|
122
123
|
) {
|
|
123
124
|
context.report({
|
package/lib/rules/lowercase.js
CHANGED
|
@@ -9,6 +9,7 @@ const { NODE_TYPES } = require("@html-eslint/parser");
|
|
|
9
9
|
const { RULE_CATEGORY } = require("../constants");
|
|
10
10
|
const SVG_CAMEL_CASE_ATTRIBUTES = require("../constants/svg-camel-case-attributes");
|
|
11
11
|
const { createVisitors } = require("./utils/visitors");
|
|
12
|
+
const { hasTemplate } = require("./utils/node");
|
|
12
13
|
|
|
13
14
|
const MESSAGE_IDS = {
|
|
14
15
|
UNEXPECTED: "unexpected",
|
|
@@ -102,6 +103,9 @@ module.exports = {
|
|
|
102
103
|
if (isAllowedAttributeKey(attribute.key.value)) {
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
106
|
+
if (hasTemplate(attribute.key)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
105
109
|
if (attribute.key.value !== attribute.key.value.toLowerCase()) {
|
|
106
110
|
context.report({
|
|
107
111
|
node: attribute.key,
|
|
@@ -41,7 +41,7 @@ module.exports = {
|
|
|
41
41
|
if (Array.isArray(node.attributes)) {
|
|
42
42
|
const attrsSet = new Set();
|
|
43
43
|
node.attributes.forEach((attr) => {
|
|
44
|
-
if (attr.key && attrsSet.has(attr.key.value)) {
|
|
44
|
+
if (attr.key && attrsSet.has(attr.key.value.toLowerCase())) {
|
|
45
45
|
context.report({
|
|
46
46
|
node: attr,
|
|
47
47
|
data: {
|
|
@@ -50,7 +50,7 @@ module.exports = {
|
|
|
50
50
|
messageId: MESSAGE_IDS.DUPLICATE_ATTRS,
|
|
51
51
|
});
|
|
52
52
|
} else {
|
|
53
|
-
attrsSet.add(attr.key.value);
|
|
53
|
+
attrsSet.add(attr.key.value.toLowerCase());
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
}
|
package/lib/rules/sort-attrs.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @typedef { import("../types").Text } Text
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
const { hasTemplate } = require("./utils/node");
|
|
8
9
|
const { RULE_CATEGORY } = require("../constants");
|
|
9
10
|
const { getSourceCode } = require("./utils/source-code");
|
|
10
11
|
const { createVisitors } = require("./utils/visitors");
|
|
@@ -62,6 +63,7 @@ module.exports = {
|
|
|
62
63
|
function compare(attrA, attrB) {
|
|
63
64
|
const keyA = attrA.key.value;
|
|
64
65
|
const keyB = attrB.key.value;
|
|
66
|
+
|
|
65
67
|
const keyAReservedValue = priority.indexOf(keyA);
|
|
66
68
|
const keyBReservedValue = priority.indexOf(keyB);
|
|
67
69
|
if (keyAReservedValue >= 0 && keyBReservedValue >= 0) {
|
|
@@ -122,6 +124,30 @@ module.exports = {
|
|
|
122
124
|
return false;
|
|
123
125
|
}
|
|
124
126
|
|
|
127
|
+
/**
|
|
128
|
+
* @param {Attribute[]} attributes
|
|
129
|
+
* @return {Attribute[][]}
|
|
130
|
+
*/
|
|
131
|
+
function groupAttributes(attributes) {
|
|
132
|
+
/**
|
|
133
|
+
* @type {Attribute[][]}
|
|
134
|
+
*/
|
|
135
|
+
const attributesList = [];
|
|
136
|
+
let index = 0;
|
|
137
|
+
|
|
138
|
+
for (const attribute of attributes) {
|
|
139
|
+
if (hasTemplate(attribute.key)) {
|
|
140
|
+
index = attributesList.length;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (!attributesList[index]) {
|
|
144
|
+
attributesList[index] = [];
|
|
145
|
+
}
|
|
146
|
+
attributesList[index].push(attribute);
|
|
147
|
+
}
|
|
148
|
+
return attributesList;
|
|
149
|
+
}
|
|
150
|
+
|
|
125
151
|
/**
|
|
126
152
|
* @param {Attribute[]} unsorted
|
|
127
153
|
*/
|
|
@@ -129,26 +155,28 @@ module.exports = {
|
|
|
129
155
|
if (unsorted.length <= 1) {
|
|
130
156
|
return;
|
|
131
157
|
}
|
|
158
|
+
const grouped = groupAttributes(unsorted);
|
|
159
|
+
grouped.forEach((unsorted) => {
|
|
160
|
+
const sorted = [...unsorted].sort(compare);
|
|
132
161
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
end: last.loc.end,
|
|
162
|
+
if (!isChanged(unsorted, sorted)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const first = unsorted[0];
|
|
166
|
+
const last = unsorted[unsorted.length - 1];
|
|
167
|
+
context.report({
|
|
168
|
+
node: {
|
|
169
|
+
range: [first.range[0], last.range[1]],
|
|
170
|
+
loc: {
|
|
171
|
+
start: first.loc.start,
|
|
172
|
+
end: last.loc.end,
|
|
173
|
+
},
|
|
146
174
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
175
|
+
messageId: MESSAGE_IDS.UNSORTED,
|
|
176
|
+
fix(fixer) {
|
|
177
|
+
return fix(fixer, unsorted, sorted);
|
|
178
|
+
},
|
|
179
|
+
});
|
|
152
180
|
});
|
|
153
181
|
}
|
|
154
182
|
|
package/lib/rules/utils/node.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @typedef { import("../../types").Comment } Comment
|
|
10
10
|
* @typedef { import("../../types").AnyNode } AnyNode
|
|
11
11
|
* @typedef { import("../../types").AttributeValue } AttributeValue
|
|
12
|
+
* @typedef { import("../../types").AttributeKey } AttributeKey
|
|
12
13
|
* @typedef { import("eslint").AST.Range } Range
|
|
13
14
|
* @typedef { import("eslint").AST.SourceLocation } SourceLocation
|
|
14
15
|
* @typedef { import("es-html-parser").AnyToken } AnyToken
|
|
@@ -67,6 +68,14 @@ function isOverlapWithTemplates(templates, range) {
|
|
|
67
68
|
.some((template) => isRangesOverlap(template.range, range));
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/**
|
|
72
|
+
* @param {AttributeKey | AttributeValue} node
|
|
73
|
+
* @returns {boolean}
|
|
74
|
+
*/
|
|
75
|
+
function hasTemplate(node) {
|
|
76
|
+
return node.templates.some((template) => template.isTemplate);
|
|
77
|
+
}
|
|
78
|
+
|
|
70
79
|
/**
|
|
71
80
|
*
|
|
72
81
|
* @param {Text | CommentContent} node
|
|
@@ -141,17 +150,6 @@ function getLocBetween(before, after) {
|
|
|
141
150
|
};
|
|
142
151
|
}
|
|
143
152
|
|
|
144
|
-
/**
|
|
145
|
-
* @param {AttributeValue} node
|
|
146
|
-
* @return {boolean}
|
|
147
|
-
*/
|
|
148
|
-
function isExpressionInTemplate(node) {
|
|
149
|
-
if (node.type === NODE_TYPES.AttributeValue) {
|
|
150
|
-
return node.value.indexOf("${") === 0;
|
|
151
|
-
}
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
153
|
/**
|
|
156
154
|
* @param {AnyNode} node
|
|
157
155
|
* @returns {node is Tag}
|
|
@@ -248,7 +246,6 @@ module.exports = {
|
|
|
248
246
|
splitToLineNodes,
|
|
249
247
|
getLocBetween,
|
|
250
248
|
findParent,
|
|
251
|
-
isExpressionInTemplate,
|
|
252
249
|
isTag,
|
|
253
250
|
isComment,
|
|
254
251
|
isText,
|
|
@@ -258,4 +255,5 @@ module.exports = {
|
|
|
258
255
|
codeToLines,
|
|
259
256
|
isRangesOverlap,
|
|
260
257
|
getTemplateTokens,
|
|
258
|
+
hasTemplate,
|
|
261
259
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@html-eslint/eslint-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "ESLint plugin for html",
|
|
5
5
|
"author": "yeonjuan",
|
|
6
6
|
"homepage": "https://github.com/yeonjuan/html-eslint#readme",
|
|
@@ -45,15 +45,17 @@
|
|
|
45
45
|
"accessibility"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@html-eslint/template-parser": "^0.
|
|
48
|
+
"@html-eslint/template-parser": "^0.34.0",
|
|
49
|
+
"@html-eslint/template-syntax-parser": "^0.34.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@html-eslint/parser": "^0.
|
|
52
|
+
"@html-eslint/parser": "^0.34.0",
|
|
52
53
|
"@types/eslint": "^9.6.1",
|
|
53
54
|
"@types/estree": "^0.0.47",
|
|
54
55
|
"es-html-parser": "^1.0.0-alpha.4",
|
|
56
|
+
"eslint": "^8",
|
|
55
57
|
"espree": "^10.3.0",
|
|
56
58
|
"typescript": "^5.7.2"
|
|
57
59
|
},
|
|
58
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "f0401cc30d1510d6f5c7511280c0a6b9779fea0c"
|
|
59
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-naming-convention.d.ts","sourceRoot":"","sources":["../../lib/rules/id-naming-convention.js"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"id-naming-convention.d.ts","sourceRoot":"","sources":["../../lib/rules/id-naming-convention.js"],"names":[],"mappings":";;;wBAqCU,UAAU;;kBApCN,OAAO,UAAU,EAAE,UAAU;WAC7B,OAAO,UAAU,EAAE,GAAG;iBACtB,OAAO,UAAU,EAAE,SAAS;gBAC5B,OAAO,UAAU,EAAE,QAAQ"}
|
|
@@ -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;;kBAjBN,OAAO,UAAU,EAAE,UAAU;WAC7B,OAAO,UAAU,EAAE,GAAG;gBACtB,OAAO,UAAU,EAAE,QAAQ;iBAC3B,OAAO,UAAU,EAAE,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort-attrs.d.ts","sourceRoot":"","sources":["../../lib/rules/sort-attrs.js"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"sort-attrs.d.ts","sourceRoot":"","sources":["../../lib/rules/sort-attrs.js"],"names":[],"mappings":";;;wBAiBU,UAAU;;iBAhBN,OAAO,QAAQ,EAAE,IAAI,CAAC,SAAS;kBAC/B,OAAO,UAAU,EAAE,UAAU;iBAC7B,OAAO,UAAU,EAAE,SAAS;YAC5B,OAAO,UAAU,EAAE,IAAI"}
|
|
@@ -8,6 +8,7 @@ export type CommentContent = import("../../types").CommentContent;
|
|
|
8
8
|
export type Comment = import("../../types").Comment;
|
|
9
9
|
export type AnyNode = import("../../types").AnyNode;
|
|
10
10
|
export type AttributeValue = import("../../types").AttributeValue;
|
|
11
|
+
export type AttributeKey = import("../../types").AttributeKey;
|
|
11
12
|
export type Range = import("eslint").AST.Range;
|
|
12
13
|
export type SourceLocation = import("eslint").AST.SourceLocation;
|
|
13
14
|
export type AnyToken = import("es-html-parser").AnyToken;
|
|
@@ -52,11 +53,6 @@ export function getLocBetween(before: {
|
|
|
52
53
|
* @returns {null | AnyNode}
|
|
53
54
|
*/
|
|
54
55
|
export function findParent(node: Exclude<AnyNode, Line>, predicate: (node: AnyNode) => boolean): null | AnyNode;
|
|
55
|
-
/**
|
|
56
|
-
* @param {AttributeValue} node
|
|
57
|
-
* @return {boolean}
|
|
58
|
-
*/
|
|
59
|
-
export function isExpressionInTemplate(node: AttributeValue): boolean;
|
|
60
56
|
/**
|
|
61
57
|
* @param {AnyNode} node
|
|
62
58
|
* @returns {node is Tag}
|
|
@@ -106,4 +102,9 @@ export function isRangesOverlap(rangeA: Range, rangeB: Range): boolean;
|
|
|
106
102
|
* @returns {((CommentContent | Text)['templates'][number])[]}
|
|
107
103
|
*/
|
|
108
104
|
export function getTemplateTokens(tokens: AnyToken[]): ((CommentContent | Text)["templates"][number])[];
|
|
105
|
+
/**
|
|
106
|
+
* @param {AttributeKey | AttributeValue} node
|
|
107
|
+
* @returns {boolean}
|
|
108
|
+
*/
|
|
109
|
+
export function hasTemplate(node: AttributeKey | AttributeValue): boolean;
|
|
109
110
|
//# sourceMappingURL=node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../lib/rules/utils/node.js"],"names":[],"mappings":"wBACc,OAAO,aAAa,EAAE,SAAS;kBAC/B,OAAO,aAAa,EAAE,GAAG;wBACzB,OAAO,aAAa,EAAE,SAAS;uBAC/B,OAAO,aAAa,EAAE,QAAQ;mBAC9B,OAAO,aAAa,EAAE,IAAI;mBAC1B,OAAO,aAAa,EAAE,IAAI;6BAC1B,OAAO,aAAa,EAAE,cAAc;sBACpC,OAAO,aAAa,EAAE,OAAO;sBAC7B,OAAO,aAAa,EAAE,OAAO;6BAC7B,OAAO,aAAa,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../lib/rules/utils/node.js"],"names":[],"mappings":"wBACc,OAAO,aAAa,EAAE,SAAS;kBAC/B,OAAO,aAAa,EAAE,GAAG;wBACzB,OAAO,aAAa,EAAE,SAAS;uBAC/B,OAAO,aAAa,EAAE,QAAQ;mBAC9B,OAAO,aAAa,EAAE,IAAI;mBAC1B,OAAO,aAAa,EAAE,IAAI;6BAC1B,OAAO,aAAa,EAAE,cAAc;sBACpC,OAAO,aAAa,EAAE,OAAO;sBAC7B,OAAO,aAAa,EAAE,OAAO;6BAC7B,OAAO,aAAa,EAAE,cAAc;2BACpC,OAAO,aAAa,EAAE,YAAY;oBAClC,OAAO,QAAQ,EAAE,GAAG,CAAC,KAAK;6BAC1B,OAAO,QAAQ,EAAE,GAAG,CAAC,cAAc;uBACnC,OAAO,gBAAgB,EAAE,QAAQ;AAM/C;;;;GAIG;AACH,+BAJW,GAAG,GAAG,SAAS,GAAG,QAAQ,OAC1B,MAAM,GACJ,SAAS,GAAG,SAAS,CAMjC;AAED;;;;GAIG;AACH,wCAHW,GAAG,GAAG,SAAS,GAAG,QAAQ,GACxB,OAAO,CAInB;AAED;;;;GAIG;AACH,6CAHW,OAAO,GACL,OAAO,CAInB;AA+BD;;;;GAIG;AACH,uCAHW,IAAI,GAAG,cAAc,GACnB,IAAI,EAAE,CAwDlB;AAED;;;;;GAKG;AACH,sCAJW;IAAC,GAAG,EAAE,cAAc,CAAA;CAAC,SACrB;IAAC,GAAG,EAAE,cAAc,CAAA;CAAC,GACnB,cAAc,CAO1B;AAoDD;;;;GAIG;AACH,iCAJW,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,aACtB,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,GACxB,IAAI,GAAG,OAAO,CAgB1B;AArED;;;GAGG;AACH,4BAHW,OAAO,GACL,IAAI,IAAI,GAAG,CAIvB;AAUD;;;GAGG;AACH,gCAHW,OAAO,GACL,IAAI,IAAI,OAAO,CAI3B;AAED;;;GAGG;AACH,6BAHW,OAAO,GACL,IAAI,IAAI,IAAI,CAIxB;AAED;;;GAGG;AACH,6BAHW,OAAO,GAAG,IAAI,GACZ,IAAI,IAAI,IAAI,CAIxB;AA9BD;;;GAGG;AACH,+BAHW,OAAO,GACL,IAAI,IAAI,SAAS,CAI7B;AA3GD;;;;GAIG;AACH,kDAJW,CAAC,IAAI,GAAG,cAAc,CAAC,CAAC,WAAW,CAAC,SACpC,KAAK,GACH,OAAO,CAMnB;AA8HD;;;GAGG;AACH,oCAHW,MAAM,GACJ,MAAM,EAAE,CAIpB;AAvJD;;;;;GAKG;AACH,wCAJW,KAAK,UACL,KAAK,GACH,OAAO,CAInB;AAsKD;;;;GAIG;AACH,0CAHW,QAAQ,EAAE,GACR,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAa5D;AAzKD;;;GAGG;AACH,kCAHW,YAAY,GAAG,cAAc,GAC3B,OAAO,CAInB"}
|
|
File without changes
|