@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.js +126 -71
- package/dist/editor.js.map +1 -1
- package/dist/editor.mjs +128 -73
- package/dist/editor.mjs.map +1 -1
- package/dist/render.js +23 -5
- package/dist/render.js.map +1 -1
- package/dist/render.mjs +24 -6
- package/dist/render.mjs.map +1 -1
- package/package.json +5 -2
- package/src/editor/dialogs/image-dialog/image-dialog.tsx +0 -1
- package/src/editor/editor.tsx +9 -6
- package/src/editor/handlers/dialog-handlers.ts +17 -31
- package/src/editor/handlers/insertion-handlers.ts +21 -39
- package/src/editor/handlers/markup-insertion.test.ts +132 -0
- package/src/editor/handlers/markup-insertion.ts +72 -0
- package/src/extensions/base/link.ts +22 -1
- package/src/utils/image-src-resolver.test.ts +54 -0
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
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
6680
|
+
tr2.setSelection(TextSelection6.near(tr2.doc.resolve($pos.before())));
|
|
6664
6681
|
} else {
|
|
6665
6682
|
tr2.insert(insertPos, imageNode);
|
|
6666
|
-
tr2.setSelection(
|
|
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(
|
|
6707
|
+
tr2.setSelection(TextSelection6.near(tr2.doc.resolve($pos.before())));
|
|
6691
6708
|
} else {
|
|
6692
6709
|
tr2.insert(insertPos, videoNode);
|
|
6693
|
-
tr2.setSelection(
|
|
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,
|
|
6717
|
+
var createHandleLinkAdd = (editor, closeDialogCommand, linkParams, savedRange) => {
|
|
6701
6718
|
if (!editor) return;
|
|
6702
|
-
const
|
|
6703
|
-
const titleLength =
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
}
|
|
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(
|
|
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
|
|
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
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
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
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
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
|
|
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
|
|
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
|
|
7695
|
-
setSavedDialogCursorPos(
|
|
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,
|
|
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(
|
|
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(
|
|
7822
|
+
isEditable && /* @__PURE__ */ jsxs35(Fragment5, { children: [
|
|
7768
7823
|
activeDialog === "image" && /* @__PURE__ */ jsx92(
|
|
7769
7824
|
ImageDialog,
|
|
7770
7825
|
{
|