Files
insertr/lib/src/core/editor.js
Joakim c777fc92dd refactor: consolidate all Node.js development into lib package
- Move scripts/ to lib/scripts/ and convert to ESM modules
- Consolidate dependencies: add live-server to lib/package.json
- Remove root package.json and node_modules split
- Preserve CLI integration via existing rebuild-library.sh
- Add development quickstart guide for new unified workflow
- Clean up outdated file references and duplicate assets
2025-09-04 21:40:45 +02:00

154 lines
4.7 KiB
JavaScript

import { InsertrFormRenderer } from '../ui/form-renderer.js';
/**
* InsertrEditor - Visual editing functionality
*/
export class InsertrEditor {
constructor(core, auth, options = {}) {
this.core = core;
this.auth = auth;
this.options = options;
this.isActive = false;
this.formRenderer = new InsertrFormRenderer();
}
start() {
if (this.isActive) return;
console.log('🚀 Starting Insertr Editor');
this.isActive = true;
// Add editor styles
this.addEditorStyles();
// Initialize all enhanced elements
const elements = this.core.getAllElements();
console.log(`📝 Found ${elements.length} editable elements`);
elements.forEach(meta => this.initializeElement(meta));
}
initializeElement(meta) {
const { element, contentId, contentType } = meta;
// Add visual indicators
element.style.cursor = 'pointer';
element.style.position = 'relative';
// Add interaction handlers
this.addHoverEffects(element);
this.addClickHandler(element, meta);
}
addHoverEffects(element) {
element.addEventListener('mouseenter', () => {
element.classList.add('insertr-editing-hover');
});
element.addEventListener('mouseleave', () => {
element.classList.remove('insertr-editing-hover');
});
}
addClickHandler(element, meta) {
element.addEventListener('click', (e) => {
// Only allow editing if authenticated and in edit mode
if (!this.auth.isAuthenticated() || !this.auth.isEditMode()) {
return; // Let normal click behavior happen
}
e.preventDefault();
this.openEditor(meta);
});
}
openEditor(meta) {
const { element } = meta;
const currentContent = this.extractCurrentContent(element);
// Show professional form instead of prompt
this.formRenderer.showEditForm(
meta,
currentContent,
(formData) => this.handleSave(meta, formData),
() => this.handleCancel(meta)
);
}
extractCurrentContent(element) {
// For links, extract both text and URL
if (element.tagName.toLowerCase() === 'a') {
return {
text: element.textContent.trim(),
url: element.getAttribute('href') || ''
};
}
// For other elements, just return text content
return element.textContent.trim();
}
handleSave(meta, formData) {
console.log('💾 Saving content:', meta.contentId, formData);
// Update element content based on type
this.updateElementContent(meta.element, formData);
// Close form
this.formRenderer.closeForm();
// TODO: Save to backend API
console.log(`✅ Content saved:`, meta.contentId, formData);
}
handleCancel(meta) {
console.log('❌ Edit cancelled:', meta.contentId);
}
updateElementContent(element, formData) {
if (element.tagName.toLowerCase() === 'a') {
// Update link element
if (formData.text !== undefined) {
element.textContent = formData.text;
}
if (formData.url !== undefined) {
element.setAttribute('href', formData.url);
}
} else {
// Update text content
element.textContent = formData.text || '';
}
}
// Legacy method - now handled by handleSave and updateElementContent
addEditorStyles() {
const styles = `
.insertr-editing-hover {
outline: 2px dashed #007cba !important;
outline-offset: 2px !important;
background-color: rgba(0, 124, 186, 0.05) !important;
}
.insertr:hover::after {
content: "✏️ " attr(data-content-type);
position: absolute;
top: -25px;
left: 0;
background: #007cba;
color: white;
padding: 2px 6px;
font-size: 11px;
border-radius: 3px;
white-space: nowrap;
z-index: 1000;
font-family: monospace;
}
`;
const styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
styleSheet.innerHTML = styles;
document.head.appendChild(styleSheet);
}
}