@ckeditor/ckeditor5-undo 41.3.1 → 41.4.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. package/dist/index-content.css +4 -0
  2. package/dist/index-editor.css +4 -0
  3. package/dist/index.css +4 -0
  4. package/dist/index.js +410 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/translations/ar.d.ts +8 -0
  7. package/dist/translations/ar.js +5 -0
  8. package/dist/translations/ast.d.ts +8 -0
  9. package/dist/translations/ast.js +5 -0
  10. package/dist/translations/az.d.ts +8 -0
  11. package/dist/translations/az.js +5 -0
  12. package/dist/translations/bg.d.ts +8 -0
  13. package/dist/translations/bg.js +5 -0
  14. package/dist/translations/bn.d.ts +8 -0
  15. package/dist/translations/bn.js +5 -0
  16. package/dist/translations/ca.d.ts +8 -0
  17. package/dist/translations/ca.js +5 -0
  18. package/dist/translations/cs.d.ts +8 -0
  19. package/dist/translations/cs.js +5 -0
  20. package/dist/translations/da.d.ts +8 -0
  21. package/dist/translations/da.js +5 -0
  22. package/dist/translations/de-ch.d.ts +8 -0
  23. package/dist/translations/de-ch.js +5 -0
  24. package/dist/translations/de.d.ts +8 -0
  25. package/dist/translations/de.js +5 -0
  26. package/dist/translations/el.d.ts +8 -0
  27. package/dist/translations/el.js +5 -0
  28. package/dist/translations/en-au.d.ts +8 -0
  29. package/dist/translations/en-au.js +5 -0
  30. package/dist/translations/en-gb.d.ts +8 -0
  31. package/dist/translations/en-gb.js +5 -0
  32. package/dist/translations/en.d.ts +8 -0
  33. package/dist/translations/en.js +5 -0
  34. package/dist/translations/eo.d.ts +8 -0
  35. package/dist/translations/eo.js +5 -0
  36. package/dist/translations/es.d.ts +8 -0
  37. package/dist/translations/es.js +5 -0
  38. package/dist/translations/et.d.ts +8 -0
  39. package/dist/translations/et.js +5 -0
  40. package/dist/translations/eu.d.ts +8 -0
  41. package/dist/translations/eu.js +5 -0
  42. package/dist/translations/fa.d.ts +8 -0
  43. package/dist/translations/fa.js +5 -0
  44. package/dist/translations/fi.d.ts +8 -0
  45. package/dist/translations/fi.js +5 -0
  46. package/dist/translations/fr.d.ts +8 -0
  47. package/dist/translations/fr.js +5 -0
  48. package/dist/translations/gl.d.ts +8 -0
  49. package/dist/translations/gl.js +5 -0
  50. package/dist/translations/he.d.ts +8 -0
  51. package/dist/translations/he.js +5 -0
  52. package/dist/translations/hi.d.ts +8 -0
  53. package/dist/translations/hi.js +5 -0
  54. package/dist/translations/hr.d.ts +8 -0
  55. package/dist/translations/hr.js +5 -0
  56. package/dist/translations/hu.d.ts +8 -0
  57. package/dist/translations/hu.js +5 -0
  58. package/dist/translations/id.d.ts +8 -0
  59. package/dist/translations/id.js +5 -0
  60. package/dist/translations/it.d.ts +8 -0
  61. package/dist/translations/it.js +5 -0
  62. package/dist/translations/ja.d.ts +8 -0
  63. package/dist/translations/ja.js +5 -0
  64. package/dist/translations/km.d.ts +8 -0
  65. package/dist/translations/km.js +5 -0
  66. package/dist/translations/kn.d.ts +8 -0
  67. package/dist/translations/kn.js +5 -0
  68. package/dist/translations/ko.d.ts +8 -0
  69. package/dist/translations/ko.js +5 -0
  70. package/dist/translations/ku.d.ts +8 -0
  71. package/dist/translations/ku.js +5 -0
  72. package/dist/translations/lt.d.ts +8 -0
  73. package/dist/translations/lt.js +5 -0
  74. package/dist/translations/lv.d.ts +8 -0
  75. package/dist/translations/lv.js +5 -0
  76. package/dist/translations/ms.d.ts +8 -0
  77. package/dist/translations/ms.js +5 -0
  78. package/dist/translations/nb.d.ts +8 -0
  79. package/dist/translations/nb.js +5 -0
  80. package/dist/translations/ne.d.ts +8 -0
  81. package/dist/translations/ne.js +5 -0
  82. package/dist/translations/nl.d.ts +8 -0
  83. package/dist/translations/nl.js +5 -0
  84. package/dist/translations/no.d.ts +8 -0
  85. package/dist/translations/no.js +5 -0
  86. package/dist/translations/pl.d.ts +8 -0
  87. package/dist/translations/pl.js +5 -0
  88. package/dist/translations/pt-br.d.ts +8 -0
  89. package/dist/translations/pt-br.js +5 -0
  90. package/dist/translations/pt.d.ts +8 -0
  91. package/dist/translations/pt.js +5 -0
  92. package/dist/translations/ro.d.ts +8 -0
  93. package/dist/translations/ro.js +5 -0
  94. package/dist/translations/ru.d.ts +8 -0
  95. package/dist/translations/ru.js +5 -0
  96. package/dist/translations/si.d.ts +8 -0
  97. package/dist/translations/si.js +5 -0
  98. package/dist/translations/sk.d.ts +8 -0
  99. package/dist/translations/sk.js +5 -0
  100. package/dist/translations/sq.d.ts +8 -0
  101. package/dist/translations/sq.js +5 -0
  102. package/dist/translations/sr-latn.d.ts +8 -0
  103. package/dist/translations/sr-latn.js +5 -0
  104. package/dist/translations/sr.d.ts +8 -0
  105. package/dist/translations/sr.js +5 -0
  106. package/dist/translations/sv.d.ts +8 -0
  107. package/dist/translations/sv.js +5 -0
  108. package/dist/translations/th.d.ts +8 -0
  109. package/dist/translations/th.js +5 -0
  110. package/dist/translations/tk.d.ts +8 -0
  111. package/dist/translations/tk.js +5 -0
  112. package/dist/translations/tr.d.ts +8 -0
  113. package/dist/translations/tr.js +5 -0
  114. package/dist/translations/tt.d.ts +8 -0
  115. package/dist/translations/tt.js +5 -0
  116. package/dist/translations/ug.d.ts +8 -0
  117. package/dist/translations/ug.js +5 -0
  118. package/dist/translations/uk.d.ts +8 -0
  119. package/dist/translations/uk.js +5 -0
  120. package/dist/translations/ur.d.ts +8 -0
  121. package/dist/translations/ur.js +5 -0
  122. package/dist/translations/uz.d.ts +8 -0
  123. package/dist/translations/uz.js +5 -0
  124. package/dist/translations/vi.d.ts +8 -0
  125. package/dist/translations/vi.js +5 -0
  126. package/dist/translations/zh-cn.d.ts +8 -0
  127. package/dist/translations/zh-cn.js +5 -0
  128. package/dist/translations/zh.d.ts +8 -0
  129. package/dist/translations/zh.js +5 -0
  130. package/dist/types/augmentation.d.ts +20 -0
  131. package/dist/types/basecommand.d.ts +76 -0
  132. package/dist/types/index.d.ts +17 -0
  133. package/dist/types/redocommand.d.ts +31 -0
  134. package/dist/types/undo.d.ts +121 -0
  135. package/dist/types/undocommand.d.ts +41 -0
  136. package/dist/types/undoediting.d.ts +41 -0
  137. package/dist/types/undoui.d.ts +38 -0
  138. package/package.json +5 -4
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
package/dist/index.css ADDED
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
package/dist/index.js ADDED
@@ -0,0 +1,410 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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
+ import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';
6
+ import { transformSets, NoOperation } from '@ckeditor/ckeditor5-engine/dist/index.js';
7
+ import { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
+
9
+ class BaseCommand extends Command {
10
+ /**
11
+ * @inheritDoc
12
+ */ refresh() {
13
+ this.isEnabled = this._stack.length > 0;
14
+ }
15
+ /**
16
+ * Returns all batches created by this command.
17
+ */ get createdBatches() {
18
+ return this._createdBatches;
19
+ }
20
+ /**
21
+ * Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}
22
+ * created by the editor which this command is registered to.
23
+ *
24
+ * @param batch The batch to add.
25
+ */ addBatch(batch) {
26
+ const docSelection = this.editor.model.document.selection;
27
+ const selection = {
28
+ ranges: docSelection.hasOwnRange ? Array.from(docSelection.getRanges()) : [],
29
+ isBackward: docSelection.isBackward
30
+ };
31
+ this._stack.push({
32
+ batch,
33
+ selection
34
+ });
35
+ this.refresh();
36
+ }
37
+ /**
38
+ * Removes all items from the stack.
39
+ */ clearStack() {
40
+ this._stack = [];
41
+ this.refresh();
42
+ }
43
+ /**
44
+ * Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.
45
+ *
46
+ * @param ranges Ranges to be restored.
47
+ * @param isBackward A flag describing whether the restored range was selected forward or backward.
48
+ * @param operations Operations which has been applied since selection has been stored.
49
+ */ _restoreSelection(ranges, isBackward, operations) {
50
+ const model = this.editor.model;
51
+ const document = model.document;
52
+ // This will keep the transformed selection ranges.
53
+ const selectionRanges = [];
54
+ // Transform all ranges from the restored selection.
55
+ const transformedRangeGroups = ranges.map((range)=>range.getTransformedByOperations(operations));
56
+ const allRanges = transformedRangeGroups.flat();
57
+ for (const rangeGroup of transformedRangeGroups){
58
+ // While transforming there could appear ranges that are contained by other ranges, we shall ignore them.
59
+ const transformed = rangeGroup.filter((range)=>range.root != document.graveyard).filter((range)=>!isRangeContainedByAnyOtherRange(range, allRanges));
60
+ // All the transformed ranges ended up in graveyard.
61
+ if (!transformed.length) {
62
+ continue;
63
+ }
64
+ // After the range got transformed, we have an array of ranges. Some of those
65
+ // ranges may be "touching" -- they can be next to each other and could be merged.
66
+ normalizeRanges(transformed);
67
+ // For each `range` from `ranges`, we take only one transformed range.
68
+ // This is because we want to prevent situation where single-range selection
69
+ // got transformed to multi-range selection.
70
+ selectionRanges.push(transformed[0]);
71
+ }
72
+ // @if CK_DEBUG_ENGINE // console.log( `Restored selection by undo: ${ selectionRanges.join( ', ' ) }` );
73
+ // `selectionRanges` may be empty if all ranges ended up in graveyard. If that is the case, do not restore selection.
74
+ if (selectionRanges.length) {
75
+ model.change((writer)=>{
76
+ writer.setSelection(selectionRanges, {
77
+ backward: isBackward
78
+ });
79
+ });
80
+ }
81
+ }
82
+ /**
83
+ * Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.
84
+ * This is a helper method for {@link #execute}.
85
+ *
86
+ * @param batchToUndo The batch to be undone.
87
+ * @param undoingBatch The batch that will contain undoing changes.
88
+ */ _undo(batchToUndo, undoingBatch) {
89
+ const model = this.editor.model;
90
+ const document = model.document;
91
+ // All changes done by the command execution will be saved as one batch.
92
+ this._createdBatches.add(undoingBatch);
93
+ const operationsToUndo = batchToUndo.operations.slice().filter((operation)=>operation.isDocumentOperation);
94
+ operationsToUndo.reverse();
95
+ // We will process each operation from `batchToUndo`, in reverse order. If there were operations A, B and C in undone batch,
96
+ // we need to revert them in reverse order, so first C' (reversed C), then B', then A'.
97
+ for (const operationToUndo of operationsToUndo){
98
+ const nextBaseVersion = operationToUndo.baseVersion + 1;
99
+ const historyOperations = Array.from(document.history.getOperations(nextBaseVersion));
100
+ const transformedSets = transformSets([
101
+ operationToUndo.getReversed()
102
+ ], historyOperations, {
103
+ useRelations: true,
104
+ document: this.editor.model.document,
105
+ padWithNoOps: false,
106
+ forceWeakRemove: true
107
+ });
108
+ const reversedOperations = transformedSets.operationsA;
109
+ // After reversed operation has been transformed by all history operations, apply it.
110
+ for (let operation of reversedOperations){
111
+ // Do not apply any operation on non-editable space.
112
+ const affectedSelectable = operation.affectedSelectable;
113
+ if (affectedSelectable && !model.canEditAt(affectedSelectable)) {
114
+ operation = new NoOperation(operation.baseVersion);
115
+ }
116
+ // Before applying, add the operation to the `undoingBatch`.
117
+ undoingBatch.addOperation(operation);
118
+ model.applyOperation(operation);
119
+ document.history.setOperationAsUndone(operationToUndo, operation);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * @inheritDoc
125
+ */ constructor(editor){
126
+ super(editor);
127
+ /**
128
+ * Stack of items stored by the command. These are pairs of:
129
+ *
130
+ * * {@link module:engine/model/batch~Batch batch} saved by the command,
131
+ * * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.
132
+ */ this._stack = [];
133
+ /**
134
+ * Stores all batches that were created by this command.
135
+ *
136
+ * @internal
137
+ */ this._createdBatches = new WeakSet();
138
+ // Refresh state, so the command is inactive right after initialization.
139
+ this.refresh();
140
+ // This command should not depend on selection change.
141
+ this._isEnabledBasedOnSelection = false;
142
+ // Set the transparent batch for the `editor.data.set()` call if the
143
+ // batch type is not set already.
144
+ this.listenTo(editor.data, 'set', (evt, data)=>{
145
+ // Create a shallow copy of the options to not change the original args.
146
+ // And make sure that an object is assigned to data[ 1 ].
147
+ data[1] = {
148
+ ...data[1]
149
+ };
150
+ const options = data[1];
151
+ // If batch type is not set, default to non-undoable batch.
152
+ if (!options.batchType) {
153
+ options.batchType = {
154
+ isUndoable: false
155
+ };
156
+ }
157
+ }, {
158
+ priority: 'high'
159
+ });
160
+ // Clear the stack for the `transparent` batches.
161
+ this.listenTo(editor.data, 'set', (evt, data)=>{
162
+ // We can assume that the object exists and it has a `batchType` property.
163
+ // It was ensured with a higher priority listener before.
164
+ const options = data[1];
165
+ if (!options.batchType.isUndoable) {
166
+ this.clearStack();
167
+ }
168
+ });
169
+ }
170
+ }
171
+ /**
172
+ * Normalizes list of ranges by joining intersecting or "touching" ranges.
173
+ *
174
+ * @param ranges Ranges to be normalized.
175
+ */ function normalizeRanges(ranges) {
176
+ ranges.sort((a, b)=>a.start.isBefore(b.start) ? -1 : 1);
177
+ for(let i = 1; i < ranges.length; i++){
178
+ const previousRange = ranges[i - 1];
179
+ const joinedRange = previousRange.getJoined(ranges[i], true);
180
+ if (joinedRange) {
181
+ // Replace the ranges on the list with the new joined range.
182
+ i--;
183
+ ranges.splice(i, 2, joinedRange);
184
+ }
185
+ }
186
+ }
187
+ function isRangeContainedByAnyOtherRange(range, ranges) {
188
+ return ranges.some((otherRange)=>otherRange !== range && otherRange.containsRange(range, true));
189
+ }
190
+
191
+ class UndoCommand extends BaseCommand {
192
+ /**
193
+ * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms
194
+ * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.
195
+ * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.
196
+ *
197
+ * @fires execute
198
+ * @fires revert
199
+ * @param batch A batch that should be undone. If not set, the last added batch will be undone.
200
+ */ execute(batch = null) {
201
+ // If batch is not given, set `batchIndex` to the last index in command stack.
202
+ const batchIndex = batch ? this._stack.findIndex((a)=>a.batch == batch) : this._stack.length - 1;
203
+ const item = this._stack.splice(batchIndex, 1)[0];
204
+ const undoingBatch = this.editor.model.createBatch({
205
+ isUndo: true
206
+ });
207
+ // All changes have to be done in one `enqueueChange` callback so other listeners will not
208
+ // step between consecutive operations, or won't do changes to the document before selection is properly restored.
209
+ this.editor.model.enqueueChange(undoingBatch, ()=>{
210
+ this._undo(item.batch, undoingBatch);
211
+ const operations = this.editor.model.document.history.getOperations(item.batch.baseVersion);
212
+ this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);
213
+ });
214
+ // Firing `revert` event after the change block to make sure that it includes all changes from post-fixers
215
+ // and make sure that the selection is "stabilized" (the selection range is saved after undo is executed and then
216
+ // restored on redo, so it is important that the selection range is saved after post-fixers are done).
217
+ this.fire('revert', item.batch, undoingBatch);
218
+ this.refresh();
219
+ }
220
+ }
221
+
222
+ class RedoCommand extends BaseCommand {
223
+ /**
224
+ * Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to
225
+ * the command's stack, applies the reverted and transformed version on the
226
+ * {@link module:engine/model/document~Document document} and removes the batch from the stack.
227
+ * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.
228
+ *
229
+ * @fires execute
230
+ */ execute() {
231
+ const item = this._stack.pop();
232
+ const redoingBatch = this.editor.model.createBatch({
233
+ isUndo: true
234
+ });
235
+ // All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive
236
+ // operations, or won't do changes to the document before selection is properly restored.
237
+ this.editor.model.enqueueChange(redoingBatch, ()=>{
238
+ const lastOperation = item.batch.operations[item.batch.operations.length - 1];
239
+ const nextBaseVersion = lastOperation.baseVersion + 1;
240
+ const operations = this.editor.model.document.history.getOperations(nextBaseVersion);
241
+ this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);
242
+ this._undo(item.batch, redoingBatch);
243
+ });
244
+ this.refresh();
245
+ }
246
+ }
247
+
248
+ class UndoEditing extends Plugin {
249
+ /**
250
+ * @inheritDoc
251
+ */ static get pluginName() {
252
+ return 'UndoEditing';
253
+ }
254
+ /**
255
+ * @inheritDoc
256
+ */ init() {
257
+ const editor = this.editor;
258
+ const t = editor.t;
259
+ // Create commands.
260
+ this._undoCommand = new UndoCommand(editor);
261
+ this._redoCommand = new RedoCommand(editor);
262
+ // Register command to the editor.
263
+ editor.commands.add('undo', this._undoCommand);
264
+ editor.commands.add('redo', this._redoCommand);
265
+ this.listenTo(editor.model, 'applyOperation', (evt, args)=>{
266
+ const operation = args[0];
267
+ // Do not register batch if the operation is not a document operation.
268
+ // This prevents from creating empty undo steps, where all operations where non-document operations.
269
+ // Non-document operations creates and alters content in detached tree fragments (for example, document fragments).
270
+ // Most of time this is preparing data before it is inserted into actual tree (for example during copy & paste).
271
+ // Such operations should not be reversed.
272
+ if (!operation.isDocumentOperation) {
273
+ return;
274
+ }
275
+ const batch = operation.batch;
276
+ const isRedoBatch = this._redoCommand.createdBatches.has(batch);
277
+ const isUndoBatch = this._undoCommand.createdBatches.has(batch);
278
+ const wasProcessed = this._batchRegistry.has(batch);
279
+ // Skip the batch if it was already processed.
280
+ if (wasProcessed) {
281
+ return;
282
+ }
283
+ // Add the batch to the registry so it will not be processed again.
284
+ this._batchRegistry.add(batch);
285
+ if (!batch.isUndoable) {
286
+ return;
287
+ }
288
+ if (isRedoBatch) {
289
+ // If this batch comes from `redoCommand`, add it to the `undoCommand` stack.
290
+ this._undoCommand.addBatch(batch);
291
+ } else if (!isUndoBatch) {
292
+ // If the batch comes neither from `redoCommand` nor from `undoCommand` then it is a new, regular batch.
293
+ // Add the batch to the `undoCommand` stack and clear the `redoCommand` stack.
294
+ this._undoCommand.addBatch(batch);
295
+ this._redoCommand.clearStack();
296
+ }
297
+ }, {
298
+ priority: 'highest'
299
+ });
300
+ this.listenTo(this._undoCommand, 'revert', (evt, undoneBatch, undoingBatch)=>{
301
+ this._redoCommand.addBatch(undoingBatch);
302
+ });
303
+ editor.keystrokes.set('CTRL+Z', 'undo');
304
+ editor.keystrokes.set('CTRL+Y', 'redo');
305
+ editor.keystrokes.set('CTRL+SHIFT+Z', 'redo');
306
+ // Add the information about the keystrokes to the accessibility database.
307
+ editor.accessibility.addKeystrokeInfos({
308
+ keystrokes: [
309
+ {
310
+ label: t('Undo'),
311
+ keystroke: 'CTRL+Z'
312
+ },
313
+ {
314
+ label: t('Redo'),
315
+ keystroke: [
316
+ [
317
+ 'CTRL+Y'
318
+ ],
319
+ [
320
+ 'CTRL+SHIFT+Z'
321
+ ]
322
+ ]
323
+ }
324
+ ]
325
+ });
326
+ }
327
+ constructor(){
328
+ super(...arguments);
329
+ /**
330
+ * Keeps track of which batches were registered in undo.
331
+ */ this._batchRegistry = new WeakSet();
332
+ }
333
+ }
334
+
335
+ class UndoUI extends Plugin {
336
+ /**
337
+ * @inheritDoc
338
+ */ static get pluginName() {
339
+ return 'UndoUI';
340
+ }
341
+ /**
342
+ * @inheritDoc
343
+ */ init() {
344
+ const editor = this.editor;
345
+ const locale = editor.locale;
346
+ const t = editor.t;
347
+ const localizedUndoIcon = locale.uiLanguageDirection == 'ltr' ? icons.undo : icons.redo;
348
+ const localizedRedoIcon = locale.uiLanguageDirection == 'ltr' ? icons.redo : icons.undo;
349
+ this._addButtonsToFactory('undo', t('Undo'), 'CTRL+Z', localizedUndoIcon);
350
+ this._addButtonsToFactory('redo', t('Redo'), 'CTRL+Y', localizedRedoIcon);
351
+ }
352
+ /**
353
+ * Creates a button for the specified command.
354
+ *
355
+ * @param name Command name.
356
+ * @param label Button label.
357
+ * @param keystroke Command keystroke.
358
+ * @param Icon Source of the icon.
359
+ */ _addButtonsToFactory(name, label, keystroke, Icon) {
360
+ const editor = this.editor;
361
+ editor.ui.componentFactory.add(name, ()=>{
362
+ const buttonView = this._createButton(ButtonView, name, label, keystroke, Icon);
363
+ buttonView.set({
364
+ tooltip: true
365
+ });
366
+ return buttonView;
367
+ });
368
+ editor.ui.componentFactory.add('menuBar:' + name, ()=>{
369
+ return this._createButton(MenuBarMenuListItemButtonView, name, label, keystroke, Icon);
370
+ });
371
+ }
372
+ /**
373
+ * TODO
374
+ */ _createButton(ButtonClass, name, label, keystroke, Icon) {
375
+ const editor = this.editor;
376
+ const locale = editor.locale;
377
+ const command = editor.commands.get(name);
378
+ const view = new ButtonClass(locale);
379
+ view.set({
380
+ label,
381
+ icon: Icon,
382
+ keystroke
383
+ });
384
+ view.bind('isEnabled').to(command, 'isEnabled');
385
+ this.listenTo(view, 'execute', ()=>{
386
+ editor.execute(name);
387
+ editor.editing.view.focus();
388
+ });
389
+ return view;
390
+ }
391
+ }
392
+
393
+ class Undo extends Plugin {
394
+ /**
395
+ * @inheritDoc
396
+ */ static get requires() {
397
+ return [
398
+ UndoEditing,
399
+ UndoUI
400
+ ];
401
+ }
402
+ /**
403
+ * @inheritDoc
404
+ */ static get pluginName() {
405
+ return 'Undo';
406
+ }
407
+ }
408
+
409
+ export { Undo, UndoEditing, UndoUI };
410
+ //# sourceMappingURL=index.js.map