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 -->
|
<!-- Toast -->
|
||||||
<div class="toast" id="toast"></div>
|
<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/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>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -640,6 +643,7 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
|||||||
return r.json();
|
return r.json();
|
||||||
}).then(function(data) {
|
}).then(function(data) {
|
||||||
previewContent.innerHTML = data.html || '<div class="preview-loading">Empty document</div>';
|
previewContent.innerHTML = data.html || '<div class="preview-loading">Empty document</div>';
|
||||||
|
processPreviewBlocks();
|
||||||
_previewLoading = false;
|
_previewLoading = false;
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
previewContent.innerHTML = '<div class="preview-loading">Render error: ' + e.message + '</div>';
|
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(); });
|
document.getElementById('poc-title').addEventListener('input', function() { markDirty(); });
|
||||||
|
|
||||||
// ---- Init ----
|
// ---- Init ----
|
||||||
|
mermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'loose' });
|
||||||
initSlashItems();
|
initSlashItems();
|
||||||
loadFile();
|
loadFile();
|
||||||
checkAIStatus();
|
checkAIStatus();
|
||||||
updateStats();
|
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('ObsiGate Editor v1 ready');
|
||||||
console.log(' File: ' + (fileVault ? fileVault + '/' + filePath : 'demo mode'));
|
console.log(' File: ' + (fileVault ? fileVault + '/' + filePath : 'demo mode'));
|
||||||
console.log(' AI: checking...');
|
console.log(' AI: checking...');
|
||||||
|
|||||||
Reference in New Issue
Block a user