Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/blockly/core/contextmenu_items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function registerUndo() {
return 'disabled';
},
callback(scope: Scope) {
scope.workspace!.undo(false);
scope.workspace!.undo();
},
scopeType: ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'undoWorkspace',
Expand All @@ -71,7 +71,7 @@ export function registerRedo() {
return 'disabled';
},
callback(scope: Scope) {
scope.workspace!.undo(true);
scope.workspace!.redo();
},
scopeType: ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'redoWorkspace',
Expand Down
4 changes: 2 additions & 2 deletions packages/blockly/core/shortcut_items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ export function registerUndo() {
callback(workspace, e) {
// 'z' for undo 'Z' is for redo.
(workspace as WorkspaceSvg).hideChaff();
workspace.undo(false);
workspace.undo();
e.preventDefault();
return true;
},
Expand Down Expand Up @@ -367,7 +367,7 @@ export function registerRedo() {
callback(workspace, e) {
// 'z' for undo 'Z' is for redo.
(workspace as WorkspaceSvg).hideChaff();
workspace.undo(true);
workspace.redo();
e.preventDefault();
return true;
},
Expand Down
9 changes: 8 additions & 1 deletion packages/blockly/core/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ export class Workspace {
*
* @param redo False if undo, true if redo.
*/
undo(redo: boolean) {
undo(redo = false) {
const inputStack = redo ? this.redoStack_ : this.undoStack_;
const outputStack = redo ? this.undoStack_ : this.redoStack_;
const inputEvent = inputStack.pop();
Expand Down Expand Up @@ -762,6 +762,13 @@ export class Workspace {
}
}

/**
* Redoes the previous action.
*/
redo() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small suggestion: it would be nice to have a few new tests specifically for this method (since it's now part of the class's public API which means it has its own contract that should be enforced). Presumably these could just be a copy of the redo undo tests, but I also don't think they should replace those since undo's contract isn't changing (other than the new defaulting behavior and I don't think that needs to necessarily be tested).

this.undo(true);
}

/** Clear the undo/redo stacks. */
clearUndo() {
this.undoStack_.length = 0;
Expand Down
10 changes: 5 additions & 5 deletions packages/blockly/tests/mocha/comment_deserialization_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ suite('Comment Deserialization', function () {
this.block.checkAndDelete();
assert.equal(this.workspace.getAllBlocks().length, 0);
// Undo.
this.workspace.undo(false);
this.workspace.undo();
assert.equal(this.workspace.getAllBlocks().length, 1);
// Check comment.
assertComment(this.workspace, 'test text');
Expand All @@ -97,12 +97,12 @@ suite('Comment Deserialization', function () {
// Create block.
this.block = createBlock(this.workspace);
// Undo & undo.
this.workspace.undo(false);
this.workspace.undo(false);
this.workspace.undo();
this.workspace.undo();
assert.equal(this.workspace.getAllBlocks().length, 0);
// Redo & redo.
this.workspace.undo(true);
this.workspace.undo(true);
this.workspace.redo();
this.workspace.redo();
assert.equal(this.workspace.getAllBlocks().length, 1);
// Check comment.
assertComment(this.workspace, 'test text');
Expand Down
12 changes: 6 additions & 6 deletions packages/blockly/tests/mocha/comment_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ suite('Comments', function () {
assert.isNotNull(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.equal(block.getCommentText(), '');

this.workspace.undo(false);
this.workspace.undo();

assert.isUndefined(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.isNull(block.getCommentText());
Expand All @@ -183,8 +183,8 @@ suite('Comments', function () {
test('Adding an empty comment can be redone', function () {
const block = this.workspace.newBlock('empty_block');
block.setCommentText('');
this.workspace.undo(false);
this.workspace.undo(true);
this.workspace.undo();
this.workspace.redo();

assert.isNotNull(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.equal(block.getCommentText(), '');
Expand All @@ -196,7 +196,7 @@ suite('Comments', function () {
assert.isNotNull(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.equal(block.getCommentText(), 'hey there');

this.workspace.undo(false);
this.workspace.undo();

assert.isUndefined(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.isNull(block.getCommentText());
Expand All @@ -205,8 +205,8 @@ suite('Comments', function () {
test('Adding a non-empty comment can be redone', function () {
const block = this.workspace.newBlock('empty_block');
block.setCommentText('hey there');
this.workspace.undo(false);
this.workspace.undo(true);
this.workspace.undo();
this.workspace.redo();

assert.isNotNull(block.getIcon(Blockly.icons.IconType.COMMENT));
assert.equal(block.getCommentText(), 'hey there');
Expand Down
4 changes: 2 additions & 2 deletions packages/blockly/tests/mocha/contextmenu_items_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ suite('Context Menu Items', function () {
test('Enabled when something to redo', function () {
// Create a new block, then undo it, which means there is something to redo.
this.workspace.newBlock('text');
this.workspace.undo(false);
this.workspace.undo();
const precondition = this.redoOption.preconditionFn(this.scope);
assert.equal(
precondition,
Expand All @@ -105,7 +105,7 @@ suite('Context Menu Items', function () {
test('Redoes adding new block', function () {
// Add a new block, then undo it, then redo it.
this.workspace.newBlock('text');
this.workspace.undo(false);
this.workspace.undo();
assert.equal(this.workspace.getTopBlocks(false).length, 0);
this.redoOption.callback(this.scope);
assert.equal(
Expand Down
6 changes: 2 additions & 4 deletions packages/blockly/tests/mocha/shortcut_items_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,6 @@ suite('Keyboard Shortcut Items', function () {
test('Simple', function () {
this.injectionDiv.dispatchEvent(keyEvent);
sinon.assert.calledOnce(this.undoSpy);
sinon.assert.calledWith(this.undoSpy, false);
sinon.assert.calledOnce(this.hideChaffSpy);
});
// Do not undo if a drag is in progress.
Expand All @@ -351,7 +350,7 @@ suite('Keyboard Shortcut Items', function () {

suite('Redo', function () {
setup(function () {
this.redoSpy = sinon.spy(this.workspace, 'undo');
this.redoSpy = sinon.spy(this.workspace, 'redo');
this.hideChaffSpy = sinon.spy(
Blockly.WorkspaceSvg.prototype,
'hideChaff',
Expand All @@ -361,11 +360,10 @@ suite('Keyboard Shortcut Items', function () {
Blockly.utils.KeyCodes.CTRL_CMD,
Blockly.utils.KeyCodes.SHIFT,
]);
// Undo.
// Redo.
test('Simple', function () {
this.injectionDiv.dispatchEvent(keyEvent);
sinon.assert.calledOnce(this.redoSpy);
sinon.assert.calledWith(this.redoSpy, true);
sinon.assert.calledOnce(this.hideChaffSpy);
});
// Do not redo if a drag is in progress.
Expand Down
37 changes: 19 additions & 18 deletions packages/blockly/tests/mocha/test_helpers/workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -1287,17 +1287,18 @@ export function testAWorkspace() {
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
assert.isNull(this.variableMap.getVariableById('id2'));

this.workspace.undo(true);
this.workspace.redo();

// Expect that variable 'id2' is recreated
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo();
this.workspace.undo();

assert.isNull(this.variableMap.getVariableById('id1'));
assert.isNull(this.variableMap.getVariableById('id2'));
this.workspace.undo(true);
this.workspace.redo();

// Expect that variable 'id1' is recreated
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
Expand Down Expand Up @@ -1365,7 +1366,7 @@ export function testAWorkspace() {
assert.isNull(this.variableMap.getVariableById('id1'));
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
// Expect that both variables are deleted
assert.isNull(this.variableMap.getVariableById('id1'));
Expand All @@ -1378,7 +1379,7 @@ export function testAWorkspace() {
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
// Expect that variable 'id2' is recreated
assert.isNull(this.variableMap.getVariableById('id1'));
Expand All @@ -1402,7 +1403,7 @@ export function testAWorkspace() {
assert.isNull(this.variableMap.getVariableById('id1'));
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
// Expect that both variables are deleted
assert.equal(this.workspace.getTopBlocks(false).length, 0);
Expand All @@ -1418,7 +1419,7 @@ export function testAWorkspace() {
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
// Expect that variable 'id2' is recreated
assertBlockVarModelName(this.workspace, 0, 'name2');
Expand All @@ -1441,7 +1442,7 @@ export function testAWorkspace() {
this.clock.runAll();
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'name2', 'type1', 'id1');
});
Expand All @@ -1457,7 +1458,7 @@ export function testAWorkspace() {
assertBlockVarModelName(this.workspace, 0, 'name1');
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertBlockVarModelName(this.workspace, 0, 'name2');
assertVariableValues(this.variableMap, 'name2', 'type1', 'id1');
Expand All @@ -1472,7 +1473,7 @@ export function testAWorkspace() {
this.clock.runAll();
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'Name1', 'type1', 'id1');
});
Expand All @@ -1488,7 +1489,7 @@ export function testAWorkspace() {
assertBlockVarModelName(this.workspace, 0, 'name1');
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertBlockVarModelName(this.workspace, 0, 'Name1');
assertVariableValues(this.variableMap, 'Name1', 'type1', 'id1');
Expand All @@ -1506,7 +1507,7 @@ export function testAWorkspace() {
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');
assert.isNull(this.variableMap.getVariableById('id1'));
Expand All @@ -1530,7 +1531,7 @@ export function testAWorkspace() {
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');
assert.isNull(this.variableMap.getVariableById('id1'));
Expand All @@ -1547,7 +1548,7 @@ export function testAWorkspace() {
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'Name2', 'type1', 'id2');
assert.isNull(this.variableMap.getVariable('name1'));
Expand All @@ -1567,7 +1568,7 @@ export function testAWorkspace() {
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type1', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'Name2', 'type1', 'id2');
assert.isNull(this.variableMap.getVariableById('id1'));
Expand All @@ -1586,7 +1587,7 @@ export function testAWorkspace() {
assertVariableValues(this.variableMap, 'name1', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'name2', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type2', 'id2');
Expand All @@ -1606,7 +1607,7 @@ export function testAWorkspace() {
assertBlockVarModelName(this.workspace, 0, 'name1');
assertBlockVarModelName(this.workspace, 1, 'name2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'name2', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type2', 'id2');
Expand All @@ -1625,7 +1626,7 @@ export function testAWorkspace() {
assertVariableValues(this.workspace, 'name1', 'type1', 'id1');
assertVariableValues(this.workspace, 'name2', 'type2', 'id2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'Name2', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type2', 'id2');
Expand All @@ -1645,7 +1646,7 @@ export function testAWorkspace() {
assertBlockVarModelName(this.workspace, 0, 'name1');
assertBlockVarModelName(this.workspace, 1, 'name2');

this.workspace.undo(true);
this.workspace.redo();
this.clock.runAll();
assertVariableValues(this.variableMap, 'Name2', 'type1', 'id1');
assertVariableValues(this.variableMap, 'name2', 'type2', 'id2');
Expand Down