mercury_editor-2.0.x-dev/source/js/preview-screen.js

source/js/preview-screen.js
((Drupal, drupalSettings, $, once) => {
  /**
   * Adds the me_id GET parameter to a URL.
   * @param {String} url The url to add the me_id GET parameter to.
   * @return {String} The url with the me_id GET parameter.
   */
  function addPreviewParam(url) {
    const mercuryEditorId = drupalSettings.mercuryEditor?.id || null;
    if (!mercuryEditorId) {
      return url;
    }
    const urlObj = new URL(url, window.location.origin);
    if (urlObj.origin !== window.location.origin) {
      return url;
    }
    urlObj.searchParams.set('me_id', mercuryEditorId);
    return urlObj.toString();
  }

  // Intercept all XMLHttpRequests to add me_id GET parameter.
  const originalOpen = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function open(
    method,
    url,
    async,
    user,
    password,
  ) {
    return originalOpen.call(
      this,
      method,
      addPreviewParam(url),
      async,
      user,
      password,
    );
  };

  // Intercept all fetch requests to add me_id GET parameter.
  const originalFetch = window.fetch;
  window.fetch = (input, init) => {
    let url = typeof input === 'string' ? input : input.url;
    if (url) {
      url = addPreviewParam(url);
    }
    return originalFetch(url || input, init);
  };

  /**
   * Prevent a click.
   *
   * @param {Event} e The click event.
   * @return {Boolean} False.
   */
  function preventDefault(e) {
    e.stopPropagation();
    e.preventDefault();
    return false;
  }

  /**
   * Uses window.postMessage() to send UI clicks to the parent window.
   *
   * @param {Event} e The click event.
   * @return {Boolean} False to prevent default action.
   */
  function lpbClickHandler(e) {
    // First, send the ajaxPageState to the parent window.
    window.parent.postMessage({
      type: 'ajaxPreviewPageState',
      settings: drupalSettings.ajaxPageState,
    });
    // Then, send the click event.
    const message = {
      type: 'drupalAjax',
      settings: {
        dialogType: e.currentTarget.getAttribute('data-dialog-type'),
        dialog: JSON.parse(e.currentTarget.getAttribute('data-dialog-options')),
        dialogRenderer: JSON.parse(
          e.currentTarget.getAttribute('data-dialog-renderer'),
        ),
        url: addPreviewParam(e.currentTarget.getAttribute('href')),
      },
    };
    window.parent.postMessage(message);
    e.stopPropagation();
    e.preventDefault();
    return false;
  }

  /**
   * Attaches the behavior to the edit screen.
   */
  Drupal.behaviors.mercuryEditorPreviewScreen = {
    attach(context) {
      // Check for duplicate data attributes.
      const duplicateContainers = Array.from(
        document.querySelectorAll('[data-me-edit-screen-key]'),
      )
        .map((container) => container.getAttribute('data-me-edit-screen-key'))
        .filter((value, index, self) => self.indexOf(value) !== index);
      if (duplicateContainers.length > 0) {
        console.error(
          'Multiple HTML elements found using the same data attribute, "data-me-edit-screen-key", which should be unique. Make sure attributes are not passed to child elements in twig templates.',
          duplicateContainers,
        );
      }
      // Send the initial ajaxPageState to the parent window.
      window.parent.postMessage({
        type: 'ajaxPreviewPageState',
        settings: drupalSettings.ajaxPageState,
      });
      window.parent.postMessage({
        type: 'layoutParagraphsSettings',
        settings: drupalSettings.lpBuilder || {}
      });
      // Attaches click handlers to links that use window.postMessage().
      once(
        'me-msg-broadcaster',
        '.js-lpb-ui.use-ajax, .js-lpb-ui .use-ajax',
      ).forEach((el) => {
        $(el).off(); // Since core attaches behavior with JQuery.
        el.addEventListener('mousedown', preventDefault);
        el.addEventListener('mouseup', preventDefault);
        el.addEventListener('click', lpbClickHandler);
      });
      // Prevent links from working in the preview iframe.
      if (window.parent !== window) {
        once('me-stop-iframed-links', 'a', context).forEach((link) => {
          if (link.closest('.lpb-controls') === null) {
            link.setAttribute('target', '_parent');
            link.addEventListener('click', (e) => {
              e.stopPropagation();
              e.preventDefault();
              return false;
            });
          }
        });
        once(
          'me-prevent-focus',
          'a, button, input, textarea, select, details',
          context,
        ).forEach((focussable) => {
          if (
            focussable.closest('.lpb-controls') === null &&
            focussable.closest('.mercury-editor-ui') === null &&
            !focussable.classList.contains('use-postmessage')
          ) {
            focussable.setAttribute('tabindex', '-1');
          }
        });
      }
    },
  };
  document.addEventListener('lpb-component:blur', (event) => {
    setTimeout(() => {
      if (!document.querySelector('.js-lpb-component[data-active]')) {
        window.parent.postMessage({
          type: 'closeModal',
          settings: {
            componentUuid: event.target.getAttribute('data-uuid'),
            componentType: event.target.getAttribute('data-type'),
          },
        });
      }
    }, 100);
  });
  document.addEventListener('lpb-component:focus', (event) => {
    if (event.detail?.originalEvent?.type !== 'lpb-component:update') {
      event.target.querySelector('.lpb-edit')?.click();
    }
  });
  document.addEventListener(
    'mouseup',
    (event) => {
      if (event.target.classList.contains('lpb-edit')) {
        window.parent.postMessage({
          type: 'openSidebar',
        });
      }
    },
    true,
  );
  // Sends all Layout Paragraphs events to the parent window.
  [
    'lpb-component:move',
    'lpb-component:drop',
    'lpb-component:insert',
    'lpb-component:delete',
    'lpb-component:update',
    'lpb-component:blur',
    'lpb-component:focus',
    'lpb-component:drag',
  ].forEach((eventName) => {
    document.addEventListener(eventName, (event) => {
      window.parent.postMessage({
        type: 'layoutParagraphsEvent',
        eventName,
        ref: event.target.getAttribute('data-uuid'),
        value: event.target.outerHTML,
      });
    });
  });
  // Posts a message that the preview has been updated.
  [
    'lpb-component:move',
    'lpb-component:drop',
    'lpb-component:insert',
    'lpb-component:delete',
    'lpb-component:update',
  ].forEach((eventName) => {
    document.addEventListener(eventName, (event) => {
      window.parent.postMessage({
        type: 'previewUpdated',
        data: {
          ref: event.target.getAttribute('data-uuid'),
          value: event.target.outerHTML,
        },
      });
    });
  });
})(Drupal, drupalSettings, jQuery, once);

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

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