raydit-editor 0.0.3 → 0.0.6
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/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +231 -2070
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +176 -2035
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -7
package/dist/index.mjs
CHANGED
|
@@ -1,31 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import { useEditor, EditorContent } from
|
|
3
|
-
import StarterKit from
|
|
4
|
-
import Placeholder from
|
|
5
|
-
import
|
|
6
|
-
import { Color } from
|
|
7
|
-
import Highlight from
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import { BubbleMenu } from "@tiptap/react/menus";
|
|
22
|
-
import { useEffect as useEffect5, useRef as useRef3 } from "react";
|
|
23
|
-
import clsx from "clsx";
|
|
1
|
+
import React, { useState, useRef, useMemo, useEffect } from 'react';
|
|
2
|
+
import { ReactRenderer, useEditor, EditorContent } from '@tiptap/react';
|
|
3
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
4
|
+
import Placeholder from '@tiptap/extension-placeholder';
|
|
5
|
+
import Underline from '@tiptap/extension-underline';
|
|
6
|
+
import { Color } from '@tiptap/extension-color';
|
|
7
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
8
|
+
import Link2 from '@tiptap/extension-link';
|
|
9
|
+
import { TableRow, TableHeader, TableCell, Table as Table$1 } from '@tiptap/extension-table';
|
|
10
|
+
import { TextStyle } from '@tiptap/extension-text-style';
|
|
11
|
+
import Superscript from '@tiptap/extension-superscript';
|
|
12
|
+
import Subscript from '@tiptap/extension-subscript';
|
|
13
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
14
|
+
import TaskList from '@tiptap/extension-task-list';
|
|
15
|
+
import TaskItem from '@tiptap/extension-task-item';
|
|
16
|
+
import clsx from 'clsx';
|
|
17
|
+
import { Extension } from '@tiptap/core';
|
|
18
|
+
import Suggestion from '@tiptap/suggestion';
|
|
19
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
20
|
+
import { Type, Heading1, Heading2, Heading3, List, ListOrdered, Quote, Code, Minus, Table, Link, MoreHorizontal } from 'lucide-react';
|
|
24
21
|
|
|
25
|
-
// src/
|
|
26
|
-
import { Extension } from "@tiptap/core";
|
|
27
|
-
import Suggestion from "@tiptap/suggestion";
|
|
28
|
-
import { ReactRenderer } from "@tiptap/react";
|
|
22
|
+
// src/NotionEditor.tsx
|
|
29
23
|
|
|
30
24
|
// node_modules/prosemirror-model/dist/index.js
|
|
31
25
|
function findDiffStart(a, b, pos) {
|
|
@@ -354,1519 +348,143 @@ var Fragment = class _Fragment {
|
|
|
354
348
|
joined.push(node);
|
|
355
349
|
}
|
|
356
350
|
}
|
|
357
|
-
return new _Fragment(joined || array, size);
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
Create a fragment from something that can be interpreted as a
|
|
361
|
-
set of nodes. For `null`, it returns the empty fragment. For a
|
|
362
|
-
fragment, the fragment itself. For a node or array of nodes, a
|
|
363
|
-
fragment containing those nodes.
|
|
364
|
-
*/
|
|
365
|
-
static from(nodes) {
|
|
366
|
-
if (!nodes)
|
|
367
|
-
return _Fragment.empty;
|
|
368
|
-
if (nodes instanceof _Fragment)
|
|
369
|
-
return nodes;
|
|
370
|
-
if (Array.isArray(nodes))
|
|
371
|
-
return this.fromArray(nodes);
|
|
372
|
-
if (nodes.attrs)
|
|
373
|
-
return new _Fragment([nodes], nodes.nodeSize);
|
|
374
|
-
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
Fragment.empty = new Fragment([], 0);
|
|
378
|
-
var found = { index: 0, offset: 0 };
|
|
379
|
-
function retIndex(index, offset2) {
|
|
380
|
-
found.index = index;
|
|
381
|
-
found.offset = offset2;
|
|
382
|
-
return found;
|
|
383
|
-
}
|
|
384
|
-
function compareDeep(a, b) {
|
|
385
|
-
if (a === b)
|
|
386
|
-
return true;
|
|
387
|
-
if (!(a && typeof a == "object") || !(b && typeof b == "object"))
|
|
388
|
-
return false;
|
|
389
|
-
let array = Array.isArray(a);
|
|
390
|
-
if (Array.isArray(b) != array)
|
|
391
|
-
return false;
|
|
392
|
-
if (array) {
|
|
393
|
-
if (a.length != b.length)
|
|
394
|
-
return false;
|
|
395
|
-
for (let i = 0; i < a.length; i++)
|
|
396
|
-
if (!compareDeep(a[i], b[i]))
|
|
397
|
-
return false;
|
|
398
|
-
} else {
|
|
399
|
-
for (let p in a)
|
|
400
|
-
if (!(p in b) || !compareDeep(a[p], b[p]))
|
|
401
|
-
return false;
|
|
402
|
-
for (let p in b)
|
|
403
|
-
if (!(p in a))
|
|
404
|
-
return false;
|
|
405
|
-
}
|
|
406
|
-
return true;
|
|
407
|
-
}
|
|
408
|
-
var Mark = class _Mark {
|
|
409
|
-
/**
|
|
410
|
-
@internal
|
|
411
|
-
*/
|
|
412
|
-
constructor(type, attrs) {
|
|
413
|
-
this.type = type;
|
|
414
|
-
this.attrs = attrs;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
Given a set of marks, create a new set which contains this one as
|
|
418
|
-
well, in the right position. If this mark is already in the set,
|
|
419
|
-
the set itself is returned. If any marks that are set to be
|
|
420
|
-
[exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present,
|
|
421
|
-
those are replaced by this one.
|
|
422
|
-
*/
|
|
423
|
-
addToSet(set) {
|
|
424
|
-
let copy, placed = false;
|
|
425
|
-
for (let i = 0; i < set.length; i++) {
|
|
426
|
-
let other = set[i];
|
|
427
|
-
if (this.eq(other))
|
|
428
|
-
return set;
|
|
429
|
-
if (this.type.excludes(other.type)) {
|
|
430
|
-
if (!copy)
|
|
431
|
-
copy = set.slice(0, i);
|
|
432
|
-
} else if (other.type.excludes(this.type)) {
|
|
433
|
-
return set;
|
|
434
|
-
} else {
|
|
435
|
-
if (!placed && other.type.rank > this.type.rank) {
|
|
436
|
-
if (!copy)
|
|
437
|
-
copy = set.slice(0, i);
|
|
438
|
-
copy.push(this);
|
|
439
|
-
placed = true;
|
|
440
|
-
}
|
|
441
|
-
if (copy)
|
|
442
|
-
copy.push(other);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
if (!copy)
|
|
446
|
-
copy = set.slice();
|
|
447
|
-
if (!placed)
|
|
448
|
-
copy.push(this);
|
|
449
|
-
return copy;
|
|
450
|
-
}
|
|
451
|
-
/**
|
|
452
|
-
Remove this mark from the given set, returning a new set. If this
|
|
453
|
-
mark is not in the set, the set itself is returned.
|
|
454
|
-
*/
|
|
455
|
-
removeFromSet(set) {
|
|
456
|
-
for (let i = 0; i < set.length; i++)
|
|
457
|
-
if (this.eq(set[i]))
|
|
458
|
-
return set.slice(0, i).concat(set.slice(i + 1));
|
|
459
|
-
return set;
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
Test whether this mark is in the given set of marks.
|
|
463
|
-
*/
|
|
464
|
-
isInSet(set) {
|
|
465
|
-
for (let i = 0; i < set.length; i++)
|
|
466
|
-
if (this.eq(set[i]))
|
|
467
|
-
return true;
|
|
468
|
-
return false;
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
Test whether this mark has the same type and attributes as
|
|
472
|
-
another mark.
|
|
473
|
-
*/
|
|
474
|
-
eq(other) {
|
|
475
|
-
return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs);
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
Convert this mark to a JSON-serializeable representation.
|
|
479
|
-
*/
|
|
480
|
-
toJSON() {
|
|
481
|
-
let obj = { type: this.type.name };
|
|
482
|
-
for (let _ in this.attrs) {
|
|
483
|
-
obj.attrs = this.attrs;
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
return obj;
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
Deserialize a mark from JSON.
|
|
490
|
-
*/
|
|
491
|
-
static fromJSON(schema, json) {
|
|
492
|
-
if (!json)
|
|
493
|
-
throw new RangeError("Invalid input for Mark.fromJSON");
|
|
494
|
-
let type = schema.marks[json.type];
|
|
495
|
-
if (!type)
|
|
496
|
-
throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
497
|
-
let mark = type.create(json.attrs);
|
|
498
|
-
type.checkAttrs(mark.attrs);
|
|
499
|
-
return mark;
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
Test whether two sets of marks are identical.
|
|
503
|
-
*/
|
|
504
|
-
static sameSet(a, b) {
|
|
505
|
-
if (a == b)
|
|
506
|
-
return true;
|
|
507
|
-
if (a.length != b.length)
|
|
508
|
-
return false;
|
|
509
|
-
for (let i = 0; i < a.length; i++)
|
|
510
|
-
if (!a[i].eq(b[i]))
|
|
511
|
-
return false;
|
|
512
|
-
return true;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
Create a properly sorted mark set from null, a single mark, or an
|
|
516
|
-
unsorted array of marks.
|
|
517
|
-
*/
|
|
518
|
-
static setFrom(marks) {
|
|
519
|
-
if (!marks || Array.isArray(marks) && marks.length == 0)
|
|
520
|
-
return _Mark.none;
|
|
521
|
-
if (marks instanceof _Mark)
|
|
522
|
-
return [marks];
|
|
523
|
-
let copy = marks.slice();
|
|
524
|
-
copy.sort((a, b) => a.type.rank - b.type.rank);
|
|
525
|
-
return copy;
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
Mark.none = [];
|
|
529
|
-
var ReplaceError = class extends Error {
|
|
530
|
-
};
|
|
531
|
-
var Slice = class _Slice {
|
|
532
|
-
/**
|
|
533
|
-
Create a slice. When specifying a non-zero open depth, you must
|
|
534
|
-
make sure that there are nodes of at least that depth at the
|
|
535
|
-
appropriate side of the fragment—i.e. if the fragment is an
|
|
536
|
-
empty paragraph node, `openStart` and `openEnd` can't be greater
|
|
537
|
-
than 1.
|
|
538
|
-
|
|
539
|
-
It is not necessary for the content of open nodes to conform to
|
|
540
|
-
the schema's content constraints, though it should be a valid
|
|
541
|
-
start/end/middle for such a node, depending on which sides are
|
|
542
|
-
open.
|
|
543
|
-
*/
|
|
544
|
-
constructor(content, openStart, openEnd) {
|
|
545
|
-
this.content = content;
|
|
546
|
-
this.openStart = openStart;
|
|
547
|
-
this.openEnd = openEnd;
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
The size this slice would add when inserted into a document.
|
|
551
|
-
*/
|
|
552
|
-
get size() {
|
|
553
|
-
return this.content.size - this.openStart - this.openEnd;
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
@internal
|
|
557
|
-
*/
|
|
558
|
-
insertAt(pos, fragment) {
|
|
559
|
-
let content = insertInto(this.content, pos + this.openStart, fragment);
|
|
560
|
-
return content && new _Slice(content, this.openStart, this.openEnd);
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
@internal
|
|
564
|
-
*/
|
|
565
|
-
removeBetween(from, to) {
|
|
566
|
-
return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
Tests whether this slice is equal to another slice.
|
|
570
|
-
*/
|
|
571
|
-
eq(other) {
|
|
572
|
-
return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
|
|
573
|
-
}
|
|
574
|
-
/**
|
|
575
|
-
@internal
|
|
576
|
-
*/
|
|
577
|
-
toString() {
|
|
578
|
-
return this.content + "(" + this.openStart + "," + this.openEnd + ")";
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
Convert a slice to a JSON-serializable representation.
|
|
582
|
-
*/
|
|
583
|
-
toJSON() {
|
|
584
|
-
if (!this.content.size)
|
|
585
|
-
return null;
|
|
586
|
-
let json = { content: this.content.toJSON() };
|
|
587
|
-
if (this.openStart > 0)
|
|
588
|
-
json.openStart = this.openStart;
|
|
589
|
-
if (this.openEnd > 0)
|
|
590
|
-
json.openEnd = this.openEnd;
|
|
591
|
-
return json;
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
Deserialize a slice from its JSON representation.
|
|
595
|
-
*/
|
|
596
|
-
static fromJSON(schema, json) {
|
|
597
|
-
if (!json)
|
|
598
|
-
return _Slice.empty;
|
|
599
|
-
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
600
|
-
if (typeof openStart != "number" || typeof openEnd != "number")
|
|
601
|
-
throw new RangeError("Invalid input for Slice.fromJSON");
|
|
602
|
-
return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
Create a slice from a fragment by taking the maximum possible
|
|
606
|
-
open value on both side of the fragment.
|
|
607
|
-
*/
|
|
608
|
-
static maxOpen(fragment, openIsolating = true) {
|
|
609
|
-
let openStart = 0, openEnd = 0;
|
|
610
|
-
for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
|
|
611
|
-
openStart++;
|
|
612
|
-
for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
|
|
613
|
-
openEnd++;
|
|
614
|
-
return new _Slice(fragment, openStart, openEnd);
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
Slice.empty = new Slice(Fragment.empty, 0, 0);
|
|
618
|
-
function removeRange(content, from, to) {
|
|
619
|
-
let { index, offset: offset2 } = content.findIndex(from), child = content.maybeChild(index);
|
|
620
|
-
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
621
|
-
if (offset2 == from || child.isText) {
|
|
622
|
-
if (offsetTo != to && !content.child(indexTo).isText)
|
|
623
|
-
throw new RangeError("Removing non-flat range");
|
|
624
|
-
return content.cut(0, from).append(content.cut(to));
|
|
625
|
-
}
|
|
626
|
-
if (index != indexTo)
|
|
627
|
-
throw new RangeError("Removing non-flat range");
|
|
628
|
-
return content.replaceChild(index, child.copy(removeRange(child.content, from - offset2 - 1, to - offset2 - 1)));
|
|
629
|
-
}
|
|
630
|
-
function insertInto(content, dist, insert, parent) {
|
|
631
|
-
let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index);
|
|
632
|
-
if (offset2 == dist || child.isText) {
|
|
633
|
-
if (parent && !parent.canReplace(index, index, insert))
|
|
634
|
-
return null;
|
|
635
|
-
return content.cut(0, dist).append(insert).append(content.cut(dist));
|
|
636
|
-
}
|
|
637
|
-
let inner = insertInto(child.content, dist - offset2 - 1, insert, child);
|
|
638
|
-
return inner && content.replaceChild(index, child.copy(inner));
|
|
639
|
-
}
|
|
640
|
-
function replace($from, $to, slice) {
|
|
641
|
-
if (slice.openStart > $from.depth)
|
|
642
|
-
throw new ReplaceError("Inserted content deeper than insertion position");
|
|
643
|
-
if ($from.depth - slice.openStart != $to.depth - slice.openEnd)
|
|
644
|
-
throw new ReplaceError("Inconsistent open depths");
|
|
645
|
-
return replaceOuter($from, $to, slice, 0);
|
|
646
|
-
}
|
|
647
|
-
function replaceOuter($from, $to, slice, depth) {
|
|
648
|
-
let index = $from.index(depth), node = $from.node(depth);
|
|
649
|
-
if (index == $to.index(depth) && depth < $from.depth - slice.openStart) {
|
|
650
|
-
let inner = replaceOuter($from, $to, slice, depth + 1);
|
|
651
|
-
return node.copy(node.content.replaceChild(index, inner));
|
|
652
|
-
} else if (!slice.content.size) {
|
|
653
|
-
return close(node, replaceTwoWay($from, $to, depth));
|
|
654
|
-
} else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) {
|
|
655
|
-
let parent = $from.parent, content = parent.content;
|
|
656
|
-
return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
|
|
657
|
-
} else {
|
|
658
|
-
let { start: start2, end: end2 } = prepareSliceForReplace(slice, $from);
|
|
659
|
-
return close(node, replaceThreeWay($from, start2, end2, $to, depth));
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
function checkJoin(main2, sub) {
|
|
663
|
-
if (!sub.type.compatibleContent(main2.type))
|
|
664
|
-
throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main2.type.name);
|
|
665
|
-
}
|
|
666
|
-
function joinable($before, $after, depth) {
|
|
667
|
-
let node = $before.node(depth);
|
|
668
|
-
checkJoin(node, $after.node(depth));
|
|
669
|
-
return node;
|
|
670
|
-
}
|
|
671
|
-
function addNode(child, target) {
|
|
672
|
-
let last = target.length - 1;
|
|
673
|
-
if (last >= 0 && child.isText && child.sameMarkup(target[last]))
|
|
674
|
-
target[last] = child.withText(target[last].text + child.text);
|
|
675
|
-
else
|
|
676
|
-
target.push(child);
|
|
677
|
-
}
|
|
678
|
-
function addRange($start, $end, depth, target) {
|
|
679
|
-
let node = ($end || $start).node(depth);
|
|
680
|
-
let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
|
|
681
|
-
if ($start) {
|
|
682
|
-
startIndex = $start.index(depth);
|
|
683
|
-
if ($start.depth > depth) {
|
|
684
|
-
startIndex++;
|
|
685
|
-
} else if ($start.textOffset) {
|
|
686
|
-
addNode($start.nodeAfter, target);
|
|
687
|
-
startIndex++;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
for (let i = startIndex; i < endIndex; i++)
|
|
691
|
-
addNode(node.child(i), target);
|
|
692
|
-
if ($end && $end.depth == depth && $end.textOffset)
|
|
693
|
-
addNode($end.nodeBefore, target);
|
|
694
|
-
}
|
|
695
|
-
function close(node, content) {
|
|
696
|
-
node.type.checkContent(content);
|
|
697
|
-
return node.copy(content);
|
|
698
|
-
}
|
|
699
|
-
function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
700
|
-
let openStart = $from.depth > depth && joinable($from, $start, depth + 1);
|
|
701
|
-
let openEnd = $to.depth > depth && joinable($end, $to, depth + 1);
|
|
702
|
-
let content = [];
|
|
703
|
-
addRange(null, $from, depth, content);
|
|
704
|
-
if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
|
|
705
|
-
checkJoin(openStart, openEnd);
|
|
706
|
-
addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
|
|
707
|
-
} else {
|
|
708
|
-
if (openStart)
|
|
709
|
-
addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
|
|
710
|
-
addRange($start, $end, depth, content);
|
|
711
|
-
if (openEnd)
|
|
712
|
-
addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
713
|
-
}
|
|
714
|
-
addRange($to, null, depth, content);
|
|
715
|
-
return new Fragment(content);
|
|
716
|
-
}
|
|
717
|
-
function replaceTwoWay($from, $to, depth) {
|
|
718
|
-
let content = [];
|
|
719
|
-
addRange(null, $from, depth, content);
|
|
720
|
-
if ($from.depth > depth) {
|
|
721
|
-
let type = joinable($from, $to, depth + 1);
|
|
722
|
-
addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
|
|
723
|
-
}
|
|
724
|
-
addRange($to, null, depth, content);
|
|
725
|
-
return new Fragment(content);
|
|
726
|
-
}
|
|
727
|
-
function prepareSliceForReplace(slice, $along) {
|
|
728
|
-
let extra = $along.depth - slice.openStart, parent = $along.node(extra);
|
|
729
|
-
let node = parent.copy(slice.content);
|
|
730
|
-
for (let i = extra - 1; i >= 0; i--)
|
|
731
|
-
node = $along.node(i).copy(Fragment.from(node));
|
|
732
|
-
return {
|
|
733
|
-
start: node.resolveNoCache(slice.openStart + extra),
|
|
734
|
-
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
var ResolvedPos = class _ResolvedPos {
|
|
738
|
-
/**
|
|
739
|
-
@internal
|
|
740
|
-
*/
|
|
741
|
-
constructor(pos, path, parentOffset) {
|
|
742
|
-
this.pos = pos;
|
|
743
|
-
this.path = path;
|
|
744
|
-
this.parentOffset = parentOffset;
|
|
745
|
-
this.depth = path.length / 3 - 1;
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
@internal
|
|
749
|
-
*/
|
|
750
|
-
resolveDepth(val) {
|
|
751
|
-
if (val == null)
|
|
752
|
-
return this.depth;
|
|
753
|
-
if (val < 0)
|
|
754
|
-
return this.depth + val;
|
|
755
|
-
return val;
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
The parent node that the position points into. Note that even if
|
|
759
|
-
a position points into a text node, that node is not considered
|
|
760
|
-
the parent—text nodes are ‘flat’ in this model, and have no content.
|
|
761
|
-
*/
|
|
762
|
-
get parent() {
|
|
763
|
-
return this.node(this.depth);
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
The root node in which the position was resolved.
|
|
767
|
-
*/
|
|
768
|
-
get doc() {
|
|
769
|
-
return this.node(0);
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
The ancestor node at the given level. `p.node(p.depth)` is the
|
|
773
|
-
same as `p.parent`.
|
|
774
|
-
*/
|
|
775
|
-
node(depth) {
|
|
776
|
-
return this.path[this.resolveDepth(depth) * 3];
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
The index into the ancestor at the given level. If this points
|
|
780
|
-
at the 3rd node in the 2nd paragraph on the top level, for
|
|
781
|
-
example, `p.index(0)` is 1 and `p.index(1)` is 2.
|
|
782
|
-
*/
|
|
783
|
-
index(depth) {
|
|
784
|
-
return this.path[this.resolveDepth(depth) * 3 + 1];
|
|
785
|
-
}
|
|
786
|
-
/**
|
|
787
|
-
The index pointing after this position into the ancestor at the
|
|
788
|
-
given level.
|
|
789
|
-
*/
|
|
790
|
-
indexAfter(depth) {
|
|
791
|
-
depth = this.resolveDepth(depth);
|
|
792
|
-
return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
The (absolute) position at the start of the node at the given
|
|
796
|
-
level.
|
|
797
|
-
*/
|
|
798
|
-
start(depth) {
|
|
799
|
-
depth = this.resolveDepth(depth);
|
|
800
|
-
return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
|
|
801
|
-
}
|
|
802
|
-
/**
|
|
803
|
-
The (absolute) position at the end of the node at the given
|
|
804
|
-
level.
|
|
805
|
-
*/
|
|
806
|
-
end(depth) {
|
|
807
|
-
depth = this.resolveDepth(depth);
|
|
808
|
-
return this.start(depth) + this.node(depth).content.size;
|
|
809
|
-
}
|
|
810
|
-
/**
|
|
811
|
-
The (absolute) position directly before the wrapping node at the
|
|
812
|
-
given level, or, when `depth` is `this.depth + 1`, the original
|
|
813
|
-
position.
|
|
814
|
-
*/
|
|
815
|
-
before(depth) {
|
|
816
|
-
depth = this.resolveDepth(depth);
|
|
817
|
-
if (!depth)
|
|
818
|
-
throw new RangeError("There is no position before the top-level node");
|
|
819
|
-
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
|
-
The (absolute) position directly after the wrapping node at the
|
|
823
|
-
given level, or the original position when `depth` is `this.depth + 1`.
|
|
824
|
-
*/
|
|
825
|
-
after(depth) {
|
|
826
|
-
depth = this.resolveDepth(depth);
|
|
827
|
-
if (!depth)
|
|
828
|
-
throw new RangeError("There is no position after the top-level node");
|
|
829
|
-
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
|
|
830
|
-
}
|
|
831
|
-
/**
|
|
832
|
-
When this position points into a text node, this returns the
|
|
833
|
-
distance between the position and the start of the text node.
|
|
834
|
-
Will be zero for positions that point between nodes.
|
|
835
|
-
*/
|
|
836
|
-
get textOffset() {
|
|
837
|
-
return this.pos - this.path[this.path.length - 1];
|
|
838
|
-
}
|
|
839
|
-
/**
|
|
840
|
-
Get the node directly after the position, if any. If the position
|
|
841
|
-
points into a text node, only the part of that node after the
|
|
842
|
-
position is returned.
|
|
843
|
-
*/
|
|
844
|
-
get nodeAfter() {
|
|
845
|
-
let parent = this.parent, index = this.index(this.depth);
|
|
846
|
-
if (index == parent.childCount)
|
|
847
|
-
return null;
|
|
848
|
-
let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
|
|
849
|
-
return dOff ? parent.child(index).cut(dOff) : child;
|
|
850
|
-
}
|
|
851
|
-
/**
|
|
852
|
-
Get the node directly before the position, if any. If the
|
|
853
|
-
position points into a text node, only the part of that node
|
|
854
|
-
before the position is returned.
|
|
855
|
-
*/
|
|
856
|
-
get nodeBefore() {
|
|
857
|
-
let index = this.index(this.depth);
|
|
858
|
-
let dOff = this.pos - this.path[this.path.length - 1];
|
|
859
|
-
if (dOff)
|
|
860
|
-
return this.parent.child(index).cut(0, dOff);
|
|
861
|
-
return index == 0 ? null : this.parent.child(index - 1);
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
Get the position at the given index in the parent node at the
|
|
865
|
-
given depth (which defaults to `this.depth`).
|
|
866
|
-
*/
|
|
867
|
-
posAtIndex(index, depth) {
|
|
868
|
-
depth = this.resolveDepth(depth);
|
|
869
|
-
let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
|
|
870
|
-
for (let i = 0; i < index; i++)
|
|
871
|
-
pos += node.child(i).nodeSize;
|
|
872
|
-
return pos;
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
Get the marks at this position, factoring in the surrounding
|
|
876
|
-
marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the
|
|
877
|
-
position is at the start of a non-empty node, the marks of the
|
|
878
|
-
node after it (if any) are returned.
|
|
879
|
-
*/
|
|
880
|
-
marks() {
|
|
881
|
-
let parent = this.parent, index = this.index();
|
|
882
|
-
if (parent.content.size == 0)
|
|
883
|
-
return Mark.none;
|
|
884
|
-
if (this.textOffset)
|
|
885
|
-
return parent.child(index).marks;
|
|
886
|
-
let main2 = parent.maybeChild(index - 1), other = parent.maybeChild(index);
|
|
887
|
-
if (!main2) {
|
|
888
|
-
let tmp = main2;
|
|
889
|
-
main2 = other;
|
|
890
|
-
other = tmp;
|
|
891
|
-
}
|
|
892
|
-
let marks = main2.marks;
|
|
893
|
-
for (var i = 0; i < marks.length; i++)
|
|
894
|
-
if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks)))
|
|
895
|
-
marks = marks[i--].removeFromSet(marks);
|
|
896
|
-
return marks;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
Get the marks after the current position, if any, except those
|
|
900
|
-
that are non-inclusive and not present at position `$end`. This
|
|
901
|
-
is mostly useful for getting the set of marks to preserve after a
|
|
902
|
-
deletion. Will return `null` if this position is at the end of
|
|
903
|
-
its parent node or its parent node isn't a textblock (in which
|
|
904
|
-
case no marks should be preserved).
|
|
905
|
-
*/
|
|
906
|
-
marksAcross($end) {
|
|
907
|
-
let after = this.parent.maybeChild(this.index());
|
|
908
|
-
if (!after || !after.isInline)
|
|
909
|
-
return null;
|
|
910
|
-
let marks = after.marks, next = $end.parent.maybeChild($end.index());
|
|
911
|
-
for (var i = 0; i < marks.length; i++)
|
|
912
|
-
if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks)))
|
|
913
|
-
marks = marks[i--].removeFromSet(marks);
|
|
914
|
-
return marks;
|
|
915
|
-
}
|
|
916
|
-
/**
|
|
917
|
-
The depth up to which this position and the given (non-resolved)
|
|
918
|
-
position share the same parent nodes.
|
|
919
|
-
*/
|
|
920
|
-
sharedDepth(pos) {
|
|
921
|
-
for (let depth = this.depth; depth > 0; depth--)
|
|
922
|
-
if (this.start(depth) <= pos && this.end(depth) >= pos)
|
|
923
|
-
return depth;
|
|
924
|
-
return 0;
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
Returns a range based on the place where this position and the
|
|
928
|
-
given position diverge around block content. If both point into
|
|
929
|
-
the same textblock, for example, a range around that textblock
|
|
930
|
-
will be returned. If they point into different blocks, the range
|
|
931
|
-
around those blocks in their shared ancestor is returned. You can
|
|
932
|
-
pass in an optional predicate that will be called with a parent
|
|
933
|
-
node to see if a range into that parent is acceptable.
|
|
934
|
-
*/
|
|
935
|
-
blockRange(other = this, pred) {
|
|
936
|
-
if (other.pos < this.pos)
|
|
937
|
-
return other.blockRange(this);
|
|
938
|
-
for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--)
|
|
939
|
-
if (other.pos <= this.end(d) && (!pred || pred(this.node(d))))
|
|
940
|
-
return new NodeRange(this, other, d);
|
|
941
|
-
return null;
|
|
942
|
-
}
|
|
943
|
-
/**
|
|
944
|
-
Query whether the given position shares the same parent node.
|
|
945
|
-
*/
|
|
946
|
-
sameParent(other) {
|
|
947
|
-
return this.pos - this.parentOffset == other.pos - other.parentOffset;
|
|
948
|
-
}
|
|
949
|
-
/**
|
|
950
|
-
Return the greater of this and the given position.
|
|
951
|
-
*/
|
|
952
|
-
max(other) {
|
|
953
|
-
return other.pos > this.pos ? other : this;
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
Return the smaller of this and the given position.
|
|
957
|
-
*/
|
|
958
|
-
min(other) {
|
|
959
|
-
return other.pos < this.pos ? other : this;
|
|
960
|
-
}
|
|
961
|
-
/**
|
|
962
|
-
@internal
|
|
963
|
-
*/
|
|
964
|
-
toString() {
|
|
965
|
-
let str = "";
|
|
966
|
-
for (let i = 1; i <= this.depth; i++)
|
|
967
|
-
str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
|
|
968
|
-
return str + ":" + this.parentOffset;
|
|
969
|
-
}
|
|
970
|
-
/**
|
|
971
|
-
@internal
|
|
972
|
-
*/
|
|
973
|
-
static resolve(doc, pos) {
|
|
974
|
-
if (!(pos >= 0 && pos <= doc.content.size))
|
|
975
|
-
throw new RangeError("Position " + pos + " out of range");
|
|
976
|
-
let path = [];
|
|
977
|
-
let start2 = 0, parentOffset = pos;
|
|
978
|
-
for (let node = doc; ; ) {
|
|
979
|
-
let { index, offset: offset2 } = node.content.findIndex(parentOffset);
|
|
980
|
-
let rem = parentOffset - offset2;
|
|
981
|
-
path.push(node, index, start2 + offset2);
|
|
982
|
-
if (!rem)
|
|
983
|
-
break;
|
|
984
|
-
node = node.child(index);
|
|
985
|
-
if (node.isText)
|
|
986
|
-
break;
|
|
987
|
-
parentOffset = rem - 1;
|
|
988
|
-
start2 += offset2 + 1;
|
|
989
|
-
}
|
|
990
|
-
return new _ResolvedPos(pos, path, parentOffset);
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
@internal
|
|
994
|
-
*/
|
|
995
|
-
static resolveCached(doc, pos) {
|
|
996
|
-
let cache = resolveCache.get(doc);
|
|
997
|
-
if (cache) {
|
|
998
|
-
for (let i = 0; i < cache.elts.length; i++) {
|
|
999
|
-
let elt = cache.elts[i];
|
|
1000
|
-
if (elt.pos == pos)
|
|
1001
|
-
return elt;
|
|
1002
|
-
}
|
|
1003
|
-
} else {
|
|
1004
|
-
resolveCache.set(doc, cache = new ResolveCache());
|
|
1005
|
-
}
|
|
1006
|
-
let result = cache.elts[cache.i] = _ResolvedPos.resolve(doc, pos);
|
|
1007
|
-
cache.i = (cache.i + 1) % resolveCacheSize;
|
|
1008
|
-
return result;
|
|
1009
|
-
}
|
|
1010
|
-
};
|
|
1011
|
-
var ResolveCache = class {
|
|
1012
|
-
constructor() {
|
|
1013
|
-
this.elts = [];
|
|
1014
|
-
this.i = 0;
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
var resolveCacheSize = 12;
|
|
1018
|
-
var resolveCache = /* @__PURE__ */ new WeakMap();
|
|
1019
|
-
var NodeRange = class {
|
|
1020
|
-
/**
|
|
1021
|
-
Construct a node range. `$from` and `$to` should point into the
|
|
1022
|
-
same node until at least the given `depth`, since a node range
|
|
1023
|
-
denotes an adjacent set of nodes in a single parent node.
|
|
1024
|
-
*/
|
|
1025
|
-
constructor($from, $to, depth) {
|
|
1026
|
-
this.$from = $from;
|
|
1027
|
-
this.$to = $to;
|
|
1028
|
-
this.depth = depth;
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
The position at the start of the range.
|
|
1032
|
-
*/
|
|
1033
|
-
get start() {
|
|
1034
|
-
return this.$from.before(this.depth + 1);
|
|
1035
|
-
}
|
|
1036
|
-
/**
|
|
1037
|
-
The position at the end of the range.
|
|
1038
|
-
*/
|
|
1039
|
-
get end() {
|
|
1040
|
-
return this.$to.after(this.depth + 1);
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
The parent node that the range points into.
|
|
1044
|
-
*/
|
|
1045
|
-
get parent() {
|
|
1046
|
-
return this.$from.node(this.depth);
|
|
1047
|
-
}
|
|
1048
|
-
/**
|
|
1049
|
-
The start index of the range in the parent node.
|
|
1050
|
-
*/
|
|
1051
|
-
get startIndex() {
|
|
1052
|
-
return this.$from.index(this.depth);
|
|
1053
|
-
}
|
|
1054
|
-
/**
|
|
1055
|
-
The end index of the range in the parent node.
|
|
1056
|
-
*/
|
|
1057
|
-
get endIndex() {
|
|
1058
|
-
return this.$to.indexAfter(this.depth);
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
var emptyAttrs = /* @__PURE__ */ Object.create(null);
|
|
1062
|
-
var Node = class _Node {
|
|
1063
|
-
/**
|
|
1064
|
-
@internal
|
|
1065
|
-
*/
|
|
1066
|
-
constructor(type, attrs, content, marks = Mark.none) {
|
|
1067
|
-
this.type = type;
|
|
1068
|
-
this.attrs = attrs;
|
|
1069
|
-
this.marks = marks;
|
|
1070
|
-
this.content = content || Fragment.empty;
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
The array of this node's child nodes.
|
|
1074
|
-
*/
|
|
1075
|
-
get children() {
|
|
1076
|
-
return this.content.content;
|
|
1077
|
-
}
|
|
1078
|
-
/**
|
|
1079
|
-
The size of this node, as defined by the integer-based [indexing
|
|
1080
|
-
scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
|
|
1081
|
-
amount of characters. For other leaf nodes, it is one. For
|
|
1082
|
-
non-leaf nodes, it is the size of the content plus two (the
|
|
1083
|
-
start and end token).
|
|
1084
|
-
*/
|
|
1085
|
-
get nodeSize() {
|
|
1086
|
-
return this.isLeaf ? 1 : 2 + this.content.size;
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
The number of children that the node has.
|
|
1090
|
-
*/
|
|
1091
|
-
get childCount() {
|
|
1092
|
-
return this.content.childCount;
|
|
1093
|
-
}
|
|
1094
|
-
/**
|
|
1095
|
-
Get the child node at the given index. Raises an error when the
|
|
1096
|
-
index is out of range.
|
|
1097
|
-
*/
|
|
1098
|
-
child(index) {
|
|
1099
|
-
return this.content.child(index);
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
Get the child node at the given index, if it exists.
|
|
1103
|
-
*/
|
|
1104
|
-
maybeChild(index) {
|
|
1105
|
-
return this.content.maybeChild(index);
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
Call `f` for every child node, passing the node, its offset
|
|
1109
|
-
into this parent node, and its index.
|
|
1110
|
-
*/
|
|
1111
|
-
forEach(f) {
|
|
1112
|
-
this.content.forEach(f);
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
Invoke a callback for all descendant nodes recursively between
|
|
1116
|
-
the given two positions that are relative to start of this
|
|
1117
|
-
node's content. The callback is invoked with the node, its
|
|
1118
|
-
position relative to the original node (method receiver),
|
|
1119
|
-
its parent node, and its child index. When the callback returns
|
|
1120
|
-
false for a given node, that node's children will not be
|
|
1121
|
-
recursed over. The last parameter can be used to specify a
|
|
1122
|
-
starting position to count from.
|
|
1123
|
-
*/
|
|
1124
|
-
nodesBetween(from, to, f, startPos = 0) {
|
|
1125
|
-
this.content.nodesBetween(from, to, f, startPos, this);
|
|
1126
|
-
}
|
|
1127
|
-
/**
|
|
1128
|
-
Call the given callback for every descendant node. Doesn't
|
|
1129
|
-
descend into a node when the callback returns `false`.
|
|
1130
|
-
*/
|
|
1131
|
-
descendants(f) {
|
|
1132
|
-
this.nodesBetween(0, this.content.size, f);
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
Concatenates all the text nodes found in this fragment and its
|
|
1136
|
-
children.
|
|
1137
|
-
*/
|
|
1138
|
-
get textContent() {
|
|
1139
|
-
return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, "");
|
|
1140
|
-
}
|
|
1141
|
-
/**
|
|
1142
|
-
Get all text between positions `from` and `to`. When
|
|
1143
|
-
`blockSeparator` is given, it will be inserted to separate text
|
|
1144
|
-
from different block nodes. If `leafText` is given, it'll be
|
|
1145
|
-
inserted for every non-text leaf node encountered, otherwise
|
|
1146
|
-
[`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
|
|
1147
|
-
*/
|
|
1148
|
-
textBetween(from, to, blockSeparator, leafText) {
|
|
1149
|
-
return this.content.textBetween(from, to, blockSeparator, leafText);
|
|
1150
|
-
}
|
|
1151
|
-
/**
|
|
1152
|
-
Returns this node's first child, or `null` if there are no
|
|
1153
|
-
children.
|
|
1154
|
-
*/
|
|
1155
|
-
get firstChild() {
|
|
1156
|
-
return this.content.firstChild;
|
|
1157
|
-
}
|
|
1158
|
-
/**
|
|
1159
|
-
Returns this node's last child, or `null` if there are no
|
|
1160
|
-
children.
|
|
1161
|
-
*/
|
|
1162
|
-
get lastChild() {
|
|
1163
|
-
return this.content.lastChild;
|
|
1164
|
-
}
|
|
1165
|
-
/**
|
|
1166
|
-
Test whether two nodes represent the same piece of document.
|
|
1167
|
-
*/
|
|
1168
|
-
eq(other) {
|
|
1169
|
-
return this == other || this.sameMarkup(other) && this.content.eq(other.content);
|
|
1170
|
-
}
|
|
1171
|
-
/**
|
|
1172
|
-
Compare the markup (type, attributes, and marks) of this node to
|
|
1173
|
-
those of another. Returns `true` if both have the same markup.
|
|
1174
|
-
*/
|
|
1175
|
-
sameMarkup(other) {
|
|
1176
|
-
return this.hasMarkup(other.type, other.attrs, other.marks);
|
|
1177
|
-
}
|
|
1178
|
-
/**
|
|
1179
|
-
Check whether this node's markup correspond to the given type,
|
|
1180
|
-
attributes, and marks.
|
|
1181
|
-
*/
|
|
1182
|
-
hasMarkup(type, attrs, marks) {
|
|
1183
|
-
return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none);
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
Create a new node with the same markup as this node, containing
|
|
1187
|
-
the given content (or empty, if no content is given).
|
|
1188
|
-
*/
|
|
1189
|
-
copy(content = null) {
|
|
1190
|
-
if (content == this.content)
|
|
1191
|
-
return this;
|
|
1192
|
-
return new _Node(this.type, this.attrs, content, this.marks);
|
|
1193
|
-
}
|
|
1194
|
-
/**
|
|
1195
|
-
Create a copy of this node, with the given set of marks instead
|
|
1196
|
-
of the node's own marks.
|
|
1197
|
-
*/
|
|
1198
|
-
mark(marks) {
|
|
1199
|
-
return marks == this.marks ? this : new _Node(this.type, this.attrs, this.content, marks);
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
Create a copy of this node with only the content between the
|
|
1203
|
-
given positions. If `to` is not given, it defaults to the end of
|
|
1204
|
-
the node.
|
|
1205
|
-
*/
|
|
1206
|
-
cut(from, to = this.content.size) {
|
|
1207
|
-
if (from == 0 && to == this.content.size)
|
|
1208
|
-
return this;
|
|
1209
|
-
return this.copy(this.content.cut(from, to));
|
|
1210
|
-
}
|
|
1211
|
-
/**
|
|
1212
|
-
Cut out the part of the document between the given positions, and
|
|
1213
|
-
return it as a `Slice` object.
|
|
1214
|
-
*/
|
|
1215
|
-
slice(from, to = this.content.size, includeParents = false) {
|
|
1216
|
-
if (from == to)
|
|
1217
|
-
return Slice.empty;
|
|
1218
|
-
let $from = this.resolve(from), $to = this.resolve(to);
|
|
1219
|
-
let depth = includeParents ? 0 : $from.sharedDepth(to);
|
|
1220
|
-
let start2 = $from.start(depth), node = $from.node(depth);
|
|
1221
|
-
let content = node.content.cut($from.pos - start2, $to.pos - start2);
|
|
1222
|
-
return new Slice(content, $from.depth - depth, $to.depth - depth);
|
|
1223
|
-
}
|
|
1224
|
-
/**
|
|
1225
|
-
Replace the part of the document between the given positions with
|
|
1226
|
-
the given slice. The slice must 'fit', meaning its open sides
|
|
1227
|
-
must be able to connect to the surrounding content, and its
|
|
1228
|
-
content nodes must be valid children for the node they are placed
|
|
1229
|
-
into. If any of this is violated, an error of type
|
|
1230
|
-
[`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown.
|
|
1231
|
-
*/
|
|
1232
|
-
replace(from, to, slice) {
|
|
1233
|
-
return replace(this.resolve(from), this.resolve(to), slice);
|
|
1234
|
-
}
|
|
1235
|
-
/**
|
|
1236
|
-
Find the node directly after the given position.
|
|
1237
|
-
*/
|
|
1238
|
-
nodeAt(pos) {
|
|
1239
|
-
for (let node = this; ; ) {
|
|
1240
|
-
let { index, offset: offset2 } = node.content.findIndex(pos);
|
|
1241
|
-
node = node.maybeChild(index);
|
|
1242
|
-
if (!node)
|
|
1243
|
-
return null;
|
|
1244
|
-
if (offset2 == pos || node.isText)
|
|
1245
|
-
return node;
|
|
1246
|
-
pos -= offset2 + 1;
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
/**
|
|
1250
|
-
Find the (direct) child node after the given offset, if any,
|
|
1251
|
-
and return it along with its index and offset relative to this
|
|
1252
|
-
node.
|
|
1253
|
-
*/
|
|
1254
|
-
childAfter(pos) {
|
|
1255
|
-
let { index, offset: offset2 } = this.content.findIndex(pos);
|
|
1256
|
-
return { node: this.content.maybeChild(index), index, offset: offset2 };
|
|
1257
|
-
}
|
|
1258
|
-
/**
|
|
1259
|
-
Find the (direct) child node before the given offset, if any,
|
|
1260
|
-
and return it along with its index and offset relative to this
|
|
1261
|
-
node.
|
|
1262
|
-
*/
|
|
1263
|
-
childBefore(pos) {
|
|
1264
|
-
if (pos == 0)
|
|
1265
|
-
return { node: null, index: 0, offset: 0 };
|
|
1266
|
-
let { index, offset: offset2 } = this.content.findIndex(pos);
|
|
1267
|
-
if (offset2 < pos)
|
|
1268
|
-
return { node: this.content.child(index), index, offset: offset2 };
|
|
1269
|
-
let node = this.content.child(index - 1);
|
|
1270
|
-
return { node, index: index - 1, offset: offset2 - node.nodeSize };
|
|
1271
|
-
}
|
|
1272
|
-
/**
|
|
1273
|
-
Resolve the given position in the document, returning an
|
|
1274
|
-
[object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context.
|
|
1275
|
-
*/
|
|
1276
|
-
resolve(pos) {
|
|
1277
|
-
return ResolvedPos.resolveCached(this, pos);
|
|
1278
|
-
}
|
|
1279
|
-
/**
|
|
1280
|
-
@internal
|
|
1281
|
-
*/
|
|
1282
|
-
resolveNoCache(pos) {
|
|
1283
|
-
return ResolvedPos.resolve(this, pos);
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
Test whether a given mark or mark type occurs in this document
|
|
1287
|
-
between the two given positions.
|
|
1288
|
-
*/
|
|
1289
|
-
rangeHasMark(from, to, type) {
|
|
1290
|
-
let found2 = false;
|
|
1291
|
-
if (to > from)
|
|
1292
|
-
this.nodesBetween(from, to, (node) => {
|
|
1293
|
-
if (type.isInSet(node.marks))
|
|
1294
|
-
found2 = true;
|
|
1295
|
-
return !found2;
|
|
1296
|
-
});
|
|
1297
|
-
return found2;
|
|
1298
|
-
}
|
|
1299
|
-
/**
|
|
1300
|
-
True when this is a block (non-inline node)
|
|
1301
|
-
*/
|
|
1302
|
-
get isBlock() {
|
|
1303
|
-
return this.type.isBlock;
|
|
1304
|
-
}
|
|
1305
|
-
/**
|
|
1306
|
-
True when this is a textblock node, a block node with inline
|
|
1307
|
-
content.
|
|
1308
|
-
*/
|
|
1309
|
-
get isTextblock() {
|
|
1310
|
-
return this.type.isTextblock;
|
|
1311
|
-
}
|
|
1312
|
-
/**
|
|
1313
|
-
True when this node allows inline content.
|
|
1314
|
-
*/
|
|
1315
|
-
get inlineContent() {
|
|
1316
|
-
return this.type.inlineContent;
|
|
1317
|
-
}
|
|
1318
|
-
/**
|
|
1319
|
-
True when this is an inline node (a text node or a node that can
|
|
1320
|
-
appear among text).
|
|
1321
|
-
*/
|
|
1322
|
-
get isInline() {
|
|
1323
|
-
return this.type.isInline;
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
True when this is a text node.
|
|
1327
|
-
*/
|
|
1328
|
-
get isText() {
|
|
1329
|
-
return this.type.isText;
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
True when this is a leaf node.
|
|
1333
|
-
*/
|
|
1334
|
-
get isLeaf() {
|
|
1335
|
-
return this.type.isLeaf;
|
|
1336
|
-
}
|
|
1337
|
-
/**
|
|
1338
|
-
True when this is an atom, i.e. when it does not have directly
|
|
1339
|
-
editable content. This is usually the same as `isLeaf`, but can
|
|
1340
|
-
be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom)
|
|
1341
|
-
on a node's spec (typically used when the node is displayed as
|
|
1342
|
-
an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)).
|
|
1343
|
-
*/
|
|
1344
|
-
get isAtom() {
|
|
1345
|
-
return this.type.isAtom;
|
|
1346
|
-
}
|
|
1347
|
-
/**
|
|
1348
|
-
Return a string representation of this node for debugging
|
|
1349
|
-
purposes.
|
|
1350
|
-
*/
|
|
1351
|
-
toString() {
|
|
1352
|
-
if (this.type.spec.toDebugString)
|
|
1353
|
-
return this.type.spec.toDebugString(this);
|
|
1354
|
-
let name = this.type.name;
|
|
1355
|
-
if (this.content.size)
|
|
1356
|
-
name += "(" + this.content.toStringInner() + ")";
|
|
1357
|
-
return wrapMarks(this.marks, name);
|
|
1358
|
-
}
|
|
1359
|
-
/**
|
|
1360
|
-
Get the content match in this node at the given index.
|
|
1361
|
-
*/
|
|
1362
|
-
contentMatchAt(index) {
|
|
1363
|
-
let match = this.type.contentMatch.matchFragment(this.content, 0, index);
|
|
1364
|
-
if (!match)
|
|
1365
|
-
throw new Error("Called contentMatchAt on a node with invalid content");
|
|
1366
|
-
return match;
|
|
1367
|
-
}
|
|
1368
|
-
/**
|
|
1369
|
-
Test whether replacing the range between `from` and `to` (by
|
|
1370
|
-
child index) with the given replacement fragment (which defaults
|
|
1371
|
-
to the empty fragment) would leave the node's content valid. You
|
|
1372
|
-
can optionally pass `start` and `end` indices into the
|
|
1373
|
-
replacement fragment.
|
|
1374
|
-
*/
|
|
1375
|
-
canReplace(from, to, replacement = Fragment.empty, start2 = 0, end2 = replacement.childCount) {
|
|
1376
|
-
let one = this.contentMatchAt(from).matchFragment(replacement, start2, end2);
|
|
1377
|
-
let two = one && one.matchFragment(this.content, to);
|
|
1378
|
-
if (!two || !two.validEnd)
|
|
1379
|
-
return false;
|
|
1380
|
-
for (let i = start2; i < end2; i++)
|
|
1381
|
-
if (!this.type.allowsMarks(replacement.child(i).marks))
|
|
1382
|
-
return false;
|
|
1383
|
-
return true;
|
|
1384
|
-
}
|
|
1385
|
-
/**
|
|
1386
|
-
Test whether replacing the range `from` to `to` (by index) with
|
|
1387
|
-
a node of the given type would leave the node's content valid.
|
|
1388
|
-
*/
|
|
1389
|
-
canReplaceWith(from, to, type, marks) {
|
|
1390
|
-
if (marks && !this.type.allowsMarks(marks))
|
|
1391
|
-
return false;
|
|
1392
|
-
let start2 = this.contentMatchAt(from).matchType(type);
|
|
1393
|
-
let end2 = start2 && start2.matchFragment(this.content, to);
|
|
1394
|
-
return end2 ? end2.validEnd : false;
|
|
1395
|
-
}
|
|
1396
|
-
/**
|
|
1397
|
-
Test whether the given node's content could be appended to this
|
|
1398
|
-
node. If that node is empty, this will only return true if there
|
|
1399
|
-
is at least one node type that can appear in both nodes (to avoid
|
|
1400
|
-
merging completely incompatible nodes).
|
|
1401
|
-
*/
|
|
1402
|
-
canAppend(other) {
|
|
1403
|
-
if (other.content.size)
|
|
1404
|
-
return this.canReplace(this.childCount, this.childCount, other.content);
|
|
1405
|
-
else
|
|
1406
|
-
return this.type.compatibleContent(other.type);
|
|
1407
|
-
}
|
|
1408
|
-
/**
|
|
1409
|
-
Check whether this node and its descendants conform to the
|
|
1410
|
-
schema, and raise an exception when they do not.
|
|
1411
|
-
*/
|
|
1412
|
-
check() {
|
|
1413
|
-
this.type.checkContent(this.content);
|
|
1414
|
-
this.type.checkAttrs(this.attrs);
|
|
1415
|
-
let copy = Mark.none;
|
|
1416
|
-
for (let i = 0; i < this.marks.length; i++) {
|
|
1417
|
-
let mark = this.marks[i];
|
|
1418
|
-
mark.type.checkAttrs(mark.attrs);
|
|
1419
|
-
copy = mark.addToSet(copy);
|
|
1420
|
-
}
|
|
1421
|
-
if (!Mark.sameSet(copy, this.marks))
|
|
1422
|
-
throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`);
|
|
1423
|
-
this.content.forEach((node) => node.check());
|
|
1424
|
-
}
|
|
1425
|
-
/**
|
|
1426
|
-
Return a JSON-serializeable representation of this node.
|
|
1427
|
-
*/
|
|
1428
|
-
toJSON() {
|
|
1429
|
-
let obj = { type: this.type.name };
|
|
1430
|
-
for (let _ in this.attrs) {
|
|
1431
|
-
obj.attrs = this.attrs;
|
|
1432
|
-
break;
|
|
1433
|
-
}
|
|
1434
|
-
if (this.content.size)
|
|
1435
|
-
obj.content = this.content.toJSON();
|
|
1436
|
-
if (this.marks.length)
|
|
1437
|
-
obj.marks = this.marks.map((n) => n.toJSON());
|
|
1438
|
-
return obj;
|
|
1439
|
-
}
|
|
1440
|
-
/**
|
|
1441
|
-
Deserialize a node from its JSON representation.
|
|
1442
|
-
*/
|
|
1443
|
-
static fromJSON(schema, json) {
|
|
1444
|
-
if (!json)
|
|
1445
|
-
throw new RangeError("Invalid input for Node.fromJSON");
|
|
1446
|
-
let marks = void 0;
|
|
1447
|
-
if (json.marks) {
|
|
1448
|
-
if (!Array.isArray(json.marks))
|
|
1449
|
-
throw new RangeError("Invalid mark data for Node.fromJSON");
|
|
1450
|
-
marks = json.marks.map(schema.markFromJSON);
|
|
1451
|
-
}
|
|
1452
|
-
if (json.type == "text") {
|
|
1453
|
-
if (typeof json.text != "string")
|
|
1454
|
-
throw new RangeError("Invalid text node in JSON");
|
|
1455
|
-
return schema.text(json.text, marks);
|
|
1456
|
-
}
|
|
1457
|
-
let content = Fragment.fromJSON(schema, json.content);
|
|
1458
|
-
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
1459
|
-
node.type.checkAttrs(node.attrs);
|
|
1460
|
-
return node;
|
|
1461
|
-
}
|
|
1462
|
-
};
|
|
1463
|
-
Node.prototype.text = void 0;
|
|
1464
|
-
function wrapMarks(marks, str) {
|
|
1465
|
-
for (let i = marks.length - 1; i >= 0; i--)
|
|
1466
|
-
str = marks[i].type.name + "(" + str + ")";
|
|
1467
|
-
return str;
|
|
1468
|
-
}
|
|
1469
|
-
var ContentMatch = class _ContentMatch {
|
|
1470
|
-
/**
|
|
1471
|
-
@internal
|
|
1472
|
-
*/
|
|
1473
|
-
constructor(validEnd) {
|
|
1474
|
-
this.validEnd = validEnd;
|
|
1475
|
-
this.next = [];
|
|
1476
|
-
this.wrapCache = [];
|
|
1477
|
-
}
|
|
1478
|
-
/**
|
|
1479
|
-
@internal
|
|
1480
|
-
*/
|
|
1481
|
-
static parse(string, nodeTypes) {
|
|
1482
|
-
let stream = new TokenStream(string, nodeTypes);
|
|
1483
|
-
if (stream.next == null)
|
|
1484
|
-
return _ContentMatch.empty;
|
|
1485
|
-
let expr = parseExpr(stream);
|
|
1486
|
-
if (stream.next)
|
|
1487
|
-
stream.err("Unexpected trailing text");
|
|
1488
|
-
let match = dfa(nfa(expr));
|
|
1489
|
-
checkForDeadEnds(match, stream);
|
|
1490
|
-
return match;
|
|
1491
|
-
}
|
|
1492
|
-
/**
|
|
1493
|
-
Match a node type, returning a match after that node if
|
|
1494
|
-
successful.
|
|
1495
|
-
*/
|
|
1496
|
-
matchType(type) {
|
|
1497
|
-
for (let i = 0; i < this.next.length; i++)
|
|
1498
|
-
if (this.next[i].type == type)
|
|
1499
|
-
return this.next[i].next;
|
|
1500
|
-
return null;
|
|
351
|
+
return new _Fragment(joined || array, size);
|
|
1501
352
|
}
|
|
1502
353
|
/**
|
|
1503
|
-
|
|
1504
|
-
|
|
354
|
+
Create a fragment from something that can be interpreted as a
|
|
355
|
+
set of nodes. For `null`, it returns the empty fragment. For a
|
|
356
|
+
fragment, the fragment itself. For a node or array of nodes, a
|
|
357
|
+
fragment containing those nodes.
|
|
1505
358
|
*/
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
359
|
+
static from(nodes) {
|
|
360
|
+
if (!nodes)
|
|
361
|
+
return _Fragment.empty;
|
|
362
|
+
if (nodes instanceof _Fragment)
|
|
363
|
+
return nodes;
|
|
364
|
+
if (Array.isArray(nodes))
|
|
365
|
+
return this.fromArray(nodes);
|
|
366
|
+
if (nodes.attrs)
|
|
367
|
+
return new _Fragment([nodes], nodes.nodeSize);
|
|
368
|
+
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
1511
369
|
}
|
|
370
|
+
};
|
|
371
|
+
Fragment.empty = new Fragment([], 0);
|
|
372
|
+
var found = { index: 0, offset: 0 };
|
|
373
|
+
function retIndex(index, offset2) {
|
|
374
|
+
found.index = index;
|
|
375
|
+
found.offset = offset2;
|
|
376
|
+
return found;
|
|
377
|
+
}
|
|
378
|
+
var ReplaceError = class extends Error {
|
|
379
|
+
};
|
|
380
|
+
var Slice = class _Slice {
|
|
1512
381
|
/**
|
|
1513
|
-
|
|
382
|
+
Create a slice. When specifying a non-zero open depth, you must
|
|
383
|
+
make sure that there are nodes of at least that depth at the
|
|
384
|
+
appropriate side of the fragment—i.e. if the fragment is an
|
|
385
|
+
empty paragraph node, `openStart` and `openEnd` can't be greater
|
|
386
|
+
than 1.
|
|
387
|
+
|
|
388
|
+
It is not necessary for the content of open nodes to conform to
|
|
389
|
+
the schema's content constraints, though it should be a valid
|
|
390
|
+
start/end/middle for such a node, depending on which sides are
|
|
391
|
+
open.
|
|
1514
392
|
*/
|
|
1515
|
-
|
|
1516
|
-
|
|
393
|
+
constructor(content, openStart, openEnd) {
|
|
394
|
+
this.content = content;
|
|
395
|
+
this.openStart = openStart;
|
|
396
|
+
this.openEnd = openEnd;
|
|
1517
397
|
}
|
|
1518
398
|
/**
|
|
1519
|
-
|
|
1520
|
-
be generated.
|
|
399
|
+
The size this slice would add when inserted into a document.
|
|
1521
400
|
*/
|
|
1522
|
-
get
|
|
1523
|
-
|
|
1524
|
-
let { type } = this.next[i];
|
|
1525
|
-
if (!(type.isText || type.hasRequiredAttrs()))
|
|
1526
|
-
return type;
|
|
1527
|
-
}
|
|
1528
|
-
return null;
|
|
401
|
+
get size() {
|
|
402
|
+
return this.content.size - this.openStart - this.openEnd;
|
|
1529
403
|
}
|
|
1530
404
|
/**
|
|
1531
405
|
@internal
|
|
1532
406
|
*/
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
if (this.next[i].type == other.next[j].type)
|
|
1537
|
-
return true;
|
|
1538
|
-
return false;
|
|
407
|
+
insertAt(pos, fragment) {
|
|
408
|
+
let content = insertInto(this.content, pos + this.openStart, fragment);
|
|
409
|
+
return content && new _Slice(content, this.openStart, this.openEnd);
|
|
1539
410
|
}
|
|
1540
411
|
/**
|
|
1541
|
-
|
|
1542
|
-
be made to match by inserting nodes in front of it. When
|
|
1543
|
-
successful, return a fragment of inserted nodes (which may be
|
|
1544
|
-
empty if nothing had to be inserted). When `toEnd` is true, only
|
|
1545
|
-
return a fragment if the resulting match goes to the end of the
|
|
1546
|
-
content expression.
|
|
412
|
+
@internal
|
|
1547
413
|
*/
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
function search(match, types) {
|
|
1551
|
-
let finished = match.matchFragment(after, startIndex);
|
|
1552
|
-
if (finished && (!toEnd || finished.validEnd))
|
|
1553
|
-
return Fragment.from(types.map((tp) => tp.createAndFill()));
|
|
1554
|
-
for (let i = 0; i < match.next.length; i++) {
|
|
1555
|
-
let { type, next } = match.next[i];
|
|
1556
|
-
if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
|
|
1557
|
-
seen.push(next);
|
|
1558
|
-
let found2 = search(next, types.concat(type));
|
|
1559
|
-
if (found2)
|
|
1560
|
-
return found2;
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
return null;
|
|
1564
|
-
}
|
|
1565
|
-
return search(this, []);
|
|
414
|
+
removeBetween(from, to) {
|
|
415
|
+
return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
|
|
1566
416
|
}
|
|
1567
417
|
/**
|
|
1568
|
-
|
|
1569
|
-
given type to appear at this position. The result may be empty
|
|
1570
|
-
(when it fits directly) and will be null when no such wrapping
|
|
1571
|
-
exists.
|
|
418
|
+
Tests whether this slice is equal to another slice.
|
|
1572
419
|
*/
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
if (this.wrapCache[i] == target)
|
|
1576
|
-
return this.wrapCache[i + 1];
|
|
1577
|
-
let computed = this.computeWrapping(target);
|
|
1578
|
-
this.wrapCache.push(target, computed);
|
|
1579
|
-
return computed;
|
|
420
|
+
eq(other) {
|
|
421
|
+
return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
|
|
1580
422
|
}
|
|
1581
423
|
/**
|
|
1582
424
|
@internal
|
|
1583
425
|
*/
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
while (active.length) {
|
|
1587
|
-
let current = active.shift(), match = current.match;
|
|
1588
|
-
if (match.matchType(target)) {
|
|
1589
|
-
let result = [];
|
|
1590
|
-
for (let obj = current; obj.type; obj = obj.via)
|
|
1591
|
-
result.push(obj.type);
|
|
1592
|
-
return result.reverse();
|
|
1593
|
-
}
|
|
1594
|
-
for (let i = 0; i < match.next.length; i++) {
|
|
1595
|
-
let { type, next } = match.next[i];
|
|
1596
|
-
if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) {
|
|
1597
|
-
active.push({ match: type.contentMatch, type, via: current });
|
|
1598
|
-
seen[type.name] = true;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
return null;
|
|
426
|
+
toString() {
|
|
427
|
+
return this.content + "(" + this.openStart + "," + this.openEnd + ")";
|
|
1603
428
|
}
|
|
1604
429
|
/**
|
|
1605
|
-
|
|
1606
|
-
automaton that describes the content expression.
|
|
430
|
+
Convert a slice to a JSON-serializable representation.
|
|
1607
431
|
*/
|
|
1608
|
-
|
|
1609
|
-
|
|
432
|
+
toJSON() {
|
|
433
|
+
if (!this.content.size)
|
|
434
|
+
return null;
|
|
435
|
+
let json = { content: this.content.toJSON() };
|
|
436
|
+
if (this.openStart > 0)
|
|
437
|
+
json.openStart = this.openStart;
|
|
438
|
+
if (this.openEnd > 0)
|
|
439
|
+
json.openEnd = this.openEnd;
|
|
440
|
+
return json;
|
|
1610
441
|
}
|
|
1611
442
|
/**
|
|
1612
|
-
|
|
1613
|
-
automaton that describes the content expression.
|
|
443
|
+
Deserialize a slice from its JSON representation.
|
|
1614
444
|
*/
|
|
1615
|
-
|
|
1616
|
-
if (
|
|
1617
|
-
|
|
1618
|
-
|
|
445
|
+
static fromJSON(schema, json) {
|
|
446
|
+
if (!json)
|
|
447
|
+
return _Slice.empty;
|
|
448
|
+
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
449
|
+
if (typeof openStart != "number" || typeof openEnd != "number")
|
|
450
|
+
throw new RangeError("Invalid input for Slice.fromJSON");
|
|
451
|
+
return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
|
|
1619
452
|
}
|
|
1620
453
|
/**
|
|
1621
|
-
|
|
454
|
+
Create a slice from a fragment by taking the maximum possible
|
|
455
|
+
open value on both side of the fragment.
|
|
1622
456
|
*/
|
|
1623
|
-
|
|
1624
|
-
let
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
}
|
|
1631
|
-
scan(this);
|
|
1632
|
-
return seen.map((m, i) => {
|
|
1633
|
-
let out = i + (m.validEnd ? "*" : " ") + " ";
|
|
1634
|
-
for (let i2 = 0; i2 < m.next.length; i2++)
|
|
1635
|
-
out += (i2 ? ", " : "") + m.next[i2].type.name + "->" + seen.indexOf(m.next[i2].next);
|
|
1636
|
-
return out;
|
|
1637
|
-
}).join("\n");
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
ContentMatch.empty = new ContentMatch(true);
|
|
1641
|
-
var TokenStream = class {
|
|
1642
|
-
constructor(string, nodeTypes) {
|
|
1643
|
-
this.string = string;
|
|
1644
|
-
this.nodeTypes = nodeTypes;
|
|
1645
|
-
this.inline = null;
|
|
1646
|
-
this.pos = 0;
|
|
1647
|
-
this.tokens = string.split(/\s*(?=\b|\W|$)/);
|
|
1648
|
-
if (this.tokens[this.tokens.length - 1] == "")
|
|
1649
|
-
this.tokens.pop();
|
|
1650
|
-
if (this.tokens[0] == "")
|
|
1651
|
-
this.tokens.shift();
|
|
1652
|
-
}
|
|
1653
|
-
get next() {
|
|
1654
|
-
return this.tokens[this.pos];
|
|
1655
|
-
}
|
|
1656
|
-
eat(tok) {
|
|
1657
|
-
return this.next == tok && (this.pos++ || true);
|
|
1658
|
-
}
|
|
1659
|
-
err(str) {
|
|
1660
|
-
throw new SyntaxError(str + " (in content expression '" + this.string + "')");
|
|
457
|
+
static maxOpen(fragment, openIsolating = true) {
|
|
458
|
+
let openStart = 0, openEnd = 0;
|
|
459
|
+
for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
|
|
460
|
+
openStart++;
|
|
461
|
+
for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
|
|
462
|
+
openEnd++;
|
|
463
|
+
return new _Slice(fragment, openStart, openEnd);
|
|
1661
464
|
}
|
|
1662
465
|
};
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
let exprs = [];
|
|
1672
|
-
do {
|
|
1673
|
-
exprs.push(parseExprSubscript(stream));
|
|
1674
|
-
} while (stream.next && stream.next != ")" && stream.next != "|");
|
|
1675
|
-
return exprs.length == 1 ? exprs[0] : { type: "seq", exprs };
|
|
1676
|
-
}
|
|
1677
|
-
function parseExprSubscript(stream) {
|
|
1678
|
-
let expr = parseExprAtom(stream);
|
|
1679
|
-
for (; ; ) {
|
|
1680
|
-
if (stream.eat("+"))
|
|
1681
|
-
expr = { type: "plus", expr };
|
|
1682
|
-
else if (stream.eat("*"))
|
|
1683
|
-
expr = { type: "star", expr };
|
|
1684
|
-
else if (stream.eat("?"))
|
|
1685
|
-
expr = { type: "opt", expr };
|
|
1686
|
-
else if (stream.eat("{"))
|
|
1687
|
-
expr = parseExprRange(stream, expr);
|
|
1688
|
-
else
|
|
1689
|
-
break;
|
|
1690
|
-
}
|
|
1691
|
-
return expr;
|
|
1692
|
-
}
|
|
1693
|
-
function parseNum(stream) {
|
|
1694
|
-
if (/\D/.test(stream.next))
|
|
1695
|
-
stream.err("Expected number, got '" + stream.next + "'");
|
|
1696
|
-
let result = Number(stream.next);
|
|
1697
|
-
stream.pos++;
|
|
1698
|
-
return result;
|
|
1699
|
-
}
|
|
1700
|
-
function parseExprRange(stream, expr) {
|
|
1701
|
-
let min2 = parseNum(stream), max2 = min2;
|
|
1702
|
-
if (stream.eat(",")) {
|
|
1703
|
-
if (stream.next != "}")
|
|
1704
|
-
max2 = parseNum(stream);
|
|
1705
|
-
else
|
|
1706
|
-
max2 = -1;
|
|
1707
|
-
}
|
|
1708
|
-
if (!stream.eat("}"))
|
|
1709
|
-
stream.err("Unclosed braced range");
|
|
1710
|
-
return { type: "range", min: min2, max: max2, expr };
|
|
1711
|
-
}
|
|
1712
|
-
function resolveName(stream, name) {
|
|
1713
|
-
let types = stream.nodeTypes, type = types[name];
|
|
1714
|
-
if (type)
|
|
1715
|
-
return [type];
|
|
1716
|
-
let result = [];
|
|
1717
|
-
for (let typeName in types) {
|
|
1718
|
-
let type2 = types[typeName];
|
|
1719
|
-
if (type2.isInGroup(name))
|
|
1720
|
-
result.push(type2);
|
|
1721
|
-
}
|
|
1722
|
-
if (result.length == 0)
|
|
1723
|
-
stream.err("No node type or group '" + name + "' found");
|
|
1724
|
-
return result;
|
|
1725
|
-
}
|
|
1726
|
-
function parseExprAtom(stream) {
|
|
1727
|
-
if (stream.eat("(")) {
|
|
1728
|
-
let expr = parseExpr(stream);
|
|
1729
|
-
if (!stream.eat(")"))
|
|
1730
|
-
stream.err("Missing closing paren");
|
|
1731
|
-
return expr;
|
|
1732
|
-
} else if (!/\W/.test(stream.next)) {
|
|
1733
|
-
let exprs = resolveName(stream, stream.next).map((type) => {
|
|
1734
|
-
if (stream.inline == null)
|
|
1735
|
-
stream.inline = type.isInline;
|
|
1736
|
-
else if (stream.inline != type.isInline)
|
|
1737
|
-
stream.err("Mixing inline and block content");
|
|
1738
|
-
return { type: "name", value: type };
|
|
1739
|
-
});
|
|
1740
|
-
stream.pos++;
|
|
1741
|
-
return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
|
|
1742
|
-
} else {
|
|
1743
|
-
stream.err("Unexpected token '" + stream.next + "'");
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
function nfa(expr) {
|
|
1747
|
-
let nfa2 = [[]];
|
|
1748
|
-
connect(compile(expr, 0), node());
|
|
1749
|
-
return nfa2;
|
|
1750
|
-
function node() {
|
|
1751
|
-
return nfa2.push([]) - 1;
|
|
1752
|
-
}
|
|
1753
|
-
function edge(from, to, term) {
|
|
1754
|
-
let edge2 = { term, to };
|
|
1755
|
-
nfa2[from].push(edge2);
|
|
1756
|
-
return edge2;
|
|
1757
|
-
}
|
|
1758
|
-
function connect(edges, to) {
|
|
1759
|
-
edges.forEach((edge2) => edge2.to = to);
|
|
1760
|
-
}
|
|
1761
|
-
function compile(expr2, from) {
|
|
1762
|
-
if (expr2.type == "choice") {
|
|
1763
|
-
return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from)), []);
|
|
1764
|
-
} else if (expr2.type == "seq") {
|
|
1765
|
-
for (let i = 0; ; i++) {
|
|
1766
|
-
let next = compile(expr2.exprs[i], from);
|
|
1767
|
-
if (i == expr2.exprs.length - 1)
|
|
1768
|
-
return next;
|
|
1769
|
-
connect(next, from = node());
|
|
1770
|
-
}
|
|
1771
|
-
} else if (expr2.type == "star") {
|
|
1772
|
-
let loop = node();
|
|
1773
|
-
edge(from, loop);
|
|
1774
|
-
connect(compile(expr2.expr, loop), loop);
|
|
1775
|
-
return [edge(loop)];
|
|
1776
|
-
} else if (expr2.type == "plus") {
|
|
1777
|
-
let loop = node();
|
|
1778
|
-
connect(compile(expr2.expr, from), loop);
|
|
1779
|
-
connect(compile(expr2.expr, loop), loop);
|
|
1780
|
-
return [edge(loop)];
|
|
1781
|
-
} else if (expr2.type == "opt") {
|
|
1782
|
-
return [edge(from)].concat(compile(expr2.expr, from));
|
|
1783
|
-
} else if (expr2.type == "range") {
|
|
1784
|
-
let cur = from;
|
|
1785
|
-
for (let i = 0; i < expr2.min; i++) {
|
|
1786
|
-
let next = node();
|
|
1787
|
-
connect(compile(expr2.expr, cur), next);
|
|
1788
|
-
cur = next;
|
|
1789
|
-
}
|
|
1790
|
-
if (expr2.max == -1) {
|
|
1791
|
-
connect(compile(expr2.expr, cur), cur);
|
|
1792
|
-
} else {
|
|
1793
|
-
for (let i = expr2.min; i < expr2.max; i++) {
|
|
1794
|
-
let next = node();
|
|
1795
|
-
edge(cur, next);
|
|
1796
|
-
connect(compile(expr2.expr, cur), next);
|
|
1797
|
-
cur = next;
|
|
1798
|
-
}
|
|
1799
|
-
}
|
|
1800
|
-
return [edge(cur)];
|
|
1801
|
-
} else if (expr2.type == "name") {
|
|
1802
|
-
return [edge(from, void 0, expr2.value)];
|
|
1803
|
-
} else {
|
|
1804
|
-
throw new Error("Unknown expr type");
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
function cmp(a, b) {
|
|
1809
|
-
return b - a;
|
|
1810
|
-
}
|
|
1811
|
-
function nullFrom(nfa2, node) {
|
|
1812
|
-
let result = [];
|
|
1813
|
-
scan(node);
|
|
1814
|
-
return result.sort(cmp);
|
|
1815
|
-
function scan(node2) {
|
|
1816
|
-
let edges = nfa2[node2];
|
|
1817
|
-
if (edges.length == 1 && !edges[0].term)
|
|
1818
|
-
return scan(edges[0].to);
|
|
1819
|
-
result.push(node2);
|
|
1820
|
-
for (let i = 0; i < edges.length; i++) {
|
|
1821
|
-
let { term, to } = edges[i];
|
|
1822
|
-
if (!term && result.indexOf(to) == -1)
|
|
1823
|
-
scan(to);
|
|
1824
|
-
}
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
function dfa(nfa2) {
|
|
1828
|
-
let labeled = /* @__PURE__ */ Object.create(null);
|
|
1829
|
-
return explore(nullFrom(nfa2, 0));
|
|
1830
|
-
function explore(states) {
|
|
1831
|
-
let out = [];
|
|
1832
|
-
states.forEach((node) => {
|
|
1833
|
-
nfa2[node].forEach(({ term, to }) => {
|
|
1834
|
-
if (!term)
|
|
1835
|
-
return;
|
|
1836
|
-
let set;
|
|
1837
|
-
for (let i = 0; i < out.length; i++)
|
|
1838
|
-
if (out[i][0] == term)
|
|
1839
|
-
set = out[i][1];
|
|
1840
|
-
nullFrom(nfa2, to).forEach((node2) => {
|
|
1841
|
-
if (!set)
|
|
1842
|
-
out.push([term, set = []]);
|
|
1843
|
-
if (set.indexOf(node2) == -1)
|
|
1844
|
-
set.push(node2);
|
|
1845
|
-
});
|
|
1846
|
-
});
|
|
1847
|
-
});
|
|
1848
|
-
let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1);
|
|
1849
|
-
for (let i = 0; i < out.length; i++) {
|
|
1850
|
-
let states2 = out[i][1].sort(cmp);
|
|
1851
|
-
state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) });
|
|
1852
|
-
}
|
|
1853
|
-
return state;
|
|
466
|
+
Slice.empty = new Slice(Fragment.empty, 0, 0);
|
|
467
|
+
function removeRange(content, from, to) {
|
|
468
|
+
let { index, offset: offset2 } = content.findIndex(from), child = content.maybeChild(index);
|
|
469
|
+
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
470
|
+
if (offset2 == from || child.isText) {
|
|
471
|
+
if (offsetTo != to && !content.child(indexTo).isText)
|
|
472
|
+
throw new RangeError("Removing non-flat range");
|
|
473
|
+
return content.cut(0, from).append(content.cut(to));
|
|
1854
474
|
}
|
|
475
|
+
if (index != indexTo)
|
|
476
|
+
throw new RangeError("Removing non-flat range");
|
|
477
|
+
return content.replaceChild(index, child.copy(removeRange(child.content, from - offset2 - 1, to - offset2 - 1)));
|
|
1855
478
|
}
|
|
1856
|
-
function
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
if (dead && !(type.isText || type.hasRequiredAttrs()))
|
|
1863
|
-
dead = false;
|
|
1864
|
-
if (work.indexOf(next) == -1)
|
|
1865
|
-
work.push(next);
|
|
1866
|
-
}
|
|
1867
|
-
if (dead)
|
|
1868
|
-
stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
|
|
479
|
+
function insertInto(content, dist, insert, parent) {
|
|
480
|
+
let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index);
|
|
481
|
+
if (offset2 == dist || child.isText) {
|
|
482
|
+
if (parent && !parent.canReplace(index, index, insert))
|
|
483
|
+
return null;
|
|
484
|
+
return content.cut(0, dist).append(insert).append(content.cut(dist));
|
|
1869
485
|
}
|
|
486
|
+
let inner = insertInto(child.content, dist - offset2 - 1, insert, child);
|
|
487
|
+
return inner && content.replaceChild(index, child.copy(inner));
|
|
1870
488
|
}
|
|
1871
489
|
|
|
1872
490
|
// node_modules/prosemirror-transform/dist/index.js
|
|
@@ -3001,7 +1619,7 @@ var FieldDesc = class {
|
|
|
3001
1619
|
this.apply = bind(desc.apply, self);
|
|
3002
1620
|
}
|
|
3003
1621
|
};
|
|
3004
|
-
|
|
1622
|
+
[
|
|
3005
1623
|
new FieldDesc("doc", {
|
|
3006
1624
|
init(config) {
|
|
3007
1625
|
return config.doc || config.schema.topNodeType.createAndFill();
|
|
@@ -3858,7 +2476,6 @@ function computeOffsets(_ref) {
|
|
|
3858
2476
|
case end:
|
|
3859
2477
|
offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
|
|
3860
2478
|
break;
|
|
3861
|
-
default:
|
|
3862
2479
|
}
|
|
3863
2480
|
}
|
|
3864
2481
|
return offsets;
|
|
@@ -3879,7 +2496,6 @@ function detectOverflow(state, options) {
|
|
|
3879
2496
|
var popperOffsets2 = computeOffsets({
|
|
3880
2497
|
reference: referenceClientRect,
|
|
3881
2498
|
element: popperRect,
|
|
3882
|
-
strategy: "absolute",
|
|
3883
2499
|
placement
|
|
3884
2500
|
});
|
|
3885
2501
|
var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
|
|
@@ -4136,7 +2752,6 @@ function popperOffsets(_ref) {
|
|
|
4136
2752
|
state.modifiersData[name] = computeOffsets({
|
|
4137
2753
|
reference: state.rects.reference,
|
|
4138
2754
|
element: state.rects.popper,
|
|
4139
|
-
strategy: "absolute",
|
|
4140
2755
|
placement: state.placement
|
|
4141
2756
|
});
|
|
4142
2757
|
}
|
|
@@ -5775,7 +4390,7 @@ function tippy(targets, optionalProps) {
|
|
|
5775
4390
|
tippy.defaultProps = defaultProps;
|
|
5776
4391
|
tippy.setDefaultProps = setDefaultProps;
|
|
5777
4392
|
tippy.currentInput = currentInput;
|
|
5778
|
-
|
|
4393
|
+
Object.assign({}, applyStyles_default, {
|
|
5779
4394
|
effect: function effect4(_ref) {
|
|
5780
4395
|
var state = _ref.state;
|
|
5781
4396
|
var initialStyles = {
|
|
@@ -5801,10 +4416,6 @@ tippy.setDefaultProps({
|
|
|
5801
4416
|
render
|
|
5802
4417
|
});
|
|
5803
4418
|
var tippy_esm_default = tippy;
|
|
5804
|
-
|
|
5805
|
-
// src/slash/SlashMenu.tsx
|
|
5806
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5807
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5808
4419
|
function SlashMenu({ items, command }) {
|
|
5809
4420
|
const [query, setQuery] = useState("");
|
|
5810
4421
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
@@ -5884,22 +4495,6 @@ function SlashMenu({ items, command }) {
|
|
|
5884
4495
|
}
|
|
5885
4496
|
) });
|
|
5886
4497
|
}
|
|
5887
|
-
|
|
5888
|
-
// src/commands/slash-commands.tsx
|
|
5889
|
-
import {
|
|
5890
|
-
Type,
|
|
5891
|
-
Heading1,
|
|
5892
|
-
Heading2,
|
|
5893
|
-
Heading3,
|
|
5894
|
-
List,
|
|
5895
|
-
ListOrdered,
|
|
5896
|
-
Quote,
|
|
5897
|
-
Code,
|
|
5898
|
-
Minus,
|
|
5899
|
-
Table,
|
|
5900
|
-
Link
|
|
5901
|
-
} from "lucide-react";
|
|
5902
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
5903
4498
|
var slashCommands = [
|
|
5904
4499
|
/* ================= AI ================= */
|
|
5905
4500
|
// {
|
|
@@ -5942,7 +4537,7 @@ var slashCommands = [
|
|
|
5942
4537
|
title: "Text",
|
|
5943
4538
|
description: "Normal paragraph",
|
|
5944
4539
|
category: "Style",
|
|
5945
|
-
icon: /* @__PURE__ */
|
|
4540
|
+
icon: /* @__PURE__ */ jsx(Type, { size: 16 }),
|
|
5946
4541
|
keywords: ["paragraph", "text"],
|
|
5947
4542
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setParagraph().run()
|
|
5948
4543
|
},
|
|
@@ -5951,7 +4546,7 @@ var slashCommands = [
|
|
|
5951
4546
|
title: "Heading 1",
|
|
5952
4547
|
description: "Big section heading",
|
|
5953
4548
|
category: "Style",
|
|
5954
|
-
icon: /* @__PURE__ */
|
|
4549
|
+
icon: /* @__PURE__ */ jsx(Heading1, { size: 16 }),
|
|
5955
4550
|
keywords: ["h1", "title"],
|
|
5956
4551
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 1 }).run()
|
|
5957
4552
|
},
|
|
@@ -5960,7 +4555,7 @@ var slashCommands = [
|
|
|
5960
4555
|
title: "Heading 2",
|
|
5961
4556
|
description: "Medium section heading",
|
|
5962
4557
|
category: "Style",
|
|
5963
|
-
icon: /* @__PURE__ */
|
|
4558
|
+
icon: /* @__PURE__ */ jsx(Heading2, { size: 16 }),
|
|
5964
4559
|
keywords: ["h2"],
|
|
5965
4560
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 2 }).run()
|
|
5966
4561
|
},
|
|
@@ -5969,7 +4564,7 @@ var slashCommands = [
|
|
|
5969
4564
|
title: "Heading 3",
|
|
5970
4565
|
description: "Small section heading",
|
|
5971
4566
|
category: "Style",
|
|
5972
|
-
icon: /* @__PURE__ */
|
|
4567
|
+
icon: /* @__PURE__ */ jsx(Heading3, { size: 16 }),
|
|
5973
4568
|
keywords: ["h3"],
|
|
5974
4569
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 3 }).run()
|
|
5975
4570
|
},
|
|
@@ -5977,7 +4572,7 @@ var slashCommands = [
|
|
|
5977
4572
|
id: "bullet-list",
|
|
5978
4573
|
title: "Bullet List",
|
|
5979
4574
|
category: "Style",
|
|
5980
|
-
icon: /* @__PURE__ */
|
|
4575
|
+
icon: /* @__PURE__ */ jsx(List, { size: 16 }),
|
|
5981
4576
|
keywords: ["ul", "bullet"],
|
|
5982
4577
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleBulletList().run()
|
|
5983
4578
|
},
|
|
@@ -5985,7 +4580,7 @@ var slashCommands = [
|
|
|
5985
4580
|
id: "ordered-list",
|
|
5986
4581
|
title: "Numbered List",
|
|
5987
4582
|
category: "Style",
|
|
5988
|
-
icon: /* @__PURE__ */
|
|
4583
|
+
icon: /* @__PURE__ */ jsx(ListOrdered, { size: 16 }),
|
|
5989
4584
|
keywords: ["ol", "number"],
|
|
5990
4585
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleOrderedList().run()
|
|
5991
4586
|
},
|
|
@@ -6001,7 +4596,7 @@ var slashCommands = [
|
|
|
6001
4596
|
id: "blockquote",
|
|
6002
4597
|
title: "Quote",
|
|
6003
4598
|
category: "Style",
|
|
6004
|
-
icon: /* @__PURE__ */
|
|
4599
|
+
icon: /* @__PURE__ */ jsx(Quote, { size: 16 }),
|
|
6005
4600
|
keywords: ["quote"],
|
|
6006
4601
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleBlockquote().run()
|
|
6007
4602
|
},
|
|
@@ -6009,7 +4604,7 @@ var slashCommands = [
|
|
|
6009
4604
|
id: "code-block",
|
|
6010
4605
|
title: "Code Block",
|
|
6011
4606
|
category: "Style",
|
|
6012
|
-
icon: /* @__PURE__ */
|
|
4607
|
+
icon: /* @__PURE__ */ jsx(Code, { size: 16 }),
|
|
6013
4608
|
keywords: ["code", "pre"],
|
|
6014
4609
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleCodeBlock().run()
|
|
6015
4610
|
},
|
|
@@ -6018,7 +4613,7 @@ var slashCommands = [
|
|
|
6018
4613
|
id: "divider",
|
|
6019
4614
|
title: "Divider",
|
|
6020
4615
|
category: "Insert",
|
|
6021
|
-
icon: /* @__PURE__ */
|
|
4616
|
+
icon: /* @__PURE__ */ jsx(Minus, { size: 16 }),
|
|
6022
4617
|
keywords: ["hr", "separator"],
|
|
6023
4618
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHorizontalRule().run()
|
|
6024
4619
|
},
|
|
@@ -6026,7 +4621,7 @@ var slashCommands = [
|
|
|
6026
4621
|
id: "table",
|
|
6027
4622
|
title: "Table",
|
|
6028
4623
|
category: "Insert",
|
|
6029
|
-
icon: /* @__PURE__ */
|
|
4624
|
+
icon: /* @__PURE__ */ jsx(Table, { size: 16 }),
|
|
6030
4625
|
keywords: ["table", "grid"],
|
|
6031
4626
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
|
|
6032
4627
|
},
|
|
@@ -6052,7 +4647,7 @@ var slashCommands = [
|
|
|
6052
4647
|
id: "link",
|
|
6053
4648
|
title: "Link",
|
|
6054
4649
|
category: "Media",
|
|
6055
|
-
icon: /* @__PURE__ */
|
|
4650
|
+
icon: /* @__PURE__ */ jsx(Link, { size: 16 }),
|
|
6056
4651
|
keywords: ["url"],
|
|
6057
4652
|
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setLink({ href: "https://example.com" }).run()
|
|
6058
4653
|
}
|
|
@@ -6178,444 +4773,9 @@ var SlashExtension = Extension.create({
|
|
|
6178
4773
|
];
|
|
6179
4774
|
}
|
|
6180
4775
|
});
|
|
6181
|
-
|
|
6182
|
-
// src/SelectionToolbar.tsx
|
|
6183
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
6184
|
-
import {
|
|
6185
|
-
Bold,
|
|
6186
|
-
Italic,
|
|
6187
|
-
Underline,
|
|
6188
|
-
Strikethrough,
|
|
6189
|
-
Code as Code2,
|
|
6190
|
-
Link2,
|
|
6191
|
-
Highlighter,
|
|
6192
|
-
Type as Type2,
|
|
6193
|
-
Heading1 as Heading12,
|
|
6194
|
-
Heading2 as Heading22,
|
|
6195
|
-
Heading3 as Heading32,
|
|
6196
|
-
List as List2,
|
|
6197
|
-
ListOrdered as ListOrdered2,
|
|
6198
|
-
CheckSquare as CheckSquare2,
|
|
6199
|
-
Quote as Quote2,
|
|
6200
|
-
Code2 as Code22,
|
|
6201
|
-
AlignLeft,
|
|
6202
|
-
AlignCenter,
|
|
6203
|
-
AlignRight,
|
|
6204
|
-
AlignJustify,
|
|
6205
|
-
MoreVertical
|
|
6206
|
-
} from "lucide-react";
|
|
6207
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
6208
|
-
function SelectionToolbar({ editor }) {
|
|
6209
|
-
const [showColors, setShowColors] = useState2(false);
|
|
6210
|
-
const [showHighlights, setShowHighlights] = useState2(false);
|
|
6211
|
-
const [showTurnInto, setShowTurnInto] = useState2(false);
|
|
6212
|
-
const [showMore, setShowMore] = useState2(false);
|
|
6213
|
-
useEffect2(() => {
|
|
6214
|
-
if (!editor) return;
|
|
6215
|
-
const closeMenu = () => {
|
|
6216
|
-
setShowTurnInto(false);
|
|
6217
|
-
setShowColors(false);
|
|
6218
|
-
setShowHighlights(false);
|
|
6219
|
-
setShowMore(false);
|
|
6220
|
-
};
|
|
6221
|
-
editor.on("selectionUpdate", closeMenu);
|
|
6222
|
-
editor.on("blur", closeMenu);
|
|
6223
|
-
return () => {
|
|
6224
|
-
editor.off("selectionUpdate", closeMenu);
|
|
6225
|
-
editor.off("blur", closeMenu);
|
|
6226
|
-
};
|
|
6227
|
-
}, [editor]);
|
|
6228
|
-
const colors = [
|
|
6229
|
-
{ name: "Default", value: "#000000" },
|
|
6230
|
-
{ name: "Gray", value: "#6B7280" },
|
|
6231
|
-
{ name: "Red", value: "#EF4444" },
|
|
6232
|
-
{ name: "Orange", value: "#F97316" },
|
|
6233
|
-
{ name: "Yellow", value: "#EAB308" },
|
|
6234
|
-
{ name: "Green", value: "#10B981" },
|
|
6235
|
-
{ name: "Blue", value: "#3B82F6" },
|
|
6236
|
-
{ name: "Purple", value: "#8B5CF6" }
|
|
6237
|
-
];
|
|
6238
|
-
const highlights = [
|
|
6239
|
-
{ name: "None", value: "transparent" },
|
|
6240
|
-
{ name: "Gray", value: "#F3F4F6" },
|
|
6241
|
-
{ name: "Red", value: "#FEE2E2" },
|
|
6242
|
-
{ name: "Orange", value: "#FFEDD5" },
|
|
6243
|
-
{ name: "Yellow", value: "#FEF3C7" },
|
|
6244
|
-
{ name: "Green", value: "#D1FAE5" },
|
|
6245
|
-
{ name: "Blue", value: "#DBEAFE" },
|
|
6246
|
-
{ name: "Purple", value: "#EDE9FE" }
|
|
6247
|
-
];
|
|
6248
|
-
const setLink = () => {
|
|
6249
|
-
const previousUrl = editor.getAttributes("link").href;
|
|
6250
|
-
const url = window.prompt("Enter URL:", previousUrl);
|
|
6251
|
-
if (url === null) {
|
|
6252
|
-
return;
|
|
6253
|
-
}
|
|
6254
|
-
if (url === "") {
|
|
6255
|
-
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
6256
|
-
return;
|
|
6257
|
-
}
|
|
6258
|
-
editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
|
6259
|
-
};
|
|
6260
|
-
const currentBlockLabel = () => {
|
|
6261
|
-
if (editor.isActive("heading", { level: 1 })) return "Heading 1";
|
|
6262
|
-
if (editor.isActive("heading", { level: 2 })) return "Heading 2";
|
|
6263
|
-
if (editor.isActive("heading", { level: 3 })) return "Heading 3";
|
|
6264
|
-
if (editor.isActive("bulletList")) return "Bulleted list";
|
|
6265
|
-
if (editor.isActive("orderedList")) return "Numbered list";
|
|
6266
|
-
if (editor.isActive("taskList")) return "To-do list";
|
|
6267
|
-
if (editor.isActive("blockquote")) return "Blockquote";
|
|
6268
|
-
if (editor.isActive("codeBlock")) return "Code block";
|
|
6269
|
-
return "Text";
|
|
6270
|
-
};
|
|
6271
|
-
const turnIntoItems = [
|
|
6272
|
-
{
|
|
6273
|
-
label: "Text",
|
|
6274
|
-
icon: /* @__PURE__ */ jsx3(Type2, { size: 16 }),
|
|
6275
|
-
isActive: () => editor.isActive("paragraph") && !editor.isActive("bulletList") && !editor.isActive("orderedList") && !editor.isActive("taskList"),
|
|
6276
|
-
action: () => {
|
|
6277
|
-
editor.chain().focus().clearNodes().setParagraph().run();
|
|
6278
|
-
}
|
|
6279
|
-
},
|
|
6280
|
-
{
|
|
6281
|
-
label: "Heading 1",
|
|
6282
|
-
icon: /* @__PURE__ */ jsx3(Heading12, { size: 16 }),
|
|
6283
|
-
isActive: () => editor.isActive("heading", { level: 1 }),
|
|
6284
|
-
action: () => editor.chain().focus().toggleHeading({ level: 1 }).run()
|
|
6285
|
-
},
|
|
6286
|
-
{
|
|
6287
|
-
label: "Heading 2",
|
|
6288
|
-
icon: /* @__PURE__ */ jsx3(Heading22, { size: 16 }),
|
|
6289
|
-
isActive: () => editor.isActive("heading", { level: 2 }),
|
|
6290
|
-
action: () => editor.chain().focus().toggleHeading({ level: 2 }).run()
|
|
6291
|
-
},
|
|
6292
|
-
{
|
|
6293
|
-
label: "Heading 3",
|
|
6294
|
-
icon: /* @__PURE__ */ jsx3(Heading32, { size: 16 }),
|
|
6295
|
-
isActive: () => editor.isActive("heading", { level: 3 }),
|
|
6296
|
-
action: () => editor.chain().focus().toggleHeading({ level: 3 }).run()
|
|
6297
|
-
},
|
|
6298
|
-
{
|
|
6299
|
-
label: "To-do list",
|
|
6300
|
-
icon: /* @__PURE__ */ jsx3(CheckSquare2, { size: 16 }),
|
|
6301
|
-
isActive: () => editor.isActive("taskList"),
|
|
6302
|
-
action: () => {
|
|
6303
|
-
if (editor.isActive("taskList")) {
|
|
6304
|
-
editor.chain().focus().liftListItem("taskItem").run();
|
|
6305
|
-
} else {
|
|
6306
|
-
editor.chain().focus().toggleTaskList().run();
|
|
6307
|
-
}
|
|
6308
|
-
}
|
|
6309
|
-
},
|
|
6310
|
-
{
|
|
6311
|
-
label: "Blockquote",
|
|
6312
|
-
icon: /* @__PURE__ */ jsx3(Quote2, { size: 16 }),
|
|
6313
|
-
isActive: () => editor.isActive("blockquote"),
|
|
6314
|
-
action: () => editor.chain().focus().toggleBlockquote().run()
|
|
6315
|
-
},
|
|
6316
|
-
{
|
|
6317
|
-
label: "Code block",
|
|
6318
|
-
icon: /* @__PURE__ */ jsx3(Code22, { size: 16 }),
|
|
6319
|
-
isActive: () => editor.isActive("codeBlock"),
|
|
6320
|
-
action: () => editor.chain().focus().toggleCodeBlock().run()
|
|
6321
|
-
}
|
|
6322
|
-
];
|
|
6323
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1 rounded-lg border border-gray-200 bg-white p-1 shadow-xl", children: [
|
|
6324
|
-
/* @__PURE__ */ jsx3(
|
|
6325
|
-
"button",
|
|
6326
|
-
{
|
|
6327
|
-
onClick: () => {
|
|
6328
|
-
if (editor.isActive("bulletList")) {
|
|
6329
|
-
editor.chain().focus().liftListItem("listItem").run();
|
|
6330
|
-
} else {
|
|
6331
|
-
editor.chain().focus().toggleBulletList().run();
|
|
6332
|
-
}
|
|
6333
|
-
},
|
|
6334
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("bulletList") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6335
|
-
title: "Bullet List",
|
|
6336
|
-
type: "button",
|
|
6337
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6338
|
-
children: /* @__PURE__ */ jsx3(List2, { size: 16 })
|
|
6339
|
-
}
|
|
6340
|
-
),
|
|
6341
|
-
/* @__PURE__ */ jsx3(
|
|
6342
|
-
"button",
|
|
6343
|
-
{
|
|
6344
|
-
onClick: () => {
|
|
6345
|
-
if (editor.isActive("orderedList")) {
|
|
6346
|
-
editor.chain().focus().liftListItem("listItem").run();
|
|
6347
|
-
} else {
|
|
6348
|
-
editor.chain().focus().toggleOrderedList().run();
|
|
6349
|
-
}
|
|
6350
|
-
},
|
|
6351
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("orderedList") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6352
|
-
title: "Numbered List",
|
|
6353
|
-
type: "button",
|
|
6354
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6355
|
-
children: /* @__PURE__ */ jsx3(ListOrdered2, { size: 16 })
|
|
6356
|
-
}
|
|
6357
|
-
),
|
|
6358
|
-
/* @__PURE__ */ jsx3("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
|
|
6359
|
-
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
6360
|
-
/* @__PURE__ */ jsxs2(
|
|
6361
|
-
"button",
|
|
6362
|
-
{
|
|
6363
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6364
|
-
onClick: () => setShowTurnInto((v) => !v),
|
|
6365
|
-
className: "rounded-md px-2 py-1 text-sm text-gray-700 hover:bg-gray-100",
|
|
6366
|
-
children: [
|
|
6367
|
-
currentBlockLabel(),
|
|
6368
|
-
" \u25BE"
|
|
6369
|
-
]
|
|
6370
|
-
}
|
|
6371
|
-
),
|
|
6372
|
-
showTurnInto && /* @__PURE__ */ jsxs2("div", { className: "absolute left-0 top-full z-50 mt-2 w-52 rounded-lg border bg-white shadow-xl", children: [
|
|
6373
|
-
/* @__PURE__ */ jsx3("div", { className: "px-3 py-2 text-xs font-semibold text-gray-500", children: "Turn into" }),
|
|
6374
|
-
/* @__PURE__ */ jsx3("div", { className: "p-1", children: turnIntoItems.map((item) => {
|
|
6375
|
-
const active = item.isActive();
|
|
6376
|
-
return /* @__PURE__ */ jsxs2(
|
|
6377
|
-
"button",
|
|
6378
|
-
{
|
|
6379
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6380
|
-
onClick: () => {
|
|
6381
|
-
item.action();
|
|
6382
|
-
setShowTurnInto(false);
|
|
6383
|
-
},
|
|
6384
|
-
className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${active ? "bg-gray-100 text-blue-600" : "text-gray-700 hover:bg-gray-100"}`,
|
|
6385
|
-
children: [
|
|
6386
|
-
/* @__PURE__ */ jsx3("span", { className: "flex h-5 w-5 items-center justify-center", children: item.icon }),
|
|
6387
|
-
/* @__PURE__ */ jsx3("span", { children: item.label })
|
|
6388
|
-
]
|
|
6389
|
-
},
|
|
6390
|
-
item.label
|
|
6391
|
-
);
|
|
6392
|
-
}) })
|
|
6393
|
-
] })
|
|
6394
|
-
] }),
|
|
6395
|
-
/* @__PURE__ */ jsx3("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
|
|
6396
|
-
/* @__PURE__ */ jsx3(
|
|
6397
|
-
"button",
|
|
6398
|
-
{
|
|
6399
|
-
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
6400
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("bold") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6401
|
-
title: "Bold (Ctrl+B)",
|
|
6402
|
-
type: "button",
|
|
6403
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6404
|
-
children: /* @__PURE__ */ jsx3(Bold, { size: 16 })
|
|
6405
|
-
}
|
|
6406
|
-
),
|
|
6407
|
-
/* @__PURE__ */ jsx3(
|
|
6408
|
-
"button",
|
|
6409
|
-
{
|
|
6410
|
-
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
6411
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("italic") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6412
|
-
title: "Italic (Ctrl+I)",
|
|
6413
|
-
type: "button",
|
|
6414
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6415
|
-
children: /* @__PURE__ */ jsx3(Italic, { size: 16 })
|
|
6416
|
-
}
|
|
6417
|
-
),
|
|
6418
|
-
/* @__PURE__ */ jsx3(
|
|
6419
|
-
"button",
|
|
6420
|
-
{
|
|
6421
|
-
onClick: () => editor.chain().focus().toggleUnderline().run(),
|
|
6422
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("underline") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6423
|
-
title: "Underline (Ctrl+U)",
|
|
6424
|
-
type: "button",
|
|
6425
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6426
|
-
children: /* @__PURE__ */ jsx3(Underline, { size: 16 })
|
|
6427
|
-
}
|
|
6428
|
-
),
|
|
6429
|
-
/* @__PURE__ */ jsx3(
|
|
6430
|
-
"button",
|
|
6431
|
-
{
|
|
6432
|
-
onClick: () => editor.chain().focus().toggleStrike().run(),
|
|
6433
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("strike") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6434
|
-
title: "Strikethrough",
|
|
6435
|
-
type: "button",
|
|
6436
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6437
|
-
children: /* @__PURE__ */ jsx3(Strikethrough, { size: 16 })
|
|
6438
|
-
}
|
|
6439
|
-
),
|
|
6440
|
-
/* @__PURE__ */ jsx3(
|
|
6441
|
-
"button",
|
|
6442
|
-
{
|
|
6443
|
-
onClick: () => editor.chain().focus().toggleCode().run(),
|
|
6444
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("code") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6445
|
-
title: "Code",
|
|
6446
|
-
type: "button",
|
|
6447
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6448
|
-
children: /* @__PURE__ */ jsx3(Code2, { size: 16 })
|
|
6449
|
-
}
|
|
6450
|
-
),
|
|
6451
|
-
/* @__PURE__ */ jsx3("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
|
|
6452
|
-
/* @__PURE__ */ jsx3(
|
|
6453
|
-
"button",
|
|
6454
|
-
{
|
|
6455
|
-
onClick: setLink,
|
|
6456
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("link") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6457
|
-
title: "Add Link",
|
|
6458
|
-
type: "button",
|
|
6459
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6460
|
-
children: /* @__PURE__ */ jsx3(Link2, { size: 16 })
|
|
6461
|
-
}
|
|
6462
|
-
),
|
|
6463
|
-
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
6464
|
-
/* @__PURE__ */ jsx3(
|
|
6465
|
-
"button",
|
|
6466
|
-
{
|
|
6467
|
-
onClick: () => {
|
|
6468
|
-
setShowColors(!showColors);
|
|
6469
|
-
setShowHighlights(false);
|
|
6470
|
-
},
|
|
6471
|
-
className: "rounded p-1.5 text-gray-700 transition-colors hover:bg-gray-100",
|
|
6472
|
-
title: "Text Color",
|
|
6473
|
-
type: "button",
|
|
6474
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6475
|
-
children: /* @__PURE__ */ jsx3(Type2, { size: 16 })
|
|
6476
|
-
}
|
|
6477
|
-
),
|
|
6478
|
-
showColors && /* @__PURE__ */ jsx3("div", { className: "absolute left-0 top-full z-50 mt-2 flex gap-1 rounded-lg border bg-white p-2 shadow-xl", children: colors.map((color) => /* @__PURE__ */ jsx3(
|
|
6479
|
-
"button",
|
|
6480
|
-
{
|
|
6481
|
-
onClick: () => {
|
|
6482
|
-
editor.chain().focus().setMark("textStyle", { color: color.value }).run();
|
|
6483
|
-
setShowColors(false);
|
|
6484
|
-
},
|
|
6485
|
-
className: "h-6 w-6 rounded border border-gray-300 transition-transform hover:scale-110",
|
|
6486
|
-
style: { backgroundColor: color.value },
|
|
6487
|
-
title: color.name,
|
|
6488
|
-
type: "button",
|
|
6489
|
-
onMouseDown: (e) => e.preventDefault()
|
|
6490
|
-
},
|
|
6491
|
-
color.value
|
|
6492
|
-
)) })
|
|
6493
|
-
] }),
|
|
6494
|
-
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
6495
|
-
/* @__PURE__ */ jsx3(
|
|
6496
|
-
"button",
|
|
6497
|
-
{
|
|
6498
|
-
onClick: () => {
|
|
6499
|
-
setShowHighlights(!showHighlights);
|
|
6500
|
-
setShowColors(false);
|
|
6501
|
-
},
|
|
6502
|
-
className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("highlight") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
|
|
6503
|
-
title: "Highlight",
|
|
6504
|
-
type: "button",
|
|
6505
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6506
|
-
children: /* @__PURE__ */ jsx3(Highlighter, { size: 16 })
|
|
6507
|
-
}
|
|
6508
|
-
),
|
|
6509
|
-
showHighlights && /* @__PURE__ */ jsx3("div", { className: "absolute left-0 top-full z-50 mt-2 flex gap-1 rounded-lg border bg-white p-2 shadow-xl", children: highlights.map((highlight) => /* @__PURE__ */ jsx3(
|
|
6510
|
-
"button",
|
|
6511
|
-
{
|
|
6512
|
-
onClick: () => {
|
|
6513
|
-
if (highlight.value === "transparent") {
|
|
6514
|
-
editor.chain().focus().unsetMark("highlight").run();
|
|
6515
|
-
} else {
|
|
6516
|
-
editor.chain().focus().setMark("highlight", { color: highlight.value }).run();
|
|
6517
|
-
}
|
|
6518
|
-
setShowHighlights(false);
|
|
6519
|
-
},
|
|
6520
|
-
className: "h-6 w-6 rounded border border-gray-300 transition-transform hover:scale-110",
|
|
6521
|
-
style: { backgroundColor: highlight.value },
|
|
6522
|
-
title: highlight.name,
|
|
6523
|
-
type: "button",
|
|
6524
|
-
onMouseDown: (e) => e.preventDefault()
|
|
6525
|
-
},
|
|
6526
|
-
highlight.value
|
|
6527
|
-
)) })
|
|
6528
|
-
] }),
|
|
6529
|
-
/* @__PURE__ */ jsx3("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
|
|
6530
|
-
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
6531
|
-
/* @__PURE__ */ jsx3(
|
|
6532
|
-
"button",
|
|
6533
|
-
{
|
|
6534
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6535
|
-
onClick: () => setShowMore((v) => !v),
|
|
6536
|
-
className: "rounded p-1.5 hover:bg-gray-100",
|
|
6537
|
-
children: /* @__PURE__ */ jsx3(MoreVertical, { size: 16 })
|
|
6538
|
-
}
|
|
6539
|
-
),
|
|
6540
|
-
showMore && /* @__PURE__ */ jsxs2("div", { className: "absolute right-0 top-full z-50 mt-2 w-56 rounded-lg border bg-white shadow-xl", children: [
|
|
6541
|
-
/* @__PURE__ */ jsx3("div", { className: "px-3 py-2 text-xs font-semibold text-gray-500", children: "More" }),
|
|
6542
|
-
/* @__PURE__ */ jsx3("div", { className: "p-1", children: [
|
|
6543
|
-
{
|
|
6544
|
-
label: "Align left",
|
|
6545
|
-
icon: /* @__PURE__ */ jsx3(AlignLeft, { size: 16 }),
|
|
6546
|
-
isActive: () => editor.isActive({ textAlign: "left" }),
|
|
6547
|
-
action: () => editor.chain().focus().setTextAlign("left").run()
|
|
6548
|
-
},
|
|
6549
|
-
{
|
|
6550
|
-
label: "Align center",
|
|
6551
|
-
icon: /* @__PURE__ */ jsx3(AlignCenter, { size: 16 }),
|
|
6552
|
-
isActive: () => editor.isActive({ textAlign: "center" }),
|
|
6553
|
-
action: () => editor.chain().focus().setTextAlign("center").run()
|
|
6554
|
-
},
|
|
6555
|
-
{
|
|
6556
|
-
label: "Align right",
|
|
6557
|
-
icon: /* @__PURE__ */ jsx3(AlignRight, { size: 16 }),
|
|
6558
|
-
isActive: () => editor.isActive({ textAlign: "right" }),
|
|
6559
|
-
action: () => editor.chain().focus().setTextAlign("right").run()
|
|
6560
|
-
},
|
|
6561
|
-
{
|
|
6562
|
-
label: "Justify",
|
|
6563
|
-
icon: /* @__PURE__ */ jsx3(AlignJustify, { size: 16 }),
|
|
6564
|
-
isActive: () => editor.isActive({ textAlign: "justify" }),
|
|
6565
|
-
action: () => editor.chain().focus().setTextAlign("justify").run()
|
|
6566
|
-
},
|
|
6567
|
-
{ divider: true },
|
|
6568
|
-
{
|
|
6569
|
-
label: "Superscript",
|
|
6570
|
-
icon: /* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold", children: "x\xB2" }),
|
|
6571
|
-
isActive: () => editor.isActive("superscript"),
|
|
6572
|
-
action: () => editor.chain().focus().toggleSuperscript().run()
|
|
6573
|
-
},
|
|
6574
|
-
{
|
|
6575
|
-
label: "Subscript",
|
|
6576
|
-
icon: /* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold", children: "x\u2082" }),
|
|
6577
|
-
isActive: () => editor.isActive("subscript"),
|
|
6578
|
-
action: () => editor.chain().focus().toggleSubscript().run()
|
|
6579
|
-
}
|
|
6580
|
-
].map((item, index) => {
|
|
6581
|
-
if ("divider" in item) {
|
|
6582
|
-
return /* @__PURE__ */ jsx3(
|
|
6583
|
-
"div",
|
|
6584
|
-
{
|
|
6585
|
-
className: "my-1 h-px bg-gray-200"
|
|
6586
|
-
},
|
|
6587
|
-
`divider-${index}`
|
|
6588
|
-
);
|
|
6589
|
-
}
|
|
6590
|
-
const active = item.isActive();
|
|
6591
|
-
return /* @__PURE__ */ jsxs2(
|
|
6592
|
-
"button",
|
|
6593
|
-
{
|
|
6594
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
6595
|
-
onClick: () => {
|
|
6596
|
-
item.action();
|
|
6597
|
-
setShowMore(false);
|
|
6598
|
-
},
|
|
6599
|
-
className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${active ? "bg-gray-100 text-blue-600" : "text-gray-700 hover:bg-gray-100"}`,
|
|
6600
|
-
children: [
|
|
6601
|
-
/* @__PURE__ */ jsx3("span", { className: "flex h-5 w-5 items-center justify-center", children: item.icon }),
|
|
6602
|
-
/* @__PURE__ */ jsx3("span", { children: item.label })
|
|
6603
|
-
]
|
|
6604
|
-
},
|
|
6605
|
-
item.label
|
|
6606
|
-
);
|
|
6607
|
-
}) })
|
|
6608
|
-
] })
|
|
6609
|
-
] })
|
|
6610
|
-
] });
|
|
6611
|
-
}
|
|
6612
|
-
var SelectionToolbar_default = SelectionToolbar;
|
|
6613
|
-
|
|
6614
|
-
// src/table/useRowHover.ts
|
|
6615
|
-
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
6616
4776
|
function useRowHover(editor) {
|
|
6617
|
-
const [rowEl, setRowEl] =
|
|
6618
|
-
|
|
4777
|
+
const [rowEl, setRowEl] = useState(null);
|
|
4778
|
+
useEffect(() => {
|
|
6619
4779
|
if (!editor) return;
|
|
6620
4780
|
const root = editor.view.dom;
|
|
6621
4781
|
const onMouseMove = (e) => {
|
|
@@ -6635,44 +4795,37 @@ function useRowHover(editor) {
|
|
|
6635
4795
|
return rowEl;
|
|
6636
4796
|
}
|
|
6637
4797
|
|
|
6638
|
-
// src/table/RowAddButton.tsx
|
|
6639
|
-
import { MoreHorizontal } from "lucide-react";
|
|
6640
|
-
|
|
6641
4798
|
// src/table/selectTableCell.ts
|
|
6642
4799
|
function selectCellByDom(editor, cell) {
|
|
6643
4800
|
const view = editor.view;
|
|
6644
4801
|
const pos = view.posAtDOM(cell, 0);
|
|
6645
4802
|
editor.commands.setTextSelection(pos);
|
|
6646
4803
|
}
|
|
6647
|
-
|
|
6648
|
-
// src/table/RowAddButton.tsx
|
|
6649
|
-
import React2 from "react";
|
|
6650
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
6651
4804
|
function RowTableMenu(editor, onClose) {
|
|
6652
|
-
return /* @__PURE__ */
|
|
6653
|
-
/* @__PURE__ */
|
|
4805
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
|
|
4806
|
+
/* @__PURE__ */ jsx(
|
|
6654
4807
|
MenuItem,
|
|
6655
4808
|
{
|
|
6656
4809
|
label: "Add row above",
|
|
6657
4810
|
onClick: () => editor.commands.addRowBefore()
|
|
6658
4811
|
}
|
|
6659
4812
|
),
|
|
6660
|
-
/* @__PURE__ */
|
|
4813
|
+
/* @__PURE__ */ jsx(
|
|
6661
4814
|
MenuItem,
|
|
6662
4815
|
{
|
|
6663
4816
|
label: "Add row below",
|
|
6664
4817
|
onClick: () => editor.commands.addRowAfter()
|
|
6665
4818
|
}
|
|
6666
4819
|
),
|
|
6667
|
-
/* @__PURE__ */
|
|
4820
|
+
/* @__PURE__ */ jsx(
|
|
6668
4821
|
MenuItem,
|
|
6669
4822
|
{
|
|
6670
4823
|
label: "Delete row",
|
|
6671
4824
|
onClick: () => editor.commands.deleteRow()
|
|
6672
4825
|
}
|
|
6673
4826
|
),
|
|
6674
|
-
/* @__PURE__ */
|
|
6675
|
-
/* @__PURE__ */
|
|
4827
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 border-t" }),
|
|
4828
|
+
/* @__PURE__ */ jsx(
|
|
6676
4829
|
MenuItem,
|
|
6677
4830
|
{
|
|
6678
4831
|
label: "Delete table",
|
|
@@ -6690,7 +4843,7 @@ function MenuItem({
|
|
|
6690
4843
|
onClick,
|
|
6691
4844
|
danger
|
|
6692
4845
|
}) {
|
|
6693
|
-
return /* @__PURE__ */
|
|
4846
|
+
return /* @__PURE__ */ jsx(
|
|
6694
4847
|
"button",
|
|
6695
4848
|
{
|
|
6696
4849
|
onClick,
|
|
@@ -6700,12 +4853,12 @@ function MenuItem({
|
|
|
6700
4853
|
);
|
|
6701
4854
|
}
|
|
6702
4855
|
function RowAddButton({ editor, row }) {
|
|
6703
|
-
const [showRowMenu, setShowRowMenu] =
|
|
4856
|
+
const [showRowMenu, setShowRowMenu] = React.useState(false);
|
|
6704
4857
|
const firstCell = row.querySelector("td, th");
|
|
6705
4858
|
if (!firstCell) return null;
|
|
6706
4859
|
const rect = row.getBoundingClientRect();
|
|
6707
|
-
return /* @__PURE__ */
|
|
6708
|
-
/* @__PURE__ */
|
|
4860
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
4861
|
+
/* @__PURE__ */ jsx(
|
|
6709
4862
|
"button",
|
|
6710
4863
|
{
|
|
6711
4864
|
style: {
|
|
@@ -6722,10 +4875,10 @@ function RowAddButton({ editor, row }) {
|
|
|
6722
4875
|
setShowRowMenu((v) => !v);
|
|
6723
4876
|
selectCellByDom(editor, firstCell);
|
|
6724
4877
|
},
|
|
6725
|
-
children: /* @__PURE__ */
|
|
4878
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
|
|
6726
4879
|
}
|
|
6727
4880
|
),
|
|
6728
|
-
showRowMenu && /* @__PURE__ */
|
|
4881
|
+
showRowMenu && /* @__PURE__ */ jsx(
|
|
6729
4882
|
"div",
|
|
6730
4883
|
{
|
|
6731
4884
|
className: "z-[1000]",
|
|
@@ -6743,12 +4896,9 @@ function RowAddButton({ editor, row }) {
|
|
|
6743
4896
|
)
|
|
6744
4897
|
] });
|
|
6745
4898
|
}
|
|
6746
|
-
|
|
6747
|
-
// src/table/useColumnHover.ts
|
|
6748
|
-
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
6749
4899
|
function useColumnHover(editor) {
|
|
6750
|
-
const [hovered, setHovered] =
|
|
6751
|
-
|
|
4900
|
+
const [hovered, setHovered] = useState(null);
|
|
4901
|
+
useEffect(() => {
|
|
6752
4902
|
if (!editor) return;
|
|
6753
4903
|
const root = editor.view.dom;
|
|
6754
4904
|
const onMouseMove = (e) => {
|
|
@@ -6776,36 +4926,31 @@ function useColumnHover(editor) {
|
|
|
6776
4926
|
}, [editor]);
|
|
6777
4927
|
return hovered;
|
|
6778
4928
|
}
|
|
6779
|
-
|
|
6780
|
-
// src/table/ColumnAddButton.tsx
|
|
6781
|
-
import { MoreHorizontal as MoreHorizontal2 } from "lucide-react";
|
|
6782
|
-
import React3 from "react";
|
|
6783
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
6784
4929
|
function ColumnTableMenu(editor, onClose) {
|
|
6785
|
-
return /* @__PURE__ */
|
|
6786
|
-
/* @__PURE__ */
|
|
4930
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
|
|
4931
|
+
/* @__PURE__ */ jsx(
|
|
6787
4932
|
MenuItem2,
|
|
6788
4933
|
{
|
|
6789
4934
|
label: "Add column left",
|
|
6790
4935
|
onClick: () => editor.commands.addColumnBefore()
|
|
6791
4936
|
}
|
|
6792
4937
|
),
|
|
6793
|
-
/* @__PURE__ */
|
|
4938
|
+
/* @__PURE__ */ jsx(
|
|
6794
4939
|
MenuItem2,
|
|
6795
4940
|
{
|
|
6796
4941
|
label: "Add column right",
|
|
6797
4942
|
onClick: () => editor.commands.addColumnAfter()
|
|
6798
4943
|
}
|
|
6799
4944
|
),
|
|
6800
|
-
/* @__PURE__ */
|
|
4945
|
+
/* @__PURE__ */ jsx(
|
|
6801
4946
|
MenuItem2,
|
|
6802
4947
|
{
|
|
6803
4948
|
label: "Delete column",
|
|
6804
4949
|
onClick: () => editor.commands.deleteColumn()
|
|
6805
4950
|
}
|
|
6806
4951
|
),
|
|
6807
|
-
/* @__PURE__ */
|
|
6808
|
-
/* @__PURE__ */
|
|
4952
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 border-t" }),
|
|
4953
|
+
/* @__PURE__ */ jsx(
|
|
6809
4954
|
MenuItem2,
|
|
6810
4955
|
{
|
|
6811
4956
|
label: "Delete table",
|
|
@@ -6823,7 +4968,7 @@ function MenuItem2({
|
|
|
6823
4968
|
onClick,
|
|
6824
4969
|
danger
|
|
6825
4970
|
}) {
|
|
6826
|
-
return /* @__PURE__ */
|
|
4971
|
+
return /* @__PURE__ */ jsx(
|
|
6827
4972
|
"button",
|
|
6828
4973
|
{
|
|
6829
4974
|
onClick,
|
|
@@ -6837,15 +4982,15 @@ function MenuItem2({
|
|
|
6837
4982
|
);
|
|
6838
4983
|
}
|
|
6839
4984
|
function ColumnAddButton({ editor, table, columnIndex }) {
|
|
6840
|
-
const [showColumnMenu, setShowColumnMenu] =
|
|
4985
|
+
const [showColumnMenu, setShowColumnMenu] = React.useState(false);
|
|
6841
4986
|
const firstRow = table.querySelector("tr");
|
|
6842
4987
|
if (!firstRow) return null;
|
|
6843
4988
|
const cells = Array.from(firstRow.children);
|
|
6844
4989
|
const cell = cells[columnIndex];
|
|
6845
4990
|
if (!cell) return null;
|
|
6846
4991
|
const rect = cell.getBoundingClientRect();
|
|
6847
|
-
return /* @__PURE__ */
|
|
6848
|
-
/* @__PURE__ */
|
|
4992
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
4993
|
+
/* @__PURE__ */ jsx(
|
|
6849
4994
|
"button",
|
|
6850
4995
|
{
|
|
6851
4996
|
style: {
|
|
@@ -6862,10 +5007,10 @@ function ColumnAddButton({ editor, table, columnIndex }) {
|
|
|
6862
5007
|
setShowColumnMenu((v) => !v);
|
|
6863
5008
|
selectCellByDom(editor, cell);
|
|
6864
5009
|
},
|
|
6865
|
-
children: /* @__PURE__ */
|
|
5010
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
|
|
6866
5011
|
}
|
|
6867
5012
|
),
|
|
6868
|
-
showColumnMenu && /* @__PURE__ */
|
|
5013
|
+
showColumnMenu && /* @__PURE__ */ jsx(
|
|
6869
5014
|
"div",
|
|
6870
5015
|
{
|
|
6871
5016
|
className: "fixed z-[1000]",
|
|
@@ -6879,9 +5024,6 @@ function ColumnAddButton({ editor, table, columnIndex }) {
|
|
|
6879
5024
|
)
|
|
6880
5025
|
] });
|
|
6881
5026
|
}
|
|
6882
|
-
|
|
6883
|
-
// src/NotionEditor.tsx
|
|
6884
|
-
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6885
5027
|
var DynamicPlaceholder = Placeholder.configure({
|
|
6886
5028
|
placeholder: ({ node }) => {
|
|
6887
5029
|
var _a;
|
|
@@ -6924,8 +5066,8 @@ var NotionEditor = ({
|
|
|
6924
5066
|
showToolbar = true,
|
|
6925
5067
|
showTableControls = true
|
|
6926
5068
|
}) => {
|
|
6927
|
-
const lastSavedRef =
|
|
6928
|
-
const isDirtyRef =
|
|
5069
|
+
const lastSavedRef = useRef("");
|
|
5070
|
+
const isDirtyRef = useRef(false);
|
|
6929
5071
|
const editor = useEditor({
|
|
6930
5072
|
autofocus: autoFocus,
|
|
6931
5073
|
editable: !disabled,
|
|
@@ -6942,7 +5084,7 @@ var NotionEditor = ({
|
|
|
6942
5084
|
includeChildren: false
|
|
6943
5085
|
}),
|
|
6944
5086
|
SlashExtension,
|
|
6945
|
-
|
|
5087
|
+
Underline,
|
|
6946
5088
|
TextStyle,
|
|
6947
5089
|
Color,
|
|
6948
5090
|
Superscript,
|
|
@@ -6953,13 +5095,13 @@ var NotionEditor = ({
|
|
|
6953
5095
|
Highlight.configure({
|
|
6954
5096
|
multicolor: true
|
|
6955
5097
|
}),
|
|
6956
|
-
|
|
5098
|
+
Link2.configure({
|
|
6957
5099
|
openOnClick: false,
|
|
6958
5100
|
HTMLAttributes: {
|
|
6959
5101
|
class: "text-blue-600 underline cursor-pointer hover:text-blue-800"
|
|
6960
5102
|
}
|
|
6961
5103
|
}),
|
|
6962
|
-
|
|
5104
|
+
Table$1.configure({
|
|
6963
5105
|
resizable: true,
|
|
6964
5106
|
lastColumnResizable: true,
|
|
6965
5107
|
allowTableNodeSelection: true
|
|
@@ -7001,23 +5143,22 @@ var NotionEditor = ({
|
|
|
7001
5143
|
});
|
|
7002
5144
|
}
|
|
7003
5145
|
});
|
|
7004
|
-
|
|
5146
|
+
useEffect(() => {
|
|
7005
5147
|
if (!editor) return;
|
|
7006
5148
|
const currentHTML = editor.getHTML();
|
|
7007
5149
|
if (content !== void 0 && content !== currentHTML) {
|
|
7008
5150
|
editor.commands.setContent(content || "");
|
|
7009
5151
|
}
|
|
7010
5152
|
}, [content, editor]);
|
|
7011
|
-
|
|
5153
|
+
useEffect(() => {
|
|
7012
5154
|
editor == null ? void 0 : editor.setEditable(!disabled);
|
|
7013
5155
|
}, [disabled, editor]);
|
|
7014
5156
|
const hoveredRow = useRowHover(editor);
|
|
7015
5157
|
const hoveredColumn = useColumnHover(editor);
|
|
7016
5158
|
if (!editor) return null;
|
|
7017
|
-
return /* @__PURE__ */
|
|
7018
|
-
|
|
7019
|
-
showTableControls && editor &&
|
|
7020
|
-
showTableControls && editor && hoveredColumn && /* @__PURE__ */ jsx6(
|
|
5159
|
+
return /* @__PURE__ */ jsxs("div", { className: clsx("relative rounded-lg border bg-white", className), children: [
|
|
5160
|
+
showTableControls && editor && hoveredRow && /* @__PURE__ */ jsx(RowAddButton, { editor, row: hoveredRow }),
|
|
5161
|
+
showTableControls && editor && hoveredColumn && /* @__PURE__ */ jsx(
|
|
7021
5162
|
ColumnAddButton,
|
|
7022
5163
|
{
|
|
7023
5164
|
editor,
|
|
@@ -7025,7 +5166,7 @@ var NotionEditor = ({
|
|
|
7025
5166
|
columnIndex: hoveredColumn.columnIndex
|
|
7026
5167
|
}
|
|
7027
5168
|
),
|
|
7028
|
-
/* @__PURE__ */
|
|
5169
|
+
/* @__PURE__ */ jsx(
|
|
7029
5170
|
EditorContent,
|
|
7030
5171
|
{
|
|
7031
5172
|
editor,
|
|
@@ -7039,7 +5180,7 @@ var NotionEditor = ({
|
|
|
7039
5180
|
] });
|
|
7040
5181
|
};
|
|
7041
5182
|
var NotionEditor_default = NotionEditor;
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
5183
|
+
|
|
5184
|
+
export { NotionEditor_default as NotionEditor };
|
|
5185
|
+
//# sourceMappingURL=index.mjs.map
|
|
7045
5186
|
//# sourceMappingURL=index.mjs.map
|