feat: Mermaid + highlight.js rendering in preview pane
Added CDN scripts: mermaid@11, highlight.js@11 with atom-one-dark theme. After server-rendered HTML is injected, processPreviewBlocks() renders Mermaid diagrams via mermaid.render() and highlights code blocks via hljs.highlightElement(). Preview now matches ObsiGate viewer fidelity.
This commit is contained in:
@@ -342,8 +342,11 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<!-- marked.js CDN for markdown rendering -->
|
||||
<!-- marked.js + highlight.js + Mermaid CDN for preview rendering -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11/styles/atom-one-dark.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/highlight.js@11/lib/highlight.min.js"></script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
@@ -640,6 +643,7 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
||||
return r.json();
|
||||
}).then(function(data) {
|
||||
previewContent.innerHTML = data.html || '<div class="preview-loading">Empty document</div>';
|
||||
processPreviewBlocks();
|
||||
_previewLoading = false;
|
||||
}).catch(function(e) {
|
||||
previewContent.innerHTML = '<div class="preview-loading">Render error: ' + e.message + '</div>';
|
||||
@@ -1161,11 +1165,42 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
||||
document.getElementById('poc-title').addEventListener('input', function() { markDirty(); });
|
||||
|
||||
// ---- Init ----
|
||||
mermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'loose' });
|
||||
initSlashItems();
|
||||
loadFile();
|
||||
checkAIStatus();
|
||||
updateStats();
|
||||
|
||||
// ---- Process preview blocks (Mermaid + highlight.js) ----
|
||||
function processPreviewBlocks() {
|
||||
// Render Mermaid diagrams
|
||||
var mermaidBlocks = previewContent.querySelectorAll('pre code.language-mermaid');
|
||||
mermaidBlocks.forEach(function(block) {
|
||||
var code = block.textContent;
|
||||
var id = 'mermaid-prev-' + Math.random().toString(36).substr(2, 8);
|
||||
try {
|
||||
mermaid.render(id, code).then(function(result) {
|
||||
var container = document.createElement('div');
|
||||
container.className = 'mermaid-rendered';
|
||||
container.innerHTML = result.svg;
|
||||
block.parentElement.replaceWith(container);
|
||||
}).catch(function() {
|
||||
// Mermaid render failed, leave code block as-is
|
||||
});
|
||||
} catch(e) {
|
||||
// ignore render errors
|
||||
}
|
||||
});
|
||||
// Syntax highlight code blocks
|
||||
if (typeof hljs !== 'undefined') {
|
||||
previewContent.querySelectorAll('pre code').forEach(function(block) {
|
||||
if (!block.classList.contains('language-mermaid')) {
|
||||
hljs.highlightElement(block);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log('ObsiGate Editor v1 ready');
|
||||
console.log(' File: ' + (fileVault ? fileVault + '/' + filePath : 'demo mode'));
|
||||
console.log(' AI: checking...');
|
||||
|
||||
Reference in New Issue
Block a user