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.

70 lines (67 loc) 2.07 kB
import { Node, Transforms, Range, Element } from 'slate'; import { isText, isPlainText } from '../utils/is-text.js'; import { filterActiveMarks } from '../utils/marks.js'; import { selectionContainsInlines } from '../utils/selection-contains-inlines.js'; function isUrl(string) { try { new URL(string); return true; } catch (_) { return false; } } function withCustomLinks(editor) { const { isInline, normalizeNode, insertData } = editor; editor.isInline = (element) => { return element.type === "custom-link" ? true : isInline(element); }; editor.normalizeNode = (entry) => { const [node, path] = entry; if (isText(node)) { const parentNode = Node.parent(editor, path); if (isComposerBodyCustomLink(parentNode)) { if (!isPlainText(node)) { const marks = filterActiveMarks(node); Transforms.unsetNodes(editor, marks, { at: path }); } } } normalizeNode(entry); }; editor.insertData = (data) => { const { selection } = editor; const pastedText = data.getData("text/plain"); let shouldInvokeDefaultBehavior = true; if (selection && !Range.isCollapsed(selection)) { if (selection.anchor.path[0] === selection.focus.path[0]) { if (isUrl(pastedText)) { if (!selectionContainsInlines(editor, (node) => !isText(node))) { Transforms.wrapNodes( editor, { type: "custom-link", url: pastedText, children: [] }, { at: selection, split: true, match: isPlainText } ); shouldInvokeDefaultBehavior = false; } } } } if (shouldInvokeDefaultBehavior) { insertData(data); } }; return editor; } function isComposerBodyCustomLink(node) { return Element.isElement(node) && node.type === "custom-link"; } export { isComposerBodyCustomLink, withCustomLinks }; //# sourceMappingURL=custom-links.js.map