diff --git a/accessible/field-segment.component.js b/accessible/field-segment.component.js index 85572e89b..e42ab9f60 100644 --- a/accessible/field-segment.component.js +++ b/accessible/field-segment.component.js @@ -66,11 +66,8 @@ blocklyApp.FieldSegmentComponent = ng.core.Component({ }) .Class({ constructor: [ - blocklyApp.NotificationsService, blocklyApp.UtilsService, - function(_notificationsService, _utilsService) { - this.notificationsService = _notificationsService; - this.utilsService = _utilsService; - + blocklyApp.NotificationsService, function(notificationsService) { + this.notificationsService = notificationsService; this.dropdownOptions = []; }], ngOnInit: function() { diff --git a/accessible/messages.js b/accessible/messages.js index e20c40c99..60c51d344 100644 --- a/accessible/messages.js +++ b/accessible/messages.js @@ -31,6 +31,7 @@ Blockly.Msg.WORKSPACE_BLOCK = Blockly.Msg.ATTACH_NEW_BLOCK_TO_LINK = 'Attach new block to link...'; Blockly.Msg.CREATE_NEW_BLOCK_GROUP = 'Create new block group...'; Blockly.Msg.ERASE_WORKSPACE = 'Erase Workspace'; +Blockly.Msg.NO_BLOCKS_IN_WORKSPACE = 'There are no blocks in the workspace.'; Blockly.Msg.COPY_BLOCK = 'Copy block'; Blockly.Msg.DELETE = 'Delete block'; diff --git a/accessible/toolbox-modal.service.js b/accessible/toolbox-modal.service.js index 162e96696..4103309f0 100644 --- a/accessible/toolbox-modal.service.js +++ b/accessible/toolbox-modal.service.js @@ -58,11 +58,11 @@ blocklyApp.ToolboxModalService = ng.core.Class({ if (toolboxCategoryElts.length) { this.allToolboxCategories = Array.from(toolboxCategoryElts).map( function(categoryElt) { - var workspace = new Blockly.Workspace(); - Blockly.Xml.domToWorkspace(categoryElt, workspace); + var tmpWorkspace = new Blockly.Workspace(); + Blockly.Xml.domToWorkspace(categoryElt, tmpWorkspace); return { categoryName: categoryElt.attributes.name.value, - blocks: workspace.topBlocks_ + blocks: tmpWorkspace.topBlocks_ }; } ); @@ -74,14 +74,14 @@ blocklyApp.ToolboxModalService = ng.core.Class({ setTimeout(function() { // If there are no top-level categories, we create a single category // containing all the top-level blocks. - var workspace = new Blockly.Workspace(); + var tmpWorkspace = new Blockly.Workspace(); Array.from(toolboxXmlElt.children).forEach(function(topLevelNode) { - Blockly.Xml.domToBlock(workspace, topLevelNode); + Blockly.Xml.domToBlock(tmpWorkspace, topLevelNode); }); that.allToolboxCategories = [{ categoryName: '', - blocks: workspace.topBlocks_ + blocks: tmpWorkspace.topBlocks_ }]; that.computeCategoriesForCreateNewGroupModal_(); diff --git a/accessible/tree.service.js b/accessible/tree.service.js index c4d37913e..db047c375 100644 --- a/accessible/tree.service.js +++ b/accessible/tree.service.js @@ -426,24 +426,6 @@ blocklyApp.TreeService = ng.core.Class({ this.audioService.playOopsSound(); } }, - // Notify the user about the tree they'll land on, if it's within the - // workspace or sidebar. - notifyUserAboutTabDestination_: function(sourceTreeId, shiftKeyIsPressed) { - var targetId = shiftKeyIsPressed ? - this.getPreviousFocusTargetId_(sourceTreeId) : - this.getNextFocusTargetId_(sourceTreeId); - if (targetId) { - var workspaceFocusTargets = this.getWorkspaceFocusTargets_(); - for (var i = 0; i < workspaceFocusTargets.length; i++) { - if (workspaceFocusTargets[i].id == targetId) { - this.notificationsService.speak( - 'Now in workspace group ' + (i + 1) + ' of ' + - workspaceFocusTargets.length); - return; - } - } - } - }, onKeypress: function(e, tree) { // TODO(sll): Instead of this, have a common ActiveContextService which // returns true if at least one modal is shown, and false otherwise. @@ -470,10 +452,8 @@ blocklyApp.TreeService = ng.core.Class({ // Return the focus to the workspace tree containing the input field. document.getElementById(treeId).focus(); - if (e.keyCode == 9) { - // Allow Tab events to propagate through. - this.notifyUserAboutTabDestination_(treeId, e.shiftKey); - } else if (e.keyCode == 27) { + // Note that Tab events are allowed to propagate through. + if (e.keyCode == 27) { e.preventDefault(); e.stopPropagation(); } @@ -528,7 +508,6 @@ blocklyApp.TreeService = ng.core.Class({ } } else if (e.keyCode == 9) { // Tab key. The event is allowed to propagate through. - this.notifyUserAboutTabDestination_(treeId, e.shiftKey); } else if ([27, 35, 36, 37, 38, 39, 40].indexOf(e.keyCode) !== -1) { if (e.keyCode == 27 || e.keyCode == 37) { // Esc or left arrow key. Go up a level, if possible. diff --git a/accessible/utils.service.js b/accessible/utils.service.js index 98316106e..5fe565ea5 100644 --- a/accessible/utils.service.js +++ b/accessible/utils.service.js @@ -18,9 +18,9 @@ */ /** - * @fileoverview Angular2 utility service for multiple components. All - * functions in this service should be stateless, since this is a singleton - * service that is used for the entire application. + * @fileoverview Angular2 utility service for multiple components. This is a + * singleton service that is used for the entire application. In general, it + * should only be used as a stateless adapter for native Blockly functions. * * @author madeeha@google.com (Madeeha Ghori) */ @@ -30,19 +30,6 @@ blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN = 'blocklyEmptyWorkspaceBtn'; blocklyApp.UtilsService = ng.core.Class({ constructor: [function() {}], - generateUniqueId: function() { - return 'blockly-' + Blockly.utils.genUid(); - }, - generateIds: function(elementsList) { - var idMap = {}; - for (var i = 0; i < elementsList.length; i++){ - idMap[elementsList[i]] = this.generateUniqueId(); - } - return idMap; - }, - generateAriaLabelledByAttr: function(mainLabel, secondLabel) { - return mainLabel + (secondLabel ? ' ' + secondLabel : ''); - }, getBlockDescription: function(block) { // We use 'BLANK' instead of the default '?' so that the string is read // out. (By default, screen readers tend to ignore punctuation.) diff --git a/accessible/workspace-block.component.js b/accessible/workspace-block.component.js index 7c8041d9d..70383576a 100644 --- a/accessible/workspace-block.component.js +++ b/accessible/workspace-block.component.js @@ -73,7 +73,7 @@ blocklyApp.WorkspaceBlockComponent = ng.core.Component({ directives: [blocklyApp.FieldSegmentComponent, ng.core.forwardRef(function() { return blocklyApp.WorkspaceBlockComponent; })], - inputs: ['block', 'level', 'tree', 'isTopLevel'], + inputs: ['block', 'level', 'tree'], pipes: [blocklyApp.TranslatePipe] }) .Class({ @@ -176,10 +176,10 @@ blocklyApp.WorkspaceBlockComponent = ng.core.Component({ // Angular change detection.) var that = this; setTimeout(function() { - if (that.tree && that.isTopLevel && !that.tree.id) { - that.tree.id = that.utilsService.generateUniqueId(); + if (that.tree && that.level === 0 && !that.tree.id) { + that.tree.id = 'blockly-' + Blockly.utils.genUid(); } - if (that.tree && that.isTopLevel && + if (that.tree && that.level === 0 && !that.treeService.getActiveDescId(that.tree.id)) { that.treeService.setActiveDesc(that.idMap['blockRoot'], that.tree.id); } @@ -198,8 +198,7 @@ blocklyApp.WorkspaceBlockComponent = ng.core.Component({ } }, generateAriaLabelledByAttr: function(mainLabel, secondLabel) { - return this.utilsService.generateAriaLabelledByAttr( - mainLabel, secondLabel); + return mainLabel + (secondLabel ? ' ' + secondLabel : ''); }, getBlockNeededLabel: function(blockInput) { // The input type name, or 'any' if any official input type qualifies. diff --git a/accessible/workspace.component.js b/accessible/workspace.component.js index ae0b1748c..39d395d0e 100644 --- a/accessible/workspace.component.js +++ b/accessible/workspace.component.js @@ -31,24 +31,24 @@ blocklyApp.WorkspaceComponent = ng.core.Component({

{{'WORKSPACE'|translate}}

-
    - + (focus)="speakLocation(groupIndex, tree.id)"> +

- There are no blocks in the workspace. + {{'NO_BLOCKS_IN_WORKSPACE'|translate}}

@@ -68,8 +68,8 @@ blocklyApp.WorkspaceComponent = ng.core.Component({ this.toolboxModalService = toolboxModalService; this.treeService = treeService; - this.workspace = blocklyApp.workspace; this.ID_FOR_EMPTY_WORKSPACE_BTN = blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN; + this.workspace = blocklyApp.workspace; } ], getActiveDescId: function(treeId) { @@ -82,9 +82,9 @@ blocklyApp.WorkspaceComponent = ng.core.Component({ this.toolboxModalService.showToolboxModalForCreateNewGroup( this.ID_FOR_EMPTY_WORKSPACE_BTN); }, - speakLocation: function(index) { + speakLocation: function(groupIndex, treeId) { this.notificationsService.speak( - 'Now in workspace group ' + (index + 1) + ' of ' + + 'Now in workspace group ' + (groupIndex + 1) + ' of ' + this.workspace.topBlocks_.length); } });