Changeset cbfbf88 in Klonkt


Ignore:
Timestamp:
06/19/2026 12:06:00 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
f8e8f9e
Parents:
5f7dba2
Message:

fix(editor): no view jump on formatting button — hold scroll position

execCommand/insert scrolls the caret into view by default → the view
jumps when clicking bold/italic/quote/code. keepScroll() saves and
restores the scroll position (window + editor, sync + after 1 frame)
around execCmd/wrapCode/toggleBlockquote. The user now scrolls manually.

Co-Authored-By: Claude <noreply@…>

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG.md

    r5f7dba2 rcbfbf88  
    1515
    1616### Opgelost
     17- Editor: het beeld verspringt niet meer bij het aanklikken van een opmaakknop.
     18  `execCommand` scrollde de caret in beeld; de scrollpositie wordt nu vastgehouden
     19  rond elk opmaak-commando, zodat je zelf scrollt.
    1720- Post-editor op mobiel: de Opslaan/Annuleren-balk blijft nu net bóven het
    1821  toetsenbord (sticky met dynamische bottom-offset = max van toetsenbord- en
  • src/views/pages/post-edit.ejs

    r5f7dba2 rcbfbf88  
    10741074
    10751075  // ── Toolbar wiring
     1076  // Houd de scrollpositie vast rond een edit-commando. execCommand/insert scrollt
     1077  // standaard de caret in beeld → het beeld "verspringt" bij het aanklikken van een
     1078  // opmaakknop. Door de positie te bewaren en terug te zetten (sync + na 1 frame)
     1079  // blijft het beeld staan; de gebruiker scrollt zelf.
     1080  function keepScroll(fn) {
     1081    const x = window.scrollX, y = window.scrollY, es = editor.scrollTop;
     1082    fn();
     1083    window.scrollTo(x, y); editor.scrollTop = es;
     1084    requestAnimationFrame(function () { window.scrollTo(x, y); editor.scrollTop = es; });
     1085  }
    10761086  function execCmd(cmd, arg) {
    1077     editor.focus({ preventScroll: true });
    1078     document.execCommand(cmd, false, arg);
     1087    keepScroll(function () {
     1088      editor.focus({ preventScroll: true });
     1089      document.execCommand(cmd, false, arg);
     1090    });
    10791091    updateToolbarState();
    10801092    updateCharCount();
     
    10831095    const sel = window.getSelection();
    10841096    if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
    1085     const range = sel.getRangeAt(0);
    1086     const code = document.createElement('code');
    1087     code.textContent = sel.toString();
    1088     range.deleteContents();
    1089     range.insertNode(code);
    1090     // Move caret after the new node
    1091     range.setStartAfter(code);
    1092     range.collapse(true);
    1093     sel.removeAllRanges();
    1094     sel.addRange(range);
    1095     editor.focus({ preventScroll: true });
     1097    keepScroll(function () {
     1098      const range = sel.getRangeAt(0);
     1099      const code = document.createElement('code');
     1100      code.textContent = sel.toString();
     1101      range.deleteContents();
     1102      range.insertNode(code);
     1103      // Move caret after the new node
     1104      range.setStartAfter(code);
     1105      range.collapse(true);
     1106      sel.removeAllRanges();
     1107      sel.addRange(range);
     1108      editor.focus({ preventScroll: true });
     1109    });
    10961110  }
    10971111  function linkPrompt() {
     
    11151129  // pak de wrapper uit; anders pas blockquote toe.
    11161130  function toggleBlockquote() {
    1117     editor.focus({ preventScroll: true });
    1118     const bq = blockquoteAncestor();
    1119     if (bq) {
    1120       const parent = bq.parentNode;
    1121       // Inhoud uit de quote halen, op z'n plek, en de lege wrapper verwijderen.
    1122       const ref = bq;
    1123       let firstMoved = null;
    1124       while (bq.firstChild) {
    1125         const child = bq.firstChild;
    1126         if (!firstMoved) firstMoved = child;
    1127         parent.insertBefore(child, ref);
     1131    keepScroll(function () {
     1132      editor.focus({ preventScroll: true });
     1133      const bq = blockquoteAncestor();
     1134      if (bq) {
     1135        const parent = bq.parentNode;
     1136        // Inhoud uit de quote halen, op z'n plek, en de lege wrapper verwijderen.
     1137        const ref = bq;
     1138        let firstMoved = null;
     1139        while (bq.firstChild) {
     1140          const child = bq.firstChild;
     1141          if (!firstMoved) firstMoved = child;
     1142          parent.insertBefore(child, ref);
     1143        }
     1144        parent.removeChild(bq);
     1145        // Caret terugzetten in de uitgepakte inhoud.
     1146        if (firstMoved) {
     1147          const sel = window.getSelection();
     1148          const range = document.createRange();
     1149          range.selectNodeContents(firstMoved.nodeType === 1 ? firstMoved : parent);
     1150          range.collapse(false);
     1151          sel.removeAllRanges();
     1152          sel.addRange(range);
     1153        }
     1154      } else {
     1155        document.execCommand('formatBlock', false, 'blockquote');
    11281156      }
    1129       parent.removeChild(bq);
    1130       // Caret terugzetten in de uitgepakte inhoud.
    1131       if (firstMoved) {
    1132         const sel = window.getSelection();
    1133         const range = document.createRange();
    1134         range.selectNodeContents(firstMoved.nodeType === 1 ? firstMoved : parent);
    1135         range.collapse(false);
    1136         sel.removeAllRanges();
    1137         sel.addRange(range);
    1138       }
    1139     } else {
    1140       document.execCommand('formatBlock', false, 'blockquote');
    1141     }
     1157    });
    11421158    updateToolbarState();
    11431159    updateCharCount();
Note: See TracChangeset for help on using the changeset viewer.