diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js index f026be0..e09ce9f 100644 --- a/core/modules/ckeditor/js/ckeditor.admin.js +++ b/core/modules/ckeditor/js/ckeditor.admin.js @@ -4,6 +4,8 @@ Drupal.ckeditor = Drupal.ckeditor || {}; +var $messages; // Aria-live element for speaking application state. + Drupal.behaviors.ckeditorAdmin = { attach: function (context, settings) { var $context = $(context); @@ -49,10 +51,18 @@ Drupal.behaviors.ckeditorAdmin = { $toolbarAdmin.find('a.ckeditor-row-remove').hide(); } + // Add aural UI focus updates when for individual toolbars. + $toolbarAdmin.on('focus.ckeditor', '.ckeditor-buttons', {'focus': true}, grantRowFocus); + $toolbarAdmin.on('blur.ckeditor', '.ckeditor-buttons', {'focus': false}, grantRowFocus); + // Identify the aria-live element for interaction updates for screen + // readers. + $messages = $('#ckeditor-button-configuration-aria-live'); + /** * Event callback for keypress. Move buttons based on arrow keys. */ function adminToolbarMoveButton(event) { + var label = Drupal.t('@label button', {'@label': $(this).attr('aria-label')}); var $button = $(this).parent(); var $currentRow = $button.closest('.ckeditor-buttons'); var $destinationRow = null; @@ -66,7 +76,6 @@ Drupal.behaviors.ckeditorAdmin = { break; case 38: // Up arrow. case 63232: // Safari up arrow. - console.log($toolbarRows); $destinationRow = $($toolbarRows[$toolbarRows.index($currentRow) - 1]); break; case 39: // Right arrow. @@ -90,6 +99,12 @@ Drupal.behaviors.ckeditorAdmin = { else { $destinationRow.append($button); } + // Post the update to the aria-live message element. + $messages.text(Drupal.t('moved to @row, position @position of @totalPositions', { + '@row': getRowInfo($destinationRow), + '@position': (destinationPosition + 1), + '@totalPositions': $destinationRow.children().length + })); // Update the toolbar value field. adminToolbarValue(event, { item: $button }); } @@ -119,22 +134,21 @@ Drupal.behaviors.ckeditorAdmin = { var enabled = $button.closest('.ckeditor-toolbar-active').length > 0; var position = $button.index() + 1; // 1-based index for humans. var rowNumber = $toolbarRows.index($currentRow) + 1; - var $info = $('#ckeditor-button-configuration-aria-live'); var type = event.data.type; if (enabled) { if (type === 'separator') { - $info.text(Drupal.t('Separators are used to visually split individual buttons. This @name is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the separator or use the keyboard arrow keys to change the position of this separator.')); + $messages.text(Drupal.t('Separators are used to visually split individual buttons. This @name is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the separator or use the keyboard arrow keys to change the position of this separator.')); } else { - $info.text(Drupal.t('The @name button is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the buttons or use the keyboard arrow keys to change the position of this button.')); + $messages.text(Drupal.t('The @name button is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the buttons or use the keyboard arrow keys to change the position of this button.')); } } else { if (type === 'separator') { - $info.text(Drupal.t('Separators are used to visually split individual buttons. This @name is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this separator into the active toolbar. You may add multiple separators to each row.')); + $messages.text(Drupal.t('Separators are used to visually split individual buttons. This @name is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this separator into the active toolbar. You may add multiple separators to each row.')); } else { - $info.text(Drupal.t('The @name button is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this button into the active toolbar.')); + $messages.text(Drupal.t('The @name button is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this button into the active toolbar.')); } } $link.focus(); @@ -151,6 +165,8 @@ Drupal.behaviors.ckeditorAdmin = { $toolbarRows = $toolbarAdmin.find('.ckeditor-buttons'); $this.siblings('a').show(); redrawToolbarGradient(); + // Post the update to the aria-live message element. + $messages.text(Drupal.t('row number @count added.', {'@count': ($rows.length + 1)})); event.preventDefault(); } @@ -171,6 +187,8 @@ Drupal.behaviors.ckeditorAdmin = { $toolbarRows = $toolbarAdmin.find('.ckeditor-buttons'); redrawToolbarGradient(); } + // Post the update to the aria-live message element. + $messages.text(Drupal.t('row removed. @count row@plural remaining.', {'@count': ($rows.length - 1), '@plural': ((($rows.length - 1) === 1 ) ? '' : 's')})); event.preventDefault(); } @@ -212,4 +230,48 @@ Drupal.behaviors.ckeditorAdmin = { } }; +/** + * Returns a string describing the type and index of a toolbar row. + * + * @param {jQuery} $row + * A jQuery object containing a .ckeditor-button row. + * + * @return {String} + * A string describing the type and index of a toolbar row. + */ +function getRowInfo ($row) { + var output = ''; + var row; + // Determine if this is an active row or an available row. + if ($row.closest('.ckeditor-toolbar-disabled').length > 0) { + row = $('.ckeditor-toolbar-disabled').find('.ckeditor-buttons').index($row) + 1; + output += Drupal.t('available button row @row', {'@row': row}); + } + else { + row = $('.ckeditor-toolbar-active').find('.ckeditor-buttons').index($row) + 1; + output += Drupal.t('active button row @row', {'@row': row}); + } + return output; +} + +/** + * Applies or removes the focused class to a toolbar row. + * + * When a button in a toolbar is focused, focus is triggered on the containing + * toolbar row. When a row is focused, the state change is announced through + * the aria-live message area. + * + * @param {jQuery} event + * A jQuery event. + */ +function grantRowFocus (event) { + var $row = $(this); + // Indicate that the current row has focus. + $row.toggleClass('focused', event.data.focus); + // Post the update to the aria-live message element. + if (event.data.focus) { + $messages.text(Drupal.t('@row', {'@row': getRowInfo($row)})); + } +} + })(jQuery, Drupal);