@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,1021 @@
|
|
|
1
|
+
import { resolveContainerAt, isInline, isSpanNode, getEnclosingBlock, hasNode, getBlock, getNodes, parentPath, getPathSubSchema, isTextBlockNode, getSibling } from "./get-path-sub-schema.js";
|
|
2
|
+
import { isKeyedSegment, getNode, isObjectNode, getNodeChildren, getChildren } from "./get-ancestor.js";
|
|
3
|
+
import { isEqualPaths, getSelectionStartPoint as getSelectionStartPoint$1, getSelectionEndPoint as getSelectionEndPoint$1, sliceBlocks, getBlockStartPoint, getBlockEndPoint, isEqualSelectionPoints, isSelectionCollapsed as isSelectionCollapsed$1, blockOffsetToSpanSelectionPoint, getAncestorTextBlock, spanSelectionPointToBlockOffset, isListBlock } from "./util.slice-blocks.js";
|
|
4
|
+
import { isSpan, isTextBlock } from "@portabletext/schema";
|
|
5
|
+
function comparePaths(path, another, root) {
|
|
6
|
+
const min = Math.min(path.length, another.length);
|
|
7
|
+
let currentChildren = root?.children, currentNode;
|
|
8
|
+
for (let i = 0; i < min; i++) {
|
|
9
|
+
const segment = path[i], otherSegment = another[i];
|
|
10
|
+
if (isKeyedSegment(segment) && isKeyedSegment(otherSegment)) {
|
|
11
|
+
if (segment._key === otherSegment._key) {
|
|
12
|
+
currentChildren && (currentNode = currentChildren.find((c) => c._key === segment._key), currentChildren = void 0);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (currentChildren) {
|
|
16
|
+
const segmentIndex = currentChildren.findIndex((c) => c._key === segment._key), otherSegmentIndex = currentChildren.findIndex((c) => c._key === otherSegment._key);
|
|
17
|
+
if (segmentIndex !== -1 && otherSegmentIndex !== -1)
|
|
18
|
+
return segmentIndex < otherSegmentIndex ? -1 : 1;
|
|
19
|
+
}
|
|
20
|
+
if (segment._key < otherSegment._key)
|
|
21
|
+
return -1;
|
|
22
|
+
if (segment._key > otherSegment._key)
|
|
23
|
+
return 1;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (typeof segment == "string" && typeof otherSegment == "string") {
|
|
27
|
+
if (segment === otherSegment) {
|
|
28
|
+
if (currentNode) {
|
|
29
|
+
const fieldValue = currentNode[segment];
|
|
30
|
+
currentChildren = Array.isArray(fieldValue) ? fieldValue : void 0, currentNode = void 0;
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (segment < otherSegment)
|
|
35
|
+
return -1;
|
|
36
|
+
if (segment > otherSegment)
|
|
37
|
+
return 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (typeof segment == "number" && typeof otherSegment == "number") {
|
|
41
|
+
if (segment < otherSegment)
|
|
42
|
+
return -1;
|
|
43
|
+
if (segment > otherSegment)
|
|
44
|
+
return 1;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
function comparePoints(point, another, root) {
|
|
52
|
+
const result = comparePaths(point.path, another.path, root);
|
|
53
|
+
return result === 0 ? point.offset < another.offset ? -1 : point.offset > another.offset ? 1 : 0 : result;
|
|
54
|
+
}
|
|
55
|
+
function isAfterPoint(point, another, root) {
|
|
56
|
+
return comparePoints(point, another, root) === 1;
|
|
57
|
+
}
|
|
58
|
+
function isBackwardRange(range, root) {
|
|
59
|
+
const {
|
|
60
|
+
anchor,
|
|
61
|
+
focus
|
|
62
|
+
} = range;
|
|
63
|
+
return isAfterPoint(anchor, focus, root);
|
|
64
|
+
}
|
|
65
|
+
function rangeEdges(range, root) {
|
|
66
|
+
const {
|
|
67
|
+
anchor,
|
|
68
|
+
focus
|
|
69
|
+
} = range;
|
|
70
|
+
return isBackwardRange(range, root) ? [focus, anchor] : [anchor, focus];
|
|
71
|
+
}
|
|
72
|
+
function isEditableContainer(snapshot, _node, path) {
|
|
73
|
+
if (snapshot.context.containers.size === 0)
|
|
74
|
+
return !1;
|
|
75
|
+
const resolved = resolveContainerAt(snapshot.context.containers, snapshot.context.value, path);
|
|
76
|
+
return !!(resolved && "field" in resolved);
|
|
77
|
+
}
|
|
78
|
+
function rangesOverlap(rangeA, rangeB, root) {
|
|
79
|
+
const [startA, endA] = rangeEdges(rangeA, root), [startB, endB] = rangeEdges(rangeB, root);
|
|
80
|
+
return comparePoints(startA, endB, root) <= 0 && comparePoints(startB, endA, root) <= 0;
|
|
81
|
+
}
|
|
82
|
+
const isSelectionCollapsed = (snapshot) => snapshot.context.selection ? isEqualPaths(snapshot.context.selection.anchor.path, snapshot.context.selection.focus.path) && snapshot.context.selection.anchor.offset === snapshot.context.selection.focus.offset : !1;
|
|
83
|
+
function getInline(snapshot, path) {
|
|
84
|
+
const entry = getNode(snapshot, path);
|
|
85
|
+
if (!(!entry || !isInline(snapshot, path)) && !(!isSpanNode({
|
|
86
|
+
schema: snapshot.context.schema
|
|
87
|
+
}, entry.node) && !isObjectNode({
|
|
88
|
+
schema: snapshot.context.schema
|
|
89
|
+
}, entry.node)))
|
|
90
|
+
return {
|
|
91
|
+
node: entry.node,
|
|
92
|
+
path: entry.path
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const getFocusChild = (snapshot) => {
|
|
96
|
+
const selection = snapshot.context.selection;
|
|
97
|
+
if (selection)
|
|
98
|
+
return getInline(snapshot, selection.focus.path);
|
|
99
|
+
}, getFocusInlineObject = (snapshot) => {
|
|
100
|
+
const focusChild = getFocusChild(snapshot);
|
|
101
|
+
return focusChild && !isSpanNode(snapshot.context, focusChild.node) ? {
|
|
102
|
+
node: focusChild.node,
|
|
103
|
+
path: focusChild.path
|
|
104
|
+
} : void 0;
|
|
105
|
+
}, getFocusSpan = (snapshot) => {
|
|
106
|
+
const focusChild = getFocusChild(snapshot);
|
|
107
|
+
return focusChild && isSpan(snapshot.context, focusChild.node) ? {
|
|
108
|
+
node: focusChild.node,
|
|
109
|
+
path: focusChild.path
|
|
110
|
+
} : void 0;
|
|
111
|
+
}, getFocusBlock = (snapshot) => {
|
|
112
|
+
const selection = snapshot.context.selection;
|
|
113
|
+
if (selection)
|
|
114
|
+
return getEnclosingBlock(snapshot, selection.focus.path);
|
|
115
|
+
}, getFocusTextBlock = (snapshot) => {
|
|
116
|
+
const focusBlock = getFocusBlock(snapshot);
|
|
117
|
+
return focusBlock && isTextBlock(snapshot.context, focusBlock.node) ? {
|
|
118
|
+
node: focusBlock.node,
|
|
119
|
+
path: focusBlock.path
|
|
120
|
+
} : void 0;
|
|
121
|
+
};
|
|
122
|
+
function getRootAcceptedTypes(schema) {
|
|
123
|
+
return /* @__PURE__ */ new Set([schema.block.name, ...schema.blockObjects.map((blockObject) => blockObject.name)]);
|
|
124
|
+
}
|
|
125
|
+
const getSelectedValue = (snapshot) => {
|
|
126
|
+
const selection = snapshot.context.selection;
|
|
127
|
+
if (!selection)
|
|
128
|
+
return [];
|
|
129
|
+
const startPoint = getSelectionStartPoint$1(selection), endPoint = getSelectionEndPoint$1(selection);
|
|
130
|
+
return !startPoint || !endPoint ? [] : sliceArray({
|
|
131
|
+
context: snapshot.context,
|
|
132
|
+
blocks: snapshot.context.value,
|
|
133
|
+
pathPrefix: [],
|
|
134
|
+
fieldNameInPrefix: void 0,
|
|
135
|
+
startEdge: startPoint,
|
|
136
|
+
endEdge: endPoint
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
function sliceArray({
|
|
140
|
+
context,
|
|
141
|
+
blocks,
|
|
142
|
+
pathPrefix,
|
|
143
|
+
fieldNameInPrefix,
|
|
144
|
+
startEdge,
|
|
145
|
+
endEdge,
|
|
146
|
+
parent
|
|
147
|
+
}) {
|
|
148
|
+
if (blocks.length === 0)
|
|
149
|
+
return [];
|
|
150
|
+
const startIdx = resolveIndex(blocks, pathPrefix, startEdge), endIdx = resolveIndex(blocks, pathPrefix, endEdge);
|
|
151
|
+
if (startIdx === -1 || endIdx === -1)
|
|
152
|
+
return [];
|
|
153
|
+
const [lo, hi, loEdge, hiEdge] = startIdx <= endIdx ? [startIdx, endIdx, startEdge, endEdge] : [endIdx, startIdx, endEdge, startEdge], result = [];
|
|
154
|
+
for (let i = lo; i <= hi; i++) {
|
|
155
|
+
const block = blocks[i], blockPath = [...pathPrefix, ...fieldNameInPrefix ? [fieldNameInPrefix] : [], {
|
|
156
|
+
_key: block._key
|
|
157
|
+
}], startPointForBlock = i === lo ? loEdge : "array-start", endPointForBlock = i === hi ? hiEdge : "array-end", startInside = edgeIsInside(startPointForBlock, blockPath), endInside = edgeIsInside(endPointForBlock, blockPath);
|
|
158
|
+
if (!startInside && !endInside) {
|
|
159
|
+
result.push(block);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (isTextBlock({
|
|
163
|
+
schema: context.schema
|
|
164
|
+
}, block)) {
|
|
165
|
+
const sliced = sliceBoundaryTextBlock({
|
|
166
|
+
context,
|
|
167
|
+
block,
|
|
168
|
+
blockPath,
|
|
169
|
+
startEdge: startPointForBlock,
|
|
170
|
+
endEdge: endPointForBlock
|
|
171
|
+
});
|
|
172
|
+
sliced && result.push(sliced);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const childInfo = getNodeChildren(context, block, parent);
|
|
176
|
+
if (!childInfo) {
|
|
177
|
+
result.push(block);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const innerSliced = sliceArray({
|
|
181
|
+
context,
|
|
182
|
+
blocks: childInfo.children,
|
|
183
|
+
pathPrefix: blockPath,
|
|
184
|
+
fieldNameInPrefix: childInfo.fieldName,
|
|
185
|
+
startEdge: startPointForBlock,
|
|
186
|
+
endEdge: endPointForBlock,
|
|
187
|
+
parent: childInfo.parent
|
|
188
|
+
}), updatedBlock = {
|
|
189
|
+
...block
|
|
190
|
+
};
|
|
191
|
+
updatedBlock[childInfo.fieldName] = innerSliced, result.push(updatedBlock);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
function resolveIndex(blocks, pathPrefix, edge) {
|
|
196
|
+
return edge === "array-start" ? 0 : edge === "array-end" ? blocks.length - 1 : findBlockIndexForPoint(blocks, pathPrefix, edge);
|
|
197
|
+
}
|
|
198
|
+
function findBlockIndexForPoint(blocks, pathPrefix, point) {
|
|
199
|
+
let nodeSegmentIndex = pathPrefix.length;
|
|
200
|
+
nodeSegmentIndex < point.path.length && typeof point.path[nodeSegmentIndex] == "string" && nodeSegmentIndex++;
|
|
201
|
+
const segment = point.path[nodeSegmentIndex];
|
|
202
|
+
return segment === void 0 ? -1 : isKeyedSegment(segment) ? blocks.findIndex((block) => block._key === segment._key) : typeof segment == "number" && segment >= 0 && segment < blocks.length ? segment : -1;
|
|
203
|
+
}
|
|
204
|
+
function edgeIsInside(edge, blockPath) {
|
|
205
|
+
return edge === "array-start" || edge === "array-end" ? !1 : edge.path.length > blockPath.length;
|
|
206
|
+
}
|
|
207
|
+
function sliceBoundaryTextBlock({
|
|
208
|
+
context,
|
|
209
|
+
block,
|
|
210
|
+
blockPath,
|
|
211
|
+
startEdge,
|
|
212
|
+
endEdge
|
|
213
|
+
}) {
|
|
214
|
+
if (!isTextBlock({
|
|
215
|
+
schema: context.schema
|
|
216
|
+
}, block))
|
|
217
|
+
return block;
|
|
218
|
+
const firstChild = block.children[0], lastChild = block.children[block.children.length - 1], blockRelativeStart = stripPrefix(startEdge, blockPath, block, {
|
|
219
|
+
fallback: "block-start",
|
|
220
|
+
firstChild
|
|
221
|
+
}), blockRelativeEnd = stripPrefix(endEdge, blockPath, block, {
|
|
222
|
+
fallback: "block-end",
|
|
223
|
+
lastChild,
|
|
224
|
+
context
|
|
225
|
+
});
|
|
226
|
+
return sliceBlocks({
|
|
227
|
+
context: {
|
|
228
|
+
...context,
|
|
229
|
+
selection: {
|
|
230
|
+
anchor: blockRelativeStart,
|
|
231
|
+
focus: blockRelativeEnd
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
blocks: [block]
|
|
235
|
+
})[0];
|
|
236
|
+
}
|
|
237
|
+
function stripPrefix(edge, blockPath, block, opts) {
|
|
238
|
+
return edge !== "array-start" && edge !== "array-end" && edge.path.length > blockPath.length ? {
|
|
239
|
+
path: edge.path.slice(blockPath.length - 1),
|
|
240
|
+
offset: edge.offset
|
|
241
|
+
} : opts.fallback === "block-start" ? {
|
|
242
|
+
path: [{
|
|
243
|
+
_key: block._key
|
|
244
|
+
}, "children", {
|
|
245
|
+
_key: opts.firstChild?._key ?? ""
|
|
246
|
+
}],
|
|
247
|
+
offset: 0
|
|
248
|
+
} : {
|
|
249
|
+
path: [{
|
|
250
|
+
_key: block._key
|
|
251
|
+
}, "children", {
|
|
252
|
+
_key: opts.lastChild?._key ?? ""
|
|
253
|
+
}],
|
|
254
|
+
offset: opts.lastChild && opts.context && isSpan({
|
|
255
|
+
schema: opts.context.schema
|
|
256
|
+
}, opts.lastChild) ? opts.lastChild.text.length : 0
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const getFragment = (snapshot) => {
|
|
260
|
+
const envelope = getSelectedValue(snapshot);
|
|
261
|
+
if (envelope.length === 0)
|
|
262
|
+
return [];
|
|
263
|
+
const {
|
|
264
|
+
schema,
|
|
265
|
+
containers,
|
|
266
|
+
value
|
|
267
|
+
} = snapshot.context, rootAcceptedTypes = getRootAcceptedTypes(schema), textBlockName = schema.block.name;
|
|
268
|
+
let lastRootValid = envelope, lastRootValidPrefix = [], current = envelope;
|
|
269
|
+
const pathPrefix = [];
|
|
270
|
+
for (; current.length === 1; ) {
|
|
271
|
+
const single = current[0], singlePath = [...pathPrefix, {
|
|
272
|
+
_key: single._key
|
|
273
|
+
}], container = resolveContainerAt(containers, value, singlePath);
|
|
274
|
+
if (!container || !("field" in container))
|
|
275
|
+
break;
|
|
276
|
+
const children = single[container.field.name];
|
|
277
|
+
if (!Array.isArray(children) || children.length === 0)
|
|
278
|
+
break;
|
|
279
|
+
const childBlocks = children;
|
|
280
|
+
if (pathPrefix.push({
|
|
281
|
+
_key: single._key
|
|
282
|
+
}, container.field.name), current = childBlocks, childBlocks.every((block) => block._type === textBlockName || rootAcceptedTypes.has(block._type))) {
|
|
283
|
+
lastRootValid = childBlocks, lastRootValidPrefix = [...pathPrefix];
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (childBlocks.length !== 1)
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
return lastRootValid.map((block) => ({
|
|
290
|
+
node: block,
|
|
291
|
+
path: [...lastRootValidPrefix, {
|
|
292
|
+
_key: block._key
|
|
293
|
+
}]
|
|
294
|
+
}));
|
|
295
|
+
}, getSelectionEndBlock = (snapshot) => {
|
|
296
|
+
const endPoint = getSelectionEndPoint$1(snapshot.context.selection);
|
|
297
|
+
if (endPoint)
|
|
298
|
+
return getFocusBlock({
|
|
299
|
+
...snapshot,
|
|
300
|
+
context: {
|
|
301
|
+
...snapshot.context,
|
|
302
|
+
selection: {
|
|
303
|
+
anchor: endPoint,
|
|
304
|
+
focus: endPoint
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}, getSelectionStartBlock = (snapshot) => {
|
|
309
|
+
const startPoint = getSelectionStartPoint$1(snapshot.context.selection);
|
|
310
|
+
if (startPoint)
|
|
311
|
+
return getFocusBlock({
|
|
312
|
+
...snapshot,
|
|
313
|
+
context: {
|
|
314
|
+
...snapshot.context,
|
|
315
|
+
selection: {
|
|
316
|
+
anchor: startPoint,
|
|
317
|
+
focus: startPoint
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
function isOverlappingSelection(selection) {
|
|
323
|
+
return (snapshot) => {
|
|
324
|
+
const editorSelection = snapshot.context.selection;
|
|
325
|
+
return !selection || !editorSelection || !hasNode(snapshot, selection.anchor.path) || !hasNode(snapshot, selection.focus.path) || !hasNode(snapshot, editorSelection.anchor.path) || !hasNode(snapshot, editorSelection.focus.path) ? !1 : rangesOverlap(selection, editorSelection, {
|
|
326
|
+
children: snapshot.context.value
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
const isSelectionExpanded$1 = (snapshot) => snapshot.context.selection !== null && !isSelectionCollapsed(snapshot), getSelectedBlocks = (snapshot) => {
|
|
331
|
+
const selection = snapshot.context.selection;
|
|
332
|
+
if (!selection)
|
|
333
|
+
return [];
|
|
334
|
+
const startPoint = getSelectionStartPoint$1(selection), endPoint = getSelectionEndPoint$1(selection);
|
|
335
|
+
if (!startPoint || !endPoint)
|
|
336
|
+
return [];
|
|
337
|
+
const startRootKey = startPoint.path.find(isKeyedSegment)?._key, endRootKey = endPoint.path.find(isKeyedSegment)?._key;
|
|
338
|
+
if (startRootKey && startRootKey === endRootKey) {
|
|
339
|
+
const block = getBlock(snapshot, [{
|
|
340
|
+
_key: startRootKey
|
|
341
|
+
}]);
|
|
342
|
+
if (block)
|
|
343
|
+
return [{
|
|
344
|
+
node: block.node,
|
|
345
|
+
path: block.path
|
|
346
|
+
}];
|
|
347
|
+
}
|
|
348
|
+
const result = [];
|
|
349
|
+
for (const entry of getNodes(snapshot, {
|
|
350
|
+
from: startPoint.path,
|
|
351
|
+
to: endPoint.path,
|
|
352
|
+
match: (_, path) => path.length === 1
|
|
353
|
+
})) {
|
|
354
|
+
const block = getBlock(snapshot, entry.path);
|
|
355
|
+
block && result.push({
|
|
356
|
+
node: block.node,
|
|
357
|
+
path: block.path
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
return result;
|
|
361
|
+
}, isSelectingEntireBlocks = (snapshot) => {
|
|
362
|
+
if (!snapshot.context.selection)
|
|
363
|
+
return !1;
|
|
364
|
+
const startPoint = snapshot.context.selection.backward ? snapshot.context.selection.focus : snapshot.context.selection.anchor, endPoint = snapshot.context.selection.backward ? snapshot.context.selection.anchor : snapshot.context.selection.focus, startBlock = getSelectionStartBlock(snapshot), endBlock = getSelectionEndBlock(snapshot);
|
|
365
|
+
if (!startBlock || !endBlock)
|
|
366
|
+
return !1;
|
|
367
|
+
const startBlockStartPoint = getBlockStartPoint({
|
|
368
|
+
context: snapshot.context,
|
|
369
|
+
block: startBlock
|
|
370
|
+
}), endBlockEndPoint = getBlockEndPoint({
|
|
371
|
+
context: snapshot.context,
|
|
372
|
+
block: endBlock
|
|
373
|
+
});
|
|
374
|
+
return isEqualSelectionPoints(startBlockStartPoint, startPoint) && isEqualSelectionPoints(endBlockEndPoint, endPoint);
|
|
375
|
+
};
|
|
376
|
+
function isBlockPath(path) {
|
|
377
|
+
const firstSegment = path.at(0);
|
|
378
|
+
return path.length === 1 && firstSegment !== void 0 && isRecord(firstSegment) && "_key" in firstSegment && typeof firstSegment._key == "string";
|
|
379
|
+
}
|
|
380
|
+
function isRecord(value) {
|
|
381
|
+
return !!value && (typeof value == "object" || typeof value == "function");
|
|
382
|
+
}
|
|
383
|
+
function isSelectionExpanded(selection) {
|
|
384
|
+
return selection ? !isSelectionCollapsed$1(selection) : !1;
|
|
385
|
+
}
|
|
386
|
+
function findSibling(snapshot, path, direction, match) {
|
|
387
|
+
if (path.length === 0)
|
|
388
|
+
return;
|
|
389
|
+
const lastSegment = path.at(-1);
|
|
390
|
+
if (!isKeyedSegment(lastSegment))
|
|
391
|
+
return;
|
|
392
|
+
const parent = parentPath(path), children = getChildren(snapshot, parent), currentIndex = children.findIndex((child) => child.node._key === lastSegment._key);
|
|
393
|
+
return currentIndex === -1 ? void 0 : (direction === "next" ? children.slice(currentIndex + 1) : children.slice(0, currentIndex).reverse()).find(match);
|
|
394
|
+
}
|
|
395
|
+
const getSelectionEndPoint = (snapshot) => {
|
|
396
|
+
if (snapshot.context.selection)
|
|
397
|
+
return snapshot.context.selection.backward ? snapshot.context.selection.anchor : snapshot.context.selection.focus;
|
|
398
|
+
}, getNextSpan = (snapshot) => {
|
|
399
|
+
const point = getSelectionEndPoint(snapshot);
|
|
400
|
+
if (point)
|
|
401
|
+
return findSibling(snapshot, point.path, "next", (entry) => isSpan(snapshot.context, entry.node));
|
|
402
|
+
}, getSelectionStartPoint = (snapshot) => {
|
|
403
|
+
if (snapshot.context.selection)
|
|
404
|
+
return snapshot.context.selection.backward ? snapshot.context.selection.focus : snapshot.context.selection.anchor;
|
|
405
|
+
}, getPreviousSpan = (snapshot) => {
|
|
406
|
+
const point = getSelectionStartPoint(snapshot);
|
|
407
|
+
if (point)
|
|
408
|
+
return findSibling(snapshot, point.path, "previous", (entry) => isSpan(snapshot.context, entry.node));
|
|
409
|
+
};
|
|
410
|
+
function getSelectedChildren(options) {
|
|
411
|
+
const filter = options?.filter;
|
|
412
|
+
return (snapshot) => {
|
|
413
|
+
const startPoint = getSelectionStartPoint$1(snapshot.context.selection), endPoint = getSelectionEndPoint$1(snapshot.context.selection);
|
|
414
|
+
if (!startPoint || !endPoint)
|
|
415
|
+
return [];
|
|
416
|
+
const startChildKey = startPoint.path.findLast(isKeyedSegment)?._key, endChildKey = endPoint.path.findLast(isKeyedSegment)?._key, result = [];
|
|
417
|
+
if (startChildKey && startChildKey === endChildKey && isInline(snapshot, startPoint.path)) {
|
|
418
|
+
const node = getNode(snapshot, startPoint.path);
|
|
419
|
+
if (node) {
|
|
420
|
+
const child = node.node;
|
|
421
|
+
let skip = !1;
|
|
422
|
+
child._key === startChildKey && isSpan(snapshot.context, child) && (startPoint.offset >= child.text.length && (skip = !0), endPoint.offset <= 0 && (skip = !0)), !skip && (!filter || filter(child)) && result.push({
|
|
423
|
+
node: child,
|
|
424
|
+
path: node.path
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
for (const entry of getNodes(snapshot, {
|
|
430
|
+
from: startPoint.path,
|
|
431
|
+
to: endPoint.path,
|
|
432
|
+
match: (_, path) => isInline(snapshot, path)
|
|
433
|
+
})) {
|
|
434
|
+
const child = entry.node;
|
|
435
|
+
child._key === startChildKey && isSpan(snapshot.context, child) && startPoint.offset >= child.text.length || child._key === endChildKey && isSpan(snapshot.context, child) && endPoint.offset <= 0 || filter && !filter(child) || result.push({
|
|
436
|
+
node: child,
|
|
437
|
+
path: entry.path
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
return result;
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
const getSelectedSpans = (snapshot) => snapshot.context.selection ? getSelectedChildren({
|
|
444
|
+
filter: (child) => isSpan(snapshot.context, child)
|
|
445
|
+
})(snapshot) : [], getMarkState = (snapshot) => {
|
|
446
|
+
if (!snapshot.context.selection)
|
|
447
|
+
return;
|
|
448
|
+
let selection = snapshot.context.selection;
|
|
449
|
+
if (isBlockPath(selection.anchor.path)) {
|
|
450
|
+
const spanSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
451
|
+
snapshot,
|
|
452
|
+
blockOffset: {
|
|
453
|
+
path: selection.anchor.path,
|
|
454
|
+
offset: selection.anchor.offset
|
|
455
|
+
},
|
|
456
|
+
direction: selection.backward ? "backward" : "forward"
|
|
457
|
+
});
|
|
458
|
+
selection = spanSelectionPoint ? {
|
|
459
|
+
...selection,
|
|
460
|
+
anchor: spanSelectionPoint
|
|
461
|
+
} : selection;
|
|
462
|
+
}
|
|
463
|
+
if (isBlockPath(selection.focus.path)) {
|
|
464
|
+
const spanSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
465
|
+
snapshot,
|
|
466
|
+
blockOffset: {
|
|
467
|
+
path: selection.focus.path,
|
|
468
|
+
offset: selection.focus.offset
|
|
469
|
+
},
|
|
470
|
+
direction: selection.backward ? "backward" : "forward"
|
|
471
|
+
});
|
|
472
|
+
selection = spanSelectionPoint ? {
|
|
473
|
+
...selection,
|
|
474
|
+
focus: spanSelectionPoint
|
|
475
|
+
} : selection;
|
|
476
|
+
}
|
|
477
|
+
const focusSpan = getFocusSpan({
|
|
478
|
+
...snapshot,
|
|
479
|
+
context: {
|
|
480
|
+
...snapshot.context,
|
|
481
|
+
selection
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
if (!focusSpan)
|
|
485
|
+
return;
|
|
486
|
+
if (isSelectionExpanded(selection)) {
|
|
487
|
+
const spanInfo = getSelectedSpans({
|
|
488
|
+
...snapshot,
|
|
489
|
+
context: {
|
|
490
|
+
...snapshot.context,
|
|
491
|
+
selection
|
|
492
|
+
}
|
|
493
|
+
}).map((span) => {
|
|
494
|
+
const block = getAncestorTextBlock(snapshot, span.path);
|
|
495
|
+
return {
|
|
496
|
+
marks: span.node.marks ?? [],
|
|
497
|
+
decoratorNames: getPathSubSchema(snapshot, span.path).decorators.map((decorator) => decorator.name),
|
|
498
|
+
markDefKeys: (block?.node.markDefs ?? []).map((markDef) => markDef._key)
|
|
499
|
+
};
|
|
500
|
+
}), candidateMarks = /* @__PURE__ */ new Set();
|
|
501
|
+
for (const {
|
|
502
|
+
marks: spanMarks
|
|
503
|
+
} of spanInfo)
|
|
504
|
+
for (const mark of spanMarks)
|
|
505
|
+
candidateMarks.add(mark);
|
|
506
|
+
const marks2 = [];
|
|
507
|
+
for (const candidate of candidateMarks) {
|
|
508
|
+
const isDecoratorSomewhere = spanInfo.some(({
|
|
509
|
+
decoratorNames
|
|
510
|
+
}) => decoratorNames.includes(candidate));
|
|
511
|
+
let active = !0;
|
|
512
|
+
for (const {
|
|
513
|
+
marks: spanMarks,
|
|
514
|
+
decoratorNames,
|
|
515
|
+
markDefKeys
|
|
516
|
+
} of spanInfo)
|
|
517
|
+
if ((isDecoratorSomewhere ? decoratorNames.includes(candidate) : markDefKeys.includes(candidate)) && !spanMarks.includes(candidate)) {
|
|
518
|
+
active = !1;
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
active && marks2.push(candidate);
|
|
522
|
+
}
|
|
523
|
+
return {
|
|
524
|
+
state: "unchanged",
|
|
525
|
+
marks: marks2
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
const decorators = getPathSubSchema(snapshot, focusSpan.path).decorators.map((decorator) => decorator.name), marks = focusSpan.node.marks ?? [], marksWithoutAnnotations = marks.filter((mark) => decorators.includes(mark)), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = focusSpan.node.text.length === 0, atTheBeginningOfSpan = snapshot.context.selection.anchor.offset === 0, atTheEndOfSpan = snapshot.context.selection.anchor.offset === focusSpan.node.text.length, previousSpan = getPreviousSpan({
|
|
529
|
+
context: {
|
|
530
|
+
...snapshot.context,
|
|
531
|
+
selection
|
|
532
|
+
}
|
|
533
|
+
}), nextSpan = getNextSpan({
|
|
534
|
+
context: {
|
|
535
|
+
...snapshot.context,
|
|
536
|
+
selection
|
|
537
|
+
}
|
|
538
|
+
}), nextSpanAnnotations = nextSpan?.node?.marks?.filter((mark) => !decorators.includes(mark)) ?? [], spanAnnotations = marks.filter((mark) => !decorators.includes(mark)), previousSpanHasAnnotations = previousSpan ? previousSpan.node.marks?.some((mark) => !decorators.includes(mark)) : !1, previousSpanHasSameAnnotations = previousSpan ? previousSpan.node.marks?.filter((mark) => !decorators.includes(mark)).every((mark) => marks.includes(mark)) : !1, previousSpanHasSameAnnotation = previousSpan ? previousSpan.node.marks?.some((mark) => !decorators.includes(mark) && marks.includes(mark)) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.node.marks?.every((mark) => marks.includes(mark)) : !1, nextSpanSharesSomeAnnotations = spanAnnotations.some((mark) => nextSpanAnnotations?.includes(mark));
|
|
539
|
+
if (spanHasAnnotations && !spanIsEmpty) {
|
|
540
|
+
if (atTheBeginningOfSpan) {
|
|
541
|
+
if (previousSpanHasSameMarks)
|
|
542
|
+
return {
|
|
543
|
+
state: "changed",
|
|
544
|
+
previousMarks: marks,
|
|
545
|
+
marks: previousSpan?.node.marks ?? []
|
|
546
|
+
};
|
|
547
|
+
if (previousSpanHasSameAnnotations)
|
|
548
|
+
return {
|
|
549
|
+
state: "changed",
|
|
550
|
+
previousMarks: marks,
|
|
551
|
+
marks: previousSpan?.node.marks ?? []
|
|
552
|
+
};
|
|
553
|
+
if (previousSpanHasSameAnnotation)
|
|
554
|
+
return {
|
|
555
|
+
state: "unchanged",
|
|
556
|
+
marks: focusSpan.node.marks ?? []
|
|
557
|
+
};
|
|
558
|
+
if (!previousSpan)
|
|
559
|
+
return {
|
|
560
|
+
state: "changed",
|
|
561
|
+
previousMarks: marks,
|
|
562
|
+
marks: []
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
if (atTheEndOfSpan) {
|
|
566
|
+
if (!nextSpan)
|
|
567
|
+
return {
|
|
568
|
+
state: "changed",
|
|
569
|
+
previousMarks: marks,
|
|
570
|
+
marks: []
|
|
571
|
+
};
|
|
572
|
+
if (nextSpanAnnotations.length > 0 && !nextSpanSharesSomeAnnotations)
|
|
573
|
+
return {
|
|
574
|
+
state: "changed",
|
|
575
|
+
previousMarks: marks,
|
|
576
|
+
marks: []
|
|
577
|
+
};
|
|
578
|
+
if (nextSpanSharesSomeAnnotations && nextSpanAnnotations.length < spanAnnotations.length || !nextSpanSharesSomeAnnotations)
|
|
579
|
+
return {
|
|
580
|
+
state: "changed",
|
|
581
|
+
previousMarks: marks,
|
|
582
|
+
marks: nextSpan?.node.marks ?? []
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return atTheBeginningOfSpan && !spanIsEmpty && previousSpan ? previousSpanHasAnnotations ? {
|
|
587
|
+
state: "changed",
|
|
588
|
+
marks,
|
|
589
|
+
previousMarks: previousSpan?.node.marks ?? []
|
|
590
|
+
} : {
|
|
591
|
+
state: "changed",
|
|
592
|
+
previousMarks: marks,
|
|
593
|
+
marks: (previousSpan?.node.marks ?? []).filter((mark) => decorators.includes(mark))
|
|
594
|
+
} : {
|
|
595
|
+
state: "unchanged",
|
|
596
|
+
marks
|
|
597
|
+
};
|
|
598
|
+
};
|
|
599
|
+
function getActiveAnnotationsMarks(snapshot) {
|
|
600
|
+
const schema = snapshot.context.schema;
|
|
601
|
+
return (getMarkState(snapshot)?.marks ?? []).filter((mark) => !schema.decorators.map((decorator) => decorator.name).includes(mark));
|
|
602
|
+
}
|
|
603
|
+
const getSelectedTextBlocks = (snapshot) => {
|
|
604
|
+
const selection = snapshot.context.selection;
|
|
605
|
+
if (!selection)
|
|
606
|
+
return [];
|
|
607
|
+
const startPoint = getSelectionStartPoint$1(selection), endPoint = getSelectionEndPoint$1(selection);
|
|
608
|
+
if (!startPoint || !endPoint)
|
|
609
|
+
return [];
|
|
610
|
+
const startBlock = getEnclosingBlock(snapshot, startPoint.path), endBlock = getEnclosingBlock(snapshot, endPoint.path);
|
|
611
|
+
if (startBlock && endBlock && startBlock.node._key === endBlock.node._key && isTextBlock(snapshot.context, startBlock.node))
|
|
612
|
+
return [{
|
|
613
|
+
node: startBlock.node,
|
|
614
|
+
path: startBlock.path
|
|
615
|
+
}];
|
|
616
|
+
const result = [];
|
|
617
|
+
for (const entry of getNodes(snapshot, {
|
|
618
|
+
from: startPoint.path,
|
|
619
|
+
to: endPoint.path,
|
|
620
|
+
match: (node) => isTextBlock(snapshot.context, node)
|
|
621
|
+
}))
|
|
622
|
+
isTextBlock(snapshot.context, entry.node) && result.push({
|
|
623
|
+
node: entry.node,
|
|
624
|
+
path: entry.path
|
|
625
|
+
});
|
|
626
|
+
return result;
|
|
627
|
+
};
|
|
628
|
+
function getActiveDecorators(snapshot) {
|
|
629
|
+
const decoratorState = snapshot.decoratorState, markState = getMarkState(snapshot), selectedBlocks = getSelectedTextBlocks(snapshot), decorators = /* @__PURE__ */ new Set();
|
|
630
|
+
for (const block of selectedBlocks)
|
|
631
|
+
for (const decorator of getPathSubSchema(snapshot, block.path).decorators)
|
|
632
|
+
decorators.add(decorator.name);
|
|
633
|
+
if (decorators.size === 0)
|
|
634
|
+
for (const decorator of snapshot.context.schema.decorators)
|
|
635
|
+
decorators.add(decorator.name);
|
|
636
|
+
let activeDecorators = (markState?.marks ?? []).filter((mark) => decorators.has(mark));
|
|
637
|
+
for (const decorator in decoratorState)
|
|
638
|
+
decoratorState[decorator] === !1 ? activeDecorators = activeDecorators.filter((activeDecorator) => activeDecorator !== decorator) : decoratorState[decorator] === !0 && (activeDecorators.includes(decorator) || activeDecorators.push(decorator));
|
|
639
|
+
return activeDecorators;
|
|
640
|
+
}
|
|
641
|
+
function isActiveAnnotation(annotation, options) {
|
|
642
|
+
return (snapshot) => {
|
|
643
|
+
if ((options?.mode ?? "full") === "partial")
|
|
644
|
+
return getSelectedValue(snapshot).flatMap((block) => isTextBlock(snapshot.context, block) ? block.markDefs ?? [] : []).some((markDef) => markDef._type === annotation);
|
|
645
|
+
const selectionMarkDefs = getSelectedTextBlocks(snapshot).flatMap((block) => block.node.markDefs ?? []), activeAnnotations = getActiveAnnotationsMarks(snapshot);
|
|
646
|
+
return selectionMarkDefs.filter((markDef) => markDef._type === annotation && activeAnnotations.includes(markDef._key)).length > 0;
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
const getApplicableSchema = (snapshot) => {
|
|
650
|
+
if (!snapshot.context.selection)
|
|
651
|
+
return EMPTY;
|
|
652
|
+
const focusBlock = getFocusBlock(snapshot), focusSub = focusBlock ? getPathSubSchema(snapshot, focusBlock.path) : void 0, insertion = focusSub ? {
|
|
653
|
+
blockObjects: namesOfArray(focusSub.blockObjects),
|
|
654
|
+
inlineObjects: namesOfArray(focusSub.inlineObjects)
|
|
655
|
+
} : {
|
|
656
|
+
blockObjects: EMPTY_SET,
|
|
657
|
+
inlineObjects: EMPTY_SET
|
|
658
|
+
}, textBlocks = getSelectedTextBlocks(snapshot);
|
|
659
|
+
if (textBlocks.length === 0)
|
|
660
|
+
return {
|
|
661
|
+
decorators: EMPTY_SET,
|
|
662
|
+
annotations: EMPTY_SET,
|
|
663
|
+
lists: EMPTY_SET,
|
|
664
|
+
styles: EMPTY_SET,
|
|
665
|
+
...insertion
|
|
666
|
+
};
|
|
667
|
+
let textApplicable = textCategoryNames(getPathSubSchema(snapshot, textBlocks[0].path));
|
|
668
|
+
for (let i = 1; i < textBlocks.length; i++)
|
|
669
|
+
textApplicable = unionTextCategories(textApplicable, textCategoryNames(getPathSubSchema(snapshot, textBlocks[i].path)));
|
|
670
|
+
return {
|
|
671
|
+
...textApplicable,
|
|
672
|
+
...insertion
|
|
673
|
+
};
|
|
674
|
+
};
|
|
675
|
+
function compareApplicableSchema(a, b) {
|
|
676
|
+
return a === b ? !0 : sameSet(a.decorators, b.decorators) && sameSet(a.annotations, b.annotations) && sameSet(a.lists, b.lists) && sameSet(a.styles, b.styles) && sameSet(a.blockObjects, b.blockObjects) && sameSet(a.inlineObjects, b.inlineObjects);
|
|
677
|
+
}
|
|
678
|
+
const EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set()), EMPTY = Object.freeze({
|
|
679
|
+
decorators: EMPTY_SET,
|
|
680
|
+
annotations: EMPTY_SET,
|
|
681
|
+
lists: EMPTY_SET,
|
|
682
|
+
styles: EMPTY_SET,
|
|
683
|
+
blockObjects: EMPTY_SET,
|
|
684
|
+
inlineObjects: EMPTY_SET
|
|
685
|
+
});
|
|
686
|
+
function textCategoryNames(schema) {
|
|
687
|
+
return {
|
|
688
|
+
decorators: namesOfArray(schema.decorators),
|
|
689
|
+
annotations: namesOfArray(schema.annotations),
|
|
690
|
+
lists: namesOfArray(schema.lists),
|
|
691
|
+
styles: namesOfArray(schema.styles)
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function unionTextCategories(a, b) {
|
|
695
|
+
return {
|
|
696
|
+
decorators: unionSet(a.decorators, b.decorators),
|
|
697
|
+
annotations: unionSet(a.annotations, b.annotations),
|
|
698
|
+
lists: unionSet(a.lists, b.lists),
|
|
699
|
+
styles: unionSet(a.styles, b.styles)
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
function namesOfArray(entries) {
|
|
703
|
+
return new Set(entries.map((entry) => entry.name));
|
|
704
|
+
}
|
|
705
|
+
function unionSet(a, b) {
|
|
706
|
+
const result = new Set(a);
|
|
707
|
+
for (const item of b)
|
|
708
|
+
result.add(item);
|
|
709
|
+
return result;
|
|
710
|
+
}
|
|
711
|
+
function sameSet(a, b) {
|
|
712
|
+
if (a === b)
|
|
713
|
+
return !0;
|
|
714
|
+
if (a.size !== b.size)
|
|
715
|
+
return !1;
|
|
716
|
+
for (const item of a)
|
|
717
|
+
if (!b.has(item))
|
|
718
|
+
return !1;
|
|
719
|
+
return !0;
|
|
720
|
+
}
|
|
721
|
+
const getActiveAnnotations = (snapshot) => {
|
|
722
|
+
if (!snapshot.context.selection)
|
|
723
|
+
return [];
|
|
724
|
+
const selectedBlocks = getSelectedTextBlocks(snapshot), markState = getMarkState(snapshot), decoratorNames = /* @__PURE__ */ new Set();
|
|
725
|
+
for (const block of selectedBlocks)
|
|
726
|
+
for (const decorator of getPathSubSchema(snapshot, block.path).decorators)
|
|
727
|
+
decoratorNames.add(decorator.name);
|
|
728
|
+
if (decoratorNames.size === 0)
|
|
729
|
+
for (const decorator of snapshot.context.schema.decorators)
|
|
730
|
+
decoratorNames.add(decorator.name);
|
|
731
|
+
const activeAnnotations = (markState?.marks ?? []).filter((mark) => !decoratorNames.has(mark));
|
|
732
|
+
return selectedBlocks.flatMap((block) => block.node.markDefs ?? []).filter((markDef) => activeAnnotations.includes(markDef._key));
|
|
733
|
+
}, getActiveListItem = (snapshot) => {
|
|
734
|
+
if (!snapshot.context.selection)
|
|
735
|
+
return;
|
|
736
|
+
const selectedTextBlocks = getSelectedTextBlocks(snapshot), firstTextBlock = selectedTextBlocks.at(0);
|
|
737
|
+
if (!firstTextBlock)
|
|
738
|
+
return;
|
|
739
|
+
const firstListItem = firstTextBlock.node.listItem;
|
|
740
|
+
if (firstListItem && selectedTextBlocks.filter((block) => getPathSubSchema(snapshot, block.path).lists.some((l) => l.name === firstListItem)).every((block) => block.node.listItem === firstListItem))
|
|
741
|
+
return firstListItem;
|
|
742
|
+
}, getActiveStyle = (snapshot) => {
|
|
743
|
+
if (!snapshot.context.selection)
|
|
744
|
+
return;
|
|
745
|
+
const selectedTextBlocks = getSelectedTextBlocks(snapshot), firstTextBlock = selectedTextBlocks.at(0);
|
|
746
|
+
if (!firstTextBlock)
|
|
747
|
+
return;
|
|
748
|
+
const firstStyle = firstTextBlock.node.style;
|
|
749
|
+
if (firstStyle && selectedTextBlocks.filter((block) => getPathSubSchema(snapshot, block.path).styles.some((s) => s.name === firstStyle)).every((block) => block.node.style === firstStyle))
|
|
750
|
+
return firstStyle;
|
|
751
|
+
}, getNextInlineObject = (snapshot) => {
|
|
752
|
+
const point = getSelectionEndPoint(snapshot);
|
|
753
|
+
return point ? findSibling(snapshot, point.path, "next", (entry) => isObjectNode({
|
|
754
|
+
schema: snapshot.context.schema
|
|
755
|
+
}, entry.node)) : void 0;
|
|
756
|
+
}, getPreviousInlineObject = (snapshot) => {
|
|
757
|
+
const point = getSelectionStartPoint(snapshot);
|
|
758
|
+
return point ? findSibling(snapshot, point.path, "previous", (entry) => isObjectNode({
|
|
759
|
+
schema: snapshot.context.schema
|
|
760
|
+
}, entry.node)) : void 0;
|
|
761
|
+
}, getSelectionText = (snapshot) => {
|
|
762
|
+
const selectedValue = getSelectedValue(snapshot);
|
|
763
|
+
return collectText(snapshot.context, selectedValue);
|
|
764
|
+
};
|
|
765
|
+
function collectText(context, blocks, parent) {
|
|
766
|
+
let text = "";
|
|
767
|
+
for (const block of blocks) {
|
|
768
|
+
if (isTextBlock(context, block)) {
|
|
769
|
+
for (const child of block.children)
|
|
770
|
+
isSpan(context, child) && (text += child.text);
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
const childInfo = getNodeChildren(context, block, parent);
|
|
774
|
+
childInfo && (text += collectText(context, childInfo.children, childInfo.parent));
|
|
775
|
+
}
|
|
776
|
+
return text;
|
|
777
|
+
}
|
|
778
|
+
const getCaretWordSelection = (snapshot) => {
|
|
779
|
+
if (!snapshot.context.selection || !isSelectionCollapsed(snapshot))
|
|
780
|
+
return null;
|
|
781
|
+
const focusTextBlock = getFocusTextBlock(snapshot), selectionStartPoint = getSelectionStartPoint(snapshot), selectionStartOffset = selectionStartPoint ? spanSelectionPointToBlockOffset({
|
|
782
|
+
snapshot,
|
|
783
|
+
selectionPoint: selectionStartPoint
|
|
784
|
+
}) : void 0;
|
|
785
|
+
if (!focusTextBlock || !selectionStartPoint || !selectionStartOffset)
|
|
786
|
+
return null;
|
|
787
|
+
const previousInlineObject = getPreviousInlineObject(snapshot), blockStartPoint = getBlockStartPoint({
|
|
788
|
+
context: snapshot.context,
|
|
789
|
+
block: focusTextBlock
|
|
790
|
+
}), textDirectlyBefore = getSelectionText({
|
|
791
|
+
context: {
|
|
792
|
+
...snapshot.context,
|
|
793
|
+
selection: {
|
|
794
|
+
anchor: previousInlineObject ? {
|
|
795
|
+
path: previousInlineObject.path,
|
|
796
|
+
offset: 0
|
|
797
|
+
} : blockStartPoint,
|
|
798
|
+
focus: selectionStartPoint
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}).split(/\s+/).at(-1), nextInlineObject = getNextInlineObject(snapshot), blockEndPoint = getBlockEndPoint({
|
|
802
|
+
context: snapshot.context,
|
|
803
|
+
block: focusTextBlock
|
|
804
|
+
}), textDirectlyAfter = getSelectionText({
|
|
805
|
+
context: {
|
|
806
|
+
...snapshot.context,
|
|
807
|
+
selection: {
|
|
808
|
+
anchor: selectionStartPoint,
|
|
809
|
+
focus: nextInlineObject ? {
|
|
810
|
+
path: nextInlineObject.path,
|
|
811
|
+
offset: 0
|
|
812
|
+
} : blockEndPoint
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}).split(/\s+/).at(0);
|
|
816
|
+
if ((textDirectlyBefore === void 0 || textDirectlyBefore === "") && (textDirectlyAfter === void 0 || textDirectlyAfter === ""))
|
|
817
|
+
return null;
|
|
818
|
+
const caretWordStartOffset = textDirectlyBefore ? {
|
|
819
|
+
...selectionStartOffset,
|
|
820
|
+
offset: selectionStartOffset.offset - textDirectlyBefore.length
|
|
821
|
+
} : selectionStartOffset, caretWordEndOffset = textDirectlyAfter ? {
|
|
822
|
+
...selectionStartOffset,
|
|
823
|
+
offset: selectionStartOffset.offset + textDirectlyAfter.length
|
|
824
|
+
} : selectionStartOffset, caretWordStartSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
825
|
+
snapshot,
|
|
826
|
+
blockOffset: caretWordStartOffset,
|
|
827
|
+
direction: "backward"
|
|
828
|
+
}), caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
829
|
+
snapshot,
|
|
830
|
+
blockOffset: caretWordEndOffset,
|
|
831
|
+
direction: "forward"
|
|
832
|
+
});
|
|
833
|
+
if (!caretWordStartSelectionPoint || !caretWordEndSelectionPoint)
|
|
834
|
+
return null;
|
|
835
|
+
const caretWordSelection = {
|
|
836
|
+
anchor: caretWordStartSelectionPoint,
|
|
837
|
+
focus: caretWordEndSelectionPoint
|
|
838
|
+
};
|
|
839
|
+
return isSelectionExpanded$1({
|
|
840
|
+
context: {
|
|
841
|
+
...snapshot.context,
|
|
842
|
+
selection: caretWordSelection
|
|
843
|
+
}
|
|
844
|
+
}) ? caretWordSelection : null;
|
|
845
|
+
}, getFirstBlock = (snapshot) => {
|
|
846
|
+
const focusBlock = getFocusBlock(snapshot);
|
|
847
|
+
if (focusBlock) {
|
|
848
|
+
const first = getChildren(snapshot, parentPath(focusBlock.path)).at(0);
|
|
849
|
+
if (first)
|
|
850
|
+
return getBlock(snapshot, first.path);
|
|
851
|
+
}
|
|
852
|
+
const node = snapshot.context.value[0];
|
|
853
|
+
return node ? {
|
|
854
|
+
node,
|
|
855
|
+
path: [{
|
|
856
|
+
_key: node._key
|
|
857
|
+
}]
|
|
858
|
+
} : void 0;
|
|
859
|
+
}, getFocusBlockObject = (snapshot) => {
|
|
860
|
+
const focusBlock = getFocusBlock(snapshot);
|
|
861
|
+
if (focusBlock && !isTextBlockNode(snapshot.context, focusBlock.node) && !isEditableContainer(snapshot, focusBlock.node, focusBlock.path))
|
|
862
|
+
return {
|
|
863
|
+
node: focusBlock.node,
|
|
864
|
+
path: focusBlock.path
|
|
865
|
+
};
|
|
866
|
+
}, getFocusListBlock = (snapshot) => {
|
|
867
|
+
const focusTextBlock = getFocusTextBlock(snapshot);
|
|
868
|
+
return focusTextBlock && isListBlock(snapshot.context, focusTextBlock.node) ? {
|
|
869
|
+
node: focusTextBlock.node,
|
|
870
|
+
path: focusTextBlock.path
|
|
871
|
+
} : void 0;
|
|
872
|
+
}, getLastBlock = (snapshot) => {
|
|
873
|
+
const focusBlock = getFocusBlock(snapshot);
|
|
874
|
+
if (focusBlock) {
|
|
875
|
+
const last = getChildren(snapshot, parentPath(focusBlock.path)).at(-1);
|
|
876
|
+
if (last)
|
|
877
|
+
return getBlock(snapshot, last.path);
|
|
878
|
+
}
|
|
879
|
+
const node = snapshot.context.value.at(-1);
|
|
880
|
+
return node ? {
|
|
881
|
+
node,
|
|
882
|
+
path: [{
|
|
883
|
+
_key: node._key
|
|
884
|
+
}]
|
|
885
|
+
} : void 0;
|
|
886
|
+
}, getNextBlock = (snapshot) => {
|
|
887
|
+
const selectionEndBlock = getSelectionEndBlock(snapshot);
|
|
888
|
+
if (!selectionEndBlock)
|
|
889
|
+
return;
|
|
890
|
+
const next = getSibling(snapshot, selectionEndBlock.path, "next");
|
|
891
|
+
if (next)
|
|
892
|
+
return getBlock(snapshot, next.path);
|
|
893
|
+
}, getPreviousBlock = (snapshot) => {
|
|
894
|
+
const selectionStartBlock = getSelectionStartBlock(snapshot);
|
|
895
|
+
if (!selectionStartBlock)
|
|
896
|
+
return;
|
|
897
|
+
const previous = getSibling(snapshot, selectionStartBlock.path, "previous");
|
|
898
|
+
if (previous)
|
|
899
|
+
return getBlock(snapshot, previous.path);
|
|
900
|
+
}, getSelectionEndChild = (snapshot) => {
|
|
901
|
+
const endPoint = getSelectionEndPoint$1(snapshot.context.selection);
|
|
902
|
+
if (endPoint)
|
|
903
|
+
return getFocusChild({
|
|
904
|
+
...snapshot,
|
|
905
|
+
context: {
|
|
906
|
+
...snapshot.context,
|
|
907
|
+
selection: {
|
|
908
|
+
anchor: endPoint,
|
|
909
|
+
focus: endPoint
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
}, getSelectionStartChild = (snapshot) => {
|
|
914
|
+
const startPoint = getSelectionStartPoint$1(snapshot.context.selection);
|
|
915
|
+
if (startPoint)
|
|
916
|
+
return getFocusChild({
|
|
917
|
+
...snapshot,
|
|
918
|
+
context: {
|
|
919
|
+
...snapshot.context,
|
|
920
|
+
selection: {
|
|
921
|
+
anchor: startPoint,
|
|
922
|
+
focus: startPoint
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
};
|
|
927
|
+
function isActiveDecorator(decorator) {
|
|
928
|
+
return (snapshot) => {
|
|
929
|
+
if (isSelectionExpanded$1(snapshot)) {
|
|
930
|
+
const inScopeSpans = getSelectedSpans(snapshot).filter((span) => getPathSubSchema(snapshot, span.path).decorators.some((d) => d.name === decorator));
|
|
931
|
+
return inScopeSpans.length > 0 && inScopeSpans.every((span) => span.node.marks?.includes(decorator));
|
|
932
|
+
}
|
|
933
|
+
return getActiveDecorators(snapshot).includes(decorator);
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function isActiveListItem(listItem) {
|
|
937
|
+
return (snapshot) => getActiveListItem(snapshot) === listItem;
|
|
938
|
+
}
|
|
939
|
+
function isActiveStyle(style) {
|
|
940
|
+
return (snapshot) => getActiveStyle(snapshot) === style;
|
|
941
|
+
}
|
|
942
|
+
function isAtTheEndOfBlock(block) {
|
|
943
|
+
return (snapshot) => {
|
|
944
|
+
if (!snapshot.context.selection || !isSelectionCollapsed(snapshot))
|
|
945
|
+
return !1;
|
|
946
|
+
const blockEndPoint = getBlockEndPoint({
|
|
947
|
+
context: snapshot.context,
|
|
948
|
+
block
|
|
949
|
+
});
|
|
950
|
+
return isEqualSelectionPoints(snapshot.context.selection.focus, blockEndPoint);
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
function isAtTheStartOfBlock(block) {
|
|
954
|
+
return (snapshot) => {
|
|
955
|
+
if (!snapshot.context.selection || !isSelectionCollapsed(snapshot))
|
|
956
|
+
return !1;
|
|
957
|
+
const blockStartPoint = getBlockStartPoint({
|
|
958
|
+
context: snapshot.context,
|
|
959
|
+
block
|
|
960
|
+
});
|
|
961
|
+
return isEqualSelectionPoints(snapshot.context.selection.focus, blockStartPoint);
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
export {
|
|
965
|
+
compareApplicableSchema,
|
|
966
|
+
comparePaths,
|
|
967
|
+
comparePoints,
|
|
968
|
+
getActiveAnnotations,
|
|
969
|
+
getActiveAnnotationsMarks,
|
|
970
|
+
getActiveDecorators,
|
|
971
|
+
getActiveListItem,
|
|
972
|
+
getActiveStyle,
|
|
973
|
+
getApplicableSchema,
|
|
974
|
+
getCaretWordSelection,
|
|
975
|
+
getFirstBlock,
|
|
976
|
+
getFocusBlock,
|
|
977
|
+
getFocusBlockObject,
|
|
978
|
+
getFocusChild,
|
|
979
|
+
getFocusInlineObject,
|
|
980
|
+
getFocusListBlock,
|
|
981
|
+
getFocusSpan,
|
|
982
|
+
getFocusTextBlock,
|
|
983
|
+
getFragment,
|
|
984
|
+
getInline,
|
|
985
|
+
getLastBlock,
|
|
986
|
+
getMarkState,
|
|
987
|
+
getNextBlock,
|
|
988
|
+
getNextInlineObject,
|
|
989
|
+
getNextSpan,
|
|
990
|
+
getPreviousBlock,
|
|
991
|
+
getPreviousInlineObject,
|
|
992
|
+
getPreviousSpan,
|
|
993
|
+
getRootAcceptedTypes,
|
|
994
|
+
getSelectedBlocks,
|
|
995
|
+
getSelectedSpans,
|
|
996
|
+
getSelectedTextBlocks,
|
|
997
|
+
getSelectedValue,
|
|
998
|
+
getSelectionEndBlock,
|
|
999
|
+
getSelectionEndChild,
|
|
1000
|
+
getSelectionEndPoint,
|
|
1001
|
+
getSelectionStartBlock,
|
|
1002
|
+
getSelectionStartChild,
|
|
1003
|
+
getSelectionStartPoint,
|
|
1004
|
+
getSelectionText,
|
|
1005
|
+
isActiveAnnotation,
|
|
1006
|
+
isActiveDecorator,
|
|
1007
|
+
isActiveListItem,
|
|
1008
|
+
isActiveStyle,
|
|
1009
|
+
isAfterPoint,
|
|
1010
|
+
isAtTheEndOfBlock,
|
|
1011
|
+
isAtTheStartOfBlock,
|
|
1012
|
+
isBackwardRange,
|
|
1013
|
+
isEditableContainer,
|
|
1014
|
+
isOverlappingSelection,
|
|
1015
|
+
isSelectingEntireBlocks,
|
|
1016
|
+
isSelectionCollapsed,
|
|
1017
|
+
isSelectionExpanded$1 as isSelectionExpanded,
|
|
1018
|
+
rangeEdges,
|
|
1019
|
+
rangesOverlap
|
|
1020
|
+
};
|
|
1021
|
+
//# sourceMappingURL=selector.is-at-the-start-of-block.js.map
|