Improve undo history (#2437)

This commit is contained in:
Felix Häusler 2020-12-23 14:20:50 +01:00 committed by GitHub
parent 0a8e49bfa5
commit 08231c0c22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 7 deletions

View File

@ -6,9 +6,11 @@ class History {
this.stack = [] this.stack = []
this.index = -1 this.index = -1
this.contentState = contentState this.contentState = contentState
this.pending = null
} }
undo () { undo () {
this.commitPending()
if (this.index > 0) { if (this.index > 0) {
this.index = this.index - 1 this.index = this.index - 1
@ -23,6 +25,7 @@ class History {
} }
redo () { redo () {
this.pending = null
const { index, stack } = this const { index, stack } = this
const len = stack.length const len = stack.length
if (index < len - 1) { if (index < len - 1) {
@ -38,6 +41,7 @@ class History {
} }
push (state) { push (state) {
this.pending = null
this.stack.splice(this.index + 1) this.stack.splice(this.index + 1)
const copyState = deepCopy(state) const copyState = deepCopy(state)
this.stack.push(copyState) this.stack.push(copyState)
@ -48,9 +52,20 @@ class History {
this.index = this.index + 1 this.index = this.index + 1
} }
pushPending (state) {
this.pending = state
}
commitPending () {
if (this.pending) {
this.push(this.pending)
}
}
clearHistory () { clearHistory () {
this.stack = [] this.stack = []
this.index = -1 this.index = -1
this.pending = null
} }
} }

View File

@ -135,16 +135,18 @@ class ContentState {
if (!(cursor instanceof Cursor)) { if (!(cursor instanceof Cursor)) {
cursor = new Cursor(cursor) cursor = new Cursor(cursor)
} }
const handler = () => {
this.prevCursor = this.currentCursor
this.currentCursor = cursor
const getHistoryState = () => {
const { blocks, renderRange, currentCursor } = this const { blocks, renderRange, currentCursor } = this
this.history.push({ return {
blocks, blocks,
renderRange, renderRange,
cursor: currentCursor cursor: currentCursor
}) }
} }
this.prevCursor = this.currentCursor
this.currentCursor = cursor
if (!cursor.noHistory) { if (!cursor.noHistory) {
if ( if (
@ -154,10 +156,19 @@ class ContentState {
this.prevCursor.end.key !== cursor.end.key this.prevCursor.end.key !== cursor.end.key
) )
) { ) {
handler() // Push history immediately
this.history.push(getHistoryState())
} else { } else {
// WORKAROUND: The current engine doesn't support a smart history and we
// need to store the whole state. Therefore, we push history only when the
// user stops typing. Pushing one pending entry allows us to commit the
// change before an undo action is triggered to partially solve #1321.
if (this.historyTimer) clearTimeout(this.historyTimer) if (this.historyTimer) clearTimeout(this.historyTimer)
this.historyTimer = setTimeout(handler, 2000) this.history.pushPending(getHistoryState())
this.historyTimer = setTimeout(() => {
this.history.commitPending()
}, 2000)
} }
} }
} }