Files
diary-news/frontend
xiaji b674fb4b22 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 字都高亮匹配项)

无后端改动。
2026-06-15 07:32:39 +08:00
..