8
0
Pārlūkot izejas kodu

Changed: undo.UndoEngine listeners. Improved tests.

Szymon Cofalik 9 gadi atpakaļ
vecāks
revīzija
749b1e131a

+ 22 - 17
packages/ckeditor5-undo/src/undoengine.js

@@ -7,6 +7,7 @@
 
 import Feature from '../feature.js';
 import UndoCommand from './undocommand.js';
+import RedoCommand from './redocommand.js';
 
 /**
  * Undo engine feature.
@@ -25,7 +26,7 @@ export default class UndoEngine extends Feature {
 		super( editor );
 
 		/**
-		 * Undo command which manages undo {@link engine.model.Batch batches} stack (history).
+		 * Command which manages undo {@link engine.model.Batch batches} stack (history).
 		 * Created and registered during {@link undo.UndoEngine#init feature initialization}.
 		 *
 		 * @private
@@ -34,7 +35,7 @@ export default class UndoEngine extends Feature {
 		this._undoCommand = null;
 
 		/**
-		 * Undo command which manages redo {@link engine.model.Batch batches} stack (history).
+		 * Command which manages redo {@link engine.model.Batch batches} stack (history).
 		 * Created and registered during {@link undo.UndoEngine#init feature initialization}.
 		 *
 		 * @private
@@ -43,7 +44,7 @@ export default class UndoEngine extends Feature {
 		this._redoCommand = null;
 
 		/**
-		 * Keeps track of which batch has already been added to undo manager.
+		 * Keeps track of which batch has been registered in Undo.
 		 *
 		 * @private
 		 * @member {WeakSet.<engine.model.Batch>} undo.UndoEngine#_batchRegistry
@@ -56,30 +57,34 @@ export default class UndoEngine extends Feature {
 	 */
 	init() {
 		// Create commands.
-		this._redoCommand = new UndoCommand( this.editor );
 		this._undoCommand = new UndoCommand( this.editor );
+		this._redoCommand = new RedoCommand( this.editor );
 
 		// Register command to the editor.
-		this.editor.commands.set( 'redo', this._redoCommand );
 		this.editor.commands.set( 'undo', this._undoCommand );
+		this.editor.commands.set( 'redo', this._redoCommand );
 
 		this.listenTo( this.editor.document, 'change', ( evt, type, changes, batch ) => {
-			// Whenever a new batch is created add it to the undo history and clear redo history.
-			if ( batch && !this._batchRegistry.has( batch ) ) {
-				this._batchRegistry.add( batch );
+			// If changes are not a part of a batch or this is not a new batch, omit those changes.
+			if ( !batch || this._batchRegistry.has( batch ) || batch.type == 'ignore' ) {
+				return;
+			}
+
+			if ( batch.type == 'undo' ) {
+				// If this batch comes from `undoCommand`, add it to `redoCommand` stack.
+				this._redoCommand.addBatch( batch );
+			} else if ( batch.type == 'redo' ) {
+				// If this batch comes from `redoCommand`, add it to `undoCommand` stack.
+				this._undoCommand.addBatch( batch );
+			} else {
+				// Any other batch - these are new changes in the document.
+				// Add them to `undoCommand` stack and clear `redoCommand` stack.
 				this._undoCommand.addBatch( batch );
 				this._redoCommand.clearStack();
 			}
-		} );
-
-		// Whenever batch is reverted by undo command, add it to redo history.
-		this.listenTo( this._redoCommand, 'revert', ( evt, batch ) => {
-			this._undoCommand.addBatch( batch );
-		} );
 
-		// Whenever batch is reverted by redo command, add it to undo history.
-		this.listenTo( this._undoCommand, 'revert', ( evt, batch ) => {
-			this._redoCommand.addBatch( batch );
+			// Add the batch to the registry so it will not be processed again.
+			this._batchRegistry.add( batch );
 		} );
 	}
 }

+ 17 - 22
packages/ckeditor5-undo/tests/undoengine.js

@@ -32,47 +32,42 @@ describe( 'UndoEngine', () => {
 		expect( editor.commands.get( 'redo' ) ).to.equal( undo._redoCommand );
 	} );
 
-	it( 'should add a batch to undo command whenever a new batch is applied to the document', () => {
+	it( 'should add a batch to undo command and clear redo stack, if it\'s type is different than "undo" and "redo"', () => {
 		sinon.spy( undo._undoCommand, 'addBatch' );
+		sinon.spy( undo._redoCommand, 'clearStack' );
 
 		expect( undo._undoCommand.addBatch.called ).to.be.false;
+		expect( undo._redoCommand.clearStack.called ).to.be.false;
 
 		batch.insert( new Position( root, [ 0 ] ), 'foobar' );
 
 		expect( undo._undoCommand.addBatch.calledOnce ).to.be.true;
-
-		batch.insert( new Position( root, [ 0 ] ), 'foobar' );
-
-		expect( undo._undoCommand.addBatch.calledOnce ).to.be.true;
+		expect( undo._redoCommand.clearStack.calledOnce ).to.be.true;
 	} );
 
-	it( 'should add a batch to redo command whenever a batch is undone by undo command', () => {
-		batch.insert( new Position( root, [ 0 ] ), 'foobar' );
-
-		sinon.spy( undo._redoCommand, 'addBatch' );
+	it( 'should add a batch to undo command, if it\'s type is redo and not clear redo stack', () => {
+		sinon.spy( undo._undoCommand, 'addBatch' );
+		sinon.spy( undo._redoCommand, 'clearStack' );
 
-		undo._undoCommand.fire( 'revert', batch );
+		batch.type = 'redo';
 
-		expect( undo._redoCommand.addBatch.calledOnce ).to.be.true;
-		expect( undo._redoCommand.addBatch.calledWith( batch ) ).to.be.true;
-	} );
+		expect( undo._undoCommand.addBatch.called ).to.be.false;
+		expect( undo._redoCommand.clearStack.called ).to.be.false;
 
-	it( 'should add a batch to undo command whenever a batch is redone by redo command', () => {
 		batch.insert( new Position( root, [ 0 ] ), 'foobar' );
 
-		sinon.spy( undo._undoCommand, 'addBatch' );
-
-		undo._redoCommand.fire( 'revert', batch );
-
 		expect( undo._undoCommand.addBatch.calledOnce ).to.be.true;
-		expect( undo._undoCommand.addBatch.calledWith( batch ) ).to.be.true;
+		expect( undo._redoCommand.clearStack.calledOnce ).to.be.false;
 	} );
 
-	it( 'should clear redo command stack whenever a new batch is applied to the document', () => {
-		sinon.spy( undo._redoCommand, 'clearStack' );
+	it( 'should add a batch to redo command, if it\'s type is undo', () => {
+		batch.type = 'undo';
+
+		sinon.spy( undo._redoCommand, 'addBatch' );
 
 		batch.insert( new Position( root, [ 0 ] ), 'foobar' );
 
-		expect( undo._redoCommand.clearStack.calledOnce ).to.be.true;
+		expect( undo._redoCommand.addBatch.calledOnce ).to.be.true;
+		expect( undo._redoCommand.addBatch.calledWith( batch ) ).to.be.true;
 	} );
 } );