diff --git a/accessible/clipboard.service.js b/accessible/clipboard.service.js index db65e2d9f..a9be69eb5 100644 --- a/accessible/clipboard.service.js +++ b/accessible/clipboard.service.js @@ -149,5 +149,7 @@ blocklyApp.ClipboardService = ng.core } this.markedConnection_ = null; + + return reconstitutedBlock.id; } }); diff --git a/accessible/tree.service.js b/accessible/tree.service.js index 4bc9f4156..b2430aee8 100644 --- a/accessible/tree.service.js +++ b/accessible/tree.service.js @@ -133,12 +133,26 @@ blocklyApp.TreeService = ng.core document.getElementById(treeId).focus(); }, 0); }, + // This clears the active descendant of the given tree. It is used just + // before the tree is deleted. + clearActiveDesc: function(treeId) { + this.unmarkActiveDesc_(this.getActiveDescId(treeId)); + delete this.activeDescendantIds_[treeId]; + }, // Make a given node the active descendant of a given tree. setActiveDesc: function(newActiveDescId, treeId) { this.unmarkActiveDesc_(this.getActiveDescId(treeId)); this.markActiveDesc_(newActiveDescId); this.activeDescendantIds_[treeId] = newActiveDescId; }, + getTreeIdForBlock: function(blockId) { + // Walk up the DOM until we get to the root node of the tree. + var domNode = document.getElementById(blockId + 'blockRoot'); + while (!domNode.classList.contains('blocklyTree')) { + domNode = domNode.parentNode; + } + return domNode.id; + }, onWorkspaceToolbarKeypress: function(e, treeId) { if (e.keyCode == 9) { // Tab key. diff --git a/accessible/workspace-tree.component.js b/accessible/workspace-tree.component.js index c27835b29..91c4c3a67 100644 --- a/accessible/workspace-tree.component.js +++ b/accessible/workspace-tree.component.js @@ -122,6 +122,8 @@ blocklyApp.WorkspaceTreeComponent = ng.core if (this.isIsolatedTopLevelBlock_(block)) { var nextNodeToFocusOn = this.treeService.getNodeToFocusOnWhenTreeIsDeleted(this.tree.id); + + this.treeService.clearActiveDesc(this.tree.id); deleteBlockFunc(); nextNodeToFocusOn.focus(); } else { @@ -165,14 +167,30 @@ blocklyApp.WorkspaceTreeComponent = ng.core }, this.tree.id); }, moveToMarkedSpot_: function() { - this.clipboardService.pasteToMarkedConnection(this.block, false); + // This involves three steps: + // - Put the block on the destination tree. + // - Remove the block from the source tree, while preserving the + // screenreader focus for that tree. + // - Change the current tree-level focus to the destination tree, and the + // screenreader focus for the destination tree to the block just moved. + var blockDescription = this.block.toString(); + + var newBlockId = this.clipboardService.pasteToMarkedConnection( + this.block, false); var that = this; this.removeBlockAndSetFocus_(this.block, function() { that.block.dispose(true); }); - alert('Block moved to marked spot: ' + this.block.toString()); + setTimeout(function() { + var destinationTreeId = that.treeService.getTreeIdForBlock(newBlockId); + document.getElementById(destinationTreeId).focus(); + that.treeService.setActiveDesc( + newBlockId + 'blockRoot', destinationTreeId); + + alert('Block moved to marked spot: ' + blockDescription); + }); }, ngOnInit: function() { var that = this; diff --git a/demos/accessible/index.html b/demos/accessible/index.html index a87b540f6..fecdbdfa1 100644 --- a/demos/accessible/index.html +++ b/demos/accessible/index.html @@ -40,6 +40,10 @@ font-weight: normal; font-size: 140%; } + + *:focus { + background: yellow; + }