feat: render AI response as markdown (marked.js)
This commit is contained in:
parent
40882b62ea
commit
5b13383d5b
@ -151,7 +151,41 @@ body { font-family: var(--font-base); background: var(--color-bg); color: var(--
|
||||
.spinner { width: 18px; height: 18px; border: 2px solid var(--color-border); border-top-color: var(--color-brand); border-radius: 50%; animation: spin 0.7s linear infinite; flex-shrink: 0; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.ai-result.hidden { display: none; }
|
||||
#ai-text { font-size: 13px; line-height: 1.65; white-space: pre-wrap; max-height: 420px; overflow-y: auto; padding: 12px; background: var(--color-bg); border-radius: 8px; margin-bottom: 10px; }
|
||||
#ai-text {
|
||||
font-size: 13px; line-height: 1.65;
|
||||
max-height: 460px; overflow-y: auto;
|
||||
padding: 14px 16px; background: var(--color-bg);
|
||||
border-radius: 8px; margin-bottom: 10px;
|
||||
}
|
||||
/* Markdown typography inside AI response */
|
||||
#ai-text h1,#ai-text h2,#ai-text h3,#ai-text h4 {
|
||||
font-weight: 700; color: var(--color-text-primary);
|
||||
margin: 14px 0 6px; line-height: 1.3;
|
||||
}
|
||||
#ai-text h1 { font-size: 15px; border-bottom: 1px solid var(--color-border); padding-bottom: 4px; }
|
||||
#ai-text h2 { font-size: 14px; }
|
||||
#ai-text h3 { font-size: 13px; color: var(--color-brand); }
|
||||
#ai-text h4 { font-size: 13px; color: var(--color-text-secondary); }
|
||||
#ai-text p { margin: 6px 0; }
|
||||
#ai-text ul,#ai-text ol { margin: 6px 0 6px 18px; }
|
||||
#ai-text li { margin: 3px 0; }
|
||||
#ai-text li::marker { color: var(--color-brand); }
|
||||
#ai-text strong { font-weight: 700; color: var(--color-text-primary); }
|
||||
#ai-text em { font-style: italic; color: var(--color-text-secondary); }
|
||||
#ai-text code {
|
||||
font-family: var(--font-mono); font-size: 11px;
|
||||
background: rgba(0,82,204,0.08); color: var(--color-brand);
|
||||
padding: 1px 5px; border-radius: 4px;
|
||||
}
|
||||
#ai-text blockquote {
|
||||
border-left: 3px solid var(--color-brand);
|
||||
margin: 8px 0; padding: 4px 12px;
|
||||
color: var(--color-text-secondary); background: rgba(0,82,204,0.04);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
#ai-text hr { border: none; border-top: 1px solid var(--color-border); margin: 10px 0; }
|
||||
#ai-text > *:first-child { margin-top: 0; }
|
||||
#ai-text > *:last-child { margin-bottom: 0; }
|
||||
.btn-copy { width: 100%; padding: 8px; background: var(--color-bg); color: var(--color-text-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-btn); font-size: 13px; font-weight: 500; cursor: pointer; font-family: var(--font-base); transition: all 0.15s; }
|
||||
.btn-copy:hover { border-color: var(--color-brand); color: var(--color-brand); }
|
||||
.ai-error { font-size: 13px; color: var(--color-red); background: var(--color-red-bg); padding: 10px 12px; border-radius: 8px; margin-top: 8px; }
|
||||
@ -308,6 +342,7 @@ body { font-family: var(--font-base); background: var(--color-bg); color: var(--
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3.0.1/dist/chartjs-plugin-annotation.min.js"></script>
|
||||
<script>
|
||||
@ -1156,7 +1191,17 @@ async function runAiAnalysis() {
|
||||
}
|
||||
|
||||
function showAiLoading(show){document.getElementById('ai-loading').classList.toggle('hidden',!show);}
|
||||
function showAiResult(text){document.getElementById('ai-text').textContent=text;document.getElementById('ai-result').classList.remove('hidden');}
|
||||
function showAiResult(text){
|
||||
const el = document.getElementById('ai-text');
|
||||
if (window.marked) {
|
||||
// Configure marked: safe renderer, no mangling
|
||||
marked.setOptions({ breaks: true, gfm: true });
|
||||
el.innerHTML = marked.parse(text);
|
||||
} else {
|
||||
el.textContent = text; // fallback if CDN failed
|
||||
}
|
||||
document.getElementById('ai-result').classList.remove('hidden');
|
||||
}
|
||||
function showAiError(msg){const el=document.getElementById('ai-error');if(msg){el.textContent=msg;el.classList.remove('hidden');}else el.classList.add('hidden');}
|
||||
function restoreAiCache(){const c=sessionStorage.getItem('lastAiResponse');if(c)showAiResult(c);}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user