@harbour-enterprises/superdoc 0.14.5-next.1 → 0.14.5-next.3

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.
Files changed (30) hide show
  1. package/dist/chunks/{super-editor.es-CbdU9k19.cjs → super-editor.es-CFpGpOoc.cjs} +492 -351
  2. package/dist/chunks/{super-editor.es-C6n5_0Ab.es.js → super-editor.es-CiA4uq6O.es.js} +492 -351
  3. package/dist/style.css +169 -169
  4. package/dist/super-editor/ai-writer.es.js +2 -2
  5. package/dist/super-editor/chunks/{converter-B7H3Sf5_.js → converter-CqN1dLza.js} +31 -25
  6. package/dist/super-editor/chunks/{docx-zipper-CRnln7Lc.js → docx-zipper-BFOjwdTS.js} +1 -1
  7. package/dist/super-editor/chunks/{editor-qdpgLEYR.js → editor-BgFDYm6H.js} +17 -16
  8. package/dist/super-editor/chunks/{toolbar-D_-x5OZN.js → toolbar-DVtiKzYb.js} +2 -2
  9. package/dist/super-editor/components/slash-menu/menuItems.d.ts.map +1 -1
  10. package/dist/super-editor/components/toolbar/defaultItems.d.ts.map +1 -1
  11. package/dist/super-editor/components/toolbar/super-toolbar.d.ts.map +1 -1
  12. package/dist/super-editor/converter.es.js +1 -1
  13. package/dist/super-editor/core/InputRule.d.ts +26 -0
  14. package/dist/super-editor/core/InputRule.d.ts.map +1 -1
  15. package/dist/super-editor/core/inputRules/docx-paste/docx-paste.d.ts +1 -1
  16. package/dist/super-editor/core/inputRules/docx-paste/docx-paste.d.ts.map +1 -1
  17. package/dist/super-editor/docx-zipper.es.js +2 -2
  18. package/dist/super-editor/editor.es.js +3 -3
  19. package/dist/super-editor/extensions/link/link.d.ts.map +1 -1
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/style.css +169 -169
  22. package/dist/super-editor/super-editor.es.js +411 -275
  23. package/dist/super-editor/toolbar.es.js +2 -2
  24. package/dist/super-editor.cjs +1 -1
  25. package/dist/super-editor.es.js +1 -1
  26. package/dist/superdoc.cjs +2 -2
  27. package/dist/superdoc.es.js +3 -3
  28. package/dist/superdoc.umd.js +493 -352
  29. package/dist/superdoc.umd.js.map +1 -1
  30. package/package.json +1 -1
@@ -15022,7 +15022,7 @@ class Selection {
15022
15022
  found.
15023
15023
  */
15024
15024
  static findFrom($pos, dir, textOnly = false) {
15025
- let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
15025
+ let inner = $pos.parent.inlineContent ? new TextSelection$1($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
15026
15026
  if (inner)
15027
15027
  return inner;
15028
15028
  for (let depth = $pos.depth - 1; depth >= 0; depth--) {
@@ -15091,7 +15091,7 @@ class Selection {
15091
15091
  returns the bookmark for that.
15092
15092
  */
15093
15093
  getBookmark() {
15094
- return TextSelection.between(this.$anchor, this.$head).getBookmark();
15094
+ return TextSelection$1.between(this.$anchor, this.$head).getBookmark();
15095
15095
  }
15096
15096
  }
15097
15097
  Selection.prototype.visible = true;
@@ -15111,7 +15111,7 @@ function checkTextSelection($pos) {
15111
15111
  console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
15112
15112
  }
15113
15113
  }
15114
- class TextSelection extends Selection {
15114
+ let TextSelection$1 = class TextSelection2 extends Selection {
15115
15115
  /**
15116
15116
  Construct a text selection between the given points.
15117
15117
  */
@@ -15132,7 +15132,7 @@ class TextSelection extends Selection {
15132
15132
  if (!$head.parent.inlineContent)
15133
15133
  return Selection.near($head);
15134
15134
  let $anchor = doc2.resolve(mapping.map(this.anchor));
15135
- return new TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head);
15135
+ return new TextSelection2($anchor.parent.inlineContent ? $anchor : $head, $head);
15136
15136
  }
15137
15137
  replace(tr, content = Slice.empty) {
15138
15138
  super.replace(tr, content);
@@ -15143,7 +15143,7 @@ class TextSelection extends Selection {
15143
15143
  }
15144
15144
  }
15145
15145
  eq(other) {
15146
- return other instanceof TextSelection && other.anchor == this.anchor && other.head == this.head;
15146
+ return other instanceof TextSelection2 && other.anchor == this.anchor && other.head == this.head;
15147
15147
  }
15148
15148
  getBookmark() {
15149
15149
  return new TextBookmark(this.anchor, this.head);
@@ -15157,7 +15157,7 @@ class TextSelection extends Selection {
15157
15157
  static fromJSON(doc2, json) {
15158
15158
  if (typeof json.anchor != "number" || typeof json.head != "number")
15159
15159
  throw new RangeError("Invalid input for TextSelection.fromJSON");
15160
- return new TextSelection(doc2.resolve(json.anchor), doc2.resolve(json.head));
15160
+ return new TextSelection2(doc2.resolve(json.anchor), doc2.resolve(json.head));
15161
15161
  }
15162
15162
  /**
15163
15163
  Create a text selection from non-resolved positions.
@@ -15194,10 +15194,10 @@ class TextSelection extends Selection {
15194
15194
  $anchor = $head;
15195
15195
  }
15196
15196
  }
15197
- return new TextSelection($anchor, $head);
15197
+ return new TextSelection2($anchor, $head);
15198
15198
  }
15199
- }
15200
- Selection.jsonID("text", TextSelection);
15199
+ };
15200
+ Selection.jsonID("text", TextSelection$1);
15201
15201
  class TextBookmark {
15202
15202
  constructor(anchor, head) {
15203
15203
  this.anchor = anchor;
@@ -15207,7 +15207,7 @@ class TextBookmark {
15207
15207
  return new TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
15208
15208
  }
15209
15209
  resolve(doc2) {
15210
- return TextSelection.between(doc2.resolve(this.anchor), doc2.resolve(this.head));
15210
+ return TextSelection$1.between(doc2.resolve(this.anchor), doc2.resolve(this.head));
15211
15211
  }
15212
15212
  }
15213
15213
  class NodeSelection extends Selection {
@@ -15326,7 +15326,7 @@ const AllBookmark = {
15326
15326
  };
15327
15327
  function findSelectionIn(doc2, node2, pos, index2, dir, text = false) {
15328
15328
  if (node2.inlineContent)
15329
- return TextSelection.create(doc2, pos);
15329
+ return TextSelection$1.create(doc2, pos);
15330
15330
  for (let i = index2 - (dir > 0 ? 0 : 1); dir > 0 ? i < node2.childCount : i >= 0; i += dir) {
15331
15331
  let child = node2.child(i);
15332
15332
  if (!child.isAtom) {
@@ -19044,7 +19044,7 @@ const getTextContentFromNodes = ($from, maxMatch = 500) => {
19044
19044
  };
19045
19045
  const handleDocxPaste = (html, editor, view, plugin2) => {
19046
19046
  const { converter } = editor;
19047
- if (!converter || !converter.convertedXml) return handleHtmlPaste(html, editor, view, plugin2);
19047
+ if (!converter || !converter.convertedXml) return handleHtmlPaste(html, editor);
19048
19048
  let cleanedHtml = convertEmToPt(html);
19049
19049
  cleanedHtml = cleanHtmlUnnecessaryTags(cleanedHtml);
19050
19050
  const tempDiv = document.createElement("div");
@@ -19364,29 +19364,13 @@ const inputRulesPlugin = ({ editor, rules }) => {
19364
19364
  const clipboard = event.clipboardData;
19365
19365
  const html = clipboard.getData("text/html");
19366
19366
  clipboard.getData("text/plain");
19367
- const fieldAnnotationContent = slice2.content.content.filter((item) => item.type.name === "fieldAnnotation");
19367
+ const fieldAnnotationContent = slice2.content.content.filter(
19368
+ (item) => item.type.name === "fieldAnnotation"
19369
+ );
19368
19370
  if (fieldAnnotationContent.length) {
19369
19371
  return false;
19370
19372
  }
19371
- let source;
19372
- if (!html) {
19373
- source = "plain-text";
19374
- } else if (isWordHtml(html)) {
19375
- source = "word-html";
19376
- } else {
19377
- source = "browser-html";
19378
- }
19379
- switch (source) {
19380
- case "plain-text":
19381
- break;
19382
- case "word-html":
19383
- if (editor.options.mode === "docx") {
19384
- return handleDocxPaste(html, editor, view, plugin2);
19385
- }
19386
- case "browser-html":
19387
- return handleHtmlPaste$1(html, editor);
19388
- }
19389
- return false;
19373
+ return handleClipboardPaste({ editor, view }, html);
19390
19374
  }
19391
19375
  },
19392
19376
  isInputRules: true
@@ -19396,7 +19380,7 @@ const inputRulesPlugin = ({ editor, rules }) => {
19396
19380
  function isWordHtml(html) {
19397
19381
  return /class=["']?Mso|xmlns:o=["']?urn:schemas-microsoft-com|<!--\[if gte mso|<meta[^>]+name=["']?Generator["']?[^>]+Word/i.test(html);
19398
19382
  }
19399
- const handleHtmlPaste$1 = (html, editor) => {
19383
+ function handleHtmlPaste(html, editor) {
19400
19384
  const htmlWithPtSizing = convertEmToPt(html);
19401
19385
  const cleanedHtml = sanitizeHtml(htmlWithPtSizing);
19402
19386
  const doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
@@ -19413,7 +19397,7 @@ const handleHtmlPaste$1 = (html, editor) => {
19413
19397
  dispatch(state2.tr.replaceSelectionWith(doc2, true));
19414
19398
  }
19415
19399
  return true;
19416
- };
19400
+ }
19417
19401
  const convertEmToPt = (html) => {
19418
19402
  return html.replace(
19419
19403
  /font-size\s*:\s*([\d.]+)em/gi,
@@ -19445,6 +19429,27 @@ function sanitizeHtml(html, forbiddenTags = ["meta", "svg", "script", "style", "
19445
19429
  walkAndClean(container);
19446
19430
  return container;
19447
19431
  }
19432
+ function handleClipboardPaste({ editor, view }, html, text) {
19433
+ let source;
19434
+ if (!html) {
19435
+ source = "plain-text";
19436
+ } else if (isWordHtml(html)) {
19437
+ source = "word-html";
19438
+ } else {
19439
+ source = "browser-html";
19440
+ }
19441
+ switch (source) {
19442
+ case "plain-text":
19443
+ return false;
19444
+ case "word-html":
19445
+ if (editor.options.mode === "docx") {
19446
+ return handleDocxPaste(html, editor, view);
19447
+ }
19448
+ case "browser-html":
19449
+ return handleHtmlPaste(html, editor);
19450
+ }
19451
+ return false;
19452
+ }
19448
19453
  function exportSchemaToJson(params2) {
19449
19454
  const { type: type2 } = params2.node || {};
19450
19455
  const router = {
@@ -24326,7 +24331,7 @@ const _SuperConverter = class _SuperConverter2 {
24326
24331
  return;
24327
24332
  }
24328
24333
  }
24329
- static updateDocumentVersion(docx = this.convertedXml, version2 = "0.14.5-next.1") {
24334
+ static updateDocumentVersion(docx = this.convertedXml, version2 = "0.14.5-next.3") {
24330
24335
  const customLocation = "docProps/custom.xml";
24331
24336
  if (!docx[customLocation]) {
24332
24337
  docx[customLocation] = generateCustomXml();
@@ -24802,7 +24807,7 @@ function storeSuperdocVersion(docx) {
24802
24807
  function generateCustomXml() {
24803
24808
  return DEFAULT_CUSTOM_XML;
24804
24809
  }
24805
- function generateSuperdocVersion(pid = 2, version2 = "0.14.5-next.1") {
24810
+ function generateSuperdocVersion(pid = 2, version2 = "0.14.5-next.3") {
24806
24811
  return {
24807
24812
  type: "element",
24808
24813
  name: "property",
@@ -28540,7 +28545,7 @@ const insertTabCharacter = ({ tr, state: state2, dispatch }) => {
28540
28545
  const { from: from2 } = tr.selection;
28541
28546
  const tabText = state2.schema.text(" ");
28542
28547
  tr = tr.replaceSelectionWith(tabText);
28543
- tr = tr.setSelection(TextSelection.create(tr.doc, from2 + 1));
28548
+ tr = tr.setSelection(TextSelection$1.create(tr.doc, from2 + 1));
28544
28549
  if (dispatch) dispatch(tr);
28545
28550
  return true;
28546
28551
  };
@@ -28777,7 +28782,7 @@ const createParagraphNear$1 = (state2, dispatch) => {
28777
28782
  if (dispatch) {
28778
28783
  let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos;
28779
28784
  let tr = state2.tr.insert(side, type2.createAndFill());
28780
- tr.setSelection(TextSelection.create(tr.doc, side + 1));
28785
+ tr.setSelection(TextSelection$1.create(tr.doc, side + 1));
28781
28786
  dispatch(tr.scrollIntoView());
28782
28787
  }
28783
28788
  return true;
@@ -28831,7 +28836,7 @@ function splitBlockAs(splitNode) {
28831
28836
  }
28832
28837
  }
28833
28838
  let tr = state2.tr;
28834
- if (state2.selection instanceof TextSelection || state2.selection instanceof AllSelection)
28839
+ if (state2.selection instanceof TextSelection$1 || state2.selection instanceof AllSelection)
28835
28840
  tr.deleteSelection();
28836
28841
  let splitPos = tr.mapping.map($from.pos);
28837
28842
  let can = canSplit(tr.doc, splitPos, types2.length, types2);
@@ -28936,7 +28941,7 @@ function selectTextblockSide(side) {
28936
28941
  if (!$pos.node(depth).isTextblock)
28937
28942
  return false;
28938
28943
  if (dispatch)
28939
- dispatch(state2.tr.setSelection(TextSelection.create(state2.doc, side < 0 ? $pos.start(depth) : $pos.end(depth))));
28944
+ dispatch(state2.tr.setSelection(TextSelection$1.create(state2.doc, side < 0 ? $pos.start(depth) : $pos.end(depth))));
28940
28945
  return true;
28941
28946
  };
28942
28947
  }
@@ -29018,7 +29023,7 @@ const splitBlock = ({ keepMarks = true } = {}) => (props) => {
29018
29023
  if (!$from.parent.isBlock) return false;
29019
29024
  if (dispatch) {
29020
29025
  const atEnd = $to.parentOffset === $to.parent.content.size;
29021
- if (selection instanceof TextSelection) tr.deleteSelection();
29026
+ if (selection instanceof TextSelection$1) tr.deleteSelection();
29022
29027
  const deflt = $from.depth === 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
29023
29028
  let types2 = atEnd && deflt ? [{ type: deflt, attrs: newAttrs }] : void 0;
29024
29029
  let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types2);
@@ -29369,7 +29374,7 @@ const handleBackspaceNextToList = () => ({ state: state2, dispatch }) => {
29369
29374
  tr.delete(oldParaPos, oldParaPos + $from.parent.nodeSize);
29370
29375
  const insertPos = paraStartPos + 1 + targetPara.content.size;
29371
29376
  tr.insert(insertPos, inlineContent);
29372
- tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos), 1));
29377
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(insertPos), 1));
29373
29378
  dispatch(tr);
29374
29379
  return true;
29375
29380
  };
@@ -29413,7 +29418,7 @@ const handleDeleteNextToList = () => ({ state: state2, dispatch }) => {
29413
29418
  tr.delete(nextListStartPos, nextListStartPos + nextNode.nodeSize);
29414
29419
  const insertPos = tr.mapping.map($from.pos);
29415
29420
  tr.insert(insertPos, targetInlineContent);
29416
- tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos), 1));
29421
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(insertPos), 1));
29417
29422
  dispatch(tr);
29418
29423
  return true;
29419
29424
  } else {
@@ -29436,7 +29441,7 @@ const handleDeleteNextToList = () => ({ state: state2, dispatch }) => {
29436
29441
  tr.delete(listStartPos, listStartPos + afterNode.nodeSize);
29437
29442
  const insertPos = tr.mapping.map($from.pos);
29438
29443
  tr.insert(insertPos, targetInlineContent);
29439
- tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos), 1));
29444
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(insertPos), 1));
29440
29445
  dispatch(tr);
29441
29446
  return true;
29442
29447
  }
@@ -31379,10 +31384,10 @@ const getParentOrderedList = (state2) => {
31379
31384
  const setSelectionInsideNewList = (tr, basePos) => {
31380
31385
  try {
31381
31386
  const $pos = tr.doc.resolve(basePos + 3);
31382
- tr.setSelection(TextSelection.near($pos));
31387
+ tr.setSelection(TextSelection$1.near($pos));
31383
31388
  } catch {
31384
31389
  const $fallback = tr.doc.resolve(basePos + 1);
31385
- tr.setSelection(TextSelection.near($fallback));
31390
+ tr.setSelection(TextSelection$1.near($fallback));
31386
31391
  }
31387
31392
  };
31388
31393
  const replaceListWithNode = ({ tr, from: from2, to, newNode }) => {
@@ -31399,7 +31404,7 @@ const convertListItemToParagraph = ({ state: state2, tr, currentNode, replaceFro
31399
31404
  replaceListWithNode({ tr, from: replaceFrom, to: replaceTo, newNode: paragraphNode });
31400
31405
  const newPos = replaceFrom + 1;
31401
31406
  const $pos = tr.doc.resolve(newPos);
31402
- tr.setSelection(TextSelection.near($pos));
31407
+ tr.setSelection(TextSelection$1.near($pos));
31403
31408
  return true;
31404
31409
  };
31405
31410
  const insertNewList = (tr, replaceFrom, replaceTo, listNode, marks = []) => {
@@ -31410,7 +31415,7 @@ const insertNewList = (tr, replaceFrom, replaceTo, listNode, marks = []) => {
31410
31415
  const paragraphNode = $paragraphStart.parent;
31411
31416
  const endPos = $paragraphStart.pos + paragraphNode.content.size;
31412
31417
  const $endPos = tr.doc.resolve(endPos);
31413
- tr.setSelection(TextSelection.near($endPos));
31418
+ tr.setSelection(TextSelection$1.near($endPos));
31414
31419
  return true;
31415
31420
  };
31416
31421
  const getListItemStyleDefinitions = ({ styleId, node: node2, numId, level, editor, tries }) => {
@@ -31608,7 +31613,7 @@ const splitListItem = () => (props) => {
31608
31613
  const insertPosition = listStart + firstList.nodeSize;
31609
31614
  tr.insert(insertPosition, secondList);
31610
31615
  const secondListStart = insertPosition + 2;
31611
- tr.setSelection(TextSelection.near(tr.doc.resolve(secondListStart)));
31616
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(secondListStart)));
31612
31617
  tr.scrollIntoView();
31613
31618
  const marks = state2.storedMarks || $from.marks() || [];
31614
31619
  if (marks?.length) {
@@ -31643,7 +31648,7 @@ const handleSplitInEmptyBlock = (props, currentListItem) => {
31643
31648
  const insertPos = parentList.pos + parentList.node.nodeSize;
31644
31649
  tr.insert(insertPos, newList);
31645
31650
  const newPos = insertPos + 2;
31646
- tr.setSelection(TextSelection.near(tr.doc.resolve(newPos)));
31651
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(newPos)));
31647
31652
  tr.scrollIntoView();
31648
31653
  return true;
31649
31654
  } catch (error) {
@@ -31692,7 +31697,7 @@ const handleSplitInEmptyBlock = (props, currentListItem) => {
31692
31697
  const listEnd = parentList.pos + parentList.node.nodeSize;
31693
31698
  tr.replaceWith(listStart, listEnd, newParagraph);
31694
31699
  const newPos = listStart + 1;
31695
- tr.setSelection(TextSelection.near(tr.doc.resolve(newPos)));
31700
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve(newPos)));
31696
31701
  tr.scrollIntoView();
31697
31702
  return true;
31698
31703
  } catch (error) {
@@ -31727,7 +31732,7 @@ const deleteListItem = () => (props) => {
31727
31732
  tr.delete(pos, pos + size2);
31728
31733
  });
31729
31734
  const $new = tr.doc.resolve(from2);
31730
- tr.setSelection(TextSelection.near($new));
31735
+ tr.setSelection(TextSelection$1.near($new));
31731
31736
  return true;
31732
31737
  }
31733
31738
  return false;
@@ -31755,7 +31760,7 @@ const deleteListItem = () => (props) => {
31755
31760
  });
31756
31761
  tr.replaceWith(listFrom, listTo, nodes);
31757
31762
  const $pos = tr.doc.resolve(listFrom + 1);
31758
- tr.setSelection(TextSelection.near($pos));
31763
+ tr.setSelection(TextSelection$1.near($pos));
31759
31764
  return true;
31760
31765
  };
31761
31766
  const increaseListIndent = () => ({ editor, tr }) => {
@@ -33192,7 +33197,7 @@ class NodeViewDesc extends ViewDesc {
33192
33197
  }
33193
33198
  localCompositionInfo(view, pos) {
33194
33199
  let { from: from2, to } = view.state.selection;
33195
- if (!(view.state.selection instanceof TextSelection) || from2 < pos || to > pos + this.node.content.size)
33200
+ if (!(view.state.selection instanceof TextSelection$1) || from2 < pos || to > pos + this.node.content.size)
33196
33201
  return null;
33197
33202
  let textNode = view.input.compositionNode;
33198
33203
  if (!textNode || !this.dom.contains(textNode.parentNode))
@@ -33958,7 +33963,7 @@ function selectionToDOM(view, force = false) {
33958
33963
  selectCursorWrapper(view);
33959
33964
  } else {
33960
33965
  let { anchor, head } = sel, resetEditableFrom, resetEditableTo;
33961
- if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {
33966
+ if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection$1)) {
33962
33967
  if (!sel.$from.parent.inlineContent)
33963
33968
  resetEditableFrom = temporarilyEditableNear(view, sel.from);
33964
33969
  if (!sel.empty && !sel.$from.parent.inlineContent)
@@ -34064,7 +34069,7 @@ function clearNodeSelection(view) {
34064
34069
  }
34065
34070
  }
34066
34071
  function selectionBetween(view, $anchor, $head, bias) {
34067
- return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias);
34072
+ return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection$1.between($anchor, $head, bias);
34068
34073
  }
34069
34074
  function hasFocusAndSelection(view) {
34070
34075
  if (view.editable && !view.hasFocus())
@@ -34098,13 +34103,13 @@ function apply$1(view, sel) {
34098
34103
  }
34099
34104
  function selectHorizontally(view, dir, mods) {
34100
34105
  let sel = view.state.selection;
34101
- if (sel instanceof TextSelection) {
34106
+ if (sel instanceof TextSelection$1) {
34102
34107
  if (mods.indexOf("s") > -1) {
34103
34108
  let { $head } = sel, node2 = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter;
34104
34109
  if (!node2 || node2.isText || !node2.isLeaf)
34105
34110
  return false;
34106
34111
  let $newHead = view.state.doc.resolve($head.pos + node2.nodeSize * (dir < 0 ? -1 : 1));
34107
- return apply$1(view, new TextSelection(sel.$anchor, $newHead));
34112
+ return apply$1(view, new TextSelection$1(sel.$anchor, $newHead));
34108
34113
  } else if (!sel.empty) {
34109
34114
  return false;
34110
34115
  } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
@@ -34122,13 +34127,13 @@ function selectHorizontally(view, dir, mods) {
34122
34127
  if (NodeSelection.isSelectable(node2)) {
34123
34128
  return apply$1(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node2.nodeSize) : $head));
34124
34129
  } else if (webkit) {
34125
- return apply$1(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node2.nodeSize)));
34130
+ return apply$1(view, new TextSelection$1(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node2.nodeSize)));
34126
34131
  } else {
34127
34132
  return false;
34128
34133
  }
34129
34134
  }
34130
34135
  } else if (sel instanceof NodeSelection && sel.node.isInline) {
34131
- return apply$1(view, new TextSelection(dir > 0 ? sel.$to : sel.$from));
34136
+ return apply$1(view, new TextSelection$1(dir > 0 ? sel.$to : sel.$from));
34132
34137
  } else {
34133
34138
  let next = moveSelectionBlock(view.state, dir);
34134
34139
  if (next)
@@ -34321,7 +34326,7 @@ function findDirection(view, pos) {
34321
34326
  }
34322
34327
  function selectVertically(view, dir, mods) {
34323
34328
  let sel = view.state.selection;
34324
- if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1)
34329
+ if (sel instanceof TextSelection$1 && !sel.empty || mods.indexOf("s") > -1)
34325
34330
  return false;
34326
34331
  if (mac$2 && mods.indexOf("m") > -1)
34327
34332
  return false;
@@ -34339,7 +34344,7 @@ function selectVertically(view, dir, mods) {
34339
34344
  return false;
34340
34345
  }
34341
34346
  function stopNativeHorizontalDelete(view, dir) {
34342
- if (!(view.state.selection instanceof TextSelection))
34347
+ if (!(view.state.selection instanceof TextSelection$1))
34343
34348
  return true;
34344
34349
  let { $head, $anchor, empty: empty2 } = view.state.selection;
34345
34350
  if (!$head.sameParent($anchor))
@@ -34769,7 +34774,7 @@ editHandlers.keypress = (view, _event) => {
34769
34774
  return;
34770
34775
  }
34771
34776
  let sel = view.state.selection;
34772
- if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {
34777
+ if (!(sel instanceof TextSelection$1) || !sel.$from.sameParent(sel.$to)) {
34773
34778
  let text = String.fromCharCode(event.charCode);
34774
34779
  let deflt = () => view.state.tr.insertText(text).scrollIntoView();
34775
34780
  if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", (f) => f(view, sel.$from.pos, sel.$to.pos, text, deflt)))
@@ -34852,7 +34857,7 @@ function defaultTripleClick(view, inside, event) {
34852
34857
  let doc2 = view.state.doc;
34853
34858
  if (inside == -1) {
34854
34859
  if (doc2.inlineContent) {
34855
- updateSelection(view, TextSelection.create(doc2, 0, doc2.content.size));
34860
+ updateSelection(view, TextSelection$1.create(doc2, 0, doc2.content.size));
34856
34861
  return true;
34857
34862
  }
34858
34863
  return false;
@@ -34862,7 +34867,7 @@ function defaultTripleClick(view, inside, event) {
34862
34867
  let node2 = i > $pos.depth ? $pos.nodeAfter : $pos.node(i);
34863
34868
  let nodePos = $pos.before(i);
34864
34869
  if (node2.inlineContent)
34865
- updateSelection(view, TextSelection.create(doc2, nodePos + 1, nodePos + 1 + node2.content.size));
34870
+ updateSelection(view, TextSelection$1.create(doc2, nodePos + 1, nodePos + 1 + node2.content.size));
34866
34871
  else if (NodeSelection.isSelectable(node2))
34867
34872
  updateSelection(view, NodeSelection.create(doc2, nodePos));
34868
34873
  else
@@ -35022,7 +35027,7 @@ editHandlers.compositionstart = editHandlers.compositionupdate = (view) => {
35022
35027
  if (!view.composing) {
35023
35028
  view.domObserver.flush();
35024
35029
  let { state: state2 } = view, $pos = state2.selection.$to;
35025
- if (state2.selection instanceof TextSelection && (state2.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m) => m.type.spec.inclusive === false))) {
35030
+ if (state2.selection instanceof TextSelection$1 && (state2.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m) => m.type.spec.inclusive === false))) {
35026
35031
  view.markCursor = view.state.storedMarks || $pos.marks();
35027
35032
  endComposition(view, true);
35028
35033
  view.markCursor = null;
@@ -36380,7 +36385,7 @@ function readDOMChange(view, from2, to, typeOver, addedNodes) {
36380
36385
  return;
36381
36386
  }
36382
36387
  if (!change) {
36383
- if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse2.sel && parse2.sel.anchor != parse2.sel.head)) {
36388
+ if (typeOver && sel instanceof TextSelection$1 && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse2.sel && parse2.sel.anchor != parse2.sel.head)) {
36384
36389
  change = { start: sel.from, endA: sel.to, endB: sel.to };
36385
36390
  } else {
36386
36391
  if (parse2.sel) {
@@ -36395,7 +36400,7 @@ function readDOMChange(view, from2, to, typeOver, addedNodes) {
36395
36400
  return;
36396
36401
  }
36397
36402
  }
36398
- if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) {
36403
+ if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection$1) {
36399
36404
  if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse2.from) {
36400
36405
  change.start = view.state.selection.from;
36401
36406
  } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse2.to) {
@@ -37823,7 +37828,7 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
37823
37828
  binding.mapping
37824
37829
  );
37825
37830
  if (anchor !== null && head !== null) {
37826
- const sel = TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head));
37831
+ const sel = TextSelection$1.between(tr.doc.resolve(anchor), tr.doc.resolve(head));
37827
37832
  tr.setSelection(sel);
37828
37833
  }
37829
37834
  }
@@ -37958,7 +37963,7 @@ class ProsemirrorBinding {
37958
37963
  if (sel) {
37959
37964
  const clampedAnchor = min$2(max$2(sel.anchor, 0), tr.doc.content.size);
37960
37965
  const clampedHead = min$2(max$2(sel.head, 0), tr.doc.content.size);
37961
- tr.setSelection(TextSelection.create(tr.doc, clampedAnchor, clampedHead));
37966
+ tr.setSelection(TextSelection$1.create(tr.doc, clampedAnchor, clampedHead));
37962
37967
  }
37963
37968
  this.prosemirrorView.dispatch(
37964
37969
  tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this })
@@ -40919,18 +40924,18 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
40919
40924
  if (tr.selectionSet) {
40920
40925
  const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName];
40921
40926
  const deletionMark = findMark(state2, deletionMarkSchema, false);
40922
- if (tr.selection instanceof TextSelection && (tr.selection.from < state2.selection.from || tr.getMeta("inputType") === "deleteContentBackward")) {
40927
+ if (tr.selection instanceof TextSelection$1 && (tr.selection.from < state2.selection.from || tr.getMeta("inputType") === "deleteContentBackward")) {
40923
40928
  const caretPos = map22.map(tr.selection.from, -1);
40924
- newTr.setSelection(new TextSelection(newTr.doc.resolve(caretPos)));
40929
+ newTr.setSelection(new TextSelection$1(newTr.doc.resolve(caretPos)));
40925
40930
  } else if (tr.selection.from > state2.selection.from && deletionMark) {
40926
40931
  const caretPos = map22.map(deletionMark.to + 1, 1);
40927
- newTr.setSelection(new TextSelection(newTr.doc.resolve(caretPos)));
40932
+ newTr.setSelection(new TextSelection$1(newTr.doc.resolve(caretPos)));
40928
40933
  } else {
40929
40934
  newTr.setSelection(tr.selection.map(newTr.doc, map22));
40930
40935
  }
40931
40936
  } else if (state2.selection.from - tr.selection.from > 1 && tr.selection.$head.depth > 1) {
40932
40937
  const caretPos = map22.map(tr.selection.from - 2, -1);
40933
- newTr.setSelection(new TextSelection(newTr.doc.resolve(caretPos)));
40938
+ newTr.setSelection(new TextSelection$1(newTr.doc.resolve(caretPos)));
40934
40939
  } else ;
40935
40940
  if (tr.storedMarksSet) {
40936
40941
  newTr.setStoredMarks(tr.storedMarks);
@@ -41507,7 +41512,7 @@ const findWordBounds = (doc2, pos) => {
41507
41512
  const setWordSelection = (view, pos) => {
41508
41513
  const { state: state2, dispatch } = view;
41509
41514
  const word = findWordBounds(state2.doc, pos);
41510
- const tr = state2.tr.setSelection(TextSelection.create(state2.doc, word.from, word.to));
41515
+ const tr = state2.tr.setSelection(TextSelection$1.create(state2.doc, word.from, word.to));
41511
41516
  dispatch(tr);
41512
41517
  };
41513
41518
  const setImageNodeSelection = (view, pos) => {
@@ -42396,7 +42401,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
42396
42401
  * @returns {Object | void} Migration results
42397
42402
  */
42398
42403
  processCollaborationMigrations() {
42399
- console.debug("[checkVersionMigrations] Current editor version", "0.14.5-next.1");
42404
+ console.debug("[checkVersionMigrations] Current editor version", "0.14.5-next.3");
42400
42405
  if (!this.options.ydoc) return;
42401
42406
  const metaMap = this.options.ydoc.getMap("meta");
42402
42407
  let docVersion = metaMap.get("version");
@@ -43594,7 +43599,7 @@ function arrow$3(axis, dir) {
43594
43599
  return function(state2, dispatch, view) {
43595
43600
  let sel = state2.selection;
43596
43601
  let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
43597
- if (sel instanceof TextSelection) {
43602
+ if (sel instanceof TextSelection$1) {
43598
43603
  if (!view.endOfTextblock(dirStr) || $start.depth == 0)
43599
43604
  return false;
43600
43605
  mustMove = false;
@@ -43631,7 +43636,7 @@ function beforeinput(view, event) {
43631
43636
  for (let i = insert.length - 1; i >= 0; i--)
43632
43637
  frag = Fragment.from(insert[i].createAndFill(null, frag));
43633
43638
  let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
43634
- tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
43639
+ tr.setSelection(TextSelection$1.near(tr.doc.resolve($from.pos + 1)));
43635
43640
  view.dispatch(tr);
43636
43641
  return false;
43637
43642
  }
@@ -46108,7 +46113,7 @@ var CellSelection = class _CellSelection extends Selection {
46108
46113
  return _CellSelection.colSelection($anchorCell, $headCell);
46109
46114
  else return new _CellSelection($anchorCell, $headCell);
46110
46115
  }
46111
- return TextSelection.between($anchorCell, $headCell);
46116
+ return TextSelection$1.between($anchorCell, $headCell);
46112
46117
  }
46113
46118
  // Returns a rectangular slice of table rows containing the selected
46114
46119
  // cells.
@@ -46380,10 +46385,10 @@ function normalizeSelection(state2, tr, allowTableNodeSelection) {
46380
46385
  const lastCell = start2 + map22.map[map22.width * map22.height - 1];
46381
46386
  normalize22 = CellSelection.create(doc2, start2 + 1, lastCell);
46382
46387
  }
46383
- } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) {
46384
- normalize22 = TextSelection.create(doc2, sel.from);
46385
- } else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) {
46386
- normalize22 = TextSelection.create(doc2, sel.$from.start(), sel.$from.end());
46388
+ } else if (sel instanceof TextSelection$1 && isCellBoundarySelection(sel)) {
46389
+ normalize22 = TextSelection$1.create(doc2, sel.from);
46390
+ } else if (sel instanceof TextSelection$1 && isTextSelectionAcrossCells(sel)) {
46391
+ normalize22 = TextSelection$1.create(doc2, sel.$from.start(), sel.$from.end());
46387
46392
  }
46388
46393
  if (normalize22) (tr || (tr = state2.tr)).setSelection(normalize22);
46389
46394
  return tr;
@@ -46979,7 +46984,7 @@ function goToNextCell(direction) {
46979
46984
  if (dispatch) {
46980
46985
  const $cell = state2.doc.resolve(cell);
46981
46986
  dispatch(
46982
- state2.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView()
46987
+ state2.tr.setSelection(TextSelection$1.between($cell, moveCellForward($cell))).scrollIntoView()
46983
46988
  );
46984
46989
  }
46985
46990
  return true;
@@ -47432,7 +47437,7 @@ function handleMouseDown(view, startEvent) {
47432
47437
  view.root.addEventListener("mousemove", move2);
47433
47438
  }
47434
47439
  function atEndOfCell(view, axis, dir) {
47435
- if (!(view.state.selection instanceof TextSelection)) return null;
47440
+ if (!(view.state.selection instanceof TextSelection$1)) return null;
47436
47441
  const { $head } = view.state.selection;
47437
47442
  for (let d = $head.depth - 1; d >= 0; d--) {
47438
47443
  const parent = $head.node(d), index2 = dir < 0 ? $head.index(d) : $head.indexAfter(d);
@@ -47999,7 +48004,7 @@ const Table = Node$1.create({
47999
48004
  const node2 = createTable(editor.schema, rows, cols, withHeaderRow);
48000
48005
  if (dispatch) {
48001
48006
  const offset2 = tr.selection.from + 1;
48002
- tr.replaceSelectionWith(node2).scrollIntoView().setSelection(TextSelection.near(tr.doc.resolve(offset2)));
48007
+ tr.replaceSelectionWith(node2).scrollIntoView().setSelection(TextSelection$1.near(tr.doc.resolve(offset2)));
48003
48008
  }
48004
48009
  return true;
48005
48010
  },
@@ -51325,7 +51330,7 @@ const Link = Mark2.create({
51325
51330
  return chain().setMark("underline").setMark(this.name, { href }).run();
51326
51331
  },
51327
51332
  unsetLink: () => ({ chain }) => {
51328
- return chain().unsetMark("underline").unsetColor().unsetMark(this.name, { extendEmptyMarkRange: true }).run();
51333
+ return chain().unsetMark("underline", { extendEmptyMarkRange: true }).unsetColor().unsetMark("link", { extendEmptyMarkRange: true }).run();
51329
51334
  },
51330
51335
  toggleLink: ({ href }) => ({ commands: commands2 }) => {
51331
51336
  if (!href) return commands2.unsetLink();
@@ -56791,7 +56796,7 @@ const Search = Extension.create({
56791
56796
  goToSearchResult: (match) => ({ state: state2, dispatch, editor }) => {
56792
56797
  const { from: from2, to } = match;
56793
56798
  editor.view.focus();
56794
- const tr = state2.tr.setSelection(TextSelection.create(state2.doc, from2, to)).scrollIntoView();
56799
+ const tr = state2.tr.setSelection(TextSelection$1.create(state2.doc, from2, to)).scrollIntoView();
56795
56800
  dispatch(tr);
56796
56801
  const { node: node2 } = editor.view.domAtPos(from2);
56797
56802
  if (node2?.scrollIntoView) {
@@ -67612,7 +67617,7 @@ const _sfc_main$f = {
67612
67617
  const { state: state2 } = props.editor;
67613
67618
  const { from: from2, to } = selectionState.value;
67614
67619
  const tr = state2.tr.setSelection(
67615
- TextSelection.create(state2.doc, from2, to)
67620
+ TextSelection$1.create(state2.doc, from2, to)
67616
67621
  );
67617
67622
  props.editor.view.dispatch(tr);
67618
67623
  } else {
@@ -67844,7 +67849,7 @@ var eventemitter3 = { exports: {} };
67844
67849
  var evt = prefix2 ? prefix2 + event : event, handlers2 = this._events[evt];
67845
67850
  if (!handlers2) return [];
67846
67851
  if (handlers2.fn) return [handlers2.fn];
67847
- for (var i = 0, l2 = handlers2.length, ee = new Array(l2); i < l2; i++) {
67852
+ for (var i = 0, l = handlers2.length, ee = new Array(l); i < l; i++) {
67848
67853
  ee[i] = handlers2[i].fn;
67849
67854
  }
67850
67855
  return ee;
@@ -68345,11 +68350,238 @@ const _sfc_main$c = {
68345
68350
  }
68346
68351
  };
68347
68352
  const LinkedStyle = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-2cf079a2"]]);
68348
- const _hoisted_1$9 = ["aria-label", "onClick", "onKeydown"];
68349
- const _hoisted_2$7 = ["innerHTML"];
68350
- const _hoisted_3$6 = ["innerHTML"];
68351
- const ROW_SIZE$1 = 7;
68353
+ const _hoisted_1$9 = {
68354
+ key: 0,
68355
+ class: "link-title"
68356
+ };
68357
+ const _hoisted_2$7 = {
68358
+ key: 1,
68359
+ class: "link-title"
68360
+ };
68361
+ const _hoisted_3$6 = {
68362
+ key: 2,
68363
+ class: "link-title"
68364
+ };
68365
+ const _hoisted_4$2 = { key: 3 };
68366
+ const _hoisted_5$1 = { class: "input-row" };
68367
+ const _hoisted_6 = ["innerHTML"];
68368
+ const _hoisted_7 = ["onKeydown"];
68369
+ const _hoisted_8 = ["innerHTML"];
68370
+ const _hoisted_9 = { class: "input-row link-buttons" };
68371
+ const _hoisted_10 = ["innerHTML"];
68372
+ const _hoisted_11 = {
68373
+ key: 4,
68374
+ class: "input-row go-to-anchor clickable"
68375
+ };
68352
68376
  const _sfc_main$b = {
68377
+ __name: "LinkInput",
68378
+ props: {
68379
+ showInput: {
68380
+ type: Boolean,
68381
+ default: true
68382
+ },
68383
+ showLink: {
68384
+ type: Boolean,
68385
+ default: true
68386
+ },
68387
+ goToAnchor: {
68388
+ type: Function,
68389
+ default: () => {
68390
+ }
68391
+ },
68392
+ editor: {
68393
+ type: Object,
68394
+ required: true
68395
+ },
68396
+ closePopover: {
68397
+ type: Function,
68398
+ default: () => {
68399
+ }
68400
+ }
68401
+ },
68402
+ setup(__props) {
68403
+ const props = __props;
68404
+ const { isHighContrastMode: isHighContrastMode2 } = useHighContrastMode();
68405
+ const urlError = ref$1(false);
68406
+ const getSelectedText = () => {
68407
+ if (!props.editor || !props.editor.state) return "";
68408
+ const { state: state2 } = props.editor;
68409
+ const { from: from2, to } = state2.selection;
68410
+ return state2.doc.textBetween(from2, to, " ");
68411
+ };
68412
+ const getLinkHrefAtSelection = () => {
68413
+ if (!props.editor || !props.editor.state) return "";
68414
+ const { state: state2 } = props.editor;
68415
+ const { schema, selection } = state2;
68416
+ const linkMark = schema.marks.link;
68417
+ if (!linkMark) return "";
68418
+ let href = "";
68419
+ const { $from, empty: empty2 } = selection;
68420
+ if (empty2) {
68421
+ const marks = state2.storedMarks || $from.marks();
68422
+ const link = marks.find((mark) => mark.type === linkMark);
68423
+ if (link) href = link.attrs.href;
68424
+ } else {
68425
+ state2.doc.nodesBetween(selection.from, selection.to, (node2) => {
68426
+ if (node2.marks) {
68427
+ const link = node2.marks.find((mark) => mark.type === linkMark);
68428
+ if (link) href = link.attrs.href;
68429
+ }
68430
+ });
68431
+ }
68432
+ return href || "";
68433
+ };
68434
+ const text = ref$1("");
68435
+ const rawUrl = ref$1("");
68436
+ const isAnchor = ref$1(false);
68437
+ const url = computed(() => {
68438
+ if (!rawUrl.value?.startsWith("http")) return "http://" + rawUrl.value;
68439
+ return rawUrl.value;
68440
+ });
68441
+ const validUrl = computed(() => {
68442
+ const urlSplit = url.value.split(".").filter(Boolean);
68443
+ return url.value.includes(".") && urlSplit.length > 1;
68444
+ });
68445
+ const isEditing = computed(() => !isAnchor.value && !!getLinkHrefAtSelection());
68446
+ const getApplyText = computed(() => showApply.value ? "Apply" : "Remove");
68447
+ const isDisabled2 = computed(() => !validUrl.value);
68448
+ const showApply = computed(() => !showRemove.value);
68449
+ const showRemove = computed(() => rawUrl.value === "" && getLinkHrefAtSelection());
68450
+ const openLink = () => {
68451
+ window.open(url.value, "_blank");
68452
+ };
68453
+ const updateFromEditor = () => {
68454
+ text.value = getSelectedText();
68455
+ rawUrl.value = getLinkHrefAtSelection();
68456
+ };
68457
+ watch(
68458
+ () => props.editor?.state?.selection,
68459
+ () => {
68460
+ updateFromEditor();
68461
+ },
68462
+ { immediate: true }
68463
+ );
68464
+ const focusInput = () => {
68465
+ const input = document.querySelector(".link-input-ctn input");
68466
+ if (!input) return;
68467
+ input.focus();
68468
+ };
68469
+ onMounted(() => {
68470
+ updateFromEditor();
68471
+ isAnchor.value = rawUrl.value.startsWith("#");
68472
+ if (props.showInput) focusInput();
68473
+ });
68474
+ const handleSubmit = () => {
68475
+ if (rawUrl.value && validUrl.value) {
68476
+ if (props.editor && props.editor.commands) {
68477
+ if (isEditing.value) {
68478
+ const { state: state2, view: view2 } = props.editor;
68479
+ const linkMark = state2.schema.marks.link;
68480
+ let { from: from2, to } = state2.selection;
68481
+ if (state2.selection.empty) {
68482
+ const range2 = getMarkRange(state2.selection.$from, linkMark);
68483
+ if (range2) {
68484
+ from2 = range2.from;
68485
+ to = range2.to;
68486
+ }
68487
+ }
68488
+ const tr2 = state2.tr.removeMark(from2, to, linkMark).addMark(from2, to, linkMark.create({ href: url.value }));
68489
+ view2.dispatch(tr2);
68490
+ } else if (props.editor.commands.toggleLink) {
68491
+ props.editor.commands.toggleLink({ href: url.value, text: text.value });
68492
+ }
68493
+ const { view } = props.editor;
68494
+ let { selection } = view.state;
68495
+ const endPos = selection.$to.pos;
68496
+ const tr = view.state.tr.setSelection(new TextSelection$1(view.state.doc.resolve(endPos)));
68497
+ view.dispatch(tr);
68498
+ setTimeout(() => {
68499
+ view.focus();
68500
+ }, 100);
68501
+ }
68502
+ props.closePopover();
68503
+ return;
68504
+ } else if (!rawUrl.value) {
68505
+ if (props.editor && props.editor.commands && props.editor.commands.unsetLink) {
68506
+ props.editor.commands.unsetLink();
68507
+ }
68508
+ props.closePopover();
68509
+ return;
68510
+ }
68511
+ urlError.value = true;
68512
+ };
68513
+ const handleRemove = () => {
68514
+ if (props.editor && props.editor.commands && props.editor.commands.unsetLink) {
68515
+ props.editor.commands.unsetLink();
68516
+ props.closePopover();
68517
+ }
68518
+ };
68519
+ return (_ctx, _cache) => {
68520
+ return openBlock(), createElementBlock("div", {
68521
+ class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode2) }])
68522
+ }, [
68523
+ isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$9, "Page anchor")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_2$7, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_3$6, "Add link")),
68524
+ __props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_4$2, [
68525
+ createBaseVNode("div", _hoisted_5$1, [
68526
+ createBaseVNode("div", {
68527
+ class: "input-icon",
68528
+ innerHTML: unref(toolbarIcons).linkInput
68529
+ }, null, 8, _hoisted_6),
68530
+ withDirectives(createBaseVNode("input", {
68531
+ type: "text",
68532
+ name: "link",
68533
+ placeholder: "Type or paste a link",
68534
+ class: normalizeClass({ error: urlError.value }),
68535
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => rawUrl.value = $event),
68536
+ onKeydown: [
68537
+ withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]),
68538
+ _cache[1] || (_cache[1] = ($event) => urlError.value = false)
68539
+ ]
68540
+ }, null, 42, _hoisted_7), [
68541
+ [vModelText, rawUrl.value]
68542
+ ]),
68543
+ createBaseVNode("div", {
68544
+ class: normalizeClass(["open-link-icon", { disabled: !validUrl.value }]),
68545
+ innerHTML: unref(toolbarIcons).openLink,
68546
+ onClick: openLink,
68547
+ "data-item": "btn-link-open"
68548
+ }, null, 10, _hoisted_8)
68549
+ ]),
68550
+ createBaseVNode("div", _hoisted_9, [
68551
+ rawUrl.value ? (openBlock(), createElementBlock("button", {
68552
+ key: 0,
68553
+ class: "remove-btn",
68554
+ onClick: handleRemove,
68555
+ "data-item": "btn-link-remove"
68556
+ }, [
68557
+ createBaseVNode("div", {
68558
+ class: "remove-btn__icon",
68559
+ innerHTML: unref(toolbarIcons).removeLink
68560
+ }, null, 8, _hoisted_10),
68561
+ _cache[3] || (_cache[3] = createTextVNode(" Remove "))
68562
+ ])) : createCommentVNode("", true),
68563
+ showApply.value ? (openBlock(), createElementBlock("button", {
68564
+ key: 1,
68565
+ class: normalizeClass(["submit-btn", { "disable-btn": isDisabled2.value }]),
68566
+ onClick: handleSubmit,
68567
+ "data-item": "btn-link-apply"
68568
+ }, toDisplayString(getApplyText.value), 3)) : createCommentVNode("", true)
68569
+ ])
68570
+ ])) : isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_11, [
68571
+ createBaseVNode("a", {
68572
+ onClick: _cache[2] || (_cache[2] = withModifiers((...args) => __props.goToAnchor && __props.goToAnchor(...args), ["stop", "prevent"]))
68573
+ }, "Go to " + toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)
68574
+ ])) : createCommentVNode("", true)
68575
+ ], 2);
68576
+ };
68577
+ }
68578
+ };
68579
+ const LinkInput = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-0c411ee5"]]);
68580
+ const _hoisted_1$8 = ["aria-label", "onClick", "onKeydown"];
68581
+ const _hoisted_2$6 = ["innerHTML"];
68582
+ const _hoisted_3$5 = ["innerHTML"];
68583
+ const ROW_SIZE$1 = 7;
68584
+ const _sfc_main$a = {
68353
68585
  __name: "IconGridRow",
68354
68586
  props: {
68355
68587
  icons: {
@@ -68468,26 +68700,26 @@ const _sfc_main$b = {
68468
68700
  class: "option__icon",
68469
68701
  innerHTML: option.icon,
68470
68702
  style: normalizeStyle(option.style)
68471
- }, null, 12, _hoisted_2$7),
68703
+ }, null, 12, _hoisted_2$6),
68472
68704
  isActive2.value(option) ? (openBlock(), createElementBlock("div", {
68473
68705
  key: 0,
68474
68706
  class: "option__check",
68475
68707
  innerHTML: unref(toolbarIcons).colorOptionCheck,
68476
68708
  style: normalizeStyle(getCheckStyle(option.value, optionIndex))
68477
- }, null, 12, _hoisted_3$6)) : createCommentVNode("", true)
68478
- ], 40, _hoisted_1$9);
68709
+ }, null, 12, _hoisted_3$5)) : createCommentVNode("", true)
68710
+ ], 40, _hoisted_1$8);
68479
68711
  }), 128))
68480
68712
  ]);
68481
68713
  }), 128);
68482
68714
  };
68483
68715
  }
68484
68716
  };
68485
- const IconGridRow = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-e89b7f5f"]]);
68717
+ const IconGridRow = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-e89b7f5f"]]);
68486
68718
  const DropIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 512c53.2 0 101.4-21.6 136.1-56.6l-298.3-235C140 257.1 128 292.3 128 320c0 106 86 192 192 192zM505.2 370.7c4.4-16.2 6.8-33.1 6.8-50.7c0-91.2-130.2-262.3-166.6-308.3C339.4 4.2 330.5 0 320.9 0l-1.8 0c-9.6 0-18.5 4.2-24.5 11.7C277.8 33 240.7 81.3 205.8 136L38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L505.2 370.7zM224 336c0 44.2 35.8 80 80 80c8.8 0 16 7.2 16 16s-7.2 16-16 16c-61.9 0-112-50.1-112-112c0-8.8 7.2-16 16-16s16 7.2 16 16z"/></svg>\n';
68487
- const _hoisted_1$8 = { class: "options-grid-wrap" };
68488
- const _hoisted_2$6 = ["innerHTML"];
68489
- const _hoisted_3$5 = { class: "option-grid-ctn" };
68490
- const _sfc_main$a = {
68719
+ const _hoisted_1$7 = { class: "options-grid-wrap" };
68720
+ const _hoisted_2$5 = ["innerHTML"];
68721
+ const _hoisted_3$4 = { class: "option-grid-ctn" };
68722
+ const _sfc_main$9 = {
68491
68723
  __name: "IconGrid",
68492
68724
  props: {
68493
68725
  icons: {
@@ -68514,7 +68746,7 @@ const _sfc_main$a = {
68514
68746
  emit("select", option);
68515
68747
  };
68516
68748
  return (_ctx, _cache) => {
68517
- return openBlock(), createElementBlock("div", _hoisted_1$8, [
68749
+ return openBlock(), createElementBlock("div", _hoisted_1$7, [
68518
68750
  __props.hasNoneIcon ? (openBlock(), createElementBlock("div", {
68519
68751
  key: 0,
68520
68752
  class: "none-option",
@@ -68525,10 +68757,10 @@ const _sfc_main$a = {
68525
68757
  createBaseVNode("span", {
68526
68758
  innerHTML: unref(DropIcon),
68527
68759
  class: "none-icon"
68528
- }, null, 8, _hoisted_2$6),
68760
+ }, null, 8, _hoisted_2$5),
68529
68761
  _cache[1] || (_cache[1] = createTextVNode(" None "))
68530
68762
  ])) : createCommentVNode("", true),
68531
- createBaseVNode("div", _hoisted_3$5, [
68763
+ createBaseVNode("div", _hoisted_3$4, [
68532
68764
  createVNode(IconGridRow, {
68533
68765
  icons: __props.icons,
68534
68766
  "active-color": __props.activeColor,
@@ -68547,7 +68779,7 @@ const _sfc_main$a = {
68547
68779
  };
68548
68780
  }
68549
68781
  };
68550
- const IconGrid = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-a00a9a3e"]]);
68782
+ const IconGrid = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-a00a9a3e"]]);
68551
68783
  const closeDropdown$1 = (dropdown) => {
68552
68784
  dropdown.expand.value = false;
68553
68785
  };
@@ -68656,10 +68888,10 @@ const icons = [
68656
68888
  const getAvailableColorOptions = () => {
68657
68889
  return icons.flat().map((item) => item.value);
68658
68890
  };
68659
- const _hoisted_1$7 = ["data-cols", "data-rows", "onKeydown", "onClick"];
68660
- const _hoisted_2$5 = ["aria-valuetext"];
68891
+ const _hoisted_1$6 = ["data-cols", "data-rows", "onKeydown", "onClick"];
68892
+ const _hoisted_2$4 = ["aria-valuetext"];
68661
68893
  const ROW_SIZE = 5;
68662
- const _sfc_main$9 = {
68894
+ const _sfc_main$8 = {
68663
68895
  __name: "TableGrid",
68664
68896
  emits: ["select", "clickoutside"],
68665
68897
  setup(__props, { emit: __emit }) {
@@ -68775,7 +69007,7 @@ const _sfc_main$9 = {
68775
69007
  ref: tableGridItems,
68776
69008
  onKeydown: withModifiers((event) => handleKeyDown2(event, n2, i), ["prevent"]),
68777
69009
  onClick: withModifiers(($event) => handleClick2({ cols: n2, rows: i }), ["stop", "prevent"])
68778
- }, null, 40, _hoisted_1$7);
69010
+ }, null, 40, _hoisted_1$6);
68779
69011
  }), 64))
68780
69012
  ], 64);
68781
69013
  }), 64))
@@ -68783,17 +69015,39 @@ const _sfc_main$9 = {
68783
69015
  createBaseVNode("div", {
68784
69016
  class: "toolbar-table-grid-value",
68785
69017
  "aria-valuetext": `${selectedRows.value} x ${selectedCols.value}`
68786
- }, toDisplayString(selectedRows.value) + " x " + toDisplayString(selectedCols.value), 9, _hoisted_2$5)
69018
+ }, toDisplayString(selectedRows.value) + " x " + toDisplayString(selectedCols.value), 9, _hoisted_2$4)
68787
69019
  ], 2);
68788
69020
  };
68789
69021
  }
68790
69022
  };
68791
- const TableGrid = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-3e1154b8"]]);
69023
+ const TableGrid = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-3e1154b8"]]);
69024
+ function getScrollableParent(element) {
69025
+ let currentElement2 = element;
69026
+ while (currentElement2) {
69027
+ const overflowY = window.getComputedStyle(currentElement2).overflowY;
69028
+ if (/(auto|scroll)/.test(overflowY) && currentElement2.scrollHeight > currentElement2.clientHeight) {
69029
+ return currentElement2;
69030
+ }
69031
+ currentElement2 = currentElement2.parentElement;
69032
+ }
69033
+ return document.scrollingElement || document.documentElement;
69034
+ }
69035
+ function scrollToElement(targetElement, options2 = { behavior: "smooth", block: "start" }) {
69036
+ if (!targetElement) return;
69037
+ const container = getScrollableParent(targetElement);
69038
+ const containerRect = container.getBoundingClientRect();
69039
+ const targetRect = targetElement.getBoundingClientRect();
69040
+ const offsetTop = targetRect.top - containerRect.top + container.scrollTop;
69041
+ container.scrollTo({
69042
+ top: options2.block === "start" ? offsetTop : offsetTop - container.clientHeight + targetElement.offsetHeight,
69043
+ behavior: options2.behavior
69044
+ });
69045
+ }
68792
69046
  const checkIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>\n';
68793
- const _hoisted_1$6 = { class: "search-input-ctn" };
68794
- const _hoisted_2$4 = { class: "row" };
68795
- const _hoisted_3$4 = ["onKeydown"];
68796
- const _sfc_main$8 = {
69047
+ const _hoisted_1$5 = { class: "search-input-ctn" };
69048
+ const _hoisted_2$3 = { class: "row" };
69049
+ const _hoisted_3$3 = ["onKeydown"];
69050
+ const _sfc_main$7 = {
68797
69051
  __name: "SearchInput",
68798
69052
  props: {
68799
69053
  searchRef: {
@@ -68808,8 +69062,8 @@ const _sfc_main$8 = {
68808
69062
  emit("submit", { value: searchValue.value });
68809
69063
  };
68810
69064
  return (_ctx, _cache) => {
68811
- return openBlock(), createElementBlock("div", _hoisted_1$6, [
68812
- createBaseVNode("div", _hoisted_2$4, [
69065
+ return openBlock(), createElementBlock("div", _hoisted_1$5, [
69066
+ createBaseVNode("div", _hoisted_2$3, [
68813
69067
  withDirectives(createBaseVNode("input", {
68814
69068
  ref: __props.searchRef,
68815
69069
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchValue.value = $event),
@@ -68818,7 +69072,7 @@ const _sfc_main$8 = {
68818
69072
  name: "search",
68819
69073
  placeholder: "Type search string",
68820
69074
  onKeydown: withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"])
68821
- }, null, 40, _hoisted_3$4), [
69075
+ }, null, 40, _hoisted_3$3), [
68822
69076
  [vModelText, searchValue.value]
68823
69077
  ])
68824
69078
  ]),
@@ -68832,7 +69086,7 @@ const _sfc_main$8 = {
68832
69086
  };
68833
69087
  }
68834
69088
  };
68835
- const SearchInput = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-af870fbd"]]);
69089
+ const SearchInput = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-af870fbd"]]);
68836
69090
  const TOOLBAR_FONTS = [
68837
69091
  {
68838
69092
  label: "Georgia",
@@ -69114,6 +69368,54 @@ const makeDefaultItems = ({
69114
69368
  })
69115
69369
  ]);
69116
69370
  };
69371
+ const link = useToolbarItem({
69372
+ type: "dropdown",
69373
+ name: "link",
69374
+ markName: "link",
69375
+ icon: toolbarIcons2.link,
69376
+ tooltip: toolbarTexts2.link,
69377
+ attributes: {
69378
+ ariaLabel: "Link dropdown"
69379
+ },
69380
+ options: [
69381
+ {
69382
+ type: "render",
69383
+ key: "linkDropdown",
69384
+ render: () => renderLinkDropdown(link)
69385
+ }
69386
+ ],
69387
+ onActivate: ({ href }) => {
69388
+ if (href) link.attributes.value = { href };
69389
+ else link.attributes.value = {};
69390
+ },
69391
+ onDeactivate: () => {
69392
+ link.attributes.value = {};
69393
+ link.expand.value = false;
69394
+ }
69395
+ });
69396
+ function renderLinkDropdown(link2) {
69397
+ return h("div", {}, [
69398
+ h(LinkInput, {
69399
+ editor: superToolbar.activeEditor,
69400
+ closePopover: () => closeDropdown(link2),
69401
+ goToAnchor: () => {
69402
+ closeDropdown(link2);
69403
+ if (!superToolbar.activeEditor || !link2.attributes.value?.href) return;
69404
+ const anchorName = link2.attributes.value?.href?.slice(1);
69405
+ const container = superToolbar.activeEditor.element;
69406
+ const anchor = container.querySelector(`a[name='${anchorName}']`);
69407
+ if (anchor) scrollToElement(anchor);
69408
+ }
69409
+ })
69410
+ ]);
69411
+ }
69412
+ const linkInput = useToolbarItem({
69413
+ type: "options",
69414
+ name: "linkInput",
69415
+ command: "toggleLink"
69416
+ });
69417
+ link.childItem = linkInput;
69418
+ linkInput.parentItem = link;
69117
69419
  const image = useToolbarItem({
69118
69420
  type: "button",
69119
69421
  name: "image",
@@ -69611,6 +69913,7 @@ const makeDefaultItems = ({
69611
69913
  colorButton,
69612
69914
  highlight,
69613
69915
  separator,
69916
+ link,
69614
69917
  image,
69615
69918
  tableItem,
69616
69919
  separator,
@@ -69947,6 +70250,35 @@ class SuperToolbar extends EventEmitter2 {
69947
70250
  }
69948
70251
  this.updateToolbarState();
69949
70252
  },
70253
+ /**
70254
+ * Toggles link formatting and updates cursor position
70255
+ * @param {Object} params - Command parameters
70256
+ * @param {CommandItem} params.item - The command item
70257
+ * @param {*} params.argument - Command arguments
70258
+ * @returns {void}
70259
+ */
70260
+ toggleLink: ({ item, argument }) => {
70261
+ let command2 = item.command;
70262
+ if (command2 in this.activeEditor.commands) {
70263
+ this.activeEditor.commands[command2](argument);
70264
+ const { view } = this.activeEditor;
70265
+ let { selection } = view.state;
70266
+ if (this.activeEditor.options.isHeaderOrFooter) {
70267
+ selection = this.activeEditor.options.lastSelection;
70268
+ }
70269
+ const endPos = selection.$to.pos;
70270
+ const newSelection = new TextSelection(view.state.doc.resolve(endPos));
70271
+ const tr = view.state.tr.setSelection(newSelection);
70272
+ const state2 = view.state.apply(tr);
70273
+ view.updateState(state2);
70274
+ if (!this.activeEditor.options.isHeaderOrFooter) {
70275
+ setTimeout(() => {
70276
+ view.focus();
70277
+ }, 100);
70278
+ }
70279
+ }
70280
+ this.updateToolbarState();
70281
+ },
69950
70282
  /**
69951
70283
  * Inserts a table into the document
69952
70284
  * @param {Object} params - Command parameters
@@ -70513,219 +70845,6 @@ async function getEditorContext(editor, event) {
70513
70845
  clipboardContent
70514
70846
  };
70515
70847
  }
70516
- const _hoisted_1$5 = {
70517
- key: 0,
70518
- class: "link-title"
70519
- };
70520
- const _hoisted_2$3 = {
70521
- key: 1,
70522
- class: "link-title"
70523
- };
70524
- const _hoisted_3$3 = {
70525
- key: 2,
70526
- class: "link-title"
70527
- };
70528
- const _hoisted_4$2 = { key: 3 };
70529
- const _hoisted_5$1 = { class: "input-row" };
70530
- const _hoisted_6 = ["innerHTML"];
70531
- const _hoisted_7 = ["onKeydown"];
70532
- const _hoisted_8 = ["innerHTML"];
70533
- const _hoisted_9 = { class: "input-row link-buttons" };
70534
- const _hoisted_10 = ["innerHTML"];
70535
- const _hoisted_11 = {
70536
- key: 4,
70537
- class: "input-row go-to-anchor clickable"
70538
- };
70539
- const _sfc_main$7 = {
70540
- __name: "LinkInput",
70541
- props: {
70542
- showInput: {
70543
- type: Boolean,
70544
- default: true
70545
- },
70546
- showLink: {
70547
- type: Boolean,
70548
- default: true
70549
- },
70550
- goToAnchor: {
70551
- type: Function,
70552
- default: () => {
70553
- }
70554
- },
70555
- editor: {
70556
- type: Object,
70557
- required: true
70558
- },
70559
- closePopover: {
70560
- type: Function,
70561
- default: () => {
70562
- }
70563
- }
70564
- },
70565
- setup(__props) {
70566
- const props = __props;
70567
- const { isHighContrastMode: isHighContrastMode2 } = useHighContrastMode();
70568
- const urlError = ref$1(false);
70569
- const getSelectedText = () => {
70570
- if (!props.editor || !props.editor.state) return "";
70571
- const { state: state2 } = props.editor;
70572
- const { from: from2, to } = state2.selection;
70573
- return state2.doc.textBetween(from2, to, " ");
70574
- };
70575
- const getLinkHrefAtSelection = () => {
70576
- if (!props.editor || !props.editor.state) return "";
70577
- const { state: state2 } = props.editor;
70578
- const { schema, selection } = state2;
70579
- const linkMark = schema.marks.link;
70580
- if (!linkMark) return "";
70581
- let href = "";
70582
- const { $from, empty: empty2 } = selection;
70583
- if (empty2) {
70584
- const marks = state2.storedMarks || $from.marks();
70585
- const link = marks.find((mark) => mark.type === linkMark);
70586
- if (link) href = link.attrs.href;
70587
- } else {
70588
- state2.doc.nodesBetween(selection.from, selection.to, (node2) => {
70589
- if (node2.marks) {
70590
- const link = node2.marks.find((mark) => mark.type === linkMark);
70591
- if (link) href = link.attrs.href;
70592
- }
70593
- });
70594
- }
70595
- return href || "";
70596
- };
70597
- const text = ref$1("");
70598
- const rawUrl = ref$1("");
70599
- const isAnchor = ref$1(false);
70600
- const url = computed(() => {
70601
- if (!rawUrl.value?.startsWith("http")) return "http://" + rawUrl.value;
70602
- return rawUrl.value;
70603
- });
70604
- const validUrl = computed(() => {
70605
- const urlSplit = url.value.split(".").filter(Boolean);
70606
- return url.value.includes(".") && urlSplit.length > 1;
70607
- });
70608
- const isEditing = computed(() => !isAnchor.value && !!getLinkHrefAtSelection());
70609
- const getApplyText = computed(() => showApply.value ? "Apply" : "Remove");
70610
- const isDisabled2 = computed(() => !validUrl.value);
70611
- const showApply = computed(() => !showRemove.value);
70612
- const showRemove = computed(() => rawUrl.value === "" && getLinkHrefAtSelection());
70613
- const openLink = () => {
70614
- window.open(url.value, "_blank");
70615
- };
70616
- const updateFromEditor = () => {
70617
- text.value = getSelectedText();
70618
- rawUrl.value = getLinkHrefAtSelection();
70619
- };
70620
- watch(
70621
- () => props.editor?.state?.selection,
70622
- () => {
70623
- updateFromEditor();
70624
- },
70625
- { immediate: true }
70626
- );
70627
- const focusInput = () => {
70628
- const input = document.querySelector(".link-input-ctn input");
70629
- if (!input) return;
70630
- input.focus();
70631
- };
70632
- onMounted(() => {
70633
- updateFromEditor();
70634
- isAnchor.value = rawUrl.value.startsWith("#");
70635
- if (props.showInput) focusInput();
70636
- });
70637
- const handleSubmit = () => {
70638
- if (rawUrl.value && validUrl.value) {
70639
- if (props.editor && props.editor.commands && props.editor.commands.toggleLink) {
70640
- props.editor.commands.toggleLink({ href: url.value, text: text.value });
70641
- const { view } = props.editor;
70642
- let { selection } = view.state;
70643
- const endPos = selection.$to.pos;
70644
- const tr = view.state.tr.setSelection(new TextSelection(view.state.doc.resolve(endPos)));
70645
- const state2 = view.state.apply(tr);
70646
- view.updateState(state2);
70647
- setTimeout(() => {
70648
- view.focus();
70649
- }, 100);
70650
- }
70651
- props.closePopover();
70652
- return;
70653
- } else if (!rawUrl.value) {
70654
- if (props.editor && props.editor.commands && props.editor.commands.unsetLink) {
70655
- props.editor.commands.unsetLink();
70656
- }
70657
- props.closePopover();
70658
- return;
70659
- }
70660
- urlError.value = true;
70661
- };
70662
- const handleRemove = () => {
70663
- if (props.editor && props.editor.commands && props.editor.commands.unsetLink) {
70664
- props.editor.commands.unsetLink();
70665
- props.closePopover();
70666
- }
70667
- };
70668
- return (_ctx, _cache) => {
70669
- return openBlock(), createElementBlock("div", {
70670
- class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode2) }])
70671
- }, [
70672
- isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$5, "Page anchor")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_2$3, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_3$3, "Add link")),
70673
- __props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_4$2, [
70674
- createBaseVNode("div", _hoisted_5$1, [
70675
- createBaseVNode("div", {
70676
- class: "input-icon",
70677
- innerHTML: unref(toolbarIcons).linkInput
70678
- }, null, 8, _hoisted_6),
70679
- withDirectives(createBaseVNode("input", {
70680
- type: "text",
70681
- name: "link",
70682
- placeholder: "Type or paste a link",
70683
- class: normalizeClass({ error: urlError.value }),
70684
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => rawUrl.value = $event),
70685
- onKeydown: [
70686
- withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]),
70687
- _cache[1] || (_cache[1] = ($event) => urlError.value = false)
70688
- ]
70689
- }, null, 42, _hoisted_7), [
70690
- [vModelText, rawUrl.value]
70691
- ]),
70692
- createBaseVNode("div", {
70693
- class: normalizeClass(["open-link-icon", { disabled: !validUrl.value }]),
70694
- innerHTML: unref(toolbarIcons).openLink,
70695
- onClick: openLink,
70696
- "data-item": "btn-link-open"
70697
- }, null, 10, _hoisted_8)
70698
- ]),
70699
- createBaseVNode("div", _hoisted_9, [
70700
- rawUrl.value ? (openBlock(), createElementBlock("button", {
70701
- key: 0,
70702
- class: "remove-btn",
70703
- onClick: handleRemove,
70704
- "data-item": "btn-link-remove"
70705
- }, [
70706
- createBaseVNode("div", {
70707
- class: "remove-btn__icon",
70708
- innerHTML: unref(toolbarIcons).removeLink
70709
- }, null, 8, _hoisted_10),
70710
- _cache[3] || (_cache[3] = createTextVNode(" Remove "))
70711
- ])) : createCommentVNode("", true),
70712
- showApply.value ? (openBlock(), createElementBlock("button", {
70713
- key: 1,
70714
- class: normalizeClass(["submit-btn", { "disable-btn": isDisabled2.value }]),
70715
- onClick: handleSubmit,
70716
- "data-item": "btn-link-apply"
70717
- }, toDisplayString(getApplyText.value), 3)) : createCommentVNode("", true)
70718
- ])
70719
- ])) : isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_11, [
70720
- createBaseVNode("a", {
70721
- onClick: _cache[2] || (_cache[2] = withModifiers((...args) => __props.goToAnchor && __props.goToAnchor(...args), ["stop", "prevent"]))
70722
- }, "Go to " + toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)
70723
- ])) : createCommentVNode("", true)
70724
- ], 2);
70725
- };
70726
- }
70727
- };
70728
- const LinkInput = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-2632571a"]]);
70729
70848
  const onMarginClickCursorChange = (event, editor) => {
70730
70849
  const y = event.clientY;
70731
70850
  const x = event.clientX;
@@ -70754,7 +70873,7 @@ const onMarginClickCursorChange = (event, editor) => {
70754
70873
  cursorPos = node2?.isText && charAtPos !== " " ? pos - 1 : pos;
70755
70874
  }
70756
70875
  const transaction = view.state.tr.setSelection(
70757
- TextSelection.create(view.state.doc, cursorPos)
70876
+ TextSelection$1.create(view.state.doc, cursorPos)
70758
70877
  );
70759
70878
  view.dispatch(transaction);
70760
70879
  view.focus();
@@ -70833,7 +70952,7 @@ function moveCursorToMouseEvent(event, editor) {
70833
70952
  const pos = view.posAtCoords(coords)?.pos;
70834
70953
  if (typeof pos === "number") {
70835
70954
  const tr = view.state.tr.setSelection(
70836
- TextSelection.create(view.state.doc, pos)
70955
+ TextSelection$1.create(view.state.doc, pos)
70837
70956
  );
70838
70957
  view.dispatch(tr);
70839
70958
  view.focus();
@@ -70973,19 +71092,29 @@ function getItems(context) {
70973
71092
  icon: ICONS.paste,
70974
71093
  action: async (editor2) => {
70975
71094
  try {
70976
- const clipboardData = await navigator.clipboard.read();
70977
- const event = new ClipboardEvent("paste", {
70978
- clipboardData: new DataTransfer(),
70979
- bubbles: true,
70980
- cancelable: true
70981
- });
70982
- for (const item of clipboardData) {
70983
- for (const type2 of item.types) {
70984
- const blob = await item.getType(type2);
70985
- event.clipboardData.setData(type2, await blob.text());
71095
+ const clipboardItems = await navigator.clipboard.read();
71096
+ let html = "";
71097
+ let text = "";
71098
+ for (const item of clipboardItems) {
71099
+ if (!html && item.types.includes("text/html")) {
71100
+ html = await (await item.getType("text/html")).text();
70986
71101
  }
71102
+ if (!text && item.types.includes("text/plain")) {
71103
+ text = await (await item.getType("text/plain")).text();
71104
+ }
71105
+ }
71106
+ const handled = handleClipboardPaste({ editor: editor2, view: editor2.view }, html, text);
71107
+ if (!handled) {
71108
+ const dataTransfer = new DataTransfer();
71109
+ if (html) dataTransfer.setData("text/html", html);
71110
+ if (text) dataTransfer.setData("text/plain", text);
71111
+ const event = new ClipboardEvent("paste", {
71112
+ clipboardData: dataTransfer,
71113
+ bubbles: true,
71114
+ cancelable: true
71115
+ });
71116
+ editor2.view.dom.dispatchEvent(event);
70987
71117
  }
70988
- editor2.view.dom.dispatchEvent(event);
70989
71118
  } catch (error) {
70990
71119
  console.warn("Failed to paste:", error);
70991
71120
  }
@@ -71045,6 +71174,11 @@ const _sfc_main$5 = {
71045
71174
  const menuRef = ref$1(null);
71046
71175
  const sections = ref$1([]);
71047
71176
  const selectedId = ref$1(null);
71177
+ const handleEditorUpdate = () => {
71178
+ if (!props.editor?.isEditable && isOpen.value) {
71179
+ closeMenu({ restoreCursor: false });
71180
+ }
71181
+ };
71048
71182
  const flattenedItems = computed(() => {
71049
71183
  const items = [];
71050
71184
  sections.value.forEach((section) => {
@@ -71129,7 +71263,9 @@ const _sfc_main$5 = {
71129
71263
  }
71130
71264
  };
71131
71265
  const handleRightClick = async (event) => {
71132
- if (event.ctrlKey) {
71266
+ const readOnly = !props.editor?.isEditable;
71267
+ const isHoldingCtrl = event.ctrlKey;
71268
+ if (readOnly || isHoldingCtrl) {
71133
71269
  return;
71134
71270
  }
71135
71271
  event.preventDefault();
@@ -71187,7 +71323,10 @@ const _sfc_main$5 = {
71187
71323
  if (!props.editor) return;
71188
71324
  document.addEventListener("keydown", handleGlobalKeyDown);
71189
71325
  document.addEventListener("mousedown", handleGlobalOutsideClick);
71326
+ props.editor.on("update", handleEditorUpdate);
71190
71327
  props.editor.on("slashMenu:open", async (event) => {
71328
+ const readOnly = !props.editor?.isEditable;
71329
+ if (readOnly) return;
71191
71330
  isOpen.value = true;
71192
71331
  menuPosition.value = event.menuPosition;
71193
71332
  searchQuery.value = "";
@@ -71208,6 +71347,7 @@ const _sfc_main$5 = {
71208
71347
  try {
71209
71348
  props.editor.off("slashMenu:open");
71210
71349
  props.editor.off("slashMenu:close");
71350
+ props.editor.off("update", handleEditorUpdate);
71211
71351
  props.editor.view.dom.removeEventListener("contextmenu", handleRightClick);
71212
71352
  } catch (error) {
71213
71353
  }
@@ -71810,8 +71950,9 @@ const _sfc_main$2 = {
71810
71950
  style: { "width": "70%" }
71811
71951
  })
71812
71952
  ])) : createCommentVNode("", true),
71813
- createVNode(GenericPopover, {
71814
- editor: editor.value ?? {},
71953
+ editor.value ? (openBlock(), createBlock(GenericPopover, {
71954
+ key: 2,
71955
+ editor: editor.value,
71815
71956
  visible: popoverControls.visible,
71816
71957
  position: popoverControls.position,
71817
71958
  onClose: closePopover
@@ -71820,12 +71961,12 @@ const _sfc_main$2 = {
71820
71961
  (openBlock(), createBlock(resolveDynamicComponent(popoverControls.component), normalizeProps(guardReactiveProps({ ...popoverControls.props, editor: editor.value, closePopover })), null, 16))
71821
71962
  ]),
71822
71963
  _: 1
71823
- }, 8, ["editor", "visible", "position"])
71964
+ }, 8, ["editor", "visible", "position"])) : createCommentVNode("", true)
71824
71965
  ]);
71825
71966
  };
71826
71967
  }
71827
71968
  };
71828
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-b71313e5"]]);
71969
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-d4ce5f62"]]);
71829
71970
  const _sfc_main$1 = {
71830
71971
  __name: "BasicUpload",
71831
71972
  emits: ["file-change"],