This commit is contained in:
2025-12-04 22:33:05 +01:00
parent 316175e158
commit 9dee06cdd6
145 changed files with 16865 additions and 88 deletions

View File

@@ -0,0 +1,166 @@
/* /assets/js/bridge/library.js — Kategorien, Defaults, Snippets (FINAL UND KORRIGIERT) */
(function(w){
  var B = w.BridgeParts = w.BridgeParts || {};
if (!B.CATEGORY_CONFIG) B.CATEGORY_CONFIG = {}; // Muss vorhanden sein
  /* Panels/Views sicherstellen (Unverändert) */
  B.ensureViews = function(ed){
    var pn = ed.Panels;
    if (!pn.getPanel('views')) pn.addPanel({ id:'views' });
    if (!pn.getButton('views','open-blocks'))
      pn.addButton('views',[{ id:'open-blocks', command:'open-blocks', togglable:1, className:'gjs-pn-btn' }]);
    if (!pn.getButton('views','open-layers'))
      pn.addButton('views',[{ id:'open-layers', command:'open-layers', togglable:1, className:'gjs-pn-btn' }]);
    if (!pn.getButton('views','open-sm'))
      pn.addButton('views',[{ id:'open-sm', command:'open-sm', togglable:1, className:'gjs-pn-btn' }]);
    try{ var b=pn.getButton('views','open-blocks'); b && b.set('active',true); }catch{}
  };
  /* Helpers --------------------------------------------------------------- */
  function addOnce(bm, id, def){
    if (!id || typeof id !== 'string') return;
    try{ if (bm.get && bm.get(id)) return; bm.add(id, def); }catch{}
  }
  // Kategorien erzeugen (Funktion unverändert)
  function forceCategory(bm, id, label, open){
    try{
      if (typeof bm.addCategory === 'function') {
        var cts = bm.getCategories && bm.getCategories();
        var find = function(){
          if (!cts) return null;
          if (typeof cts.findWhere === 'function') {
            return cts.findWhere({ id }) || cts.findWhere({ label });
          }
          var arr = cts.models || cts || [];
          for (var i=0;i<arr.length;i++){
            var m = arr[i], lid = (m.get?m.get('id'):m.id), lbl=(m.get?m.get('label'):m.label);
            if (lid===id || lbl===label) return m;
          }
          return null;
        };
        var c = find();
        if (!c) c = bm.addCategory({ id:id, label:label, open:!!open });
        try { c.set && c.set('open', !!open); } catch {}
        return c;
      }
    }catch{}
    return { id:id, label:label, open:!!open, __labelOnly:true };
  }
  function ensureCategories(bm){
    // Stellt sicher, dass die vier Hauptkategorien erstellt werden.
    var C_CUSTOM = forceCategory(bm,'custom', B.CATEGORY_CONFIG.custom.label, true);
    var C_STD  = forceCategory(bm,'bausteine', B.CATEGORY_CONFIG.bausteine.label, true);
    var C_LIB  = forceCategory(bm,'mysnips', B.CATEGORY_CONFIG.mysnips.label, true);
    var C_TPLS = forceCategory(bm,'lib-templates', B.CATEGORY_CONFIG['lib-templates'].label, true);
   
    return { C_CUSTOM, C_STD, C_LIB, C_TPLS };
  }
  B._ensureCategories = ensureCategories;
  /* Harte Zuordnung von Custom-IDs → Kategorien (ENTFERNT) */
  B.forceFixFlexCategories = function(ed){
    // Logik liegt jetzt im Plugin
  };
  // **Harte** Sortierung der Kategorien Sammlung + DOM (DOM-Fallback)
  B.enforceCategoryOrder = function(ed){
    try{
      var bm  = ed.BlockManager;
      setTimeout(function(){
        try{
          var cont = bm.getContainer && bm.getContainer();
          if (!cont) return;
          // Notfall-DOM-Sortierung (falls das Plugin versagt)
          var nodes = Array.prototype.slice.call(cont.querySelectorAll('.gjs-block-category'));
          if (!nodes.length) return;
          function nodeRank(n){
            var t = (n.querySelector('.gjs-title') || n).textContent || '';
            var s = t.trim().toLowerCase();
            if (s==='bibliothek: templates (ref)') return 1; // Prio 1
            if (s==='custom')                       return 2; // Prio 2
            if (s==='bausteine')                    return 3; // Prio 3
            if (s.startsWith('bibliothek'))         return 4; // Prio 4+
            return 99;
          }
          nodes.sort(function(a,b){ return nodeRank(a)-nodeRank(b); })
               .forEach(function(n){ cont.appendChild(n); });
        }catch{}
      },0);
    }catch{}
  };
  /* Kategorien normalisieren + sortieren (ENTFERNT) */
  B.normalizeCategories = function(ed){
    // Logik liegt jetzt im Plugin
  };
  /* Bausteine (Explizite Zuweisung zur ID 'bausteine') */
  B.addDefaultBlocks = function(ed){
    var bm = ed.BlockManager;
    B._ensureCategories(bm); // Stellen Sie sicher, dass alle Hauptkategorien existieren
    // Explizite Kategorie-Definition basierend auf der ID 'bausteine'
    var cat_bausteine = { id:'bausteine', label:B.CATEGORY_CONFIG.bausteine.label, open:true };
  addOnce(bm,'blk-img', { label:'Bild', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="5" width="18" height="14" fill="none" stroke="currentColor" stroke-width="2"/><path d="M8 13l3-3 5 6" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="9" cy="9" r="1.5" fill="currentColor"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td align="center"><img src="https://via.placeholder.com/600x200" alt="" width="600" style="max-width:100%;display:block;border:0;" /></td></tr></table>' });
  addOnce(bm,'blk-btn', { label:'Button', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="4" y="7" width="16" height="10" rx="5" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" cellpadding="0" cellspacing="0" align="center" style="font-family:Arial,sans-serif;margin:16px auto;"><tr><td><a href="#" style="background:#0ea5e9;color:#fff;text-decoration:none;padding:12px 20px;border-radius:6px;display:inline-block;">Call to Action</a></td></tr></table>' });
  addOnce(bm,'blk-text', { label:'Text', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 7h16M4 12h10M4 17h8" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td style="font-size:16px;line-height:1.5;color:#0f172a;"><p style="margin:0 0 12px 0;">Überschrift</p><p style="margin:0;">Fließtext …</p></td></tr></table>' });
  addOnce(bm,'blk-2cols', { label:'2 Spalten', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="4" y="6" width="7" height="12" fill="none" stroke="currentColor" stroke-width="2"/><rect x="13" y="6" width="7" height="12" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td width="50%" valign="top" style="padding:8px;"><p style="margin:0;">Linke Spalte</p></td><td width="50%" valign="top" style="padding:8px;"><p style="margin:0;">Rechte Spalte</p></td></tr></table>' });
  addOnce(bm,'blk-600', { label:'Container 600px', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="7" width="18" height="10" rx="2" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td align="center"><table role="presentation" width="600" cellpadding="0" cellspacing="0" style="width:600px;max-width:100%;background:#ffffff;border:1px solid #e5e7eb;border-radius:6px;"><tr><td style="padding:16px;"><p style="margin:0;">Inhalt hier hinein …</p></td></tr></table></td></tr></table>' });
  addOnce(bm,'blk-hr', { label:'Trenner', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 12h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td style="padding:8px 0;"><hr style="border:none;border-top:1px solid #e5e7eb;margin:0;" /></td></tr></table>' });
  addOnce(bm,'blk-spacer', { label:'Abstand', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M12 6v12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="6" r="1.5" fill="currentColor"/><circle cx="12" cy="18" r="1.5" fill="currentColor"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td style="height:16px;line-height:16px;font-size:0;">&nbsp;</td></tr></table>' });
  };
  /* Snippets → Custom (Initiale Zuweisung zur ID 'custom') */
  B.replaceSnippetBlocks = function(ed, list){
    try{
      var bm = ed.BlockManager;
      B._ensureCategories(bm);
      var all = (bm.getAll && bm.getAll()) || [];
      (all.models || all).forEach(function(b){
        if (!b) return;
        var id=b.get&&b.get('id');
        // Entferne alte Snippets
        if(id && String(id).startsWith('snip-')) try{ bm.remove(id); }catch{}
      });
      // Explizite Kategorie-Definition basierend auf der ID 'custom'
      var cat_custom = { id:'custom', label:B.CATEGORY_CONFIG.custom.label, open:true };
      (list||[]).forEach(function(raw){
        if(!raw) return;
        var html = raw.html || raw.content || '';
        if(!html) return;
        var id = 'snip-'+(raw.id ?? ('x'+Math.random().toString(36).slice(2)));
        addOnce(bm, id, {
          label: raw.name || ('Snippet '+(raw.id ?? '')),
          // Zuweisung zur 'Custom' Kategorie
          category: cat_custom,
          media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M5 7h14M5 12h10M5 17h8" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/></svg>',
          content: html
        });
      });
    }catch{}
    B.renderBlocks && B.renderBlocks(ed);
  };
  /* Snippets nachladen (für Buttons) */
  B.fetchSnippets = async function(){
    try{
      var res = await fetch('../api.php?resource=snippets&action=list&t='+Date.now(), {
        credentials:'same-origin', cache:'no-store', headers:{'Cache-Control':'no-cache'}
      });
      var rows = await res.json();
      rows = rows && rows.items ? rows.items : (Array.isArray(rows) ? rows : []);
      return rows.map(function(r){ return { id:r.id, name:r.name, html:r.content||r.html||'' }; });
    }catch(e){ B.log && B.log('reload-snippets-error:'+e); return []; }
  };
})(window);