@html-eslint/eslint-plugin 0.31.1 → 0.33.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.
Files changed (135) hide show
  1. package/lib/rules/attrs-newline.js +3 -5
  2. package/lib/rules/element-newline.js +11 -9
  3. package/lib/rules/id-naming-convention.js +5 -5
  4. package/lib/rules/indent/indent.js +121 -69
  5. package/lib/rules/index.js +20 -0
  6. package/lib/rules/lowercase.js +7 -8
  7. package/lib/rules/max-element-depth.js +96 -0
  8. package/lib/rules/no-abstract-roles.js +4 -4
  9. package/lib/rules/no-accesskey-attrs.js +4 -4
  10. package/lib/rules/no-duplicate-attrs.js +4 -4
  11. package/lib/rules/no-duplicate-id.js +7 -7
  12. package/lib/rules/no-extra-spacing-attrs.js +14 -14
  13. package/lib/rules/no-extra-spacing-text.js +9 -10
  14. package/lib/rules/no-heading-inside-button.js +54 -0
  15. package/lib/rules/no-inline-styles.js +0 -1
  16. package/lib/rules/no-invalid-role.js +287 -0
  17. package/lib/rules/no-multiple-empty-lines.js +5 -5
  18. package/lib/rules/no-multiple-h1.js +2 -2
  19. package/lib/rules/no-nested-interactive.js +120 -0
  20. package/lib/rules/no-positive-tabindex.js +4 -4
  21. package/lib/rules/no-restricted-attr-values.js +6 -6
  22. package/lib/rules/no-restricted-attrs.js +6 -6
  23. package/lib/rules/no-script-style-type.js +4 -4
  24. package/lib/rules/no-skip-heading-levels.js +2 -2
  25. package/lib/rules/no-trailing-spaces.js +3 -3
  26. package/lib/rules/prefer-https.js +106 -0
  27. package/lib/rules/quotes.js +8 -8
  28. package/lib/rules/require-attrs.js +14 -6
  29. package/lib/rules/require-closing-tags.js +4 -4
  30. package/lib/rules/require-explicit-size.js +122 -0
  31. package/lib/rules/require-form-method.js +81 -0
  32. package/lib/rules/require-img-alt.js +2 -3
  33. package/lib/rules/require-input-label.js +77 -0
  34. package/lib/rules/require-meta-charset.js +3 -3
  35. package/lib/rules/require-meta-description.js +3 -3
  36. package/lib/rules/require-meta-viewport.js +3 -3
  37. package/lib/rules/require-open-graph-protocol.js +3 -3
  38. package/lib/rules/require-title.js +5 -5
  39. package/lib/rules/sort-attrs.js +12 -12
  40. package/lib/rules/utils/node.js +72 -32
  41. package/lib/rules/utils/settings.js +2 -2
  42. package/lib/rules/utils/visitors.js +1 -1
  43. package/lib/types/ast.d.ts +204 -0
  44. package/lib/types/index.d.ts +3 -0
  45. package/lib/types/rule.d.ts +83 -0
  46. package/lib/types/settings.ts +13 -0
  47. package/package.json +4 -4
  48. package/types/rules/attrs-newline.d.ts +2 -3
  49. package/types/rules/attrs-newline.d.ts.map +1 -1
  50. package/types/rules/element-newline.d.ts +8 -9
  51. package/types/rules/element-newline.d.ts.map +1 -1
  52. package/types/rules/id-naming-convention.d.ts +4 -4
  53. package/types/rules/id-naming-convention.d.ts.map +1 -1
  54. package/types/rules/indent/indent.d.ts +12 -5
  55. package/types/rules/indent/indent.d.ts.map +1 -1
  56. package/types/rules/index.d.ts +8 -0
  57. package/types/rules/lowercase.d.ts +4 -5
  58. package/types/rules/lowercase.d.ts.map +1 -1
  59. package/types/rules/max-element-depth.d.ts +10 -0
  60. package/types/rules/max-element-depth.d.ts.map +1 -0
  61. package/types/rules/no-abstract-roles.d.ts +4 -4
  62. package/types/rules/no-abstract-roles.d.ts.map +1 -1
  63. package/types/rules/no-accesskey-attrs.d.ts +4 -4
  64. package/types/rules/no-accesskey-attrs.d.ts.map +1 -1
  65. package/types/rules/no-duplicate-attrs.d.ts +4 -4
  66. package/types/rules/no-duplicate-attrs.d.ts.map +1 -1
  67. package/types/rules/no-duplicate-id.d.ts +5 -5
  68. package/types/rules/no-duplicate-id.d.ts.map +1 -1
  69. package/types/rules/no-extra-spacing-attrs.d.ts +11 -11
  70. package/types/rules/no-extra-spacing-attrs.d.ts.map +1 -1
  71. package/types/rules/no-extra-spacing-text.d.ts +7 -8
  72. package/types/rules/no-extra-spacing-text.d.ts.map +1 -1
  73. package/types/rules/no-heading-inside-button.d.ts +7 -0
  74. package/types/rules/no-heading-inside-button.d.ts.map +1 -0
  75. package/types/rules/no-inline-styles.d.ts +1 -2
  76. package/types/rules/no-inline-styles.d.ts.map +1 -1
  77. package/types/rules/no-invalid-role.d.ts +7 -0
  78. package/types/rules/no-invalid-role.d.ts.map +1 -0
  79. package/types/rules/no-multiple-empty-lines.d.ts +5 -5
  80. package/types/rules/no-multiple-empty-lines.d.ts.map +1 -1
  81. package/types/rules/no-multiple-h1.d.ts +2 -2
  82. package/types/rules/no-multiple-h1.d.ts.map +1 -1
  83. package/types/rules/no-nested-interactive.d.ts +8 -0
  84. package/types/rules/no-nested-interactive.d.ts.map +1 -0
  85. package/types/rules/no-positive-tabindex.d.ts +4 -4
  86. package/types/rules/no-positive-tabindex.d.ts.map +1 -1
  87. package/types/rules/no-restricted-attr-values.d.ts +5 -5
  88. package/types/rules/no-restricted-attr-values.d.ts.map +1 -1
  89. package/types/rules/no-restricted-attrs.d.ts +5 -5
  90. package/types/rules/no-restricted-attrs.d.ts.map +1 -1
  91. package/types/rules/no-script-style-type.d.ts +4 -4
  92. package/types/rules/no-script-style-type.d.ts.map +1 -1
  93. package/types/rules/no-skip-heading-levels.d.ts +2 -2
  94. package/types/rules/no-skip-heading-levels.d.ts.map +1 -1
  95. package/types/rules/no-trailing-spaces.d.ts +3 -3
  96. package/types/rules/no-trailing-spaces.d.ts.map +1 -1
  97. package/types/rules/prefer-https.d.ts +11 -0
  98. package/types/rules/prefer-https.d.ts.map +1 -0
  99. package/types/rules/quotes.d.ts +6 -6
  100. package/types/rules/quotes.d.ts.map +1 -1
  101. package/types/rules/require-attrs.d.ts +9 -4
  102. package/types/rules/require-attrs.d.ts.map +1 -1
  103. package/types/rules/require-closing-tags.d.ts +2 -2
  104. package/types/rules/require-closing-tags.d.ts.map +1 -1
  105. package/types/rules/require-explicit-size.d.ts +9 -0
  106. package/types/rules/require-explicit-size.d.ts.map +1 -0
  107. package/types/rules/require-form-method.d.ts +7 -0
  108. package/types/rules/require-form-method.d.ts.map +1 -0
  109. package/types/rules/require-img-alt.d.ts +2 -2
  110. package/types/rules/require-img-alt.d.ts.map +1 -1
  111. package/types/rules/require-input-label.d.ts +8 -0
  112. package/types/rules/require-input-label.d.ts.map +1 -0
  113. package/types/rules/require-meta-charset.d.ts +3 -3
  114. package/types/rules/require-meta-charset.d.ts.map +1 -1
  115. package/types/rules/require-meta-description.d.ts +3 -3
  116. package/types/rules/require-meta-description.d.ts.map +1 -1
  117. package/types/rules/require-meta-viewport.d.ts +3 -3
  118. package/types/rules/require-meta-viewport.d.ts.map +1 -1
  119. package/types/rules/require-open-graph-protocol.d.ts +3 -3
  120. package/types/rules/require-open-graph-protocol.d.ts.map +1 -1
  121. package/types/rules/require-title.d.ts +4 -4
  122. package/types/rules/require-title.d.ts.map +1 -1
  123. package/types/rules/sort-attrs.d.ts +4 -4
  124. package/types/rules/sort-attrs.d.ts.map +1 -1
  125. package/types/rules/utils/node.d.ts +56 -37
  126. package/types/rules/utils/node.d.ts.map +1 -1
  127. package/types/rules/utils/settings.d.ts +2 -2
  128. package/types/rules/utils/settings.d.ts.map +1 -1
  129. package/types/rules/utils/source-code.d.ts +1 -1
  130. package/types/rules/utils/source-code.d.ts.map +1 -1
  131. package/types/rules/utils/visitors.d.ts +1 -1
  132. package/types/rules/utils/visitors.d.ts.map +1 -1
  133. package/types/types/settings.d.ts +13 -0
  134. package/types/types/settings.d.ts.map +1 -0
  135. package/lib/types.d.ts +0 -289
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @typedef { import("../types").RuleModule } RuleModule
3
- * @typedef { import("es-html-parser").TagNode } TagNode
4
- * @typedef { import("es-html-parser").TextNode } TextNode
5
- * @typedef { import("es-html-parser").AnyNode } AnyNode
3
+ * @typedef { import("../types").Tag } Tag
4
+ * @typedef { import("../types").Text } Text
5
+ * @typedef { import("../types").AnyNode } AnyNode
6
6
  */
7
7
 
8
8
  const { RULE_CATEGORY } = require("../constants");
@@ -16,7 +16,7 @@ const MESSAGE_IDS = {
16
16
 
17
17
  /**
18
18
  * @param {AnyNode} node
19
- * @returns {node is TagNode}
19
+ * @returns {node is Tag}
20
20
  */
21
21
  function isTitle(node) {
22
22
  return isTag(node) && node.name === "title";
@@ -24,7 +24,7 @@ function isTitle(node) {
24
24
 
25
25
  /**
26
26
  * @param {AnyNode} node
27
- * @returns {node is TextNode}
27
+ * @returns {node is Text}
28
28
  */
29
29
  function isNonEmptyText(node) {
30
30
  return isText(node) && node.value.trim().length > 0;
@@ -1,8 +1,8 @@
1
1
  /**
2
+ * @typedef { import("eslint").Rule.RuleFixer } RuleFixer
2
3
  * @typedef { import("../types").RuleModule } RuleModule
3
- * @typedef { import("../types").AttributeNode } AttributeNode
4
- * @typedef { import("../types").TextNode } TextNode
5
- * @typedef { import("../types").RuleFixer } RuleFixer
4
+ * @typedef { import("../types").Attribute } Attribute
5
+ * @typedef { import("../types").Text } Text
6
6
  */
7
7
 
8
8
  const { RULE_CATEGORY } = require("../constants");
@@ -55,8 +55,8 @@ module.exports = {
55
55
  const priority = option.priority;
56
56
 
57
57
  /**
58
- * @param {AttributeNode} attrA
59
- * @param {AttributeNode} attrB
58
+ * @param {Attribute} attrA
59
+ * @param {Attribute} attrB
60
60
  * @return {number}
61
61
  */
62
62
  function compare(attrA, attrB) {
@@ -76,8 +76,8 @@ module.exports = {
76
76
 
77
77
  /**
78
78
  * @param {string} source
79
- * @param {AttributeNode[]} unsorted
80
- * @param {AttributeNode[]} sorted
79
+ * @param {Attribute[]} unsorted
80
+ * @param {Attribute[]} sorted
81
81
  * @returns {string}
82
82
  */
83
83
  function getSortedCode(source, unsorted, sorted) {
@@ -99,8 +99,8 @@ module.exports = {
99
99
 
100
100
  /**
101
101
  * @param {RuleFixer} fixer
102
- * @param {AttributeNode[]} unsorted
103
- * @param {AttributeNode[]} sorted
102
+ * @param {Attribute[]} unsorted
103
+ * @param {Attribute[]} sorted
104
104
  */
105
105
  function fix(fixer, unsorted, sorted) {
106
106
  const source = sourceCode.getText();
@@ -111,8 +111,8 @@ module.exports = {
111
111
  }
112
112
 
113
113
  /**
114
- * @param {AttributeNode[]} before
115
- * @param {AttributeNode[]} after
114
+ * @param {Attribute[]} before
115
+ * @param {Attribute[]} after
116
116
  * @returns {boolean}
117
117
  */
118
118
  function isChanged(before, after) {
@@ -123,7 +123,7 @@ module.exports = {
123
123
  }
124
124
 
125
125
  /**
126
- * @param {AttributeNode[]} unsorted
126
+ * @param {Attribute[]} unsorted
127
127
  */
128
128
  function checkSorting(unsorted) {
129
129
  if (unsorted.length <= 1) {
@@ -1,26 +1,26 @@
1
1
  /**
2
- * @typedef { import("es-html-parser").TagNode } TagNode
3
- * @typedef { import("es-html-parser").ScriptTagNode } ScriptTagNode
4
- * @typedef { import("es-html-parser").StyleTagNode } StyleTagNode
5
- * @typedef { import("es-html-parser").AttributeNode } AttributeNode
6
- * @typedef { import("es-html-parser").AttributeValueNode } AttributeValueNode
7
- * @typedef { import("es-html-parser").AnyNode } AnyNode
8
- * @typedef { import("es-html-parser").TextNode } TextNode
9
- * @typedef { import("es-html-parser").CommentContentNode } CommentContentNode
10
- * @typedef { import("es-html-parser").CommentNode } CommentNode
11
- * @typedef { import("es-html-parser").AnyToken} AnyToken
12
- * @typedef { import("../../types").LineNode } LineNode
13
- * @typedef { import("../../types").BaseNode } BaseNode
14
- * @typedef { import("../../types").Location } Location
15
- * @typedef { import("../../types").Range } Range
2
+ * @typedef { import("../../types").Attribute } Attribute
3
+ * @typedef { import("../../types").Tag } Tag
4
+ * @typedef { import("../../types").ScriptTag } ScriptTag
5
+ * @typedef { import("../../types").StyleTag } StyleTag
6
+ * @typedef { import("../../types").Line } Line
7
+ * @typedef { import("../../types").Text } Text
8
+ * @typedef { import("../../types").CommentContent } CommentContent
9
+ * @typedef { import("../../types").Comment } Comment
10
+ * @typedef { import("../../types").AnyNode } AnyNode
11
+ * @typedef { import("../../types").AttributeValue } AttributeValue
12
+ * @typedef { import("eslint").AST.Range } Range
13
+ * @typedef { import("eslint").AST.SourceLocation } SourceLocation
14
+ * @typedef { import("es-html-parser").AnyToken } AnyToken
15
+
16
16
  */
17
17
 
18
18
  const { NODE_TYPES } = require("@html-eslint/parser");
19
19
 
20
20
  /**
21
- * @param {TagNode | ScriptTagNode | StyleTagNode} node
21
+ * @param {Tag | ScriptTag | StyleTag} node
22
22
  * @param {string} key
23
- * @returns {AttributeNode | undefined}
23
+ * @returns {Attribute | undefined}
24
24
  */
25
25
  function findAttr(node, key) {
26
26
  return node.attributes.find(
@@ -30,7 +30,7 @@ function findAttr(node, key) {
30
30
 
31
31
  /**
32
32
  * Checks whether a node's attributes is empty or not.
33
- * @param {TagNode | ScriptTagNode | StyleTagNode} node
33
+ * @param {Tag | ScriptTag | StyleTag} node
34
34
  * @returns {boolean}
35
35
  */
36
36
  function isAttributesEmpty(node) {
@@ -57,7 +57,7 @@ function isRangesOverlap(rangeA, rangeB) {
57
57
  }
58
58
 
59
59
  /**
60
- * @param {(TextNode | CommentContentNode)['templates']} templates
60
+ * @param {(Text | CommentContent)['templates']} templates
61
61
  * @param {Range} range
62
62
  * @returns {boolean}
63
63
  */
@@ -69,21 +69,21 @@ function isOverlapWithTemplates(templates, range) {
69
69
 
70
70
  /**
71
71
  *
72
- * @param {TextNode | CommentContentNode} node
73
- * @returns {LineNode[]}
72
+ * @param {Text | CommentContent} node
73
+ * @returns {Line[]}
74
74
  */
75
75
  function splitToLineNodes(node) {
76
76
  let start = node.range[0];
77
77
  let line = node.loc.start.line;
78
78
  const startCol = node.loc.start.column;
79
79
  /**
80
- * @type {LineNode[]}
80
+ * @type {Line[]}
81
81
  */
82
82
  const lineNodes = [];
83
83
  const templates = node.templates || [];
84
84
  /**
85
85
  *
86
- * @param {import("../../types").Range} range
86
+ * @param {Range} range
87
87
  */
88
88
  function shouldSkipIndentCheck(range) {
89
89
  return templates.some(
@@ -95,7 +95,7 @@ function splitToLineNodes(node) {
95
95
  node.value.split("\n").forEach((value, index) => {
96
96
  const columnStart = index === 0 ? startCol : 0;
97
97
  /**
98
- * @type {import("../../types").Range}
98
+ * @type {Range}
99
99
  */
100
100
  const range = [start, start + value.length];
101
101
  const loc = {
@@ -109,7 +109,7 @@ function splitToLineNodes(node) {
109
109
  },
110
110
  };
111
111
  /**
112
- * @type {LineNode}
112
+ * @type {Line}
113
113
  */
114
114
  const lineNode = {
115
115
  type: "Line",
@@ -130,9 +130,9 @@ function splitToLineNodes(node) {
130
130
 
131
131
  /**
132
132
  * Get location between two nodes.
133
- * @param {BaseNode} before A node placed in before
134
- * @param {BaseNode} after A node placed in after
135
- * @returns {Location} location between two nodes.
133
+ * @param {{loc: SourceLocation}} before A node placed in before
134
+ * @param {{loc: SourceLocation}} after A node placed in after
135
+ * @returns {SourceLocation} location between two nodes.
136
136
  */
137
137
  function getLocBetween(before, after) {
138
138
  return {
@@ -142,7 +142,7 @@ function getLocBetween(before, after) {
142
142
  }
143
143
 
144
144
  /**
145
- * @param {AttributeValueNode} node
145
+ * @param {AttributeValue} node
146
146
  * @return {boolean}
147
147
  */
148
148
  function isExpressionInTemplate(node) {
@@ -154,7 +154,7 @@ function isExpressionInTemplate(node) {
154
154
 
155
155
  /**
156
156
  * @param {AnyNode} node
157
- * @returns {node is TagNode}
157
+ * @returns {node is Tag}
158
158
  */
159
159
  function isTag(node) {
160
160
  return node.type === NODE_TYPES.Tag;
@@ -162,7 +162,15 @@ function isTag(node) {
162
162
 
163
163
  /**
164
164
  * @param {AnyNode} node
165
- * @returns {node is CommentNode}
165
+ * @returns {node is ScriptTag}
166
+ */
167
+ function isScript(node) {
168
+ return node.type === NODE_TYPES.ScriptTag;
169
+ }
170
+
171
+ /**
172
+ * @param {AnyNode} node
173
+ * @returns {node is Comment}
166
174
  */
167
175
  function isComment(node) {
168
176
  return node.type === NODE_TYPES.Comment;
@@ -170,12 +178,20 @@ function isComment(node) {
170
178
 
171
179
  /**
172
180
  * @param {AnyNode} node
173
- * @returns {node is TextNode}
181
+ * @returns {node is Text}
174
182
  */
175
183
  function isText(node) {
176
184
  return node.type === NODE_TYPES.Text;
177
185
  }
178
186
 
187
+ /**
188
+ * @param {AnyNode | Line} node
189
+ * @returns {node is Line}
190
+ */
191
+ function isLine(node) {
192
+ return node.type === "Line";
193
+ }
194
+
179
195
  const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u;
180
196
  const lineEndingPattern = new RegExp(lineBreakPattern.source, "gu");
181
197
  /**
@@ -186,10 +202,31 @@ function codeToLines(source) {
186
202
  return source.split(lineEndingPattern);
187
203
  }
188
204
 
205
+ /**
206
+ * @param {Exclude<AnyNode, Line>} node
207
+ * @param {(node: AnyNode) => boolean} predicate
208
+ * @returns {null | AnyNode}
209
+ */
210
+ function findParent(node, predicate) {
211
+ if (!node.parent) {
212
+ return null;
213
+ }
214
+ if (
215
+ node.type === "TaggedTemplateExpression" ||
216
+ node.type === "TemplateLiteral"
217
+ ) {
218
+ return null;
219
+ }
220
+ if (predicate(node.parent)) {
221
+ return node.parent;
222
+ }
223
+ return findParent(node.parent, predicate);
224
+ }
225
+
189
226
  /**
190
227
  *
191
228
  * @param {AnyToken[]} tokens
192
- * @returns {((CommentContentNode | TextNode)['templates'][number])[]}
229
+ * @returns {((CommentContent | Text)['templates'][number])[]}
193
230
  */
194
231
  function getTemplateTokens(tokens) {
195
232
  return (
@@ -210,10 +247,13 @@ module.exports = {
210
247
  isNodeTokensOnSameLine,
211
248
  splitToLineNodes,
212
249
  getLocBetween,
250
+ findParent,
213
251
  isExpressionInTemplate,
214
252
  isTag,
215
253
  isComment,
216
254
  isText,
255
+ isLine,
256
+ isScript,
217
257
  isOverlapWithTemplates,
218
258
  codeToLines,
219
259
  isRangesOverlap,
@@ -2,8 +2,8 @@
2
2
  * @typedef {import("../../types").MaybeHTMLSettings} MaybeHTMLSettings
3
3
  * @typedef {import("../../types").HTMLSettings} HTMLSettings
4
4
  * @typedef {import("../../types").Context} Context
5
- * @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpression
6
- * @typedef {import("estree").TemplateLiteral} TemplateLiteral
5
+ * @typedef {import("../../types").TaggedTemplateExpression} TaggedTemplateExpression
6
+ * @typedef {import("../../types").TemplateLiteral} TemplateLiteral
7
7
  */
8
8
 
9
9
  const { getSourceCode } = require("../utils/source-code");
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @typedef { import("../../types").RuleListener } RuleListener
3
2
  * @typedef { import("../../types").Context } Context
3
+ * @typedef { import("../../types").RuleListener } RuleListener
4
4
  */
5
5
 
6
6
  const {
@@ -0,0 +1,204 @@
1
+ import * as Parser from "es-html-parser";
2
+ import eslint from "eslint";
3
+ import * as estree from "estree";
4
+
5
+ export interface Document extends Parser.DocumentNode {
6
+ parent: null;
7
+ children: Array<Tag | Text | Comment | Doctype | ScriptTag | StyleTag>;
8
+ }
9
+
10
+ export interface Doctype extends Parser.DoctypeNode {
11
+ parent: Document | Tag;
12
+ open: DoctypeOpen;
13
+ close: DoctypeClose;
14
+ attributes: Array<DoctypeAttribute>;
15
+ }
16
+
17
+ export interface DoctypeOpen extends Parser.DoctypeOpenNode {
18
+ parent: Doctype;
19
+ }
20
+
21
+ export interface DoctypeClose extends Parser.DoctypeCloseNode {
22
+ parent: Doctype;
23
+ }
24
+
25
+ export interface DoctypeAttribute extends Parser.DoctypeAttributeNode {
26
+ parent: Doctype;
27
+ }
28
+
29
+ export interface Comment extends Parser.CommentNode {
30
+ parent: Tag | Document;
31
+ open: CommentOpen;
32
+ close: CommentClose;
33
+ value: CommentContent;
34
+ }
35
+
36
+ export interface CommentOpen extends Parser.CommentOpenNode {
37
+ parent: Comment;
38
+ }
39
+
40
+ export interface CommentClose extends Parser.CommentCloseNode {
41
+ parent: Comment;
42
+ }
43
+
44
+ export interface CommentContent extends Parser.CommentContentNode {
45
+ parent: Comment;
46
+ }
47
+
48
+ export interface Tag extends Parser.TagNode {
49
+ parent: Document | Tag;
50
+ openStart: OpenTagStart;
51
+ openEnd: OpenTagEnd;
52
+ attributes: Array<Attribute>;
53
+ close?: CloseTag;
54
+ children: Array<Tag | Text | StyleTag | ScriptTag>;
55
+ }
56
+
57
+ export interface OpenTagStart extends Parser.OpenTagStartNode {
58
+ parent: Tag;
59
+ }
60
+
61
+ export interface OpenTagEnd extends Parser.OpenTagEndNode {
62
+ parent: Tag;
63
+ }
64
+
65
+ export interface CloseTag extends Parser.CloseTagNode {
66
+ parent: Tag;
67
+ }
68
+
69
+ export interface ScriptTag extends Parser.ScriptTagNode {
70
+ parent: Document | Tag;
71
+ attributes: Array<Attribute>;
72
+ openStart: OpenScriptTagStart;
73
+ openEnd: OpenScriptTagEnd;
74
+ value?: ScriptTagContent;
75
+ }
76
+
77
+ export interface OpenScriptTagStart extends Parser.OpenScriptTagStartNode {
78
+ parent: ScriptTag;
79
+ }
80
+
81
+ export interface OpenScriptTagEnd extends Parser.OpenScriptTagEndNode {
82
+ parent: ScriptTag;
83
+ }
84
+
85
+ export interface CloseScriptTag extends Parser.CloseScriptTagNode {
86
+ parent: ScriptTag;
87
+ }
88
+
89
+ export interface ScriptTagContent extends Parser.ScriptTagContentNode {
90
+ parent: ScriptTag;
91
+ }
92
+
93
+ export interface StyleTag extends Parser.StyleTagNode {
94
+ parent: Document | Tag;
95
+ attributes: Array<Attribute>;
96
+ openStart: OpenStyleTagStart;
97
+ openEnd: OpenStyleTagEnd;
98
+ value?: StyleTagContent;
99
+ }
100
+
101
+ export interface OpenStyleTagStart extends Parser.OpenStyleTagStartNode {
102
+ parent: StyleTag;
103
+ }
104
+
105
+ export interface OpenStyleTagEnd extends Parser.OpenStyleTagEndNode {
106
+ parent: StyleTag;
107
+ }
108
+
109
+ export interface CloseStyleTag extends Parser.CloseStyleTagNode {
110
+ parent: StyleTag;
111
+ }
112
+
113
+ export interface StyleTagContent extends Parser.StyleTagContentNode {
114
+ parent: StyleTag;
115
+ }
116
+
117
+ export interface Attribute extends Parser.AttributeNode {
118
+ parent: Tag;
119
+ key: AttributeKey;
120
+ value?: AttributeValue;
121
+ startWrapper?: AttributeValueWrapperStart;
122
+ endWrapper?: AttributeValueWrapperEnd;
123
+ }
124
+
125
+ export interface AttributeKey extends Parser.AttributeKeyNode {
126
+ parent: Attribute;
127
+ }
128
+
129
+ export interface AttributeValue extends Parser.AttributeValueNode {
130
+ parent: Attribute;
131
+ }
132
+
133
+ export interface AttributeValueWrapperStart
134
+ extends Parser.AttributeValueWrapperStartNode {
135
+ parent: Attribute;
136
+ }
137
+
138
+ export interface AttributeValueWrapperEnd
139
+ extends Parser.AttributeValueWrapperEndNode {
140
+ parent: Attribute;
141
+ }
142
+
143
+ export interface Text extends Parser.TextNode {
144
+ parent: Document | Tag;
145
+ }
146
+
147
+ /**
148
+ * This is not a node generated by es-html-parser; it is created by utils's splitToLineNodes.
149
+ */
150
+ export interface Line {
151
+ type: "Line";
152
+ value: string;
153
+ skipIndentCheck: boolean;
154
+ range: eslint.AST.Range;
155
+ loc: eslint.AST.SourceLocation;
156
+ }
157
+
158
+ export interface TaggedTemplateExpression
159
+ extends estree.TaggedTemplateExpression {
160
+ parent: estree.Node | null;
161
+ loc: eslint.AST.SourceLocation;
162
+ range: eslint.AST.Range;
163
+ quasi: TemplateLiteral;
164
+ }
165
+
166
+ export interface TemplateLiteral extends estree.TemplateLiteral {
167
+ parent: estree.Node | null;
168
+ loc: eslint.AST.SourceLocation;
169
+ range: eslint.AST.Range;
170
+ }
171
+
172
+ export type AnyNode =
173
+ | Document
174
+ | Doctype
175
+ | DoctypeOpen
176
+ | DoctypeClose
177
+ | DoctypeAttribute
178
+ | Comment
179
+ | CommentOpen
180
+ | CommentClose
181
+ | CommentContent
182
+ | Tag
183
+ | OpenTagStart
184
+ | OpenTagEnd
185
+ | CloseTag
186
+ | ScriptTag
187
+ | OpenScriptTagStart
188
+ | OpenScriptTagEnd
189
+ | ScriptTagContent
190
+ | CloseScriptTag
191
+ | StyleTag
192
+ | OpenStyleTagStart
193
+ | OpenStyleTagEnd
194
+ | StyleTagContent
195
+ | CloseStyleTag
196
+ | Attribute
197
+ | AttributeKey
198
+ | AttributeValue
199
+ | AttributeValueWrapperEnd
200
+ | AttributeValueWrapperStart
201
+ | Text
202
+ | Line
203
+ | TaggedTemplateExpression
204
+ | TemplateLiteral;
@@ -0,0 +1,3 @@
1
+ export * from "./ast";
2
+ export * from "./rule";
3
+ export * from "./settings";
@@ -0,0 +1,83 @@
1
+ import eslint from "eslint";
2
+ import * as AST from "./ast";
3
+
4
+ type PostFix<T, S extends string> = {
5
+ [K in keyof T as `${K & string}${S}`]: T[K];
6
+ };
7
+
8
+ interface BaseRuleListener {
9
+ Document?: (node: AST.Document) => void;
10
+ AttributeKey?: (node: AST.AttributeKey) => void;
11
+ Text?: (node: AST.Text) => void;
12
+ Tag?: (node: AST.Tag) => void;
13
+ OpenTagStart?: (node: AST.OpenTagStart) => void;
14
+ OpenTagEnd?: (node: AST.OpenTagEnd) => void;
15
+ CloseTag?: (node: AST.CloseTag) => void;
16
+ Attribute?: (node: AST.Attribute) => void;
17
+ AttributeValue?: (node: AST.AttributeValue) => void;
18
+ AttributeValueWrapperEnd?: (node: AST.AttributeValueWrapperEnd) => void;
19
+ AttributeValueWrapperStart?: (node: AST.AttributeValueWrapperStart) => void;
20
+ ScriptTag?: (node: AST.ScriptTag) => void;
21
+ OpenScriptTagStart?: (node: AST.OpenScriptTagStart) => void;
22
+ CloseScriptTag?: (node: AST.CloseScriptTag) => void;
23
+ OpenScriptTagEnd?: (node: AST.OpenScriptTagEnd) => void;
24
+ ScriptTagContent?: (node: AST.ScriptTagContent) => void;
25
+ StyleTag?: (node: AST.StyleTag) => void;
26
+ OpenStyleTagStart?: (node: AST.OpenStyleTagStart) => void;
27
+ OpenStyleTagEnd?: (node: AST.OpenStyleTagEnd) => void;
28
+ StyleTagContent?: (node: AST.StyleTagContent) => void;
29
+ CloseStyleTag?: (node: AST.CloseStyleTag) => void;
30
+ Comment?: (node: AST.Comment) => void;
31
+ CommentOpen?: (node: AST.CommentOpen) => void;
32
+ CommentClose?: (node: AST.CommentClose) => void;
33
+ CommentContent?: (node: AST.CommentContent) => void;
34
+ Doctype?: (node: AST.Doctype) => void;
35
+ DoctypeOpen?: (node: AST.DoctypeOpen) => void;
36
+ DoctypeClose?: (node: AST.DoctypeClose) => void;
37
+ DoctypeAttribute?: (node: AST.DoctypeAttribute) => void;
38
+ DoctypeAttributeValue?: (node: AST.DoctypeAttributeValue) => void;
39
+ DoctypeAttributeWrapperStart?: (
40
+ node: AST.DoctypeAttributeWrapperStart
41
+ ) => void;
42
+ DoctypeAttributeWrapperEnd?: (node: AST.DoctypeAttributeWrapperEnd) => void;
43
+ TaggedTemplateExpression?: (node: AST.TaggedTemplateExpression) => void;
44
+ TemplateLiteral?: (node: AST.TemplateLiteral) => void;
45
+ }
46
+
47
+ interface ReportDescriptorOptionsBase {
48
+ data?: { [key: string]: string };
49
+
50
+ fix?:
51
+ | null
52
+ | ((fixer: RuleFixer) => null | Fix | IterableIterator<Fix> | Fix[]);
53
+ }
54
+
55
+ type SuggestionDescriptorMessage = { desc: string } | { messageId: string };
56
+ type SuggestionReportDescriptor = SuggestionDescriptorMessage &
57
+ ReportDescriptorOptionsBase;
58
+
59
+ interface ReportDescriptorOptions extends ReportDescriptorOptionsBase {
60
+ suggest?: SuggestionReportDescriptor[] | null;
61
+ }
62
+
63
+ type ReportDescriptor = ReportDescriptorMessage &
64
+ ReportDescriptorLocation &
65
+ ReportDescriptorOptions;
66
+ type ReportDescriptorMessage = { message: string } | { messageId: string };
67
+ type ReportDescriptorLocation = {
68
+ node?: BaseNode;
69
+ loc?: ESLint.AST.SourceLocation;
70
+ line?: number;
71
+ column?: number;
72
+ };
73
+
74
+ export interface Context extends Omit<ESLint.Rule.RuleContext, "report"> {
75
+ report(descriptor: ReportDescriptor): void;
76
+ }
77
+
78
+ export type RuleListener = BaseRuleListener &
79
+ PostFix<BaseRuleListener, ":exit">;
80
+
81
+ export interface RuleModule extends eslint.Rule.RuleModule {
82
+ create(context: Context): RuleListener;
83
+ }
@@ -0,0 +1,13 @@
1
+ export type MaybeHTMLSettings = {
2
+ templateLiterals?: {
3
+ tags?: string[];
4
+ comments?: string[];
5
+ };
6
+ };
7
+
8
+ export type HTMLSettings = {
9
+ templateLiterals: {
10
+ tags: RegExp[];
11
+ comments: RegExp[];
12
+ };
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.31.1",
3
+ "version": "0.33.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,15 @@
45
45
  "accessibility"
46
46
  ],
47
47
  "dependencies": {
48
- "@html-eslint/template-parser": "^0.31.0"
48
+ "@html-eslint/template-parser": "^0.33.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@html-eslint/parser": "^0.31.0",
51
+ "@html-eslint/parser": "^0.33.0",
52
52
  "@types/eslint": "^9.6.1",
53
53
  "@types/estree": "^0.0.47",
54
54
  "es-html-parser": "^1.0.0-alpha.4",
55
55
  "espree": "^10.3.0",
56
56
  "typescript": "^5.7.2"
57
57
  },
58
- "gitHead": "96d3cb165f2d777d36e7efbba174e46f437faec0"
58
+ "gitHead": "4a0ee932a671f8c54bf1a86849fe886e9628b777"
59
59
  }
@@ -1,11 +1,10 @@
1
1
  declare namespace _exports {
2
- export { RuleFixer, RuleModule, TagNode, MessageId };
2
+ export { RuleFixer, RuleModule, MessageId };
3
3
  }
4
4
  declare const _exports: RuleModule;
5
5
  export = _exports;
6
- type RuleFixer = import("../types").RuleFixer;
6
+ type RuleFixer = import("eslint").Rule.RuleFixer;
7
7
  type RuleModule = import("../types").RuleModule;
8
- type TagNode = import("../types").TagNode;
9
8
  type MessageId = {
10
9
  CLOSE_STYLE_WRONG: "closeStyleWrong";
11
10
  NEWLINE_MISSING: "newlineMissing";
@@ -1 +1 @@
1
- {"version":3,"file":"attrs-newline.d.ts","sourceRoot":"","sources":["../../lib/rules/attrs-newline.js"],"names":[],"mappings":";;;wBAyBU,UAAU;;iBAxBN,OAAO,UAAU,EAAE,SAAS;kBAC5B,OAAO,UAAU,EAAE,UAAU;eAC7B,OAAO,UAAU,EAAE,OAAO;;uBAG1B,iBAAiB;qBACjB,gBAAgB;wBAChB,mBAAmB"}
1
+ {"version":3,"file":"attrs-newline.d.ts","sourceRoot":"","sources":["../../lib/rules/attrs-newline.js"],"names":[],"mappings":";;;wBAuBU,UAAU;;iBAtBN,OAAO,QAAQ,EAAE,IAAI,CAAC,SAAS;kBAC/B,OAAO,UAAU,EAAE,UAAU;;uBAG7B,iBAAiB;qBACjB,gBAAgB;wBAChB,mBAAmB"}