Changeset 91d948c in Klonkt


Ignore:
Timestamp:
06/18/2026 04:28:28 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
b08b5bc
Parents:
fbc8628
Message:

Editor: blockquote button is now a real toggle (turning it off works)

execCommand('formatBlock','blockquote') turns a quote ON but never turns
it OFF (browser quirk: the <blockquote> wrapper stays, even after ¶).
New toggleBlockquote() detects whether the caret is already inside a
blockquote and unwraps it (content put back in place, caret preserved);
otherwise it applies the quote. Button shows is-active when inside a quote.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/pages/post-edit.ejs

    rfbc8628 r91d948c  
    10501050    execCmd('createLink', url);
    10511051  }
     1052  // De huidige selectie zit in een <blockquote> binnen de editor? Geef 'm terug.
     1053  function blockquoteAncestor() {
     1054    const sel = window.getSelection();
     1055    if (!sel || sel.rangeCount === 0) return null;
     1056    let node = sel.anchorNode;
     1057    while (node && node !== editor) {
     1058      if (node.nodeType === 1 && node.tagName === 'BLOCKQUOTE') return node;
     1059      node = node.parentNode;
     1060    }
     1061    return null;
     1062  }
     1063  // Echte toggle: execCommand('formatBlock','blockquote') zet 'm wél AAN maar
     1064  // krijgt 'm nooit meer UIT (browser-quirk). Staat de caret al in een quote →
     1065  // pak de wrapper uit; anders pas blockquote toe.
     1066  function toggleBlockquote() {
     1067    editor.focus();
     1068    const bq = blockquoteAncestor();
     1069    if (bq) {
     1070      const parent = bq.parentNode;
     1071      // Inhoud uit de quote halen, op z'n plek, en de lege wrapper verwijderen.
     1072      const ref = bq;
     1073      let firstMoved = null;
     1074      while (bq.firstChild) {
     1075        const child = bq.firstChild;
     1076        if (!firstMoved) firstMoved = child;
     1077        parent.insertBefore(child, ref);
     1078      }
     1079      parent.removeChild(bq);
     1080      // Caret terugzetten in de uitgepakte inhoud.
     1081      if (firstMoved) {
     1082        const sel = window.getSelection();
     1083        const range = document.createRange();
     1084        range.selectNodeContents(firstMoved.nodeType === 1 ? firstMoved : parent);
     1085        range.collapse(false);
     1086        sel.removeAllRanges();
     1087        sel.addRange(range);
     1088      }
     1089    } else {
     1090      document.execCommand('formatBlock', false, 'blockquote');
     1091    }
     1092    updateToolbarState();
     1093    updateCharCount();
     1094  }
    10521095
    10531096  if (toolbar) {
     
    10601103      if (cmd === 'link-prompt') linkPrompt();
    10611104      else if (cmd === 'code-wrap') wrapCode();
     1105      else if (cmd === 'formatBlock' && arg === 'blockquote') toggleBlockquote();
    10621106      else execCmd(cmd, arg);
    10631107    });
     
    10731117      try { btn.classList.toggle('is-active', document.queryCommandState(cmd)); } catch(_) {}
    10741118    }
     1119    // Quote-knop: actief als de caret in een <blockquote> staat (toggle-feedback).
     1120    const bqBtn = toolbar.querySelector('button[data-cmd="formatBlock"][data-arg="blockquote"]');
     1121    if (bqBtn) bqBtn.classList.toggle('is-active', !!blockquoteAncestor());
    10751122  }
    10761123  document.addEventListener('selectionchange', () => {
Note: See TracChangeset for help on using the changeset viewer.