Add the missing "Reset All" functionality from Legacy Document Control to the enhanced EditControl panel for complete feature parity. ## New Functionality - Added "Reset All" button in Document Actions section - Comprehensive reset functionality with user confirmation - Resets font size, editing mode, unsaved changes, highlights - Integrates with SectionManager, DocumentControls, and DebugControl - Offers page reload as ultimate fallback for complete reset ## Implementation Details - Button styled consistently with Legacy Document Control (🔄 Reset All) - Uses #ffc107 background with #212529 text to match legacy styling - Comprehensive confirmation dialog explains all actions - Safe operation wrapper with proper error handling - Graceful fallbacks when integrated components are unavailable ## Integration - Deployed to both markitect system and deployment source - Compatible with existing enhanced ControlBase architecture - Maintains consistency with other EditControl actions - Ready for immediate use in production environment Users now have access to the familiar Reset All functionality within the modern enhanced control panel system. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
568 lines
23 KiB
JavaScript
568 lines
23 KiB
JavaScript
/**
|
|
* EditControl - Document Editing Tools and Actions Control
|
|
*
|
|
* Provides a comprehensive set of document editing tools including text formatting,
|
|
* document actions (print, save, export), navigation helpers, and editing modes.
|
|
* Designed to enhance the writing and editing experience within the TestDrive-JSUI
|
|
* environment.
|
|
*
|
|
* Features:
|
|
* - Document actions (print, save, export to various formats)
|
|
* - Text formatting tools (bold, italic, headers)
|
|
* - Navigation helpers (scroll to top/bottom, go to line)
|
|
* - Word processing features (find/replace, word count)
|
|
* - Accessibility tools (font size, contrast adjustment)
|
|
* - Markdown formatting shortcuts
|
|
*
|
|
* Dependencies:
|
|
* - ControlBase (base control functionality)
|
|
*/
|
|
|
|
/**
|
|
* EditControl - Comprehensive document editing control
|
|
*
|
|
* This control provides writers and editors with essential tools for document
|
|
* creation and modification. It includes both basic text operations and
|
|
* advanced features for content management and formatting.
|
|
*/
|
|
class EditControl extends ControlBase {
|
|
constructor() {
|
|
super();
|
|
|
|
// Configure for editing functionality
|
|
this.config = {
|
|
icon: '✏️',
|
|
title: 'Edit',
|
|
className: 'edit-control',
|
|
defaultContent: 'Document editing tools loading...',
|
|
ariaLabel: 'Document Edit Control',
|
|
position: 'e' // East positioning
|
|
};
|
|
|
|
// Edit control state
|
|
this.editingMode = 'view'; // 'view', 'edit', 'preview'
|
|
this.fontSize = 16;
|
|
this.lastSaveTime = null;
|
|
this.unsavedChanges = false;
|
|
this.shortcuts = new Map();
|
|
|
|
this.initializeShortcuts();
|
|
}
|
|
|
|
/**
|
|
* Initialize keyboard shortcuts for editing
|
|
*/
|
|
initializeShortcuts() {
|
|
this.shortcuts.set('Ctrl+S', () => this.saveDocument());
|
|
this.shortcuts.set('Ctrl+P', () => this.printDocument());
|
|
this.shortcuts.set('Ctrl+F', () => this.showFindDialog());
|
|
this.shortcuts.set('Ctrl+B', () => this.toggleBold());
|
|
this.shortcuts.set('Ctrl+I', () => this.toggleItalic());
|
|
this.shortcuts.set('Escape', () => this.exitEditMode());
|
|
}
|
|
|
|
/**
|
|
* Generate the main editing tools HTML
|
|
*/
|
|
generateEditToolsHTML() {
|
|
return this.safeOperation(() => {
|
|
return `
|
|
<div style="padding: 1rem; font-size: 0.8rem;">
|
|
<h4 style="margin-top: 0; margin-bottom: 1rem;">Edit Tools</h4>
|
|
|
|
<!-- Document Actions -->
|
|
<div class="action-section" style="margin-bottom: 1rem;">
|
|
<h5 style="margin: 0 0 0.5rem 0; font-size: 0.9em; color: #666;">Document Actions</h5>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.printDocument()"
|
|
style="width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #28a745; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.8rem;">
|
|
🖨️ Print Document
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.saveDocument()"
|
|
style="width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #007bff; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.8rem;">
|
|
💾 Save Changes
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.exportDocument()"
|
|
style="width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #17a2b8; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.8rem;">
|
|
📄 Export Document
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.resetAll()"
|
|
style="width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #ffc107; color: #212529; border: none; border-radius: 3px; cursor: pointer; font-size: 0.8rem;">
|
|
🔄 Reset All
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Navigation Tools -->
|
|
<div class="navigation-section" style="margin-bottom: 1rem;">
|
|
<h5 style="margin: 0 0 0.5rem 0; font-size: 0.9em; color: #666;">Navigation</h5>
|
|
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem;">
|
|
<button onclick="this.closest('.edit-control').editControl.scrollToTop()"
|
|
style="padding: 0.4rem; background: #6c757d; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
⬆️ Top
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.scrollToBottom()"
|
|
style="padding: 0.4rem; background: #6c757d; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
⬇️ Bottom
|
|
</button>
|
|
</div>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.showGoToLine()"
|
|
style="width: 100%; padding: 0.4rem; margin-top: 0.3rem; background: #6c757d; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
🎯 Go to Line
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Text Tools -->
|
|
<div class="text-section" style="margin-bottom: 1rem;">
|
|
<h5 style="margin: 0 0 0.5rem 0; font-size: 0.9em; color: #666;">Text Tools</h5>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.showFindReplace()"
|
|
style="width: 100%; padding: 0.4rem; margin-bottom: 0.3rem; background: #ffc107; color: #000; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
🔍 Find & Replace
|
|
</button>
|
|
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem; margin-bottom: 0.3rem;">
|
|
<button onclick="this.closest('.edit-control').editControl.increaseFontSize()"
|
|
style="padding: 0.4rem; background: #20c997; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
🔍+ Font
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.decreaseFontSize()"
|
|
style="padding: 0.4rem; background: #20c997; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
🔍- Font
|
|
</button>
|
|
</div>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.copyLink()"
|
|
style="width: 100%; padding: 0.4rem; margin-bottom: 0.3rem; background: #fd7e14; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
📋 Copy Page Link
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Markdown Tools -->
|
|
<div class="markdown-section" style="margin-bottom: 1rem;">
|
|
<h5 style="margin: 0 0 0.5rem 0; font-size: 0.9em; color: #666;">Markdown Tools</h5>
|
|
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem;">
|
|
<button onclick="this.closest('.edit-control').editControl.insertMarkdown('**', '**', 'Bold text')"
|
|
style="padding: 0.4rem; background: #495057; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
**B**
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.insertMarkdown('*', '*', 'Italic text')"
|
|
style="padding: 0.4rem; background: #495057; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
*I*
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.insertMarkdown('## ', '', 'Heading')"
|
|
style="padding: 0.4rem; background: #495057; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
H2
|
|
</button>
|
|
|
|
<button onclick="this.closest('.edit-control').editControl.insertMarkdown('- ', '', 'List item')"
|
|
style="padding: 0.4rem; background: #495057; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.7rem;">
|
|
•List
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status Info -->
|
|
<div class="status-section" style="border-top: 1px solid #eee; padding-top: 0.5rem;">
|
|
<div style="font-size: 0.7rem; color: #666;">
|
|
<div>Mode: <span style="color: #007bff;">${this.editingMode}</span></div>
|
|
<div>Font: <span style="color: #007bff;">${this.fontSize}px</span></div>
|
|
${this.lastSaveTime ? `<div>Saved: ${new Date(this.lastSaveTime).toLocaleTimeString()}</div>` : ''}
|
|
${this.unsavedChanges ? '<div style="color: #dc3545;">⚠️ Unsaved changes</div>' : ''}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
}, '<p>Error generating edit tools</p>', 'generateEditToolsHTML');
|
|
}
|
|
|
|
/**
|
|
* Print the document
|
|
*/
|
|
printDocument() {
|
|
return this.safeOperation(() => {
|
|
window.print();
|
|
|
|
// Show feedback
|
|
this.showActionFeedback('🖨️ Print dialog opened', '#28a745');
|
|
}, null, 'printDocument');
|
|
}
|
|
|
|
/**
|
|
* Save document (placeholder - would integrate with actual save system)
|
|
*/
|
|
saveDocument() {
|
|
return this.safeOperation(() => {
|
|
// In a real implementation, this would save to a backend
|
|
this.lastSaveTime = Date.now();
|
|
this.unsavedChanges = false;
|
|
|
|
// Update display
|
|
this.buildContent();
|
|
|
|
// Show feedback
|
|
this.showActionFeedback('💾 Document saved', '#007bff');
|
|
}, null, 'saveDocument');
|
|
}
|
|
|
|
/**
|
|
* Export document to various formats
|
|
*/
|
|
exportDocument() {
|
|
return this.safeOperation(() => {
|
|
const contentArea = document.querySelector('#markitect-content') || document.body;
|
|
const htmlContent = contentArea.innerHTML;
|
|
const textContent = contentArea.textContent;
|
|
|
|
// Create export menu
|
|
const exportMenu = document.createElement('div');
|
|
exportMenu.style.cssText = `
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: white;
|
|
border: 2px solid #007bff;
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
z-index: 10000;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
`;
|
|
|
|
exportMenu.innerHTML = `
|
|
<h4 style="margin-top: 0;">Export Document</h4>
|
|
<button onclick="this.parentElement.exportAsHTML()" style="display: block; width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #28a745; color: white; border: none; border-radius: 3px; cursor: pointer;">
|
|
Export as HTML
|
|
</button>
|
|
<button onclick="this.parentElement.exportAsText()" style="display: block; width: 100%; padding: 0.5rem; margin-bottom: 0.3rem; background: #17a2b8; color: white; border: none; border-radius: 3px; cursor: pointer;">
|
|
Export as Text
|
|
</button>
|
|
<button onclick="this.parentElement.exportAsMarkdown()" style="display: block; width: 100%; padding: 0.5rem; margin-bottom: 1rem; background: #6f42c1; color: white; border: none; border-radius: 3px; cursor: pointer;">
|
|
Export as Markdown
|
|
</button>
|
|
<button onclick="document.body.removeChild(this.parentElement)" style="width: 100%; padding: 0.3rem; background: #6c757d; color: white; border: none; border-radius: 3px; cursor: pointer;">
|
|
Cancel
|
|
</button>
|
|
`;
|
|
|
|
// Add export functions
|
|
exportMenu.exportAsHTML = () => {
|
|
this.downloadFile(htmlContent, 'document.html', 'text/html');
|
|
document.body.removeChild(exportMenu);
|
|
};
|
|
|
|
exportMenu.exportAsText = () => {
|
|
this.downloadFile(textContent, 'document.txt', 'text/plain');
|
|
document.body.removeChild(exportMenu);
|
|
};
|
|
|
|
exportMenu.exportAsMarkdown = () => {
|
|
// Simple HTML to Markdown conversion (basic)
|
|
let markdown = htmlContent
|
|
.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n\n')
|
|
.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n\n')
|
|
.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n\n')
|
|
.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n')
|
|
.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**')
|
|
.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*')
|
|
.replace(/<[^>]*>/g, ''); // Remove remaining HTML tags
|
|
|
|
this.downloadFile(markdown, 'document.md', 'text/markdown');
|
|
document.body.removeChild(exportMenu);
|
|
};
|
|
|
|
document.body.appendChild(exportMenu);
|
|
|
|
}, null, 'exportDocument');
|
|
}
|
|
|
|
/**
|
|
* Download a file with given content
|
|
*/
|
|
downloadFile(content, filename, mimeType) {
|
|
const blob = new Blob([content], { type: mimeType });
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = filename;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* Reset all changes and restore document to original state
|
|
*/
|
|
resetAll() {
|
|
return this.safeOperation(() => {
|
|
// Show confirmation dialog
|
|
const confirmed = window.confirm(
|
|
'Reset all changes?\n\nThis will:\n' +
|
|
'• Restore document to original state\n' +
|
|
'• Clear all unsaved changes\n' +
|
|
'• Reset font size and other settings\n\n' +
|
|
'This action cannot be undone.'
|
|
);
|
|
|
|
if (!confirmed) {
|
|
this.showActionFeedback('🚫 Reset cancelled', '#6c757d');
|
|
return;
|
|
}
|
|
|
|
// Reset edit control state
|
|
this.fontSize = 16;
|
|
this.editingMode = 'view';
|
|
this.unsavedChanges = false;
|
|
this.lastSaveTime = null;
|
|
|
|
// Reset font size
|
|
this.applyFontSize();
|
|
|
|
// Clear any highlights
|
|
document.querySelectorAll('.edit-highlight').forEach(el => {
|
|
el.outerHTML = el.innerHTML;
|
|
});
|
|
|
|
// Try to reset sections if SectionManager is available
|
|
if (window.sectionManager && typeof window.sectionManager.resetAllSections === 'function') {
|
|
window.sectionManager.resetAllSections();
|
|
}
|
|
|
|
// Try to reset document controls if available
|
|
if (window.documentControls && typeof window.documentControls.resetAllChanges === 'function') {
|
|
window.documentControls.resetAllChanges();
|
|
}
|
|
|
|
// Clear any debug messages if debug control is available
|
|
if (window.debugControl && typeof window.debugControl.clearMessages === 'function') {
|
|
window.debugControl.clearMessages();
|
|
}
|
|
|
|
// Reload the page as ultimate fallback
|
|
if (window.confirm('Reload page to complete reset?')) {
|
|
window.location.reload();
|
|
return;
|
|
}
|
|
|
|
// Update the control display
|
|
this.buildContent();
|
|
|
|
// Show feedback
|
|
this.showActionFeedback('🔄 All changes reset', '#ffc107', '#212529');
|
|
|
|
}, null, 'resetAll');
|
|
}
|
|
|
|
/**
|
|
* Scroll to top of document
|
|
*/
|
|
scrollToTop() {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
this.showActionFeedback('⬆️ Scrolled to top', '#6c757d');
|
|
}
|
|
|
|
/**
|
|
* Scroll to bottom of document
|
|
*/
|
|
scrollToBottom() {
|
|
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
|
|
this.showActionFeedback('⬇️ Scrolled to bottom', '#6c757d');
|
|
}
|
|
|
|
/**
|
|
* Show go to line dialog
|
|
*/
|
|
showGoToLine() {
|
|
const lineNumber = prompt('Go to line number:');
|
|
if (lineNumber && !isNaN(lineNumber)) {
|
|
// Simple implementation - scroll to approximate position
|
|
const totalHeight = document.body.scrollHeight;
|
|
const approximatePosition = (parseInt(lineNumber) / 100) * totalHeight;
|
|
window.scrollTo({ top: approximatePosition, behavior: 'smooth' });
|
|
this.showActionFeedback(`🎯 Went to line ${lineNumber}`, '#6c757d');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show find and replace dialog
|
|
*/
|
|
showFindReplace() {
|
|
const searchTerm = prompt('Find text:');
|
|
if (searchTerm) {
|
|
// Simple highlight implementation
|
|
this.highlightText(searchTerm);
|
|
this.showActionFeedback(`🔍 Highlighted "${searchTerm}"`, '#ffc107', '#000');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Highlight text in the document
|
|
*/
|
|
highlightText(searchTerm) {
|
|
return this.safeOperation(() => {
|
|
// Remove previous highlights
|
|
document.querySelectorAll('.edit-highlight').forEach(el => {
|
|
el.outerHTML = el.innerHTML;
|
|
});
|
|
|
|
// Add new highlights
|
|
const contentArea = document.querySelector('#markitect-content') || document.body;
|
|
const walker = document.createTreeWalker(
|
|
contentArea,
|
|
NodeFilter.SHOW_TEXT,
|
|
null,
|
|
false
|
|
);
|
|
|
|
const textNodes = [];
|
|
let node;
|
|
while (node = walker.nextNode()) {
|
|
textNodes.push(node);
|
|
}
|
|
|
|
textNodes.forEach(textNode => {
|
|
const parent = textNode.parentNode;
|
|
const text = textNode.textContent;
|
|
if (text.toLowerCase().includes(searchTerm.toLowerCase())) {
|
|
const regex = new RegExp(`(${searchTerm})`, 'gi');
|
|
const highlightedHTML = text.replace(regex, '<span class="edit-highlight" style="background-color: yellow; padding: 0.1rem;">$1</span>');
|
|
|
|
const wrapper = document.createElement('div');
|
|
wrapper.innerHTML = highlightedHTML;
|
|
while (wrapper.firstChild) {
|
|
parent.insertBefore(wrapper.firstChild, textNode);
|
|
}
|
|
parent.removeChild(textNode);
|
|
}
|
|
});
|
|
}, null, 'highlightText');
|
|
}
|
|
|
|
/**
|
|
* Increase font size
|
|
*/
|
|
increaseFontSize() {
|
|
this.fontSize = Math.min(this.fontSize + 2, 24);
|
|
this.applyFontSize();
|
|
this.buildContent();
|
|
}
|
|
|
|
/**
|
|
* Decrease font size
|
|
*/
|
|
decreaseFontSize() {
|
|
this.fontSize = Math.max(this.fontSize - 2, 12);
|
|
this.applyFontSize();
|
|
this.buildContent();
|
|
}
|
|
|
|
/**
|
|
* Apply font size to document
|
|
*/
|
|
applyFontSize() {
|
|
const contentArea = document.querySelector('#markitect-content') || document.body;
|
|
contentArea.style.fontSize = `${this.fontSize}px`;
|
|
}
|
|
|
|
/**
|
|
* Copy page link to clipboard
|
|
*/
|
|
copyLink() {
|
|
return this.safeOperation(() => {
|
|
const url = window.location.href;
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(url).then(() => {
|
|
this.showActionFeedback('📋 Link copied to clipboard', '#fd7e14');
|
|
});
|
|
} else {
|
|
// Fallback for older browsers
|
|
prompt('Copy this link:', url);
|
|
this.showActionFeedback('📋 Link displayed for copying', '#fd7e14');
|
|
}
|
|
}, null, 'copyLink');
|
|
}
|
|
|
|
/**
|
|
* Insert markdown formatting
|
|
*/
|
|
insertMarkdown(prefix, suffix, placeholder) {
|
|
// This would integrate with an actual text editor
|
|
// For now, just show what would be inserted
|
|
const text = `${prefix}${placeholder}${suffix}`;
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(text);
|
|
this.showActionFeedback(`📋 Copied: ${text}`, '#495057');
|
|
} else {
|
|
prompt('Markdown to copy:', text);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show action feedback message
|
|
*/
|
|
showActionFeedback(message, backgroundColor, color = 'white') {
|
|
const feedback = document.createElement('div');
|
|
feedback.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: ${backgroundColor};
|
|
color: ${color};
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 4px;
|
|
z-index: 9999;
|
|
font-size: 0.8rem;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
|
`;
|
|
feedback.textContent = message;
|
|
document.body.appendChild(feedback);
|
|
|
|
setTimeout(() => {
|
|
if (feedback.parentNode) {
|
|
document.body.removeChild(feedback);
|
|
}
|
|
}, 3000);
|
|
}
|
|
|
|
/**
|
|
* Build the control content
|
|
* Override of base class method to provide edit-specific functionality
|
|
*/
|
|
buildContent() {
|
|
return this.safeOperation(() => {
|
|
const content = this.element?.querySelector('.control-content');
|
|
if (content) {
|
|
content.innerHTML = this.generateEditToolsHTML();
|
|
|
|
// Store reference to this control for onclick handlers
|
|
this.element.editControl = this;
|
|
}
|
|
}, null, 'buildContent');
|
|
}
|
|
|
|
/**
|
|
* Exit edit mode
|
|
*/
|
|
exitEditMode() {
|
|
this.editingMode = 'view';
|
|
this.buildContent();
|
|
}
|
|
}
|
|
|
|
// Export for module systems or attach to global for direct usage
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = EditControl;
|
|
} else {
|
|
window.EditControl = EditControl;
|
|
} |