Files
blockly/accessible/fieldview.component.js
M 6474fcd774 AccessibleBlockly (#354)
* adding a folder in demos for blind and setting up the package.json file for development. Adding package.json to .gitignore

* removing gitignore~ file

* copied blind blockly demo code over. set up a new dev environment. Up for review: the blind blockly demo code. Much of the drop downs don't actually do anything, but a general look at the way angular is used would be helpful in shaping future development.

* adding an index file that was being ignored by .gitignore

* adding required angular files and libraries previously ignored by git add --a for some unknown reason.

* starting work on toolbox

* got workspace and toolbox connected. Copy to workspace annd copy to clipboard working at 80%.

* cleaning up autogenerated files

* adding my own files. Not sure why the test files are being added.

* cleaning up comments

* removed empty html_formatter.html file from project and put on git ignore list. The file is used on my end to help with formatting the html in javascript files.

* getting rid of unnecessary html_formatter file

* removing merge conflicts

* cleaned up comments

* cleaned up comments, organized file structure, made ToolboxXML a file that can be changed by other developers porting this code, added copyright and file summaries to js files, linted files, moved third party libraries to lib folder

* removing lint files that shouldn't be tracked.

* Made the clipboard a service instead of multiple pieces embedded within the app. Not sold on the name ClipboardService. Open to suggestions.

* syncing up demo updates

* adding insert block menus above and below appropriate blocks.

* hacky version of getting code to run.

* changing toolbox to be a menu. making both the toolbox and workspace ordered lists

* adding new folder dev-old containing a version of blind blockly that uses nested lists for the toolbox

* getting rid of menubar experiment

* adding treeview shenanigans part 1

* adding treeview experiment page and finishing up treeview.

* getting a treeview implementation working in the toolbox

* creating a fishfood folder for fishfood development

* making first level of fishfood

* fixing something

* adding index file for fishfood

* beginning merging the treeview system.

* creating two treeviews

* fishfood level 1 without working music blocks

* fixes to treeview navigation

* final fishfood features done

* adding support for toolboxes without categories

* beginning integration of Sean's new music code

* adding Sean's music blocks and beginning music_player integration.

* merged Sean's music block code into fishfood

* merged Sean's music code and fixed treeview bug with toolbox when no categories

* adding blank_demo

* fixing tab navigation.

* fixing bug with shift-tab. New bug found in alt+tab not opening dropdown?

* fixing labels

* fixing bugs and finding more.

* removing dropdowns in favor of buttons part 1. Still need to change field options.

* index.html for blank_demo

* beginning cleanup

* adding blockly- prefix to label ids.

* integrating AccessibleBlockly with Blockly library.

* remove closure library

* removing testing files that aren't in develop

* removing all demo stuff for a later pull request

* removing gitignore file that doesn't exist in developer branch

* syncing with develop branch files

* removing music files from this pull request

* doing some lint cleanup

* rolling back accidental package.json change

* removing var blocklyApp = blocklyApp || {} from each extraneous file

* adding last debug statement

* changed name of inputType function

* renaming _service arguments

* fixing function names

* fixing all comments.

* fixing minor comments

* renaming variables, etc

* fixing bugs that break demo. Adding the run code and clear workspace buttons back to the workspaceview as their current position breaks tab navigation.

* fixing minor comments

* fixing function names, etc.

* adding comments to getInputTypeLabel function

* removing addClass() calls from the template

* small change to clipboardService

* splitting getCategoryDependantId into two functions: getCategoryId and setActiveDesc

* fixing minor bug with last commit

* using conditional attributes to remove setActiveAttributes function from treeService and do same work in template.

* deleting unnecessary comment created in previous commit.

* adding a utilsService to remove duplicated code.

* changing function names in utilsService

* changing delete to [delete] to allow HTMLText functions to return an empty string instead of undefined. Also renaming concatStringWithSpaces to generateAriaLabelledByAttr

* generating ids in ngOnInit instead of on the fly, allowing us to use [attr.aria-labelledBy] in the template instead of using setLabelledBy(element). Deleting function utilsService.setLabelledBy.

* fixing small bug with tree service left arrow: was throwing an error when you can't go any further left.

* reformatting html to make it easier to read.

* moving from importing the xml file to using an xml toolbox in the demo.

* fixing minor bugs and removing code relevant only to the music game.

* minor fixes

* adding alerts to copy, paste, and mark actions. renaming blocklyApp.TreeView to blocklyApp.WorkspaceTreeView

* Beginning to add Blockly.msg strings.

* making sure index file is being tracked

* adding all demo bits

* removing demo files from this pull request

* fixing providers, some linting, and removing getInfo() function.

* adding small todo comment for sll@

* adding minimal Accessible Blockly demo

* removing demo: accidentally committed to wrong branch

* fixing Blockly.Msg string bugs

* fixing TODOs

* package file changed by an automerge. Changing back.

* addressing sll's comments. Creating shim for utilsService functions.

* fixing comments, changing fieldview to deal with this.field.

* fixing clipboard service bug

* fixing focus bug when editing a text input.

* fixed clipboard bug and added README

* fixing workspaceview not to implement on runCode() function and adding note to README
2016-05-23 16:42:18 -07:00

149 lines
5.4 KiB
JavaScript

/**
* 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 Blockly.Field is
* rendered in the toolbox in AccessibleBlockly. Also handles any interactions
* 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'])"
[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-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')"
[attr.aria-level]="level+1" aria-selected=false>
<button [id]="idMap[optionValue + 'Button']" (click)="handleDropdownChange(field, optionValue)">
{{optionText[optionValue]}}
</button>
</li>
</ol>
</li>
<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()"
[attr.aria-level]="level" aria-selected=false>
<label [id]="idMap['label']">
{{field.getText()}}
</label>
</li>
`,
inputs: ['field', 'level', 'index', 'parentId'],
providers: [blocklyApp.TreeService, blocklyApp.UtilsService],
})
.Class({
constructor: [blocklyApp.TreeService, blocklyApp.UtilsService,
function(_treeService, _utilsService) {
this.optionText = {
keys: []
};
this.treeService = _treeService;
this.utilsService = _utilsService;
this.stringMap = {
'CURRENT_ARGUMENT_VALUE': Blockly.Msg.CURRENT_ARGUMENT_VALUE,
};
}],
ngOnInit: function() {
var elementsNeedingIds = this.generateElementNames(this.field);
this.idMap = this.utilsService.generateIds(elementsNeedingIds);
},
generateAriaLabelledByAttr: function() {
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;
}
return elementNames;
},
isTextInput: function() {
return this.field instanceof Blockly.FieldTextInput;
},
isDropdown: function() {
return this.field instanceof Blockly.FieldDropdown;
},
isCheckbox: function() {
return this.field instanceof Blockly.FieldCheckbox;
},
isTextField: function() {
return !(this.field instanceof Blockly.FieldTextInput) &&
!(this.field instanceof Blockly.FieldDropdown) &&
!(this.field instanceof Blockly.FieldCheckbox);
},
hasVisibleText: function() {
var text = this.field.getText().trim();
return !!text;
},
getOptions: function() {
if (this.optionText.keys.length) {
return this.optionText.keys;
}
var options = this.field.getOptions_();
for (var i = 0; i < options.length; i++) {
var tuple = options[i];
this.optionText[tuple[1]] = tuple[0];
this.optionText.keys.push(tuple[1]);
}
return this.optionText.keys;
},
handleDropdownChange: function(field, text) {
if (text == 'NO_ACTION') {
return;
}
if (this.field instanceof Blockly.FieldVariable) {
blocklyApp.debug && console.log();
Blockly.FieldVariable.dropdownChange.call(this.field, text);
} else {
this.field.setValue(text);
}
}
});