From 78df2249cf20a6f5ccc1c3e907331e6ea9fa8cda Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Sun, 12 Apr 2026 19:59:28 +0800 Subject: [PATCH] fix: stabilize markdown code block selection and copy --- static/src/composables/useMarkdownRenderer.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/static/src/composables/useMarkdownRenderer.ts b/static/src/composables/useMarkdownRenderer.ts index 5b66a05..b37bca7 100644 --- a/static/src/composables/useMarkdownRenderer.ts +++ b/static/src/composables/useMarkdownRenderer.ts @@ -5,6 +5,18 @@ import renderMathInElement from 'katex/contrib/auto-render'; let latexRenderTimer: number | null = null; const markdownCache = new Map(); +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) { if (isStreaming) { return html; @@ -16,7 +28,7 @@ function wrapCodeBlocks(html: string, isStreaming = false) { (match, attributes, content) => { const langMatch = attributes.match(/class="[^"]*language-(\w+)/); const language = langMatch ? langMatch[1] : 'text'; - const blockId = `code-${Date.now()}-${counter++}`; + const blockId = `code-${stableHash(`${attributes}|${content}|${counter++}`)}`; const escapedContent = content .replace(/&/g, '&') .replace(/ 20) { const firstKey = markdownCache.keys().next().value as string | undefined;