From 2ef956da87ac2cd0e01479b089dad7ff72e361ce Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 25 Nov 2024 21:58:56 +0200 Subject: [PATCH] feat(mermaid): load ELK library on demand --- src/public/app/services/library_loader.js | 12 +++++++++- src/public/app/services/mermaid.js | 28 +++++++++++++++++++++++ src/public/app/widgets/mermaid.js | 10 ++++---- 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/public/app/services/mermaid.js diff --git a/src/public/app/services/library_loader.js b/src/public/app/services/library_loader.js index 19394ebfd..1757a841c 100644 --- a/src/public/app/services/library_loader.js +++ b/src/public/app/services/library_loader.js @@ -59,7 +59,16 @@ const FORCE_GRAPH = { const MERMAID = { js: [ - "node_modules/mermaid/dist/mermaid.min.js", + "node_modules/mermaid/dist/mermaid.min.js" + ] +} + +/** + * The ELK extension of Mermaid.js, which supports more advanced layouts. + * See https://www.npmjs.com/package/@mermaid-js/layout-elk for more information. + */ +const MERMAID_ELK = { + js: [ "libraries/mermaid-elk/elk.min.js" ] } @@ -200,6 +209,7 @@ export default { WHEEL_ZOOM, FORCE_GRAPH, MERMAID, + MERMAID_ELK, EXCALIDRAW, MARKJS, I18NEXT, diff --git a/src/public/app/services/mermaid.js b/src/public/app/services/mermaid.js new file mode 100644 index 000000000..152f14252 --- /dev/null +++ b/src/public/app/services/mermaid.js @@ -0,0 +1,28 @@ +import library_loader from "./library_loader.js"; + +let elkLoaded = false; + +/** + * Determines whether the ELK extension of Mermaid.js needs to be loaded (which is a relatively large library), based on the + * front-matter of the diagram and loads the library if needed. + * + *

+ * If the library has already been loaded or the diagram does not require it, the method will exit immediately. + * + * @param mermaidContent the plain text of the mermaid diagram, potentially including a frontmatter. + */ +export async function loadElkIfNeeded(mermaidContent) { + if (elkLoaded) { + // Exit immediately since the ELK library is already loaded. + return; + } + + const parsedContent = await mermaid.parse(mermaidContent, { + suppressErrors: true + }); + if (parsedContent?.config?.layout === "elk") { + elkLoaded = true; + await library_loader.requireLibrary(library_loader.MERMAID_ELK); + mermaid.registerLayoutLoaders(MERMAID_ELK); + } +} \ No newline at end of file diff --git a/src/public/app/widgets/mermaid.js b/src/public/app/widgets/mermaid.js index 79e639d5f..20aad6975 100644 --- a/src/public/app/widgets/mermaid.js +++ b/src/public/app/widgets/mermaid.js @@ -3,6 +3,7 @@ import libraryLoader from "../services/library_loader.js"; import NoteContextAwareWidget from "./note_context_aware_widget.js"; import server from "../services/server.js"; import utils from "../services/utils.js"; +import { loadElkIfNeeded } from "../services/mermaid.js"; const TPL = `