main
js 83 lines 2.12 KB
Raw
1 import { createStore } from "/js/AlpineStore.js";
2 import { renderSafeMarkdown } from "/js/safe-markdown.js";
3
4 export const store = createStore("markdownModal", {
5 title: "",
6 content: "",
7 error: null,
8 viewer: "rendered",
9 editor: null,
10
11 open(title, content, options = {}) {
12 this.title = title;
13 this.content = content;
14 this.error = null;
15 this.viewer = options.viewer || "rendered";
16 this.destroyEditor();
17 },
18
19 get renderedHtml() {
20 if (!this.content) return "";
21 return renderSafeMarkdown(this.content);
22 },
23
24 get isAce() {
25 return this.viewer === "ace";
26 },
27
28 onOpen() {
29 if (this.isAce) {
30 this.scheduleEditorInit();
31 }
32 },
33
34 scheduleEditorInit() {
35 window.requestAnimationFrame(() => {
36 if (!this.isAce || this.error) return;
37 window.requestAnimationFrame(() => this.initEditor());
38 });
39 },
40
41 initEditor() {
42 const container = document.getElementById("markdown-ace-viewer-container");
43 if (!container) return;
44
45 this.destroyEditor();
46
47 if (!window.ace?.edit) {
48 this.error = "Editor library not loaded";
49 return;
50 }
51
52 const editor = window.ace.edit("markdown-ace-viewer-container");
53 if (!editor) {
54 this.error = "Failed to initialize editor";
55 return;
56 }
57
58 const darkMode = window.localStorage?.getItem("darkMode");
59 const theme = darkMode !== "false" ? "ace/theme/github_dark" : "ace/theme/tomorrow";
60
61 this.editor = editor;
62 this.editor.setTheme(theme);
63 this.editor.session.setMode("ace/mode/markdown");
64 this.editor.setValue(this.content || "", -1);
65 this.editor.setReadOnly(true);
66 this.editor.clearSelection();
67 },
68
69 destroyEditor() {
70 if (this.editor?.destroy) {
71 this.editor.destroy();
72 }
73 this.editor = null;
74 },
75
76 cleanup() {
77 this.destroyEditor();
78 this.title = "";
79 this.content = "";
80 this.error = null;
81 this.viewer = "rendered";
82 },
83 });