@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
JavaScript
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