@ckeditor/ckeditor5-undo 39.0.2 → 40.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +4 -4
- package/src/augmentation.d.ts +16 -16
- package/src/augmentation.js +5 -5
- package/src/basecommand.d.ts +72 -72
- package/src/basecommand.js +192 -192
- package/src/index.d.ts +13 -13
- package/src/index.js +11 -11
- package/src/redocommand.d.ts +27 -27
- package/src/redocommand.js +40 -40
- package/src/undo.d.ts +117 -117
- package/src/undo.js +121 -121
- package/src/undocommand.d.ts +37 -37
- package/src/undocommand.js +44 -44
- package/src/undoediting.d.ts +37 -37
- package/src/undoediting.js +82 -82
- package/src/undoui.d.ts +30 -30
- package/src/undoui.js +61 -61
package/src/redocommand.d.ts
CHANGED
@@ -1,27 +1,27 @@
|
|
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
|
-
}
|
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
|
+
}
|
package/src/redocommand.js
CHANGED
@@ -1,40 +1,40 @@
|
|
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() {
|
27
|
-
const item = this._stack.pop();
|
28
|
-
const redoingBatch = this.editor.model.createBatch({ isUndo: true });
|
29
|
-
// All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive
|
30
|
-
// operations, or won't do changes to the document before selection is properly restored.
|
31
|
-
this.editor.model.enqueueChange(redoingBatch, () => {
|
32
|
-
const lastOperation = item.batch.operations[item.batch.operations.length - 1];
|
33
|
-
const nextBaseVersion = lastOperation.baseVersion + 1;
|
34
|
-
const operations = this.editor.model.document.history.getOperations(nextBaseVersion);
|
35
|
-
this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);
|
36
|
-
this._undo(item.batch, redoingBatch);
|
37
|
-
});
|
38
|
-
this.refresh();
|
39
|
-
}
|
40
|
-
}
|
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() {
|
27
|
+
const item = this._stack.pop();
|
28
|
+
const redoingBatch = this.editor.model.createBatch({ isUndo: true });
|
29
|
+
// All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive
|
30
|
+
// operations, or won't do changes to the document before selection is properly restored.
|
31
|
+
this.editor.model.enqueueChange(redoingBatch, () => {
|
32
|
+
const lastOperation = item.batch.operations[item.batch.operations.length - 1];
|
33
|
+
const nextBaseVersion = lastOperation.baseVersion + 1;
|
34
|
+
const operations = this.editor.model.document.history.getOperations(nextBaseVersion);
|
35
|
+
this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);
|
36
|
+
this._undo(item.batch, redoingBatch);
|
37
|
+
});
|
38
|
+
this.refresh();
|
39
|
+
}
|
40
|
+
}
|
package/src/undo.d.ts
CHANGED
@@ -1,117 +1,117 @@
|
|
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 } from '@ckeditor/ckeditor5-core';
|
9
|
-
import UndoEditing from './undoediting';
|
10
|
-
import UndoUI from './undoui';
|
11
|
-
/**
|
12
|
-
* The undo feature.
|
13
|
-
*
|
14
|
-
* This is a "glue" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}
|
15
|
-
* and the {@link module:undo/undoui~UndoUI undo UI feature}.
|
16
|
-
*
|
17
|
-
* Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:
|
18
|
-
*
|
19
|
-
* Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the
|
20
|
-
* {@link module:engine/model/document~Document document}, it is saved to `History` as is.
|
21
|
-
* The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in
|
22
|
-
* {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the
|
23
|
-
* operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation
|
24
|
-
* and a batch is seen as one undo step.
|
25
|
-
*
|
26
|
-
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
27
|
-
*
|
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
|
-
* ```
|
39
|
-
*
|
40
|
-
* Where operations starting with the same letter are from same batch.
|
41
|
-
*
|
42
|
-
* Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.
|
43
|
-
* For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing
|
44
|
-
* operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`
|
45
|
-
* need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`
|
46
|
-
* does not know that operations `Y` and `Z` happened.
|
47
|
-
*
|
48
|
-
* After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},
|
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`
|
50
|
-
* bases on up-to-date document state, so it can be applied to the document.
|
51
|
-
*
|
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
|
-
* ```
|
64
|
-
*
|
65
|
-
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
66
|
-
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
67
|
-
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
68
|
-
*
|
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
|
-
* ```
|
83
|
-
*
|
84
|
-
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
85
|
-
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
86
|
-
*
|
87
|
-
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
88
|
-
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
89
|
-
*
|
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
|
-
* ```
|
107
|
-
*/
|
108
|
-
export default class Undo extends Plugin {
|
109
|
-
/**
|
110
|
-
* @inheritDoc
|
111
|
-
*/
|
112
|
-
static get requires(): readonly [typeof UndoEditing, typeof UndoUI];
|
113
|
-
/**
|
114
|
-
* @inheritDoc
|
115
|
-
*/
|
116
|
-
static get pluginName(): "Undo";
|
117
|
-
}
|
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 } from '@ckeditor/ckeditor5-core';
|
9
|
+
import UndoEditing from './undoediting';
|
10
|
+
import UndoUI from './undoui';
|
11
|
+
/**
|
12
|
+
* The undo feature.
|
13
|
+
*
|
14
|
+
* This is a "glue" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}
|
15
|
+
* and the {@link module:undo/undoui~UndoUI undo UI feature}.
|
16
|
+
*
|
17
|
+
* Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:
|
18
|
+
*
|
19
|
+
* Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the
|
20
|
+
* {@link module:engine/model/document~Document document}, it is saved to `History` as is.
|
21
|
+
* The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in
|
22
|
+
* {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the
|
23
|
+
* operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation
|
24
|
+
* and a batch is seen as one undo step.
|
25
|
+
*
|
26
|
+
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
27
|
+
*
|
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
|
+
* ```
|
39
|
+
*
|
40
|
+
* Where operations starting with the same letter are from same batch.
|
41
|
+
*
|
42
|
+
* Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.
|
43
|
+
* For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing
|
44
|
+
* operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`
|
45
|
+
* need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`
|
46
|
+
* does not know that operations `Y` and `Z` happened.
|
47
|
+
*
|
48
|
+
* After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},
|
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`
|
50
|
+
* bases on up-to-date document state, so it can be applied to the document.
|
51
|
+
*
|
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
|
+
* ```
|
64
|
+
*
|
65
|
+
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
66
|
+
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
67
|
+
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
68
|
+
*
|
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
|
+
* ```
|
83
|
+
*
|
84
|
+
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
85
|
+
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
86
|
+
*
|
87
|
+
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
88
|
+
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
89
|
+
*
|
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
|
+
* ```
|
107
|
+
*/
|
108
|
+
export default class Undo extends Plugin {
|
109
|
+
/**
|
110
|
+
* @inheritDoc
|
111
|
+
*/
|
112
|
+
static get requires(): readonly [typeof UndoEditing, typeof UndoUI];
|
113
|
+
/**
|
114
|
+
* @inheritDoc
|
115
|
+
*/
|
116
|
+
static get pluginName(): "Undo";
|
117
|
+
}
|
package/src/undo.js
CHANGED
@@ -1,121 +1,121 @@
|
|
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 } from '@ckeditor/ckeditor5-core';
|
9
|
-
import UndoEditing from './undoediting';
|
10
|
-
import UndoUI from './undoui';
|
11
|
-
/**
|
12
|
-
* The undo feature.
|
13
|
-
*
|
14
|
-
* This is a "glue" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}
|
15
|
-
* and the {@link module:undo/undoui~UndoUI undo UI feature}.
|
16
|
-
*
|
17
|
-
* Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:
|
18
|
-
*
|
19
|
-
* Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the
|
20
|
-
* {@link module:engine/model/document~Document document}, it is saved to `History` as is.
|
21
|
-
* The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in
|
22
|
-
* {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the
|
23
|
-
* operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation
|
24
|
-
* and a batch is seen as one undo step.
|
25
|
-
*
|
26
|
-
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
27
|
-
*
|
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
|
-
* ```
|
39
|
-
*
|
40
|
-
* Where operations starting with the same letter are from same batch.
|
41
|
-
*
|
42
|
-
* Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.
|
43
|
-
* For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing
|
44
|
-
* operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`
|
45
|
-
* need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`
|
46
|
-
* does not know that operations `Y` and `Z` happened.
|
47
|
-
*
|
48
|
-
* After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},
|
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`
|
50
|
-
* bases on up-to-date document state, so it can be applied to the document.
|
51
|
-
*
|
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
|
-
* ```
|
64
|
-
*
|
65
|
-
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
66
|
-
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
67
|
-
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
68
|
-
*
|
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
|
-
* ```
|
83
|
-
*
|
84
|
-
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
85
|
-
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
86
|
-
*
|
87
|
-
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
88
|
-
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
89
|
-
*
|
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
|
-
* ```
|
107
|
-
*/
|
108
|
-
export default class Undo extends Plugin {
|
109
|
-
/**
|
110
|
-
* @inheritDoc
|
111
|
-
*/
|
112
|
-
static get requires() {
|
113
|
-
return [UndoEditing, UndoUI];
|
114
|
-
}
|
115
|
-
/**
|
116
|
-
* @inheritDoc
|
117
|
-
*/
|
118
|
-
static get pluginName() {
|
119
|
-
return 'Undo';
|
120
|
-
}
|
121
|
-
}
|
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 } from '@ckeditor/ckeditor5-core';
|
9
|
+
import UndoEditing from './undoediting';
|
10
|
+
import UndoUI from './undoui';
|
11
|
+
/**
|
12
|
+
* The undo feature.
|
13
|
+
*
|
14
|
+
* This is a "glue" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}
|
15
|
+
* and the {@link module:undo/undoui~UndoUI undo UI feature}.
|
16
|
+
*
|
17
|
+
* Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:
|
18
|
+
*
|
19
|
+
* Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the
|
20
|
+
* {@link module:engine/model/document~Document document}, it is saved to `History` as is.
|
21
|
+
* The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in
|
22
|
+
* {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the
|
23
|
+
* operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation
|
24
|
+
* and a batch is seen as one undo step.
|
25
|
+
*
|
26
|
+
* After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:
|
27
|
+
*
|
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
|
+
* ```
|
39
|
+
*
|
40
|
+
* Where operations starting with the same letter are from same batch.
|
41
|
+
*
|
42
|
+
* Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.
|
43
|
+
* For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing
|
44
|
+
* operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`
|
45
|
+
* need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`
|
46
|
+
* does not know that operations `Y` and `Z` happened.
|
47
|
+
*
|
48
|
+
* After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},
|
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`
|
50
|
+
* bases on up-to-date document state, so it can be applied to the document.
|
51
|
+
*
|
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
|
+
* ```
|
64
|
+
*
|
65
|
+
* Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be
|
66
|
+
* transformed by operations from history that happened after it, so it "knows" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,
|
67
|
+
* where `*` means "transformed by". Rest of operations from that batch are processed in the same fashion.
|
68
|
+
*
|
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
|
+
* ```
|
83
|
+
*
|
84
|
+
* Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.
|
85
|
+
* The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.
|
86
|
+
*
|
87
|
+
* Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from
|
88
|
+
* the batch that is re-done are reversed-back, transformed in proper order and applied to the document.
|
89
|
+
*
|
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
|
+
* ```
|
107
|
+
*/
|
108
|
+
export default class Undo extends Plugin {
|
109
|
+
/**
|
110
|
+
* @inheritDoc
|
111
|
+
*/
|
112
|
+
static get requires() {
|
113
|
+
return [UndoEditing, UndoUI];
|
114
|
+
}
|
115
|
+
/**
|
116
|
+
* @inheritDoc
|
117
|
+
*/
|
118
|
+
static get pluginName() {
|
119
|
+
return 'Undo';
|
120
|
+
}
|
121
|
+
}
|