@blueking/chat-x 0.0.35 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1804 -1740
- package/dist/index.js.map +1 -1
- package/dist/mcp/generated/docs/markdown-content.md +25 -7
- package/dist/mcp/generated/docs/shortcut-render.md +4 -0
- package/dist/mcp/generated/index.json +1 -1
- package/dist/utils/css-sanitizer.d.ts +7 -0
- package/dist/utils/html-sanitizer.d.ts +7 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/tokens-to-vnodes.d.ts +6 -0
- package/package.json +2 -2
|
@@ -23,8 +23,8 @@ AI 消息内容渲染的核心原子组件,集成代码高亮、LaTeX 公式
|
|
|
23
23
|
## 组件结构与渲染流程
|
|
24
24
|
|
|
25
25
|
```
|
|
26
|
-
props.content → completeMarkdownSyntax → md.parse
|
|
27
|
-
|
|
26
|
+
props.content → completeMarkdownSyntax → md.parse(html: true)→ groupTokens → groupedTokens
|
|
27
|
+
│
|
|
28
28
|
div.ai-markdown-content(contain: layout style)
|
|
29
29
|
│
|
|
30
30
|
status === 'error' → CommonErrorContent(:content)
|
|
@@ -39,12 +39,21 @@ props.content → completeMarkdownSyntax → md.parse → groupTokens → groupe
|
|
|
39
39
|
↓ ↓ ↓ ↓
|
|
40
40
|
MermaidContent LatexContent CodeContent VNodeRenderer
|
|
41
41
|
@mounted @mounted @mounted @vue:mounted
|
|
42
|
-
│
|
|
43
|
-
└──── handleTokenMounted(throttle 100ms
|
|
42
|
+
│ │
|
|
43
|
+
└──── handleTokenMounted(throttle 100ms) │
|
|
44
|
+
→ containerScroll.toScrollBottom() │
|
|
45
|
+
sanitize(DOMPurify + sanitizeCSS)
|
|
46
|
+
sanitizeHtmlFragment(流式片段净化)
|
|
44
47
|
```
|
|
45
48
|
|
|
46
49
|
`VNodeRenderer` 的 `options` 中包含与当前 `MarkdownIt` 实例一致的 `mditOptions`(即 `md.options`),以便 `tokensToVNodes` 调用 `renderer.rules` 时第三参与 markdown-it 原生规则签名一致。
|
|
47
50
|
|
|
51
|
+
`MarkdownIt` 构造时开启 `html: true`,允许行内 HTML 标签(如 `<font>`、`<div>`)通过 markdown-it 解析为 `html_inline` / `html_block` token。
|
|
52
|
+
|
|
53
|
+
两组净化函数各司其职:
|
|
54
|
+
- `sanitize`:DOMPurify 全局过滤后,再对 `style` 属性值进行 CSS 属性白名单校验(`sanitizeCSS`),用于最终渲染的完整 HTML。
|
|
55
|
+
- `sanitizeHtmlFragment`:轻量级片段净化,**不自动闭合标签**,专用于流式渲染中拆分到多个 token 的 HTML 标签场景。
|
|
56
|
+
|
|
48
57
|
### Token 分组(groupTokens)
|
|
49
58
|
|
|
50
59
|
`groupTokens` 使用栈将扁平 Token 数组转为分组数组,每组对应一个顶层 DOM 节点(段落、标题、列表、代码块等):
|
|
@@ -189,15 +198,24 @@ props.content → completeMarkdownSyntax → md.parse → groupTokens → groupe
|
|
|
189
198
|
|
|
190
199
|
### 安全性
|
|
191
200
|
|
|
192
|
-
|
|
201
|
+
HTML 渲染采用两层安全策略:
|
|
202
|
+
|
|
203
|
+
**第一层 — DOMPurify**:全局过滤,移除危险标签和属性,同时允许 KaTeX 和 `<font>` 标签所需的内容:
|
|
193
204
|
|
|
194
205
|
```typescript
|
|
195
206
|
const domPurifyConfig = {
|
|
196
|
-
ADD_TAGS: ['semantics', 'mrow', 'mi', 'mo', 'mn', 'msup', 'msub', 'mfrac', 'mtext', 'annotation'],
|
|
197
|
-
ADD_ATTR: ['xmlns', 'mathvariant', 'encoding', 'style'],
|
|
207
|
+
ADD_TAGS: ['font', 'semantics', 'mrow', 'mi', 'mo', 'mn', 'msup', 'msub', 'mfrac', 'mtext', 'annotation'],
|
|
208
|
+
ADD_ATTR: ['xmlns', 'mathvariant', 'encoding', 'style', 'color', 'size', 'face'],
|
|
209
|
+
FORBID_TAGS: ['style'],
|
|
198
210
|
};
|
|
199
211
|
```
|
|
200
212
|
|
|
213
|
+
> `FORBID_TAGS: ['style']` 防止 `<style>` 标签注入全局 CSS,样式属性通过 `style` 属性(attribute)而非 `<style>` 标签(tag)控制。
|
|
214
|
+
|
|
215
|
+
**第二层 — CSS 属性白名单**(`sanitizeCSS`):DOMPurify 处理后,对 `style` 属性值做二次过滤,仅保留白名单内的安全 CSS 属性,拦截 `url()`、`expression()`、`javascript:` 等危险模式。
|
|
216
|
+
|
|
217
|
+
**流式场景 — `sanitizeHtmlFragment`**:流式渲染中 HTML 标签可能被拆分到多个 `html_inline` token(如 `<font color="red">` 和 `</font>` 分属不同 token),DOMPurify 会自动闭合未匹配标签导致样式丢失。`sanitizeHtmlFragment` 只做危险模式匹配不自动闭合,专用于此场景。
|
|
218
|
+
|
|
201
219
|
> `CodeContent`、`MermaidContent`、`LatexContent` 各自内部处理安全性(KaTeX `errorColor`、highlight.js 转义等),不经过 DOMPurify。
|
|
202
220
|
|
|
203
221
|
## 关联组件
|
|
@@ -411,6 +411,10 @@ interface BaseShortcutComponent {
|
|
|
411
411
|
}
|
|
412
412
|
```
|
|
413
413
|
|
|
414
|
+
## 样式说明
|
|
415
|
+
|
|
416
|
+
组件内部使用 SCSS 变量 `$bk-prefix` 拼接 bkui-vue 组件类名(如 `Form`、`FormItem`、`Radio`、`Checkbox` 等),替代原先硬编码的 `.bk-*` 类名选择器,确保在不同构建环境下类名前缀的一致性。
|
|
417
|
+
|
|
414
418
|
## 关联组件
|
|
415
419
|
|
|
416
420
|
- [ShortcutBtn](../atomic/shortcut-btn.md) — 与 Shortcut 数据模型一致的入口按钮
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export interface TokenToVNodeOptions {
|
|
|
17
17
|
* HTML 净化函数,用于处理 innerHTML 的内容
|
|
18
18
|
*/
|
|
19
19
|
sanitize?: (html: string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* HTML 片段净化函数,用于流式场景下 html_inline/html_block token 的净化。
|
|
22
|
+
* 与 sanitize 不同,此函数不会自动闭合未匹配的标签,
|
|
23
|
+
* 因为流式渲染中 HTML 标签可能被拆分到不同的 token 中。
|
|
24
|
+
*/
|
|
25
|
+
sanitizeHtmlFragment?: (html: string) => string;
|
|
20
26
|
}
|
|
21
27
|
type TokenAttrs = [string, string][];
|
|
22
28
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blueking/chat-x",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.36",
|
|
4
4
|
"description": "蓝鲸智云 AI Chat 组件库 —— 遵循 AG-UI,为 AI Agent 和人类开发者共同设计的对话 UI 组件库。",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"vitepress": "2.0.0-alpha.16",
|
|
79
79
|
"vitest": "^4.0.18",
|
|
80
80
|
"vue-tsc": "^3.1.4",
|
|
81
|
-
"@blueking/chat-helper": "0.0.
|
|
81
|
+
"@blueking/chat-helper": "0.0.4"
|
|
82
82
|
},
|
|
83
83
|
"scripts": {
|
|
84
84
|
"dev": "vite --config vite.config.ts",
|