annotate core/modules/ckeditor/js/ckeditor.admin.es6.js @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 /**
Chris@0 2 * @file
Chris@0 3 * CKEditor button and group configuration user interface.
Chris@0 4 */
Chris@0 5
Chris@17 6 (function($, Drupal, drupalSettings, _) {
Chris@0 7 Drupal.ckeditor = Drupal.ckeditor || {};
Chris@0 8
Chris@0 9 /**
Chris@0 10 * Sets config behaviour and creates config views for the CKEditor toolbar.
Chris@0 11 *
Chris@0 12 * @type {Drupal~behavior}
Chris@0 13 *
Chris@0 14 * @prop {Drupal~behaviorAttach} attach
Chris@0 15 * Attaches admin behaviour to the CKEditor buttons.
Chris@0 16 * @prop {Drupal~behaviorDetach} detach
Chris@0 17 * Detaches admin behaviour from the CKEditor buttons on 'unload'.
Chris@0 18 */
Chris@0 19 Drupal.behaviors.ckeditorAdmin = {
Chris@0 20 attach(context) {
Chris@0 21 // Process the CKEditor configuration fragment once.
Chris@17 22 const $configurationForm = $(context)
Chris@17 23 .find('.ckeditor-toolbar-configuration')
Chris@17 24 .once('ckeditor-configuration');
Chris@0 25 if ($configurationForm.length) {
Chris@0 26 const $textarea = $configurationForm
Chris@0 27 // Hide the textarea that contains the serialized representation of the
Chris@0 28 // CKEditor configuration.
Chris@0 29 .find('.js-form-item-editor-settings-toolbar-button-groups')
Chris@0 30 .hide()
Chris@0 31 // Return the textarea child node from this expression.
Chris@0 32 .find('textarea');
Chris@0 33
Chris@0 34 // The HTML for the CKEditor configuration is assembled on the server
Chris@0 35 // and sent to the client as a serialized DOM fragment.
Chris@0 36 $configurationForm.append(drupalSettings.ckeditor.toolbarAdmin);
Chris@0 37
Chris@0 38 // Create a configuration model.
Chris@14 39 Drupal.ckeditor.models.Model = new Drupal.ckeditor.Model({
Chris@0 40 $textarea,
Chris@0 41 activeEditorConfig: JSON.parse($textarea.val()),
Chris@0 42 hiddenEditorConfig: drupalSettings.ckeditor.hiddenCKEditorConfig,
Chris@0 43 });
Chris@0 44
Chris@0 45 // Create the configuration Views.
Chris@0 46 const viewDefaults = {
Chris@14 47 model: Drupal.ckeditor.models.Model,
Chris@0 48 el: $('.ckeditor-toolbar-configuration'),
Chris@0 49 };
Chris@0 50 Drupal.ckeditor.views = {
Chris@0 51 controller: new Drupal.ckeditor.ControllerView(viewDefaults),
Chris@0 52 visualView: new Drupal.ckeditor.VisualView(viewDefaults),
Chris@0 53 keyboardView: new Drupal.ckeditor.KeyboardView(viewDefaults),
Chris@0 54 auralView: new Drupal.ckeditor.AuralView(viewDefaults),
Chris@0 55 };
Chris@0 56 }
Chris@0 57 },
Chris@0 58 detach(context, settings, trigger) {
Chris@0 59 // Early-return if the trigger for detachment is something else than
Chris@0 60 // unload.
Chris@0 61 if (trigger !== 'unload') {
Chris@0 62 return;
Chris@0 63 }
Chris@0 64
Chris@0 65 // We're detaching because CKEditor as text editor has been disabled; this
Chris@0 66 // really means that all CKEditor toolbar buttons have been removed.
Chris@0 67 // Hence,all editor features will be removed, so any reactions from
Chris@0 68 // filters will be undone.
Chris@17 69 const $configurationForm = $(context)
Chris@17 70 .find('.ckeditor-toolbar-configuration')
Chris@17 71 .findOnce('ckeditor-configuration');
Chris@17 72 if (
Chris@17 73 $configurationForm.length &&
Chris@17 74 Drupal.ckeditor.models &&
Chris@17 75 Drupal.ckeditor.models.Model
Chris@17 76 ) {
Chris@0 77 const config = Drupal.ckeditor.models.Model.toJSON().activeEditorConfig;
Chris@0 78 const buttons = Drupal.ckeditor.views.controller.getButtonList(config);
Chris@17 79 const $activeToolbar = $('.ckeditor-toolbar-configuration').find(
Chris@17 80 '.ckeditor-toolbar-active',
Chris@17 81 );
Chris@0 82 for (let i = 0; i < buttons.length; i++) {
Chris@17 83 $activeToolbar.trigger('CKEditorToolbarChanged', [
Chris@17 84 'removed',
Chris@17 85 buttons[i],
Chris@17 86 ]);
Chris@0 87 }
Chris@0 88 }
Chris@0 89 },
Chris@0 90 };
Chris@0 91
Chris@0 92 /**
Chris@0 93 * CKEditor configuration UI methods of Backbone objects.
Chris@0 94 *
Chris@0 95 * @namespace
Chris@0 96 */
Chris@0 97 Drupal.ckeditor = {
Chris@0 98 /**
Chris@0 99 * A hash of View instances.
Chris@0 100 *
Chris@0 101 * @type {object}
Chris@0 102 */
Chris@0 103 views: {},
Chris@0 104
Chris@0 105 /**
Chris@0 106 * A hash of Model instances.
Chris@0 107 *
Chris@0 108 * @type {object}
Chris@0 109 */
Chris@0 110 models: {},
Chris@0 111
Chris@0 112 /**
Chris@0 113 * Translates changes in CKEditor config DOM structure to the config model.
Chris@0 114 *
Chris@0 115 * If the button is moved within an existing group, the DOM structure is
Chris@0 116 * simply translated to a configuration model. If the button is moved into a
Chris@0 117 * new group placeholder, then a process is launched to name that group
Chris@0 118 * before the button move is translated into configuration.
Chris@0 119 *
Chris@0 120 * @param {Backbone.View} view
Chris@0 121 * The Backbone View that invoked this function.
Chris@0 122 * @param {jQuery} $button
Chris@0 123 * A jQuery set that contains an li element that wraps a button element.
Chris@0 124 * @param {function} callback
Chris@0 125 * A callback to invoke after the button group naming modal dialog has
Chris@0 126 * been closed.
Chris@0 127 *
Chris@0 128 */
Chris@0 129 registerButtonMove(view, $button, callback) {
Chris@0 130 const $group = $button.closest('.ckeditor-toolbar-group');
Chris@0 131
Chris@0 132 // If dropped in a placeholder button group, the user must name it.
Chris@0 133 if ($group.hasClass('placeholder')) {
Chris@0 134 if (view.isProcessing) {
Chris@0 135 return;
Chris@0 136 }
Chris@0 137 view.isProcessing = true;
Chris@0 138
Chris@0 139 Drupal.ckeditor.openGroupNameDialog(view, $group, callback);
Chris@17 140 } else {
Chris@0 141 view.model.set('isDirty', true);
Chris@0 142 callback(true);
Chris@0 143 }
Chris@0 144 },
Chris@0 145
Chris@0 146 /**
Chris@0 147 * Translates changes in CKEditor config DOM structure to the config model.
Chris@0 148 *
Chris@0 149 * Each row has a placeholder group at the end of the row. A user may not
Chris@0 150 * move an existing button group past the placeholder group at the end of a
Chris@0 151 * row.
Chris@0 152 *
Chris@0 153 * @param {Backbone.View} view
Chris@0 154 * The Backbone View that invoked this function.
Chris@0 155 * @param {jQuery} $group
Chris@0 156 * A jQuery set that contains an li element that wraps a group of buttons.
Chris@0 157 */
Chris@0 158 registerGroupMove(view, $group) {
Chris@0 159 // Remove placeholder classes if necessary.
Chris@0 160 let $row = $group.closest('.ckeditor-row');
Chris@0 161 if ($row.hasClass('placeholder')) {
Chris@0 162 $row.removeClass('placeholder');
Chris@0 163 }
Chris@0 164 // If there are any rows with just a placeholder group, mark the row as a
Chris@0 165 // placeholder.
Chris@17 166 $row
Chris@17 167 .parent()
Chris@17 168 .children()
Chris@17 169 .each(function() {
Chris@17 170 $row = $(this);
Chris@17 171 if (
Chris@17 172 $row.find('.ckeditor-toolbar-group').not('.placeholder').length ===
Chris@17 173 0
Chris@17 174 ) {
Chris@17 175 $row.addClass('placeholder');
Chris@17 176 }
Chris@17 177 });
Chris@0 178 view.model.set('isDirty', true);
Chris@0 179 },
Chris@0 180
Chris@0 181 /**
Chris@0 182 * Opens a dialog with a form for changing the title of a button group.
Chris@0 183 *
Chris@0 184 * @param {Backbone.View} view
Chris@0 185 * The Backbone View that invoked this function.
Chris@0 186 * @param {jQuery} $group
Chris@0 187 * A jQuery set that contains an li element that wraps a group of buttons.
Chris@0 188 * @param {function} callback
Chris@0 189 * A callback to invoke after the button group naming modal dialog has
Chris@0 190 * been closed.
Chris@0 191 */
Chris@0 192 openGroupNameDialog(view, $group, callback) {
Chris@17 193 callback = callback || function() {};
Chris@0 194
Chris@0 195 /**
Chris@0 196 * Validates the string provided as a button group title.
Chris@0 197 *
Chris@0 198 * @param {HTMLElement} form
Chris@0 199 * The form DOM element that contains the input with the new button
Chris@0 200 * group title string.
Chris@0 201 *
Chris@0 202 * @return {bool}
Chris@0 203 * Returns true when an error exists, otherwise returns false.
Chris@0 204 */
Chris@0 205 function validateForm(form) {
Chris@0 206 if (form.elements[0].value.length === 0) {
Chris@0 207 const $form = $(form);
Chris@0 208 if (!$form.hasClass('errors')) {
Chris@0 209 $form
Chris@0 210 .addClass('errors')
Chris@0 211 .find('input')
Chris@0 212 .addClass('error')
Chris@0 213 .attr('aria-invalid', 'true');
Chris@17 214 $(
Chris@17 215 `<div class="description" >${Drupal.t(
Chris@17 216 'Please provide a name for the button group.',
Chris@17 217 )}</div>`,
Chris@17 218 ).insertAfter(form.elements[0]);
Chris@0 219 }
Chris@0 220 return true;
Chris@0 221 }
Chris@0 222 return false;
Chris@0 223 }
Chris@0 224
Chris@0 225 /**
Chris@0 226 * Attempts to close the dialog; Validates user input.
Chris@0 227 *
Chris@0 228 * @param {string} action
Chris@0 229 * The dialog action chosen by the user: 'apply' or 'cancel'.
Chris@0 230 * @param {HTMLElement} form
Chris@0 231 * The form DOM element that contains the input with the new button
Chris@0 232 * group title string.
Chris@0 233 */
Chris@0 234 function closeDialog(action, form) {
Chris@0 235 /**
Chris@0 236 * Closes the dialog when the user cancels or supplies valid data.
Chris@0 237 */
Chris@0 238 function shutdown() {
Chris@17 239 // eslint-disable-next-line no-use-before-define
Chris@0 240 dialog.close(action);
Chris@0 241
Chris@0 242 // The processing marker can be deleted since the dialog has been
Chris@0 243 // closed.
Chris@0 244 delete view.isProcessing;
Chris@0 245 }
Chris@0 246
Chris@0 247 /**
Chris@0 248 * Applies a string as the name of a CKEditor button group.
Chris@0 249 *
Chris@0 250 * @param {jQuery} $group
Chris@0 251 * A jQuery set that contains an li element that wraps a group of
Chris@0 252 * buttons.
Chris@0 253 * @param {string} name
Chris@0 254 * The new name of the CKEditor button group.
Chris@0 255 */
Chris@0 256 function namePlaceholderGroup($group, name) {
Chris@0 257 // If it's currently still a placeholder, then that means we're
Chris@0 258 // creating a new group, and we must do some extra work.
Chris@0 259 if ($group.hasClass('placeholder')) {
Chris@0 260 // Remove all whitespace from the name, lowercase it and ensure
Chris@0 261 // HTML-safe encoding, then use this as the group ID for CKEditor
Chris@0 262 // configuration UI accessibility purposes only.
Chris@17 263 const groupID = `ckeditor-toolbar-group-aria-label-for-${Drupal.checkPlain(
Chris@17 264 name.toLowerCase().replace(/\s/g, '-'),
Chris@17 265 )}`;
Chris@0 266 $group
Chris@0 267 // Update the group container.
Chris@0 268 .removeAttr('aria-label')
Chris@0 269 .attr('data-drupal-ckeditor-type', 'group')
Chris@0 270 .attr('tabindex', 0)
Chris@0 271 // Update the group heading.
Chris@0 272 .children('.ckeditor-toolbar-group-name')
Chris@0 273 .attr('id', groupID)
Chris@0 274 .end()
Chris@0 275 // Update the group items.
Chris@0 276 .children('.ckeditor-toolbar-group-buttons')
Chris@0 277 .attr('aria-labelledby', groupID);
Chris@0 278 }
Chris@0 279
Chris@0 280 $group
Chris@0 281 .attr('data-drupal-ckeditor-toolbar-group-name', name)
Chris@0 282 .children('.ckeditor-toolbar-group-name')
Chris@0 283 .text(name);
Chris@0 284 }
Chris@0 285
Chris@0 286 // Invoke a user-provided callback and indicate failure.
Chris@0 287 if (action === 'cancel') {
Chris@0 288 shutdown();
Chris@0 289 callback(false, $group);
Chris@0 290 return;
Chris@0 291 }
Chris@0 292
Chris@0 293 // Validate that a group name was provided.
Chris@0 294 if (form && validateForm(form)) {
Chris@0 295 return;
Chris@0 296 }
Chris@0 297
Chris@0 298 // React to application of a valid group name.
Chris@0 299 if (action === 'apply') {
Chris@0 300 shutdown();
Chris@0 301 // Apply the provided name to the button group label.
Chris@17 302 namePlaceholderGroup(
Chris@17 303 $group,
Chris@17 304 Drupal.checkPlain(form.elements[0].value),
Chris@17 305 );
Chris@0 306 // Remove placeholder classes so that new placeholders will be
Chris@0 307 // inserted.
Chris@17 308 $group
Chris@17 309 .closest('.ckeditor-row.placeholder')
Chris@17 310 .addBack()
Chris@17 311 .removeClass('placeholder');
Chris@0 312
Chris@0 313 // Invoke a user-provided callback and indicate success.
Chris@0 314 callback(true, $group);
Chris@0 315
Chris@0 316 // Signal that the active toolbar DOM structure has changed.
Chris@0 317 view.model.set('isDirty', true);
Chris@0 318 }
Chris@0 319 }
Chris@0 320
Chris@0 321 // Create a Drupal dialog that will get a button group name from the user.
Chris@17 322 const $ckeditorButtonGroupNameForm = $(
Chris@17 323 Drupal.theme('ckeditorButtonGroupNameForm'),
Chris@17 324 );
Chris@14 325 const dialog = Drupal.dialog($ckeditorButtonGroupNameForm.get(0), {
Chris@0 326 title: Drupal.t('Button group name'),
Chris@0 327 dialogClass: 'ckeditor-name-toolbar-group',
Chris@0 328 resizable: false,
Chris@0 329 buttons: [
Chris@0 330 {
Chris@0 331 text: Drupal.t('Apply'),
Chris@0 332 click() {
Chris@0 333 closeDialog('apply', this);
Chris@0 334 },
Chris@0 335 primary: true,
Chris@0 336 },
Chris@0 337 {
Chris@0 338 text: Drupal.t('Cancel'),
Chris@0 339 click() {
Chris@0 340 closeDialog('cancel');
Chris@0 341 },
Chris@0 342 },
Chris@0 343 ],
Chris@0 344 open() {
Chris@0 345 const form = this;
Chris@0 346 const $form = $(this);
Chris@0 347 const $widget = $form.parent();
Chris@0 348 $widget.find('.ui-dialog-titlebar-close').remove();
Chris@0 349 // Set a click handler on the input and button in the form.
Chris@17 350 $widget.on('keypress.ckeditor', 'input, button', event => {
Chris@0 351 // React to enter key press.
Chris@0 352 if (event.keyCode === 13) {
Chris@0 353 const $target = $(event.currentTarget);
Chris@0 354 const data = $target.data('ui-button');
Chris@0 355 let action = 'apply';
Chris@0 356 // Assume 'apply', but take into account that the user might have
Chris@0 357 // pressed the enter key on the dialog buttons.
Chris@0 358 if (data && data.options && data.options.label) {
Chris@0 359 action = data.options.label.toLowerCase();
Chris@0 360 }
Chris@0 361 closeDialog(action, form);
Chris@0 362 event.stopPropagation();
Chris@0 363 event.stopImmediatePropagation();
Chris@0 364 event.preventDefault();
Chris@0 365 }
Chris@0 366 });
Chris@0 367 // Announce to the user that a modal dialog is open.
Chris@17 368 let text = Drupal.t(
Chris@17 369 'Editing the name of the new button group in a dialog.',
Chris@17 370 );
Chris@17 371 if (
Chris@17 372 typeof $group.attr('data-drupal-ckeditor-toolbar-group-name') !==
Chris@17 373 'undefined'
Chris@17 374 ) {
Chris@17 375 text = Drupal.t(
Chris@17 376 'Editing the name of the "@groupName" button group in a dialog.',
Chris@17 377 {
Chris@17 378 '@groupName': $group.attr(
Chris@17 379 'data-drupal-ckeditor-toolbar-group-name',
Chris@17 380 ),
Chris@17 381 },
Chris@17 382 );
Chris@0 383 }
Chris@0 384 Drupal.announce(text);
Chris@0 385 },
Chris@0 386 close(event) {
Chris@0 387 // Automatically destroy the DOM element that was used for the dialog.
Chris@0 388 $(event.target).remove();
Chris@0 389 },
Chris@0 390 });
Chris@17 391
Chris@0 392 // A modal dialog is used because the user must provide a button group
Chris@0 393 // name or cancel the button placement before taking any other action.
Chris@0 394 dialog.showModal();
Chris@0 395
Chris@17 396 $(
Chris@17 397 document
Chris@17 398 .querySelector('.ckeditor-name-toolbar-group')
Chris@17 399 .querySelector('input'),
Chris@17 400 )
Chris@0 401 // When editing, set the "group name" input in the form to the current
Chris@0 402 // value.
Chris@0 403 .attr('value', $group.attr('data-drupal-ckeditor-toolbar-group-name'))
Chris@0 404 // Focus on the "group name" input in the form.
Chris@0 405 .trigger('focus');
Chris@0 406 },
Chris@0 407 };
Chris@0 408
Chris@0 409 /**
Chris@0 410 * Automatically shows/hides settings of buttons-only CKEditor plugins.
Chris@0 411 *
Chris@0 412 * @type {Drupal~behavior}
Chris@0 413 *
Chris@0 414 * @prop {Drupal~behaviorAttach} attach
Chris@0 415 * Attaches show/hide behaviour to Plugin Settings buttons.
Chris@0 416 */
Chris@0 417 Drupal.behaviors.ckeditorAdminButtonPluginSettings = {
Chris@0 418 attach(context) {
Chris@0 419 const $context = $(context);
Chris@17 420 const $ckeditorPluginSettings = $context
Chris@17 421 .find('#ckeditor-plugin-settings')
Chris@17 422 .once('ckeditor-plugin-settings');
Chris@0 423 if ($ckeditorPluginSettings.length) {
Chris@0 424 // Hide all button-dependent plugin settings initially.
Chris@17 425 $ckeditorPluginSettings
Chris@17 426 .find('[data-ckeditor-buttons]')
Chris@17 427 .each(function() {
Chris@17 428 const $this = $(this);
Chris@17 429 if ($this.data('verticalTab')) {
Chris@17 430 $this.data('verticalTab').tabHide();
Chris@17 431 } else {
Chris@17 432 // On very narrow viewports, Vertical Tabs are disabled.
Chris@17 433 $this.hide();
Chris@17 434 }
Chris@17 435 $this.data('ckeditorButtonPluginSettingsActiveButtons', []);
Chris@17 436 });
Chris@0 437
Chris@0 438 // Whenever a button is added or removed, check if we should show or
Chris@0 439 // hide the corresponding plugin settings. (Note that upon
Chris@0 440 // initialization, each button that already is part of the toolbar still
Chris@0 441 // is considered "added", hence it also works correctly for buttons that
Chris@0 442 // were added previously.)
Chris@0 443 $context
Chris@0 444 .find('.ckeditor-toolbar-active')
Chris@0 445 .off('CKEditorToolbarChanged.ckeditorAdminPluginSettings')
Chris@17 446 .on(
Chris@17 447 'CKEditorToolbarChanged.ckeditorAdminPluginSettings',
Chris@17 448 (event, action, button) => {
Chris@17 449 const $pluginSettings = $ckeditorPluginSettings.find(
Chris@17 450 `[data-ckeditor-buttons~=${button}]`,
Chris@17 451 );
Chris@0 452
Chris@17 453 // No settings for this button.
Chris@17 454 if ($pluginSettings.length === 0) {
Chris@17 455 return;
Chris@17 456 }
Chris@0 457
Chris@17 458 const verticalTab = $pluginSettings.data('verticalTab');
Chris@17 459 const activeButtons = $pluginSettings.data(
Chris@17 460 'ckeditorButtonPluginSettingsActiveButtons',
Chris@17 461 );
Chris@17 462 if (action === 'added') {
Chris@17 463 activeButtons.push(button);
Chris@17 464 // Show this plugin's settings if >=1 of its buttons are active.
Chris@0 465 if (verticalTab) {
Chris@17 466 verticalTab.tabShow();
Chris@17 467 } else {
Chris@17 468 // On very narrow viewports, Vertical Tabs remain fieldsets.
Chris@17 469 $pluginSettings.show();
Chris@0 470 }
Chris@17 471 } else {
Chris@17 472 // Remove this button from the list of active buttons.
Chris@17 473 activeButtons.splice(activeButtons.indexOf(button), 1);
Chris@17 474 // Show this plugin's settings 0 of its buttons are active.
Chris@17 475 if (activeButtons.length === 0) {
Chris@17 476 if (verticalTab) {
Chris@17 477 verticalTab.tabHide();
Chris@17 478 } else {
Chris@17 479 // On very narrow viewports, Vertical Tabs are disabled.
Chris@17 480 $pluginSettings.hide();
Chris@17 481 }
Chris@0 482 }
Chris@0 483 }
Chris@17 484 $pluginSettings.data(
Chris@17 485 'ckeditorButtonPluginSettingsActiveButtons',
Chris@17 486 activeButtons,
Chris@17 487 );
Chris@17 488 },
Chris@17 489 );
Chris@0 490 }
Chris@0 491 },
Chris@0 492 };
Chris@0 493
Chris@0 494 /**
Chris@0 495 * Themes a blank CKEditor row.
Chris@0 496 *
Chris@0 497 * @return {string}
Chris@0 498 * A HTML string for a CKEditor row.
Chris@0 499 */
Chris@17 500 Drupal.theme.ckeditorRow = function() {
Chris@0 501 return '<li class="ckeditor-row placeholder" role="group"><ul class="ckeditor-toolbar-groups clearfix"></ul></li>';
Chris@0 502 };
Chris@0 503
Chris@0 504 /**
Chris@0 505 * Themes a blank CKEditor button group.
Chris@0 506 *
Chris@0 507 * @return {string}
Chris@0 508 * A HTML string for a CKEditor button group.
Chris@0 509 */
Chris@17 510 Drupal.theme.ckeditorToolbarGroup = function() {
Chris@0 511 let group = '';
Chris@17 512 group += `<li class="ckeditor-toolbar-group placeholder" role="presentation" aria-label="${Drupal.t(
Chris@17 513 'Place a button to create a new button group.',
Chris@17 514 )}">`;
Chris@17 515 group += `<h3 class="ckeditor-toolbar-group-name">${Drupal.t(
Chris@17 516 'New group',
Chris@17 517 )}</h3>`;
Chris@17 518 group +=
Chris@17 519 '<ul class="ckeditor-buttons ckeditor-toolbar-group-buttons" role="toolbar" data-drupal-ckeditor-button-sorting="target"></ul>';
Chris@0 520 group += '</li>';
Chris@0 521 return group;
Chris@0 522 };
Chris@0 523
Chris@0 524 /**
Chris@0 525 * Themes a form for changing the title of a CKEditor button group.
Chris@0 526 *
Chris@0 527 * @return {string}
Chris@0 528 * A HTML string for the form for the title of a CKEditor button group.
Chris@0 529 */
Chris@17 530 Drupal.theme.ckeditorButtonGroupNameForm = function() {
Chris@0 531 return '<form><input name="group-name" required="required"></form>';
Chris@0 532 };
Chris@0 533
Chris@0 534 /**
Chris@0 535 * Themes a button that will toggle the button group names in active config.
Chris@0 536 *
Chris@0 537 * @return {string}
Chris@0 538 * A HTML string for the button to toggle group names.
Chris@0 539 */
Chris@17 540 Drupal.theme.ckeditorButtonGroupNamesToggle = function() {
Chris@0 541 return '<button class="link ckeditor-groupnames-toggle" aria-pressed="false"></button>';
Chris@0 542 };
Chris@0 543
Chris@0 544 /**
Chris@0 545 * Themes a button that will prompt the user to name a new button group.
Chris@0 546 *
Chris@0 547 * @return {string}
Chris@0 548 * A HTML string for the button to create a name for a new button group.
Chris@0 549 */
Chris@17 550 Drupal.theme.ckeditorNewButtonGroup = function() {
Chris@17 551 return `<li class="ckeditor-add-new-group"><button aria-label="${Drupal.t(
Chris@17 552 'Add a CKEditor button group to the end of this row.',
Chris@17 553 )}">${Drupal.t('Add group')}</button></li>`;
Chris@0 554 };
Chris@17 555 })(jQuery, Drupal, drupalSettings, _);