feat: CodeViewer click link and auto wrap

This commit is contained in:
feitianbubu
2026-01-30 11:18:49 +08:00
parent 1c983a04d3
commit ac8a92655e

View File

@@ -106,6 +106,22 @@ const highlightJson = (str) => {
); );
}; };
const linkRegex = /(https?:\/\/[^\s<"'\]),;}]+)/g;
const linkifyHtml = (html) => {
const parts = html.split(/(<[^>]+>)/g);
return parts
.map((part) => {
if (part.startsWith('<')) return part;
return part.replace(
linkRegex,
(url) =>
`<a href="${url}" target="_blank" rel="noreferrer">${url}</a>`,
);
})
.join('');
};
const isJsonLike = (content, language) => { const isJsonLike = (content, language) => {
if (language === 'json') return true; if (language === 'json') return true;
const trimmed = content.trim(); const trimmed = content.trim();
@@ -179,6 +195,10 @@ const CodeViewer = ({ content, title, language = 'json' }) => {
return displayContent; return displayContent;
}, [displayContent, language, contentMetrics.isVeryLarge, isExpanded]); }, [displayContent, language, contentMetrics.isVeryLarge, isExpanded]);
const renderedContent = useMemo(() => {
return linkifyHtml(highlightedContent);
}, [highlightedContent]);
const handleCopy = useCallback(async () => { const handleCopy = useCallback(async () => {
try { try {
const textToCopy = const textToCopy =
@@ -276,6 +296,8 @@ const CodeViewer = ({ content, title, language = 'json' }) => {
style={{ style={{
...codeThemeStyles.content, ...codeThemeStyles.content,
paddingTop: contentPadding, paddingTop: contentPadding,
whiteSpace: 'pre-wrap',
wordBreak: 'break-word',
}} }}
className='model-settings-scroll' className='model-settings-scroll'
> >
@@ -303,7 +325,7 @@ const CodeViewer = ({ content, title, language = 'json' }) => {
{t('正在处理大内容...')} {t('正在处理大内容...')}
</div> </div>
) : ( ) : (
<div dangerouslySetInnerHTML={{ __html: highlightedContent }} /> <div dangerouslySetInnerHTML={{ __html: renderedContent }} />
)} )}
</div> </div>