From 664e6dcf7ea947107c723c0637799c18066c24aa Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Mon, 28 Nov 2016 16:34:52 -0800 Subject: [PATCH] Set focus correctly when toolbox modal is dismissed. --- accessible/block-options-modal.component.js | 13 ++++--- accessible/block-options-modal.service.js | 8 ++--- accessible/sidebar.component.js | 21 ++++++++--- accessible/toolbox-modal.component.js | 39 ++++++++++++--------- accessible/toolbox-modal.service.js | 15 +++++--- accessible/workspace.component.js | 7 ++-- 6 files changed, 66 insertions(+), 37 deletions(-) diff --git a/accessible/block-options-modal.component.js b/accessible/block-options-modal.component.js index 0a81f6029..e44c15244 100644 --- a/accessible/block-options-modal.component.js +++ b/accessible/block-options-modal.component.js @@ -64,15 +64,15 @@ blocklyApp.BlockOptionsModalComponent = ng.core.Component({ this.modalIsVisible = false; this.actionButtonsInfo = []; this.activeActionButtonIndex = 0; - this.onCancelCallback = null; + this.onDismissCallback = null; var that = this; this.blockOptionsModalService.registerPreShowHook( - function(newActionButtonsInfo, onCancelCallback) { + function(newActionButtonsInfo, onDismissCallback) { that.modalIsVisible = true; that.actionButtonsInfo = newActionButtonsInfo; that.activeActionButtonIndex = 0; - that.onCancelCallback = onCancelCallback; + that.onDismissCallback = onDismissCallback; that.keyboardInputService.setOverride({ // Tab key: no-op. @@ -83,20 +83,23 @@ blocklyApp.BlockOptionsModalComponent = ng.core.Component({ // Enter key: selects an action, performs it, and closes the // modal. '13': function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var button = document.getElementById( that.getOptionId(that.activeActionButtonIndex)); if (that.activeActionButtonIndex < that.actionButtonsInfo.length) { that.actionButtonsInfo[that.activeActionButtonIndex].action(); } else { - that.onCancelCallback(); + that.onDismissCallback(); } that.hideModal(); }, // Escape key: closes the modal. '27': function() { - that.onCancelCallback(); + that.onDismissCallback(); that.hideModal(); }, // Up key: navigates to the previous item in the list. diff --git a/accessible/block-options-modal.service.js b/accessible/block-options-modal.service.js index 6b77b92bd..82e425c05 100644 --- a/accessible/block-options-modal.service.js +++ b/accessible/block-options-modal.service.js @@ -32,19 +32,19 @@ blocklyApp.BlockOptionsModalService = ng.core.Class({ 'before it can be shown.'); }; this.modalIsShown = false; - this.onCancelCallback = null; + this.onDismissCallback = null; }], registerPreShowHook: function(preShowHook) { this.preShowHook = function() { - preShowHook(this.actionButtonsInfo, this.onCancelCallback); + preShowHook(this.actionButtonsInfo, this.onDismissCallback); }; }, isModalShown: function() { return this.modalIsShown; }, - showModal: function(actionButtonsInfo, onCancelCallback) { + showModal: function(actionButtonsInfo, onDismissCallback) { this.actionButtonsInfo = actionButtonsInfo; - this.onCancelCallback = onCancelCallback; + this.onDismissCallback = onDismissCallback; this.preShowHook(); this.modalIsShown = true; diff --git a/accessible/sidebar.component.js b/accessible/sidebar.component.js index 225195b16..3df591fdd 100644 --- a/accessible/sidebar.component.js +++ b/accessible/sidebar.component.js @@ -37,17 +37,19 @@ blocklyApp.SidebarComponent = ng.core.Component({ {{buttonConfig.text}} - - - @@ -83,11 +83,14 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({ var that = this; this.toolboxModalService.registerPreShowHook( - function(toolboxCategories, isBlockAvailable, onSelectBlockCallback) { + function( + toolboxCategories, isBlockAvailable, onSelectBlockCallback, + onDismissCallback) { that.modalIsVisible = true; that.toolboxCategories = toolboxCategories; that.isBlockAvailable = isBlockAvailable; that.onSelectBlockCallback = onSelectBlockCallback; + that.onDismissCallback = onDismissCallback; var cumulativeIndex = 0; that.toolboxCategories.forEach(function(category) { @@ -107,15 +110,12 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({ // Enter key: selects an action, performs it, and closes the // modal. '13': function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var button = document.getElementById( that.getOptionId(that.activeButtonIndex)); - if (button.disabled) { - evt.preventDefault(); - evt.stopPropagation(); - return; - } - for (var i = 0; i < that.toolboxCategories.length; i++) { if (that.firstBlockIndexes[i + 1] > that.activeButtonIndex) { var categoryIndex = i; @@ -128,11 +128,11 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({ } // The 'Cancel' button has been pressed. - that.hideModal(); + that.dismissModal(); }, // Escape key: closes the modal. '27': function() { - that.hideModal(); + that.dismissModal(); }, // Up key: navigates to the previous item in the list. '38': function(evt) { @@ -163,6 +163,12 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({ ); } ], + // Closes the modal (on both success and failure). + hideModal_: function() { + this.modalIsVisible = false; + this.keyboardInputService.clearOverride(); + this.toolboxModalService.hideModal(); + }, getOverallIndex: function(categoryIndex, blockIndex) { return this.firstBlockIndexes[categoryIndex] + blockIndex; }, @@ -191,12 +197,11 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({ }, selectBlock: function(block) { this.onSelectBlockCallback(block); - this.hideModal(); + this.hideModal_(); }, - // Closes the modal. - hideModal: function() { - this.modalIsVisible = false; - this.keyboardInputService.clearOverride(); - this.toolboxModalService.hideModal(); + // Dismisses and closes the modal. + dismissModal: function() { + this.hideModal_(); + this.onDismissCallback(); } }); diff --git a/accessible/toolbox-modal.service.js b/accessible/toolbox-modal.service.js index 788193872..7b6adbfbf 100644 --- a/accessible/toolbox-modal.service.js +++ b/accessible/toolbox-modal.service.js @@ -39,6 +39,7 @@ blocklyApp.ToolboxModalService = ng.core.Class({ this.isBlockAvailable = null; this.onSelectBlockCallback = null; + this.onDismissCallback = null; this.preShowHook = function() { throw Error( 'A pre-show hook must be defined for the toolbox modal before it ' + @@ -84,15 +85,17 @@ blocklyApp.ToolboxModalService = ng.core.Class({ this.preShowHook = function() { preShowHook( this.toolboxCategories, this.isBlockAvailable, - this.onSelectBlockCallback); + this.onSelectBlockCallback, this.onDismissCallback); }; }, isModalShown: function() { return this.modalIsShown; }, - showModal_: function(isBlockAvailable, onSelectBlockCallback) { + showModal_: function( + isBlockAvailable, onSelectBlockCallback, onDismissCallback) { this.isBlockAvailable = isBlockAvailable; this.onSelectBlockCallback = onSelectBlockCallback; + this.onDismissCallback = onDismissCallback; this.preShowHook(); this.modalIsShown = true; @@ -100,7 +103,7 @@ blocklyApp.ToolboxModalService = ng.core.Class({ hideModal: function() { this.modalIsShown = false; }, - showToolboxModalForAttachToMarkedConnection: function() { + showToolboxModalForAttachToMarkedConnection: function(sourceButtonId) { var that = this; this.showModal_(function(block) { return that.clipboardService.canBeAttachedToMarkedConnection(block); @@ -131,9 +134,11 @@ blocklyApp.ToolboxModalService = ng.core.Class({ blockDescription + ' connected. ' + 'Now on copied block in workspace.'); }); + }, function() { + document.getElementById(sourceButtonId).focus(); }); }, - showToolboxModalForCreateNewGroup: function() { + showToolboxModalForCreateNewGroup: function(sourceButtonId) { var that = this; this.showModal_(function(block) { return true; @@ -148,6 +153,8 @@ blocklyApp.ToolboxModalService = ng.core.Class({ blockDescription + ' added to workspace. ' + 'Now on added block in workspace.'); }); + }, function() { + document.getElementById(sourceButtonId).focus(); }); } }); diff --git a/accessible/workspace.component.js b/accessible/workspace.component.js index 5d658d200..bbc84b9df 100644 --- a/accessible/workspace.component.js +++ b/accessible/workspace.component.js @@ -45,7 +45,7 @@ blocklyApp.WorkspaceComponent = ng.core.Component({ There are no blocks in the workspace.

@@ -63,6 +63,8 @@ blocklyApp.WorkspaceComponent = ng.core.Component({ this.treeService = _treeService; this.toolboxModalService = _toolboxModalService; this.workspace = blocklyApp.workspace; + + this.ID_FOR_EMPTY_WORKSPACE_BTN = 'blocklyEmptyWorkspaceButton'; } ], getActiveDescId: function(treeId) { @@ -72,6 +74,7 @@ blocklyApp.WorkspaceComponent = ng.core.Component({ this.treeService.onKeypress(e, tree); }, showToolboxModalForCreateNewGroup: function() { - this.toolboxModalService.showToolboxModalForCreateNewGroup(); + this.toolboxModalService.showToolboxModalForCreateNewGroup( + this.ID_FOR_EMPTY_WORKSPACE_BTN); } });