@portabletext/editor 6.6.3 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/_chunks-dts/behavior.types.action.d.ts +683 -512
- package/lib/_chunks-dts/behavior.types.action.d.ts.map +1 -1
- package/lib/_chunks-dts/resolve-containers.d.ts +688 -0
- package/lib/_chunks-dts/resolve-containers.d.ts.map +1 -0
- package/lib/_chunks-es/get-ancestor.js +192 -0
- package/lib/_chunks-es/get-ancestor.js.map +1 -0
- package/lib/_chunks-es/get-first-child.js +130 -0
- package/lib/_chunks-es/get-first-child.js.map +1 -0
- package/lib/_chunks-es/get-path-sub-schema.js +266 -0
- package/lib/_chunks-es/get-path-sub-schema.js.map +1 -0
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js +1021 -0
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -0
- package/lib/_chunks-es/use-editor.js +4 -13
- package/lib/_chunks-es/use-editor.js.map +1 -1
- package/lib/_chunks-es/util.is-empty-text-block.js +15 -0
- package/lib/_chunks-es/util.is-empty-text-block.js.map +1 -0
- package/lib/_chunks-es/util.slice-blocks.js +347 -198
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.d.ts +2 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +5442 -5604
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.ts +18 -2
- package/lib/plugins/index.d.ts.map +1 -1
- package/lib/plugins/index.js +18 -2
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.d.ts +220 -5
- package/lib/selectors/index.d.ts.map +1 -1
- package/lib/selectors/index.js +62 -71
- package/lib/selectors/index.js.map +1 -1
- package/lib/traversal/index.d.ts +235 -0
- package/lib/traversal/index.d.ts.map +1 -0
- package/lib/traversal/index.js +30 -0
- package/lib/traversal/index.js.map +1 -0
- package/lib/utils/index.d.ts +11 -57
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +36 -107
- package/lib/utils/index.js.map +1 -1
- package/package.json +19 -17
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +0 -806
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +0 -1
- package/lib/_chunks-es/util.slice-text-block.js +0 -60
- package/lib/_chunks-es/util.slice-text-block.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.is-at-the-start-of-block.js","sources":["../../src/slate/path/compare-paths.ts","../../src/slate/point/compare-points.ts","../../src/slate/point/is-after-point.ts","../../src/slate/range/is-backward-range.ts","../../src/slate/range/range-edges.ts","../../src/schema/is-editable-container.ts","../../src/slate/range/ranges-overlap.ts","../../src/selectors/selector.is-selection-collapsed.ts","../../src/node-traversal/get-inline.ts","../../src/selectors/selector.get-focus-child.ts","../../src/selectors/selector.get-focus-inline-object.ts","../../src/selectors/selector.get-focus-span.ts","../../src/selectors/selector.get-focus-block.ts","../../src/selectors/selector.get-focus-text-block.ts","../../src/schema/get-root-accepted-types.ts","../../src/selectors/selector.get-selected-value.ts","../../src/selectors/selector.get-fragment.ts","../../src/selectors/selector.get-selection-end-block.ts","../../src/selectors/selector.get-selection-start-block.ts","../../src/selectors/selector.is-overlapping-selection.ts","../../src/selectors/selector.is-selection-expanded.ts","../../src/selectors/selector.get-selected-blocks.ts","../../src/selectors/selector.is-selecting-entire-blocks.ts","../../src/types/paths.ts","../../src/utils/util.is-selection-expanded.ts","../../src/node-traversal/find-sibling.ts","../../src/selectors/selector.get-selection-end-point.ts","../../src/selectors/selector.get-next-span.ts","../../src/selectors/selector.get-selection-start-point.ts","../../src/selectors/selector.get-previous-span.ts","../../src/selectors/selector.get-selected-children.ts","../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.get-mark-state.ts","../../src/selectors/selector.get-active-annotation-marks.ts","../../src/selectors/selector.get-selected-text-blocks.ts","../../src/selectors/selector.get-active-decorators.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.get-applicable-schema.ts","../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-next-inline-object.ts","../../src/selectors/selector.get-previous-inline-object.ts","../../src/selectors/selector.get-selection-text.ts","../../src/selectors/selector.get-caret-word-selection.ts","../../src/selectors/selector.get-first-block.ts","../../src/selectors/selector.get-focus-block-object.ts","../../src/selectors/selector.get-focus-list-block.ts","../../src/selectors/selector.get-last-block.ts","../../src/selectors/selector.get-next-block.ts","../../src/selectors/selector.get-previous-block.ts","../../src/selectors/selector.get-selection-end-child.ts","../../src/selectors/selector.get-selection-start-child.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts","../../src/selectors/selector.is-at-the-end-of-block.ts","../../src/selectors/selector.is-at-the-start-of-block.ts"],"sourcesContent":["import {isKeyedSegment} from '../../utils/util.is-keyed-segment'\nimport type {Node} from '../interfaces/node'\nimport type {Path} from '../interfaces/path'\n\n/**\n * Compare two paths in document order.\n *\n * When paths contain keyed segments, the root node tree is needed to\n * resolve document order. Without a root, keyed segments are compared\n * by _key string (consistent but not necessarily document order).\n */\nexport function comparePaths(\n path: Path,\n another: Path,\n root: {children: Array<Node>},\n): -1 | 0 | 1 {\n const min = Math.min(path.length, another.length)\n let currentChildren: Array<Node> | undefined = root?.children\n let currentNode: Node | undefined\n\n for (let i = 0; i < min; i++) {\n const segment = path[i]!\n const otherSegment = another[i]!\n\n if (isKeyedSegment(segment) && isKeyedSegment(otherSegment)) {\n if (segment._key === otherSegment._key) {\n if (currentChildren) {\n currentNode = currentChildren.find((c) => c._key === segment._key)\n currentChildren = undefined\n }\n continue\n }\n\n if (currentChildren) {\n const segmentIndex = currentChildren.findIndex(\n (c) => c._key === segment._key,\n )\n const otherSegmentIndex = currentChildren.findIndex(\n (c) => c._key === otherSegment._key,\n )\n if (segmentIndex !== -1 && otherSegmentIndex !== -1) {\n return segmentIndex < otherSegmentIndex ? -1 : 1\n }\n }\n\n // Fallback: compare by _key string\n if (segment._key < otherSegment._key) {\n return -1\n }\n if (segment._key > otherSegment._key) {\n return 1\n }\n continue\n }\n\n if (typeof segment === 'string' && typeof otherSegment === 'string') {\n if (segment === otherSegment) {\n if (currentNode) {\n const fieldValue = (currentNode as Record<string, unknown>)[segment]\n currentChildren = Array.isArray(fieldValue)\n ? (fieldValue as Array<Node>)\n : undefined\n currentNode = undefined\n }\n continue\n }\n if (segment < otherSegment) {\n return -1\n }\n if (segment > otherSegment) {\n return 1\n }\n continue\n }\n\n if (typeof segment === 'number' && typeof otherSegment === 'number') {\n if (segment < otherSegment) {\n return -1\n }\n if (segment > otherSegment) {\n return 1\n }\n continue\n }\n\n break\n }\n\n return 0\n}\n","import type {Node} from '../interfaces/node'\nimport type {Point} from '../interfaces/point'\nimport {comparePaths} from '../path/compare-paths'\n\nexport function comparePoints(\n point: Point,\n another: Point,\n root: {children: Array<Node>},\n): -1 | 0 | 1 {\n const result = comparePaths(point.path, another.path, root)\n if (result === 0) {\n if (point.offset < another.offset) {\n return -1\n }\n if (point.offset > another.offset) {\n return 1\n }\n return 0\n }\n return result\n}\n","import type {Node} from '../interfaces/node'\nimport type {Point} from '../interfaces/point'\nimport {comparePoints} from './compare-points'\n\nexport function isAfterPoint(\n point: Point,\n another: Point,\n root: {children: Array<Node>},\n): boolean {\n return comparePoints(point, another, root) === 1\n}\n","import type {Node} from '../interfaces/node'\nimport type {Range} from '../interfaces/range'\nimport {isAfterPoint} from '../point/is-after-point'\n\nexport function isBackwardRange(\n range: Range,\n root: {children: Array<Node>},\n): boolean {\n const {anchor, focus} = range\n return isAfterPoint(anchor, focus, root)\n}\n","import type {Node} from '../interfaces/node'\nimport type {Point} from '../interfaces/point'\nimport type {Range} from '../interfaces/range'\nimport {isBackwardRange} from './is-backward-range'\n\nexport function rangeEdges(\n range: Range,\n root: {children: Array<Node>},\n): [Point, Point] {\n const {anchor, focus} = range\n return isBackwardRange(range, root) ? [focus, anchor] : [anchor, focus]\n}\n","import type {TraversalSnapshot} from '../node-traversal/traversal-snapshot'\nimport type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {resolveContainerAt} from './resolve-container-at'\n\n/**\n * Check if a node at the given path is a registered editable container.\n *\n * Position-aware: {@link resolveContainerAt} descends from the editor\n * root threading the resolved parent at each step, so positionally-\n * registered containers (e.g. `cell` registered only inside\n * `table.of`) are recognized when reached through their declared\n * parent.\n */\nexport function isEditableContainer(\n snapshot: TraversalSnapshot,\n _node: Node,\n path: Path,\n): boolean {\n if (snapshot.context.containers.size === 0) {\n return false\n }\n\n // `resolveContainerAt` aborts on the first unregistered object-node\n // ancestor (chain validity falls out of the single descent), so the\n // single call below answers both \"is the node here a container?\" and\n // \"is the ancestor chain valid?\" in one walk.\n const resolved = resolveContainerAt(\n snapshot.context.containers,\n snapshot.context.value,\n path,\n )\n return !!(resolved && 'field' in resolved)\n}\n","import type {Node} from '../interfaces/node'\nimport type {Range} from '../interfaces/range'\nimport {comparePoints} from '../point/compare-points'\nimport {rangeEdges} from './range-edges'\n\n/**\n * Returns true if the two ranges share at least one point.\n *\n * Two ranges overlap iff each one's start is at or before the other's end.\n * Adjacent ranges that touch at a single point are considered overlapping.\n */\nexport function rangesOverlap(\n rangeA: Range,\n rangeB: Range,\n root: {children: Array<Node>},\n): boolean {\n const [startA, endA] = rangeEdges(rangeA, root)\n const [startB, endB] = rangeEdges(rangeB, root)\n return (\n comparePoints(startA, endB, root) <= 0 &&\n comparePoints(startB, endA, root) <= 0\n )\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isEqualPaths} from '../utils/util.is-equal-paths'\n\n/**\n * @public\n */\nexport const isSelectionCollapsed: EditorSelector<boolean> = (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n return (\n isEqualPaths(\n snapshot.context.selection.anchor.path,\n snapshot.context.selection.focus.path,\n ) &&\n snapshot.context.selection.anchor.offset ===\n snapshot.context.selection.focus.offset\n )\n}\n","import type {PortableTextObject, PortableTextSpan} from '@portabletext/schema'\nimport type {Path} from '../slate/interfaces/path'\nimport {isObjectNode} from '../slate/node/is-object-node'\nimport {isSpanNode} from '../slate/node/is-span-node'\nimport {getNode} from './get-node'\nimport {isInline} from './is-inline'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the node at the given path if it is inline (a span or inline object).\n *\n * A node is inline if its parent is a text block. Returns the node narrowed\n * to `PortableTextSpan | PortableTextObject`, or `undefined` if the node\n * doesn't exist or is not inline.\n */\nexport function getInline(\n snapshot: TraversalSnapshot,\n path: Path,\n): {node: PortableTextSpan | PortableTextObject; path: Path} | undefined {\n const entry = getNode(snapshot, path)\n\n if (!entry || !isInline(snapshot, path)) {\n return undefined\n }\n\n if (\n !isSpanNode({schema: snapshot.context.schema}, entry.node) &&\n !isObjectNode({schema: snapshot.context.schema}, entry.node)\n ) {\n return undefined\n }\n\n return {node: entry.node, path: entry.path}\n}\n","import type {PortableTextObject, PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getInline} from '../node-traversal/get-inline'\nimport type {ChildPath} from '../types/paths'\n\n/**\n * Returns the child (span or inline object) containing the focus selection,\n * resolved at any depth.\n *\n * @public\n */\nexport const getFocusChild: EditorSelector<\n | {\n node: PortableTextObject | PortableTextSpan\n path: ChildPath\n }\n | undefined\n> = (snapshot) => {\n const selection = snapshot.context.selection\n\n if (!selection) {\n return undefined\n }\n\n return getInline(snapshot, selection.focus.path)\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isSpanNode} from '../slate/node/is-span-node'\nimport type {ChildPath} from '../types/paths'\nimport {getFocusChild} from './selector.get-focus-child'\n\n/**\n * Returns the inline object containing the focus selection, resolved at any\n * depth.\n *\n * @public\n */\nexport const getFocusInlineObject: EditorSelector<\n {node: PortableTextObject; path: ChildPath} | undefined\n> = (snapshot) => {\n const focusChild = getFocusChild(snapshot)\n\n return focusChild && !isSpanNode(snapshot.context, focusChild.node)\n ? {node: focusChild.node, path: focusChild.path}\n : undefined\n}\n","import {isSpan, type PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {ChildPath} from '../types/paths'\nimport {getFocusChild} from './selector.get-focus-child'\n\n/**\n * Returns the span containing the focus selection, resolved at any depth.\n *\n * @public\n */\nexport const getFocusSpan: EditorSelector<\n {node: PortableTextSpan; path: ChildPath} | undefined\n> = (snapshot) => {\n const focusChild = getFocusChild(snapshot)\n\n return focusChild && isSpan(snapshot.context, focusChild.node)\n ? {node: focusChild.node, path: focusChild.path}\n : undefined\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getEnclosingBlock} from '../node-traversal/get-enclosing-block'\nimport type {BlockPath} from '../types/paths'\n\n/**\n * Returns the block containing the focus selection, resolved at any depth.\n *\n * When the focus is inside an editable container (e.g. a code block's line),\n * this returns the innermost block ancestor (the line), not the outer\n * container. When the focus is at root, behavior is unchanged.\n *\n * @public\n */\nexport const getFocusBlock: EditorSelector<\n {node: PortableTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const selection = snapshot.context.selection\n\n if (!selection) {\n return undefined\n }\n\n return getEnclosingBlock(snapshot, selection.focus.path)\n}\n","import {isTextBlock, type PortableTextTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the text block containing the focus selection, resolved at any depth.\n *\n * When the focus is inside an editable container (e.g. a code block's line),\n * this returns the innermost text block ancestor (the line), not the outer\n * container. When the focus is at root, behavior is unchanged.\n *\n * @public\n */\nexport const getFocusTextBlock: EditorSelector<\n {node: PortableTextTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const focusBlock = getFocusBlock(snapshot)\n\n return focusBlock && isTextBlock(snapshot.context, focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n","import type {EditorSchema} from '../editor/editor-schema'\n\n/**\n * Set of types that are valid at the root of the editor's value: the\n * configured text-block type plus every registered block-object type.\n *\n * The editor accepts these at the top level of `value` and uses them\n * to validate input and as the implicit accept-list for any payload\n * that escapes registered containers.\n */\nexport function getRootAcceptedTypes(schema: EditorSchema): Set<string> {\n return new Set<string>([\n schema.block.name,\n ...schema.blockObjects.map((blockObject) => blockObject.name),\n ])\n}\n","import {\n isSpan,\n isTextBlock,\n type PortableTextBlock,\n type PortableTextChild,\n} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {getNodeChildren} from '../node-traversal/get-children'\nimport type {RegisteredContainer} from '../schema/resolve-containers'\nimport type {Path} from '../slate/interfaces/path'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {sliceBlocks} from '../utils/util.slice-blocks'\n\ntype Edge = EditorSelectionPoint | 'array-start' | 'array-end'\n\ntype SliceContext = Pick<\n EditorContext,\n 'schema' | 'selection' | 'value' | 'containers'\n> & {keyGenerator?: () => string}\n\n/**\n * Returns the portion of the document's value covered by the selection,\n * resolved at any depth.\n *\n * Containers fully inside the selection are preserved verbatim. Containers\n * on the selection boundary are recursed into so only the selected portion\n * of their content is kept. Text blocks on the boundary are span-sliced.\n *\n * The result preserves the full ancestor envelope around the selection. For\n * the clipboard-shaped view that unwraps the envelope toward the selection's\n * lowest common ancestor, see {@link getFragment}.\n *\n * @public\n */\nexport const getSelectedValue: EditorSelector<Array<PortableTextBlock>> = (\n snapshot,\n) => {\n const selection = snapshot.context.selection\n\n if (!selection) {\n return []\n }\n\n const startPoint = getSelectionStartPoint(selection)\n const endPoint = getSelectionEndPoint(selection)\n\n if (!startPoint || !endPoint) {\n return []\n }\n\n return sliceArray({\n context: snapshot.context,\n blocks: snapshot.context.value,\n pathPrefix: [],\n fieldNameInPrefix: undefined,\n startEdge: startPoint,\n endEdge: endPoint,\n })\n}\n\nfunction sliceArray({\n context,\n blocks,\n pathPrefix,\n fieldNameInPrefix,\n startEdge,\n endEdge,\n parent,\n}: {\n context: SliceContext\n blocks: ReadonlyArray<PortableTextBlock>\n pathPrefix: Path\n fieldNameInPrefix: string | undefined\n startEdge: Edge\n endEdge: Edge\n parent?: RegisteredContainer\n}): Array<PortableTextBlock> {\n if (blocks.length === 0) {\n return []\n }\n\n const startIdx = resolveIndex(blocks, pathPrefix, startEdge)\n const endIdx = resolveIndex(blocks, pathPrefix, endEdge)\n\n if (startIdx === -1 || endIdx === -1) {\n return []\n }\n\n const [lo, hi, loEdge, hiEdge] =\n startIdx <= endIdx\n ? [startIdx, endIdx, startEdge, endEdge]\n : [endIdx, startIdx, endEdge, startEdge]\n\n const result: Array<PortableTextBlock> = []\n\n for (let i = lo; i <= hi; i++) {\n const block = blocks[i]!\n const blockPath: Path = [\n ...pathPrefix,\n ...(fieldNameInPrefix ? [fieldNameInPrefix] : []),\n {_key: block._key},\n ]\n\n const startPointForBlock: Edge = i === lo ? loEdge : 'array-start'\n const endPointForBlock: Edge = i === hi ? hiEdge : 'array-end'\n\n const startInside = edgeIsInside(startPointForBlock, blockPath)\n const endInside = edgeIsInside(endPointForBlock, blockPath)\n\n if (!startInside && !endInside) {\n result.push(block)\n continue\n }\n\n if (isTextBlock({schema: context.schema}, block)) {\n const sliced = sliceBoundaryTextBlock({\n context,\n block,\n blockPath,\n startEdge: startPointForBlock,\n endEdge: endPointForBlock,\n })\n if (sliced) {\n result.push(sliced)\n }\n continue\n }\n\n const childInfo = getNodeChildren(context, block, parent)\n\n if (!childInfo) {\n result.push(block)\n continue\n }\n\n const innerSliced = sliceArray({\n context,\n blocks: childInfo.children as Array<PortableTextBlock>,\n pathPrefix: blockPath,\n fieldNameInPrefix: childInfo.fieldName,\n startEdge: startPointForBlock,\n endEdge: endPointForBlock,\n parent: childInfo.parent,\n })\n\n const updatedBlock: PortableTextBlock = {...block}\n ;(updatedBlock as Record<string, unknown>)[childInfo.fieldName] =\n innerSliced\n\n result.push(updatedBlock)\n }\n\n return result\n}\n\nfunction resolveIndex(\n blocks: ReadonlyArray<PortableTextBlock>,\n pathPrefix: Path,\n edge: Edge,\n): number {\n if (edge === 'array-start') {\n return 0\n }\n if (edge === 'array-end') {\n return blocks.length - 1\n }\n return findBlockIndexForPoint(blocks, pathPrefix, edge)\n}\n\nfunction findBlockIndexForPoint(\n blocks: ReadonlyArray<PortableTextBlock>,\n pathPrefix: Path,\n point: EditorSelectionPoint,\n): number {\n let nodeSegmentIndex = pathPrefix.length\n\n if (\n nodeSegmentIndex < point.path.length &&\n typeof point.path[nodeSegmentIndex] === 'string'\n ) {\n nodeSegmentIndex++\n }\n\n const segment = point.path[nodeSegmentIndex]\n\n if (segment === undefined) {\n return -1\n }\n\n if (isKeyedSegment(segment)) {\n return blocks.findIndex((block) => block._key === segment._key)\n }\n\n if (typeof segment === 'number') {\n return segment >= 0 && segment < blocks.length ? segment : -1\n }\n\n return -1\n}\n\nfunction edgeIsInside(edge: Edge, blockPath: Path): boolean {\n if (edge === 'array-start' || edge === 'array-end') {\n return false\n }\n return edge.path.length > blockPath.length\n}\n\nfunction sliceBoundaryTextBlock({\n context,\n block,\n blockPath,\n startEdge,\n endEdge,\n}: {\n context: SliceContext\n block: PortableTextBlock\n blockPath: Path\n startEdge: Edge\n endEdge: Edge\n}): PortableTextBlock | undefined {\n if (!isTextBlock({schema: context.schema}, block)) {\n return block\n }\n\n const firstChild = block.children[0]\n const lastChild = block.children[block.children.length - 1]\n\n // Build block-relative selection points. `sliceBlocks` assumes paths start\n // at the block level (e.g. `[{block}, 'children', {child}]`), so we strip\n // any ancestor container prefix from the path.\n const blockRelativeStart = stripPrefix(startEdge, blockPath, block, {\n fallback: 'block-start',\n firstChild,\n })\n const blockRelativeEnd = stripPrefix(endEdge, blockPath, block, {\n fallback: 'block-end',\n lastChild,\n context,\n })\n\n const sliced = sliceBlocks({\n context: {\n ...context,\n selection: {anchor: blockRelativeStart, focus: blockRelativeEnd},\n },\n blocks: [block],\n })\n\n return sliced[0]\n}\n\nfunction stripPrefix(\n edge: Edge,\n blockPath: Path,\n block: PortableTextBlock,\n opts: {\n fallback: 'block-start' | 'block-end'\n firstChild?: PortableTextChild\n lastChild?: PortableTextChild\n context?: SliceContext\n },\n): EditorSelectionPoint {\n if (edge !== 'array-start' && edge !== 'array-end') {\n // Is the point inside this block? If yes, strip the prefix.\n if (edge.path.length > blockPath.length) {\n return {\n path: edge.path.slice(blockPath.length - 1),\n offset: edge.offset,\n }\n }\n }\n // Fall back to block start or end.\n if (opts.fallback === 'block-start') {\n return {\n path: [\n {_key: block._key},\n 'children',\n {_key: opts.firstChild?._key ?? ''},\n ],\n offset: 0,\n }\n }\n return {\n path: [{_key: block._key}, 'children', {_key: opts.lastChild?._key ?? ''}],\n offset:\n opts.lastChild &&\n opts.context &&\n isSpan({schema: opts.context.schema}, opts.lastChild)\n ? opts.lastChild.text.length\n : 0,\n }\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getRootAcceptedTypes} from '../schema/get-root-accepted-types'\nimport {resolveContainerAt} from '../schema/resolve-container-at'\nimport type {Path} from '../slate/interfaces/path'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectedValue} from './selector.get-selected-value'\n\n/**\n * Returns the smallest top-level-valid fragment of the editor's value\n * that covers the current selection.\n *\n * Starts from {@link getSelectedValue}'s envelope and unwraps it toward\n * the selection's lowest common ancestor, stopping at the deepest level\n * whose siblings are all root-accepted types. Intermediate single-child\n * containers (a single row inside a table, a single cell inside a row)\n * are walked through to look for a deeper unwrap target; an intermediate\n * level with multiple siblings (the lowest common ancestor across two\n * cells in one row) ends the walk and the last root-valid wrapping is\n * returned.\n *\n * Backs every registered clipboard converter, `editor.getFragment()`\n * (which projects to blocks only), and the drag preview pipeline (which\n * uses the paths to find DOM nodes). Exposed for custom converters and\n * any consumer that needs the clipboard-shaped view of the current\n * selection without redundant ancestor envelopes.\n *\n * @public\n */\nexport const getFragment: EditorSelector<\n Array<{node: PortableTextBlock; path: BlockPath}>\n> = (snapshot) => {\n const envelope = getSelectedValue(snapshot)\n\n if (envelope.length === 0) {\n return []\n }\n\n const {schema, containers, value} = snapshot.context\n const rootAcceptedTypes = getRootAcceptedTypes(schema)\n const textBlockName = schema.block.name\n\n // The outer envelope is rooted in `editor.value` so its top-level types\n // are root-accepted by construction.\n let lastRootValid: Array<PortableTextBlock> = envelope\n let lastRootValidPrefix: Path = []\n let current: Array<PortableTextBlock> = envelope\n const pathPrefix: Path = []\n\n while (current.length === 1) {\n const single = current[0]!\n const singlePath: Path = [...pathPrefix, {_key: single._key}]\n const container = resolveContainerAt(containers, value, singlePath)\n\n if (!container || !('field' in container)) {\n break\n }\n\n const children = (single as Record<string, unknown>)[container.field.name]\n if (!Array.isArray(children) || children.length === 0) {\n break\n }\n\n const childBlocks = children as Array<PortableTextBlock>\n pathPrefix.push({_key: single._key}, container.field.name)\n current = childBlocks\n\n const allRootAccepted = childBlocks.every(\n (block) =>\n block._type === textBlockName || rootAcceptedTypes.has(block._type),\n )\n\n if (allRootAccepted) {\n lastRootValid = childBlocks\n lastRootValidPrefix = [...pathPrefix]\n // Keep walking - a deeper level might also be root-valid (a single\n // block inside the cell that is itself a container, etc.).\n continue\n }\n\n // Children are intermediate types (e.g. `row`, `cell`). If there is\n // a single intermediate child, walk through it; otherwise the lowest\n // common ancestor is here and we stop with the last root-valid level.\n if (childBlocks.length !== 1) {\n break\n }\n }\n\n return lastRootValid.map((block) => ({\n node: block,\n path: [...lastRootValidPrefix, {_key: block._key}],\n }))\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the block containing the selection's end point, resolved at any\n * depth.\n *\n * @public\n */\nexport const getSelectionEndBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: BlockPath\n }\n | undefined\n> = (snapshot) => {\n const endPoint = getSelectionEndPoint(snapshot.context.selection)\n\n if (!endPoint) {\n return undefined\n }\n\n return getFocusBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: endPoint,\n focus: endPoint,\n },\n },\n })\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the block containing the selection's start point, resolved at any\n * depth.\n *\n * @public\n */\nexport const getSelectionStartBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: BlockPath\n }\n | undefined\n> = (snapshot) => {\n const startPoint = getSelectionStartPoint(snapshot.context.selection)\n\n if (!startPoint) {\n return undefined\n }\n\n return getFocusBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: startPoint,\n focus: startPoint,\n },\n },\n })\n}\n","import {hasNode} from '../node-traversal/has-node'\nimport {rangesOverlap} from '../slate/range/ranges-overlap'\nimport type {EditorSelection} from '../types/editor'\nimport type {EditorSelector} from './../editor/editor-selector'\n\n/**\n * Returns true if the supplied selection shares at least one point with the\n * editor's current selection. Resolves at any container depth.\n *\n * Two selections that touch at a single endpoint share that point and are\n * considered overlapping.\n *\n * @public\n */\nexport function isOverlappingSelection(\n selection: EditorSelection,\n): EditorSelector<boolean> {\n return (snapshot) => {\n const editorSelection = snapshot.context.selection\n\n if (!selection || !editorSelection) {\n return false\n }\n\n if (\n !hasNode(snapshot, selection.anchor.path) ||\n !hasNode(snapshot, selection.focus.path) ||\n !hasNode(snapshot, editorSelection.anchor.path) ||\n !hasNode(snapshot, editorSelection.focus.path)\n ) {\n return false\n }\n\n return rangesOverlap(selection, editorSelection, {\n children: snapshot.context.value,\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport const isSelectionExpanded: EditorSelector<boolean> = (snapshot) => {\n return snapshot.context.selection !== null && !isSelectionCollapsed(snapshot)\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getNodes} from '../node-traversal/get-nodes'\nimport {getBlock} from '../node-traversal/is-block'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\n\n/**\n * Returns the root-level blocks the selection covers.\n *\n * Only looks at direct children of the editor. If the selection is inside\n * an editable container, the container itself is returned - not its inner\n * blocks. Containers are preserved whole.\n *\n * Use for block-level operations like `move.block up/down` and\n * drag-and-drop. For \"selection as portable text\" use `getSelectedValue`;\n * for \"text blocks at any depth\" use `getSelectedTextBlocks`.\n *\n * @public\n */\nexport const getSelectedBlocks: EditorSelector<\n Array<{node: PortableTextBlock; path: BlockPath}>\n> = (snapshot) => {\n const selection = snapshot.context.selection\n\n if (!selection) {\n return []\n }\n\n const startPoint = getSelectionStartPoint(selection)\n const endPoint = getSelectionEndPoint(selection)\n\n if (!startPoint || !endPoint) {\n return []\n }\n\n // Fast path: when both endpoints share the same root-level block, that\n // single block is the answer. The range walk only needs to run when\n // the selection crosses block boundaries.\n const startRootKey = startPoint.path.find(isKeyedSegment)?._key\n const endRootKey = endPoint.path.find(isKeyedSegment)?._key\n if (startRootKey && startRootKey === endRootKey) {\n const block = getBlock(snapshot, [{_key: startRootKey}])\n if (block) {\n return [{node: block.node, path: block.path}]\n }\n }\n\n const result: Array<{node: PortableTextBlock; path: BlockPath}> = []\n\n for (const entry of getNodes(snapshot, {\n from: startPoint.path,\n to: endPoint.path,\n match: (_, path) => path.length === 1,\n })) {\n const block = getBlock(snapshot, entry.path)\n if (block) {\n result.push({node: block.node, path: block.path})\n }\n }\n\n return result\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getBlockEndPoint} from '../utils/util.get-block-end-point'\nimport {getBlockStartPoint} from '../utils/util.get-block-start-point'\nimport {isEqualSelectionPoints} from '../utils/util.is-equal-selection-points'\nimport {getSelectionEndBlock} from './selector.get-selection-end-block'\nimport {getSelectionStartBlock} from './selector.get-selection-start-block'\n\n/**\n * @public\n */\nexport const isSelectingEntireBlocks: EditorSelector<boolean> = (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const startPoint = snapshot.context.selection.backward\n ? snapshot.context.selection.focus\n : snapshot.context.selection.anchor\n const endPoint = snapshot.context.selection.backward\n ? snapshot.context.selection.anchor\n : snapshot.context.selection.focus\n\n const startBlock = getSelectionStartBlock(snapshot)\n const endBlock = getSelectionEndBlock(snapshot)\n\n if (!startBlock || !endBlock) {\n return false\n }\n\n const startBlockStartPoint = getBlockStartPoint({\n context: snapshot.context,\n block: startBlock,\n })\n const endBlockEndPoint = getBlockEndPoint({\n context: snapshot.context,\n block: endBlock,\n })\n\n return (\n isEqualSelectionPoints(startBlockStartPoint, startPoint) &&\n isEqualSelectionPoints(endBlockEndPoint, endPoint)\n )\n}\n","/**\n * A segment in a path that identifies an element by its `_key` property.\n * @public\n */\nexport interface KeyedSegment {\n _key: string\n}\n\n/**\n * A tuple representing a range selection, e.g., `[0, 5]` or `['', 3]`.\n * @public\n */\nexport type IndexTuple = [number | '', number | '']\n\n/**\n * A single segment in a path. Can be:\n * - A string (property name)\n * - A number (array index)\n * - A KeyedSegment (object with `_key`)\n * - An IndexTuple (range selection)\n * @public\n */\nexport type PathSegment = string | number | KeyedSegment | IndexTuple\n\n/**\n * A path is an array of path segments that describes a location in a document.\n * @public\n */\nexport type Path = PathSegment[]\n\n/**\n * A path to a block in the value.\n *\n * @public\n */\nexport type BlockPath = Path\n\n/**\n * @public\n */\nexport function isBlockPath(path: Path): path is BlockPath {\n const firstSegment = path.at(0)\n\n return (\n path.length === 1 &&\n firstSegment !== undefined &&\n isRecord(firstSegment) &&\n '_key' in firstSegment &&\n typeof firstSegment._key === 'string'\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && (typeof value === 'object' || typeof value === 'function')\n}\n\n/**\n * A path to an annotation markDef on a block.\n *\n * @public\n */\nexport type AnnotationPath = Path\n\n/**\n * A path to a child of a text block.\n *\n * @public\n */\nexport type ChildPath = Path\n","import type {EditorSelection} from '../types/editor'\nimport {isSelectionCollapsed} from './util.is-selection-collapsed'\n\n/**\n * @public\n */\nexport function isSelectionExpanded(selection: EditorSelection) {\n if (!selection) {\n return false\n }\n\n return !isSelectionCollapsed(selection)\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {parentPath} from '../slate/path/parent-path'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {getChildren} from './get-children'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Walk siblings of the node at the given path in a direction, returning the\n * first sibling that matches the predicate.\n *\n * The predicate may be a type guard, in which case the returned `node` is\n * narrowed accordingly.\n */\nexport function findSibling<TNode extends Node = Node>(\n snapshot: TraversalSnapshot,\n path: Path,\n direction: 'next' | 'previous',\n match: (entry: {\n node: Node\n path: Path\n }) => entry is {node: TNode; path: Path},\n): {node: TNode; path: Path} | undefined\nexport function findSibling(\n snapshot: TraversalSnapshot,\n path: Path,\n direction: 'next' | 'previous',\n match: (entry: {node: Node; path: Path}) => boolean,\n): {node: Node; path: Path} | undefined\nexport function findSibling(\n snapshot: TraversalSnapshot,\n path: Path,\n direction: 'next' | 'previous',\n match: (entry: {node: Node; path: Path}) => boolean,\n): {node: Node; path: Path} | undefined {\n if (path.length === 0) {\n return undefined\n }\n\n const lastSegment = path.at(-1)\n\n if (!isKeyedSegment(lastSegment)) {\n return undefined\n }\n\n const parent = parentPath(path)\n const children = getChildren(snapshot, parent)\n const currentIndex = children.findIndex(\n (child) => child.node._key === lastSegment._key,\n )\n\n if (currentIndex === -1) {\n return undefined\n }\n\n const candidates =\n direction === 'next'\n ? children.slice(currentIndex + 1)\n : children.slice(0, currentIndex).reverse()\n\n return candidates.find(match)\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport const getSelectionEndPoint: EditorSelector<\n EditorSelectionPoint | undefined\n> = (snapshot) => {\n if (!snapshot.context.selection) {\n return undefined\n }\n\n return snapshot.context.selection.backward\n ? snapshot.context.selection.anchor\n : snapshot.context.selection.focus\n}\n","import {isSpan, type PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {findSibling} from '../node-traversal/find-sibling'\nimport type {Path} from '../slate/interfaces/path'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\n\n/**\n * Returns the span after the selection end within the same text block,\n * resolved at any depth.\n *\n * @public\n */\nexport const getNextSpan: EditorSelector<\n {node: PortableTextSpan; path: Path} | undefined\n> = (snapshot) => {\n const point = getSelectionEndPoint(snapshot)\n\n if (!point) {\n return undefined\n }\n\n return findSibling(\n snapshot,\n point.path,\n 'next',\n (entry): entry is {node: PortableTextSpan; path: Path} =>\n isSpan(snapshot.context, entry.node),\n )\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport const getSelectionStartPoint: EditorSelector<\n EditorSelectionPoint | undefined\n> = (snapshot) => {\n if (!snapshot.context.selection) {\n return undefined\n }\n\n return snapshot.context.selection.backward\n ? snapshot.context.selection.focus\n : snapshot.context.selection.anchor\n}\n","import {isSpan, type PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {findSibling} from '../node-traversal/find-sibling'\nimport type {Path} from '../slate/interfaces/path'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\n\n/**\n * Returns the span before the selection start within the same text block,\n * resolved at any depth.\n *\n * @public\n */\nexport const getPreviousSpan: EditorSelector<\n {node: PortableTextSpan; path: Path} | undefined\n> = (snapshot) => {\n const point = getSelectionStartPoint(snapshot)\n\n if (!point) {\n return undefined\n }\n\n return findSibling(\n snapshot,\n point.path,\n 'previous',\n (entry): entry is {node: PortableTextSpan; path: Path} =>\n isSpan(snapshot.context, entry.node),\n )\n}\n","import {isSpan, type PortableTextChild} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getNode} from '../node-traversal/get-node'\nimport {getNodes} from '../node-traversal/get-nodes'\nimport {isInline} from '../node-traversal/is-inline'\nimport type {Path} from '../slate/interfaces/path'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\n\ntype SelectedChild<TChild extends PortableTextChild = PortableTextChild> = {\n node: TChild\n path: Path\n}\n\ntype GetSelectedChildrenOptions<\n TChild extends PortableTextChild = PortableTextChild,\n> = {\n filter?: (child: PortableTextChild) => child is TChild\n}\n\n/**\n * Returns the inline children (spans and inline objects) touched by the\n * selection, resolved at any depth.\n *\n * @public\n */\nexport function getSelectedChildren<\n TChild extends PortableTextChild = PortableTextChild,\n>(\n options?: GetSelectedChildrenOptions<TChild>,\n): EditorSelector<Array<SelectedChild<TChild>>> {\n const filter = options?.filter\n\n return (snapshot) => {\n const startPoint = getSelectionStartPoint(snapshot.context.selection)\n const endPoint = getSelectionEndPoint(snapshot.context.selection)\n\n if (!startPoint || !endPoint) {\n return []\n }\n\n const startChildKey = startPoint.path.findLast(isKeyedSegment)?._key\n const endChildKey = endPoint.path.findLast(isKeyedSegment)?._key\n\n const result: Array<SelectedChild<TChild>> = []\n\n // Fast path: when both endpoints reference the same inline child -\n // the common case for collapsed selections and intra-span selections\n // - resolve that child directly instead of walking the range.\n if (\n startChildKey &&\n startChildKey === endChildKey &&\n isInline(snapshot, startPoint.path)\n ) {\n const node = getNode(snapshot, startPoint.path)\n if (node) {\n const child = node.node as PortableTextChild\n let skip = false\n if (child._key === startChildKey && isSpan(snapshot.context, child)) {\n if (startPoint.offset >= child.text.length) {\n skip = true\n }\n if (endPoint.offset <= 0) {\n skip = true\n }\n }\n if (!skip && (!filter || filter(child))) {\n result.push({node: child as TChild, path: node.path})\n }\n }\n return result\n }\n\n for (const entry of getNodes(snapshot, {\n from: startPoint.path,\n to: endPoint.path,\n match: (_, path) => isInline(snapshot, path),\n })) {\n const child = entry.node as PortableTextChild\n\n // Skip the start child when the selection begins exactly at its end\n // and skip the end child when the selection ends exactly at its start.\n if (child._key === startChildKey && isSpan(snapshot.context, child)) {\n if (startPoint.offset >= child.text.length) {\n continue\n }\n }\n\n if (child._key === endChildKey && isSpan(snapshot.context, child)) {\n if (endPoint.offset <= 0) {\n continue\n }\n }\n\n if (filter && !filter(child)) {\n continue\n }\n\n result.push({node: child as TChild, path: entry.path})\n }\n\n return result\n }\n}\n","import {isSpan, type PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {ChildPath} from '../types/paths'\nimport {getSelectedChildren} from './selector.get-selected-children'\n\n/**\n * Returns the spans touched by the selection, resolved at any depth.\n *\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: ChildPath\n }>\n> = (snapshot) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n return getSelectedChildren({\n filter: (child) => isSpan(snapshot.context, child),\n })(snapshot)\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getAncestorTextBlock} from '../node-traversal/get-ancestor-text-block'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {isBlockPath} from '../types/paths'\nimport {blockOffsetToSpanSelectionPoint} from '../utils/util.block-offset'\nimport {isSelectionExpanded} from '../utils/util.is-selection-expanded'\nimport {getFocusSpan} from './selector.get-focus-span'\nimport {getNextSpan} from './selector.get-next-span'\nimport {getPreviousSpan} from './selector.get-previous-span'\nimport {getSelectedSpans} from './selector.get-selected-spans'\n\n/**\n * @beta\n */\nexport type MarkState =\n | {\n state: 'unchanged'\n marks: Array<string>\n }\n | {\n state: 'changed'\n marks: Array<string>\n previousMarks: Array<string>\n }\n\n/**\n * Given that text is inserted at the current position, what marks should\n * be applied?\n * @beta\n */\nexport const getMarkState: EditorSelector<MarkState | undefined> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return undefined\n }\n\n let selection = snapshot.context.selection\n\n if (isBlockPath(selection.anchor.path)) {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n snapshot,\n blockOffset: {\n path: selection.anchor.path,\n offset: selection.anchor.offset,\n },\n direction: selection.backward ? 'backward' : 'forward',\n })\n\n selection = spanSelectionPoint\n ? {\n ...selection,\n anchor: spanSelectionPoint,\n }\n : selection\n }\n\n if (isBlockPath(selection.focus.path)) {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n snapshot,\n blockOffset: {\n path: selection.focus.path,\n offset: selection.focus.offset,\n },\n direction: selection.backward ? 'backward' : 'forward',\n })\n\n selection = spanSelectionPoint\n ? {\n ...selection,\n focus: spanSelectionPoint,\n }\n : selection\n }\n\n const focusSpan = getFocusSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection,\n },\n })\n\n if (!focusSpan) {\n return undefined\n }\n\n if (isSelectionExpanded(selection)) {\n const selectedSpans = getSelectedSpans({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection,\n },\n })\n\n // Per-span info: marks present, the decorator names declared by the\n // span's block sub-schema, and the annotation markDef keys declared on\n // the span's enclosing block. Used so that out-of-scope spans (where\n // the mark cannot apply) don't disqualify the mark across the\n // selection.\n const spanInfo = selectedSpans.map((span) => {\n const block = getAncestorTextBlock(snapshot, span.path)\n return {\n marks: span.node.marks ?? [],\n decoratorNames: getPathSubSchema(snapshot, span.path).decorators.map(\n (decorator) => decorator.name,\n ),\n markDefKeys: (block?.node.markDefs ?? []).map(\n (markDef) => markDef._key,\n ),\n }\n })\n\n // Candidate marks: union of all marks present on any selected span.\n const candidateMarks = new Set<string>()\n for (const {marks: spanMarks} of spanInfo) {\n for (const mark of spanMarks) {\n candidateMarks.add(mark)\n }\n }\n\n const marks: Array<string> = []\n for (const candidate of candidateMarks) {\n const isDecoratorSomewhere = spanInfo.some(({decoratorNames}) =>\n decoratorNames.includes(candidate),\n )\n let active = true\n for (const {marks: spanMarks, decoratorNames, markDefKeys} of spanInfo) {\n const inScope = isDecoratorSomewhere\n ? decoratorNames.includes(candidate)\n : markDefKeys.includes(candidate)\n if (!inScope) {\n continue\n }\n if (!spanMarks.includes(candidate)) {\n active = false\n break\n }\n }\n if (active) {\n marks.push(candidate)\n }\n }\n\n return {\n state: 'unchanged',\n marks,\n }\n }\n\n const focusSubSchema = getPathSubSchema(snapshot, focusSpan.path)\n const decorators = focusSubSchema.decorators.map(\n (decorator) => decorator.name,\n )\n const marks = focusSpan.node.marks ?? []\n const marksWithoutAnnotations = marks.filter((mark) =>\n decorators.includes(mark),\n )\n\n const spanHasAnnotations = marks.length > marksWithoutAnnotations.length\n\n const spanIsEmpty = focusSpan.node.text.length === 0\n\n const atTheBeginningOfSpan = snapshot.context.selection.anchor.offset === 0\n const atTheEndOfSpan =\n snapshot.context.selection.anchor.offset === focusSpan.node.text.length\n\n const previousSpan = getPreviousSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection,\n },\n })\n const nextSpan = getNextSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection,\n },\n })\n const nextSpanAnnotations =\n nextSpan?.node?.marks?.filter((mark) => !decorators.includes(mark)) ?? []\n const spanAnnotations = marks.filter((mark) => !decorators.includes(mark))\n\n const previousSpanHasAnnotations = previousSpan\n ? previousSpan.node.marks?.some((mark) => !decorators.includes(mark))\n : false\n const previousSpanHasSameAnnotations = previousSpan\n ? previousSpan.node.marks\n ?.filter((mark) => !decorators.includes(mark))\n .every((mark) => marks.includes(mark))\n : false\n const previousSpanHasSameAnnotation = previousSpan\n ? previousSpan.node.marks?.some(\n (mark) => !decorators.includes(mark) && marks.includes(mark),\n )\n : false\n\n const previousSpanHasSameMarks = previousSpan\n ? previousSpan.node.marks?.every((mark) => marks.includes(mark))\n : false\n const nextSpanSharesSomeAnnotations = spanAnnotations.some((mark) =>\n nextSpanAnnotations?.includes(mark),\n )\n\n if (spanHasAnnotations && !spanIsEmpty) {\n if (atTheBeginningOfSpan) {\n if (previousSpanHasSameMarks) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: previousSpan?.node.marks ?? [],\n }\n } else if (previousSpanHasSameAnnotations) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: previousSpan?.node.marks ?? [],\n }\n } else if (previousSpanHasSameAnnotation) {\n return {\n state: 'unchanged',\n marks: focusSpan.node.marks ?? [],\n }\n } else if (!previousSpan) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: [],\n }\n }\n }\n\n if (atTheEndOfSpan) {\n if (!nextSpan) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: [],\n }\n }\n\n if (nextSpanAnnotations.length > 0 && !nextSpanSharesSomeAnnotations) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: [],\n }\n }\n\n if (\n (nextSpanSharesSomeAnnotations &&\n nextSpanAnnotations.length < spanAnnotations.length) ||\n !nextSpanSharesSomeAnnotations\n ) {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: nextSpan?.node.marks ?? [],\n }\n }\n }\n }\n\n if (atTheBeginningOfSpan && !spanIsEmpty && !!previousSpan) {\n if (previousSpanHasAnnotations) {\n return {\n state: 'changed',\n marks,\n previousMarks: previousSpan?.node.marks ?? [],\n }\n } else {\n return {\n state: 'changed',\n previousMarks: marks,\n marks: (previousSpan?.node.marks ?? []).filter((mark) =>\n decorators.includes(mark),\n ),\n }\n }\n }\n\n return {\n state: 'unchanged',\n marks,\n }\n}\n","import type {EditorSnapshot} from '../editor/editor-snapshot'\nimport {getMarkState} from './selector.get-mark-state'\n\nexport function getActiveAnnotationsMarks(snapshot: EditorSnapshot) {\n const schema = snapshot.context.schema\n const markState = getMarkState(snapshot)\n\n return (markState?.marks ?? []).filter(\n (mark) =>\n !schema.decorators.map((decorator) => decorator.name).includes(mark),\n )\n}\n","import {isTextBlock, type PortableTextTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getEnclosingBlock} from '../node-traversal/get-enclosing-block'\nimport {getNodes} from '../node-traversal/get-nodes'\nimport type {Path} from '../slate/interfaces/path'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\n\n/**\n * Returns the text blocks touched by the selection, resolved at any depth.\n *\n * Walks the tree between the selection endpoints and returns every text\n * block found, regardless of container nesting. For toolbar state and\n * anywhere that needs \"text blocks with text in the selection\".\n *\n * @public\n */\nexport const getSelectedTextBlocks: EditorSelector<\n Array<{node: PortableTextTextBlock; path: Path}>\n> = (snapshot) => {\n const selection = snapshot.context.selection\n\n if (!selection) {\n return []\n }\n\n const startPoint = getSelectionStartPoint(selection)\n const endPoint = getSelectionEndPoint(selection)\n\n if (!startPoint || !endPoint) {\n return []\n }\n\n // Fast path: when both endpoints sit inside the same text block - the\n // common case for toolbar state on a collapsed or single-block\n // selection - skip the range walk entirely. The range walk visits\n // every descendant in document order between the endpoints; that's\n // O(tree) work and gets very expensive in deeply nested containers.\n const startBlock = getEnclosingBlock(snapshot, startPoint.path)\n const endBlock = getEnclosingBlock(snapshot, endPoint.path)\n if (\n startBlock &&\n endBlock &&\n startBlock.node._key === endBlock.node._key &&\n isTextBlock(snapshot.context, startBlock.node)\n ) {\n return [{node: startBlock.node, path: startBlock.path}]\n }\n\n const result: Array<{node: PortableTextTextBlock; path: Path}> = []\n\n for (const entry of getNodes(snapshot, {\n from: startPoint.path,\n to: endPoint.path,\n match: (node) => isTextBlock(snapshot.context, node),\n })) {\n if (isTextBlock(snapshot.context, entry.node)) {\n result.push({node: entry.node, path: entry.path})\n }\n }\n\n return result\n}\n","import type {EditorSnapshot} from '../editor/editor-snapshot'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getMarkState} from './selector.get-mark-state'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\n\nexport function getActiveDecorators(snapshot: EditorSnapshot) {\n const decoratorState = snapshot.decoratorState\n const markState = getMarkState(snapshot)\n\n // Union of decorator names across all selected blocks' sub-schemas. At\n // root this is the full schema; inside containers it's the union of\n // each block's sub-schema decorators (so cross-container selections\n // include decorators that any in-scope span allows).\n const selectedBlocks = getSelectedTextBlocks(snapshot)\n const decorators = new Set<string>()\n for (const block of selectedBlocks) {\n for (const decorator of getPathSubSchema(snapshot, block.path).decorators) {\n decorators.add(decorator.name)\n }\n }\n if (decorators.size === 0) {\n for (const decorator of snapshot.context.schema.decorators) {\n decorators.add(decorator.name)\n }\n }\n\n const markStateDecorators = (markState?.marks ?? []).filter((mark) =>\n decorators.has(mark),\n )\n\n let activeDecorators: Array<string> = markStateDecorators\n\n for (const decorator in decoratorState) {\n if (decoratorState[decorator] === false) {\n activeDecorators = activeDecorators.filter(\n (activeDecorator) => activeDecorator !== decorator,\n )\n } else if (decoratorState[decorator] === true) {\n if (!activeDecorators.includes(decorator)) {\n activeDecorators.push(decorator)\n }\n }\n }\n\n return activeDecorators\n}\n","import {isTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveAnnotationsMarks} from './selector.get-active-annotation-marks'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\nimport {getSelectedValue} from './selector.get-selected-value'\n\n/**\n * Check whether an annotation is active in the given `snapshot`.\n *\n * @public\n */\nexport function isActiveAnnotation(\n annotation: string,\n options?: {\n /**\n * Choose whether the annotation has to take up the entire selection in the\n * `snapshot` or if the annotation can be partially selected.\n *\n * Defaults to 'full'\n */\n mode?: 'partial' | 'full'\n },\n): EditorSelector<boolean> {\n return (snapshot) => {\n const mode = options?.mode ?? 'full'\n\n if (mode === 'partial') {\n const selectedValue = getSelectedValue(snapshot)\n\n const selectionMarkDefs = selectedValue.flatMap((block) =>\n isTextBlock(snapshot.context, block) ? (block.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.some((markDef) => markDef._type === annotation)\n }\n\n const selectedBlocks = getSelectedTextBlocks(snapshot)\n const selectionMarkDefs = selectedBlocks.flatMap(\n (block) => block.node.markDefs ?? [],\n )\n const activeAnnotations = getActiveAnnotationsMarks(snapshot)\n const activeMarkDefs = selectionMarkDefs.filter(\n (markDef) =>\n markDef._type === annotation &&\n activeAnnotations.includes(markDef._key),\n )\n\n return activeMarkDefs.length > 0\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getFocusBlock} from './selector.get-focus-block'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\n\n/**\n * The set of schema member names applicable at the current selection,\n * grouped by category.\n *\n * @beta\n */\nexport type ApplicableSchema = {\n decorators: ReadonlySet<string>\n annotations: ReadonlySet<string>\n lists: ReadonlySet<string>\n styles: ReadonlySet<string>\n blockObjects: ReadonlySet<string>\n inlineObjects: ReadonlySet<string>\n}\n\n/**\n * Resolve which schema members are applicable at the current selection. For\n * each named category (decorators, annotations, lists, styles, block objects,\n * inline objects) returns the set of names that the editor allows at the\n * current selection.\n *\n * Categories split by what they apply to:\n *\n * Text-only (decorators, annotations, lists, styles): require text-block\n * content in the selection. A name is applicable when at least one text\n * block the range covers declares it (union). The underlying operations\n * apply per-block, validating each block's sub-schema and skipping blocks\n * that don't declare the type, so the result reflects \"will this produce\n * any effect?\" semantics. Selection on a void block, or no selection,\n * returns empty sets.\n *\n * Insertion (blockObjects, inlineObjects): the things consumers might\n * insert AT the current selection. The focus block's sub-schema applies\n * even when the selection is on a void block (the question \"what can I\n * insert here?\" still has an answer). No selection returns empty sets.\n *\n * Useful for gating toolbar buttons, slash-command items, command palettes,\n * keyboard-shortcut hints and other selection-aware UIs.\n *\n * Pair with `getUnionSchema` (from `@portabletext/editor/traversal`) to render a static toolbar whose\n * buttons stay stable across selection moves while gating their enabled\n * state on whether the corresponding name is in the relevant set.\n *\n * Note for React consumers: the returned object is a fresh value on every\n * call, so subscribing via `useEditorSelector` requires a structural\n * compare to avoid re-rendering on every editor tick. Use\n * {@link compareApplicableSchema} as the third argument.\n *\n * @beta\n */\nexport const getApplicableSchema: EditorSelector<ApplicableSchema> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return EMPTY\n }\n\n const focusBlock = getFocusBlock(snapshot)\n const focusSub = focusBlock\n ? getPathSubSchema(snapshot, focusBlock.path)\n : undefined\n\n const insertion = focusSub\n ? {\n blockObjects: namesOfArray(focusSub.blockObjects),\n inlineObjects: namesOfArray(focusSub.inlineObjects),\n }\n : {blockObjects: EMPTY_SET, inlineObjects: EMPTY_SET}\n\n const textBlocks = getSelectedTextBlocks(snapshot)\n\n if (textBlocks.length === 0) {\n return {\n decorators: EMPTY_SET,\n annotations: EMPTY_SET,\n lists: EMPTY_SET,\n styles: EMPTY_SET,\n ...insertion,\n }\n }\n\n let textApplicable = textCategoryNames(\n getPathSubSchema(snapshot, textBlocks[0]!.path),\n )\n for (let i = 1; i < textBlocks.length; i++) {\n textApplicable = unionTextCategories(\n textApplicable,\n textCategoryNames(getPathSubSchema(snapshot, textBlocks[i]!.path)),\n )\n }\n\n return {\n ...textApplicable,\n ...insertion,\n }\n}\n\n/**\n * Structural comparator for {@link ApplicableSchema} values. Two results\n * compare equal when every category contains the same names (set equality).\n * Pass as the `compare` argument to `useEditorSelector` to keep React\n * subscriptions stable.\n *\n * @beta\n */\nexport function compareApplicableSchema(\n a: ApplicableSchema,\n b: ApplicableSchema,\n): boolean {\n if (a === b) {\n return true\n }\n return (\n sameSet(a.decorators, b.decorators) &&\n sameSet(a.annotations, b.annotations) &&\n sameSet(a.lists, b.lists) &&\n sameSet(a.styles, b.styles) &&\n sameSet(a.blockObjects, b.blockObjects) &&\n sameSet(a.inlineObjects, b.inlineObjects)\n )\n}\n\nconst EMPTY_SET: ReadonlySet<string> = Object.freeze(new Set<string>())\n\nconst EMPTY: ApplicableSchema = Object.freeze({\n decorators: EMPTY_SET,\n annotations: EMPTY_SET,\n lists: EMPTY_SET,\n styles: EMPTY_SET,\n blockObjects: EMPTY_SET,\n inlineObjects: EMPTY_SET,\n})\n\ntype TextCategoryNames = Pick<\n ApplicableSchema,\n 'decorators' | 'annotations' | 'lists' | 'styles'\n>\n\nfunction textCategoryNames(schema: {\n decorators: ReadonlyArray<{name: string}>\n annotations: ReadonlyArray<{name: string}>\n lists: ReadonlyArray<{name: string}>\n styles: ReadonlyArray<{name: string}>\n}): TextCategoryNames {\n return {\n decorators: namesOfArray(schema.decorators),\n annotations: namesOfArray(schema.annotations),\n lists: namesOfArray(schema.lists),\n styles: namesOfArray(schema.styles),\n }\n}\n\nfunction unionTextCategories(\n a: TextCategoryNames,\n b: TextCategoryNames,\n): TextCategoryNames {\n return {\n decorators: unionSet(a.decorators, b.decorators),\n annotations: unionSet(a.annotations, b.annotations),\n lists: unionSet(a.lists, b.lists),\n styles: unionSet(a.styles, b.styles),\n }\n}\n\nfunction namesOfArray(\n entries: ReadonlyArray<{name: string}>,\n): ReadonlySet<string> {\n return new Set(entries.map((entry) => entry.name))\n}\n\nfunction unionSet(a: ReadonlySet<string>, b: ReadonlySet<string>): Set<string> {\n const result = new Set<string>(a)\n for (const item of b) {\n result.add(item)\n }\n return result\n}\n\nfunction sameSet(a: ReadonlySet<string>, b: ReadonlySet<string>) {\n if (a === b) {\n return true\n }\n if (a.size !== b.size) {\n return false\n }\n for (const item of a) {\n if (!b.has(item)) {\n return false\n }\n }\n return true\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getMarkState} from './selector.get-mark-state'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedTextBlocks(snapshot)\n const markState = getMarkState(snapshot)\n\n // Union of decorator names across selected blocks' sub-schemas. Marks\n // that aren't decorators in any in-scope sub-schema are annotations.\n const decoratorNames = new Set<string>()\n for (const block of selectedBlocks) {\n for (const decorator of getPathSubSchema(snapshot, block.path).decorators) {\n decoratorNames.add(decorator.name)\n }\n }\n if (decoratorNames.size === 0) {\n for (const decorator of snapshot.context.schema.decorators) {\n decoratorNames.add(decorator.name)\n }\n }\n\n const activeAnnotations = (markState?.marks ?? []).filter(\n (mark) => !decoratorNames.has(mark),\n )\n\n const selectionMarkDefs = selectedBlocks.flatMap(\n (block) => block.node.markDefs ?? [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n activeAnnotations.includes(markDef._key),\n )\n}\n","import type {PortableTextListBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = (snapshot) => {\n if (!snapshot.context.selection) {\n return undefined\n }\n\n const selectedTextBlocks = getSelectedTextBlocks(snapshot)\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.node.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n // Skip blocks whose sub-schema does not declare the list. A list item\n // is active when every in-scope block carries it.\n const inScopeBlocks = selectedTextBlocks.filter((block) =>\n getPathSubSchema(snapshot, block.path).lists.some(\n (l) => l.name === firstListItem,\n ),\n )\n\n if (inScopeBlocks.every((block) => block.node.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getSelectedTextBlocks} from './selector.get-selected-text-blocks'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return undefined\n }\n\n const selectedTextBlocks = getSelectedTextBlocks(snapshot)\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.node.style\n\n if (!firstStyle) {\n return undefined\n }\n\n // Skip blocks whose sub-schema does not declare the style. A style is\n // active when every in-scope block carries it.\n const inScopeBlocks = selectedTextBlocks.filter((block) =>\n getPathSubSchema(snapshot, block.path).styles.some(\n (s) => s.name === firstStyle,\n ),\n )\n\n if (inScopeBlocks.every((block) => block.node.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {findSibling} from '../node-traversal/find-sibling'\nimport {isObjectNode} from '../slate/node/is-object-node'\nimport type {ChildPath} from '../types/paths'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\n\n/**\n * Returns the inline object after the selection end within the same text\n * block, resolved at any depth.\n *\n * @public\n */\nexport const getNextInlineObject: EditorSelector<\n {node: PortableTextObject; path: ChildPath} | undefined\n> = (snapshot) => {\n const point = getSelectionEndPoint(snapshot)\n\n if (!point) {\n return undefined\n }\n\n const sibling = findSibling(\n snapshot,\n point.path,\n 'next',\n (entry): entry is {node: PortableTextObject; path: ChildPath} =>\n isObjectNode({schema: snapshot.context.schema}, entry.node),\n )\n\n return sibling\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {findSibling} from '../node-traversal/find-sibling'\nimport {isObjectNode} from '../slate/node/is-object-node'\nimport type {ChildPath} from '../types/paths'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\n\n/**\n * Returns the inline object before the selection start within the same text\n * block, resolved at any depth.\n *\n * @public\n */\nexport const getPreviousInlineObject: EditorSelector<\n {node: PortableTextObject; path: ChildPath} | undefined\n> = (snapshot) => {\n const point = getSelectionStartPoint(snapshot)\n\n if (!point) {\n return undefined\n }\n\n const sibling = findSibling(\n snapshot,\n point.path,\n 'previous',\n (entry): entry is {node: PortableTextObject; path: ChildPath} =>\n isObjectNode({schema: snapshot.context.schema}, entry.node),\n )\n\n return sibling\n}\n","import {isSpan, isTextBlock, type PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {getNodeChildren} from '../node-traversal/get-children'\nimport type {RegisteredContainer} from '../schema/resolve-containers'\nimport type {Node} from '../slate/interfaces/node'\nimport {getSelectedValue} from './selector.get-selected-value'\n\n/**\n * @public\n */\nexport const getSelectionText: EditorSelector<string> = (snapshot) => {\n const selectedValue = getSelectedValue(snapshot)\n\n return collectText(snapshot.context, selectedValue)\n}\n\nfunction collectText(\n context: Pick<EditorContext, 'schema' | 'containers'>,\n blocks: ReadonlyArray<Node | PortableTextBlock>,\n parent?: RegisteredContainer,\n): string {\n let text = ''\n\n for (const block of blocks) {\n if (isTextBlock(context, block)) {\n for (const child of block.children) {\n if (isSpan(context, child)) {\n text += child.text\n }\n }\n continue\n }\n\n const childInfo = getNodeChildren(context, block, parent)\n\n if (!childInfo) {\n continue\n }\n\n text += collectText(context, childInfo.children, childInfo.parent)\n }\n\n return text\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelection} from '../types/editor'\nimport {\n blockOffsetToSpanSelectionPoint,\n spanSelectionPointToBlockOffset,\n} from '../utils/util.block-offset'\nimport {getBlockEndPoint} from '../utils/util.get-block-end-point'\nimport {getBlockStartPoint} from '../utils/util.get-block-start-point'\nimport {getFocusTextBlock} from './selector.get-focus-text-block'\nimport {getNextInlineObject} from './selector.get-next-inline-object'\nimport {getPreviousInlineObject} from './selector.get-previous-inline-object'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\nimport {getSelectionText} from './selector.get-selection-text'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n * Returns the selection of the of the word the caret is placed in.\n * Note: Only returns a word selection if the current selection is collapsed\n */\nexport const getCaretWordSelection: EditorSelector<EditorSelection> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return null\n }\n\n if (!isSelectionCollapsed(snapshot)) {\n return null\n }\n\n const focusTextBlock = getFocusTextBlock(snapshot)\n const selectionStartPoint = getSelectionStartPoint(snapshot)\n const selectionStartOffset = selectionStartPoint\n ? spanSelectionPointToBlockOffset({\n snapshot,\n selectionPoint: selectionStartPoint,\n })\n : undefined\n\n if (!focusTextBlock || !selectionStartPoint || !selectionStartOffset) {\n return null\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n const blockStartPoint = getBlockStartPoint({\n context: snapshot.context,\n block: focusTextBlock,\n })\n const textBefore = getSelectionText({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: previousInlineObject\n ? {path: previousInlineObject.path, offset: 0}\n : blockStartPoint,\n focus: selectionStartPoint,\n },\n },\n })\n const textDirectlyBefore = textBefore.split(/\\s+/).at(-1)\n\n const nextInlineObject = getNextInlineObject(snapshot)\n const blockEndPoint = getBlockEndPoint({\n context: snapshot.context,\n block: focusTextBlock,\n })\n const textAfter = getSelectionText({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: selectionStartPoint,\n focus: nextInlineObject\n ? {path: nextInlineObject.path, offset: 0}\n : blockEndPoint,\n },\n },\n })\n const textDirectlyAfter = textAfter.split(/\\s+/).at(0)\n\n if (\n (textDirectlyBefore === undefined || textDirectlyBefore === '') &&\n (textDirectlyAfter === undefined || textDirectlyAfter === '')\n ) {\n return null\n }\n\n const caretWordStartOffset: BlockOffset = textDirectlyBefore\n ? {\n ...selectionStartOffset,\n offset: selectionStartOffset.offset - textDirectlyBefore.length,\n }\n : selectionStartOffset\n const caretWordEndOffset: BlockOffset = textDirectlyAfter\n ? {\n ...selectionStartOffset,\n offset: selectionStartOffset.offset + textDirectlyAfter.length,\n }\n : selectionStartOffset\n\n const caretWordStartSelectionPoint = blockOffsetToSpanSelectionPoint({\n snapshot,\n blockOffset: caretWordStartOffset,\n direction: 'backward',\n })\n const caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({\n snapshot,\n blockOffset: caretWordEndOffset,\n direction: 'forward',\n })\n\n if (!caretWordStartSelectionPoint || !caretWordEndSelectionPoint) {\n return null\n }\n\n const caretWordSelection = {\n anchor: caretWordStartSelectionPoint,\n focus: caretWordEndSelectionPoint,\n }\n\n return isSelectionExpanded({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: caretWordSelection,\n },\n })\n ? caretWordSelection\n : null\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getChildren} from '../node-traversal/get-children'\nimport {getBlock} from '../node-traversal/is-block'\nimport {parentPath} from '../slate/path/parent-path'\nimport type {BlockPath} from '../types/paths'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the first block at the current container scope.\n *\n * When the focus is inside an editable container (e.g. a code block's line),\n * this returns the first block within that container (the first line). When\n * the focus is at root, or there is no selection, this returns the first\n * block in the document.\n *\n * @public\n */\nexport const getFirstBlock: EditorSelector<\n {node: PortableTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const focusBlock = getFocusBlock(snapshot)\n\n if (focusBlock) {\n const siblings = getChildren(snapshot, parentPath(focusBlock.path))\n const first = siblings.at(0)\n\n if (first) {\n return getBlock(snapshot, first.path)\n }\n }\n\n const node = snapshot.context.value[0]\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isEditableContainer} from '../schema/is-editable-container'\nimport {isTextBlockNode} from '../slate/node/is-text-block-node'\nimport type {BlockPath} from '../types/paths'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the void block object containing the focus selection, resolved at\n * any depth.\n *\n * Excludes text blocks and editable containers (which have their own children\n * and are not \"void\"). When the focus is at root, behavior is unchanged.\n *\n * @public\n */\nexport const getFocusBlockObject: EditorSelector<\n {node: PortableTextObject; path: BlockPath} | undefined\n> = (snapshot) => {\n const focusBlock = getFocusBlock(snapshot)\n\n if (!focusBlock) {\n return undefined\n }\n\n if (isTextBlockNode(snapshot.context, focusBlock.node)) {\n return undefined\n }\n\n if (isEditableContainer(snapshot, focusBlock.node, focusBlock.path)) {\n return undefined\n }\n\n return {node: focusBlock.node, path: focusBlock.path}\n}\n","import type {PortableTextListBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {isListBlock} from '../utils/parse-blocks'\nimport {getFocusTextBlock} from './selector.get-focus-text-block'\n\n/**\n * Returns the list block containing the focus selection, resolved at any\n * depth.\n *\n * @public\n */\nexport const getFocusListBlock: EditorSelector<\n {node: PortableTextListBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const focusTextBlock = getFocusTextBlock(snapshot)\n\n return focusTextBlock && isListBlock(snapshot.context, focusTextBlock.node)\n ? {node: focusTextBlock.node, path: focusTextBlock.path}\n : undefined\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getChildren} from '../node-traversal/get-children'\nimport {getBlock} from '../node-traversal/is-block'\nimport {parentPath} from '../slate/path/parent-path'\nimport type {BlockPath} from '../types/paths'\nimport {getFocusBlock} from './selector.get-focus-block'\n\n/**\n * Returns the last block at the current container scope.\n *\n * When the focus is inside an editable container (e.g. a code block's line),\n * this returns the last block within that container (the last line). When\n * the focus is at root, or there is no selection, this returns the last\n * block in the document.\n *\n * @public\n */\nexport const getLastBlock: EditorSelector<\n {node: PortableTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const focusBlock = getFocusBlock(snapshot)\n\n if (focusBlock) {\n const siblings = getChildren(snapshot, parentPath(focusBlock.path))\n const last = siblings.at(-1)\n\n if (last) {\n return getBlock(snapshot, last.path)\n }\n }\n\n const node = snapshot.context.value.at(-1)\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSibling} from '../node-traversal/get-sibling'\nimport {getBlock} from '../node-traversal/is-block'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectionEndBlock} from './selector.get-selection-end-block'\n\n/**\n * Returns the block after the selection's end block within the same\n * container scope, if any.\n *\n * Siblings are resolved within the enclosing container (or the document root\n * if the selection is at root level). Never crosses container boundaries.\n *\n * @public\n */\nexport const getNextBlock: EditorSelector<\n {node: PortableTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const selectionEndBlock = getSelectionEndBlock(snapshot)\n\n if (!selectionEndBlock) {\n return undefined\n }\n\n const next = getSibling(snapshot, selectionEndBlock.path, 'next')\n\n if (!next) {\n return undefined\n }\n\n return getBlock(snapshot, next.path)\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSibling} from '../node-traversal/get-sibling'\nimport {getBlock} from '../node-traversal/is-block'\nimport type {BlockPath} from '../types/paths'\nimport {getSelectionStartBlock} from './selector.get-selection-start-block'\n\n/**\n * Returns the block before the selection's start block within the same\n * container scope, if any.\n *\n * Siblings are resolved within the enclosing container (or the document root\n * if the selection is at root level). Never crosses container boundaries.\n *\n * @public\n */\nexport const getPreviousBlock: EditorSelector<\n {node: PortableTextBlock; path: BlockPath} | undefined\n> = (snapshot) => {\n const selectionStartBlock = getSelectionStartBlock(snapshot)\n\n if (!selectionStartBlock) {\n return undefined\n }\n\n const previous = getSibling(snapshot, selectionStartBlock.path, 'previous')\n\n if (!previous) {\n return undefined\n }\n\n return getBlock(snapshot, previous.path)\n}\n","import type {PortableTextObject, PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {ChildPath} from '../types/paths'\nimport {getSelectionEndPoint} from '../utils/util.get-selection-end-point'\nimport {getFocusChild} from './selector.get-focus-child'\n\n/**\n * Returns the child containing the selection's end point, resolved at any\n * depth.\n *\n * @public\n */\nexport const getSelectionEndChild: EditorSelector<\n | {\n node: PortableTextSpan | PortableTextObject\n path: ChildPath\n }\n | undefined\n> = (snapshot) => {\n const endPoint = getSelectionEndPoint(snapshot.context.selection)\n\n if (!endPoint) {\n return undefined\n }\n\n return getFocusChild({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: endPoint,\n focus: endPoint,\n },\n },\n })\n}\n","import type {PortableTextObject, PortableTextSpan} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {ChildPath} from '../types/paths'\nimport {getSelectionStartPoint} from '../utils/util.get-selection-start-point'\nimport {getFocusChild} from './selector.get-focus-child'\n\n/**\n * Returns the child containing the selection's start point, resolved at any\n * depth.\n *\n * @public\n */\nexport const getSelectionStartChild: EditorSelector<\n | {\n node: PortableTextSpan | PortableTextObject\n path: ChildPath\n }\n | undefined\n> = (snapshot) => {\n const startPoint = getSelectionStartPoint(snapshot.context.selection)\n\n if (!startPoint) {\n return undefined\n }\n\n return getFocusChild({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: startPoint,\n focus: startPoint,\n },\n },\n })\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getPathSubSchema} from '../traversal/get-path-sub-schema'\nimport {getActiveDecorators} from './selector.get-active-decorators'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n // Skip spans whose enclosing block sub-schema does not declare the\n // decorator. A mark is active when every in-scope span carries it.\n const inScopeSpans = selectedSpans.filter((span) =>\n getPathSubSchema(snapshot, span.path).decorators.some(\n (d) => d.name === decorator,\n ),\n )\n\n return (\n inScopeSpans.length > 0 &&\n inScopeSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n const activeDecorators = getActiveDecorators(snapshot)\n\n return activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\n }\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {getBlockEndPoint} from '../utils/util.get-block-end-point'\nimport {isEqualSelectionPoints} from '../utils/util.is-equal-selection-points'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport function isAtTheEndOfBlock(block: {\n node: PortableTextBlock\n path: BlockPath\n}): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection || !isSelectionCollapsed(snapshot)) {\n return false\n }\n\n const blockEndPoint = getBlockEndPoint({\n context: snapshot.context,\n block,\n })\n\n return isEqualSelectionPoints(\n snapshot.context.selection.focus,\n blockEndPoint,\n )\n }\n}\n","import type {PortableTextBlock} from '@portabletext/schema'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {BlockPath} from '../types/paths'\nimport {getBlockStartPoint} from '../utils/util.get-block-start-point'\nimport {isEqualSelectionPoints} from '../utils/util.is-equal-selection-points'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport function isAtTheStartOfBlock(block: {\n node: PortableTextBlock\n path: BlockPath\n}): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection || !isSelectionCollapsed(snapshot)) {\n return false\n }\n\n const blockStartPoint = getBlockStartPoint({\n context: snapshot.context,\n block,\n })\n\n return isEqualSelectionPoints(\n snapshot.context.selection.focus,\n blockStartPoint,\n )\n }\n}\n"],"names":["comparePaths","path","another","root","min","Math","length","currentChildren","children","currentNode","i","segment","otherSegment","isKeyedSegment","_key","find","c","undefined","segmentIndex","findIndex","otherSegmentIndex","fieldValue","Array","isArray","comparePoints","point","result","offset","isAfterPoint","isBackwardRange","range","anchor","focus","rangeEdges","isEditableContainer","snapshot","_node","context","containers","size","resolved","resolveContainerAt","value","rangesOverlap","rangeA","rangeB","startA","endA","startB","endB","isSelectionCollapsed","selection","isEqualPaths","getInline","entry","getNode","isInline","isSpanNode","schema","node","isObjectNode","getFocusChild","getFocusInlineObject","focusChild","getFocusSpan","isSpan","getFocusBlock","getEnclosingBlock","getFocusTextBlock","focusBlock","isTextBlock","getRootAcceptedTypes","Set","block","name","blockObjects","map","blockObject","getSelectedValue","startPoint","getSelectionStartPoint","endPoint","getSelectionEndPoint","sliceArray","blocks","pathPrefix","fieldNameInPrefix","startEdge","endEdge","parent","startIdx","resolveIndex","endIdx","lo","hi","loEdge","hiEdge","blockPath","startPointForBlock","endPointForBlock","startInside","edgeIsInside","endInside","push","sliced","sliceBoundaryTextBlock","childInfo","getNodeChildren","innerSliced","fieldName","updatedBlock","edge","findBlockIndexForPoint","nodeSegmentIndex","firstChild","lastChild","blockRelativeStart","stripPrefix","fallback","blockRelativeEnd","sliceBlocks","opts","slice","text","getFragment","envelope","rootAcceptedTypes","textBlockName","lastRootValid","lastRootValidPrefix","current","single","singlePath","container","field","childBlocks","every","_type","has","getSelectionEndBlock","getSelectionStartBlock","isOverlappingSelection","editorSelection","hasNode","isSelectionExpanded","getSelectedBlocks","startRootKey","endRootKey","getBlock","getNodes","from","to","match","_","isSelectingEntireBlocks","backward","startBlock","endBlock","startBlockStartPoint","getBlockStartPoint","endBlockEndPoint","getBlockEndPoint","isEqualSelectionPoints","isBlockPath","firstSegment","at","isRecord","findSibling","direction","lastSegment","parentPath","getChildren","currentIndex","child","reverse","getNextSpan","getPreviousSpan","getSelectedChildren","options","filter","startChildKey","findLast","endChildKey","skip","getSelectedSpans","getMarkState","spanSelectionPoint","blockOffsetToSpanSelectionPoint","blockOffset","focusSpan","spanInfo","span","getAncestorTextBlock","marks","decoratorNames","getPathSubSchema","decorators","decorator","markDefKeys","markDefs","markDef","candidateMarks","spanMarks","mark","add","candidate","isDecoratorSomewhere","some","includes","active","state","marksWithoutAnnotations","spanHasAnnotations","spanIsEmpty","atTheBeginningOfSpan","atTheEndOfSpan","previousSpan","nextSpan","nextSpanAnnotations","spanAnnotations","previousSpanHasAnnotations","previousSpanHasSameAnnotations","previousSpanHasSameAnnotation","previousSpanHasSameMarks","nextSpanSharesSomeAnnotations","previousMarks","getActiveAnnotationsMarks","getSelectedTextBlocks","getActiveDecorators","decoratorState","markState","selectedBlocks","activeDecorators","activeDecorator","isActiveAnnotation","annotation","mode","flatMap","selectionMarkDefs","activeAnnotations","getApplicableSchema","EMPTY","focusSub","insertion","namesOfArray","inlineObjects","EMPTY_SET","textBlocks","annotations","lists","styles","textApplicable","textCategoryNames","unionTextCategories","compareApplicableSchema","a","b","sameSet","Object","freeze","unionSet","entries","item","getActiveAnnotations","getActiveListItem","selectedTextBlocks","firstTextBlock","firstListItem","listItem","l","getActiveStyle","firstStyle","style","s","getNextInlineObject","getPreviousInlineObject","getSelectionText","selectedValue","collectText","getCaretWordSelection","focusTextBlock","selectionStartPoint","selectionStartOffset","spanSelectionPointToBlockOffset","selectionPoint","previousInlineObject","blockStartPoint","textDirectlyBefore","split","nextInlineObject","blockEndPoint","textDirectlyAfter","caretWordStartOffset","caretWordEndOffset","caretWordStartSelectionPoint","caretWordEndSelectionPoint","caretWordSelection","getFirstBlock","first","getFocusBlockObject","isTextBlockNode","getFocusListBlock","isListBlock","getLastBlock","last","getNextBlock","selectionEndBlock","next","getSibling","getPreviousBlock","selectionStartBlock","previous","getSelectionEndChild","getSelectionStartChild","isActiveDecorator","inScopeSpans","d","isActiveListItem","isActiveStyle","isAtTheEndOfBlock","isAtTheStartOfBlock"],"mappings":"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"}
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import React, { createContext } from "react";
|
|
2
|
-
function getGlobalScope() {
|
|
3
|
-
if (typeof globalThis < "u")
|
|
4
|
-
return globalThis;
|
|
5
|
-
if (typeof window < "u")
|
|
6
|
-
return window;
|
|
7
|
-
if (typeof self < "u")
|
|
8
|
-
return self;
|
|
9
|
-
if (typeof global < "u")
|
|
10
|
-
return global;
|
|
11
|
-
throw new Error("@portabletext/editor: could not locate global scope");
|
|
12
|
-
}
|
|
13
|
-
const globalScope = getGlobalScope();
|
|
14
2
|
function createGloballyScopedContext(key, defaultValue) {
|
|
15
3
|
const symbol = Symbol.for(key);
|
|
16
|
-
|
|
4
|
+
if (typeof document > "u")
|
|
5
|
+
return createContext(defaultValue);
|
|
6
|
+
const scope = globalThis;
|
|
7
|
+
return scope[symbol] = scope[symbol] ?? createContext(defaultValue), scope[symbol];
|
|
17
8
|
}
|
|
18
9
|
const EditorContext = createGloballyScopedContext("@portabletext/editor/context/editor", null);
|
|
19
10
|
function useEditor() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-editor.js","sources":["../../src/internal-utils/
|
|
1
|
+
{"version":3,"file":"use-editor.js","sources":["../../src/internal-utils/globally-scoped-context.ts","../../src/editor/editor-context.tsx","../../src/editor/use-editor.ts"],"sourcesContent":["import {createContext, type Context} from 'react'\n\n/**\n * As `@portabletext/editor` is declared as a dependency, and may be\n * duplicated, sometimes across major versions it's critical that vital\n * React Contexts are shared even when there is a duplicate.\n *\n * We have to support a Sanity Plugin being able to call hooks like\n * `useEditor`, and then read the context setup by `sanity`, which calls\n * `EditorProvider`, even if the provider and hook are different instances in\n * memory.\n *\n * For this reason it's vital that all changes to globally scoped providers\n * remain fully backwards compatible.\n */\nexport function createGloballyScopedContext<\n ContextType,\n const T extends ContextType = ContextType,\n>(\n /**\n * Enforce that all Symbol.for keys used for globally scoped contexts have a predictable prefix\n */\n key: `@portabletext/editor/context/${string}`,\n defaultValue: T,\n): Context<ContextType> {\n const symbol = Symbol.for(key)\n\n /**\n * Prevent errors about re-renders on React SSR on Next.js App Router\n */\n if (typeof document === 'undefined') {\n return createContext<ContextType>(defaultValue)\n }\n\n const scope = globalThis as any\n scope[symbol] = scope[symbol] ?? createContext<T>(defaultValue)\n\n return scope[symbol]\n}\n","import type {Editor} from '../editor'\nimport {createGloballyScopedContext} from '../internal-utils/globally-scoped-context'\n\nexport const EditorContext = createGloballyScopedContext<Editor | null>(\n '@portabletext/editor/context/editor',\n null,\n)\n","import React from 'react'\nimport {EditorContext} from './editor-context'\n\n/**\n * @public\n * Get the current editor context from the `EditorProvider`.\n * Must be used inside the `EditorProvider` component.\n * @returns The current editor object.\n * @example\n * ```tsx\n * import { useEditor } from '@portabletext/editor'\n *\n * function MyComponent() {\n * const editor = useEditor()\n * }\n * ```\n * @group Hooks\n */\nexport function useEditor() {\n const editor = React.useContext(EditorContext)\n\n if (!editor) {\n throw new Error('No Editor set. Use EditorProvider to set one.')\n }\n\n return editor\n}\n"],"names":["createGloballyScopedContext","key","defaultValue","symbol","Symbol","for","document","createContext","scope","globalThis","EditorContext","useEditor","editor","React","useContext","Error"],"mappings":";AAeO,SAASA,4BAOdC,KACAC,cACsB;AACtB,QAAMC,SAASC,OAAOC,IAAIJ,GAAG;AAK7B,MAAI,OAAOK,WAAa;AACtB,WAAOC,cAA2BL,YAAY;AAGhD,QAAMM,QAAQC;AACdD,SAAAA,MAAML,MAAM,IAAIK,MAAML,MAAM,KAAKI,cAAiBL,YAAY,GAEvDM,MAAML,MAAM;AACrB;ACnCO,MAAMO,gBAAgBV,4BAC3B,uCACA,IACF;ACYO,SAAAW,YAAA;AACL,QAAAC,SAAeC,MAAKC,WAAYJ,aAAa;AAE7C,MAAI,CAACE;AACH,UAAM,IAAIG,MAAM,+CAA+C;AAChE,SAEMH;AAAM;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isTextBlock, isSpan } from "@portabletext/schema";
|
|
2
|
+
function getTextBlockText(block) {
|
|
3
|
+
return block.children.map((child) => child.text ?? "").join("");
|
|
4
|
+
}
|
|
5
|
+
function isEmptyTextBlock(context, block) {
|
|
6
|
+
if (!isTextBlock(context, block))
|
|
7
|
+
return !1;
|
|
8
|
+
const onlyText = block.children.every((child) => isSpan(context, child)), blockText = getTextBlockText(block);
|
|
9
|
+
return onlyText && blockText === "";
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
getTextBlockText,
|
|
13
|
+
isEmptyTextBlock
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=util.is-empty-text-block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.is-empty-text-block.js","sources":["../../src/utils/util.get-text-block-text.ts","../../src/utils/util.is-empty-text-block.ts"],"sourcesContent":["import type {PortableTextTextBlock} from '@portabletext/schema'\n\n/**\n * @public\n */\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","import {isSpan, isTextBlock, type PortableTextBlock} from '@portabletext/schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {getTextBlockText} from './util.get-text-block-text'\n\n/**\n * @public\n */\nexport function isEmptyTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock | unknown,\n) {\n if (!isTextBlock(context, block)) {\n return false\n }\n\n const onlyText = block.children.every((child) => isSpan(context, child))\n const blockText = getTextBlockText(block)\n\n return onlyText && blockText === ''\n}\n"],"names":["getTextBlockText","block","children","map","child","text","join","isEmptyTextBlock","context","isTextBlock","onlyText","every","isSpan","blockText"],"mappings":";AAKO,SAASA,iBAAiBC,OAA8B;AAC7D,SAAOA,MAAMC,SAASC,IAAKC,CAAAA,UAAUA,MAAMC,QAAQ,EAAE,EAAEC,KAAK,EAAE;AAChE;ACAO,SAASC,iBACdC,SACAP,OACA;AACA,MAAI,CAACQ,YAAYD,SAASP,KAAK;AAC7B,WAAO;AAGT,QAAMS,WAAWT,MAAMC,SAASS,MAAOP,CAAAA,UAAUQ,OAAOJ,SAASJ,KAAK,CAAC,GACjES,YAAYb,iBAAiBC,KAAK;AAExC,SAAOS,YAAYG,cAAc;AACnC;"}
|