youssefreda9 commited on
Commit
bf8500f
·
1 Parent(s): ece7379

fix: unified undo/redo - toolbar+keyboard use same stack, works with typing+formatting+Quran apply

Browse files
Files changed (3) hide show
  1. src/index.html +1 -0
  2. src/js/editor.js +5 -0
  3. src/js/format.js +4 -3
src/index.html CHANGED
@@ -1347,6 +1347,7 @@
1347
  function _replaceInEditor(newText, ref) {
1348
  var editor = document.getElementById('editor-container');
1349
  if (!editor || !_quranCurrentQuery) return false;
 
1350
  closeQuranModal();
1351
  // Replace in editor: wrap in quran-applied span to protect from analysis
1352
  var plain = editor.textContent || '';
 
1347
  function _replaceInEditor(newText, ref) {
1348
  var editor = document.getElementById('editor-container');
1349
  if (!editor || !_quranCurrentQuery) return false;
1350
+ pushUndoState(); // Save state before Quran replace
1351
  closeQuranModal();
1352
  // Replace in editor: wrap in quran-applied span to protect from analysis
1353
  var plain = editor.textContent || '';
src/js/editor.js CHANGED
@@ -79,6 +79,8 @@ function initEditor() {
79
  }
80
  } catch (e) {}
81
 
 
 
82
  editor.addEventListener('input', () => {
83
  // Pipeline Hardening v3.3: Skip re-analysis when programmatically applying suggestions
84
  if (_isApplyingSuggestion) return;
@@ -86,6 +88,9 @@ function initEditor() {
86
  updateEditorStats();
87
  updatePlaceholder();
88
  analyzeTextDelayed();
 
 
 
89
  try {
90
  localStorage.setItem('bayan_editor_draft', editor.innerHTML);
91
  } catch (e) {}
 
79
  }
80
  } catch (e) {}
81
 
82
+ // Debounced undo push — saves state after 500ms of no typing
83
+ let _undoInputTimer = null;
84
  editor.addEventListener('input', () => {
85
  // Pipeline Hardening v3.3: Skip re-analysis when programmatically applying suggestions
86
  if (_isApplyingSuggestion) return;
 
88
  updateEditorStats();
89
  updatePlaceholder();
90
  analyzeTextDelayed();
91
+ // Push undo state after typing pauses
92
+ clearTimeout(_undoInputTimer);
93
+ _undoInputTimer = setTimeout(pushUndoState, 500);
94
  try {
95
  localStorage.setItem('bayan_editor_draft', editor.innerHTML);
96
  } catch (e) {}
src/js/format.js CHANGED
@@ -8,6 +8,7 @@
8
  * @param {boolean} [keepSelection] - if true, don't collapse selection
9
  */
10
  function execFormat(command, value, keepSelection) {
 
11
  document.execCommand(command, false, value !== undefined ? value : null);
12
  const editor = getEditorElement();
13
  if (editor) editor.focus();
@@ -29,9 +30,9 @@ function formatItalic() { execFormat('italic'); }
29
  function formatUnderline() { execFormat('underline'); }
30
  function formatStrikethrough() { execFormat('strikethrough'); }
31
 
32
- /* ── Undo / Redo (handles both typing and formatting) ── */
33
- function formatUndo() { execFormat('undo', undefined, true); }
34
- function formatRedo() { execFormat('redo', undefined, true); }
35
 
36
  /* ── Alignment (applies to paragraph containing selection/cursor) ── */
37
  function formatAlignRight() { execFormat('justifyRight'); }
 
8
  * @param {boolean} [keepSelection] - if true, don't collapse selection
9
  */
10
  function execFormat(command, value, keepSelection) {
11
+ pushUndoState(); // Save state before formatting
12
  document.execCommand(command, false, value !== undefined ? value : null);
13
  const editor = getEditorElement();
14
  if (editor) editor.focus();
 
30
  function formatUnderline() { execFormat('underline'); }
31
  function formatStrikethrough() { execFormat('strikethrough'); }
32
 
33
+ /* ── Undo / Redo (uses custom stack same as Ctrl+Z/Y) ── */
34
+ function formatUndo() { editorUndo(); }
35
+ function formatRedo() { editorRedo(); }
36
 
37
  /* ── Alignment (applies to paragraph containing selection/cursor) ── */
38
  function formatAlignRight() { execFormat('justifyRight'); }