Skip to content

Commit

Permalink
fix(gatsby-remark-images): support resolving markdown images from chi…
Browse files Browse the repository at this point in the history
…ld nodes (#28093)

* fix(gatsby-remark-images): support resolving markdown images from child nodes

- in case where remark nodes are created from other nodes
  (e.g. gatsby-plugin-json-remark) the parent node
  of a remark document is not a file.
- in order to resolve the images still, it is necessary
  to go up the parent chain until the closest File node

* fix snapshots

* Revert unrelated snapshot change

* Set windows timeout to 15m

* Fix

Co-authored-by: Kyle Mathews <[email protected]>
  • Loading branch information
rburgst and KyleAMathews committed May 3, 2022
1 parent 9f450e1 commit 496cb5d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ jobs:
- run:
name: Run tests
command: yarn jest --ci --runInBand ((yarn jest --listTests) | Foreach-Object {$_ -replace '.*\\packages', 'packages'} | Foreach-Object {$_ -replace '\\', '/'} | circleci tests split --split-by=timings)
no_output_timeout: 15m
environment:
NODE_OPTIONS: --max-old-space-size=2048
GENERATE_JEST_REPORT: "true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,37 @@ exports[`it transforms images in markdown and uses getRemarkFileDependency when
</span>"
`;

exports[`it transforms images in markdown in nested markdown node 1`] = `
"<span
class=\\"gatsby-resp-image-wrapper\\"
style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px; \\"
>
<a
class=\\"gatsby-resp-image-link\\"
href=\\"not-a-real-dir/images/my-image.jpeg\\"
style=\\"display: block\\"
target=\\"_blank\\"
rel=\\"noopener\\"
>
<span
class=\\"gatsby-resp-image-background-image\\"
style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw'); background-size: cover; display: block;\\"
></span>
<img
class=\\"gatsby-resp-image-image\\"
alt=\\"image\\"
title=\\"image\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\\"
loading=\\"lazy\\"
decoding=\\"async\\"
/>
</a>
</span>"
`;

exports[`it transforms images in markdown with query strings 1`] = `
"<span
class=\\"gatsby-resp-image-wrapper\\"
Expand Down
48 changes: 48 additions & 0 deletions packages/gatsby-remark-images/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,37 @@ const createPluginOptions = (
getRemarkFileDependency,
}
}
const createRecursivePluginOptions = (content, imagePaths = `/`) => {
const dirName = `not-a-real-dir`
return {
files: [].concat(imagePaths).map(imagePath => {
return {
absolutePath: queryString.parseUrl(`${dirName}/${imagePath}`).url,
}
}),
markdownNode: createNode(content),
markdownAST: remark.parse(content),
getNode: id => {
if (id === 1234) {
return {
id: 1234,
internal: { type: `JsonRemarkProperty` },
parent: 2345,
}
}
return {
dir: dirName,
internal: {
type: `File`,
},
}
},
compiler: {
parseString: remark.parse.bind(remark),
generateHTML: node => hastToHTML(toHAST(node)),
},
}
}

test(`it returns empty array when 0 images`, async () => {
const content = `
Expand Down Expand Up @@ -170,6 +201,23 @@ test(`it transforms images in markdown`, async () => {
expect(node.value).not.toMatch(`<html>`)
})

test(`it transforms images in markdown in nested markdown node`, async () => {
const imagePath = `images/my-image.jpeg`
const content = `
![image](./${imagePath})
`.trim()

const nodes = await plugin(createRecursivePluginOptions(content, imagePath))

expect(nodes.length).toBe(1)

const node = nodes.pop()
expect(node.type).toBe(`html`)
expect(node.value).toMatchSnapshot()
expect(node.value).not.toMatch(`<html>`)
})

test(`it transforms images in markdown with the "withWebp" option`, async () => {
const imagePath = `images/my-image.jpeg`
const content = `
Expand Down
26 changes: 25 additions & 1 deletion packages/gatsby-remark-images/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,31 @@ module.exports = (
) {
// Check if this markdownNode has a File parent. This plugin
// won't work if the image isn't hosted locally.
const parentNode = getNode(markdownNode.parent)
let parentNode = getNode(markdownNode.parent)
// check if the parent node is a File node, otherwise go up the chain and
// search for the closest parent File node. This is necessary in case
// you have markdown in child nodes (e.g. gatsby-plugin-json-remark).
if (
parentNode &&
parentNode.internal &&
parentNode.internal.type !== `File`
) {
let tempParentNode = parentNode
while (
tempParentNode &&
tempParentNode.internal &&
tempParentNode.internal.type !== `File`
) {
tempParentNode = getNode(tempParentNode.parent)
}
if (
tempParentNode &&
tempParentNode.internal &&
tempParentNode.internal.type === `File`
) {
parentNode = tempParentNode
}
}
let imagePath
if (parentNode && parentNode.dir) {
imagePath = slash(path.join(parentNode.dir, getImageInfo(node.url).url))
Expand Down

0 comments on commit 496cb5d

Please sign in to comment.