No file specified. Drag a .md file onto the window or open one from the command line.
'; + return; + } + + // 2. Load state/preferences + this.state = await window.mdview.getState(); + + // 3. Read file + const content = await window.mdview.readFile(filePath); + const fileSize = FileScanner.getFileSize(content); + + // 4. Create loading UI + const loadingDiv = this.createLoadingOverlay(); + const progressIndicator = this.createProgressIndicator(); + document.body.appendChild(loadingDiv); + document.body.appendChild(progressIndicator); + + // Activate body class for CSS scoping + document.body.classList.add('mdview-active'); + + // 5. Apply theme + const theme = this.state.preferences.theme || 'github-light'; + await this.themeEngine.applyTheme(theme); + + // 6. Set up progress callback + const cleanupProgress = this.renderPipeline.onProgress((progress: RenderProgress) => { + this.updateProgress(progressIndicator, loadingDiv, progress); + }); + + // 7. Render + await this.renderPipeline.render({ + container, + markdown: content, + progressive: fileSize > 500000, + filePath, + theme, + preferences: this.state.preferences, + useCache: true, + useWorkers: false, // Workers not available in Electron renderer with contextIsolation + }); + + cleanupProgress(); + loadingDiv.remove(); + + // 8. Post-render: TOC + if (this.state.preferences.showToc) { + const headings = this.extractHeadings(container); + if (headings.length > 0) { + this.tocRenderer = new TocRenderer(headings, { + maxDepth: this.state.preferences.tocMaxDepth ?? 6, + autoCollapse: this.state.preferences.tocAutoCollapse ?? false, + position: this.state.preferences.tocPosition ?? 'left', + style: this.state.preferences.tocStyle ?? 'floating', + }); + this.tocRenderer.render(container); + } + } + + // 9. Post-render: Export UI + this.exportUI = new ExportUI({ + messaging: new ElectronMessagingAdapter(), + }); + this.exportUI.render(container); + + // 10. Post-render: Comments + if (this.state.preferences.commentsEnabled !== false) { + this.commentManager = new CommentManager({ + file: this.fileAdapter, + identity: this.identityAdapter, + }); + await this.commentManager.initialize(content, filePath, container); + } + + // 11. Auto-reload + if (this.state.preferences.autoReload) { + this.setupAutoReload(filePath, container, content); + } + + // 12. Listen for preference/theme updates from main + this.setupEventListeners(container, filePath); + } catch (error) { + console.error('[mdview] Initialization error:', error); + container.innerHTML = `Error loading file: ${String(error)}
`; + } + } + + private createLoadingOverlay(): HTMLElement { + const div = document.createElement('div'); + div.id = 'mdview-loading-overlay'; + div.className = 'mdview-loading'; + div.textContent = 'Rendering markdown...'; + return div; + } + + private createProgressIndicator(): HTMLElement { + const div = document.createElement('div'); + div.id = 'mdview-progress-indicator'; + div.innerHTML = ` +