@html-eslint/eslint-plugin 0.42.0 → 0.43.1

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 (189) hide show
  1. package/lib/languages/html-language.js +3 -3
  2. package/lib/languages/html-source-code.js +9 -11
  3. package/lib/languages/html-traversal-step.js +4 -3
  4. package/lib/rules/attrs-newline.js +3 -4
  5. package/lib/rules/element-newline.js +4 -14
  6. package/lib/rules/id-naming-convention.js +3 -6
  7. package/lib/rules/indent/indent-level.js +1 -1
  8. package/lib/rules/indent/indent.js +18 -23
  9. package/lib/rules/lowercase.js +3 -5
  10. package/lib/rules/max-element-depth.js +3 -5
  11. package/lib/rules/no-abstract-roles.js +3 -5
  12. package/lib/rules/no-accesskey-attrs.js +3 -5
  13. package/lib/rules/no-aria-hidden-body.js +2 -2
  14. package/lib/rules/no-aria-hidden-on-focusable.js +3 -3
  15. package/lib/rules/no-duplicate-attrs.js +8 -8
  16. package/lib/rules/no-duplicate-class.js +3 -6
  17. package/lib/rules/no-duplicate-id.js +6 -9
  18. package/lib/rules/no-duplicate-in-head.js +6 -9
  19. package/lib/rules/no-empty-headings.js +3 -4
  20. package/lib/rules/no-extra-spacing-attrs.js +4 -14
  21. package/lib/rules/no-extra-spacing-text.js +3 -9
  22. package/lib/rules/no-heading-inside-button.js +2 -2
  23. package/lib/rules/no-inline-styles.js +2 -2
  24. package/lib/rules/no-invalid-entity.js +3 -4
  25. package/lib/rules/no-invalid-role.js +2 -2
  26. package/lib/rules/no-multiple-empty-lines.js +10 -11
  27. package/lib/rules/no-multiple-h1.js +3 -3
  28. package/lib/rules/no-nested-interactive.js +3 -3
  29. package/lib/rules/no-non-scalable-viewport.js +2 -2
  30. package/lib/rules/no-obsolete-tags.js +2 -2
  31. package/lib/rules/no-positive-tabindex.js +3 -5
  32. package/lib/rules/no-restricted-attr-values.js +4 -6
  33. package/lib/rules/no-restricted-attrs.js +4 -6
  34. package/lib/rules/no-script-style-type.js +3 -5
  35. package/lib/rules/no-skip-heading-levels.js +3 -3
  36. package/lib/rules/no-target-blank.js +2 -2
  37. package/lib/rules/no-trailing-spaces.js +10 -9
  38. package/lib/rules/prefer-https.js +3 -6
  39. package/lib/rules/quotes.js +25 -10
  40. package/lib/rules/require-attrs.js +3 -8
  41. package/lib/rules/require-button-type.js +3 -4
  42. package/lib/rules/require-closing-tags.js +3 -3
  43. package/lib/rules/require-doctype.js +2 -2
  44. package/lib/rules/require-explicit-size.js +2 -5
  45. package/lib/rules/require-form-method.js +2 -2
  46. package/lib/rules/require-frame-title.js +2 -2
  47. package/lib/rules/require-img-alt.js +4 -4
  48. package/lib/rules/require-input-label.js +3 -3
  49. package/lib/rules/require-lang.js +2 -2
  50. package/lib/rules/require-li-container.js +2 -2
  51. package/lib/rules/require-meta-charset.js +3 -4
  52. package/lib/rules/require-meta-description.js +3 -4
  53. package/lib/rules/require-meta-viewport.js +3 -4
  54. package/lib/rules/require-open-graph-protocol.js +3 -6
  55. package/lib/rules/require-title.js +3 -5
  56. package/lib/rules/sort-attrs.js +4 -5
  57. package/lib/rules/use-baseline.js +3 -6
  58. package/lib/rules/utils/baseline.js +7 -4
  59. package/lib/rules/utils/node.js +11 -26
  60. package/lib/rules/utils/settings.js +4 -7
  61. package/lib/rules/utils/source-code.js +2 -2
  62. package/lib/rules/utils/template-literal.js +43 -0
  63. package/lib/rules/utils/visitors.js +6 -7
  64. package/package.json +6 -6
  65. package/types/languages/html-language.d.ts +0 -5
  66. package/types/languages/html-language.d.ts.map +1 -1
  67. package/types/languages/html-source-code.d.ts +13 -14
  68. package/types/languages/html-source-code.d.ts.map +1 -1
  69. package/types/languages/html-traversal-step.d.ts +5 -5
  70. package/types/languages/html-traversal-step.d.ts.map +1 -1
  71. package/types/rules/attrs-newline.d.ts +3 -4
  72. package/types/rules/attrs-newline.d.ts.map +1 -1
  73. package/types/rules/element-newline.d.ts +5 -13
  74. package/types/rules/element-newline.d.ts.map +1 -1
  75. package/types/rules/id-naming-convention.d.ts +3 -6
  76. package/types/rules/id-naming-convention.d.ts.map +1 -1
  77. package/types/rules/indent/indent-level.d.ts +3 -3
  78. package/types/rules/indent/indent-level.d.ts.map +1 -1
  79. package/types/rules/indent/indent.d.ts +5 -18
  80. package/types/rules/indent/indent.d.ts.map +1 -1
  81. package/types/rules/lowercase.d.ts +2 -8
  82. package/types/rules/lowercase.d.ts.map +1 -1
  83. package/types/rules/max-element-depth.d.ts +3 -6
  84. package/types/rules/max-element-depth.d.ts.map +1 -1
  85. package/types/rules/no-abstract-roles.d.ts +2 -8
  86. package/types/rules/no-abstract-roles.d.ts.map +1 -1
  87. package/types/rules/no-accesskey-attrs.d.ts +2 -8
  88. package/types/rules/no-accesskey-attrs.d.ts.map +1 -1
  89. package/types/rules/no-aria-hidden-body.d.ts +2 -5
  90. package/types/rules/no-aria-hidden-body.d.ts.map +1 -1
  91. package/types/rules/no-aria-hidden-on-focusable.d.ts +2 -6
  92. package/types/rules/no-aria-hidden-on-focusable.d.ts.map +1 -1
  93. package/types/rules/no-duplicate-attrs.d.ts +2 -10
  94. package/types/rules/no-duplicate-attrs.d.ts.map +1 -1
  95. package/types/rules/no-duplicate-class.d.ts +3 -7
  96. package/types/rules/no-duplicate-class.d.ts.map +1 -1
  97. package/types/rules/no-duplicate-id.d.ts +2 -9
  98. package/types/rules/no-duplicate-id.d.ts.map +1 -1
  99. package/types/rules/no-duplicate-in-head.d.ts +2 -9
  100. package/types/rules/no-duplicate-in-head.d.ts.map +1 -1
  101. package/types/rules/no-empty-headings.d.ts +2 -7
  102. package/types/rules/no-empty-headings.d.ts.map +1 -1
  103. package/types/rules/no-extra-spacing-attrs.d.ts +3 -14
  104. package/types/rules/no-extra-spacing-attrs.d.ts.map +1 -1
  105. package/types/rules/no-extra-spacing-text.d.ts +3 -9
  106. package/types/rules/no-extra-spacing-text.d.ts.map +1 -1
  107. package/types/rules/no-heading-inside-button.d.ts +2 -5
  108. package/types/rules/no-heading-inside-button.d.ts.map +1 -1
  109. package/types/rules/no-inline-styles.d.ts +2 -5
  110. package/types/rules/no-inline-styles.d.ts.map +1 -1
  111. package/types/rules/no-invalid-entity.d.ts +3 -5
  112. package/types/rules/no-invalid-entity.d.ts.map +1 -1
  113. package/types/rules/no-invalid-role.d.ts +2 -5
  114. package/types/rules/no-invalid-role.d.ts.map +1 -1
  115. package/types/rules/no-multiple-empty-lines.d.ts +3 -7
  116. package/types/rules/no-multiple-empty-lines.d.ts.map +1 -1
  117. package/types/rules/no-multiple-h1.d.ts +2 -6
  118. package/types/rules/no-multiple-h1.d.ts.map +1 -1
  119. package/types/rules/no-nested-interactive.d.ts +2 -6
  120. package/types/rules/no-nested-interactive.d.ts.map +1 -1
  121. package/types/rules/no-non-scalable-viewport.d.ts +2 -5
  122. package/types/rules/no-non-scalable-viewport.d.ts.map +1 -1
  123. package/types/rules/no-obsolete-tags.d.ts +2 -5
  124. package/types/rules/no-obsolete-tags.d.ts.map +1 -1
  125. package/types/rules/no-positive-tabindex.d.ts +2 -8
  126. package/types/rules/no-positive-tabindex.d.ts.map +1 -1
  127. package/types/rules/no-restricted-attr-values.d.ts +3 -7
  128. package/types/rules/no-restricted-attr-values.d.ts.map +1 -1
  129. package/types/rules/no-restricted-attrs.d.ts +3 -7
  130. package/types/rules/no-restricted-attrs.d.ts.map +1 -1
  131. package/types/rules/no-script-style-type.d.ts +2 -8
  132. package/types/rules/no-script-style-type.d.ts.map +1 -1
  133. package/types/rules/no-skip-heading-levels.d.ts +2 -6
  134. package/types/rules/no-skip-heading-levels.d.ts.map +1 -1
  135. package/types/rules/no-target-blank.d.ts +2 -5
  136. package/types/rules/no-target-blank.d.ts.map +1 -1
  137. package/types/rules/no-trailing-spaces.d.ts +2 -7
  138. package/types/rules/no-trailing-spaces.d.ts.map +1 -1
  139. package/types/rules/prefer-https.d.ts +2 -9
  140. package/types/rules/prefer-https.d.ts.map +1 -1
  141. package/types/rules/quotes.d.ts +7 -9
  142. package/types/rules/quotes.d.ts.map +1 -1
  143. package/types/rules/require-attrs.d.ts +3 -8
  144. package/types/rules/require-attrs.d.ts.map +1 -1
  145. package/types/rules/require-button-type.d.ts +2 -7
  146. package/types/rules/require-button-type.d.ts.map +1 -1
  147. package/types/rules/require-closing-tags.d.ts +3 -4
  148. package/types/rules/require-closing-tags.d.ts.map +1 -1
  149. package/types/rules/require-doctype.d.ts +2 -5
  150. package/types/rules/require-doctype.d.ts.map +1 -1
  151. package/types/rules/require-explicit-size.d.ts +3 -5
  152. package/types/rules/require-explicit-size.d.ts.map +1 -1
  153. package/types/rules/require-form-method.d.ts +2 -5
  154. package/types/rules/require-form-method.d.ts.map +1 -1
  155. package/types/rules/require-frame-title.d.ts +2 -5
  156. package/types/rules/require-frame-title.d.ts.map +1 -1
  157. package/types/rules/require-img-alt.d.ts +3 -4
  158. package/types/rules/require-img-alt.d.ts.map +1 -1
  159. package/types/rules/require-input-label.d.ts +2 -6
  160. package/types/rules/require-input-label.d.ts.map +1 -1
  161. package/types/rules/require-lang.d.ts +2 -5
  162. package/types/rules/require-lang.d.ts.map +1 -1
  163. package/types/rules/require-li-container.d.ts +2 -5
  164. package/types/rules/require-li-container.d.ts.map +1 -1
  165. package/types/rules/require-meta-charset.d.ts +2 -7
  166. package/types/rules/require-meta-charset.d.ts.map +1 -1
  167. package/types/rules/require-meta-description.d.ts +2 -7
  168. package/types/rules/require-meta-description.d.ts.map +1 -1
  169. package/types/rules/require-meta-viewport.d.ts +2 -7
  170. package/types/rules/require-meta-viewport.d.ts.map +1 -1
  171. package/types/rules/require-open-graph-protocol.d.ts +3 -5
  172. package/types/rules/require-open-graph-protocol.d.ts.map +1 -1
  173. package/types/rules/require-title.d.ts +2 -8
  174. package/types/rules/require-title.d.ts.map +1 -1
  175. package/types/rules/sort-attrs.d.ts +3 -6
  176. package/types/rules/sort-attrs.d.ts.map +1 -1
  177. package/types/rules/use-baseline.d.ts +3 -7
  178. package/types/rules/use-baseline.d.ts.map +1 -1
  179. package/types/rules/utils/baseline.d.ts.map +1 -1
  180. package/types/rules/utils/node.d.ts +25 -29
  181. package/types/rules/utils/node.d.ts.map +1 -1
  182. package/types/rules/utils/settings.d.ts +7 -9
  183. package/types/rules/utils/settings.d.ts.map +1 -1
  184. package/types/rules/utils/source-code.d.ts +4 -4
  185. package/types/rules/utils/source-code.d.ts.map +1 -1
  186. package/types/rules/utils/template-literal.d.ts +18 -0
  187. package/types/rules/utils/template-literal.d.ts.map +1 -0
  188. package/types/rules/utils/visitors.d.ts +4 -4
  189. package/types/rules/utils/visitors.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @typedef { import("../types").RuleModule<[]> } RuleModule
2
+ * @import {RuleModule} from "../types";
3
3
  */
4
4
 
5
5
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -13,7 +13,7 @@ const MESSAGE_IDS = {
13
13
  const VALID_CONTAINERS = ["ul", "ol", "menu"];
14
14
 
15
15
  /**
16
- * @type {RuleModule}
16
+ * @type {RuleModule<[]>}
17
17
  */
18
18
  module.exports = {
19
19
  meta: {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Tag } Tag
3
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
4
- * @typedef { import("../types").RuleModule<[]> } RuleModule
2
+ * @import {RuleModule} from "../types";
3
+ * @import {Tag, AnyNode} from "@html-eslint/types";
5
4
  */
6
5
 
7
6
  const { RULE_CATEGORY } = require("../constants");
@@ -23,7 +22,7 @@ function isMetaCharset(node) {
23
22
  }
24
23
 
25
24
  /**
26
- * @type {RuleModule}
25
+ * @type {RuleModule<[]>}
27
26
  */
28
27
  module.exports = {
29
28
  meta: {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Tag } Tag
3
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
4
- * @typedef { import("../types").RuleModule<[]> } RuleModule
2
+ * @import {Tag, AnyNode} from "@html-eslint/types";
3
+ * @import {RuleModule} from "../types";
5
4
  */
6
5
  const { RULE_CATEGORY } = require("../constants");
7
6
  const { filter } = require("./utils/array");
@@ -22,7 +21,7 @@ function isMetaTagNode(node) {
22
21
  }
23
22
 
24
23
  /**
25
- * @type {RuleModule}
24
+ * @type {RuleModule<[]>}
26
25
  */
27
26
  module.exports = {
28
27
  meta: {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Tag } Tag
3
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
4
- * @typedef { import("../types").RuleModule<[]> } RuleModule
2
+ * @import {Tag, AnyNode} from "@html-eslint/types";
3
+ * @import {RuleModule} from "../types";
5
4
  */
6
5
 
7
6
  const { RULE_CATEGORY } = require("../constants");
@@ -31,7 +30,7 @@ function isMetaViewport(node) {
31
30
  }
32
31
 
33
32
  /**
34
- * @type {RuleModule}
33
+ * @type {RuleModule<[]>}
35
34
  */
36
35
  module.exports = {
37
36
  meta: {
@@ -1,10 +1,7 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Tag } Tag
3
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
4
- *
2
+ * @import {Tag, AnyNode} from "@html-eslint/types";
3
+ * @import {RuleModule} from "../types";
5
4
  * @typedef {string[]} Option
6
- *
7
- * @typedef { import("../types").RuleModule<[Option]> } RuleModule
8
5
  */
9
6
 
10
7
  const { RULE_CATEGORY } = require("../constants");
@@ -36,7 +33,7 @@ function normalize(properties) {
36
33
  }
37
34
 
38
35
  /**
39
- * @type {RuleModule}
36
+ * @type {RuleModule<[Option]>}
40
37
  */
41
38
  module.exports = {
42
39
  meta: {
@@ -1,8 +1,6 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Tag } Tag
3
- * @typedef { import("@html-eslint/types").Text } Text
4
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
5
- * @typedef { import("../types").RuleModule<[]> } RuleModule
2
+ * @import {Tag, Text, AnyNode} from "@html-eslint/types";
3
+ * @import {RuleModule} from "../types";
6
4
  */
7
5
 
8
6
  const { RULE_CATEGORY } = require("../constants");
@@ -32,7 +30,7 @@ function isNonEmptyText(node) {
32
30
  }
33
31
 
34
32
  /**
35
- * @type {RuleModule}
33
+ * @type {RuleModule<[]>}
36
34
  */
37
35
  module.exports = {
38
36
  meta: {
@@ -1,11 +1,9 @@
1
1
  /**
2
- * @typedef { import("../types").RuleFixer } RuleFixer
3
- * @typedef { import("@html-eslint/types").Attribute } Attribute
4
- * @typedef { import("@html-eslint/types").Text } Text
2
+ * @import {Attribute} from "@html-eslint/types";
3
+ * @import {RuleFixer, RuleModule} from "../types";
5
4
  *
6
5
  * @typedef {Object} Option
7
6
  * @property {string[]} [Option.priority]
8
- * @typedef { import("../types").RuleModule<[Option]> } RuleModule
9
7
  */
10
8
 
11
9
  const { hasTemplate } = require("./utils/node");
@@ -19,7 +17,7 @@ const MESSAGE_IDS = {
19
17
  };
20
18
 
21
19
  /**
22
- * @type {RuleModule}
20
+ * @type {RuleModule<[Option]>}
23
21
  */
24
22
  module.exports = {
25
23
  meta: {
@@ -44,6 +42,7 @@ module.exports = {
44
42
  },
45
43
  },
46
44
  },
45
+ additionalProperties: false,
47
46
  },
48
47
  ],
49
48
  messages: {
@@ -1,11 +1,8 @@
1
1
  /**
2
+ * @import {RuleModule} from "../types";
3
+ * @import {Attribute, Tag, ScriptTag, StyleTag} from "@html-eslint/types";
2
4
  * @typedef {Object} Option
3
5
  * @property {"widely" | "newly" | number} Option.available
4
- * @typedef { import("../types").RuleModule<[Option]> } RuleModule
5
- * @typedef {import("@html-eslint/types").Attribute} Attribute
6
- * @typedef {import("@html-eslint/types").Tag} Tag
7
- * @typedef {import("@html-eslint/types").ScriptTag} ScriptTag
8
- * @typedef {import("@html-eslint/types").StyleTag} StyleTag
9
6
  */
10
7
 
11
8
  const { RULE_CATEGORY } = require("../constants");
@@ -25,7 +22,7 @@ const MESSAGE_IDS = {
25
22
  };
26
23
 
27
24
  /**
28
- * @type {RuleModule}
25
+ * @type {RuleModule<[Option]>}
29
26
  */
30
27
  module.exports = {
31
28
  meta: {
@@ -119,6 +119,7 @@ const elements = new Map([
119
119
  ["details.open", "10:2020"],
120
120
  ["dfn", "10:2015"],
121
121
  ["dialog", "10:2022"],
122
+ ["dialog.closedby", "0:"],
122
123
  ["dialog.open", "10:2022"],
123
124
  ["div", "10:2015"],
124
125
  ["dl", "10:2015"],
@@ -151,6 +152,7 @@ const elements = new Map([
151
152
  ["form.rel", "5:2023"],
152
153
  ["form.target", "10:2015"],
153
154
  ["h1", "10:2015"],
155
+ ["h1.no_ua_styles_in_article_aside_nav_section", "0:"],
154
156
  ["h2", "10:2015"],
155
157
  ["h3", "10:2015"],
156
158
  ["h4", "10:2015"],
@@ -235,6 +237,7 @@ const elements = new Map([
235
237
  ["img.referrerpolicy.origin-when-cross-origin", "0:"],
236
238
  ["img.referrerpolicy.unsafe-url", "0:"],
237
239
  ["img.sizes", "10:2016"],
240
+ ["img.sizes.auto", "0:"],
238
241
  ["img.src", "10:2015"],
239
242
  ["img.srcset", "10:2015"],
240
243
  ["img.usemap", "10:2015"],
@@ -324,7 +327,7 @@ const elements = new Map([
324
327
  ["link.rel", "10:2015"],
325
328
  ["link.rel.alternate_stylesheet", "0:"],
326
329
  ["link.rel.compression-dictionary", "0:"],
327
- ["link.rel.dns-prefetch", "5:2024"],
330
+ ["link.rel.dns-prefetch", "0:"],
328
331
  ["link.rel.expect", "0:"],
329
332
  ["link.rel.manifest", "0:"],
330
333
  ["link.rel.modulepreload", "5:2023"],
@@ -432,6 +435,7 @@ const elements = new Map([
432
435
  ],
433
436
  ["script.type.speculationrules.source_optional", "0:"],
434
437
  ["script.type.speculationrules.tag", "0:"],
438
+ ["script.type.speculationrules.target_hint", "0:"],
435
439
  ["script.type.speculationrules.urls", "0:"],
436
440
  ["script.type.speculationrules.where", "0:"],
437
441
  ["search", "5:2023"],
@@ -449,13 +453,13 @@ const elements = new Map([
449
453
  ["slot.name", "10:2020"],
450
454
  ["small", "10:2015"],
451
455
  ["source", "10:2015"],
452
- ["source.height", "5:2022"],
456
+ ["source.height", "10:2022"],
453
457
  ["source.media", "10:2015"],
454
458
  ["source.sizes", "10:2016"],
455
459
  ["source.src", "10:2015"],
456
460
  ["source.srcset", "10:2016"],
457
461
  ["source.type", "10:2015"],
458
- ["source.width", "5:2022"],
462
+ ["source.width", "10:2022"],
459
463
  ["span", "10:2015"],
460
464
  ["strong", "10:2015"],
461
465
  ["style", "10:2015"],
@@ -514,7 +518,6 @@ const elements = new Map([
514
518
  ["textarea.readonly", "10:2015"],
515
519
  ["textarea.required", "10:2015"],
516
520
  ["textarea.rows", "10:2015"],
517
- ["textarea.spellcheck", "10:2015"],
518
521
  ["textarea.wrap", "10:2015"],
519
522
  ["textarea.wrap.hard", "0:"],
520
523
  ["tfoot", "10:2015"],
@@ -1,22 +1,7 @@
1
1
  /**
2
- * @typedef { import("@html-eslint/types").Attribute } Attribute
3
- * @typedef { import("@html-eslint/types").Tag } Tag
4
- * @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
5
- * @typedef { import("@html-eslint/types").StyleTag } StyleTag
6
- * @typedef { import("@html-eslint/types").AnyNode } AnyNode
7
- * @typedef { import("../../types").Line } Line
8
- * @typedef { import("../../types").BaseNode } BaseNode
9
- * @typedef { import("@html-eslint/types").Text } Text
10
- * @typedef { import("@html-eslint/types").CommentContent } CommentContent
11
- * @typedef { import("@html-eslint/types").Comment } Comment
12
- * @typedef { import("@html-eslint/types").AttributeValue } AttributeValue
13
- * @typedef { import("@html-eslint/types").AttributeKey } AttributeKey
14
- * @typedef { import("@html-eslint/types").TemplateText } TemplateText
15
- * @typedef { import("@html-eslint/types").OpenTemplate } OpenTemplate
16
- * @typedef { import("@html-eslint/types").CloseTemplate } CloseTemplate
17
- * @typedef { import("eslint").AST.Range } Range
18
- * @typedef { import("eslint").AST.SourceLocation } SourceLocation
19
- * @typedef { import("@html-eslint/types").AnyToken } AnyToken
2
+ * @import {Attribute, Tag, ScriptTag, StyleTag, AnyNode, Text, CommentContent, Comment, AttributeValue, AttributeKey, AnyToken} from "@html-eslint/types";
3
+ * @import {Line, BaseNode} from "../../types";
4
+ * @import {AST} from "eslint";
20
5
  */
21
6
 
22
7
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -52,8 +37,8 @@ function isNodeTokensOnSameLine(node) {
52
37
 
53
38
  /**
54
39
  *
55
- * @param {Range} rangeA
56
- * @param {Range} rangeB
40
+ * @param {AST.Range} rangeA
41
+ * @param {AST.Range} rangeB
57
42
  * @returns {boolean}
58
43
  */
59
44
  function isRangesOverlap(rangeA, rangeB) {
@@ -62,7 +47,7 @@ function isRangesOverlap(rangeA, rangeB) {
62
47
 
63
48
  /**
64
49
  * @param {(Text | CommentContent)['parts']} parts
65
- * @param {Range} range
50
+ * @param {AST.Range} range
66
51
  * @returns {boolean}
67
52
  */
68
53
  function isOverlapWithTemplates(parts, range) {
@@ -95,7 +80,7 @@ function splitToLineNodes(node) {
95
80
  const parts = node.parts || [];
96
81
  /**
97
82
  *
98
- * @param {Range} range
83
+ * @param {AST.Range} range
99
84
  */
100
85
  function hasTemplate(range) {
101
86
  return parts.some(
@@ -107,7 +92,7 @@ function splitToLineNodes(node) {
107
92
  node.value.split("\n").forEach((value, index) => {
108
93
  const columnStart = index === 0 ? startCol : 0;
109
94
  /**
110
- * @type {Range}
95
+ * @type {AST.Range}
111
96
  */
112
97
  const range = [start, start + value.length];
113
98
  const loc = {
@@ -142,9 +127,9 @@ function splitToLineNodes(node) {
142
127
 
143
128
  /**
144
129
  * Get location between two nodes.
145
- * @param {{loc: SourceLocation}} before A node placed in before
146
- * @param {{loc: SourceLocation}} after A node placed in after
147
- * @returns {SourceLocation} location between two nodes.
130
+ * @param {{loc: AST.SourceLocation}} before A node placed in before
131
+ * @param {{loc: AST.SourceLocation}} after A node placed in after
132
+ * @returns {AST.SourceLocation} location between two nodes.
148
133
  */
149
134
  function getLocBetween(before, after) {
150
135
  return {
@@ -1,9 +1,6 @@
1
1
  /**
2
- * @typedef {import("../../types").MaybeHTMLSettings} MaybeHTMLSettings
3
- * @typedef {import("../../types").HTMLSettings} HTMLSettings
4
- * @typedef {import("../../types").Context<any[]>} Context
5
- * @typedef {import("@html-eslint/types").TaggedTemplateExpression} TaggedTemplateExpression
6
- * @typedef {import("@html-eslint/types").TemplateLiteral} TemplateLiteral
2
+ * @import {MaybeHTMLSettings, HTMLSettings, Context} from "../../types";
3
+ * @import {TaggedTemplateExpression, TemplateLiteral} from "@html-eslint/types";
7
4
  */
8
5
 
9
6
  const { getSourceCode } = require("../utils/source-code");
@@ -53,7 +50,7 @@ function getSettings(settings) {
53
50
 
54
51
  /**
55
52
  * @param {TaggedTemplateExpression} node
56
- * @param {Context} context
53
+ * @param {Context<any[]>} context
57
54
  * @returns {boolean}
58
55
  */
59
56
  function shouldCheckTaggedTemplateExpression(node, context) {
@@ -68,7 +65,7 @@ function shouldCheckTaggedTemplateExpression(node, context) {
68
65
  /**
69
66
  *
70
67
  * @param {TemplateLiteral} node
71
- * @param {Context} context
68
+ * @param {Context<any[]>} context
72
69
  * @returns {boolean}
73
70
  */
74
71
  function shouldCheckTemplateLiteral(node, context) {
@@ -1,9 +1,9 @@
1
1
  /**
2
- * @typedef {import("../../types").Context<any[]>} Context
2
+ * @import {Context} from "../../types";
3
3
  */
4
4
 
5
5
  /**
6
- * @param {Context} context
6
+ * @param {Context<any[]>} context
7
7
  */
8
8
  function getSourceCode(context) {
9
9
  return context.sourceCode || context.getSourceCode();
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @import {TemplateLiteral} from "@html-eslint/types";
3
+ * @import {DocumentNode, AnyToken} from "es-html-parser";
4
+ * @import {SourceCode} from "eslint";
5
+ * @import {TemplateHTMLVisitor} from "@html-eslint/template-parser"
6
+ */
7
+
8
+ const { parse, traverse } = require("@html-eslint/template-parser");
9
+
10
+ /**
11
+ * Cache for parsed template literals to avoid re-parsing the same template multiple times.
12
+ * Uses WeakMap for automatic garbage collection when nodes are no longer referenced.
13
+ * @type {WeakMap<TemplateLiteral, {ast: any, html: string, tokens: any[]}>}
14
+ */
15
+ const templateCache = new WeakMap();
16
+
17
+ /**
18
+ * Get or create cached parse result for a template literal.
19
+ * @param {TemplateLiteral} node
20
+ * @param {SourceCode} sourceCode
21
+ * @param {TemplateHTMLVisitor} [visitor]
22
+ * @returns {{ast: DocumentNode, html: string, tokens: AnyToken[]}}
23
+ */
24
+ function parseTemplateLiteral(node, sourceCode, visitor) {
25
+ // Check if we already have a cached result for this node
26
+ const cachedResult = templateCache.get(node);
27
+ if (cachedResult) {
28
+ if (visitor) {
29
+ traverse(cachedResult.ast, visitor);
30
+ }
31
+ return cachedResult;
32
+ }
33
+
34
+ // Parse and cache the result
35
+ const result = parse(node, sourceCode);
36
+ templateCache.set(node, result);
37
+ if (visitor) {
38
+ traverse(result.ast, visitor);
39
+ }
40
+ return result;
41
+ }
42
+
43
+ module.exports = { parseTemplateLiteral };
@@ -1,17 +1,16 @@
1
1
  /**
2
- * @typedef { import("../../types").Context<any[]> } Context
3
- * @typedef { import("../../types").RuleListener } RuleListener
2
+ * @import {Context, RuleListener} from "../../types";
4
3
  */
5
4
 
6
5
  const {
7
6
  shouldCheckTaggedTemplateExpression,
8
7
  shouldCheckTemplateLiteral,
9
8
  } = require("./settings");
10
- const { parse } = require("@html-eslint/template-parser");
9
+ const { parseTemplateLiteral } = require("./template-literal");
11
10
  const { getSourceCode } = require("./source-code");
12
11
 
13
12
  /**
14
- * @param {Context} context
13
+ * @param {Context<any[]>} context
15
14
  * @param {any} visitors
16
15
  * @returns {RuleListener}
17
16
  */
@@ -19,19 +18,19 @@ function createTemplateVisitors(context, visitors) {
19
18
  return {
20
19
  TaggedTemplateExpression(node) {
21
20
  if (shouldCheckTaggedTemplateExpression(node, context)) {
22
- parse(node.quasi, getSourceCode(context), visitors);
21
+ parseTemplateLiteral(node.quasi, getSourceCode(context), visitors);
23
22
  }
24
23
  },
25
24
  TemplateLiteral(node) {
26
25
  if (shouldCheckTemplateLiteral(node, context)) {
27
- parse(node, getSourceCode(context), visitors);
26
+ parseTemplateLiteral(node, getSourceCode(context), visitors);
28
27
  }
29
28
  },
30
29
  };
31
30
  }
32
31
 
33
32
  /**
34
- * @param {Context} context
33
+ * @param {Context<any[]>} context
35
34
  * @param {RuleListener} visitors
36
35
  * @param {any} [templateVisitors]
37
36
  * @returns {RuleListener}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.42.0",
3
+ "version": "0.43.1",
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.42.0",
44
- "@html-eslint/template-parser": "^0.42.0",
45
- "@html-eslint/template-syntax-parser": "^0.42.0"
43
+ "@html-eslint/parser": "^0.43.0",
44
+ "@html-eslint/template-parser": "^0.43.0",
45
+ "@html-eslint/template-syntax-parser": "^0.43.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.42.0",
52
+ "@html-eslint/types": "^0.43.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": "30e536dad0fef8ea04b8ef383024f203a3f2655f"
62
+ "gitHead": "5a4e4b08419cfb8bdf27ca65c7703e5ce037914a"
63
63
  }
@@ -1,8 +1,3 @@
1
- /**
2
- * @import { Language, ParseResult, File, FileError, OkParseResult } from "@eslint/core";
3
- * @import { ParserOptions } from "@html-eslint/parser";
4
- * @import { AST } from "eslint";
5
- */
6
1
  /**
7
2
  * @implements {Language<{ LangOptions: ParserOptions; Code: HTMLSourceCode; RootNode: AST.Program; Node: {}}>}
8
3
  */
@@ -1 +1 @@
1
- {"version":3,"file":"html-language.d.ts","sourceRoot":"","sources":["../../lib/languages/html-language.js"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH;;GAEG;AACH;IAEI;;;OAGG;IACH,UAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,CAAC,GAAC,CAAC,CAEK;IAElB;;;OAGG;IACH,aAFU,CAAC,GAAC,CAAC,CAEO;IAEpB;;OAEG;IACH,aAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,aAFU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEJ;IAGhC;;OAEG;IACH,yCAFW,aAAa,QAqBvB;IAED;;;;;OAKG;IACH,YALW,IAAI,YAEZ;QAA+B,eAAe,EAAtC,aAAa;KACrB,GAAU,YAAY,WAAW,CAAC,CAkBpC;IAED;;;OAGG;IACH,uBAHW,IAAI,eACJ,cAAc,WAAW,CAAC,kBAQpC;CACF;8BAnGyE,cAAc;mCACtD,qBAAqB;0BADmB,cAAc;yBAEhE,QAAQ;iCAF0C,cAAc;mCAAd,cAAc"}
1
+ {"version":3,"file":"html-language.d.ts","sourceRoot":"","sources":["../../lib/languages/html-language.js"],"names":[],"mappings":"AASA;;GAEG;AACH;IAEI;;;OAGG;IACH,UAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,CAAC,GAAC,CAAC,CAEK;IAElB;;;OAGG;IACH,aAFU,CAAC,GAAC,CAAC,CAEO;IAEpB;;OAEG;IACH,aAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,aAFU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEJ;IAGhC;;OAEG;IACH,yCAFW,aAAa,QAqBvB;IAED;;;;;OAKG;IACH,YALW,IAAI,YAEZ;QAA+B,eAAe,EAAtC,aAAa;KACrB,GAAU,YAAY,WAAW,CAAC,CAkBpC;IAED;;;OAGG;IACH,uBAHW,IAAI,eACJ,cAAc,WAAW,CAAC,kBAQpC;CACF;8BAtGyE,cAAc;mCACtD,qBAAqB;0BADmB,cAAc;yBAEhE,QAAQ;iCAF0C,cAAc;mCAAd,cAAc"}
@@ -1,30 +1,22 @@
1
- export type Program = import("eslint").AST.Program;
2
- export type SourceLocation = import("@eslint/plugin-kit").SourceLocation;
3
- export type DirectiveType = import("@eslint/plugin-kit").DirectiveType;
4
- export type TraversalStep = import("@eslint/core").TraversalStep;
5
- export type CommentContent = import("@html-eslint/types").CommentContent;
6
- export type AnyHTMLNode = import("@html-eslint/types").AnyHTMLNode;
7
- export type Position = import("@eslint/core").Position;
8
- export type BaseNode = import("../types").BaseNode;
9
1
  export class HTMLSourceCode extends TextSourceCodeBase<import("@eslint/core").SourceCodeBaseTypeOptions & {
10
2
  SyntaxElementWithLoc: object;
11
3
  }> {
12
4
  /**
13
- * @param {{ast: Program, text: string, comments: CommentContent[]}} config
5
+ * @param {{ast: AST.Program, text: string, comments: CommentContent[]}} config
14
6
  */
15
7
  constructor({ ast, text, comments }: {
16
- ast: Program;
8
+ ast: AST.Program;
17
9
  text: string;
18
10
  comments: CommentContent[];
19
11
  });
20
12
  /**
21
13
  * @property
22
14
  */
23
- ast: import("eslint").AST.Program;
15
+ ast: AST.Program;
24
16
  /**
25
17
  * @property
26
18
  */
27
- comments: import("@html-eslint/types").CommentContent[];
19
+ comments: CommentContent[];
28
20
  parentsMap: Map<any, any>;
29
21
  lineStartIndices: number[];
30
22
  /**
@@ -50,7 +42,7 @@ export class HTMLSourceCode extends TextSourceCodeBase<import("@eslint/core").So
50
42
  * @returns {Position}
51
43
  */
52
44
  getLocFromIndex(index: number): Position;
53
- getInlineConfigNodes(): import("@html-eslint/types").CommentContent[];
45
+ getInlineConfigNodes(): CommentContent[];
54
46
  getDisableDirectives(): {
55
47
  problems: {
56
48
  ruleId: null | string;
@@ -59,7 +51,7 @@ export class HTMLSourceCode extends TextSourceCodeBase<import("@eslint/core").So
59
51
  }[];
60
52
  directives: Directive[];
61
53
  };
62
- traverse(): import("@eslint/core").TraversalStep[];
54
+ traverse(): TraversalStep[];
63
55
  /**
64
56
  * @param {AnyHTMLNode} node
65
57
  * @returns
@@ -67,5 +59,12 @@ export class HTMLSourceCode extends TextSourceCodeBase<import("@eslint/core").So
67
59
  getParent(node: AnyHTMLNode): any;
68
60
  }
69
61
  import { TextSourceCodeBase } from "@eslint/plugin-kit";
62
+ import type { AST } from 'eslint';
63
+ import type { CommentContent } from '@html-eslint/types';
64
+ import type { BaseNode } from '../types';
65
+ import type { Position } from '@eslint/core';
66
+ import type { SourceLocation } from '@eslint/plugin-kit';
70
67
  import { Directive } from "@eslint/plugin-kit";
68
+ import type { TraversalStep } from '@eslint/core';
69
+ import type { AnyHTMLNode } from '@html-eslint/types';
71
70
  //# sourceMappingURL=html-source-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-source-code.d.ts","sourceRoot":"","sources":["../../lib/languages/html-source-code.js"],"names":[],"mappings":"sBACc,OAAO,QAAQ,EAAE,GAAG,CAAC,OAAO;6BAC5B,OAAO,oBAAoB,EAAE,cAAc;4BAC3C,OAAO,oBAAoB,EAAE,aAAa;4BAC1C,OAAO,cAAc,EAAE,aAAa;6BACpC,OAAO,oBAAoB,EAAE,cAAc;0BAC3C,OAAO,oBAAoB,EAAE,WAAW;uBACxC,OAAO,cAAc,EAAE,QAAQ;uBAC/B,OAAO,UAAU,EAAE,QAAQ;AAqBzC;;;IACE;;OAEG;IACH,qCAFW;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAC,EAsBlE;IAjBC;;OAEG;IACH,kCAAc;IACd;;OAEG;IACH,wDAAwB;IACxB,0BAA2B;IAE3B,2BAA2B;IAS7B;;;OAGG;IACH,eAHW,QAAQ,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5B;IAED;;;OAGG;IACH,aAHW,QAAQ,GACN,OAAO,oBAAoB,EAAE,cAAc,CAIvD;IAED,qBAEC;IAGD;;;;OAIG;IACH,qBAHW,QAAQ,GACN,MAAM,CA0ClB;IAGD;;;;OAIG;IACH,uBAHW,MAAM,GACJ,QAAQ,CA8BpB;IAED,sEAEC;IAED;;oBAEqB,IAAI,GAAG,MAAM;qBAAW,MAAM;iBAAO,cAAc;;;MA8CvE;IAED,mDAgDC;IAED;;;OAGG;IACH,gBAHW,WAAW,OAKrB;CACF"}
1
+ {"version":3,"file":"html-source-code.d.ts","sourceRoot":"","sources":["../../lib/languages/html-source-code.js"],"names":[],"mappings":"AA2BA;;;IACE;;OAEG;IACH,qCAFW;QAAC,GAAG,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAC,EAsBtE;IAjBC;;OAEG;IACH,iBAAc;IACd;;OAEG;IACH,2BAAwB;IACxB,0BAA2B;IAE3B,2BAA2B;IAS7B;;;OAGG;IACH,eAHW,QAAQ,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5B;IAED;;;OAGG;IACH,aAHW,QAAQ,GACN,OAAO,oBAAoB,EAAE,cAAc,CAIvD;IAED,qBAEC;IAGD;;;;OAIG;IACH,qBAHW,QAAQ,GACN,MAAM,CA0ClB;IAGD;;;;OAIG;IACH,uBAHW,MAAM,GACJ,QAAQ,CA8BpB;IAED,yCAEC;IAED;;oBAEqB,IAAI,GAAG,MAAM;qBAAW,MAAM;iBAAO,cAAc;;;MA8CvE;IAED,4BAgDC;IAED;;;OAGG;IACH,gBAHW,WAAW,OAKrB;CACF;;yBA3QqB,QAAQ;oCAGgB,oBAAoB;8BACvC,UAAU;8BAFK,cAAc;oCADR,oBAAoB;;mCAC1B,cAAc;iCACV,oBAAoB"}
@@ -1,22 +1,22 @@
1
- export type Program = import("eslint").AST.Program;
2
- export type AnyHTMLNode = import("@html-eslint/types").AnyHTMLNode;
3
1
  export class HTMLTraversalStep extends VisitNodeStep {
4
2
  /**
5
3
  * @param {Object} options
6
- * @param {AnyHTMLNode | Program} options.target
4
+ * @param {AnyHTMLNode | AST.Program} options.target
7
5
  * @param {1|2} options.phase
8
6
  * @param {Array<any>} options.args
9
7
  */
10
8
  constructor({ target, phase, args }: {
11
- target: AnyHTMLNode | Program;
9
+ target: AnyHTMLNode | AST.Program;
12
10
  phase: 1 | 2;
13
11
  args: Array<any>;
14
12
  });
15
- target: import("eslint").AST.Program | import("@html-eslint/types").AnyHTMLNode;
13
+ target: AST.Program | AnyHTMLNode;
16
14
  }
17
15
  export namespace STEP_PHASE {
18
16
  let ENTER: 1;
19
17
  let EXIT: 2;
20
18
  }
21
19
  import { VisitNodeStep } from "@eslint/plugin-kit";
20
+ import type { AST } from 'eslint';
21
+ import type { AnyHTMLNode } from '@html-eslint/types';
22
22
  //# sourceMappingURL=html-traversal-step.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-traversal-step.d.ts","sourceRoot":"","sources":["../../lib/languages/html-traversal-step.js"],"names":[],"mappings":"sBACc,OAAO,QAAQ,EAAE,GAAG,CAAC,OAAO;0BAC7B,OAAO,oBAAoB,EAAE,WAAW;AAerD;IACE;;;;;OAKG;IACH,qCAJG;QAAuC,MAAM,EAArC,WAAW,GAAG,OAAO;QACR,KAAK,EAAlB,CAAC,GAAC,CAAC;QACiB,IAAI,EAAxB,KAAK,CAAC,GAAG,CAAC;KACpB,EAIA;IADC,gFAAoB;CAEvB;;eApBW,CAAC;cAID,CAAC"}
1
+ {"version":3,"file":"html-traversal-step.d.ts","sourceRoot":"","sources":["../../lib/languages/html-traversal-step.js"],"names":[],"mappings":"AAkBA;IACE;;;;;OAKG;IACH,qCAJG;QAA2C,MAAM,EAAzC,WAAW,GAAG,WAAW;QACZ,KAAK,EAAlB,CAAC,GAAC,CAAC;QACiB,IAAI,EAAxB,KAAK,CAAC,GAAG,CAAC;KACpB,EAIA;IADC,kCAAoB;CAEvB;;eApBW,CAAC;cAID,CAAC;;;yBAZS,QAAQ;iCACA,oBAAoB"}
@@ -1,9 +1,8 @@
1
1
  declare namespace _exports {
2
- export { RuleFixer, MessageId, Option, RuleModule };
2
+ export { MessageId, Option };
3
3
  }
4
- declare const _exports: RuleModule;
4
+ declare const _exports: RuleModule<[Option]>;
5
5
  export = _exports;
6
- type RuleFixer = import("../types").RuleFixer;
7
6
  type MessageId = {
8
7
  CLOSE_STYLE_WRONG: "closeStyleWrong";
9
8
  NEWLINE_MISSING: "newlineMissing";
@@ -12,5 +11,5 @@ type Option = {
12
11
  closeStyle?: "sameline" | "newline" | undefined;
13
12
  ifAttrsMoreThan?: number | undefined;
14
13
  };
15
- type RuleModule = import("../types").RuleModule<[Option]>;
14
+ import type { RuleModule } from '../types';
16
15
  //# sourceMappingURL=attrs-newline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attrs-newline.d.ts","sourceRoot":"","sources":["../../lib/rules/attrs-newline.js"],"names":[],"mappings":";;;wBA2BU,UAAU;;iBA1BN,OAAO,UAAU,EAAE,SAAS;;uBAG5B,iBAAiB;qBACjB,gBAAgB;;;;;;kBAMhB,OAAO,UAAU,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"attrs-newline.d.ts","sourceRoot":"","sources":["../../lib/rules/attrs-newline.js"],"names":[],"mappings":";;;wBAyBU,WAAW,CAAC,MAAM,CAAC,CAAC;;;uBArBhB,iBAAiB;qBACjB,gBAAgB;;;;;;gCAJY,UAAU"}