UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

131 lines (130 loc) 4.1 kB
import { getChildren, getNode, isKeyedSegment, getNodeChildren } from "./get-ancestor.js"; import { isSpan, isTextBlock, getSubSchema } from "@portabletext/schema"; import { getNodes } from "./get-path-sub-schema.js"; function getLeaf(snapshot, path, options) { const { edge } = options; let currentPath = path; if (currentPath.length === 0) { const children = getChildren(snapshot, []); if (children.length === 0) return; const firstOrLast = edge === "end" ? children.at(-1) : children.at(0); if (getChildren(snapshot, firstOrLast.path).length === 0) return firstOrLast; currentPath = firstOrLast.path; } else { const entry = getNode(snapshot, currentPath); if (!entry) return; if (getChildren(snapshot, currentPath).length === 0) return entry; } for (; ; ) { const children = getChildren(snapshot, currentPath); if (children.length === 0) return getNode(snapshot, currentPath) ?? void 0; currentPath = (edge === "end" ? children.at(-1) : children.at(0)).path; } } function getText(snapshot, path) { const entry = getNode(snapshot, path); if (!entry) return; if (isSpan({ schema: snapshot.context.schema }, entry.node)) return entry.node.text; let text = ""; for (const descendant of getNodes(snapshot, { at: path })) isSpan({ schema: snapshot.context.schema }, descendant.node) && (text += descendant.node.text); return text; } function getSpanNode(snapshot, path) { const entry = getNode(snapshot, path); if (entry && isSpan({ schema: snapshot.context.schema }, entry.node)) return { node: entry.node, path: entry.path }; } function getTextBlockNode(snapshot, path) { const entry = getNode(snapshot, path); if (entry && isTextBlock({ schema: snapshot.context.schema }, entry.node)) return { node: entry.node, path: entry.path }; } function getUnionSchema(schema, containers) { const decorators = mergeByName(schema.decorators, []), annotations = mergeByName(schema.annotations, []), lists = mergeByName(schema.lists, []), styles = mergeByName(schema.styles, []), inlineObjects = mergeByName(schema.inlineObjects, []), blockObjects = mergeByName(schema.blockObjects, []); for (const container of containers.values()) { if (!acceptsTextBlock(container.field.of, schema.block.name)) continue; const sub = getSubSchema(schema, container.field.of); mergeByName(sub.decorators, decorators), mergeByName(sub.annotations, annotations), mergeByName(sub.lists, lists), mergeByName(sub.styles, styles), mergeByName(sub.inlineObjects, inlineObjects), mergeByName(sub.blockObjects, blockObjects); } return { ...schema, decorators, annotations, lists, styles, inlineObjects, blockObjects }; } function acceptsTextBlock(of, blockName) { return of.some((member) => member.type === "block" || member.type === blockName); } function mergeByName(source, target) { for (const entry of source) target.some((existing) => existing.name === entry.name) || target.push(entry); return target; } function isLeaf(snapshot, path) { if (path.length === 0) return !1; let currentChildren = snapshot.context.value, currentParent; for (let i = 0; i < path.length; i++) { const segment = path[i]; let node; if (isKeyedSegment(segment)) node = currentChildren.find((child) => child._key === segment._key); else if (typeof segment == "number") node = currentChildren.at(segment); else continue; if (!node) return !1; const next = getNodeChildren(snapshot.context, node, currentParent); if (i === path.length - 1) return next === void 0; if (!next) return !1; currentChildren = next.children, currentParent = next.parent; } return !1; } function getFirstChild(snapshot, path) { return getChildren(snapshot, path).at(0); } export { getFirstChild, getLeaf, getSpanNode, getText, getTextBlockNode, getUnionSchema, isLeaf }; //# sourceMappingURL=get-first-child.js.map