Skip to content

Commit c9de444

Browse files
authored
fix: detect errors after comments in no-multiple-h1 and require-alt-text (#468)
1 parent 7c17d59 commit c9de444

File tree

7 files changed

+210
-10
lines changed

7 files changed

+210
-10
lines changed

src/rules/no-empty-definitions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
* @author Pixel998
44
*/
55

6+
//-----------------------------------------------------------------------------
7+
// Imports
8+
//-----------------------------------------------------------------------------
9+
10+
import { htmlCommentPattern } from "../util.js";
11+
612
//-----------------------------------------------------------------------------
713
// Type Definitions
814
//-----------------------------------------------------------------------------
@@ -18,8 +24,6 @@
1824
// Helpers
1925
//-----------------------------------------------------------------------------
2026

21-
const htmlCommentPattern = /<!--[\s\S]*?-->/gu;
22-
2327
/**
2428
* Checks if a string contains only HTML comments.
2529
* @param {string} value The input string to check.

src/rules/no-missing-link-fragments.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//-----------------------------------------------------------------------------
99

1010
import GithubSlugger from "github-slugger";
11+
import { htmlCommentPattern } from "../util.js";
1112

1213
//-----------------------------------------------------------------------------
1314
// Type Definitions
@@ -27,7 +28,6 @@ import GithubSlugger from "github-slugger";
2728

2829
const githubLineReferencePattern = /^L\d+(?:C\d+)?(?:-L\d+(?:C\d+)?)?$/u;
2930
const customHeadingIdPattern = /\{#([^}\s]+)\}\s*$/u;
30-
const htmlCommentPattern = /<!--[\s\S]*?-->/gu;
3131
const htmlIdNamePattern =
3232
/(?<!<)<(?:[^>]+)\s(?:id|name)\s*=\s*["']?([^"'\s>]+)["']?/giu;
3333

src/rules/no-multiple-h1.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
// Imports
88
//-----------------------------------------------------------------------------
99

10-
import { findOffsets, frontmatterHasTitle } from "../util.js";
10+
import {
11+
findOffsets,
12+
frontmatterHasTitle,
13+
stripHtmlComments,
14+
} from "../util.js";
1115

1216
//-----------------------------------------------------------------------------
1317
// Type Definitions
@@ -24,7 +28,7 @@ import { findOffsets, frontmatterHasTitle } from "../util.js";
2428
// Helpers
2529
//-----------------------------------------------------------------------------
2630

27-
const h1TagPattern = /(?<!<!--[\s\S]*?)<h1[^>]*>[\s\S]*?<\/h1>/giu;
31+
const h1TagPattern = /<h1[^>]*>[\s\S]*?<\/h1>/giu;
2832

2933
//-----------------------------------------------------------------------------
3034
// Rule Definition
@@ -91,8 +95,10 @@ export default {
9195
},
9296

9397
html(node) {
98+
const text = stripHtmlComments(node.value);
99+
94100
let match;
95-
while ((match = h1TagPattern.exec(node.value)) !== null) {
101+
while ((match = h1TagPattern.exec(text)) !== null) {
96102
h1Count++;
97103
if (h1Count > 1) {
98104
const {

src/rules/require-alt-text.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// Imports
88
//-----------------------------------------------------------------------------
99

10-
import { findOffsets } from "../util.js";
10+
import { findOffsets, stripHtmlComments } from "../util.js";
1111

1212
//-----------------------------------------------------------------------------
1313
// Type Definitions
@@ -24,7 +24,7 @@ import { findOffsets } from "../util.js";
2424
// Helpers
2525
//-----------------------------------------------------------------------------
2626

27-
const imgTagPattern = /(?<!<!--[\s\S]*?)<img[^>]*>/giu;
27+
const imgTagPattern = /<img[^>]*>/giu;
2828

2929
/**
3030
* Creates a regex to match HTML attributes
@@ -76,9 +76,10 @@ export default {
7676
},
7777

7878
html(node) {
79-
let match;
79+
const text = stripHtmlComments(node.value);
8080

81-
while ((match = imgTagPattern.exec(node.value)) !== null) {
81+
let match;
82+
while ((match = imgTagPattern.exec(text)) !== null) {
8283
const imgTag = match[0];
8384
const ariaHiddenMatch = imgTag.match(
8485
getHtmlAttributeRe("aria-hidden"),

src/util.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
*/
1111
export const illegalShorthandTailPattern = /\]\[\s+\]$/u;
1212

13+
/**
14+
* Regular expression to match HTML comments, including multiline comments.
15+
*/
16+
export const htmlCommentPattern = /<!--[\s\S]*?-->/gu;
17+
1318
/**
1419
* Finds the line and column offsets for a given offset in a string.
1520
* @param {string} text The text to search.
@@ -56,3 +61,14 @@ export function frontmatterHasTitle(value, pattern) {
5661
}
5762
return false;
5863
}
64+
65+
/**
66+
* Remove all HTML comments from a string.
67+
* @param {string} value The string to remove HTML comments from.
68+
* @returns {string} The string with HTML comments removed.
69+
*/
70+
export function stripHtmlComments(value) {
71+
return value.replace(htmlCommentPattern, match =>
72+
match.replace(/[^\n]/gu, " "),
73+
);
74+
}

tests/rules/no-multiple-h1.test.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,33 @@ ruleTester.run("no-multiple-h1", rule, {
351351
<!-- <h1>Commented Heading</h1> -->
352352
<!-- <h1>Commented Heading</h1> -->
353353
`,
354+
dedent`
355+
# Heading 1
356+
357+
<!--
358+
<h1>Commented Heading</h1>
359+
<p>Some text</p>
360+
-->
361+
`,
362+
dedent`
363+
# Heading 1
364+
Some text <!-- <h1>Commented</h1> --> more text.
365+
`,
366+
dedent`
367+
# Heading 1
368+
<!-- <h1>Comment with --- extra dashes</h1> -->
369+
`,
370+
dedent`
371+
# Heading 1
372+
<!--<h1>No spaces</h1>-->
373+
<!-- <h1>Extra spaces</h1> -->
374+
`,
375+
dedent`
376+
# Heading 1
377+
\`\`\`html
378+
<!-- <h1>Commented in code</h1> -->
379+
\`\`\`
380+
`,
354381
],
355382
invalid: [
356383
{
@@ -1097,5 +1124,83 @@ ruleTester.run("no-multiple-h1", rule, {
10971124
},
10981125
],
10991126
},
1127+
{
1128+
code: dedent`
1129+
<!-- <h1>Commented</h1> -->
1130+
<h1>Heading 1</h1>
1131+
<h1>Another H1</h1>
1132+
`,
1133+
errors: [
1134+
{
1135+
messageId: "multipleH1",
1136+
line: 3,
1137+
column: 1,
1138+
endLine: 3,
1139+
endColumn: 20,
1140+
},
1141+
],
1142+
},
1143+
{
1144+
code: dedent`
1145+
# Heading 1
1146+
<!-- <h1>Commented</h1> -->
1147+
<h1>Another H1</h1>
1148+
`,
1149+
errors: [
1150+
{
1151+
messageId: "multipleH1",
1152+
line: 3,
1153+
column: 1,
1154+
endLine: 3,
1155+
endColumn: 20,
1156+
},
1157+
],
1158+
},
1159+
{
1160+
code: dedent`
1161+
# Heading 1
1162+
<!- Not a valid comment ->
1163+
<h1>Another H1</h1>
1164+
`,
1165+
errors: [
1166+
{
1167+
messageId: "multipleH1",
1168+
line: 3,
1169+
column: 1,
1170+
endLine: 3,
1171+
endColumn: 20,
1172+
},
1173+
],
1174+
},
1175+
{
1176+
code: dedent`
1177+
# Heading 1
1178+
<!-- comment --> <h1>Another H1</h1>
1179+
`,
1180+
errors: [
1181+
{
1182+
messageId: "multipleH1",
1183+
line: 2,
1184+
column: 18,
1185+
endLine: 2,
1186+
endColumn: 37,
1187+
},
1188+
],
1189+
},
1190+
{
1191+
code: dedent`
1192+
<h1>Heading 1</h1>
1193+
<!-- comment --> <h1>Another H1</h1>
1194+
`,
1195+
errors: [
1196+
{
1197+
messageId: "multipleH1",
1198+
line: 2,
1199+
column: 18,
1200+
endLine: 2,
1201+
endColumn: 37,
1202+
},
1203+
],
1204+
},
11001205
],
11011206
});

tests/rules/require-alt-text.test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ ruleTester.run("require-alt-text", rule, {
4545
'<img src="image.png" ARIA-HIDDEN="TRUE" />',
4646
'<p><img src="image.png" alt="Descriptive text" /></p>',
4747
'<!-- <img src="image.png" /> -->',
48+
'Some text <!-- <img src="image.png" /> --> more text.',
49+
dedent`
50+
<!--
51+
<img src="image.png" />
52+
<p>Some text</p>
53+
-->
54+
`,
55+
dedent`
56+
<!--<img src="image.png" />-->
57+
<!-- <img src="image.png" /> -->
58+
`,
59+
dedent`
60+
\`\`\`html
61+
<img src="image.png" />
62+
\`\`\`
63+
`,
4864
],
4965
invalid: [
5066
{
@@ -240,5 +256,57 @@ ruleTester.run("require-alt-text", rule, {
240256
},
241257
],
242258
},
259+
{
260+
code: dedent`
261+
<!-- <img src="image.png" /> -->
262+
<img src="image.png" />
263+
`,
264+
errors: [
265+
{
266+
messageId: "altTextRequired",
267+
line: 2,
268+
column: 1,
269+
endLine: 2,
270+
endColumn: 24,
271+
},
272+
],
273+
},
274+
{
275+
code: dedent`
276+
<!- Not a valid comment ->
277+
<img src="image.png" />
278+
`,
279+
errors: [
280+
{
281+
messageId: "altTextRequired",
282+
line: 2,
283+
column: 1,
284+
endLine: 2,
285+
endColumn: 24,
286+
},
287+
],
288+
},
289+
{
290+
code: dedent`
291+
<img src="image.png" />
292+
<!-- comment --> <img src="image.png" />
293+
`,
294+
errors: [
295+
{
296+
messageId: "altTextRequired",
297+
line: 1,
298+
column: 1,
299+
endLine: 1,
300+
endColumn: 24,
301+
},
302+
{
303+
messageId: "altTextRequired",
304+
line: 2,
305+
column: 18,
306+
endLine: 2,
307+
endColumn: 41,
308+
},
309+
],
310+
},
243311
],
244312
});

0 commit comments

Comments
 (0)