From bbfa65f78e17d5f5985537ec26960b10e17acde9 Mon Sep 17 00:00:00 2001 From: zpj80231 Date: Wed, 25 Mar 2026 17:48:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(widget):=20=E6=B7=BB=E5=8A=A0=20emoji=20?= =?UTF-8?q?=E8=A1=A8=E6=83=85=E6=94=AF=E6=8C=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 node-emoji 依赖库支持 emoji 解析 - 实现防错处理确保 emoji 渲染失败时返回原始文本 --- docs/widget/package.json | 5 ++-- docs/widget/src/components/CommentItem.js | 3 ++- docs/widget/src/utils/markdown.js | 28 ++++++++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/widget/package.json b/docs/widget/package.json index 209d3ed..ba6e15d 100644 --- a/docs/widget/package.json +++ b/docs/widget/package.json @@ -34,6 +34,7 @@ }, "dependencies": { "dompurify": "^3.3.1", - "marked": "^17.0.1" + "marked": "^17.0.1", + "node-emoji": "^2.2.0" } -} \ No newline at end of file +} diff --git a/docs/widget/src/components/CommentItem.js b/docs/widget/src/components/CommentItem.js index 9fe0b57..3f77917 100644 --- a/docs/widget/src/components/CommentItem.js +++ b/docs/widget/src/components/CommentItem.js @@ -5,6 +5,7 @@ import { Component } from './Component.js'; import { ReplyEditor } from './ReplyEditor.js'; import { formatRelativeTime } from '@/utils/date.js'; +import { replaceEmojiInHtml } from '@/utils/markdown.js'; export class CommentItem extends Component { // 防抖缓存,防止连续点击 @@ -202,7 +203,7 @@ export class CommentItem extends Component { // 设置评论内容的 TEXT const contentEl = root.querySelector('.cwd-comment-content'); if (contentEl) { - contentEl.innerHTML = comment.contentHtml; + contentEl.innerHTML = replaceEmojiInHtml(comment.contentHtml); } // 创建回复编辑器 diff --git a/docs/widget/src/utils/markdown.js b/docs/widget/src/utils/markdown.js index e166d00..861c2b6 100644 --- a/docs/widget/src/utils/markdown.js +++ b/docs/widget/src/utils/markdown.js @@ -1,5 +1,6 @@ import { marked } from 'marked'; import DOMPurify from 'dompurify'; +import * as emoji from 'node-emoji'; // 配置 marked try { @@ -11,6 +12,30 @@ try { console.error('Failed to configure marked:', e); } +/** + * 替换文本中的 emoji 代码为实际 emoji + * @param {string} text 包含 emoji 代码的文本 + * @returns {string} 替换后的文本 + */ +function replaceEmoji(text) { + if (!text) return text; + try { + return emoji.emojify(text); + } catch (e) { + return text; + } +} + +/** + * 替换 HTML 中的 emoji 代码为实际 emoji + * @param {string} html 包含 emoji 代码的 HTML + * @returns {string} 替换后的 HTML + */ +export function replaceEmojiInHtml(html) { + if (!html) return html; + return replaceEmoji(html); +} + /** * 渲染 Markdown 为 HTML,并进行净化 * @param {string} content Markdown 内容 @@ -19,7 +44,8 @@ try { export function renderMarkdown(content) { if (!content) return ''; try { - const html = marked.parse(content); + const contentWithEmoji = replaceEmoji(content); + const html = marked.parse(contentWithEmoji); // marked.parse can return a Promise if async is enabled, but we are using sync mode // Just in case, handle potential Promise (though unlikely with current config) if (html instanceof Promise) {