...
This commit is contained in:
		| @@ -32,10 +32,15 @@ class MarkdownEditor { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         // Update preview on change | ||||
|         this.editor.on('change', () => { | ||||
|         // Update preview on change with debouncing | ||||
|         this.editor.on('change', this.debounce(() => { | ||||
|             this.updatePreview(); | ||||
|         }); | ||||
|         }, 300)); | ||||
|  | ||||
|         // Initial preview render | ||||
|         setTimeout(() => { | ||||
|             this.updatePreview(); | ||||
|         }, 100); | ||||
|  | ||||
|         // Sync scroll | ||||
|         this.editor.on('scroll', () => { | ||||
| @@ -47,17 +52,21 @@ class MarkdownEditor { | ||||
|      * Initialize markdown parser | ||||
|      */ | ||||
|     initMarkdown() { | ||||
|         this.marked = window.marked; | ||||
|         this.marked.setOptions({ | ||||
|             breaks: true, | ||||
|             gfm: true, | ||||
|             highlight: (code, lang) => { | ||||
|                 if (lang && window.Prism.languages[lang]) { | ||||
|                     return window.Prism.highlight(code, window.Prism.languages[lang], lang); | ||||
|         if (window.marked) { | ||||
|             this.marked = window.marked; | ||||
|             this.marked.setOptions({ | ||||
|                 breaks: true, | ||||
|                 gfm: true, | ||||
|                 highlight: (code, lang) => { | ||||
|                     if (lang && window.Prism.languages[lang]) { | ||||
|                         return window.Prism.highlight(code, window.Prism.languages[lang], lang); | ||||
|                     } | ||||
|                     return code; | ||||
|                 } | ||||
|                 return code; | ||||
|             } | ||||
|         }); | ||||
|             }); | ||||
|         } else { | ||||
|             console.error('Marked library not found.'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -123,10 +132,9 @@ class MarkdownEditor { | ||||
|                 window.showNotification('✅ Saved', 'success'); | ||||
|             } | ||||
|  | ||||
|             // Trigger file tree reload | ||||
|             if (window.fileTree) { | ||||
|                 await window.fileTree.load(); | ||||
|                 window.fileTree.selectNode(path); | ||||
|             // Dispatch event to reload file tree | ||||
|             if (window.eventBus) { | ||||
|                 window.eventBus.dispatch('file-saved', path); | ||||
|             } | ||||
|         } catch (error) { | ||||
|             console.error('Failed to save file:', error); | ||||
| @@ -192,24 +200,66 @@ class MarkdownEditor { | ||||
|      */ | ||||
|     updatePreview() { | ||||
|         const markdown = this.editor.getValue(); | ||||
|         let html = window.marked.parse(markdown); | ||||
|         const previewDiv = this.previewElement; | ||||
|  | ||||
|         // Process mermaid diagrams | ||||
|         html = html.replace(/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g, (match, code) => { | ||||
|             const id = 'mermaid-' + Math.random().toString(36).substr(2, 9); | ||||
|             return `<div class="mermaid" id="${id}">${code}</div>`; | ||||
|         }); | ||||
|  | ||||
|         this.previewElement.innerHTML = html; | ||||
|  | ||||
|         // Render mermaid diagrams | ||||
|         if (window.mermaid) { | ||||
|             window.mermaid.init(undefined, this.previewElement.querySelectorAll('.mermaid')); | ||||
|         if (!markdown || !markdown.trim()) { | ||||
|             previewDiv.innerHTML = ` | ||||
|                 <div class="text-muted text-center mt-5"> | ||||
|                     <p>Start typing to see preview...</p> | ||||
|                 </div> | ||||
|             `; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Highlight code blocks | ||||
|         if (window.Prism) { | ||||
|             window.Prism.highlightAllUnder(this.previewElement); | ||||
|         try { | ||||
|             // Parse markdown to HTML | ||||
|             if (!this.marked) { | ||||
|                 console.error("Markdown parser (marked) not initialized."); | ||||
|                 previewDiv.innerHTML = `<div class="alert alert-danger">Preview engine not loaded.</div>`; | ||||
|                 return; | ||||
|             } | ||||
|             let html = this.marked.parse(markdown); | ||||
|  | ||||
|             // Replace mermaid code blocks with div containers | ||||
|             html = html.replace( | ||||
|                 /<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g, | ||||
|                 (match, code) => { | ||||
|                     const id = 'mermaid-' + Math.random().toString(36).substr(2, 9); | ||||
|                     return `<div class="mermaid" id="${id}">${code.trim()}</div>`; | ||||
|                 } | ||||
|             ); | ||||
|  | ||||
|             previewDiv.innerHTML = html; | ||||
|  | ||||
|             // Apply syntax highlighting to code blocks | ||||
|             const codeBlocks = previewDiv.querySelectorAll('pre code'); | ||||
|             codeBlocks.forEach(block => { | ||||
|                 const languageClass = Array.from(block.classList) | ||||
|                     .find(cls => cls.startsWith('language-')); | ||||
|                 if (languageClass && languageClass !== 'language-mermaid') { | ||||
|                     if (window.Prism) { | ||||
|                         window.Prism.highlightElement(block); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             // Render mermaid diagrams | ||||
|             const mermaidElements = previewDiv.querySelectorAll('.mermaid'); | ||||
|             if (mermaidElements.length > 0 && window.mermaid) { | ||||
|                 try { | ||||
|                     window.mermaid.contentLoaded(); | ||||
|                 } catch (error) { | ||||
|                     console.warn('Mermaid rendering error:', error); | ||||
|                 } | ||||
|             } | ||||
|         } catch (error) { | ||||
|             console.error('Preview rendering error:', error); | ||||
|             previewDiv.innerHTML = ` | ||||
|                 <div class="alert alert-danger" role="alert"> | ||||
|                     <strong>Error rendering preview:</strong><br> | ||||
|                     ${error.message} | ||||
|                 </div> | ||||
|             `; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -266,6 +316,21 @@ class MarkdownEditor { | ||||
|     setValue(content) { | ||||
|         this.editor.setValue(content); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Debounce function | ||||
|      */ | ||||
|     debounce(func, wait) { | ||||
|         let timeout; | ||||
|         return function executedFunction(...args) { | ||||
|             const later = () => { | ||||
|                 clearTimeout(timeout); | ||||
|                 func(...args); | ||||
|             }; | ||||
|             clearTimeout(timeout); | ||||
|             timeout = setTimeout(later, wait); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Export for use in other modules | ||||
|   | ||||
		Reference in New Issue
	
	Block a user