chore(react/type_widget): render inline mermaid in read-only text

This commit is contained in:
Elian Doran 2025-09-21 20:15:57 +03:00
parent e4eb96a1ae
commit 2f3c2bbac8
No known key found for this signature in database
2 changed files with 28 additions and 19 deletions

View File

@ -10,12 +10,20 @@ import RawHtml from "../../react/RawHtml";
import "@triliumnext/ckeditor5";
import FNote from "../../../entities/fnote";
import { getLocaleById } from "../../../services/i18n";
import { getMermaidConfig } from "../../../services/mermaid";
export default function ReadOnlyText({ note }: TypeWidgetProps) {
const blob = useNoteBlob(note);
const contentRef = useRef<HTMLDivElement>(null);
const { isRtl } = useNoteLanguage(note);
useEffect(() => {
const container = contentRef.current;
if (!container) return;
applyInlineMermaid(container);
}, [ blob ]);
return (
<div
className="note-detail-readonly-text note-detail-printable"
@ -39,3 +47,23 @@ function useNoteLanguage(note: FNote) {
}, [ language ]);
return { isRtl };
}
async function applyInlineMermaid(container: HTMLDivElement) {
const mermaidBlocks = container.querySelectorAll('pre:has(code[class="language-mermaid"])');
if (!mermaidBlocks.length) return;
const nodes: HTMLElement[] = [];
// Rewrite the code block from <pre><code> to <div> in order not to apply a codeblock style to it.
for (const mermaidBlock of mermaidBlocks) {
const div = document.createElement("div");
div.classList.add("mermaid-diagram");
div.innerHTML = mermaidBlock.querySelector("code")?.innerHTML ?? "";
mermaidBlock.replaceWith(div);
nodes.push(div);
}
// Initialize mermaid
const mermaid = (await import("mermaid")).default;
mermaid.initialize(getMermaidConfig());
mermaid.run({ nodes });
}

View File

@ -53,25 +53,6 @@ export default class ReadOnlyTextTypeWidget extends AbstractTextTypeWidget {
await formatCodeBlocks(this.$content);
}
async #applyInlineMermaid() {
const $el = this.$content.find('code[class="language-mermaid"]').closest("pre");
if (!$el.length) {
return;
}
// Rewrite the code block from <pre><code> to <div> in order not to apply a codeblock style to it.
$el.replaceWith((i, content) => {
return $('<div class="mermaid-diagram">').text($(content).text());
});
// Initialize mermaid
const mermaid = (await import("mermaid")).default;
mermaid.initialize(getMermaidConfig());
mermaid.run({
nodes: this.$content.find(".mermaid-diagram")
});
}
async refreshIncludedNoteEvent({ noteId }: EventData<"refreshIncludedNote">) {
this.refreshIncludedNote(this.$content, noteId);
}