{"version":3,"file":"paste.cjs","sources":["../../../src/slate/plugins/paste.ts"],"sourcesContent":["import type { Descendant, Editor, Node as SlateNode } from \"slate\";\nimport { Transforms } from \"slate\";\nimport { jsx } from \"slate-hyperscript\";\n\nimport type {\n  ComposerBodyAutoLink,\n  ComposerBodyBlockElement,\n  ComposerBodyCustomLink,\n  ComposerBodyInlineElement,\n  ComposerBodyParagraph,\n  ComposerBodyText,\n} from \"../../types\";\nimport { getFiles } from \"../../utils/data-transfer\";\n\n// Based on: https://github.com/ianstormtaylor/slate/blob/main/site/examples/paste-html.tsx\n\nconst NEWLINE_REGEX = /[\\r\\n]/g;\nconst WHITESPACE_REGEX = /\\s+/g;\n\ntype OmitTextChildren<T> = Omit<T, \"text\" | \"children\">;\n\ntype ComposerBodyElementTag = OmitTextChildren<\n  ComposerBodyBlockElement | ComposerBodyInlineElement\n>;\ntype ComposerBodyTextTag = OmitTextChildren<ComposerBodyText>;\n\ntype DeserializedNode =\n  | null\n  | string\n  | Descendant\n  | Descendant[]\n  | DeserializedNode[];\n\nfunction areUrlsEqual(a: string, b: string) {\n  try {\n    const urlA = new URL(a);\n    const urlB = new URL(b);\n\n    return urlA.origin === urlB.origin && urlA.pathname === urlB.pathname;\n  } catch {\n    return false;\n  }\n}\n\nconst createParagraphElement = (): OmitTextChildren<ComposerBodyParagraph> => ({\n  type: \"paragraph\",\n});\n\nconst ELEMENT_TAGS = {\n  A: (\n    element\n  ): OmitTextChildren<ComposerBodyCustomLink | ComposerBodyAutoLink> => {\n    const href = element.getAttribute(\"href\");\n    const innerText = element.innerText;\n\n    return {\n      type: href && areUrlsEqual(href, innerText) ? \"auto-link\" : \"custom-link\",\n      url: href ?? \"\",\n    };\n  },\n  P: createParagraphElement,\n  // Falling back to paragraphs for unsupported elements\n  BLOCKQUOTE: createParagraphElement,\n  H1: createParagraphElement,\n  H2: createParagraphElement,\n  H3: createParagraphElement,\n  H4: createParagraphElement,\n  H5: createParagraphElement,\n  H6: createParagraphElement,\n  LI: createParagraphElement,\n} as Record<string, (node: HTMLElement) => ComposerBodyElementTag>;\n\nconst TEXT_TAGS = {\n  CODE: (): ComposerBodyTextTag => ({ code: true }),\n  DEL: (): ComposerBodyTextTag => ({ strikethrough: true }),\n  EM: (): ComposerBodyTextTag => ({ italic: true }),\n  I: (): ComposerBodyTextTag => ({ italic: true }),\n  S: (): ComposerBodyTextTag => ({ strikethrough: true }),\n  STRONG: (): ComposerBodyTextTag => ({ bold: true }),\n  B: (): ComposerBodyTextTag => ({ bold: true }),\n} as Record<string, (node: HTMLElement) => ComposerBodyTextTag>;\n\nfunction flattenListItems(node: HTMLElement): HTMLElement[] {\n  const listItems: HTMLElement[] = [];\n\n  if (node.nodeName === \"LI\") {\n    listItems.push(node);\n  }\n\n  node.childNodes.forEach((child) => {\n    if (child.nodeType === 1) {\n      listItems.push(...flattenListItems(child as HTMLElement));\n    }\n  });\n\n  return listItems;\n}\n\nfunction jsxTextChildren(\n  children: DeserializedNode[],\n  attrs?: ComposerBodyTextTag\n) {\n  return children.map((child) => jsx(\"text\", attrs, child));\n}\n\nfunction deserialize(node: Node): DeserializedNode {\n  if (node.nodeType === 3) {\n    let text = node.textContent;\n    const isMultiLine = text && NEWLINE_REGEX.test(text);\n\n    if (text && isMultiLine) {\n      text = text.replace(WHITESPACE_REGEX, \" \").trim();\n    }\n\n    return text ? { text } : null;\n  } else if (node.nodeType !== 1) {\n    return null;\n  } else if (node.nodeName === \"BR\") {\n    // Insert a new paragraph\n    return jsx(\"element\", createParagraphElement(), []);\n  }\n\n  const childNodes = Array.from(node.childNodes);\n  let children = childNodes.map(deserialize).flat();\n\n  // Lists aren't supported (yet), so we flatten them into paragraphs\n  if (node.nodeName === \"UL\" || node.nodeName === \"OL\") {\n    const listItems = flattenListItems(node as HTMLElement);\n\n    children = listItems.map((li) => deserialize(li)).flat();\n  }\n\n  if (children.length === 0) {\n    children = [{ text: \"\" }];\n  }\n\n  if (node.nodeName === \"BODY\") {\n    // If the body only contains text nodes, we wrap it in a paragraph\n    if (\n      children.length > 0 &&\n      children.every((child) => typeof child === \"string\")\n    ) {\n      children = [\n        { type: \"paragraph\", children: [{ text: children.join(\"\") }] },\n      ];\n    }\n\n    return jsx(\n      \"fragment\",\n      {},\n      children.filter((child) => typeof child !== \"string\")\n    );\n  }\n\n  if (ELEMENT_TAGS[node.nodeName]) {\n    const attrs = ELEMENT_TAGS[node.nodeName]!(node as HTMLElement);\n\n    return jsx(\"element\", attrs, children);\n  }\n\n  if (TEXT_TAGS[node.nodeName]) {\n    const attrs = TEXT_TAGS[node.nodeName]!(node as HTMLElement);\n\n    // If there is at least one non-text child, we skip this node\n    if (\n      children.some(\n        (child) => child && typeof child !== \"string\" && \"type\" in child\n      )\n    ) {\n      return jsx(\"fragment\", {}, children);\n    }\n\n    return jsxTextChildren(children, attrs);\n  }\n\n  // Guess inline marks based on styles\n  if (node.nodeName === \"SPAN\") {\n    const style = (node as HTMLElement).style;\n    const attrs: ComposerBodyTextTag = {};\n\n    if (\n      style.fontWeight === \"bold\" ||\n      style.fontWeight === \"700\" ||\n      style.fontWeight === \"800\" ||\n      style.fontWeight === \"900\"\n    ) {\n      attrs.bold = true;\n    }\n\n    if (style.fontStyle === \"italic\") {\n      attrs.italic = true;\n    }\n\n    if (style.textDecoration === \"line-through\") {\n      attrs.strikethrough = true;\n    }\n\n    return jsxTextChildren(children, attrs);\n  }\n\n  return children as DeserializedNode;\n}\n\nexport function withPaste(\n  editor: Editor,\n  {\n    createAttachments,\n    pasteFilesAsAttachments,\n  }: {\n    createAttachments: (files: File[]) => void;\n    pasteFilesAsAttachments?: boolean;\n  }\n) {\n  const { insertData } = editor;\n\n  editor.insertData = (data) => {\n    // Create attachments from files when pasting\n    if (data.types.includes(\"Files\") && pasteFilesAsAttachments) {\n      const files = getFiles(data);\n\n      if (files.length > 0) {\n        createAttachments(files);\n\n        return;\n      }\n    }\n\n    // Deserialize rich text from HTML when pasting (unless there's also Slate data)\n    if (\n      data.types.includes(\"text/html\") &&\n      !data.types.includes(\"application/x-slate-fragment\")\n    ) {\n      const html = data.getData(\"text/html\");\n\n      try {\n        const { body } = new DOMParser().parseFromString(html, \"text/html\");\n\n        // WebKit browsers can add a trailing `<br>`\n        body.querySelector(\"br.Apple-interchange-newline\")?.remove();\n\n        // Google Docs can use `<b>` as a wrapper for the entire document,\n        // it shouldn't be supported so we remove it\n        if (body.children.length === 1 && body.children[0]?.nodeName === \"B\") {\n          const wrapper = body.children[0] as HTMLElement;\n\n          while (wrapper.firstChild) {\n            body.insertBefore(wrapper.firstChild, wrapper);\n          }\n\n          body.removeChild(wrapper);\n        }\n\n        const fragment = deserialize(body);\n\n        if (fragment !== null && Array.isArray(fragment)) {\n          Transforms.insertFragment(editor, fragment as SlateNode[]);\n\n          return;\n        }\n      } catch {\n        // Fallback to default `insertData` behavior\n      }\n    }\n\n    // Default `insertData` behavior\n    insertData(data);\n  };\n\n  return editor;\n}\n"],"names":["jsx","getFiles","Transforms"],"mappings":"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"}