diff --git a/accessible/README b/accessible/README index d133fa828..37ea67879 100644 --- a/accessible/README +++ b/accessible/README @@ -25,15 +25,16 @@ the main component to be loaded. This will usually be blocklyApp.AppView, but if you have another component that wraps it, use that one instead. -Customizing the Toolbar ------------------------ +Customizing the Toolbar and Audio +--------------------------------- The Accessible Blockly workspace comes with a customizable toolbar. To customize the toolbar, you will need to declare an ACCESSIBLE_GLOBALS object in the global scope that looks like this: var ACCESSIBLE_GLOBALS = { - toolbarButtonConfig: [] + toolbarButtonConfig: [], + mediaPathPrefix: null }; The value corresponding to 'toolbarButtonConfig' can be modified by adding @@ -43,6 +44,9 @@ two keys: - 'text' (the text to display on the button) - 'action' (the function that gets run when the button is clicked) +In addition, if you want audio to be played, set mediaPathPrefix to the +location of the accessible/media folder. + Limitations ----------- diff --git a/accessible/app.component.js b/accessible/app.component.js index f220af98b..063a5ea50 100644 --- a/accessible/app.component.js +++ b/accessible/app.component.js @@ -64,7 +64,8 @@ blocklyApp.AppView = ng.core // https://www.sitepoint.com/angular-2-components-providers-classes-factories-values/ providers: [ blocklyApp.ClipboardService, blocklyApp.NotificationsService, - blocklyApp.TreeService, blocklyApp.UtilsService] + blocklyApp.TreeService, blocklyApp.UtilsService, + blocklyApp.AudioService] }) .Class({ constructor: [blocklyApp.NotificationsService, function(_notificationsService) { diff --git a/accessible/audio.service.js b/accessible/audio.service.js new file mode 100644 index 000000000..c358c083b --- /dev/null +++ b/accessible/audio.service.js @@ -0,0 +1,57 @@ +/** + * 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 plays audio files. + * @author sll@google.com (Sean Lip) + */ + +blocklyApp.AudioService = ng.core + .Class({ + constructor: [function() { + // We do not play any audio unless a media path prefix is specified. + this.canPlayAudio = false; + if (ACCESSIBLE_GLOBALS.hasOwnProperty('mediaPathPrefix')) { + this.canPlayAudio = true; + var mediaPathPrefix = ACCESSIBLE_GLOBALS['mediaPathPrefix']; + this.AUDIO_PATHS_ = { + 'connect': mediaPathPrefix + 'click.mp3', + 'delete': mediaPathPrefix + 'delete.mp3' + }; + } + + // TODO(sll): Add ogg and mp3 fallbacks. + this.cachedAudioFiles_ = {}; + }], + play_: function(audioId) { + if (this.canPlayAudio) { + if (!this.cachedAudioFiles_.hasOwnProperty(audioId)) { + this.cachedAudioFiles_[audioId] = new Audio( + this.AUDIO_PATHS_[audioId]); + } + this.cachedAudioFiles_[audioId].play(); + } + }, + playConnectSound: function() { + this.play_('connect'); + }, + playDeleteSound: function() { + this.play_('delete'); + } + }); diff --git a/accessible/clipboard.service.js b/accessible/clipboard.service.js index 84b0b4f52..05b0afe63 100644 --- a/accessible/clipboard.service.js +++ b/accessible/clipboard.service.js @@ -26,7 +26,8 @@ blocklyApp.ClipboardService = ng.core .Class({ constructor: [ blocklyApp.NotificationsService, blocklyApp.UtilsService, - function(_notificationsService, _utilsService) { + blocklyApp.AudioService, + function(_notificationsService, _utilsService, _audioService) { this.clipboardBlockXml_ = null; this.clipboardBlockPreviousConnection_ = null; this.clipboardBlockNextConnection_ = null; @@ -34,6 +35,7 @@ blocklyApp.ClipboardService = ng.core this.markedConnection_ = null; this.notificationsService = _notificationsService; this.utilsService = _utilsService; + this.audioService = _audioService; }], areConnectionsCompatible_: function(blockConnection, connection) { // Check that both connections exist, that it's the right kind of @@ -130,6 +132,7 @@ blocklyApp.ClipboardService = ng.core default: connection.connect(reconstitutedBlock.outputConnection); } + this.audioService.playConnectSound(); this.notificationsService.setStatusMessage( this.utilsService.getBlockDescription(reconstitutedBlock) + ' ' + Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG); @@ -151,6 +154,7 @@ blocklyApp.ClipboardService = ng.core if (this.areConnectionsCompatible_( this.markedConnection_, potentialConnections[i])) { this.markedConnection_.connect(potentialConnections[i]); + this.audioService.playConnectSound(); connectionSuccessful = true; break; } diff --git a/media/accessible.css b/accessible/media/accessible.css similarity index 100% rename from media/accessible.css rename to accessible/media/accessible.css diff --git a/accessible/media/click.mp3 b/accessible/media/click.mp3 new file mode 100644 index 000000000..4534b0ddc Binary files /dev/null and b/accessible/media/click.mp3 differ diff --git a/accessible/media/click.ogg b/accessible/media/click.ogg new file mode 100644 index 000000000..e8ae42a61 Binary files /dev/null and b/accessible/media/click.ogg differ diff --git a/accessible/media/click.wav b/accessible/media/click.wav new file mode 100644 index 000000000..41a50cd76 Binary files /dev/null and b/accessible/media/click.wav differ diff --git a/accessible/media/delete.mp3 b/accessible/media/delete.mp3 new file mode 100644 index 000000000..442bd9c1f Binary files /dev/null and b/accessible/media/delete.mp3 differ diff --git a/accessible/media/delete.ogg b/accessible/media/delete.ogg new file mode 100644 index 000000000..67f84ac19 Binary files /dev/null and b/accessible/media/delete.ogg differ diff --git a/accessible/media/delete.wav b/accessible/media/delete.wav new file mode 100644 index 000000000..18debcf96 Binary files /dev/null and b/accessible/media/delete.wav differ diff --git a/accessible/workspace-tree.component.js b/accessible/workspace-tree.component.js index 8d7d02e7c..39e33b048 100644 --- a/accessible/workspace-tree.component.js +++ b/accessible/workspace-tree.component.js @@ -102,13 +102,15 @@ blocklyApp.WorkspaceTreeComponent = ng.core constructor: [ blocklyApp.ClipboardService, blocklyApp.NotificationsService, blocklyApp.TreeService, blocklyApp.UtilsService, + blocklyApp.AudioService, function( _clipboardService, _notificationsService, _treeService, - _utilsService) { + _utilsService, _audioService) { this.clipboardService = _clipboardService; this.notificationsService = _notificationsService; this.treeService = _treeService; this.utilsService = _utilsService; + this.audioService = _audioService; }], getBlockDescription: function() { return this.utilsService.getBlockDescription(this.block); @@ -172,6 +174,7 @@ blocklyApp.WorkspaceTreeComponent = ng.core var that = this; this.removeBlockAndSetFocus_(this.block, function() { that.block.dispose(true); + that.audioService.playDeleteSound(); }); setTimeout(function() { diff --git a/demos/accessible/index.html b/demos/accessible/index.html index 14bc2c952..af424764d 100644 --- a/demos/accessible/index.html +++ b/demos/accessible/index.html @@ -19,6 +19,7 @@ + @@ -31,7 +32,7 @@ - + -

Blockly > - Demos > Accessible Blockly

+

+ Blockly > + Demos > Accessible Blockly +

This is a simple demo of a version of Blockly designed for screen readers.

@@ -70,7 +73,9 @@ var ACCESSIBLE_GLOBALS = { // Additional buttons for the workspace toolbar that // go before the "Clear Workspace" button. - toolbarButtonConfig: [] + toolbarButtonConfig: [], + // Prefix of path to sound files. + mediaPathPrefix: '../../accessible/media/' }; document.addEventListener('DOMContentLoaded', function() { ng.platform.browser.bootstrap(blocklyApp.AppView);