Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit deb7b47

Browse files
committed
fix(plugins/plugin-client-common): Markdown component does not properly handle local relative image paths
Fixes #6547
1 parent 81b55e0 commit deb7b47

File tree

1 file changed

+23
-9
lines changed
  • plugins/plugin-client-common/src/components/Content

1 file changed

+23
-9
lines changed

plugins/plugin-client-common/src/components/Content/Markdown.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import React from 'react'
1818
import { v4 as uuid } from 'uuid'
1919
import TurndownService from 'turndown'
2020
import ReactMarkdown from 'react-markdown'
21-
import { dirname, join, relative } from 'path'
2221
import { REPL, Tab as KuiTab } from '@kui-shell/core'
22+
import { dirname, isAbsolute, join, relative } from 'path'
2323

2424
import {
2525
Link,
@@ -78,6 +78,14 @@ export default class Markdown extends React.PureComponent<Props> {
7878
}
7979
}
8080

81+
private handleImage(src: string, width?: number) {
82+
const isLocal = !/^http/i.test(src)
83+
if (isLocal && this.props.fullpath) {
84+
const absoluteSrc = isAbsolute(src) ? src : join(dirname(this.props.fullpath), src)
85+
return <img src={absoluteSrc} width={width} />
86+
}
87+
}
88+
8189
public render() {
8290
return (
8391
<ReactMarkdown
@@ -88,6 +96,19 @@ export default class Markdown extends React.PureComponent<Props> {
8896
(!this.props.nested ? ' scrollable scrollable-x scrollable-auto' : ' full-height')
8997
}
9098
renderers={{
99+
html: props => {
100+
if (/<img/.test(props.value)) {
101+
const srcMatch = props.value.match(/src="?([^"\s]+)"?/)
102+
const widthMatch = props.value.match(/width="?(\d+)"?/)
103+
if (srcMatch) {
104+
return this.handleImage(srcMatch[1], widthMatch[1]) || <span />
105+
}
106+
}
107+
108+
// Render the raw string for all other raw html tags
109+
return <span>{props.value}</span>
110+
},
111+
91112
link: props => {
92113
const isLocal = !/^http/i.test(props.href)
93114
const target = !isLocal ? '_blank' : undefined
@@ -153,14 +174,7 @@ export default class Markdown extends React.PureComponent<Props> {
153174
)
154175
},
155176
image: props => {
156-
const isLocal = !/^http/i.test(props.src)
157-
if (isLocal && this.props.fullpath) {
158-
const absoluteSrc = join(dirname(this.props.fullpath), props.src)
159-
const relativeToCWD = relative(process.cwd() || process.env.PWD, absoluteSrc)
160-
return <img src={relativeToCWD} />
161-
} else {
162-
return <img {...props} />
163-
}
177+
return this.handleImage(props.src, props.width) || <img {...props} />
164178
},
165179
list: props => {
166180
return React.createElement(

0 commit comments

Comments
 (0)