UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

167 lines (163 loc) 5.06 kB
'use strict'; var slate = require('slate'); var slateHyperscript = require('slate-hyperscript'); var dataTransfer = require('../../utils/data-transfer.cjs'); const NEWLINE_REGEX = /[\r\n]/g; const WHITESPACE_REGEX = /\s+/g; function areUrlsEqual(a, b) { try { const urlA = new URL(a); const urlB = new URL(b); return urlA.origin === urlB.origin && urlA.pathname === urlB.pathname; } catch { return false; } } const createParagraphElement = () => ({ type: "paragraph" }); const ELEMENT_TAGS = { A: (element) => { const href = element.getAttribute("href"); const innerText = element.innerText; return { type: href && areUrlsEqual(href, innerText) ? "auto-link" : "custom-link", url: href ?? "" }; }, P: createParagraphElement, BLOCKQUOTE: createParagraphElement, H1: createParagraphElement, H2: createParagraphElement, H3: createParagraphElement, H4: createParagraphElement, H5: createParagraphElement, H6: createParagraphElement, LI: createParagraphElement }; const TEXT_TAGS = { CODE: () => ({ code: true }), DEL: () => ({ strikethrough: true }), EM: () => ({ italic: true }), I: () => ({ italic: true }), S: () => ({ strikethrough: true }), STRONG: () => ({ bold: true }), B: () => ({ bold: true }) }; function flattenListItems(node) { const listItems = []; if (node.nodeName === "LI") { listItems.push(node); } node.childNodes.forEach((child) => { if (child.nodeType === 1) { listItems.push(...flattenListItems(child)); } }); return listItems; } function jsxTextChildren(children, attrs) { return children.map((child) => slateHyperscript.jsx("text", attrs, child)); } function deserialize(node) { if (node.nodeType === 3) { let text = node.textContent; const isMultiLine = text && NEWLINE_REGEX.test(text); if (text && isMultiLine) { text = text.replace(WHITESPACE_REGEX, " ").trim(); } return text ? { text } : null; } else if (node.nodeType !== 1) { return null; } else if (node.nodeName === "BR") { return slateHyperscript.jsx("element", createParagraphElement(), []); } const childNodes = Array.from(node.childNodes); let children = childNodes.map(deserialize).flat(); if (node.nodeName === "UL" || node.nodeName === "OL") { const listItems = flattenListItems(node); children = listItems.map((li) => deserialize(li)).flat(); } if (children.length === 0) { children = [{ text: "" }]; } if (node.nodeName === "BODY") { if (children.length > 0 && children.every((child) => typeof child === "string")) { children = [ { type: "paragraph", children: [{ text: children.join("") }] } ]; } return slateHyperscript.jsx( "fragment", {}, children.filter((child) => typeof child !== "string") ); } if (ELEMENT_TAGS[node.nodeName]) { const attrs = ELEMENT_TAGS[node.nodeName](node); return slateHyperscript.jsx("element", attrs, children); } if (TEXT_TAGS[node.nodeName]) { const attrs = TEXT_TAGS[node.nodeName](node); if (children.some( (child) => child && typeof child !== "string" && "type" in child )) { return slateHyperscript.jsx("fragment", {}, children); } return jsxTextChildren(children, attrs); } if (node.nodeName === "SPAN") { const style = node.style; const attrs = {}; if (style.fontWeight === "bold" || style.fontWeight === "700" || style.fontWeight === "800" || style.fontWeight === "900") { attrs.bold = true; } if (style.fontStyle === "italic") { attrs.italic = true; } if (style.textDecoration === "line-through") { attrs.strikethrough = true; } return jsxTextChildren(children, attrs); } return children; } function withPaste(editor, { createAttachments, pasteFilesAsAttachments }) { const { insertData } = editor; editor.insertData = (data) => { if (data.types.includes("Files") && pasteFilesAsAttachments) { const files = dataTransfer.getFiles(data); if (files.length > 0) { createAttachments(files); return; } } if (data.types.includes("text/html") && !data.types.includes("application/x-slate-fragment")) { const html = data.getData("text/html"); try { const { body } = new DOMParser().parseFromString(html, "text/html"); body.querySelector("br.Apple-interchange-newline")?.remove(); if (body.children.length === 1 && body.children[0]?.nodeName === "B") { const wrapper = body.children[0]; while (wrapper.firstChild) { body.insertBefore(wrapper.firstChild, wrapper); } body.removeChild(wrapper); } const fragment = deserialize(body); if (fragment !== null && Array.isArray(fragment)) { slate.Transforms.insertFragment(editor, fragment); return; } } catch { } } insertData(data); }; return editor; } exports.withPaste = withPaste; //# sourceMappingURL=paste.cjs.map