@cgi-learning-hub/ui 1.14.0-dev.1785493355 → 1.14.0-dev.1785507581
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/dist/tiptap/index.cjs.js +21 -3910
- package/dist/tiptap/index.es.js +2 -3891
- package/package.json +1 -1
package/dist/tiptap/index.cjs.js
CHANGED
|
@@ -4,7 +4,9 @@ let react = require("react");
|
|
|
4
4
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
5
|
let _mui_material_styles = require("@mui/material/styles");
|
|
6
6
|
let _mui_material_utils = require("@mui/material/utils");
|
|
7
|
+
let _tiptap_pm_state = require("@tiptap/pm/state");
|
|
7
8
|
let _tiptap_react = require("@tiptap/react");
|
|
9
|
+
require("@tiptap/pm/tables");
|
|
8
10
|
let _mui_material_ToggleButton = require("@mui/material/ToggleButton");
|
|
9
11
|
let _mui_material_Tooltip = require("@mui/material/Tooltip");
|
|
10
12
|
let _mui_material_Badge = require("@mui/material/Badge");
|
|
@@ -17,3038 +19,6 @@ let _mui_material_Stack = require("@mui/material/Stack");
|
|
|
17
19
|
let _mui_material_InputBase = require("@mui/material/InputBase");
|
|
18
20
|
let _mui_material_Divider = require("@mui/material/Divider");
|
|
19
21
|
let _mui_material_Popover = require("@mui/material/Popover");
|
|
20
|
-
//#region ../../node_modules/.pnpm/prosemirror-model@1.25.11/node_modules/prosemirror-model/dist/index.js
|
|
21
|
-
function findDiffStart(a, b, pos) {
|
|
22
|
-
for (let i = 0;; i++) {
|
|
23
|
-
if (i == a.childCount || i == b.childCount) return a.childCount == b.childCount ? null : pos;
|
|
24
|
-
let childA = a.child(i), childB = b.child(i);
|
|
25
|
-
if (childA == childB) {
|
|
26
|
-
pos += childA.nodeSize;
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (!childA.sameMarkup(childB)) return pos;
|
|
30
|
-
if (childA.isText && childA.text != childB.text) {
|
|
31
|
-
let tA = childA.text, tB = childB.text, j = 0;
|
|
32
|
-
for (; tA[j] == tB[j]; j++) pos++;
|
|
33
|
-
if (j && j < tA.length && j < tB.length && surrogateHigh(tA.charCodeAt(j - 1)) && surrogateLow(tA.charCodeAt(j))) pos--;
|
|
34
|
-
return pos;
|
|
35
|
-
}
|
|
36
|
-
if (childA.content.size || childB.content.size) {
|
|
37
|
-
let inner = findDiffStart(childA.content, childB.content, pos + 1);
|
|
38
|
-
if (inner != null) return inner;
|
|
39
|
-
}
|
|
40
|
-
pos += childA.nodeSize;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function findDiffEnd(a, b, posA, posB) {
|
|
44
|
-
for (let iA = a.childCount, iB = b.childCount;;) {
|
|
45
|
-
if (iA == 0 || iB == 0) return iA == iB ? null : {
|
|
46
|
-
a: posA,
|
|
47
|
-
b: posB
|
|
48
|
-
};
|
|
49
|
-
let childA = a.child(--iA), childB = b.child(--iB), size = childA.nodeSize;
|
|
50
|
-
if (childA == childB) {
|
|
51
|
-
posA -= size;
|
|
52
|
-
posB -= size;
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (!childA.sameMarkup(childB)) return {
|
|
56
|
-
a: posA,
|
|
57
|
-
b: posB
|
|
58
|
-
};
|
|
59
|
-
if (childA.isText && childA.text != childB.text) {
|
|
60
|
-
let tA = childA.text, tB = childB.text, iA = tA.length, iB = tB.length;
|
|
61
|
-
while (iA > 0 && iB > 0 && tA[iA - 1] == tB[iB - 1]) {
|
|
62
|
-
iA--;
|
|
63
|
-
iB--;
|
|
64
|
-
posA--;
|
|
65
|
-
posB--;
|
|
66
|
-
}
|
|
67
|
-
if (iA && iB && iA < tA.length && surrogateHigh(tA.charCodeAt(iA - 1)) && surrogateLow(tA.charCodeAt(iA))) {
|
|
68
|
-
posA++;
|
|
69
|
-
posB++;
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
a: posA,
|
|
73
|
-
b: posB
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
if (childA.content.size || childB.content.size) {
|
|
77
|
-
let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1);
|
|
78
|
-
if (inner) return inner;
|
|
79
|
-
}
|
|
80
|
-
posA -= size;
|
|
81
|
-
posB -= size;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function surrogateLow(ch) {
|
|
85
|
-
return ch >= 56320 && ch < 57344;
|
|
86
|
-
}
|
|
87
|
-
function surrogateHigh(ch) {
|
|
88
|
-
return ch >= 55296 && ch < 56320;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
A fragment represents a node's collection of child nodes.
|
|
92
|
-
|
|
93
|
-
Like nodes, fragments are persistent data structures, and you
|
|
94
|
-
should not mutate them or their content. Rather, you create new
|
|
95
|
-
instances whenever needed. The API tries to make this easy.
|
|
96
|
-
*/
|
|
97
|
-
var Fragment$1 = class Fragment$1 {
|
|
98
|
-
/**
|
|
99
|
-
@internal
|
|
100
|
-
*/
|
|
101
|
-
constructor(content, size) {
|
|
102
|
-
this.content = content;
|
|
103
|
-
this.size = size || 0;
|
|
104
|
-
if (size == null) for (let i = 0; i < content.length; i++) this.size += content[i].nodeSize;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
Invoke a callback for all descendant nodes between the given two
|
|
108
|
-
positions (relative to start of this fragment). Doesn't descend
|
|
109
|
-
into a node when the callback returns `false`.
|
|
110
|
-
*/
|
|
111
|
-
nodesBetween(from, to, f, nodeStart = 0, parent) {
|
|
112
|
-
for (let i = 0, pos = 0; pos < to; i++) {
|
|
113
|
-
let child = this.content[i], end = pos + child.nodeSize;
|
|
114
|
-
if (end > from && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) {
|
|
115
|
-
let start = pos + 1;
|
|
116
|
-
child.nodesBetween(Math.max(0, from - start), Math.min(child.content.size, to - start), f, nodeStart + start);
|
|
117
|
-
}
|
|
118
|
-
pos = end;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
Call the given callback for every descendant node. `pos` will be
|
|
123
|
-
relative to the start of the fragment. The callback may return
|
|
124
|
-
`false` to prevent traversal of a given node's children.
|
|
125
|
-
*/
|
|
126
|
-
descendants(f) {
|
|
127
|
-
this.nodesBetween(0, this.size, f);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
Extract the text between `from` and `to`. See the same method on
|
|
131
|
-
[`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween).
|
|
132
|
-
*/
|
|
133
|
-
textBetween(from, to, blockSeparator, leafText) {
|
|
134
|
-
let text = "", first = true;
|
|
135
|
-
this.nodesBetween(from, to, (node, pos) => {
|
|
136
|
-
let nodeText = node.isText ? node.text.slice(Math.max(from, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : "";
|
|
137
|
-
if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) if (first) first = false;
|
|
138
|
-
else text += blockSeparator;
|
|
139
|
-
text += nodeText;
|
|
140
|
-
}, 0);
|
|
141
|
-
return text;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
Create a new fragment containing the combined content of this
|
|
145
|
-
fragment and the other.
|
|
146
|
-
*/
|
|
147
|
-
append(other) {
|
|
148
|
-
if (!other.size) return this;
|
|
149
|
-
if (!this.size) return other;
|
|
150
|
-
let last = this.lastChild, first = other.firstChild, content = this.content.slice(), i = 0;
|
|
151
|
-
if (last.isText && last.sameMarkup(first)) {
|
|
152
|
-
content[content.length - 1] = last.withText(last.text + first.text);
|
|
153
|
-
i = 1;
|
|
154
|
-
}
|
|
155
|
-
for (; i < other.content.length; i++) content.push(other.content[i]);
|
|
156
|
-
return new Fragment$1(content, this.size + other.size);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
Cut out the sub-fragment between the two given positions.
|
|
160
|
-
*/
|
|
161
|
-
cut(from, to = this.size) {
|
|
162
|
-
if (from == 0 && to == this.size) return this;
|
|
163
|
-
let result = [], size = 0;
|
|
164
|
-
if (to > from) for (let i = 0, pos = 0; pos < to; i++) {
|
|
165
|
-
let child = this.content[i], end = pos + child.nodeSize;
|
|
166
|
-
if (end > from) {
|
|
167
|
-
if (pos < from || end > to) if (child.isText) child = child.cut(Math.max(0, from - pos), Math.min(child.text.length, to - pos));
|
|
168
|
-
else child = child.cut(Math.max(0, from - pos - 1), Math.min(child.content.size, to - pos - 1));
|
|
169
|
-
result.push(child);
|
|
170
|
-
size += child.nodeSize;
|
|
171
|
-
}
|
|
172
|
-
pos = end;
|
|
173
|
-
}
|
|
174
|
-
return new Fragment$1(result, size);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
@internal
|
|
178
|
-
*/
|
|
179
|
-
cutByIndex(from, to) {
|
|
180
|
-
if (from == to) return Fragment$1.empty;
|
|
181
|
-
if (from == 0 && to == this.content.length) return this;
|
|
182
|
-
return new Fragment$1(this.content.slice(from, to));
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
Create a new fragment in which the node at the given index is
|
|
186
|
-
replaced by the given node.
|
|
187
|
-
*/
|
|
188
|
-
replaceChild(index, node) {
|
|
189
|
-
let current = this.content[index];
|
|
190
|
-
if (current == node) return this;
|
|
191
|
-
let copy = this.content.slice();
|
|
192
|
-
let size = this.size + node.nodeSize - current.nodeSize;
|
|
193
|
-
copy[index] = node;
|
|
194
|
-
return new Fragment$1(copy, size);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
Create a new fragment by prepending the given node to this
|
|
198
|
-
fragment.
|
|
199
|
-
*/
|
|
200
|
-
addToStart(node) {
|
|
201
|
-
return new Fragment$1([node].concat(this.content), this.size + node.nodeSize);
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
Create a new fragment by appending the given node to this
|
|
205
|
-
fragment.
|
|
206
|
-
*/
|
|
207
|
-
addToEnd(node) {
|
|
208
|
-
return new Fragment$1(this.content.concat(node), this.size + node.nodeSize);
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
Compare this fragment to another one.
|
|
212
|
-
*/
|
|
213
|
-
eq(other) {
|
|
214
|
-
if (this.content.length != other.content.length) return false;
|
|
215
|
-
for (let i = 0; i < this.content.length; i++) if (!this.content[i].eq(other.content[i])) return false;
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
The first child of the fragment, or `null` if it is empty.
|
|
220
|
-
*/
|
|
221
|
-
get firstChild() {
|
|
222
|
-
return this.content.length ? this.content[0] : null;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
The last child of the fragment, or `null` if it is empty.
|
|
226
|
-
*/
|
|
227
|
-
get lastChild() {
|
|
228
|
-
return this.content.length ? this.content[this.content.length - 1] : null;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
The number of child nodes in this fragment.
|
|
232
|
-
*/
|
|
233
|
-
get childCount() {
|
|
234
|
-
return this.content.length;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
Get the child node at the given index. Raise an error when the
|
|
238
|
-
index is out of range.
|
|
239
|
-
*/
|
|
240
|
-
child(index) {
|
|
241
|
-
let found = this.content[index];
|
|
242
|
-
if (!found) throw new RangeError("Index " + index + " out of range for " + this);
|
|
243
|
-
return found;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
Get the child node at the given index, if it exists.
|
|
247
|
-
*/
|
|
248
|
-
maybeChild(index) {
|
|
249
|
-
return this.content[index] || null;
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
Call `f` for every child node, passing the node, its offset
|
|
253
|
-
into this parent node, and its index.
|
|
254
|
-
*/
|
|
255
|
-
forEach(f) {
|
|
256
|
-
for (let i = 0, p = 0; i < this.content.length; i++) {
|
|
257
|
-
let child = this.content[i];
|
|
258
|
-
f(child, p, i);
|
|
259
|
-
p += child.nodeSize;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
Find the first position at which this fragment and another
|
|
264
|
-
fragment differ, or `null` if they are the same.
|
|
265
|
-
*/
|
|
266
|
-
findDiffStart(other, pos = 0) {
|
|
267
|
-
return findDiffStart(this, other, pos);
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
Find the first position, searching from the end, at which this
|
|
271
|
-
fragment and the given fragment differ, or `null` if they are
|
|
272
|
-
the same. Since this position will not be the same in both
|
|
273
|
-
nodes, an object with two separate positions is returned.
|
|
274
|
-
*/
|
|
275
|
-
findDiffEnd(other, pos = this.size, otherPos = other.size) {
|
|
276
|
-
return findDiffEnd(this, other, pos, otherPos);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
Find the index and inner offset corresponding to a given relative
|
|
280
|
-
position in this fragment. The result object will be reused
|
|
281
|
-
(overwritten) the next time the function is called. @internal
|
|
282
|
-
*/
|
|
283
|
-
findIndex(pos) {
|
|
284
|
-
if (pos == 0) return retIndex(0, pos);
|
|
285
|
-
if (pos == this.size) return retIndex(this.content.length, pos);
|
|
286
|
-
if (pos > this.size || pos < 0) throw new RangeError(`Position ${pos} outside of fragment (${this})`);
|
|
287
|
-
for (let i = 0, curPos = 0;; i++) {
|
|
288
|
-
let cur = this.child(i), end = curPos + cur.nodeSize;
|
|
289
|
-
if (end >= pos) {
|
|
290
|
-
if (end == pos) return retIndex(i + 1, end);
|
|
291
|
-
return retIndex(i, curPos);
|
|
292
|
-
}
|
|
293
|
-
curPos = end;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
Return a debugging string that describes this fragment.
|
|
298
|
-
*/
|
|
299
|
-
toString() {
|
|
300
|
-
return "<" + this.toStringInner() + ">";
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
@internal
|
|
304
|
-
*/
|
|
305
|
-
toStringInner() {
|
|
306
|
-
return this.content.join(", ");
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
Create a JSON-serializeable representation of this fragment.
|
|
310
|
-
*/
|
|
311
|
-
toJSON() {
|
|
312
|
-
return this.content.length ? this.content.map((n) => n.toJSON()) : null;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
Deserialize a fragment from its JSON representation.
|
|
316
|
-
*/
|
|
317
|
-
static fromJSON(schema, value) {
|
|
318
|
-
if (!value) return Fragment$1.empty;
|
|
319
|
-
if (!Array.isArray(value)) throw new RangeError("Invalid input for Fragment.fromJSON");
|
|
320
|
-
return Fragment$1.fromArray(value.map(schema.nodeFromJSON));
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
Build a fragment from an array of nodes. Ensures that adjacent
|
|
324
|
-
text nodes with the same marks are joined together.
|
|
325
|
-
*/
|
|
326
|
-
static fromArray(array) {
|
|
327
|
-
if (!array.length) return Fragment$1.empty;
|
|
328
|
-
let joined, size = 0;
|
|
329
|
-
for (let i = 0; i < array.length; i++) {
|
|
330
|
-
let node = array[i];
|
|
331
|
-
size += node.nodeSize;
|
|
332
|
-
if (i && node.isText && array[i - 1].sameMarkup(node)) {
|
|
333
|
-
if (!joined) joined = array.slice(0, i);
|
|
334
|
-
joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text);
|
|
335
|
-
} else if (joined) joined.push(node);
|
|
336
|
-
}
|
|
337
|
-
return new Fragment$1(joined || array, size);
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
Create a fragment from something that can be interpreted as a
|
|
341
|
-
set of nodes. For `null`, it returns the empty fragment. For a
|
|
342
|
-
fragment, the fragment itself. For a node or array of nodes, a
|
|
343
|
-
fragment containing those nodes.
|
|
344
|
-
*/
|
|
345
|
-
static from(nodes) {
|
|
346
|
-
if (!nodes) return Fragment$1.empty;
|
|
347
|
-
if (nodes instanceof Fragment$1) return nodes;
|
|
348
|
-
if (Array.isArray(nodes)) return this.fromArray(nodes);
|
|
349
|
-
if (nodes.attrs) return new Fragment$1([nodes], nodes.nodeSize);
|
|
350
|
-
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
/**
|
|
354
|
-
An empty fragment. Intended to be reused whenever a node doesn't
|
|
355
|
-
contain anything (rather than allocating a new empty fragment for
|
|
356
|
-
each leaf node).
|
|
357
|
-
*/
|
|
358
|
-
Fragment$1.empty = new Fragment$1([], 0);
|
|
359
|
-
var found = {
|
|
360
|
-
index: 0,
|
|
361
|
-
offset: 0
|
|
362
|
-
};
|
|
363
|
-
function retIndex(index, offset) {
|
|
364
|
-
found.index = index;
|
|
365
|
-
found.offset = offset;
|
|
366
|
-
return found;
|
|
367
|
-
}
|
|
368
|
-
function compareDeep(a, b) {
|
|
369
|
-
if (a === b) return true;
|
|
370
|
-
if (!(a && typeof a == "object") || !(b && typeof b == "object")) return false;
|
|
371
|
-
let array = Array.isArray(a);
|
|
372
|
-
if (Array.isArray(b) != array) return false;
|
|
373
|
-
if (array) {
|
|
374
|
-
if (a.length != b.length) return false;
|
|
375
|
-
for (let i = 0; i < a.length; i++) if (!compareDeep(a[i], b[i])) return false;
|
|
376
|
-
} else {
|
|
377
|
-
for (let p in a) if (!(p in b) || !compareDeep(a[p], b[p])) return false;
|
|
378
|
-
for (let p in b) if (!(p in a)) return false;
|
|
379
|
-
}
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
A mark is a piece of information that can be attached to a node,
|
|
384
|
-
such as it being emphasized, in code font, or a link. It has a
|
|
385
|
-
type and optionally a set of attributes that provide further
|
|
386
|
-
information (such as the target of the link). Marks are created
|
|
387
|
-
through a `Schema`, which controls which types exist and which
|
|
388
|
-
attributes they have.
|
|
389
|
-
*/
|
|
390
|
-
var Mark = class Mark {
|
|
391
|
-
/**
|
|
392
|
-
@internal
|
|
393
|
-
*/
|
|
394
|
-
constructor(type, attrs) {
|
|
395
|
-
this.type = type;
|
|
396
|
-
this.attrs = attrs;
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
Given a set of marks, create a new set which contains this one as
|
|
400
|
-
well, in the right position. If this mark is already in the set,
|
|
401
|
-
the set itself is returned. If any marks that are set to be
|
|
402
|
-
[exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present,
|
|
403
|
-
those are replaced by this one.
|
|
404
|
-
*/
|
|
405
|
-
addToSet(set) {
|
|
406
|
-
let copy, placed = false;
|
|
407
|
-
for (let i = 0; i < set.length; i++) {
|
|
408
|
-
let other = set[i];
|
|
409
|
-
if (this.eq(other)) return set;
|
|
410
|
-
if (this.type.excludes(other.type)) {
|
|
411
|
-
if (!copy) copy = set.slice(0, i);
|
|
412
|
-
} else if (other.type.excludes(this.type)) return set;
|
|
413
|
-
else {
|
|
414
|
-
if (!placed && other.type.rank > this.type.rank) {
|
|
415
|
-
if (!copy) copy = set.slice(0, i);
|
|
416
|
-
copy.push(this);
|
|
417
|
-
placed = true;
|
|
418
|
-
}
|
|
419
|
-
if (copy) copy.push(other);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
if (!copy) copy = set.slice();
|
|
423
|
-
if (!placed) copy.push(this);
|
|
424
|
-
return copy;
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
Remove this mark from the given set, returning a new set. If this
|
|
428
|
-
mark is not in the set, the set itself is returned.
|
|
429
|
-
*/
|
|
430
|
-
removeFromSet(set) {
|
|
431
|
-
for (let i = 0; i < set.length; i++) if (this.eq(set[i])) return set.slice(0, i).concat(set.slice(i + 1));
|
|
432
|
-
return set;
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
Test whether this mark is in the given set of marks.
|
|
436
|
-
*/
|
|
437
|
-
isInSet(set) {
|
|
438
|
-
for (let i = 0; i < set.length; i++) if (this.eq(set[i])) return true;
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
Test whether this mark has the same type and attributes as
|
|
443
|
-
another mark.
|
|
444
|
-
*/
|
|
445
|
-
eq(other) {
|
|
446
|
-
return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs);
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
Convert this mark to a JSON-serializeable representation.
|
|
450
|
-
*/
|
|
451
|
-
toJSON() {
|
|
452
|
-
let obj = { type: this.type.name };
|
|
453
|
-
for (let _ in this.attrs) {
|
|
454
|
-
obj.attrs = this.attrs;
|
|
455
|
-
break;
|
|
456
|
-
}
|
|
457
|
-
return obj;
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
Deserialize a mark from JSON.
|
|
461
|
-
*/
|
|
462
|
-
static fromJSON(schema, json) {
|
|
463
|
-
if (!json) throw new RangeError("Invalid input for Mark.fromJSON");
|
|
464
|
-
let type = schema.marks[json.type];
|
|
465
|
-
if (!type) throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
466
|
-
let mark = type.create(json.attrs);
|
|
467
|
-
type.checkAttrs(mark.attrs);
|
|
468
|
-
return mark;
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
Test whether two sets of marks are identical.
|
|
472
|
-
*/
|
|
473
|
-
static sameSet(a, b) {
|
|
474
|
-
if (a == b) return true;
|
|
475
|
-
if (a.length != b.length) return false;
|
|
476
|
-
for (let i = 0; i < a.length; i++) if (!a[i].eq(b[i])) return false;
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
Create a properly sorted mark set from null, a single mark, or an
|
|
481
|
-
unsorted array of marks.
|
|
482
|
-
*/
|
|
483
|
-
static setFrom(marks) {
|
|
484
|
-
if (!marks || Array.isArray(marks) && marks.length == 0) return Mark.none;
|
|
485
|
-
if (marks instanceof Mark) return [marks];
|
|
486
|
-
let copy = marks.slice();
|
|
487
|
-
copy.sort((a, b) => a.type.rank - b.type.rank);
|
|
488
|
-
return copy;
|
|
489
|
-
}
|
|
490
|
-
};
|
|
491
|
-
/**
|
|
492
|
-
The empty set of marks.
|
|
493
|
-
*/
|
|
494
|
-
Mark.none = [];
|
|
495
|
-
/**
|
|
496
|
-
Error type raised by [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) when
|
|
497
|
-
given an invalid replacement.
|
|
498
|
-
*/
|
|
499
|
-
var ReplaceError = class extends Error {};
|
|
500
|
-
/**
|
|
501
|
-
A slice represents a piece cut out of a larger document. It
|
|
502
|
-
stores not only a fragment, but also the depth up to which nodes on
|
|
503
|
-
both side are ‘open’ (cut through).
|
|
504
|
-
*/
|
|
505
|
-
var Slice = class Slice {
|
|
506
|
-
/**
|
|
507
|
-
Create a slice. When specifying a non-zero open depth, you must
|
|
508
|
-
make sure that there are nodes of at least that depth at the
|
|
509
|
-
appropriate side of the fragment—i.e. if the fragment is an
|
|
510
|
-
empty paragraph node, `openStart` and `openEnd` can't be greater
|
|
511
|
-
than 1.
|
|
512
|
-
|
|
513
|
-
It is not necessary for the content of open nodes to conform to
|
|
514
|
-
the schema's content constraints, though it should be a valid
|
|
515
|
-
start/end/middle for such a node, depending on which sides are
|
|
516
|
-
open.
|
|
517
|
-
*/
|
|
518
|
-
constructor(content, openStart, openEnd) {
|
|
519
|
-
this.content = content;
|
|
520
|
-
this.openStart = openStart;
|
|
521
|
-
this.openEnd = openEnd;
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
The size this slice would add when inserted into a document.
|
|
525
|
-
*/
|
|
526
|
-
get size() {
|
|
527
|
-
return this.content.size - this.openStart - this.openEnd;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
@internal
|
|
531
|
-
*/
|
|
532
|
-
insertAt(pos, fragment) {
|
|
533
|
-
let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
|
|
534
|
-
return content && new Slice(content, this.openStart, this.openEnd);
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
@internal
|
|
538
|
-
*/
|
|
539
|
-
removeBetween(from, to) {
|
|
540
|
-
return new Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
Tests whether this slice is equal to another slice.
|
|
544
|
-
*/
|
|
545
|
-
eq(other) {
|
|
546
|
-
return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
@internal
|
|
550
|
-
*/
|
|
551
|
-
toString() {
|
|
552
|
-
return this.content + "(" + this.openStart + "," + this.openEnd + ")";
|
|
553
|
-
}
|
|
554
|
-
/**
|
|
555
|
-
Convert a slice to a JSON-serializable representation.
|
|
556
|
-
*/
|
|
557
|
-
toJSON() {
|
|
558
|
-
if (!this.content.size) return null;
|
|
559
|
-
let json = { content: this.content.toJSON() };
|
|
560
|
-
if (this.openStart > 0) json.openStart = this.openStart;
|
|
561
|
-
if (this.openEnd > 0) json.openEnd = this.openEnd;
|
|
562
|
-
return json;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
Deserialize a slice from its JSON representation.
|
|
566
|
-
*/
|
|
567
|
-
static fromJSON(schema, json) {
|
|
568
|
-
if (!json) return Slice.empty;
|
|
569
|
-
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
570
|
-
if (typeof openStart != "number" || typeof openEnd != "number") throw new RangeError("Invalid input for Slice.fromJSON");
|
|
571
|
-
return new Slice(Fragment$1.fromJSON(schema, json.content), openStart, openEnd);
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
Create a slice from a fragment by taking the maximum possible
|
|
575
|
-
open value on both side of the fragment.
|
|
576
|
-
*/
|
|
577
|
-
static maxOpen(fragment, openIsolating = true) {
|
|
578
|
-
let openStart = 0, openEnd = 0;
|
|
579
|
-
for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild) openStart++;
|
|
580
|
-
for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild) openEnd++;
|
|
581
|
-
return new Slice(fragment, openStart, openEnd);
|
|
582
|
-
}
|
|
583
|
-
};
|
|
584
|
-
/**
|
|
585
|
-
The empty slice.
|
|
586
|
-
*/
|
|
587
|
-
Slice.empty = new Slice(Fragment$1.empty, 0, 0);
|
|
588
|
-
function removeRange(content, from, to) {
|
|
589
|
-
let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
|
|
590
|
-
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
591
|
-
if (offset == from || child.isText) {
|
|
592
|
-
if (offsetTo != to && !content.child(indexTo).isText) throw new RangeError("Removing non-flat range");
|
|
593
|
-
return content.cut(0, from).append(content.cut(to));
|
|
594
|
-
}
|
|
595
|
-
if (index != indexTo) throw new RangeError("Removing non-flat range");
|
|
596
|
-
return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
|
|
597
|
-
}
|
|
598
|
-
function insertInto(content, dist, insert, openStart, openEnd, parent) {
|
|
599
|
-
let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
|
|
600
|
-
if (offset == dist || child.isText) {
|
|
601
|
-
if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert)) return null;
|
|
602
|
-
return content.cut(0, dist).append(insert).append(content.cut(dist));
|
|
603
|
-
}
|
|
604
|
-
let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
|
|
605
|
-
return inner && content.replaceChild(index, child.copy(inner));
|
|
606
|
-
}
|
|
607
|
-
function replace($from, $to, slice) {
|
|
608
|
-
if (slice.openStart > $from.depth) throw new ReplaceError("Inserted content deeper than insertion position");
|
|
609
|
-
if ($from.depth - slice.openStart != $to.depth - slice.openEnd) throw new ReplaceError("Inconsistent open depths");
|
|
610
|
-
return replaceOuter($from, $to, slice, 0);
|
|
611
|
-
}
|
|
612
|
-
function replaceOuter($from, $to, slice, depth) {
|
|
613
|
-
let index = $from.index(depth), node = $from.node(depth);
|
|
614
|
-
if (index == $to.index(depth) && depth < $from.depth - slice.openStart) {
|
|
615
|
-
let inner = replaceOuter($from, $to, slice, depth + 1);
|
|
616
|
-
return node.copy(node.content.replaceChild(index, inner));
|
|
617
|
-
} else if (!slice.content.size) return close(node, replaceTwoWay($from, $to, depth));
|
|
618
|
-
else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) {
|
|
619
|
-
let parent = $from.parent, content = parent.content;
|
|
620
|
-
return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
|
|
621
|
-
} else {
|
|
622
|
-
let { start, end } = prepareSliceForReplace(slice, $from);
|
|
623
|
-
return close(node, replaceThreeWay($from, start, end, $to, depth));
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
function checkJoin(main, sub) {
|
|
627
|
-
if (!sub.type.compatibleContent(main.type)) throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name);
|
|
628
|
-
}
|
|
629
|
-
function joinable($before, $after, depth) {
|
|
630
|
-
let node = $before.node(depth);
|
|
631
|
-
checkJoin(node, $after.node(depth));
|
|
632
|
-
return node;
|
|
633
|
-
}
|
|
634
|
-
function addNode(child, target) {
|
|
635
|
-
let last = target.length - 1;
|
|
636
|
-
if (last >= 0 && child.isText && child.sameMarkup(target[last])) target[last] = child.withText(target[last].text + child.text);
|
|
637
|
-
else target.push(child);
|
|
638
|
-
}
|
|
639
|
-
function addRange($start, $end, depth, target) {
|
|
640
|
-
let node = ($end || $start).node(depth);
|
|
641
|
-
let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
|
|
642
|
-
if ($start) {
|
|
643
|
-
startIndex = $start.index(depth);
|
|
644
|
-
if ($start.depth > depth) startIndex++;
|
|
645
|
-
else if ($start.textOffset) {
|
|
646
|
-
addNode($start.nodeAfter, target);
|
|
647
|
-
startIndex++;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
for (let i = startIndex; i < endIndex; i++) addNode(node.child(i), target);
|
|
651
|
-
if ($end && $end.depth == depth && $end.textOffset) addNode($end.nodeBefore, target);
|
|
652
|
-
}
|
|
653
|
-
function close(node, content) {
|
|
654
|
-
if (!node.type.validContent(content)) throw new ReplaceError("Invalid content for node " + node.type.name);
|
|
655
|
-
return node.copy(content);
|
|
656
|
-
}
|
|
657
|
-
function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
658
|
-
let openStart = $from.depth > depth && joinable($from, $start, depth + 1);
|
|
659
|
-
let openEnd = $to.depth > depth && joinable($end, $to, depth + 1);
|
|
660
|
-
let content = [];
|
|
661
|
-
addRange(null, $from, depth, content);
|
|
662
|
-
if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
|
|
663
|
-
checkJoin(openStart, openEnd);
|
|
664
|
-
addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
|
|
665
|
-
} else {
|
|
666
|
-
if (openStart) addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
|
|
667
|
-
addRange($start, $end, depth, content);
|
|
668
|
-
if (openEnd) addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
669
|
-
}
|
|
670
|
-
addRange($to, null, depth, content);
|
|
671
|
-
return new Fragment$1(content);
|
|
672
|
-
}
|
|
673
|
-
function replaceTwoWay($from, $to, depth) {
|
|
674
|
-
let content = [];
|
|
675
|
-
addRange(null, $from, depth, content);
|
|
676
|
-
if ($from.depth > depth) addNode(close(joinable($from, $to, depth + 1), replaceTwoWay($from, $to, depth + 1)), content);
|
|
677
|
-
addRange($to, null, depth, content);
|
|
678
|
-
return new Fragment$1(content);
|
|
679
|
-
}
|
|
680
|
-
function prepareSliceForReplace(slice, $along) {
|
|
681
|
-
let extra = $along.depth - slice.openStart;
|
|
682
|
-
let node = $along.node(extra).copy(slice.content);
|
|
683
|
-
for (let i = extra - 1; i >= 0; i--) node = $along.node(i).copy(Fragment$1.from(node));
|
|
684
|
-
return {
|
|
685
|
-
start: node.resolveNoCache(slice.openStart + extra),
|
|
686
|
-
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
You can [_resolve_](https://prosemirror.net/docs/ref/#model.Node.resolve) a position to get more
|
|
691
|
-
information about it. Objects of this class represent such a
|
|
692
|
-
resolved position, providing various pieces of context
|
|
693
|
-
information, and some helper methods.
|
|
694
|
-
|
|
695
|
-
Throughout this interface, methods that take an optional `depth`
|
|
696
|
-
parameter will interpret undefined as `this.depth` and negative
|
|
697
|
-
numbers as `this.depth + value`.
|
|
698
|
-
*/
|
|
699
|
-
var ResolvedPos = class ResolvedPos {
|
|
700
|
-
/**
|
|
701
|
-
@internal
|
|
702
|
-
*/
|
|
703
|
-
constructor(pos, path, parentOffset) {
|
|
704
|
-
this.pos = pos;
|
|
705
|
-
this.path = path;
|
|
706
|
-
this.parentOffset = parentOffset;
|
|
707
|
-
this.depth = path.length / 3 - 1;
|
|
708
|
-
}
|
|
709
|
-
/**
|
|
710
|
-
@internal
|
|
711
|
-
*/
|
|
712
|
-
resolveDepth(val) {
|
|
713
|
-
if (val == null) return this.depth;
|
|
714
|
-
if (val < 0) return this.depth + val;
|
|
715
|
-
return val;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
The parent node that the position points into. Note that even if
|
|
719
|
-
a position points into a text node, that node is not considered
|
|
720
|
-
the parent—text nodes are ‘flat’ in this model, and have no content.
|
|
721
|
-
*/
|
|
722
|
-
get parent() {
|
|
723
|
-
return this.node(this.depth);
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
The root node in which the position was resolved.
|
|
727
|
-
*/
|
|
728
|
-
get doc() {
|
|
729
|
-
return this.node(0);
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
The ancestor node at the given level. `p.node(p.depth)` is the
|
|
733
|
-
same as `p.parent`.
|
|
734
|
-
*/
|
|
735
|
-
node(depth) {
|
|
736
|
-
return this.path[this.resolveDepth(depth) * 3];
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
The index into the ancestor at the given level. If this points
|
|
740
|
-
at the 3rd node in the 2nd paragraph on the top level, for
|
|
741
|
-
example, `p.index(0)` is 1 and `p.index(1)` is 2.
|
|
742
|
-
*/
|
|
743
|
-
index(depth) {
|
|
744
|
-
return this.path[this.resolveDepth(depth) * 3 + 1];
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
The index pointing after this position into the ancestor at the
|
|
748
|
-
given level.
|
|
749
|
-
*/
|
|
750
|
-
indexAfter(depth) {
|
|
751
|
-
depth = this.resolveDepth(depth);
|
|
752
|
-
return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
The (absolute) position at the start of the node at the given
|
|
756
|
-
level.
|
|
757
|
-
*/
|
|
758
|
-
start(depth) {
|
|
759
|
-
depth = this.resolveDepth(depth);
|
|
760
|
-
return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
The (absolute) position at the end of the node at the given
|
|
764
|
-
level.
|
|
765
|
-
*/
|
|
766
|
-
end(depth) {
|
|
767
|
-
depth = this.resolveDepth(depth);
|
|
768
|
-
return this.start(depth) + this.node(depth).content.size;
|
|
769
|
-
}
|
|
770
|
-
/**
|
|
771
|
-
The (absolute) position directly before the wrapping node at the
|
|
772
|
-
given level, or, when `depth` is `this.depth + 1`, the original
|
|
773
|
-
position.
|
|
774
|
-
*/
|
|
775
|
-
before(depth) {
|
|
776
|
-
depth = this.resolveDepth(depth);
|
|
777
|
-
if (!depth) throw new RangeError("There is no position before the top-level node");
|
|
778
|
-
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
The (absolute) position directly after the wrapping node at the
|
|
782
|
-
given level, or the original position when `depth` is `this.depth + 1`.
|
|
783
|
-
*/
|
|
784
|
-
after(depth) {
|
|
785
|
-
depth = this.resolveDepth(depth);
|
|
786
|
-
if (!depth) throw new RangeError("There is no position after the top-level node");
|
|
787
|
-
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
When this position points into a text node, this returns the
|
|
791
|
-
distance between the position and the start of the text node.
|
|
792
|
-
Will be zero for positions that point between nodes.
|
|
793
|
-
*/
|
|
794
|
-
get textOffset() {
|
|
795
|
-
return this.pos - this.path[this.path.length - 1];
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
Get the node directly after the position, if any. If the position
|
|
799
|
-
points into a text node, only the part of that node after the
|
|
800
|
-
position is returned.
|
|
801
|
-
*/
|
|
802
|
-
get nodeAfter() {
|
|
803
|
-
let parent = this.parent, index = this.index(this.depth);
|
|
804
|
-
if (index == parent.childCount) return null;
|
|
805
|
-
let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
|
|
806
|
-
return dOff ? parent.child(index).cut(dOff) : child;
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
Get the node directly before the position, if any. If the
|
|
810
|
-
position points into a text node, only the part of that node
|
|
811
|
-
before the position is returned.
|
|
812
|
-
*/
|
|
813
|
-
get nodeBefore() {
|
|
814
|
-
let index = this.index(this.depth);
|
|
815
|
-
let dOff = this.pos - this.path[this.path.length - 1];
|
|
816
|
-
if (dOff) return this.parent.child(index).cut(0, dOff);
|
|
817
|
-
return index == 0 ? null : this.parent.child(index - 1);
|
|
818
|
-
}
|
|
819
|
-
/**
|
|
820
|
-
Get the position at the given index in the parent node at the
|
|
821
|
-
given depth (which defaults to `this.depth`).
|
|
822
|
-
*/
|
|
823
|
-
posAtIndex(index, depth) {
|
|
824
|
-
depth = this.resolveDepth(depth);
|
|
825
|
-
let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
|
|
826
|
-
for (let i = 0; i < index; i++) pos += node.child(i).nodeSize;
|
|
827
|
-
return pos;
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
Get the marks at this position, factoring in the surrounding
|
|
831
|
-
marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the
|
|
832
|
-
position is at the start of a non-empty node, the marks of the
|
|
833
|
-
node after it (if any) are returned.
|
|
834
|
-
*/
|
|
835
|
-
marks() {
|
|
836
|
-
let parent = this.parent, index = this.index();
|
|
837
|
-
if (parent.content.size == 0) return Mark.none;
|
|
838
|
-
if (this.textOffset) return parent.child(index).marks;
|
|
839
|
-
let main = parent.maybeChild(index - 1), other = parent.maybeChild(index);
|
|
840
|
-
if (!main) {
|
|
841
|
-
let tmp = main;
|
|
842
|
-
main = other;
|
|
843
|
-
other = tmp;
|
|
844
|
-
}
|
|
845
|
-
let marks = main.marks;
|
|
846
|
-
for (var i = 0; i < marks.length; i++) if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks))) marks = marks[i--].removeFromSet(marks);
|
|
847
|
-
return marks;
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
Get the marks after the current position, if any, except those
|
|
851
|
-
that are non-inclusive and not present at position `$end`. This
|
|
852
|
-
is mostly useful for getting the set of marks to preserve after a
|
|
853
|
-
deletion. Will return `null` if this position is at the end of
|
|
854
|
-
its parent node or its parent node isn't a textblock (in which
|
|
855
|
-
case no marks should be preserved).
|
|
856
|
-
*/
|
|
857
|
-
marksAcross($end) {
|
|
858
|
-
let after = this.parent.maybeChild(this.index());
|
|
859
|
-
if (!after || !after.isInline) return null;
|
|
860
|
-
let marks = after.marks, next = $end.parent.maybeChild($end.index());
|
|
861
|
-
for (var i = 0; i < marks.length; i++) if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks))) marks = marks[i--].removeFromSet(marks);
|
|
862
|
-
return marks;
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
The depth up to which this position and the given (non-resolved)
|
|
866
|
-
position share the same parent nodes.
|
|
867
|
-
*/
|
|
868
|
-
sharedDepth(pos) {
|
|
869
|
-
for (let depth = this.depth; depth > 0; depth--) if (this.start(depth) <= pos && this.end(depth) >= pos) return depth;
|
|
870
|
-
return 0;
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
Returns a range based on the place where this position and the
|
|
874
|
-
given position diverge around block content. If both point into
|
|
875
|
-
the same textblock, for example, a range around that textblock
|
|
876
|
-
will be returned. If they point into different blocks, the range
|
|
877
|
-
around those blocks in their shared ancestor is returned. You can
|
|
878
|
-
pass in an optional predicate that will be called with a parent
|
|
879
|
-
node to see if a range into that parent is acceptable.
|
|
880
|
-
*/
|
|
881
|
-
blockRange(other = this, pred) {
|
|
882
|
-
if (other.pos < this.pos) return other.blockRange(this);
|
|
883
|
-
for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--) if (other.pos <= this.end(d) && (!pred || pred(this.node(d)))) return new NodeRange(this, other, d);
|
|
884
|
-
return null;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
Query whether the given position shares the same parent node.
|
|
888
|
-
*/
|
|
889
|
-
sameParent(other) {
|
|
890
|
-
return this.pos - this.parentOffset == other.pos - other.parentOffset;
|
|
891
|
-
}
|
|
892
|
-
/**
|
|
893
|
-
Return the greater of this and the given position.
|
|
894
|
-
*/
|
|
895
|
-
max(other) {
|
|
896
|
-
return other.pos > this.pos ? other : this;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
Return the smaller of this and the given position.
|
|
900
|
-
*/
|
|
901
|
-
min(other) {
|
|
902
|
-
return other.pos < this.pos ? other : this;
|
|
903
|
-
}
|
|
904
|
-
/**
|
|
905
|
-
@internal
|
|
906
|
-
*/
|
|
907
|
-
toString() {
|
|
908
|
-
let str = "";
|
|
909
|
-
for (let i = 1; i <= this.depth; i++) str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
|
|
910
|
-
return str + ":" + this.parentOffset;
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
@internal
|
|
914
|
-
*/
|
|
915
|
-
static resolve(doc, pos) {
|
|
916
|
-
if (!(pos >= 0 && pos <= doc.content.size)) throw new RangeError("Position " + pos + " out of range");
|
|
917
|
-
let path = [];
|
|
918
|
-
let start = 0, parentOffset = pos;
|
|
919
|
-
for (let node = doc;;) {
|
|
920
|
-
let { index, offset } = node.content.findIndex(parentOffset);
|
|
921
|
-
let rem = parentOffset - offset;
|
|
922
|
-
path.push(node, index, start + offset);
|
|
923
|
-
if (!rem) break;
|
|
924
|
-
node = node.child(index);
|
|
925
|
-
if (node.isText) break;
|
|
926
|
-
parentOffset = rem - 1;
|
|
927
|
-
start += offset + 1;
|
|
928
|
-
}
|
|
929
|
-
return new ResolvedPos(pos, path, parentOffset);
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
@internal
|
|
933
|
-
*/
|
|
934
|
-
static resolveCached(doc, pos) {
|
|
935
|
-
let cache = resolveCache.get(doc);
|
|
936
|
-
if (cache) for (let i = 0; i < cache.elts.length; i++) {
|
|
937
|
-
let elt = cache.elts[i];
|
|
938
|
-
if (elt.pos == pos) return elt;
|
|
939
|
-
}
|
|
940
|
-
else resolveCache.set(doc, cache = new ResolveCache());
|
|
941
|
-
let result = cache.elts[cache.i] = ResolvedPos.resolve(doc, pos);
|
|
942
|
-
cache.i = (cache.i + 1) % resolveCacheSize;
|
|
943
|
-
return result;
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
var ResolveCache = class {
|
|
947
|
-
constructor() {
|
|
948
|
-
this.elts = [];
|
|
949
|
-
this.i = 0;
|
|
950
|
-
}
|
|
951
|
-
};
|
|
952
|
-
var resolveCacheSize = 12, resolveCache = /* @__PURE__ */ new WeakMap();
|
|
953
|
-
/**
|
|
954
|
-
Represents a flat range of content, i.e. one that starts and
|
|
955
|
-
ends in the same node.
|
|
956
|
-
*/
|
|
957
|
-
var NodeRange = class {
|
|
958
|
-
/**
|
|
959
|
-
Construct a node range. `$from` and `$to` should point into the
|
|
960
|
-
same node until at least the given `depth`, since a node range
|
|
961
|
-
denotes an adjacent set of nodes in a single parent node.
|
|
962
|
-
*/
|
|
963
|
-
constructor($from, $to, depth) {
|
|
964
|
-
this.$from = $from;
|
|
965
|
-
this.$to = $to;
|
|
966
|
-
this.depth = depth;
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
The position at the start of the range.
|
|
970
|
-
*/
|
|
971
|
-
get start() {
|
|
972
|
-
return this.$from.before(this.depth + 1);
|
|
973
|
-
}
|
|
974
|
-
/**
|
|
975
|
-
The position at the end of the range.
|
|
976
|
-
*/
|
|
977
|
-
get end() {
|
|
978
|
-
return this.$to.after(this.depth + 1);
|
|
979
|
-
}
|
|
980
|
-
/**
|
|
981
|
-
The parent node that the range points into.
|
|
982
|
-
*/
|
|
983
|
-
get parent() {
|
|
984
|
-
return this.$from.node(this.depth);
|
|
985
|
-
}
|
|
986
|
-
/**
|
|
987
|
-
The start index of the range in the parent node.
|
|
988
|
-
*/
|
|
989
|
-
get startIndex() {
|
|
990
|
-
return this.$from.index(this.depth);
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
The end index of the range in the parent node.
|
|
994
|
-
*/
|
|
995
|
-
get endIndex() {
|
|
996
|
-
return this.$to.indexAfter(this.depth);
|
|
997
|
-
}
|
|
998
|
-
};
|
|
999
|
-
var emptyAttrs = Object.create(null);
|
|
1000
|
-
/**
|
|
1001
|
-
This class represents a node in the tree that makes up a
|
|
1002
|
-
ProseMirror document. So a document is an instance of `Node`, with
|
|
1003
|
-
children that are also instances of `Node`.
|
|
1004
|
-
|
|
1005
|
-
Nodes are persistent data structures. Instead of changing them, you
|
|
1006
|
-
create new ones with the content you want. Old ones keep pointing
|
|
1007
|
-
at the old document shape. This is made cheaper by sharing
|
|
1008
|
-
structure between the old and new data as much as possible, which a
|
|
1009
|
-
tree shape like this (without back pointers) makes easy.
|
|
1010
|
-
|
|
1011
|
-
**Do not** directly mutate the properties of a `Node` object. See
|
|
1012
|
-
[the guide](https://prosemirror.net/docs/guide/#doc) for more information.
|
|
1013
|
-
*/
|
|
1014
|
-
var Node = class Node {
|
|
1015
|
-
/**
|
|
1016
|
-
@internal
|
|
1017
|
-
*/
|
|
1018
|
-
constructor(type, attrs, content, marks = Mark.none) {
|
|
1019
|
-
this.type = type;
|
|
1020
|
-
this.attrs = attrs;
|
|
1021
|
-
this.marks = marks;
|
|
1022
|
-
this.content = content || Fragment$1.empty;
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
The array of this node's child nodes.
|
|
1026
|
-
*/
|
|
1027
|
-
get children() {
|
|
1028
|
-
return this.content.content;
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
The size of this node, as defined by the integer-based [indexing
|
|
1032
|
-
scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
|
|
1033
|
-
amount of characters. For other leaf nodes, it is one. For
|
|
1034
|
-
non-leaf nodes, it is the size of the content plus two (the
|
|
1035
|
-
start and end token).
|
|
1036
|
-
*/
|
|
1037
|
-
get nodeSize() {
|
|
1038
|
-
return this.isLeaf ? 1 : 2 + this.content.size;
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
The number of children that the node has.
|
|
1042
|
-
*/
|
|
1043
|
-
get childCount() {
|
|
1044
|
-
return this.content.childCount;
|
|
1045
|
-
}
|
|
1046
|
-
/**
|
|
1047
|
-
Get the child node at the given index. Raises an error when the
|
|
1048
|
-
index is out of range.
|
|
1049
|
-
*/
|
|
1050
|
-
child(index) {
|
|
1051
|
-
return this.content.child(index);
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
Get the child node at the given index, if it exists.
|
|
1055
|
-
*/
|
|
1056
|
-
maybeChild(index) {
|
|
1057
|
-
return this.content.maybeChild(index);
|
|
1058
|
-
}
|
|
1059
|
-
/**
|
|
1060
|
-
Call `f` for every child node, passing the node, its offset
|
|
1061
|
-
into this parent node, and its index.
|
|
1062
|
-
*/
|
|
1063
|
-
forEach(f) {
|
|
1064
|
-
this.content.forEach(f);
|
|
1065
|
-
}
|
|
1066
|
-
/**
|
|
1067
|
-
Invoke a callback for all descendant nodes recursively overlapping
|
|
1068
|
-
the given two positions that are relative to start of this
|
|
1069
|
-
node's content. This includes all ancestors of the nodes
|
|
1070
|
-
containing the two positions. The callback is invoked with the
|
|
1071
|
-
node, its position relative to the original node (method receiver),
|
|
1072
|
-
its parent node, and its child index. When the callback returns
|
|
1073
|
-
false for a given node, that node's children will not be
|
|
1074
|
-
recursed over. The last parameter can be used to specify a
|
|
1075
|
-
starting position to count from.
|
|
1076
|
-
*/
|
|
1077
|
-
nodesBetween(from, to, f, startPos = 0) {
|
|
1078
|
-
this.content.nodesBetween(from, to, f, startPos, this);
|
|
1079
|
-
}
|
|
1080
|
-
/**
|
|
1081
|
-
Call the given callback for every descendant node. Doesn't
|
|
1082
|
-
descend into a node when the callback returns `false`.
|
|
1083
|
-
*/
|
|
1084
|
-
descendants(f) {
|
|
1085
|
-
this.nodesBetween(0, this.content.size, f);
|
|
1086
|
-
}
|
|
1087
|
-
/**
|
|
1088
|
-
Concatenates all the text nodes found in this fragment and its
|
|
1089
|
-
children.
|
|
1090
|
-
*/
|
|
1091
|
-
get textContent() {
|
|
1092
|
-
return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, "");
|
|
1093
|
-
}
|
|
1094
|
-
/**
|
|
1095
|
-
Get all text between positions `from` and `to`. When
|
|
1096
|
-
`blockSeparator` is given, it will be inserted to separate text
|
|
1097
|
-
from different block nodes. If `leafText` is given, it'll be
|
|
1098
|
-
inserted for every non-text leaf node encountered, otherwise
|
|
1099
|
-
[`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
|
|
1100
|
-
*/
|
|
1101
|
-
textBetween(from, to, blockSeparator, leafText) {
|
|
1102
|
-
return this.content.textBetween(from, to, blockSeparator, leafText);
|
|
1103
|
-
}
|
|
1104
|
-
/**
|
|
1105
|
-
Returns this node's first child, or `null` if there are no
|
|
1106
|
-
children.
|
|
1107
|
-
*/
|
|
1108
|
-
get firstChild() {
|
|
1109
|
-
return this.content.firstChild;
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
Returns this node's last child, or `null` if there are no
|
|
1113
|
-
children.
|
|
1114
|
-
*/
|
|
1115
|
-
get lastChild() {
|
|
1116
|
-
return this.content.lastChild;
|
|
1117
|
-
}
|
|
1118
|
-
/**
|
|
1119
|
-
Test whether two nodes represent the same piece of document.
|
|
1120
|
-
*/
|
|
1121
|
-
eq(other) {
|
|
1122
|
-
return this == other || this.sameMarkup(other) && this.content.eq(other.content);
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
Compare the markup (type, attributes, and marks) of this node to
|
|
1126
|
-
those of another. Returns `true` if both have the same markup.
|
|
1127
|
-
*/
|
|
1128
|
-
sameMarkup(other) {
|
|
1129
|
-
return this.hasMarkup(other.type, other.attrs, other.marks);
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
Check whether this node's markup correspond to the given type,
|
|
1133
|
-
attributes, and marks.
|
|
1134
|
-
*/
|
|
1135
|
-
hasMarkup(type, attrs, marks) {
|
|
1136
|
-
return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none);
|
|
1137
|
-
}
|
|
1138
|
-
/**
|
|
1139
|
-
Create a new node with the same markup as this node, containing
|
|
1140
|
-
the given content (or empty, if no content is given).
|
|
1141
|
-
*/
|
|
1142
|
-
copy(content = null) {
|
|
1143
|
-
if (content == this.content) return this;
|
|
1144
|
-
return new Node(this.type, this.attrs, content, this.marks);
|
|
1145
|
-
}
|
|
1146
|
-
/**
|
|
1147
|
-
Create a copy of this node, with the given set of marks instead
|
|
1148
|
-
of the node's own marks.
|
|
1149
|
-
*/
|
|
1150
|
-
mark(marks) {
|
|
1151
|
-
return marks == this.marks ? this : new Node(this.type, this.attrs, this.content, marks);
|
|
1152
|
-
}
|
|
1153
|
-
/**
|
|
1154
|
-
Create a copy of this node with only the content between the
|
|
1155
|
-
given positions. If `to` is not given, it defaults to the end of
|
|
1156
|
-
the node.
|
|
1157
|
-
*/
|
|
1158
|
-
cut(from, to = this.content.size) {
|
|
1159
|
-
if (from == 0 && to == this.content.size) return this;
|
|
1160
|
-
return this.copy(this.content.cut(from, to));
|
|
1161
|
-
}
|
|
1162
|
-
/**
|
|
1163
|
-
Cut out the part of the document between the given positions, and
|
|
1164
|
-
return it as a `Slice` object.
|
|
1165
|
-
*/
|
|
1166
|
-
slice(from, to = this.content.size, includeParents = false) {
|
|
1167
|
-
if (from == to) return Slice.empty;
|
|
1168
|
-
let $from = this.resolve(from), $to = this.resolve(to);
|
|
1169
|
-
let depth = includeParents ? 0 : $from.sharedDepth(to);
|
|
1170
|
-
let start = $from.start(depth);
|
|
1171
|
-
return new Slice($from.node(depth).content.cut($from.pos - start, $to.pos - start), $from.depth - depth, $to.depth - depth);
|
|
1172
|
-
}
|
|
1173
|
-
/**
|
|
1174
|
-
Replace the part of the document between the given positions with
|
|
1175
|
-
the given slice. The slice must 'fit', meaning its open sides
|
|
1176
|
-
must be able to connect to the surrounding content, and its
|
|
1177
|
-
content nodes must be valid children for the node they are placed
|
|
1178
|
-
into. If any of this is violated, an error of type
|
|
1179
|
-
[`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown.
|
|
1180
|
-
*/
|
|
1181
|
-
replace(from, to, slice) {
|
|
1182
|
-
return replace(this.resolve(from), this.resolve(to), slice);
|
|
1183
|
-
}
|
|
1184
|
-
/**
|
|
1185
|
-
Find the node directly after the given position.
|
|
1186
|
-
*/
|
|
1187
|
-
nodeAt(pos) {
|
|
1188
|
-
for (let node = this;;) {
|
|
1189
|
-
let { index, offset } = node.content.findIndex(pos);
|
|
1190
|
-
node = node.maybeChild(index);
|
|
1191
|
-
if (!node) return null;
|
|
1192
|
-
if (offset == pos || node.isText) return node;
|
|
1193
|
-
pos -= offset + 1;
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
Find the (direct) child node after the given offset, if any,
|
|
1198
|
-
and return it along with its index and offset relative to this
|
|
1199
|
-
node.
|
|
1200
|
-
*/
|
|
1201
|
-
childAfter(pos) {
|
|
1202
|
-
let { index, offset } = this.content.findIndex(pos);
|
|
1203
|
-
return {
|
|
1204
|
-
node: this.content.maybeChild(index),
|
|
1205
|
-
index,
|
|
1206
|
-
offset
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1209
|
-
/**
|
|
1210
|
-
Find the (direct) child node before the given offset, if any,
|
|
1211
|
-
and return it along with its index and offset relative to this
|
|
1212
|
-
node.
|
|
1213
|
-
*/
|
|
1214
|
-
childBefore(pos) {
|
|
1215
|
-
if (pos == 0) return {
|
|
1216
|
-
node: null,
|
|
1217
|
-
index: 0,
|
|
1218
|
-
offset: 0
|
|
1219
|
-
};
|
|
1220
|
-
let { index, offset } = this.content.findIndex(pos);
|
|
1221
|
-
if (offset < pos) return {
|
|
1222
|
-
node: this.content.child(index),
|
|
1223
|
-
index,
|
|
1224
|
-
offset
|
|
1225
|
-
};
|
|
1226
|
-
let node = this.content.child(index - 1);
|
|
1227
|
-
return {
|
|
1228
|
-
node,
|
|
1229
|
-
index: index - 1,
|
|
1230
|
-
offset: offset - node.nodeSize
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
/**
|
|
1234
|
-
Resolve the given position in the document, returning an
|
|
1235
|
-
[object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context.
|
|
1236
|
-
*/
|
|
1237
|
-
resolve(pos) {
|
|
1238
|
-
return ResolvedPos.resolveCached(this, pos);
|
|
1239
|
-
}
|
|
1240
|
-
/**
|
|
1241
|
-
@internal
|
|
1242
|
-
*/
|
|
1243
|
-
resolveNoCache(pos) {
|
|
1244
|
-
return ResolvedPos.resolve(this, pos);
|
|
1245
|
-
}
|
|
1246
|
-
/**
|
|
1247
|
-
Test whether a given mark or mark type occurs in this document
|
|
1248
|
-
between the two given positions.
|
|
1249
|
-
*/
|
|
1250
|
-
rangeHasMark(from, to, type) {
|
|
1251
|
-
let found = false;
|
|
1252
|
-
if (to > from) this.nodesBetween(from, to, (node) => {
|
|
1253
|
-
if (type.isInSet(node.marks)) found = true;
|
|
1254
|
-
return !found;
|
|
1255
|
-
});
|
|
1256
|
-
return found;
|
|
1257
|
-
}
|
|
1258
|
-
/**
|
|
1259
|
-
True when this is a block (non-inline node)
|
|
1260
|
-
*/
|
|
1261
|
-
get isBlock() {
|
|
1262
|
-
return this.type.isBlock;
|
|
1263
|
-
}
|
|
1264
|
-
/**
|
|
1265
|
-
True when this is a textblock node, a block node with inline
|
|
1266
|
-
content.
|
|
1267
|
-
*/
|
|
1268
|
-
get isTextblock() {
|
|
1269
|
-
return this.type.isTextblock;
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
True when this node allows inline content.
|
|
1273
|
-
*/
|
|
1274
|
-
get inlineContent() {
|
|
1275
|
-
return this.type.inlineContent;
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
True when this is an inline node (a text node or a node that can
|
|
1279
|
-
appear among text).
|
|
1280
|
-
*/
|
|
1281
|
-
get isInline() {
|
|
1282
|
-
return this.type.isInline;
|
|
1283
|
-
}
|
|
1284
|
-
/**
|
|
1285
|
-
True when this is a text node.
|
|
1286
|
-
*/
|
|
1287
|
-
get isText() {
|
|
1288
|
-
return this.type.isText;
|
|
1289
|
-
}
|
|
1290
|
-
/**
|
|
1291
|
-
True when this is a leaf node.
|
|
1292
|
-
*/
|
|
1293
|
-
get isLeaf() {
|
|
1294
|
-
return this.type.isLeaf;
|
|
1295
|
-
}
|
|
1296
|
-
/**
|
|
1297
|
-
True when this is an atom, i.e. when it does not have directly
|
|
1298
|
-
editable content. This is usually the same as `isLeaf`, but can
|
|
1299
|
-
be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom)
|
|
1300
|
-
on a node's spec (typically used when the node is displayed as
|
|
1301
|
-
an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)).
|
|
1302
|
-
*/
|
|
1303
|
-
get isAtom() {
|
|
1304
|
-
return this.type.isAtom;
|
|
1305
|
-
}
|
|
1306
|
-
/**
|
|
1307
|
-
Return a string representation of this node for debugging
|
|
1308
|
-
purposes.
|
|
1309
|
-
*/
|
|
1310
|
-
toString() {
|
|
1311
|
-
if (this.type.spec.toDebugString) return this.type.spec.toDebugString(this);
|
|
1312
|
-
let name = this.type.name;
|
|
1313
|
-
if (this.content.size) name += "(" + this.content.toStringInner() + ")";
|
|
1314
|
-
return wrapMarks(this.marks, name);
|
|
1315
|
-
}
|
|
1316
|
-
/**
|
|
1317
|
-
Get the content match in this node at the given index.
|
|
1318
|
-
*/
|
|
1319
|
-
contentMatchAt(index) {
|
|
1320
|
-
let match = this.type.contentMatch.matchFragment(this.content, 0, index);
|
|
1321
|
-
if (!match) throw new Error("Called contentMatchAt on a node with invalid content");
|
|
1322
|
-
return match;
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
Test whether replacing the range between `from` and `to` (by
|
|
1326
|
-
child index) with the given replacement fragment (which defaults
|
|
1327
|
-
to the empty fragment) would leave the node's content valid. You
|
|
1328
|
-
can optionally pass `start` and `end` indices into the
|
|
1329
|
-
replacement fragment.
|
|
1330
|
-
*/
|
|
1331
|
-
canReplace(from, to, replacement = Fragment$1.empty, start = 0, end = replacement.childCount) {
|
|
1332
|
-
let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
|
|
1333
|
-
let two = one && one.matchFragment(this.content, to);
|
|
1334
|
-
if (!two || !two.validEnd) return false;
|
|
1335
|
-
for (let i = start; i < end; i++) if (!this.type.allowsMarks(replacement.child(i).marks)) return false;
|
|
1336
|
-
return true;
|
|
1337
|
-
}
|
|
1338
|
-
/**
|
|
1339
|
-
Test whether replacing the range `from` to `to` (by index) with
|
|
1340
|
-
a node of the given type would leave the node's content valid.
|
|
1341
|
-
*/
|
|
1342
|
-
canReplaceWith(from, to, type, marks) {
|
|
1343
|
-
if (marks && !this.type.allowsMarks(marks)) return false;
|
|
1344
|
-
let start = this.contentMatchAt(from).matchType(type);
|
|
1345
|
-
let end = start && start.matchFragment(this.content, to);
|
|
1346
|
-
return end ? end.validEnd : false;
|
|
1347
|
-
}
|
|
1348
|
-
/**
|
|
1349
|
-
Test whether the given node's content could be appended to this
|
|
1350
|
-
node. If that node is empty, this will only return true if there
|
|
1351
|
-
is at least one node type that can appear in both nodes (to avoid
|
|
1352
|
-
merging completely incompatible nodes).
|
|
1353
|
-
*/
|
|
1354
|
-
canAppend(other) {
|
|
1355
|
-
if (other.content.size) return this.canReplace(this.childCount, this.childCount, other.content);
|
|
1356
|
-
else return this.type.compatibleContent(other.type);
|
|
1357
|
-
}
|
|
1358
|
-
/**
|
|
1359
|
-
Check whether this node and its descendants conform to the
|
|
1360
|
-
schema, and raise an exception when they do not.
|
|
1361
|
-
*/
|
|
1362
|
-
check() {
|
|
1363
|
-
this.type.checkContent(this.content);
|
|
1364
|
-
this.type.checkAttrs(this.attrs);
|
|
1365
|
-
let copy = Mark.none;
|
|
1366
|
-
for (let i = 0; i < this.marks.length; i++) {
|
|
1367
|
-
let mark = this.marks[i];
|
|
1368
|
-
mark.type.checkAttrs(mark.attrs);
|
|
1369
|
-
copy = mark.addToSet(copy);
|
|
1370
|
-
}
|
|
1371
|
-
if (!Mark.sameSet(copy, this.marks)) throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`);
|
|
1372
|
-
this.content.forEach((node) => node.check());
|
|
1373
|
-
}
|
|
1374
|
-
/**
|
|
1375
|
-
Return a JSON-serializeable representation of this node.
|
|
1376
|
-
*/
|
|
1377
|
-
toJSON() {
|
|
1378
|
-
let obj = { type: this.type.name };
|
|
1379
|
-
for (let _ in this.attrs) {
|
|
1380
|
-
obj.attrs = this.attrs;
|
|
1381
|
-
break;
|
|
1382
|
-
}
|
|
1383
|
-
if (this.content.size) obj.content = this.content.toJSON();
|
|
1384
|
-
if (this.marks.length) obj.marks = this.marks.map((n) => n.toJSON());
|
|
1385
|
-
return obj;
|
|
1386
|
-
}
|
|
1387
|
-
/**
|
|
1388
|
-
Deserialize a node from its JSON representation.
|
|
1389
|
-
*/
|
|
1390
|
-
static fromJSON(schema, json) {
|
|
1391
|
-
if (!json) throw new RangeError("Invalid input for Node.fromJSON");
|
|
1392
|
-
let marks = void 0;
|
|
1393
|
-
if (json.marks) {
|
|
1394
|
-
if (!Array.isArray(json.marks)) throw new RangeError("Invalid mark data for Node.fromJSON");
|
|
1395
|
-
marks = json.marks.map(schema.markFromJSON);
|
|
1396
|
-
}
|
|
1397
|
-
if (json.type == "text") {
|
|
1398
|
-
if (typeof json.text != "string") throw new RangeError("Invalid text node in JSON");
|
|
1399
|
-
return schema.text(json.text, marks);
|
|
1400
|
-
}
|
|
1401
|
-
let content = Fragment$1.fromJSON(schema, json.content);
|
|
1402
|
-
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
1403
|
-
node.type.checkAttrs(node.attrs);
|
|
1404
|
-
return node;
|
|
1405
|
-
}
|
|
1406
|
-
};
|
|
1407
|
-
Node.prototype.text = void 0;
|
|
1408
|
-
function wrapMarks(marks, str) {
|
|
1409
|
-
for (let i = marks.length - 1; i >= 0; i--) str = marks[i].type.name + "(" + str + ")";
|
|
1410
|
-
return str;
|
|
1411
|
-
}
|
|
1412
|
-
/**
|
|
1413
|
-
Instances of this class represent a match state of a node type's
|
|
1414
|
-
[content expression](https://prosemirror.net/docs/ref/#model.NodeSpec.content), and can be used to
|
|
1415
|
-
find out whether further content matches here, and whether a given
|
|
1416
|
-
position is a valid end of the node.
|
|
1417
|
-
*/
|
|
1418
|
-
var ContentMatch = class ContentMatch {
|
|
1419
|
-
/**
|
|
1420
|
-
@internal
|
|
1421
|
-
*/
|
|
1422
|
-
constructor(validEnd) {
|
|
1423
|
-
this.validEnd = validEnd;
|
|
1424
|
-
/**
|
|
1425
|
-
@internal
|
|
1426
|
-
*/
|
|
1427
|
-
this.next = [];
|
|
1428
|
-
/**
|
|
1429
|
-
@internal
|
|
1430
|
-
*/
|
|
1431
|
-
this.wrapCache = [];
|
|
1432
|
-
}
|
|
1433
|
-
/**
|
|
1434
|
-
@internal
|
|
1435
|
-
*/
|
|
1436
|
-
static parse(string, nodeTypes) {
|
|
1437
|
-
let stream = new TokenStream(string, nodeTypes);
|
|
1438
|
-
if (stream.next == null) return ContentMatch.empty;
|
|
1439
|
-
let expr = parseExpr(stream);
|
|
1440
|
-
if (stream.next) stream.err("Unexpected trailing text");
|
|
1441
|
-
let match = dfa(nfa(expr));
|
|
1442
|
-
checkForDeadEnds(match, stream);
|
|
1443
|
-
return match;
|
|
1444
|
-
}
|
|
1445
|
-
/**
|
|
1446
|
-
Match a node type, returning a match after that node if
|
|
1447
|
-
successful.
|
|
1448
|
-
*/
|
|
1449
|
-
matchType(type) {
|
|
1450
|
-
for (let i = 0; i < this.next.length; i++) if (this.next[i].type == type) return this.next[i].next;
|
|
1451
|
-
return null;
|
|
1452
|
-
}
|
|
1453
|
-
/**
|
|
1454
|
-
Try to match a fragment. Returns the resulting match when
|
|
1455
|
-
successful.
|
|
1456
|
-
*/
|
|
1457
|
-
matchFragment(frag, start = 0, end = frag.childCount) {
|
|
1458
|
-
let cur = this;
|
|
1459
|
-
for (let i = start; cur && i < end; i++) cur = cur.matchType(frag.child(i).type);
|
|
1460
|
-
return cur;
|
|
1461
|
-
}
|
|
1462
|
-
/**
|
|
1463
|
-
@internal
|
|
1464
|
-
*/
|
|
1465
|
-
get inlineContent() {
|
|
1466
|
-
return this.next.length != 0 && this.next[0].type.isInline;
|
|
1467
|
-
}
|
|
1468
|
-
/**
|
|
1469
|
-
Get the first matching node type at this match position that can
|
|
1470
|
-
be generated.
|
|
1471
|
-
*/
|
|
1472
|
-
get defaultType() {
|
|
1473
|
-
for (let i = 0; i < this.next.length; i++) {
|
|
1474
|
-
let { type } = this.next[i];
|
|
1475
|
-
if (!(type.isText || type.hasRequiredAttrs())) return type;
|
|
1476
|
-
}
|
|
1477
|
-
return null;
|
|
1478
|
-
}
|
|
1479
|
-
/**
|
|
1480
|
-
@internal
|
|
1481
|
-
*/
|
|
1482
|
-
compatible(other) {
|
|
1483
|
-
for (let i = 0; i < this.next.length; i++) for (let j = 0; j < other.next.length; j++) if (this.next[i].type == other.next[j].type) return true;
|
|
1484
|
-
return false;
|
|
1485
|
-
}
|
|
1486
|
-
/**
|
|
1487
|
-
Try to match the given fragment, and if that fails, see if it can
|
|
1488
|
-
be made to match by inserting nodes in front of it. When
|
|
1489
|
-
successful, return a fragment of inserted nodes (which may be
|
|
1490
|
-
empty if nothing had to be inserted). When `toEnd` is true, only
|
|
1491
|
-
return a fragment if the resulting match goes to the end of the
|
|
1492
|
-
content expression.
|
|
1493
|
-
*/
|
|
1494
|
-
fillBefore(after, toEnd = false, startIndex = 0) {
|
|
1495
|
-
let seen = [this];
|
|
1496
|
-
function search(match, types) {
|
|
1497
|
-
let finished = match.matchFragment(after, startIndex);
|
|
1498
|
-
if (finished && (!toEnd || finished.validEnd)) return Fragment$1.from(types.map((tp) => tp.createAndFill()));
|
|
1499
|
-
for (let i = 0; i < match.next.length; i++) {
|
|
1500
|
-
let { type, next } = match.next[i];
|
|
1501
|
-
if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
|
|
1502
|
-
seen.push(next);
|
|
1503
|
-
let found = search(next, types.concat(type));
|
|
1504
|
-
if (found) return found;
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
return null;
|
|
1508
|
-
}
|
|
1509
|
-
return search(this, []);
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
Find a set of wrapping node types that would allow a node of the
|
|
1513
|
-
given type to appear at this position. The result may be empty
|
|
1514
|
-
(when it fits directly) and will be null when no such wrapping
|
|
1515
|
-
exists.
|
|
1516
|
-
*/
|
|
1517
|
-
findWrapping(target) {
|
|
1518
|
-
for (let i = 0; i < this.wrapCache.length; i += 2) if (this.wrapCache[i] == target) return this.wrapCache[i + 1];
|
|
1519
|
-
let computed = this.computeWrapping(target);
|
|
1520
|
-
this.wrapCache.push(target, computed);
|
|
1521
|
-
return computed;
|
|
1522
|
-
}
|
|
1523
|
-
/**
|
|
1524
|
-
@internal
|
|
1525
|
-
*/
|
|
1526
|
-
computeWrapping(target) {
|
|
1527
|
-
let seen = Object.create(null), active = [{
|
|
1528
|
-
match: this,
|
|
1529
|
-
type: null,
|
|
1530
|
-
via: null
|
|
1531
|
-
}];
|
|
1532
|
-
while (active.length) {
|
|
1533
|
-
let current = active.shift(), match = current.match;
|
|
1534
|
-
if (match.matchType(target)) {
|
|
1535
|
-
let result = [];
|
|
1536
|
-
for (let obj = current; obj.type; obj = obj.via) result.push(obj.type);
|
|
1537
|
-
return result.reverse();
|
|
1538
|
-
}
|
|
1539
|
-
for (let i = 0; i < match.next.length; i++) {
|
|
1540
|
-
let { type, next } = match.next[i];
|
|
1541
|
-
if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) {
|
|
1542
|
-
active.push({
|
|
1543
|
-
match: type.contentMatch,
|
|
1544
|
-
type,
|
|
1545
|
-
via: current
|
|
1546
|
-
});
|
|
1547
|
-
seen[type.name] = true;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
return null;
|
|
1552
|
-
}
|
|
1553
|
-
/**
|
|
1554
|
-
The number of outgoing edges this node has in the finite
|
|
1555
|
-
automaton that describes the content expression.
|
|
1556
|
-
*/
|
|
1557
|
-
get edgeCount() {
|
|
1558
|
-
return this.next.length;
|
|
1559
|
-
}
|
|
1560
|
-
/**
|
|
1561
|
-
Get the _n_th outgoing edge from this node in the finite
|
|
1562
|
-
automaton that describes the content expression.
|
|
1563
|
-
*/
|
|
1564
|
-
edge(n) {
|
|
1565
|
-
if (n >= this.next.length) throw new RangeError(`There's no ${n}th edge in this content match`);
|
|
1566
|
-
return this.next[n];
|
|
1567
|
-
}
|
|
1568
|
-
/**
|
|
1569
|
-
@internal
|
|
1570
|
-
*/
|
|
1571
|
-
toString() {
|
|
1572
|
-
let seen = [];
|
|
1573
|
-
function scan(m) {
|
|
1574
|
-
seen.push(m);
|
|
1575
|
-
for (let i = 0; i < m.next.length; i++) if (seen.indexOf(m.next[i].next) == -1) scan(m.next[i].next);
|
|
1576
|
-
}
|
|
1577
|
-
scan(this);
|
|
1578
|
-
return seen.map((m, i) => {
|
|
1579
|
-
let out = i + (m.validEnd ? "*" : " ") + " ";
|
|
1580
|
-
for (let i = 0; i < m.next.length; i++) out += (i ? ", " : "") + m.next[i].type.name + "->" + seen.indexOf(m.next[i].next);
|
|
1581
|
-
return out;
|
|
1582
|
-
}).join("\n");
|
|
1583
|
-
}
|
|
1584
|
-
};
|
|
1585
|
-
/**
|
|
1586
|
-
@internal
|
|
1587
|
-
*/
|
|
1588
|
-
ContentMatch.empty = new ContentMatch(true);
|
|
1589
|
-
var TokenStream = class {
|
|
1590
|
-
constructor(string, nodeTypes) {
|
|
1591
|
-
this.string = string;
|
|
1592
|
-
this.nodeTypes = nodeTypes;
|
|
1593
|
-
this.inline = null;
|
|
1594
|
-
this.pos = 0;
|
|
1595
|
-
this.tokens = string.split(/\s*(?=\b|\W|$)/);
|
|
1596
|
-
if (this.tokens[this.tokens.length - 1] == "") this.tokens.pop();
|
|
1597
|
-
if (this.tokens[0] == "") this.tokens.shift();
|
|
1598
|
-
}
|
|
1599
|
-
get next() {
|
|
1600
|
-
return this.tokens[this.pos];
|
|
1601
|
-
}
|
|
1602
|
-
eat(tok) {
|
|
1603
|
-
return this.next == tok && (this.pos++ || true);
|
|
1604
|
-
}
|
|
1605
|
-
err(str) {
|
|
1606
|
-
throw new SyntaxError(str + " (in content expression '" + this.string + "')");
|
|
1607
|
-
}
|
|
1608
|
-
};
|
|
1609
|
-
function parseExpr(stream) {
|
|
1610
|
-
let exprs = [];
|
|
1611
|
-
do
|
|
1612
|
-
exprs.push(parseExprSeq(stream));
|
|
1613
|
-
while (stream.eat("|"));
|
|
1614
|
-
return exprs.length == 1 ? exprs[0] : {
|
|
1615
|
-
type: "choice",
|
|
1616
|
-
exprs
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
function parseExprSeq(stream) {
|
|
1620
|
-
let exprs = [];
|
|
1621
|
-
do
|
|
1622
|
-
exprs.push(parseExprSubscript(stream));
|
|
1623
|
-
while (stream.next && stream.next != ")" && stream.next != "|");
|
|
1624
|
-
return exprs.length == 1 ? exprs[0] : {
|
|
1625
|
-
type: "seq",
|
|
1626
|
-
exprs
|
|
1627
|
-
};
|
|
1628
|
-
}
|
|
1629
|
-
function parseExprSubscript(stream) {
|
|
1630
|
-
let expr = parseExprAtom(stream);
|
|
1631
|
-
for (;;) if (stream.eat("+")) expr = {
|
|
1632
|
-
type: "plus",
|
|
1633
|
-
expr
|
|
1634
|
-
};
|
|
1635
|
-
else if (stream.eat("*")) expr = {
|
|
1636
|
-
type: "star",
|
|
1637
|
-
expr
|
|
1638
|
-
};
|
|
1639
|
-
else if (stream.eat("?")) expr = {
|
|
1640
|
-
type: "opt",
|
|
1641
|
-
expr
|
|
1642
|
-
};
|
|
1643
|
-
else if (stream.eat("{")) expr = parseExprRange(stream, expr);
|
|
1644
|
-
else break;
|
|
1645
|
-
return expr;
|
|
1646
|
-
}
|
|
1647
|
-
function parseNum(stream) {
|
|
1648
|
-
if (/\D/.test(stream.next)) stream.err("Expected number, got '" + stream.next + "'");
|
|
1649
|
-
let result = Number(stream.next);
|
|
1650
|
-
stream.pos++;
|
|
1651
|
-
return result;
|
|
1652
|
-
}
|
|
1653
|
-
function parseExprRange(stream, expr) {
|
|
1654
|
-
let min = parseNum(stream), max = min;
|
|
1655
|
-
if (stream.eat(",")) if (stream.next != "}") max = parseNum(stream);
|
|
1656
|
-
else max = -1;
|
|
1657
|
-
if (!stream.eat("}")) stream.err("Unclosed braced range");
|
|
1658
|
-
return {
|
|
1659
|
-
type: "range",
|
|
1660
|
-
min,
|
|
1661
|
-
max,
|
|
1662
|
-
expr
|
|
1663
|
-
};
|
|
1664
|
-
}
|
|
1665
|
-
function resolveName(stream, name) {
|
|
1666
|
-
let types = stream.nodeTypes, type = types[name];
|
|
1667
|
-
if (type) return [type];
|
|
1668
|
-
let result = [];
|
|
1669
|
-
for (let typeName in types) {
|
|
1670
|
-
let type = types[typeName];
|
|
1671
|
-
if (type.isInGroup(name)) result.push(type);
|
|
1672
|
-
}
|
|
1673
|
-
if (result.length == 0) stream.err("No node type or group '" + name + "' found");
|
|
1674
|
-
return result;
|
|
1675
|
-
}
|
|
1676
|
-
function parseExprAtom(stream) {
|
|
1677
|
-
if (stream.eat("(")) {
|
|
1678
|
-
let expr = parseExpr(stream);
|
|
1679
|
-
if (!stream.eat(")")) stream.err("Missing closing paren");
|
|
1680
|
-
return expr;
|
|
1681
|
-
} else if (!/\W/.test(stream.next)) {
|
|
1682
|
-
let exprs = resolveName(stream, stream.next).map((type) => {
|
|
1683
|
-
if (stream.inline == null) stream.inline = type.isInline;
|
|
1684
|
-
else if (stream.inline != type.isInline) stream.err("Mixing inline and block content");
|
|
1685
|
-
return {
|
|
1686
|
-
type: "name",
|
|
1687
|
-
value: type
|
|
1688
|
-
};
|
|
1689
|
-
});
|
|
1690
|
-
stream.pos++;
|
|
1691
|
-
return exprs.length == 1 ? exprs[0] : {
|
|
1692
|
-
type: "choice",
|
|
1693
|
-
exprs
|
|
1694
|
-
};
|
|
1695
|
-
} else stream.err("Unexpected token '" + stream.next + "'");
|
|
1696
|
-
}
|
|
1697
|
-
function nfa(expr) {
|
|
1698
|
-
let nfa = [[]];
|
|
1699
|
-
connect(compile(expr, 0), node());
|
|
1700
|
-
return nfa;
|
|
1701
|
-
function node() {
|
|
1702
|
-
return nfa.push([]) - 1;
|
|
1703
|
-
}
|
|
1704
|
-
function edge(from, to, term) {
|
|
1705
|
-
let edge = {
|
|
1706
|
-
term,
|
|
1707
|
-
to
|
|
1708
|
-
};
|
|
1709
|
-
nfa[from].push(edge);
|
|
1710
|
-
return edge;
|
|
1711
|
-
}
|
|
1712
|
-
function connect(edges, to) {
|
|
1713
|
-
edges.forEach((edge) => edge.to = to);
|
|
1714
|
-
}
|
|
1715
|
-
function compile(expr, from) {
|
|
1716
|
-
if (expr.type == "choice") return expr.exprs.reduce((out, expr) => out.concat(compile(expr, from)), []);
|
|
1717
|
-
else if (expr.type == "seq") for (let i = 0;; i++) {
|
|
1718
|
-
let next = compile(expr.exprs[i], from);
|
|
1719
|
-
if (i == expr.exprs.length - 1) return next;
|
|
1720
|
-
connect(next, from = node());
|
|
1721
|
-
}
|
|
1722
|
-
else if (expr.type == "star") {
|
|
1723
|
-
let loop = node();
|
|
1724
|
-
edge(from, loop);
|
|
1725
|
-
connect(compile(expr.expr, loop), loop);
|
|
1726
|
-
return [edge(loop)];
|
|
1727
|
-
} else if (expr.type == "plus") {
|
|
1728
|
-
let loop = node();
|
|
1729
|
-
connect(compile(expr.expr, from), loop);
|
|
1730
|
-
connect(compile(expr.expr, loop), loop);
|
|
1731
|
-
return [edge(loop)];
|
|
1732
|
-
} else if (expr.type == "opt") return [edge(from)].concat(compile(expr.expr, from));
|
|
1733
|
-
else if (expr.type == "range") {
|
|
1734
|
-
let cur = from;
|
|
1735
|
-
for (let i = 0; i < expr.min; i++) {
|
|
1736
|
-
let next = node();
|
|
1737
|
-
connect(compile(expr.expr, cur), next);
|
|
1738
|
-
cur = next;
|
|
1739
|
-
}
|
|
1740
|
-
if (expr.max == -1) connect(compile(expr.expr, cur), cur);
|
|
1741
|
-
else for (let i = expr.min; i < expr.max; i++) {
|
|
1742
|
-
let next = node();
|
|
1743
|
-
edge(cur, next);
|
|
1744
|
-
connect(compile(expr.expr, cur), next);
|
|
1745
|
-
cur = next;
|
|
1746
|
-
}
|
|
1747
|
-
return [edge(cur)];
|
|
1748
|
-
} else if (expr.type == "name") return [edge(from, void 0, expr.value)];
|
|
1749
|
-
else throw new Error("Unknown expr type");
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
function cmp(a, b) {
|
|
1753
|
-
return b - a;
|
|
1754
|
-
}
|
|
1755
|
-
function nullFrom(nfa, node) {
|
|
1756
|
-
let result = [];
|
|
1757
|
-
scan(node);
|
|
1758
|
-
return result.sort(cmp);
|
|
1759
|
-
function scan(node) {
|
|
1760
|
-
let edges = nfa[node];
|
|
1761
|
-
if (edges.length == 1 && !edges[0].term) return scan(edges[0].to);
|
|
1762
|
-
result.push(node);
|
|
1763
|
-
for (let i = 0; i < edges.length; i++) {
|
|
1764
|
-
let { term, to } = edges[i];
|
|
1765
|
-
if (!term && result.indexOf(to) == -1) scan(to);
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
function dfa(nfa) {
|
|
1770
|
-
let labeled = Object.create(null);
|
|
1771
|
-
return explore(nullFrom(nfa, 0));
|
|
1772
|
-
function explore(states) {
|
|
1773
|
-
let out = [];
|
|
1774
|
-
states.forEach((node) => {
|
|
1775
|
-
nfa[node].forEach(({ term, to }) => {
|
|
1776
|
-
if (!term) return;
|
|
1777
|
-
let set;
|
|
1778
|
-
for (let i = 0; i < out.length; i++) if (out[i][0] == term) set = out[i][1];
|
|
1779
|
-
nullFrom(nfa, to).forEach((node) => {
|
|
1780
|
-
if (!set) out.push([term, set = []]);
|
|
1781
|
-
if (set.indexOf(node) == -1) set.push(node);
|
|
1782
|
-
});
|
|
1783
|
-
});
|
|
1784
|
-
});
|
|
1785
|
-
let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa.length - 1) > -1);
|
|
1786
|
-
for (let i = 0; i < out.length; i++) {
|
|
1787
|
-
let states = out[i][1].sort(cmp);
|
|
1788
|
-
state.next.push({
|
|
1789
|
-
type: out[i][0],
|
|
1790
|
-
next: labeled[states.join(",")] || explore(states)
|
|
1791
|
-
});
|
|
1792
|
-
}
|
|
1793
|
-
return state;
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
function checkForDeadEnds(match, stream) {
|
|
1797
|
-
for (let i = 0, work = [match]; i < work.length; i++) {
|
|
1798
|
-
let state = work[i], dead = !state.validEnd, nodes = [];
|
|
1799
|
-
for (let j = 0; j < state.next.length; j++) {
|
|
1800
|
-
let { type, next } = state.next[j];
|
|
1801
|
-
nodes.push(type.name);
|
|
1802
|
-
if (dead && !(type.isText || type.hasRequiredAttrs())) dead = false;
|
|
1803
|
-
if (work.indexOf(next) == -1) work.push(next);
|
|
1804
|
-
}
|
|
1805
|
-
if (dead) stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
//#endregion
|
|
1809
|
-
//#region ../../node_modules/.pnpm/prosemirror-transform@1.12.0/node_modules/prosemirror-transform/dist/index.js
|
|
1810
|
-
var lower16 = 65535;
|
|
1811
|
-
var factor16 = Math.pow(2, 16);
|
|
1812
|
-
function makeRecover(index, offset) {
|
|
1813
|
-
return index + offset * factor16;
|
|
1814
|
-
}
|
|
1815
|
-
function recoverIndex(value) {
|
|
1816
|
-
return value & lower16;
|
|
1817
|
-
}
|
|
1818
|
-
function recoverOffset(value) {
|
|
1819
|
-
return (value - (value & lower16)) / factor16;
|
|
1820
|
-
}
|
|
1821
|
-
var DEL_BEFORE = 1, DEL_AFTER = 2, DEL_ACROSS = 4, DEL_SIDE = 8;
|
|
1822
|
-
/**
|
|
1823
|
-
An object representing a mapped position with extra
|
|
1824
|
-
information.
|
|
1825
|
-
*/
|
|
1826
|
-
var MapResult = class {
|
|
1827
|
-
/**
|
|
1828
|
-
@internal
|
|
1829
|
-
*/
|
|
1830
|
-
constructor(pos, delInfo, recover) {
|
|
1831
|
-
this.pos = pos;
|
|
1832
|
-
this.delInfo = delInfo;
|
|
1833
|
-
this.recover = recover;
|
|
1834
|
-
}
|
|
1835
|
-
/**
|
|
1836
|
-
Tells you whether the position was deleted, that is, whether the
|
|
1837
|
-
step removed the token on the side queried (via the `assoc`)
|
|
1838
|
-
argument from the document.
|
|
1839
|
-
*/
|
|
1840
|
-
get deleted() {
|
|
1841
|
-
return (this.delInfo & DEL_SIDE) > 0;
|
|
1842
|
-
}
|
|
1843
|
-
/**
|
|
1844
|
-
Tells you whether the token before the mapped position was deleted.
|
|
1845
|
-
*/
|
|
1846
|
-
get deletedBefore() {
|
|
1847
|
-
return (this.delInfo & 5) > 0;
|
|
1848
|
-
}
|
|
1849
|
-
/**
|
|
1850
|
-
True when the token after the mapped position was deleted.
|
|
1851
|
-
*/
|
|
1852
|
-
get deletedAfter() {
|
|
1853
|
-
return (this.delInfo & 6) > 0;
|
|
1854
|
-
}
|
|
1855
|
-
/**
|
|
1856
|
-
Tells whether any of the steps mapped through deletes across the
|
|
1857
|
-
position (including both the token before and after the
|
|
1858
|
-
position).
|
|
1859
|
-
*/
|
|
1860
|
-
get deletedAcross() {
|
|
1861
|
-
return (this.delInfo & DEL_ACROSS) > 0;
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
|
-
/**
|
|
1865
|
-
A map describing the deletions and insertions made by a step, which
|
|
1866
|
-
can be used to find the correspondence between positions in the
|
|
1867
|
-
pre-step version of a document and the same position in the
|
|
1868
|
-
post-step version.
|
|
1869
|
-
*/
|
|
1870
|
-
var StepMap = class StepMap {
|
|
1871
|
-
/**
|
|
1872
|
-
Create a position map. The modifications to the document are
|
|
1873
|
-
represented as an array of numbers, in which each group of three
|
|
1874
|
-
represents a modified chunk as `[start, oldSize, newSize]`.
|
|
1875
|
-
*/
|
|
1876
|
-
constructor(ranges, inverted = false) {
|
|
1877
|
-
this.ranges = ranges;
|
|
1878
|
-
this.inverted = inverted;
|
|
1879
|
-
if (!ranges.length && StepMap.empty) return StepMap.empty;
|
|
1880
|
-
}
|
|
1881
|
-
/**
|
|
1882
|
-
@internal
|
|
1883
|
-
*/
|
|
1884
|
-
recover(value) {
|
|
1885
|
-
let diff = 0, index = recoverIndex(value);
|
|
1886
|
-
if (!this.inverted) for (let i = 0; i < index; i++) diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1];
|
|
1887
|
-
return this.ranges[index * 3] + diff + recoverOffset(value);
|
|
1888
|
-
}
|
|
1889
|
-
mapResult(pos, assoc = 1) {
|
|
1890
|
-
return this._map(pos, assoc, false);
|
|
1891
|
-
}
|
|
1892
|
-
map(pos, assoc = 1) {
|
|
1893
|
-
return this._map(pos, assoc, true);
|
|
1894
|
-
}
|
|
1895
|
-
/**
|
|
1896
|
-
@internal
|
|
1897
|
-
*/
|
|
1898
|
-
_map(pos, assoc, simple) {
|
|
1899
|
-
let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
1900
|
-
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
1901
|
-
let start = this.ranges[i] - (this.inverted ? diff : 0);
|
|
1902
|
-
if (start > pos) break;
|
|
1903
|
-
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize;
|
|
1904
|
-
if (pos <= end) {
|
|
1905
|
-
let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc;
|
|
1906
|
-
let result = start + diff + (side < 0 ? 0 : newSize);
|
|
1907
|
-
if (simple) return result;
|
|
1908
|
-
let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
|
|
1909
|
-
let del = pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS;
|
|
1910
|
-
if (assoc < 0 ? pos != start : pos != end) del |= DEL_SIDE;
|
|
1911
|
-
return new MapResult(result, del, recover);
|
|
1912
|
-
}
|
|
1913
|
-
diff += newSize - oldSize;
|
|
1914
|
-
}
|
|
1915
|
-
return simple ? pos + diff : new MapResult(pos + diff, 0, null);
|
|
1916
|
-
}
|
|
1917
|
-
/**
|
|
1918
|
-
@internal
|
|
1919
|
-
*/
|
|
1920
|
-
touches(pos, recover) {
|
|
1921
|
-
let diff = 0, index = recoverIndex(recover);
|
|
1922
|
-
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
1923
|
-
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
1924
|
-
let start = this.ranges[i] - (this.inverted ? diff : 0);
|
|
1925
|
-
if (start > pos) break;
|
|
1926
|
-
let oldSize = this.ranges[i + oldIndex];
|
|
1927
|
-
if (pos <= start + oldSize && i == index * 3) return true;
|
|
1928
|
-
diff += this.ranges[i + newIndex] - oldSize;
|
|
1929
|
-
}
|
|
1930
|
-
return false;
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
Calls the given function on each of the changed ranges included in
|
|
1934
|
-
this map.
|
|
1935
|
-
*/
|
|
1936
|
-
forEach(f) {
|
|
1937
|
-
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
1938
|
-
for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {
|
|
1939
|
-
let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff);
|
|
1940
|
-
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex];
|
|
1941
|
-
f(oldStart, oldStart + oldSize, newStart, newStart + newSize);
|
|
1942
|
-
diff += newSize - oldSize;
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
/**
|
|
1946
|
-
Create an inverted version of this map. The result can be used to
|
|
1947
|
-
map positions in the post-step document to the pre-step document.
|
|
1948
|
-
*/
|
|
1949
|
-
invert() {
|
|
1950
|
-
return new StepMap(this.ranges, !this.inverted);
|
|
1951
|
-
}
|
|
1952
|
-
/**
|
|
1953
|
-
@internal
|
|
1954
|
-
*/
|
|
1955
|
-
toString() {
|
|
1956
|
-
return (this.inverted ? "-" : "") + JSON.stringify(this.ranges);
|
|
1957
|
-
}
|
|
1958
|
-
/**
|
|
1959
|
-
Create a map that moves all positions by offset `n` (which may be
|
|
1960
|
-
negative). This can be useful when applying steps meant for a
|
|
1961
|
-
sub-document to a larger document, or vice-versa.
|
|
1962
|
-
*/
|
|
1963
|
-
static offset(n) {
|
|
1964
|
-
return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [
|
|
1965
|
-
0,
|
|
1966
|
-
-n,
|
|
1967
|
-
0
|
|
1968
|
-
] : [
|
|
1969
|
-
0,
|
|
1970
|
-
0,
|
|
1971
|
-
n
|
|
1972
|
-
]);
|
|
1973
|
-
}
|
|
1974
|
-
};
|
|
1975
|
-
/**
|
|
1976
|
-
A StepMap that contains no changed ranges.
|
|
1977
|
-
*/
|
|
1978
|
-
StepMap.empty = new StepMap([]);
|
|
1979
|
-
var stepsByID = Object.create(null);
|
|
1980
|
-
/**
|
|
1981
|
-
A step object represents an atomic change. It generally applies
|
|
1982
|
-
only to the document it was created for, since the positions
|
|
1983
|
-
stored in it will only make sense for that document.
|
|
1984
|
-
|
|
1985
|
-
New steps are defined by creating classes that extend `Step`,
|
|
1986
|
-
overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`
|
|
1987
|
-
methods, and registering your class with a unique
|
|
1988
|
-
JSON-serialization identifier using
|
|
1989
|
-
[`Step.jsonID`](https://prosemirror.net/docs/ref/#transform.Step^jsonID).
|
|
1990
|
-
*/
|
|
1991
|
-
var Step = class {
|
|
1992
|
-
/**
|
|
1993
|
-
Get the step map that represents the changes made by this step,
|
|
1994
|
-
and which can be used to transform between positions in the old
|
|
1995
|
-
and the new document.
|
|
1996
|
-
*/
|
|
1997
|
-
getMap() {
|
|
1998
|
-
return StepMap.empty;
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
Try to merge this step with another one, to be applied directly
|
|
2002
|
-
after it. Returns the merged step when possible, null if the
|
|
2003
|
-
steps can't be merged.
|
|
2004
|
-
*/
|
|
2005
|
-
merge(other) {
|
|
2006
|
-
return null;
|
|
2007
|
-
}
|
|
2008
|
-
/**
|
|
2009
|
-
Deserialize a step from its JSON representation. Will call
|
|
2010
|
-
through to the step class' own implementation of this method.
|
|
2011
|
-
*/
|
|
2012
|
-
static fromJSON(schema, json) {
|
|
2013
|
-
if (!json || !json.stepType) throw new RangeError("Invalid input for Step.fromJSON");
|
|
2014
|
-
let type = stepsByID[json.stepType];
|
|
2015
|
-
if (!type) throw new RangeError(`No step type ${json.stepType} defined`);
|
|
2016
|
-
return type.fromJSON(schema, json);
|
|
2017
|
-
}
|
|
2018
|
-
/**
|
|
2019
|
-
To be able to serialize steps to JSON, each step needs a string
|
|
2020
|
-
ID to attach to its JSON representation. Use this method to
|
|
2021
|
-
register an ID for your step classes. Try to pick something
|
|
2022
|
-
that's unlikely to clash with steps from other modules.
|
|
2023
|
-
*/
|
|
2024
|
-
static jsonID(id, stepClass) {
|
|
2025
|
-
if (id in stepsByID) throw new RangeError("Duplicate use of step JSON ID " + id);
|
|
2026
|
-
stepsByID[id] = stepClass;
|
|
2027
|
-
stepClass.prototype.jsonID = id;
|
|
2028
|
-
return stepClass;
|
|
2029
|
-
}
|
|
2030
|
-
};
|
|
2031
|
-
/**
|
|
2032
|
-
The result of [applying](https://prosemirror.net/docs/ref/#transform.Step.apply) a step. Contains either a
|
|
2033
|
-
new document or a failure value.
|
|
2034
|
-
*/
|
|
2035
|
-
var StepResult = class StepResult {
|
|
2036
|
-
/**
|
|
2037
|
-
@internal
|
|
2038
|
-
*/
|
|
2039
|
-
constructor(doc, failed) {
|
|
2040
|
-
this.doc = doc;
|
|
2041
|
-
this.failed = failed;
|
|
2042
|
-
}
|
|
2043
|
-
/**
|
|
2044
|
-
Create a successful step result.
|
|
2045
|
-
*/
|
|
2046
|
-
static ok(doc) {
|
|
2047
|
-
return new StepResult(doc, null);
|
|
2048
|
-
}
|
|
2049
|
-
/**
|
|
2050
|
-
Create a failed step result.
|
|
2051
|
-
*/
|
|
2052
|
-
static fail(message) {
|
|
2053
|
-
return new StepResult(null, message);
|
|
2054
|
-
}
|
|
2055
|
-
/**
|
|
2056
|
-
Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given
|
|
2057
|
-
arguments. Create a successful result if it succeeds, and a
|
|
2058
|
-
failed one if it throws a `ReplaceError`.
|
|
2059
|
-
*/
|
|
2060
|
-
static fromReplace(doc, from, to, slice) {
|
|
2061
|
-
try {
|
|
2062
|
-
return StepResult.ok(doc.replace(from, to, slice));
|
|
2063
|
-
} catch (e) {
|
|
2064
|
-
if (e instanceof ReplaceError) return StepResult.fail(e.message);
|
|
2065
|
-
throw e;
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
};
|
|
2069
|
-
function mapFragment(fragment, f, parent) {
|
|
2070
|
-
let mapped = [];
|
|
2071
|
-
for (let i = 0; i < fragment.childCount; i++) {
|
|
2072
|
-
let child = fragment.child(i);
|
|
2073
|
-
if (child.content.size) child = child.copy(mapFragment(child.content, f, child));
|
|
2074
|
-
if (child.isInline) child = f(child, parent, i);
|
|
2075
|
-
mapped.push(child);
|
|
2076
|
-
}
|
|
2077
|
-
return Fragment$1.fromArray(mapped);
|
|
2078
|
-
}
|
|
2079
|
-
/**
|
|
2080
|
-
Add a mark to all inline content between two positions.
|
|
2081
|
-
*/
|
|
2082
|
-
var AddMarkStep = class AddMarkStep extends Step {
|
|
2083
|
-
/**
|
|
2084
|
-
Create a mark step.
|
|
2085
|
-
*/
|
|
2086
|
-
constructor(from, to, mark) {
|
|
2087
|
-
super();
|
|
2088
|
-
this.from = from;
|
|
2089
|
-
this.to = to;
|
|
2090
|
-
this.mark = mark;
|
|
2091
|
-
}
|
|
2092
|
-
apply(doc) {
|
|
2093
|
-
let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from);
|
|
2094
|
-
let parent = $from.node($from.sharedDepth(this.to));
|
|
2095
|
-
let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {
|
|
2096
|
-
if (!node.isAtom || !parent.type.allowsMarkType(this.mark.type)) return node;
|
|
2097
|
-
return node.mark(this.mark.addToSet(node.marks));
|
|
2098
|
-
}, parent), oldSlice.openStart, oldSlice.openEnd);
|
|
2099
|
-
return StepResult.fromReplace(doc, this.from, this.to, slice);
|
|
2100
|
-
}
|
|
2101
|
-
invert() {
|
|
2102
|
-
return new RemoveMarkStep(this.from, this.to, this.mark);
|
|
2103
|
-
}
|
|
2104
|
-
map(mapping) {
|
|
2105
|
-
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
2106
|
-
if (from.deleted && to.deleted || from.pos >= to.pos) return null;
|
|
2107
|
-
return new AddMarkStep(from.pos, to.pos, this.mark);
|
|
2108
|
-
}
|
|
2109
|
-
merge(other) {
|
|
2110
|
-
if (other instanceof AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) return new AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
2111
|
-
return null;
|
|
2112
|
-
}
|
|
2113
|
-
toJSON() {
|
|
2114
|
-
return {
|
|
2115
|
-
stepType: "addMark",
|
|
2116
|
-
mark: this.mark.toJSON(),
|
|
2117
|
-
from: this.from,
|
|
2118
|
-
to: this.to
|
|
2119
|
-
};
|
|
2120
|
-
}
|
|
2121
|
-
/**
|
|
2122
|
-
@internal
|
|
2123
|
-
*/
|
|
2124
|
-
static fromJSON(schema, json) {
|
|
2125
|
-
if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for AddMarkStep.fromJSON");
|
|
2126
|
-
return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
2127
|
-
}
|
|
2128
|
-
};
|
|
2129
|
-
Step.jsonID("addMark", AddMarkStep);
|
|
2130
|
-
/**
|
|
2131
|
-
Remove a mark from all inline content between two positions.
|
|
2132
|
-
*/
|
|
2133
|
-
var RemoveMarkStep = class RemoveMarkStep extends Step {
|
|
2134
|
-
/**
|
|
2135
|
-
Create a mark-removing step.
|
|
2136
|
-
*/
|
|
2137
|
-
constructor(from, to, mark) {
|
|
2138
|
-
super();
|
|
2139
|
-
this.from = from;
|
|
2140
|
-
this.to = to;
|
|
2141
|
-
this.mark = mark;
|
|
2142
|
-
}
|
|
2143
|
-
apply(doc) {
|
|
2144
|
-
let oldSlice = doc.slice(this.from, this.to);
|
|
2145
|
-
let slice = new Slice(mapFragment(oldSlice.content, (node) => {
|
|
2146
|
-
return node.mark(this.mark.removeFromSet(node.marks));
|
|
2147
|
-
}, doc), oldSlice.openStart, oldSlice.openEnd);
|
|
2148
|
-
return StepResult.fromReplace(doc, this.from, this.to, slice);
|
|
2149
|
-
}
|
|
2150
|
-
invert() {
|
|
2151
|
-
return new AddMarkStep(this.from, this.to, this.mark);
|
|
2152
|
-
}
|
|
2153
|
-
map(mapping) {
|
|
2154
|
-
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
2155
|
-
if (from.deleted && to.deleted || from.pos >= to.pos) return null;
|
|
2156
|
-
return new RemoveMarkStep(from.pos, to.pos, this.mark);
|
|
2157
|
-
}
|
|
2158
|
-
merge(other) {
|
|
2159
|
-
if (other instanceof RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) return new RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
2160
|
-
return null;
|
|
2161
|
-
}
|
|
2162
|
-
toJSON() {
|
|
2163
|
-
return {
|
|
2164
|
-
stepType: "removeMark",
|
|
2165
|
-
mark: this.mark.toJSON(),
|
|
2166
|
-
from: this.from,
|
|
2167
|
-
to: this.to
|
|
2168
|
-
};
|
|
2169
|
-
}
|
|
2170
|
-
/**
|
|
2171
|
-
@internal
|
|
2172
|
-
*/
|
|
2173
|
-
static fromJSON(schema, json) {
|
|
2174
|
-
if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");
|
|
2175
|
-
return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
2176
|
-
}
|
|
2177
|
-
};
|
|
2178
|
-
Step.jsonID("removeMark", RemoveMarkStep);
|
|
2179
|
-
/**
|
|
2180
|
-
Add a mark to a specific node.
|
|
2181
|
-
*/
|
|
2182
|
-
var AddNodeMarkStep = class AddNodeMarkStep extends Step {
|
|
2183
|
-
/**
|
|
2184
|
-
Create a node mark step.
|
|
2185
|
-
*/
|
|
2186
|
-
constructor(pos, mark) {
|
|
2187
|
-
super();
|
|
2188
|
-
this.pos = pos;
|
|
2189
|
-
this.mark = mark;
|
|
2190
|
-
}
|
|
2191
|
-
apply(doc) {
|
|
2192
|
-
let node = doc.nodeAt(this.pos);
|
|
2193
|
-
if (!node) return StepResult.fail("No node at mark step's position");
|
|
2194
|
-
let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
2195
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$1.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
2196
|
-
}
|
|
2197
|
-
invert(doc) {
|
|
2198
|
-
let node = doc.nodeAt(this.pos);
|
|
2199
|
-
if (node) {
|
|
2200
|
-
let newSet = this.mark.addToSet(node.marks);
|
|
2201
|
-
if (newSet.length == node.marks.length) {
|
|
2202
|
-
for (let i = 0; i < node.marks.length; i++) if (!node.marks[i].isInSet(newSet)) return new AddNodeMarkStep(this.pos, node.marks[i]);
|
|
2203
|
-
return new AddNodeMarkStep(this.pos, this.mark);
|
|
2204
|
-
}
|
|
2205
|
-
}
|
|
2206
|
-
return new RemoveNodeMarkStep(this.pos, this.mark);
|
|
2207
|
-
}
|
|
2208
|
-
map(mapping) {
|
|
2209
|
-
let pos = mapping.mapResult(this.pos, 1);
|
|
2210
|
-
return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
|
|
2211
|
-
}
|
|
2212
|
-
toJSON() {
|
|
2213
|
-
return {
|
|
2214
|
-
stepType: "addNodeMark",
|
|
2215
|
-
pos: this.pos,
|
|
2216
|
-
mark: this.mark.toJSON()
|
|
2217
|
-
};
|
|
2218
|
-
}
|
|
2219
|
-
/**
|
|
2220
|
-
@internal
|
|
2221
|
-
*/
|
|
2222
|
-
static fromJSON(schema, json) {
|
|
2223
|
-
if (typeof json.pos != "number") throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");
|
|
2224
|
-
return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
2225
|
-
}
|
|
2226
|
-
};
|
|
2227
|
-
Step.jsonID("addNodeMark", AddNodeMarkStep);
|
|
2228
|
-
/**
|
|
2229
|
-
Remove a mark from a specific node.
|
|
2230
|
-
*/
|
|
2231
|
-
var RemoveNodeMarkStep = class RemoveNodeMarkStep extends Step {
|
|
2232
|
-
/**
|
|
2233
|
-
Create a mark-removing step.
|
|
2234
|
-
*/
|
|
2235
|
-
constructor(pos, mark) {
|
|
2236
|
-
super();
|
|
2237
|
-
this.pos = pos;
|
|
2238
|
-
this.mark = mark;
|
|
2239
|
-
}
|
|
2240
|
-
apply(doc) {
|
|
2241
|
-
let node = doc.nodeAt(this.pos);
|
|
2242
|
-
if (!node) return StepResult.fail("No node at mark step's position");
|
|
2243
|
-
let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
|
|
2244
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$1.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
2245
|
-
}
|
|
2246
|
-
invert(doc) {
|
|
2247
|
-
let node = doc.nodeAt(this.pos);
|
|
2248
|
-
if (!node || !this.mark.isInSet(node.marks)) return this;
|
|
2249
|
-
return new AddNodeMarkStep(this.pos, this.mark);
|
|
2250
|
-
}
|
|
2251
|
-
map(mapping) {
|
|
2252
|
-
let pos = mapping.mapResult(this.pos, 1);
|
|
2253
|
-
return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
|
|
2254
|
-
}
|
|
2255
|
-
toJSON() {
|
|
2256
|
-
return {
|
|
2257
|
-
stepType: "removeNodeMark",
|
|
2258
|
-
pos: this.pos,
|
|
2259
|
-
mark: this.mark.toJSON()
|
|
2260
|
-
};
|
|
2261
|
-
}
|
|
2262
|
-
/**
|
|
2263
|
-
@internal
|
|
2264
|
-
*/
|
|
2265
|
-
static fromJSON(schema, json) {
|
|
2266
|
-
if (typeof json.pos != "number") throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");
|
|
2267
|
-
return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
2268
|
-
}
|
|
2269
|
-
};
|
|
2270
|
-
Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
|
|
2271
|
-
/**
|
|
2272
|
-
Replace a part of the document with a slice of new content.
|
|
2273
|
-
*/
|
|
2274
|
-
var ReplaceStep = class ReplaceStep extends Step {
|
|
2275
|
-
/**
|
|
2276
|
-
The given `slice` should fit the 'gap' between `from` and
|
|
2277
|
-
`to`—the depths must line up, and the surrounding nodes must be
|
|
2278
|
-
able to be joined with the open sides of the slice. When
|
|
2279
|
-
`structure` is true, the step will fail if the content between
|
|
2280
|
-
from and to is not just a sequence of closing and then opening
|
|
2281
|
-
tokens (this is to guard against rebased replace steps
|
|
2282
|
-
overwriting something they weren't supposed to).
|
|
2283
|
-
*/
|
|
2284
|
-
constructor(from, to, slice, structure = false) {
|
|
2285
|
-
super();
|
|
2286
|
-
this.from = from;
|
|
2287
|
-
this.to = to;
|
|
2288
|
-
this.slice = slice;
|
|
2289
|
-
this.structure = structure;
|
|
2290
|
-
}
|
|
2291
|
-
apply(doc) {
|
|
2292
|
-
if (this.structure && contentBetween(doc, this.from, this.to)) return StepResult.fail("Structure replace would overwrite content");
|
|
2293
|
-
return StepResult.fromReplace(doc, this.from, this.to, this.slice);
|
|
2294
|
-
}
|
|
2295
|
-
getMap() {
|
|
2296
|
-
return new StepMap([
|
|
2297
|
-
this.from,
|
|
2298
|
-
this.to - this.from,
|
|
2299
|
-
this.slice.size
|
|
2300
|
-
]);
|
|
2301
|
-
}
|
|
2302
|
-
invert(doc) {
|
|
2303
|
-
return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
|
|
2304
|
-
}
|
|
2305
|
-
map(mapping) {
|
|
2306
|
-
let to = mapping.mapResult(this.to, -1);
|
|
2307
|
-
let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
|
|
2308
|
-
if (from.deletedAcross && to.deletedAcross) return null;
|
|
2309
|
-
return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
|
|
2310
|
-
}
|
|
2311
|
-
merge(other) {
|
|
2312
|
-
if (!(other instanceof ReplaceStep) || other.structure || this.structure) return null;
|
|
2313
|
-
if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {
|
|
2314
|
-
let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd);
|
|
2315
|
-
return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure);
|
|
2316
|
-
} else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {
|
|
2317
|
-
let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd);
|
|
2318
|
-
return new ReplaceStep(other.from, this.to, slice, this.structure);
|
|
2319
|
-
} else return null;
|
|
2320
|
-
}
|
|
2321
|
-
toJSON() {
|
|
2322
|
-
let json = {
|
|
2323
|
-
stepType: "replace",
|
|
2324
|
-
from: this.from,
|
|
2325
|
-
to: this.to
|
|
2326
|
-
};
|
|
2327
|
-
if (this.slice.size) json.slice = this.slice.toJSON();
|
|
2328
|
-
if (this.structure) json.structure = true;
|
|
2329
|
-
return json;
|
|
2330
|
-
}
|
|
2331
|
-
/**
|
|
2332
|
-
@internal
|
|
2333
|
-
*/
|
|
2334
|
-
static fromJSON(schema, json) {
|
|
2335
|
-
if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for ReplaceStep.fromJSON");
|
|
2336
|
-
return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
|
|
2337
|
-
}
|
|
2338
|
-
};
|
|
2339
|
-
/**
|
|
2340
|
-
By default, for backwards compatibility, an inserting step
|
|
2341
|
-
mapped over an insertion at that same position fill move after
|
|
2342
|
-
the inserted content. In a collaborative editing situation, that
|
|
2343
|
-
can make redone insertions appear in unexpected places. You can
|
|
2344
|
-
set this to -1 to make such mapping keep the step before the
|
|
2345
|
-
insertion instead.
|
|
2346
|
-
*/
|
|
2347
|
-
ReplaceStep.MAP_BIAS = 1;
|
|
2348
|
-
Step.jsonID("replace", ReplaceStep);
|
|
2349
|
-
/**
|
|
2350
|
-
Replace a part of the document with a slice of content, but
|
|
2351
|
-
preserve a range of the replaced content by moving it into the
|
|
2352
|
-
slice.
|
|
2353
|
-
*/
|
|
2354
|
-
var ReplaceAroundStep = class ReplaceAroundStep extends Step {
|
|
2355
|
-
/**
|
|
2356
|
-
Create a replace-around step with the given range and gap.
|
|
2357
|
-
`insert` should be the point in the slice into which the content
|
|
2358
|
-
of the gap should be moved. `structure` has the same meaning as
|
|
2359
|
-
it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class.
|
|
2360
|
-
*/
|
|
2361
|
-
constructor(from, to, gapFrom, gapTo, slice, insert, structure = false) {
|
|
2362
|
-
super();
|
|
2363
|
-
this.from = from;
|
|
2364
|
-
this.to = to;
|
|
2365
|
-
this.gapFrom = gapFrom;
|
|
2366
|
-
this.gapTo = gapTo;
|
|
2367
|
-
this.slice = slice;
|
|
2368
|
-
this.insert = insert;
|
|
2369
|
-
this.structure = structure;
|
|
2370
|
-
}
|
|
2371
|
-
apply(doc) {
|
|
2372
|
-
if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || contentBetween(doc, this.gapTo, this.to))) return StepResult.fail("Structure gap-replace would overwrite content");
|
|
2373
|
-
let gap = doc.slice(this.gapFrom, this.gapTo);
|
|
2374
|
-
if (gap.openStart || gap.openEnd) return StepResult.fail("Gap is not a flat range");
|
|
2375
|
-
let inserted = this.slice.insertAt(this.insert, gap.content);
|
|
2376
|
-
if (!inserted) return StepResult.fail("Content does not fit in gap");
|
|
2377
|
-
return StepResult.fromReplace(doc, this.from, this.to, inserted);
|
|
2378
|
-
}
|
|
2379
|
-
getMap() {
|
|
2380
|
-
return new StepMap([
|
|
2381
|
-
this.from,
|
|
2382
|
-
this.gapFrom - this.from,
|
|
2383
|
-
this.insert,
|
|
2384
|
-
this.gapTo,
|
|
2385
|
-
this.to - this.gapTo,
|
|
2386
|
-
this.slice.size - this.insert
|
|
2387
|
-
]);
|
|
2388
|
-
}
|
|
2389
|
-
invert(doc) {
|
|
2390
|
-
let gap = this.gapTo - this.gapFrom;
|
|
2391
|
-
return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure);
|
|
2392
|
-
}
|
|
2393
|
-
map(mapping) {
|
|
2394
|
-
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
2395
|
-
let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1);
|
|
2396
|
-
let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1);
|
|
2397
|
-
if (from.deletedAcross && to.deletedAcross || gapFrom < from.pos || gapTo > to.pos) return null;
|
|
2398
|
-
return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure);
|
|
2399
|
-
}
|
|
2400
|
-
toJSON() {
|
|
2401
|
-
let json = {
|
|
2402
|
-
stepType: "replaceAround",
|
|
2403
|
-
from: this.from,
|
|
2404
|
-
to: this.to,
|
|
2405
|
-
gapFrom: this.gapFrom,
|
|
2406
|
-
gapTo: this.gapTo,
|
|
2407
|
-
insert: this.insert
|
|
2408
|
-
};
|
|
2409
|
-
if (this.slice.size) json.slice = this.slice.toJSON();
|
|
2410
|
-
if (this.structure) json.structure = true;
|
|
2411
|
-
return json;
|
|
2412
|
-
}
|
|
2413
|
-
/**
|
|
2414
|
-
@internal
|
|
2415
|
-
*/
|
|
2416
|
-
static fromJSON(schema, json) {
|
|
2417
|
-
if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");
|
|
2418
|
-
return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure);
|
|
2419
|
-
}
|
|
2420
|
-
};
|
|
2421
|
-
Step.jsonID("replaceAround", ReplaceAroundStep);
|
|
2422
|
-
function contentBetween(doc, from, to) {
|
|
2423
|
-
let $from = doc.resolve(from), dist = to - from, depth = $from.depth;
|
|
2424
|
-
while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {
|
|
2425
|
-
depth--;
|
|
2426
|
-
dist--;
|
|
2427
|
-
}
|
|
2428
|
-
if (dist > 0) {
|
|
2429
|
-
let next = $from.node(depth).maybeChild($from.indexAfter(depth));
|
|
2430
|
-
while (dist > 0) {
|
|
2431
|
-
if (!next || next.isLeaf) return true;
|
|
2432
|
-
next = next.firstChild;
|
|
2433
|
-
dist--;
|
|
2434
|
-
}
|
|
2435
|
-
}
|
|
2436
|
-
return false;
|
|
2437
|
-
}
|
|
2438
|
-
/**
|
|
2439
|
-
Update an attribute in a specific node.
|
|
2440
|
-
*/
|
|
2441
|
-
var AttrStep = class AttrStep extends Step {
|
|
2442
|
-
/**
|
|
2443
|
-
Construct an attribute step.
|
|
2444
|
-
*/
|
|
2445
|
-
constructor(pos, attr, value) {
|
|
2446
|
-
super();
|
|
2447
|
-
this.pos = pos;
|
|
2448
|
-
this.attr = attr;
|
|
2449
|
-
this.value = value;
|
|
2450
|
-
}
|
|
2451
|
-
apply(doc) {
|
|
2452
|
-
let node = doc.nodeAt(this.pos);
|
|
2453
|
-
if (!node) return StepResult.fail("No node at attribute step's position");
|
|
2454
|
-
let attrs = Object.create(null);
|
|
2455
|
-
for (let name in node.attrs) attrs[name] = node.attrs[name];
|
|
2456
|
-
attrs[this.attr] = this.value;
|
|
2457
|
-
let updated = node.type.create(attrs, null, node.marks);
|
|
2458
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$1.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
2459
|
-
}
|
|
2460
|
-
getMap() {
|
|
2461
|
-
return StepMap.empty;
|
|
2462
|
-
}
|
|
2463
|
-
invert(doc) {
|
|
2464
|
-
return new AttrStep(this.pos, this.attr, doc.nodeAt(this.pos).attrs[this.attr]);
|
|
2465
|
-
}
|
|
2466
|
-
map(mapping) {
|
|
2467
|
-
let pos = mapping.mapResult(this.pos, 1);
|
|
2468
|
-
return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
|
|
2469
|
-
}
|
|
2470
|
-
toJSON() {
|
|
2471
|
-
return {
|
|
2472
|
-
stepType: "attr",
|
|
2473
|
-
pos: this.pos,
|
|
2474
|
-
attr: this.attr,
|
|
2475
|
-
value: this.value
|
|
2476
|
-
};
|
|
2477
|
-
}
|
|
2478
|
-
static fromJSON(schema, json) {
|
|
2479
|
-
if (typeof json.pos != "number" || typeof json.attr != "string") throw new RangeError("Invalid input for AttrStep.fromJSON");
|
|
2480
|
-
return new AttrStep(json.pos, json.attr, json.value);
|
|
2481
|
-
}
|
|
2482
|
-
};
|
|
2483
|
-
Step.jsonID("attr", AttrStep);
|
|
2484
|
-
/**
|
|
2485
|
-
Update an attribute in the doc node.
|
|
2486
|
-
*/
|
|
2487
|
-
var DocAttrStep = class DocAttrStep extends Step {
|
|
2488
|
-
/**
|
|
2489
|
-
Construct an attribute step.
|
|
2490
|
-
*/
|
|
2491
|
-
constructor(attr, value) {
|
|
2492
|
-
super();
|
|
2493
|
-
this.attr = attr;
|
|
2494
|
-
this.value = value;
|
|
2495
|
-
}
|
|
2496
|
-
apply(doc) {
|
|
2497
|
-
let attrs = Object.create(null);
|
|
2498
|
-
for (let name in doc.attrs) attrs[name] = doc.attrs[name];
|
|
2499
|
-
attrs[this.attr] = this.value;
|
|
2500
|
-
let updated = doc.type.create(attrs, doc.content, doc.marks);
|
|
2501
|
-
return StepResult.ok(updated);
|
|
2502
|
-
}
|
|
2503
|
-
getMap() {
|
|
2504
|
-
return StepMap.empty;
|
|
2505
|
-
}
|
|
2506
|
-
invert(doc) {
|
|
2507
|
-
return new DocAttrStep(this.attr, doc.attrs[this.attr]);
|
|
2508
|
-
}
|
|
2509
|
-
map(mapping) {
|
|
2510
|
-
return this;
|
|
2511
|
-
}
|
|
2512
|
-
toJSON() {
|
|
2513
|
-
return {
|
|
2514
|
-
stepType: "docAttr",
|
|
2515
|
-
attr: this.attr,
|
|
2516
|
-
value: this.value
|
|
2517
|
-
};
|
|
2518
|
-
}
|
|
2519
|
-
static fromJSON(schema, json) {
|
|
2520
|
-
if (typeof json.attr != "string") throw new RangeError("Invalid input for DocAttrStep.fromJSON");
|
|
2521
|
-
return new DocAttrStep(json.attr, json.value);
|
|
2522
|
-
}
|
|
2523
|
-
};
|
|
2524
|
-
Step.jsonID("docAttr", DocAttrStep);
|
|
2525
|
-
/**
|
|
2526
|
-
@internal
|
|
2527
|
-
*/
|
|
2528
|
-
var TransformError = class extends Error {};
|
|
2529
|
-
TransformError = function TransformError(message) {
|
|
2530
|
-
let err = Error.call(this, message);
|
|
2531
|
-
err.__proto__ = TransformError.prototype;
|
|
2532
|
-
return err;
|
|
2533
|
-
};
|
|
2534
|
-
TransformError.prototype = Object.create(Error.prototype);
|
|
2535
|
-
TransformError.prototype.constructor = TransformError;
|
|
2536
|
-
TransformError.prototype.name = "TransformError";
|
|
2537
|
-
//#endregion
|
|
2538
|
-
//#region ../../node_modules/.pnpm/prosemirror-state@1.4.4/node_modules/prosemirror-state/dist/index.js
|
|
2539
|
-
var classesById = Object.create(null);
|
|
2540
|
-
/**
|
|
2541
|
-
Superclass for editor selections. Every selection type should
|
|
2542
|
-
extend this. Should not be instantiated directly.
|
|
2543
|
-
*/
|
|
2544
|
-
var Selection = class {
|
|
2545
|
-
/**
|
|
2546
|
-
Initialize a selection with the head and anchor and ranges. If no
|
|
2547
|
-
ranges are given, constructs a single range across `$anchor` and
|
|
2548
|
-
`$head`.
|
|
2549
|
-
*/
|
|
2550
|
-
constructor($anchor, $head, ranges) {
|
|
2551
|
-
this.$anchor = $anchor;
|
|
2552
|
-
this.$head = $head;
|
|
2553
|
-
this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))];
|
|
2554
|
-
}
|
|
2555
|
-
/**
|
|
2556
|
-
The selection's anchor, as an unresolved position.
|
|
2557
|
-
*/
|
|
2558
|
-
get anchor() {
|
|
2559
|
-
return this.$anchor.pos;
|
|
2560
|
-
}
|
|
2561
|
-
/**
|
|
2562
|
-
The selection's head.
|
|
2563
|
-
*/
|
|
2564
|
-
get head() {
|
|
2565
|
-
return this.$head.pos;
|
|
2566
|
-
}
|
|
2567
|
-
/**
|
|
2568
|
-
The lower bound of the selection's main range.
|
|
2569
|
-
*/
|
|
2570
|
-
get from() {
|
|
2571
|
-
return this.$from.pos;
|
|
2572
|
-
}
|
|
2573
|
-
/**
|
|
2574
|
-
The upper bound of the selection's main range.
|
|
2575
|
-
*/
|
|
2576
|
-
get to() {
|
|
2577
|
-
return this.$to.pos;
|
|
2578
|
-
}
|
|
2579
|
-
/**
|
|
2580
|
-
The resolved lower bound of the selection's main range.
|
|
2581
|
-
*/
|
|
2582
|
-
get $from() {
|
|
2583
|
-
return this.ranges[0].$from;
|
|
2584
|
-
}
|
|
2585
|
-
/**
|
|
2586
|
-
The resolved upper bound of the selection's main range.
|
|
2587
|
-
*/
|
|
2588
|
-
get $to() {
|
|
2589
|
-
return this.ranges[0].$to;
|
|
2590
|
-
}
|
|
2591
|
-
/**
|
|
2592
|
-
Indicates whether the selection contains any content.
|
|
2593
|
-
*/
|
|
2594
|
-
get empty() {
|
|
2595
|
-
let ranges = this.ranges;
|
|
2596
|
-
for (let i = 0; i < ranges.length; i++) if (ranges[i].$from.pos != ranges[i].$to.pos) return false;
|
|
2597
|
-
return true;
|
|
2598
|
-
}
|
|
2599
|
-
/**
|
|
2600
|
-
Get the content of this selection as a slice.
|
|
2601
|
-
*/
|
|
2602
|
-
content() {
|
|
2603
|
-
return this.$from.doc.slice(this.from, this.to, true);
|
|
2604
|
-
}
|
|
2605
|
-
/**
|
|
2606
|
-
Replace the selection with a slice or, if no slice is given,
|
|
2607
|
-
delete the selection. Will append to the given transaction.
|
|
2608
|
-
*/
|
|
2609
|
-
replace(tr, content = Slice.empty) {
|
|
2610
|
-
let lastNode = content.content.lastChild, lastParent = null;
|
|
2611
|
-
for (let i = 0; i < content.openEnd; i++) {
|
|
2612
|
-
lastParent = lastNode;
|
|
2613
|
-
lastNode = lastNode.lastChild;
|
|
2614
|
-
}
|
|
2615
|
-
let mapFrom = tr.steps.length, ranges = this.ranges;
|
|
2616
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
2617
|
-
let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
2618
|
-
tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
|
|
2619
|
-
if (i == 0) selectionToInsertionEnd(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1);
|
|
2620
|
-
}
|
|
2621
|
-
}
|
|
2622
|
-
/**
|
|
2623
|
-
Replace the selection with the given node, appending the changes
|
|
2624
|
-
to the given transaction.
|
|
2625
|
-
*/
|
|
2626
|
-
replaceWith(tr, node) {
|
|
2627
|
-
let mapFrom = tr.steps.length, ranges = this.ranges;
|
|
2628
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
2629
|
-
let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
2630
|
-
let from = mapping.map($from.pos), to = mapping.map($to.pos);
|
|
2631
|
-
if (i) tr.deleteRange(from, to);
|
|
2632
|
-
else {
|
|
2633
|
-
tr.replaceRangeWith(from, to, node);
|
|
2634
|
-
selectionToInsertionEnd(tr, mapFrom, node.isInline ? -1 : 1);
|
|
2635
|
-
}
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2638
|
-
/**
|
|
2639
|
-
Find a valid cursor or leaf node selection starting at the given
|
|
2640
|
-
position and searching back if `dir` is negative, and forward if
|
|
2641
|
-
positive. When `textOnly` is true, only consider cursor
|
|
2642
|
-
selections. Will return null when no valid selection position is
|
|
2643
|
-
found.
|
|
2644
|
-
*/
|
|
2645
|
-
static findFrom($pos, dir, textOnly = false) {
|
|
2646
|
-
let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
|
|
2647
|
-
if (inner) return inner;
|
|
2648
|
-
for (let depth = $pos.depth - 1; depth >= 0; depth--) {
|
|
2649
|
-
let found = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly);
|
|
2650
|
-
if (found) return found;
|
|
2651
|
-
}
|
|
2652
|
-
return null;
|
|
2653
|
-
}
|
|
2654
|
-
/**
|
|
2655
|
-
Find a valid cursor or leaf node selection near the given
|
|
2656
|
-
position. Searches forward first by default, but if `bias` is
|
|
2657
|
-
negative, it will search backwards first.
|
|
2658
|
-
*/
|
|
2659
|
-
static near($pos, bias = 1) {
|
|
2660
|
-
return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0));
|
|
2661
|
-
}
|
|
2662
|
-
/**
|
|
2663
|
-
Find the cursor or leaf node selection closest to the start of
|
|
2664
|
-
the given document. Will return an
|
|
2665
|
-
[`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position
|
|
2666
|
-
exists.
|
|
2667
|
-
*/
|
|
2668
|
-
static atStart(doc) {
|
|
2669
|
-
return findSelectionIn(doc, doc, 0, 0, 1) || new AllSelection(doc);
|
|
2670
|
-
}
|
|
2671
|
-
/**
|
|
2672
|
-
Find the cursor or leaf node selection closest to the end of the
|
|
2673
|
-
given document.
|
|
2674
|
-
*/
|
|
2675
|
-
static atEnd(doc) {
|
|
2676
|
-
return findSelectionIn(doc, doc, doc.content.size, doc.childCount, -1) || new AllSelection(doc);
|
|
2677
|
-
}
|
|
2678
|
-
/**
|
|
2679
|
-
Deserialize the JSON representation of a selection. Must be
|
|
2680
|
-
implemented for custom classes (as a static class method).
|
|
2681
|
-
*/
|
|
2682
|
-
static fromJSON(doc, json) {
|
|
2683
|
-
if (!json || !json.type) throw new RangeError("Invalid input for Selection.fromJSON");
|
|
2684
|
-
let cls = classesById[json.type];
|
|
2685
|
-
if (!cls) throw new RangeError(`No selection type ${json.type} defined`);
|
|
2686
|
-
return cls.fromJSON(doc, json);
|
|
2687
|
-
}
|
|
2688
|
-
/**
|
|
2689
|
-
To be able to deserialize selections from JSON, custom selection
|
|
2690
|
-
classes must register themselves with an ID string, so that they
|
|
2691
|
-
can be disambiguated. Try to pick something that's unlikely to
|
|
2692
|
-
clash with classes from other modules.
|
|
2693
|
-
*/
|
|
2694
|
-
static jsonID(id, selectionClass) {
|
|
2695
|
-
if (id in classesById) throw new RangeError("Duplicate use of selection JSON ID " + id);
|
|
2696
|
-
classesById[id] = selectionClass;
|
|
2697
|
-
selectionClass.prototype.jsonID = id;
|
|
2698
|
-
return selectionClass;
|
|
2699
|
-
}
|
|
2700
|
-
/**
|
|
2701
|
-
Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection,
|
|
2702
|
-
which is a value that can be mapped without having access to a
|
|
2703
|
-
current document, and later resolved to a real selection for a
|
|
2704
|
-
given document again. (This is used mostly by the history to
|
|
2705
|
-
track and restore old selections.) The default implementation of
|
|
2706
|
-
this method just converts the selection to a text selection and
|
|
2707
|
-
returns the bookmark for that.
|
|
2708
|
-
*/
|
|
2709
|
-
getBookmark() {
|
|
2710
|
-
return TextSelection.between(this.$anchor, this.$head).getBookmark();
|
|
2711
|
-
}
|
|
2712
|
-
};
|
|
2713
|
-
Selection.prototype.visible = true;
|
|
2714
|
-
/**
|
|
2715
|
-
Represents a selected range in a document.
|
|
2716
|
-
*/
|
|
2717
|
-
var SelectionRange = class {
|
|
2718
|
-
/**
|
|
2719
|
-
Create a range.
|
|
2720
|
-
*/
|
|
2721
|
-
constructor($from, $to) {
|
|
2722
|
-
this.$from = $from;
|
|
2723
|
-
this.$to = $to;
|
|
2724
|
-
}
|
|
2725
|
-
};
|
|
2726
|
-
var warnedAboutTextSelection = false;
|
|
2727
|
-
function checkTextSelection($pos) {
|
|
2728
|
-
if (!warnedAboutTextSelection && !$pos.parent.inlineContent) {
|
|
2729
|
-
warnedAboutTextSelection = true;
|
|
2730
|
-
console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
|
|
2731
|
-
}
|
|
2732
|
-
}
|
|
2733
|
-
/**
|
|
2734
|
-
A text selection represents a classical editor selection, with a
|
|
2735
|
-
head (the moving side) and anchor (immobile side), both of which
|
|
2736
|
-
point into textblock nodes. It can be empty (a regular cursor
|
|
2737
|
-
position).
|
|
2738
|
-
*/
|
|
2739
|
-
var TextSelection = class TextSelection extends Selection {
|
|
2740
|
-
/**
|
|
2741
|
-
Construct a text selection between the given points.
|
|
2742
|
-
*/
|
|
2743
|
-
constructor($anchor, $head = $anchor) {
|
|
2744
|
-
checkTextSelection($anchor);
|
|
2745
|
-
checkTextSelection($head);
|
|
2746
|
-
super($anchor, $head);
|
|
2747
|
-
}
|
|
2748
|
-
/**
|
|
2749
|
-
Returns a resolved position if this is a cursor selection (an
|
|
2750
|
-
empty text selection), and null otherwise.
|
|
2751
|
-
*/
|
|
2752
|
-
get $cursor() {
|
|
2753
|
-
return this.$anchor.pos == this.$head.pos ? this.$head : null;
|
|
2754
|
-
}
|
|
2755
|
-
map(doc, mapping) {
|
|
2756
|
-
let $head = doc.resolve(mapping.map(this.head));
|
|
2757
|
-
if (!$head.parent.inlineContent) return Selection.near($head);
|
|
2758
|
-
let $anchor = doc.resolve(mapping.map(this.anchor));
|
|
2759
|
-
return new TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head);
|
|
2760
|
-
}
|
|
2761
|
-
replace(tr, content = Slice.empty) {
|
|
2762
|
-
super.replace(tr, content);
|
|
2763
|
-
if (content == Slice.empty) {
|
|
2764
|
-
let marks = this.$from.marksAcross(this.$to);
|
|
2765
|
-
if (marks) tr.ensureMarks(marks);
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
eq(other) {
|
|
2769
|
-
return other instanceof TextSelection && other.anchor == this.anchor && other.head == this.head;
|
|
2770
|
-
}
|
|
2771
|
-
getBookmark() {
|
|
2772
|
-
return new TextBookmark(this.anchor, this.head);
|
|
2773
|
-
}
|
|
2774
|
-
toJSON() {
|
|
2775
|
-
return {
|
|
2776
|
-
type: "text",
|
|
2777
|
-
anchor: this.anchor,
|
|
2778
|
-
head: this.head
|
|
2779
|
-
};
|
|
2780
|
-
}
|
|
2781
|
-
/**
|
|
2782
|
-
@internal
|
|
2783
|
-
*/
|
|
2784
|
-
static fromJSON(doc, json) {
|
|
2785
|
-
if (typeof json.anchor != "number" || typeof json.head != "number") throw new RangeError("Invalid input for TextSelection.fromJSON");
|
|
2786
|
-
return new TextSelection(doc.resolve(json.anchor), doc.resolve(json.head));
|
|
2787
|
-
}
|
|
2788
|
-
/**
|
|
2789
|
-
Create a text selection from non-resolved positions.
|
|
2790
|
-
*/
|
|
2791
|
-
static create(doc, anchor, head = anchor) {
|
|
2792
|
-
let $anchor = doc.resolve(anchor);
|
|
2793
|
-
return new this($anchor, head == anchor ? $anchor : doc.resolve(head));
|
|
2794
|
-
}
|
|
2795
|
-
/**
|
|
2796
|
-
Return a text selection that spans the given positions or, if
|
|
2797
|
-
they aren't text positions, find a text selection near them.
|
|
2798
|
-
`bias` determines whether the method searches forward (default)
|
|
2799
|
-
or backwards (negative number) first. Will fall back to calling
|
|
2800
|
-
[`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document
|
|
2801
|
-
doesn't contain a valid text position.
|
|
2802
|
-
*/
|
|
2803
|
-
static between($anchor, $head, bias) {
|
|
2804
|
-
let dPos = $anchor.pos - $head.pos;
|
|
2805
|
-
if (!bias || dPos) bias = dPos >= 0 ? 1 : -1;
|
|
2806
|
-
if (!$head.parent.inlineContent) {
|
|
2807
|
-
let found = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true);
|
|
2808
|
-
if (found) $head = found.$head;
|
|
2809
|
-
else return Selection.near($head, bias);
|
|
2810
|
-
}
|
|
2811
|
-
if (!$anchor.parent.inlineContent) if (dPos == 0) $anchor = $head;
|
|
2812
|
-
else {
|
|
2813
|
-
$anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor;
|
|
2814
|
-
if ($anchor.pos < $head.pos != dPos < 0) $anchor = $head;
|
|
2815
|
-
}
|
|
2816
|
-
return new TextSelection($anchor, $head);
|
|
2817
|
-
}
|
|
2818
|
-
};
|
|
2819
|
-
Selection.jsonID("text", TextSelection);
|
|
2820
|
-
var TextBookmark = class TextBookmark {
|
|
2821
|
-
constructor(anchor, head) {
|
|
2822
|
-
this.anchor = anchor;
|
|
2823
|
-
this.head = head;
|
|
2824
|
-
}
|
|
2825
|
-
map(mapping) {
|
|
2826
|
-
return new TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
|
|
2827
|
-
}
|
|
2828
|
-
resolve(doc) {
|
|
2829
|
-
return TextSelection.between(doc.resolve(this.anchor), doc.resolve(this.head));
|
|
2830
|
-
}
|
|
2831
|
-
};
|
|
2832
|
-
/**
|
|
2833
|
-
A node selection is a selection that points at a single node. All
|
|
2834
|
-
nodes marked [selectable](https://prosemirror.net/docs/ref/#model.NodeSpec.selectable) can be the
|
|
2835
|
-
target of a node selection. In such a selection, `from` and `to`
|
|
2836
|
-
point directly before and after the selected node, `anchor` equals
|
|
2837
|
-
`from`, and `head` equals `to`..
|
|
2838
|
-
*/
|
|
2839
|
-
var NodeSelection = class NodeSelection extends Selection {
|
|
2840
|
-
/**
|
|
2841
|
-
Create a node selection. Does not verify the validity of its
|
|
2842
|
-
argument.
|
|
2843
|
-
*/
|
|
2844
|
-
constructor($pos) {
|
|
2845
|
-
let node = $pos.nodeAfter;
|
|
2846
|
-
let $end = $pos.node(0).resolve($pos.pos + node.nodeSize);
|
|
2847
|
-
super($pos, $end);
|
|
2848
|
-
this.node = node;
|
|
2849
|
-
}
|
|
2850
|
-
map(doc, mapping) {
|
|
2851
|
-
let { deleted, pos } = mapping.mapResult(this.anchor);
|
|
2852
|
-
let $pos = doc.resolve(pos);
|
|
2853
|
-
if (deleted) return Selection.near($pos);
|
|
2854
|
-
return new NodeSelection($pos);
|
|
2855
|
-
}
|
|
2856
|
-
content() {
|
|
2857
|
-
return new Slice(Fragment$1.from(this.node), 0, 0);
|
|
2858
|
-
}
|
|
2859
|
-
eq(other) {
|
|
2860
|
-
return other instanceof NodeSelection && other.anchor == this.anchor;
|
|
2861
|
-
}
|
|
2862
|
-
toJSON() {
|
|
2863
|
-
return {
|
|
2864
|
-
type: "node",
|
|
2865
|
-
anchor: this.anchor
|
|
2866
|
-
};
|
|
2867
|
-
}
|
|
2868
|
-
getBookmark() {
|
|
2869
|
-
return new NodeBookmark(this.anchor);
|
|
2870
|
-
}
|
|
2871
|
-
/**
|
|
2872
|
-
@internal
|
|
2873
|
-
*/
|
|
2874
|
-
static fromJSON(doc, json) {
|
|
2875
|
-
if (typeof json.anchor != "number") throw new RangeError("Invalid input for NodeSelection.fromJSON");
|
|
2876
|
-
return new NodeSelection(doc.resolve(json.anchor));
|
|
2877
|
-
}
|
|
2878
|
-
/**
|
|
2879
|
-
Create a node selection from non-resolved positions.
|
|
2880
|
-
*/
|
|
2881
|
-
static create(doc, from) {
|
|
2882
|
-
return new NodeSelection(doc.resolve(from));
|
|
2883
|
-
}
|
|
2884
|
-
/**
|
|
2885
|
-
Determines whether the given node may be selected as a node
|
|
2886
|
-
selection.
|
|
2887
|
-
*/
|
|
2888
|
-
static isSelectable(node) {
|
|
2889
|
-
return !node.isText && node.type.spec.selectable !== false;
|
|
2890
|
-
}
|
|
2891
|
-
};
|
|
2892
|
-
NodeSelection.prototype.visible = false;
|
|
2893
|
-
Selection.jsonID("node", NodeSelection);
|
|
2894
|
-
var NodeBookmark = class NodeBookmark {
|
|
2895
|
-
constructor(anchor) {
|
|
2896
|
-
this.anchor = anchor;
|
|
2897
|
-
}
|
|
2898
|
-
map(mapping) {
|
|
2899
|
-
let { deleted, pos } = mapping.mapResult(this.anchor);
|
|
2900
|
-
return deleted ? new TextBookmark(pos, pos) : new NodeBookmark(pos);
|
|
2901
|
-
}
|
|
2902
|
-
resolve(doc) {
|
|
2903
|
-
let $pos = doc.resolve(this.anchor), node = $pos.nodeAfter;
|
|
2904
|
-
if (node && NodeSelection.isSelectable(node)) return new NodeSelection($pos);
|
|
2905
|
-
return Selection.near($pos);
|
|
2906
|
-
}
|
|
2907
|
-
};
|
|
2908
|
-
/**
|
|
2909
|
-
A selection type that represents selecting the whole document
|
|
2910
|
-
(which can not necessarily be expressed with a text selection, when
|
|
2911
|
-
there are for example leaf block nodes at the start or end of the
|
|
2912
|
-
document).
|
|
2913
|
-
*/
|
|
2914
|
-
var AllSelection = class AllSelection extends Selection {
|
|
2915
|
-
/**
|
|
2916
|
-
Create an all-selection over the given document.
|
|
2917
|
-
*/
|
|
2918
|
-
constructor(doc) {
|
|
2919
|
-
super(doc.resolve(0), doc.resolve(doc.content.size));
|
|
2920
|
-
}
|
|
2921
|
-
replace(tr, content = Slice.empty) {
|
|
2922
|
-
if (content == Slice.empty) {
|
|
2923
|
-
tr.delete(0, tr.doc.content.size);
|
|
2924
|
-
let sel = Selection.atStart(tr.doc);
|
|
2925
|
-
if (!sel.eq(tr.selection)) tr.setSelection(sel);
|
|
2926
|
-
} else super.replace(tr, content);
|
|
2927
|
-
}
|
|
2928
|
-
toJSON() {
|
|
2929
|
-
return { type: "all" };
|
|
2930
|
-
}
|
|
2931
|
-
/**
|
|
2932
|
-
@internal
|
|
2933
|
-
*/
|
|
2934
|
-
static fromJSON(doc) {
|
|
2935
|
-
return new AllSelection(doc);
|
|
2936
|
-
}
|
|
2937
|
-
map(doc) {
|
|
2938
|
-
return new AllSelection(doc);
|
|
2939
|
-
}
|
|
2940
|
-
eq(other) {
|
|
2941
|
-
return other instanceof AllSelection;
|
|
2942
|
-
}
|
|
2943
|
-
getBookmark() {
|
|
2944
|
-
return AllBookmark;
|
|
2945
|
-
}
|
|
2946
|
-
};
|
|
2947
|
-
Selection.jsonID("all", AllSelection);
|
|
2948
|
-
var AllBookmark = {
|
|
2949
|
-
map() {
|
|
2950
|
-
return this;
|
|
2951
|
-
},
|
|
2952
|
-
resolve(doc) {
|
|
2953
|
-
return new AllSelection(doc);
|
|
2954
|
-
}
|
|
2955
|
-
};
|
|
2956
|
-
function findSelectionIn(doc, node, pos, index, dir, text = false) {
|
|
2957
|
-
if (node.inlineContent) return TextSelection.create(doc, pos);
|
|
2958
|
-
for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) {
|
|
2959
|
-
let child = node.child(i);
|
|
2960
|
-
if (!child.isAtom) {
|
|
2961
|
-
let inner = findSelectionIn(doc, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text);
|
|
2962
|
-
if (inner) return inner;
|
|
2963
|
-
} else if (!text && NodeSelection.isSelectable(child)) return NodeSelection.create(doc, pos - (dir < 0 ? child.nodeSize : 0));
|
|
2964
|
-
pos += child.nodeSize * dir;
|
|
2965
|
-
}
|
|
2966
|
-
return null;
|
|
2967
|
-
}
|
|
2968
|
-
function selectionToInsertionEnd(tr, startLen, bias) {
|
|
2969
|
-
let last = tr.steps.length - 1;
|
|
2970
|
-
if (last < startLen) return;
|
|
2971
|
-
let step = tr.steps[last];
|
|
2972
|
-
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return;
|
|
2973
|
-
let map = tr.mapping.maps[last], end;
|
|
2974
|
-
map.forEach((_from, _to, _newFrom, newTo) => {
|
|
2975
|
-
if (end == null) end = newTo;
|
|
2976
|
-
});
|
|
2977
|
-
tr.setSelection(Selection.near(tr.doc.resolve(end), bias));
|
|
2978
|
-
}
|
|
2979
|
-
function bind(f, self) {
|
|
2980
|
-
return !self || !f ? f : f.bind(self);
|
|
2981
|
-
}
|
|
2982
|
-
var FieldDesc = class {
|
|
2983
|
-
constructor(name, desc, self) {
|
|
2984
|
-
this.name = name;
|
|
2985
|
-
this.init = bind(desc.init, self);
|
|
2986
|
-
this.apply = bind(desc.apply, self);
|
|
2987
|
-
}
|
|
2988
|
-
};
|
|
2989
|
-
new FieldDesc("doc", {
|
|
2990
|
-
init(config) {
|
|
2991
|
-
return config.doc || config.schema.topNodeType.createAndFill();
|
|
2992
|
-
},
|
|
2993
|
-
apply(tr) {
|
|
2994
|
-
return tr.doc;
|
|
2995
|
-
}
|
|
2996
|
-
}), new FieldDesc("selection", {
|
|
2997
|
-
init(config, instance) {
|
|
2998
|
-
return config.selection || Selection.atStart(instance.doc);
|
|
2999
|
-
},
|
|
3000
|
-
apply(tr) {
|
|
3001
|
-
return tr.selection;
|
|
3002
|
-
}
|
|
3003
|
-
}), new FieldDesc("storedMarks", {
|
|
3004
|
-
init(config) {
|
|
3005
|
-
return config.storedMarks || null;
|
|
3006
|
-
},
|
|
3007
|
-
apply(tr, _marks, _old, state) {
|
|
3008
|
-
return state.selection.$cursor ? tr.storedMarks : null;
|
|
3009
|
-
}
|
|
3010
|
-
}), new FieldDesc("scrollToSelection", {
|
|
3011
|
-
init() {
|
|
3012
|
-
return 0;
|
|
3013
|
-
},
|
|
3014
|
-
apply(tr, prev) {
|
|
3015
|
-
return tr.scrolledIntoView ? prev + 1 : prev;
|
|
3016
|
-
}
|
|
3017
|
-
});
|
|
3018
|
-
var keys = Object.create(null);
|
|
3019
|
-
function createKey(name) {
|
|
3020
|
-
if (name in keys) return name + "$" + ++keys[name];
|
|
3021
|
-
keys[name] = 0;
|
|
3022
|
-
return name + "$";
|
|
3023
|
-
}
|
|
3024
|
-
/**
|
|
3025
|
-
A key is used to [tag](https://prosemirror.net/docs/ref/#state.PluginSpec.key) plugins in a way
|
|
3026
|
-
that makes it possible to find them, given an editor state.
|
|
3027
|
-
Assigning a key does mean only one plugin of that type can be
|
|
3028
|
-
active in a state.
|
|
3029
|
-
*/
|
|
3030
|
-
var PluginKey = class {
|
|
3031
|
-
/**
|
|
3032
|
-
Create a plugin key.
|
|
3033
|
-
*/
|
|
3034
|
-
constructor(name = "key") {
|
|
3035
|
-
this.key = createKey(name);
|
|
3036
|
-
}
|
|
3037
|
-
/**
|
|
3038
|
-
Get the active plugin with this key, if any, from an editor
|
|
3039
|
-
state.
|
|
3040
|
-
*/
|
|
3041
|
-
get(state) {
|
|
3042
|
-
return state.config.pluginsByKey[this.key];
|
|
3043
|
-
}
|
|
3044
|
-
/**
|
|
3045
|
-
Get the plugin's state from an editor state.
|
|
3046
|
-
*/
|
|
3047
|
-
getState(state) {
|
|
3048
|
-
return state[this.key];
|
|
3049
|
-
}
|
|
3050
|
-
};
|
|
3051
|
-
//#endregion
|
|
3052
22
|
//#region src/tiptap/components/icons/text-snippet-icon.tsx
|
|
3053
23
|
var TextSnippetIcon = (0, _mui_material_utils.createSvgIcon)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M14.17,5L19,9.83V19H5V5L14.17,5L14.17,5 M14.17,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V9.83 c0-0.53-0.21-1.04-0.59-1.41l-4.83-4.83C15.21,3.21,14.7,3,14.17,3L14.17,3z M7,15h10v2H7V15z M7,11h10v2H7V11z M7,7h7v2H7V7z" }), "TextSnippet");
|
|
3054
24
|
//#endregion
|
|
@@ -3101,865 +71,6 @@ function useTiptapEditor(providedEditor) {
|
|
|
3101
71
|
}) ?? { editor: null };
|
|
3102
72
|
}
|
|
3103
73
|
//#endregion
|
|
3104
|
-
//#region ../../node_modules/.pnpm/w3c-keyname@2.2.8/node_modules/w3c-keyname/index.js
|
|
3105
|
-
var base = {
|
|
3106
|
-
8: "Backspace",
|
|
3107
|
-
9: "Tab",
|
|
3108
|
-
10: "Enter",
|
|
3109
|
-
12: "NumLock",
|
|
3110
|
-
13: "Enter",
|
|
3111
|
-
16: "Shift",
|
|
3112
|
-
17: "Control",
|
|
3113
|
-
18: "Alt",
|
|
3114
|
-
20: "CapsLock",
|
|
3115
|
-
27: "Escape",
|
|
3116
|
-
32: " ",
|
|
3117
|
-
33: "PageUp",
|
|
3118
|
-
34: "PageDown",
|
|
3119
|
-
35: "End",
|
|
3120
|
-
36: "Home",
|
|
3121
|
-
37: "ArrowLeft",
|
|
3122
|
-
38: "ArrowUp",
|
|
3123
|
-
39: "ArrowRight",
|
|
3124
|
-
40: "ArrowDown",
|
|
3125
|
-
44: "PrintScreen",
|
|
3126
|
-
45: "Insert",
|
|
3127
|
-
46: "Delete",
|
|
3128
|
-
59: ";",
|
|
3129
|
-
61: "=",
|
|
3130
|
-
91: "Meta",
|
|
3131
|
-
92: "Meta",
|
|
3132
|
-
106: "*",
|
|
3133
|
-
107: "+",
|
|
3134
|
-
108: ",",
|
|
3135
|
-
109: "-",
|
|
3136
|
-
110: ".",
|
|
3137
|
-
111: "/",
|
|
3138
|
-
144: "NumLock",
|
|
3139
|
-
145: "ScrollLock",
|
|
3140
|
-
160: "Shift",
|
|
3141
|
-
161: "Shift",
|
|
3142
|
-
162: "Control",
|
|
3143
|
-
163: "Control",
|
|
3144
|
-
164: "Alt",
|
|
3145
|
-
165: "Alt",
|
|
3146
|
-
173: "-",
|
|
3147
|
-
186: ";",
|
|
3148
|
-
187: "=",
|
|
3149
|
-
188: ",",
|
|
3150
|
-
189: "-",
|
|
3151
|
-
190: ".",
|
|
3152
|
-
191: "/",
|
|
3153
|
-
192: "`",
|
|
3154
|
-
219: "[",
|
|
3155
|
-
220: "\\",
|
|
3156
|
-
221: "]",
|
|
3157
|
-
222: "'"
|
|
3158
|
-
};
|
|
3159
|
-
var shift = {
|
|
3160
|
-
48: ")",
|
|
3161
|
-
49: "!",
|
|
3162
|
-
50: "@",
|
|
3163
|
-
51: "#",
|
|
3164
|
-
52: "$",
|
|
3165
|
-
53: "%",
|
|
3166
|
-
54: "^",
|
|
3167
|
-
55: "&",
|
|
3168
|
-
56: "*",
|
|
3169
|
-
57: "(",
|
|
3170
|
-
59: ":",
|
|
3171
|
-
61: "+",
|
|
3172
|
-
173: "_",
|
|
3173
|
-
186: ":",
|
|
3174
|
-
187: "+",
|
|
3175
|
-
188: "<",
|
|
3176
|
-
189: "_",
|
|
3177
|
-
190: ">",
|
|
3178
|
-
191: "?",
|
|
3179
|
-
192: "~",
|
|
3180
|
-
219: "{",
|
|
3181
|
-
220: "|",
|
|
3182
|
-
221: "}",
|
|
3183
|
-
222: "\""
|
|
3184
|
-
};
|
|
3185
|
-
var mac$1 = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
|
|
3186
|
-
var ie = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
|
|
3187
|
-
for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i);
|
|
3188
|
-
for (var i = 1; i <= 24; i++) base[i + 111] = "F" + i;
|
|
3189
|
-
for (var i = 65; i <= 90; i++) {
|
|
3190
|
-
base[i] = String.fromCharCode(i + 32);
|
|
3191
|
-
shift[i] = String.fromCharCode(i);
|
|
3192
|
-
}
|
|
3193
|
-
for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
|
|
3194
|
-
function keyName(event) {
|
|
3195
|
-
var name = !(mac$1 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified") && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified";
|
|
3196
|
-
if (name == "Esc") name = "Escape";
|
|
3197
|
-
if (name == "Del") name = "Delete";
|
|
3198
|
-
if (name == "Left") name = "ArrowLeft";
|
|
3199
|
-
if (name == "Up") name = "ArrowUp";
|
|
3200
|
-
if (name == "Right") name = "ArrowRight";
|
|
3201
|
-
if (name == "Down") name = "ArrowDown";
|
|
3202
|
-
return name;
|
|
3203
|
-
}
|
|
3204
|
-
//#endregion
|
|
3205
|
-
//#region ../../node_modules/.pnpm/prosemirror-keymap@1.2.3/node_modules/prosemirror-keymap/dist/index.js
|
|
3206
|
-
var mac = typeof navigator != "undefined" && /Mac|iP(hone|[oa]d)/.test(navigator.platform);
|
|
3207
|
-
var windows = typeof navigator != "undefined" && /Win/.test(navigator.platform);
|
|
3208
|
-
function normalizeKeyName(name) {
|
|
3209
|
-
let parts = name.split(/-(?!$)/), result = parts[parts.length - 1];
|
|
3210
|
-
if (result == "Space") result = " ";
|
|
3211
|
-
let alt, ctrl, shift, meta;
|
|
3212
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3213
|
-
let mod = parts[i];
|
|
3214
|
-
if (/^(cmd|meta|m)$/i.test(mod)) meta = true;
|
|
3215
|
-
else if (/^a(lt)?$/i.test(mod)) alt = true;
|
|
3216
|
-
else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
|
|
3217
|
-
else if (/^s(hift)?$/i.test(mod)) shift = true;
|
|
3218
|
-
else if (/^mod$/i.test(mod)) if (mac) meta = true;
|
|
3219
|
-
else ctrl = true;
|
|
3220
|
-
else throw new Error("Unrecognized modifier name: " + mod);
|
|
3221
|
-
}
|
|
3222
|
-
if (alt) result = "Alt-" + result;
|
|
3223
|
-
if (ctrl) result = "Ctrl-" + result;
|
|
3224
|
-
if (meta) result = "Meta-" + result;
|
|
3225
|
-
if (shift) result = "Shift-" + result;
|
|
3226
|
-
return result;
|
|
3227
|
-
}
|
|
3228
|
-
function normalize(map) {
|
|
3229
|
-
let copy = Object.create(null);
|
|
3230
|
-
for (let prop in map) copy[normalizeKeyName(prop)] = map[prop];
|
|
3231
|
-
return copy;
|
|
3232
|
-
}
|
|
3233
|
-
function modifiers(name, event, shift = true) {
|
|
3234
|
-
if (event.altKey) name = "Alt-" + name;
|
|
3235
|
-
if (event.ctrlKey) name = "Ctrl-" + name;
|
|
3236
|
-
if (event.metaKey) name = "Meta-" + name;
|
|
3237
|
-
if (shift && event.shiftKey) name = "Shift-" + name;
|
|
3238
|
-
return name;
|
|
3239
|
-
}
|
|
3240
|
-
/**
|
|
3241
|
-
Given a set of bindings (using the same format as
|
|
3242
|
-
[`keymap`](https://prosemirror.net/docs/ref/#keymap.keymap)), return a [keydown
|
|
3243
|
-
handler](https://prosemirror.net/docs/ref/#view.EditorProps.handleKeyDown) that handles them.
|
|
3244
|
-
*/
|
|
3245
|
-
function keydownHandler(bindings) {
|
|
3246
|
-
let map = normalize(bindings);
|
|
3247
|
-
return function(view, event) {
|
|
3248
|
-
let name = keyName(event), baseName, direct = map[modifiers(name, event)];
|
|
3249
|
-
if (direct && direct(view.state, view.dispatch, view)) return true;
|
|
3250
|
-
if (name.length == 1 && name != " ") {
|
|
3251
|
-
if (event.shiftKey) {
|
|
3252
|
-
let noShift = map[modifiers(name, event, false)];
|
|
3253
|
-
if (noShift && noShift(view.state, view.dispatch, view)) return true;
|
|
3254
|
-
}
|
|
3255
|
-
if ((event.altKey || event.metaKey || event.ctrlKey) && !(windows && event.ctrlKey && event.altKey) && (baseName = base[event.keyCode]) && baseName != name) {
|
|
3256
|
-
let fromCode = map[modifiers(baseName, event)];
|
|
3257
|
-
if (fromCode && fromCode(view.state, view.dispatch, view)) return true;
|
|
3258
|
-
}
|
|
3259
|
-
}
|
|
3260
|
-
return false;
|
|
3261
|
-
};
|
|
3262
|
-
}
|
|
3263
|
-
//#endregion
|
|
3264
|
-
//#region ../../node_modules/.pnpm/prosemirror-tables@1.8.5/node_modules/prosemirror-tables/dist/index.js
|
|
3265
|
-
var readFromCache;
|
|
3266
|
-
var addToCache;
|
|
3267
|
-
if (typeof WeakMap != "undefined") {
|
|
3268
|
-
let cache = /* @__PURE__ */ new WeakMap();
|
|
3269
|
-
readFromCache = (key) => cache.get(key);
|
|
3270
|
-
addToCache = (key, value) => {
|
|
3271
|
-
cache.set(key, value);
|
|
3272
|
-
return value;
|
|
3273
|
-
};
|
|
3274
|
-
} else {
|
|
3275
|
-
const cache = [];
|
|
3276
|
-
const cacheSize = 10;
|
|
3277
|
-
let cachePos = 0;
|
|
3278
|
-
readFromCache = (key) => {
|
|
3279
|
-
for (let i = 0; i < cache.length; i += 2) if (cache[i] == key) return cache[i + 1];
|
|
3280
|
-
};
|
|
3281
|
-
addToCache = (key, value) => {
|
|
3282
|
-
if (cachePos == cacheSize) cachePos = 0;
|
|
3283
|
-
cache[cachePos++] = key;
|
|
3284
|
-
return cache[cachePos++] = value;
|
|
3285
|
-
};
|
|
3286
|
-
}
|
|
3287
|
-
/**
|
|
3288
|
-
* A table map describes the structure of a given table. To avoid
|
|
3289
|
-
* recomputing them all the time, they are cached per table node. To
|
|
3290
|
-
* be able to do that, positions saved in the map are relative to the
|
|
3291
|
-
* start of the table, rather than the start of the document.
|
|
3292
|
-
*
|
|
3293
|
-
* @public
|
|
3294
|
-
*/
|
|
3295
|
-
var TableMap = class {
|
|
3296
|
-
constructor(width, height, map, problems) {
|
|
3297
|
-
this.width = width;
|
|
3298
|
-
this.height = height;
|
|
3299
|
-
this.map = map;
|
|
3300
|
-
this.problems = problems;
|
|
3301
|
-
}
|
|
3302
|
-
findCell(pos) {
|
|
3303
|
-
for (let i = 0; i < this.map.length; i++) {
|
|
3304
|
-
const curPos = this.map[i];
|
|
3305
|
-
if (curPos != pos) continue;
|
|
3306
|
-
const left = i % this.width;
|
|
3307
|
-
const top = i / this.width | 0;
|
|
3308
|
-
let right = left + 1;
|
|
3309
|
-
let bottom = top + 1;
|
|
3310
|
-
for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) right++;
|
|
3311
|
-
for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) bottom++;
|
|
3312
|
-
return {
|
|
3313
|
-
left,
|
|
3314
|
-
top,
|
|
3315
|
-
right,
|
|
3316
|
-
bottom
|
|
3317
|
-
};
|
|
3318
|
-
}
|
|
3319
|
-
throw new RangeError(`No cell with offset ${pos} found`);
|
|
3320
|
-
}
|
|
3321
|
-
colCount(pos) {
|
|
3322
|
-
for (let i = 0; i < this.map.length; i++) if (this.map[i] == pos) return i % this.width;
|
|
3323
|
-
throw new RangeError(`No cell with offset ${pos} found`);
|
|
3324
|
-
}
|
|
3325
|
-
nextCell(pos, axis, dir) {
|
|
3326
|
-
const { left, right, top, bottom } = this.findCell(pos);
|
|
3327
|
-
if (axis == "horiz") {
|
|
3328
|
-
if (dir < 0 ? left == 0 : right == this.width) return null;
|
|
3329
|
-
return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
|
|
3330
|
-
} else {
|
|
3331
|
-
if (dir < 0 ? top == 0 : bottom == this.height) return null;
|
|
3332
|
-
return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
|
|
3333
|
-
}
|
|
3334
|
-
}
|
|
3335
|
-
rectBetween(a, b) {
|
|
3336
|
-
const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a);
|
|
3337
|
-
const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b);
|
|
3338
|
-
return {
|
|
3339
|
-
left: Math.min(leftA, leftB),
|
|
3340
|
-
top: Math.min(topA, topB),
|
|
3341
|
-
right: Math.max(rightA, rightB),
|
|
3342
|
-
bottom: Math.max(bottomA, bottomB)
|
|
3343
|
-
};
|
|
3344
|
-
}
|
|
3345
|
-
cellsInRect(rect) {
|
|
3346
|
-
const result = [];
|
|
3347
|
-
const seen = {};
|
|
3348
|
-
for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
|
|
3349
|
-
const index = row * this.width + col;
|
|
3350
|
-
const pos = this.map[index];
|
|
3351
|
-
if (seen[pos]) continue;
|
|
3352
|
-
seen[pos] = true;
|
|
3353
|
-
if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) continue;
|
|
3354
|
-
result.push(pos);
|
|
3355
|
-
}
|
|
3356
|
-
return result;
|
|
3357
|
-
}
|
|
3358
|
-
positionAt(row, col, table) {
|
|
3359
|
-
for (let i = 0, rowStart = 0;; i++) {
|
|
3360
|
-
const rowEnd = rowStart + table.child(i).nodeSize;
|
|
3361
|
-
if (i == row) {
|
|
3362
|
-
let index = col + row * this.width;
|
|
3363
|
-
const rowEndIndex = (row + 1) * this.width;
|
|
3364
|
-
while (index < rowEndIndex && this.map[index] < rowStart) index++;
|
|
3365
|
-
return index == rowEndIndex ? rowEnd - 1 : this.map[index];
|
|
3366
|
-
}
|
|
3367
|
-
rowStart = rowEnd;
|
|
3368
|
-
}
|
|
3369
|
-
}
|
|
3370
|
-
static get(table) {
|
|
3371
|
-
return readFromCache(table) || addToCache(table, computeMap(table));
|
|
3372
|
-
}
|
|
3373
|
-
};
|
|
3374
|
-
function computeMap(table) {
|
|
3375
|
-
if (table.type.spec.tableRole != "table") throw new RangeError("Not a table node: " + table.type.name);
|
|
3376
|
-
const width = findWidth(table), height = table.childCount;
|
|
3377
|
-
const map = [];
|
|
3378
|
-
let mapPos = 0;
|
|
3379
|
-
let problems = null;
|
|
3380
|
-
const colWidths = [];
|
|
3381
|
-
for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
|
|
3382
|
-
for (let row = 0, pos = 0; row < height; row++) {
|
|
3383
|
-
const rowNode = table.child(row);
|
|
3384
|
-
pos++;
|
|
3385
|
-
for (let i = 0;; i++) {
|
|
3386
|
-
while (mapPos < map.length && map[mapPos] != 0) mapPos++;
|
|
3387
|
-
if (i == rowNode.childCount) break;
|
|
3388
|
-
const cellNode = rowNode.child(i);
|
|
3389
|
-
const { colspan, rowspan, colwidth } = cellNode.attrs;
|
|
3390
|
-
for (let h = 0; h < rowspan; h++) {
|
|
3391
|
-
if (h + row >= height) {
|
|
3392
|
-
(problems || (problems = [])).push({
|
|
3393
|
-
type: "overlong_rowspan",
|
|
3394
|
-
pos,
|
|
3395
|
-
n: rowspan - h
|
|
3396
|
-
});
|
|
3397
|
-
break;
|
|
3398
|
-
}
|
|
3399
|
-
const start = mapPos + h * width;
|
|
3400
|
-
for (let w = 0; w < colspan; w++) {
|
|
3401
|
-
if (map[start + w] == 0) map[start + w] = pos;
|
|
3402
|
-
else (problems || (problems = [])).push({
|
|
3403
|
-
type: "collision",
|
|
3404
|
-
row,
|
|
3405
|
-
pos,
|
|
3406
|
-
n: colspan - w
|
|
3407
|
-
});
|
|
3408
|
-
const colW = colwidth && colwidth[w];
|
|
3409
|
-
if (colW) {
|
|
3410
|
-
const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
|
|
3411
|
-
if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
|
|
3412
|
-
colWidths[widthIndex] = colW;
|
|
3413
|
-
colWidths[widthIndex + 1] = 1;
|
|
3414
|
-
} else if (prev == colW) colWidths[widthIndex + 1]++;
|
|
3415
|
-
}
|
|
3416
|
-
}
|
|
3417
|
-
}
|
|
3418
|
-
mapPos += colspan;
|
|
3419
|
-
pos += cellNode.nodeSize;
|
|
3420
|
-
}
|
|
3421
|
-
const expectedPos = (row + 1) * width;
|
|
3422
|
-
let missing = 0;
|
|
3423
|
-
while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
|
|
3424
|
-
if (missing) (problems || (problems = [])).push({
|
|
3425
|
-
type: "missing",
|
|
3426
|
-
row,
|
|
3427
|
-
n: missing
|
|
3428
|
-
});
|
|
3429
|
-
pos++;
|
|
3430
|
-
}
|
|
3431
|
-
if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
|
|
3432
|
-
const tableMap = new TableMap(width, height, map, problems);
|
|
3433
|
-
let badWidths = false;
|
|
3434
|
-
for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
|
|
3435
|
-
if (badWidths) findBadColWidths(tableMap, colWidths, table);
|
|
3436
|
-
return tableMap;
|
|
3437
|
-
}
|
|
3438
|
-
function findWidth(table) {
|
|
3439
|
-
let width = -1;
|
|
3440
|
-
let hasRowSpan = false;
|
|
3441
|
-
for (let row = 0; row < table.childCount; row++) {
|
|
3442
|
-
const rowNode = table.child(row);
|
|
3443
|
-
let rowWidth = 0;
|
|
3444
|
-
if (hasRowSpan) for (let j = 0; j < row; j++) {
|
|
3445
|
-
const prevRow = table.child(j);
|
|
3446
|
-
for (let i = 0; i < prevRow.childCount; i++) {
|
|
3447
|
-
const cell = prevRow.child(i);
|
|
3448
|
-
if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
|
|
3449
|
-
}
|
|
3450
|
-
}
|
|
3451
|
-
for (let i = 0; i < rowNode.childCount; i++) {
|
|
3452
|
-
const cell = rowNode.child(i);
|
|
3453
|
-
rowWidth += cell.attrs.colspan;
|
|
3454
|
-
if (cell.attrs.rowspan > 1) hasRowSpan = true;
|
|
3455
|
-
}
|
|
3456
|
-
if (width == -1) width = rowWidth;
|
|
3457
|
-
else if (width != rowWidth) width = Math.max(width, rowWidth);
|
|
3458
|
-
}
|
|
3459
|
-
return width;
|
|
3460
|
-
}
|
|
3461
|
-
function findBadColWidths(map, colWidths, table) {
|
|
3462
|
-
if (!map.problems) map.problems = [];
|
|
3463
|
-
const seen = {};
|
|
3464
|
-
for (let i = 0; i < map.map.length; i++) {
|
|
3465
|
-
const pos = map.map[i];
|
|
3466
|
-
if (seen[pos]) continue;
|
|
3467
|
-
seen[pos] = true;
|
|
3468
|
-
const node = table.nodeAt(pos);
|
|
3469
|
-
if (!node) throw new RangeError(`No cell with offset ${pos} found`);
|
|
3470
|
-
let updated = null;
|
|
3471
|
-
const attrs = node.attrs;
|
|
3472
|
-
for (let j = 0; j < attrs.colspan; j++) {
|
|
3473
|
-
const colWidth = colWidths[(i + j) % map.width * 2];
|
|
3474
|
-
if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth)) (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
|
|
3475
|
-
}
|
|
3476
|
-
if (updated) map.problems.unshift({
|
|
3477
|
-
type: "colwidth mismatch",
|
|
3478
|
-
pos,
|
|
3479
|
-
colwidth: updated
|
|
3480
|
-
});
|
|
3481
|
-
}
|
|
3482
|
-
}
|
|
3483
|
-
function freshColWidth(attrs) {
|
|
3484
|
-
if (attrs.colwidth) return attrs.colwidth.slice();
|
|
3485
|
-
const result = [];
|
|
3486
|
-
for (let i = 0; i < attrs.colspan; i++) result.push(0);
|
|
3487
|
-
return result;
|
|
3488
|
-
}
|
|
3489
|
-
/**
|
|
3490
|
-
* @public
|
|
3491
|
-
*/
|
|
3492
|
-
function tableNodeTypes(schema) {
|
|
3493
|
-
let result = schema.cached.tableNodeTypes;
|
|
3494
|
-
if (!result) {
|
|
3495
|
-
result = schema.cached.tableNodeTypes = {};
|
|
3496
|
-
for (const name in schema.nodes) {
|
|
3497
|
-
const type = schema.nodes[name], role = type.spec.tableRole;
|
|
3498
|
-
if (role) result[role] = type;
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
return result;
|
|
3502
|
-
}
|
|
3503
|
-
new PluginKey("selectingCells");
|
|
3504
|
-
/**
|
|
3505
|
-
* @public
|
|
3506
|
-
*/
|
|
3507
|
-
function cellAround($pos) {
|
|
3508
|
-
for (let d = $pos.depth - 1; d > 0; d--) if ($pos.node(d).type.spec.tableRole == "row") return $pos.node(0).resolve($pos.before(d + 1));
|
|
3509
|
-
return null;
|
|
3510
|
-
}
|
|
3511
|
-
/**
|
|
3512
|
-
* @public
|
|
3513
|
-
*/
|
|
3514
|
-
function isInTable(state) {
|
|
3515
|
-
const $head = state.selection.$head;
|
|
3516
|
-
for (let d = $head.depth; d > 0; d--) if ($head.node(d).type.spec.tableRole == "row") return true;
|
|
3517
|
-
return false;
|
|
3518
|
-
}
|
|
3519
|
-
/**
|
|
3520
|
-
* @internal
|
|
3521
|
-
*/
|
|
3522
|
-
function selectionCell(state) {
|
|
3523
|
-
const sel = state.selection;
|
|
3524
|
-
if ("$anchorCell" in sel && sel.$anchorCell) return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
|
|
3525
|
-
else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") return sel.$anchor;
|
|
3526
|
-
const $cell = cellAround(sel.$head) || cellNear(sel.$head);
|
|
3527
|
-
if ($cell) return $cell;
|
|
3528
|
-
throw new RangeError(`No cell found around position ${sel.head}`);
|
|
3529
|
-
}
|
|
3530
|
-
/**
|
|
3531
|
-
* @public
|
|
3532
|
-
*/
|
|
3533
|
-
function cellNear($pos) {
|
|
3534
|
-
for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
|
|
3535
|
-
const role = after.type.spec.tableRole;
|
|
3536
|
-
if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
|
|
3537
|
-
}
|
|
3538
|
-
for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
|
|
3539
|
-
const role = before.type.spec.tableRole;
|
|
3540
|
-
if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos - before.nodeSize);
|
|
3541
|
-
}
|
|
3542
|
-
}
|
|
3543
|
-
/**
|
|
3544
|
-
* @public
|
|
3545
|
-
*/
|
|
3546
|
-
function pointsAtCell($pos) {
|
|
3547
|
-
return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
|
|
3548
|
-
}
|
|
3549
|
-
/**
|
|
3550
|
-
* @internal
|
|
3551
|
-
*/
|
|
3552
|
-
function inSameTable($cellA, $cellB) {
|
|
3553
|
-
return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
|
|
3554
|
-
}
|
|
3555
|
-
/**
|
|
3556
|
-
* @public
|
|
3557
|
-
*/
|
|
3558
|
-
function nextCell($pos, axis, dir) {
|
|
3559
|
-
const table = $pos.node(-1);
|
|
3560
|
-
const map = TableMap.get(table);
|
|
3561
|
-
const tableStart = $pos.start(-1);
|
|
3562
|
-
const moved = map.nextCell($pos.pos - tableStart, axis, dir);
|
|
3563
|
-
return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
|
|
3564
|
-
}
|
|
3565
|
-
/**
|
|
3566
|
-
* @public
|
|
3567
|
-
*/
|
|
3568
|
-
function removeColSpan(attrs, pos, n = 1) {
|
|
3569
|
-
const result = {
|
|
3570
|
-
...attrs,
|
|
3571
|
-
colspan: attrs.colspan - n
|
|
3572
|
-
};
|
|
3573
|
-
if (result.colwidth) {
|
|
3574
|
-
result.colwidth = result.colwidth.slice();
|
|
3575
|
-
result.colwidth.splice(pos, n);
|
|
3576
|
-
if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
|
|
3577
|
-
}
|
|
3578
|
-
return result;
|
|
3579
|
-
}
|
|
3580
|
-
/**
|
|
3581
|
-
* A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
|
|
3582
|
-
* subclass that represents a cell selection spanning part of a table.
|
|
3583
|
-
* With the plugin enabled, these will be created when the user
|
|
3584
|
-
* selects across cells, and will be drawn by giving selected cells a
|
|
3585
|
-
* `selectedCell` CSS class.
|
|
3586
|
-
*
|
|
3587
|
-
* @public
|
|
3588
|
-
*/
|
|
3589
|
-
var CellSelection = class CellSelection extends Selection {
|
|
3590
|
-
constructor($anchorCell, $headCell = $anchorCell) {
|
|
3591
|
-
const table = $anchorCell.node(-1);
|
|
3592
|
-
const map = TableMap.get(table);
|
|
3593
|
-
const tableStart = $anchorCell.start(-1);
|
|
3594
|
-
const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
|
|
3595
|
-
const doc = $anchorCell.node(0);
|
|
3596
|
-
const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
|
|
3597
|
-
cells.unshift($headCell.pos - tableStart);
|
|
3598
|
-
const ranges = cells.map((pos) => {
|
|
3599
|
-
const cell = table.nodeAt(pos);
|
|
3600
|
-
if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
|
|
3601
|
-
const from = tableStart + pos + 1;
|
|
3602
|
-
return new SelectionRange(doc.resolve(from), doc.resolve(from + cell.content.size));
|
|
3603
|
-
});
|
|
3604
|
-
super(ranges[0].$from, ranges[0].$to, ranges);
|
|
3605
|
-
this.$anchorCell = $anchorCell;
|
|
3606
|
-
this.$headCell = $headCell;
|
|
3607
|
-
}
|
|
3608
|
-
map(doc, mapping) {
|
|
3609
|
-
const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
|
|
3610
|
-
const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
|
|
3611
|
-
if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
|
|
3612
|
-
const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
|
|
3613
|
-
if (tableChanged && this.isRowSelection()) return CellSelection.rowSelection($anchorCell, $headCell);
|
|
3614
|
-
else if (tableChanged && this.isColSelection()) return CellSelection.colSelection($anchorCell, $headCell);
|
|
3615
|
-
else return new CellSelection($anchorCell, $headCell);
|
|
3616
|
-
}
|
|
3617
|
-
return TextSelection.between($anchorCell, $headCell);
|
|
3618
|
-
}
|
|
3619
|
-
content() {
|
|
3620
|
-
const table = this.$anchorCell.node(-1);
|
|
3621
|
-
const map = TableMap.get(table);
|
|
3622
|
-
const tableStart = this.$anchorCell.start(-1);
|
|
3623
|
-
const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
|
|
3624
|
-
const seen = {};
|
|
3625
|
-
const rows = [];
|
|
3626
|
-
for (let row = rect.top; row < rect.bottom; row++) {
|
|
3627
|
-
const rowContent = [];
|
|
3628
|
-
for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
|
|
3629
|
-
const pos = map.map[index];
|
|
3630
|
-
if (seen[pos]) continue;
|
|
3631
|
-
seen[pos] = true;
|
|
3632
|
-
const cellRect = map.findCell(pos);
|
|
3633
|
-
let cell = table.nodeAt(pos);
|
|
3634
|
-
if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
|
|
3635
|
-
const extraLeft = rect.left - cellRect.left;
|
|
3636
|
-
const extraRight = cellRect.right - rect.right;
|
|
3637
|
-
if (extraLeft > 0 || extraRight > 0) {
|
|
3638
|
-
let attrs = cell.attrs;
|
|
3639
|
-
if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft);
|
|
3640
|
-
if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
|
|
3641
|
-
if (cellRect.left < rect.left) {
|
|
3642
|
-
cell = cell.type.createAndFill(attrs);
|
|
3643
|
-
if (!cell) throw new RangeError(`Could not create cell with attrs ${JSON.stringify(attrs)}`);
|
|
3644
|
-
} else cell = cell.type.create(attrs, cell.content);
|
|
3645
|
-
}
|
|
3646
|
-
if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
|
|
3647
|
-
const attrs = {
|
|
3648
|
-
...cell.attrs,
|
|
3649
|
-
rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
|
|
3650
|
-
};
|
|
3651
|
-
if (cellRect.top < rect.top) cell = cell.type.createAndFill(attrs);
|
|
3652
|
-
else cell = cell.type.create(attrs, cell.content);
|
|
3653
|
-
}
|
|
3654
|
-
rowContent.push(cell);
|
|
3655
|
-
}
|
|
3656
|
-
rows.push(table.child(row).copy(Fragment$1.from(rowContent)));
|
|
3657
|
-
}
|
|
3658
|
-
const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
|
|
3659
|
-
return new Slice(Fragment$1.from(fragment), 1, 1);
|
|
3660
|
-
}
|
|
3661
|
-
replace(tr, content = Slice.empty) {
|
|
3662
|
-
const mapFrom = tr.steps.length, ranges = this.ranges;
|
|
3663
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
3664
|
-
const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
3665
|
-
tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
|
|
3666
|
-
}
|
|
3667
|
-
const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
|
|
3668
|
-
if (sel) tr.setSelection(sel);
|
|
3669
|
-
}
|
|
3670
|
-
replaceWith(tr, node) {
|
|
3671
|
-
this.replace(tr, new Slice(Fragment$1.from(node), 0, 0));
|
|
3672
|
-
}
|
|
3673
|
-
forEachCell(f) {
|
|
3674
|
-
const table = this.$anchorCell.node(-1);
|
|
3675
|
-
const map = TableMap.get(table);
|
|
3676
|
-
const tableStart = this.$anchorCell.start(-1);
|
|
3677
|
-
const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
|
|
3678
|
-
for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
|
|
3679
|
-
}
|
|
3680
|
-
isColSelection() {
|
|
3681
|
-
const anchorTop = this.$anchorCell.index(-1);
|
|
3682
|
-
const headTop = this.$headCell.index(-1);
|
|
3683
|
-
if (Math.min(anchorTop, headTop) > 0) return false;
|
|
3684
|
-
const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
|
|
3685
|
-
const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
|
|
3686
|
-
return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
|
|
3687
|
-
}
|
|
3688
|
-
static colSelection($anchorCell, $headCell = $anchorCell) {
|
|
3689
|
-
const table = $anchorCell.node(-1);
|
|
3690
|
-
const map = TableMap.get(table);
|
|
3691
|
-
const tableStart = $anchorCell.start(-1);
|
|
3692
|
-
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
3693
|
-
const headRect = map.findCell($headCell.pos - tableStart);
|
|
3694
|
-
const doc = $anchorCell.node(0);
|
|
3695
|
-
if (anchorRect.top <= headRect.top) {
|
|
3696
|
-
if (anchorRect.top > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
|
|
3697
|
-
if (headRect.bottom < map.height) $headCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]);
|
|
3698
|
-
} else {
|
|
3699
|
-
if (headRect.top > 0) $headCell = doc.resolve(tableStart + map.map[headRect.left]);
|
|
3700
|
-
if (anchorRect.bottom < map.height) $anchorCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
|
|
3701
|
-
}
|
|
3702
|
-
return new CellSelection($anchorCell, $headCell);
|
|
3703
|
-
}
|
|
3704
|
-
isRowSelection() {
|
|
3705
|
-
const table = this.$anchorCell.node(-1);
|
|
3706
|
-
const map = TableMap.get(table);
|
|
3707
|
-
const tableStart = this.$anchorCell.start(-1);
|
|
3708
|
-
const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
|
|
3709
|
-
const headLeft = map.colCount(this.$headCell.pos - tableStart);
|
|
3710
|
-
if (Math.min(anchorLeft, headLeft) > 0) return false;
|
|
3711
|
-
const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
|
|
3712
|
-
const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
|
|
3713
|
-
return Math.max(anchorRight, headRight) == map.width;
|
|
3714
|
-
}
|
|
3715
|
-
eq(other) {
|
|
3716
|
-
return other instanceof CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
|
|
3717
|
-
}
|
|
3718
|
-
static rowSelection($anchorCell, $headCell = $anchorCell) {
|
|
3719
|
-
const table = $anchorCell.node(-1);
|
|
3720
|
-
const map = TableMap.get(table);
|
|
3721
|
-
const tableStart = $anchorCell.start(-1);
|
|
3722
|
-
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
3723
|
-
const headRect = map.findCell($headCell.pos - tableStart);
|
|
3724
|
-
const doc = $anchorCell.node(0);
|
|
3725
|
-
if (anchorRect.left <= headRect.left) {
|
|
3726
|
-
if (anchorRect.left > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.top * map.width]);
|
|
3727
|
-
if (headRect.right < map.width) $headCell = doc.resolve(tableStart + map.map[map.width * (headRect.top + 1) - 1]);
|
|
3728
|
-
} else {
|
|
3729
|
-
if (headRect.left > 0) $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
|
|
3730
|
-
if (anchorRect.right < map.width) $anchorCell = doc.resolve(tableStart + map.map[map.width * (anchorRect.top + 1) - 1]);
|
|
3731
|
-
}
|
|
3732
|
-
return new CellSelection($anchorCell, $headCell);
|
|
3733
|
-
}
|
|
3734
|
-
toJSON() {
|
|
3735
|
-
return {
|
|
3736
|
-
type: "cell",
|
|
3737
|
-
anchor: this.$anchorCell.pos,
|
|
3738
|
-
head: this.$headCell.pos
|
|
3739
|
-
};
|
|
3740
|
-
}
|
|
3741
|
-
static fromJSON(doc, json) {
|
|
3742
|
-
return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
|
|
3743
|
-
}
|
|
3744
|
-
static create(doc, anchorCell, headCell = anchorCell) {
|
|
3745
|
-
return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
|
|
3746
|
-
}
|
|
3747
|
-
getBookmark() {
|
|
3748
|
-
return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
|
|
3749
|
-
}
|
|
3750
|
-
};
|
|
3751
|
-
CellSelection.prototype.visible = false;
|
|
3752
|
-
Selection.jsonID("cell", CellSelection);
|
|
3753
|
-
/**
|
|
3754
|
-
* @public
|
|
3755
|
-
*/
|
|
3756
|
-
var CellBookmark = class CellBookmark {
|
|
3757
|
-
constructor(anchor, head) {
|
|
3758
|
-
this.anchor = anchor;
|
|
3759
|
-
this.head = head;
|
|
3760
|
-
}
|
|
3761
|
-
map(mapping) {
|
|
3762
|
-
return new CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
|
|
3763
|
-
}
|
|
3764
|
-
resolve(doc) {
|
|
3765
|
-
const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
|
|
3766
|
-
if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell)) return new CellSelection($anchorCell, $headCell);
|
|
3767
|
-
else return Selection.near($headCell, 1);
|
|
3768
|
-
}
|
|
3769
|
-
};
|
|
3770
|
-
new PluginKey("fix-tables");
|
|
3771
|
-
/**
|
|
3772
|
-
* Helper to get the selected rectangle in a table, if any. Adds table
|
|
3773
|
-
* map, table node, and table start offset to the object for
|
|
3774
|
-
* convenience.
|
|
3775
|
-
*
|
|
3776
|
-
* @public
|
|
3777
|
-
*/
|
|
3778
|
-
function selectedRect(state) {
|
|
3779
|
-
const sel = state.selection;
|
|
3780
|
-
const $pos = selectionCell(state);
|
|
3781
|
-
const table = $pos.node(-1);
|
|
3782
|
-
const tableStart = $pos.start(-1);
|
|
3783
|
-
const map = TableMap.get(table);
|
|
3784
|
-
return {
|
|
3785
|
-
...sel instanceof CellSelection ? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map.findCell($pos.pos - tableStart),
|
|
3786
|
-
tableStart,
|
|
3787
|
-
map,
|
|
3788
|
-
table
|
|
3789
|
-
};
|
|
3790
|
-
}
|
|
3791
|
-
function deprecated_toggleHeader(type) {
|
|
3792
|
-
return function(state, dispatch) {
|
|
3793
|
-
if (!isInTable(state)) return false;
|
|
3794
|
-
if (dispatch) {
|
|
3795
|
-
const types = tableNodeTypes(state.schema);
|
|
3796
|
-
const rect = selectedRect(state), tr = state.tr;
|
|
3797
|
-
const cells = rect.map.cellsInRect(type == "column" ? {
|
|
3798
|
-
left: rect.left,
|
|
3799
|
-
top: 0,
|
|
3800
|
-
right: rect.right,
|
|
3801
|
-
bottom: rect.map.height
|
|
3802
|
-
} : type == "row" ? {
|
|
3803
|
-
left: 0,
|
|
3804
|
-
top: rect.top,
|
|
3805
|
-
right: rect.map.width,
|
|
3806
|
-
bottom: rect.bottom
|
|
3807
|
-
} : rect);
|
|
3808
|
-
const nodes = cells.map((pos) => rect.table.nodeAt(pos));
|
|
3809
|
-
for (let i = 0; i < cells.length; i++) if (nodes[i].type == types.header_cell) tr.setNodeMarkup(rect.tableStart + cells[i], types.cell, nodes[i].attrs);
|
|
3810
|
-
if (tr.steps.length === 0) for (let i = 0; i < cells.length; i++) tr.setNodeMarkup(rect.tableStart + cells[i], types.header_cell, nodes[i].attrs);
|
|
3811
|
-
dispatch(tr);
|
|
3812
|
-
}
|
|
3813
|
-
return true;
|
|
3814
|
-
};
|
|
3815
|
-
}
|
|
3816
|
-
function isHeaderEnabledByType(type, rect, types) {
|
|
3817
|
-
const cellPositions = rect.map.cellsInRect({
|
|
3818
|
-
left: 0,
|
|
3819
|
-
top: 0,
|
|
3820
|
-
right: type == "row" ? rect.map.width : 1,
|
|
3821
|
-
bottom: type == "column" ? rect.map.height : 1
|
|
3822
|
-
});
|
|
3823
|
-
for (let i = 0; i < cellPositions.length; i++) {
|
|
3824
|
-
const cell = rect.table.nodeAt(cellPositions[i]);
|
|
3825
|
-
if (cell && cell.type !== types.header_cell) return false;
|
|
3826
|
-
}
|
|
3827
|
-
return true;
|
|
3828
|
-
}
|
|
3829
|
-
/**
|
|
3830
|
-
* Toggles between row/column header and normal cells (Only applies to first row/column).
|
|
3831
|
-
* For deprecated behavior pass `useDeprecatedLogic` in options with true.
|
|
3832
|
-
*
|
|
3833
|
-
* @public
|
|
3834
|
-
*/
|
|
3835
|
-
function toggleHeader(type, options) {
|
|
3836
|
-
options = options || { useDeprecatedLogic: false };
|
|
3837
|
-
if (options.useDeprecatedLogic) return deprecated_toggleHeader(type);
|
|
3838
|
-
return function(state, dispatch) {
|
|
3839
|
-
if (!isInTable(state)) return false;
|
|
3840
|
-
if (dispatch) {
|
|
3841
|
-
const types = tableNodeTypes(state.schema);
|
|
3842
|
-
const rect = selectedRect(state), tr = state.tr;
|
|
3843
|
-
const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
|
|
3844
|
-
const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
|
|
3845
|
-
const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;
|
|
3846
|
-
const cellsRect = type == "column" ? {
|
|
3847
|
-
left: 0,
|
|
3848
|
-
top: selectionStartsAt,
|
|
3849
|
-
right: 1,
|
|
3850
|
-
bottom: rect.map.height
|
|
3851
|
-
} : type == "row" ? {
|
|
3852
|
-
left: selectionStartsAt,
|
|
3853
|
-
top: 0,
|
|
3854
|
-
right: rect.map.width,
|
|
3855
|
-
bottom: 1
|
|
3856
|
-
} : rect;
|
|
3857
|
-
const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
|
|
3858
|
-
rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
|
|
3859
|
-
const cellPos = relativeCellPos + rect.tableStart;
|
|
3860
|
-
const cell = tr.doc.nodeAt(cellPos);
|
|
3861
|
-
if (cell) tr.setNodeMarkup(cellPos, newType, cell.attrs);
|
|
3862
|
-
});
|
|
3863
|
-
dispatch(tr);
|
|
3864
|
-
}
|
|
3865
|
-
return true;
|
|
3866
|
-
};
|
|
3867
|
-
}
|
|
3868
|
-
toggleHeader("row", { useDeprecatedLogic: true });
|
|
3869
|
-
toggleHeader("column", { useDeprecatedLogic: true });
|
|
3870
|
-
toggleHeader("cell", { useDeprecatedLogic: true });
|
|
3871
|
-
/**
|
|
3872
|
-
* Deletes the content of the selected cells, if they are not empty.
|
|
3873
|
-
*
|
|
3874
|
-
* @public
|
|
3875
|
-
*/
|
|
3876
|
-
function deleteCellSelection(state, dispatch) {
|
|
3877
|
-
const sel = state.selection;
|
|
3878
|
-
if (!(sel instanceof CellSelection)) return false;
|
|
3879
|
-
if (dispatch) {
|
|
3880
|
-
const tr = state.tr;
|
|
3881
|
-
const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
|
|
3882
|
-
sel.forEachCell((cell, pos) => {
|
|
3883
|
-
if (!cell.content.eq(baseContent)) tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
|
|
3884
|
-
});
|
|
3885
|
-
if (tr.docChanged) dispatch(tr);
|
|
3886
|
-
}
|
|
3887
|
-
return true;
|
|
3888
|
-
}
|
|
3889
|
-
keydownHandler({
|
|
3890
|
-
ArrowLeft: arrow("horiz", -1),
|
|
3891
|
-
ArrowRight: arrow("horiz", 1),
|
|
3892
|
-
ArrowUp: arrow("vert", -1),
|
|
3893
|
-
ArrowDown: arrow("vert", 1),
|
|
3894
|
-
"Shift-ArrowLeft": shiftArrow("horiz", -1),
|
|
3895
|
-
"Shift-ArrowRight": shiftArrow("horiz", 1),
|
|
3896
|
-
"Shift-ArrowUp": shiftArrow("vert", -1),
|
|
3897
|
-
"Shift-ArrowDown": shiftArrow("vert", 1),
|
|
3898
|
-
Backspace: deleteCellSelection,
|
|
3899
|
-
"Mod-Backspace": deleteCellSelection,
|
|
3900
|
-
Delete: deleteCellSelection,
|
|
3901
|
-
"Mod-Delete": deleteCellSelection
|
|
3902
|
-
});
|
|
3903
|
-
function maybeSetSelection(state, dispatch, selection) {
|
|
3904
|
-
if (selection.eq(state.selection)) return false;
|
|
3905
|
-
if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
|
|
3906
|
-
return true;
|
|
3907
|
-
}
|
|
3908
|
-
/**
|
|
3909
|
-
* @internal
|
|
3910
|
-
*/
|
|
3911
|
-
function arrow(axis, dir) {
|
|
3912
|
-
return (state, dispatch, view) => {
|
|
3913
|
-
if (!view) return false;
|
|
3914
|
-
const sel = state.selection;
|
|
3915
|
-
if (sel instanceof CellSelection) return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
|
|
3916
|
-
if (axis != "horiz" && !sel.empty) return false;
|
|
3917
|
-
const end = atEndOfCell(view, axis, dir);
|
|
3918
|
-
if (end == null) return false;
|
|
3919
|
-
if (axis == "horiz") return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
|
|
3920
|
-
else {
|
|
3921
|
-
const $cell = state.doc.resolve(end);
|
|
3922
|
-
const $next = nextCell($cell, axis, dir);
|
|
3923
|
-
let newSel;
|
|
3924
|
-
if ($next) newSel = Selection.near($next, 1);
|
|
3925
|
-
else if (dir < 0) newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
|
|
3926
|
-
else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
|
|
3927
|
-
return maybeSetSelection(state, dispatch, newSel);
|
|
3928
|
-
}
|
|
3929
|
-
};
|
|
3930
|
-
}
|
|
3931
|
-
function shiftArrow(axis, dir) {
|
|
3932
|
-
return (state, dispatch, view) => {
|
|
3933
|
-
if (!view) return false;
|
|
3934
|
-
const sel = state.selection;
|
|
3935
|
-
let cellSel;
|
|
3936
|
-
if (sel instanceof CellSelection) cellSel = sel;
|
|
3937
|
-
else {
|
|
3938
|
-
const end = atEndOfCell(view, axis, dir);
|
|
3939
|
-
if (end == null) return false;
|
|
3940
|
-
cellSel = new CellSelection(state.doc.resolve(end));
|
|
3941
|
-
}
|
|
3942
|
-
const $head = nextCell(cellSel.$headCell, axis, dir);
|
|
3943
|
-
if (!$head) return false;
|
|
3944
|
-
return maybeSetSelection(state, dispatch, new CellSelection(cellSel.$anchorCell, $head));
|
|
3945
|
-
};
|
|
3946
|
-
}
|
|
3947
|
-
function atEndOfCell(view, axis, dir) {
|
|
3948
|
-
if (!(view.state.selection instanceof TextSelection)) return null;
|
|
3949
|
-
const { $head } = view.state.selection;
|
|
3950
|
-
for (let d = $head.depth - 1; d >= 0; d--) {
|
|
3951
|
-
const parent = $head.node(d);
|
|
3952
|
-
if ((dir < 0 ? $head.index(d) : $head.indexAfter(d)) != (dir < 0 ? 0 : parent.childCount)) return null;
|
|
3953
|
-
if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
|
|
3954
|
-
const cellPos = $head.before(d);
|
|
3955
|
-
const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
|
|
3956
|
-
return view.endOfTextblock(dirStr) ? cellPos : null;
|
|
3957
|
-
}
|
|
3958
|
-
}
|
|
3959
|
-
return null;
|
|
3960
|
-
}
|
|
3961
|
-
new PluginKey("tableColumnResizing");
|
|
3962
|
-
//#endregion
|
|
3963
74
|
//#region src/tiptap/lib/tiptap-utils.ts
|
|
3964
75
|
var MAC_SYMBOLS = {
|
|
3965
76
|
mod: "⌘",
|
|
@@ -4128,7 +239,7 @@ function isNodeTypeSelected(editor, nodeTypeNames = [], checkAncestorNodes = fal
|
|
|
4128
239
|
if (!editor || !editor.state.selection) return false;
|
|
4129
240
|
const { selection } = editor.state;
|
|
4130
241
|
if (selection.empty) return false;
|
|
4131
|
-
if (selection instanceof NodeSelection) {
|
|
242
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
4132
243
|
const selectedNode = selection.node;
|
|
4133
244
|
return selectedNode ? nodeTypeNames.includes(selectedNode.type.name) : false;
|
|
4134
245
|
}
|
|
@@ -4153,11 +264,11 @@ function selectionWithinConvertibleTypes(editor, types = []) {
|
|
|
4153
264
|
const { state } = editor;
|
|
4154
265
|
const { selection } = state;
|
|
4155
266
|
const allowed = new Set(types);
|
|
4156
|
-
if (selection instanceof NodeSelection) {
|
|
267
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
4157
268
|
const nodeType = selection.node?.type?.name;
|
|
4158
269
|
return !!nodeType && allowed.has(nodeType);
|
|
4159
270
|
}
|
|
4160
|
-
if (selection instanceof TextSelection || selection instanceof AllSelection) {
|
|
271
|
+
if (selection instanceof _tiptap_pm_state.TextSelection || selection instanceof _tiptap_pm_state.AllSelection) {
|
|
4161
272
|
let valid = true;
|
|
4162
273
|
state.doc.nodesBetween(selection.from, selection.to, (node) => {
|
|
4163
274
|
if (node.isTextblock && !allowed.has(node.type.name)) {
|
|
@@ -4253,26 +364,26 @@ function toggleBlockquote(editor) {
|
|
|
4253
364
|
"blockquote",
|
|
4254
365
|
"codeBlock"
|
|
4255
366
|
]) && blocks.length === 1;
|
|
4256
|
-
if ((state.selection.empty || state.selection instanceof TextSelection) && isPossibleToTurnInto) {
|
|
367
|
+
if ((state.selection.empty || state.selection instanceof _tiptap_pm_state.TextSelection) && isPossibleToTurnInto) {
|
|
4257
368
|
const pos = findNodePosition({
|
|
4258
369
|
editor,
|
|
4259
370
|
node: state.selection.$anchor.node(1)
|
|
4260
371
|
})?.pos;
|
|
4261
372
|
if (!isValidPosition(pos)) return false;
|
|
4262
|
-
tr = tr.setSelection(NodeSelection.create(state.doc, pos));
|
|
373
|
+
tr = tr.setSelection(_tiptap_pm_state.NodeSelection.create(state.doc, pos));
|
|
4263
374
|
view.dispatch(tr);
|
|
4264
375
|
state = view.state;
|
|
4265
376
|
}
|
|
4266
377
|
const selection = state.selection;
|
|
4267
378
|
let chain = editor.chain().focus();
|
|
4268
|
-
if (selection instanceof NodeSelection) {
|
|
379
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
4269
380
|
const firstChild = selection.node.firstChild?.firstChild;
|
|
4270
381
|
const lastChild = selection.node.lastChild?.lastChild;
|
|
4271
382
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
4272
383
|
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
4273
384
|
const resolvedFrom = state.doc.resolve(from);
|
|
4274
385
|
const resolvedTo = state.doc.resolve(to);
|
|
4275
|
-
chain = chain.setTextSelection(TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
386
|
+
chain = chain.setTextSelection(_tiptap_pm_state.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
4276
387
|
}
|
|
4277
388
|
(editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote")).run();
|
|
4278
389
|
editor.chain().focus().selectTextblockEnd().run();
|
|
@@ -4522,26 +633,26 @@ function toggleCodeBlock(editor) {
|
|
|
4522
633
|
"blockquote",
|
|
4523
634
|
"codeBlock"
|
|
4524
635
|
]) && blocks.length === 1;
|
|
4525
|
-
if ((state.selection.empty || state.selection instanceof TextSelection) && isPossibleToTurnInto) {
|
|
636
|
+
if ((state.selection.empty || state.selection instanceof _tiptap_pm_state.TextSelection) && isPossibleToTurnInto) {
|
|
4526
637
|
const pos = findNodePosition({
|
|
4527
638
|
editor,
|
|
4528
639
|
node: state.selection.$anchor.node(1)
|
|
4529
640
|
})?.pos;
|
|
4530
641
|
if (!isValidPosition(pos)) return false;
|
|
4531
|
-
tr = tr.setSelection(NodeSelection.create(state.doc, pos));
|
|
642
|
+
tr = tr.setSelection(_tiptap_pm_state.NodeSelection.create(state.doc, pos));
|
|
4532
643
|
view.dispatch(tr);
|
|
4533
644
|
state = view.state;
|
|
4534
645
|
}
|
|
4535
646
|
const selection = state.selection;
|
|
4536
647
|
let chain = editor.chain().focus();
|
|
4537
|
-
if (selection instanceof NodeSelection) {
|
|
648
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
4538
649
|
const firstChild = selection.node.firstChild?.firstChild;
|
|
4539
650
|
const lastChild = selection.node.lastChild?.lastChild;
|
|
4540
651
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
4541
652
|
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
4542
653
|
const resolvedFrom = state.doc.resolve(from);
|
|
4543
654
|
const resolvedTo = state.doc.resolve(to);
|
|
4544
|
-
chain = chain.setTextSelection(TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
655
|
+
chain = chain.setTextSelection(_tiptap_pm_state.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
4545
656
|
}
|
|
4546
657
|
(editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph")).run();
|
|
4547
658
|
editor.chain().focus().selectTextblockEnd().run();
|
|
@@ -4820,26 +931,26 @@ function toggleHeading(editor, level) {
|
|
|
4820
931
|
"blockquote",
|
|
4821
932
|
"codeBlock"
|
|
4822
933
|
]) && blocks.length === 1;
|
|
4823
|
-
if ((state.selection.empty || state.selection instanceof TextSelection) && isPossibleToTurnInto) {
|
|
934
|
+
if ((state.selection.empty || state.selection instanceof _tiptap_pm_state.TextSelection) && isPossibleToTurnInto) {
|
|
4824
935
|
const pos = findNodePosition({
|
|
4825
936
|
editor,
|
|
4826
937
|
node: state.selection.$anchor.node(1)
|
|
4827
938
|
})?.pos;
|
|
4828
939
|
if (!isValidPosition(pos)) return false;
|
|
4829
|
-
tr = tr.setSelection(NodeSelection.create(state.doc, pos));
|
|
940
|
+
tr = tr.setSelection(_tiptap_pm_state.NodeSelection.create(state.doc, pos));
|
|
4830
941
|
view.dispatch(tr);
|
|
4831
942
|
state = view.state;
|
|
4832
943
|
}
|
|
4833
944
|
const selection = state.selection;
|
|
4834
945
|
let chain = editor.chain().focus();
|
|
4835
|
-
if (selection instanceof NodeSelection) {
|
|
946
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
4836
947
|
const firstChild = selection.node.firstChild?.firstChild;
|
|
4837
948
|
const lastChild = selection.node.lastChild?.lastChild;
|
|
4838
949
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
4839
950
|
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
4840
951
|
const resolvedFrom = state.doc.resolve(from);
|
|
4841
952
|
const resolvedTo = state.doc.resolve(to);
|
|
4842
|
-
chain = chain.setTextSelection(TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
953
|
+
chain = chain.setTextSelection(_tiptap_pm_state.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
4843
954
|
}
|
|
4844
955
|
(levels.some((l) => editor.isActive("heading", { level: l })) ? chain.setNode("paragraph") : chain.setNode("heading", { level: toggleLevel })).run();
|
|
4845
956
|
editor.chain().focus().selectTextblockEnd().run();
|
|
@@ -5637,26 +1748,26 @@ function toggleList(editor, type) {
|
|
|
5637
1748
|
"blockquote",
|
|
5638
1749
|
"codeBlock"
|
|
5639
1750
|
]) && blocks.length === 1;
|
|
5640
|
-
if ((state.selection.empty || state.selection instanceof TextSelection) && isPossibleToTurnInto) {
|
|
1751
|
+
if ((state.selection.empty || state.selection instanceof _tiptap_pm_state.TextSelection) && isPossibleToTurnInto) {
|
|
5641
1752
|
const pos = findNodePosition({
|
|
5642
1753
|
editor,
|
|
5643
1754
|
node: state.selection.$anchor.node(1)
|
|
5644
1755
|
})?.pos;
|
|
5645
1756
|
if (!isValidPosition(pos)) return false;
|
|
5646
|
-
tr = tr.setSelection(NodeSelection.create(state.doc, pos));
|
|
1757
|
+
tr = tr.setSelection(_tiptap_pm_state.NodeSelection.create(state.doc, pos));
|
|
5647
1758
|
view.dispatch(tr);
|
|
5648
1759
|
state = view.state;
|
|
5649
1760
|
}
|
|
5650
1761
|
const selection = state.selection;
|
|
5651
1762
|
let chain = editor.chain().focus();
|
|
5652
|
-
if (selection instanceof NodeSelection) {
|
|
1763
|
+
if (selection instanceof _tiptap_pm_state.NodeSelection) {
|
|
5653
1764
|
const firstChild = selection.node.firstChild?.firstChild;
|
|
5654
1765
|
const lastChild = selection.node.lastChild?.lastChild;
|
|
5655
1766
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
5656
1767
|
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
5657
1768
|
const resolvedFrom = state.doc.resolve(from);
|
|
5658
1769
|
const resolvedTo = state.doc.resolve(to);
|
|
5659
|
-
chain = chain.setTextSelection(TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
1770
|
+
chain = chain.setTextSelection(_tiptap_pm_state.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
5660
1771
|
}
|
|
5661
1772
|
if (editor.isActive(type)) chain.liftListItem("listItem").lift("bulletList").lift("orderedList").run();
|
|
5662
1773
|
else {
|