| 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 | }); |