fix(mermaid): bring back rendering

This commit is contained in:
Elian Doran 2025-03-21 22:27:33 +02:00
parent 8952ff512f
commit 67ab91267d
No known key found for this signature in database
3 changed files with 84 additions and 10 deletions

View File

@ -7,12 +7,8 @@ import { DEFAULT_GUTTER_SIZE } from "../../services/resizer.js";
const TPL = `\
<div class="note-detail-split note-detail-printable split-horizontal">
<div class="note-detail-split-preview">
Preview goes here.
</div>
<div class="note-detail-split-editor">
</div>
<div class="note-detail-split-preview"></div>
<div class="note-detail-split-editor"></div>
<style>
.note-detail-split {
@ -49,11 +45,11 @@ const TPL = `\
*
* - The two panes are resizeable via a split, on desktop.
*/
export default class SplitTypeEditor extends TypeWidget {
export default abstract class AbstractSplitTypeWidget extends TypeWidget {
private splitInstance?: Split.Instance;
private $preview!: JQuery<HTMLElement>;
protected $preview!: JQuery<HTMLElement>;
private $editor!: JQuery<HTMLElement>;
private editorTypeWidget: EditableCodeTypeWidget;

View File

@ -0,0 +1,42 @@
import type FNote from "../../entities/fnote.js";
import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";
/**
* A specialization of `SplitTypeWidget` meant for note types that have a SVG preview.
*
* This adds the following functionality:
*
*/
export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTypeWidget {
private $renderContainer!: JQuery<HTMLElement>;
doRender(): void {
super.doRender();
this.$renderContainer = $(`<div class="render-container"></div>`);
this.$preview.append(this.$renderContainer);
}
async doRefresh(note: FNote | null | undefined) {
super.doRefresh(note);
if (note) {
const blob = await note.getBlob();
const content = blob?.content || "";
console.log(content);
const svg = await this.renderSvg(content);
this.$renderContainer.html(svg);
}
}
/**
* Called upon when the SVG preview needs refreshing, such as when the editor has switched to a new note or the content has switched.
*
* The method must return a valid SVG string that will be automatically displayed in the preview.
*
* @param content the content of the note, in plain text.
*/
abstract renderSvg(content: string): Promise<string>;
}

View File

@ -1,9 +1,45 @@
import SplitTypeEditor from "./abstract_split_type_widget.js";
import library_loader from "../../services/library_loader.js";
import { postprocessMermaidSvg } from "../../services/mermaid.js";
import AbstractSvgSplitTypeWidget from "./abstract_svg_split_type_widget.js";
export class MermaidTypeWidget extends SplitTypeEditor {
let idCounter = 1;
export class MermaidTypeWidget extends AbstractSvgSplitTypeWidget {
static getType() {
return "mermaid";
}
async renderSvg(content: string) {
await library_loader.requireLibrary(library_loader.MERMAID);
mermaid.mermaidAPI.initialize({
startOnLoad: false,
...(getMermaidConfig() as any)
});
idCounter++;
const { svg } = await mermaid.mermaidAPI.render(`mermaid-graph-${idCounter}`, content);
return postprocessMermaidSvg(svg);
}
}
export function getMermaidConfig(): MermaidConfig {
const documentStyle = window.getComputedStyle(document.documentElement);
const mermaidTheme = documentStyle.getPropertyValue("--mermaid-theme");
return {
theme: mermaidTheme.trim(),
securityLevel: "antiscript",
// TODO: Are all these options correct?
flow: { useMaxWidth: false },
sequence: { useMaxWidth: false },
gantt: { useMaxWidth: false },
class: { useMaxWidth: false },
state: { useMaxWidth: false },
pie: { useMaxWidth: true },
journey: { useMaxWidth: false },
git: { useMaxWidth: false }
};
}