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 error TypeError: Cannot read property 'matchesNode' of null
Anyone know how?
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 prosemirror-history. Related: https://discuss.prosemirror.net/t/reset-history-plugin-state/1883
Feel free to create a PR for prosemirror.
Sent a simple PR for this https://github.com/ProseMirror/prosemirror-history/pull/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 Editor.loadDocument(doc, version)?
this.editor.options.content = jsonDocOrHTML this.editor.view.updateState(this.editor.createState())
So updating current editor state is not the best solution in my case. It breaks menu positioning so menu.left and menu.bottom always return 0. I believe that I found the right-way solution:
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);
TextSelection should be imported from 'tiptap' as well.
Note: this code only prevents pushing new content to the history stack but NOT clears the entire history. It can be useful when you need to replace content after fetching it from API.
Most helpful comment
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: