mirror of
https://github.com/google/blockly.git
synced 2026-01-05 08:00:09 +01:00
Set focus correctly when toolbox modal is dismissed.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -37,17 +37,19 @@ blocklyApp.SidebarComponent = ng.core.Component({
|
||||
{{buttonConfig.text}}
|
||||
</button>
|
||||
</span>
|
||||
<button (click)="showToolboxModalForAttachToMarkedConnection()"
|
||||
<button id="{{ID_FOR_ATTACH_TO_LINK_BUTTON}}"
|
||||
(click)="showToolboxModalForAttachToMarkedConnection()"
|
||||
[attr.disabled]="isAnyConnectionMarked() ? undefined : 'disabled'"
|
||||
[attr.aria-disabled]="!isAnyConnectionMarked()"
|
||||
class="blocklySidebarButton">
|
||||
Attach new block to link...
|
||||
</button>
|
||||
<button (click)="showToolboxModalForCreateNewGroup()"
|
||||
<button id="{{ID_FOR_CREATE_NEW_GROUP_BUTTON}}"
|
||||
(click)="showToolboxModalForCreateNewGroup()"
|
||||
class="blocklySidebarButton">
|
||||
Create new block group...
|
||||
</button>
|
||||
<button id="clear-workspace" (click)="workspace.clear()"
|
||||
<button id="clear-workspace" (click)="clearWorkspace()"
|
||||
[attr.disabled]="isWorkspaceEmpty() ? 'disabled' : undefined"
|
||||
[attr.aria-disabled]="isWorkspaceEmpty()"
|
||||
class="blocklySidebarButton">
|
||||
@@ -79,6 +81,9 @@ blocklyApp.SidebarComponent = ng.core.Component({
|
||||
this.utilsService = _utilsService;
|
||||
this.toolboxModalService = _toolboxModalService;
|
||||
this.clipboardService = _clipboardService;
|
||||
|
||||
this.ID_FOR_ATTACH_TO_LINK_BUTTON = 'blocklyAttachToLinkBtn';
|
||||
this.ID_FOR_CREATE_NEW_GROUP_BUTTON = 'blocklyCreateNewGroupBtn';
|
||||
}
|
||||
],
|
||||
isAnyConnectionMarked: function() {
|
||||
@@ -91,6 +96,10 @@ blocklyApp.SidebarComponent = ng.core.Component({
|
||||
buttonConfig.onClickNotification);
|
||||
}
|
||||
},
|
||||
clearWorkspace: function() {
|
||||
this.workspace.clear();
|
||||
document.getElementById(this.ID_FOR_CREATE_NEW_GROUP_BUTTON).focus();
|
||||
},
|
||||
onSidebarKeypress: function(e) {
|
||||
this.treeService.onSidebarKeypress(e, document.activeElement.id);
|
||||
},
|
||||
@@ -98,9 +107,11 @@ blocklyApp.SidebarComponent = ng.core.Component({
|
||||
return this.utilsService.isWorkspaceEmpty();
|
||||
},
|
||||
showToolboxModalForAttachToMarkedConnection: function() {
|
||||
this.toolboxModalService.showToolboxModalForAttachToMarkedConnection();
|
||||
this.toolboxModalService.showToolboxModalForAttachToMarkedConnection(
|
||||
this.ID_FOR_ATTACH_TO_LINK_BUTTON);
|
||||
},
|
||||
showToolboxModalForCreateNewGroup: function() {
|
||||
this.toolboxModalService.showToolboxModalForCreateNewGroup();
|
||||
this.toolboxModalService.showToolboxModalForCreateNewGroup(
|
||||
this.ID_FOR_CREATE_NEW_GROUP_BUTTON);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({
|
||||
selector: 'blockly-toolbox-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible" id="toolboxModal" role="dialog" tabindex="-1">
|
||||
<div (click)="hideModal()" class="blocklyModalCurtain">
|
||||
<div (click)="dismissModal()" class="blocklyModalCurtain">
|
||||
<!-- The $event.stopPropagation() here prevents the modal from
|
||||
closing when its interior is clicked. -->
|
||||
<div class="blocklyModal" (click)="$event.stopPropagation()" role="document">
|
||||
@@ -48,7 +48,7 @@ blocklyApp.ToolboxModalComponent = ng.core.Component({
|
||||
</div>
|
||||
<hr>
|
||||
<div class="blocklyModalButtonContainer">
|
||||
<button [id]="getCancelOptionId()" (click)="hideModal()"
|
||||
<button [id]="getCancelOptionId()" (click)="dismissModal()"
|
||||
[ngClass]="{activeButton: activeButtonIndex == totalNumBlocks}">
|
||||
{{'CANCEL'|translate}}
|
||||
</button>
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ blocklyApp.WorkspaceComponent = ng.core.Component({
|
||||
There are no blocks in the workspace.
|
||||
<button (click)="showToolboxModalForCreateNewGroup()"
|
||||
class="blocklyWorkspaceFocusTarget"
|
||||
id="blocklyEmptyWorkspaceButton">
|
||||
id="{{ID_FOR_EMPTY_WORKSPACE_BTN}}">
|
||||
Create new block group...
|
||||
</button>
|
||||
</p>
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user