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:
committed by
Ian Storm Taylor
parent
6e56932ee4
commit
de376d79b8
@@ -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
|
||||||
|
@@ -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.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user