@cyberyozh/text-editor 0.2.1 → 0.3.0

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/editor.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/editor/editor.tsx
2
2
  import { useState as useState13, useEffect as useEffect11 } from "react";
3
3
  import { NodeSelection } from "@tiptap/pm/state";
4
- import { Slice as Slice2 } from "@tiptap/pm/model";
4
+ import { Slice as Slice3 } from "@tiptap/pm/model";
5
5
  import { useEditor, EditorContent } from "@tiptap/react";
6
6
  import { BubbleMenu } from "@tiptap/react/menus";
7
7
  import "highlight.js/styles/github-dark.css";
@@ -2021,7 +2021,6 @@ var ImageDialog = ({
2021
2021
  setIsUploading(true);
2022
2022
  try {
2023
2023
  const result = await uploadHandler(formState.file);
2024
- console.log("\u{1F440} ~ handleAddImage ~ result:", result);
2025
2024
  onImageAdd({
2026
2025
  fileId: result.fileId,
2027
2026
  src: result.fileUrl,
@@ -3100,7 +3099,8 @@ var BaseCustomQuoteSign = Node2.create({
3100
3099
 
3101
3100
  // src/extensions/base/link.ts
3102
3101
  import Link, { isAllowedUri } from "@tiptap/extension-link";
3103
- import { markPasteRule } from "@tiptap/core";
3102
+ import { getMarkRange, markPasteRule } from "@tiptap/core";
3103
+ import { Plugin, TextSelection as TextSelection3 } from "@tiptap/pm/state";
3104
3104
 
3105
3105
  // node_modules/linkifyjs/dist/linkify.mjs
3106
3106
  var encodedTlds = "aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5m\xF6gensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2";
@@ -4279,6 +4279,23 @@ var LinkExtension = Link.extend({
4279
4279
  }
4280
4280
  })
4281
4281
  ];
4282
+ },
4283
+ addProseMirrorPlugins() {
4284
+ return [
4285
+ ...this.parent?.() ?? [],
4286
+ new Plugin({
4287
+ props: {
4288
+ handleClick: (view, pos) => {
4289
+ if (!view.editable) return false;
4290
+ const range = getMarkRange(view.state.doc.resolve(pos), this.type);
4291
+ if (!range) return false;
4292
+ const selection = TextSelection3.create(view.state.doc, range.from, range.to);
4293
+ view.dispatch(view.state.tr.setSelection(selection));
4294
+ return true;
4295
+ }
4296
+ }
4297
+ })
4298
+ ];
4282
4299
  }
4283
4300
  }).configure({
4284
4301
  openOnClick: false,
@@ -4325,7 +4342,7 @@ var BaseMythReality = Node3.create({
4325
4342
 
4326
4343
  // src/extensions/base/prompt.ts
4327
4344
  import { Node as Node4, mergeAttributes as mergeAttributes5 } from "@tiptap/core";
4328
- import { TextSelection as TextSelection3 } from "@tiptap/pm/state";
4345
+ import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
4329
4346
  var BasePrompt = Node4.create({
4330
4347
  name: "prompt",
4331
4348
  group: "block",
@@ -4357,7 +4374,7 @@ var BasePrompt = Node4.create({
4357
4374
  const paragraphNode = schema.nodes.paragraph.createAndFill();
4358
4375
  if (!paragraphNode) return false;
4359
4376
  tr2.insert(posAfter, paragraphNode);
4360
- tr2.setSelection(TextSelection3.create(tr2.doc, posAfter + 1));
4377
+ tr2.setSelection(TextSelection4.create(tr2.doc, posAfter + 1));
4361
4378
  view.dispatch(tr2);
4362
4379
  return true;
4363
4380
  }
@@ -4599,7 +4616,7 @@ var BaseFigure = Image2.extend({
4599
4616
 
4600
4617
  // src/extensions/base/compatibility.ts
4601
4618
  import { mergeAttributes as mergeAttributes7, Node as Node6 } from "@tiptap/core";
4602
- import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
4619
+ import { TextSelection as TextSelection5 } from "@tiptap/pm/state";
4603
4620
  import Image3 from "@tiptap/extension-image";
4604
4621
  var BaseLegacyBookAlert = Node6.create({
4605
4622
  name: "calloutAlert",
@@ -4743,7 +4760,7 @@ var BaseLegacySEQuote = Node6.create({
4743
4760
  const paragraphNode = schema.nodes.paragraph.createAndFill();
4744
4761
  if (!paragraphNode) return false;
4745
4762
  tr2.insert(posAfter, paragraphNode);
4746
- tr2.setSelection(TextSelection4.create(tr2.doc, posAfter + 1));
4763
+ tr2.setSelection(TextSelection5.create(tr2.doc, posAfter + 1));
4747
4764
  view.dispatch(tr2);
4748
4765
  return true;
4749
4766
  }
@@ -4791,7 +4808,7 @@ var BaseLegacyPromptSE = Node6.create({
4791
4808
  const paragraphNode = schema.nodes.paragraph.createAndFill();
4792
4809
  if (!paragraphNode) return false;
4793
4810
  tr2.insert(posAfter, paragraphNode);
4794
- tr2.setSelection(TextSelection4.create(tr2.doc, posAfter + 1));
4811
+ tr2.setSelection(TextSelection5.create(tr2.doc, posAfter + 1));
4795
4812
  view.dispatch(tr2);
4796
4813
  return true;
4797
4814
  }
@@ -6649,7 +6666,7 @@ function getEditorExtensions(options) {
6649
6666
  }
6650
6667
 
6651
6668
  // src/editor/handlers/dialog-handlers.ts
6652
- import { TextSelection as TextSelection5 } from "@tiptap/pm/state";
6669
+ import { TextSelection as TextSelection6 } from "@tiptap/pm/state";
6653
6670
  var createHandleImageAdd = (editor, closeDialogCommand, savedPos) => {
6654
6671
  return (attrs) => {
6655
6672
  if (!editor) return;
@@ -6660,10 +6677,10 @@ var createHandleImageAdd = (editor, closeDialogCommand, savedPos) => {
6660
6677
  const imageNode = state2.schema.nodes.image.create({ ...attrs });
6661
6678
  if ($pos.parent.type.name === "paragraph" && $pos.parent.textContent === "") {
6662
6679
  tr2.replaceWith($pos.before(), $pos.after(), imageNode);
6663
- tr2.setSelection(TextSelection5.near(tr2.doc.resolve($pos.before())));
6680
+ tr2.setSelection(TextSelection6.near(tr2.doc.resolve($pos.before())));
6664
6681
  } else {
6665
6682
  tr2.insert(insertPos, imageNode);
6666
- tr2.setSelection(TextSelection5.near(tr2.doc.resolve(insertPos)));
6683
+ tr2.setSelection(TextSelection6.near(tr2.doc.resolve(insertPos)));
6667
6684
  }
6668
6685
  return true;
6669
6686
  }).run();
@@ -6687,40 +6704,29 @@ var createHandleVideoAdd = (editor, closeDialogCommand, savedPos) => {
6687
6704
  const videoNode = state2.schema.nodes.video.create({ src: url });
6688
6705
  if ($pos.parent.type.name === "paragraph" && $pos.parent.textContent === "") {
6689
6706
  tr2.replaceWith($pos.before(), $pos.after(), videoNode);
6690
- tr2.setSelection(TextSelection5.near(tr2.doc.resolve($pos.before())));
6707
+ tr2.setSelection(TextSelection6.near(tr2.doc.resolve($pos.before())));
6691
6708
  } else {
6692
6709
  tr2.insert(insertPos, videoNode);
6693
- tr2.setSelection(TextSelection5.near(tr2.doc.resolve(insertPos)));
6710
+ tr2.setSelection(TextSelection6.near(tr2.doc.resolve(insertPos)));
6694
6711
  }
6695
6712
  return true;
6696
6713
  }).run();
6697
6714
  closeDialogCommand();
6698
6715
  };
6699
6716
  };
6700
- var createHandleLinkAdd = (editor, closeDialogCommand, linkParams, savedPos) => {
6717
+ var createHandleLinkAdd = (editor, closeDialogCommand, linkParams, savedRange) => {
6701
6718
  if (!editor) return;
6702
- const hasSelection = !editor.state.selection.empty;
6703
- const titleLength = linkParams.title?.length ?? 0;
6704
- if (hasSelection) {
6705
- editor.chain().focus().command(({ tr: tr2, state }) => {
6706
- const { from, to } = state.selection;
6707
- tr2.insertText(linkParams.title ?? "", from, to);
6708
- tr2.removeMark(from, from + titleLength);
6709
- tr2.addMark(from, from + titleLength, editor.schema.marks.link.create({ ...linkParams }));
6710
- return true;
6711
- }).run();
6712
- } else {
6713
- const { state } = editor;
6714
- const insertPos = savedPos ?? state.selection.from;
6715
- const titleLength2 = linkParams.title?.length ?? 0;
6716
- editor.chain().focus().command(({ tr: tr2 }) => {
6717
- const linkMark = editor.schema.marks.link.create({ ...linkParams });
6718
- const textNode = editor.schema.text(linkParams.title ?? "", [linkMark]);
6719
- tr2.insert(insertPos, textNode);
6720
- tr2.setSelection(TextSelection5.create(tr2.doc, insertPos, insertPos + titleLength2));
6721
- return true;
6722
- }).run();
6723
- }
6719
+ const title = linkParams.title ?? "";
6720
+ const titleLength = title.length;
6721
+ const from = savedRange?.from ?? editor.state.selection.from;
6722
+ const to = savedRange?.to ?? editor.state.selection.to;
6723
+ editor.chain().focus().command(({ tr: tr2 }) => {
6724
+ tr2.insertText(title, from, to);
6725
+ tr2.removeMark(from, from + titleLength);
6726
+ tr2.addMark(from, from + titleLength, editor.schema.marks.link.create({ ...linkParams }));
6727
+ tr2.setSelection(TextSelection6.create(tr2.doc, from, from + titleLength));
6728
+ return true;
6729
+ }).run();
6724
6730
  closeDialogCommand();
6725
6731
  };
6726
6732
  var createHandleKatexAdd = (editor, closeDialogCommand, savedPos) => {
@@ -6734,7 +6740,7 @@ var createHandleKatexAdd = (editor, closeDialogCommand, savedPos) => {
6734
6740
  editor.chain().focus().command(({ tr: tr2, state: state2 }) => {
6735
6741
  const inlineMathNode = state2.schema.nodes.inlineMath.create({ latex });
6736
6742
  tr2.insert(insertPos, inlineMathNode);
6737
- tr2.setSelection(TextSelection5.near(tr2.doc.resolve(insertPos)));
6743
+ tr2.setSelection(TextSelection6.near(tr2.doc.resolve(insertPos)));
6738
6744
  return true;
6739
6745
  }).run();
6740
6746
  }
@@ -6745,6 +6751,9 @@ var createHandleKatexAdd = (editor, closeDialogCommand, savedPos) => {
6745
6751
  // src/editor/handlers/insertion-handlers.ts
6746
6752
  import { useEffect as useEffect10, useState as useState12 } from "react";
6747
6753
 
6754
+ // src/editor/handlers/markup-insertion.ts
6755
+ import { Fragment as Fragment4, Slice as Slice2 } from "@tiptap/pm/model";
6756
+
6748
6757
  // src/utils/prosemirror-iterator.ts
6749
6758
  import { Fragment as Fragment3, Slice } from "@tiptap/pm/model";
6750
6759
  function prosemirrorIterator(slice, cb) {
@@ -6771,8 +6780,61 @@ function collectFragmentChildren(fragment, stack) {
6771
6780
  }
6772
6781
  }
6773
6782
 
6783
+ // src/editor/handlers/markup-insertion.ts
6784
+ function collectRehostableImages(slice) {
6785
+ const imagesToNodes = [];
6786
+ prosemirrorIterator(slice, (node) => {
6787
+ if (node.type.name === "image" && !node.attrs.fileId) {
6788
+ try {
6789
+ const url = new URL(node.attrs.src).toString();
6790
+ imagesToNodes.push([url, node]);
6791
+ } catch {
6792
+ }
6793
+ }
6794
+ });
6795
+ return imagesToNodes;
6796
+ }
6797
+ function removeImagesFromFragment(fragment) {
6798
+ const newNodes = [];
6799
+ fragment.forEach((node) => {
6800
+ if (node.type.name === "image" && !node.attrs.fileId) return;
6801
+ newNodes.push(node.childCount > 0 ? node.copy(removeImagesFromFragment(node.content)) : node);
6802
+ });
6803
+ return Fragment4.from(newNodes);
6804
+ }
6805
+ function validOpenDepth(fragment, requestedDepth, fromEnd = false) {
6806
+ let depth = 0;
6807
+ let current = fragment;
6808
+ while (depth < requestedDepth) {
6809
+ if (current.childCount === 0) break;
6810
+ const node = fromEnd ? current.lastChild : current.firstChild;
6811
+ if (node.isLeaf) break;
6812
+ current = node.content;
6813
+ depth++;
6814
+ }
6815
+ return depth;
6816
+ }
6817
+ function removeImagesFromSlice(slice) {
6818
+ const newContent = removeImagesFromFragment(slice.content);
6819
+ return new Slice2(
6820
+ newContent,
6821
+ validOpenDepth(newContent, slice.openStart),
6822
+ validOpenDepth(newContent, slice.openEnd, true)
6823
+ );
6824
+ }
6825
+ function applyUploadResultsToNodes(imagesToNodes, results) {
6826
+ results.forEach((result, index) => {
6827
+ if (!result) return;
6828
+ const node = imagesToNodes[index]?.[1];
6829
+ if (!node) return;
6830
+ node.attrs.src = result.fileUrl ?? null;
6831
+ node.attrs.fileId = result.fileId;
6832
+ node.attrs.storageKey = result.storageKey;
6833
+ });
6834
+ }
6835
+
6774
6836
  // src/editor/handlers/insertion-handlers.ts
6775
- function useInsertionHandlers() {
6837
+ function useInsertionHandlers(imageHandlers) {
6776
6838
  const [insertedImage, setInsertedImage] = useState12(null);
6777
6839
  const { activeDialog, openDialogCommand } = useDialogCommand();
6778
6840
  useEffect10(() => {
@@ -6784,6 +6846,7 @@ function useInsertionHandlers() {
6784
6846
  if (!file || !file.type.startsWith("image/")) return;
6785
6847
  event.preventDefault();
6786
6848
  event.stopPropagation();
6849
+ if (!imageHandlers?.upload) return;
6787
6850
  setInsertedImage(file);
6788
6851
  openDialogCommand("image");
6789
6852
  }
@@ -6795,8 +6858,7 @@ function useInsertionHandlers() {
6795
6858
  const file = event.dataTransfer?.files?.[0];
6796
6859
  genericInsertionHandler(file, event);
6797
6860
  }
6798
- function onMarkupInsertion(view, event, slice, setDisabled, uploadMultipleByURL) {
6799
- if (!uploadMultipleByURL) return;
6861
+ function onMarkupInsertion(view, event, slice, setDisabled) {
6800
6862
  let hasMarkupInsertion = false;
6801
6863
  if ("clipboardData" in event && Array.from(event.clipboardData?.items ?? []).some(
6802
6864
  (item) => item.type === "text/html"
@@ -6809,28 +6871,18 @@ function useInsertionHandlers() {
6809
6871
  hasMarkupInsertion = true;
6810
6872
  }
6811
6873
  if (hasMarkupInsertion) {
6812
- const imagesToNodes = [];
6813
- setDisabled(true);
6814
- prosemirrorIterator(slice, (node) => {
6815
- if (node.type.name === "image" && !node.attrs.fileId) {
6816
- try {
6817
- const url = new URL(node.attrs.src).toString();
6818
- imagesToNodes.push([url, node]);
6819
- } catch {
6820
- }
6821
- }
6822
- });
6823
- uploadMultipleByURL(imagesToNodes.map(([url]) => url)).then((results) => {
6824
- results.forEach((result, index) => {
6825
- const node = imagesToNodes[index][1];
6826
- node.attrs.src = null;
6827
- node.attrs.fileId = result?.fileId;
6828
- node.attrs.storageKey = result?.storageKey;
6874
+ if (imageHandlers?.uploadMultipleByURL) {
6875
+ setDisabled(true);
6876
+ const imagesToNodes = collectRehostableImages(slice);
6877
+ imageHandlers.uploadMultipleByURL(imagesToNodes.map(([url]) => url)).then((results) => {
6878
+ applyUploadResultsToNodes(imagesToNodes, results);
6879
+ view.dispatch(view.state.tr.replaceSelection(slice));
6880
+ }).finally(() => {
6881
+ setDisabled(false);
6829
6882
  });
6830
- view.dispatch(view.state.tr.replaceSelection(slice));
6831
- }).finally(() => {
6832
- setDisabled(false);
6833
- });
6883
+ } else {
6884
+ view.dispatch(view.state.tr.replaceSelection(removeImagesFromSlice(slice)));
6885
+ }
6834
6886
  return true;
6835
6887
  }
6836
6888
  }
@@ -7591,7 +7643,7 @@ function getTranslations(lang) {
7591
7643
  }
7592
7644
 
7593
7645
  // src/editor/editor.tsx
7594
- import { Fragment as Fragment4, jsx as jsx92, jsxs as jsxs35 } from "react/jsx-runtime";
7646
+ import { Fragment as Fragment5, jsx as jsx92, jsxs as jsxs35 } from "react/jsx-runtime";
7595
7647
  function TiptapContent({
7596
7648
  content,
7597
7649
  handleChange,
@@ -7607,6 +7659,9 @@ function TiptapContent({
7607
7659
  );
7608
7660
  const [editFigureContext, setEditFigureContext] = useState13(null);
7609
7661
  const [savedDialogCursorPos, setSavedDialogCursorPos] = useState13(void 0);
7662
+ const [savedDialogRange, setSavedDialogRange] = useState13(
7663
+ void 0
7664
+ );
7610
7665
  const { activeDialog, closeDialogCommand, openDialogCommand } = useDialogCommand();
7611
7666
  const translations2 = useTiptapTranslations();
7612
7667
  const [isDisabledInternal, setIsDisabledInternal] = useState13(isDisabled);
@@ -7622,7 +7677,7 @@ function TiptapContent({
7622
7677
  onPaste,
7623
7678
  onDrop,
7624
7679
  onMarkupInsertion
7625
- } = useInsertionHandlers();
7680
+ } = useInsertionHandlers(imageHandlers);
7626
7681
  const editor = useEditor(
7627
7682
  {
7628
7683
  editable: isEditable && !disabled,
@@ -7653,8 +7708,7 @@ function TiptapContent({
7653
7708
  view,
7654
7709
  event,
7655
7710
  slice,
7656
- setIsDisabledInternal,
7657
- imageHandlers?.uploadMultipleByURL
7711
+ setIsDisabledInternal
7658
7712
  );
7659
7713
  if (typeof toReturn === "boolean") return toReturn;
7660
7714
  return false;
@@ -7664,8 +7718,7 @@ function TiptapContent({
7664
7718
  view,
7665
7719
  event,
7666
7720
  slice,
7667
- setIsDisabledInternal,
7668
- imageHandlers?.uploadMultipleByURL
7721
+ setIsDisabledInternal
7669
7722
  );
7670
7723
  if (typeof toReturn === "boolean") return toReturn;
7671
7724
  try {
@@ -7674,7 +7727,7 @@ function TiptapContent({
7674
7727
  const json = JSON.parse(text);
7675
7728
  if (json.type === "doc" && json.content) {
7676
7729
  const node = view.state.schema.nodeFromJSON(json);
7677
- const newSlice = new Slice2(node.content, 0, 0);
7730
+ const newSlice = new Slice3(node.content, 0, 0);
7678
7731
  view.dispatch(view.state.tr.replaceSelection(newSlice));
7679
7732
  return true;
7680
7733
  }
@@ -7691,8 +7744,9 @@ function TiptapContent({
7691
7744
  );
7692
7745
  useEffect11(() => {
7693
7746
  if (activeDialog && editor && !editor.isDestroyed) {
7694
- const pos = editor.state.selection.from;
7695
- setSavedDialogCursorPos(pos);
7747
+ const { from, to } = editor.state.selection;
7748
+ setSavedDialogCursorPos(from);
7749
+ setSavedDialogRange({ from, to });
7696
7750
  }
7697
7751
  }, [activeDialog, editor]);
7698
7752
  const handleCloseDialog = () => {
@@ -7700,6 +7754,7 @@ function TiptapContent({
7700
7754
  setKatexDialogContext(null);
7701
7755
  setEditFigureContext(null);
7702
7756
  setSavedDialogCursorPos(void 0);
7757
+ setSavedDialogRange(void 0);
7703
7758
  closeDialogCommand();
7704
7759
  };
7705
7760
  const handleImageAdd = (attrs) => {
@@ -7710,7 +7765,7 @@ function TiptapContent({
7710
7765
  createHandleVideoAdd(editor, handleCloseDialog, savedDialogCursorPos)(url);
7711
7766
  };
7712
7767
  const handleLinkAdd = (params) => {
7713
- createHandleLinkAdd(editor, handleCloseDialog, params, savedDialogCursorPos);
7768
+ createHandleLinkAdd(editor, handleCloseDialog, params, savedDialogRange);
7714
7769
  };
7715
7770
  const handleKatexAdd = (latex) => {
7716
7771
  const katexHandler = createHandleKatexAdd(editor, handleCloseDialog, savedDialogCursorPos);
@@ -7735,7 +7790,7 @@ function TiptapContent({
7735
7790
  return true;
7736
7791
  };
7737
7792
  if (!editor) return null;
7738
- return /* @__PURE__ */ jsxs35(Fragment4, { children: [
7793
+ return /* @__PURE__ */ jsxs35(Fragment5, { children: [
7739
7794
  /* @__PURE__ */ jsx92(DragHandle, { editor }),
7740
7795
  isEditable && !disabled && /* @__PURE__ */ jsx92(TableMenu, { editor }),
7741
7796
  isEditable && !disabled && /* @__PURE__ */ jsx92(
@@ -7764,7 +7819,7 @@ function TiptapContent({
7764
7819
  }
7765
7820
  ),
7766
7821
  !!error && /* @__PURE__ */ jsx92("p", { className: "tiptap-error-message", children: error }),
7767
- isEditable && /* @__PURE__ */ jsxs35(Fragment4, { children: [
7822
+ isEditable && /* @__PURE__ */ jsxs35(Fragment5, { children: [
7768
7823
  activeDialog === "image" && /* @__PURE__ */ jsx92(
7769
7824
  ImageDialog,
7770
7825
  {