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
18 changes: 13 additions & 5 deletions packages/blockly/core/dragging/block_drag_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,16 @@ export class BlockDragStrategy implements IDragStrategy {
// Enable all blocks including children.
this.enableAllDraggedBlocks(this.block);

// Cached connection pairs are primarily used for keyboard-driven moves,
// but they are also needed in order to determine whether announcement text
// must disambiguate between multiple compatible connections. This is a
// relatively expensive operation, so we only do it once at the start of
// the drag.
this.cacheAllConnectionPairs();

// For keyboard-driven moves, cache a list of valid connection points for
// use in constrained moved mode.
if (e instanceof KeyboardEvent) {
this.cacheAllConnectionPairs();

// Scooch the block to be offset from the connection preview indicator.
const neighbour = this.updateConnectionPreview(
this.block,
Expand Down Expand Up @@ -380,10 +385,13 @@ export class BlockDragStrategy implements IDragStrategy {
}

/**
* Handles any setup for starting the drag, including disconnecting the block
* from any parent blocks.
* Caches a list of all valid connection pairs between the dragging block
* and any other blocks on the workspace. This is used to determine the
* closest valid connection during keyboard-driven moves and to determine
* the need to disambiguate between multiple compatible connections when
* announcing moves to assistive technologies.
*/
private cacheAllConnectionPairs() {
cacheAllConnectionPairs() {
const connectionChecker = this.block.workspace.connectionChecker;
const workspaceConns = [];
this.allConnectionPairs = [];
Expand Down
60 changes: 60 additions & 0 deletions packages/blockly/tests/mocha/keyboard_movement_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,66 @@ suite('Keyboard-driven movement', function () {
EXPECTED_SIMPLE_LEFT,
),
);
suite('Recaching after inputs change mid-move', function () {
setup(function () {
this.mover = this.workspace.getBlockById(VALUE_SIMPLE.id);
this.join = this.workspace.getBlockById('join0');
this.strategy = this.mover.getDragStrategy();

Blockly.getFocusManager().focusNode(this.mover);
startMove(this.workspace);

// Snapshot the start-of-drag cache before the block grows.
this.originalPairs = [...this.strategy.allConnectionPairs];

this.join.appendValueInput('ADD2');
this.newConnection = this.join.getInput('ADD2').connection;
});

teardown(function () {
if (Blockly.KeyboardMover.mover.isMoving()) {
cancelMove(this.workspace);
}
});

test('the original cache excludes the new connection', function () {
assert.isFalse(
this.originalPairs.some(
(pair) => pair.neighbour === this.newConnection,
),
);
});

test('the refreshed cache includes the new connection', function () {
this.strategy.cacheAllConnectionPairs();

assert.isTrue(
this.strategy.allConnectionPairs.some(
(pair) => pair.neighbour === this.newConnection,
),
);
});

test('traverses to the new connection in order after recaching', function () {
this.strategy.cacheAllConnectionPairs();

moveRight(this.workspace);
console.log(getConnectionCandidate());
assert.deepEqual(getConnectionCandidate(), {
id: 'join0',
index: 2,
ownIndex: 0,
});

moveRight(this.workspace);
console.log(getConnectionCandidate());
assert.deepEqual(getConnectionCandidate(), {
id: 'join0',
index: 3,
ownIndex: 0,
});
});
});
});

suite('Constrained moves of row of value blocks', function () {
Expand Down
Loading