mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
refactor(client): use webpack for mermaid
This commit is contained in:
parent
f4d5b9fc29
commit
28c51cb38a
@ -76,7 +76,6 @@ try {
|
||||
"node_modules/dayjs/",
|
||||
"node_modules/boxicons/css/",
|
||||
"node_modules/boxicons/fonts/",
|
||||
"node_modules/mermaid/dist/",
|
||||
"node_modules/jquery/dist/",
|
||||
"node_modules/jquery-hotkeys/",
|
||||
"node_modules/split.js/dist/",
|
||||
|
@ -16,7 +16,6 @@ import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons
|
||||
import SvgExportButton from "../widgets/floating_buttons/svg_export_button.js";
|
||||
import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js";
|
||||
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
|
||||
import MermaidWidget from "../widgets/mermaid.js";
|
||||
import NoteListWidget from "../widgets/note_list.js";
|
||||
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
|
||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||
@ -165,7 +164,6 @@ export default class MobileLayout {
|
||||
.child(new BacklinksWidget())
|
||||
.child(new HideFloatingButtonsButton())
|
||||
)
|
||||
.child(new MermaidWidget())
|
||||
.child(new PromotedAttributesWidget())
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
|
@ -15,6 +15,7 @@ import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
||||
import renderDoc from "./doc_renderer.js";
|
||||
import { t } from "i18next";
|
||||
import type { Mermaid } from "mermaid";
|
||||
|
||||
let idCounter = 1;
|
||||
|
||||
@ -226,7 +227,7 @@ function renderFile(entity: FNote | FAttachment, type: string, $renderedContent:
|
||||
}
|
||||
|
||||
async function renderMermaid(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>) {
|
||||
await libraryLoader.requireLibrary(libraryLoader.MERMAID);
|
||||
const mermaid = (await import("mermaid")).default;
|
||||
|
||||
const blob = await note.getBlob();
|
||||
const content = blob?.content || "";
|
||||
@ -236,10 +237,10 @@ async function renderMermaid(note: FNote | FAttachment, $renderedContent: JQuery
|
||||
const documentStyle = window.getComputedStyle(document.documentElement);
|
||||
const mermaidTheme = documentStyle.getPropertyValue("--mermaid-theme");
|
||||
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false, theme: mermaidTheme.trim(), securityLevel: "antiscript" });
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false, theme: mermaidTheme.trim() as "default", securityLevel: "antiscript" });
|
||||
|
||||
try {
|
||||
await loadElkIfNeeded(content);
|
||||
await loadElkIfNeeded(mermaid, content);
|
||||
const { svg } = await mermaid.mermaidAPI.render("in-mermaid-graph-" + idCounter++, content);
|
||||
|
||||
$renderedContent.append($(postprocessMermaidSvg(svg)));
|
||||
|
@ -55,10 +55,6 @@ const WHEEL_ZOOM: Library = {
|
||||
js: ["node_modules/vanilla-js-wheel-zoom/dist/wheel-zoom.min.js"]
|
||||
};
|
||||
|
||||
const MERMAID: Library = {
|
||||
js: ["node_modules/mermaid/dist/mermaid.min.js"]
|
||||
};
|
||||
|
||||
const MARKJS: Library = {
|
||||
js: ["node_modules/mark.js/dist/jquery.mark.es6.min.js"]
|
||||
};
|
||||
@ -181,7 +177,6 @@ export default {
|
||||
CALENDAR_WIDGET,
|
||||
KATEX,
|
||||
WHEEL_ZOOM,
|
||||
MERMAID,
|
||||
MARKJS,
|
||||
HIGHLIGHT_JS,
|
||||
LEAFLET
|
||||
|
@ -1,3 +1,5 @@
|
||||
import type { Mermaid } from "mermaid";
|
||||
|
||||
let elkLoaded = false;
|
||||
|
||||
/**
|
||||
@ -9,7 +11,7 @@ let elkLoaded = false;
|
||||
*
|
||||
* @param mermaidContent the plain text of the mermaid diagram, potentially including a frontmatter.
|
||||
*/
|
||||
export async function loadElkIfNeeded(mermaidContent: string) {
|
||||
export async function loadElkIfNeeded(mermaid: Mermaid, mermaidContent: string) {
|
||||
if (elkLoaded) {
|
||||
// Exit immediately since the ELK library is already loaded.
|
||||
return;
|
||||
@ -18,7 +20,7 @@ export async function loadElkIfNeeded(mermaidContent: string) {
|
||||
const parsedContent = await mermaid.parse(mermaidContent, {
|
||||
suppressErrors: true
|
||||
});
|
||||
if (parsedContent?.config?.layout === "elk") {
|
||||
if (parsedContent && parsedContent.config?.layout === "elk") {
|
||||
elkLoaded = true;
|
||||
mermaid.registerLayoutLoaders((await import("@mermaid-js/layout-elk")).default);
|
||||
}
|
||||
|
42
src/public/app/types.d.ts
vendored
42
src/public/app/types.d.ts
vendored
@ -8,6 +8,7 @@ import library_loader, { Library } from "./services/library_loader.ts";
|
||||
import type { init } from "i18next";
|
||||
import type { lint } from "./services/eslint.ts";
|
||||
import type { RelationType } from "./widgets/type_widgets/relation_map.ts";
|
||||
import type { Mermaid } from "mermaid";
|
||||
|
||||
interface ElectronProcess {
|
||||
type: string;
|
||||
@ -138,45 +139,6 @@ declare global {
|
||||
zoomOnClick: boolean
|
||||
})
|
||||
};
|
||||
interface MermaidApi {
|
||||
initialize(opts: {
|
||||
startOnLoad: boolean,
|
||||
theme: string,
|
||||
securityLevel: "antiscript"
|
||||
}): void;
|
||||
render(selector: string, data: string);
|
||||
}
|
||||
interface MermaidLoader {
|
||||
|
||||
}
|
||||
interface MermaidChartConfig {
|
||||
useMaxWidth: boolean;
|
||||
}
|
||||
interface MermaidConfig {
|
||||
theme: string;
|
||||
securityLevel: "antiscript",
|
||||
flow: MermaidChartConfig;
|
||||
sequence: MermaidChartConfig;
|
||||
gantt: MermaidChartConfig;
|
||||
class: MermaidChartConfig;
|
||||
state: MermaidChartConfig;
|
||||
pie: MermaidChartConfig;
|
||||
journey: MermaidChartConfig;
|
||||
git: MermaidChartConfig;
|
||||
}
|
||||
var mermaid: {
|
||||
mermaidAPI: MermaidApi;
|
||||
registerLayoutLoaders(loader: MermaidLoader);
|
||||
init(config: MermaidConfig, el: HTMLElement | JQuery<HTMLElement>);
|
||||
parse(content: string, opts: {
|
||||
suppressErrors: true
|
||||
}): Promise<{
|
||||
config: {
|
||||
layout: string;
|
||||
}
|
||||
}>
|
||||
};
|
||||
|
||||
interface CKCodeBlockLanguage {
|
||||
language: string;
|
||||
label: string;
|
||||
@ -207,7 +169,7 @@ declare global {
|
||||
enablePreview: boolean
|
||||
},
|
||||
mermaid: {
|
||||
lazyLoad: () => Promise<void>,
|
||||
lazyLoad: () => Promise<Mermaid>,
|
||||
config: MermaidConfig
|
||||
}
|
||||
});
|
||||
|
@ -7,6 +7,7 @@ import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";
|
||||
* This adds the following functionality:
|
||||
*
|
||||
* - Automatic handling of the preview when content or the note changes.
|
||||
* - Built-in pan and zoom functionality with automatic re-centering.
|
||||
*
|
||||
*/
|
||||
export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTypeWidget {
|
||||
|
@ -13,10 +13,10 @@ import dialogService from "../../services/dialog.js";
|
||||
import { initSyntaxHighlighting } from "./ckeditor/syntax_highlight.js";
|
||||
import options from "../../services/options.js";
|
||||
import toast from "../../services/toast.js";
|
||||
import { getMermaidConfig } from "../mermaid.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "../../services/mime_type_definitions.js";
|
||||
import { buildConfig, buildToolbarConfig } from "./ckeditor/config.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import { getMermaidConfig } from "./mermaid.js";
|
||||
|
||||
const ENABLE_INSPECTOR = false;
|
||||
|
||||
@ -279,7 +279,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
enablePreview: true // Enable preview view
|
||||
},
|
||||
mermaid: {
|
||||
lazyLoad: async () => await libraryLoader.requireLibrary(libraryLoader.MERMAID),
|
||||
lazyLoad: async () => (await import("mermaid")).default, // FIXME
|
||||
config: getMermaidConfig()
|
||||
}
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { MermaidConfig } from "mermaid";
|
||||
import library_loader from "../../services/library_loader.js";
|
||||
import { loadElkIfNeeded, postprocessMermaidSvg } from "../../services/mermaid.js";
|
||||
import AbstractSvgSplitTypeWidget from "./abstract_svg_split_type_widget.js";
|
||||
@ -11,8 +12,8 @@ export class MermaidTypeWidget extends AbstractSvgSplitTypeWidget {
|
||||
}
|
||||
|
||||
async renderSvg(content: string) {
|
||||
await library_loader.requireLibrary(library_loader.MERMAID);
|
||||
await loadElkIfNeeded(content);
|
||||
const mermaid = (await import("mermaid")).default;
|
||||
await loadElkIfNeeded(mermaid, content);
|
||||
|
||||
mermaid.mermaidAPI.initialize({
|
||||
startOnLoad: false,
|
||||
@ -28,19 +29,18 @@ export class MermaidTypeWidget extends AbstractSvgSplitTypeWidget {
|
||||
|
||||
export function getMermaidConfig(): MermaidConfig {
|
||||
const documentStyle = window.getComputedStyle(document.documentElement);
|
||||
const mermaidTheme = documentStyle.getPropertyValue("--mermaid-theme");
|
||||
const mermaidTheme = documentStyle.getPropertyValue("--mermaid-theme") as "default";
|
||||
|
||||
return {
|
||||
theme: mermaidTheme.trim(),
|
||||
theme: mermaidTheme.trim() as "default",
|
||||
securityLevel: "antiscript",
|
||||
// TODO: Are all these options correct?
|
||||
flow: { useMaxWidth: false },
|
||||
flowchart: { useMaxWidth: false },
|
||||
sequence: { useMaxWidth: false },
|
||||
gantt: { useMaxWidth: false },
|
||||
class: { useMaxWidth: false },
|
||||
state: { useMaxWidth: false },
|
||||
pie: { useMaxWidth: true },
|
||||
journey: { useMaxWidth: false },
|
||||
git: { useMaxWidth: false }
|
||||
gitGraph: { useMaxWidth: false }
|
||||
};
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import AbstractTextTypeWidget from "./abstract_text_type_widget.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import { applySyntaxHighlight } from "../../services/syntax_highlight.js";
|
||||
import { getMermaidConfig } from "../mermaid.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
import { getLocaleById } from "../../services/i18n.js";
|
||||
import { getMermaidConfig } from "./mermaid.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail-readonly-text note-detail-printable">
|
||||
@ -141,8 +141,8 @@ export default class ReadOnlyTextTypeWidget extends AbstractTextTypeWidget {
|
||||
});
|
||||
|
||||
// Initialize mermaid
|
||||
await libraryLoader.requireLibrary(libraryLoader.MERMAID);
|
||||
mermaid.init(getMermaidConfig(), this.$content.find(".mermaid-diagram"));
|
||||
const mermaid = (await import("mermaid")).default;
|
||||
mermaid.init(getMermaidConfig(), this.$content.find(".mermaid-diagram")[0]);
|
||||
}
|
||||
|
||||
async refreshIncludedNoteEvent({ noteId }: EventData<"refreshIncludedNote">) {
|
||||
|
@ -64,8 +64,6 @@ async function register(app: express.Application) {
|
||||
app.use(`/${assetPath}/node_modules/boxicons/css/`, persistentCacheStatic(path.join(srcRoot, "..", "node_modules/boxicons/css/")));
|
||||
app.use(`/${assetPath}/node_modules/boxicons/fonts/`, persistentCacheStatic(path.join(srcRoot, "..", "node_modules/boxicons/fonts/")));
|
||||
|
||||
app.use(`/${assetPath}/node_modules/mermaid/dist/`, persistentCacheStatic(path.join(srcRoot, "..", "node_modules/mermaid/dist/")));
|
||||
|
||||
app.use(`/${assetPath}/node_modules/jquery/dist/`, persistentCacheStatic(path.join(srcRoot, "..", "node_modules/jquery/dist/")));
|
||||
|
||||
app.use(`/${assetPath}/node_modules/jquery-hotkeys/`, persistentCacheStatic(path.join(srcRoot, "..", "node_modules/jquery-hotkeys/")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user