From 711d1fbd4e50fbc4a2709463e566ca93df4c08d7 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Mon, 12 Jan 2026 00:15:09 +0100 Subject: [PATCH] asdasd --- public/assets/js/bridge/blocks-placeholder.js | 179 ++---------------- public/editor/bridge-core.js | 26 ++- 2 files changed, 44 insertions(+), 161 deletions(-) diff --git a/public/assets/js/bridge/blocks-placeholder.js b/public/assets/js/bridge/blocks-placeholder.js index 04a288e..4263b24 100644 --- a/public/assets/js/bridge/blocks-placeholder.js +++ b/public/assets/js/bridge/blocks-placeholder.js @@ -150,22 +150,9 @@ const refreshPlaceholderComponent = (component) => { return (payload.key || 'PLATZHALTER').toUpperCase(); }; -const buildPlaceholderHTML = (payload) => { - const type = payload.type === 'database' ? 'database' : 'custom'; - const attrs = [ - `data-gjs-type="${PLACEHOLDER_COMPONENT}"`, - `data-placeholder-type="${type}"`, - `contenteditable="false"`, - `class="${INLINE_PLACEHOLDER_CLASS}"`, - ]; - if (type === 'database') { - attrs.push(`data-placeholder-table="${payload.table || ''}"`); - attrs.push(`data-placeholder-column="${payload.column || ''}"`); - } else { - attrs.push(`data-placeholder-key="${payload.key || ''}"`); - } + const buildPlaceholderText = (payload) => { const label = buildPlaceholderLabel(payload); - return `{{${label}}}`; + return `{{${label}}}`; }; const buildField = (labelText, control) => { @@ -201,24 +188,7 @@ const buildPlaceholderHTML = (payload) => { return comps; }; - const reparseTextComponent = (component, editor) => { - if (!component || typeof component.components !== 'function') return; - const viewEl = component.view && component.view.el; - if (!viewEl) return; - const comps = buildTextnodeComponents(viewEl); - try { - if (comps.length) { - component.components(comps); - } - if (component.em && typeof component.em.trigger === 'function') { - component.em.trigger('component:update', component); - } else if (editor && typeof editor.trigger === 'function') { - editor.trigger('component:update', component); - } - } catch (err) { - log('PLACEHOLDER ERROR', `Reparsing des Text-Elements fehlgeschlagen: ${err && err.message ? err.message : err}`, 'red', 'error'); - } - }; + const reparseTextComponent = () => {}; const captureRteSelection = (rteInstance) => { const doc = rteInstance && rteInstance.doc @@ -247,7 +217,7 @@ const buildPlaceholderHTML = (payload) => { } }; - const insertPlaceholderIntoSelection = (rteInstance, html) => { + const insertTextIntoSelection = (rteInstance, text) => { const doc = rteInstance && rteInstance.doc ? rteInstance.doc : (rteInstance && rteInstance.el && rteInstance.el.ownerDocument) || document; @@ -258,70 +228,20 @@ const buildPlaceholderHTML = (payload) => { if (!range) return false; range.deleteContents(); - const temp = doc.createElement('div'); - temp.innerHTML = html; - const fragment = doc.createDocumentFragment(); - while (temp.firstChild) { - fragment.appendChild(temp.firstChild); - } - range.insertNode(fragment); - range.collapse(false); + const textNode = doc.createTextNode(text); + range.insertNode(textNode); + range.setStartAfter(textNode); + range.collapse(true); sel.removeAllRanges(); sel.addRange(range); return true; }; - const insertCaretMarker = (rteInstance, markerId) => { - if (!markerId) return false; - const markerHtml = ``; - if (insertPlaceholderIntoSelection(rteInstance, markerHtml)) { - return true; - } - if (rteInstance && typeof rteInstance.insertHTML === 'function') { - rteInstance.insertHTML(markerHtml); - return true; - } - if (typeof document !== 'undefined' && document.execCommand) { - document.execCommand('insertHTML', false, markerHtml); - return true; - } - return false; - }; + const insertCaretMarker = () => false; - const removeMarkerFromComponent = (component, markerId, editor) => { - if (!component || !markerId) return false; - const viewEl = component.view && component.view.el; - if (!viewEl) return false; - const selector = `[${PLACEHOLDER_MARKER_ATTR}="${markerId}"]`; - const marker = viewEl.querySelector(selector); - if (!marker || !marker.parentNode) return false; - marker.parentNode.removeChild(marker); - reparseTextComponent(component, editor); - return true; - }; + const removeMarkerFromComponent = () => false; - const replaceMarkerWithPlaceholder = (component, markerId, payload, editor) => { - if (!component || !markerId) return false; - const viewEl = component.view && component.view.el; - if (!viewEl) return false; - const marker = viewEl.querySelector(`[${PLACEHOLDER_MARKER_ATTR}="${markerId}"]`); - if (!marker) return false; - if (typeof document === 'undefined') return false; - const temp = document.createElement('div'); - temp.innerHTML = buildPlaceholderHTML(payload); - const placeholderNode = temp.firstElementChild || temp.firstChild; - if (!placeholderNode) return false; - if (typeof marker.replaceWith === 'function') { - marker.replaceWith(placeholderNode); - } else if (marker.parentNode) { - marker.parentNode.insertBefore(placeholderNode, marker); - marker.parentNode.removeChild(marker); - } else { - return false; - } - reparseTextComponent(component, editor); - return true; - }; + const replaceMarkerWithPlaceholder = () => false; const openPlaceholderModal = (editor, component, opts = {}) => { if (!editor) return; @@ -641,59 +561,27 @@ const buildPlaceholderHTML = (payload) => { log('PLACEHOLDER ERROR', 'Keine Text-Selektion gefunden. Bitte Cursor setzen und erneut versuchen.', 'red', 'error'); return; } - const markerId = `bridge-placeholder-marker-${Date.now()}-${Math.random().toString(36).slice(2)}`; const restoreSelection = () => restoreRteSelection(selectionSnapshot); - let markerInserted = false; - if (restoreSelection()) { - markerInserted = insertCaretMarker(rteInstance, markerId); - if (markerInserted) { - setTimeout(() => reparseTextComponent(target, editor), 0); - } - } - const cleanupMarker = () => { - if (markerInserted) { - removeMarkerFromComponent(target, markerId, editor); - markerInserted = false; - } - }; openPlaceholderModal(editor, null, { onCancel: () => { - cleanupMarker(); if (rteInstance && typeof rteInstance.focus === 'function') { setTimeout(() => rteInstance.focus(), 0); } }, onSubmit: (payload) => { - if (editor) { - editor.__bridgePlaceholderSuppressAdd = (editor.__bridgePlaceholderSuppressAdd || 0) + 1; + if (!restoreSelection()) { + log('PLACEHOLDER ERROR', 'Cursor-Position konnte nicht wiederhergestellt werden.', 'red', 'error'); + return false; } - let replaced = false; - if (markerInserted) { - replaced = replaceMarkerWithPlaceholder(target, markerId, payload, editor); - } - if (!replaced && restoreSelection()) { - const html = buildPlaceholderHTML(payload); - if (insertPlaceholderIntoSelection(rteInstance, html)) { - setTimeout(() => reparseTextComponent(target, editor), 0); - replaced = true; - } - } - if (!replaced) { - cleanupMarker(); - const viewEl = target.view && target.view.el; - if (viewEl) { - viewEl.insertAdjacentHTML('beforeend', buildPlaceholderHTML(payload)); - reparseTextComponent(target, editor); - replaced = true; - } else { - log('PLACEHOLDER ERROR', 'Placeholder konnte nicht eingefügt werden (kein Ziel).', 'red', 'error'); - return false; - } + const text = buildPlaceholderText(payload); + if (!insertTextIntoSelection(rteInstance, text)) { + log('PLACEHOLDER ERROR', 'Placeholder konnte nicht eingefügt werden.', 'red', 'error'); + return false; } if (rteInstance && typeof rteInstance.focus === 'function') { setTimeout(() => rteInstance.focus(), 0); } - return replaced; + return true; } }); }, @@ -1048,8 +936,6 @@ const buildPlaceholderHTML = (payload) => { function register(editor) { log('EXECUTION', `Starte Placeholder-Registrierung für ${TARGET_CAT_ID}.`, '#DAA520'); const bm = editor.BlockManager; - ensurePlaceholderComponent(editor); - ensureTextSupportsPlaceholders(editor); if (!placeholderSchemaStore.promise && placeholderSchemaStore.status !== false) { fetchPlaceholderSchema().catch(() => {}); } @@ -1069,33 +955,6 @@ const buildPlaceholderHTML = (payload) => { if (!editor.__bridgePlaceholderEventsBound) { editor.__bridgePlaceholderEventsBound = true; - - editor.on('component:dblclick', (cmp) => { - if (cmp && cmp.is && cmp.is(PLACEHOLDER_COMPONENT)) { - openPlaceholderModal(editor, cmp); - return false; - } - return undefined; - }); - - editor.on('component:add', (cmp) => { - if (!cmp || !cmp.is || !cmp.is(PLACEHOLDER_COMPONENT)) return; - if (editor.__bridgePlaceholderSuppressAdd) { - editor.__bridgePlaceholderSuppressAdd = Math.max(0, (editor.__bridgePlaceholderSuppressAdd || 1) - 1); - return; - } - if (window.__GJS_IS_PARSING) return; - if (cmp.__bridgePlaceholderPrompted) return; - cmp.__bridgePlaceholderPrompted = true; - cmp.__bridgePlaceholderNew = true; - setTimeout(() => openPlaceholderModal(editor, cmp, { - onCancel: () => { - if (cmp.__bridgePlaceholderNew) { - safeRemoveComponent(cmp); - } - } - }), 50); - }); } const bindRteButton = () => ensureRtePlaceholderButton(editor); diff --git a/public/editor/bridge-core.js b/public/editor/bridge-core.js index ff38211..518891a 100644 --- a/public/editor/bridge-core.js +++ b/public/editor/bridge-core.js @@ -371,7 +371,31 @@ } }); } - // Placeholder-Plugin entfernt: kein Fallback-Laden. + const ensurePlaceholderRte = () => { + if (ed.__bridgePlaceholderActive) { + return true; + } + if (window.BridgeBlocksPlaceholder && typeof window.BridgeBlocksPlaceholder.register === 'function') { + try { + window.BridgeBlocksPlaceholder.register(ed); + ed.__bridgePlaceholderActive = true; + log('PLACEHOLDER SYNC', 'Placeholder-RTE aktiv.', 'lime'); + } catch (err) { + log('PLACEHOLDER ERROR', `Placeholder-RTE Fehler: ${err.message}`, 'red', 'error'); + } + return true; + } + return false; + }; + if (!ensurePlaceholderRte()) { + const fallbackSrc = B.BASE_PATH_BRIDGE + 'blocks-placeholder.js'; + log('PLACEHOLDER LOAD', 'Placeholder-RTE wird geladen.', '#B45309', 'warn'); + loadScript(fallbackSrc, () => { + if (!ensurePlaceholderRte()) { + log('PLACEHOLDER ERROR', 'Placeholder-RTE konnte nicht initialisiert werden.', 'red', 'error'); + } + }); + } // --------------------------------------------------- log('INIT API', 'API-Elemente werden nun durch das Plugin bridge-blocks-api geladen. (ASYNCHRON)', 'orange');