From 6c43b92bf1f39926728044e7bfb5c04f3f05b9fb Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 29 Jul 2022 00:32:28 +0200 Subject: [PATCH] mermaid export button WIP --- src/public/app/layouts/desktop_layout.js | 2 + src/public/app/services/link.js | 11 ++-- .../floating_buttons/mermaid_export_button.js | 26 ++++++++ src/public/app/widgets/mermaid.js | 60 ++++++++++++++----- 4 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 src/public/app/widgets/floating_buttons/mermaid_export_button.js diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 70af45140..d36e15982 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -77,6 +77,7 @@ import PromptDialog from "../widgets/dialogs/prompt.js"; import OptionsDialog from "../widgets/dialogs/options.js"; import FloatingButtons from "../widgets/floating_buttons/floating_buttons.js"; import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons.js"; +import MermaidExportButton from "../widgets/floating_buttons/mermaid_export_button.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -181,6 +182,7 @@ export default class DesktopLayout { .child(new NoteUpdateStatusWidget()) .child(new FloatingButtons() .child(new RelationMapButtons()) + .child(new MermaidExportButton()) .child(new BacklinksWidget()) ) .child(new MermaidWidget()) diff --git a/src/public/app/services/link.js b/src/public/app/services/link.js index fb08b8ef1..93c7a128a 100644 --- a/src/public/app/services/link.js +++ b/src/public/app/services/link.js @@ -85,11 +85,16 @@ function getNotePathFromLink($link) { } function goToLink(e) { + const $link = $(e.target).closest("a,.block-link"); + const address = $link.attr('href'); + + if (address.startsWith("data:")) { + return true; + } + e.preventDefault(); e.stopPropagation(); - const $link = $(e.target).closest("a,.block-link"); - const notePath = getNotePathFromLink($link); if (notePath) { @@ -115,8 +120,6 @@ function goToLink(e) { || $link.hasClass("ck-link-actions__preview") // within edit link dialog single click suffices || $link.closest("[contenteditable]").length === 0 // outside of CKEditor single click suffices ) { - const address = $link.attr('href'); - if (address) { if (address.toLowerCase().startsWith('http')) { window.open(address, '_blank'); diff --git a/src/public/app/widgets/floating_buttons/mermaid_export_button.js b/src/public/app/widgets/floating_buttons/mermaid_export_button.js new file mode 100644 index 000000000..85556c929 --- /dev/null +++ b/src/public/app/widgets/floating_buttons/mermaid_export_button.js @@ -0,0 +1,26 @@ +import NoteContextAwareWidget from "../note_context_aware_widget.js"; +import dialogService from "../dialog.js"; +import server from "../../services/server.js"; +import toastService from "../../services/toast.js"; + +const TPL = ` + +`; + +export default class MermaidExportButton extends NoteContextAwareWidget { + isEnabled() { + return super.isEnabled() + && this.note?.type === 'mermaid' + && this.note.isContentAvailable(); + } + + doRender() { + super.doRender(); + + this.$widget = $(TPL); + this.$widget.on('click', () => this.triggerEvent('exportMermaid', {ntxId: this.ntxId})); + this.contentSized(); + } +} diff --git a/src/public/app/widgets/mermaid.js b/src/public/app/widgets/mermaid.js index ae89edadf..089fe4b25 100644 --- a/src/public/app/widgets/mermaid.js +++ b/src/public/app/widgets/mermaid.js @@ -68,29 +68,23 @@ export default class MermaidWidget extends NoteContextAwareWidget { git: { useMaxWidth: false }, }); - const noteComplement = await froca.getNoteComplement(note.noteId); - const content = noteComplement.content || ""; - this.$display.empty(); - const libLoaded = libraryLoader.requireLibrary(libraryLoader.WHEEL_ZOOM); + const wheelZoomLoaded = libraryLoader.requireLibrary(libraryLoader.WHEEL_ZOOM); try { - const idNumber = idCounter++; + const renderedSvg = await this.renderSvg(); + this.$display.html(renderedSvg); - mermaid.mermaidAPI.render('mermaid-graph-' + idNumber, content, async content => { - this.$display.html(content); + await wheelZoomLoaded; - await libLoaded; + this.$display.attr("id", 'mermaid-render-' + idCounter); - this.$display.attr("id", 'mermaid-render-' + idNumber); - - WZoom.create('#mermaid-render-' + idNumber, { - type: 'html', - maxScale: 10, - speed: 20, - zoomOnClick: false - }); + WZoom.create('#mermaid-render-' + idCounter, { + type: 'html', + maxScale: 10, + speed: 20, + zoomOnClick: false }); this.$errorContainer.hide(); @@ -100,9 +94,43 @@ export default class MermaidWidget extends NoteContextAwareWidget { } } + renderSvg() { + return new Promise(async res => { + idCounter++; + + const noteComplement = await froca.getNoteComplement(this.noteId); + const content = noteComplement.content || ""; + + mermaid.mermaidAPI.render('mermaid-graph-' + idCounter, content, res); + }); + } + async entitiesReloadedEvent({loadResults}) { if (loadResults.isNoteContentReloaded(this.noteId)) { await this.refresh(); } } + + async exportMermaidEvent({ntxId}) { + if (!this.isNoteContext(ntxId)) { + return; + } + + const renderedSvg = await this.renderSvg(); + + this.download(this.note.title + ".svg", renderedSvg); + } + + download(filename, text) { + var element = document.createElement('a'); + element.setAttribute('href', 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(text)); + element.setAttribute('download', filename); + + element.style.display = 'none'; + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); + } }