8
0

history.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module engine/model/history
  7. */
  8. /**
  9. * `History` keeps the track of all the operations applied to the {@link module:engine/model/document~Document document}.
  10. */
  11. export default class History {
  12. /**
  13. * Creates an empty History instance.
  14. */
  15. constructor() {
  16. /**
  17. * Operations added to the history.
  18. *
  19. * @protected
  20. * @member {Array.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_operations
  21. */
  22. this._operations = [];
  23. /**
  24. * Holds an information which {@link module:engine/model/operation/operation~Operation operation} undoes which
  25. * {@link module:engine/model/operation/operation~Operation operation}.
  26. *
  27. * Keys of the map are "undoing operations", that is operations that undone some other operations. For each key, the
  28. * value is an operation that has been undone by the "undoing operation".
  29. *
  30. * @private
  31. * @member {Map} module:engine/model/history~History#_undoPairs
  32. */
  33. this._undoPairs = new Map();
  34. /**
  35. * Holds all undone operations.
  36. *
  37. * @private
  38. * @member {Set.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_undoneOperations
  39. */
  40. this._undoneOperations = new Set();
  41. }
  42. /**
  43. * Adds an operation to the history.
  44. *
  45. * @param {module:engine/model/operation/operation~Operation} operation Operation to add.
  46. */
  47. addOperation( operation ) {
  48. if ( this._operations.includes( operation ) ) {
  49. return;
  50. }
  51. this._operations.push( operation );
  52. }
  53. /**
  54. * Returns operations added to the history.
  55. *
  56. * @param {Number} [from=0] Base version from which operations should be returned (inclusive). Defaults to `0`, which means
  57. * that operations from the first one will be returned.
  58. * @param {Number} [to=Number.POSITIVE_INFINITY] Base version up to which operations should be returned (exclusive).
  59. * Defaults to `Number.POSITIVE_INFINITY` which means that operations up to the last one will be returned.
  60. * @returns {Iterable.<module:engine/model/operation/operation~Operation>} Operations added to the history.
  61. */
  62. getOperations( from = 0, to = Number.POSITIVE_INFINITY ) {
  63. if ( from < 0 ) {
  64. return [];
  65. }
  66. return this._operations.slice( from, to );
  67. }
  68. /**
  69. * Returns operation from the history that bases on given `baseVersion`.
  70. *
  71. * @param {Number} baseVersion Base version of the operation to get.
  72. * @returns {module:engine/model/operation/operation~Operation|null} Operation with given base version or `null` if
  73. * there is no such operation in history.
  74. */
  75. getOperation( baseVersion ) {
  76. return this._operations[ baseVersion ];
  77. }
  78. /**
  79. * Marks in history that one operation is an operation that is undoing the other operation. By marking operation this way,
  80. * history is keeping more context information about operations, which helps in operational transformation.
  81. *
  82. * @param {module:engine/model/operation/operation~Operation} undoneOperation Operation which is undone by `undoingOperation`.
  83. * @param {module:engine/model/operation/operation~Operation} undoingOperation Operation which undoes `undoneOperation`.
  84. */
  85. setOperationAsUndone( undoneOperation, undoingOperation ) {
  86. this._undoPairs.set( undoingOperation, undoneOperation );
  87. this._undoneOperations.add( undoneOperation );
  88. }
  89. /**
  90. * Checks whether given `operation` is undoing any other operation.
  91. *
  92. * @param {module:engine/model/operation/operation~Operation} operation Operation to check.
  93. * @returns {Boolean} `true` if given `operation` is undoing any other operation, `false` otherwise.
  94. */
  95. isUndoingOperation( operation ) {
  96. return this._undoPairs.has( operation );
  97. }
  98. /**
  99. * Checks whether given `operation` has been undone by any other operation.
  100. *
  101. * @param {module:engine/model/operation/operation~Operation} operation Operation to check.
  102. * @returns {Boolean} `true` if given `operation` has been undone any other operation, `false` otherwise.
  103. */
  104. isUndoneOperation( operation ) {
  105. return this._undoneOperations.has( operation );
  106. }
  107. /**
  108. * For given `undoingOperation`, returns the operation which has been undone by it.
  109. *
  110. * @param {module:engine/model/operation/operation~Operation} undoingOperation
  111. * @returns {module:engine/model/operation/operation~Operation|undefined} Operation that has been undone by given
  112. * `undoingOperation` or `undefined` if given `undoingOperation` is not undoing any other operation.
  113. */
  114. getUndoneOperation( undoingOperation ) {
  115. return this._undoPairs.get( undoingOperation );
  116. }
  117. }