undocommand.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module undo/undocommand
  7. */
  8. import BaseCommand from './basecommand';
  9. import Batch from '@ckeditor/ckeditor5-engine/src/model/batch';
  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. * @extends module:undo/basecommand~BaseCommand
  18. */
  19. export default class UndoCommand extends BaseCommand {
  20. /**
  21. * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms
  22. * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.
  23. * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.
  24. *
  25. * @fires execute
  26. * @fires revert
  27. * @param {module:engine/model/batch~Batch} [batch] A batch that should be undone. If not set, the last added batch will be undone.
  28. */
  29. execute( batch = null ) {
  30. // If batch is not given, set `batchIndex` to the last index in command stack.
  31. const batchIndex = batch ? this._stack.findIndex( a => a.batch == batch ) : this._stack.length - 1;
  32. const item = this._stack.splice( batchIndex, 1 )[ 0 ];
  33. const undoingBatch = new Batch();
  34. // All changes has to be done in one `enqueueChange` callback so other listeners will not
  35. // step between consecutive operations, or won't do changes to the document before selection is properly restored.
  36. this.editor.model.enqueueChange( undoingBatch, () => {
  37. this._undo( item.batch, undoingBatch );
  38. const operations = this.editor.model.document.history.getOperations( item.batch.baseVersion );
  39. this._restoreSelection( item.selection.ranges, item.selection.isBackward, operations );
  40. this.fire( 'revert', item.batch, undoingBatch );
  41. } );
  42. this.refresh();
  43. }
  44. }
  45. /**
  46. * Fired when execution of the command reverts some batch.
  47. *
  48. * @event revert
  49. */