mirror of
https://github.com/google/blockly.git
synced 2026-01-31 12:40:09 +01:00
Delete the on-screen toolbox.
This commit is contained in:
@@ -36,20 +36,17 @@ blocklyApp.AppView = ng.core.Component({
|
||||
<blockly-toolbox-modal></blockly-toolbox-modal>
|
||||
|
||||
<div>
|
||||
<blockly-toolbox></blockly-toolbox>
|
||||
<blockly-workspace></blockly-workspace>
|
||||
<blockly-sidebar></blockly-sidebar>
|
||||
</div>
|
||||
|
||||
<label aria-hidden="true" hidden id="blockly-button">{{'BUTTON'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-more-options">{{'MORE_OPTIONS'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-toolbox-block">{{'TOOLBOX_BLOCK'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-workspace-block">{{'WORKSPACE_BLOCK'|translate}}</label>
|
||||
`,
|
||||
directives: [
|
||||
blocklyApp.ToolboxComponent, blocklyApp.WorkspaceComponent,
|
||||
blocklyApp.BlockOptionsModalComponent, blocklyApp.SidebarComponent,
|
||||
blocklyApp.ToolboxModalComponent],
|
||||
blocklyApp.WorkspaceComponent, blocklyApp.BlockOptionsModalComponent,
|
||||
blocklyApp.SidebarComponent, blocklyApp.ToolboxModalComponent],
|
||||
pipes: [blocklyApp.TranslatePipe],
|
||||
// All services are declared here, so that all components in the
|
||||
// application use the same instance of the service.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
.blocklyToolboxColumn {
|
||||
float: left;
|
||||
width: 350px;
|
||||
}
|
||||
.blocklyWorkspaceColumn {
|
||||
float: left;
|
||||
width: 350px;
|
||||
width: 700px;
|
||||
}
|
||||
.blocklySidebarColumn {
|
||||
float: left;
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Blockly.Msg.TOOLBOX = 'Toolbox';
|
||||
Blockly.Msg.WORKSPACE = 'Workspace';
|
||||
Blockly.Msg.TOOLBOX_BLOCK = 'toolbox block. Move right to view submenu.';
|
||||
Blockly.Msg.WORKSPACE_BLOCK =
|
||||
'workspace block. Move right to edit. Press Enter for more options.';
|
||||
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component that details how blocks are
|
||||
* rendered in the toolbox in AccessibleBlockly. Also handles any interactions
|
||||
* with the blocks.
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
blocklyApp.ToolboxTreeComponent = ng.core.Component({
|
||||
selector: 'blockly-toolbox-tree',
|
||||
template: `
|
||||
<li [id]="idMap['toolboxBlockRoot']" role="treeitem"
|
||||
[ngClass]="{blocklyHasChildren: displayBlockMenu}"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['toolboxBlockSummary'], 'blockly-toolbox-block')"
|
||||
[attr.aria-level]="level">
|
||||
<label #toolboxBlockSummary [id]="idMap['toolboxBlockSummary']">{{getBlockDescription()}}</label>
|
||||
<ol role="group" *ngIf="displayBlockMenu">
|
||||
<li [id]="idMap['sendToSelected']" role="treeitem" *ngIf="!isWorkspaceEmpty()"
|
||||
[attr.aria-label]="getAriaLabelForCopyToMarkedSpotButton()"
|
||||
[attr.aria-level]="level + 1"
|
||||
[attr.aria-disabled]="!canBeCopiedToMarkedConnection()">
|
||||
<button [id]="idMap['sendToSelectedButton']" (click)="copyToMarkedSpot()"
|
||||
[disabled]="!canBeCopiedToMarkedConnection()" tabindex="-1">
|
||||
{{'COPY_TO_MARKED_SPOT'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
<li [id]="idMap['workspaceCopy']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
|
||||
[attr.aria-level]="level + 1">
|
||||
<button [id]="idMap['workspaceCopyButton']" (click)="copyToWorkspace()" tabindex="-1">
|
||||
{{'COPY_TO_WORKSPACE'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
`,
|
||||
directives: [ng.core.forwardRef(function() {
|
||||
return blocklyApp.ToolboxTreeComponent;
|
||||
})],
|
||||
inputs: [
|
||||
'block', 'displayBlockMenu', 'level', 'tree', 'isFirstToolboxTree'],
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.ClipboardService, blocklyApp.NotificationsService,
|
||||
blocklyApp.TreeService, blocklyApp.UtilsService,
|
||||
function(
|
||||
_clipboardService, _notificationsService,
|
||||
_treeService, _utilsService) {
|
||||
this.clipboardService = _clipboardService;
|
||||
this.notificationsService = _notificationsService;
|
||||
this.treeService = _treeService;
|
||||
this.utilsService = _utilsService;
|
||||
}],
|
||||
ngOnInit: function() {
|
||||
var idKeys = ['toolboxBlockRoot', 'toolboxBlockSummary'];
|
||||
if (this.displayBlockMenu) {
|
||||
idKeys = idKeys.concat([
|
||||
'workspaceCopy', 'workspaceCopyButton', 'sendToSelected',
|
||||
'sendToSelectedButton', 'blockCopy', 'blockCopyButton']);
|
||||
}
|
||||
|
||||
this.idMap = {};
|
||||
for (var i = 0; i < idKeys.length; i++) {
|
||||
this.idMap[idKeys[i]] = this.block.id + idKeys[i];
|
||||
}
|
||||
},
|
||||
ngAfterViewInit: function() {
|
||||
// If this is the first tree in the category-less toolbox, set its active
|
||||
// descendant after the ids have been computed.
|
||||
// Note that a timeout is needed here in order to trigger Angular
|
||||
// change detection.
|
||||
if (this.isFirstToolboxTree) {
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.treeService.setActiveDesc(
|
||||
that.idMap['toolboxBlockRoot'], 'blockly-toolbox-tree');
|
||||
});
|
||||
}
|
||||
},
|
||||
getAriaLabelForCopyToMarkedSpotButton: function() {
|
||||
// TODO(sll): Find a way to make this more like the other buttons.
|
||||
var ariaLabel = 'Attach to link button';
|
||||
if (!this.clipboardService.isAnyConnectionMarked()) {
|
||||
ariaLabel += ', unavailable. Add a link in the workspace first.';
|
||||
}
|
||||
return ariaLabel;
|
||||
},
|
||||
isWorkspaceEmpty: function() {
|
||||
return this.utilsService.isWorkspaceEmpty();
|
||||
},
|
||||
getBlockDescription: function() {
|
||||
return this.utilsService.getBlockDescription(this.block);
|
||||
},
|
||||
generateAriaLabelledByAttr: function(mainLabel, secondLabel) {
|
||||
return this.utilsService.generateAriaLabelledByAttr(
|
||||
mainLabel, secondLabel);
|
||||
},
|
||||
canBeCopiedToMarkedConnection: function() {
|
||||
return this.clipboardService.canBeCopiedToMarkedConnection(this.block);
|
||||
},
|
||||
copyToClipboard: function() {
|
||||
this.clipboardService.copy(this.block);
|
||||
this.notificationsService.setStatusMessage(
|
||||
this.getBlockDescription() + ' ' + Blockly.Msg.COPIED_BLOCK_MSG);
|
||||
},
|
||||
copyToWorkspace: function() {
|
||||
var blockDescription = this.getBlockDescription();
|
||||
var xml = Blockly.Xml.blockToDom(this.block);
|
||||
var newBlockId = Blockly.Xml.domToBlock(blocklyApp.workspace, xml).id;
|
||||
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.treeService.focusOnBlock(newBlockId);
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' added to workspace. ' +
|
||||
'Now on added block in workspace.');
|
||||
});
|
||||
},
|
||||
copyToMarkedSpot: function() {
|
||||
var blockDescription = this.getBlockDescription();
|
||||
// Clean up the active desc for the destination tree.
|
||||
var oldDestinationTreeId = this.treeService.getTreeIdForBlock(
|
||||
this.clipboardService.getMarkedConnectionBlock().id);
|
||||
this.treeService.clearActiveDesc(oldDestinationTreeId);
|
||||
|
||||
var newBlockId = this.clipboardService.pasteToMarkedConnection(
|
||||
this.block);
|
||||
|
||||
// Invoke a digest cycle, so that the DOM settles.
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.treeService.focusOnBlock(newBlockId);
|
||||
|
||||
var newDestinationTreeId = that.treeService.getTreeIdForBlock(
|
||||
newBlockId);
|
||||
if (newDestinationTreeId != oldDestinationTreeId) {
|
||||
// It is possible for the tree ID for the pasted block to change
|
||||
// after the paste operation, e.g. when inserting a block between two
|
||||
// existing blocks that are joined together. In this case, we need to
|
||||
// also reset the active desc for the old destination tree.
|
||||
that.treeService.initActiveDesc(oldDestinationTreeId);
|
||||
}
|
||||
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' connected. ' +
|
||||
'Now on copied block in workspace.');
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,133 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component that details how a toolbox is rendered
|
||||
* in AccessibleBlockly. Also handles any interactions with the toolbox.
|
||||
*
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
blocklyApp.ToolboxComponent = ng.core.Component({
|
||||
selector: 'blockly-toolbox',
|
||||
template: `
|
||||
<div class="blocklyToolboxColumn">
|
||||
<h3 #toolboxTitle id="blockly-toolbox-title">{{'TOOLBOX'|translate}}</h3>
|
||||
<ol #tree
|
||||
id="blockly-toolbox-tree" role="tree" class="blocklyTree"
|
||||
*ngIf="toolboxCategories && toolboxCategories.length > 0"
|
||||
tabindex="0"
|
||||
[attr.aria-labelledby]="toolboxTitle.id"
|
||||
[attr.aria-activedescendant]="getActiveDescId()"
|
||||
(keydown)="treeService.onKeypress($event, tree)">
|
||||
<template [ngIf]="xmlHasCategories">
|
||||
<li #parent
|
||||
[id]="idMap['Parent' + i]" role="treeitem"
|
||||
[ngClass]="{blocklyHasChildren: true, blocklyActiveDescendant: tree.getAttribute('aria-activedescendant') == idMap['Parent' + i]}"
|
||||
*ngFor="#category of toolboxCategories; #i=index"
|
||||
aria-level="0"
|
||||
[attr.aria-label]="getCategoryAriaLabel(category)">
|
||||
<div *ngIf="category && category.attributes">
|
||||
<label [id]="idMap['Label' + i]" #name>
|
||||
{{category.attributes.name.value}}
|
||||
</label>
|
||||
<ol role="group" *ngIf="getToolboxWorkspace(category).topBlocks_.length > 0">
|
||||
<blockly-toolbox-tree *ngFor="#block of getToolboxWorkspace(category).topBlocks_"
|
||||
[level]="1" [block]="block"
|
||||
[displayBlockMenu]="true"
|
||||
[tree]="tree">
|
||||
</blockly-toolbox-tree>
|
||||
</ol>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<div *ngIf="!xmlHasCategories">
|
||||
<blockly-toolbox-tree *ngFor="#block of getToolboxWorkspace(toolboxCategories[0]).topBlocks_; #i=index"
|
||||
role="treeitem" [level]="0" [block]="block"
|
||||
[tree]="tree" [displayBlockMenu]="true"
|
||||
[isFirstToolboxTree]="i === 0">
|
||||
</blockly-toolbox-tree>
|
||||
</div>
|
||||
</ol>
|
||||
</div>
|
||||
`,
|
||||
directives: [blocklyApp.ToolboxTreeComponent],
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.TreeService, blocklyApp.UtilsService,
|
||||
function(_treeService, _utilsService) {
|
||||
this.toolboxCategories = [];
|
||||
this.treeService = _treeService;
|
||||
this.utilsService = _utilsService;
|
||||
|
||||
this.xmlHasCategories = false;
|
||||
}
|
||||
],
|
||||
ngOnInit: function() {
|
||||
// Note that sometimes the toolbox may not have categories; it may
|
||||
// display individual blocks directly (which is often the case in,
|
||||
// e.g., Blockly Games).
|
||||
var xmlToolboxElt = document.getElementById('blockly-toolbox-xml');
|
||||
var xmlCategoryElts = xmlToolboxElt.getElementsByTagName('category');
|
||||
if (xmlCategoryElts.length) {
|
||||
this.xmlHasCategories = true;
|
||||
this.toolboxCategories = Array.from(xmlCategoryElts);
|
||||
|
||||
var elementsNeedingIds = [];
|
||||
for (var i = 0; i < this.toolboxCategories.length; i++) {
|
||||
elementsNeedingIds.push('Parent' + i, 'Label' + i);
|
||||
}
|
||||
this.idMap = this.utilsService.generateIds(elementsNeedingIds);
|
||||
for (var i = 0; i < this.toolboxCategories.length; i++) {
|
||||
this.idMap['Parent' + i] = 'blockly-toolbox-tree-node' + i;
|
||||
}
|
||||
} else {
|
||||
// Create a single category with all the top-level blocks.
|
||||
this.xmlHasCategories = false;
|
||||
this.toolboxCategories = [Array.from(xmlToolboxElt.children)];
|
||||
}
|
||||
},
|
||||
ngAfterViewInit: function() {
|
||||
// If this is a top-level tree in the toolbox, set its active
|
||||
// descendant after the ids have been computed.
|
||||
// Note that a timeout is needed here in order to trigger Angular
|
||||
// change detection.
|
||||
if (this.xmlHasCategories) {
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.treeService.setActiveDesc(
|
||||
'blockly-toolbox-tree-node0', 'blockly-toolbox-tree');
|
||||
});
|
||||
}
|
||||
},
|
||||
getActiveDescId: function() {
|
||||
return this.treeService.getActiveDescId('blockly-toolbox-tree');
|
||||
},
|
||||
getCategoryAriaLabel: function(category) {
|
||||
var numBlocks = this.getToolboxWorkspace(category).topBlocks_.length;
|
||||
return category.attributes.name.value + ' category. ' +
|
||||
'Move right to access ' + numBlocks + ' blocks in this category.';
|
||||
},
|
||||
getToolboxWorkspace: function(categoryNode) {
|
||||
return this.treeService.getToolboxWorkspace(categoryNode);
|
||||
}
|
||||
});
|
||||
@@ -39,12 +39,8 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
this.clipboardService = _clipboardService;
|
||||
this.blockOptionsModalService = _blockOptionsModalService;
|
||||
this.audioService = _audioService;
|
||||
this.toolboxWorkspaces = {};
|
||||
}
|
||||
],
|
||||
getToolboxTreeNode_: function() {
|
||||
return document.getElementById('blockly-toolbox-tree');
|
||||
},
|
||||
// Returns a list of all top-level workspace tree nodes on the page.
|
||||
getWorkspaceTreeNodes_: function() {
|
||||
return Array.from(document.querySelectorAll('ol.blocklyWorkspaceTree'));
|
||||
@@ -52,45 +48,10 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
getSidebarButtonNodes_: function() {
|
||||
return Array.from(document.querySelectorAll('button.blocklySidebarButton'));
|
||||
},
|
||||
getToolboxWorkspace: function(categoryNode) {
|
||||
if (categoryNode.attributes && categoryNode.attributes.name) {
|
||||
var categoryName = categoryNode.attributes.name.value;
|
||||
} else {
|
||||
var categoryName = 'no-category';
|
||||
}
|
||||
|
||||
if (this.toolboxWorkspaces.hasOwnProperty(categoryName)) {
|
||||
return this.toolboxWorkspaces[categoryName];
|
||||
} else {
|
||||
var categoryWorkspace = new Blockly.Workspace();
|
||||
if (categoryName == 'no-category') {
|
||||
for (var i = 0; i < categoryNode.length; i++) {
|
||||
Blockly.Xml.domToBlock(categoryWorkspace, categoryNode[i]);
|
||||
}
|
||||
} else {
|
||||
Blockly.Xml.domToWorkspace(categoryNode, categoryWorkspace);
|
||||
}
|
||||
|
||||
this.toolboxWorkspaces[categoryName] = categoryWorkspace;
|
||||
return this.toolboxWorkspaces[categoryName];
|
||||
}
|
||||
},
|
||||
getToolboxBlockById: function(blockId) {
|
||||
for (var categoryName in this.toolboxWorkspaces) {
|
||||
var putativeBlock = this.utilsService.getBlockByIdFromWorkspace(
|
||||
blockId, this.toolboxWorkspaces[categoryName]);
|
||||
if (putativeBlock) {
|
||||
return putativeBlock;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
// Returns a list of all top-level tree nodes on the page.
|
||||
getAllTreeNodes_: function() {
|
||||
var treeNodes = [this.getToolboxTreeNode_()];
|
||||
treeNodes = treeNodes.concat(this.getWorkspaceTreeNodes_());
|
||||
treeNodes = treeNodes.concat(this.getSidebarButtonNodes_());
|
||||
return treeNodes;
|
||||
return this.getWorkspaceTreeNodes_().concat(
|
||||
this.getSidebarButtonNodes_());
|
||||
},
|
||||
isTopLevelWorkspaceTree: function(treeId) {
|
||||
return this.getWorkspaceTreeNodes_().some(function(tree) {
|
||||
@@ -99,20 +60,15 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
},
|
||||
getNodeToFocusOnWhenTreeIsDeleted: function(deletedTreeId) {
|
||||
// This returns the node to focus on after the deletion happens.
|
||||
// We shift focus to the next tree (if it exists), otherwise we shift
|
||||
// focus to the previous tree.
|
||||
// We shift focus to the next tree (which may be a button in the sidebar).
|
||||
var trees = this.getAllTreeNodes_();
|
||||
for (var i = 0; i < trees.length; i++) {
|
||||
if (trees[i].id == deletedTreeId) {
|
||||
if (i + 1 < trees.length) {
|
||||
return trees[i + 1];
|
||||
} else if (i > 0) {
|
||||
return trees[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.getToolboxTreeNode_();
|
||||
},
|
||||
focusOnCurrentTree_: function(treeId) {
|
||||
var trees = this.getAllTreeNodes_();
|
||||
@@ -268,16 +224,12 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
console.error('Could not handle deletion of block.' + blockRootNode);
|
||||
},
|
||||
notifyUserAboutCurrentTree_: function(treeId) {
|
||||
if (this.getToolboxTreeNode_().id == treeId) {
|
||||
this.notificationsService.setStatusMessage('Now in toolbox.');
|
||||
} else {
|
||||
var workspaceTreeNodes = this.getWorkspaceTreeNodes_();
|
||||
for (var i = 0; i < workspaceTreeNodes.length; i++) {
|
||||
if (workspaceTreeNodes[i].id == treeId) {
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Now in workspace group ' + (i + 1) + ' of ' +
|
||||
workspaceTreeNodes.length);
|
||||
}
|
||||
var workspaceTreeNodes = this.getWorkspaceTreeNodes_();
|
||||
for (var i = 0; i < workspaceTreeNodes.length; i++) {
|
||||
if (workspaceTreeNodes[i].id == treeId) {
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Now in workspace group ' + (i + 1) + ' of ' +
|
||||
workspaceTreeNodes.length);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -444,26 +396,24 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
that.focusOnBlock(block.id);
|
||||
});
|
||||
},
|
||||
getBlockRootSuffix_: function(inToolbox) {
|
||||
return inToolbox ? 'toolboxBlockRoot' : 'blockRoot';
|
||||
getBlockRootSuffix_: function() {
|
||||
return 'blockRoot';
|
||||
},
|
||||
getCurrentBlockRootNode_: function(inToolbox, activeDesc) {
|
||||
getCurrentBlockRootNode_: function(activeDesc) {
|
||||
// Starting from the activeDesc, walk up the tree until we find the
|
||||
// root of the current block.
|
||||
var blockRootSuffix = this.getBlockRootSuffix_(inToolbox);
|
||||
var blockRootSuffix = this.getBlockRootSuffix_();
|
||||
var putativeBlockRootNode = activeDesc;
|
||||
while (putativeBlockRootNode.id.indexOf(blockRootSuffix) === -1) {
|
||||
putativeBlockRootNode = putativeBlockRootNode.parentNode;
|
||||
}
|
||||
return putativeBlockRootNode;
|
||||
},
|
||||
getBlockFromRootNode_: function(inToolbox, blockRootNode) {
|
||||
var blockRootSuffix = this.getBlockRootSuffix_(inToolbox);
|
||||
getBlockFromRootNode_: function(blockRootNode) {
|
||||
var blockRootSuffix = this.getBlockRootSuffix_();
|
||||
var blockId = blockRootNode.id.substring(
|
||||
0, blockRootNode.id.length - blockRootSuffix.length);
|
||||
return inToolbox ?
|
||||
this.getToolboxBlockById(blockId) :
|
||||
this.utilsService.getBlockById(blockId);
|
||||
return this.utilsService.getBlockById(blockId);
|
||||
},
|
||||
onKeypress: function(e, tree) {
|
||||
// TODO(sll): Instead of this, have a common ActiveContextService which
|
||||
@@ -485,36 +435,15 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
// Scout up the tree to see whether we're in the toolbox or workspace.
|
||||
var scoutNode = activeDesc;
|
||||
var TARGET_TAG_NAMES = ['BLOCKLY-TOOLBOX', 'BLOCKLY-WORKSPACE'];
|
||||
while (TARGET_TAG_NAMES.indexOf(scoutNode.tagName) === -1) {
|
||||
scoutNode = scoutNode.parentNode;
|
||||
}
|
||||
var inToolbox = (scoutNode.tagName == 'BLOCKLY-TOOLBOX');
|
||||
|
||||
if (e.ctrlKey) {
|
||||
// Disallow cutting and pasting in the toolbox.
|
||||
if (inToolbox && e.keyCode != 67) {
|
||||
if (e.keyCode == 86) {
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Cannot paste block in toolbox.');
|
||||
} else if (e.keyCode == 88) {
|
||||
this.notificationsService.setStatusMessage(
|
||||
'Cannot cut block in toolbox. Try copying instead.');
|
||||
}
|
||||
}
|
||||
|
||||
var blockRootNode = this.getCurrentBlockRootNode_(
|
||||
inToolbox, activeDesc);
|
||||
var block = this.getBlockFromRootNode_(inToolbox, blockRootNode);
|
||||
var blockRootNode = this.getCurrentBlockRootNode_(activeDesc);
|
||||
var block = this.getBlockFromRootNode_(blockRootNode);
|
||||
|
||||
if (e.keyCode == 88) {
|
||||
// Cut block.
|
||||
this.cutBlock_(block, blockRootNode);
|
||||
} else if (e.keyCode == 67) {
|
||||
// Copy block. Note that, in this case, we might be in the workspace
|
||||
// or toolbox.
|
||||
// Copy block.
|
||||
this.copyBlock_(block);
|
||||
} else if (e.keyCode == 86) {
|
||||
// Paste block, if possible.
|
||||
@@ -582,10 +511,9 @@ blocklyApp.TreeService = ng.core.Class({
|
||||
|
||||
// If we cannot find a field to interact with, we open the modal for
|
||||
// the current block instead.
|
||||
if (!found && !inToolbox) {
|
||||
var blockRootNode = this.getCurrentBlockRootNode_(
|
||||
false, activeDesc);
|
||||
var block = this.getBlockFromRootNode_(false, blockRootNode);
|
||||
if (!found) {
|
||||
var blockRootNode = this.getCurrentBlockRootNode_(activeDesc);
|
||||
var block = this.getBlockFromRootNode_(blockRootNode);
|
||||
|
||||
e.stopPropagation();
|
||||
this.showBlockOptionsModal(block, blockRootNode);
|
||||
|
||||
@@ -67,11 +67,6 @@ blocklyApp.UtilsService = ng.core.Class({
|
||||
return !blocklyApp.workspace.topBlocks_.length;
|
||||
},
|
||||
getBlockById: function(blockId) {
|
||||
return this.getBlockByIdFromWorkspace(blockId, blocklyApp.workspace);
|
||||
},
|
||||
getBlockByIdFromWorkspace: function(blockId, workspace) {
|
||||
// This is used for non-default workspaces, such as those comprising the
|
||||
// toolbox.
|
||||
return workspace.getBlockById(blockId);
|
||||
return blocklyApp.workspace.getBlockById(blockId);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
<script src="../../accessible/field-segment.component.js"></script>
|
||||
<script src="../../accessible/block-options-modal.component.js"></script>
|
||||
<script src="../../accessible/toolbox-modal.component.js"></script>
|
||||
<script src="../../accessible/toolbox-tree.component.js"></script>
|
||||
<script src="../../accessible/toolbox.component.js"></script>
|
||||
<script src="../../accessible/sidebar.component.js"></script>
|
||||
<script src="../../accessible/workspace-tree.component.js"></script>
|
||||
<script src="../../accessible/workspace.component.js"></script>
|
||||
@@ -60,13 +58,16 @@
|
||||
<a href="../index.html">Demos</a> > Accessible Blockly
|
||||
</h1>
|
||||
|
||||
<p>This is a simple demo of a version of Blockly designed for screen readers.</p>
|
||||
|
||||
<p>
|
||||
In Blockly, you can move blocks from the toolbox to the workspace and join
|
||||
them to create programs. To navigate between components, use Tab or
|
||||
Shift-Tab. When you're on a block, move right to access its submenus, and
|
||||
move up or down to go to the next or previous block in the sequence.
|
||||
This is a demo of a version of Blockly designed for screen readers. It
|
||||
allows users to create programs in a workspace by manipulating groups of
|
||||
blocks.
|
||||
<ul>
|
||||
<li>To explore a group of blocks, use the arrow keys.</li>
|
||||
<li>To navigate between groups, use Tab or Shift-Tab.</li>
|
||||
<li>To add new blocks, use the buttons in the menu on the right.</li>
|
||||
<li>To delete or add links to existing blocks, press Enter while you're on that block.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<!--
|
||||
|
||||
Reference in New Issue
Block a user