mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
Make aria-levels 1-indexed. Allow pressing Enter to go down a level, and pressing Escape to go up a level. Add a guard against incorrect status message when reaching the top of the outermost level.
This commit is contained in:
parent
48f181e1e3
commit
966cda6088
3 changed files with 40 additions and 21 deletions
|
@ -40,7 +40,7 @@ blocklyApp.ToolboxComponent = ng.core
|
|||
[id]="idMap['Parent' + i]" role="treeitem"
|
||||
[ngClass]="{blocklyHasChildren: true, blocklyActiveDescendant: tree.getAttribute('aria-activedescendant') == idMap['Parent' + i]}"
|
||||
*ngFor="#category of toolboxCategories; #i=index"
|
||||
aria-level="1"
|
||||
aria-level="0"
|
||||
[attr.aria-label]="getCategoryAriaLabel(category)">
|
||||
<div *ngIf="category && category.attributes">
|
||||
<label [id]="idMap['Label' + i]" #name>
|
||||
|
@ -48,7 +48,7 @@ blocklyApp.ToolboxComponent = ng.core
|
|||
</label>
|
||||
<ol role="group" *ngIf="getToolboxWorkspace(category).topBlocks_.length > 0">
|
||||
<blockly-toolbox-tree *ngFor="#block of getToolboxWorkspace(category).topBlocks_"
|
||||
[level]="2" [block]="block"
|
||||
[level]="1" [block]="block"
|
||||
[displayBlockMenu]="true"
|
||||
[tree]="tree">
|
||||
</blockly-toolbox-tree>
|
||||
|
@ -59,7 +59,7 @@ blocklyApp.ToolboxComponent = ng.core
|
|||
|
||||
<div *ngIf="!xmlHasCategories">
|
||||
<blockly-toolbox-tree *ngFor="#block of getToolboxWorkspace(toolboxCategories[0]).topBlocks_; #i=index"
|
||||
role="treeitem" [level]="1" [block]="block"
|
||||
role="treeitem" [level]="0" [block]="block"
|
||||
[tree]="tree" [displayBlockMenu]="true"
|
||||
[isFirstToolboxTree]="i === 0">
|
||||
</blockly-toolbox-tree>
|
||||
|
|
|
@ -440,23 +440,26 @@ blocklyApp.TreeService = ng.core
|
|||
// Outside an input field, Enter, Tab and navigation keys are all
|
||||
// recognized.
|
||||
if (e.keyCode == 13) {
|
||||
// Enter key. The user wants to interact with a button or an input
|
||||
// field.
|
||||
// Enter key. The user wants to interact with a button, interact with
|
||||
// an input field, or move down one level.
|
||||
// Algorithm to find the field: do a DFS through the children until
|
||||
// we find an INPUT or BUTTON element (in which case we use it).
|
||||
// Truncate the search at child LI elements.
|
||||
var found = false;
|
||||
var dfsStack = Array.from(activeDesc.children);
|
||||
while (dfsStack.length) {
|
||||
var currentNode = dfsStack.shift();
|
||||
if (currentNode.tagName == 'BUTTON') {
|
||||
this.moveActiveDescToParent(treeId);
|
||||
this.moveUpOneLevel_(treeId);
|
||||
currentNode.click();
|
||||
found = true;
|
||||
break;
|
||||
} else if (currentNode.tagName == 'INPUT') {
|
||||
currentNode.focus();
|
||||
currentNode.select();
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Type a value, then press Escape to exit');
|
||||
found = true;
|
||||
break;
|
||||
} else if (currentNode.tagName == 'LI') {
|
||||
continue;
|
||||
|
@ -469,6 +472,12 @@ blocklyApp.TreeService = ng.core
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot find a field to interact with, we try moving down a
|
||||
// level instead.
|
||||
if (!found) {
|
||||
this.moveDownOneLevel_(treeId);
|
||||
}
|
||||
} else if (e.keyCode == 9) {
|
||||
// Tab key. Note that allowing the event to propagate through is
|
||||
// intentional.
|
||||
|
@ -478,6 +487,8 @@ blocklyApp.TreeService = ng.core
|
|||
if (destinationTreeId) {
|
||||
this.notifyUserAboutCurrentTree_(destinationTreeId);
|
||||
}
|
||||
} else if (e.keyCode == 27) {
|
||||
this.moveUpOneLevel_(treeId);
|
||||
} else if (e.keyCode >= 35 && e.keyCode <= 40) {
|
||||
// End, home, and arrow keys.
|
||||
if (e.keyCode == 35) {
|
||||
|
@ -494,22 +505,22 @@ blocklyApp.TreeService = ng.core
|
|||
}
|
||||
} else if (e.keyCode == 37) {
|
||||
// Left arrow key. Go up a level, if possible.
|
||||
this.moveActiveDescToParent(treeId);
|
||||
this.moveUpOneLevel_(treeId);
|
||||
} else if (e.keyCode == 38) {
|
||||
// Up arrow key. Go to the previous sibling, if possible.
|
||||
var prevSibling = this.getPreviousSibling(activeDesc);
|
||||
if (prevSibling) {
|
||||
this.setActiveDesc(prevSibling.id, treeId);
|
||||
} else {
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Reached top of list. Press left to go to parent list.');
|
||||
var statusMessage = 'Reached top of list.';
|
||||
if (this.getParentListElement_(activeDesc)) {
|
||||
statusMessage += ' Press left to go to parent list.';
|
||||
}
|
||||
this.notificationsService.setStatusMessage(statusMessage);
|
||||
}
|
||||
} else if (e.keyCode == 39) {
|
||||
// Right arrow key. Go down a level, if possible.
|
||||
var firstChild = this.getFirstChild(activeDesc);
|
||||
if (firstChild) {
|
||||
this.setActiveDesc(firstChild.id, treeId);
|
||||
}
|
||||
this.moveDownOneLevel_(treeId);
|
||||
} else if (e.keyCode == 40) {
|
||||
// Down arrow key. Go to the next sibling, if possible.
|
||||
var nextSibling = this.getNextSibling(activeDesc);
|
||||
|
@ -526,19 +537,27 @@ blocklyApp.TreeService = ng.core
|
|||
}
|
||||
}
|
||||
},
|
||||
moveActiveDescToParent: function(treeId) {
|
||||
moveDownOneLevel_: function(treeId) {
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
var nextNode = activeDesc.parentNode;
|
||||
if (this.isButtonOrFieldNode_(activeDesc)) {
|
||||
nextNode = nextNode.parentNode;
|
||||
}
|
||||
while (nextNode && nextNode.tagName != 'LI') {
|
||||
nextNode = nextNode.parentNode;
|
||||
var firstChild = this.getFirstChild(activeDesc);
|
||||
if (firstChild) {
|
||||
this.setActiveDesc(firstChild.id, treeId);
|
||||
}
|
||||
},
|
||||
moveUpOneLevel_: function(treeId) {
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
var nextNode = this.getParentListElement_(activeDesc);
|
||||
if (nextNode) {
|
||||
this.setActiveDesc(nextNode.id, treeId);
|
||||
}
|
||||
},
|
||||
getParentListElement_: function(element) {
|
||||
var nextNode = element.parentNode;
|
||||
while (nextNode && nextNode.tagName != 'LI') {
|
||||
nextNode = nextNode.parentNode;
|
||||
}
|
||||
return nextNode;
|
||||
},
|
||||
getFirstChild: function(element) {
|
||||
if (!element) {
|
||||
return element;
|
||||
|
|
|
@ -36,7 +36,7 @@ blocklyApp.WorkspaceComponent = ng.core
|
|||
[attr.aria-activedescendant]="getActiveDescId(tree.id)"
|
||||
[attr.aria-labelledby]="workspaceTitle.id"
|
||||
(keydown)="onKeypress($event, tree)">
|
||||
<blockly-workspace-tree [level]=1 [block]="block" [tree]="tree" [isTopLevel]="true">
|
||||
<blockly-workspace-tree [level]="0" [block]="block" [tree]="tree" [isTopLevel]="true">
|
||||
</blockly-workspace-tree>
|
||||
</ol>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue