@harbour-enterprises/superdoc 0.21.0-next.4 → 0.21.0-next.5
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/chunks/{PdfViewer-OZDJ7gwT.cjs → PdfViewer-DYQ6TKSD.cjs} +1 -1
- package/dist/chunks/{PdfViewer-D3zo7tPo.es.js → PdfViewer-p-D44U59.es.js} +1 -1
- package/dist/chunks/{index-MzW5BVNd.es.js → index-CDJb8aX-.es.js} +4 -3
- package/dist/chunks/{index-CfYf4T_z.cjs → index-CtZxITmf.cjs} +4 -3
- package/dist/chunks/{super-editor.es-U-GVCd_F.cjs → super-editor.es-Do6Vcsbv.cjs} +377 -118
- package/dist/chunks/{super-editor.es-Bntob7Wd.es.js → super-editor.es-HiSJrA0J.es.js} +377 -118
- package/dist/core/types/index.d.ts +8 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/style.css +32 -27
- package/dist/super-editor/src/components/slash-menu/menuItems.d.ts +5 -1
- package/dist/super-editor/src/components/slash-menu/tests/testHelpers.d.ts +466 -0
- package/dist/super-editor/src/components/slash-menu/utils.d.ts +9 -2
- package/dist/super-editor/style.css +5 -0
- package/dist/super-editor/super-editor.es.js +377 -118
- package/dist/super-editor.cjs +1 -1
- package/dist/super-editor.es.js +1 -1
- package/dist/superdoc.cjs +2 -2
- package/dist/superdoc.es.js +2 -2
- package/dist/superdoc.umd.js +379 -119
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/superdoc.umd.js
CHANGED
|
@@ -91267,6 +91267,115 @@ ${style2}
|
|
|
91267
91267
|
this.updateToolbarState();
|
|
91268
91268
|
}
|
|
91269
91269
|
};
|
|
91270
|
+
const onMarginClickCursorChange = (event, editor) => {
|
|
91271
|
+
const y2 = event.clientY;
|
|
91272
|
+
const x = event.clientX;
|
|
91273
|
+
const { view } = editor;
|
|
91274
|
+
const editorRect = view.dom.getBoundingClientRect();
|
|
91275
|
+
let coords = {
|
|
91276
|
+
left: 0,
|
|
91277
|
+
top: y2
|
|
91278
|
+
};
|
|
91279
|
+
let isRightMargin = false;
|
|
91280
|
+
if (x > editorRect.right) {
|
|
91281
|
+
coords.left = editorRect.left + editorRect.width - 1;
|
|
91282
|
+
isRightMargin = true;
|
|
91283
|
+
} else if (x < editorRect.left) {
|
|
91284
|
+
coords.left = editorRect.left;
|
|
91285
|
+
}
|
|
91286
|
+
const pos = view.posAtCoords(coords)?.pos;
|
|
91287
|
+
if (pos) {
|
|
91288
|
+
let cursorPos = pos;
|
|
91289
|
+
if (isRightMargin) {
|
|
91290
|
+
const $pos = view.state.doc.resolve(pos);
|
|
91291
|
+
const charOffset = $pos.textOffset;
|
|
91292
|
+
const node = view.state.doc.nodeAt(pos);
|
|
91293
|
+
const text = node?.text;
|
|
91294
|
+
const charAtPos = text?.charAt(charOffset);
|
|
91295
|
+
cursorPos = node?.isText && charAtPos !== " " ? pos - 1 : pos;
|
|
91296
|
+
}
|
|
91297
|
+
const transaction = view.state.tr.setSelection(TextSelection$1.create(view.state.doc, cursorPos));
|
|
91298
|
+
view.dispatch(transaction);
|
|
91299
|
+
view.focus();
|
|
91300
|
+
}
|
|
91301
|
+
};
|
|
91302
|
+
const checkNodeSpecificClicks = (editor, event, popoverControls) => {
|
|
91303
|
+
if (!editor) return;
|
|
91304
|
+
if (selectionHasNodeOrMark(editor.view.state, "link", { requireEnds: true })) {
|
|
91305
|
+
popoverControls.component = LinkInput;
|
|
91306
|
+
popoverControls.position = {
|
|
91307
|
+
left: `${event.clientX - editor.element.getBoundingClientRect().left}px`,
|
|
91308
|
+
top: `${event.clientY - editor.element.getBoundingClientRect().top + 15}px`
|
|
91309
|
+
};
|
|
91310
|
+
popoverControls.props = {
|
|
91311
|
+
showInput: true
|
|
91312
|
+
};
|
|
91313
|
+
popoverControls.visible = true;
|
|
91314
|
+
}
|
|
91315
|
+
};
|
|
91316
|
+
function selectionHasNodeOrMark(state2, name, options = {}) {
|
|
91317
|
+
const { requireEnds = false } = options;
|
|
91318
|
+
const $from = state2.selection.$from;
|
|
91319
|
+
const $to = state2.selection.$to;
|
|
91320
|
+
if (requireEnds) {
|
|
91321
|
+
for (let d2 = $from.depth; d2 > 0; d2--) {
|
|
91322
|
+
if ($from.node(d2).type.name === name) {
|
|
91323
|
+
return true;
|
|
91324
|
+
}
|
|
91325
|
+
}
|
|
91326
|
+
for (let d2 = $to.depth; d2 > 0; d2--) {
|
|
91327
|
+
if ($to.node(d2).type.name === name) {
|
|
91328
|
+
return true;
|
|
91329
|
+
}
|
|
91330
|
+
}
|
|
91331
|
+
} else {
|
|
91332
|
+
for (let d2 = $from.depth; d2 > 0; d2--) {
|
|
91333
|
+
if ($from.node(d2).type.name === name) {
|
|
91334
|
+
return true;
|
|
91335
|
+
}
|
|
91336
|
+
}
|
|
91337
|
+
}
|
|
91338
|
+
const markType = state2.schema.marks[name];
|
|
91339
|
+
if (markType) {
|
|
91340
|
+
const { from: from2, to, empty: empty2 } = state2.selection;
|
|
91341
|
+
if (requireEnds) {
|
|
91342
|
+
const fromMarks = markType.isInSet($from.marks());
|
|
91343
|
+
const toMarks = markType.isInSet($to.marks());
|
|
91344
|
+
if (fromMarks || toMarks) {
|
|
91345
|
+
return true;
|
|
91346
|
+
}
|
|
91347
|
+
if (empty2 && markType.isInSet(state2.storedMarks || $from.marks())) {
|
|
91348
|
+
return true;
|
|
91349
|
+
}
|
|
91350
|
+
} else {
|
|
91351
|
+
if (empty2) {
|
|
91352
|
+
if (markType.isInSet(state2.storedMarks || $from.marks())) {
|
|
91353
|
+
return true;
|
|
91354
|
+
}
|
|
91355
|
+
} else {
|
|
91356
|
+
let hasMark = false;
|
|
91357
|
+
state2.doc.nodesBetween(from2, to, (node) => {
|
|
91358
|
+
if (markType.isInSet(node.marks)) {
|
|
91359
|
+
hasMark = true;
|
|
91360
|
+
return false;
|
|
91361
|
+
}
|
|
91362
|
+
});
|
|
91363
|
+
if (hasMark) return true;
|
|
91364
|
+
}
|
|
91365
|
+
}
|
|
91366
|
+
}
|
|
91367
|
+
return false;
|
|
91368
|
+
}
|
|
91369
|
+
function moveCursorToMouseEvent(event, editor) {
|
|
91370
|
+
const { view } = editor;
|
|
91371
|
+
const coords = { left: event.clientX, top: event.clientY };
|
|
91372
|
+
const pos = view.posAtCoords(coords)?.pos;
|
|
91373
|
+
if (typeof pos === "number") {
|
|
91374
|
+
const tr = view.state.tr.setSelection(TextSelection$1.create(view.state.doc, pos));
|
|
91375
|
+
view.dispatch(tr);
|
|
91376
|
+
view.focus();
|
|
91377
|
+
}
|
|
91378
|
+
}
|
|
91270
91379
|
const ICONS = {
|
|
91271
91380
|
addRowBefore: plusIconSvg,
|
|
91272
91381
|
addRowAfter: plusIconSvg,
|
|
@@ -91466,6 +91575,30 @@ ${style2}
|
|
|
91466
91575
|
return baseProps;
|
|
91467
91576
|
}
|
|
91468
91577
|
};
|
|
91578
|
+
function normalizeClipboardContent(rawClipboardContent) {
|
|
91579
|
+
if (!rawClipboardContent) {
|
|
91580
|
+
return {
|
|
91581
|
+
html: null,
|
|
91582
|
+
text: null,
|
|
91583
|
+
hasContent: false,
|
|
91584
|
+
raw: null
|
|
91585
|
+
};
|
|
91586
|
+
}
|
|
91587
|
+
const html = typeof rawClipboardContent.html === "string" ? rawClipboardContent.html : null;
|
|
91588
|
+
const text = typeof rawClipboardContent.text === "string" ? rawClipboardContent.text : null;
|
|
91589
|
+
const hasHtml = !!html && html.trim().length > 0;
|
|
91590
|
+
const hasText = !!text && text.length > 0;
|
|
91591
|
+
const isObject2 = typeof rawClipboardContent === "object" && rawClipboardContent !== null;
|
|
91592
|
+
const fragmentSize = typeof rawClipboardContent.size === "number" ? rawClipboardContent.size : null;
|
|
91593
|
+
const nestedSize = isObject2 && rawClipboardContent.content && typeof rawClipboardContent.content.size === "number" ? rawClipboardContent.content.size : null;
|
|
91594
|
+
const hasFragmentContent = (fragmentSize ?? nestedSize ?? 0) > 0;
|
|
91595
|
+
return {
|
|
91596
|
+
html,
|
|
91597
|
+
text,
|
|
91598
|
+
hasContent: hasHtml || hasText || hasFragmentContent,
|
|
91599
|
+
raw: rawClipboardContent
|
|
91600
|
+
};
|
|
91601
|
+
}
|
|
91469
91602
|
async function getEditorContext(editor, event) {
|
|
91470
91603
|
const { view } = editor;
|
|
91471
91604
|
const { state: state2 } = view;
|
|
@@ -91481,123 +91614,144 @@ ${style2}
|
|
|
91481
91614
|
pos = from2;
|
|
91482
91615
|
node = state2.doc.nodeAt(pos);
|
|
91483
91616
|
}
|
|
91484
|
-
const
|
|
91617
|
+
const rawClipboardContent = await readFromClipboard(state2);
|
|
91618
|
+
const clipboardContent = normalizeClipboardContent(rawClipboardContent);
|
|
91619
|
+
const structureFromResolvedPos = pos !== null ? getStructureFromResolvedPos(state2, pos) : null;
|
|
91620
|
+
const isInTable2 = structureFromResolvedPos?.isInTable ?? selectionHasNodeOrMark(state2, "table", { requireEnds: true });
|
|
91621
|
+
const isInList = structureFromResolvedPos?.isInList ?? (selectionHasNodeOrMark(state2, "bulletList", { requireEnds: false }) || selectionHasNodeOrMark(state2, "orderedList", { requireEnds: false }));
|
|
91622
|
+
const isInSectionNode = structureFromResolvedPos?.isInSectionNode ?? selectionHasNodeOrMark(state2, "documentSection", { requireEnds: true });
|
|
91623
|
+
const currentNodeType = node?.type?.name || null;
|
|
91624
|
+
const activeMarks = [];
|
|
91625
|
+
if (event && pos !== null) {
|
|
91626
|
+
const $pos = state2.doc.resolve(pos);
|
|
91627
|
+
if ($pos.marks && typeof $pos.marks === "function") {
|
|
91628
|
+
$pos.marks().forEach((mark) => activeMarks.push(mark.type.name));
|
|
91629
|
+
}
|
|
91630
|
+
if (node && node.marks) {
|
|
91631
|
+
node.marks.forEach((mark) => activeMarks.push(mark.type.name));
|
|
91632
|
+
}
|
|
91633
|
+
} else {
|
|
91634
|
+
state2.storedMarks?.forEach((mark) => activeMarks.push(mark.type.name));
|
|
91635
|
+
state2.selection.$head.marks().forEach((mark) => activeMarks.push(mark.type.name));
|
|
91636
|
+
}
|
|
91637
|
+
const isTrackedChange = activeMarks.includes("trackInsert") || activeMarks.includes("trackDelete");
|
|
91638
|
+
let trackedChangeId = null;
|
|
91639
|
+
if (isTrackedChange && event && pos !== null) {
|
|
91640
|
+
const $pos = state2.doc.resolve(pos);
|
|
91641
|
+
const marksAtPos = $pos.marks();
|
|
91642
|
+
const trackedMark = marksAtPos.find((mark) => mark.type.name === "trackInsert" || mark.type.name === "trackDelete");
|
|
91643
|
+
if (trackedMark) {
|
|
91644
|
+
trackedChangeId = trackedMark.attrs.id;
|
|
91645
|
+
}
|
|
91646
|
+
}
|
|
91647
|
+
const cursorCoords = pos ? view.coordsAtPos(pos) : null;
|
|
91648
|
+
const cursorPosition = cursorCoords ? {
|
|
91649
|
+
x: cursorCoords.left,
|
|
91650
|
+
y: cursorCoords.top
|
|
91651
|
+
} : null;
|
|
91485
91652
|
return {
|
|
91486
|
-
|
|
91653
|
+
// Selection info
|
|
91487
91654
|
selectedText,
|
|
91655
|
+
hasSelection: !empty2,
|
|
91656
|
+
selectionStart: from2,
|
|
91657
|
+
selectionEnd: to,
|
|
91658
|
+
// Document structure
|
|
91659
|
+
isInTable: isInTable2,
|
|
91660
|
+
isInList,
|
|
91661
|
+
isInSectionNode,
|
|
91662
|
+
currentNodeType,
|
|
91663
|
+
activeMarks,
|
|
91664
|
+
// Document state
|
|
91665
|
+
isTrackedChange,
|
|
91666
|
+
trackedChangeId,
|
|
91667
|
+
documentMode: editor.options?.documentMode || "editing",
|
|
91668
|
+
canUndo: computeCanUndo(editor, state2),
|
|
91669
|
+
canRedo: computeCanRedo(editor, state2),
|
|
91670
|
+
isEditable: editor.isEditable,
|
|
91671
|
+
// Clipboard
|
|
91672
|
+
clipboardContent,
|
|
91673
|
+
// Position and trigger info
|
|
91674
|
+
cursorPosition,
|
|
91488
91675
|
pos,
|
|
91489
91676
|
node,
|
|
91490
91677
|
event,
|
|
91491
|
-
|
|
91678
|
+
// Editor reference for advanced use cases
|
|
91679
|
+
editor
|
|
91492
91680
|
};
|
|
91493
91681
|
}
|
|
91494
|
-
|
|
91495
|
-
|
|
91496
|
-
|
|
91497
|
-
|
|
91498
|
-
|
|
91499
|
-
|
|
91500
|
-
|
|
91501
|
-
|
|
91502
|
-
|
|
91503
|
-
|
|
91504
|
-
if (x > editorRect.right) {
|
|
91505
|
-
coords.left = editorRect.left + editorRect.width - 1;
|
|
91506
|
-
isRightMargin = true;
|
|
91507
|
-
} else if (x < editorRect.left) {
|
|
91508
|
-
coords.left = editorRect.left;
|
|
91682
|
+
function computeCanUndo(editor, state2) {
|
|
91683
|
+
if (typeof editor?.can === "function") {
|
|
91684
|
+
try {
|
|
91685
|
+
const can = editor.can();
|
|
91686
|
+
if (can && typeof can.undo === "function") {
|
|
91687
|
+
return !!can.undo();
|
|
91688
|
+
}
|
|
91689
|
+
} catch (error) {
|
|
91690
|
+
console.warn("[SlashMenu] Unable to determine undo availability via editor.can():", error);
|
|
91691
|
+
}
|
|
91509
91692
|
}
|
|
91510
|
-
|
|
91511
|
-
|
|
91512
|
-
|
|
91513
|
-
|
|
91514
|
-
|
|
91515
|
-
|
|
91516
|
-
const node = view.state.doc.nodeAt(pos);
|
|
91517
|
-
const text = node?.text;
|
|
91518
|
-
const charAtPos = text?.charAt(charOffset);
|
|
91519
|
-
cursorPos = node?.isText && charAtPos !== " " ? pos - 1 : pos;
|
|
91693
|
+
if (isCollaborationEnabled(editor)) {
|
|
91694
|
+
try {
|
|
91695
|
+
const undoManager = yUndoPluginKey.getState(state2)?.undoManager;
|
|
91696
|
+
return !!undoManager && undoManager.undoStack.length > 0;
|
|
91697
|
+
} catch (error) {
|
|
91698
|
+
console.warn("[SlashMenu] Unable to determine undo availability via y-prosemirror:", error);
|
|
91520
91699
|
}
|
|
91521
|
-
const transaction = view.state.tr.setSelection(TextSelection$1.create(view.state.doc, cursorPos));
|
|
91522
|
-
view.dispatch(transaction);
|
|
91523
|
-
view.focus();
|
|
91524
91700
|
}
|
|
91525
|
-
|
|
91526
|
-
|
|
91527
|
-
|
|
91528
|
-
|
|
91529
|
-
|
|
91530
|
-
popoverControls.position = {
|
|
91531
|
-
left: `${event.clientX - editor.element.getBoundingClientRect().left}px`,
|
|
91532
|
-
top: `${event.clientY - editor.element.getBoundingClientRect().top + 15}px`
|
|
91533
|
-
};
|
|
91534
|
-
popoverControls.props = {
|
|
91535
|
-
showInput: true
|
|
91536
|
-
};
|
|
91537
|
-
popoverControls.visible = true;
|
|
91701
|
+
try {
|
|
91702
|
+
return undoDepth(state2) > 0;
|
|
91703
|
+
} catch (error) {
|
|
91704
|
+
console.warn("[SlashMenu] Unable to determine undo availability via history plugin:", error);
|
|
91705
|
+
return false;
|
|
91538
91706
|
}
|
|
91539
|
-
}
|
|
91540
|
-
function
|
|
91541
|
-
|
|
91542
|
-
|
|
91543
|
-
|
|
91544
|
-
|
|
91545
|
-
|
|
91546
|
-
if ($from.node(d2).type.name === name) {
|
|
91547
|
-
return true;
|
|
91548
|
-
}
|
|
91549
|
-
}
|
|
91550
|
-
for (let d2 = $to.depth; d2 > 0; d2--) {
|
|
91551
|
-
if ($to.node(d2).type.name === name) {
|
|
91552
|
-
return true;
|
|
91553
|
-
}
|
|
91554
|
-
}
|
|
91555
|
-
} else {
|
|
91556
|
-
for (let d2 = $from.depth; d2 > 0; d2--) {
|
|
91557
|
-
if ($from.node(d2).type.name === name) {
|
|
91558
|
-
return true;
|
|
91707
|
+
}
|
|
91708
|
+
function computeCanRedo(editor, state2) {
|
|
91709
|
+
if (typeof editor?.can === "function") {
|
|
91710
|
+
try {
|
|
91711
|
+
const can = editor.can();
|
|
91712
|
+
if (can && typeof can.redo === "function") {
|
|
91713
|
+
return !!can.redo();
|
|
91559
91714
|
}
|
|
91715
|
+
} catch (error) {
|
|
91716
|
+
console.warn("[SlashMenu] Unable to determine redo availability via editor.can():", error);
|
|
91560
91717
|
}
|
|
91561
91718
|
}
|
|
91562
|
-
|
|
91563
|
-
|
|
91564
|
-
|
|
91565
|
-
|
|
91566
|
-
|
|
91567
|
-
|
|
91568
|
-
if (fromMarks || toMarks) {
|
|
91569
|
-
return true;
|
|
91570
|
-
}
|
|
91571
|
-
if (empty2 && markType.isInSet(state2.storedMarks || $from.marks())) {
|
|
91572
|
-
return true;
|
|
91573
|
-
}
|
|
91574
|
-
} else {
|
|
91575
|
-
if (empty2) {
|
|
91576
|
-
if (markType.isInSet(state2.storedMarks || $from.marks())) {
|
|
91577
|
-
return true;
|
|
91578
|
-
}
|
|
91579
|
-
} else {
|
|
91580
|
-
let hasMark = false;
|
|
91581
|
-
state2.doc.nodesBetween(from2, to, (node) => {
|
|
91582
|
-
if (markType.isInSet(node.marks)) {
|
|
91583
|
-
hasMark = true;
|
|
91584
|
-
return false;
|
|
91585
|
-
}
|
|
91586
|
-
});
|
|
91587
|
-
if (hasMark) return true;
|
|
91588
|
-
}
|
|
91719
|
+
if (isCollaborationEnabled(editor)) {
|
|
91720
|
+
try {
|
|
91721
|
+
const undoManager = yUndoPluginKey.getState(state2)?.undoManager;
|
|
91722
|
+
return !!undoManager && undoManager.redoStack.length > 0;
|
|
91723
|
+
} catch (error) {
|
|
91724
|
+
console.warn("[SlashMenu] Unable to determine redo availability via y-prosemirror:", error);
|
|
91589
91725
|
}
|
|
91590
91726
|
}
|
|
91591
|
-
|
|
91727
|
+
try {
|
|
91728
|
+
return redoDepth(state2) > 0;
|
|
91729
|
+
} catch (error) {
|
|
91730
|
+
console.warn("[SlashMenu] Unable to determine redo availability via history plugin:", error);
|
|
91731
|
+
return false;
|
|
91732
|
+
}
|
|
91592
91733
|
}
|
|
91593
|
-
function
|
|
91594
|
-
|
|
91595
|
-
|
|
91596
|
-
|
|
91597
|
-
|
|
91598
|
-
const
|
|
91599
|
-
|
|
91600
|
-
|
|
91734
|
+
function isCollaborationEnabled(editor) {
|
|
91735
|
+
return Boolean(editor?.options?.collaborationProvider && editor?.options?.ydoc);
|
|
91736
|
+
}
|
|
91737
|
+
function getStructureFromResolvedPos(state2, pos) {
|
|
91738
|
+
try {
|
|
91739
|
+
const $pos = state2.doc.resolve(pos);
|
|
91740
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
91741
|
+
for (let depth = $pos.depth; depth > 0; depth--) {
|
|
91742
|
+
ancestors.add($pos.node(depth).type.name);
|
|
91743
|
+
}
|
|
91744
|
+
const isInList = ancestors.has("bulletList") || ancestors.has("orderedList");
|
|
91745
|
+
const isInTable2 = ancestors.has("table") || ancestors.has("tableRow") || ancestors.has("tableCell") || ancestors.has("tableHeader");
|
|
91746
|
+
const isInSectionNode = ancestors.has("documentSection");
|
|
91747
|
+
return {
|
|
91748
|
+
isInTable: isInTable2,
|
|
91749
|
+
isInList,
|
|
91750
|
+
isInSectionNode
|
|
91751
|
+
};
|
|
91752
|
+
} catch (error) {
|
|
91753
|
+
console.warn("[SlashMenu] Unable to resolve position for structural context:", error);
|
|
91754
|
+
return null;
|
|
91601
91755
|
}
|
|
91602
91756
|
}
|
|
91603
91757
|
const isModuleEnabled = (editorOptions, moduleName) => {
|
|
@@ -91611,8 +91765,52 @@ ${style2}
|
|
|
91611
91765
|
return true;
|
|
91612
91766
|
}
|
|
91613
91767
|
};
|
|
91768
|
+
function applyCustomMenuConfiguration(defaultSections, context) {
|
|
91769
|
+
const { editor } = context;
|
|
91770
|
+
const slashMenuConfig = editor.options?.slashMenuConfig;
|
|
91771
|
+
if (!slashMenuConfig) {
|
|
91772
|
+
return defaultSections;
|
|
91773
|
+
}
|
|
91774
|
+
let sections = [];
|
|
91775
|
+
if (slashMenuConfig.includeDefaultItems !== false) {
|
|
91776
|
+
sections = [...defaultSections];
|
|
91777
|
+
}
|
|
91778
|
+
if (slashMenuConfig.customItems && Array.isArray(slashMenuConfig.customItems)) {
|
|
91779
|
+
sections = [...sections, ...slashMenuConfig.customItems];
|
|
91780
|
+
}
|
|
91781
|
+
if (typeof slashMenuConfig.menuProvider === "function") {
|
|
91782
|
+
try {
|
|
91783
|
+
sections = slashMenuConfig.menuProvider(context, sections) || sections;
|
|
91784
|
+
} catch (error) {
|
|
91785
|
+
console.warn("[SlashMenu] Error in custom menuProvider:", error);
|
|
91786
|
+
}
|
|
91787
|
+
}
|
|
91788
|
+
return sections;
|
|
91789
|
+
}
|
|
91790
|
+
function filterCustomItems(sections, context) {
|
|
91791
|
+
return sections.map((section) => {
|
|
91792
|
+
const filteredItems = section.items.filter((item) => {
|
|
91793
|
+
if (typeof item.showWhen === "function") {
|
|
91794
|
+
try {
|
|
91795
|
+
return item.showWhen(context);
|
|
91796
|
+
} catch (error) {
|
|
91797
|
+
console.warn(`[SlashMenu] Error in showWhen for item ${item.id}:`, error);
|
|
91798
|
+
return false;
|
|
91799
|
+
}
|
|
91800
|
+
}
|
|
91801
|
+
return true;
|
|
91802
|
+
});
|
|
91803
|
+
return {
|
|
91804
|
+
...section,
|
|
91805
|
+
items: filteredItems
|
|
91806
|
+
};
|
|
91807
|
+
}).filter((section) => section.items.length > 0);
|
|
91808
|
+
}
|
|
91614
91809
|
function getItems(context) {
|
|
91615
91810
|
const { editor, selectedText, trigger: trigger2, clipboardContent } = context;
|
|
91811
|
+
const clipboardHasContent = Boolean(
|
|
91812
|
+
clipboardContent?.hasContent || clipboardContent?.html || clipboardContent?.text || typeof clipboardContent?.size === "number" && clipboardContent.size > 0 || clipboardContent && typeof clipboardContent?.content?.size === "number" && clipboardContent.content.size > 0 || clipboardContent?.raw && typeof clipboardContent.raw.size === "number" && clipboardContent.raw.size > 0 || clipboardContent?.raw && typeof clipboardContent.raw?.content?.size === "number" && clipboardContent.raw.content.size > 0
|
|
91813
|
+
);
|
|
91616
91814
|
const isInTable2 = selectionHasNodeOrMark(editor.view.state, "table", { requireEnds: true });
|
|
91617
91815
|
const isInSectionNode = selectionHasNodeOrMark(editor.view.state, "documentSection", { requireEnds: true });
|
|
91618
91816
|
const sections = [
|
|
@@ -91749,12 +91947,13 @@ ${style2}
|
|
|
91749
91947
|
]
|
|
91750
91948
|
}
|
|
91751
91949
|
];
|
|
91752
|
-
|
|
91950
|
+
let allSections = applyCustomMenuConfiguration(sections, context);
|
|
91951
|
+
const filteredSections = allSections.map((section) => {
|
|
91753
91952
|
const filteredItems = section.items.filter((item) => {
|
|
91754
91953
|
if (item.requiresModule && !isModuleEnabled(editor?.options, item.requiresModule)) return false;
|
|
91755
91954
|
if (item.requiresSelection && !selectedText) return false;
|
|
91756
91955
|
if (!item.allowedTriggers.includes(trigger2)) return false;
|
|
91757
|
-
if (item.requiresClipboard && !
|
|
91956
|
+
if (item.requiresClipboard && !clipboardHasContent) return false;
|
|
91758
91957
|
if (item.requiresTableParent && !isInTable2 || item.id === "insert-table" && isInTable2) return false;
|
|
91759
91958
|
if (item.requiresSectionParent && !isInSectionNode) return false;
|
|
91760
91959
|
return true;
|
|
@@ -91764,7 +91963,8 @@ ${style2}
|
|
|
91764
91963
|
items: filteredItems
|
|
91765
91964
|
};
|
|
91766
91965
|
}).filter((section) => section.items.length > 0);
|
|
91767
|
-
|
|
91966
|
+
const finalSections = filterCustomItems(filteredSections, context);
|
|
91967
|
+
return finalSections;
|
|
91768
91968
|
}
|
|
91769
91969
|
const _hoisted_1$3$1 = { class: "slash-menu-items" };
|
|
91770
91970
|
const _hoisted_2$1$1 = {
|
|
@@ -91799,6 +91999,7 @@ ${style2}
|
|
|
91799
91999
|
const menuRef = ref$1(null);
|
|
91800
92000
|
const sections = ref$1([]);
|
|
91801
92001
|
const selectedId = ref$1(null);
|
|
92002
|
+
const currentContext = ref$1(null);
|
|
91802
92003
|
const handleEditorUpdate = () => {
|
|
91803
92004
|
if (!props.editor?.isEditable && isOpen.value) {
|
|
91804
92005
|
closeMenu({ restoreCursor: false });
|
|
@@ -91844,6 +92045,44 @@ ${style2}
|
|
|
91844
92045
|
selectedId.value = newItems[0].id;
|
|
91845
92046
|
}
|
|
91846
92047
|
});
|
|
92048
|
+
const customItemRefs = /* @__PURE__ */ new Map();
|
|
92049
|
+
const setCustomItemRef = (el, item) => {
|
|
92050
|
+
if (el && item.render) {
|
|
92051
|
+
customItemRefs.set(item.id, { element: el, item });
|
|
92052
|
+
nextTick(() => {
|
|
92053
|
+
renderCustomItem(item.id);
|
|
92054
|
+
});
|
|
92055
|
+
}
|
|
92056
|
+
};
|
|
92057
|
+
const renderCustomItem = async (itemId) => {
|
|
92058
|
+
const refData = customItemRefs.get(itemId);
|
|
92059
|
+
if (!refData || refData.element.hasCustomContent) return;
|
|
92060
|
+
const { element, item } = refData;
|
|
92061
|
+
try {
|
|
92062
|
+
if (!currentContext.value) {
|
|
92063
|
+
currentContext.value = await getEditorContext(props.editor);
|
|
92064
|
+
}
|
|
92065
|
+
const context = currentContext.value;
|
|
92066
|
+
const customElement = item.render(context);
|
|
92067
|
+
if (customElement instanceof HTMLElement) {
|
|
92068
|
+
element.innerHTML = "";
|
|
92069
|
+
element.appendChild(customElement);
|
|
92070
|
+
element.hasCustomContent = true;
|
|
92071
|
+
}
|
|
92072
|
+
} catch (error) {
|
|
92073
|
+
console.warn(`[SlashMenu] Error rendering custom item ${itemId}:`, error);
|
|
92074
|
+
element.innerHTML = `<span>${item.label || "Custom Item"}</span>`;
|
|
92075
|
+
element.hasCustomContent = true;
|
|
92076
|
+
}
|
|
92077
|
+
};
|
|
92078
|
+
const cleanupCustomItems = () => {
|
|
92079
|
+
customItemRefs.forEach((refData) => {
|
|
92080
|
+
if (refData.element) {
|
|
92081
|
+
refData.element.hasCustomContent = false;
|
|
92082
|
+
}
|
|
92083
|
+
});
|
|
92084
|
+
customItemRefs.clear();
|
|
92085
|
+
};
|
|
91847
92086
|
const handleGlobalKeyDown = (event) => {
|
|
91848
92087
|
if (event.key === "Escape") {
|
|
91849
92088
|
event.preventDefault();
|
|
@@ -91894,22 +92133,23 @@ ${style2}
|
|
|
91894
92133
|
return;
|
|
91895
92134
|
}
|
|
91896
92135
|
event.preventDefault();
|
|
92136
|
+
const context = await getEditorContext(props.editor, event);
|
|
92137
|
+
currentContext.value = context;
|
|
92138
|
+
sections.value = getItems({ ...context, trigger: "click" });
|
|
92139
|
+
selectedId.value = flattenedItems.value[0]?.id || null;
|
|
92140
|
+
searchQuery.value = "";
|
|
91897
92141
|
props.editor.view.dispatch(
|
|
91898
92142
|
props.editor.view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
91899
92143
|
type: "open",
|
|
91900
|
-
pos: props.editor.view.state.selection.from,
|
|
92144
|
+
pos: context?.pos ?? props.editor.view.state.selection.from,
|
|
91901
92145
|
clientX: event.clientX,
|
|
91902
92146
|
clientY: event.clientY
|
|
91903
92147
|
})
|
|
91904
92148
|
);
|
|
91905
|
-
searchQuery.value = "";
|
|
91906
|
-
const context = await getEditorContext(props.editor, event);
|
|
91907
|
-
sections.value = getItems({ ...context, trigger: "click" });
|
|
91908
|
-
selectedId.value = flattenedItems.value[0]?.id || null;
|
|
91909
92149
|
};
|
|
91910
92150
|
const executeCommand = async (item) => {
|
|
91911
92151
|
if (props.editor) {
|
|
91912
|
-
item.action ? await item.action(props.editor) : null;
|
|
92152
|
+
item.action ? await item.action(props.editor, currentContext.value) : null;
|
|
91913
92153
|
if (item.component) {
|
|
91914
92154
|
menuRef.value;
|
|
91915
92155
|
const componentProps = getPropsByItemId(item.id, props);
|
|
@@ -91927,7 +92167,7 @@ ${style2}
|
|
|
91927
92167
|
const closeMenu = (options = { restoreCursor: true }) => {
|
|
91928
92168
|
if (props.editor?.view) {
|
|
91929
92169
|
const pluginState = SlashMenuPluginKey.getState(props.editor.view.state);
|
|
91930
|
-
const
|
|
92170
|
+
const anchorPos = pluginState?.anchorPos;
|
|
91931
92171
|
props.editor.view.dispatch(
|
|
91932
92172
|
props.editor.view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
91933
92173
|
type: "close"
|
|
@@ -91940,6 +92180,8 @@ ${style2}
|
|
|
91940
92180
|
props.editor.view.dispatch(tr);
|
|
91941
92181
|
props.editor.view.focus();
|
|
91942
92182
|
}
|
|
92183
|
+
cleanupCustomItems();
|
|
92184
|
+
currentContext.value = null;
|
|
91943
92185
|
isOpen.value = false;
|
|
91944
92186
|
searchQuery.value = "";
|
|
91945
92187
|
sections.value = [];
|
|
@@ -91956,19 +92198,29 @@ ${style2}
|
|
|
91956
92198
|
isOpen.value = true;
|
|
91957
92199
|
menuPosition.value = event.menuPosition;
|
|
91958
92200
|
searchQuery.value = "";
|
|
91959
|
-
|
|
91960
|
-
|
|
91961
|
-
|
|
92201
|
+
if (!currentContext.value) {
|
|
92202
|
+
const context = await getEditorContext(props.editor);
|
|
92203
|
+
currentContext.value = context;
|
|
92204
|
+
sections.value = getItems({ ...context, trigger: "slash" });
|
|
92205
|
+
selectedId.value = flattenedItems.value[0]?.id || null;
|
|
92206
|
+
} else if (sections.value.length === 0) {
|
|
92207
|
+
const trigger2 = currentContext.value.event?.type === "contextmenu" ? "click" : "slash";
|
|
92208
|
+
sections.value = getItems({ ...currentContext.value, trigger: trigger2 });
|
|
92209
|
+
selectedId.value = flattenedItems.value[0]?.id || null;
|
|
92210
|
+
}
|
|
91962
92211
|
});
|
|
91963
92212
|
props.editor.view.dom.addEventListener("contextmenu", handleRightClick);
|
|
91964
92213
|
props.editor.on("slashMenu:close", () => {
|
|
92214
|
+
cleanupCustomItems();
|
|
91965
92215
|
isOpen.value = false;
|
|
91966
92216
|
searchQuery.value = "";
|
|
92217
|
+
currentContext.value = null;
|
|
91967
92218
|
});
|
|
91968
92219
|
});
|
|
91969
92220
|
onBeforeUnmount(() => {
|
|
91970
92221
|
document.removeEventListener("keydown", handleGlobalKeyDown);
|
|
91971
92222
|
document.removeEventListener("mousedown", handleGlobalOutsideClick);
|
|
92223
|
+
cleanupCustomItems();
|
|
91972
92224
|
if (props.editor) {
|
|
91973
92225
|
try {
|
|
91974
92226
|
props.editor.off("slashMenu:open");
|
|
@@ -92015,12 +92267,19 @@ ${style2}
|
|
|
92015
92267
|
class: normalizeClass(["slash-menu-item", { "is-selected": item.id === selectedId.value }]),
|
|
92016
92268
|
onClick: ($event) => executeCommand(item)
|
|
92017
92269
|
}, [
|
|
92018
|
-
item.
|
|
92270
|
+
item.render ? (openBlock(), createElementBlock("div", {
|
|
92019
92271
|
key: 0,
|
|
92020
|
-
|
|
92021
|
-
|
|
92022
|
-
|
|
92023
|
-
|
|
92272
|
+
ref_for: true,
|
|
92273
|
+
ref: (el) => setCustomItemRef(el, item),
|
|
92274
|
+
class: "slash-menu-custom-item"
|
|
92275
|
+
}, null, 512)) : (openBlock(), createElementBlock(Fragment$1, { key: 1 }, [
|
|
92276
|
+
item.icon ? (openBlock(), createElementBlock("span", {
|
|
92277
|
+
key: 0,
|
|
92278
|
+
class: "slash-menu-item-icon",
|
|
92279
|
+
innerHTML: item.icon
|
|
92280
|
+
}, null, 8, _hoisted_4$5)) : createCommentVNode("", true),
|
|
92281
|
+
createBaseVNode("span", null, toDisplayString(item.label), 1)
|
|
92282
|
+
], 64))
|
|
92024
92283
|
], 10, _hoisted_3$1$1);
|
|
92025
92284
|
}), 128))
|
|
92026
92285
|
], 64);
|
|
@@ -109582,6 +109841,7 @@ ${style2}
|
|
|
109582
109841
|
annotations: proxy.$superdoc.config.annotations,
|
|
109583
109842
|
isCommentsEnabled: proxy.$superdoc.config.modules?.comments,
|
|
109584
109843
|
isAiEnabled: proxy.$superdoc.config.modules?.ai,
|
|
109844
|
+
slashMenuConfig: proxy.$superdoc.config.modules?.slashMenu,
|
|
109585
109845
|
onBeforeCreate: onEditorBeforeCreate,
|
|
109586
109846
|
onCreate: onEditorCreate,
|
|
109587
109847
|
onDestroy: onEditorDestroy,
|
|
@@ -109943,7 +110203,7 @@ ${style2}
|
|
|
109943
110203
|
};
|
|
109944
110204
|
}
|
|
109945
110205
|
};
|
|
109946
|
-
const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-
|
|
110206
|
+
const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-dbfba5b9"]]);
|
|
109947
110207
|
const createSuperdocVueApp = () => {
|
|
109948
110208
|
const app = createApp(App);
|
|
109949
110209
|
const pinia = createPinia();
|