"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var tiptap_exports = {};
__export(tiptap_exports, {
  tiptapExtensions: () => tiptapExtensions
});
module.exports = __toCommonJS(tiptap_exports);
var import_ricos_content = require("./../../ricos-content/index.js");
var import_convert_block_data_to_ricos = require("./../../ricos-content/lib/convert-block-data-to-ricos.js");
var import_plugin_commons = require("./../../plugin-commons/index.js");
var import_utils = require("../lib/utils.js");
var import_types = require("../types.js");
var import_embed = require("./embed.js");
var import_link_preview = require("./link-preview.js");
const urlRegex = (
  // oxlint-disable-next-line max-len
  /(?:https?:\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi
);
const urlRegexExact = new RegExp("^" + urlRegex.source + "$", "gi");
const isLinkOnlyBlock = ({
  pos,
  fromShortcut
}) => fromShortcut ? pos.parent.childCount === 1 && pos.nodeBefore?.text?.search(urlRegexExact) !== -1 : pos.parent.text?.search(urlRegexExact) !== -1;
const getLinkDeletionRange = ({
  pos,
  fromShortcut
}) => {
  const parentText = pos.parent.textContent;
  const match = parentText.match(urlRegexExact);
  if (match) {
    const startIndex = parentText.indexOf(match[0]);
    return {
      from: pos.start() + startIndex,
      to: pos.start() + startIndex + match[0].length
    };
  }
  if (fromShortcut) {
    return {
      from: pos.pos - (pos.nodeBefore?.nodeSize || 0),
      to: pos.pos + (pos.nodeAfter?.nodeSize || 0)
    };
  }
  return { from: pos.start(), to: pos.end() };
};
const extractUrlFromNode = (node) => {
  const linkMark = node.marks.find((mark) => mark.type.name === "LINK");
  const rawUrl = linkMark?.attrs?.link?.url ?? linkMark?.attrs?.href;
  return rawUrl?.trim();
};
const addLinkPreview = (config) => (
  // @ts-expect-error
  ({ editor, tr }) => {
    tr?.setMeta("preventDispatch", true);
    const pos = editor.state.selection.$anchor;
    const {
      enableEmbed = true,
      enableLinkPreview = true,
      fetchData,
      link: linkConfig,
      fromShortcut = true
    } = config || {};
    if (pos.nodeBefore?.text && isLinkOnlyBlock({ pos, fromShortcut }) && fetchData && (enableEmbed || enableLinkPreview)) {
      let isPreviewAdded = false;
      const { target, rel } = linkConfig || {};
      const url = extractUrlFromNode(pos.nodeBefore);
      if (!url) {
        return false;
      }
      insertPreviewPlaceholder(editor, url, pos, fromShortcut);
      (0, import_utils.fetchLinkPreview)(fetchData, url).then((linkPreviewData) => {
        const shouldEmbed = (0, import_utils.shouldAddEmbed)(
          linkPreviewData.html,
          enableEmbed,
          linkPreviewData.fixedUrl
        );
        const shouldPreview = (0, import_utils.shouldAddLinkPreview)(linkPreviewData.title, enableLinkPreview);
        if (!shouldEmbed && !shouldPreview) {
          return;
        }
        isPreviewAdded = true;
        return (0, import_utils.createLinkPreviewData)({ url, target, rel }, linkPreviewData, config).then(
          (linkPreviewComponentData) => {
            const convertedLinkPreviewData = (0, import_convert_block_data_to_ricos.convertBlockDataToRicos)(
              import_types.LINK_PREVIEW_TYPE,
              linkPreviewComponentData
            );
            const placeholder = findPlaceholderNode(editor, url);
            if (!placeholder) {
              return;
            }
            if (shouldEmbed) {
              replacePlaceholderWithEmbed(editor, placeholder, convertedLinkPreviewData);
            } else {
              updatePlaceholderAttributes(editor, placeholder.id, {
                ...convertedLinkPreviewData,
                loading: false,
                error: false
              });
            }
          }
        );
      }).catch(() => {
        const placeholder = findPlaceholderNode(editor, url);
        if (placeholder) {
          updatePlaceholderAttributes(editor, placeholder.id, {
            loading: false,
            error: true,
            link: { url }
          });
        }
      }).finally(() => {
      });
      return isPreviewAdded;
    }
    return false;
  }
);
const insertPreviewPlaceholder = (editor, url, pos, fromShortcut) => {
  editor.chain().focus().deleteRange(getLinkDeletionRange({ pos, fromShortcut })).insertContent([
    { type: import_ricos_content.TIPTAP_LINK_PREVIEW_TYPE, attrs: { link: { url }, loading: true, error: false } },
    { type: "PARAGRAPH" }
  ]).run();
};
const findPlaceholderNode = (editor, url) => {
  let placeholderNode = null;
  editor.state.doc.descendants((node, pos) => {
    if (node.type.name === import_ricos_content.TIPTAP_LINK_PREVIEW_TYPE && node.attrs.link?.url === url && node.attrs.loading === true) {
      placeholderNode = { id: node.attrs.id, pos, size: node.nodeSize };
      return false;
    }
    return true;
  });
  return placeholderNode;
};
const replacePlaceholderWithEmbed = (editor, placeholder, embedAttrs) => {
  editor.state.doc.descendants((node, pos) => {
    if (node.type.name === import_ricos_content.TIPTAP_LINK_PREVIEW_TYPE && node.attrs.id === placeholder.id) {
      editor.commands.deleteRange({ from: pos, to: pos + node.nodeSize });
      return false;
    }
    return true;
  });
  editor.chain().focus().insertContent([{ type: import_ricos_content.TIPTAP_EMBED_TYPE, attrs: embedAttrs }, { type: "PARAGRAPH" }]).run();
};
const updatePlaceholderAttributes = (editor, nodeId, attrs) => {
  editor.chain().setNodeAttrsById(nodeId, attrs).setMeta("addToHistory", false).run();
};
const tiptapExtensions = [
  (0, import_plugin_commons.createRicosNodeExtension)({
    name: import_ricos_content.TIPTAP_LINK_PREVIEW_TYPE,
    groups: [
      "draggable",
      "not-overtypable",
      { group: "resizable", options: { expandToFullWidthOnOverdrag: true } }
    ],
    type: "react-node",
    reconfigure: (config, _extensions, _props, settings) => ({
      ...config,
      addOptions: () => settings
    }),
    Component: import_link_preview.LinkPreview,
    createExtensionConfig() {
      return {
        group: "block smartBlockCellContent layoutCellContent collapsibleListItemBodyContent tableCellContent",
        selectable: true,
        draggable: true,
        name: this.name,
        addAttributes: () => ({
          containerData: null,
          link: null,
          title: null,
          thumbnailUrl: null,
          description: null,
          html: null,
          styles: null,
          loading: {
            default: false
          },
          error: {
            default: false
          }
        }),
        addCommands() {
          return {
            setLinkPreviewLoading: (loading) => ({ commands }) => {
              return commands.setNode("linkPreview", { loading });
            },
            setLinkPreviewError: (error) => ({ commands }) => {
              return commands.setNode("linkPreview", { error });
            },
            setLinkPreview: (attributes) => ({ commands }) => {
              return commands.setNode("linkPreview", attributes);
            }
          };
        }
      };
    }
  }),
  (0, import_plugin_commons.createRicosNodeExtension)({
    name: import_ricos_content.TIPTAP_EMBED_TYPE,
    groups: ["overlay", "draggable", "not-overtypable"],
    type: "react-node",
    reconfigure: (config, _extensions, _props, settings) => ({
      ...config,
      addOptions: () => settings
    }),
    Component: import_embed.Embed,
    createExtensionConfig() {
      return {
        group: "block smartBlockCellContent layoutCellContent collapsibleListItemBodyContent tableCellContent",
        selectable: true,
        draggable: true,
        name: this.name,
        addAttributes: () => ({
          containerData: null,
          oembed: null,
          src: null
        })
      };
    }
  }),
  (0, import_plugin_commons.createRicosFunctionalExtension)({
    type: "extension",
    groups: ["shortcuts-enabled"],
    name: "linkPreviewEnter",
    reconfigure: (config, _extensions, _props, settings, services) => ({
      ...config,
      addKeyboardShortcuts() {
        const enableEnterToConvertLinks = settings.enableEnterToConvertLinks ?? true;
        if (!enableEnterToConvertLinks) {
          return {};
        }
        const newLine = addLinkPreview(settings);
        const tiptapKeyboardShortcuts = {
          Enter: newLine
        };
        const newLineShortcuts = [];
        services.shortcuts.shortcuts.forEach((shortcut) => {
          if (shortcut.shortcut.name === "NewLine") {
            newLineShortcuts.push(shortcut);
          }
        });
        newLineShortcuts.forEach((newLineShortcut) => {
          const modifier = newLineShortcut.keys.macOs.modifiers[0];
          const key = newLineShortcut.keys.macOs.key;
          const shortcutKey = modifier ? `${modifier}-${key}` : key;
          tiptapKeyboardShortcuts[shortcutKey] = newLine;
        });
        return {
          ...tiptapKeyboardShortcuts
        };
      },
      addCommands() {
        const linkPreviewCommand = addLinkPreview({
          ...settings,
          fromShortcut: false
        });
        return {
          createLinkPreview: () => linkPreviewCommand
        };
      }
    }),
    createExtensionConfig() {
      return {
        name: this.name,
        priority: 101
      };
    }
  })
];
//# sourceMappingURL=tiptap.js.map
