Prevent the tabbable area from being restricted to the toolbox and workspace.

This commit is contained in:
Sean Lip
2016-08-10 18:30:16 -07:00
parent 73fbc06d4a
commit 3a1d9cdec1
6 changed files with 36 additions and 33 deletions

View File

@@ -30,11 +30,13 @@ blocklyApp.FieldComponent = ng.core
template: `
<input *ngIf="isTextInput()" [id]="mainFieldId" type="text" [disabled]="disabled"
[ngModel]="field.getValue()" (ngModelChange)="field.setValue($event)"
[attr.aria-label]="disabled ? 'Disabled text field' : 'Press Enter to edit text'">
[attr.aria-label]="disabled ? 'Disabled text field' : 'Press Enter to edit text'"
tabindex="-1">
<input *ngIf="isNumberInput()" [id]="mainFieldId" type="number" [disabled]="disabled"
[ngModel]="field.getValue()" (ngModelChange)="field.setValue($event)"
[attr.aria-label]="disabled ? 'Disabled number field' : 'Press Enter to edit number'">
[attr.aria-label]="disabled ? 'Disabled number field' : 'Press Enter to edit number'"
tabindex="-1">
<div *ngIf="isDropdown()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-menu', idMap['label'])">
@@ -43,7 +45,7 @@ blocklyApp.FieldComponent = ng.core
<li [id]="idMap[optionValue]" role="treeitem" *ngFor="#optionValue of getOptions()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap[optionValue + 'Button'], 'blockly-button')">
<button [id]="idMap[optionValue + 'Button']" (click)="handleDropdownChange(field, optionValue)"
[disabled]="disabled">
[disabled]="disabled" tabindex="-1">
{{optionText[optionValue]}}
</button>
</li>

View File

@@ -37,14 +37,14 @@ blocklyApp.ToolboxTreeComponent = ng.core
<li [id]="idMap['workspaceCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
[attr.aria-level]="level + 2">
<button [id]="idMap['workspaceCopyButton']" (click)="copyToWorkspace()">
<button [id]="idMap['workspaceCopyButton']" (click)="copyToWorkspace()" tabindex="-1">
{{'COPY_TO_WORKSPACE'|translate}}
</button>
</li>
<li [id]="idMap['blockCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockCopyButton'], 'blockly-button')"
[attr.aria-level]="level + 2">
<button [id]="idMap['blockCopyButton']" (click)="copyToClipboard()">
<button [id]="idMap['blockCopyButton']" (click)="copyToClipboard()" tabindex="-1">
{{'COPY_TO_CLIPBOARD'|translate}}
</button>
</li>
@@ -52,7 +52,7 @@ blocklyApp.ToolboxTreeComponent = ng.core
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', !canBeCopiedToMarkedConnection())"
[attr.aria-level]="level + 2">
<button [id]="idMap['sendToSelectedButton']" (click)="copyToMarkedSpot()"
[disabled]="!canBeCopiedToMarkedConnection()">
[disabled]="!canBeCopiedToMarkedConnection()" tabindex="-1">
{{'COPY_TO_MARKED_SPOT'|translate}}
</button>
</li>

View File

@@ -30,7 +30,7 @@ blocklyApp.ToolboxComponent = ng.core
<h3 #toolboxTitle id="blockly-toolbox-title">Toolbox</h3>
<ol #tree
id="blockly-toolbox-tree" role="tree" class="blocklyTree"
*ngIf="toolboxCategories && toolboxCategories.length > 0" tabIndex="0"
*ngIf="toolboxCategories && toolboxCategories.length > 0" tabindex="0"
[attr.aria-labelledby]="toolboxTitle.id"
[attr.aria-activedescendant]="getActiveDescId()"
(keydown)="treeService.onKeypress($event, tree)">

View File

@@ -82,21 +82,19 @@ blocklyApp.TreeService = ng.core
}
return null;
},
focusOnNextTree_: function(treeId) {
getIdOfNextTree_: function(treeId) {
var trees = this.getAllTreeNodes_();
for (var i = 0; i < trees.length - 1; i++) {
if (trees[i].id == treeId) {
trees[i + 1].focus();
return trees[i + 1].id;
}
}
return null;
},
focusOnPreviousTree_: function(treeId) {
getIdOfPreviousTree_: function(treeId) {
var trees = this.getAllTreeNodes_();
for (var i = trees.length - 1; i > 0; i--) {
if (trees[i].id == treeId) {
trees[i - 1].focus();
return trees[i - 1].id;
}
}
@@ -190,12 +188,11 @@ blocklyApp.TreeService = ng.core
if (e.keyCode == 9) {
// Tab key.
var destinationTreeId =
e.shiftKey ? this.focusOnPreviousTree_(treeId) :
this.focusOnNextTree_(treeId);
this.notifyUserAboutCurrentTree_(destinationTreeId);
e.preventDefault();
e.stopPropagation();
e.shiftKey ? this.getIdOfPreviousTree_(treeId) :
this.getIdOfNextTree_(treeId);
if (destinationTreeId) {
this.notifyUserAboutCurrentTree_(destinationTreeId);
}
}
},
isButtonOrFieldNode_: function(node) {
@@ -260,16 +257,20 @@ blocklyApp.TreeService = ng.core
// For Esc and Tab keys, the focus is removed from the input field.
this.focusOnCurrentTree_(treeId);
// In addition, for Tab keys, the user tabs to the previous/next tree.
if (e.keyCode == 9) {
var destinationTreeId =
e.shiftKey ? this.focusOnPreviousTree_(treeId) :
this.focusOnNextTree_(treeId);
this.notifyUserAboutCurrentTree_(destinationTreeId);
e.shiftKey ? this.getIdOfPreviousTree_(treeId) :
this.getIdOfNextTree_(treeId);
if (destinationTreeId) {
this.notifyUserAboutCurrentTree_(destinationTreeId);
}
}
e.preventDefault();
e.stopPropagation();
// Allow Tab keypresses to go through.
if (e.keyCode == 27) {
e.preventDefault();
e.stopPropagation();
}
}
} else {
// Outside an input field, Enter, Tab and navigation keys are all
@@ -302,14 +303,14 @@ blocklyApp.TreeService = ng.core
}
}
} else if (e.keyCode == 9) {
// Tab key.
// Tab key. Note that allowing the event to propagate through is
// intentional.
var destinationTreeId =
e.shiftKey ? this.focusOnPreviousTree_(treeId) :
this.focusOnNextTree_(treeId);
this.notifyUserAboutCurrentTree_(destinationTreeId);
e.preventDefault();
e.stopPropagation();
e.shiftKey ? this.getIdOfPreviousTree_(treeId) :
this.getIdOfNextTree_(treeId);
if (destinationTreeId) {
this.notifyUserAboutCurrentTree_(destinationTreeId);
}
} else if (e.keyCode >= 35 && e.keyCode <= 40) {
// End, home, and arrow keys.
if (e.keyCode == 35) {

View File

@@ -60,7 +60,7 @@ blocklyApp.WorkspaceTreeComponent = ng.core
[attr.aria-level]="level + 2">
<button [id]="idMap[fieldButtonInfo.baseIdKey + 'Button' + i]"
(click)="fieldButtonInfo.action(inputBlock.connection)"
[disabled]="fieldButtonInfo.isDisabled(inputBlock.connection)">
[disabled]="fieldButtonInfo.isDisabled(inputBlock.connection)" tabindex="-1">
{{fieldButtonInfo.translationIdForText|translate}}
</button>
</li>
@@ -78,7 +78,7 @@ blocklyApp.WorkspaceTreeComponent = ng.core
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap[buttonInfo.baseIdKey + 'Button'], 'blockly-button', buttonInfo.isDisabled())"
[attr.aria-level]="level + 2">
<button [id]="idMap[buttonInfo.baseIdKey + 'Button']" (click)="buttonInfo.action()"
[disabled]="buttonInfo.isDisabled()">
[disabled]="buttonInfo.isDisabled()" tabindex="-1">
{{buttonInfo.translationIdForText|translate}}
</button>
</li>

View File

@@ -47,7 +47,7 @@ blocklyApp.WorkspaceComponent = ng.core
<div *ngIf="workspace">
<ol #tree *ngFor="#block of workspace.topBlocks_; #i = index"
tabIndex="0" role="tree" class="blocklyTree blocklyWorkspaceTree"
tabindex="0" role="tree" class="blocklyTree blocklyWorkspaceTree"
[attr.aria-activedescendant]="getActiveDescId(tree.id)"
[attr.aria-labelledby]="workspaceTitle.id"
(keydown)="onKeypress($event, tree)">