0
# History Editor
1
2
The `HistoryEditor` interface extends Slate's base editor with history-specific methods and provides utilities for controlling history behavior, managing operation batching, and accessing history state.
3
4
## Capabilities
5
6
### HistoryEditor Interface
7
8
Extended editor interface that includes history functionality and state management methods.
9
10
```typescript { .api }
11
interface HistoryEditor extends BaseEditor {
12
/** History object containing undo and redo stacks */
13
history: History;
14
/** Undo the last batch of operations */
15
undo: () => void;
16
/** Redo the last undone batch of operations */
17
redo: () => void;
18
/** Write a batch of operations to the specified history stack */
19
writeHistory: (stack: 'undos' | 'redos', batch: any) => void;
20
}
21
```
22
23
### Type Guards
24
25
Check if an editor has history functionality.
26
27
```typescript { .api }
28
/**
29
* Check if a value is a HistoryEditor (has history functionality)
30
* @param value - Value to check
31
* @returns True if value is a HistoryEditor
32
*/
33
function isHistoryEditor(value: any): value is HistoryEditor;
34
```
35
36
**Usage Example:**
37
38
```typescript
39
import { HistoryEditor } from "slate-history";
40
41
if (HistoryEditor.isHistoryEditor(editor)) {
42
// Safe to use history methods
43
editor.undo();
44
editor.redo();
45
console.log(editor.history.undos.length);
46
}
47
```
48
49
### Undo and Redo Operations
50
51
Static methods for performing undo and redo operations.
52
53
```typescript { .api }
54
/**
55
* Undo to the previous saved state
56
* @param editor - HistoryEditor instance
57
*/
58
function undo(editor: HistoryEditor): void;
59
60
/**
61
* Redo to the next saved state
62
* @param editor - HistoryEditor instance
63
*/
64
function redo(editor: HistoryEditor): void;
65
```
66
67
**Usage Examples:**
68
69
```typescript
70
import { HistoryEditor } from "slate-history";
71
72
// Using static methods
73
HistoryEditor.undo(editor);
74
HistoryEditor.redo(editor);
75
76
// Using instance methods (equivalent)
77
editor.undo();
78
editor.redo();
79
```
80
81
### State Management Utilities
82
83
Methods for checking and controlling editor history state flags.
84
85
```typescript { .api }
86
/**
87
* Get the current merging flag value
88
* @param editor - HistoryEditor instance
89
* @returns Current merging state (undefined, true, or false)
90
*/
91
function isMerging(editor: HistoryEditor): boolean | undefined;
92
93
/**
94
* Get the current saving flag value
95
* @param editor - HistoryEditor instance
96
* @returns Current saving state (undefined, true, or false)
97
*/
98
function isSaving(editor: HistoryEditor): boolean | undefined;
99
100
/**
101
* Get the current splitting once flag value
102
* @param editor - HistoryEditor instance
103
* @returns Current splitting state (undefined, true, or false)
104
*/
105
function isSplittingOnce(editor: HistoryEditor): boolean | undefined;
106
107
/**
108
* Set the splitting once flag value
109
* @param editor - HistoryEditor instance
110
* @param value - New splitting state
111
*/
112
function setSplittingOnce(editor: HistoryEditor, value: boolean | undefined): void;
113
```
114
115
### Operation Control Methods
116
117
Methods for controlling how operations are batched and saved to history.
118
119
```typescript { .api }
120
/**
121
* Apply operations inside a function with merging enabled
122
* Operations will be merged into the previous history batch
123
* @param editor - HistoryEditor instance
124
* @param fn - Function to execute with merging enabled
125
*/
126
function withMerging(editor: HistoryEditor, fn: () => void): void;
127
128
/**
129
* Apply operations ensuring the first operation starts a new batch
130
* Subsequent operations will be merged as usual
131
* @param editor - HistoryEditor instance
132
* @param fn - Function to execute with new batch behavior
133
*/
134
function withNewBatch(editor: HistoryEditor, fn: () => void): void;
135
136
/**
137
* Apply operations without merging into previous save point
138
* Each operation will create its own history batch
139
* @param editor - HistoryEditor instance
140
* @param fn - Function to execute without merging
141
*/
142
function withoutMerging(editor: HistoryEditor, fn: () => void): void;
143
144
/**
145
* Apply operations without saving to history
146
* Operations will not be recorded for undo/redo
147
* @param editor - HistoryEditor instance
148
* @param fn - Function to execute without saving
149
*/
150
function withoutSaving(editor: HistoryEditor, fn: () => void): void;
151
```
152
153
**Usage Examples:**
154
155
```typescript
156
import { HistoryEditor } from "slate-history";
157
158
// Merge multiple operations into one undo batch
159
HistoryEditor.withMerging(editor, () => {
160
editor.insertText("Hello");
161
editor.insertText(" ");
162
editor.insertText("World");
163
// All three insertions will be undone together
164
});
165
166
// Create a new batch even if operations would normally merge
167
HistoryEditor.withNewBatch(editor, () => {
168
editor.insertText("New batch");
169
editor.insertText(" continues"); // This will merge with above
170
});
171
172
// Prevent operations from merging
173
HistoryEditor.withoutMerging(editor, () => {
174
editor.insertText("Each");
175
editor.insertText("word"); // Each insertion is separate undo batch
176
});
177
178
// Perform operations without recording in history
179
HistoryEditor.withoutSaving(editor, () => {
180
editor.insertText("Temporary change");
181
// This won't be undoable
182
});
183
```
184
185
## WeakMap State Storage
186
187
The HistoryEditor uses WeakMaps for internal state management:
188
189
```typescript { .api }
190
/** WeakMap for attaching History objects to editors */
191
const HISTORY: WeakMap<Editor, History>;
192
193
/** WeakMap for tracking saving state */
194
const SAVING: WeakMap<Editor, boolean | undefined>;
195
196
/** WeakMap for tracking merging state */
197
const MERGING: WeakMap<Editor, boolean | undefined>;
198
199
/** WeakMap for tracking splitting once state */
200
const SPLITTING_ONCE: WeakMap<Editor, boolean | undefined>;
201
```
202
203
These WeakMaps are used internally by the history system and are exported for advanced use cases, but typical usage should rely on the provided static methods for state management.
204
205
## State Management Patterns
206
207
**Checking State:**
208
209
```typescript
210
// Check if operations are currently being merged
211
if (HistoryEditor.isMerging(editor)) {
212
console.log("Operations will be merged");
213
}
214
215
// Check if operations are being saved to history
216
if (HistoryEditor.isSaving(editor) !== false) {
217
console.log("Operations will be saved");
218
}
219
```
220
221
**Nested State Control:**
222
223
```typescript
224
// State control methods properly handle nesting
225
HistoryEditor.withoutSaving(editor, () => {
226
HistoryEditor.withMerging(editor, () => {
227
// Operations here are merged but not saved
228
editor.insertText("temp");
229
});
230
});
231
```