Skip to content

Commit e4d7245

Browse files
authored
fix: Visit all nodes in getNextSibling and getPreviousSibling (#9080)
* WIP on line by line navigation Doesn't work, likely due to isValid check. * Add all inputs to the list of siblings * Fix formatting * Add tests * Remove dupe keys
1 parent 6dbd7b8 commit e4d7245

File tree

2 files changed

+113
-13
lines changed

2 files changed

+113
-13
lines changed

core/keyboard_nav/block_navigation_policy.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class BlockNavigationPolicy implements INavigationPolicy<BlockSvg> {
5757
* Returns the next peer node of the given block.
5858
*
5959
* @param current The block to find the following element of.
60-
* @returns The first block of the next stack if the given block is a terminal
60+
* @returns The first node of the next input/stack if the given block is a terminal
6161
* block, or its next connection.
6262
*/
6363
getNextSibling(current: BlockSvg): IFocusableNode | null {
@@ -70,12 +70,10 @@ export class BlockNavigationPolicy implements INavigationPolicy<BlockSvg> {
7070
let siblings: (BlockSvg | Field)[] = [];
7171
if (parent instanceof BlockSvg) {
7272
for (let i = 0, input; (input = parent.inputList[i]); i++) {
73-
if (input.connection) {
74-
siblings.push(...input.fieldRow);
75-
const child = input.connection.targetBlock();
76-
if (child) {
77-
siblings.push(child as BlockSvg);
78-
}
73+
siblings.push(...input.fieldRow);
74+
const child = input.connection?.targetBlock();
75+
if (child) {
76+
siblings.push(child as BlockSvg);
7977
}
8078
}
8179
} else if (parent instanceof WorkspaceSvg) {
@@ -114,12 +112,10 @@ export class BlockNavigationPolicy implements INavigationPolicy<BlockSvg> {
114112
let siblings: (BlockSvg | Field)[] = [];
115113
if (parent instanceof BlockSvg) {
116114
for (let i = 0, input; (input = parent.inputList[i]); i++) {
117-
if (input.connection) {
118-
siblings.push(...input.fieldRow);
119-
const child = input.connection.targetBlock();
120-
if (child) {
121-
siblings.push(child as BlockSvg);
122-
}
115+
siblings.push(...input.fieldRow);
116+
const child = input.connection?.targetBlock();
117+
if (child) {
118+
siblings.push(child as BlockSvg);
123119
}
124120
}
125121
} else if (parent instanceof WorkspaceSvg) {

tests/mocha/navigation_test.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,61 @@ suite('Navigation', function () {
283283
'tooltip': '',
284284
'helpUrl': '',
285285
},
286+
{
287+
'type': 'buttons',
288+
'message0': 'If %1 %2 Then %3 %4 more %5 %6 %7',
289+
'args0': [
290+
{
291+
'type': 'field_image',
292+
'name': 'BUTTON1',
293+
'src': 'https://www.gstatic.com/codesite/ph/images/star_on.gif',
294+
'width': 30,
295+
'height': 30,
296+
'alt': '*',
297+
},
298+
{
299+
'type': 'input_value',
300+
'name': 'VALUE1',
301+
'check': '',
302+
},
303+
{
304+
'type': 'field_image',
305+
'name': 'BUTTON2',
306+
'src': 'https://www.gstatic.com/codesite/ph/images/star_on.gif',
307+
'width': 30,
308+
'height': 30,
309+
'alt': '*',
310+
},
311+
{
312+
'type': 'input_dummy',
313+
'name': 'DUMMY1',
314+
'check': '',
315+
},
316+
{
317+
'type': 'input_value',
318+
'name': 'VALUE2',
319+
'check': '',
320+
},
321+
{
322+
'type': 'input_statement',
323+
'name': 'STATEMENT1',
324+
'check': 'Number',
325+
},
326+
{
327+
'type': 'field_image',
328+
'name': 'BUTTON3',
329+
'src': 'https://www.gstatic.com/codesite/ph/images/star_on.gif',
330+
'width': 30,
331+
'height': 30,
332+
'alt': '*',
333+
},
334+
],
335+
'previousStatement': null,
336+
'nextStatement': null,
337+
'colour': 230,
338+
'tooltip': '',
339+
'helpUrl': '',
340+
},
286341
]);
287342
const noNextConnection = this.workspace.newBlock('top_connection');
288343
const fieldAndInputs = this.workspace.newBlock('fields_and_input');
@@ -313,6 +368,27 @@ suite('Navigation', function () {
313368
const outputNextBlock = this.workspace.newBlock('output_next');
314369
this.blocks.secondBlock = secondBlock;
315370
this.blocks.outputNextBlock = outputNextBlock;
371+
372+
const buttonBlock = this.workspace.newBlock('buttons');
373+
const buttonInput1 = this.workspace.newBlock('field_input');
374+
const buttonInput2 = this.workspace.newBlock('field_input');
375+
buttonBlock.inputList[0].connection.connect(
376+
buttonInput1.outputConnection,
377+
);
378+
buttonBlock.inputList[2].connection.connect(
379+
buttonInput2.outputConnection,
380+
);
381+
// Make buttons by adding a click handler
382+
const clickHandler = function () {
383+
return;
384+
};
385+
buttonBlock.getField('BUTTON1').setOnClickHandler(clickHandler);
386+
buttonBlock.getField('BUTTON2').setOnClickHandler(clickHandler);
387+
buttonBlock.getField('BUTTON3').setOnClickHandler(clickHandler);
388+
this.blocks.buttonBlock = buttonBlock;
389+
this.blocks.buttonInput1 = buttonInput1;
390+
this.blocks.buttonInput2 = buttonInput2;
391+
316392
this.workspace.cleanUp();
317393
});
318394
suite('Next', function () {
@@ -427,6 +503,20 @@ suite('Navigation', function () {
427503
const nextNode = this.navigator.getNextSibling(icons[0]);
428504
assert.isNull(nextNode);
429505
});
506+
test('fromBlockToFieldInNextInput', function () {
507+
const field = this.blocks.buttonBlock.getField('BUTTON2');
508+
const prevNode = this.navigator.getNextSibling(
509+
this.blocks.buttonInput1,
510+
);
511+
assert.equal(prevNode, field);
512+
});
513+
test('fromBlockToFieldSkippingInput', function () {
514+
const field = this.blocks.buttonBlock.getField('BUTTON3');
515+
const prevNode = this.navigator.getNextSibling(
516+
this.blocks.buttonInput2,
517+
);
518+
assert.equal(prevNode, field);
519+
});
430520
});
431521

432522
suite('Previous', function () {
@@ -541,6 +631,20 @@ suite('Navigation', function () {
541631
const prevNode = this.navigator.getPreviousSibling(icons[0]);
542632
assert.isNull(prevNode);
543633
});
634+
test('fromBlockToFieldInSameInput', function () {
635+
const field = this.blocks.buttonBlock.getField('BUTTON1');
636+
const prevNode = this.navigator.getPreviousSibling(
637+
this.blocks.buttonInput1,
638+
);
639+
assert.equal(prevNode, field);
640+
});
641+
test('fromBlockToFieldInPrevInput', function () {
642+
const field = this.blocks.buttonBlock.getField('BUTTON2');
643+
const prevNode = this.navigator.getPreviousSibling(
644+
this.blocks.buttonInput2,
645+
);
646+
assert.equal(prevNode, field);
647+
});
544648
});
545649

546650
suite('In', function () {

0 commit comments

Comments
 (0)