From 2f64dd1d8176302d5255b1f377b0f79a9e23b48a Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Sat, 27 Feb 2021 13:04:04 +0100 Subject: [PATCH] feat(command): attach command to previous undo/redo context This adds the ability to attach commands to the previous undo/redo context. By doing so I can execute things invisible to the user (from the undo/redo) perspective. ```javascript // given commandStack.registerHandler('simple-command', SimpleCommand); var context = { element: { trace: [] } }; commandStack.execute('simple-command', context, true); commandStack.execute('simple-command', context, true); // when commandStack.undo(); // then // both commands are undone ``` --- lib/command/CommandStack.js | 9 ++++-- test/spec/command/CommandStackSpec.js | 43 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/lib/command/CommandStack.js b/lib/command/CommandStack.js index 253d0f0bf..23574089a 100644 --- a/lib/command/CommandStack.js +++ b/lib/command/CommandStack.js @@ -139,15 +139,20 @@ CommandStack.$inject = [ 'eventBus', 'injector' ]; * * @param {string} command the command to execute * @param {Object} context the environment to execute the command in + * @param {boolean} [append=false] if true, append this execution to the existing undo step */ -CommandStack.prototype.execute = function(command, context) { +CommandStack.prototype.execute = function(command, context, compact) { if (!command) { throw new Error('command required'); } this._currentExecution.trigger = 'execute'; - var action = { command: command, context: context }; + var action = { + id: compact && this.canUndo() ? this._getUndoAction().id : null, + command: command, + context: context, + }; this._pushAction(action); this._internalExecute(action); diff --git a/test/spec/command/CommandStackSpec.js b/test/spec/command/CommandStackSpec.js index e883daaf5..8eecce2d5 100755 --- a/test/spec/command/CommandStackSpec.js +++ b/test/spec/command/CommandStackSpec.js @@ -362,6 +362,49 @@ describe('command/CommandStack', function() { }); + describe('#execute compact', function() { + + it('should undo in single step', inject(function(commandStack) { + + // given + commandStack.registerHandler('simple-command', SimpleCommand); + + var context = { element: { trace: [] } }; + + commandStack.execute('simple-command', context, true); + commandStack.execute('simple-command', context, true); + + // when + commandStack.undo(); + + // then + expect(commandStack._stack.length).to.equal(2); + expect(commandStack._stackIdx).to.equal(-1); + })); + + + it('should redo in single step', inject(function(commandStack) { + + // given + commandStack.registerHandler('simple-command', SimpleCommand); + + var context = { element: { trace: [] } }; + + commandStack.execute('simple-command', context, true); + commandStack.execute('simple-command', context, true); + + // when + commandStack.undo(); + commandStack.redo(); + + // then + expect(commandStack._stack.length).to.equal(2); + expect(commandStack._stackIdx).to.equal(1); + })); + + }); + + describe('command context', function() { it('should pass command context to handler', inject(function(commandStack) {