UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

1,324 lines (1,323 loc) 420 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEffectEvent = require("use-effect-event"), useEditor = require("./_chunks-cjs/use-editor.cjs"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), noop = require("lodash/noop.js"), slate = require("slate"), slateReact = require("slate-react"), debug$g = require("debug"), slateDom = require("slate-dom"), selectionPoint = require("./_chunks-cjs/selection-point.cjs"), util_isEqualSelectionPoints = require("./_chunks-cjs/util.is-equal-selection-points.cjs"), util_selectionPointToBlockOffset = require("./_chunks-cjs/util.selection-point-to-block-offset.cjs"), isEqual = require("lodash/isEqual.js"), types = require("@sanity/types"), selector_isSelectionExpanded = require("./_chunks-cjs/selector.is-selection-expanded.cjs"), selector_isSelectingEntireBlocks = require("./_chunks-cjs/selector.is-selecting-entire-blocks.cjs"), getRandomValues = require("get-random-values-esm"), behaviors_index = require("./behaviors/index.cjs"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), xstate = require("xstate"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), schema = require("@sanity/schema"), flatten = require("lodash/flatten.js"), omit = require("lodash/omit.js"), util_childSelectionPointToBlockOffset = require("./_chunks-cjs/util.child-selection-point-to-block-offset.cjs"), patches = require("@portabletext/patches"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), immer = require("immer"), startCase = require("lodash.startcase"), isPlainObject = require("lodash/isPlainObject.js"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var React__default = /* @__PURE__ */ _interopDefaultCompat(React), noop__default = /* @__PURE__ */ _interopDefaultCompat(noop), debug__default = /* @__PURE__ */ _interopDefaultCompat(debug$g), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual), getRandomValues__default = /* @__PURE__ */ _interopDefaultCompat(getRandomValues), uniq__default = /* @__PURE__ */ _interopDefaultCompat(uniq), flatten__default = /* @__PURE__ */ _interopDefaultCompat(flatten), omit__default = /* @__PURE__ */ _interopDefaultCompat(omit), get__default = /* @__PURE__ */ _interopDefaultCompat(get), isUndefined__default = /* @__PURE__ */ _interopDefaultCompat(isUndefined), omitBy__default = /* @__PURE__ */ _interopDefaultCompat(omitBy), startCase__default = /* @__PURE__ */ _interopDefaultCompat(startCase), isPlainObject__default = /* @__PURE__ */ _interopDefaultCompat(isPlainObject); function EditorEventListener(props) { const $ = reactCompilerRuntime.c(5), editor = useEditor.useEditor(), on = useEffectEvent.useEffectEvent(props.on); let t0; $[0] !== editor || $[1] !== on ? (t0 = () => { const subscription = editor.on("*", on); return () => { subscription.unsubscribe(); }; }, $[0] = editor, $[1] = on, $[2] = t0) : t0 = $[2]; let t1; return $[3] !== editor ? (t1 = [editor], $[3] = editor, $[4] = t1) : t1 = $[4], React.useEffect(t0, t1), null; } const rootName = "sanity-pte:"; debug__default.default(rootName); function debugWithName(name) { const namespace = `${rootName}${name}`; return debug__default.default && debug__default.default.enabled(namespace) ? debug__default.default(namespace) : debug__default.default(rootName); } const VOID_CHILD_KEY = "void-child"; function keepObjectEquality(object, keyMap) { const value = keyMap[object._key]; return value && isEqual__default.default(object, value) ? value : (keyMap[object._key] = object, object); } function toSlateValue(value, { schemaTypes }, keyMap = {}) { return value && Array.isArray(value) ? value.map((block) => { const { _type, _key, ...rest } = block; if (block && block._type === schemaTypes.block.name) { const textBlock = block; let hasInlines = !1; const hasMissingStyle = typeof textBlock.style > "u", hasMissingMarkDefs = typeof textBlock.markDefs > "u", hasMissingChildren = typeof textBlock.children > "u", children = (textBlock.children || []).map((child) => { const { _type: cType, _key: cKey, ...cRest } = child; return cType !== "span" ? (hasInlines = !0, keepObjectEquality({ _type: cType, _key: cKey, children: [{ _key: VOID_CHILD_KEY, _type: "span", text: "", marks: [] }], value: cRest, __inline: !0 }, keyMap)) : child; }); return !hasMissingStyle && !hasMissingMarkDefs && !hasMissingChildren && !hasInlines && slate.Element.isElement(block) ? block : (hasMissingStyle && (rest.style = schemaTypes.styles[0].name), keepObjectEquality({ _type, _key, ...rest, children }, keyMap)); } return keepObjectEquality({ _type, _key, children: [{ _key: VOID_CHILD_KEY, _type: "span", text: "", marks: [] }], value: rest }, keyMap); }) : []; } function fromSlateValue(value, textBlockType, keyMap = {}) { return value.map((block) => { const { _key, _type } = block; if (!_key || !_type) throw new Error("Not a valid block"); if (_type === textBlockType && "children" in block && Array.isArray(block.children) && _key) { let hasInlines = !1; const children = block.children.map((child) => { const { _type: _cType } = child; if ("value" in child && _cType !== "span") { hasInlines = !0; const { value: v, _key: k, _type: t, __inline: _i, children: _c, ...rest } = child; return keepObjectEquality({ ...rest, ...v, _key: k, _type: t }, keyMap); } return child; }); return hasInlines ? keepObjectEquality({ ...block, children, _key, _type }, keyMap) : block; } const blockValue = "value" in block && block.value; return keepObjectEquality({ _key, _type, ...typeof blockValue == "object" ? blockValue : {} }, keyMap); }); } function isEqualToEmptyEditor(children, schemaTypes) { return children === void 0 || children && Array.isArray(children) && children.length === 0 || children && Array.isArray(children) && children.length === 1 && slate.Element.isElement(children[0]) && children[0]._type === schemaTypes.block.name && "style" in children[0] && children[0].style === schemaTypes.styles[0].name && !("listItem" in children[0]) && Array.isArray(children[0].children) && children[0].children.length === 1 && slate.Text.isText(children[0].children[0]) && children[0].children[0]._type === "span" && !children[0].children[0].marks?.join("") && children[0].children[0].text === ""; } function getBlockPath({ editor, _key }) { const [, blockPath] = Array.from(slate.Editor.nodes(editor, { at: [], match: (n) => n._key === _key })).at(0) ?? [void 0, void 0], blockIndex = blockPath?.at(0); if (blockIndex !== void 0) return [blockIndex]; } function getFocusBlock({ editor }) { if (!editor.selection) return [void 0, void 0]; try { return slate.Editor.node(editor, editor.selection.focus.path.slice(0, 1)) ?? [void 0, void 0]; } catch { return [void 0, void 0]; } } function getFocusSpan({ editor }) { if (!editor.selection) return [void 0, void 0]; try { const [node, path] = slate.Editor.node(editor, editor.selection.focus.path); if (editor.isTextSpan(node)) return [node, path]; } catch { return [void 0, void 0]; } return [void 0, void 0]; } function getSelectionStartBlock({ editor }) { if (!editor.selection) return [void 0, void 0]; const selectionStartPoint = slate.Range.start(editor.selection); return getPointBlock({ editor, point: selectionStartPoint }); } function getSelectionEndBlock({ editor }) { if (!editor.selection) return [void 0, void 0]; const selectionEndPoint = slate.Range.end(editor.selection); return getPointBlock({ editor, point: selectionEndPoint }); } function getPointBlock({ editor, point }) { try { const [block] = slate.Editor.node(editor, point.path.slice(0, 1)) ?? [void 0, void 0]; return block ? [block, point.path.slice(0, 1)] : [void 0, void 0]; } catch { return [void 0, void 0]; } } function getFocusChild({ editor }) { const [focusBlock, focusBlockPath] = getFocusBlock({ editor }), childIndex = editor.selection?.focus.path.at(1); if (!focusBlock || !focusBlockPath || childIndex === void 0) return [void 0, void 0]; try { const focusChild = slate.Node.child(focusBlock, childIndex); return focusChild ? [focusChild, [...focusBlockPath, childIndex]] : [void 0, void 0]; } catch { return [void 0, void 0]; } } function getPointChild({ editor, point }) { const [block, blockPath] = getPointBlock({ editor, point }), childIndex = point.path.at(1); if (!block || !blockPath || childIndex === void 0) return [void 0, void 0]; try { const pointChild = slate.Node.child(block, childIndex); return pointChild ? [pointChild, [...blockPath, childIndex]] : [void 0, void 0]; } catch { return [void 0, void 0]; } } function getFirstBlock({ editor }) { if (editor.children.length === 0) return [void 0, void 0]; const firstBlockPath = slate.Editor.start(editor, []).path.at(0); try { return firstBlockPath !== void 0 ? slate.Editor.node(editor, [firstBlockPath]) ?? [void 0, void 0] : [void 0, void 0]; } catch { return [void 0, void 0]; } } function getLastBlock({ editor }) { if (editor.children.length === 0) return [void 0, void 0]; const lastBlockPath = slate.Editor.end(editor, []).path.at(0); try { return lastBlockPath !== void 0 ? slate.Editor.node(editor, [lastBlockPath]) ?? [void 0, void 0] : [void 0, void 0]; } catch { return [void 0, void 0]; } } function getNodeBlock({ editor, schema: schema2, node }) { if (slate.Editor.isEditor(node)) return; if (isBlockElement({ editor, schema: schema2 }, node)) return elementToBlock({ schema: schema2, element: node }); const parent = Array.from(slate.Editor.nodes(editor, { mode: "highest", at: [], match: (n) => isBlockElement({ editor, schema: schema2 }, n) && n.children.some((child) => child._key === node._key) })).at(0)?.at(0); return slate.Element.isElement(parent) ? elementToBlock({ schema: schema2, element: parent }) : void 0; } function elementToBlock({ schema: schema2, element }) { return fromSlateValue([element], schema2.block.name)?.at(0); } function isBlockElement({ editor, schema: schema2 }, node) { return slate.Element.isElement(node) && !editor.isInline(node) && (schema2.block.name === node._type || schema2.blockObjects.some((blockObject) => blockObject.name === node._type)); } function isListItemActive({ editor, listItem }) { if (!editor.selection) return !1; const selectedBlocks = [...slate.Editor.nodes(editor, { at: editor.selection, match: (node) => editor.isTextBlock(node) })]; return selectedBlocks.length > 0 ? selectedBlocks.every(([node]) => editor.isListBlock(node) && node.listItem === listItem) : !1; } function isStyleActive({ editor, style }) { if (!editor.selection) return !1; const selectedBlocks = [...slate.Editor.nodes(editor, { at: editor.selection, match: (node) => editor.isTextBlock(node) })]; return selectedBlocks.length > 0 ? selectedBlocks.every(([node]) => node.style === style) : !1; } function slateRangeToSelection({ schema: schema2, editor, range }) { const [anchorBlock] = getPointBlock({ editor, point: range.anchor }), [focusBlock] = getPointBlock({ editor, point: range.focus }); if (!anchorBlock || !focusBlock) return null; const [anchorChild] = anchorBlock._type === schema2.block.name ? getPointChild({ editor, point: range.anchor }) : [void 0, void 0], [focusChild] = focusBlock._type === schema2.block.name ? getPointChild({ editor, point: range.focus }) : [void 0, void 0], selection = { anchor: { path: [{ _key: anchorBlock._key }], offset: range.anchor.offset }, focus: { path: [{ _key: focusBlock._key }], offset: range.focus.offset }, backward: slate.Range.isBackward(range) }; return anchorChild && (selection.anchor.path.push("children"), selection.anchor.path.push({ _key: anchorChild._key })), focusChild && (selection.focus.path.push("children"), selection.focus.path.push({ _key: focusChild._key })), selection; } function getEventPosition({ editorActor, slateEditor, event }) { if (editorActor.getSnapshot().matches({ setup: "setting up" })) return; const eventNode = getEventNode({ slateEditor, event }); if (!eventNode) return; const eventBlock = getNodeBlock({ editor: slateEditor, schema: editorActor.getSnapshot().context.schema, node: eventNode }), eventPositionBlock = getEventPositionBlock({ node: eventNode, slateEditor, event }), eventSelection = getEventSelection({ schema: editorActor.getSnapshot().context.schema, slateEditor, event }); if (eventBlock && eventPositionBlock && !eventSelection && !slate.Editor.isEditor(eventNode)) return { block: eventPositionBlock, isEditor: !1, selection: { anchor: selectionPoint.getBlockStartPoint({ context: editorActor.getSnapshot().context, block: { node: eventBlock, path: [{ _key: eventBlock._key }] } }), focus: util_isEqualSelectionPoints.getBlockEndPoint({ context: editorActor.getSnapshot().context, block: { node: eventBlock, path: [{ _key: eventBlock._key }] } }) } }; if (!eventPositionBlock || !eventSelection) return; const eventSelectionFocusBlockKey = selectionPoint.getBlockKeyFromSelectionPoint(eventSelection.focus); if (eventSelectionFocusBlockKey !== void 0) return util_selectionPointToBlockOffset.isSelectionCollapsed(eventSelection) && eventBlock && eventSelectionFocusBlockKey !== eventBlock._key ? { block: eventPositionBlock, isEditor: !1, selection: { anchor: selectionPoint.getBlockStartPoint({ context: editorActor.getSnapshot().context, block: { node: eventBlock, path: [{ _key: eventBlock._key }] } }), focus: util_isEqualSelectionPoints.getBlockEndPoint({ context: editorActor.getSnapshot().context, block: { node: eventBlock, path: [{ _key: eventBlock._key }] } }) } } : { block: eventPositionBlock, isEditor: slate.Editor.isEditor(eventNode), selection: eventSelection }; } function getEventNode({ slateEditor, event }) { return slateDom.DOMEditor.hasTarget(slateEditor, event.target) ? slateDom.DOMEditor.toSlateNode(slateEditor, event.target) : void 0; } function getEventPositionBlock({ node, slateEditor, event }) { const [firstBlock] = getFirstBlock({ editor: slateEditor }); if (!firstBlock) return; const firstBlockRect = slateDom.DOMEditor.toDOMNode(slateEditor, firstBlock).getBoundingClientRect(); if (event.pageY < firstBlockRect.top) return "start"; const [lastBlock] = getLastBlock({ editor: slateEditor }); if (!lastBlock) return; const lastBlockRef = slateDom.DOMEditor.toDOMNode(slateEditor, lastBlock).getBoundingClientRect(); if (event.pageY > lastBlockRef.bottom) return "end"; const elementRect = slateDom.DOMEditor.toDOMNode(slateEditor, node).getBoundingClientRect(), top = elementRect.top, height = elementRect.height; return Math.abs(top - event.pageY) < height / 2 ? "start" : "end"; } function getEventSelection({ schema: schema2, slateEditor, event }) { const range = getSlateRangeFromEvent(slateEditor, event); return range ? slateRangeToSelection({ schema: schema2, editor: slateEditor, range }) : null; } function getSlateRangeFromEvent(editor, event) { if (!event.target || !slateDom.isDOMNode(event.target)) return; const window2 = slateDom.DOMEditor.getWindow(editor); let domRange; if (window2.document.caretPositionFromPoint !== void 0) { const position = window2.document.caretPositionFromPoint(event.clientX, event.clientY); if (position) try { domRange = window2.document.createRange(), domRange.setStart(position.offsetNode, position.offset), domRange.setEnd(position.offsetNode, position.offset); } catch { } } else if (window2.document.caretRangeFromPoint !== void 0) domRange = window2.document.caretRangeFromPoint(event.clientX, event.clientY) ?? void 0; else { console.warn("Neither caretPositionFromPoint nor caretRangeFromPoint is supported"); return; } if (!domRange) return; let range; try { range = slateDom.DOMEditor.toSlateRange(editor, domRange, { exactMatch: !1, // It can still throw even with this option set to true suppressThrow: !1 }); } catch { } return range; } function toSlatePath(path, editor) { if (!editor) return []; const [block, blockPath] = Array.from(slate.Editor.nodes(editor, { at: [], match: (n) => types.isKeySegment(path[0]) && n._key === path[0]._key }))[0] || [void 0, void 0]; if (!block || !slate.Element.isElement(block)) return []; if (editor.isVoid(block)) return [blockPath[0], 0]; const childPath = [path[2]], childIndex = block.children.findIndex((child) => isEqual__default.default([{ _key: child._key }], childPath)); if (childIndex >= 0 && block.children[childIndex]) { const child = block.children[childIndex]; return slate.Element.isElement(child) && editor.isVoid(child) ? blockPath.concat(childIndex).concat(0) : blockPath.concat(childIndex); } return [blockPath[0], 0]; } function toSlateRange(selection, editor) { if (!selection || !editor) return null; const anchor = { path: toSlatePath(selection.anchor.path, editor), offset: selection.anchor.offset }, focus = { path: toSlatePath(selection.focus.path, editor), offset: selection.focus.offset }; return focus.path.length === 0 || anchor.path.length === 0 ? null : anchor && focus ? { anchor, focus } : null; } function moveRangeByOperation(range, operation) { const anchor = slate.Point.transform(range.anchor, operation), focus = slate.Point.transform(range.focus, operation); return anchor === null || focus === null ? null : slate.Point.equals(anchor, range.anchor) && slate.Point.equals(focus, range.focus) ? range : { anchor, focus }; } function normalizePoint(point, value) { if (!point || !value) return null; const newPath = []; let newOffset = point.offset || 0; const blockKey = typeof point.path[0] == "object" && "_key" in point.path[0] && point.path[0]._key, childKey = typeof point.path[2] == "object" && "_key" in point.path[2] && point.path[2]._key, block = value.find((blk) => blk._key === blockKey); if (block) newPath.push({ _key: block._key }); else return null; if (block && point.path[1] === "children") { if (!block.children || Array.isArray(block.children) && block.children.length === 0) return null; const child = Array.isArray(block.children) && block.children.find((cld) => cld._key === childKey); if (child) newPath.push("children"), newPath.push({ _key: child._key }), newOffset = child.text && child.text.length >= point.offset ? point.offset : child.text && child.text.length || 0; else return null; } return { path: newPath, offset: newOffset }; } function normalizeSelection(selection, value) { if (!selection || !value || value.length === 0) return null; let newAnchor = null, newFocus = null; const { anchor, focus } = selection; return anchor && value.find((blk) => isEqual__default.default({ _key: blk._key }, anchor.path[0])) && (newAnchor = normalizePoint(anchor, value)), focus && value.find((blk) => isEqual__default.default({ _key: blk._key }, focus.path[0])) && (newFocus = normalizePoint(focus, value)), newAnchor && newFocus ? { anchor: newAnchor, focus: newFocus, backward: selection.backward } : null; } const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE_ELEMENT = /* @__PURE__ */ new WeakMap(), KEY_TO_VALUE_ELEMENT = /* @__PURE__ */ new WeakMap(), SLATE_TO_PORTABLE_TEXT_RANGE = /* @__PURE__ */ new WeakMap(), EditorActorContext = React.createContext({}); function DropIndicator() { const $ = reactCompilerRuntime.c(1); let t0; return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsxRuntime.jsx("div", { contentEditable: !1, className: "pt-drop-indicator", style: { position: "absolute", width: "100%", height: 1, borderBottom: "1px solid currentColor", zIndex: 5 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", {}) }), $[0] = t0) : t0 = $[0], t0; } function RenderDefaultBlockObject(props) { const $ = reactCompilerRuntime.c(4); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = { userSelect: "none" }, $[0] = t0) : t0 = $[0]; let t1; return $[1] !== props.blockObject._key || $[2] !== props.blockObject._type ? (t1 = /* @__PURE__ */ jsxRuntime.jsxs("div", { style: t0, children: [ "[", props.blockObject._type, ": ", props.blockObject._key, "]" ] }), $[1] = props.blockObject._key, $[2] = props.blockObject._type, $[3] = t1) : t1 = $[3], t1; } function RenderDefaultInlineObject(props) { const $ = reactCompilerRuntime.c(4); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = { userSelect: "none" }, $[0] = t0) : t0 = $[0]; let t1; return $[1] !== props.inlineObject._key || $[2] !== props.inlineObject._type ? (t1 = /* @__PURE__ */ jsxRuntime.jsxs("span", { style: t0, children: [ "[", props.inlineObject._type, ": ", props.inlineObject._key, "]" ] }), $[1] = props.inlineObject._key, $[2] = props.inlineObject._type, $[3] = t1) : t1 = $[3], t1; } function getDragSelection({ eventSelection, snapshot }) { let dragSelection = eventSelection; if (selector_isSelectingEntireBlocks.getFocusInlineObject({ context: { ...snapshot.context, selection: eventSelection } })) return dragSelection; const draggingCollapsedSelection = selector_isSelectionExpanded.isSelectionCollapsed({ context: { ...snapshot.context, selection: eventSelection } }), draggedTextBlock = selector_isSelectionExpanded.getFocusTextBlock({ context: { ...snapshot.context, selection: eventSelection } }), draggedSpan = selector_isSelectionExpanded.getFocusSpan({ context: { ...snapshot.context, selection: eventSelection } }); draggingCollapsedSelection && draggedTextBlock && draggedSpan && (dragSelection = { anchor: selectionPoint.getBlockStartPoint({ context: snapshot.context, block: draggedTextBlock }), focus: util_isEqualSelectionPoints.getBlockEndPoint({ context: snapshot.context, block: draggedTextBlock }) }); const selectedBlocks = selector_isSelectionExpanded.getSelectedBlocks(snapshot); if (snapshot.context.selection && selector_isSelectionExpanded.isSelectionExpanded(snapshot) && selectedBlocks.length > 1) { const selectionStartBlock = selector_isSelectionExpanded.getSelectionStartBlock(snapshot), selectionEndBlock = selector_isSelectionExpanded.getSelectionEndBlock(snapshot); if (!selectionStartBlock || !selectionEndBlock) return dragSelection; const selectionStartPoint = selectionPoint.getBlockStartPoint({ context: snapshot.context, block: selectionStartBlock }), selectionEndPoint = util_isEqualSelectionPoints.getBlockEndPoint({ context: snapshot.context, block: selectionEndBlock }); selector_isSelectingEntireBlocks.isOverlappingSelection(eventSelection)({ ...snapshot, context: { ...snapshot.context, selection: { anchor: selectionStartPoint, focus: selectionEndPoint } } }) && (dragSelection = { anchor: selectionStartPoint, focus: selectionEndPoint }); } return dragSelection; } const defaultKeyGenerator = () => randomKey(12), getByteHexTable = /* @__PURE__ */ (() => { let table; return () => { if (table) return table; table = []; for (let i = 0; i < 256; ++i) table[i] = (i + 256).toString(16).slice(1); return table; }; })(); function whatwgRNG(length = 16) { const rnds8 = new Uint8Array(length); return getRandomValues__default.default(rnds8), rnds8; } function randomKey(length) { const table = getByteHexTable(); return whatwgRNG(length).reduce((str, n) => str + table[n], "").slice(0, length); } function createEditorPriority(config) { return { id: defaultKeyGenerator(), name: config?.name, reference: config?.reference }; } const corePriority = createEditorPriority({ name: "core" }); function createCoreBlockElementBehaviorsConfig({ key, onSetDragPositionBlock }) { return [{ behavior: behaviors_index.defineBehavior({ on: "drag.dragover", guard: ({ snapshot, event }) => { const dropFocusBlock = selector_isSelectionExpanded.getFocusBlock({ context: { ...snapshot.context, selection: event.position.selection } }); if (!dropFocusBlock || dropFocusBlock.node._key !== key) return !1; const dragOrigin = event.dragOrigin; if (!dragOrigin) return !1; const dragSelection = getDragSelection({ eventSelection: dragOrigin.selection, snapshot }); return selector_isSelectionExpanded.getSelectedBlocks({ context: { ...snapshot.context, selection: dragSelection } }).some((draggedBlock) => draggedBlock.node._key === key) ? !1 : selector_isSelectingEntireBlocks.isSelectingEntireBlocks({ context: { ...snapshot.context, selection: dragSelection } }); }, actions: [({ event }) => [{ type: "effect", effect: () => { onSetDragPositionBlock(event.position.block); } }]] }), priority: createEditorPriority({ reference: { priority: corePriority, importance: "lower" } }) }, { behavior: behaviors_index.defineBehavior({ on: "drag.*", guard: ({ event }) => event.type !== "drag.dragover", actions: [({ event }) => [{ type: "effect", effect: () => { onSetDragPositionBlock(void 0); } }, behaviors_index.forward(event)]] }), priority: createEditorPriority({ reference: { priority: corePriority, importance: "lower" } }) }]; } function useCoreBlockElementBehaviors(t0) { const $ = reactCompilerRuntime.c(5), { key, onSetDragPositionBlock } = t0, editorActor = React.useContext(EditorActorContext); let t1, t2; $[0] !== editorActor || $[1] !== key || $[2] !== onSetDragPositionBlock ? (t1 = () => { const behaviorConfigs = createCoreBlockElementBehaviorsConfig({ key, onSetDragPositionBlock }); for (const behaviorConfig of behaviorConfigs) editorActor.send({ type: "add behavior", behaviorConfig }); return () => { for (const behaviorConfig_0 of behaviorConfigs) editorActor.send({ type: "remove behavior", behaviorConfig: behaviorConfig_0 }); }; }, t2 = [editorActor, key, onSetDragPositionBlock], $[0] = editorActor, $[1] = key, $[2] = onSetDragPositionBlock, $[3] = t1, $[4] = t2) : (t1 = $[3], t2 = $[4]), React.useEffect(t1, t2); } function RenderBlockObject(props) { const [dragPositionBlock, setDragPositionBlock] = React.useState(), blockObjectRef = React.useRef(null), slateEditor = slateReact.useSlateStatic(), selected = slateReact.useSelected(), editorActor = React.useContext(EditorActorContext); useCoreBlockElementBehaviors({ key: props.element._key, onSetDragPositionBlock: setDragPositionBlock }); const legacySchemaType = react.useSelector(editorActor, (s) => s.context.getLegacySchema().blockObjects.find((blockObject) => blockObject.name === props.element._type)); legacySchemaType || console.error(`Block object type ${props.element._type} not found in Schema`); const focused = selected && slateEditor.selection !== null && slate.Range.isCollapsed(slateEditor.selection); return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...props.attributes, className: "pt-block pt-object-block", "data-block-key": props.element._key, "data-block-name": props.element._type, "data-block-type": "object", children: [ dragPositionBlock === "start" ? /* @__PURE__ */ jsxRuntime.jsx(DropIndicator, {}) : null, props.children, /* @__PURE__ */ jsxRuntime.jsx("div", { ref: blockObjectRef, contentEditable: !1, draggable: !props.readOnly, children: props.renderBlock && legacySchemaType ? props.renderBlock({ children: /* @__PURE__ */ jsxRuntime.jsx(RenderDefaultBlockObject, { blockObject: props.blockObject }), editorElementRef: blockObjectRef, focused, path: [{ _key: props.element._key }], schemaType: legacySchemaType, selected, type: legacySchemaType, value: props.blockObject }) : /* @__PURE__ */ jsxRuntime.jsx(RenderDefaultBlockObject, { blockObject: props.blockObject }) }), dragPositionBlock === "end" ? /* @__PURE__ */ jsxRuntime.jsx(DropIndicator, {}) : null ] }); } function RenderInlineObject(props) { const inlineObjectRef = React.useRef(null), slateEditor = slateReact.useSlateStatic(), selected = slateReact.useSelected(), editorActor = React.useContext(EditorActorContext), legacySchemaType = react.useSelector(editorActor, (s) => s.context.getLegacySchema().inlineObjects.find((inlineObject) => inlineObject.name === props.element._type)); legacySchemaType || console.error(`Inline object type ${props.element._type} not found in Schema`); const focused = selected && slateEditor.selection !== null && slate.Range.isCollapsed(slateEditor.selection), path = slateDom.DOMEditor.findPath(slateEditor, props.element), [block] = getPointBlock({ editor: slateEditor, point: { path, offset: 0 } }); return block || console.error(`Unable to find parent block of inline object ${props.element._key}`), /* @__PURE__ */ jsxRuntime.jsxs("span", { ...props.attributes, draggable: !props.readOnly, className: "pt-inline-object", "data-child-key": props.inlineObject._key, "data-child-name": props.inlineObject._type, "data-child-type": "object", children: [ props.children, /* @__PURE__ */ jsxRuntime.jsx("span", { ref: inlineObjectRef, style: { display: "inline-block" }, children: props.renderChild && block && legacySchemaType ? props.renderChild({ annotations: [], children: /* @__PURE__ */ jsxRuntime.jsx(RenderDefaultInlineObject, { inlineObject: props.inlineObject }), editorElementRef: inlineObjectRef, selected, focused, path: [{ _key: block._key }, "children", { _key: props.element._key }], schemaType: legacySchemaType, value: props.inlineObject, type: legacySchemaType }) : /* @__PURE__ */ jsxRuntime.jsx(RenderDefaultInlineObject, { inlineObject: props.inlineObject }) }) ] }); } function RenderTextBlock(props) { const [dragPositionBlock, setDragPositionBlock] = React.useState(), blockRef = React.useRef(null), slateEditor = slateReact.useSlateStatic(), selected = slateReact.useSelected(), editorActor = React.useContext(EditorActorContext); useCoreBlockElementBehaviors({ key: props.element._key, onSetDragPositionBlock: setDragPositionBlock }); const legacySchema = react.useSelector(editorActor, (s) => s.context.getLegacySchema()), focused = selected && slateEditor.selection !== null && slate.Range.isCollapsed(slateEditor.selection); let children = props.children; const legacyBlockSchemaType = legacySchema.block; if (props.renderStyle && props.textBlock.style) { const legacyStyleSchemaType = props.textBlock.style !== void 0 ? legacySchema.styles.find((style) => style.value === props.textBlock.style) : void 0; legacyStyleSchemaType ? children = props.renderStyle({ block: props.textBlock, children, editorElementRef: blockRef, focused, path: [{ _key: props.textBlock._key }], schemaType: legacyStyleSchemaType, selected, value: props.textBlock.style }) : console.error(`Unable to find Schema type for text block style ${props.textBlock.style}`); } if (props.renderListItem && props.textBlock.listItem) { const legacyListItemSchemaType = legacySchema.lists.find((list) => list.value === props.textBlock.listItem); legacyListItemSchemaType ? children = props.renderListItem({ block: props.textBlock, children, editorElementRef: blockRef, focused, level: props.textBlock.level ?? 1, path: [{ _key: props.textBlock._key }], selected, value: props.textBlock.listItem, schemaType: legacyListItemSchemaType }) : console.error(`Unable to find Schema type for text block list item ${props.textBlock.listItem}`); } return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...props.attributes, className: ["pt-block", "pt-text-block", ...props.textBlock.style ? [`pt-text-block-style-${props.textBlock.style}`] : [], ...props.textBlock.listItem ? ["pt-list-item", `pt-list-item-${props.textBlock.listItem}`, `pt-list-item-level-${props.textBlock.level ?? 1}`] : []].join(" "), spellCheck: props.spellCheck, "data-block-key": props.textBlock._key, "data-block-name": props.textBlock._type, "data-block-type": "text", ...props.textBlock.listItem !== void 0 ? { "data-list-item": props.textBlock.listItem } : {}, ...props.textBlock.level !== void 0 ? { "data-level": props.textBlock.level } : {}, ...props.textBlock.style !== void 0 ? { "data-style": props.textBlock.style } : {}, children: [ dragPositionBlock === "start" ? /* @__PURE__ */ jsxRuntime.jsx(DropIndicator, {}) : null, /* @__PURE__ */ jsxRuntime.jsx("div", { ref: blockRef, children: props.renderBlock ? props.renderBlock({ children, editorElementRef: blockRef, focused, level: props.textBlock.level, listItem: props.textBlock.listItem, path: [{ _key: props.textBlock._key }], selected, schemaType: legacyBlockSchemaType, style: props.textBlock.style, type: legacyBlockSchemaType, value: props.textBlock }) : children }), dragPositionBlock === "end" ? /* @__PURE__ */ jsxRuntime.jsx(DropIndicator, {}) : null ] }); } function RenderElement(props) { const $ = reactCompilerRuntime.c(43), editorActor = React.useContext(EditorActorContext), schema2 = react.useSelector(editorActor, _temp$1); if ("__inline" in props.element && props.element.__inline === !0) { let t02; $[0] !== props.element ? (t02 = "value" in props.element && typeof props.element.value == "object" ? props.element.value : {}, $[0] = props.element, $[1] = t02) : t02 = $[1]; let t12; $[2] !== props.element._key || $[3] !== props.element._type || $[4] !== t02 ? (t12 = { _key: props.element._key, _type: props.element._type, ...t02 }, $[2] = props.element._key, $[3] = props.element._type, $[4] = t02, $[5] = t12) : t12 = $[5]; const inlineObject = t12; schema2.inlineObjects.find((inlineObject_0) => inlineObject_0.name === props.element._type) || console.error(`Unable to find Inline Object "${props.element._type}" in Schema`); let t22; $[6] !== inlineObject || $[7] !== props.element._key || $[8] !== props.element._type ? (t22 = inlineObject ?? { _key: props.element._key, _type: props.element._type }, $[6] = inlineObject, $[7] = props.element._key, $[8] = props.element._type, $[9] = t22) : t22 = $[9]; let t32; return $[10] !== props.attributes || $[11] !== props.children || $[12] !== props.element || $[13] !== props.readOnly || $[14] !== props.renderChild || $[15] !== t22 ? (t32 = /* @__PURE__ */ jsxRuntime.jsx(RenderInlineObject, { attributes: props.attributes, element: props.element, inlineObject: t22, readOnly: props.readOnly, renderChild: props.renderChild, children: props.children }), $[10] = props.attributes, $[11] = props.children, $[12] = props.element, $[13] = props.readOnly, $[14] = props.renderChild, $[15] = t22, $[16] = t32) : t32 = $[16], t32; } if (selectionPoint.isTextBlock({ schema: schema2 }, props.element)) { let t02; return $[17] !== props.attributes || $[18] !== props.children || $[19] !== props.element || $[20] !== props.readOnly || $[21] !== props.renderBlock || $[22] !== props.renderListItem || $[23] !== props.renderStyle || $[24] !== props.spellCheck ? (t02 = /* @__PURE__ */ jsxRuntime.jsx(RenderTextBlock, { attributes: props.attributes, element: props.element, readOnly: props.readOnly, renderBlock: props.renderBlock, renderListItem: props.renderListItem, renderStyle: props.renderStyle, spellCheck: props.spellCheck, textBlock: props.element, children: props.children }), $[17] = props.attributes, $[18] = props.children, $[19] = props.element, $[20] = props.readOnly, $[21] = props.renderBlock, $[22] = props.renderListItem, $[23] = props.renderStyle, $[24] = props.spellCheck, $[25] = t02) : t02 = $[25], t02; } let t0; $[26] !== props.element ? (t0 = "value" in props.element && typeof props.element.value == "object" ? props.element.value : {}, $[26] = props.element, $[27] = t0) : t0 = $[27]; let t1; $[28] !== props.element._key || $[29] !== props.element._type || $[30] !== t0 ? (t1 = { _key: props.element._key, _type: props.element._type, ...t0 }, $[28] = props.element._key, $[29] = props.element._type, $[30] = t0, $[31] = t1) : t1 = $[31]; const blockObject = t1; schema2.blockObjects.find((blockObject_0) => blockObject_0.name === props.element._type) || console.error(`Unable to find Block Object "${props.element._type}" in Schema`); let t2; $[32] !== blockObject || $[33] !== props.element._key || $[34] !== props.element._type ? (t2 = blockObject ?? { _key: props.element._key, _type: props.element._type }, $[32] = blockObject, $[33] = props.element._key, $[34] = props.element._type, $[35] = t2) : t2 = $[35]; let t3; return $[36] !== props.attributes || $[37] !== props.children || $[38] !== props.element || $[39] !== props.readOnly || $[40] !== props.renderBlock || $[41] !== t2 ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(RenderBlockObject, { attributes: props.attributes, blockObject: t2, element: props.element, readOnly: props.readOnly, renderBlock: props.renderBlock, children: props.children }), $[36] = props.attributes, $[37] = props.children, $[38] = props.element, $[39] = props.readOnly, $[40] = props.renderBlock, $[41] = t2, $[42] = t3) : t3 = $[42], t3; } function _temp$1(s) { return s.context.schema; } const PortableTextEditorContext = React.createContext(null), usePortableTextEditor = () => { const editor = React.useContext(PortableTextEditorContext); if (!editor) throw new Error("The `usePortableTextEditor` hook must be used inside the <PortableTextEditor> component's context."); return editor; }, forEachActor = (actorRef, callback) => { callback(actorRef); const children = actorRef.getSnapshot().children; children && Object.values(children).forEach((child) => { forEachActor(child, callback); }); }; function stopActor(actorRef) { const persistedSnapshots = []; forEachActor(actorRef, (ref) => { persistedSnapshots.push([ref, ref.getSnapshot()]), ref.observers = /* @__PURE__ */ new Set(); }); const systemSnapshot = actorRef.system.getSnapshot?.(); actorRef.stop(), actorRef.system._snapshot = systemSnapshot, persistedSnapshots.forEach(([ref, snapshot]) => { ref._processingStatus = 0, ref._snapshot = snapshot; }); } const converterJson = { mimeType: "application/json", serialize: ({ snapshot, event }) => { const portableTextConverter = snapshot.context.converters.find((converter) => converter.mimeType === "application/x-portable-text"); return portableTextConverter ? { ...portableTextConverter.serialize({ snapshot, event }), mimeType: "application/json", originEvent: event.originEvent } : { type: "serialization.failure", mimeType: "application/json", originEvent: event.originEvent, reason: "No application/x-portable-text Converter found" }; }, deserialize: ({ snapshot, event }) => { const portableTextConverter = snapshot.context.converters.find((converter) => converter.mimeType === "application/x-portable-text"); return portableTextConverter ? { ...portableTextConverter.deserialize({ snapshot, event }), mimeType: "application/json" } : { type: "deserialization.failure", mimeType: "application/json", reason: "No application/x-portable-text Converter found" }; } }, converterPortableText = { mimeType: "application/x-portable-text", serialize: ({ snapshot, event }) => { const selection = snapshot.context.selection; if (!selection) return { type: "serialization.failure", mimeType: "application/x-portable-text", originEvent: event.originEvent, reason: "No selection" }; const blocks = selectionPoint.sliceBlocks({ context: { selection, schema: snapshot.context.schema }, blocks: snapshot.context.value }); return blocks.length === 0 ? { type: "serialization.failure", mimeType: "application/x-portable-text", reason: "No blocks serialized", originEvent: event.originEvent } : { type: "serialization.success", data: JSON.stringify(blocks), mimeType: "application/x-portable-text", originEvent: event.originEvent }; }, deserialize: ({ snapshot, event }) => { const blocks = JSON.parse(event.data); if (!Array.isArray(blocks)) return { type: "deserialization.failure", mimeType: "application/x-portable-text", reason: "Data is not an array" }; const parsedBlocks = blocks.flatMap((block) => { const parsedBlock = selectionPoint.parseBlock({ context: snapshot.context, block, options: { refreshKeys: !0, validateFields: !1 } }); return parsedBlock ? [parsedBlock] : []; }); return parsedBlocks.length === 0 && blocks.length > 0 ? { type: "deserialization.failure", mimeType: "application/x-portable-text", reason: "No blocks were parsed" } : { type: "deserialization.success", data: parsedBlocks, mimeType: "application/x-portable-text" }; } }; function createConverterTextHtml(legacySchema) { return { mimeType: "text/html", serialize: ({ snapshot, event }) => { const selection = snapshot.context.selection; if (!selection) return { type: "serialization.failure", mimeType: "text/html", originEvent: event.originEvent, reason: "No selection" }; const blocks = selectionPoint.sliceBlocks({ context: { selection, schema: snapshot.context.schema }, blocks: snapshot.context.value }), html = toHtml.toHTML(blocks, { onMissingComponent: !1, components: { unknownType: ({ children }) => children !== void 0 ? `${children}` : "" } }); return html === "" ? { type: "serialization.failure", mimeType: "text/html", originEvent: event.originEvent, reason: "Serialized HTML is empty" } : { type: "serialization.success", data: html, mimeType: "text/html", originEvent: event.originEvent }; }, deserialize: ({ snapshot, event }) => { const parsedBlocks = blockTools.htmlToBlocks(event.data, legacySchema.portableText, { keyGenerator: snapshot.context.keyGenerator, unstable_whitespaceOnPasteMode: legacySchema.block.options.unstable_whitespaceOnPasteMode }).flatMap((block) => { const parsedBlock = selectionPoint.parseBlock({ context: snapshot.context, block, options: { refreshKeys: !1, validateFields: !0 } }); return parsedBlock ? [parsedBlock] : []; }); return parsedBlocks.length === 0 ? { type: "deserialization.failure", mimeType: "text/html", reason: "No blocks deserialized" } : { type: "deserialization.success", data: parsedBlocks, mimeType: "text/html" }; } }; } function createConverterTextPlain(legacySchema) { return { mimeType: "text/plain", serialize: ({ snapshot, event }) => { const selection = snapshot.context.selection; return selection ? { type: "serialization.success", data: selectionPoint.sliceBlocks({ context: { selection, schema: snapshot.context.schema }, blocks: snapshot.context.value }).map((block) => selectionPoint.isTextBlock(snapshot.context, block) ? block.children.map((child) => child._type === snapshot.context.schema.span.name ? child.text : event.originEvent === "drag.dragstart" ? `[${snapshot.context.schema.inlineObjects.find((inlineObjectType) => inlineObjectType.name === child._type)?.title ?? "Object"}]` : "").join("") : event.originEvent === "drag.dragstart" ? `[${snapshot.context.schema.blockObjects.find((blockObjectType) => blockObjectType.name === block._type)?.title ?? "Object"}]` : "").filter((block) => block !== "").join(` `), mimeType: "text/plain", originEvent: event.originEvent } : { type: "serialization.failure", mimeType: "text/plain", originEvent: event.originEvent, reason: "No selection" }; }, deserialize: ({ snapshot, event }) => { const textToHtml = `<html><body>${escapeHtml(event.data).split(/\n{2,}/).map((line) => line ? `<p>${line.replace(/(?:\r\n|\r|\n)/g, "<br/>")}</p>` : "<p></p>").join("")}</body></html>`, parsedBlocks = blockTools.htmlToBlocks(textToHtml, legacySchema.portableText, { keyGenerator: snapshot.context.keyGenerator }).flatMap((block) => { const parsedBlock = selectionPoint.parseBlock({ context: snapshot.context, block, options: { refreshKeys: !1, validateFields: !0 } }); return parsedBlock ? [parsedBlock] : []; }); return parsedBlocks.length === 0 ? { type: "deserialization.failure", mimeType: "text/plain", reason: "No blocks deserialized" } : { type: "deserialization.success", data: parsedBlocks, mimeType: "text/plain" }; } }; } const entityMap = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;", "/": "&#x2F;", "`": "&#x60;", "=": "&#x3D;" }; function escapeHtml(str) { return String(str).replace(/[&<>"'`=/]/g, (s) => entityMap[s]); } function createCoreConverters(legacySchema) { return [converterJson, converterPortableText, createConverterTextHtml(legacySchema), createConverterTextPlain(legacySchema)]; } function compileType(rawType) { return schema.Schema.compile({ name: "blockTypeSchema", types: [rawType] }).get(rawType.name); } function createPlaceholderBlock(context) { return { _type: context.schema.block.name, _key: context.keyGenerator(), style: context.schema.styles[0].name ?? "normal", markDefs: [], children: [{ _type: context.schema.span.name, _key: context.keyGenerator(), text: "", marks: [] }] }; } function getActiveAnnotations({ markState, schema: schema2 }) { return (markState?.marks ?? []).filter((mark) => !schema2.decorators.map((decorator) => decorator.name).includes(mark)); } function getActiveDecorators({ decoratorState, markState, schema: schema2 }) { const decorators = schema2.decorators.map((decorator) => decorator.name); let activeDecorators = (markState?.marks ?? []).filter((mark) => decorators.includes(mark)); for (const decorator in decoratorState) decoratorState[decorator] === !1 ? activeDecorators = activeDecorators.filter((activeDecorator) =>