@portabletext/editor
Version:
Portable Text Editor made in React
131 lines (130 loc) • 4.1 kB
JavaScript
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