1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-11 17:53:59 +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 Text from './text'
import convertRangesToCharacters from '../utils/convert-ranges-to-characters' import convertRangesToCharacters from '../utils/convert-ranges-to-characters'
import toCamel from 'to-camel-case' import toCamel from 'to-camel-case'
import { OrderedMap, Record } from 'immutable' import { OrderedMap, Record, Stack } from 'immutable'
/** /**
* Record. * Record.
@@ -12,7 +12,9 @@ import { OrderedMap, Record } from 'immutable'
const StateRecord = new Record({ const StateRecord = new Record({
nodes: new OrderedMap(), 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 { class State extends StateRecord {
/** /**
* Create a new `State` from `attrs`. * Create a new `State` from a Javascript `object`.
* *
* @param {Objetc} object
* @return {State} state * @return {State} state
*/ */
@@ -554,6 +557,80 @@ class State extends StateRecord {
return state 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 if (IS_WINDOWS && e.shiftKey) return
e.preventDefault() e.preventDefault()
return isWord(e) return isWord(e)
? state.backspaceWord() ? state.save().backspaceWord()
: state.deleteBackward() : state.save().deleteBackward()
} }
case 'delete': { case 'delete': {
@@ -40,8 +40,8 @@ const CORE_PLUGIN = {
if (IS_WINDOWS && e.shiftKey) return if (IS_WINDOWS && e.shiftKey) return
e.preventDefault() e.preventDefault()
return isWord(e) return isWord(e)
? state.deleteWord() ? state.save().deleteWord()
: state.deleteForward() : state.save().deleteForward()
} }
case 'y': { case 'y': {