text: /**
   * @file
   * JavaScript behaviors for webforms.
   */
  
  (function ($, Drupal) {
  
    'use strict';
  
    /**
     * Autofocus first input.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for the webform autofocusing.
     */
    Drupal.behaviors.webformAutofocus = {
      attach: function (context) {
        $(context).find('.webform-submission-form.js-webform-autofocus :input:visible:enabled:first').focus();
      }
    };
  
    /**
     * Prevent webform autosubmit on wizard pages.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for disabling webform autosubmit.
     */
    Drupal.behaviors.webformDisableAutoSubmit = {
      attach: function (context) {
        // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter
        $(context).find('.webform-submission-form.js-webform-disable-autosubmit input')
          .not(':button, :input[type="image"], :input[type="file"]')
          .once('webform-disable-autosubmit')
          .on('keyup keypress', function (e) {
            var keyCode = e.keyCode || e.which;
            if (keyCode === 13) {
              e.preventDefault();
              return false;
            }
          });
      }
    };
  
    /**
     * Skip client-side validation when submit button is pressed.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for the skipping client-side validation.
     */
    Drupal.behaviors.webformSubmitNoValidate = {
      attach: function (context) {
        $(context).find(':submit.js-webform-novalidate').once('webform-novalidate').on('click', function () {
          $(this.form).attr('novalidate', 'novalidate');
        });
      }
    };
  
    /**
     * Attach behaviors to trigger submit button from input onchange.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches form trigger submit events.
     */
    Drupal.behaviors.webformSubmitTrigger = {
      attach: function (context) {
        $('[data-webform-trigger-submit]').once('webform-trigger-submit').on('change', function () {
          var submit = $(this).attr('data-webform-trigger-submit');
          $(submit).mousedown();
        });
      }
    };
  
    /**
     * Custom required error message.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for the webform custom required error message.
     *
     * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message
     */
    Drupal.behaviors.webformRequiredError = {
      attach: function (context) {
        $(context).find(':input[data-webform-required-error]').once('webform-required-error')
          .on('invalid', function() {
            this.setCustomValidity('');
            if (!this.valid) {
              this.setCustomValidity($(this).attr('data-webform-required-error'));
            }
          })
          .on('input, change', function() {
            // Find all related elements by name and reset custom validity.
            // This specifically applies to required radios and checkboxes.
            var name = $(this).attr('name');
            $(this.form).find(':input[name="' + name + '"]').each(
              function() {this.setCustomValidity('');
            });
          });
      }
    };
  
    /**
     * Disable validate when save draft submit button is clicked.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for the webform draft submit button.
     */
    Drupal.behaviors.webformDraft = {
      attach: function (context) {
        $(context).find('#edit-draft').once('webform-draft').on('click', function () {
          $(this.form).attr('novalidate', 'novalidate');
        });
      }
    };
  
    /**
     * Filters the webform element list by a text input search string.
     *
     * The text input will have the selector `input.webform-form-filter-text`.
     *
     * The target element to do searching in will be in the selector
     * `input.webform-form-filter-text[data-element]`
     *
     * The text source where the text should be found will have the selector
     * `.webform-form-filter-text-source`
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for the webform element filtering.
     */
    Drupal.behaviors.webformFilterByText = {
      attach: function (context, settings) {
        var $input = $('input.webform-form-filter-text').once('webform-form-filter-text');
        var $table = $($input.attr('data-element'));
        var $details = $table.closest('details');
        var $filter_rows;
  
        /**
         * Filters the webform element list.
         *
         * @param {jQuery.Event} e
         *   The jQuery event for the keyup event that triggered the filter.
         */
        function filterElementList(e) {
          var query = $(e.target).val().toLowerCase();
  
          /**
           * Shows or hides the webform element entry based on the query.
           *
           * @param {number} index
           *   The index in the loop, as provided by `jQuery.each`
           * @param {HTMLElement} label
           *   The label of the webform.
           */
          function toggleEntry(index, label) {
            var $label = $(label);
            var $row = $label.closest('tr');
            var textMatch = $label.text().toLowerCase().indexOf(query) !== -1;
            $row.toggle(textMatch);
            if (textMatch && $details.length) {
              $row.closest('details').show();
            }
          }
  
          // Filter if the length of the query is at least 2 characters.
          if (query.length >= 2) {
            if ($details.length) {
              $details.hide();
            }
            $filter_rows.each(toggleEntry);
          }
          else {
            $filter_rows.each(function (index) {
              $(this).closest('tr').show();
              if ($details.length) {
                $details.show();
              }
            });
          }
        }
  
        if ($table.length) {
          $filter_rows = $table.find('div.webform-form-filter-text-source');
          $input.on('keyup', filterElementList);
          if ($input.val()) {
            $input.keyup();
          }
        }
      }
    };
  
    if (window.imceInput) {
      window.imceInput.processUrlInput = function (i, el) {
        var button = imceInput.createUrlButton(el.id, el.getAttribute('data-imce-type'));
        el.parentNode.insertAfter(button, el);
      };
    }
  
    /**
     * Reacts to contextual links being added.
     *
     * @param {jQuery.Event} event
     *   The `drupalContextualLinkAdded` event.
     * @param {object} data
     *   An object containing the data relevant to the event.
     *
     * @listens event:drupalContextualLinkAdded
     */
    $(document).on('drupalContextualLinkAdded', function (event, data) {
      // Bind Ajax behaviors to all items showing the class.
      // @todo Fix contextual links to work with use-ajax links in
      //    https://www.drupal.org/node/2764931.
      Drupal.attachBehaviors(data.$el[0]);
    });
  
  })(jQuery, Drupal);
  