From 2fb53e30d1e184f278579576a43e0846a063a83a Mon Sep 17 00:00:00 2001 From: Karl Kemister-Sheppard Date: Wed, 22 Jul 2026 11:13:00 +1000 Subject: [PATCH 1/2] Docs: TINYDOC-3435 - Document undo level grouping and IME typing behavior --- .../custom_undo_redo_levels.adoc | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc b/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc index 9df5fbf3b1..62907453f7 100644 --- a/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc +++ b/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc @@ -16,3 +16,33 @@ tinymce.init({ custom_undo_redo_levels: 10 }); ---- + +=== How typing is grouped into undo levels + +{productname} groups consecutive typing into a single undo level. A new undo level begins only when a boundary event occurs, such as pressing a navigation key (arrow keys, `+Home+`, `+End+`, `+Page Up+`, or `+Page Down+`), clicking in the content, moving focus away from the editor, or running an editor command. Until a boundary event occurs, all text typed since the previous level is merged into one level. As a result, a single undo can remove everything typed since the last boundary event. + +This grouping applies regardless of the language or input method. It is more noticeable when typing with an Input Method Editor (IME), for example when entering Chinese, Japanese, or Korean, because a whole composed phrase or sentence can be added without a boundary event. In that case, a single undo can remove a large block of text. + +The `+custom_undo_redo_levels+` option controls the depth of the undo stack, which is the number of levels retained. It does not change how typing is grouped into a level. There is no built-in option to create a separate undo level for each keystroke. + +=== Creating finer-grained undo levels + +To add undo levels at chosen points, call the xref:apis/tinymce.undomanager.adoc#add[UndoManager `+add()+`] method. Because continuous typing is otherwise merged into one level, a timer can be used to add periodic checkpoints while the editor has focus. A new level is only recorded when the content has changed since the previous level. + +[source,js] +---- +tinymce.init({ + selector: 'textarea', // change this value according to your HTML + setup: (editor) => { + let checkpoint; + + editor.on('focus', () => { + checkpoint = window.setInterval(() => editor.undoManager.add(), 5000); + }); + + editor.on('blur', () => { + window.clearInterval(checkpoint); + }); + } +}); +---- From 6105c3e7e541f51453c85e381e03076da724529f Mon Sep 17 00:00:00 2001 From: Karl Kemister-Sheppard Date: Wed, 22 Jul 2026 11:21:16 +1000 Subject: [PATCH 2/2] Docs: TINYDOC-3435 - Use editor-aware Delay.setEditorInterval in undo checkpoint example --- .../configuration/custom_undo_redo_levels.adoc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc b/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc index 62907453f7..cf657c3e4e 100644 --- a/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc +++ b/modules/ROOT/partials/configuration/custom_undo_redo_levels.adoc @@ -27,22 +27,17 @@ The `+custom_undo_redo_levels+` option controls the depth of the undo stack, whi === Creating finer-grained undo levels -To add undo levels at chosen points, call the xref:apis/tinymce.undomanager.adoc#add[UndoManager `+add()+`] method. Because continuous typing is otherwise merged into one level, a timer can be used to add periodic checkpoints while the editor has focus. A new level is only recorded when the content has changed since the previous level. +To add undo levels at chosen points, call the xref:apis/tinymce.undomanager.adoc#add[UndoManager `+add()+`] method. Because continuous typing is otherwise merged into one level, periodic checkpoints can be added with xref:apis/tinymce.util.delay.adoc#setEditorInterval[`+tinymce.util.Delay.setEditorInterval+`], which behaves like the browser `+setInterval+` but stops automatically when the editor is removed. A new level is only recorded when the content has changed since the previous level. [source,js] ---- tinymce.init({ selector: 'textarea', // change this value according to your HTML setup: (editor) => { - let checkpoint; - - editor.on('focus', () => { - checkpoint = window.setInterval(() => editor.undoManager.add(), 5000); - }); - - editor.on('blur', () => { - window.clearInterval(checkpoint); - }); + // Add an undo checkpoint every five seconds. + tinymce.util.Delay.setEditorInterval(editor, () => { + editor.undoManager.add(); + }, 5000); } }); ----