diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index 24e52ba9525..f4578a9410b 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -573,18 +573,13 @@ export class BlockDragStrategy implements IDragStrategy { const direction = this.getDirectionToNewLocation( Coordinate.sum(this.startLoc!, delta), ); - const candidate = this.findTraversalCandidate(direction); - if (candidate) { - return candidate; - } - - delta = new Coordinate(0, 0); + return this.findTraversalCandidate(direction); } // If we do not have a candidate yet, we fallback to the closest one nearby. let radius = this.getSearchRadius(); const localConns = this.getLocalConnections(this.block); - let candidate = null; + let candidate: ConnectionCandidate | null = null; for (const conn of localConns) { const {connection: neighbour, radius: rad} = conn.closest(radius, delta); @@ -775,30 +770,40 @@ export class BlockDragStrategy implements IDragStrategy { * @returns A candidate connection and radius, or null if none was found. */ findTraversalCandidate(direction: Direction): ConnectionCandidate | null { - const currentPairIndex = this.allConnectionPairs.findIndex( + const pairs = this.allConnectionPairs; + if (direction === Direction.NONE || !pairs.length) { + return this.connectionCandidate; + } + const forwardTraversal = + direction === Direction.RIGHT || direction === Direction.DOWN; + const currentPairIndex = pairs.findIndex( (pair) => this.connectionCandidate?.local === pair.local && this.connectionCandidate?.neighbour === pair.neighbour, ); - if (currentPairIndex !== -1) { - if (direction === Direction.UP || direction === Direction.LEFT) { - const nextPair = - this.allConnectionPairs[currentPairIndex - 1] ?? - this.allConnectionPairs[this.allConnectionPairs.length - 1]; - return {...nextPair, distance: 0}; - } else if ( - direction === Direction.DOWN || - direction === Direction.RIGHT - ) { - const nextPair = - this.allConnectionPairs[currentPairIndex + 1] ?? - this.allConnectionPairs[0]; - return {...nextPair, distance: 0}; + + if (forwardTraversal) { + if (currentPairIndex === -1) { + return this.pairToCandidate(pairs[0]); + } else if (currentPairIndex === pairs.length - 1) { + return null; + } else { + return this.pairToCandidate(pairs[currentPairIndex + 1]); + } + } else { + if (currentPairIndex === -1) { + return this.pairToCandidate(pairs[pairs.length - 1]); + } else if (currentPairIndex === 0) { + return null; + } else { + return this.pairToCandidate(pairs[currentPairIndex - 1]); } } - return null; } + private pairToCandidate(pair: ConnectionPair): ConnectionCandidate { + return {...pair, distance: 0}; + } /** * Returns the cardinal direction that the block being dragged would have to * move in to reach the given location. diff --git a/packages/blockly/tests/mocha/keyboard_movement_test.js b/packages/blockly/tests/mocha/keyboard_movement_test.js index 547bfdc1ca0..115275e6395 100644 --- a/packages/blockly/tests/mocha/keyboard_movement_test.js +++ b/packages/blockly/tests/mocha/keyboard_movement_test.js @@ -583,6 +583,7 @@ suite('Keyboard-driven movement', function () { {id: 'controls_if', index: 6, ownIndex: 0}, // "Else" statement input. {id: 'controls_if', index: 1, ownIndex: 0}, // Next. {id: 'p5_draw', index: 0, ownIndex: 0}, // Statement input. + null, // Disconnected on workspace ]; /** * Expected connection candidates when moving STATEMENT_SIMPLE after @@ -653,6 +654,7 @@ suite('Keyboard-driven movement', function () { {id: 'controls_if', index: 6, ownIndex: 0}, // "Else" statement input. {id: 'controls_if', index: 1, ownIndex: 0}, // Next. {id: 'p5_draw', index: 0, ownIndex: 0}, // Statement input. + null, // Disconnected on workspace ]; /** * Expected connection candidates when moving STATEMENT_COMPLEX after @@ -761,6 +763,7 @@ suite('Keyboard-driven movement', function () { {id: 'join2', index: 1, ownIndex: 0}, // Join block ADD0 input. {id: 'join2', index: 2, ownIndex: 0}, // Join block ADD1 input. // Skip input of unattached join block. + null, // Disconnected on workspace ]; /** * Expected connection candidates when moving BLOCK_SIMPLE, after