Skip to content

Commit 41ae6c8

Browse files
authored
fix: add null check and use getLocFromIndex in require-alt-text (#543)
* wip * wip: fix crash * wip * wip
1 parent 1bd528f commit 41ae6c8

File tree

2 files changed

+16
-43
lines changed

2 files changed

+16
-43
lines changed

src/rules/require-alt-text.js

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
// Imports
88
//-----------------------------------------------------------------------------
99

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

1212
//-----------------------------------------------------------------------------
1313
// Type Definitions
1414
//-----------------------------------------------------------------------------
1515

1616
/**
17+
* @import { Image, ImageReference } from "mdast";
1718
* @import { MarkdownRuleDefinition } from "../types.js";
1819
* @typedef {"altTextRequired"} RequireAltTextMessageIds
1920
* @typedef {[]} RequireAltTextOptions
@@ -56,17 +57,12 @@ export default {
5657
},
5758

5859
create(context) {
59-
return {
60-
image(node) {
61-
if (node.alt.trim().length === 0) {
62-
context.report({
63-
loc: node.position,
64-
messageId: "altTextRequired",
65-
});
66-
}
67-
},
60+
const { sourceCode } = context;
6861

69-
imageReference(node) {
62+
return {
63+
"image, imageReference"(
64+
/** @type {Image | ImageReference} */ node,
65+
) {
7066
if (node.alt.trim().length === 0) {
7167
context.report({
7268
loc: node.position,
@@ -78,14 +74,17 @@ export default {
7874
html(node) {
7975
const text = stripHtmlComments(node.value);
8076

77+
/** @type {RegExpExecArray} */
8178
let match;
79+
8280
while ((match = imgTagPattern.exec(text)) !== null) {
8381
const imgTag = match[0];
8482
const ariaHiddenMatch = imgTag.match(
8583
getHtmlAttributeRe("aria-hidden"),
8684
);
8785
if (
8886
ariaHiddenMatch &&
87+
ariaHiddenMatch[1] &&
8988
ariaHiddenMatch[1].toLowerCase() === "true"
9089
) {
9190
continue;
@@ -98,41 +97,14 @@ export default {
9897
altMatch[1].trim().length === 0 &&
9998
altMatch[1].length > 0)
10099
) {
101-
const {
102-
lineOffset: startLineOffset,
103-
columnOffset: startColumnOffset,
104-
} = findOffsets(node.value, match.index);
105-
106-
const {
107-
lineOffset: endLineOffset,
108-
columnOffset: endColumnOffset,
109-
} = findOffsets(
110-
node.value,
111-
match.index + imgTag.length,
112-
);
113-
114-
const nodeStartLine = node.position.start.line;
115-
const nodeStartColumn = node.position.start.column;
116-
const startLine = nodeStartLine + startLineOffset;
117-
const endLine = nodeStartLine + endLineOffset;
118-
const startColumn =
119-
(startLine === nodeStartLine
120-
? nodeStartColumn
121-
: 1) + startColumnOffset;
122-
const endColumn =
123-
(endLine === nodeStartLine ? nodeStartColumn : 1) +
124-
endColumnOffset;
100+
const startOffset = // Adjust `imgTagPattern` match indices to the full source code.
101+
match.index + node.position.start.offset;
102+
const endOffset = startOffset + imgTag.length;
125103

126104
context.report({
127105
loc: {
128-
start: {
129-
line: startLine,
130-
column: startColumn,
131-
},
132-
end: {
133-
line: endLine,
134-
column: endColumn,
135-
},
106+
start: sourceCode.getLocFromIndex(startOffset),
107+
end: sourceCode.getLocFromIndex(endOffset),
136108
},
137109
messageId: "altTextRequired",
138110
});

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ ruleTester.run("require-alt-text", rule, {
4141
'<img src="image.png" alt="" />',
4242
"<img src=\"image.png\" alt='' />",
4343
'<IMG SRC="image.png" ALT="Descriptive text"/>',
44+
'<img src="image.png" aria-hidden alt="alt">',
4445
'<img src="image.png" aria-hidden="true"/>',
4546
'<img src="image.png" ARIA-HIDDEN="TRUE" />',
4647
'<p><img src="image.png" alt="Descriptive text" /></p>',

0 commit comments

Comments
 (0)