Cleanup of style and simplifications. (#378)

* Cleanup of style and simplifications.

* Removing unused addClass function.
This commit is contained in:
Neil Fraser
2016-05-25 00:02:28 -07:00
parent 763e9b938f
commit 5dc6fc4657
10 changed files with 138 additions and 153 deletions

View File

@@ -22,7 +22,9 @@
* app is rendered on the page.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.workspace = new Blockly.Workspace();
// If the debug flag is true, print console.logs to help with debugging.
blocklyApp.debug = false;
@@ -51,7 +53,7 @@ blocklyApp.AppView = ng.core
<label id="blockly-disabled" aria-hidden="true" hidden>{{stringMap['UNAVAILABLE']}}</label>
`,
directives: [blocklyApp.ToolboxView, blocklyApp.WorkspaceView],
// ClipboardService declared here so that all components are using the same
// ClipboardService declared here so that all components are using the same
// instance of the clipboard.
// https://www.sitepoint.com/angular-2-components-providers-classes-factories-values/
providers: [blocklyApp.ClipboardService]
@@ -60,7 +62,7 @@ blocklyApp.AppView = ng.core
constructor: function() {
this.stringMap = {
['TOOLBOX_LOAD']: Blockly.Msg.TOOLBOX_LOAD_MSG,
['WORKSPACE_LOAD']: Blockly.Msg.WORKSPACE_LOAD_MSG,
['WORKSPACE_LOAD']: Blockly.Msg.WORKSPACE_LOAD_MSG,
['BLOCK_SUMMARY']: Blockly.Msg.BLOCK_SUMMARY,
['BLOCK_ACTION_LIST']: Blockly.Msg.BLOCK_ACTION_LIST,
['OPTION_LIST']: Blockly.Msg.OPTION_LIST,
@@ -69,7 +71,7 @@ blocklyApp.AppView = ng.core
['BUTTON']: Blockly.Msg.BUTTON,
['TEXT']: Blockly.Msg.TEXT,
['ARGUMENT_BLOCK_ACTION_LIST']: Blockly.Msg.ARGUMENT_BLOCK_ACTION_LIST,
['ARGUMENT_INPUT']: Blockly.Msg.ARGUMENT_INPUT,
['ARGUMENT_INPUT']: Blockly.Msg.ARGUMENT_INPUT
};
}
});

View File

@@ -21,6 +21,7 @@
* @fileoverview Angular2 Service that handles the clipboard and marked spots.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.ClipboardService = ng.core
.Class({
constructor: function() {
@@ -71,7 +72,7 @@ blocklyApp.ClipboardService = ng.core
reconstitutedBlock.previousConnection);
blocklyApp.debug && console.log('paste to marked connection');
if (announce) {
alert(Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG + block.toString());
alert(Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG + block.toString());
}
},
markConnection: function(connection) {

View File

@@ -23,22 +23,23 @@
* with the field.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.FieldView = ng.core
.Component({
selector: 'field-view',
template: `
<li [id]="idMap['listItem']" role="treeitem" *ngIf="isTextInput()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-input', idMap['input'])"
<li [id]="idMap['listItem']" role="treeitem" *ngIf="isTextInput()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-input', idMap['input'])"
[attr.aria-level]="level" aria-selected=false>
<input [id]="idMap['input']" [ngModel]="field.getValue()" (ngModelChange)="field.setValue($event)">
</li>
<li [id]="idMap['listItem']" *ngIf="isDropdown()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-menu', idMap['label'])"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-menu', idMap['label'])"
[attr.aria-level]="level" aria-selected=false role="treeitem">
<label [id]="idMap['label']">{{stringMap['CURRENT_ARGUMENT_VALUE']}} {{field.getText()}}</label>
<ol role="group" [attr.aria-level]="level+1">
<li [id]="idMap[optionValue]" role="treeitem" *ngFor="#optionValue of getOptions()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap[optionValue + 'Button'], 'blockly-button')"
<li [id]="idMap[optionValue]" role="treeitem" *ngFor="#optionValue of getOptions()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap[optionValue + 'Button'], 'blockly-button')"
[attr.aria-level]="level+1" aria-selected=false>
<button [id]="idMap[optionValue + 'Button']" (click)="handleDropdownChange(field, optionValue)">
{{optionText[optionValue]}}
@@ -46,14 +47,14 @@ blocklyApp.FieldView = ng.core
</li>
</ol>
</li>
<li [id]="idMap['listItem']" role="treeitem"
*ngIf="isCheckbox()" [attr.aria-level]="level"
<li [id]="idMap['listItem']" role="treeitem"
*ngIf="isCheckbox()" [attr.aria-level]="level"
aria-selected=false>
// Checkboxes not currently supported.
</li>
<li [id]="idMap['listItem']" role="treeitem"
[attr.aria-labelledBy]="utilsService.generateAriaLabelledByAttr('blockly-argument-text', idMap['label'])"
*ngIf="isTextField() && hasVisibleText()"
<li [id]="idMap['listItem']" role="treeitem"
[attr.aria-labelledBy]="utilsService.generateAriaLabelledByAttr('blockly-argument-text', idMap['label'])"
*ngIf="isTextField() && hasVisibleText()"
[attr.aria-level]="level" aria-selected=false>
<label [id]="idMap['label']">
{{field.getText()}}
@@ -61,10 +62,10 @@ blocklyApp.FieldView = ng.core
</li>
`,
inputs: ['field', 'level', 'index', 'parentId'],
providers: [blocklyApp.TreeService, blocklyApp.UtilsService],
providers: [blocklyApp.TreeService, blocklyApp.UtilsService]
})
.Class({
constructor: [blocklyApp.TreeService, blocklyApp.UtilsService,
constructor: [blocklyApp.TreeService, blocklyApp.UtilsService,
function(_treeService, _utilsService) {
this.optionText = {
keys: []
@@ -72,7 +73,7 @@ blocklyApp.FieldView = ng.core
this.treeService = _treeService;
this.utilsService = _utilsService;
this.stringMap = {
'CURRENT_ARGUMENT_VALUE': Blockly.Msg.CURRENT_ARGUMENT_VALUE,
'CURRENT_ARGUMENT_VALUE': Blockly.Msg.CURRENT_ARGUMENT_VALUE
};
}],
ngOnInit: function() {
@@ -80,27 +81,21 @@ blocklyApp.FieldView = ng.core
this.idMap = this.utilsService.generateIds(elementsNeedingIds);
},
generateAriaLabelledByAttr: function() {
return this.utilsService.generateAriaLabelledByAttr.apply(this,arguments);
return this.utilsService.generateAriaLabelledByAttr.apply(this,
arguments);
},
generateElementNames: function() {
var elementNames = ['listItem'];
switch(true) {
case this.isTextInput():
elementNames.push('input');
break;
case this.isDropdown():
elementNames.push('label');
var keys = this.getOptions();
for (var i = 0; i < keys.length; i++){
elementNames.push(keys[i]);
elementNames.push(keys[i] + 'Button');
}
break;
case this.isTextField() && this.hasVisibleText():
elementNames.push('label');
break;
default:
break;
if (this.isTextInput()) {
elementNames.push('input');
} else if (this.isDropdown()) {
elementNames.push('label');
var keys = this.getOptions();
for (var i = 0; i < keys.length; i++){
elementNames.push(keys[i], keys[i] + 'Button');
}
} else if (this.isTextField() && this.hasVisibleText()) {
elementNames.push('label');
}
return elementNames;
},

View File

@@ -23,14 +23,15 @@
* with the blocks.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.ToolboxTreeView = ng.core
.Component({
selector: 'toolbox-tree-view',
template: `
<li #parentList [id]="idMap['parentList']" role="treeitem"
[ngClass]="{blocklyHasChildren: displayBlockMenu || block.inputList.length > 0, blocklyActiveDescendant: index == 0 && noCategories}"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummaryLabel'])"
[attr.aria-selected]="index == 0 && tree.getAttribute('aria-activedescendant') == 'blockly-toolbox-tree-node0'"
[ngClass]="{blocklyHasChildren: displayBlockMenu || block.inputList.length > 0, blocklyActiveDescendant: index == 0 && noCategories}"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummaryLabel'])"
[attr.aria-selected]="index == 0 && tree.getAttribute('aria-activedescendant') == 'blockly-toolbox-tree-node0'"
[attr.aria-level]="level">
{{setActiveDesc(parentList)}}
<label #blockSummaryLabel [id]="idMap['blockSummaryLabel']">{{block.toString()}}</label>
@@ -38,22 +39,22 @@ blocklyApp.ToolboxTreeView = ng.core
<li #listItem [attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', idMap['blockSummaryLabel'])" class="blocklyHasChildren" [id]="idMap['listItem']" *ngIf="displayBlockMenu" role="treeitem" aria-selected=false [attr.aria-level]="level+1">
<label #label [id]="idMap['label']">{{stringMap['BLOCK_ACTION_LIST']}}</label>
<ol role="group" *ngIf="displayBlockMenu" [attr.aria-level]="level+2">
<li #workspaceCopy [id]="idMap['workspaceCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
<li #workspaceCopy [id]="idMap['workspaceCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['workspaceCopyButton'], 'blockly-button')"
[attr.aria-level]="level+2" aria-selected=false>
<button #workspaceCopyButton [id]="idMap['workspaceCopyButton']"
<button #workspaceCopyButton [id]="idMap['workspaceCopyButton']"
(click)="copyToWorkspace(block)">{{stringMap['COPY_TO_WORKSPACE']}}</button>
</li>
<li #blockCopy [id]="idMap['blockCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockCopyButton'], 'blockly-button')"
<li #blockCopy [id]="idMap['blockCopy']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['blockCopyButton'], 'blockly-button')"
[attr.aria-level]="level+2" aria-selected=false>
<button #blockCopyButton [id]="idMap['blockCopyButton']"
<button #blockCopyButton [id]="idMap['blockCopyButton']"
(click)="clipboardService.copy(block, true)">{{stringMap['COPY_TO_CLIPBOARD']}}</button>
</li>
<li #sendToSelected [id]="idMap['sendToSelected']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', utilsService.getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block)))"
<li #sendToSelected [id]="idMap['sendToSelected']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', utilsService.getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block)))"
[attr.aria-level]="level+2" aria-selected=false>
<button #sendToSelectedButton [id]="idMap['sendToSelectedButton']" (click)="copyToMarked(block)"
<button #sendToSelectedButton [id]="idMap['sendToSelectedButton']" (click)="copyToMarked(block)"
[disabled]="getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block))">
{{stringMap['COPY_TO_MARKED_SPOT']}}</button>
</li>
@@ -62,9 +63,9 @@ blocklyApp.ToolboxTreeView = ng.core
<div *ngFor="#inputBlock of block.inputList; #i=index">
<field-view *ngFor="#field of inputBlock.fieldRow; #j=index" [attr.aria-level]="level+1" [field]="field" [level]="level+1"></field-view>
<toolbox-tree-view *ngIf="inputBlock.connection && inputBlock.connection.targetBlock()" [block]="inputBlock.connection.targetBlock()" [displayBlockMenu]="false" [level]="level+1"></toolbox-tree-view>
<li #listItem1 [id]="idMap['listItem' + i]" role="treeitem"
*ngIf="inputBlock.connection && !inputBlock.connection.targetBlock()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-text', idMap['listItem' + i + 'Label'])"
<li #listItem1 [id]="idMap['listItem' + i]" role="treeitem"
*ngIf="inputBlock.connection && !inputBlock.connection.targetBlock()"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-argument-text', idMap['listItem' + i + 'Label'])"
[attr.aria-level]="level+1" aria-selected=false>
<!--TODO(madeeha): i18n here will need to happen in a different way due to the way grammar changes based on language.-->
<label #label [id]="idMap['listItem' + i + 'Label']">{{utilsService.getInputTypeLabel(inputBlock.connection)}} {{utilsService.getBlockTypeLabel(inputBlock)}} needed:</label>
@@ -77,8 +78,9 @@ blocklyApp.ToolboxTreeView = ng.core
directives: [ng.core.forwardRef(
function() { return blocklyApp.ToolboxTreeView; }),
blocklyApp.FieldView],
inputs: ['block', 'displayBlockMenu', 'level', 'index', 'tree', 'noCategories'],
providers: [blocklyApp.TreeService, blocklyApp.UtilsService],
inputs: ['block', 'displayBlockMenu', 'level', 'index', 'tree',
'noCategories'],
providers: [blocklyApp.TreeService, blocklyApp.UtilsService]
})
.Class({
constructor: [blocklyApp.ClipboardService, blocklyApp.TreeService,
@@ -92,15 +94,15 @@ blocklyApp.ToolboxTreeView = ng.core
'BLOCK_ACTION_LIST': Blockly.Msg.BLOCK_ACTION_LIST,
'COPY_TO_CLIPBOARD': Blockly.Msg.COPY_TO_CLIPBOARD,
'COPY_TO_WORKSPACE': Blockly.Msg.COPY_TO_WORKSPACE,
'COPY_TO_MARKED_SPOT': Blockly.Msg.COPY_TO_MARKED_SPOT,
'COPY_TO_MARKED_SPOT': Blockly.Msg.COPY_TO_MARKED_SPOT
};
}],
ngOnInit: function() {
var elementsNeedingIds = ['blockSummaryLabel'];
if (this.displayBlockMenu || this.block.inputList.length){
elementsNeedingIds = elementsNeedingIds.concat(['listItem', 'label', 'workspaceCopy',
'workspaceCopyButton', 'blockCopy', 'blockCopyButton',
'sendToSelected', 'sendToSelectedButton']);
elementsNeedingIds = elementsNeedingIds.concat(['listItem', 'label',
'workspaceCopy', 'workspaceCopyButton', 'blockCopy',
'blockCopyButton', 'sendToSelected', 'sendToSelectedButton']);
}
for (var i = 0; i < this.block.inputList.length; i++){
elementsNeedingIds.push('listItem' + i);
@@ -114,10 +116,12 @@ blocklyApp.ToolboxTreeView = ng.core
}
},
getMarkedBlockCompatibilityHTMLText: function(isCompatible) {
return this.utilsService.getMarkedBlockCompatibilityHTMLText(isCompatible);
return this.utilsService.getMarkedBlockCompatibilityHTMLText(
isCompatible);
},
generateAriaLabelledByAttr: function() {
return this.utilsService.generateAriaLabelledByAttr.apply(this,arguments);
return this.utilsService.generateAriaLabelledByAttr.apply(this,
arguments);
},
setActiveDesc: function(parentList) {
// If this is the first child of the toolbox and the
@@ -128,19 +132,6 @@ blocklyApp.ToolboxTreeView = ng.core
this.treeService.setActiveDesc(parentList, this.tree.id);
}
},
addClass: function(node, classText) {
// Ensure that node doesn't have class already in it.
var classList = (node.className || '').split(' ');
var canAdd = classList.indexOf(classText) == -1;
// Add class if it doesn't.
if (canAdd) {
if (classList.length) {
node.className += ' ' + classText;
} else {
node.className = classText;
}
}
},
copyToWorkspace: function(block) {
var xml = Blockly.Xml.blockToDom(block);
Blockly.Xml.domToBlock(blocklyApp.workspace, xml);

View File

@@ -22,22 +22,23 @@
* in AccessibleBlockly. Also handles any interactions with the toolbox.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.ToolboxView = ng.core
.Component({
selector: 'toolbox-view',
template: `
<h3 #toolboxTitle id="blockly-toolbox-title">Toolbox</h3>
<ol #tree id="blockly-toolbox-tree" role="group" class="blocklyTree"
*ngIf="makeArray(sightedToolbox) && makeArray(sightedToolbox).length > 0"
tabIndex="0" [attr.aria-labelledby]="toolboxTitle.id"
[attr.aria-activedescendant]="tree.getAttribute('aria-activedescendant') || tree.id + '-node0' "
*ngIf="makeArray(sightedToolbox) && makeArray(sightedToolbox).length > 0"
tabIndex="0" [attr.aria-labelledby]="toolboxTitle.id"
[attr.aria-activedescendant]="tree.getAttribute('aria-activedescendant') || tree.id + '-node0' "
(keydown)="treeService.onKeypress($event, tree)">
<li #parent [id]="idMap['Parent' + i]" role="treeitem"
<li #parent [id]="idMap['Parent' + i]" role="treeitem"
[ngClass]="{blocklyHasChildren: true,
blocklyActiveDescendant: tree.getAttribute('aria-activedescendant') == idMap['Parent' + i]}"
*ngIf="toolboxHasCategories" *ngFor="#category of makeArray(sightedToolbox); #i=index"
blocklyActiveDescendant: tree.getAttribute('aria-activedescendant') == idMap['Parent' + i]}"
*ngIf="toolboxHasCategories" *ngFor="#category of makeArray(sightedToolbox); #i=index"
aria-level="1" aria-selected=false>
<!-- TODO(madeeha): There seems to be some bug in Angular that makes it
<!-- TODO(madeeha): There seems to be some bug in Angular that makes it
access index=undefined in the ngFor loop. This causes it to throw an error once it reaches line
44. To combat this, we have added the div at line 43. Talk to fraser@.-->
<div *ngIf="category && category.attributes">
@@ -87,7 +88,7 @@ blocklyApp.ToolboxView = ng.core
parent.setAttribute('aria-label', label.innerText);
parent.id = 'blockly-toolbox-tree-node' + i;
if (i == 0 && tree.getAttribute('aria-activedescendant') ==
'blockly-toolbox-tree-node0') {
'blockly-toolbox-tree-node0') {
this.treeService.setActiveDesc(parent, tree.id);
parent.setAttribute('aria-selected', 'true');
}
@@ -131,4 +132,3 @@ blocklyApp.ToolboxView = ng.core
}
}
});

View File

@@ -21,6 +21,7 @@
* @fileoverview Angular2 Service that handles all tree keyboard navigation.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.TreeService = ng.core
.Class({
constructor: function() {
@@ -46,7 +47,8 @@ blocklyApp.TreeService = ng.core
this.activeDesc_[id] = node;
},
getActiveDesc: function(id) {
return this.activeDesc_[id] || document.getElementById((document.getElementById(id)).getAttribute('aria-activedescendant'));
return this.activeDesc_[id] ||
document.getElementById((document.getElementById(id)).getAttribute('aria-activedescendant'));
},
// Makes a given node the active descendant of a given tree.
updateSelectedNode: function(node, tree, keepFocus) {
@@ -80,16 +82,12 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('shifttabbing');
// If the previous key is shift, we're shift-tabbing mode.
this.goToPreviousTree(treeId);
e.preventDefault();
e.stopPropagation();
} else {
// If previous key isn't shift, we're tabbing.
this.goToNextTree(treeId);
e.preventDefault();
e.stopPropagation();
}
break;
default:
e.preventDefault();
e.stopPropagation();
break;
}
},
@@ -131,24 +129,20 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('shifttabbing');
// If the previous key is shift, we're shift-tabbing.
this.goToPreviousTree(treeId);
e.preventDefault();
e.stopPropagation();
} else {
// If previous key isn't shift, we're tabbing
// we want to go to the run code button.
this.goToNextTree(treeId);
e.preventDefault();
e.stopPropagation();
}
// Setting the previous key variable in each case because
// we only want to save the previous navigation keystroke,
// not any typing.
this.previousKey_ = e.keyCode;
e.preventDefault();
e.stopPropagation();
break;
case 37:
// Left-facing arrow: go out a level, if possible. If not, do nothing.
e.preventDefault();
e.stopPropagation();
blocklyApp.debug && console.log('in left arrow section');
var nextNode = node.parentNode;
if (node.tagName == 'BUTTON' || node.tagName == 'INPUT') {
@@ -163,11 +157,11 @@ blocklyApp.TreeService = ng.core
}
this.updateSelectedNode(nextNode, tree, keepFocus);
this.previousKey_ = e.keyCode;
e.preventDefault();
e.stopPropagation();
break;
case 38:
// Up-facing arrow: go up a level, if possible. If not, do nothing.
e.preventDefault();
e.stopPropagation();
blocklyApp.debug && console.log('node passed in: ' + node.id);
var prevSibling = this.getPreviousSibling(node);
if (prevSibling && prevSibling.tagName != 'H1') {
@@ -176,10 +170,10 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('no previous sibling');
}
this.previousKey_ = e.keyCode;
break;
case 39:
e.preventDefault();
e.stopPropagation();
break;
case 39:
blocklyApp.debug && console.log('in right arrow section');
var firstChild = this.getFirstChild(node);
if (firstChild) {
@@ -188,13 +182,13 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('no valid child');
}
this.previousKey_ = e.keyCode;
e.preventDefault();
e.stopPropagation();
break;
case 40:
// Down-facing arrow: go down a level, if possible.
// If not, do nothing.
blocklyApp.debug && console.log('preventing propogation');
e.preventDefault();
e.stopPropagation();
var nextSibling = this.getNextSibling(node);
if (nextSibling) {
this.updateSelectedNode(nextSibling, tree, keepFocus);
@@ -202,6 +196,8 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('no next sibling');
}
this.previousKey_ = e.keyCode;
e.preventDefault();
e.stopPropagation();
break;
case 13:
// If I've pressed enter, I want to interact with a child.
@@ -224,8 +220,6 @@ blocklyApp.TreeService = ng.core
}
this.previousKey_ = e.keyCode;
break;
default:
break;
}
},
getFirstChild: function(element) {
@@ -285,7 +279,7 @@ blocklyApp.TreeService = ng.core
}
} else {
var parent = element.parentNode;
while (parent != null) {
while (parent) {
blocklyApp.debug && console.log('looping');
if (parent.tagName == 'OL') {
break;
@@ -327,5 +321,5 @@ blocklyApp.TreeService = ng.core
blocklyApp.debug && console.log('no last child');
return null;
}
},
}
});

View File

@@ -22,7 +22,9 @@
* components.
* @author madeeha@google.com (Madeeha Ghori)
*/
var blocklyApp = {};
blocklyApp.UtilsService = ng.core
.Class({
constructor: function() {
@@ -38,11 +40,7 @@ blocklyApp.UtilsService = ng.core
return idMap;
},
generateAriaLabelledByAttr: function() {
var labels = arguments[0];
for (i = 1; i < arguments.length; i++) {
labels += ' ' + arguments[i];
}
return labels.trim();
return Array.from(arguments).join(' ').trim();
},
getInputTypeLabel: function(connection) {
// Returns an upper case string in the case of official input type names.

View File

@@ -23,59 +23,60 @@
* interactions with the blocks.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.WorkspaceTreeView = ng.core
.Component({
selector: 'tree-view',
template: `
<li #parentList [id]="idMap['parentList']" role="treeitem" class="blocklyHasChildren"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummary'])"
<li #parentList [id]="idMap['parentList']" role="treeitem" class="blocklyHasChildren"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-summary', idMap['blockSummary'])"
[attr.aria-level]="level" aria-selected=false>
{{checkParentList(parentList)}}
<label [id]="idMap['blockSummary']">{{block.toString()}}</label>
<ol role="group" [attr.aria-level]="level+1">
<li [id]="idMap['listItem']" class="blocklyHasChildren" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', idMap['blockSummary'])"
<li [id]="idMap['listItem']" class="blocklyHasChildren" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-block-menu', idMap['blockSummary'])"
[attr.aria-level]="level+1" aria-selected=false>
<label [id]="idMap['label']">{{stringMap['BLOCK_ACTION_LIST']}}</label>
<ol role="group" [attr.aria-level]="level+2">
<li [id]="idMap['cutListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['cutButton'], 'blockly-button')"
<li [id]="idMap['cutListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['cutButton'], 'blockly-button')"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['cutButton']" (click)="clipboardService.cut(block)">{{stringMap['CUT_BLOCK']}}</button>
</li>
<li [id]="idMap['copyListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['copyButton'], 'blockly-button')"
<li [id]="idMap['copyListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['copyButton'], 'blockly-button')"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['copyButton']" (click)="clipboardService.copy(block, true)">{{stringMap['COPY_BLOCK']}}</button>
</li>
<li [id]="idMap['pasteBelow']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteBelowButton'], 'blockly-button', (getNoNextConnectionHTMLText(block)||clipboardService.getClipboardCompatibilityHTMLText(block.nextConnection)))"
<li [id]="idMap['pasteBelow']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteBelowButton'], 'blockly-button', (getNoNextConnectionHTMLText(block)||clipboardService.getClipboardCompatibilityHTMLText(block.nextConnection)))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['pasteBelowButton']" (click)="clipboardService.pasteFromClipboard(block.nextConnection)"
<button [id]="idMap['pasteBelowButton']" (click)="clipboardService.pasteFromClipboard(block.nextConnection)"
[disabled]="getNoNextConnectionHTMLText(block)" [disabled]="clipboardService.getClipboardCompatibilityHTMLText(block.nextConnection)">{{stringMap['PASTE_BELOW']}}</button>
</li>
<li [id]="idMap['pasteAbove']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteAboveButton'], 'blockly-button', (getNoPreviousConnectionHTMLText(block) || clipboardService.getClipboardCompatibilityHTMLText(block.previousConnection)))"
<li [id]="idMap['pasteAbove']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteAboveButton'], 'blockly-button', (getNoPreviousConnectionHTMLText(block) || clipboardService.getClipboardCompatibilityHTMLText(block.previousConnection)))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['pasteAboveButton']" (click)="clipboardService.pasteFromClipboard(block.previousConnection)"
<button [id]="idMap['pasteAboveButton']" (click)="clipboardService.pasteFromClipboard(block.previousConnection)"
[disabled]="getNoPreviousConnectionHTMLText(block)" [disabled]="clipboardService.getClipboardCompatibilityHTMLText(block.previousConnection)">{{stringMap['PASTE_ABOVE']}}</button>
</li>
<li [id]="idMap['markBelow']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markBelowButton'], 'blockly-button', getNoNextConnectionHTMLText(block))"
<li [id]="idMap['markBelow']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markBelowButton'], 'blockly-button', getNoNextConnectionHTMLText(block))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['markBelowButton']" (click)="clipboardService.markConnection(block.nextConnection)"
<button [id]="idMap['markBelowButton']" (click)="clipboardService.markConnection(block.nextConnection)"
[disabled]="getNoNextConnectionHTMLText(block)">{{stringMap['MARK_SPOT_BELOW']}}</button>
</li>
<li [id]="idMap['markAbove']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markAboveButton'], 'blockly-button', getNoPreviousConnectionHTMLText(block))"
<li [id]="idMap['markAbove']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markAboveButton'], 'blockly-button', getNoPreviousConnectionHTMLText(block))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['markAboveButton']" (click)="clipboardService.markConnection(block.previousConnection)"
<button [id]="idMap['markAboveButton']" (click)="clipboardService.markConnection(block.previousConnection)"
[disabled]="getNoPreviousConnectionHTMLText(block)">{{stringMap['MARK_SPOT_ABOVE']}}</button>
</li>
<li [id]="idMap['sendToSelectedListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', utilsService.getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block)))"
<li [id]="idMap['sendToSelectedListItem']" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['sendToSelectedButton'], 'blockly-button', utilsService.getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block)))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['sendToSelectedButton']" (click)="sendToSelected(block)"
<button [id]="idMap['sendToSelectedButton']" (click)="sendToSelected(block)"
[disabled]="getMarkedBlockCompatibilityHTMLText(clipboardService.isBlockCompatibleWithMarkedConnection(block))">{{stringMap['MOVE_TO_MARKED_SPOT']}}</button>
</li>
<li [attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['deleteButton'], 'blockly-button')" [id]="idMap['delete']" role="treeitem" aria-selected=false [attr.aria-level]="level+2">
@@ -86,21 +87,21 @@ blocklyApp.WorkspaceTreeView = ng.core
<div *ngFor="#inputBlock of block.inputList; #i = index">
<field-view *ngFor="#field of inputBlock.fieldRow" [field]="field"></field-view>
<tree-view *ngIf="inputBlock.connection && inputBlock.connection.targetBlock()" [block]="inputBlock.connection.targetBlock()" [isTopBlock]="false" [level]="level"></tree-view>
<li #inputList [attr.aria-level]="level + 1" [id]="idMap['inputList' + i]"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-menu', idMap['inputMenuLabel' + i])"
<li #inputList [attr.aria-level]="level + 1" [id]="idMap['inputList' + i]"
[attr.aria-labelledBy]="generateAriaLabelledByAttr('blockly-menu', idMap['inputMenuLabel' + i])"
*ngIf="inputBlock.connection && !inputBlock.connection.targetBlock()" (keydown)="treeService.onKeypress($event, tree)">
<!-- TODO(madeeha): i18n here will need to happen in a different way due to the way grammar changes based on language. -->
<label [id]="idMap['inputMenuLabel' + i]"> {{utilsService.getInputTypeLabel(inputBlock.connection)}} {{utilsService.getBlockTypeLabel(inputBlock)}} needed: </label>
<ol role="group" [attr.aria-level]="level+2">
<li [id]="idMap['markSpot' + i]" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markButton' + i], 'blockly-button')"
<li [id]="idMap['markSpot' + i]" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['markButton' + i], 'blockly-button')"
[attr.aria-level]="level + 2" aria-selected=false>
<button [id]="idMap['markSpotButton + i']" (click)="clipboardService.markConnection(inputBlock.connection)">{{stringMap['MARK_THIS_SPOT']}}</button>
</li>
<li [id]="idMap['paste' + i]" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteButton' + i], 'blockly-button', clipboardService.getClipboardCompatibilityHTMLText(inputBlock.connection))"
<li [id]="idMap['paste' + i]" role="treeitem"
[attr.aria-labelledBy]="generateAriaLabelledByAttr(idMap['pasteButton' + i], 'blockly-button', clipboardService.getClipboardCompatibilityHTMLText(inputBlock.connection))"
[attr.aria-level]="level+2" aria-selected=false>
<button [id]="idMap['pasteButton' + i]" (click)="clipboardService.pasteFromClipboard(inputBlock.connection)"
<button [id]="idMap['pasteButton' + i]" (click)="clipboardService.pasteFromClipboard(inputBlock.connection)"
[disabled]="clipboardService.getClipboardCompatibilityHTMLText(inputBlock.connection)">{{stringMap['PASTE']}}</button>
</li>
</ol>
@@ -134,13 +135,13 @@ blocklyApp.WorkspaceTreeView = ng.core
'CUT_BLOCK': Blockly.Msg.CUT_BLOCK,
'COPY_BLOCK': Blockly.Msg.COPY_BLOCK,
'MOVE_TO_MARKED_SPOT': Blockly.Msg.MOVE_TO_MARKED_SPOT,
'DELETE': Blockly.Msg.DELETE,
'DELETE': Blockly.Msg.DELETE
};
}],
deleteBlock: function(block) {
// If this is the top block, we should shift focus to the previous tree
var topBlocks = blocklyApp.workspace.topBlocks_;
for (var i=0; i < topBlocks.length; i++) {
for (var i = 0; i < topBlocks.length; i++) {
if (topBlocks[i].id == block.id) {
this.treeService.goToPreviousTree(this.parentId);
break;
@@ -154,7 +155,8 @@ blocklyApp.WorkspaceTreeView = ng.core
return this.utilsService.getMarkedBlockCompatibilityHTMLText(isCompatible);
},
generateAriaLabelledByAttr: function() {
return this.utilsService.generateAriaLabelledByAttr.apply(this,arguments);
return this.utilsService.generateAriaLabelledByAttr.apply(this,
arguments);
},
ngOnInit: function() {
var elementsNeedingIds = ['blockSummary', 'listItem', 'label',
@@ -166,7 +168,8 @@ blocklyApp.WorkspaceTreeView = ng.core
for (var i = 0; i < this.block.inputList.length; i++) {
var inputBlock = this.block.inputList[i];
if (inputBlock.connection && !inputBlock.connection.targetBlock()) {
elementsNeedingIds = elementsNeedingIds.concat(['inputList' + i, 'inputMenuLabel' + i, 'markSpot' + i,
elementsNeedingIds = elementsNeedingIds.concat(
['inputList' + i, 'inputMenuLabel' + i, 'markSpot' + i,
'markSpotButton' + i, 'paste' + i, 'pasteButton' + i]);
}
}

View File

@@ -22,6 +22,7 @@
* rendered in AccessibleBlockly.
* @author madeeha@google.com (Madeeha Ghori)
*/
blocklyApp.WorkspaceView = ng.core
.Component({
selector: 'workspace-view',
@@ -31,22 +32,22 @@ blocklyApp.WorkspaceView = ng.core
<h3 #workspaceTitle id="blockly-workspace-title">{{stringMap['WORKSPACE']}}</h3>
</label>
<div id="blockly-workspace-toolbar" (keydown)="onWorkspaceToolbarKeypress($event, getActiveElementId())">
<button id='run-code' (click)='runCode()' disabled={{disableRunCode()}}
<button id='run-code' (click)='runCode()' disabled={{disableRunCode()}}
[attr.aria-disabled]='disableRunCode()' class='blocklyTree'>{{stringMap['RUN_CODE']}}</button>
<button id='clear-workspace' (click)='workspace.clear()' disabled={{disableRunCode()}}
<button id='clear-workspace' (click)='workspace.clear()' disabled={{disableRunCode()}}
[attr.aria-disabled]='disableRunCode()' class='blocklyTree'>{{stringMap['CLEAR_WORKSPACE']}}</button>
</div>
<div *ngIf="workspace">
<ol #tree id={{makeId(i)}} *ngFor="#block of workspace.topBlocks_; #i=index"
tabIndex="0" role="group" class="blocklyTree" [attr.aria-labelledby]="workspaceTitle.id"
[attr.aria-activedescendant]="tree.getAttribute('aria-activedescendant') || tree.id + '-node0' "
<ol #tree id={{makeId(i)}} *ngFor="#block of workspace.topBlocks_; #i=index"
tabIndex="0" role="group" class="blocklyTree" [attr.aria-labelledby]="workspaceTitle.id"
[attr.aria-activedescendant]="tree.getAttribute('aria-activedescendant') || tree.id + '-node0' "
(keydown)="onKeypress($event, tree)">
<tree-view [level]=1 [block]="block" [isTopBlock]="true" [topBlockIndex]="i" [parentId]="tree.id"></tree-view>
</ol>
</div>
`,
directives: [blocklyApp.WorkspaceTreeView],
providers: [blocklyApp.TreeService],
providers: [blocklyApp.TreeService]
})
.Class({
constructor: [blocklyApp.TreeService, function(_treeService) {
@@ -57,7 +58,7 @@ blocklyApp.WorkspaceView = ng.core
this.stringMap = {
'WORKSPACE': Blockly.Msg.WORKSPACE,
'RUN_CODE': Blockly.Msg.RUN_CODE,
'CLEAR_WORKSPACE': Blockly.Msg.CLEAR_WORKSPACE,
'CLEAR_WORKSPACE': Blockly.Msg.CLEAR_WORKSPACE
};
}],
onWorkspaceToolbarKeypress: function(event, id) {
@@ -76,10 +77,10 @@ blocklyApp.WorkspaceView = ng.core
runCode();
},
disableRunCode: function() {
if (blocklyApp.workspace.topBlocks_.length == 0){
return 'blockly-disabled';
} else {
if (blocklyApp.workspace.topBlocks_.length){
return undefined;
} else {
return 'blockly-disabled';
}
},
}
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 939 B

After

Width:  |  Height:  |  Size: 1.4 KiB