-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to clear history? #491
Comments
Did you find out how to clear the history? |
I ended up doing my custom history. Not ideal but I couldn't find any other way. |
Just destroy your editor and create a new one seems to do the trick. private editor = new Editor(this.editorOptions);
private get editorOptions() {
return {
...
};
}
clearHistory() {
this.editor.destroy();
this.editor = new Editor(this.editorOptions);
} And I didn't notice any stuttering by recreating the editor (yet) |
There is not such a feature in Feel free to create a PR for prosemirror. |
Sent a simple PR for this ProseMirror/prosemirror-history#5 |
When loading a new file, you should create a fresh ProseMirror state. I don't intend to merge that PR until someone comes up with a more compelling use case. |
@marijnh Thanks for the quick response. That makes sense. Actually, I added it according to your suggestion here https://discuss.prosemirror.net/t/reset-history-plugin-state/1883 |
Ah right, seems I did suggest that last year. But there's other weird effects you'll get when trying to start a new document without starting a new state (decorations might stick around, other plugins might still drag around irrelevant state), so unless someone has a more solid reason for needing this, I think providing it just steers people in the wrong direction. |
As per the suggestion of the author we should set brand new state when loading new document. I am doing it in this way if anyone needs: this.editor.options.content = jsonDocOrHTML
this.editor.view.updateState(this.editor.createState()) |
It would be good to encapsulate this functionality, preferably also handling the collaboration plugin state (#691). How about |
So updating current editor state is not the best solution in my case. It breaks menu positioning so const { doc, tr } = this.editor.state;
const document = this.editor.createDocument(yourHTMLOrJSONContentHere);
const selection = TextSelection.create(doc, 0, doc.content.size);
const transaction = tr
.setSelection(selection)
.replaceSelectionWith(document, false)
.setMeta('preventUpdate', true) // true by default but you can set it to false
.setMeta('addToHistory', false); // Finally we prevent pushing content to the history
this.editor.view.dispatch(transaction);
Note: this code only prevents pushing new content to the history stack but DOES NOT clear the entire history. It can be useful when you need to replace content after fetching it from API. |
We can create an extension like this: import { Extension } from '@tiptap/core';
export default Extension.create({
name: 'loaddoc',
addCommands() {
return {
loadContent:
(content) => ({ tr, dispatch, commands }) => {
commands.setContent(content, false, { preserveWhitespace: 'full' });
if (dispatch) {
tr.setMeta('addToHistory', false); // Finally we prevent pushing content to the history
}
return true;
},
};
},
}); |
Is it possible to do this like this in the current version of @marijnh Curious if you see any issues with this?
|
I don't know if this is the best approach but after fetching content from api and using |
The previous answers did not work for me because of missing types and/or members. The following code worked for me and I could not see any side effects in my application. import { Editor } from "@tiptap/core";
import { EditorState } from 'prosemirror-state';
function resetEditorContent(editor: Editor, newContent: string) {
editor.commands.setContent(newContent);
// The following code clears the history. Hopefully without side effects.
const newEditorState = EditorState.create({
doc: editor.state.doc,
plugins: editor.state.plugins,
schema: editor.state.schema
});
editor.view.updateState(newEditorState);
} |
Thank you this one worked great and clean. |
Previous two answers work great, though I'm setting the document directly in the state (saves one transaction I guess): import { Editor, createDocument } from '@tiptap/core'
import { EditorState } from 'prosemirror-state'
function resetEditorState(editor: Editor, content: string) {
const newState = EditorState.create({
doc: createDocument(content, editor.schema),
schema: editor.schema,
plugins: editor.state.plugins,
})
editor.view.updateState(newState)
} |
I tried this, but when I clicked the content of editor, the cursor sometimes would jump to the beginning of the line... A little problem though. |
Here is the solution. I hope it helps for future seekers.
|
This solution unfortunately did not work for me, and I am unable to figure out why. I am loading new content into existing editor instance after fetching the content from backend. I am using the vue-3 package although not sure if that matters. But I did find an alternative solution that works for me. It's involves unregistering the history plugin, and re-registering it with a new instance of the plugin: import { history } from '@tiptap/pm/history';
const editor = useEditor({ ...});
await useFetch('/content', {
onResponse(ctx) {
if (ctx.response.ok) {
editor.value.commands.setContent(ctx.response._data.content, false); // <-- data from backend
// unregister and re-register history plugin to clear data when fetching new content
editor.value?.unregisterPlugin('history');
editor.value?.registerPlugin(history());
editor.value.commands.focus('end');
}
},
}); |
I do this --
but I get a Any idea? |
Is it possible to clear the history?
The problem is that I'm changing the content in the editor dynamically when user selects a new "file", but then the history from the last file will still be available.
Basically, when a user changes file, and hit undo, the content from the last file will be put into the editor. So I want to clear history every time the user changes files.
I've tried recreating the component using the "hack"
:key="componentKey"
- but it just gave an errorTypeError: Cannot read property 'matchesNode' of null
Anyone know how?
The text was updated successfully, but these errors were encountered: