UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

240 lines (239 loc) 7.5 kB
import { isPortableTextTextBlock, isPortableTextSpan, isKeySegment } from "@sanity/types"; function isKeyedSegment(segment) { return typeof segment == "object" && segment !== null && "_key" in segment; } function blockOffsetToSpanSelectionPoint({ value, blockOffset, direction }) { let offsetLeft = blockOffset.offset, selectionPoint, skippedInlineObject = !1; for (const block of value) if (block._key === blockOffset.path[0]._key && isPortableTextTextBlock(block)) for (const child of block.children) { if (direction === "forward") { if (!isPortableTextSpan(child)) continue; if (offsetLeft <= child.text.length) { selectionPoint = { path: [...blockOffset.path, "children", { _key: child._key }], offset: offsetLeft }; break; } offsetLeft -= child.text.length; continue; } if (!isPortableTextSpan(child)) { skippedInlineObject = !0; continue; } if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) { skippedInlineObject && (selectionPoint = { path: [...blockOffset.path, "children", { _key: child._key }], offset: 0 }); break; } if (offsetLeft > child.text.length) { offsetLeft -= child.text.length; continue; } if (offsetLeft <= child.text.length && (selectionPoint = { path: [...blockOffset.path, "children", { _key: child._key }], offset: offsetLeft }, offsetLeft -= child.text.length, offsetLeft !== 0)) break; } return selectionPoint; } function spanSelectionPointToBlockOffset({ value, selectionPoint }) { let offset = 0; const blockKey = isKeyedSegment(selectionPoint.path[0]) ? selectionPoint.path[0]._key : void 0, spanKey = isKeyedSegment(selectionPoint.path[2]) ? selectionPoint.path[2]._key : void 0; if (!(!blockKey || !spanKey)) { for (const block of value) if (block._key === blockKey && isPortableTextTextBlock(block)) { for (const child of block.children) if (isPortableTextSpan(child)) { if (child._key === spanKey) return { path: [{ _key: block._key }], offset: offset + selectionPoint.offset }; offset += child.text.length; } } } } function getBlockEndPoint({ node, path }) { if (isPortableTextTextBlock(node)) { const lastChild = node.children[node.children.length - 1]; if (lastChild) return { path: [...path, "children", { _key: lastChild._key }], offset: isPortableTextSpan(lastChild) ? lastChild.text.length : 0 }; } return { path, offset: 0 }; } function getBlockStartPoint({ node, path }) { return isPortableTextTextBlock(node) ? { path: [...path, "children", { _key: node.children[0]._key }], offset: 0 } : { path, offset: 0 }; } function getTextBlockText(block) { return block.children.map((child) => child.text ?? "").join(""); } function isEmptyTextBlock(block) { if (!isPortableTextTextBlock(block)) return !1; const onlyText = block.children.every(isPortableTextSpan), blockText = getTextBlockText(block); return onlyText && blockText === ""; } function isEqualSelectionPoints(a, b) { return a.offset === b.offset && JSON.stringify(a.path) === JSON.stringify(b.path); } function isSpan(context, child) { return child._type === context.schema.span.name; } function reverseSelection(selection) { return selection && (selection.backward ? { anchor: selection.focus, focus: selection.anchor, backward: !1 } : { anchor: selection.focus, focus: selection.anchor, backward: !0 }); } function sliceBlocks({ blocks, selection }) { const slice = []; if (!selection) return slice; let startBlock; const middleBlocks = []; let endBlock; const startPoint = selection.backward ? selection.focus : selection.anchor, endPoint = selection.backward ? selection.anchor : selection.focus, startBlockKey = isKeySegment(startPoint.path[0]) ? startPoint.path[0]._key : void 0, endBlockKey = isKeySegment(endPoint.path[0]) ? endPoint.path[0]._key : void 0, startChildKey = isKeySegment(startPoint.path[2]) ? startPoint.path[2]._key : void 0, endChildKey = isKeySegment(endPoint.path[2]) ? endPoint.path[2]._key : void 0; if (!startBlockKey || !endBlockKey) return slice; for (const block of blocks) { if (!isPortableTextTextBlock(block) && block._key === startBlockKey && block._key === endBlockKey) { startBlock = block; break; } if (block._key === startBlockKey) { if (!isPortableTextTextBlock(block)) { startBlock = block; continue; } if (startChildKey) { for (const child of block.children) { if (child._key === startChildKey) { if (isPortableTextSpan(child)) { const text = child._key === endChildKey ? child.text.slice(startPoint.offset, endPoint.offset) : child.text.slice(startPoint.offset); startBlock = { ...block, children: [{ ...child, text }] }; } else startBlock = { ...block, children: [child] }; if (startChildKey === endChildKey) break; continue; } if (startBlock && isPortableTextTextBlock(startBlock) && (endChildKey && child._key === endChildKey && isPortableTextSpan(child) ? startBlock.children.push({ ...child, text: child.text.slice(0, endPoint.offset) }) : startBlock.children.push(child), block._key === endBlockKey && endChildKey && child._key === endChildKey)) break; } if (startBlockKey === endBlockKey) break; continue; } if (startBlock = block, startBlockKey === endBlockKey) break; } if (block._key === endBlockKey) { if (!isPortableTextTextBlock(block)) { endBlock = block; break; } if (endChildKey) { endBlock = { ...block, children: [] }; for (const child of block.children) if (endBlock && isPortableTextTextBlock(endBlock)) { if (child._key === endChildKey && isPortableTextSpan(child)) { endBlock.children.push({ ...child, text: child.text.slice(0, endPoint.offset) }); break; } if (endBlock.children.push(child), endChildKey && child._key === endChildKey) break; } break; } endBlock = block; break; } startBlock && middleBlocks.push(block); } return [...startBlock ? [startBlock] : [], ...middleBlocks, ...endBlock ? [endBlock] : []]; } export { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isEqualSelectionPoints, isKeyedSegment, isSpan, reverseSelection, sliceBlocks, spanSelectionPointToBlockOffset }; //# sourceMappingURL=util.slice-blocks.js.map