Skip to content

Commit a861b7d

Browse files
authored
Improve image validation (#561)
* Disable image checks for badges and vector graphics * Simplify CSS width/height checking logic + improve error message
1 parent bd63856 commit a861b7d

File tree

2 files changed

+20
-58
lines changed

2 files changed

+20
-58
lines changed

website/.validationignore

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -82,41 +82,6 @@
8282
/docs/organization.mdx
8383
/docs/purchase.mdx
8484
/docs/requests.mdx
85-
/docs/sdk-reference/android.mdx
86-
/docs/sdk-reference/community/deno.mdx
87-
/docs/sdk-reference/community/laravel.mdx
88-
/docs/sdk-reference/community/vue.mdx
89-
/docs/sdk-reference/cpp.mdx
90-
/docs/sdk-reference/dart.mdx
91-
/docs/sdk-reference/dotnet.mdx
92-
/docs/sdk-reference/elixir.mdx
93-
/docs/sdk-reference/go.mdx
94-
/docs/sdk-reference/ios.mdx
95-
/docs/sdk-reference/java.mdx
96-
/docs/sdk-reference/js-ssr.mdx
97-
/docs/sdk-reference/js.mdx
98-
/docs/sdk-reference/kotlin.mdx
99-
/docs/sdk-reference/node.mdx
100-
/docs/sdk-reference/openfeature/dotnet.mdx
101-
/docs/sdk-reference/openfeature/go.mdx
102-
/docs/sdk-reference/openfeature/java.mdx
103-
/docs/sdk-reference/openfeature/js.mdx
104-
/docs/sdk-reference/openfeature/node.mdx
105-
/docs/sdk-reference/openfeature/overview.mdx
106-
/docs/sdk-reference/openfeature/php.mdx
107-
/docs/sdk-reference/openfeature/python.mdx
108-
/docs/sdk-reference/openfeature/rust.mdx
109-
/docs/sdk-reference/openfeature/ruby.mdx
110-
/docs/sdk-reference/openfeature/swift.mdx
111-
/docs/sdk-reference/openfeature/kotlin.mdx
112-
/docs/sdk-reference/overview.mdx
113-
/docs/sdk-reference/php.mdx
114-
/docs/sdk-reference/python.mdx
115-
/docs/sdk-reference/react.mdx
116-
/docs/sdk-reference/ruby.mdx
117-
/docs/sdk-reference/rust.mdx
118-
/docs/sdk-reference/unity.mdx
119-
/docs/sdk-reference/unreal.mdx
12085
/docs/service/status.mdx
12186
/docs/subscription-plan-limits.mdx
12287
/docs/targeting/feature-flag-evaluation.mdx

website/validate-document.js

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,12 @@ const checkImageDimensions = async (imageTag, imagePath, cssWidth, cssHeight, dp
4949

5050
const { width, height } = imageMetaData;
5151

52-
if (cssWidth != null) {
53-
const factor = dpi / 96;
54-
const expectedWidth = cssWidth * factor;
55-
// NOTE: We need to account for the integer division used to calculate the value of the `width` attribute.
56-
if (width < expectedWidth || expectedWidth + factor <= width) {
57-
errors.push(['warn', `Horizontal image resolution doesn't correspond to attribute (width="...") in ${imageTag}. The image should be ${expectedWidth} pixels wide, considering the image DPI (${dpi}).`]);
58-
}
52+
if (cssWidth != null && cssWidth !== Math.trunc(width * 96 / dpi)) {
53+
errors.push(['warn', `The relation \`CSS width = image width in pixels * 96 / DPI\` is not satisfied. CSS width specified via attribute (width="...") = ${cssWidth}, image width in pixels = ${width}, DPI = ${dpi}.`]);
5954
}
6055

61-
if (cssHeight != null) {
62-
const factor = dpi / 96;
63-
const expectedHeight = cssHeight * factor;
64-
// NOTE: We need to account for the integer division used to calculate the value of the `height` attribute.
65-
if (height < expectedHeight || expectedHeight + factor <= height) {
66-
errors.push(['warn', `Vertical image resolution doesn't correspond to attribute (height="...") in ${imageTag}. The image should be ${expectedHeight} pixels tall, considering the image DPI (${dpi}).`]);
67-
}
56+
if (cssHeight != null && cssHeight !== Math.trunc(height * 96 / dpi)) {
57+
errors.push(['warn', `The relation \`CSS height = image height in pixels * 96 / DPI\` is not satisfied. CSS height specified via attribute (height="...") = ${cssHeight}, image height in pixels = ${height}, DPI = ${dpi}.`]);
6858
}
6959
}
7060

@@ -114,23 +104,24 @@ const checkImages = async (content) => {
114104
const errors = [];
115105

116106
let i = -1;
117-
for (const tag of extractImageData(content)) {
107+
for (const [tag, mdImageSrc] of extractImageData(content)) {
118108
i++;
119109

120110
const isMarkdown = tag.startsWith('![');
121-
if (isMarkdown) {
122-
// Markdown image detected
123-
errors.push(['warn', `Markdown image syntax found (${tag}). Use <img src="..." alt="..." width="..." height="..." /> instead for images.`]);
111+
if (isMarkdown) { // Markdown image detected
112+
if (shouldCheckImage(mdImageSrc)) {
113+
errors.push(['warn', `Markdown image syntax found (${tag}). Use <img src="..." alt="..." width="..." height="..." /> instead for images.`]);
114+
}
124115
continue;
125116
}
126117

127118
let [imageSrc, cssWidth, cssHeight] = checkForImageAttributes(tag, errors);
128119

129120
const pathPrefix = "/docs/"
130-
if (imageSrc.startsWith(pathPrefix)) {
131-
imageSrc = imageSrc.substring(pathPrefix.length - 1);
132-
} else if (/^https?:/i.test(imageSrc)) {
121+
if (!shouldCheckImage(imageSrc)) {
133122
continue;
123+
} else if (imageSrc.startsWith(pathPrefix)) {
124+
imageSrc = imageSrc.substring(pathPrefix.length - 1);
134125
} else {
135126
errors.push(`Invalid image src found in ${tag}`);
136127
continue;
@@ -222,13 +213,19 @@ function attributeRegex(attribute) {
222213
function* extractImageData(content) {
223214
let imageTagsRegexMatch;
224215
while ((imageTagsRegexMatch = imageTagsRegex.exec(content)) !== null) {
225-
const [tag] = imageTagsRegexMatch;
226-
yield tag;
216+
const [tag, , mdImageSrc] = imageTagsRegexMatch;
217+
yield [tag, mdImageSrc?.trim()];
227218
}
228219
}
229220

230221
function getImageFullPath(imagePath) {
231222
return path.join(__dirname, 'static', imagePath);
232223
}
233224

225+
function shouldCheckImage(imageSrc) {
226+
if (/^https?:/i.test(imageSrc)) return false;
227+
if (path.extname(imageSrc).toLowerCase() === ".svg") return false;
228+
return true;
229+
}
230+
234231
checkFiles();

0 commit comments

Comments
 (0)