feat(search): 搜索结果关键字高亮(标题/正文/评论)
Feed.vue 搜索 q 时,命中的关键字在卡片标题/正文/双 provider
评论预览里 <mark> 包裹高亮(暖黄底 + 加粗)。
实现:
- 新增 escapeHtml(text) — 防止 XSS(content 来自外部 RSS/ingest,
不可信;先 escape 再 replace,确保 <mark> 之外不会有任何原始
HTML 进入 DOM)
- 新增 highlightHtml(text, q) — 不区分大小写匹配,正则元字符
(.*+?^${}()|[]\\) 自动转义(避免用户搜 "*.x" 时被当 regex)
q 为空时返回纯 escape 文本(行为与原来 {{ }} 插值一致)
- 改造 previewCommentary(text, max, q) — 第三个参数 q 透传
highlightHtml
- 4 处渲染改 {{ }} -> v-html,传 highlightHtml(previewCommentary
(..., q)):
- 中文标题 + 原标题
- 正文摘要
- Angel 评论预览
- 美团评论预览
样式:
- .feed-list :deep(mark) 暖黄底 (#fff3a0) + inherit 父级文字色 +
padding 2px + 加粗
- :deep() 避免 Naive UI 组件 scoped 样式隔离问题
安全:
- 所有用户内容先 escapeHtml,再 replace
- <mark> 标签是 escape 之后才插入,不会引入新的 XSS 通道
- q 特殊字符转义,不构成 regex DoS
不影响:
- q 为空时(highlightHtml(text, '') = escapeHtml(text) 等价于
Vue 原生 {{ }} 自动 escape) - 非搜索场景行为完全不变
- waiting/failed 状态的评论不显示评论内容,不需高亮
- 短新闻正文也支持高亮(q 不空时,完整 5000 字都高亮匹配项)
无后端改动。