| @@ -21,7 +21,6 @@ import ImageGallery from '@/app/components/base/image-gallery' | |||
| import { useChatContext } from '@/app/components/base/chat/chat/context' | |||
| import VideoGallery from '@/app/components/base/video-gallery' | |||
| import AudioGallery from '@/app/components/base/audio-gallery' | |||
| import SVGRenderer from '@/app/components/base/svg-gallery' | |||
| import MarkdownButton from '@/app/components/base/markdown-blocks/button' | |||
| import MarkdownForm from '@/app/components/base/markdown-blocks/form' | |||
| import ThinkBlock from '@/app/components/base/markdown-blocks/think-block' | |||
| @@ -137,13 +136,14 @@ const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => | |||
| </div> | |||
| ) | |||
| } | |||
| else if (language === 'svg' && isSVG) { | |||
| return ( | |||
| <ErrorBoundary> | |||
| <SVGRenderer content={content} /> | |||
| </ErrorBoundary> | |||
| ) | |||
| } | |||
| // Attention: SVGRenderer has xss vulnerability | |||
| // else if (language === 'svg' && isSVG) { | |||
| // return ( | |||
| // <ErrorBoundary> | |||
| // <SVGRenderer content={content} /> | |||
| // </ErrorBoundary> | |||
| // ) | |||
| // } | |||
| else { | |||
| return ( | |||
| <SyntaxHighlighter | |||
| @@ -175,7 +175,7 @@ const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => | |||
| <div className='flex items-center gap-1'> | |||
| {(['mermaid', 'svg']).includes(language!) && <SVGBtn isSVG={isSVG} setIsSVG={setIsSVG} />} | |||
| <ActionButton> | |||
| <CopyIcon content={String(children).replace(/\n$/, '')}/> | |||
| <CopyIcon content={String(children).replace(/\n$/, '')} /> | |||
| </ActionButton> | |||
| </div> | |||
| </div> | |||
| @@ -240,11 +240,20 @@ const Link = ({ node, ...props }: any) => { | |||
| } | |||
| } | |||
| function escapeSVGTags(htmlString: string): string { | |||
| return htmlString.replace(/(<svg[\s\S]*?>)([\s\S]*?)(<\/svg>)/gi, (match: string, openTag: string, innerContent: string, closeTag: string): string => { | |||
| return openTag.replace(/</g, '<').replace(/>/g, '>') | |||
| + innerContent.replace(/</g, '<').replace(/>/g, '>') | |||
| + closeTag.replace(/</g, '<').replace(/>/g, '>') | |||
| }) | |||
| } | |||
| export function Markdown(props: { content: string; className?: string; customDisallowedElements?: string[] }) { | |||
| const latexContent = flow([ | |||
| preprocessThinkTag, | |||
| preprocessLaTeX, | |||
| ])(props.content) | |||
| ])(escapeSVGTags(props.content)) | |||
| return ( | |||
| <div className={cn('markdown-body', '!text-text-primary', props.className)}> | |||
| <ReactMarkdown | |||