/** * Configuration Loader - Clean interface between Python and JavaScript * * This module provides the ONLY interface for Python-generated data. * All dynamic data from Python must be passed through this JSON configuration. */ class MarkitectConfig { constructor() { this.config = null; this.loaded = false; // Simple immediate loading - if script is loaded, DOM is ready this.loadConfig(); } loadConfig() { try { const configElement = document.getElementById('markitect-config'); if (!configElement) { throw new Error('Markitect configuration not found - missing markitect-config script element'); } this.config = JSON.parse(configElement.textContent); this.loaded = true; console.log('✅ Markitect configuration loaded successfully'); // Validate required fields this.validateConfig(); } catch (error) { console.error('❌ Failed to load Markitect configuration:', error); this.config = this.getDefaultConfig(); } } validateConfig() { const required = ['markdownContent', 'mode']; const missing = required.filter(key => !(key in this.config)); if (missing.length > 0) { console.warn('⚠️ Missing required config fields:', missing); } } getDefaultConfig() { return { markdownContent: '# Default Content\n\nConfiguration failed to load.', markdownContentWithDogtag: '# Default Content\n\nConfiguration failed to load.', dogtagContent: '', mode: 'edit', theme: 'github', keyboardShortcuts: true, autosave: false, sections: true, originalFilename: 'document', version: 'Markitect v0.8.1', repoName: 'Markitect', base64References: {} }; } // Getter methods for clean access get markdownContent() { return this.config.markdownContent || ''; } get markdownContentWithDogtag() { return this.config.markdownContentWithDogtag || this.markdownContent; } get dogtagContent() { return this.config.dogtagContent || ''; } get mode() { return this.config.mode || 'edit'; } get isEditMode() { return this.mode === 'edit'; } get isInsertMode() { return this.mode === 'insert'; } get theme() { return this.config.theme || 'github'; } get originalFilename() { return this.config.originalFilename || 'document'; } get version() { return this.config.version || 'Markitect v0.8.1'; } get repoName() { return this.config.repoName || 'Markitect'; } get keyboardShortcuts() { return this.config.keyboardShortcuts !== false; } get base64References() { return this.config.base64References || {}; } get restrictedHeadingLevels() { return this.config.restrictedHeadingLevels || [1, 2, 3]; } // Check if config is ready for access isReady() { return this.loaded && this.config !== null; } // Wait for config to be ready waitForReady(callback, maxWait = 5000) { const startTime = Date.now(); const checkReady = () => { if (this.isReady()) { callback(); } else if (Date.now() - startTime < maxWait) { setTimeout(checkReady, 50); } else { console.error('❌ Configuration loading timeout after', maxWait, 'ms'); callback(); // Call anyway with default config } }; checkReady(); } // Get full editor configuration object getEditorConfig() { if (!this.isReady()) { console.warn('⚠️ Configuration not ready, using defaults'); return this.getDefaultConfig(); } return { mode: this.mode, theme: this.theme, keyboardShortcuts: this.keyboardShortcuts, autosave: this.config.autosave || false, sections: this.config.sections !== false, originalFilename: this.originalFilename, version: this.version, repoName: this.repoName, restrictedHeadingLevels: this.restrictedHeadingLevels }; } } // Global configuration instance window.markitectConfig = new MarkitectConfig(); // Legacy compatibility - expose common config values globally window.editorConfig = window.markitectConfig.getEditorConfig(); window.markitectBase64References = window.markitectConfig.base64References; // Export for module use if (typeof module !== 'undefined' && module.exports) { module.exports = MarkitectConfig; }