1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-04-19 21:01:57 +02:00

added undo/redo support

This commit is contained in:
Ian Storm Taylor 2016-06-17 16:10:44 -07:00
parent e907979ff6
commit 8b9f5f0c00
2 changed files with 84 additions and 7 deletions

View File

@ -4,7 +4,7 @@ import Node from './node'
import Text from './text'
import convertRangesToCharacters from '../utils/convert-ranges-to-characters'
import toCamel from 'to-camel-case'
import { OrderedMap, Record } from 'immutable'
import { OrderedMap, Record, Stack } from 'immutable'
/**
* Record.
@ -12,7 +12,9 @@ import { OrderedMap, Record } from 'immutable'
const StateRecord = new Record({
nodes: new OrderedMap(),
selection: new Selection()
selection: new Selection(),
undoStack: new Stack(),
redoStack: new Stack()
})
/**
@ -58,8 +60,9 @@ const SELECTION_LIKE_METHODS = [
class State extends StateRecord {
/**
* Create a new `State` from `attrs`.
* Create a new `State` from a Javascript `object`.
*
* @param {Objetc} object
* @return {State} state
*/
@ -554,6 +557,80 @@ class State extends StateRecord {
return state
}
/**
* Save the current state into the history.
*
* @return {State} state
*/
save() {
let state = this
let { undoStack, redoStack } = state
undoStack = undoStack.unshift(state)
redoStack = redoStack.clear()
state = state.merge({
undoStack,
redoStack
})
return state
}
/**
* Undo.
*
* @return {State} state
*/
undo() {
let state = this
let { undoStack, redoStack } = state
// If there's no previous state, do nothing.
let previous = undoStack.peek()
if (!previous) return state
// Remove the previous state from the undo stack.
undoStack = undoStack.shift()
// Move the current state into the redo stack.
redoStack = redoStack.unshift(state)
// Return the previous state, with the new history.
return previous.merge({
undoStack,
redoStack
})
}
/**
* Redo.
*
* @return {State} state
*/
redo() {
let state = this
let { undoStack, redoStack } = state
// If there's no next state, do nothing.
let next = redoStack.peek()
if (!next) return state
// Remove the next state from the redo stack.
redoStack = redoStack.shift()
// Move the current state into the undo stack.
undoStack = undoStack.unshift(state)
// Return the next state, with the new history.
return next.merge({
undoStack,
redoStack
})
}
}
/**

View File

@ -31,8 +31,8 @@ const CORE_PLUGIN = {
if (IS_WINDOWS && e.shiftKey) return
e.preventDefault()
return isWord(e)
? state.backspaceWord()
: state.deleteBackward()
? state.save().backspaceWord()
: state.save().deleteBackward()
}
case 'delete': {
@ -40,8 +40,8 @@ const CORE_PLUGIN = {
if (IS_WINDOWS && e.shiftKey) return
e.preventDefault()
return isWord(e)
? state.deleteWord()
: state.deleteForward()
? state.save().deleteWord()
: state.save().deleteForward()
}
case 'y': {