feat: 详情弹框内容支持Markdown格式显示
This commit is contained in:
@@ -1074,6 +1074,16 @@ INDEX_TEMPLATE = '''
|
||||
.type-todo { border-left: 4px solid #ffc107; }
|
||||
.is-starred { border-left: 4px solid #ffc107; background: #fffbe6; }
|
||||
.is-starred:hover { background: #fff9e0; }
|
||||
/* Markdown内容样式 */
|
||||
.markdown-content { line-height: 1.6; }
|
||||
.markdown-content h3 { font-size: 1.2em; margin-bottom: 0.5em; }
|
||||
.markdown-content h4 { font-size: 1.1em; margin-bottom: 0.4em; }
|
||||
.markdown-content h5 { font-size: 1.0em; margin-bottom: 0.3em; }
|
||||
.markdown-content h6 { font-size: 0.9em; margin-bottom: 0.2em; }
|
||||
.markdown-content code { font-size: 0.9em; }
|
||||
.markdown-content pre { font-size: 0.85em; overflow-x: auto; }
|
||||
.markdown-content ul, .markdown-content ol { margin-bottom: 0.5em; }
|
||||
.markdown-content a { color: #0d6efd; }
|
||||
.star-btn { font-size: 11px; }
|
||||
.status-pending { color: #ffc107; }
|
||||
.status-in_progress { color: #17a2b8; }
|
||||
@@ -2681,7 +2691,7 @@ async function showDetail(id) {
|
||||
}
|
||||
|
||||
if (item.content) {
|
||||
html += `<div class="mb-3"><strong>内容:</strong><br><div class="border rounded p-3 bg-light" style="white-space: pre-wrap; word-break: break-all;">${escapeHtml(item.content)}</div></div>`;
|
||||
html += `<div class="mb-3"><strong>内容:</strong><br><div class="border rounded p-3 bg-light markdown-content">${renderMarkdown(item.content)}</div></div>`;
|
||||
}
|
||||
|
||||
if (item.source) {
|
||||
@@ -2701,7 +2711,7 @@ async function showDetail(id) {
|
||||
}
|
||||
|
||||
if (item.note) {
|
||||
html += `<div class="mb-3"><strong>详情/备注:</strong><br><div class="border rounded p-3 bg-light" style="white-space: pre-wrap; word-break: break-all;">${escapeHtml(item.note)}</div></div>`;
|
||||
html += `<div class="mb-3"><strong>详情/备注:</strong><br><div class="border rounded p-3 bg-light markdown-content">${renderMarkdown(item.note)}</div></div>`;
|
||||
}
|
||||
|
||||
html += `<div class="text-muted small"><strong>创建时间:</strong> ${formatDate(item.created_at)}<br><strong>更新时间:</strong> ${formatDate(item.updated_at)}</div>`;
|
||||
@@ -3032,6 +3042,55 @@ function escapeHtml(str) {
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
// 简单Markdown渲染(支持标题、粗体、斜体、代码、链接、列表)
|
||||
function renderMarkdown(text) {
|
||||
if (!text) return '';
|
||||
|
||||
// 先转义HTML
|
||||
let html = escapeHtml(text);
|
||||
|
||||
// 代码块 ```code```
|
||||
html = html.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre class="bg-dark text-light p-2 rounded"><code>$2</code></pre>');
|
||||
|
||||
// 行内代码 `code`
|
||||
html = html.replace(/`([^`]+)`/g, '<code class="bg-light px-1 rounded">$1</code>');
|
||||
|
||||
// 标题 # ## ### ####
|
||||
html = html.replace(/^#### (.+)$/gm, '<h6 class="mt-2">$1</h6>');
|
||||
html = html.replace(/^### (.+)$/gm, '<h5 class="mt-2">$1</h5>');
|
||||
html = html.replace(/^## (.+)$/gm, '<h4 class="mt-2">$1</h4>');
|
||||
html = html.replace(/^# (.+)$/gm, '<h3 class="mt-2">$1</h3>');
|
||||
|
||||
// 粗体 **text**
|
||||
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
|
||||
|
||||
// 斜体 *text*
|
||||
html = html.replace(/\*([^*]+)\*/g, '<em>$1</em>');
|
||||
|
||||
// 链接 [text](url)
|
||||
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
|
||||
|
||||
// 无序列表 - item
|
||||
html = html.replace(/^- (.+)$/gm, '<li class="ms-3">$1</li>');
|
||||
html = html.replace(/(<li.*<\/li>\n?)+/g, '<ul class="mb-2">$&</ul>');
|
||||
|
||||
// 有序列表 1. item
|
||||
html = html.replace(/^\d+\. (.+)$/gm, '<li class="ms-3">$1</li>');
|
||||
|
||||
// 段落分隔(两个换行)
|
||||
html = html.replace(/\n\n/g, '</p><p class="mb-2">');
|
||||
|
||||
// 单换行
|
||||
html = html.replace(/\n/g, '<br>');
|
||||
|
||||
// 包装在段落中
|
||||
if (!html.startsWith('<')) {
|
||||
html = '<p class="mb-2">' + html + '</p>';
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
// 标签管理
|
||||
let allTags = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user