diff --git a/core/modules/ckeditor/ckeditor.admin.inc b/core/modules/ckeditor/ckeditor.admin.inc index e99518a..73f856b 100644 --- a/core/modules/ckeditor/ckeditor.admin.inc +++ b/core/modules/ckeditor/ckeditor.admin.inc @@ -125,10 +125,6 @@ function theme_ckeditor_settings_toolbar($variables) { $output .= '' . t('Toolbar configuration') . ''; $output .= '
'; - // aria-live region for outputing aural information about the state of the - // configuration. - $output .= '
'; - $output .= '
' . t('Move a button into the Active toolbar to enable it, or into the list of Available buttons to disable it. Use dividers to create button groups. Buttons may be moved with the mouse or keyboard arrow keys.') . '
'; $output .= '
'; diff --git a/core/modules/ckeditor/css/ckeditor.admin.css b/core/modules/ckeditor/css/ckeditor.admin.css index 5e1b2ab..191d8aa 100644 --- a/core/modules/ckeditor/css/ckeditor.admin.css +++ b/core/modules/ckeditor/css/ckeditor.admin.css @@ -96,9 +96,10 @@ ul.ckeditor-buttons li .cke-icon-only { width: 16px; } ul.ckeditor-buttons li a:focus, +ul.ckeditor-buttons li a:active, ul.ckeditor-multiple-buttons li a:focus { + outline: thin dotted; z-index: 11; /* Ensure focused buttons show their outline on all sides. */ - outline: 1px dotted #333; } ul.ckeditor-buttons li:first-child a { border-top-left-radius: 2px; /* LTR */ diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js index 338ae6e..df71caf 100644 --- a/core/modules/ckeditor/js/ckeditor.admin.js +++ b/core/modules/ckeditor/js/ckeditor.admin.js @@ -4,9 +4,6 @@ Drupal.ckeditor = Drupal.ckeditor || {}; -// Aria-live element for speaking application state. -var $messages; - Drupal.behaviors.ckeditorAdmin = { attach: function (context) { var $context = $(context); @@ -58,14 +55,14 @@ Drupal.behaviors.ckeditorAdmin = { else { $destinationRow.append($button); } + // Update the toolbar value field. + adminToolbarValue(event, { item: $button }); // Post the update to the aria-live message element. - $messages.text(Drupal.t('moved to @row, position @position of @totalPositions', { - '@row': getRowInfo($destinationRow), + Drupal.announce(Drupal.t('Moved to @row, position @position of @totalPositions.', { + '@row': getRowName($destinationRow), '@position': (destinationPosition + 1), '@totalPositions': $destinationRow.children().length })); - // Update the toolbar value field. - adminToolbarValue(event, { item: $button }); } event.preventDefault(); } @@ -91,17 +88,15 @@ Drupal.behaviors.ckeditorAdmin = { var $button = $link.parent(); var $currentRow = $button.closest('.ckeditor-buttons'); 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 type = event.data.type; var message; if (enabled) { if (type === 'separator') { - message = 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.'); + message = Drupal.t('Separators are used to visually split individual buttons. This @name is currently enabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag and drop the separator or use the keyboard arrow keys to change the position of this separator.'); } else { - message = 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.'); + message = Drupal.t('The "@name" button is currently enabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag and drop the buttons or use the keyboard arrow keys to change the position of this button.'); } } else { @@ -109,10 +104,10 @@ Drupal.behaviors.ckeditorAdmin = { message = 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 { - message = 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.'); + message = Drupal.t('The "@name" button is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the down arrow key to move this button into the active toolbar.'); } } - $messages.text(message); + alert(message); $link.focus(); event.preventDefault(); } @@ -129,7 +124,7 @@ Drupal.behaviors.ckeditorAdmin = { $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)})); + Drupal.announce(Drupal.t('Row number @count added.', {'@count': ($rows.length + 1)})); event.preventDefault(); } @@ -151,7 +146,7 @@ Drupal.behaviors.ckeditorAdmin = { redrawToolbarGradient(); } // Post the update to the aria-live message element. - $messages.text(Drupal.formatPlural($rows.length - 1, 'row removed. 1 row remaining.', 'row removed. @count rows remaining.')); + Drupal.announce(Drupal.t('Row removed.') + ' ' + Drupal.formatPlural($rows.length - 1, 'One row remaining.', '@count rows remaining.')); event.preventDefault(); } @@ -166,8 +161,14 @@ Drupal.behaviors.ckeditorAdmin = { } /** - * jQuery Sortable stop event. Save updated toolbar positions to the - * textarea. + * jQuery Sortable start event. Remove focus from any other buttons. + */ + function adminToolbarStartDrag (event, ui) { + $toolbarRows.find('a:focus').blur(); + } + + /** + * jQuery Sortable stop event. Save new toolbar positions to the textarea. */ function adminToolbarValue (event, ui) { var oldToolbarConfig = JSON.parse($textarea.val()); @@ -370,6 +371,7 @@ Drupal.behaviors.ckeditorAdmin = { forcePlaceholderSize: true, tolerance: 'pointer', cursor: 'move', + start: adminToolbarStartDrag, stop: adminToolbarValue }; // Add the toolbar to the page. @@ -402,10 +404,7 @@ Drupal.behaviors.ckeditorAdmin = { } // Add aural UI focus updates when for individual toolbars. - $toolbarAdmin.on('focus.ckeditor', '.ckeditor-buttons', grantRowFocus); - // Identify the aria-live element for interaction updates for screen - // readers. - $messages = $('#ckeditor-button-configuration-aria-live'); + $toolbarAdmin.on('focus.ckeditor', '.ckeditor-buttons a', announceButtonPosition); getCKEditorFeatures(hiddenCKEditorConfig, function (features) { featuresMetadata = features; @@ -477,43 +476,36 @@ Drupal.behaviors.ckeditorAdmin = { * A jQuery object containing a .ckeditor-button row. * * @return {String} - * A string describing the type and index of a toolbar row. + * A string describing a toolbar row. */ -function getRowInfo ($row) { +function getRowName ($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}); + output += Drupal.t('available buttons row'); } else { row = $('.ckeditor-toolbar-active').find('.ckeditor-buttons').index($row) + 1; - output += Drupal.t('active button row @row', {'@row': row}); + output += Drupal.t('active buttons 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. + * Announces current button position when a button receives focus. * * @param {jQuery} event * A jQuery event. */ -function grantRowFocus (event) { - var $row = $(event.currentTarget); - // Remove the focused class from all other toolbars. - $('.ckeditor-buttons.focused').not($row).removeClass('focused'); - // Post the update to the aria-live message element. - if (!$row.hasClass('focused')) { - // Indicate that the current row has focus. - $row.addClass('focused'); - $messages.text(Drupal.t('@row', {'@row': getRowInfo($row)})); - } +function announceButtonPosition (event) { + var $button = $(event.currentTarget); + var $row = $button.closest('.ckeditor-buttons'); + Drupal.announce(Drupal.t('Position @position of @totalPositions in @row.', { + '@position': $row.find('li a').index($button) + 1, + '@totalPositions': $row.children().length, + '@row': getRowName($row) + })); } })(jQuery, Drupal, drupalSettings, CKEDITOR, _);