Render chat and previews through the shared HTML cleaner
Why: The conversation and office fallbacks wrote marked output straight into the page, including converted docx HTML. Evidence: html-sinks ratchet forbids new innerHTML writes outside @ui safeHtml. Impact: Conversation keeps line-break rendering. Unsafe links are stripped after docx and pptx preview. dompurify is deduped with the UI package. Refs: feature/sillytavern-review Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
// 中栏:消息流(Part 渲染器注册表)+ 流式渲染 + 过程折叠 + HITL 卡片 + 输入区(4.4)。
|
||||
// 重设计方案 阶段④:折叠区全部迁 @ui Collapsible(<details> 已禁);工具调用块走
|
||||
// ToolBlock 契约(运行态扫光、完成边沿收起、展开态记忆);live 行扫光 + 已工作计时。
|
||||
import { Icon, Avatar, BrandMark, Collapsible, getPersistedOpen, setPersistedOpen } from '@ui'
|
||||
import { Icon, Avatar, BrandMark, Collapsible, getPersistedOpen, setPersistedOpen, SafeMarkdown } from '@ui'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { marked } from 'marked'
|
||||
import { api } from '../api'
|
||||
import { store, useStore, activeRun, type LiveState, type ContextObs } from '../store'
|
||||
import { scrollRatio, scrollTopForRatio } from '../scrollsync'
|
||||
@@ -19,15 +18,15 @@ function hasFiles(dt: DataTransfer | null): boolean {
|
||||
return !!dt && Array.from(dt.types).includes('Files')
|
||||
}
|
||||
|
||||
// marked 走标准 Markdown 语义(不开 breaks):模型输出按块级排版渲染,
|
||||
// 行内换行交给段落折叠,避免与 CSS 块间距叠加出松散排版。
|
||||
// 对话正文沿用 breaks:卡片渲染器曾经把全局 marked 设成 breaks,
|
||||
// 去重后的同一份 marked 让对话也按行内换行显示。这里显式保持这个效果。
|
||||
|
||||
// Part 渲染器注册表:按类型查表;未知类型静默忽略(前向兼容)。
|
||||
function PartView({ part, live }: { part: Part; live?: boolean | null }) {
|
||||
switch (part.type) {
|
||||
case 'text':
|
||||
return <div className={live ? 'part-text cursor-blink' : 'part-text'}
|
||||
dangerouslySetInnerHTML={{ __html: marked.parse(markMissingArtifacts(part.text ?? '', id => !!findArtifact(id))) as string }} />
|
||||
return <SafeMarkdown className={live ? 'part-text cursor-blink' : 'part-text'} breaks
|
||||
markdown={markMissingArtifacts(part.text ?? '', id => !!findArtifact(id))} />
|
||||
case 'thinking':
|
||||
// 流式期间展开可实时看到思考;run 终态后收进过程折叠区,默认收起。
|
||||
//(此单件形态用于过程组之外散落的思考;组内思考由 ProcessParts 渲染。)
|
||||
|
||||
Reference in New Issue
Block a user