@ckeditor/ckeditor5-undo 36.0.0 → 37.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -14
- package/src/basecommand.d.ts +70 -0
- package/src/basecommand.js +20 -22
- package/src/index.d.ts +11 -0
- package/src/redocommand.d.ts +32 -0
- package/src/redocommand.js +0 -2
- package/src/undo.d.ts +120 -0
- package/src/undo.js +54 -48
- package/src/undocommand.d.ts +42 -0
- package/src/undocommand.js +1 -3
- package/src/undoediting.d.ts +42 -0
- package/src/undoediting.js +9 -31
- package/src/undoui.d.ts +35 -0
- package/src/undoui.js +4 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-undo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "37.0.0-alpha.0",
|
|
4
4
|
"description": "Undo feature for CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
],
|
|
13
13
|
"main": "src/index.js",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ckeditor/ckeditor5-core": "^
|
|
16
|
-
"@ckeditor/ckeditor5-engine": "^
|
|
17
|
-
"@ckeditor/ckeditor5-ui": "^
|
|
15
|
+
"@ckeditor/ckeditor5-core": "^37.0.0-alpha.0",
|
|
16
|
+
"@ckeditor/ckeditor5-engine": "^37.0.0-alpha.0",
|
|
17
|
+
"@ckeditor/ckeditor5-ui": "^37.0.0-alpha.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@ckeditor/ckeditor5-basic-styles": "^
|
|
21
|
-
"@ckeditor/ckeditor5-clipboard": "^
|
|
22
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
|
23
|
-
"@ckeditor/ckeditor5-enter": "^
|
|
24
|
-
"@ckeditor/ckeditor5-heading": "^
|
|
25
|
-
"@ckeditor/ckeditor5-paragraph": "^
|
|
26
|
-
"@ckeditor/ckeditor5-typing": "^
|
|
27
|
-
"@ckeditor/ckeditor5-table": "^
|
|
28
|
-
"@ckeditor/ckeditor5-utils": "^
|
|
20
|
+
"@ckeditor/ckeditor5-basic-styles": "^37.0.0-alpha.0",
|
|
21
|
+
"@ckeditor/ckeditor5-clipboard": "^37.0.0-alpha.0",
|
|
22
|
+
"@ckeditor/ckeditor5-editor-classic": "^37.0.0-alpha.0",
|
|
23
|
+
"@ckeditor/ckeditor5-enter": "^37.0.0-alpha.0",
|
|
24
|
+
"@ckeditor/ckeditor5-heading": "^37.0.0-alpha.0",
|
|
25
|
+
"@ckeditor/ckeditor5-paragraph": "^37.0.0-alpha.0",
|
|
26
|
+
"@ckeditor/ckeditor5-typing": "^37.0.0-alpha.0",
|
|
27
|
+
"@ckeditor/ckeditor5-table": "^37.0.0-alpha.0",
|
|
28
|
+
"@ckeditor/ckeditor5-utils": "^37.0.0-alpha.0",
|
|
29
29
|
"typescript": "^4.8.4",
|
|
30
30
|
"webpack": "^5.58.1",
|
|
31
31
|
"webpack-cli": "^4.9.0"
|
|
@@ -54,5 +54,6 @@
|
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsc -p ./tsconfig.release.json",
|
|
56
56
|
"postversion": "npm run build"
|
|
57
|
-
}
|
|
57
|
+
},
|
|
58
|
+
"types": "src/index.d.ts"
|
|
58
59
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/basecommand
|
|
7
|
+
*/
|
|
8
|
+
import { Command, type Editor } from '@ckeditor/ckeditor5-core';
|
|
9
|
+
import { type Batch, type Operation, type Range } from '@ckeditor/ckeditor5-engine';
|
|
10
|
+
/**
|
|
11
|
+
* Base class for the undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.
|
|
12
|
+
*/
|
|
13
|
+
export default abstract class BaseCommand extends Command {
|
|
14
|
+
/**
|
|
15
|
+
* Stack of items stored by the command. These are pairs of:
|
|
16
|
+
*
|
|
17
|
+
* * {@link module:engine/model/batch~Batch batch} saved by the command,
|
|
18
|
+
* * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.
|
|
19
|
+
*/
|
|
20
|
+
protected _stack: Array<{
|
|
21
|
+
batch: Batch;
|
|
22
|
+
selection: {
|
|
23
|
+
ranges: Array<Range>;
|
|
24
|
+
isBackward: boolean;
|
|
25
|
+
};
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Stores all batches that were created by this command.
|
|
29
|
+
*/
|
|
30
|
+
protected _createdBatches: WeakSet<Batch>;
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
constructor(editor: Editor);
|
|
35
|
+
/**
|
|
36
|
+
* @inheritDoc
|
|
37
|
+
*/
|
|
38
|
+
refresh(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Returns all batches created by this command.
|
|
41
|
+
*/
|
|
42
|
+
get createdBatches(): WeakSet<Batch>;
|
|
43
|
+
/**
|
|
44
|
+
* Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}
|
|
45
|
+
* created by the editor which this command is registered to.
|
|
46
|
+
*
|
|
47
|
+
* @param batch The batch to add.
|
|
48
|
+
*/
|
|
49
|
+
addBatch(batch: Batch): void;
|
|
50
|
+
/**
|
|
51
|
+
* Removes all items from the stack.
|
|
52
|
+
*/
|
|
53
|
+
clearStack(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.
|
|
56
|
+
*
|
|
57
|
+
* @param ranges Ranges to be restored.
|
|
58
|
+
* @param isBackward A flag describing whether the restored range was selected forward or backward.
|
|
59
|
+
* @param operations Operations which has been applied since selection has been stored.
|
|
60
|
+
*/
|
|
61
|
+
protected _restoreSelection(ranges: Array<Range>, isBackward: boolean, operations: Array<Operation>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.
|
|
64
|
+
* This is a helper method for {@link #execute}.
|
|
65
|
+
*
|
|
66
|
+
* @param batchToUndo The batch to be undone.
|
|
67
|
+
* @param undoingBatch The batch that will contain undoing changes.
|
|
68
|
+
*/
|
|
69
|
+
protected _undo(batchToUndo: Batch, undoingBatch: Batch): void;
|
|
70
|
+
}
|
package/src/basecommand.js
CHANGED
|
@@ -9,11 +9,11 @@ import { Command } from '@ckeditor/ckeditor5-core';
|
|
|
9
9
|
import { transformSets } from '@ckeditor/ckeditor5-engine';
|
|
10
10
|
/**
|
|
11
11
|
* Base class for the undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.
|
|
12
|
-
*
|
|
13
|
-
* @protected
|
|
14
|
-
* @extends module:core/command~Command
|
|
15
12
|
*/
|
|
16
13
|
export default class BaseCommand extends Command {
|
|
14
|
+
/**
|
|
15
|
+
* @inheritDoc
|
|
16
|
+
*/
|
|
17
17
|
constructor(editor) {
|
|
18
18
|
super(editor);
|
|
19
19
|
/**
|
|
@@ -21,16 +21,10 @@ export default class BaseCommand extends Command {
|
|
|
21
21
|
*
|
|
22
22
|
* * {@link module:engine/model/batch~Batch batch} saved by the command,
|
|
23
23
|
* * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.
|
|
24
|
-
*
|
|
25
|
-
* @protected
|
|
26
|
-
* @member {Array} #_stack
|
|
27
24
|
*/
|
|
28
25
|
this._stack = [];
|
|
29
26
|
/**
|
|
30
27
|
* Stores all batches that were created by this command.
|
|
31
|
-
*
|
|
32
|
-
* @protected
|
|
33
|
-
* @member {WeakSet.<module:engine/model/batch~Batch>} #_createdBatches
|
|
34
28
|
*/
|
|
35
29
|
this._createdBatches = new WeakSet();
|
|
36
30
|
// Refresh state, so the command is inactive right after initialization.
|
|
@@ -63,11 +57,17 @@ export default class BaseCommand extends Command {
|
|
|
63
57
|
refresh() {
|
|
64
58
|
this.isEnabled = this._stack.length > 0;
|
|
65
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns all batches created by this command.
|
|
62
|
+
*/
|
|
63
|
+
get createdBatches() {
|
|
64
|
+
return this._createdBatches;
|
|
65
|
+
}
|
|
66
66
|
/**
|
|
67
67
|
* Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}
|
|
68
68
|
* created by the editor which this command is registered to.
|
|
69
69
|
*
|
|
70
|
-
* @param
|
|
70
|
+
* @param batch The batch to add.
|
|
71
71
|
*/
|
|
72
72
|
addBatch(batch) {
|
|
73
73
|
const docSelection = this.editor.model.document.selection;
|
|
@@ -88,11 +88,9 @@ export default class BaseCommand extends Command {
|
|
|
88
88
|
/**
|
|
89
89
|
* Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.
|
|
90
90
|
*
|
|
91
|
-
* @
|
|
92
|
-
* @param
|
|
93
|
-
* @param
|
|
94
|
-
* @param {Array.<module:engine/model/operation/operation~Operation>} operations Operations which has been applied
|
|
95
|
-
* since selection has been stored.
|
|
91
|
+
* @param ranges Ranges to be restored.
|
|
92
|
+
* @param isBackward A flag describing whether the restored range was selected forward or backward.
|
|
93
|
+
* @param operations Operations which has been applied since selection has been stored.
|
|
96
94
|
*/
|
|
97
95
|
_restoreSelection(ranges, isBackward, operations) {
|
|
98
96
|
const model = this.editor.model;
|
|
@@ -131,9 +129,8 @@ export default class BaseCommand extends Command {
|
|
|
131
129
|
* Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.
|
|
132
130
|
* This is a helper method for {@link #execute}.
|
|
133
131
|
*
|
|
134
|
-
* @
|
|
135
|
-
* @param
|
|
136
|
-
* @param {module:engine/model/batch~Batch} undoingBatch The batch that will contain undoing changes.
|
|
132
|
+
* @param batchToUndo The batch to be undone.
|
|
133
|
+
* @param undoingBatch The batch that will contain undoing changes.
|
|
137
134
|
*/
|
|
138
135
|
_undo(batchToUndo, undoingBatch) {
|
|
139
136
|
const model = this.editor.model;
|
|
@@ -164,10 +161,11 @@ export default class BaseCommand extends Command {
|
|
|
164
161
|
}
|
|
165
162
|
}
|
|
166
163
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Normalizes list of ranges by joining intersecting or "touching" ranges.
|
|
166
|
+
*
|
|
167
|
+
* @param ranges Ranges to be normalized.
|
|
168
|
+
*/
|
|
171
169
|
function normalizeRanges(ranges) {
|
|
172
170
|
ranges.sort((a, b) => a.start.isBefore(b.start) ? -1 : 1);
|
|
173
171
|
for (let i = 1; i < ranges.length; i++) {
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo
|
|
7
|
+
*/
|
|
8
|
+
export { default as Undo } from './undo';
|
|
9
|
+
export { default as UndoEditing } from './undoediting';
|
|
10
|
+
export { default as UndoUi } from './undoui';
|
|
11
|
+
export type { default as UndoCommand } from './undocommand';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/redocommand
|
|
7
|
+
*/
|
|
8
|
+
import BaseCommand from './basecommand';
|
|
9
|
+
/**
|
|
10
|
+
* The redo command stores {@link module:engine/model/batch~Batch batches} that were used to undo a batch by
|
|
11
|
+
* {@link module:undo/undocommand~UndoCommand}. It is able to redo a previously undone batch by reversing the undoing
|
|
12
|
+
* batches created by `UndoCommand`. The reversed batch is transformed by all the batches from
|
|
13
|
+
* {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.
|
|
14
|
+
*
|
|
15
|
+
* The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.
|
|
16
|
+
*/
|
|
17
|
+
export default class RedoCommand extends BaseCommand {
|
|
18
|
+
/**
|
|
19
|
+
* Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to
|
|
20
|
+
* the command's stack, applies the reverted and transformed version on the
|
|
21
|
+
* {@link module:engine/model/document~Document document} and removes the batch from the stack.
|
|
22
|
+
* Then, it restores the {@link module:engine/model/document~Document#selection document selection}.
|
|
23
|
+
*
|
|
24
|
+
* @fires execute
|
|
25
|
+
*/
|
|
26
|
+
execute(): void;
|
|
27
|
+
}
|
|
28
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
29
|
+
interface CommandsMap {
|
|
30
|
+
redo: RedoCommand;
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/redocommand.js
CHANGED
|
@@ -13,8 +13,6 @@ import BaseCommand from './basecommand';
|
|
|
13
13
|
* {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.
|
|
14
14
|
*
|
|
15
15
|
* The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.
|
|
16
|
-
*
|
|
17
|
-
* @extends module:undo/basecommand~BaseCommand
|
|
18
16
|
*/
|
|
19
17
|
export default class RedoCommand extends BaseCommand {
|
|
20
18
|
/**
|
package/src/undo.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/undo
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin, type PluginDependencies } from '@ckeditor/ckeditor5-core';
|
|
9
|
+
/**
|
|
10
|
+
* The undo feature.
|
|
11
|
+
*
|
|
12
|
+
* This is a "glue" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}
|
|
13
|
+
* and the {@link module:undo/undoui~UndoUI undo UI feature}.
|
|
14
|
+
*
|
|
15
|
+
* Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:
|
|
16
|
+
*
|
|
17
|
+
* Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the
|
|
18
|
+
* {@link module:engine/model/document~Document document}, it is saved to `History` as is.
|
|
19
|
+
* The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in
|
|
20
|
+
* {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the
|
|
21
|
+
* operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation
|
|
22
|
+
* and a batch is seen as one undo step.
|
|
23
|
+
*
|
|
24
|
+
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
|
25
|
+
*
|
|
26
|
+
* ```
|
|
27
|
+
* History Undo stack
|
|
28
|
+
* ============== ==================================
|
|
29
|
+
* [operation A1] [ batch A ]
|
|
30
|
+
* [operation B1] [ batch B ]
|
|
31
|
+
* [operation B2] [ batch C ]
|
|
32
|
+
* [operation C1]
|
|
33
|
+
* [operation C2]
|
|
34
|
+
* [operation B3]
|
|
35
|
+
* [operation C3]
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Where operations starting with the same letter are from same batch.
|
|
39
|
+
*
|
|
40
|
+
* Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.
|
|
41
|
+
* For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing
|
|
42
|
+
* operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`
|
|
43
|
+
* need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`
|
|
44
|
+
* does not know that operations `Y` and `Z` happened.
|
|
45
|
+
*
|
|
46
|
+
* After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},
|
|
47
|
+
* one needs to make sure if they are ready to be applied. In the scenario above, operation `C3` is the last operation and `C3r`
|
|
48
|
+
* bases on up-to-date document state, so it can be applied to the document.
|
|
49
|
+
*
|
|
50
|
+
* ```
|
|
51
|
+
* History Undo stack
|
|
52
|
+
* ================= ==================================
|
|
53
|
+
* [ operation A1 ] [ batch A ]
|
|
54
|
+
* [ operation B1 ] [ batch B ]
|
|
55
|
+
* [ operation B2 ] [ processing undoing batch C ]
|
|
56
|
+
* [ operation C1 ]
|
|
57
|
+
* [ operation C2 ]
|
|
58
|
+
* [ operation B3 ]
|
|
59
|
+
* [ operation C3 ]
|
|
60
|
+
* [ operation C3r ]
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
|
64
|
+
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
|
65
|
+
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
|
66
|
+
*
|
|
67
|
+
* ```
|
|
68
|
+
* History Undo stack Redo stack
|
|
69
|
+
* ================= ================================== ==================================
|
|
70
|
+
* [ operation A1 ] [ batch A ] [ batch Cr ]
|
|
71
|
+
* [ operation B1 ] [ batch B ]
|
|
72
|
+
* [ operation B2 ]
|
|
73
|
+
* [ operation C1 ]
|
|
74
|
+
* [ operation C2 ]
|
|
75
|
+
* [ operation B3 ]
|
|
76
|
+
* [ operation C3 ]
|
|
77
|
+
* [ operation C3r ]
|
|
78
|
+
* [ operation C2' ]
|
|
79
|
+
* [ operation C1' ]
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
|
83
|
+
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
|
84
|
+
*
|
|
85
|
+
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
|
86
|
+
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
|
87
|
+
*
|
|
88
|
+
* ```
|
|
89
|
+
* History Undo stack Redo stack
|
|
90
|
+
* ================= ================================== ==================================
|
|
91
|
+
* [ operation A1 ] [ batch A ]
|
|
92
|
+
* [ operation B1 ] [ batch B ]
|
|
93
|
+
* [ operation B2 ] [ batch Crr ]
|
|
94
|
+
* [ operation C1 ]
|
|
95
|
+
* [ operation C2 ]
|
|
96
|
+
* [ operation B3 ]
|
|
97
|
+
* [ operation C3 ]
|
|
98
|
+
* [ operation C3r ]
|
|
99
|
+
* [ operation C2' ]
|
|
100
|
+
* [ operation C1' ]
|
|
101
|
+
* [ operation C1'r]
|
|
102
|
+
* [ operation C2'r]
|
|
103
|
+
* [ operation C3rr]
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export default class Undo extends Plugin {
|
|
107
|
+
/**
|
|
108
|
+
* @inheritDoc
|
|
109
|
+
*/
|
|
110
|
+
static get requires(): PluginDependencies;
|
|
111
|
+
/**
|
|
112
|
+
* @inheritDoc
|
|
113
|
+
*/
|
|
114
|
+
static get pluginName(): 'Undo';
|
|
115
|
+
}
|
|
116
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
117
|
+
interface PluginsMap {
|
|
118
|
+
[Undo.pluginName]: Undo;
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/undo.js
CHANGED
|
@@ -25,15 +25,17 @@ import UndoUI from './undoui';
|
|
|
25
25
|
*
|
|
26
26
|
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
28
|
+
* ```
|
|
29
|
+
* History Undo stack
|
|
30
|
+
* ============== ==================================
|
|
31
|
+
* [operation A1] [ batch A ]
|
|
32
|
+
* [operation B1] [ batch B ]
|
|
33
|
+
* [operation B2] [ batch C ]
|
|
34
|
+
* [operation C1]
|
|
35
|
+
* [operation C2]
|
|
36
|
+
* [operation B3]
|
|
37
|
+
* [operation C3]
|
|
38
|
+
* ```
|
|
37
39
|
*
|
|
38
40
|
* Where operations starting with the same letter are from same batch.
|
|
39
41
|
*
|
|
@@ -47,33 +49,37 @@ import UndoUI from './undoui';
|
|
|
47
49
|
* one needs to make sure if they are ready to be applied. In the scenario above, operation `C3` is the last operation and `C3r`
|
|
48
50
|
* bases on up-to-date document state, so it can be applied to the document.
|
|
49
51
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
52
|
+
* ```
|
|
53
|
+
* History Undo stack
|
|
54
|
+
* ================= ==================================
|
|
55
|
+
* [ operation A1 ] [ batch A ]
|
|
56
|
+
* [ operation B1 ] [ batch B ]
|
|
57
|
+
* [ operation B2 ] [ processing undoing batch C ]
|
|
58
|
+
* [ operation C1 ]
|
|
59
|
+
* [ operation C2 ]
|
|
60
|
+
* [ operation B3 ]
|
|
61
|
+
* [ operation C3 ]
|
|
62
|
+
* [ operation C3r ]
|
|
63
|
+
* ```
|
|
60
64
|
*
|
|
61
65
|
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
|
62
66
|
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
|
63
67
|
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
|
64
68
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
69
|
+
* ```
|
|
70
|
+
* History Undo stack Redo stack
|
|
71
|
+
* ================= ================================== ==================================
|
|
72
|
+
* [ operation A1 ] [ batch A ] [ batch Cr ]
|
|
73
|
+
* [ operation B1 ] [ batch B ]
|
|
74
|
+
* [ operation B2 ]
|
|
75
|
+
* [ operation C1 ]
|
|
76
|
+
* [ operation C2 ]
|
|
77
|
+
* [ operation B3 ]
|
|
78
|
+
* [ operation C3 ]
|
|
79
|
+
* [ operation C3r ]
|
|
80
|
+
* [ operation C2' ]
|
|
81
|
+
* [ operation C1' ]
|
|
82
|
+
* ```
|
|
77
83
|
*
|
|
78
84
|
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
|
79
85
|
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
|
@@ -81,23 +87,23 @@ import UndoUI from './undoui';
|
|
|
81
87
|
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
|
82
88
|
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
|
83
89
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
90
|
+
* ```
|
|
91
|
+
* History Undo stack Redo stack
|
|
92
|
+
* ================= ================================== ==================================
|
|
93
|
+
* [ operation A1 ] [ batch A ]
|
|
94
|
+
* [ operation B1 ] [ batch B ]
|
|
95
|
+
* [ operation B2 ] [ batch Crr ]
|
|
96
|
+
* [ operation C1 ]
|
|
97
|
+
* [ operation C2 ]
|
|
98
|
+
* [ operation B3 ]
|
|
99
|
+
* [ operation C3 ]
|
|
100
|
+
* [ operation C3r ]
|
|
101
|
+
* [ operation C2' ]
|
|
102
|
+
* [ operation C1' ]
|
|
103
|
+
* [ operation C1'r]
|
|
104
|
+
* [ operation C2'r]
|
|
105
|
+
* [ operation C3rr]
|
|
106
|
+
* ```
|
|
101
107
|
*/
|
|
102
108
|
export default class Undo extends Plugin {
|
|
103
109
|
/**
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/undocommand
|
|
7
|
+
*/
|
|
8
|
+
import BaseCommand from './basecommand';
|
|
9
|
+
import type { Batch } from '@ckeditor/ckeditor5-engine';
|
|
10
|
+
/**
|
|
11
|
+
* The undo command stores {@link module:engine/model/batch~Batch batches} applied to the
|
|
12
|
+
* {@link module:engine/model/document~Document document} and is able to undo a batch by reversing it and transforming by
|
|
13
|
+
* batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.
|
|
14
|
+
*
|
|
15
|
+
* The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.
|
|
16
|
+
*/
|
|
17
|
+
export default class UndoCommand extends BaseCommand {
|
|
18
|
+
/**
|
|
19
|
+
* Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms
|
|
20
|
+
* and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.
|
|
21
|
+
* Then, it restores the {@link module:engine/model/document~Document#selection document selection}.
|
|
22
|
+
*
|
|
23
|
+
* @fires execute
|
|
24
|
+
* @fires revert
|
|
25
|
+
* @param batch A batch that should be undone. If not set, the last added batch will be undone.
|
|
26
|
+
*/
|
|
27
|
+
execute(batch?: Batch | null): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fired when execution of the command reverts some batch.
|
|
31
|
+
*
|
|
32
|
+
* @eventName revert
|
|
33
|
+
*/
|
|
34
|
+
export type UndoCommandRevertEvent = {
|
|
35
|
+
name: 'revert';
|
|
36
|
+
args: [batch: Batch, undoingBatch: Batch];
|
|
37
|
+
};
|
|
38
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
39
|
+
interface CommandsMap {
|
|
40
|
+
undo: UndoCommand;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/undocommand.js
CHANGED
|
@@ -12,8 +12,6 @@ import BaseCommand from './basecommand';
|
|
|
12
12
|
* batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.
|
|
13
13
|
*
|
|
14
14
|
* The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.
|
|
15
|
-
*
|
|
16
|
-
* @extends module:undo/basecommand~BaseCommand
|
|
17
15
|
*/
|
|
18
16
|
export default class UndoCommand extends BaseCommand {
|
|
19
17
|
/**
|
|
@@ -23,7 +21,7 @@ export default class UndoCommand extends BaseCommand {
|
|
|
23
21
|
*
|
|
24
22
|
* @fires execute
|
|
25
23
|
* @fires revert
|
|
26
|
-
* @param
|
|
24
|
+
* @param batch A batch that should be undone. If not set, the last added batch will be undone.
|
|
27
25
|
*/
|
|
28
26
|
execute(batch = null) {
|
|
29
27
|
// If batch is not given, set `batchIndex` to the last index in command stack.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/undoediting
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
9
|
+
/**
|
|
10
|
+
* The undo engine feature.
|
|
11
|
+
*
|
|
12
|
+
* It introduces the `'undo'` and `'redo'` commands to the editor.
|
|
13
|
+
*/
|
|
14
|
+
export default class UndoEditing extends Plugin {
|
|
15
|
+
/**
|
|
16
|
+
* The command that manages the undo {@link module:engine/model/batch~Batch batches} stack (history).
|
|
17
|
+
* Created and registered during the {@link #init feature initialization}.
|
|
18
|
+
*/
|
|
19
|
+
private _undoCommand;
|
|
20
|
+
/**
|
|
21
|
+
* The command that manages the redo {@link module:engine/model/batch~Batch batches} stack (history).
|
|
22
|
+
* Created and registered during the {@link #init feature initialization}.
|
|
23
|
+
*/
|
|
24
|
+
private _redoCommand;
|
|
25
|
+
/**
|
|
26
|
+
* Keeps track of which batches were registered in undo.
|
|
27
|
+
*/
|
|
28
|
+
private _batchRegistry;
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
*/
|
|
32
|
+
static get pluginName(): 'UndoEditing';
|
|
33
|
+
/**
|
|
34
|
+
* @inheritDoc
|
|
35
|
+
*/
|
|
36
|
+
init(): void;
|
|
37
|
+
}
|
|
38
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
39
|
+
interface PluginsMap {
|
|
40
|
+
[UndoEditing.pluginName]: UndoEditing;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/undoediting.js
CHANGED
|
@@ -12,43 +12,21 @@ import RedoCommand from './redocommand';
|
|
|
12
12
|
* The undo engine feature.
|
|
13
13
|
*
|
|
14
14
|
* It introduces the `'undo'` and `'redo'` commands to the editor.
|
|
15
|
-
*
|
|
16
|
-
* @extends module:core/plugin~Plugin
|
|
17
15
|
*/
|
|
18
16
|
export default class UndoEditing extends Plugin {
|
|
17
|
+
constructor() {
|
|
18
|
+
super(...arguments);
|
|
19
|
+
/**
|
|
20
|
+
* Keeps track of which batches were registered in undo.
|
|
21
|
+
*/
|
|
22
|
+
this._batchRegistry = new WeakSet();
|
|
23
|
+
}
|
|
19
24
|
/**
|
|
20
25
|
* @inheritDoc
|
|
21
26
|
*/
|
|
22
27
|
static get pluginName() {
|
|
23
28
|
return 'UndoEditing';
|
|
24
29
|
}
|
|
25
|
-
/**
|
|
26
|
-
* @inheritDoc
|
|
27
|
-
*/
|
|
28
|
-
constructor(editor) {
|
|
29
|
-
super(editor);
|
|
30
|
-
/**
|
|
31
|
-
* The command that manages the undo {@link module:engine/model/batch~Batch batches} stack (history).
|
|
32
|
-
* Created and registered during the {@link #init feature initialization}.
|
|
33
|
-
*
|
|
34
|
-
* @private
|
|
35
|
-
* @member {module:undo/undocommand~UndoCommand} #_undoCommand
|
|
36
|
-
*/
|
|
37
|
-
/**
|
|
38
|
-
* The command that manages the redo {@link module:engine/model/batch~Batch batches} stack (history).
|
|
39
|
-
* Created and registered during the {@link #init feature initialization}.
|
|
40
|
-
*
|
|
41
|
-
* @private
|
|
42
|
-
* @member {module:undo/undocommand~UndoCommand} #_redoCommand
|
|
43
|
-
*/
|
|
44
|
-
/**
|
|
45
|
-
* Keeps track of which batches were registered in undo.
|
|
46
|
-
*
|
|
47
|
-
* @private
|
|
48
|
-
* @member {WeakSet.<module:engine/model/batch~Batch>}
|
|
49
|
-
*/
|
|
50
|
-
this._batchRegistry = new WeakSet();
|
|
51
|
-
}
|
|
52
30
|
/**
|
|
53
31
|
* @inheritDoc
|
|
54
32
|
*/
|
|
@@ -71,8 +49,8 @@ export default class UndoEditing extends Plugin {
|
|
|
71
49
|
return;
|
|
72
50
|
}
|
|
73
51
|
const batch = operation.batch;
|
|
74
|
-
const isRedoBatch = this._redoCommand.
|
|
75
|
-
const isUndoBatch = this._undoCommand.
|
|
52
|
+
const isRedoBatch = this._redoCommand.createdBatches.has(batch);
|
|
53
|
+
const isUndoBatch = this._undoCommand.createdBatches.has(batch);
|
|
76
54
|
const wasProcessed = this._batchRegistry.has(batch);
|
|
77
55
|
// Skip the batch if it was already processed.
|
|
78
56
|
if (wasProcessed) {
|
package/src/undoui.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module undo/undoui
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
9
|
+
/**
|
|
10
|
+
* The undo UI feature. It introduces the `'undo'` and `'redo'` buttons to the editor.
|
|
11
|
+
*/
|
|
12
|
+
export default class UndoUI extends Plugin {
|
|
13
|
+
/**
|
|
14
|
+
* @inheritDoc
|
|
15
|
+
*/
|
|
16
|
+
static get pluginName(): 'UndoUI';
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
init(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a button for the specified command.
|
|
23
|
+
*
|
|
24
|
+
* @param name Command name.
|
|
25
|
+
* @param label Button label.
|
|
26
|
+
* @param keystroke Command keystroke.
|
|
27
|
+
* @param Icon Source of the icon.
|
|
28
|
+
*/
|
|
29
|
+
private _addButton;
|
|
30
|
+
}
|
|
31
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
32
|
+
interface PluginsMap {
|
|
33
|
+
[UndoUI.pluginName]: UndoUI;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/undoui.js
CHANGED
|
@@ -11,8 +11,6 @@ import undoIcon from '../theme/icons/undo.svg';
|
|
|
11
11
|
import redoIcon from '../theme/icons/redo.svg';
|
|
12
12
|
/**
|
|
13
13
|
* The undo UI feature. It introduces the `'undo'` and `'redo'` buttons to the editor.
|
|
14
|
-
*
|
|
15
|
-
* @extends module:core/plugin~Plugin
|
|
16
14
|
*/
|
|
17
15
|
export default class UndoUI extends Plugin {
|
|
18
16
|
/**
|
|
@@ -36,11 +34,10 @@ export default class UndoUI extends Plugin {
|
|
|
36
34
|
/**
|
|
37
35
|
* Creates a button for the specified command.
|
|
38
36
|
*
|
|
39
|
-
* @
|
|
40
|
-
* @param
|
|
41
|
-
* @param
|
|
42
|
-
* @param
|
|
43
|
-
* @param {String} Icon Source of the icon.
|
|
37
|
+
* @param name Command name.
|
|
38
|
+
* @param label Button label.
|
|
39
|
+
* @param keystroke Command keystroke.
|
|
40
|
+
* @param Icon Source of the icon.
|
|
44
41
|
*/
|
|
45
42
|
_addButton(name, label, keystroke, Icon) {
|
|
46
43
|
const editor = this.editor;
|