@portabletext/editor 6.6.4 → 7.0.1
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 +5457 -5611
- 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,192 @@
|
|
|
1
|
+
import { isTextBlock } from "@portabletext/schema";
|
|
2
|
+
function isTypedObject(object) {
|
|
3
|
+
return isRecord(object) && typeof object._type == "string";
|
|
4
|
+
}
|
|
5
|
+
function isRecord(value) {
|
|
6
|
+
return !!value && (typeof value == "object" || typeof value == "function");
|
|
7
|
+
}
|
|
8
|
+
function isObjectNode(context, node) {
|
|
9
|
+
return isTypedObject(node) && node._type !== context.schema.block.name && node._type !== context.schema.span.name;
|
|
10
|
+
}
|
|
11
|
+
function isKeyedSegment(segment) {
|
|
12
|
+
return typeof segment == "object" && segment !== null && "_key" in segment;
|
|
13
|
+
}
|
|
14
|
+
function getChildren(snapshot, path) {
|
|
15
|
+
let currentChildren = snapshot.context.value, currentFieldName = "value", currentPath = [], isRoot = !0, currentParent;
|
|
16
|
+
for (const segment of path) {
|
|
17
|
+
if (typeof segment == "string")
|
|
18
|
+
continue;
|
|
19
|
+
let node;
|
|
20
|
+
if (isKeyedSegment(segment) ? node = currentChildren.find((child) => child._key === segment._key) : typeof segment == "number" && (node = currentChildren.at(segment)), !node)
|
|
21
|
+
return [];
|
|
22
|
+
currentPath = isRoot ? [{
|
|
23
|
+
_key: node._key
|
|
24
|
+
}] : [...currentPath, currentFieldName, {
|
|
25
|
+
_key: node._key
|
|
26
|
+
}], isRoot = !1;
|
|
27
|
+
const next = getNodeChildren(snapshot.context, node, currentParent);
|
|
28
|
+
if (!next)
|
|
29
|
+
return [];
|
|
30
|
+
currentChildren = next.children, currentFieldName = next.fieldName, currentParent = next.parent;
|
|
31
|
+
}
|
|
32
|
+
return currentChildren.map((child) => ({
|
|
33
|
+
node: child,
|
|
34
|
+
path: isRoot ? [{
|
|
35
|
+
_key: child._key
|
|
36
|
+
}] : [...currentPath, currentFieldName, {
|
|
37
|
+
_key: child._key
|
|
38
|
+
}]
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
function getNodeChildren(context, node, parent) {
|
|
42
|
+
if (isTextBlock(context, node))
|
|
43
|
+
return {
|
|
44
|
+
children: node.children,
|
|
45
|
+
fieldName: "children",
|
|
46
|
+
parent: void 0
|
|
47
|
+
};
|
|
48
|
+
if (isObjectNode(context, node)) {
|
|
49
|
+
const resolved = resolveNodeContainer(context.containers, parent, node);
|
|
50
|
+
if (!resolved)
|
|
51
|
+
return;
|
|
52
|
+
const fieldValue = node[resolved.field.name];
|
|
53
|
+
return Array.isArray(fieldValue) ? {
|
|
54
|
+
children: fieldValue,
|
|
55
|
+
fieldName: resolved.field.name,
|
|
56
|
+
parent: resolved
|
|
57
|
+
} : void 0;
|
|
58
|
+
}
|
|
59
|
+
if ("value" in node && Array.isArray(node.value) && !("_key" in node) && !("_type" in node))
|
|
60
|
+
return {
|
|
61
|
+
children: node.value,
|
|
62
|
+
fieldName: "value",
|
|
63
|
+
parent: void 0
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function resolveNodeContainer(containers, parent, node) {
|
|
67
|
+
if (parent?.of) {
|
|
68
|
+
for (const entry of parent.of)
|
|
69
|
+
if (entry.type === node._type)
|
|
70
|
+
return "field" in entry ? entry : void 0;
|
|
71
|
+
}
|
|
72
|
+
return containers.get(node._type);
|
|
73
|
+
}
|
|
74
|
+
function getNode(snapshot, path) {
|
|
75
|
+
if (path.length === 0)
|
|
76
|
+
return;
|
|
77
|
+
const {
|
|
78
|
+
context,
|
|
79
|
+
blockIndexMap
|
|
80
|
+
} = snapshot;
|
|
81
|
+
let currentChildren = context.value, node, currentParent;
|
|
82
|
+
const resolvedPath = [];
|
|
83
|
+
let isRootLevel = !0;
|
|
84
|
+
for (let i = 0; i < path.length; i++) {
|
|
85
|
+
const segment = path[i];
|
|
86
|
+
if (typeof segment == "string") {
|
|
87
|
+
resolvedPath.push(segment);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (isKeyedSegment(segment)) {
|
|
91
|
+
if (isRootLevel && blockIndexMap.size === currentChildren.length) {
|
|
92
|
+
const index = blockIndexMap.get(segment._key);
|
|
93
|
+
if (index !== void 0) {
|
|
94
|
+
const candidate = currentChildren[index];
|
|
95
|
+
candidate && candidate._key === segment._key ? node = candidate : node = currentChildren.find((child) => child._key === segment._key);
|
|
96
|
+
} else
|
|
97
|
+
node = currentChildren.find((child) => child._key === segment._key);
|
|
98
|
+
} else
|
|
99
|
+
node = currentChildren.find((child) => child._key === segment._key);
|
|
100
|
+
resolvedPath.push(segment), isRootLevel = !1;
|
|
101
|
+
} else if (typeof segment == "number")
|
|
102
|
+
node = currentChildren.at(segment), node && resolvedPath.push({
|
|
103
|
+
_key: node._key
|
|
104
|
+
});
|
|
105
|
+
else
|
|
106
|
+
return;
|
|
107
|
+
if (!node)
|
|
108
|
+
return;
|
|
109
|
+
let hasMoreSegments = !1;
|
|
110
|
+
for (let j = i + 1; j < path.length; j++) {
|
|
111
|
+
const s = path[j];
|
|
112
|
+
if (isKeyedSegment(s) || typeof s == "number") {
|
|
113
|
+
hasMoreSegments = !0;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (hasMoreSegments) {
|
|
118
|
+
const next = getNodeChildren(context, node, currentParent);
|
|
119
|
+
if (!next)
|
|
120
|
+
return;
|
|
121
|
+
currentChildren = next.children, currentParent = next.parent;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (node)
|
|
125
|
+
return {
|
|
126
|
+
node,
|
|
127
|
+
path: resolvedPath
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function getAncestors(snapshot, path) {
|
|
131
|
+
const keyedIndices = [];
|
|
132
|
+
for (let i = 0; i < path.length; i++)
|
|
133
|
+
isKeyedSegment(path[i]) && keyedIndices.push(i);
|
|
134
|
+
if (keyedIndices.length <= 1)
|
|
135
|
+
return [];
|
|
136
|
+
const {
|
|
137
|
+
context,
|
|
138
|
+
blockIndexMap
|
|
139
|
+
} = snapshot;
|
|
140
|
+
let currentChildren = context.value, isRootLevel = !0, currentParent;
|
|
141
|
+
const ancestorsByDepth = [], resolvedPath = [], targetKeyedIndex = keyedIndices[keyedIndices.length - 1];
|
|
142
|
+
let segmentIndex = 0;
|
|
143
|
+
for (; segmentIndex < targetKeyedIndex; ) {
|
|
144
|
+
const segment = path[segmentIndex];
|
|
145
|
+
if (typeof segment == "string") {
|
|
146
|
+
resolvedPath.push(segment), segmentIndex++;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
let node;
|
|
150
|
+
if (isKeyedSegment(segment)) {
|
|
151
|
+
if (isRootLevel && blockIndexMap.size === currentChildren.length) {
|
|
152
|
+
const index = blockIndexMap.get(segment._key);
|
|
153
|
+
node = index !== void 0 ? currentChildren[index] : currentChildren.find((child) => child._key === segment._key);
|
|
154
|
+
} else
|
|
155
|
+
node = currentChildren.find((child) => child._key === segment._key);
|
|
156
|
+
resolvedPath.push(segment), isRootLevel = !1;
|
|
157
|
+
} else if (typeof segment == "number")
|
|
158
|
+
node = currentChildren.at(segment), node && resolvedPath.push({
|
|
159
|
+
_key: node._key
|
|
160
|
+
});
|
|
161
|
+
else
|
|
162
|
+
return [];
|
|
163
|
+
if (!node)
|
|
164
|
+
return [];
|
|
165
|
+
const next = getNodeChildren(context, node, currentParent);
|
|
166
|
+
if (!next)
|
|
167
|
+
return [];
|
|
168
|
+
ancestorsByDepth.push({
|
|
169
|
+
node,
|
|
170
|
+
path: resolvedPath.slice()
|
|
171
|
+
}), currentChildren = next.children, currentParent = next.parent, segmentIndex++;
|
|
172
|
+
}
|
|
173
|
+
return ancestorsByDepth.reverse();
|
|
174
|
+
}
|
|
175
|
+
function getAncestor(snapshot, path, match) {
|
|
176
|
+
const ancestors = getAncestors(snapshot, path);
|
|
177
|
+
for (const ancestor of ancestors)
|
|
178
|
+
if (match(ancestor.node, ancestor.path))
|
|
179
|
+
return ancestor;
|
|
180
|
+
}
|
|
181
|
+
export {
|
|
182
|
+
getAncestor,
|
|
183
|
+
getAncestors,
|
|
184
|
+
getChildren,
|
|
185
|
+
getNode,
|
|
186
|
+
getNodeChildren,
|
|
187
|
+
isKeyedSegment,
|
|
188
|
+
isObjectNode,
|
|
189
|
+
isRecord,
|
|
190
|
+
isTypedObject
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=get-ancestor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-ancestor.js","sources":["../../src/utils/asserters.ts","../../src/slate/node/is-object-node.ts","../../src/utils/util.is-keyed-segment.ts","../../src/node-traversal/get-children.ts","../../src/node-traversal/get-node.ts","../../src/node-traversal/get-ancestors.ts","../../src/node-traversal/get-ancestor.ts"],"sourcesContent":["import type {TypedObject} from '@portabletext/schema'\n\nexport function isTypedObject(object: unknown): object is TypedObject {\n return isRecord(object) && typeof object['_type'] === 'string'\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && (typeof value === 'object' || typeof value === 'function')\n}\n","import type {PortableTextObject} from '@portabletext/schema'\nimport type {EditorSchema} from '../../editor/editor-schema'\nimport {isTypedObject} from '../../utils/asserters'\n\nexport function isObjectNode(\n context: {schema: EditorSchema},\n node: unknown,\n): node is PortableTextObject {\n return (\n isTypedObject(node) &&\n node._type !== context.schema.block.name &&\n node._type !== context.schema.span.name\n )\n}\n","import type {KeyedSegment} from '../types/paths'\n\n/**\n * @public\n */\nexport function isKeyedSegment(segment: unknown): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import {isTextBlock} from '@portabletext/schema'\nimport type {EditorSchema} from '../editor/editor-schema'\nimport type {\n Containers,\n RegisteredContainer,\n} from '../schema/resolve-containers'\nimport type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {isObjectNode} from '../slate/node/is-object-node'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the children of a node at a given path.\n *\n * @beta\n */\nexport function getChildren(\n snapshot: TraversalSnapshot,\n path: Path,\n): Array<{node: Node; path: Path}> {\n let currentChildren: Array<Node> = snapshot.context.value\n let currentFieldName = 'value'\n let currentPath: Path = []\n let isRoot = true\n let currentParent: RegisteredContainer | undefined\n\n for (const segment of path) {\n if (typeof segment === 'string') {\n continue\n }\n\n let node: Node | undefined\n if (isKeyedSegment(segment)) {\n node = currentChildren.find((child) => child._key === segment._key)\n } else if (typeof segment === 'number') {\n node = currentChildren.at(segment)\n }\n\n if (!node) {\n return []\n }\n\n currentPath = isRoot\n ? [{_key: node._key}]\n : [...currentPath, currentFieldName, {_key: node._key}]\n isRoot = false\n\n const next = getNodeChildren(snapshot.context, node, currentParent)\n\n if (!next) {\n return []\n }\n\n currentChildren = next.children\n currentFieldName = next.fieldName\n currentParent = next.parent\n }\n\n return currentChildren.map((child) => ({\n node: child,\n path: isRoot\n ? [{_key: child._key}]\n : [...currentPath, currentFieldName, {_key: child._key}],\n }))\n}\n\n/**\n * Resolve a node's editable child array.\n *\n * When `parent` is provided and its `of` declares a positional entry\n * matching `node._type`, that positional entry's `field` is used.\n * Otherwise the top-level `containers.get(node._type)` provides the\n * fallback.\n *\n * The returned `parent` is the resolved container entry for `node`\n * itself (used by the caller to thread further descent).\n *\n * @beta\n */\nexport function getNodeChildren(\n context: {\n schema: EditorSchema\n containers: Containers\n },\n node: Node | {value: Array<Node>},\n parent?: RegisteredContainer,\n):\n | {\n children: Array<Node>\n fieldName: string\n parent: RegisteredContainer | undefined\n }\n | undefined {\n // Text blocks store children in .children\n if (isTextBlock(context, node)) {\n return {\n children: node.children,\n fieldName: 'children',\n parent: undefined,\n }\n }\n\n if (isObjectNode(context, node)) {\n const resolved = resolveNodeContainer(context.containers, parent, node)\n\n if (!resolved) {\n return undefined\n }\n\n const fieldValue = (node as Record<string, unknown>)[resolved.field.name]\n\n if (!Array.isArray(fieldValue)) {\n return undefined\n }\n\n return {\n children: fieldValue as Array<Node>,\n fieldName: resolved.field.name,\n parent: resolved,\n }\n }\n\n // Root context: has .value array but no _key or _type\n if (\n 'value' in node &&\n Array.isArray(node['value']) &&\n !('_key' in node) &&\n !('_type' in node)\n ) {\n return {\n children: node['value'] as Array<Node>,\n fieldName: 'value',\n parent: undefined,\n }\n }\n\n return undefined\n}\n\n/**\n * Pick the positional override from `parent.of` if present; fall back\n * to the top-level entry. Returns only `RegisteredContainer` entries\n * since leaves do not have editable children.\n */\nfunction resolveNodeContainer(\n containers: Containers,\n parent: RegisteredContainer | undefined,\n node: Node,\n): RegisteredContainer | undefined {\n if (parent?.of) {\n for (const entry of parent.of) {\n if (entry.type === node._type) {\n // Only return container entries; leaves have no editable children.\n if ('field' in entry) {\n return entry\n }\n return undefined\n }\n }\n }\n return containers.get(node._type)\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {getNodeChildren} from './get-children'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the node at a given path.\n *\n * The path can be either keyed (KeyedSegment + field name strings) or\n * indexed (numbers). Keyed segments are resolved by matching `_key`,\n * field name strings are skipped (they're structural), and numbers\n * are resolved by index.\n *\n * The returned path is always fully keyed, even if the input path\n * contained numeric indices.\n *\n * @beta\n */\nexport function getNode(\n snapshot: TraversalSnapshot,\n path: Path,\n): {node: Node; path: Path} | undefined {\n if (path.length === 0) {\n return undefined\n }\n\n const {context, blockIndexMap} = snapshot\n let currentChildren: Array<Node> = context.value\n let node: Node | undefined\n let currentParent:\n | import('../schema/resolve-containers').RegisteredContainer\n | undefined\n const resolvedPath: Path = []\n let isRootLevel = true\n\n for (let i = 0; i < path.length; i++) {\n const segment = path[i]\n\n if (typeof segment === 'string') {\n resolvedPath.push(segment)\n continue\n }\n\n if (isKeyedSegment(segment)) {\n if (isRootLevel && blockIndexMap.size === currentChildren.length) {\n const index = blockIndexMap.get(segment._key)\n if (index !== undefined) {\n const candidate = currentChildren[index]\n if (candidate && candidate._key === segment._key) {\n node = candidate\n } else {\n node = currentChildren.find((child) => child._key === segment._key)\n }\n } else {\n node = currentChildren.find((child) => child._key === segment._key)\n }\n } else {\n node = currentChildren.find((child) => child._key === segment._key)\n }\n resolvedPath.push(segment)\n isRootLevel = false\n } else if (typeof segment === 'number') {\n node = currentChildren.at(segment)\n if (node) {\n resolvedPath.push({_key: node._key})\n }\n } else {\n return undefined\n }\n\n if (!node) {\n return undefined\n }\n\n let hasMoreSegments = false\n for (let j = i + 1; j < path.length; j++) {\n const s = path[j]\n if (isKeyedSegment(s) || typeof s === 'number') {\n hasMoreSegments = true\n break\n }\n }\n\n if (hasMoreSegments) {\n const next = getNodeChildren(context, node, currentParent)\n\n if (!next) {\n return undefined\n }\n\n currentChildren = next.children\n currentParent = next.parent\n }\n }\n\n if (!node) {\n return undefined\n }\n\n return {node, path: resolvedPath}\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {getNodeChildren} from './get-children'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get all ancestors of the node at a given path, from nearest to furthest.\n *\n * For a path like [{_key:'t1'}, 'rows', {_key:'r1'}, 'cells', {_key:'c1'}],\n * the ancestors are (nearest first):\n * [{_key:'t1'}, 'rows', {_key:'r1'}]\n * [{_key:'t1'}]\n *\n * Walks from root to the target in a single pass collecting each ancestor\n * as it goes.\n *\n * @beta\n */\nexport function getAncestors(\n snapshot: TraversalSnapshot,\n path: Path,\n): Array<{node: Node; path: Path}> {\n // Collect keyed-segment indices to know where each ancestor's path ends.\n const keyedIndices: Array<number> = []\n for (let i = 0; i < path.length; i++) {\n if (isKeyedSegment(path[i])) {\n keyedIndices.push(i)\n }\n }\n\n // Need at least 2 keyed segments to have an ancestor (the last is self).\n if (keyedIndices.length <= 1) {\n return []\n }\n\n const {context, blockIndexMap} = snapshot\n let currentChildren: Array<Node> = context.value\n let isRootLevel = true\n let currentParent:\n | import('../schema/resolve-containers').RegisteredContainer\n | undefined\n\n const ancestorsByDepth: Array<{node: Node; path: Path}> = []\n const resolvedPath: Path = []\n\n // Descend once. We walk only as far as the second-to-last keyed segment;\n // the last keyed segment is the target itself, which is not an ancestor.\n const targetKeyedIndex = keyedIndices[keyedIndices.length - 1]!\n\n let segmentIndex = 0\n while (segmentIndex < targetKeyedIndex) {\n const segment = path[segmentIndex]!\n\n if (typeof segment === 'string') {\n resolvedPath.push(segment)\n segmentIndex++\n continue\n }\n\n let node: Node | undefined\n if (isKeyedSegment(segment)) {\n // Production snapshots maintain `blockIndexMap` in lockstep with\n // `context.value` so this fast path always fires. Some test\n // fixtures still pass empty or stale maps, which is the debt this\n // size check is working around - see /specs/snapshot-invariants.md.\n // When the fixtures are aligned, drop the guard and use the map\n // directly.\n if (isRootLevel && blockIndexMap.size === currentChildren.length) {\n const index = blockIndexMap.get(segment._key)\n node =\n index !== undefined\n ? currentChildren[index]\n : currentChildren.find((child) => child._key === segment._key)\n } else {\n node = currentChildren.find((child) => child._key === segment._key)\n }\n resolvedPath.push(segment)\n isRootLevel = false\n } else if (typeof segment === 'number') {\n node = currentChildren.at(segment)\n if (node) {\n resolvedPath.push({_key: node._key})\n }\n } else {\n return []\n }\n\n if (!node) {\n return []\n }\n\n // Descend with positional awareness. `getNodeChildren` checks the\n // current parent's `of` for a positional override before falling\n // back to the top-level `containers` map - so same-`_type`\n // registered under different parents with different `field`\n // resolves to the right entry at this position.\n const next = getNodeChildren(context, node, currentParent)\n if (!next) {\n return []\n }\n\n ancestorsByDepth.push({\n node,\n path: resolvedPath.slice(),\n })\n\n currentChildren = next.children\n currentParent = next.parent\n segmentIndex++\n }\n\n // Return nearest-first (reverse of document order at the call site).\n return ancestorsByDepth.reverse()\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {getAncestors} from './get-ancestors'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Find the first ancestor of the node at a given path that matches a predicate.\n * Does not check the node at the path itself, only its ancestors.\n *\n * When `match` is a type predicate, the returned `node` narrows to that type.\n *\n * @beta\n */\nexport function getAncestor<TMatch extends Node>(\n snapshot: TraversalSnapshot,\n path: Path,\n match: (node: Node, path: Path) => node is TMatch,\n): {node: TMatch; path: Path} | undefined\n/**\n * @beta\n */\nexport function getAncestor(\n snapshot: TraversalSnapshot,\n path: Path,\n match: (node: Node, path: Path) => boolean,\n): {node: Node; path: Path} | undefined\nexport function getAncestor(\n snapshot: TraversalSnapshot,\n path: Path,\n match: (node: Node, path: Path) => boolean,\n): {node: Node; path: Path} | undefined {\n const ancestors = getAncestors(snapshot, path)\n\n for (const ancestor of ancestors) {\n if (match(ancestor.node, ancestor.path)) {\n return ancestor\n }\n }\n\n return undefined\n}\n"],"names":["isTypedObject","object","isRecord","value","isObjectNode","context","node","_type","schema","block","name","span","isKeyedSegment","segment","getChildren","snapshot","path","currentChildren","currentFieldName","currentPath","isRoot","currentParent","find","child","_key","at","next","getNodeChildren","children","fieldName","parent","map","isTextBlock","undefined","resolved","resolveNodeContainer","containers","fieldValue","field","Array","isArray","of","entry","type","get","getNode","length","blockIndexMap","resolvedPath","isRootLevel","i","push","size","index","candidate","hasMoreSegments","j","s","getAncestors","keyedIndices","ancestorsByDepth","targetKeyedIndex","segmentIndex","slice","reverse","getAncestor","match","ancestors","ancestor"],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { getChildren, getNode, isKeyedSegment, getNodeChildren } from "./get-ancestor.js";
|
|
2
|
+
import { isSpan, isTextBlock, getSubSchema } from "@portabletext/schema";
|
|
3
|
+
import { getNodes } from "./get-path-sub-schema.js";
|
|
4
|
+
function getLeaf(snapshot, path, options) {
|
|
5
|
+
const {
|
|
6
|
+
edge
|
|
7
|
+
} = options;
|
|
8
|
+
let currentPath = path;
|
|
9
|
+
if (currentPath.length === 0) {
|
|
10
|
+
const children = getChildren(snapshot, []);
|
|
11
|
+
if (children.length === 0)
|
|
12
|
+
return;
|
|
13
|
+
const firstOrLast = edge === "end" ? children.at(-1) : children.at(0);
|
|
14
|
+
if (getChildren(snapshot, firstOrLast.path).length === 0)
|
|
15
|
+
return firstOrLast;
|
|
16
|
+
currentPath = firstOrLast.path;
|
|
17
|
+
} else {
|
|
18
|
+
const entry = getNode(snapshot, currentPath);
|
|
19
|
+
if (!entry)
|
|
20
|
+
return;
|
|
21
|
+
if (getChildren(snapshot, currentPath).length === 0)
|
|
22
|
+
return entry;
|
|
23
|
+
}
|
|
24
|
+
for (; ; ) {
|
|
25
|
+
const children = getChildren(snapshot, currentPath);
|
|
26
|
+
if (children.length === 0)
|
|
27
|
+
return getNode(snapshot, currentPath) ?? void 0;
|
|
28
|
+
currentPath = (edge === "end" ? children.at(-1) : children.at(0)).path;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getText(snapshot, path) {
|
|
32
|
+
const entry = getNode(snapshot, path);
|
|
33
|
+
if (!entry)
|
|
34
|
+
return;
|
|
35
|
+
if (isSpan({
|
|
36
|
+
schema: snapshot.context.schema
|
|
37
|
+
}, entry.node))
|
|
38
|
+
return entry.node.text;
|
|
39
|
+
let text = "";
|
|
40
|
+
for (const descendant of getNodes(snapshot, {
|
|
41
|
+
at: path
|
|
42
|
+
}))
|
|
43
|
+
isSpan({
|
|
44
|
+
schema: snapshot.context.schema
|
|
45
|
+
}, descendant.node) && (text += descendant.node.text);
|
|
46
|
+
return text;
|
|
47
|
+
}
|
|
48
|
+
function getSpanNode(snapshot, path) {
|
|
49
|
+
const entry = getNode(snapshot, path);
|
|
50
|
+
if (entry && isSpan({
|
|
51
|
+
schema: snapshot.context.schema
|
|
52
|
+
}, entry.node))
|
|
53
|
+
return {
|
|
54
|
+
node: entry.node,
|
|
55
|
+
path: entry.path
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function getTextBlockNode(snapshot, path) {
|
|
59
|
+
const entry = getNode(snapshot, path);
|
|
60
|
+
if (entry && isTextBlock({
|
|
61
|
+
schema: snapshot.context.schema
|
|
62
|
+
}, entry.node))
|
|
63
|
+
return {
|
|
64
|
+
node: entry.node,
|
|
65
|
+
path: entry.path
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function getUnionSchema(schema, containers) {
|
|
69
|
+
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, []);
|
|
70
|
+
for (const container of containers.values()) {
|
|
71
|
+
if (!acceptsTextBlock(container.field.of, schema.block.name))
|
|
72
|
+
continue;
|
|
73
|
+
const sub = getSubSchema(schema, container.field.of);
|
|
74
|
+
mergeByName(sub.decorators, decorators), mergeByName(sub.annotations, annotations), mergeByName(sub.lists, lists), mergeByName(sub.styles, styles), mergeByName(sub.inlineObjects, inlineObjects), mergeByName(sub.blockObjects, blockObjects);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
...schema,
|
|
78
|
+
decorators,
|
|
79
|
+
annotations,
|
|
80
|
+
lists,
|
|
81
|
+
styles,
|
|
82
|
+
inlineObjects,
|
|
83
|
+
blockObjects
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function acceptsTextBlock(of, blockName) {
|
|
87
|
+
return of.some((member) => member.type === "block" || member.type === blockName);
|
|
88
|
+
}
|
|
89
|
+
function mergeByName(source, target) {
|
|
90
|
+
for (const entry of source)
|
|
91
|
+
target.some((existing) => existing.name === entry.name) || target.push(entry);
|
|
92
|
+
return target;
|
|
93
|
+
}
|
|
94
|
+
function isLeaf(snapshot, path) {
|
|
95
|
+
if (path.length === 0)
|
|
96
|
+
return !1;
|
|
97
|
+
let currentChildren = snapshot.context.value, currentParent;
|
|
98
|
+
for (let i = 0; i < path.length; i++) {
|
|
99
|
+
const segment = path[i];
|
|
100
|
+
let node;
|
|
101
|
+
if (isKeyedSegment(segment))
|
|
102
|
+
node = currentChildren.find((child) => child._key === segment._key);
|
|
103
|
+
else if (typeof segment == "number")
|
|
104
|
+
node = currentChildren.at(segment);
|
|
105
|
+
else
|
|
106
|
+
continue;
|
|
107
|
+
if (!node)
|
|
108
|
+
return !1;
|
|
109
|
+
const next = getNodeChildren(snapshot.context, node, currentParent);
|
|
110
|
+
if (i === path.length - 1)
|
|
111
|
+
return next === void 0;
|
|
112
|
+
if (!next)
|
|
113
|
+
return !1;
|
|
114
|
+
currentChildren = next.children, currentParent = next.parent;
|
|
115
|
+
}
|
|
116
|
+
return !1;
|
|
117
|
+
}
|
|
118
|
+
function getFirstChild(snapshot, path) {
|
|
119
|
+
return getChildren(snapshot, path).at(0);
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
getFirstChild,
|
|
123
|
+
getLeaf,
|
|
124
|
+
getSpanNode,
|
|
125
|
+
getText,
|
|
126
|
+
getTextBlockNode,
|
|
127
|
+
getUnionSchema,
|
|
128
|
+
isLeaf
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=get-first-child.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-first-child.js","sources":["../../src/node-traversal/get-leaf.ts","../../src/node-traversal/get-text.ts","../../src/node-traversal/get-span-node.ts","../../src/node-traversal/get-text-block-node.ts","../../src/traversal/get-union-schema.ts","../../src/node-traversal/is-leaf.ts","../../src/node-traversal/get-first-child.ts"],"sourcesContent":["import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {getChildren} from './get-children'\nimport {getNode} from './get-node'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the deepest leaf node starting from a path, walking toward either the\n * start or end edge. A leaf is any node that has no children according to the\n * traversal context.\n *\n * @beta\n */\nexport function getLeaf(\n snapshot: TraversalSnapshot,\n path: Path,\n options: {edge: 'start' | 'end'},\n): {node: Node; path: Path} | undefined {\n const {edge} = options\n\n let currentPath = path\n\n // If starting from root (empty path), descend into first/last child\n if (currentPath.length === 0) {\n const children = getChildren(snapshot, [])\n if (children.length === 0) {\n return undefined\n }\n const firstOrLast = edge === 'end' ? children.at(-1)! : children.at(0)!\n const nodeChildren = getChildren(snapshot, firstOrLast.path)\n if (nodeChildren.length === 0) {\n return firstOrLast\n }\n currentPath = firstOrLast.path\n } else {\n // Check if the node at path is already a leaf\n const entry = getNode(snapshot, currentPath)\n if (!entry) {\n return undefined\n }\n const children = getChildren(snapshot, currentPath)\n if (children.length === 0) {\n return entry\n }\n }\n\n // Descend to deepest leaf\n while (true) {\n const children = getChildren(snapshot, currentPath)\n if (children.length === 0) {\n const entry = getNode(snapshot, currentPath)\n return entry ?? undefined\n }\n const child = edge === 'end' ? children.at(-1)! : children.at(0)!\n currentPath = child.path\n }\n}\n","import {isSpan} from '@portabletext/schema'\nimport type {Path} from '../slate/interfaces/path'\nimport {getNode} from './get-node'\nimport {getNodes} from './get-nodes'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the concatenated text content of the node at a given path.\n *\n * @beta\n */\nexport function getText(\n snapshot: TraversalSnapshot,\n path: Path,\n): string | undefined {\n const entry = getNode(snapshot, path)\n\n if (!entry) {\n return undefined\n }\n\n if (isSpan({schema: snapshot.context.schema}, entry.node)) {\n return entry.node.text\n }\n\n let text = ''\n\n for (const descendant of getNodes(snapshot, {at: path})) {\n if (isSpan({schema: snapshot.context.schema}, descendant.node)) {\n text += descendant.node.text\n }\n }\n\n return text\n}\n","import {isSpan, type PortableTextSpan} from '@portabletext/schema'\nimport type {Path} from '../slate/interfaces/path'\nimport {getNode} from './get-node'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the span node at a given path.\n *\n * @beta\n */\nexport function getSpanNode(\n snapshot: TraversalSnapshot,\n path: Path,\n): {node: PortableTextSpan; path: Path} | undefined {\n const entry = getNode(snapshot, path)\n\n if (!entry) {\n return undefined\n }\n\n if (!isSpan({schema: snapshot.context.schema}, entry.node)) {\n return undefined\n }\n\n return {node: entry.node, path: entry.path}\n}\n","import {isTextBlock, type PortableTextTextBlock} from '@portabletext/schema'\nimport type {Path} from '../slate/interfaces/path'\nimport {getNode} from './get-node'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the text block node at a given path.\n *\n * @beta\n */\nexport function getTextBlockNode(\n snapshot: TraversalSnapshot,\n path: Path,\n): {node: PortableTextTextBlock; path: Path} | undefined {\n const entry = getNode(snapshot, path)\n\n if (!entry) {\n return undefined\n }\n\n if (!isTextBlock({schema: snapshot.context.schema}, entry.node)) {\n return undefined\n }\n\n return {node: entry.node, path: entry.path}\n}\n","import {getSubSchema, type Schema} from '@portabletext/schema'\nimport type {Containers} from '../schema/resolve-containers'\n\n/**\n * Return a `Schema` that contains every named member declared anywhere\n * in the editor's schema graph that is reachable from a position where text\n * is edited - the root schema merged with the sub-schema of every registered\n * container whose field accepts text blocks, deduped by name. Useful for\n * rendering a static toolbar whose buttons stay stable across selection\n * moves while still reflecting everything that could plausibly be edited or\n * inserted somewhere.\n *\n * Containers whose field does NOT accept text blocks (e.g. a `table`\n * container whose `rows` field only accepts `row` objects, or a `row`\n * container whose `cells` field only accepts `cell` objects) are\n * **structural**: their immediate `of` types are organizational, not\n * insertable user content. Those structural types are excluded from the\n * union. Their nested text-block-accepting descendants (e.g. a `cell`\n * that contains a `content` field of `{type: 'block'}`) are reached via\n * those descendants' own container registration.\n *\n * Pair with `getPathSubSchema` (or a path-based intersection across a\n * range) to determine which of the union's members are applicable at the\n * current selection.\n *\n * @beta\n */\nexport function getUnionSchema(schema: Schema, containers: Containers): Schema {\n const decorators = mergeByName(schema.decorators, [])\n const annotations = mergeByName(schema.annotations, [])\n const lists = mergeByName(schema.lists, [])\n const styles = mergeByName(schema.styles, [])\n const inlineObjects = mergeByName(schema.inlineObjects, [])\n const blockObjects = mergeByName(schema.blockObjects, [])\n\n for (const container of containers.values()) {\n if (!acceptsTextBlock(container.field.of, schema.block.name)) {\n continue\n }\n const sub = getSubSchema(schema, container.field.of)\n mergeByName(sub.decorators, decorators)\n mergeByName(sub.annotations, annotations)\n mergeByName(sub.lists, lists)\n mergeByName(sub.styles, styles)\n mergeByName(sub.inlineObjects, inlineObjects)\n mergeByName(sub.blockObjects, blockObjects)\n }\n\n return {\n ...schema,\n decorators,\n annotations,\n lists,\n styles,\n inlineObjects,\n blockObjects,\n }\n}\n\nfunction acceptsTextBlock(\n of: ReadonlyArray<{type: string}>,\n blockName: string,\n): boolean {\n return of.some(\n (member) => member.type === 'block' || member.type === blockName,\n )\n}\n\nfunction mergeByName<T extends {name: string}>(\n source: ReadonlyArray<T>,\n target: Array<T>,\n): Array<T> {\n for (const entry of source) {\n if (target.some((existing) => existing.name === entry.name)) {\n continue\n }\n target.push(entry)\n }\n return target\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {getNodeChildren} from './get-children'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Determine if a node at the given path is a leaf.\n *\n * A leaf node cannot have children. Spans and non-editable object nodes are\n * leaves. Text blocks and editable container objects are not.\n *\n * @beta\n */\nexport function isLeaf(snapshot: TraversalSnapshot, path: Path): boolean {\n if (path.length === 0) {\n return false\n }\n\n let currentChildren: Array<Node> = snapshot.context.value\n let currentParent:\n | import('../schema/resolve-containers').RegisteredContainer\n | undefined\n\n for (let i = 0; i < path.length; i++) {\n const segment = path[i]!\n let node: Node | undefined\n\n if (isKeyedSegment(segment)) {\n node = currentChildren.find((child) => child._key === segment._key)\n } else if (typeof segment === 'number') {\n node = currentChildren.at(segment)\n } else {\n continue\n }\n\n if (!node) {\n return false\n }\n\n const next = getNodeChildren(snapshot.context, node, currentParent)\n\n if (i === path.length - 1) {\n return next === undefined\n }\n\n if (!next) {\n return false\n }\n\n currentChildren = next.children\n currentParent = next.parent\n }\n\n return false\n}\n","import type {Node} from '../slate/interfaces/node'\nimport type {Path} from '../slate/interfaces/path'\nimport {getChildren} from './get-children'\nimport type {TraversalSnapshot} from './traversal-snapshot'\n\n/**\n * Get the first child of a node at a given path.\n *\n * @beta\n */\nexport function getFirstChild(\n snapshot: TraversalSnapshot,\n path: Path,\n): {node: Node; path: Path} | undefined {\n return getChildren(snapshot, path).at(0)\n}\n"],"names":["getLeaf","snapshot","path","options","edge","currentPath","length","children","getChildren","firstOrLast","at","entry","getNode","undefined","getText","isSpan","schema","context","node","text","descendant","getNodes","getSpanNode","getTextBlockNode","isTextBlock","getUnionSchema","containers","decorators","mergeByName","annotations","lists","styles","inlineObjects","blockObjects","container","values","acceptsTextBlock","field","of","block","name","sub","getSubSchema","blockName","some","member","type","source","target","existing","push","isLeaf","currentChildren","value","currentParent","i","segment","isKeyedSegment","find","child","_key","next","getNodeChildren","parent","getFirstChild"],"mappings":"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"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { isTypedObject, isKeyedSegment, getNode, getAncestors, getChildren, getNodeChildren, isObjectNode } from "./get-ancestor.js";
|
|
2
|
+
import { getSubSchema } from "@portabletext/schema";
|
|
3
|
+
function isSpanNode(context, node) {
|
|
4
|
+
return isTypedObject(node) && node._type === context.schema.span.name;
|
|
5
|
+
}
|
|
6
|
+
function isTextBlockNode(context, node) {
|
|
7
|
+
return isTypedObject(node) && node._type === context.schema.block.name;
|
|
8
|
+
}
|
|
9
|
+
function parentPath(path) {
|
|
10
|
+
if (path.length === 0)
|
|
11
|
+
throw new Error(`Cannot get the parent path of the root path [${path}].`);
|
|
12
|
+
let lastNodeIndex = -1;
|
|
13
|
+
for (let i = path.length - 1; i >= 0; i--)
|
|
14
|
+
if (isKeyedSegment(path[i]) || typeof path[i] == "number") {
|
|
15
|
+
lastNodeIndex = i;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
if (lastNodeIndex === -1)
|
|
19
|
+
return [];
|
|
20
|
+
const result = path.slice(0, lastNodeIndex);
|
|
21
|
+
return result.length > 0 && typeof result[result.length - 1] == "string" ? result.slice(0, -1) : result;
|
|
22
|
+
}
|
|
23
|
+
function getParent(snapshot, path) {
|
|
24
|
+
if (path.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
const parent = parentPath(path);
|
|
27
|
+
if (parent.length !== 0)
|
|
28
|
+
return getNode(snapshot, parent);
|
|
29
|
+
}
|
|
30
|
+
function isBlock(snapshot, path) {
|
|
31
|
+
const parent = getParent(snapshot, path);
|
|
32
|
+
return parent ? !isTextBlockNode({
|
|
33
|
+
schema: snapshot.context.schema
|
|
34
|
+
}, parent.node) : !0;
|
|
35
|
+
}
|
|
36
|
+
function getBlock(snapshot, path) {
|
|
37
|
+
const entry = getNode(snapshot, path);
|
|
38
|
+
if (entry && isBlock(snapshot, path) && !isSpanNode({
|
|
39
|
+
schema: snapshot.context.schema
|
|
40
|
+
}, entry.node))
|
|
41
|
+
return {
|
|
42
|
+
node: entry.node,
|
|
43
|
+
path: entry.path
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function hasNode(snapshot, path) {
|
|
47
|
+
return getNode(snapshot, path) !== void 0;
|
|
48
|
+
}
|
|
49
|
+
function resolveContainerAt(containers, value, path) {
|
|
50
|
+
const keyedIndices = [];
|
|
51
|
+
for (let index = 0; index < path.length; index++)
|
|
52
|
+
isKeyedSegment(path[index]) && keyedIndices.push(index);
|
|
53
|
+
if (keyedIndices.length === 0)
|
|
54
|
+
return;
|
|
55
|
+
let currentChildren = value, parent, resolved;
|
|
56
|
+
const targetKeyedIndex = keyedIndices[keyedIndices.length - 1];
|
|
57
|
+
let segmentIndex = 0;
|
|
58
|
+
for (; segmentIndex <= targetKeyedIndex; ) {
|
|
59
|
+
const segment = path[segmentIndex];
|
|
60
|
+
if (typeof segment == "string") {
|
|
61
|
+
segmentIndex++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let node;
|
|
65
|
+
if (isKeyedSegment(segment))
|
|
66
|
+
node = currentChildren.find((child) => child._key === segment._key);
|
|
67
|
+
else if (typeof segment == "number")
|
|
68
|
+
node = currentChildren.at(segment);
|
|
69
|
+
else
|
|
70
|
+
return;
|
|
71
|
+
if (!node || (resolved = resolveNodeEntry(containers, parent, node), !resolved))
|
|
72
|
+
return;
|
|
73
|
+
if (segmentIndex < targetKeyedIndex) {
|
|
74
|
+
if (!("field" in resolved))
|
|
75
|
+
return;
|
|
76
|
+
const fieldValue = node[resolved.field.name];
|
|
77
|
+
if (!Array.isArray(fieldValue))
|
|
78
|
+
return;
|
|
79
|
+
parent = resolved, currentChildren = fieldValue;
|
|
80
|
+
}
|
|
81
|
+
segmentIndex++;
|
|
82
|
+
}
|
|
83
|
+
return resolved;
|
|
84
|
+
}
|
|
85
|
+
function resolveNodeEntry(containers, parent, node) {
|
|
86
|
+
if (parent?.of) {
|
|
87
|
+
for (const entry of parent.of)
|
|
88
|
+
if (entry.type === node._type)
|
|
89
|
+
return entry;
|
|
90
|
+
}
|
|
91
|
+
return containers.get(node._type);
|
|
92
|
+
}
|
|
93
|
+
function getEnclosingBlock(snapshot, path) {
|
|
94
|
+
const direct = getBlock(snapshot, path);
|
|
95
|
+
if (direct)
|
|
96
|
+
return direct;
|
|
97
|
+
for (const ancestor of getAncestors(snapshot, path))
|
|
98
|
+
if (isBlock(snapshot, ancestor.path)) {
|
|
99
|
+
const block = getBlock(snapshot, ancestor.path);
|
|
100
|
+
if (block)
|
|
101
|
+
return block;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function isAncestorPath(path, another) {
|
|
105
|
+
if (path.length >= another.length)
|
|
106
|
+
return !1;
|
|
107
|
+
for (let i = 0; i < path.length; i++) {
|
|
108
|
+
const segment = path[i], otherSegment = another[i];
|
|
109
|
+
if (isKeyedSegment(segment) && isKeyedSegment(otherSegment)) {
|
|
110
|
+
if (segment._key !== otherSegment._key)
|
|
111
|
+
return !1;
|
|
112
|
+
} else if (segment !== otherSegment)
|
|
113
|
+
return !1;
|
|
114
|
+
}
|
|
115
|
+
return !0;
|
|
116
|
+
}
|
|
117
|
+
function* getNodes(snapshot, options = {}) {
|
|
118
|
+
const {
|
|
119
|
+
at = [],
|
|
120
|
+
from,
|
|
121
|
+
to,
|
|
122
|
+
match,
|
|
123
|
+
reverse = !1
|
|
124
|
+
} = options;
|
|
125
|
+
if (from === void 0 && to === void 0) {
|
|
126
|
+
yield* getNodesSimple(snapshot, at, {
|
|
127
|
+
match,
|
|
128
|
+
reverse
|
|
129
|
+
});
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
yield* getNodesInRange(snapshot, at, {
|
|
133
|
+
from,
|
|
134
|
+
to,
|
|
135
|
+
match,
|
|
136
|
+
reverse
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function* getNodesSimple(snapshot, path, options) {
|
|
140
|
+
const {
|
|
141
|
+
match,
|
|
142
|
+
reverse = !1
|
|
143
|
+
} = options, children = getChildren(snapshot, path), entries = reverse ? [...children].reverse() : children;
|
|
144
|
+
for (const entry of entries)
|
|
145
|
+
(!match || match(entry.node, entry.path)) && (yield entry), yield* getNodesSimple(snapshot, entry.path, options);
|
|
146
|
+
}
|
|
147
|
+
function comparePathsInTree(snapshot, pathA, pathB) {
|
|
148
|
+
const keysA = pathA.filter(isKeyedSegment), keysB = pathB.filter(isKeyedSegment), {
|
|
149
|
+
context
|
|
150
|
+
} = snapshot;
|
|
151
|
+
let currentChildren = context.value, currentParent, isRootLevel = !0;
|
|
152
|
+
const minDepth = Math.min(keysA.length, keysB.length);
|
|
153
|
+
for (let depth = 0; depth < minDepth; depth++) {
|
|
154
|
+
const keyA = keysA[depth], keyB = keysB[depth];
|
|
155
|
+
if (keyA._key === keyB._key) {
|
|
156
|
+
let matchedNode;
|
|
157
|
+
if (isRootLevel && snapshot.blockIndexMap.has(keyA._key)) {
|
|
158
|
+
const index = snapshot.blockIndexMap.get(keyA._key);
|
|
159
|
+
index !== void 0 && (matchedNode = currentChildren[index]);
|
|
160
|
+
} else
|
|
161
|
+
matchedNode = currentChildren.find((c) => c._key === keyA._key);
|
|
162
|
+
if (!matchedNode)
|
|
163
|
+
return 0;
|
|
164
|
+
const next = getNodeChildren(context, matchedNode, currentParent);
|
|
165
|
+
if (!next)
|
|
166
|
+
return 0;
|
|
167
|
+
currentChildren = next.children, currentParent = next.parent, isRootLevel = !1;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (isRootLevel) {
|
|
171
|
+
const indexA2 = snapshot.blockIndexMap.get(keyA._key) ?? -1, indexB2 = snapshot.blockIndexMap.get(keyB._key) ?? -1;
|
|
172
|
+
if (indexA2 !== -1 && indexB2 !== -1)
|
|
173
|
+
return indexA2 < indexB2 ? -1 : indexA2 > indexB2 ? 1 : 0;
|
|
174
|
+
}
|
|
175
|
+
let indexA = -1, indexB = -1;
|
|
176
|
+
for (let i = 0; i < currentChildren.length; i++) {
|
|
177
|
+
const sibling = currentChildren[i];
|
|
178
|
+
if (sibling._key === keyA._key && (indexA = i), sibling._key === keyB._key && (indexB = i), indexA !== -1 && indexB !== -1)
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
return indexA < indexB ? -1 : indexA > indexB ? 1 : 0;
|
|
182
|
+
}
|
|
183
|
+
return keysA.length < keysB.length ? -1 : keysA.length > keysB.length ? 1 : 0;
|
|
184
|
+
}
|
|
185
|
+
function* getNodesInRange(snapshot, path, options) {
|
|
186
|
+
const {
|
|
187
|
+
from,
|
|
188
|
+
to,
|
|
189
|
+
match,
|
|
190
|
+
reverse = !1
|
|
191
|
+
} = options, children = getChildren(snapshot, path), entries = reverse ? [...children].reverse() : children;
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
if (canStopTraversal(snapshot, entry.path, from, to, reverse))
|
|
194
|
+
return;
|
|
195
|
+
couldContainInRangeNodes(snapshot, entry.path, from, to) && (isInRange(snapshot, entry.path, from, to) && (!match || match(entry.node, entry.path)) && (yield entry), yield* getNodesInRange(snapshot, entry.path, options));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function isInRange(snapshot, nodePath, from, to) {
|
|
199
|
+
return !(from !== void 0 && comparePathsInTree(snapshot, nodePath, from) === -1 && !isAncestorPath(nodePath, from) || to !== void 0 && comparePathsInTree(snapshot, nodePath, to) === 1 && !isAncestorPath(nodePath, to));
|
|
200
|
+
}
|
|
201
|
+
function couldContainInRangeNodes(snapshot, nodePath, from, to) {
|
|
202
|
+
return !!(isInRange(snapshot, nodePath, from, to) || from !== void 0 && isAncestorPath(nodePath, from) || to !== void 0 && isAncestorPath(nodePath, to));
|
|
203
|
+
}
|
|
204
|
+
function canStopTraversal(snapshot, nodePath, from, to, reverse) {
|
|
205
|
+
return reverse ? from === void 0 ? !1 : comparePathsInTree(snapshot, nodePath, from) === -1 && !isAncestorPath(nodePath, from) : to === void 0 ? !1 : comparePathsInTree(snapshot, nodePath, to) === 1;
|
|
206
|
+
}
|
|
207
|
+
function getSibling(snapshot, path, direction) {
|
|
208
|
+
if (path.length === 0)
|
|
209
|
+
return;
|
|
210
|
+
const lastSegment = path.at(-1);
|
|
211
|
+
if (!isKeyedSegment(lastSegment))
|
|
212
|
+
return;
|
|
213
|
+
const parent = parentPath(path), children = getChildren(snapshot, parent), currentIndex = children.findIndex((child) => child.node._key === lastSegment._key);
|
|
214
|
+
if (currentIndex === -1)
|
|
215
|
+
return;
|
|
216
|
+
const siblingIndex = direction === "next" ? currentIndex + 1 : currentIndex - 1;
|
|
217
|
+
if (!(siblingIndex < 0 || siblingIndex >= children.length))
|
|
218
|
+
return children[siblingIndex];
|
|
219
|
+
}
|
|
220
|
+
function isInline(snapshot, path) {
|
|
221
|
+
return !isBlock(snapshot, path);
|
|
222
|
+
}
|
|
223
|
+
function descendToParent(snapshot, path) {
|
|
224
|
+
const ancestors = getAncestors(snapshot, path);
|
|
225
|
+
for (const ancestor of ancestors) {
|
|
226
|
+
if (!isObjectNode({
|
|
227
|
+
schema: snapshot.context.schema
|
|
228
|
+
}, ancestor.node))
|
|
229
|
+
continue;
|
|
230
|
+
const resolved = resolveContainerAt(snapshot.context.containers, snapshot.context.value, ancestor.path);
|
|
231
|
+
return !resolved || !("field" in resolved) ? void 0 : {
|
|
232
|
+
parent: resolved,
|
|
233
|
+
parentPath: ancestor.path
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function getEnclosingContainer(snapshot, path) {
|
|
238
|
+
const descent = descendToParent(snapshot, path);
|
|
239
|
+
if (descent)
|
|
240
|
+
return {
|
|
241
|
+
of: descent.parent.field.of,
|
|
242
|
+
path: descent.parentPath
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function getPathSubSchema(snapshot, path) {
|
|
246
|
+
const enclosing = getEnclosingContainer(snapshot, path);
|
|
247
|
+
return enclosing ? getSubSchema(snapshot.context.schema, enclosing.of) : snapshot.context.schema;
|
|
248
|
+
}
|
|
249
|
+
export {
|
|
250
|
+
getBlock,
|
|
251
|
+
getEnclosingBlock,
|
|
252
|
+
getEnclosingContainer,
|
|
253
|
+
getNodes,
|
|
254
|
+
getParent,
|
|
255
|
+
getPathSubSchema,
|
|
256
|
+
getSibling,
|
|
257
|
+
hasNode,
|
|
258
|
+
isAncestorPath,
|
|
259
|
+
isBlock,
|
|
260
|
+
isInline,
|
|
261
|
+
isSpanNode,
|
|
262
|
+
isTextBlockNode,
|
|
263
|
+
parentPath,
|
|
264
|
+
resolveContainerAt
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=get-path-sub-schema.js.map
|