feat: restore modern Abstract Control class system with compass positioning

- Replace old DocumentNavigator with sophisticated 507-line Control architecture
- Implement compass-based positioning system (N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW)
- Add four specialized controls with precise positioning:
  * ContentsControl (upper left - nw): Table of contents navigation
  * StatusControl (right - e): Document statistics and change tracking
  * DebugControl (lower right - se): Debug messages and system info
  * EditControl (upper right - ne): Document editing tools
- Integrate external JavaScript files following GUARDRAILS.md principles
- Add drag & drop, resize handles, expand/collapse, and hover behaviors
- Implement Fail Fast error handling with safe operation wrappers
- Preserve backup HTML files for reference and recovery validation
- Generate 144KB functional HTML vs previous 12KB broken output

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-12 01:47:29 +01:00
parent de49c76ff9
commit e0bc5daeeb
5 changed files with 8877 additions and 32 deletions

View File

@@ -1306,7 +1306,7 @@ MISSING: {len(missing_components)} components
return ""
def _get_clean_editor_scripts(self) -> str:
"""Load the modular editor JavaScript components for edit/insert modes."""
"""Load the modular editor JavaScript components from external files."""
from pathlib import Path
# Define the modular components to load in order
@@ -1314,7 +1314,12 @@ MISSING: {len(missing_components)} components
'js/core/section-manager.js',
'js/components/debug-panel.js',
'js/components/document-controls.js',
'js/components/dom-renderer.js'
'js/components/dom-renderer.js',
'js/controls/control-base.js',
'js/controls/contents-control.js',
'js/controls/status-control.js',
'js/controls/debug-control.js',
'js/controls/edit-control.js'
]
base_path = Path(__file__).parent / 'static'
@@ -1339,45 +1344,154 @@ MISSING: {len(missing_components)} components
# Add initialization script to wire up the components
initialization_script = """
// === Component Initialization ===
function initializeCleanEditor() {
console.log('🚀 Initializing Clean Editor Components...');
document.addEventListener('DOMContentLoaded', function() {
// Create container for the markdown content
const container = document.getElementById('markdown-content') || document.body;
try {
// Initialize components
const sectionManager = new SectionManager();
const domRenderer = new DOMRenderer(sectionManager, container);
const debugPanel = new DebugPanel();
const documentControls = new DocumentControls();
// Initialize components
const sectionManager = new SectionManager();
const domRenderer = new DOMRenderer(sectionManager, container);
const debugPanel = new DebugPanel();
const documentControls = new DocumentControls();
// Create document controls
documentControls.create();
// Create document controls
documentControls.create();
console.log('✓ Clean Editor initialized successfully');
console.log('✓ Click on any section to start editing');
// Step 4: Initialize modern Control-based architecture with compass positioning
console.log("🎛️ Initializing modern Control system with compass positioning...");
// Make components globally available for debugging
window.editorComponents = {
sectionManager,
domRenderer,
debugPanel,
documentControls
};
// ContentsControl (positioned upper left - nw)
const contentsControl = new ContentsControl();
contentsControl.control.config.position = 'nw'; // Upper left
contentsControl.createControl();
window.contentsControl = contentsControl;
} catch (error) {
console.error('❌ Clean Editor initialization failed:', error);
throw error;
// StatusControl (positioned right - e)
const statusControl = new StatusControl();
statusControl.control.config.position = 'e'; // Right
statusControl.createControl();
window.statusControl = statusControl;
// DebugControl (positioned lower right - se)
const debugControl = new DebugControl();
debugControl.control.config.position = 'se'; // Lower right
debugControl.createControl();
window.debugControl = debugControl;
// EditControl (positioned upper right - ne)
const editControl = new EditControl();
editControl.control.config.position = 'ne'; // Upper right
editControl.createControl();
window.editControl = editControl;
console.log("🎛️ Modern Control system initialized with compass positioning");
// Wire up event handlers
documentControls.setEventHandlers({
'save-document': () => {
console.log('Save document clicked');
try {
// Get current markdown content from section manager
const currentMarkdown = sectionManager.getDocumentMarkdown();
// Create filename with timestamp suffix following the established convention
const now = new Date();
const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-').replace('T', '-');
// Extract original filename from config or use default
const originalFilename = window.editorConfig?.originalFilename || 'document';
const editedFilename = `${originalFilename}-edited-${timestamp}.md`;
// Create and download the file
const blob = new Blob([currentMarkdown], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = editedFilename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// Log success to debug panel
debugPanel.addMessage(`Document saved as: ${editedFilename}`, 'SUCCESS');
console.log(`Document successfully saved as: ${editedFilename}`);
} catch (error) {
debugPanel.addMessage(`Save failed: ${error.message}`, 'ERROR');
console.error('Save error:', error);
}
},
'reset-all': () => {
console.log('Reset all clicked');
// Hide any open editors
domRenderer.hideCurrentEditor();
// Reset all sections to original state
const allSections = Array.from(sectionManager.sections.values());
allSections.forEach(section => {
section.resetToOriginal();
});
// Re-render all sections
domRenderer.renderAllSections(allSections);
debugPanel.addMessage(`Reset all sections to original state`, 'INFO');
},
'show-status': () => {
const status = sectionManager.getDocumentStatus();
alert(`Document Status:\\nTotal Sections: ${status.totalSections}\\nEditing Sections: ${status.editingSections}`);
},
'toggle-debug': () => {
debugPanel.toggle();
}
});
// Set up debug panel integration
sectionManager.on('sections-created', (data) => {
debugPanel.addMessage(`Created ${data.count} sections`, 'INFO');
});
sectionManager.on('edit-started', (data) => {
debugPanel.addMessage(`Edit started for section: ${data.sectionId}`, 'DEBUG');
});
sectionManager.on('changes-accepted', (data) => {
debugPanel.addMessage(`Changes accepted for section: ${data.sectionId}`, 'SUCCESS');
// Re-render the section to show updated content
const section = sectionManager.sections.get(data.sectionId);
if (section) {
const sectionElement = domRenderer.findSectionElement(data.sectionId);
if (sectionElement) {
const newElement = domRenderer.renderSection(section);
sectionElement.parentNode.replaceChild(newElement, sectionElement);
debugPanel.addMessage(`DOM updated for section: ${data.sectionId}`, 'INFO');
}
}
});
sectionManager.on('changes-cancelled', (data) => {
debugPanel.addMessage(`Changes cancelled for section: ${data.sectionId}`, 'WARNING');
});
// Initialize with markdown content
const markdownToRender = markdownContent || '';
if (markdownToRender.trim()) {
const sections = sectionManager.createSectionsFromMarkdown(markdownToRender);
domRenderer.renderAllSections(sections);
debugPanel.addMessage(`Initialized with ${sections.length} sections`, 'INFO');
} else {
debugPanel.addMessage('No markdown content to initialize', 'WARNING');
}
}
function initializeScrollIndicators() {
// Placeholder for scroll indicators - can be implemented later
console.log('📍 Scroll indicators initialized');
}
// Make components globally available for debugging
window.markitectComponents = {
sectionManager,
domRenderer,
debugPanel,
documentControls
};
console.log('Markitect modular editor initialized successfully');
});
"""
combined_script.append(initialization_script)
return '\n'.join(combined_script)