diff --git a/config/current.ver b/config/current.ver index 7ca8559..6e10d36 100644 --- a/config/current.ver +++ b/config/current.ver @@ -1 +1 @@ -1.2.45 \ No newline at end of file +1.2.46 \ 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 93e2f75..4152b50 100644 --- a/public/assets/js/bridge/blocks-api.js +++ b/public/assets/js/bridge/blocks-api.js @@ -481,7 +481,7 @@ } // Sicherstellen, dass ggf. aktive Text-Edits vor dem Speichern synchronisiert werden - let syncInfo = { stage: 'pre', active: null, selected: null, contentSynced: false }; + let syncInfo = { stage: 'pre', active: null, selected: null, selection: null, synced: [] }; try { const wrapper = editor.getWrapper && editor.getWrapper(); const resolveComponent = (el) => { @@ -492,16 +492,29 @@ const found = wrapper.find(`#${id}`); return found && found[0]; }; - const syncElement = (el) => { + const syncElement = (el, label = '') => { const comp = resolveComponent(el); if (!comp || !comp.set) return; const root = (el.closest && el.closest('[data-gjs-type="text"]')) || el; const html = root && root.innerHTML ? root.innerHTML : ''; const current = typeof comp.get === 'function' ? (comp.get('content') || '') : ''; + const beforeLen = String(current || '').length; + const htmlLen = String(html || '').length; if (!html.trim() && current.trim()) return; comp.set('content', html); comp.trigger && comp.trigger('change:content'); - syncInfo.contentSynced = true; + if (editor && typeof editor.trigger === 'function') { + editor.trigger('component:update', comp); + } + const after = typeof comp.get === 'function' ? (comp.get('content') || '') : ''; + syncInfo.synced.push({ + label, + compId: comp.getId ? comp.getId() : (comp.get && comp.get('id')), + htmlLen, + htmlPreview: String(html || '').slice(0, 200), + modelBeforeLen: beforeLen, + modelAfterLen: String(after || '').length, + }); }; const doc = editor.Canvas && editor.Canvas.getDocument ? editor.Canvas.getDocument() : null; @@ -515,7 +528,22 @@ }; } if (active && (active.isContentEditable || (active.getAttribute && active.getAttribute('contenteditable') === 'true'))) { - syncElement(active); + syncElement(active, 'activeElement'); + } + + if (doc && doc.getSelection) { + const sel = doc.getSelection(); + const node = sel && (sel.focusNode || sel.anchorNode); + const el = node ? (node.nodeType === 1 ? node : node.parentElement) : null; + if (el) { + syncInfo.selection = { + tag: el.tagName, + isEditable: !!(el.isContentEditable || (el.getAttribute && el.getAttribute('contenteditable') === 'true')), + htmlLen: (el.innerHTML || '').length, + htmlPreview: (el.innerHTML || '').slice(0, 200), + }; + syncElement(el, 'selection'); + } } const selected = editor.getSelected && editor.getSelected(); @@ -528,9 +556,9 @@ }; } if (view && view.el && (view.el.isContentEditable || (view.el.getAttribute && view.el.getAttribute('contenteditable') === 'true'))) { - syncElement(view.el); + syncElement(view.el, 'selectedView'); } else if (selected && typeof selected.is === 'function' && (selected.is('text') || selected.is('textnode')) && view && view.el) { - syncElement(view.el); + syncElement(view.el, 'selectedFallback'); } syncInfo.stage = 'post'; writeDebugLog({ @@ -539,6 +567,7 @@ sectionId: SECTION_ID || null, syncInfo, editorHtmlLen: (editor.getHtml && String(editor.getHtml() || '').length) || 0, + editorHtmlPreview: (editor.getHtml && String(editor.getHtml() || '').slice(0, 300)) || '', editorCssLen: (editor.getCss && String(editor.getCss() || '').length) || 0, }); } catch (e) {