@html-eslint/eslint-plugin 0.50.0 → 0.52.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 (173) hide show
  1. package/lib/configs/recommended.js +8 -2
  2. package/lib/index.js +2 -6
  3. package/lib/languages/html-language.js +23 -15
  4. package/lib/languages/html-source-code.js +34 -26
  5. package/lib/languages/html-traversal-step.js +6 -10
  6. package/lib/rules/attrs-newline.js +9 -9
  7. package/lib/rules/class-spacing.js +148 -0
  8. package/lib/rules/element-newline.js +18 -21
  9. package/lib/rules/id-naming-convention.js +15 -12
  10. package/lib/rules/indent/indent-level.js +10 -17
  11. package/lib/rules/indent/indent.js +51 -56
  12. package/lib/rules/index.js +7 -1
  13. package/lib/rules/lowercase.js +11 -23
  14. package/lib/rules/max-element-depth.js +8 -10
  15. package/lib/rules/no-abstract-roles.js +8 -8
  16. package/lib/rules/no-accesskey-attrs.js +8 -8
  17. package/lib/rules/no-aria-hidden-body.js +2 -6
  18. package/lib/rules/no-aria-hidden-on-focusable.js +4 -5
  19. package/lib/rules/no-duplicate-attrs.js +12 -8
  20. package/lib/rules/no-duplicate-class.js +8 -14
  21. package/lib/rules/no-duplicate-id.js +9 -15
  22. package/lib/rules/no-duplicate-in-head.js +10 -17
  23. package/lib/rules/no-empty-headings.js +7 -8
  24. package/lib/rules/no-extra-spacing-attrs.js +13 -8
  25. package/lib/rules/no-extra-spacing-text.js +11 -14
  26. package/lib/rules/no-heading-inside-button.js +2 -6
  27. package/lib/rules/no-ineffective-attrs.js +14 -15
  28. package/lib/rules/no-inline-styles.js +2 -6
  29. package/lib/rules/no-invalid-entity.js +4 -8
  30. package/lib/rules/no-invalid-role.js +3 -10
  31. package/lib/rules/no-multiple-empty-lines.js +7 -7
  32. package/lib/rules/no-multiple-h1.js +4 -8
  33. package/lib/rules/no-nested-interactive.js +5 -9
  34. package/lib/rules/no-non-scalable-viewport.js +2 -6
  35. package/lib/rules/no-obsolete-attrs.js +83 -0
  36. package/lib/rules/no-obsolete-tags.js +2 -6
  37. package/lib/rules/no-positive-tabindex.js +8 -8
  38. package/lib/rules/no-restricted-attr-values.js +18 -21
  39. package/lib/rules/no-restricted-attrs.js +18 -22
  40. package/lib/rules/no-restricted-tags.js +17 -20
  41. package/lib/rules/no-script-style-type.js +7 -6
  42. package/lib/rules/no-skip-heading-levels.js +4 -8
  43. package/lib/rules/no-target-blank.js +3 -6
  44. package/lib/rules/no-trailing-spaces.js +7 -6
  45. package/lib/rules/no-whitespace-only-children.js +113 -0
  46. package/lib/rules/prefer-https.js +11 -14
  47. package/lib/rules/quotes.js +13 -16
  48. package/lib/rules/require-attrs.js +18 -17
  49. package/lib/rules/require-button-type.js +6 -5
  50. package/lib/rules/require-closing-tags.js +9 -12
  51. package/lib/rules/require-doctype.js +2 -6
  52. package/lib/rules/require-explicit-size.js +2 -5
  53. package/lib/rules/require-form-method.js +2 -6
  54. package/lib/rules/require-frame-title.js +2 -6
  55. package/lib/rules/require-img-alt.js +3 -6
  56. package/lib/rules/require-input-label.js +3 -5
  57. package/lib/rules/require-lang.js +2 -6
  58. package/lib/rules/require-li-container.js +2 -6
  59. package/lib/rules/require-meta-charset.js +6 -5
  60. package/lib/rules/require-meta-description.js +6 -5
  61. package/lib/rules/require-meta-viewport.js +6 -5
  62. package/lib/rules/require-open-graph-protocol.js +7 -8
  63. package/lib/rules/require-title.js +7 -5
  64. package/lib/rules/sort-attrs.js +13 -19
  65. package/lib/rules/use-baseline.js +8 -6
  66. package/lib/rules/utils/baseline.js +4 -6
  67. package/lib/rules/utils/naming.js +14 -7
  68. package/lib/rules/utils/node.js +63 -29
  69. package/lib/rules/utils/rule.js +1 -4
  70. package/lib/rules/utils/settings.js +9 -3
  71. package/lib/rules/utils/source-code.js +2 -6
  72. package/lib/rules/utils/template-literal.js +16 -7
  73. package/lib/rules/utils/visitors.js +4 -1
  74. package/lib/specs/index.js +5 -0
  75. package/lib/specs/obsolete-attrs.js +604 -0
  76. package/lib/types/ast.ts +5 -2
  77. package/package.json +6 -6
  78. package/types/configs/recommended.d.ts +2 -1
  79. package/types/configs/recommended.d.ts.map +1 -1
  80. package/types/index.d.ts +2 -6
  81. package/types/index.d.ts.map +1 -1
  82. package/types/languages/html-language.d.ts +12 -10
  83. package/types/languages/html-language.d.ts.map +1 -1
  84. package/types/languages/html-source-code.d.ts +13 -6
  85. package/types/languages/html-source-code.d.ts.map +1 -1
  86. package/types/languages/html-traversal-step.d.ts +5 -5
  87. package/types/languages/html-traversal-step.d.ts.map +1 -1
  88. package/types/rules/attrs-newline.d.ts +1 -1
  89. package/types/rules/attrs-newline.d.ts.map +1 -1
  90. package/types/rules/class-spacing.d.ts +4 -0
  91. package/types/rules/class-spacing.d.ts.map +1 -0
  92. package/types/rules/element-newline.d.ts +3 -3
  93. package/types/rules/element-newline.d.ts.map +1 -1
  94. package/types/rules/id-naming-convention.d.ts.map +1 -1
  95. package/types/rules/indent/indent-level.d.ts +10 -17
  96. package/types/rules/indent/indent-level.d.ts.map +1 -1
  97. package/types/rules/indent/indent.d.ts.map +1 -1
  98. package/types/rules/lowercase.d.ts.map +1 -1
  99. package/types/rules/max-element-depth.d.ts.map +1 -1
  100. package/types/rules/no-abstract-roles.d.ts.map +1 -1
  101. package/types/rules/no-accesskey-attrs.d.ts.map +1 -1
  102. package/types/rules/no-aria-hidden-body.d.ts.map +1 -1
  103. package/types/rules/no-aria-hidden-on-focusable.d.ts.map +1 -1
  104. package/types/rules/no-duplicate-attrs.d.ts.map +1 -1
  105. package/types/rules/no-duplicate-class.d.ts.map +1 -1
  106. package/types/rules/no-duplicate-id.d.ts.map +1 -1
  107. package/types/rules/no-duplicate-in-head.d.ts.map +1 -1
  108. package/types/rules/no-empty-headings.d.ts.map +1 -1
  109. package/types/rules/no-extra-spacing-attrs.d.ts.map +1 -1
  110. package/types/rules/no-extra-spacing-text.d.ts.map +1 -1
  111. package/types/rules/no-heading-inside-button.d.ts.map +1 -1
  112. package/types/rules/no-ineffective-attrs.d.ts.map +1 -1
  113. package/types/rules/no-inline-styles.d.ts.map +1 -1
  114. package/types/rules/no-invalid-entity.d.ts.map +1 -1
  115. package/types/rules/no-invalid-role.d.ts.map +1 -1
  116. package/types/rules/no-multiple-empty-lines.d.ts.map +1 -1
  117. package/types/rules/no-multiple-h1.d.ts.map +1 -1
  118. package/types/rules/no-nested-interactive.d.ts.map +1 -1
  119. package/types/rules/no-non-scalable-viewport.d.ts.map +1 -1
  120. package/types/rules/no-obsolete-attrs.d.ts +4 -0
  121. package/types/rules/no-obsolete-attrs.d.ts.map +1 -0
  122. package/types/rules/no-obsolete-tags.d.ts.map +1 -1
  123. package/types/rules/no-positive-tabindex.d.ts.map +1 -1
  124. package/types/rules/no-restricted-attr-values.d.ts.map +1 -1
  125. package/types/rules/no-restricted-attrs.d.ts.map +1 -1
  126. package/types/rules/no-restricted-tags.d.ts.map +1 -1
  127. package/types/rules/no-script-style-type.d.ts.map +1 -1
  128. package/types/rules/no-skip-heading-levels.d.ts.map +1 -1
  129. package/types/rules/no-target-blank.d.ts.map +1 -1
  130. package/types/rules/no-trailing-spaces.d.ts.map +1 -1
  131. package/types/rules/no-whitespace-only-children.d.ts +6 -0
  132. package/types/rules/no-whitespace-only-children.d.ts.map +1 -0
  133. package/types/rules/prefer-https.d.ts.map +1 -1
  134. package/types/rules/quotes.d.ts.map +1 -1
  135. package/types/rules/require-attrs.d.ts.map +1 -1
  136. package/types/rules/require-button-type.d.ts.map +1 -1
  137. package/types/rules/require-closing-tags.d.ts.map +1 -1
  138. package/types/rules/require-doctype.d.ts.map +1 -1
  139. package/types/rules/require-explicit-size.d.ts.map +1 -1
  140. package/types/rules/require-form-method.d.ts.map +1 -1
  141. package/types/rules/require-frame-title.d.ts.map +1 -1
  142. package/types/rules/require-img-alt.d.ts.map +1 -1
  143. package/types/rules/require-input-label.d.ts.map +1 -1
  144. package/types/rules/require-lang.d.ts.map +1 -1
  145. package/types/rules/require-li-container.d.ts.map +1 -1
  146. package/types/rules/require-meta-charset.d.ts.map +1 -1
  147. package/types/rules/require-meta-description.d.ts.map +1 -1
  148. package/types/rules/require-meta-viewport.d.ts.map +1 -1
  149. package/types/rules/require-open-graph-protocol.d.ts.map +1 -1
  150. package/types/rules/require-title.d.ts.map +1 -1
  151. package/types/rules/sort-attrs.d.ts.map +1 -1
  152. package/types/rules/use-baseline.d.ts.map +1 -1
  153. package/types/rules/utils/baseline.d.ts +1 -3
  154. package/types/rules/utils/baseline.d.ts.map +1 -1
  155. package/types/rules/utils/naming.d.ts +14 -7
  156. package/types/rules/utils/naming.d.ts.map +1 -1
  157. package/types/rules/utils/node.d.ts +11 -10
  158. package/types/rules/utils/node.d.ts.map +1 -1
  159. package/types/rules/utils/rule.d.ts +1 -4
  160. package/types/rules/utils/rule.d.ts.map +1 -1
  161. package/types/rules/utils/settings.d.ts +0 -1
  162. package/types/rules/utils/settings.d.ts.map +1 -1
  163. package/types/rules/utils/source-code.d.ts +2 -6
  164. package/types/rules/utils/source-code.d.ts.map +1 -1
  165. package/types/rules/utils/template-literal.d.ts +2 -1
  166. package/types/rules/utils/template-literal.d.ts.map +1 -1
  167. package/types/rules/utils/visitors.d.ts.map +1 -1
  168. package/types/specs/index.d.ts +3 -0
  169. package/types/specs/index.d.ts.map +1 -0
  170. package/types/specs/obsolete-attrs.d.ts +19 -0
  171. package/types/specs/obsolete-attrs.d.ts.map +1 -0
  172. package/types/types/ast.d.ts +5 -2
  173. package/types/types/ast.d.ts.map +1 -1
@@ -1,8 +1,16 @@
1
1
  /**
2
- * @import {StyleTag, Attribute, Tag, ScriptTag} from "@html-eslint/types";
3
- * @import {RuleModule} from "../types";
4
- * @typedef {{tagPatterns: string[], attrPatterns: string[], message?: string}[]} Options
5
- *
2
+ * @import {
3
+ * Attribute,
4
+ * ScriptTag,
5
+ * StyleTag,
6
+ * Tag
7
+ * } from "@html-eslint/types"
8
+ * @import {RuleModule} from "../types"
9
+ * @typedef {{
10
+ * tagPatterns: string[];
11
+ * attrPatterns: string[];
12
+ * message?: string;
13
+ * }[]} Options
6
14
  */
7
15
 
8
16
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -14,9 +22,7 @@ const MESSAGE_IDS = {
14
22
  RESTRICTED: "restricted",
15
23
  };
16
24
 
17
- /**
18
- * @type {RuleModule<Options>}
19
- */
25
+ /** @type {RuleModule<Options>} */
20
26
  module.exports = {
21
27
  meta: {
22
28
  type: "code",
@@ -61,15 +67,11 @@ module.exports = {
61
67
  },
62
68
 
63
69
  create(context) {
64
- /**
65
- * @type {Options}
66
- */
70
+ /** @type {Options} */
67
71
  const options = context.options;
68
72
  const checkers = options.map((option) => new PatternChecker(option));
69
73
 
70
- /**
71
- * @param {Tag | StyleTag | ScriptTag} node
72
- */
74
+ /** @param {Tag | StyleTag | ScriptTag} node */
73
75
  function check(node) {
74
76
  const tagName =
75
77
  node.type === NODE_TYPES.Tag
@@ -89,9 +91,7 @@ module.exports = {
89
91
  return;
90
92
  }
91
93
 
92
- /**
93
- * @type {{node: Attribute, message: string, messageId?: string}}
94
- */
94
+ /** @type {{ node: Attribute; message: string; messageId?: string }} */
95
95
  const result = {
96
96
  node: attr,
97
97
  message: "",
@@ -121,9 +121,7 @@ module.exports = {
121
121
  };
122
122
 
123
123
  class PatternChecker {
124
- /**
125
- * @param {Options[number]} option
126
- */
124
+ /** @param {Options[number]} option */
127
125
  constructor(option) {
128
126
  this.option = option;
129
127
  this.tagRegExps = option.tagPatterns.map(
@@ -147,9 +145,7 @@ class PatternChecker {
147
145
  return result;
148
146
  }
149
147
 
150
- /**
151
- * @returns {string}
152
- */
148
+ /** @returns {string} */
153
149
  getMessage() {
154
150
  return this.message || "";
155
151
  }
@@ -1,8 +1,11 @@
1
1
  /**
2
- * @import {StyleTag, Tag, ScriptTag} from "@html-eslint/types";
3
- * @import {RuleModule} from "../types";
4
- * @typedef {{tagPatterns: string[], message?: string}[]} Options
5
- *
2
+ * @import {
3
+ * ScriptTag,
4
+ * StyleTag,
5
+ * Tag
6
+ * } from "@html-eslint/types"
7
+ * @import {RuleModule} from "../types"
8
+ * @typedef {{ tagPatterns: string[]; message?: string }[]} Options
6
9
  */
7
10
 
8
11
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -14,9 +17,7 @@ const MESSAGE_IDS = {
14
17
  RESTRICTED: "restricted",
15
18
  };
16
19
 
17
- /**
18
- * @type {RuleModule<Options>}
19
- */
20
+ /** @type {RuleModule<Options>} */
20
21
  module.exports = {
21
22
  meta: {
22
23
  type: "code",
@@ -55,15 +56,11 @@ module.exports = {
55
56
  },
56
57
 
57
58
  create(context) {
58
- /**
59
- * @type {Options}
60
- */
59
+ /** @type {Options} */
61
60
  const options = context.options;
62
61
  const checkers = options.map((option) => new PatternChecker(option));
63
62
 
64
- /**
65
- * @param {Tag | StyleTag | ScriptTag} node
66
- */
63
+ /** @param {Tag | StyleTag | ScriptTag} node */
67
64
  function check(node) {
68
65
  const tagName =
69
66
  node.type === NODE_TYPES.Tag
@@ -79,7 +76,11 @@ module.exports = {
79
76
  }
80
77
 
81
78
  /**
82
- * @type {{node: Tag | StyleTag | ScriptTag, message: string, messageId?: string}}
79
+ * @type {{
80
+ * node: Tag | StyleTag | ScriptTag;
81
+ * message: string;
82
+ * messageId?: string;
83
+ * }}
83
84
  */
84
85
  const result = {
85
86
  node: node,
@@ -109,9 +110,7 @@ module.exports = {
109
110
  };
110
111
 
111
112
  class PatternChecker {
112
- /**
113
- * @param {Options[number]} option
114
- */
113
+ /** @param {Options[number]} option */
115
114
  constructor(option) {
116
115
  this.option = option;
117
116
  this.tagRegExps = option.tagPatterns.map(
@@ -129,9 +128,7 @@ class PatternChecker {
129
128
  return result;
130
129
  }
131
130
 
132
- /**
133
- * @returns {string}
134
- */
131
+ /** @returns {string} */
135
132
  getMessage() {
136
133
  return this.message || "";
137
134
  }
@@ -1,6 +1,10 @@
1
1
  /**
2
- * @import {RuleModule} from "../types";
3
- * @import {StyleTag, Tag, ScriptTag} from "@html-eslint/types";
2
+ * @import {
3
+ * ScriptTag,
4
+ * StyleTag,
5
+ * Tag
6
+ * } from "@html-eslint/types"
7
+ * @import {RuleModule} from "../types"
4
8
  */
5
9
 
6
10
  const { RULE_CATEGORY } = require("../constants");
@@ -12,9 +16,7 @@ const MESSAGE_IDS = {
12
16
  UNNECESSARY: "unnecessary",
13
17
  };
14
18
 
15
- /**
16
- * @type {RuleModule<[]>}
17
- */
19
+ /** @type {RuleModule<[]>} */
18
20
  module.exports = {
19
21
  meta: {
20
22
  type: "code",
@@ -36,7 +38,6 @@ module.exports = {
36
38
 
37
39
  create(context) {
38
40
  /**
39
- *
40
41
  * @param {ScriptTag | Tag | StyleTag} node
41
42
  * @param {string} unnecessaryValue
42
43
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @import {RuleModule} from "../types";
3
- * @import {Tag} from "@html-eslint/types";
2
+ * @import {Tag} from "@html-eslint/types"
3
+ * @import {RuleModule} from "../types"
4
4
  */
5
5
 
6
6
  const { RULE_CATEGORY } = require("../constants");
@@ -10,9 +10,7 @@ const MESSAGE_IDS = {
10
10
  UNEXPECTED: "unexpected",
11
11
  };
12
12
 
13
- /**
14
- * @type {RuleModule<[]>}
15
- */
13
+ /** @type {RuleModule<[]>} */
16
14
  module.exports = {
17
15
  meta: {
18
16
  type: "code",
@@ -33,9 +31,7 @@ module.exports = {
33
31
  },
34
32
 
35
33
  create(context) {
36
- /**
37
- * @type {{node: Tag; level: number}[]}
38
- */
34
+ /** @type {{ node: Tag; level: number }[]} */
39
35
  const headings = [];
40
36
 
41
37
  return {
@@ -1,6 +1,4 @@
1
- /**
2
- * @import {RuleModule} from "../types";
3
- */
1
+ /** @import {RuleModule} from "../types" */
4
2
 
5
3
  const { RULE_CATEGORY } = require("../constants");
6
4
  const { findAttr } = require("./utils/node");
@@ -11,9 +9,7 @@ const MESSAGE_IDS = {
11
9
  MISSING: "missing",
12
10
  };
13
11
 
14
- /**
15
- * @type {RuleModule<[]>}
16
- */
12
+ /** @type {RuleModule<[]>} */
17
13
  module.exports = {
18
14
  meta: {
19
15
  type: "code",
@@ -35,6 +31,7 @@ module.exports = {
35
31
  create(context) {
36
32
  /**
37
33
  * Checks whether a link is an external link or not.
34
+ *
38
35
  * @param {string} link A link to check
39
36
  * @returns {boolean}
40
37
  */
@@ -1,6 +1,9 @@
1
1
  /**
2
- * @import {RuleModule} from "../types";
3
- * @import {CommentContent, Text} from "@html-eslint/types";
2
+ * @import {
3
+ * CommentContent,
4
+ * Text
5
+ * } from "@html-eslint/types"
6
+ * @import {RuleModule} from "../types"
4
7
  */
5
8
 
6
9
  const { parseTemplateLiteral } = require("./utils/template-literal");
@@ -21,9 +24,7 @@ const MESSAGE_IDS = {
21
24
  TRAILING_SPACE: "trailingSpace",
22
25
  };
23
26
 
24
- /**
25
- * @type {RuleModule<[]>}
26
- */
27
+ /** @type {RuleModule<[]>} */
27
28
  module.exports = {
28
29
  meta: {
29
30
  type: "layout",
@@ -49,7 +50,7 @@ module.exports = {
49
50
  * @param {number} offset.range
50
51
  * @param {number} offset.line
51
52
  * @param {number} offset.column
52
- * @param {((CommentContent | Text)['parts'][number])[]} tokens
53
+ * @param {(CommentContent | Text)["parts"][number][]} tokens
53
54
  */
54
55
  function check(source, lines, offset, tokens) {
55
56
  const lineBreaks = source.match(/\r\n|[\r\n\u2028\u2029]/gu);
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @import {
3
+ * Tag,
4
+ * Text
5
+ * } from "@html-eslint/types"
6
+ * @import {RuleModule} from "../types"
7
+ */
8
+
9
+ const { RULE_CATEGORY } = require("../constants");
10
+ const { isText, isComment, getLocBetween } = require("./utils/node");
11
+ const { createVisitors } = require("./utils/visitors");
12
+ const { getRuleUrl } = require("./utils/rule");
13
+
14
+ const MESSAGE_IDS = {
15
+ WHITESPACE_ONLY_CHILDREN: "whitespaceOnlyChildren",
16
+ };
17
+
18
+ /** @param {Tag} node */
19
+ function hasOnlyWhitespaceChildren(node) {
20
+ if (!node.children || node.children.length === 0) {
21
+ return false;
22
+ }
23
+
24
+ if (node.children.every((child) => isComment(child))) {
25
+ return false;
26
+ }
27
+
28
+ for (const child of node.children) {
29
+ if (isComment(child)) {
30
+ continue;
31
+ }
32
+ if (isText(child)) {
33
+ // Check if text contains any non-whitespace characters
34
+ if (child.value && child.value.trim().length > 0) {
35
+ return false;
36
+ }
37
+ } else {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ return true;
43
+ }
44
+
45
+ /** @type {RuleModule<[{ tagPatterns?: string[] }]>} */
46
+ module.exports = {
47
+ meta: {
48
+ type: "code",
49
+ docs: {
50
+ description: "Disallow tags with only whitespace children.",
51
+ recommended: false,
52
+ category: RULE_CATEGORY.BEST_PRACTICE,
53
+ url: getRuleUrl("no-whitespace-only-children"),
54
+ },
55
+ fixable: "whitespace",
56
+ schema: [
57
+ {
58
+ type: "object",
59
+ properties: {
60
+ tagPatterns: {
61
+ type: "array",
62
+ items: {
63
+ type: "string",
64
+ },
65
+ },
66
+ },
67
+ additionalProperties: false,
68
+ },
69
+ ],
70
+ messages: {
71
+ [MESSAGE_IDS.WHITESPACE_ONLY_CHILDREN]:
72
+ "Tag should not have only whitespace children.",
73
+ },
74
+ },
75
+ create(context) {
76
+ const options = context.options[0] || {};
77
+ const tagPatterns = (options.tagPatterns || []).map(
78
+ (pattern) => new RegExp(pattern, "u")
79
+ );
80
+
81
+ return createVisitors(context, {
82
+ Tag(node) {
83
+ if (!node.close) {
84
+ return;
85
+ }
86
+ if (tagPatterns.length <= 0) {
87
+ return;
88
+ }
89
+
90
+ const tagName = node.name.toLowerCase();
91
+
92
+ // If tagPatterns is specified, check if tag name matches any pattern
93
+ const matches = tagPatterns.some((pattern) => pattern.test(tagName));
94
+ if (!matches) {
95
+ return;
96
+ }
97
+
98
+ if (hasOnlyWhitespaceChildren(node)) {
99
+ const loc = getLocBetween(node.openEnd, node.close);
100
+ context.report({
101
+ loc,
102
+ messageId: MESSAGE_IDS.WHITESPACE_ONLY_CHILDREN,
103
+ fix(fixer) {
104
+ return node.children
105
+ .filter((child) => isText(child))
106
+ .map((child) => fixer.removeRange(child.range));
107
+ },
108
+ });
109
+ }
110
+ },
111
+ });
112
+ },
113
+ };
@@ -1,6 +1,11 @@
1
1
  /**
2
- * @import {Tag, ScriptTag, Attribute, AttributeValue} from "@html-eslint/types";
3
- * @import {RuleModule} from "../types";
2
+ * @import {
3
+ * Attribute,
4
+ * AttributeValue,
5
+ * ScriptTag,
6
+ * Tag
7
+ * } from "@html-eslint/types"
8
+ * @import {RuleModule} from "../types"
4
9
  */
5
10
 
6
11
  const { RULE_CATEGORY } = require("../constants");
@@ -12,9 +17,7 @@ const MESSAGE_IDS = {
12
17
  UNEXPECTED: "unexpected",
13
18
  };
14
19
 
15
- /**
16
- * @param {string} url
17
- */
20
+ /** @param {string} url */
18
21
  function getProtocol(url) {
19
22
  try {
20
23
  return new URL(url).protocol;
@@ -29,9 +32,7 @@ function getProtocol(url) {
29
32
  * @returns {AttributeValue | undefined}
30
33
  */
31
34
  function getResourceAttributeValue(node) {
32
- /**
33
- * @type {Attribute | undefined}
34
- */
35
+ /** @type {Attribute | undefined} */
35
36
  let attribute;
36
37
  if (isScript(node)) {
37
38
  attribute = findAttr(node, "src");
@@ -62,9 +63,7 @@ function getResourceAttributeValue(node) {
62
63
  return undefined;
63
64
  }
64
65
 
65
- /**
66
- * @type {RuleModule<[]>}
67
- */
66
+ /** @type {RuleModule<[]>} */
68
67
  module.exports = {
69
68
  meta: {
70
69
  type: "code",
@@ -82,9 +81,7 @@ module.exports = {
82
81
  },
83
82
 
84
83
  create(context) {
85
- /**
86
- * @param {Tag | ScriptTag} node
87
- */
84
+ /** @param {Tag | ScriptTag} node */
88
85
  function check(node) {
89
86
  const attributeValue = getResourceAttributeValue(node);
90
87
  if (attributeValue && !attributeValue.parts.length) {
@@ -1,10 +1,15 @@
1
1
  /**
2
- * @import {AST} from "eslint";
3
- * @import {Attribute, Tag, ScriptTag, StyleTag} from "@html-eslint/types";
4
- * @import {RuleModule} from "../types";
5
- *
2
+ * @import {
3
+ * Attribute,
4
+ * ScriptTag,
5
+ * StyleTag,
6
+ * Tag
7
+ * } from "@html-eslint/types"
8
+ * @import {AST} from "eslint"
9
+ * @import {RuleModule} from "../types"
6
10
  * @typedef {"single" | "double"} SingleOrQuoteOption
7
- * @typedef {{enforceTemplatedAttrValue: boolean}} ObjectOption
11
+ *
12
+ * @typedef {{ enforceTemplatedAttrValue: boolean }} ObjectOption
8
13
  */
9
14
 
10
15
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -25,9 +30,7 @@ const QUOTES_STYLES = {
25
30
 
26
31
  const QUOTES_CODES = [`"`, `'`];
27
32
 
28
- /**
29
- * @type {RuleModule<[SingleOrQuoteOption, ObjectOption]>}
30
- */
33
+ /** @type {RuleModule<[SingleOrQuoteOption, ObjectOption]>} */
31
34
  module.exports = {
32
35
  meta: {
33
36
  type: "code",
@@ -85,7 +88,6 @@ module.exports = {
85
88
  }
86
89
 
87
90
  /**
88
- *
89
91
  * @param {Attribute} attr
90
92
  * @returns {[string, string]}
91
93
  */
@@ -102,10 +104,7 @@ module.exports = {
102
104
  if (!attr.value || attr.value.value.includes(expectedQuote)) {
103
105
  return;
104
106
  }
105
- /**
106
- * Allow template expression.
107
- * ex: html`<div foo=${foo}></div>`
108
- */
107
+ /** Allow template expression. ex: html`<div foo=${foo}></div>` */
109
108
  if (
110
109
  !enforceTemplatedAttrValue &&
111
110
  attr.value.parts.some((part) => part.type === NODE_TYPES.Template)
@@ -160,9 +159,7 @@ module.exports = {
160
159
  });
161
160
  }
162
161
  }
163
- /**
164
- * @param {Tag | ScriptTag | StyleTag} node
165
- */
162
+ /** @param {Tag | ScriptTag | StyleTag} node */
166
163
  function check(node) {
167
164
  node.attributes.forEach((attr) => checkQuotes(attr));
168
165
  }
@@ -1,13 +1,19 @@
1
1
  /**
2
- * @import {Tag, ScriptTag, StyleTag, Attribute} from "@html-eslint/types";
3
- * @import {RuleModule, ReportFixFunction} from "../types";
4
- *
2
+ * @import {
3
+ * Attribute,
4
+ * ScriptTag,
5
+ * StyleTag,
6
+ * Tag
7
+ * } from "@html-eslint/types"
8
+ * @import {
9
+ * ReportFixFunction,
10
+ * RuleModule
11
+ * } from "../types"
5
12
  * @typedef {Object} Option
6
13
  * @property {string} tag
7
14
  * @property {string} attr
8
15
  * @property {string} [value]
9
16
  * @property {string} [message]
10
- *
11
17
  */
12
18
 
13
19
  const { NODE_TYPES } = require("@html-eslint/parser");
@@ -20,9 +26,7 @@ const MESSAGE_IDS = {
20
26
  UNEXPECTED: "unexpected",
21
27
  };
22
28
 
23
- /**
24
- * @type {RuleModule<Option[]>}
25
- */
29
+ /** @type {RuleModule<Option[]>} */
26
30
  module.exports = {
27
31
  meta: {
28
32
  type: "code",
@@ -56,12 +60,13 @@ module.exports = {
56
60
  },
57
61
 
58
62
  create(context) {
59
- /**
60
- * @type {Option[]}
61
- */
63
+ /** @type {Option[]} */
62
64
  const options = context.options || [];
63
65
  /**
64
- * @type {Map<string, { tag: string, attr: string, value?: string, message?: string}[]>}
66
+ * @type {Map<
67
+ * string,
68
+ * { tag: string; attr: string; value?: string; message?: string }[]
69
+ * >}
65
70
  */
66
71
  const tagOptionsMap = new Map();
67
72
 
@@ -137,9 +142,7 @@ module.exports = {
137
142
  });
138
143
  }
139
144
 
140
- /**
141
- * @param {StyleTag | ScriptTag} node
142
- */
145
+ /** @param {StyleTag | ScriptTag} node */
143
146
  function checkStyleOrScript(node) {
144
147
  const tagName = node.type === NODE_TYPES.StyleTag ? "style" : "script";
145
148
  if (!tagOptionsMap.has(tagName)) {
@@ -148,9 +151,7 @@ module.exports = {
148
151
  check(node, tagName);
149
152
  }
150
153
 
151
- /**
152
- * @param {Tag} node
153
- */
154
+ /** @param {Tag} node */
154
155
  function checkTag(node) {
155
156
  const tagName = node.name.toLowerCase();
156
157
  if (!tagOptionsMap.has(tagName)) {
@@ -1,6 +1,9 @@
1
1
  /**
2
- * @import {RuleModule, SuggestionReportDescriptor} from "../types";
3
- * @import {AttributeValue} from "@html-eslint/types";
2
+ * @import {AttributeValue} from "@html-eslint/types"
3
+ * @import {
4
+ * RuleModule,
5
+ * SuggestionReportDescriptor
6
+ * } from "../types"
4
7
  */
5
8
 
6
9
  const { RULE_CATEGORY } = require("../constants");
@@ -18,9 +21,7 @@ const MESSAGE_IDS = {
18
21
 
19
22
  const VALID_BUTTON_TYPES_SET = new Set(["submit", "button", "reset"]);
20
23
 
21
- /**
22
- * @type {RuleModule<[]>}
23
- */
24
+ /** @type {RuleModule<[]>} */
24
25
  module.exports = {
25
26
  meta: {
26
27
  type: "code",
@@ -1,7 +1,10 @@
1
1
  /**
2
- * @import {ScriptTag, StyleTag, Tag} from "@html-eslint/types";
3
- * @import {RuleModule} from "../types";
4
- *
2
+ * @import {
3
+ * ScriptTag,
4
+ * StyleTag,
5
+ * Tag
6
+ * } from "@html-eslint/types"
7
+ * @import {RuleModule} from "../types"
5
8
  * @typedef {Object} Option
6
9
  * @property {"always" | "never"} [Option.selfClosing]
7
10
  * @property {string[]} [Option.selfClosingCustomPatterns]
@@ -20,9 +23,7 @@ const MESSAGE_IDS = {
20
23
  UNEXPECTED: "unexpected",
21
24
  };
22
25
 
23
- /**
24
- * @type {RuleModule<[Option]>}
25
- */
26
+ /** @type {RuleModule<[Option]>} */
26
27
  module.exports = {
27
28
  meta: {
28
29
  type: "code",
@@ -76,9 +77,7 @@ module.exports = {
76
77
  (i) => new RegExp(i)
77
78
  );
78
79
 
79
- /**
80
- * @param {Tag | ScriptTag | StyleTag} node
81
- */
80
+ /** @param {Tag | ScriptTag | StyleTag} node */
82
81
  function checkClosing(node) {
83
82
  const name = getNameOf(node);
84
83
  if (!node.close) {
@@ -157,9 +156,7 @@ module.exports = {
157
156
  }
158
157
  if (["svg", "math"].includes(node.name)) foreignContext.push(node.name);
159
158
  },
160
- /**
161
- * @param {Tag} node
162
- */
159
+ /** @param {Tag} node */
163
160
  "Tag:exit"(node) {
164
161
  if (node.name === foreignContext[foreignContext.length - 1]) {
165
162
  foreignContext.pop();
@@ -1,6 +1,4 @@
1
- /**
2
- * @import {RuleModule} from "../types";
3
- */
1
+ /** @import {RuleModule} from "../types" */
4
2
 
5
3
  const { RULE_CATEGORY } = require("../constants");
6
4
  const { getRuleUrl } = require("./utils/rule");
@@ -9,9 +7,7 @@ const MESSAGE_IDS = {
9
7
  MISSING: "missing",
10
8
  };
11
9
 
12
- /**
13
- * @type {RuleModule<[]>}
14
- */
10
+ /** @type {RuleModule<[]>} */
15
11
  module.exports = {
16
12
  meta: {
17
13
  type: "code",
@@ -1,6 +1,5 @@
1
1
  /**
2
- * @import {RuleModule} from "../types";
3
- *
2
+ * @import {RuleModule} from "../types"
4
3
  * @typedef {Object} Option
5
4
  * @property {string[]} [Option.allowClass]
6
5
  * @property {string[]} [Option.allowId]
@@ -18,9 +17,7 @@ const MESSAGE_IDS = {
18
17
 
19
18
  const TARGET_ELEMENTS = ["img", "iframe"];
20
19
 
21
- /**
22
- * @type {RuleModule<[Option]>}
23
- */
20
+ /** @type {RuleModule<[Option]>} */
24
21
  module.exports = {
25
22
  meta: {
26
23
  type: "code",