deltareplayer.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module engine/dev-utils/deltareplayer
  7. */
  8. /* global setTimeout, console */
  9. import DeltaFactory from '../model/delta/deltafactory';
  10. /**
  11. * DeltaReplayer is a dev-tool created for easily replaying operations on the document from stringified deltas.
  12. */
  13. export default class DeltaReplayer {
  14. /**
  15. * @param {module:engine/model/document~Document} document Document to reply deltas on.
  16. * @param {String} logSeparator Separator between deltas.
  17. * @param {String} stringifiedDeltas Deltas to replay.
  18. */
  19. constructor( document, logSeparator, stringifiedDeltas ) {
  20. this._document = document;
  21. this._logSeparator = logSeparator;
  22. this.setStringifiedDeltas( stringifiedDeltas );
  23. }
  24. /**
  25. * Parses given string containing stringified deltas and sets parsed deltas as deltas to reply.
  26. *
  27. * @param {String} stringifiedDeltas Stringified deltas to replay.
  28. */
  29. setStringifiedDeltas( stringifiedDeltas ) {
  30. if ( stringifiedDeltas === '' ) {
  31. this._deltasToReplay = [];
  32. return;
  33. }
  34. this._deltasToReplay = stringifiedDeltas
  35. .split( this._logSeparator )
  36. .map( stringifiedDelta => JSON.parse( stringifiedDelta ) );
  37. }
  38. /**
  39. * Returns deltas to reply.
  40. *
  41. * @returns {Array.<module:engine/model/delta/delta~Delta>}
  42. */
  43. getDeltasToReplay() {
  44. return this._deltasToReplay;
  45. }
  46. /**
  47. * Applies all deltas with delay between actions.
  48. *
  49. * @param {Number} timeInterval Time between applying deltas.
  50. * @returns {Promise}
  51. */
  52. play( timeInterval = 1000 ) {
  53. const deltaReplayer = this;
  54. return new Promise( ( res ) => {
  55. play();
  56. function play() {
  57. if ( deltaReplayer._deltasToReplay.length === 0 ) {
  58. return res();
  59. }
  60. deltaReplayer.applyNextDelta().then( () => {
  61. setTimeout( play, timeInterval );
  62. }, res );
  63. }
  64. } );
  65. }
  66. /**
  67. * Applies `numberOfDeltas` deltas, beginning after the last applied delta (or first delta, if no deltas were applied).
  68. *
  69. * @param {Number} numberOfDeltas Number of deltas to apply.
  70. * @returns {Promise}
  71. */
  72. applyDeltas( numberOfDeltas ) {
  73. if ( numberOfDeltas <= 0 ) {
  74. return;
  75. }
  76. return this.applyNextDelta()
  77. .then( () => this.applyDeltas( numberOfDeltas - 1 ) )
  78. .catch( err => console.warn( err ) );
  79. }
  80. /**
  81. * Applies all deltas to replay at once.
  82. *
  83. * @returns {Promise}
  84. */
  85. applyAllDeltas() {
  86. return this.applyNextDelta()
  87. .then( () => this.applyAllDeltas() )
  88. .catch( () => {} );
  89. }
  90. /**
  91. * Applies the next delta to replay.
  92. *
  93. * @returns {Promise}
  94. */
  95. applyNextDelta() {
  96. const document = this._document;
  97. return new Promise( ( res, rej ) => {
  98. document.enqueueChanges( () => {
  99. const jsonDelta = this._deltasToReplay.shift();
  100. if ( !jsonDelta ) {
  101. return rej( new Error( 'No deltas to replay' ) );
  102. }
  103. const delta = DeltaFactory.fromJSON( jsonDelta, this._document );
  104. const batch = document.batch();
  105. batch.addDelta( delta );
  106. for ( const operation of delta.operations ) {
  107. document.applyOperation( operation );
  108. }
  109. res();
  110. } );
  111. } );
  112. }
  113. }