text: /**
   * @file
   * Extends the Drupal AJAX functionality to integrate the dialog API.
   */
  
  (function($, Drupal) {
    /**
     * Initialize dialogs for Ajax purposes.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behaviors for dialog ajax functionality.
     */
    Drupal.behaviors.dialog = {
      attach(context, settings) {
        const $context = $(context);
  
        // Provide a known 'drupal-modal' DOM element for Drupal-based modal
        // dialogs. Non-modal dialogs are responsible for creating their own
        // elements, since there can be multiple non-modal dialogs at a time.
        if (!$('#drupal-modal').length) {
          // Add 'ui-front' jQuery UI class so jQuery UI widgets like autocomplete
          // sit on top of dialogs. For more information see
          // http://api.jqueryui.com/theming/stacking-elements/.
          $('<div id="drupal-modal" class="ui-front"/>')
            .hide()
            .appendTo('body');
        }
  
        // Special behaviors specific when attaching content within a dialog.
        // These behaviors usually fire after a validation error inside a dialog.
        const $dialog = $context.closest('.ui-dialog-content');
        if ($dialog.length) {
          // Remove and replace the dialog buttons with those from the new form.
          if ($dialog.dialog('option', 'drupalAutoButtons')) {
            // Trigger an event to detect/sync changes to buttons.
            $dialog.trigger('dialogButtonsChange');
          }
  
          // Force focus on the modal when the behavior is run.
          $dialog.dialog('widget').trigger('focus');
        }
  
        const originalClose = settings.dialog.close;
        // Overwrite the close method to remove the dialog on closing.
        settings.dialog.close = function(event, ...args) {
          originalClose.apply(settings.dialog, [event, ...args]);
          $(event.target).remove();
        };
      },
  
      /**
       * Scan a dialog for any primary buttons and move them to the button area.
       *
       * @param {jQuery} $dialog
       *   An jQuery object containing the element that is the dialog target.
       *
       * @return {Array}
       *   An array of buttons that need to be added to the button area.
       */
      prepareDialogButtons($dialog) {
        const buttons = [];
        const $buttons = $dialog.find(
          '.form-actions input[type=submit], .form-actions a.button',
        );
        $buttons.each(function() {
          // Hidden form buttons need special attention. For browser consistency,
          // the button needs to be "visible" in order to have the enter key fire
          // the form submit event. So instead of a simple "hide" or
          // "display: none", we set its dimensions to zero.
          // See http://mattsnider.com/how-forms-submit-when-pressing-enter/
          const $originalButton = $(this).css({
            display: 'block',
            width: 0,
            height: 0,
            padding: 0,
            border: 0,
            overflow: 'hidden',
          });
          buttons.push({
            text: $originalButton.html() || $originalButton.attr('value'),
            class: $originalButton.attr('class'),
            click(e) {
              // If the original button is an anchor tag, triggering the "click"
              // event will not simulate a click. Use the click method instead.
              if ($originalButton.is('a')) {
                $originalButton[0].click();
              } else {
                $originalButton
                  .trigger('mousedown')
                  .trigger('mouseup')
                  .trigger('click');
                e.preventDefault();
              }
            },
          });
        });
        return buttons;
      },
    };
  
    /**
     * Command to open a dialog.
     *
     * @param {Drupal.Ajax} ajax
     *   The Drupal Ajax object.
     * @param {object} response
     *   Object holding the server response.
     * @param {number} [status]
     *   The HTTP status code.
     *
     * @return {bool|undefined}
     *   Returns false if there was no selector property in the response object.
     */
    Drupal.AjaxCommands.prototype.openDialog = function(ajax, response, status) {
      if (!response.selector) {
        return false;
      }
      let $dialog = $(response.selector);
      if (!$dialog.length) {
        // Create the element if needed.
        $dialog = $(
          `<div id="${response.selector.replace(/^#/, '')}" class="ui-front"/>`,
        ).appendTo('body');
      }
      // Set up the wrapper, if there isn't one.
      if (!ajax.wrapper) {
        ajax.wrapper = $dialog.attr('id');
      }
  
      // Use the ajax.js insert command to populate the dialog contents.
      response.command = 'insert';
      response.method = 'html';
      ajax.commands.insert(ajax, response, status);
  
      // Move the buttons to the jQuery UI dialog buttons area.
      if (!response.dialogOptions.buttons) {
        response.dialogOptions.drupalAutoButtons = true;
        response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons(
          $dialog,
        );
      }
  
      // Bind dialogButtonsChange.
      $dialog.on('dialogButtonsChange', () => {
        const buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
        $dialog.dialog('option', 'buttons', buttons);
      });
  
      // Open the dialog itself.
      response.dialogOptions = response.dialogOptions || {};
      const dialog = Drupal.dialog($dialog.get(0), response.dialogOptions);
      if (response.dialogOptions.modal) {
        dialog.showModal();
      } else {
        dialog.show();
      }
  
      // Add the standard Drupal class for buttons for style consistency.
      $dialog
        .parent()
        .find('.ui-dialog-buttonset')
        .addClass('form-actions');
    };
  
    /**
     * Command to close a dialog.
     *
     * If no selector is given, it defaults to trying to close the modal.
     *
     * @param {Drupal.Ajax} [ajax]
     *   The ajax object.
     * @param {object} response
     *   Object holding the server response.
     * @param {string} response.selector
     *   The selector of the dialog.
     * @param {bool} response.persist
     *   Whether to persist the dialog element or not.
     * @param {number} [status]
     *   The HTTP status code.
     */
    Drupal.AjaxCommands.prototype.closeDialog = function(ajax, response, status) {
      const $dialog = $(response.selector);
      if ($dialog.length) {
        Drupal.dialog($dialog.get(0)).close();
        if (!response.persist) {
          $dialog.remove();
        }
      }
  
      // Unbind dialogButtonsChange.
      $dialog.off('dialogButtonsChange');
    };
  
    /**
     * Command to set a dialog property.
     *
     * JQuery UI specific way of setting dialog options.
     *
     * @param {Drupal.Ajax} [ajax]
     *   The Drupal Ajax object.
     * @param {object} response
     *   Object holding the server response.
     * @param {string} response.selector
     *   Selector for the dialog element.
     * @param {string} response.optionsName
     *   Name of a key to set.
     * @param {string} response.optionValue
     *   Value to set.
     * @param {number} [status]
     *   The HTTP status code.
     */
    Drupal.AjaxCommands.prototype.setDialogOption = function(
      ajax,
      response,
      status,
    ) {
      const $dialog = $(response.selector);
      if ($dialog.length) {
        $dialog.dialog('option', response.optionName, response.optionValue);
      }
    };
  
    /**
     * Binds a listener on dialog creation to handle the cancel link.
     *
     * @param {jQuery.Event} e
     *   The event triggered.
     * @param {Drupal.dialog~dialogDefinition} dialog
     *   The dialog instance.
     * @param {jQuery} $element
     *   The jQuery collection of the dialog element.
     * @param {object} [settings]
     *   Dialog settings.
     */
    $(window).on('dialog:aftercreate', (e, dialog, $element, settings) => {
      $element.on('click.dialog', '.dialog-cancel', e => {
        dialog.close('cancel');
        e.preventDefault();
        e.stopPropagation();
      });
    });
  
    /**
     * Removes all 'dialog' listeners.
     *
     * @param {jQuery.Event} e
     *   The event triggered.
     * @param {Drupal.dialog~dialogDefinition} dialog
     *   The dialog instance.
     * @param {jQuery} $element
     *   jQuery collection of the dialog element.
     */
    $(window).on('dialog:beforeclose', (e, dialog, $element) => {
      $element.off('.dialog');
    });
  })(jQuery, Drupal);
  