feat: remove legacy DocumentControls component
Some checks failed
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Some checks failed
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Remove deprecated DocumentControls from TestDrive JSUI plugin system: - Remove document-controls.js from plugin asset list - Remove script reference from HTML template - Delete legacy document-controls files - Consolidate all functionality into enhanced control panels All control panel functionality now provided by enhanced controls: - ContentsControl (NW): Table of contents and navigation - StatusControl (E): Document status and metrics - DebugControl (SE): Debug messages and system info - EditControl (NE): Editing tools including Reset All button 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- **BREAKING**: Legacy DocumentControls component from TestDrive JSUI plugin system - all control panel functionality now provided by enhanced control panels (ContentsControl, StatusControl, DebugControl, EditControl) with Reset All button functionality moved to EditControl for better maintainability and elimination of code duplication
|
||||||
|
|
||||||
## [0.9.0] - 2025-11-14
|
## [0.9.0] - 2025-11-14
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -1,289 +0,0 @@
|
|||||||
/**
|
|
||||||
* DocumentControlsLegacy Component
|
|
||||||
*
|
|
||||||
* Legacy implementation extracted from monolithic editor.js as part of architecture refactoring.
|
|
||||||
* Handles the floating control panel and document-level actions.
|
|
||||||
*
|
|
||||||
* ⚠️ LEGACY COMPONENT: This implementation is maintained for backward compatibility.
|
|
||||||
* New projects should use the modern control system components instead.
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - None (standalone component)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DocumentControlsLegacy - Legacy floating control panel manager
|
|
||||||
*
|
|
||||||
* @deprecated This is a legacy implementation. Use modern control components for new development.
|
|
||||||
*/
|
|
||||||
class DocumentControlsLegacy {
|
|
||||||
constructor() {
|
|
||||||
this.controlPanel = null;
|
|
||||||
this.buttons = new Map();
|
|
||||||
this.eventHandlers = new Map();
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the control panel and add it to the DOM
|
|
||||||
*/
|
|
||||||
create() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.destroy(); // Remove existing panel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also remove any existing panel with the same ID in the DOM
|
|
||||||
const existingPanel = document.getElementById('markitect-global-controls');
|
|
||||||
if (existingPanel && existingPanel.parentNode) {
|
|
||||||
existingPanel.parentNode.removeChild(existingPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the floating control panel
|
|
||||||
this.controlPanel = document.createElement('div');
|
|
||||||
this.controlPanel.id = 'markitect-global-controls';
|
|
||||||
this.controlPanel.style.cssText = `
|
|
||||||
position: fixed;
|
|
||||||
top: 20px;
|
|
||||||
right: 20px;
|
|
||||||
background: rgba(248, 249, 250, 0.95);
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 12px;
|
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
||||||
z-index: 1000;
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
min-width: 200px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Add title
|
|
||||||
const title = document.createElement('div');
|
|
||||||
title.style.cssText = `
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #495057;
|
|
||||||
border-bottom: 1px solid #dee2e6;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
`;
|
|
||||||
title.textContent = 'Document Controls';
|
|
||||||
|
|
||||||
// Create button container
|
|
||||||
const buttonContainer = document.createElement('div');
|
|
||||||
buttonContainer.id = 'button-container';
|
|
||||||
buttonContainer.style.cssText = `
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 6px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.controlPanel.appendChild(title);
|
|
||||||
this.controlPanel.appendChild(buttonContainer);
|
|
||||||
|
|
||||||
// Add default buttons
|
|
||||||
this.addDefaultButtons();
|
|
||||||
|
|
||||||
// Add debug messages container
|
|
||||||
this.addDebugContainer();
|
|
||||||
|
|
||||||
// Add to DOM
|
|
||||||
document.body.appendChild(this.controlPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add default buttons to the control panel
|
|
||||||
*/
|
|
||||||
addDefaultButtons() {
|
|
||||||
// Save Document button
|
|
||||||
this.addButton('save-document', '💾 Save Document', '#28a745');
|
|
||||||
|
|
||||||
// Reset All button
|
|
||||||
this.addButton('reset-all', '🔄 Reset All', '#ffc107', '#212529');
|
|
||||||
|
|
||||||
// Show Status button
|
|
||||||
this.addButton('show-status', '📊 Show Status', '#17a2b8');
|
|
||||||
|
|
||||||
// Debug button
|
|
||||||
this.addButton('toggle-debug', '🔍 Debug', '#6c757d');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add debug container to the control panel
|
|
||||||
*/
|
|
||||||
addDebugContainer() {
|
|
||||||
const debugContainer = document.createElement('div');
|
|
||||||
debugContainer.id = 'debug-messages-container';
|
|
||||||
debugContainer.style.cssText = `
|
|
||||||
margin-top: 12px;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #f8f9fa;
|
|
||||||
padding: 8px;
|
|
||||||
font-family: 'Courier New', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.4;
|
|
||||||
display: none;
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.controlPanel.appendChild(debugContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a button to the control panel
|
|
||||||
*/
|
|
||||||
addButton(id, text, backgroundColor, textColor = 'white') {
|
|
||||||
const buttonContainer = this.controlPanel.querySelector('#button-container');
|
|
||||||
if (!buttonContainer) {
|
|
||||||
throw new Error('Button container not found. Call create() first.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const button = document.createElement('button');
|
|
||||||
button.id = id;
|
|
||||||
button.textContent = text;
|
|
||||||
button.style.cssText = `
|
|
||||||
background: ${backgroundColor};
|
|
||||||
color: ${textColor};
|
|
||||||
border: none;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
`;
|
|
||||||
|
|
||||||
buttonContainer.appendChild(button);
|
|
||||||
this.buttons.set(id, button);
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a button from the control panel
|
|
||||||
*/
|
|
||||||
removeButton(id) {
|
|
||||||
const button = this.buttons.get(id);
|
|
||||||
if (button && button.parentNode) {
|
|
||||||
button.parentNode.removeChild(button);
|
|
||||||
this.buttons.delete(id);
|
|
||||||
this.eventHandlers.delete(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set event handlers for buttons
|
|
||||||
*/
|
|
||||||
setEventHandlers(handlers) {
|
|
||||||
for (const [buttonId, handler] of Object.entries(handlers)) {
|
|
||||||
const button = this.buttons.get(buttonId);
|
|
||||||
if (button) {
|
|
||||||
// Remove existing handler if any
|
|
||||||
if (this.eventHandlers.has(buttonId)) {
|
|
||||||
button.removeEventListener('click', this.eventHandlers.get(buttonId));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new handler
|
|
||||||
button.addEventListener('click', handler);
|
|
||||||
this.eventHandlers.set(buttonId, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the control panel
|
|
||||||
*/
|
|
||||||
show() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.controlPanel.style.display = 'block';
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide the control panel
|
|
||||||
*/
|
|
||||||
hide() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.controlPanel.style.display = 'none';
|
|
||||||
this.isVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update status display (can be extended as needed)
|
|
||||||
*/
|
|
||||||
updateStatus(status) {
|
|
||||||
// This method can be extended to show status information
|
|
||||||
// For now, it just stores the status for potential display
|
|
||||||
this.lastStatus = status;
|
|
||||||
|
|
||||||
// Could update a status indicator in the panel if needed
|
|
||||||
if (status && this.controlPanel) {
|
|
||||||
const title = this.controlPanel.querySelector('div');
|
|
||||||
if (title) {
|
|
||||||
const statusText = `Document Controls (${status.totalSections} sections, ${status.editingSections} editing)`;
|
|
||||||
// Could update title or add status indicator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the control panel element
|
|
||||||
*/
|
|
||||||
getControlPanel() {
|
|
||||||
return this.controlPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the control panel and clean up
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
if (this.controlPanel && this.controlPanel.parentNode) {
|
|
||||||
this.controlPanel.parentNode.removeChild(this.controlPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up references
|
|
||||||
this.controlPanel = null;
|
|
||||||
this.buttons.clear();
|
|
||||||
this.eventHandlers.clear();
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the control panel is visible
|
|
||||||
*/
|
|
||||||
isVisible() {
|
|
||||||
return this.isVisible && this.controlPanel && this.controlPanel.style.display !== 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all button IDs
|
|
||||||
*/
|
|
||||||
getButtonIds() {
|
|
||||||
return Array.from(this.buttons.keys());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific button by ID
|
|
||||||
*/
|
|
||||||
getButton(id) {
|
|
||||||
return this.buttons.get(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export for use in tests and other modules
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
module.exports = { DocumentControlsLegacy };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export for browser use and global access
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
window.DocumentControlsLegacy = DocumentControlsLegacy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also make available in global for tests
|
|
||||||
if (typeof global !== 'undefined') {
|
|
||||||
global.DocumentControlsLegacy = DocumentControlsLegacy;
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,6 @@ class TestDriveJSUIEngine(RenderingEnginePlugin):
|
|||||||
"static/js/core/debug-system.js",
|
"static/js/core/debug-system.js",
|
||||||
"static/js/core/section-manager.js",
|
"static/js/core/section-manager.js",
|
||||||
"static/js/components/debug-panel.js",
|
"static/js/components/debug-panel.js",
|
||||||
"static/js/components/document-controls.js",
|
|
||||||
"static/js/components/dom-renderer.js",
|
"static/js/components/dom-renderer.js",
|
||||||
"static/js/controls/control-base.js",
|
"static/js/controls/control-base.js",
|
||||||
"static/js/controls/contents-control.js",
|
"static/js/controls/contents-control.js",
|
||||||
|
|||||||
@@ -75,12 +75,7 @@ const MarkitectMain = {
|
|||||||
console.log('✅ DebugPanel initialized');
|
console.log('✅ DebugPanel initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize document controls
|
// Legacy DocumentControls removed - functionality now in enhanced control panels
|
||||||
if (typeof DocumentControls !== 'undefined') {
|
|
||||||
this.documentControls = new DocumentControls();
|
|
||||||
this.documentControls.create();
|
|
||||||
console.log('✅ DocumentControls initialized');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Initialize enhanced control panels with compass positioning
|
// Initialize enhanced control panels with compass positioning
|
||||||
@@ -124,73 +119,11 @@ const MarkitectMain = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Setup event handlers
|
// Setup core event handlers (enhanced control panels handle their own events)
|
||||||
setupEventHandlers: function() {
|
setupEventHandlers: function() {
|
||||||
console.log('🔌 Setting up event handlers...');
|
console.log('🔌 Setting up core event handlers...');
|
||||||
|
|
||||||
if (!this.documentControls) return;
|
// Setup section manager event handlers for debug panel
|
||||||
|
|
||||||
this.documentControls.setEventHandlers({
|
|
||||||
'save-document': () => {
|
|
||||||
console.log('💾 Save document clicked');
|
|
||||||
try {
|
|
||||||
const currentMarkdown = this.sectionManager.getDocumentMarkdown();
|
|
||||||
const now = new Date();
|
|
||||||
const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-').replace('T', '-');
|
|
||||||
const filename = `${this.config.originalFilename}-edited-${timestamp}.md`;
|
|
||||||
|
|
||||||
const blob = new Blob([currentMarkdown], { type: 'text/markdown' });
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = filename;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
document.body.removeChild(a);
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
|
|
||||||
if (this.debugPanel) {
|
|
||||||
this.debugPanel.addMessage(`Document saved as: ${filename}`, 'SUCCESS');
|
|
||||||
}
|
|
||||||
console.log(`✅ Document saved as: ${filename}`);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
if (this.debugPanel) {
|
|
||||||
this.debugPanel.addMessage(`Save failed: ${error.message}`, 'ERROR');
|
|
||||||
}
|
|
||||||
console.error('❌ Save error:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'reset-all': () => {
|
|
||||||
console.log('🔄 Reset all clicked');
|
|
||||||
try {
|
|
||||||
this.domRenderer.hideCurrentEditor();
|
|
||||||
const allSections = Array.from(this.sectionManager.sections.values());
|
|
||||||
allSections.forEach(section => section.resetToOriginal());
|
|
||||||
this.domRenderer.renderAllSections(allSections);
|
|
||||||
|
|
||||||
if (this.debugPanel) {
|
|
||||||
this.debugPanel.addMessage('Reset all sections to original state', 'INFO');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Reset all failed:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'show-status': () => {
|
|
||||||
const status = this.sectionManager.getDocumentStatus();
|
|
||||||
alert(`Document Status:\nTotal Sections: ${status.totalSections}\nEditing Sections: ${status.editingSections}`);
|
|
||||||
},
|
|
||||||
|
|
||||||
'toggle-debug': () => {
|
|
||||||
if (this.debugPanel) {
|
|
||||||
this.debugPanel.toggle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Setup section manager event handlers
|
|
||||||
if (this.sectionManager && this.debugPanel) {
|
if (this.sectionManager && this.debugPanel) {
|
||||||
this.sectionManager.on('sections-created', (data) => {
|
this.sectionManager.on('sections-created', (data) => {
|
||||||
this.debugPanel.addMessage(`Created ${data.count} sections`, 'INFO');
|
this.debugPanel.addMessage(`Created ${data.count} sections`, 'INFO');
|
||||||
@@ -209,6 +142,13 @@ const MarkitectMain = {
|
|||||||
this.debugPanel.addMessage(`Changes cancelled for section: ${data.sectionId}`, 'WARNING');
|
this.debugPanel.addMessage(`Changes cancelled for section: ${data.sectionId}`, 'WARNING');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make core components available globally for enhanced controls
|
||||||
|
window.sectionManager = this.sectionManager;
|
||||||
|
window.domRenderer = this.domRenderer;
|
||||||
|
window.debugPanel = this.debugPanel;
|
||||||
|
|
||||||
|
console.log('✅ Core event handlers and global references set up');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Render content using the configuration
|
// Render content using the configuration
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
<script src="markitect/static/js/core/debug-system.js"></script>
|
<script src="markitect/static/js/core/debug-system.js"></script>
|
||||||
<script src="markitect/static/js/core/section-manager.js"></script>
|
<script src="markitect/static/js/core/section-manager.js"></script>
|
||||||
<script src="markitect/static/js/components/debug-panel.js"></script>
|
<script src="markitect/static/js/components/debug-panel.js"></script>
|
||||||
<script src="markitect/static/js/components/document-controls.js"></script>
|
|
||||||
<script src="markitect/static/js/components/dom-renderer.js"></script>
|
<script src="markitect/static/js/components/dom-renderer.js"></script>
|
||||||
<script src="markitect/static/js/controls/control-base.js"></script>
|
<script src="markitect/static/js/controls/control-base.js"></script>
|
||||||
<script src="markitect/static/js/controls/contents-control.js"></script>
|
<script src="markitect/static/js/controls/contents-control.js"></script>
|
||||||
|
|||||||
@@ -1,279 +0,0 @@
|
|||||||
/**
|
|
||||||
* DocumentControls Component
|
|
||||||
*
|
|
||||||
* Extracted from monolithic editor.js as part of architecture refactoring.
|
|
||||||
* Handles the floating control panel and document-level actions.
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - None (standalone component)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DocumentControls - Manages the floating control panel and its buttons
|
|
||||||
*/
|
|
||||||
class DocumentControls {
|
|
||||||
constructor() {
|
|
||||||
this.controlPanel = null;
|
|
||||||
this.buttons = new Map();
|
|
||||||
this.eventHandlers = new Map();
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the control panel and add it to the DOM
|
|
||||||
*/
|
|
||||||
create() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.destroy(); // Remove existing panel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also remove any existing panel with the same ID in the DOM
|
|
||||||
const existingPanel = document.getElementById('markitect-global-controls');
|
|
||||||
if (existingPanel && existingPanel.parentNode) {
|
|
||||||
existingPanel.parentNode.removeChild(existingPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the floating control panel
|
|
||||||
this.controlPanel = document.createElement('div');
|
|
||||||
this.controlPanel.id = 'markitect-global-controls';
|
|
||||||
this.controlPanel.style.cssText = `
|
|
||||||
position: fixed;
|
|
||||||
top: 20px;
|
|
||||||
right: 20px;
|
|
||||||
background: rgba(248, 249, 250, 0.95);
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 12px;
|
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
||||||
z-index: 1000;
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
min-width: 200px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Add title
|
|
||||||
const title = document.createElement('div');
|
|
||||||
title.style.cssText = `
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #495057;
|
|
||||||
border-bottom: 1px solid #dee2e6;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
`;
|
|
||||||
title.textContent = 'Document Controls';
|
|
||||||
|
|
||||||
// Create button container
|
|
||||||
const buttonContainer = document.createElement('div');
|
|
||||||
buttonContainer.id = 'button-container';
|
|
||||||
buttonContainer.style.cssText = `
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 6px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.controlPanel.appendChild(title);
|
|
||||||
this.controlPanel.appendChild(buttonContainer);
|
|
||||||
|
|
||||||
// Add default buttons
|
|
||||||
this.addDefaultButtons();
|
|
||||||
|
|
||||||
// Add debug messages container
|
|
||||||
this.addDebugContainer();
|
|
||||||
|
|
||||||
// Add to DOM
|
|
||||||
document.body.appendChild(this.controlPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add default buttons to the control panel
|
|
||||||
*/
|
|
||||||
addDefaultButtons() {
|
|
||||||
// Save Document button
|
|
||||||
this.addButton('save-document', '💾 Save Document', '#28a745');
|
|
||||||
|
|
||||||
// Reset All button
|
|
||||||
this.addButton('reset-all', '🔄 Reset All', '#ffc107', '#212529');
|
|
||||||
|
|
||||||
// Show Status button
|
|
||||||
this.addButton('show-status', '📊 Show Status', '#17a2b8');
|
|
||||||
|
|
||||||
// Debug button
|
|
||||||
this.addButton('toggle-debug', '🔍 Debug', '#6c757d');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add debug container to the control panel
|
|
||||||
*/
|
|
||||||
addDebugContainer() {
|
|
||||||
const debugContainer = document.createElement('div');
|
|
||||||
debugContainer.id = 'debug-messages-container';
|
|
||||||
debugContainer.style.cssText = `
|
|
||||||
margin-top: 12px;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #f8f9fa;
|
|
||||||
padding: 8px;
|
|
||||||
font-family: 'Courier New', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.4;
|
|
||||||
display: none;
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.controlPanel.appendChild(debugContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a button to the control panel
|
|
||||||
*/
|
|
||||||
addButton(id, text, backgroundColor, textColor = 'white') {
|
|
||||||
const buttonContainer = this.controlPanel.querySelector('#button-container');
|
|
||||||
if (!buttonContainer) {
|
|
||||||
throw new Error('Button container not found. Call create() first.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const button = document.createElement('button');
|
|
||||||
button.id = id;
|
|
||||||
button.textContent = text;
|
|
||||||
button.style.cssText = `
|
|
||||||
background: ${backgroundColor};
|
|
||||||
color: ${textColor};
|
|
||||||
border: none;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
`;
|
|
||||||
|
|
||||||
buttonContainer.appendChild(button);
|
|
||||||
this.buttons.set(id, button);
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a button from the control panel
|
|
||||||
*/
|
|
||||||
removeButton(id) {
|
|
||||||
const button = this.buttons.get(id);
|
|
||||||
if (button && button.parentNode) {
|
|
||||||
button.parentNode.removeChild(button);
|
|
||||||
this.buttons.delete(id);
|
|
||||||
this.eventHandlers.delete(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set event handlers for buttons
|
|
||||||
*/
|
|
||||||
setEventHandlers(handlers) {
|
|
||||||
for (const [buttonId, handler] of Object.entries(handlers)) {
|
|
||||||
const button = this.buttons.get(buttonId);
|
|
||||||
if (button) {
|
|
||||||
// Remove existing handler if any
|
|
||||||
if (this.eventHandlers.has(buttonId)) {
|
|
||||||
button.removeEventListener('click', this.eventHandlers.get(buttonId));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new handler
|
|
||||||
button.addEventListener('click', handler);
|
|
||||||
this.eventHandlers.set(buttonId, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the control panel
|
|
||||||
*/
|
|
||||||
show() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.controlPanel.style.display = 'block';
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide the control panel
|
|
||||||
*/
|
|
||||||
hide() {
|
|
||||||
if (this.controlPanel) {
|
|
||||||
this.controlPanel.style.display = 'none';
|
|
||||||
this.isVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update status display (can be extended as needed)
|
|
||||||
*/
|
|
||||||
updateStatus(status) {
|
|
||||||
// This method can be extended to show status information
|
|
||||||
// For now, it just stores the status for potential display
|
|
||||||
this.lastStatus = status;
|
|
||||||
|
|
||||||
// Could update a status indicator in the panel if needed
|
|
||||||
if (status && this.controlPanel) {
|
|
||||||
const title = this.controlPanel.querySelector('div');
|
|
||||||
if (title) {
|
|
||||||
const statusText = `Document Controls (${status.totalSections} sections, ${status.editingSections} editing)`;
|
|
||||||
// Could update title or add status indicator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the control panel element
|
|
||||||
*/
|
|
||||||
getControlPanel() {
|
|
||||||
return this.controlPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the control panel and clean up
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
if (this.controlPanel && this.controlPanel.parentNode) {
|
|
||||||
this.controlPanel.parentNode.removeChild(this.controlPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up references
|
|
||||||
this.controlPanel = null;
|
|
||||||
this.buttons.clear();
|
|
||||||
this.eventHandlers.clear();
|
|
||||||
this.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the control panel is visible
|
|
||||||
*/
|
|
||||||
isVisible() {
|
|
||||||
return this.isVisible && this.controlPanel && this.controlPanel.style.display !== 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all button IDs
|
|
||||||
*/
|
|
||||||
getButtonIds() {
|
|
||||||
return Array.from(this.buttons.keys());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific button by ID
|
|
||||||
*/
|
|
||||||
getButton(id) {
|
|
||||||
return this.buttons.get(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export for use in tests and other modules
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
module.exports = { DocumentControls };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export for browser use
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
window.DocumentControls = DocumentControls;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user