1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-16 12:14:14 +02:00

Fix several undo/redo issues related to selection operation (#2948)

Should fix the following issues: #2891, #2729
This commit is contained in:
Stan Gurenkov
2019-08-22 11:28:13 -07:00
committed by Ian Storm Taylor
parent 6e56932ee4
commit de376d79b8
2 changed files with 33 additions and 6 deletions

View File

@@ -11,6 +11,7 @@ import {
IS_FIREFOX, IS_FIREFOX,
HAS_INPUT_EVENTS_LEVEL_2, HAS_INPUT_EVENTS_LEVEL_2,
} from 'slate-dev-environment' } from 'slate-dev-environment'
import Hotkeys from 'slate-hotkeys'
import EVENT_HANDLERS from '../constants/event-handlers' import EVENT_HANDLERS from '../constants/event-handlers'
import DATA_ATTRS from '../constants/data-attributes' import DATA_ATTRS from '../constants/data-attributes'
@@ -386,10 +387,15 @@ class Content extends React.Component {
onEvent(handler, event) { onEvent(handler, event) {
debug('onEvent', handler) debug('onEvent', handler)
const nativeEvent = event.nativeEvent || event
const isUndoRedo =
event.type === 'keydown' &&
(Hotkeys.isUndo(nativeEvent) || Hotkeys.isRedo(nativeEvent))
// Ignore `onBlur`, `onFocus` and `onSelect` events generated // Ignore `onBlur`, `onFocus` and `onSelect` events generated
// programmatically while updating selection. // programmatically while updating selection.
if ( if (
this.tmp.isUpdatingSelection && (this.tmp.isUpdatingSelection || isUndoRedo) &&
(handler === 'onSelect' || handler === 'onBlur' || handler === 'onFocus') (handler === 'onSelect' || handler === 'onBlur' || handler === 'onFocus')
) { ) {
return return

View File

@@ -20,7 +20,7 @@ Commands.save = (editor, operation) => {
const { operations, value } = editor const { operations, value } = editor
const { data } = value const { data } = value
let { save, merge } = editor.tmp let { save, merge } = editor.tmp
if (save === false) return if (save === false || !isValidOperation(operation)) return
let undos = data.get('undos') || List() let undos = data.get('undos') || List()
const lastBatch = undos.last() const lastBatch = undos.last()
@@ -78,12 +78,12 @@ Commands.redo = editor => {
editor.withoutNormalizing(() => { editor.withoutNormalizing(() => {
// Replay the batch of operations. // Replay the batch of operations.
batch.forEach(op => { batch.forEach(op => {
const { type, properties } = op const { type, newProperties } = op
// When the operation mutates the selection, omit its `isFocused` value to // When the operation mutates the selection, omit its `isFocused` value to
// prevent the editor focus from changing during redoing. // prevent the editor focus from changing during redoing.
if (type === 'set_selection') { if (type === 'set_selection') {
op = op.set('properties', omit(properties, 'isFocused')) op = op.set('newProperties', omit(newProperties, 'isFocused'))
} }
editor.applyOperation(op) editor.applyOperation(op)
@@ -120,12 +120,15 @@ Commands.undo = editor => {
.reverse() .reverse()
.map(op => op.invert()) .map(op => op.invert())
.forEach(inverse => { .forEach(inverse => {
const { type, properties } = inverse const { type, newProperties } = inverse
// When the operation mutates the selection, omit its `isFocused` value to // When the operation mutates the selection, omit its `isFocused` value to
// prevent the editor focus from changing during undoing. // prevent the editor focus from changing during undoing.
if (type === 'set_selection') { if (type === 'set_selection') {
inverse = inverse.set('properties', omit(properties, 'isFocused')) inverse = inverse.set(
'newProperties',
omit(newProperties, 'isFocused')
)
} }
editor.applyOperation(inverse) editor.applyOperation(inverse)
@@ -195,6 +198,24 @@ function shouldMerge(o, p) {
return merge return merge
} }
/**
* Check weather an operation needs to be saved to the history
* @param {Object} o - operation
* @returns {Boolean}
*/
function isValidOperation(o) {
if (o.type === 'set_selection') {
const { isFocused, anchor, focus } = o.newProperties
// this is blur/focus operation, dont need to store it into the history
if (isFocused !== undefined && !anchor && !focus) {
return false
}
}
return true
}
/** /**
* Export. * Export.
* *