diff --git a/config/current.ver b/config/current.ver index 4d668e7..f4872e7 100644 --- a/config/current.ver +++ b/config/current.ver @@ -1 +1 @@ -1.2.48 \ No newline at end of file +1.2.49 \ No newline at end of file diff --git a/public/assets/js/bridge/blocks-api.js b/public/assets/js/bridge/blocks-api.js index 8523a37..745b455 100644 --- a/public/assets/js/bridge/blocks-api.js +++ b/public/assets/js/bridge/blocks-api.js @@ -480,15 +480,57 @@ return; } - // Kein aktives Sync mehr vor dem Speichern, nur Logging + // Minimaler Sync: nur aktives Text-Element (Selection) in das Model schreiben try { const doc = editor.Canvas && editor.Canvas.getDocument ? editor.Canvas.getDocument() : null; const active = doc && doc.activeElement; const selectionNode = doc && doc.getSelection ? (doc.getSelection().focusNode || doc.getSelection().anchorNode) : null; const selectionEl = selectionNode ? (selectionNode.nodeType === 1 ? selectionNode : selectionNode.parentElement) : null; const selected = editor.getSelected && editor.getSelected(); + let syncResult = null; + let syncReason = 'no-editable-selection'; + + const syncFromElement = (comp, el, reason) => { + if (!comp || !comp.set || !el) return false; + const html = el.innerHTML || ''; + const before = typeof comp.get === 'function' ? (comp.get('content') || '') : ''; + if (html.trim() || !String(before || '').trim()) { + comp.set('content', html); + comp.trigger && comp.trigger('change:content'); + syncResult = { + compId: comp.getId ? comp.getId() : (comp.get && comp.get('id')), + beforeLen: String(before || '').length, + afterLen: String(html || '').length, + reason, + }; + syncReason = reason; + return true; + } + return false; + }; + + // 1) Bevorzugt: ausgewähltes Component-Element aus der View + if (selected) { + const selEl = (selected.getEl && selected.getEl()) || (selected.view && selected.view.el); + if (selEl && (selEl.isContentEditable || (selEl.getAttribute && selEl.getAttribute('contenteditable') === 'true'))) { + syncFromElement(selected, selEl, 'selected:view'); + } + } + + // 2) Fallback: Selection im DOM suchen + if (!syncResult && doc && selectionEl && (selectionEl.isContentEditable || (selectionEl.getAttribute && selectionEl.getAttribute('contenteditable') === 'true'))) { + const root = (selectionEl.closest && selectionEl.closest('[data-gjs-type="text"]')) || selectionEl; + const id = root && root.getAttribute ? root.getAttribute('id') : null; + const wrapper = editor.getWrapper && editor.getWrapper(); + if (id && wrapper && wrapper.find) { + const found = wrapper.find(`#${id}`); + const comp = found && found[0]; + syncFromElement(comp, root, 'selection:root'); + } + } + writeDebugLog({ - event: 'save:sync:skipped', + event: 'save:sync:minimal', entityId: CURRENT_ENTITY_ID, sectionId: SECTION_ID || null, active: active ? { @@ -504,6 +546,8 @@ type: selected.get ? selected.get('type') : null, contentLen: selected.get ? String(selected.get('content') || '').length : 0, } : null, + syncResult, + syncReason, editorHtmlLen: (editor.getHtml && String(editor.getHtml() || '').length) || 0, editorHtmlPreview: (editor.getHtml && String(editor.getHtml() || '').slice(0, 300)) || '', });