mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
Remove superfluous menus from toolbox. Use aria live region instead of alerts, and redo the text based on user feedback. Add a simple tutorial at the top of the demo page.
This commit is contained in:
@@ -29,6 +29,9 @@ blocklyApp.AppView = ng.core
|
||||
.Component({
|
||||
selector: 'blockly-app',
|
||||
template: `
|
||||
<div aria-hidden="true">
|
||||
Status: <span aria-live="polite" role="status">{{getStatusMessage()}}</span>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="blocklyTable">
|
||||
@@ -44,21 +47,29 @@ blocklyApp.AppView = ng.core
|
||||
<label aria-hidden="true" hidden id="blockly-argument-input">{{'ARGUMENT_INPUT'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-argument-menu">{{'ARGUMENT_OPTIONS_LIST'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-argument-text">{{'TEXT'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-block-menu">{{'BLOCK_ACTION_LIST'|translate}} {{'FOR'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-block-menu">{{'BLOCK_ACTION_LIST'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-block-summary">{{'BLOCK_SUMMARY'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-submenu-indicator">{{'SUBMENU_INDICATOR'|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>
|
||||
<label aria-hidden="true" hidden id="blockly-button">{{'BUTTON'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-disabled">{{'DISABLED'|translate}}</label>
|
||||
<label aria-hidden="true" hidden id="blockly-menu">{{'OPTION_LIST'|translate}}</label>
|
||||
`,
|
||||
directives: [blocklyApp.ToolboxComponent, blocklyApp.WorkspaceComponent],
|
||||
pipes: [blocklyApp.TranslatePipe],
|
||||
// The clipboard, tree and utils services are declared here, so that all
|
||||
// components in the application use the same instance of the service.
|
||||
// All services are declared here, so that all components in the
|
||||
// application use the same instance of the service.
|
||||
// https://www.sitepoint.com/angular-2-components-providers-classes-factories-values/
|
||||
providers: [
|
||||
blocklyApp.ClipboardService, blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService]
|
||||
blocklyApp.ClipboardService, blocklyApp.NotificationsService,
|
||||
blocklyApp.TreeService, blocklyApp.UtilsService]
|
||||
})
|
||||
.Class({
|
||||
constructor: [function() {}]
|
||||
constructor: [blocklyApp.NotificationsService, function(_notificationsService) {
|
||||
this.notificationsService = _notificationsService;
|
||||
}],
|
||||
getStatusMessage: function() {
|
||||
return this.notificationsService.getStatusMessage();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -24,12 +24,15 @@
|
||||
|
||||
blocklyApp.ClipboardService = ng.core
|
||||
.Class({
|
||||
constructor: [blocklyApp.UtilsService, function(_utilsService) {
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService, blocklyApp.UtilsService,
|
||||
function(_notificationsService, _utilsService) {
|
||||
this.clipboardBlockXml_ = null;
|
||||
this.clipboardBlockPreviousConnection_ = null;
|
||||
this.clipboardBlockNextConnection_ = null;
|
||||
this.clipboardBlockOutputConnection_ = null;
|
||||
this.markedConnection_ = null;
|
||||
this.notificationsService = _notificationsService;
|
||||
this.utilsService = _utilsService;
|
||||
}],
|
||||
areConnectionsCompatible_: function(blockConnection, connection) {
|
||||
@@ -93,23 +96,17 @@ blocklyApp.ClipboardService = ng.core
|
||||
},
|
||||
markConnection: function(connection) {
|
||||
this.markedConnection_ = connection;
|
||||
alert(Blockly.Msg.MARKED_SPOT_MSG);
|
||||
this.notificationsService.setStatusMessage(Blockly.Msg.MARKED_SPOT_MSG);
|
||||
},
|
||||
cut: function(block) {
|
||||
this.copy(block, false);
|
||||
this.copy(block);
|
||||
block.dispose(true);
|
||||
},
|
||||
copy: function(block, announce) {
|
||||
copy: function(block) {
|
||||
this.clipboardBlockXml_ = Blockly.Xml.blockToDom(block);
|
||||
this.clipboardBlockPreviousConnection_ = block.previousConnection;
|
||||
this.clipboardBlockNextConnection_ = block.nextConnection;
|
||||
this.clipboardBlockOutputConnection_ = block.outputConnection;
|
||||
|
||||
if (announce) {
|
||||
alert(
|
||||
Blockly.Msg.COPIED_BLOCK_MSG +
|
||||
this.utilsService.getBlockDescription(block));
|
||||
}
|
||||
},
|
||||
pasteFromClipboard: function(inputConnection) {
|
||||
var connection = inputConnection;
|
||||
@@ -133,9 +130,9 @@ blocklyApp.ClipboardService = ng.core
|
||||
default:
|
||||
connection.connect(reconstitutedBlock.outputConnection);
|
||||
}
|
||||
alert(
|
||||
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG +
|
||||
this.utilsService.getBlockDescription(reconstitutedBlock));
|
||||
this.notificationsService.setStatusMessage(
|
||||
this.utilsService.getBlockDescription(reconstitutedBlock) + ' ' +
|
||||
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG);
|
||||
return reconstitutedBlock.id;
|
||||
},
|
||||
pasteToMarkedConnection: function(block) {
|
||||
|
||||
@@ -62,8 +62,11 @@ Blockly.Msg.FOR = 'for';
|
||||
Blockly.Msg.STATEMENT = 'statement';
|
||||
Blockly.Msg.VALUE = 'value';
|
||||
Blockly.Msg.CUT_BLOCK_MSG = 'Cut block: ';
|
||||
Blockly.Msg.COPIED_BLOCK_MSG = 'Copied block to clipboard: ';
|
||||
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG = 'Pasted block from clipboard: ';
|
||||
Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG = 'Pasted block to marked spot: ';
|
||||
Blockly.Msg.COPIED_BLOCK_MSG = 'copied';
|
||||
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG = 'pasted';
|
||||
Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG = 'moved to marked spot';
|
||||
Blockly.Msg.MARKED_SPOT_MSG = 'Marked spot';
|
||||
Blockly.Msg.BLOCK_MOVED_TO_MARKED_SPOT_MSB = 'Block moved to marked spot: ';
|
||||
Blockly.Msg.TOOLBOX_BLOCK = 'toolbox block';
|
||||
Blockly.Msg.WORKSPACE_BLOCK = 'workspace block';
|
||||
Blockly.Msg.SUBMENU_INDICATOR = 'move right to view submenu';
|
||||
|
||||
44
accessible/notifications.service.js
Normal file
44
accessible/notifications.service.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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 Service that notifies the user about actions that
|
||||
* they have taken, by updating an ARIA live region.
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
blocklyApp.NotificationsService = ng.core
|
||||
.Class({
|
||||
constructor: [function() {
|
||||
this.statusMessage_ = '';
|
||||
}],
|
||||
getStatusMessage: function() {
|
||||
return this.statusMessage_;
|
||||
},
|
||||
setStatusMessage: function(newMessage) {
|
||||
// Introduce a temporary status message, so that if, e.g., two "copy"
|
||||
// operations are done in succession, both messages will be read.
|
||||
this.statusMessage_ = '';
|
||||
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.statusMessage_ = newMessage;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -30,39 +30,31 @@ blocklyApp.ToolboxTreeComponent = ng.core
|
||||
template: `
|
||||
<li #parentList [id]="idMap['parentList']" role="treeitem"
|
||||
[ngClass]="{blocklyHasChildren: displayBlockMenu, blocklyActiveDescendant: index == 0 && noCategories}"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummaryLabel'])"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockSummaryLabel'], 'blockly-toolbox-block')"
|
||||
[attr.aria-level]="level">
|
||||
<label #blockSummaryLabel [id]="idMap['blockSummaryLabel']">{{getBlockDescription()}}</label>
|
||||
<ol role="group" *ngIf="displayBlockMenu">
|
||||
<li #listItem class="blocklyHasChildren" [id]="idMap['listItem']"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', idMap['blockSummaryLabel'])"
|
||||
*ngIf="displayBlockMenu" role="treeitem"
|
||||
[attr.aria-level]="level + 1">
|
||||
<label #label [id]="idMap['label']">{{'BLOCK_ACTION_LIST'|translate}}</label>
|
||||
<ol role="group" *ngIf="displayBlockMenu">
|
||||
<li [id]="idMap['workspaceCopy']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['workspaceCopyButton']" (click)="copyToWorkspace()">
|
||||
{{'COPY_TO_WORKSPACE'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
<li [id]="idMap['blockCopy']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockCopyButton'], 'blockly-button')"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['blockCopyButton']" (click)="copyToClipboard()">
|
||||
{{'COPY_TO_CLIPBOARD'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
<li [id]="idMap['sendToSelected']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', !canBeCopiedToMarkedConnection())"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['sendToSelectedButton']" (click)="copyToMarkedSpot()"
|
||||
[disabled]="!canBeCopiedToMarkedConnection()">
|
||||
{{'COPY_TO_MARKED_SPOT'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
</ol>
|
||||
<li [id]="idMap['workspaceCopy']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['workspaceCopyButton']" (click)="copyToWorkspace()">
|
||||
{{'COPY_TO_WORKSPACE'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
<li [id]="idMap['blockCopy']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockCopyButton'], 'blockly-button')"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['blockCopyButton']" (click)="copyToClipboard()">
|
||||
{{'COPY_TO_CLIPBOARD'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
<li [id]="idMap['sendToSelected']" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', !canBeCopiedToMarkedConnection())"
|
||||
[attr.aria-level]="level + 2">
|
||||
<button [id]="idMap['sendToSelectedButton']" (click)="copyToMarkedSpot()"
|
||||
[disabled]="!canBeCopiedToMarkedConnection()">
|
||||
{{'COPY_TO_MARKED_SPOT'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
@@ -82,19 +74,20 @@ blocklyApp.ToolboxTreeComponent = ng.core
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.ClipboardService, blocklyApp.TreeService, blocklyApp.UtilsService,
|
||||
function(_clipboardService, _treeService, _utilsService) {
|
||||
// ClipboardService and UtilsService are app-wide singleton services.
|
||||
// TreeService is from the parent ToolboxComponent.
|
||||
this.infoBlocks = Object.create(null);
|
||||
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 elementsNeedingIds = ['blockSummaryLabel'];
|
||||
if (this.displayBlockMenu) {
|
||||
elementsNeedingIds = elementsNeedingIds.concat(['listItem', 'label',
|
||||
elementsNeedingIds = elementsNeedingIds.concat(['blockSummarylabel',
|
||||
'workspaceCopy', 'workspaceCopyButton', 'blockCopy',
|
||||
'blockCopyButton', 'sendToSelected', 'sendToSelectedButton']);
|
||||
}
|
||||
@@ -123,11 +116,15 @@ blocklyApp.ToolboxTreeComponent = ng.core
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.treeService.focusOnBlock(newBlockId);
|
||||
alert('Added block to workspace: ' + blockDescription);
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' copied to workspace. ' +
|
||||
'Now on copied block in workspace.');
|
||||
});
|
||||
},
|
||||
copyToClipboard: function() {
|
||||
this.clipboardService.copy(this.block, true);
|
||||
this.clipboardService.copy(this.block);
|
||||
this.notificationsService.setStatusMessage(
|
||||
this.getBlockDescription() + ' ' + Blockly.Msg.COPIED_BLOCK_MSG);
|
||||
},
|
||||
copyToMarkedSpot: function() {
|
||||
var blockDescription = this.getBlockDescription();
|
||||
@@ -154,7 +151,9 @@ blocklyApp.ToolboxTreeComponent = ng.core
|
||||
that.treeService.initActiveDesc(oldDestinationTreeId);
|
||||
}
|
||||
|
||||
alert('Block copied to marked spot: ' + blockDescription);
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' copied to marked spot. ' +
|
||||
'Now on copied block in workspace.');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ blocklyApp.ToolboxComponent = ng.core
|
||||
[ngClass]="{blocklyHasChildren: true, blocklyActiveDescendant: tree.getAttribute('aria-activedescendant') == idMap['Parent' + i]}"
|
||||
*ngFor="#category of toolboxCategories; #i=index"
|
||||
aria-level="1"
|
||||
[attr.aria-label]="getCategoryAriaLabel(category.attributes.name.value)">
|
||||
[attr.aria-label]="getCategoryAriaLabel(category)">
|
||||
<div *ngIf="category && category.attributes">
|
||||
<label [id]="idMap['Label' + i]" #name>
|
||||
{{category.attributes.name.value}}
|
||||
@@ -119,8 +119,10 @@ blocklyApp.ToolboxComponent = ng.core
|
||||
getActiveDescId: function() {
|
||||
return this.treeService.getActiveDescId('blockly-toolbox-tree');
|
||||
},
|
||||
getCategoryAriaLabel: function(categoryName) {
|
||||
return categoryName + ' category';
|
||||
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) {
|
||||
if (categoryNode.attributes && categoryNode.attributes.name) {
|
||||
|
||||
@@ -67,5 +67,8 @@ blocklyApp.UtilsService = ng.core
|
||||
// We use 'BLANK' instead of the default '?' so that the string is read
|
||||
// out. (By default, screen readers tend to ignore punctuation.)
|
||||
return block.toString(undefined, 'BLANK');
|
||||
},
|
||||
isWorkspaceEmpty: function() {
|
||||
return !blocklyApp.workspace.topBlocks_.length;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,13 +29,13 @@ blocklyApp.WorkspaceTreeComponent = ng.core
|
||||
selector: 'blockly-workspace-tree',
|
||||
template: `
|
||||
<li [id]="idMap['blockRoot']" role="treeitem" class="blocklyHasChildren"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummary'])"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockSummary'], 'blockly-workspace-block')"
|
||||
[attr.aria-level]="level">
|
||||
<label [id]="idMap['blockSummary']">{{getBlockDescription()}}</label>
|
||||
|
||||
<ol role="group">
|
||||
<li [id]="idMap['listItem']" class="blocklyHasChildren" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', idMap['blockSummary'])"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', 'blockly-submenu-indicator')"
|
||||
[attr.aria-level]="level + 1">
|
||||
<label [id]="idMap['label']">{{'BLOCK_ACTION_LIST'|translate}}</label>
|
||||
<ol role="group">
|
||||
@@ -100,11 +100,13 @@ blocklyApp.WorkspaceTreeComponent = ng.core
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.ClipboardService, blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService,
|
||||
function(_clipboardService, _treeService, _utilsService) {
|
||||
this.infoBlocks = Object.create(null);
|
||||
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;
|
||||
}],
|
||||
@@ -154,7 +156,15 @@ blocklyApp.WorkspaceTreeComponent = ng.core
|
||||
that.clipboardService.cut(that.block);
|
||||
});
|
||||
|
||||
alert(Blockly.Msg.CUT_BLOCK_MSG + blockDescription);
|
||||
setTimeout(function() {
|
||||
if (that.utilsService.isWorkspaceEmpty()) {
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' cut. Workspace is empty.');
|
||||
} else {
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' cut. Now on workspace.');
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteBlock_: function() {
|
||||
var blockDescription = this.getBlockDescription();
|
||||
@@ -164,7 +174,15 @@ blocklyApp.WorkspaceTreeComponent = ng.core
|
||||
that.block.dispose(true);
|
||||
});
|
||||
|
||||
alert('Block deleted: ' + blockDescription);
|
||||
setTimeout(function() {
|
||||
if (that.utilsService.isWorkspaceEmpty()) {
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' deleted. Workspace is empty.');
|
||||
} else {
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' deleted. Now on workspace.');
|
||||
}
|
||||
});
|
||||
},
|
||||
pasteToConnection_: function(connection) {
|
||||
var destinationTreeId = this.treeService.getTreeIdForBlock(
|
||||
@@ -207,11 +225,16 @@ blocklyApp.WorkspaceTreeComponent = ng.core
|
||||
that.treeService.initActiveDesc(oldDestinationTreeId);
|
||||
}
|
||||
|
||||
alert('Block moved to marked spot: ' + blockDescription);
|
||||
that.notificationsService.setStatusMessage(
|
||||
blockDescription + ' ' +
|
||||
Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG +
|
||||
'. Now on moved block in workspace.');
|
||||
});
|
||||
},
|
||||
copyBlock_: function() {
|
||||
this.clipboardService.copy(this.block, true);
|
||||
this.clipboardService.copy(this.block);
|
||||
this.notificationsService.setStatusMessage(
|
||||
this.getBlockDescription() + ' ' + Blockly.Msg.COPIED_BLOCK_MSG);
|
||||
},
|
||||
markSpotBelow_: function() {
|
||||
this.clipboardService.markConnection(this.block.nextConnection);
|
||||
|
||||
@@ -60,7 +60,9 @@ blocklyApp.WorkspaceComponent = ng.core
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [blocklyApp.TreeService, function(_treeService) {
|
||||
constructor: [
|
||||
blocklyApp.TreeService, blocklyApp.UtilsService,
|
||||
function(_treeService, _utilsService) {
|
||||
// ACCESSIBLE_GLOBALS is a global variable defined by the containing
|
||||
// page. It should contain a key, toolbarButtonConfig, whose
|
||||
// corresponding value is an Array with two keys: 'text' and 'action'.
|
||||
@@ -71,6 +73,7 @@ blocklyApp.WorkspaceComponent = ng.core
|
||||
ACCESSIBLE_GLOBALS.toolbarButtonConfig : [];
|
||||
this.workspace = blocklyApp.workspace;
|
||||
this.treeService = _treeService;
|
||||
this.utilsService = _utilsService;
|
||||
}],
|
||||
clearWorkspace: function() {
|
||||
this.workspace.clear();
|
||||
@@ -86,6 +89,6 @@ blocklyApp.WorkspaceComponent = ng.core
|
||||
this.treeService.onKeypress(e, tree);
|
||||
},
|
||||
isWorkspaceEmpty: function() {
|
||||
return !this.workspace.topBlocks_.length;
|
||||
return this.utilsService.isWorkspaceEmpty();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<script src="../../accessible/libs/angular2-all.umd.min.js"></script>
|
||||
|
||||
<script src="../../accessible/utils.service.js"></script>
|
||||
<script src="../../accessible/notifications.service.js"></script>
|
||||
<script src="../../accessible/clipboard.service.js"></script>
|
||||
<script src="../../accessible/tree.service.js"></script>
|
||||
<script src="../../accessible/translate.pipe.js"></script>
|
||||
@@ -52,6 +53,13 @@
|
||||
|
||||
<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.
|
||||
</p>
|
||||
|
||||
<!--
|
||||
<p>→ More info on <a href="https://developers.google.com/blockly/">accessible Blockly</a>…</p>
|
||||
-->
|
||||
@@ -328,9 +336,6 @@
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Variables" colour="330" custom="VARIABLE"></category>
|
||||
<category name="Functions" colour="290" custom="PROCEDURE"></category>
|
||||
</xml>
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user