Skip to content

Commit 7e77b10

Browse files
authored
fix: Make up/previous navigation consistent with down/next. (#9437)
* fix: Make up/previous navigation consistent with down/next. * fix: Don't visit nested input blocks when moving up/previous.
1 parent ae3a610 commit 7e77b10

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

core/keyboard_nav/block_navigation_policy.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ function getBlockNavigationCandidates(
137137
.lastConnectionInStack(false)
138138
?.getSourceBlock();
139139
if (lastStackBlock) {
140-
// When navigating backward, the last block in a stack in a statement
141-
// input is navigable.
142-
candidates.push(lastStackBlock);
140+
// When navigating backward, the last next connection in a stack in a
141+
// statement input is navigable.
142+
candidates.push(lastStackBlock.nextConnection);
143143
}
144144
} else {
145145
// When navigating forward, a child block connected to a statement
@@ -198,9 +198,13 @@ export function navigateStacks(current: ISelectable, delta: number) {
198198
}
199199

200200
// When navigating to a previous block stack, our previous sibling is the last
201-
// block in it.
201+
// block or nested next connection in it.
202202
if (delta < 0 && result instanceof BlockSvg) {
203-
return result.lastConnectionInStack(false)?.getSourceBlock() ?? result;
203+
result = result.lastConnectionInStack(false)?.getSourceBlock() ?? result;
204+
205+
if (result instanceof BlockSvg && result.statementInputCount > 0) {
206+
result = getBlockNavigationCandidates(result, false).at(-1) ?? result;
207+
}
204208
}
205209

206210
return result;

core/keyboard_nav/line_cursor.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,44 @@ export class LineCursor extends Marker {
338338
return true;
339339
}
340340

341-
const current = this.getSourceBlockFromNode(this.getCurNode());
342-
if (candidate instanceof BlockSvg && current instanceof BlockSvg) {
341+
const currentNode = this.getCurNode();
342+
if (direction === NavigationDirection.PREVIOUS) {
343+
// Don't visit rightmost/nested blocks in statement blocks when
344+
// navigating to the previous block.
345+
if (
346+
currentNode instanceof RenderedConnection &&
347+
currentNode.type === ConnectionType.NEXT_STATEMENT &&
348+
!currentNode.getParentInput() &&
349+
candidate !== currentNode.getSourceBlock()
350+
) {
351+
return false;
352+
}
353+
354+
// Don't visit the first value/input block in a block with statement
355+
// inputs when navigating to the previous block. This is consistent
356+
// with the behavior when navigating to the next block and avoids
357+
// duplicative screen reader narration. Also don't visit value
358+
// blocks nested in non-statement inputs.
359+
if (
360+
candidate instanceof BlockSvg &&
361+
candidate.outputConnection?.targetConnection
362+
) {
363+
const parentInput =
364+
candidate.outputConnection.targetConnection.getParentInput();
365+
if (
366+
!parentInput?.getSourceBlock().statementInputCount ||
367+
parentInput?.getSourceBlock().inputList[0] === parentInput
368+
) {
369+
return false;
370+
}
371+
}
372+
}
373+
374+
const currentBlock = this.getSourceBlockFromNode(currentNode);
375+
if (
376+
candidate instanceof BlockSvg &&
377+
currentBlock instanceof BlockSvg
378+
) {
343379
// If the candidate's parent uses inline inputs, disallow the
344380
// candidate; it follows that it must be on the same row as its
345381
// parent.
@@ -352,13 +388,13 @@ export class LineCursor extends Marker {
352388
// block, disallow it; it cannot be on a different row than the
353389
// current block.
354390
if (
355-
current === this.getCurNode() &&
356-
candidateParents.has(current)
391+
currentBlock === this.getCurNode() &&
392+
candidateParents.has(currentBlock)
357393
) {
358394
return false;
359395
}
360396

361-
const currentParents = this.getParents(current);
397+
const currentParents = this.getParents(currentBlock);
362398

363399
const sharedParents = currentParents.intersection(candidateParents);
364400
// Allow the candidate if it and the current block have no parents

0 commit comments

Comments
 (0)