annotate core/modules/ckeditor/js/views/AuralView.es6.js @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
rev   line source
Chris@0 1 /**
Chris@0 2 * @file
Chris@0 3 * A Backbone View that provides the aural view of CKEditor toolbar
Chris@0 4 * configuration.
Chris@0 5 */
Chris@0 6
Chris@0 7 (function (Drupal, Backbone, $) {
Chris@0 8 Drupal.ckeditor.AuralView = Backbone.View.extend(/** @lends Drupal.ckeditor.AuralView# */{
Chris@0 9
Chris@0 10 /**
Chris@0 11 * @type {object}
Chris@0 12 */
Chris@0 13 events: {
Chris@0 14 'click .ckeditor-buttons a': 'announceButtonHelp',
Chris@0 15 'click .ckeditor-multiple-buttons a': 'announceSeparatorHelp',
Chris@0 16 'focus .ckeditor-button a': 'onFocus',
Chris@0 17 'focus .ckeditor-button-separator a': 'onFocus',
Chris@0 18 'focus .ckeditor-toolbar-group': 'onFocus',
Chris@0 19 },
Chris@0 20
Chris@0 21 /**
Chris@0 22 * Backbone View for CKEditor toolbar configuration; aural UX (output only).
Chris@0 23 *
Chris@0 24 * @constructs
Chris@0 25 *
Chris@0 26 * @augments Backbone.View
Chris@0 27 */
Chris@0 28 initialize() {
Chris@0 29 // Announce the button and group positions when the model is no longer
Chris@0 30 // dirty.
Chris@0 31 this.listenTo(this.model, 'change:isDirty', this.announceMove);
Chris@0 32 },
Chris@0 33
Chris@0 34 /**
Chris@0 35 * Calls announce on buttons and groups when their position is changed.
Chris@0 36 *
Chris@0 37 * @param {Drupal.ckeditor.ConfigurationModel} model
Chris@0 38 * The ckeditor configuration model.
Chris@0 39 * @param {bool} isDirty
Chris@0 40 * A model attribute that indicates if the changed toolbar configuration
Chris@0 41 * has been stored or not.
Chris@0 42 */
Chris@0 43 announceMove(model, isDirty) {
Chris@0 44 // Announce the position of a button or group after the model has been
Chris@0 45 // updated.
Chris@0 46 if (!isDirty) {
Chris@0 47 const item = document.activeElement || null;
Chris@0 48 if (item) {
Chris@0 49 const $item = $(item);
Chris@0 50 if ($item.hasClass('ckeditor-toolbar-group')) {
Chris@0 51 this.announceButtonGroupPosition($item);
Chris@0 52 }
Chris@0 53 else if ($item.parent().hasClass('ckeditor-button')) {
Chris@0 54 this.announceButtonPosition($item.parent());
Chris@0 55 }
Chris@0 56 }
Chris@0 57 }
Chris@0 58 },
Chris@0 59
Chris@0 60 /**
Chris@0 61 * Handles the focus event of elements in the active and available toolbars.
Chris@0 62 *
Chris@0 63 * @param {jQuery.Event} event
Chris@0 64 * The focus event that was triggered.
Chris@0 65 */
Chris@0 66 onFocus(event) {
Chris@0 67 event.stopPropagation();
Chris@0 68
Chris@0 69 const $originalTarget = $(event.target);
Chris@0 70 const $currentTarget = $(event.currentTarget);
Chris@0 71 const $parent = $currentTarget.parent();
Chris@0 72 if ($parent.hasClass('ckeditor-button') || $parent.hasClass('ckeditor-button-separator')) {
Chris@0 73 this.announceButtonPosition($currentTarget.parent());
Chris@0 74 }
Chris@0 75 else if ($originalTarget.attr('role') !== 'button' && $currentTarget.hasClass('ckeditor-toolbar-group')) {
Chris@0 76 this.announceButtonGroupPosition($currentTarget);
Chris@0 77 }
Chris@0 78 },
Chris@0 79
Chris@0 80 /**
Chris@0 81 * Announces the current position of a button group.
Chris@0 82 *
Chris@0 83 * @param {jQuery} $group
Chris@0 84 * A jQuery set that contains an li element that wraps a group of buttons.
Chris@0 85 */
Chris@0 86 announceButtonGroupPosition($group) {
Chris@0 87 const $groups = $group.parent().children();
Chris@0 88 const $row = $group.closest('.ckeditor-row');
Chris@0 89 const $rows = $row.parent().children();
Chris@0 90 const position = $groups.index($group) + 1;
Chris@0 91 const positionCount = $groups.not('.placeholder').length;
Chris@0 92 const row = $rows.index($row) + 1;
Chris@0 93 const rowCount = $rows.not('.placeholder').length;
Chris@0 94 let text = Drupal.t('@groupName button group in position @position of @positionCount in row @row of @rowCount.', {
Chris@0 95 '@groupName': $group.attr('data-drupal-ckeditor-toolbar-group-name'),
Chris@0 96 '@position': position,
Chris@0 97 '@positionCount': positionCount,
Chris@0 98 '@row': row,
Chris@0 99 '@rowCount': rowCount,
Chris@0 100 });
Chris@0 101 // If this position is the first in the last row then tell the user that
Chris@0 102 // pressing the down arrow key will create a new row.
Chris@0 103 if (position === 1 && row === rowCount) {
Chris@0 104 text += '\n';
Chris@0 105 text += Drupal.t('Press the down arrow key to create a new row.');
Chris@0 106 }
Chris@0 107 Drupal.announce(text, 'assertive');
Chris@0 108 },
Chris@0 109
Chris@0 110 /**
Chris@0 111 * Announces current button position.
Chris@0 112 *
Chris@0 113 * @param {jQuery} $button
Chris@0 114 * A jQuery set that contains an li element that wraps a button.
Chris@0 115 */
Chris@0 116 announceButtonPosition($button) {
Chris@0 117 const $row = $button.closest('.ckeditor-row');
Chris@0 118 const $rows = $row.parent().children();
Chris@0 119 const $buttons = $button.closest('.ckeditor-buttons').children();
Chris@0 120 const $group = $button.closest('.ckeditor-toolbar-group');
Chris@0 121 const $groups = $group.parent().children();
Chris@0 122 const groupPosition = $groups.index($group) + 1;
Chris@0 123 const groupPositionCount = $groups.not('.placeholder').length;
Chris@0 124 const position = $buttons.index($button) + 1;
Chris@0 125 const positionCount = $buttons.length;
Chris@0 126 const row = $rows.index($row) + 1;
Chris@0 127 const rowCount = $rows.not('.placeholder').length;
Chris@0 128 // The name of the button separator is 'button separator' and its type
Chris@0 129 // is 'separator', so we do not want to print the type of this item,
Chris@0 130 // otherwise the UA will speak 'button separator separator'.
Chris@0 131 const type = ($button.attr('data-drupal-ckeditor-type') === 'separator') ? '' : Drupal.t('button');
Chris@0 132 let text;
Chris@0 133 // The button is located in the available button set.
Chris@0 134 if ($button.closest('.ckeditor-toolbar-disabled').length > 0) {
Chris@0 135 text = Drupal.t('@name @type.', {
Chris@0 136 '@name': $button.children().attr('aria-label'),
Chris@0 137 '@type': type,
Chris@0 138 });
Chris@0 139 text += `\n${Drupal.t('Press the down arrow key to activate.')}`;
Chris@0 140
Chris@0 141 Drupal.announce(text, 'assertive');
Chris@0 142 }
Chris@0 143 // The button is in the active toolbar.
Chris@0 144 else if ($group.not('.placeholder').length === 1) {
Chris@0 145 text = Drupal.t('@name @type in position @position of @positionCount in @groupName button group in row @row of @rowCount.', {
Chris@0 146 '@name': $button.children().attr('aria-label'),
Chris@0 147 '@type': type,
Chris@0 148 '@position': position,
Chris@0 149 '@positionCount': positionCount,
Chris@0 150 '@groupName': $group.attr('data-drupal-ckeditor-toolbar-group-name'),
Chris@0 151 '@row': row,
Chris@0 152 '@rowCount': rowCount,
Chris@0 153 });
Chris@0 154 // If this position is the first in the last row then tell the user that
Chris@0 155 // pressing the down arrow key will create a new row.
Chris@0 156 if (groupPosition === 1 && position === 1 && row === rowCount) {
Chris@0 157 text += '\n';
Chris@0 158 text += Drupal.t('Press the down arrow key to create a new button group in a new row.');
Chris@0 159 }
Chris@0 160 // If this position is the last one in this row then tell the user that
Chris@0 161 // moving the button to the next group will create a new group.
Chris@0 162 if (groupPosition === groupPositionCount && position === positionCount) {
Chris@0 163 text += '\n';
Chris@0 164 text += Drupal.t('This is the last group. Move the button forward to create a new group.');
Chris@0 165 }
Chris@0 166 Drupal.announce(text, 'assertive');
Chris@0 167 }
Chris@0 168 },
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Provides help information when a button is clicked.
Chris@0 172 *
Chris@0 173 * @param {jQuery.Event} event
Chris@0 174 * The click event for the button click.
Chris@0 175 */
Chris@0 176 announceButtonHelp(event) {
Chris@0 177 const $link = $(event.currentTarget);
Chris@0 178 const $button = $link.parent();
Chris@0 179 const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
Chris@0 180 let message;
Chris@0 181
Chris@0 182 if (enabled) {
Chris@0 183 message = Drupal.t('The "@name" button is currently enabled.', {
Chris@0 184 '@name': $link.attr('aria-label'),
Chris@0 185 });
Chris@0 186 message += `\n${Drupal.t('Use the keyboard arrow keys to change the position of this button.')}`;
Chris@0 187 message += `\n${Drupal.t('Press the up arrow key on the top row to disable the button.')}`;
Chris@0 188 }
Chris@0 189 else {
Chris@0 190 message = Drupal.t('The "@name" button is currently disabled.', {
Chris@0 191 '@name': $link.attr('aria-label'),
Chris@0 192 });
Chris@0 193 message += `\n${Drupal.t('Use the down arrow key to move this button into the active toolbar.')}`;
Chris@0 194 }
Chris@0 195 Drupal.announce(message);
Chris@0 196 event.preventDefault();
Chris@0 197 },
Chris@0 198
Chris@0 199 /**
Chris@0 200 * Provides help information when a separator is clicked.
Chris@0 201 *
Chris@0 202 * @param {jQuery.Event} event
Chris@0 203 * The click event for the separator click.
Chris@0 204 */
Chris@0 205 announceSeparatorHelp(event) {
Chris@0 206 const $link = $(event.currentTarget);
Chris@0 207 const $button = $link.parent();
Chris@0 208 const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
Chris@0 209 let message;
Chris@0 210
Chris@0 211 if (enabled) {
Chris@0 212 message = Drupal.t('This @name is currently enabled.', {
Chris@0 213 '@name': $link.attr('aria-label'),
Chris@0 214 });
Chris@0 215 message += `\n${Drupal.t('Use the keyboard arrow keys to change the position of this separator.')}`;
Chris@0 216 }
Chris@0 217 else {
Chris@0 218 message = Drupal.t('Separators are used to visually split individual buttons.');
Chris@0 219 message += `\n${Drupal.t('This @name is currently disabled.', {
Chris@0 220 '@name': $link.attr('aria-label'),
Chris@0 221 })}`;
Chris@0 222 message += `\n${Drupal.t('Use the down arrow key to move this separator into the active toolbar.')}`;
Chris@0 223 message += `\n${Drupal.t('You may add multiple separators to each button group.')}`;
Chris@0 224 }
Chris@0 225 Drupal.announce(message);
Chris@0 226 event.preventDefault();
Chris@0 227 },
Chris@0 228 });
Chris@0 229 }(Drupal, Backbone, jQuery));