fix: stabilize markdown code block selection and copy
This commit is contained in:
parent
49bd994cfa
commit
78df2249cf
@ -5,6 +5,18 @@ import renderMathInElement from 'katex/contrib/auto-render';
|
|||||||
let latexRenderTimer: number | null = null;
|
let latexRenderTimer: number | null = null;
|
||||||
const markdownCache = new Map<string, string>();
|
const markdownCache = new Map<string, string>();
|
||||||
|
|
||||||
|
function stableHash(input: string): string {
|
||||||
|
let hash = 5381;
|
||||||
|
for (let i = 0; i < input.length; i += 1) {
|
||||||
|
hash = (hash * 33) ^ input.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return (hash >>> 0).toString(36);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCacheKey(text: string): string {
|
||||||
|
return `md_${text.length}_${stableHash(text)}`;
|
||||||
|
}
|
||||||
|
|
||||||
function wrapCodeBlocks(html: string, isStreaming = false) {
|
function wrapCodeBlocks(html: string, isStreaming = false) {
|
||||||
if (isStreaming) {
|
if (isStreaming) {
|
||||||
return html;
|
return html;
|
||||||
@ -16,7 +28,7 @@ function wrapCodeBlocks(html: string, isStreaming = false) {
|
|||||||
(match, attributes, content) => {
|
(match, attributes, content) => {
|
||||||
const langMatch = attributes.match(/class="[^"]*language-(\w+)/);
|
const langMatch = attributes.match(/class="[^"]*language-(\w+)/);
|
||||||
const language = langMatch ? langMatch[1] : 'text';
|
const language = langMatch ? langMatch[1] : 'text';
|
||||||
const blockId = `code-${Date.now()}-${counter++}`;
|
const blockId = `code-${stableHash(`${attributes}|${content}|${counter++}`)}`;
|
||||||
const escapedContent = content
|
const escapedContent = content
|
||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
@ -50,7 +62,7 @@ export function renderMarkdown(text: string, isStreaming = false) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isStreaming) {
|
if (!isStreaming) {
|
||||||
const cacheKey = `${text.length}_${text.substring(0, 100)}`;
|
const cacheKey = buildCacheKey(text);
|
||||||
if (markdownCache.has(cacheKey)) {
|
if (markdownCache.has(cacheKey)) {
|
||||||
return markdownCache.get(cacheKey) as string;
|
return markdownCache.get(cacheKey) as string;
|
||||||
}
|
}
|
||||||
@ -61,7 +73,7 @@ export function renderMarkdown(text: string, isStreaming = false) {
|
|||||||
html = wrapCodeBlocks(html, isStreaming);
|
html = wrapCodeBlocks(html, isStreaming);
|
||||||
|
|
||||||
if (!isStreaming && text.length < 10000) {
|
if (!isStreaming && text.length < 10000) {
|
||||||
const cacheKey = `${text.length}_${text.substring(0, 100)}`;
|
const cacheKey = buildCacheKey(text);
|
||||||
markdownCache.set(cacheKey, html);
|
markdownCache.set(cacheKey, html);
|
||||||
if (markdownCache.size > 20) {
|
if (markdownCache.size > 20) {
|
||||||
const firstKey = markdownCache.keys().next().value as string | undefined;
|
const firstKey = markdownCache.keys().next().value as string | undefined;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user