I'm working with a custom build based on ckeditor5-editor-classic. Everything works great and was relatively easy to configure. Thanks! I'm left with just one issue which is how to disable the default undo/redo behavior because I need to handle those functions myself. After reading the documentation it seemed that adding 'Undo' to the removePlugins option in the components config should do the trick. No luck. After more reading I found that the Undo plugin is bundled into the Essentials plugin, so I removed this from my custom build's source file and added ClipBoard, Enter, and Typing to keep things working. But, alas, the default ctrl-z/ctrl-y behavior still remains. I don't know what else to try. Any help will be greatly appreciated. Here is the configuration for my custom build:
export default class CustomEditor extends ClassicEditorBase {}
// Plugins to include in the build.
CustomEditor.builtinPlugins = [
ClipBoard,
Enter,
FontColor,
FontSize,
Autoformat,
Bold,
Italic,
BlockQuote,
CKFinder,
EasyImage,
Heading,
Image,
ImageCaption,
ImageStyle,
ImageToolbar,
ImageUpload,
Indent,
Link,
List,
MediaEmbed,
Paragraph,
PasteFromOffice,
SimpleUploadAdapter,
Table,
TableToolbar,
Typing,
Underline
];
// Editor configuration.
CustomEditor.defaultConfig = {
toolbar: {
items: [
"heading",
"|",
"bold",
"fontSize",
"fontColor",
"underline",
"italic",
"link",
"bulletedList",
"numberedList",
"|",
"indent",
"outdent",
"|",
"imageUpload",
"blockQuote",
"insertTable",
"mediaEmbed",
]
},
image: {
toolbar: [
"imageStyle:full",
"imageStyle:side",
"|",
"imageTextAlternative"
]
},
mediaEmbed: {
previewsInData: true
},
simpleUpload: {
uploadUrl: 'https://dev.redacted.com/image'
},
table: {
contentToolbar: ["tableColumn", "tableRow", "mergeTableCells"]
},
// This value must be kept in sync with the language defined in webpack.config.js.
language: "en",
};
Hi, thanks for the question. To start off, I would say that undo in CKEditor 5 is quite complicated mechanism and it's not just simply undoing the history operation-by-operation. The Undo class is also interconnected with other mechanisms, so I guess tinkering with it might be a bit risky.
You can read about it here.
It would be easier for us to answer your question, if you could explain precisely what you mean by 'handling undo yourself'.
Ok, I'm using CKEditor in an app to edit content for a tabbed display on a web page.
On the web page I have tabs Tab 1, Tab 2, and Tab 3 above a container. Click Tab 1 and the content associated with Tab 1 are displayed. Click Tab 2 and the content of Tab 2 are displayed. etc..
In my app the same tabs are displayed above my editor. Click Tab 1 and the contents of Tab 1 are displayed for editing using editor.setData(). And it's the same for the rest of the tabs.
It seems that editor.setData() clears the editor's history, so at least I don't have to worry about ctrl-z switching the contents to those of another tab. However, if I'm working in Tab 1 and switch over to Tab 2 I lose the history of Tab 1. So, I've been storing the history of each tab in my React state so that ctrl-z will set the content of the editor based on what tabbed is currently active. I hope that makes sense.
You've helped me come to a more complete understanding of my problem. Thanks! It's clear now that the best solution is to have a separate editor for each tab I'm working with so I can leverage CKEditor 5's excellent undo/redo feature instead of fighting with it.
I know that I need to refactor my app, but it would be useful for posterity to know if there is a way to prevent ctrl-z affecting the contents of the editor. If there is no builtin way to do it with CKEditor 5, I thought that by setting an event listener on the editable area of the editor I might be able to intercept the event and prevent it's propagation, like so,
editableArea.addEventListener('keydown', (e) => {
if (e.ctrlKey === true && e.key === 'z') {
e.stopPropagation()
}
})
But that doesn't work because CKEditor5 registers it's event first. Any other ideas?
If you want to listen to ctrl+z and intercept the native event, you can use:
editor.keystrokes.set( 'Ctrl+Z', ( keyEvtData, cancel ) => {
console.log( 'Ctrl+Z has been pressed' );
// ..do something
cancel();
}, { priority: 'high' } )
This will overwrite native ctrl+z and stop further propagation with cancel(), thus blocking native undo command fired by that keystroke.
Remember to set { priority: 'high' }, because without it the native keystroke related to undo will take the precedence and this will have no effect. Here you can read more about keystroke handlers.
Apart from that, you need to block undo command by adding:
editor.commands.get( 'undo' ).forceDisabled()
Without this, the undo command will still work when using toolbar buttons.
Hope that helps!
That's exactly what I was looking for! I really appreciate your help.
Hello @FilipTokarski @chhatch i have exactly same use case can u please tell me where did you place this code
editor.keystrokes.set( 'Ctrl+Z', ( keyEvtData, cancel ) => {
console.log( 'Ctrl+Z has been pressed' );
// ..do something
cancel();
}, { priority: 'high' } )
to make things working for you. I'm also working with a custom balloon build in react project?
@shivakantshukla55, here's the component I ended up using:
<CKEditor
editor={CustomEditor}
data={productTabs.tabData.description.content}
onInit={editor => {
// You can store the "editor" and use when it is needed.
window.editor = editor
window.editorChange = 'user'
//this disables ctrl-z
editor.commands.get('undo').forceDisabled()
editor.keystrokes.set(
'Ctrl+Z',
(keyEvtData, cancel) => {
undo()
},
{priority: 'high'},
)
editor.keystrokes.set(
'Ctrl+Y',
(keyEvtData, cancel) => {
redo()
},
{priority: 'high'},
)
}}
onChange={(event, editor) => {
//this is how I'm avoiding triggering the
//onChange function when the chane comes from
//a script
if (window.editorChange !== 'script') {
store.dispatch(updateTabContent(editor))
} else {
window.editorChange = 'user'
}
}}
onBlur={(event, editor) => {}}
onFocus={(event, editor) => {}}
/>
I hope that helps.
Thanks a lot @chhatch I really appreciate your help.
while using onInit ckeditor suggested me to use onReady instead. After the change it worked perfectly as expected.
But when the _focus is removed_ from the text block and then when i hit 'Ctrl+Z' it undo the text i typed.
current i have used cancel() in place of undo().
Note: when the text block is focused it does not undo. which is working as expected.
Any workaround for this? Thankyou
I think I had the same issue. This didn't solve all my problems, and I don't think I ever got things working perfectly. It may have been the same issue you're describing.
Unfortunately, the project I was working on got abandoned shortly after I posted this question, which feels like a lifetime ago. I remember doing lots of debugging trying to figure out the flow of events for 'Ctrl-Z'. One of my last commits says, "
Removing ckeditor undo plugin.. stuck." :sweat_smile:
Good luck!
Most helpful comment
I think I had the same issue. This didn't solve all my problems, and I don't think I ever got things working perfectly. It may have been the same issue you're describing.
Unfortunately, the project I was working on got abandoned shortly after I posted this question, which feels like a lifetime ago. I remember doing lots of debugging trying to figure out the flow of events for 'Ctrl-Z'. One of my last commits says, "
Removing ckeditor undo plugin.. stuck." :sweat_smile:
Good luck!