refreshless-8.x-1.x-dev/modules/refreshless_turbo/js/behaviours.js

modules/refreshless_turbo/js/behaviours.js
(function(Drupal, drupalSettings, $) {

  'use strict';

  /**
   * Our event namespace.
   *
   * @type {String}
   *
   * @see https://learn.jquery.com/events/event-basics/#namespacing-events
   */
  const eventNamespace = 'refreshless-turbo-behaviour-manager';

  /**
   * RefreshLess Turbo behaviours attach and detach class.
   */
  class Behaviours {

    /**
     * The context element to attach to; usually the <html> element.
     *
     * @type {HTMLElement}
     */
    #context;

    /**
     * A Promise that resolves when all newly merged scripts have loaded.
     *
     * @type {Promise|null}
     */
    #loadedPromise = null;

    constructor(context) {

      this.#context = context;

      this.#bindEventHandlers();

    };

    /**
     * Destroy this instance.
     */
    destroy() {

      this.#unbindEventHandlers();

    }

    /**
     * Bind all of our event handlers.
     */
    #bindEventHandlers() {

      // @see https://ambientimpact.com/web/snippets/javascript-template-literal-as-object-property-name
      $(this.#context).on({
        [`refreshless:before-scripts-merge.${eventNamespace}`]: (event) => {
          this.#beforeMergeHandler(event);
        },
      });

    }

    /**
     * Unbind all of our event handlers.
     */
    #unbindEventHandlers() {

      $(this.#context).off(`.${eventNamespace}`);

    }

    /**
     * 'refreshless:before-scripts-merge' event handler.
     *
     * @param {jQuery.Event} event
     */
    #beforeMergeHandler(event) {

      // Since this event handler is triggered twice, avoid overwriting the
      // Promise if it exists.
      if (this.#loadedPromise !== null) {
        return;
      }

      // This needs to be registered before merging so that it's as early as
      // possible in the page load cycle.
      this.#loadedPromise = new Promise((resolve, reject) => {

        $(this.#context).one({
          [`refreshless:scripts-loaded.${eventNamespace}`]: resolve,
        });

      });

    }

    /**
     * Attach behaviours.
     *
     * @param {Boolean} notify
     *   If true (the default), an attach event will be triggered.
     *
     * @return {Promise}
     *   A Promise that fulfills once Drupal.attachBehaviors() has been called.
     */
    async attach(notify = true) {

      // Delay attaching until all script elements have loaded.
      await this.#loadedPromise;

      // Set the Promise back to null so our before merge handler knows to
      // create a new Promise on the next load.
      this.#loadedPromise = null;

      Drupal.attachBehaviors(this.#context, drupalSettings);

      if (notify === true) {

        const attachEvent = new CustomEvent('refreshless:attach', {
          // Since we're dispatching on an abitrary context element.
          bubbles: true,
        });

        this.#context.dispatchEvent(attachEvent);

      }

      return Promise.resolve();

    };

    /**
     * Detach behaviours.
     *
     * @param {Boolean} notify
     *   If true (the default), a detach event will be triggered.
     *
     * @param {String} trigger
     *   The reason for the detach. Commonly used values:
     *
     *   - 'unload': Triggered when the user is leaving the current page, both
     *     by core and RefreshLess.
     *
     *   - 'serialize': Triggered by core's Ajax framework before form field
     *     values are collected and sent to the back-end.
     *
     *   - 'move': Triggered by core's table drag on table rows.
     *
     *   RefreshLess also provides the following:
     *
     *   - 'refreshless:before-cache': Triggered on the page before it's about
     *     to be cached.
     *
     *   - 'refreshless:cached-snapshot': Triggered on a cached snapshot that's
     *     about to be rendered.
     *
     *   Defaults to 'unload' if not specified.
     *
     * @return {Promise}
     *   A Promise that fulfills when Drupal.detachBehaviors() has been called.
     */
    detach(notify = true, trigger = 'unload') {

      Drupal.detachBehaviors(this.#context, drupalSettings, trigger);

      if (notify === true) {

        const detachEvent = new CustomEvent('refreshless:detach', {
          // Since we're dispatching on an abitrary context element.
          bubbles: true,
          detail: {
            trigger: trigger,
          },
        });

        this.#context.dispatchEvent(detachEvent);

      }

      return Promise.resolve();

    };

  }

  // Merge Drupal.RefreshLess.classes into the existing Drupal global.
  $.extend(true, Drupal, {RefreshLess: {classes: {
    TurboBehaviours: Behaviours,
  }}});

})(Drupal, drupalSettings, jQuery);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc