Skip to content

Commit 37cc21f

Browse files
anotherjamesDSchau
authored andcommitted
fix(gatsby-remark-images): ensure query string is ignored when detecting images (#11743)
## Description Referencing an image in markdown like this: ``` ![Alt text](../path/to/image.png?raw=true) ``` Does not load the image. This PR uses `query-string` to parse the URL out of the path. ## Related Issues (No issue opened yet.) This is my first PR, I hope it's ok!
1 parent 930164a commit 37cc21f

File tree

4 files changed

+92
-5
lines changed

4 files changed

+92
-5
lines changed

packages/gatsby-remark-images/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"is-relative-url": "^2.0.0",
1313
"lodash": "^4.17.10",
1414
"mdast-util-definitions": "^1.2.0",
15+
"query-string": "^6.1.0",
1516
"slash": "^1.0.0",
1617
"unist-util-select": "^1.5.0",
1718
"unist-util-visit-parents": "^2.0.1"

packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,41 @@ exports[`it transforms images in markdown 1`] = `
124124
</span>
125125
</a>"
126126
`;
127+
128+
exports[`it transforms HTML img tags with query strings 1`] = `
129+
"<a class=\\"gatsby-resp-image-link\\" href=\\"not-a-real-dir/image/my-image.jpeg\\" style=\\"display: block\\" target=\\"_blank\\" rel=\\"noopener\\">
130+
<span class=\\"gatsby-resp-image-wrapper\\" style=\\"position: relative; display: block; max-width: 300px; margin-left: auto; margin-right: auto;\\">
131+
<span class=\\"gatsby-resp-image-background-image\\" style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;url(&apos;data:image/png;base64, iVBORw)&apos;); background-size: cover; display: block;\\"></span>
132+
<img class=\\"gatsby-resp-image-image\\" style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\" alt=\\"my image\\" title=\\"\\" src=\\"not-a-real-dir/image/my-image.jpeg\\" srcset=\\"not-a-real-dir/image/my-image.jpeg, not-a-real-dir/image/my-image.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
133+
</span>
134+
</a>"
135+
`;
136+
137+
exports[`it transforms images in markdown with query strings 1`] = `
138+
"<a
139+
class=\\"gatsby-resp-image-link\\"
140+
href=\\"not-a-real-dir/images/my-image.jpeg\\"
141+
style=\\"display: block\\"
142+
target=\\"_blank\\"
143+
rel=\\"noopener\\"
144+
>
145+
<span
146+
class=\\"gatsby-resp-image-wrapper\\"
147+
style=\\"position: relative; display: block; max-width: 300px; margin-left: auto; margin-right: auto;\\"
148+
>
149+
<span
150+
class=\\"gatsby-resp-image-background-image\\"
151+
style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url('url('data:image/png;base64, iVBORw)'); background-size: cover; display: block;\\"
152+
></span>
153+
<img
154+
class=\\"gatsby-resp-image-image\\"
155+
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
156+
alt=\\"image\\"
157+
title=\\"\\"
158+
src=\\"not-a-real-dir/images/my-image.jpeg\\"
159+
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
160+
sizes=\\"(max-width: 650px) 100vw, 650px\\"
161+
/>
162+
</span>
163+
</a>"
164+
`;

packages/gatsby-remark-images/src/__tests__/index.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jest.mock(`gatsby-plugin-sharp`, () => {
1515
})
1616

1717
const Remark = require(`remark`)
18+
const queryString = require(`query-string`)
1819

1920
const plugin = require(`../`)
2021

@@ -53,7 +54,7 @@ const createPluginOptions = (content, imagePaths = `/`) => {
5354
return {
5455
files: [].concat(imagePaths).map(imagePath => {
5556
return {
56-
absolutePath: `${dirName}/${imagePath}`,
57+
absolutePath: queryString.parseUrl(`${dirName}/${imagePath}`).url,
5758
}
5859
}),
5960
markdownNode: createNode(content),
@@ -268,3 +269,37 @@ test(`it handles goofy nesting properly`, async () => {
268269
expect(node.value).toMatchSnapshot()
269270
expect(node.value).not.toMatch(`<html>`)
270271
})
272+
273+
test(`it transforms HTML img tags with query strings`, async () => {
274+
const imagePath = `image/my-image.jpeg?query=string`
275+
276+
const content = `
277+
<img src="./${imagePath}">
278+
`.trim()
279+
280+
const nodes = await plugin(createPluginOptions(content, imagePath))
281+
282+
expect(nodes.length).toBe(1)
283+
284+
const node = nodes.pop()
285+
expect(node.type).toBe(`html`)
286+
expect(node.value).toMatchSnapshot()
287+
expect(node.value).not.toMatch(`<html>`)
288+
})
289+
290+
test(`it transforms images in markdown with query strings`, async () => {
291+
const imagePath = `images/my-image.jpeg?query=string`
292+
const content = `
293+
294+
![image](./${imagePath})
295+
`.trim()
296+
297+
const nodes = await plugin(createPluginOptions(content, imagePath))
298+
299+
expect(nodes.length).toBe(1)
300+
301+
const node = nodes.pop()
302+
expect(node.type).toBe(`html`)
303+
expect(node.value).toMatchSnapshot()
304+
expect(node.value).not.toMatch(`<html>`)
305+
})

packages/gatsby-remark-images/src/index.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const {
66
const visitWithParents = require(`unist-util-visit-parents`)
77
const getDefinitions = require(`mdast-util-definitions`)
88
const path = require(`path`)
9+
const queryString = require(`query-string`)
910
const isRelativeUrl = require(`is-relative-url`)
1011
const _ = require(`lodash`)
1112
const { fluid } = require(`gatsby-plugin-sharp`)
@@ -67,6 +68,18 @@ module.exports = (
6768
}
6869
)
6970

71+
const getImageInfo = uri => {
72+
const { url, query } = queryString.parseUrl(uri)
73+
return {
74+
ext: path
75+
.extname(url)
76+
.split(`.`)
77+
.pop(),
78+
url,
79+
query,
80+
}
81+
}
82+
7083
// Takes a node and generates the needed images and then returns
7184
// the needed HTML replacement for the image
7285
const generateImagesAndUpdateNode = async function(
@@ -80,7 +93,7 @@ module.exports = (
8093
const parentNode = getNode(markdownNode.parent)
8194
let imagePath
8295
if (parentNode && parentNode.dir) {
83-
imagePath = slash(path.join(parentNode.dir, node.url))
96+
imagePath = slash(path.join(parentNode.dir, getImageInfo(node.url).url))
8497
} else {
8598
return null
8699
}
@@ -113,7 +126,7 @@ module.exports = (
113126
const presentationWidth = fluidResult.presentationWidth
114127

115128
// Generate default alt tag
116-
const srcSplit = node.url.split(`/`)
129+
const srcSplit = getImageInfo(node.url).url.split(`/`)
117130
const fileName = srcSplit[srcSplit.length - 1]
118131
const fileNameNoExt = fileName.replace(/\.[^/.]+$/, ``)
119132
const defaultAlt = fileNameNoExt.replace(/[^A-Z0-9]/gi, ` `)
@@ -264,7 +277,7 @@ module.exports = (
264277
return resolve()
265278
}
266279
}
267-
const fileType = node.url.slice(-3)
280+
const fileType = getImageInfo(node.url).ext
268281

269282
// Ignore gifs as we can't process them,
270283
// svgs as they are already responsive by definition
@@ -328,7 +341,7 @@ module.exports = (
328341
return resolve()
329342
}
330343

331-
const fileType = formattedImgTag.url.slice(-3)
344+
const fileType = getImageInfo(formattedImgTag.url).ext
332345

333346
// Ignore gifs as we can't process them,
334347
// svgs as they are already responsive by definition

0 commit comments

Comments
 (0)