Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / misc / ajax.es6.js
index 6248e46efe6eb6f8c4e46ec0cbdae245c34ed67f..c3633b463663fb28efb3d54ede599d4ba314916e 100644 (file)
   Drupal.behaviors.AJAX = {
     attach(context, settings) {
       function loadAjaxBehavior(base) {
-        const element_settings = settings.ajax[base];
-        if (typeof element_settings.selector === 'undefined') {
-          element_settings.selector = `#${base}`;
+        const elementSettings = settings.ajax[base];
+        if (typeof elementSettings.selector === 'undefined') {
+          elementSettings.selector = `#${base}`;
         }
-        $(element_settings.selector).once('drupal-ajax').each(function () {
-          element_settings.element = this;
-          element_settings.base = base;
-          Drupal.ajax(element_settings);
+        $(elementSettings.selector).once('drupal-ajax').each(function () {
+          elementSettings.element = this;
+          elementSettings.base = base;
+          Drupal.ajax(elementSettings);
         });
       }
 
       // Load all Ajax behaviors specified in the settings.
-      for (const base in settings.ajax) {
-        if (settings.ajax.hasOwnProperty(base)) {
-          loadAjaxBehavior(base);
-        }
-      }
+      Object.keys(settings.ajax || {}).forEach(base => loadAjaxBehavior(base));
 
-      // Bind Ajax behaviors to all items showing the class.
-      $('.use-ajax').once('ajax').each(function () {
-        const element_settings = {};
-        // Clicked links look better with the throbber than the progress bar.
-        element_settings.progress = { type: 'throbber' };
-
-        // For anchor tags, these will go to the target of the anchor rather
-        // than the usual location.
-        const href = $(this).attr('href');
-        if (href) {
-          element_settings.url = href;
-          element_settings.event = 'click';
-        }
-        element_settings.dialogType = $(this).data('dialog-type');
-        element_settings.dialogRenderer = $(this).data('dialog-renderer');
-        element_settings.dialog = $(this).data('dialog-options');
-        element_settings.base = $(this).attr('id');
-        element_settings.element = this;
-        Drupal.ajax(element_settings);
-      });
+      Drupal.ajax.bindAjaxLinks(document.body);
 
       // This class means to submit the form to the action using Ajax.
       $('.use-ajax-submit').once('ajax').each(function () {
-        const element_settings = {};
+        const elementSettings = {};
 
         // Ajax submits specified in this manner automatically submit to the
         // normal form action.
-        element_settings.url = $(this.form).attr('action');
+        elementSettings.url = $(this.form).attr('action');
         // Form submit button clicks need to tell the form what was clicked so
         // it gets passed in the POST request.
-        element_settings.setClick = true;
+        elementSettings.setClick = true;
         // Form buttons use the 'click' event rather than mousedown.
-        element_settings.event = 'click';
+        elementSettings.event = 'click';
         // Clicked form buttons look better with the throbber than the progress
         // bar.
-        element_settings.progress = { type: 'throbber' };
-        element_settings.base = $(this).attr('id');
-        element_settings.element = this;
+        elementSettings.progress = { type: 'throbber' };
+        elementSettings.base = $(this).attr('id');
+        elementSettings.element = this;
 
-        Drupal.ajax(element_settings);
+        Drupal.ajax(elementSettings);
       });
     },
 
   Drupal.AjaxError = function (xmlhttp, uri, customMessage) {
     let statusCode;
     let statusText;
-    let pathText;
     let responseText;
-    let readyStateText;
     if (xmlhttp.status) {
       statusCode = `\n${Drupal.t('An AJAX HTTP error occurred.')}\n${Drupal.t('HTTP Result Code: !status', { '!status': xmlhttp.status })}`;
     }
       statusCode = `\n${Drupal.t('An AJAX HTTP request terminated abnormally.')}`;
     }
     statusCode += `\n${Drupal.t('Debugging information follows.')}`;
-    pathText = `\n${Drupal.t('Path: !uri', { '!uri': uri })}`;
+    const pathText = `\n${Drupal.t('Path: !uri', { '!uri': uri })}`;
     statusText = '';
     // In some cases, when statusCode === 0, xmlhttp.statusText may not be
     // defined. Unfortunately, testing for it with typeof, etc, doesn't seem to
     responseText = responseText.replace(/[\n]+\s+/g, '\n');
 
     // We don't need readyState except for status == 0.
-    readyStateText = xmlhttp.status === 0 ? (`\n${Drupal.t('ReadyState: !readyState', { '!readyState': xmlhttp.readyState })}`) : '';
+    const readyStateText = xmlhttp.status === 0 ? (`\n${Drupal.t('ReadyState: !readyState', { '!readyState': xmlhttp.readyState })}`) : '';
 
     customMessage = customMessage ? (`\n${Drupal.t('CustomMessage: !customMessage', { '!customMessage': customMessage })}`) : '';
 
     return Drupal.ajax.instances.filter(instance => instance && instance.element !== false && !document.body.contains(instance.element));
   };
 
+  /**
+   * Bind Ajax functionality to links that use the 'use-ajax' class.
+   *
+   * @param {HTMLElement} element
+   *   Element to enable Ajax functionality for.
+   */
+  Drupal.ajax.bindAjaxLinks = (element) => {
+    // Bind Ajax behaviors to all items showing the class.
+    $(element).find('.use-ajax').once('ajax').each((i, ajaxLink) => {
+      const $linkElement = $(ajaxLink);
+
+      const elementSettings = {
+        // Clicked links look better with the throbber than the progress bar.
+        progress: { type: 'throbber' },
+        dialogType: $linkElement.data('dialog-type'),
+        dialog: $linkElement.data('dialog-options'),
+        dialogRenderer: $linkElement.data('dialog-renderer'),
+        base: $linkElement.attr('id'),
+        element: ajaxLink,
+      };
+      const href = $linkElement.attr('href');
+      /**
+       * For anchor tags, these will go to the target of the anchor rather
+       * than the usual location.
+       */
+      if (href) {
+        elementSettings.url = href;
+        elementSettings.event = 'click';
+      }
+      Drupal.ajax(elementSettings);
+    });
+  };
+
   /**
    * Settings for an Ajax object.
    *
-   * @typedef {object} Drupal.Ajax~element_settings
+   * @typedef {object} Drupal.Ajax~elementSettings
    *
    * @prop {string} url
    *   Target of the Ajax request.
    * @param {HTMLElement} [element]
    *   Element parameter of {@link Drupal.Ajax} constructor, element on which
    *   event listeners will be bound.
-   * @param {Drupal.Ajax~element_settings} element_settings
+   * @param {Drupal.Ajax~elementSettings} elementSettings
    *   Settings for this Ajax object.
    */
-  Drupal.Ajax = function (base, element, element_settings) {
+  Drupal.Ajax = function (base, element, elementSettings) {
     const defaults = {
       event: element ? 'mousedown' : null,
       keypress: true,
       },
     };
 
-    $.extend(this, defaults, element_settings);
+    $.extend(this, defaults, elementSettings);
 
     /**
      * @type {Drupal.AjaxCommands}
     this.element = element;
 
     /**
-     * @type {Drupal.Ajax~element_settings}
+     * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
+     * Use elementSettings.
+     *
+     * @type {Drupal.Ajax~elementSettings}
      */
-    this.element_settings = element_settings;
+    this.element_settings = elementSettings;
+
+    /**
+     * @type {Drupal.Ajax~elementSettings}
+     */
+    this.elementSettings = elementSettings;
 
     // If there isn't a form, jQuery.ajax() will be used instead, allowing us to
     // bind Ajax to links as well.
     ajax.options = {
       url: ajax.url,
       data: ajax.submit,
-      beforeSerialize(element_settings, options) {
-        return ajax.beforeSerialize(element_settings, options);
+      beforeSerialize(elementSettings, options) {
+        return ajax.beforeSerialize(elementSettings, options);
       },
-      beforeSubmit(form_values, element_settings, options) {
+      beforeSubmit(formValues, elementSettings, options) {
         ajax.ajaxing = true;
-        return ajax.beforeSubmit(form_values, element_settings, options);
+        return ajax.beforeSubmit(formValues, elementSettings, options);
       },
       beforeSend(xmlhttprequest, options) {
         ajax.ajaxing = true;
       type: 'POST',
     };
 
-    if (element_settings.dialog) {
-      ajax.options.data.dialogOptions = element_settings.dialog;
+    if (elementSettings.dialog) {
+      ajax.options.data.dialogOptions = elementSettings.dialog;
     }
 
     // Ensure that we have a valid URL by adding ? when no query parameter is
       ajax.options.url += '&';
     }
     // If this element has a dialog type use if for the wrapper if not use 'ajax'.
-    let wrapper = `drupal_${(element_settings.dialogType || 'ajax')}`;
-    if (element_settings.dialogRenderer) {
-      wrapper += `.${element_settings.dialogRenderer}`;
+    let wrapper = `drupal_${(elementSettings.dialogType || 'ajax')}`;
+    if (elementSettings.dialogRenderer) {
+      wrapper += `.${elementSettings.dialogRenderer}`;
     }
     ajax.options.url += `${Drupal.ajax.WRAPPER_FORMAT}=${wrapper}`;
 
 
     // Bind the ajaxSubmit function to the element event.
-    $(ajax.element).on(element_settings.event, function (event) {
+    $(ajax.element).on(elementSettings.event, function (event) {
       if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) {
         throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', { '!url': ajax.url }));
       }
     // If necessary, enable keyboard submission so that Ajax behaviors
     // can be triggered through keyboard input as well as e.g. a mousedown
     // action.
-    if (element_settings.keypress) {
+    if (elementSettings.keypress) {
       $(ajax.element).on('keypress', function (event) {
         return ajax.keypressResponse(this, event);
       });
     // If necessary, prevent the browser default action of an additional event.
     // For example, prevent the browser default action of a click, even if the
     // Ajax behavior binds to mousedown.
-    if (element_settings.prevent) {
-      $(ajax.element).on(element_settings.prevent, false);
+    if (elementSettings.prevent) {
+      $(ajax.element).on(elementSettings.prevent, false);
     }
   };
 
       element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number')) {
       event.preventDefault();
       event.stopPropagation();
-      $(element).trigger(ajax.element_settings.event);
+      $(element).trigger(ajax.elementSettings.event);
     }
   };
 
    * before field data is collected.
    *
    * @param {object} [element]
-   *   Ajax object's `element_settings`.
+   *   Ajax object's `elementSettings`.
    * @param {object} options
    *   jQuery.ajax options.
    */
   /**
    * Modify form values prior to form submission.
    *
-   * @param {Array.<object>} form_values
+   * @param {Array.<object>} formValues
    *   Processed form values.
    * @param {jQuery} element
    *   The form node as a jQuery object.
    * @param {object} options
    *   jQuery.ajax options.
    */
-  Drupal.Ajax.prototype.beforeSubmit = function (form_values, element, options) {
+  Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {
     // This function is left empty to make it simple to override for modules
     // that wish to add functionality here.
   };
     // Track if any command is altering the focus so we can avoid changing the
     // focus set by the Ajax command.
     let focusChanged = false;
-    for (const i in response) {
-      if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) {
+    Object.keys(response || {}).forEach((i) => {
+      if (response[i].command && this.commands[response[i].command]) {
         this.commands[response[i].command](this, response[i], status);
         if (response[i].command === 'invoke' && response[i].method === 'focus') {
           focusChanged = true;
         }
       }
-    }
+    });
 
     // If the focus hasn't be changed by the ajax commands, try to refocus the
     // triggering element or one of its parents if that element does not exist
    * @param {object} response
    *   Drupal Ajax response.
    * @param {string} [response.effect]
-   *   Override the default value of {@link Drupal.Ajax#element_settings}.
+   *   Override the default value of {@link Drupal.Ajax#elementSettings}.
    * @param {string|number} [response.speed]
-   *   Override the default value of {@link Drupal.Ajax#element_settings}.
+   *   Override the default value of {@link Drupal.Ajax#elementSettings}.
    *
    * @return {object}
    *   Returns an object with `showEffect`, `hideEffect` and `showSpeed`
       // $(response.data) as new HTML rather than a CSS selector. Also, if
       // response.data contains top-level text nodes, they get lost with either
       // $(response.data) or $('<div></div>').replaceWith(response.data).
-      const $new_content_wrapped = $('<div></div>').html(response.data);
-      let $new_content = $new_content_wrapped.contents();
+      const $newContentWrapped = $('<div></div>').html(response.data);
+      let $newContent = $newContentWrapped.contents();
 
       // For legacy reasons, the effects processing code assumes that
-      // $new_content consists of a single top-level element. Also, it has not
+      // $newContent consists of a single top-level element. Also, it has not
       // been sufficiently tested whether attachBehaviors() can be successfully
       // called with a context object that includes top-level text nodes.
       // However, to give developers full control of the HTML appearing in the
       // of a single top-level element, and only use the container <div> created
       // above when it doesn't. For more information, please see
       // https://www.drupal.org/node/736066.
-      if ($new_content.length !== 1 || $new_content.get(0).nodeType !== 1) {
-        $new_content = $new_content_wrapped;
+      if ($newContent.length !== 1 || $newContent.get(0).nodeType !== 1) {
+        $newContent = $newContentWrapped;
       }
 
       // If removing content from the wrapper, detach behaviors first.
       }
 
       // Add the new content to the page.
-      $wrapper[method]($new_content);
+      $wrapper[method]($newContent);
 
       // Immediately hide the new content if we're using any effects.
       if (effect.showEffect !== 'show') {
-        $new_content.hide();
+        $newContent.hide();
       }
 
       // Determine which effect to use and what content will receive the
       // effect, then show the new content.
-      if ($new_content.find('.ajax-new-content').length > 0) {
-        $new_content.find('.ajax-new-content').hide();
-        $new_content.show();
-        $new_content.find('.ajax-new-content')[effect.showEffect](effect.showSpeed);
+      if ($newContent.find('.ajax-new-content').length > 0) {
+        $newContent.find('.ajax-new-content').hide();
+        $newContent.show();
+        $newContent.find('.ajax-new-content')[effect.showEffect](effect.showSpeed);
       }
       else if (effect.showEffect !== 'show') {
-        $new_content[effect.showEffect](effect.showSpeed);
+        $newContent[effect.showEffect](effect.showSpeed);
       }
 
       // Attach all JavaScript behaviors to the new content, if it was
       // successfully added to the page, this if statement allows
       // `#ajax['wrapper']` to be optional.
-      if ($new_content.parents('html').length > 0) {
+      if ($newContent.parents('html').length > 0) {
         // Apply any settings from the returned JSON if available.
         settings = response.settings || ajax.settings || drupalSettings;
-        Drupal.attachBehaviors($new_content.get(0), settings);
+        Drupal.attachBehaviors($newContent.get(0), settings);
       }
     },
 
       // :even and :odd are reversed because jQuery counts from 0 and
       // we count from 1, so we're out of sync.
       // Match immediate children of the parent element to allow nesting.
-      $(response.selector).find('> tbody > tr:visible, > tr:visible')
+      $(response.selector)
+        .find('> tbody > tr:visible, > tr:visible')
         .removeClass('odd even')
-        .filter(':even').addClass('odd').end()
-        .filter(':odd').addClass('even');
+        .filter(':even')
+        .addClass('odd')
+        .end()
+        .filter(':odd')
+        .addClass('even');
     },
 
     /**