({src, resolveImage, node, alt, ...props})
| 11 | // Image src may be an async-resolved attachment token (editor) or a plain |
| 12 | // URL / data URL (saved content). Resolve both. |
| 13 | function ResolvedImage({src, resolveImage, node, alt, ...props}) { |
| 14 | const [url, setUrl] = useState(null); |
| 15 | useEffect(() => { |
| 16 | let alive = true; |
| 17 | Promise.resolve(resolveImage ? resolveImage(src) : src) |
| 18 | .then((u) => alive && setUrl(u ?? null)) |
| 19 | .catch(() => alive && setUrl(src)); |
| 20 | return () => { |
| 21 | alive = false; |
| 22 | }; |
| 23 | }, [src, resolveImage]); |
| 24 | if (!url) return null; |
| 25 | return <img src={url} alt={alt ?? ""} loading="lazy" {...props}/>; |
| 26 | } |
| 27 | |
| 28 | // Image src may be an editor attachment token or an inline image data URL — |
| 29 | // both are safe and must survive react-markdown's URI sanitization. Everything |
nothing calls this directly
no outgoing calls
no test coverage detected