@mario9/tiptap-editor 0.2.0 → 1.0.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/README.md +99 -56
- package/dist/index.d.ts +28 -31
- package/dist/tiptap-editor.css +1 -1
- package/dist/tiptap-editor.js +985 -950
- package/dist/tiptap-editor.umd.cjs +1 -1
- package/package.json +8 -8
package/dist/tiptap-editor.js
CHANGED
|
@@ -1,255 +1,21 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { TaskList as
|
|
5
|
-
import { TextAlign as
|
|
1
|
+
import { defineComponent as c, createVNode as e, mergeProps as b, inject as H, computed as T, provide as P, watch as R, ref as k, nextTick as z, createTextVNode as m, watchEffect as G, Fragment as de, h as pe } from "vue";
|
|
2
|
+
import Ce from "@tiptap/starter-kit";
|
|
3
|
+
import { useEditor as ve, EditorContent as fe, nodeViewProps as he, NodeViewWrapper as me, VueNodeViewRenderer as ge } from "@tiptap/vue-3";
|
|
4
|
+
import { TaskList as we, TaskItem as be } from "@tiptap/extension-list";
|
|
5
|
+
import { TextAlign as xe } from "@tiptap/extension-text-align";
|
|
6
6
|
import { Placeholder as ke } from "@tiptap/extension-placeholder";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { BubbleMenu as He } from "@tiptap/vue-3/menus";
|
|
8
|
+
import { ElTooltip as D, ElButton as Z, ElPopover as J, ElInput as X, ElDropdown as j, ElDropdownMenu as W, ElDropdownItem as E, ElDialog as Be, ElRadioGroup as ye, ElRadioButton as q } from "element-plus";
|
|
9
9
|
import { Image as Ae } from "@tiptap/extension-image";
|
|
10
|
-
import { Plugin as
|
|
11
|
-
import { Decoration as Le, DecorationSet as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
10
|
+
import { Plugin as Me, NodeSelection as Ie } from "@tiptap/pm/state";
|
|
11
|
+
import { Decoration as Le, DecorationSet as Ee } from "@tiptap/pm/view";
|
|
12
|
+
import { CodeBlockLowlight as Fe } from "@tiptap/extension-code-block-lowlight";
|
|
13
|
+
import { createLowlight as Te, common as Ve } from "lowlight";
|
|
14
|
+
import { TableRow as Ze, TableHeader as De, TableCell as Re, Table as Se } from "@tiptap/extension-table";
|
|
15
|
+
import { Mathematics as Ue } from "@tiptap/extension-mathematics";
|
|
16
16
|
import _e from "katex";
|
|
17
|
-
import {
|
|
18
|
-
const
|
|
19
|
-
addAttributes() {
|
|
20
|
-
return {
|
|
21
|
-
...this.parent?.(),
|
|
22
|
-
align: {
|
|
23
|
-
default: "left",
|
|
24
|
-
parseHTML: (t) => t.getAttribute("data-align") ?? "left",
|
|
25
|
-
renderHTML: (t) => ({ "data-align": t.align })
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
addProseMirrorPlugins() {
|
|
30
|
-
const t = this.name;
|
|
31
|
-
return [
|
|
32
|
-
new Be({
|
|
33
|
-
props: {
|
|
34
|
-
decorations(l) {
|
|
35
|
-
const n = [];
|
|
36
|
-
return l.doc.descendants((o, u) => {
|
|
37
|
-
o.type.name === t && o.attrs.align && n.push(
|
|
38
|
-
Le.node(u, u + o.nodeSize, {
|
|
39
|
-
"data-align": o.attrs.align
|
|
40
|
-
})
|
|
41
|
-
);
|
|
42
|
-
}), Ie.create(l.doc, n);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
];
|
|
47
|
-
}
|
|
48
|
-
}), $e = /* @__PURE__ */ p({
|
|
49
|
-
name: "ImageUploadView",
|
|
50
|
-
props: Ce,
|
|
51
|
-
setup(t) {
|
|
52
|
-
const l = F(() => t.node.attrs.accept), n = F(() => t.node.attrs.limit), o = F(() => t.node.attrs.maxSize), u = y([]), d = y(), f = y(!1), m = async (a) => {
|
|
53
|
-
if (o.value > 0 && a.size > o.value)
|
|
54
|
-
return t.extension.options.onError?.(new Error(`文件大小超出限制 ${o.value / 1024 / 1024}MB`)), null;
|
|
55
|
-
const C = crypto.randomUUID();
|
|
56
|
-
u.value.push({
|
|
57
|
-
id: C,
|
|
58
|
-
file: a,
|
|
59
|
-
progress: 0,
|
|
60
|
-
status: "uploading"
|
|
61
|
-
});
|
|
62
|
-
try {
|
|
63
|
-
const v = t.extension.options.upload;
|
|
64
|
-
if (!v) throw new Error("未配置 upload 函数");
|
|
65
|
-
const h = await v(a);
|
|
66
|
-
if (!h) throw new Error("上传失败:未返回 URL");
|
|
67
|
-
const B = u.value.find((V) => V.id === C);
|
|
68
|
-
return B && (B.status = "success", B.progress = 100), t.extension.options.onSuccess?.(h), h;
|
|
69
|
-
} catch (v) {
|
|
70
|
-
const h = u.value.find((B) => B.id === C);
|
|
71
|
-
return h && (h.status = "error", h.progress = 0), t.extension.options.onError?.(v instanceof Error ? v : new Error("上传失败")), null;
|
|
72
|
-
}
|
|
73
|
-
}, c = async (a) => {
|
|
74
|
-
if (!a.length) return;
|
|
75
|
-
if (a.length > n.value) {
|
|
76
|
-
t.extension.options.onError?.(new Error(`最多上传 ${n.value} 个文件`));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const C = (await Promise.all(a.map(m))).filter((v) => !!v);
|
|
80
|
-
if (C.length > 0) {
|
|
81
|
-
const v = t.getPos();
|
|
82
|
-
if (typeof v != "number") return;
|
|
83
|
-
const h = C.map((B) => ({
|
|
84
|
-
type: "image",
|
|
85
|
-
attrs: {
|
|
86
|
-
src: B
|
|
87
|
-
}
|
|
88
|
-
}));
|
|
89
|
-
t.editor.chain().focus().deleteRange({
|
|
90
|
-
from: v,
|
|
91
|
-
to: v + t.node.nodeSize
|
|
92
|
-
}).insertContentAt(v, h).run();
|
|
93
|
-
}
|
|
94
|
-
}, H = () => {
|
|
95
|
-
u.value.length === 0 && d.value && (d.value.value = "", d.value.click());
|
|
96
|
-
}, i = (a) => {
|
|
97
|
-
const C = a.target.files;
|
|
98
|
-
C && c(Array.from(C));
|
|
99
|
-
}, s = (a) => {
|
|
100
|
-
a.preventDefault(), f.value = !0;
|
|
101
|
-
}, r = (a) => {
|
|
102
|
-
a.currentTarget.contains(a.relatedTarget) || (f.value = !1);
|
|
103
|
-
}, x = (a) => {
|
|
104
|
-
a.preventDefault(), f.value = !1;
|
|
105
|
-
const C = Array.from(a.dataTransfer?.files ?? []);
|
|
106
|
-
C.length && c(C);
|
|
107
|
-
}, k = (a) => {
|
|
108
|
-
u.value = u.value.filter((C) => C.id !== a);
|
|
109
|
-
};
|
|
110
|
-
return () => e(ve, {
|
|
111
|
-
class: "tiptap-image-upload"
|
|
112
|
-
}, {
|
|
113
|
-
default: () => [e("div", {
|
|
114
|
-
onClick: H
|
|
115
|
-
}, [u.value.length ? e("div", {
|
|
116
|
-
class: "tiptap-image-upload-previews"
|
|
117
|
-
}, [u.value.map((a) => e("div", {
|
|
118
|
-
key: a.id,
|
|
119
|
-
class: "tiptap-image-upload-preview"
|
|
120
|
-
}, [a.status === "uploading" && e("div", {
|
|
121
|
-
class: "tiptap-image-upload-progress",
|
|
122
|
-
style: {
|
|
123
|
-
width: `${a.progress}%`
|
|
124
|
-
}
|
|
125
|
-
}, null), e("div", {
|
|
126
|
-
class: "tiptap-image-upload-preview-content"
|
|
127
|
-
}, [e("span", {
|
|
128
|
-
class: "tiptap-image-upload-text"
|
|
129
|
-
}, [a.file.name]), e("span", {
|
|
130
|
-
class: "tiptap-image-upload-subtext"
|
|
131
|
-
}, [a.status === "uploading" ? `${a.progress}%` : a.status === "error" ? "上传失败" : "上传成功"]), e("button", {
|
|
132
|
-
class: "tiptap-image-upload-remove",
|
|
133
|
-
onClick: (C) => {
|
|
134
|
-
C.stopPropagation(), k(a.id);
|
|
135
|
-
}
|
|
136
|
-
}, [g("×")])])]))]) : e("div", {
|
|
137
|
-
class: ["tiptap-image-upload-drag-area", {
|
|
138
|
-
"drag-active": f.value
|
|
139
|
-
}],
|
|
140
|
-
onDragover: s,
|
|
141
|
-
onDragleave: r,
|
|
142
|
-
onDrop: x
|
|
143
|
-
}, [e("div", {
|
|
144
|
-
class: "tiptap-image-upload-content"
|
|
145
|
-
}, [e("span", {
|
|
146
|
-
class: "tiptap-image-upload-text"
|
|
147
|
-
}, [e("em", null, [g("点击上传")]), g(" 或拖拽图片到此处")]), e("span", {
|
|
148
|
-
class: "tiptap-image-upload-subtext"
|
|
149
|
-
}, [g("最多 "), n.value, g(" 个文件"), o.value ? `,每个不超过 ${o.value / 1024 / 1024}MB` : ""])])]), e("input", {
|
|
150
|
-
ref: d,
|
|
151
|
-
type: "file",
|
|
152
|
-
accept: l.value,
|
|
153
|
-
multiple: n.value > 1,
|
|
154
|
-
onChange: i,
|
|
155
|
-
onClick: (a) => a.stopPropagation()
|
|
156
|
-
}, null)])]
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}), ze = Re.create({
|
|
160
|
-
name: "imageUpload",
|
|
161
|
-
group: "block",
|
|
162
|
-
draggable: !0,
|
|
163
|
-
selectable: !0,
|
|
164
|
-
atom: !0,
|
|
165
|
-
addOptions() {
|
|
166
|
-
return {
|
|
167
|
-
type: "image",
|
|
168
|
-
accept: "image/*",
|
|
169
|
-
limit: 1,
|
|
170
|
-
maxSize: 0,
|
|
171
|
-
upload: (t) => new Promise((l) => {
|
|
172
|
-
const n = new FileReader();
|
|
173
|
-
n.onloadend = () => l(n.result), n.readAsDataURL(t);
|
|
174
|
-
}),
|
|
175
|
-
onError: void 0,
|
|
176
|
-
onSuccess: void 0,
|
|
177
|
-
HTMLAttributes: {}
|
|
178
|
-
};
|
|
179
|
-
},
|
|
180
|
-
addAttributes() {
|
|
181
|
-
return {
|
|
182
|
-
accept: {
|
|
183
|
-
default: this.options.accept
|
|
184
|
-
},
|
|
185
|
-
limit: {
|
|
186
|
-
default: this.options.limit
|
|
187
|
-
},
|
|
188
|
-
maxSize: {
|
|
189
|
-
default: this.options.maxSize
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
},
|
|
193
|
-
parseHTML() {
|
|
194
|
-
return [{
|
|
195
|
-
tag: 'div[data-type="image-upload"]'
|
|
196
|
-
}];
|
|
197
|
-
},
|
|
198
|
-
renderHTML({
|
|
199
|
-
HTMLAttributes: t
|
|
200
|
-
}) {
|
|
201
|
-
return ["div", De({
|
|
202
|
-
"data-type": "image-upload"
|
|
203
|
-
}, t)];
|
|
204
|
-
},
|
|
205
|
-
addNodeView() {
|
|
206
|
-
return fe($e);
|
|
207
|
-
},
|
|
208
|
-
addCommands() {
|
|
209
|
-
return {
|
|
210
|
-
setImageUploadNode: () => ({
|
|
211
|
-
commands: t
|
|
212
|
-
}) => t.insertContent({
|
|
213
|
-
type: this.name
|
|
214
|
-
})
|
|
215
|
-
};
|
|
216
|
-
},
|
|
217
|
-
addKeyboardShortcuts() {
|
|
218
|
-
return {
|
|
219
|
-
Enter: ({
|
|
220
|
-
editor: t
|
|
221
|
-
}) => {
|
|
222
|
-
const {
|
|
223
|
-
selection: l
|
|
224
|
-
} = t.state, {
|
|
225
|
-
nodeAfter: n
|
|
226
|
-
} = l.$from;
|
|
227
|
-
if (n?.type.name === "imageUpload" && t.isActive("imageUpload")) {
|
|
228
|
-
const o = t.view.nodeDOM(l.$from.pos);
|
|
229
|
-
if (o instanceof HTMLElement) {
|
|
230
|
-
const u = o.firstChild;
|
|
231
|
-
if (u instanceof HTMLElement)
|
|
232
|
-
return u.click(), !0;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return !1;
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
}), Ne = [
|
|
240
|
-
"undo-redo",
|
|
241
|
-
"|",
|
|
242
|
-
"text-style",
|
|
243
|
-
"code-block",
|
|
244
|
-
"|",
|
|
245
|
-
"list",
|
|
246
|
-
"|",
|
|
247
|
-
"text-align",
|
|
248
|
-
"|",
|
|
249
|
-
"image",
|
|
250
|
-
"table",
|
|
251
|
-
"math"
|
|
252
|
-
], je = {
|
|
17
|
+
import { Node as Pe, mergeAttributes as ze } from "@tiptap/core";
|
|
18
|
+
const Oe = {
|
|
253
19
|
icon: {
|
|
254
20
|
type: Object,
|
|
255
21
|
required: !0
|
|
@@ -268,11 +34,11 @@ const Pe = Ae.extend({
|
|
|
268
34
|
onClick: {
|
|
269
35
|
type: Function
|
|
270
36
|
}
|
|
271
|
-
}, w = /* @__PURE__ */
|
|
37
|
+
}, w = /* @__PURE__ */ c({
|
|
272
38
|
name: "IconButton",
|
|
273
|
-
props:
|
|
39
|
+
props: Oe,
|
|
274
40
|
setup(t) {
|
|
275
|
-
return () => e(
|
|
41
|
+
return () => e(D, {
|
|
276
42
|
showArrow: !1,
|
|
277
43
|
offset: 6,
|
|
278
44
|
content: t.tooltip
|
|
@@ -288,7 +54,242 @@ const Pe = Ae.extend({
|
|
|
288
54
|
}, null)]
|
|
289
55
|
});
|
|
290
56
|
}
|
|
291
|
-
}),
|
|
57
|
+
}), Q = /* @__PURE__ */ c({
|
|
58
|
+
name: "BoldIcon",
|
|
59
|
+
setup(t, {
|
|
60
|
+
attrs: l
|
|
61
|
+
}) {
|
|
62
|
+
return () => e("svg", b({
|
|
63
|
+
width: "24",
|
|
64
|
+
height: "24",
|
|
65
|
+
viewBox: "0 0 24 24",
|
|
66
|
+
fill: "currentColor",
|
|
67
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
68
|
+
}, l), [e("path", {
|
|
69
|
+
"fill-rule": "evenodd",
|
|
70
|
+
"clip-rule": "evenodd",
|
|
71
|
+
d: "M6 2.5C5.17157 2.5 4.5 3.17157 4.5 4V20C4.5 20.8284 5.17157 21.5 6 21.5H15C16.4587 21.5 17.8576 20.9205 18.8891 19.8891C19.9205 18.8576 20.5 17.4587 20.5 16C20.5 14.5413 19.9205 13.1424 18.8891 12.1109C18.6781 11.9 18.4518 11.7079 18.2128 11.5359C19.041 10.5492 19.5 9.29829 19.5 8C19.5 6.54131 18.9205 5.14236 17.8891 4.11091C16.8576 3.07946 15.4587 2.5 14 2.5H6ZM14 10.5C14.663 10.5 15.2989 10.2366 15.7678 9.76777C16.2366 9.29893 16.5 8.66304 16.5 8C16.5 7.33696 16.2366 6.70107 15.7678 6.23223C15.2989 5.76339 14.663 5.5 14 5.5H7.5V10.5H14ZM7.5 18.5V13.5H15C15.663 13.5 16.2989 13.7634 16.7678 14.2322C17.2366 14.7011 17.5 15.337 17.5 16C17.5 16.663 17.2366 17.2989 16.7678 17.7678C16.2989 18.2366 15.663 18.5 15 18.5H7.5Z",
|
|
72
|
+
fill: "currentColor"
|
|
73
|
+
}, null)]);
|
|
74
|
+
}
|
|
75
|
+
}), Y = /* @__PURE__ */ c({
|
|
76
|
+
name: "ItalicIcon",
|
|
77
|
+
setup(t, {
|
|
78
|
+
attrs: l
|
|
79
|
+
}) {
|
|
80
|
+
return () => e("svg", b({
|
|
81
|
+
width: "24",
|
|
82
|
+
height: "24",
|
|
83
|
+
viewBox: "0 0 24 24",
|
|
84
|
+
fill: "currentColor",
|
|
85
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
86
|
+
}, l), [e("path", {
|
|
87
|
+
d: "M15.0222 3H19C19.5523 3 20 3.44772 20 4C20 4.55228 19.5523 5 19 5H15.693L10.443 19H14C14.5523 19 15 19.4477 15 20C15 20.5523 14.5523 21 14 21H9.02418C9.00802 21.0004 8.99181 21.0004 8.97557 21H5C4.44772 21 4 20.5523 4 20C4 19.4477 4.44772 19 5 19H8.30704L13.557 5H10C9.44772 5 9 4.55228 9 4C9 3.44772 9.44772 3 10 3H14.9782C14.9928 2.99968 15.0075 2.99967 15.0222 3Z",
|
|
88
|
+
fill: "currentColor"
|
|
89
|
+
}, null)]);
|
|
90
|
+
}
|
|
91
|
+
}), ee = /* @__PURE__ */ c({
|
|
92
|
+
name: "StrikeIcon",
|
|
93
|
+
setup(t, {
|
|
94
|
+
attrs: l
|
|
95
|
+
}) {
|
|
96
|
+
return () => e("svg", b({
|
|
97
|
+
width: "24",
|
|
98
|
+
height: "24",
|
|
99
|
+
viewBox: "0 0 24 24",
|
|
100
|
+
fill: "currentColor",
|
|
101
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
102
|
+
}, l), [e("path", {
|
|
103
|
+
d: "M9.00039 3H16.0001C16.5524 3 17.0001 3.44772 17.0001 4C17.0001 4.55229 16.5524 5 16.0001 5H9.00011C8.68006 4.99983 8.36412 5.07648 8.07983 5.22349C7.79555 5.37051 7.55069 5.5836 7.36585 5.84487C7.181 6.10614 7.06155 6.40796 7.01754 6.72497C6.97352 7.04198 7.00623 7.36492 7.11292 7.66667C7.29701 8.18737 7.02414 8.75872 6.50344 8.94281C5.98274 9.1269 5.4114 8.85403 5.2273 8.33333C5.01393 7.72984 4.94851 7.08396 5.03654 6.44994C5.12456 5.81592 5.36346 5.21229 5.73316 4.68974C6.10285 4.1672 6.59256 3.74101 7.16113 3.44698C7.72955 3.15303 8.36047 2.99975 9.00039 3Z",
|
|
104
|
+
fill: "currentColor"
|
|
105
|
+
}, null), e("path", {
|
|
106
|
+
d: "M18 13H20C20.5523 13 21 12.5523 21 12C21 11.4477 20.5523 11 20 11H4C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13H14C14.7956 13 15.5587 13.3161 16.1213 13.8787C16.6839 14.4413 17 15.2044 17 16C17 16.7956 16.6839 17.5587 16.1213 18.1213C15.5587 18.6839 14.7956 19 14 19H6C5.44772 19 5 19.4477 5 20C5 20.5523 5.44772 21 6 21H14C15.3261 21 16.5979 20.4732 17.5355 19.5355C18.4732 18.5979 19 17.3261 19 16C19 14.9119 18.6453 13.8604 18 13Z",
|
|
107
|
+
fill: "currentColor"
|
|
108
|
+
}, null)]);
|
|
109
|
+
}
|
|
110
|
+
}), te = /* @__PURE__ */ c({
|
|
111
|
+
name: "UnderlineIcon",
|
|
112
|
+
setup(t, {
|
|
113
|
+
attrs: l
|
|
114
|
+
}) {
|
|
115
|
+
return () => e("svg", b({
|
|
116
|
+
width: "24",
|
|
117
|
+
height: "24",
|
|
118
|
+
viewBox: "0 0 24 24",
|
|
119
|
+
fill: "currentColor",
|
|
120
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
121
|
+
}, l), [e("path", {
|
|
122
|
+
"fill-rule": "evenodd",
|
|
123
|
+
"clip-rule": "evenodd",
|
|
124
|
+
d: "M7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4V10C5 11.8565 5.7375 13.637 7.05025 14.9497C8.36301 16.2625 10.1435 17 12 17C13.8565 17 15.637 16.2625 16.9497 14.9497C18.2625 13.637 19 11.8565 19 10V4C19 3.44772 18.5523 3 18 3C17.4477 3 17 3.44772 17 4V10C17 11.3261 16.4732 12.5979 15.5355 13.5355C14.5979 14.4732 13.3261 15 12 15C10.6739 15 9.40215 14.4732 8.46447 13.5355C7.52678 12.5979 7 11.3261 7 10V4ZM4 19C3.44772 19 3 19.4477 3 20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20C21 19.4477 20.5523 19 20 19H4Z",
|
|
125
|
+
fill: "currentColor"
|
|
126
|
+
}, null)]);
|
|
127
|
+
}
|
|
128
|
+
}), $e = /* @__PURE__ */ c({
|
|
129
|
+
name: "BubbleMenuBar",
|
|
130
|
+
setup() {
|
|
131
|
+
const t = H("editor"), l = H("readonly");
|
|
132
|
+
return () => t?.value ? e(He, {
|
|
133
|
+
editor: t.value,
|
|
134
|
+
class: "bubble-menu",
|
|
135
|
+
options: {
|
|
136
|
+
placement: "top",
|
|
137
|
+
offset: {
|
|
138
|
+
mainAxis: 8
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
shouldShow: (n) => {
|
|
142
|
+
if (l?.value) return !1;
|
|
143
|
+
const {
|
|
144
|
+
editor: o,
|
|
145
|
+
from: i,
|
|
146
|
+
to: r
|
|
147
|
+
} = n;
|
|
148
|
+
return !(i === r || o.isActive("image") || o.isActive("table"));
|
|
149
|
+
}
|
|
150
|
+
}, {
|
|
151
|
+
default: () => [e("div", {
|
|
152
|
+
class: "bubble-menu-content"
|
|
153
|
+
}, [e(w, {
|
|
154
|
+
icon: Q,
|
|
155
|
+
tooltip: "粗体",
|
|
156
|
+
isActive: t.value.isActive("bold"),
|
|
157
|
+
onClick: () => t.value?.chain().focus().toggleBold().run()
|
|
158
|
+
}, null), e(w, {
|
|
159
|
+
icon: Y,
|
|
160
|
+
tooltip: "斜体",
|
|
161
|
+
isActive: t.value.isActive("italic"),
|
|
162
|
+
onClick: () => t.value?.chain().focus().toggleItalic().run()
|
|
163
|
+
}, null), e(w, {
|
|
164
|
+
icon: ee,
|
|
165
|
+
tooltip: "删除线",
|
|
166
|
+
isActive: t.value.isActive("strike"),
|
|
167
|
+
onClick: () => t.value?.chain().focus().toggleStrike().run()
|
|
168
|
+
}, null), e(w, {
|
|
169
|
+
icon: te,
|
|
170
|
+
tooltip: "下划线",
|
|
171
|
+
isActive: t.value.isActive("underline"),
|
|
172
|
+
onClick: () => t.value?.chain().focus().toggleUnderline().run()
|
|
173
|
+
}, null)])]
|
|
174
|
+
}) : null;
|
|
175
|
+
}
|
|
176
|
+
}), qt = /* @__PURE__ */ c({
|
|
177
|
+
name: "TiptapEditor",
|
|
178
|
+
props: {
|
|
179
|
+
modelValue: {
|
|
180
|
+
type: String,
|
|
181
|
+
default: ""
|
|
182
|
+
},
|
|
183
|
+
placeholder: {
|
|
184
|
+
type: String,
|
|
185
|
+
default: "请输入内容..."
|
|
186
|
+
},
|
|
187
|
+
readonly: {
|
|
188
|
+
type: Boolean,
|
|
189
|
+
default: !1
|
|
190
|
+
},
|
|
191
|
+
features: {
|
|
192
|
+
type: Array,
|
|
193
|
+
default: () => []
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
emits: ["update:modelValue"],
|
|
197
|
+
setup(t, {
|
|
198
|
+
emit: l
|
|
199
|
+
}) {
|
|
200
|
+
const n = T(() => t.readonly ?? !1);
|
|
201
|
+
P("readonly", n);
|
|
202
|
+
const o = t.features.map((r) => ({
|
|
203
|
+
plugin: r,
|
|
204
|
+
result: r.install({
|
|
205
|
+
readonly: n,
|
|
206
|
+
provide: (v, p) => P(v, p)
|
|
207
|
+
})
|
|
208
|
+
})), i = ve({
|
|
209
|
+
content: t.modelValue,
|
|
210
|
+
editable: !t.readonly,
|
|
211
|
+
extensions: [Ce.configure({
|
|
212
|
+
codeBlock: !1,
|
|
213
|
+
link: {
|
|
214
|
+
openOnClick: !1,
|
|
215
|
+
enableClickSelection: !0
|
|
216
|
+
}
|
|
217
|
+
}), ke.configure({
|
|
218
|
+
placeholder: t.placeholder
|
|
219
|
+
}), xe.configure({
|
|
220
|
+
types: ["heading", "paragraph"]
|
|
221
|
+
}), we, be.configure({
|
|
222
|
+
nested: !0
|
|
223
|
+
}), ...o.flatMap(({
|
|
224
|
+
result: r
|
|
225
|
+
}) => r.extensions)],
|
|
226
|
+
onUpdate: ({
|
|
227
|
+
editor: r
|
|
228
|
+
}) => {
|
|
229
|
+
l("update:modelValue", r.getHTML());
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
return P("editor", i), R(() => t.modelValue, (r) => {
|
|
233
|
+
i.value && r !== i.value.getHTML() && i.value.commands.setContent(r, {
|
|
234
|
+
emitUpdate: !1
|
|
235
|
+
});
|
|
236
|
+
}), R(() => t.readonly, (r) => {
|
|
237
|
+
i.value?.setEditable(!r);
|
|
238
|
+
}), () => e("div", {
|
|
239
|
+
class: "tiptap-editor"
|
|
240
|
+
}, [!t.readonly && e("div", {
|
|
241
|
+
class: "tiptap-toolbar"
|
|
242
|
+
}, [o.map(({
|
|
243
|
+
plugin: r
|
|
244
|
+
}) => {
|
|
245
|
+
const v = r.toolbarComponent;
|
|
246
|
+
return v ? e(v, {
|
|
247
|
+
key: r.name
|
|
248
|
+
}, null) : null;
|
|
249
|
+
})]), e(fe, {
|
|
250
|
+
class: "tiptap-content",
|
|
251
|
+
editor: i.value
|
|
252
|
+
}, null), e($e, null, null), o.map(({
|
|
253
|
+
plugin: r,
|
|
254
|
+
result: v
|
|
255
|
+
}) => {
|
|
256
|
+
const p = v.controlComponent;
|
|
257
|
+
return p ? e(p, {
|
|
258
|
+
key: `${r.name}-control`
|
|
259
|
+
}, null) : null;
|
|
260
|
+
})]);
|
|
261
|
+
}
|
|
262
|
+
}), Ne = Ae.extend({
|
|
263
|
+
addAttributes() {
|
|
264
|
+
return {
|
|
265
|
+
...this.parent?.(),
|
|
266
|
+
align: {
|
|
267
|
+
default: "left",
|
|
268
|
+
parseHTML: (t) => t.getAttribute("data-align") ?? "left",
|
|
269
|
+
renderHTML: (t) => ({ "data-align": t.align })
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
},
|
|
273
|
+
addProseMirrorPlugins() {
|
|
274
|
+
const t = this.name;
|
|
275
|
+
return [
|
|
276
|
+
new Me({
|
|
277
|
+
props: {
|
|
278
|
+
decorations(l) {
|
|
279
|
+
const n = [];
|
|
280
|
+
return l.doc.descendants((o, i) => {
|
|
281
|
+
o.type.name === t && o.attrs.align && n.push(
|
|
282
|
+
Le.node(i, i + o.nodeSize, {
|
|
283
|
+
"data-align": o.attrs.align
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
}), Ee.create(l.doc, n);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
}), je = /* @__PURE__ */ c({
|
|
292
293
|
name: "UndoIcon",
|
|
293
294
|
setup(t, {
|
|
294
295
|
attrs: l
|
|
@@ -306,7 +307,7 @@ const Pe = Ae.extend({
|
|
|
306
307
|
fill: "currentColor"
|
|
307
308
|
}, null)]);
|
|
308
309
|
}
|
|
309
|
-
}),
|
|
310
|
+
}), We = /* @__PURE__ */ c({
|
|
310
311
|
name: "RedoIcon",
|
|
311
312
|
setup(t, {
|
|
312
313
|
attrs: l
|
|
@@ -324,23 +325,27 @@ const Pe = Ae.extend({
|
|
|
324
325
|
fill: "currentColor"
|
|
325
326
|
}, null)]);
|
|
326
327
|
}
|
|
327
|
-
}),
|
|
328
|
+
}), qe = /* @__PURE__ */ c({
|
|
328
329
|
name: "UndoRedoButton",
|
|
329
330
|
setup() {
|
|
330
|
-
const t =
|
|
331
|
+
const t = H("editor"), l = T(() => t?.value?.can().undo() ?? !1), n = T(() => t?.value?.can().redo() ?? !1);
|
|
331
332
|
return () => e("div", null, [e(w, {
|
|
332
|
-
icon:
|
|
333
|
+
icon: je,
|
|
333
334
|
tooltip: "撤销",
|
|
334
335
|
disabled: !l.value,
|
|
335
336
|
onClick: () => t?.value?.chain().focus().undo().run()
|
|
336
337
|
}, null), e(w, {
|
|
337
|
-
icon:
|
|
338
|
+
icon: We,
|
|
338
339
|
tooltip: "重做",
|
|
339
340
|
disabled: !n.value,
|
|
340
341
|
onClick: () => t?.value?.chain().focus().redo().run()
|
|
341
342
|
}, null)]);
|
|
342
343
|
}
|
|
343
|
-
}),
|
|
344
|
+
}), Kt = {
|
|
345
|
+
name: "undo-redo",
|
|
346
|
+
install: () => ({ extensions: [] }),
|
|
347
|
+
toolbarComponent: qe
|
|
348
|
+
}, Ke = /* @__PURE__ */ c({
|
|
344
349
|
name: "LinkIcon",
|
|
345
350
|
setup(t, {
|
|
346
351
|
attrs: l
|
|
@@ -359,7 +364,7 @@ const Pe = Ae.extend({
|
|
|
359
364
|
fill: "currentColor"
|
|
360
365
|
}, null)]);
|
|
361
366
|
}
|
|
362
|
-
}),
|
|
367
|
+
}), Ge = /* @__PURE__ */ c({
|
|
363
368
|
name: "CornerDownLeftIcon",
|
|
364
369
|
setup(t, {
|
|
365
370
|
attrs: l
|
|
@@ -380,7 +385,7 @@ const Pe = Ae.extend({
|
|
|
380
385
|
d: "M20 4v7a4 4 0 0 1-4 4H4"
|
|
381
386
|
}, null)]);
|
|
382
387
|
}
|
|
383
|
-
}),
|
|
388
|
+
}), Je = /* @__PURE__ */ c({
|
|
384
389
|
name: "ExternalLinkIcon",
|
|
385
390
|
setup(t, {
|
|
386
391
|
attrs: l
|
|
@@ -406,7 +411,7 @@ const Pe = Ae.extend({
|
|
|
406
411
|
y2: "3"
|
|
407
412
|
}, null)]);
|
|
408
413
|
}
|
|
409
|
-
}),
|
|
414
|
+
}), Xe = /* @__PURE__ */ c({
|
|
410
415
|
name: "TrashIcon",
|
|
411
416
|
setup(t, {
|
|
412
417
|
attrs: l
|
|
@@ -427,52 +432,52 @@ const Pe = Ae.extend({
|
|
|
427
432
|
d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
|
|
428
433
|
}, null)]);
|
|
429
434
|
}
|
|
430
|
-
}),
|
|
435
|
+
}), Qe = /* @__PURE__ */ c({
|
|
431
436
|
name: "LinkPopover",
|
|
432
437
|
setup() {
|
|
433
|
-
const t =
|
|
438
|
+
const t = H("editor"), l = k(!1), n = k("");
|
|
434
439
|
let o = !1;
|
|
435
|
-
|
|
436
|
-
o ||
|
|
440
|
+
R(() => t?.value?.isActive("link"), (u) => {
|
|
441
|
+
o || u && (n.value = t?.value?.getAttributes("link").href ?? "", z(() => {
|
|
437
442
|
l.value = !0;
|
|
438
443
|
}));
|
|
439
444
|
});
|
|
440
|
-
const
|
|
441
|
-
const
|
|
442
|
-
if (!
|
|
445
|
+
const i = () => {
|
|
446
|
+
const u = t?.value;
|
|
447
|
+
if (!u || !n.value) return;
|
|
443
448
|
o = !0;
|
|
444
449
|
const {
|
|
445
|
-
empty:
|
|
446
|
-
} =
|
|
447
|
-
let
|
|
450
|
+
empty: C
|
|
451
|
+
} = u.state.selection;
|
|
452
|
+
let g = u.chain().focus().extendMarkRange("link").setLink({
|
|
448
453
|
href: n.value
|
|
449
454
|
});
|
|
450
|
-
|
|
455
|
+
C && (g = g.insertContent({
|
|
451
456
|
type: "text",
|
|
452
457
|
text: n.value
|
|
453
|
-
})),
|
|
458
|
+
})), g.run(), l.value = !1, z(() => {
|
|
454
459
|
o = !1;
|
|
455
460
|
});
|
|
456
|
-
},
|
|
457
|
-
const
|
|
458
|
-
|
|
461
|
+
}, r = () => {
|
|
462
|
+
const u = t?.value;
|
|
463
|
+
u && (o = !0, u.chain().focus().extendMarkRange("link").unsetLink().run(), n.value = "", l.value = !1, z(() => {
|
|
459
464
|
o = !1;
|
|
460
465
|
}));
|
|
461
|
-
},
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
},
|
|
465
|
-
|
|
466
|
-
},
|
|
467
|
-
|
|
468
|
-
},
|
|
469
|
-
n.value =
|
|
466
|
+
}, v = () => {
|
|
467
|
+
const u = t?.value?.getAttributes("link").href;
|
|
468
|
+
u && window.open(u, "_blank", "noopener,noreferrer");
|
|
469
|
+
}, p = (u) => {
|
|
470
|
+
u.key === "Enter" && (u.preventDefault(), i());
|
|
471
|
+
}, s = (u) => {
|
|
472
|
+
u && (n.value = t?.value?.getAttributes("link").href ?? ""), l.value = u;
|
|
473
|
+
}, y = (u) => {
|
|
474
|
+
n.value = u;
|
|
470
475
|
};
|
|
471
476
|
return () => {
|
|
472
|
-
const
|
|
477
|
+
const u = t?.value?.isActive("link") ?? !1;
|
|
473
478
|
return e(J, {
|
|
474
479
|
visible: l.value,
|
|
475
|
-
"onUpdate:visible":
|
|
480
|
+
"onUpdate:visible": s,
|
|
476
481
|
placement: "bottom",
|
|
477
482
|
width: 300,
|
|
478
483
|
trigger: "click",
|
|
@@ -484,133 +489,62 @@ const Pe = Ae.extend({
|
|
|
484
489
|
tooltip: "链接",
|
|
485
490
|
icon: Ke,
|
|
486
491
|
class: ["tiptap-button", {
|
|
487
|
-
"is-active":
|
|
492
|
+
"is-active": u
|
|
488
493
|
}]
|
|
489
494
|
}, null)]),
|
|
490
495
|
default: () => e("div", {
|
|
491
496
|
class: "link-popover-inner"
|
|
492
497
|
}, [e(X, {
|
|
493
498
|
modelValue: n.value,
|
|
494
|
-
"onUpdate:modelValue":
|
|
499
|
+
"onUpdate:modelValue": y,
|
|
495
500
|
type: "url",
|
|
496
501
|
placeholder: "请输入链接...",
|
|
497
502
|
size: "small",
|
|
498
503
|
autofocus: !0,
|
|
499
|
-
onKeydown:
|
|
504
|
+
onKeydown: p
|
|
500
505
|
}, null), e("div", {
|
|
501
506
|
class: "link-popover-actions"
|
|
502
|
-
}, [e(
|
|
507
|
+
}, [e(D, {
|
|
503
508
|
content: "确认",
|
|
504
509
|
showArrow: !1,
|
|
505
510
|
offset: 4
|
|
506
511
|
}, {
|
|
507
512
|
default: () => [e(Z, {
|
|
508
513
|
text: !0,
|
|
509
|
-
icon:
|
|
514
|
+
icon: Ge,
|
|
510
515
|
disabled: !n.value,
|
|
511
|
-
onClick:
|
|
516
|
+
onClick: i
|
|
512
517
|
}, null)]
|
|
513
|
-
}), e(
|
|
518
|
+
}), e(D, {
|
|
514
519
|
content: "在新标签页打开",
|
|
515
520
|
showArrow: !1,
|
|
516
521
|
offset: 4
|
|
517
522
|
}, {
|
|
518
523
|
default: () => [e(Z, {
|
|
519
524
|
text: !0,
|
|
520
|
-
icon:
|
|
521
|
-
disabled: !n.value && !
|
|
522
|
-
onClick:
|
|
525
|
+
icon: Je,
|
|
526
|
+
disabled: !n.value && !u,
|
|
527
|
+
onClick: v
|
|
523
528
|
}, null)]
|
|
524
|
-
}), e(
|
|
529
|
+
}), e(D, {
|
|
525
530
|
content: "移除链接",
|
|
526
531
|
showArrow: !1,
|
|
527
532
|
offset: 4
|
|
528
533
|
}, {
|
|
529
534
|
default: () => [e(Z, {
|
|
530
535
|
text: !0,
|
|
531
|
-
icon:
|
|
532
|
-
disabled: !
|
|
533
|
-
onClick:
|
|
536
|
+
icon: Xe,
|
|
537
|
+
disabled: !u,
|
|
538
|
+
onClick: r
|
|
534
539
|
}, null)]
|
|
535
540
|
})])])
|
|
536
541
|
});
|
|
537
542
|
};
|
|
538
543
|
}
|
|
539
|
-
}),
|
|
540
|
-
name: "BoldIcon",
|
|
541
|
-
setup(t, {
|
|
542
|
-
attrs: l
|
|
543
|
-
}) {
|
|
544
|
-
return () => e("svg", b({
|
|
545
|
-
width: "24",
|
|
546
|
-
height: "24",
|
|
547
|
-
viewBox: "0 0 24 24",
|
|
548
|
-
fill: "currentColor",
|
|
549
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
550
|
-
}, l), [e("path", {
|
|
551
|
-
"fill-rule": "evenodd",
|
|
552
|
-
"clip-rule": "evenodd",
|
|
553
|
-
d: "M6 2.5C5.17157 2.5 4.5 3.17157 4.5 4V20C4.5 20.8284 5.17157 21.5 6 21.5H15C16.4587 21.5 17.8576 20.9205 18.8891 19.8891C19.9205 18.8576 20.5 17.4587 20.5 16C20.5 14.5413 19.9205 13.1424 18.8891 12.1109C18.6781 11.9 18.4518 11.7079 18.2128 11.5359C19.041 10.5492 19.5 9.29829 19.5 8C19.5 6.54131 18.9205 5.14236 17.8891 4.11091C16.8576 3.07946 15.4587 2.5 14 2.5H6ZM14 10.5C14.663 10.5 15.2989 10.2366 15.7678 9.76777C16.2366 9.29893 16.5 8.66304 16.5 8C16.5 7.33696 16.2366 6.70107 15.7678 6.23223C15.2989 5.76339 14.663 5.5 14 5.5H7.5V10.5H14ZM7.5 18.5V13.5H15C15.663 13.5 16.2989 13.7634 16.7678 14.2322C17.2366 14.7011 17.5 15.337 17.5 16C17.5 16.663 17.2366 17.2989 16.7678 17.7678C16.2989 18.2366 15.663 18.5 15 18.5H7.5Z",
|
|
554
|
-
fill: "currentColor"
|
|
555
|
-
}, null)]);
|
|
556
|
-
}
|
|
557
|
-
}), Y = /* @__PURE__ */ p({
|
|
558
|
-
name: "ItalicIcon",
|
|
559
|
-
setup(t, {
|
|
560
|
-
attrs: l
|
|
561
|
-
}) {
|
|
562
|
-
return () => e("svg", b({
|
|
563
|
-
width: "24",
|
|
564
|
-
height: "24",
|
|
565
|
-
viewBox: "0 0 24 24",
|
|
566
|
-
fill: "currentColor",
|
|
567
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
568
|
-
}, l), [e("path", {
|
|
569
|
-
d: "M15.0222 3H19C19.5523 3 20 3.44772 20 4C20 4.55228 19.5523 5 19 5H15.693L10.443 19H14C14.5523 19 15 19.4477 15 20C15 20.5523 14.5523 21 14 21H9.02418C9.00802 21.0004 8.99181 21.0004 8.97557 21H5C4.44772 21 4 20.5523 4 20C4 19.4477 4.44772 19 5 19H8.30704L13.557 5H10C9.44772 5 9 4.55228 9 4C9 3.44772 9.44772 3 10 3H14.9782C14.9928 2.99968 15.0075 2.99967 15.0222 3Z",
|
|
570
|
-
fill: "currentColor"
|
|
571
|
-
}, null)]);
|
|
572
|
-
}
|
|
573
|
-
}), ee = /* @__PURE__ */ p({
|
|
574
|
-
name: "StrikeIcon",
|
|
575
|
-
setup(t, {
|
|
576
|
-
attrs: l
|
|
577
|
-
}) {
|
|
578
|
-
return () => e("svg", b({
|
|
579
|
-
width: "24",
|
|
580
|
-
height: "24",
|
|
581
|
-
viewBox: "0 0 24 24",
|
|
582
|
-
fill: "currentColor",
|
|
583
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
584
|
-
}, l), [e("path", {
|
|
585
|
-
d: "M9.00039 3H16.0001C16.5524 3 17.0001 3.44772 17.0001 4C17.0001 4.55229 16.5524 5 16.0001 5H9.00011C8.68006 4.99983 8.36412 5.07648 8.07983 5.22349C7.79555 5.37051 7.55069 5.5836 7.36585 5.84487C7.181 6.10614 7.06155 6.40796 7.01754 6.72497C6.97352 7.04198 7.00623 7.36492 7.11292 7.66667C7.29701 8.18737 7.02414 8.75872 6.50344 8.94281C5.98274 9.1269 5.4114 8.85403 5.2273 8.33333C5.01393 7.72984 4.94851 7.08396 5.03654 6.44994C5.12456 5.81592 5.36346 5.21229 5.73316 4.68974C6.10285 4.1672 6.59256 3.74101 7.16113 3.44698C7.72955 3.15303 8.36047 2.99975 9.00039 3Z",
|
|
586
|
-
fill: "currentColor"
|
|
587
|
-
}, null), e("path", {
|
|
588
|
-
d: "M18 13H20C20.5523 13 21 12.5523 21 12C21 11.4477 20.5523 11 20 11H4C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13H14C14.7956 13 15.5587 13.3161 16.1213 13.8787C16.6839 14.4413 17 15.2044 17 16C17 16.7956 16.6839 17.5587 16.1213 18.1213C15.5587 18.6839 14.7956 19 14 19H6C5.44772 19 5 19.4477 5 20C5 20.5523 5.44772 21 6 21H14C15.3261 21 16.5979 20.4732 17.5355 19.5355C18.4732 18.5979 19 17.3261 19 16C19 14.9119 18.6453 13.8604 18 13Z",
|
|
589
|
-
fill: "currentColor"
|
|
590
|
-
}, null)]);
|
|
591
|
-
}
|
|
592
|
-
}), te = /* @__PURE__ */ p({
|
|
593
|
-
name: "UnderlineIcon",
|
|
594
|
-
setup(t, {
|
|
595
|
-
attrs: l
|
|
596
|
-
}) {
|
|
597
|
-
return () => e("svg", b({
|
|
598
|
-
width: "24",
|
|
599
|
-
height: "24",
|
|
600
|
-
viewBox: "0 0 24 24",
|
|
601
|
-
fill: "currentColor",
|
|
602
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
603
|
-
}, l), [e("path", {
|
|
604
|
-
"fill-rule": "evenodd",
|
|
605
|
-
"clip-rule": "evenodd",
|
|
606
|
-
d: "M7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4V10C5 11.8565 5.7375 13.637 7.05025 14.9497C8.36301 16.2625 10.1435 17 12 17C13.8565 17 15.637 16.2625 16.9497 14.9497C18.2625 13.637 19 11.8565 19 10V4C19 3.44772 18.5523 3 18 3C17.4477 3 17 3.44772 17 4V10C17 11.3261 16.4732 12.5979 15.5355 13.5355C14.5979 14.4732 13.3261 15 12 15C10.6739 15 9.40215 14.4732 8.46447 13.5355C7.52678 12.5979 7 11.3261 7 10V4ZM4 19C3.44772 19 3 19.4477 3 20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20C21 19.4477 20.5523 19 20 19H4Z",
|
|
607
|
-
fill: "currentColor"
|
|
608
|
-
}, null)]);
|
|
609
|
-
}
|
|
610
|
-
}), e1 = /* @__PURE__ */ p({
|
|
544
|
+
}), Ye = /* @__PURE__ */ c({
|
|
611
545
|
name: "TextStyleButton",
|
|
612
546
|
setup() {
|
|
613
|
-
const t =
|
|
547
|
+
const t = H("editor");
|
|
614
548
|
return () => e("div", null, [e(w, {
|
|
615
549
|
icon: Q,
|
|
616
550
|
tooltip: "粗体",
|
|
@@ -631,9 +565,13 @@ const Pe = Ae.extend({
|
|
|
631
565
|
tooltip: "下划线",
|
|
632
566
|
isActive: t?.value?.isActive("underline"),
|
|
633
567
|
onClick: () => t?.value?.chain().focus().toggleUnderline().run()
|
|
634
|
-
}, null), e(
|
|
568
|
+
}, null), e(Qe, null, null)]);
|
|
635
569
|
}
|
|
636
|
-
}),
|
|
570
|
+
}), Gt = {
|
|
571
|
+
name: "text-style",
|
|
572
|
+
install: () => ({ extensions: [] }),
|
|
573
|
+
toolbarComponent: Ye
|
|
574
|
+
}, le = /* @__PURE__ */ c({
|
|
637
575
|
name: "AlignLeftIcon",
|
|
638
576
|
setup(t, {
|
|
639
577
|
attrs: l
|
|
@@ -661,7 +599,7 @@ const Pe = Ae.extend({
|
|
|
661
599
|
fill: "currentColor"
|
|
662
600
|
}, null)]);
|
|
663
601
|
}
|
|
664
|
-
}), ne = /* @__PURE__ */
|
|
602
|
+
}), ne = /* @__PURE__ */ c({
|
|
665
603
|
name: "AlignCenterIcon",
|
|
666
604
|
setup(t, {
|
|
667
605
|
attrs: l
|
|
@@ -689,7 +627,7 @@ const Pe = Ae.extend({
|
|
|
689
627
|
fill: "currentColor"
|
|
690
628
|
}, null)]);
|
|
691
629
|
}
|
|
692
|
-
}), oe = /* @__PURE__ */
|
|
630
|
+
}), oe = /* @__PURE__ */ c({
|
|
693
631
|
name: "AlignRightIcon",
|
|
694
632
|
setup(t, {
|
|
695
633
|
attrs: l
|
|
@@ -717,7 +655,7 @@ const Pe = Ae.extend({
|
|
|
717
655
|
fill: "currentColor"
|
|
718
656
|
}, null)]);
|
|
719
657
|
}
|
|
720
|
-
}),
|
|
658
|
+
}), et = /* @__PURE__ */ c({
|
|
721
659
|
name: "AlignJustifyIcon",
|
|
722
660
|
setup(t, {
|
|
723
661
|
attrs: l
|
|
@@ -745,10 +683,10 @@ const Pe = Ae.extend({
|
|
|
745
683
|
fill: "currentColor"
|
|
746
684
|
}, null)]);
|
|
747
685
|
}
|
|
748
|
-
}),
|
|
686
|
+
}), tt = /* @__PURE__ */ c({
|
|
749
687
|
name: "TextAlignButton",
|
|
750
688
|
setup() {
|
|
751
|
-
const t =
|
|
689
|
+
const t = H("editor");
|
|
752
690
|
return () => e("div", null, [e(w, {
|
|
753
691
|
icon: le,
|
|
754
692
|
tooltip: "左边对齐",
|
|
@@ -771,7 +709,7 @@ const Pe = Ae.extend({
|
|
|
771
709
|
}),
|
|
772
710
|
onClick: () => t?.value?.chain().focus().setTextAlign("right").run()
|
|
773
711
|
}, null), e(w, {
|
|
774
|
-
icon:
|
|
712
|
+
icon: et,
|
|
775
713
|
tooltip: "两端对齐",
|
|
776
714
|
isActive: t?.value?.isActive({
|
|
777
715
|
textAlign: "justify"
|
|
@@ -779,7 +717,11 @@ const Pe = Ae.extend({
|
|
|
779
717
|
onClick: () => t?.value?.chain().focus().setTextAlign("justify").run()
|
|
780
718
|
}, null)]);
|
|
781
719
|
}
|
|
782
|
-
}),
|
|
720
|
+
}), Jt = {
|
|
721
|
+
name: "text-align",
|
|
722
|
+
install: () => ({ extensions: [] }),
|
|
723
|
+
toolbarComponent: tt
|
|
724
|
+
}, lt = /* @__PURE__ */ c({
|
|
783
725
|
name: "ListIcon",
|
|
784
726
|
setup(t, {
|
|
785
727
|
attrs: l
|
|
@@ -822,7 +764,7 @@ const Pe = Ae.extend({
|
|
|
822
764
|
fill: "currentColor"
|
|
823
765
|
}, null)]);
|
|
824
766
|
}
|
|
825
|
-
}),
|
|
767
|
+
}), nt = /* @__PURE__ */ c({
|
|
826
768
|
name: "ListOrderedIcon",
|
|
827
769
|
setup(t, {
|
|
828
770
|
attrs: l
|
|
@@ -865,7 +807,7 @@ const Pe = Ae.extend({
|
|
|
865
807
|
fill: "currentColor"
|
|
866
808
|
}, null)]);
|
|
867
809
|
}
|
|
868
|
-
}),
|
|
810
|
+
}), ot = /* @__PURE__ */ c({
|
|
869
811
|
name: "ListTodoIcon",
|
|
870
812
|
setup(t, {
|
|
871
813
|
attrs: l
|
|
@@ -903,29 +845,33 @@ const Pe = Ae.extend({
|
|
|
903
845
|
fill: "currentColor"
|
|
904
846
|
}, null)]);
|
|
905
847
|
}
|
|
906
|
-
}),
|
|
848
|
+
}), it = /* @__PURE__ */ c({
|
|
907
849
|
name: "ListButton",
|
|
908
850
|
setup() {
|
|
909
|
-
const t =
|
|
851
|
+
const t = H("editor");
|
|
910
852
|
return () => e("div", null, [e(w, {
|
|
911
|
-
icon:
|
|
853
|
+
icon: lt,
|
|
912
854
|
tooltip: "无序列表",
|
|
913
855
|
isActive: t?.value?.isActive("bulletList"),
|
|
914
856
|
onClick: () => t?.value?.chain().focus().toggleBulletList().run()
|
|
915
857
|
}, null), e(w, {
|
|
916
|
-
icon:
|
|
858
|
+
icon: nt,
|
|
917
859
|
tooltip: "有序列表",
|
|
918
860
|
isActive: t?.value?.isActive("orderedList"),
|
|
919
861
|
onClick: () => t?.value?.chain().focus().toggleOrderedList().run()
|
|
920
862
|
}, null), e(w, {
|
|
921
|
-
icon:
|
|
863
|
+
icon: ot,
|
|
922
864
|
tooltip: "任务列表",
|
|
923
865
|
isActive: t?.value?.isActive("taskList"),
|
|
924
866
|
onClick: () => t?.value?.chain().focus().toggleTaskList().run()
|
|
925
867
|
}, null)]);
|
|
926
868
|
}
|
|
927
|
-
}),
|
|
928
|
-
name: "
|
|
869
|
+
}), Xt = {
|
|
870
|
+
name: "list",
|
|
871
|
+
install: () => ({ extensions: [] }),
|
|
872
|
+
toolbarComponent: it
|
|
873
|
+
}, rt = /* @__PURE__ */ c({
|
|
874
|
+
name: "CodeBlockIcon",
|
|
929
875
|
setup(t, {
|
|
930
876
|
attrs: l
|
|
931
877
|
}) {
|
|
@@ -933,26 +879,36 @@ const Pe = Ae.extend({
|
|
|
933
879
|
width: "24",
|
|
934
880
|
height: "24",
|
|
935
881
|
viewBox: "0 0 24 24",
|
|
936
|
-
fill: "
|
|
882
|
+
fill: "none",
|
|
883
|
+
stroke: "currentColor",
|
|
884
|
+
"stroke-width": "2",
|
|
885
|
+
"stroke-linecap": "round",
|
|
886
|
+
"stroke-linejoin": "round",
|
|
937
887
|
xmlns: "http://www.w3.org/2000/svg"
|
|
938
|
-
}, l), [e("
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
fill: "currentColor"
|
|
943
|
-
}, null)]);
|
|
944
|
-
}
|
|
945
|
-
}), a1 = /* @__PURE__ */ p({
|
|
946
|
-
name: "ImageButton",
|
|
947
|
-
setup() {
|
|
948
|
-
const t = A("editor");
|
|
949
|
-
return () => e("div", null, [e(w, {
|
|
950
|
-
icon: r1,
|
|
951
|
-
tooltip: "图片",
|
|
952
|
-
onClick: () => t?.value?.commands.setImageUploadNode()
|
|
888
|
+
}, l), [e("polyline", {
|
|
889
|
+
points: "16 18 22 12 16 6"
|
|
890
|
+
}, null), e("polyline", {
|
|
891
|
+
points: "8 6 2 12 8 18"
|
|
953
892
|
}, null)]);
|
|
954
893
|
}
|
|
955
|
-
}),
|
|
894
|
+
}), ut = /* @__PURE__ */ c({
|
|
895
|
+
name: "CodeBlockButton",
|
|
896
|
+
setup() {
|
|
897
|
+
const t = H("editor");
|
|
898
|
+
return () => e(w, {
|
|
899
|
+
icon: rt,
|
|
900
|
+
tooltip: "代码块",
|
|
901
|
+
isActive: t?.value?.isActive("codeBlock"),
|
|
902
|
+
onClick: () => t?.value?.chain().focus().toggleCodeBlock().run()
|
|
903
|
+
}, null);
|
|
904
|
+
}
|
|
905
|
+
}), at = Te(Ve), Qt = {
|
|
906
|
+
name: "code-block",
|
|
907
|
+
install: () => ({
|
|
908
|
+
extensions: [Fe.configure({ lowlight: at, defaultLanguage: "plaintext" })]
|
|
909
|
+
}),
|
|
910
|
+
toolbarComponent: ut
|
|
911
|
+
}, st = /* @__PURE__ */ c({
|
|
956
912
|
name: "TableIcon",
|
|
957
913
|
setup(t, {
|
|
958
914
|
attrs: l
|
|
@@ -970,30 +926,30 @@ const Pe = Ae.extend({
|
|
|
970
926
|
fill: "currentColor"
|
|
971
927
|
}, null)]);
|
|
972
928
|
}
|
|
973
|
-
}),
|
|
929
|
+
}), ct = 8, dt = 8, pt = /* @__PURE__ */ c({
|
|
974
930
|
name: "TableButton",
|
|
975
931
|
setup() {
|
|
976
|
-
const t =
|
|
977
|
-
n.value =
|
|
978
|
-
},
|
|
932
|
+
const t = H("editor"), l = k(!1), n = k(0), o = k(0), i = (p, s) => {
|
|
933
|
+
n.value = p, o.value = s;
|
|
934
|
+
}, r = () => {
|
|
979
935
|
n.value = 0, o.value = 0;
|
|
980
|
-
},
|
|
936
|
+
}, v = (p, s) => {
|
|
981
937
|
t?.value?.chain().focus().insertTable({
|
|
982
|
-
rows:
|
|
983
|
-
cols:
|
|
938
|
+
rows: s,
|
|
939
|
+
cols: p,
|
|
984
940
|
withHeaderRow: !0
|
|
985
941
|
}).run(), l.value = !1;
|
|
986
942
|
};
|
|
987
943
|
return () => e(J, {
|
|
988
944
|
visible: l.value,
|
|
989
|
-
"onUpdate:visible": (
|
|
945
|
+
"onUpdate:visible": (p) => l.value = p,
|
|
990
946
|
trigger: "click",
|
|
991
947
|
placement: "bottom-start",
|
|
992
948
|
popperClass: "table-picker-popper",
|
|
993
949
|
width: "auto",
|
|
994
950
|
showArrow: !1
|
|
995
951
|
}, {
|
|
996
|
-
reference: () => e("span", null, [e(
|
|
952
|
+
reference: () => e("span", null, [e(D, {
|
|
997
953
|
content: "表格",
|
|
998
954
|
showArrow: !1,
|
|
999
955
|
offset: 6,
|
|
@@ -1005,7 +961,7 @@ const Pe = Ae.extend({
|
|
|
1005
961
|
"is-active": l.value
|
|
1006
962
|
}]
|
|
1007
963
|
}, {
|
|
1008
|
-
default: () => [e(
|
|
964
|
+
default: () => [e(st, {
|
|
1009
965
|
class: "tiptap-button-icon"
|
|
1010
966
|
}, null)]
|
|
1011
967
|
})]
|
|
@@ -1014,34 +970,34 @@ const Pe = Ae.extend({
|
|
|
1014
970
|
class: "table-picker"
|
|
1015
971
|
}, [e("div", {
|
|
1016
972
|
class: "table-picker-grid",
|
|
1017
|
-
onMouseleave:
|
|
973
|
+
onMouseleave: r
|
|
1018
974
|
}, [Array.from({
|
|
1019
|
-
length:
|
|
1020
|
-
}, (
|
|
1021
|
-
key:
|
|
975
|
+
length: dt
|
|
976
|
+
}, (p, s) => e("div", {
|
|
977
|
+
key: s,
|
|
1022
978
|
class: "table-picker-row"
|
|
1023
979
|
}, [Array.from({
|
|
1024
|
-
length:
|
|
1025
|
-
}, (
|
|
1026
|
-
key:
|
|
980
|
+
length: ct
|
|
981
|
+
}, (y, u) => e("div", {
|
|
982
|
+
key: u,
|
|
1027
983
|
class: ["table-picker-cell", {
|
|
1028
|
-
"is-active":
|
|
984
|
+
"is-active": u < n.value && s < o.value
|
|
1029
985
|
}],
|
|
1030
|
-
onMouseenter: () => u
|
|
1031
|
-
onClick: () =>
|
|
986
|
+
onMouseenter: () => i(u + 1, s + 1),
|
|
987
|
+
onClick: () => v(u + 1, s + 1)
|
|
1032
988
|
}, null))]))]), e("div", {
|
|
1033
989
|
class: "table-picker-footer"
|
|
1034
990
|
}, [e("div", {
|
|
1035
991
|
class: "table-picker-counter"
|
|
1036
|
-
}, [e("span", null, [
|
|
992
|
+
}, [e("span", null, [m("列")]), e("span", null, [n.value || 1])]), e("span", {
|
|
1037
993
|
class: "table-picker-x"
|
|
1038
|
-
}, [
|
|
994
|
+
}, [m("x")]), e("div", {
|
|
1039
995
|
class: "table-picker-counter"
|
|
1040
|
-
}, [e("span", null, [
|
|
996
|
+
}, [e("span", null, [m("行")]), e("span", null, [o.value || 1])])])])
|
|
1041
997
|
});
|
|
1042
998
|
}
|
|
1043
999
|
});
|
|
1044
|
-
function
|
|
1000
|
+
function Ct(t) {
|
|
1045
1001
|
let l = t.nodeType === Node.TEXT_NODE ? t.parentElement : t;
|
|
1046
1002
|
for (; l && l instanceof HTMLElement; ) {
|
|
1047
1003
|
if (l.tagName === "TD" || l.tagName === "TH") return l;
|
|
@@ -1049,106 +1005,106 @@ function C1(t) {
|
|
|
1049
1005
|
}
|
|
1050
1006
|
return null;
|
|
1051
1007
|
}
|
|
1052
|
-
function
|
|
1008
|
+
function vt(t) {
|
|
1053
1009
|
if (!t.isActive("tableCell") && !t.isActive("tableHeader")) return null;
|
|
1054
1010
|
const {
|
|
1055
1011
|
node: l
|
|
1056
|
-
} = t.view.domAtPos(t.state.selection.from), n =
|
|
1012
|
+
} = t.view.domAtPos(t.state.selection.from), n = Ct(l);
|
|
1057
1013
|
if (!n) return null;
|
|
1058
|
-
const o = n.parentElement,
|
|
1059
|
-
if (!
|
|
1060
|
-
const
|
|
1014
|
+
const o = n.parentElement, i = o.parentElement, r = n.closest("table");
|
|
1015
|
+
if (!r) return null;
|
|
1016
|
+
const v = Array.from(o.children).indexOf(n), p = Array.from(i.children).indexOf(o), s = o.children.length, y = i.children.length, u = n.getBoundingClientRect(), C = r.getBoundingClientRect(), g = t.view.dom.closest(".tiptap-editor").getBoundingClientRect();
|
|
1061
1017
|
return {
|
|
1062
1018
|
cell: n,
|
|
1063
|
-
colIndex:
|
|
1064
|
-
rowIndex:
|
|
1065
|
-
totalCols:
|
|
1066
|
-
totalRows:
|
|
1067
|
-
cellRect:
|
|
1068
|
-
tableRect:
|
|
1069
|
-
editorRect:
|
|
1019
|
+
colIndex: v,
|
|
1020
|
+
rowIndex: p,
|
|
1021
|
+
totalCols: s,
|
|
1022
|
+
totalRows: y,
|
|
1023
|
+
cellRect: u,
|
|
1024
|
+
tableRect: C,
|
|
1025
|
+
editorRect: g
|
|
1070
1026
|
};
|
|
1071
1027
|
}
|
|
1072
|
-
function
|
|
1028
|
+
function K(t) {
|
|
1073
1029
|
const {
|
|
1074
1030
|
state: l
|
|
1075
1031
|
} = t, n = l.selection.from;
|
|
1076
1032
|
let o = null;
|
|
1077
|
-
return l.doc.nodesBetween(0, l.doc.content.size, (
|
|
1078
|
-
if (
|
|
1033
|
+
return l.doc.nodesBetween(0, l.doc.content.size, (i, r) => {
|
|
1034
|
+
if (i.type.name === "table" && r <= n && n <= r + i.nodeSize)
|
|
1079
1035
|
return o = {
|
|
1080
|
-
node:
|
|
1081
|
-
pos:
|
|
1036
|
+
node: i,
|
|
1037
|
+
pos: r
|
|
1082
1038
|
}, !1;
|
|
1083
1039
|
}), o;
|
|
1084
1040
|
}
|
|
1085
|
-
const
|
|
1041
|
+
const ft = /* @__PURE__ */ c({
|
|
1086
1042
|
name: "TableControls",
|
|
1087
1043
|
setup() {
|
|
1088
|
-
const t =
|
|
1089
|
-
function
|
|
1090
|
-
const
|
|
1091
|
-
if (o.value && (o.value.classList.remove("tcc-cell-focused"), o.value = null), !
|
|
1044
|
+
const t = H("editor"), l = H("readonly"), n = k(null), o = k(null);
|
|
1045
|
+
function i() {
|
|
1046
|
+
const u = t?.value;
|
|
1047
|
+
if (o.value && (o.value.classList.remove("tcc-cell-focused"), o.value = null), !u) {
|
|
1092
1048
|
n.value = null;
|
|
1093
1049
|
return;
|
|
1094
1050
|
}
|
|
1095
|
-
const
|
|
1096
|
-
n.value =
|
|
1051
|
+
const C = vt(u);
|
|
1052
|
+
n.value = C, C && (C.cell.classList.add("tcc-cell-focused"), o.value = C.cell);
|
|
1097
1053
|
}
|
|
1098
|
-
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1054
|
+
G((u) => {
|
|
1055
|
+
const C = t?.value;
|
|
1056
|
+
C && (C.on("selectionUpdate", i), C.on("transaction", i), u(() => {
|
|
1057
|
+
C.off("selectionUpdate", i), C.off("transaction", i), o.value && (o.value.classList.remove("tcc-cell-focused"), o.value = null);
|
|
1102
1058
|
}));
|
|
1103
1059
|
});
|
|
1104
|
-
function
|
|
1105
|
-
const
|
|
1106
|
-
if (!
|
|
1060
|
+
function r(u) {
|
|
1061
|
+
const C = t?.value;
|
|
1062
|
+
if (!C || !n.value) return;
|
|
1107
1063
|
const {
|
|
1108
|
-
colIndex:
|
|
1109
|
-
totalCols:
|
|
1110
|
-
} = n.value,
|
|
1111
|
-
if (
|
|
1112
|
-
const a =
|
|
1064
|
+
colIndex: g,
|
|
1065
|
+
totalCols: I
|
|
1066
|
+
} = n.value, x = u === "left" ? g - 1 : g + 1;
|
|
1067
|
+
if (x < 0 || x >= I) return;
|
|
1068
|
+
const a = K(C);
|
|
1113
1069
|
if (!a) return;
|
|
1114
1070
|
const {
|
|
1115
|
-
node:
|
|
1116
|
-
pos:
|
|
1071
|
+
node: d,
|
|
1072
|
+
pos: f
|
|
1117
1073
|
} = a, h = [];
|
|
1118
|
-
|
|
1119
|
-
if (
|
|
1120
|
-
h.push(
|
|
1074
|
+
d.forEach((L) => {
|
|
1075
|
+
if (L.type.name !== "tableRow") {
|
|
1076
|
+
h.push(L);
|
|
1121
1077
|
return;
|
|
1122
1078
|
}
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
const S =
|
|
1126
|
-
|
|
1079
|
+
const A = [];
|
|
1080
|
+
L.forEach((U) => A.push(U));
|
|
1081
|
+
const S = A[g];
|
|
1082
|
+
A[g] = A[x], A[x] = S, h.push(L.type.create(L.attrs, A, L.marks));
|
|
1127
1083
|
});
|
|
1128
|
-
const B =
|
|
1129
|
-
|
|
1084
|
+
const B = d.type.create(d.attrs, h, d.marks), V = C.state.tr.replaceWith(f, f + d.nodeSize, B);
|
|
1085
|
+
C.view.dispatch(V);
|
|
1130
1086
|
}
|
|
1131
|
-
function
|
|
1132
|
-
const
|
|
1133
|
-
if (!
|
|
1087
|
+
function v(u) {
|
|
1088
|
+
const C = t?.value;
|
|
1089
|
+
if (!C || !n.value) return;
|
|
1134
1090
|
const {
|
|
1135
|
-
rowIndex:
|
|
1136
|
-
totalRows:
|
|
1137
|
-
} = n.value,
|
|
1138
|
-
if (
|
|
1139
|
-
const a =
|
|
1091
|
+
rowIndex: g,
|
|
1092
|
+
totalRows: I
|
|
1093
|
+
} = n.value, x = u === "up" ? g - 1 : g + 1;
|
|
1094
|
+
if (x < 0 || x >= I) return;
|
|
1095
|
+
const a = K(C);
|
|
1140
1096
|
if (!a) return;
|
|
1141
1097
|
const {
|
|
1142
|
-
node:
|
|
1143
|
-
pos:
|
|
1098
|
+
node: d,
|
|
1099
|
+
pos: f
|
|
1144
1100
|
} = a, h = [];
|
|
1145
|
-
|
|
1146
|
-
const B = h[
|
|
1147
|
-
h[
|
|
1148
|
-
const V =
|
|
1149
|
-
|
|
1101
|
+
d.forEach((A) => h.push(A));
|
|
1102
|
+
const B = h[g];
|
|
1103
|
+
h[g] = h[x], h[x] = B;
|
|
1104
|
+
const V = d.type.create(d.attrs, h, d.marks), L = C.state.tr.replaceWith(f, f + d.nodeSize, V);
|
|
1105
|
+
C.view.dispatch(L);
|
|
1150
1106
|
}
|
|
1151
|
-
const
|
|
1107
|
+
const p = () => e("svg", {
|
|
1152
1108
|
width: "16",
|
|
1153
1109
|
height: "4",
|
|
1154
1110
|
viewBox: "0 0 16 4",
|
|
@@ -1165,7 +1121,7 @@ const f1 = /* @__PURE__ */ p({
|
|
|
1165
1121
|
cx: "14",
|
|
1166
1122
|
cy: "2",
|
|
1167
1123
|
r: "1.5"
|
|
1168
|
-
}, null)]),
|
|
1124
|
+
}, null)]), s = () => e("svg", {
|
|
1169
1125
|
width: "4",
|
|
1170
1126
|
height: "16",
|
|
1171
1127
|
viewBox: "0 0 4 16",
|
|
@@ -1182,7 +1138,7 @@ const f1 = /* @__PURE__ */ p({
|
|
|
1182
1138
|
cx: "2",
|
|
1183
1139
|
cy: "14",
|
|
1184
1140
|
r: "1.5"
|
|
1185
|
-
}, null)]),
|
|
1141
|
+
}, null)]), y = () => e("svg", {
|
|
1186
1142
|
width: "10",
|
|
1187
1143
|
height: "10",
|
|
1188
1144
|
viewBox: "0 0 10 10",
|
|
@@ -1195,122 +1151,505 @@ const f1 = /* @__PURE__ */ p({
|
|
|
1195
1151
|
}, null)]);
|
|
1196
1152
|
return () => {
|
|
1197
1153
|
if (l?.value) return null;
|
|
1198
|
-
const
|
|
1199
|
-
if (!
|
|
1154
|
+
const u = n.value;
|
|
1155
|
+
if (!u) return null;
|
|
1200
1156
|
const {
|
|
1201
|
-
colIndex:
|
|
1202
|
-
rowIndex:
|
|
1203
|
-
totalCols:
|
|
1204
|
-
totalRows:
|
|
1157
|
+
colIndex: C,
|
|
1158
|
+
rowIndex: g,
|
|
1159
|
+
totalCols: I,
|
|
1160
|
+
totalRows: x,
|
|
1205
1161
|
cellRect: a,
|
|
1206
|
-
tableRect:
|
|
1207
|
-
editorRect:
|
|
1208
|
-
} =
|
|
1162
|
+
tableRect: d,
|
|
1163
|
+
editorRect: f
|
|
1164
|
+
} = u, h = d.top - f.top, B = d.left - f.left, V = d.right - f.left, L = d.bottom - f.top, A = a.left - f.left, S = a.top - f.top, U = a.width, O = a.height, ie = {
|
|
1209
1165
|
position: "absolute",
|
|
1210
1166
|
top: `${h - 20}px`,
|
|
1211
|
-
left: `${
|
|
1212
|
-
},
|
|
1167
|
+
left: `${A + U / 2 - 18}px`
|
|
1168
|
+
}, re = {
|
|
1213
1169
|
position: "absolute",
|
|
1214
|
-
top: `${S +
|
|
1170
|
+
top: `${S + O / 2 - 18}px`,
|
|
1215
1171
|
left: `${B - 20}px`
|
|
1216
|
-
},
|
|
1172
|
+
}, ue = {
|
|
1217
1173
|
position: "absolute",
|
|
1218
|
-
top: `${S +
|
|
1174
|
+
top: `${S + O / 2 - 12}px`,
|
|
1219
1175
|
left: `${V + 6}px`
|
|
1220
1176
|
}, ae = {
|
|
1221
1177
|
position: "absolute",
|
|
1222
|
-
top: `${
|
|
1223
|
-
left: `${
|
|
1224
|
-
}, se =
|
|
1178
|
+
top: `${L + 6}px`,
|
|
1179
|
+
left: `${A + U / 2 - 12}px`
|
|
1180
|
+
}, se = C === 0, $ = C === I - 1, ce = g === 0, N = g === x - 1, F = t?.value;
|
|
1225
1181
|
return e("div", {
|
|
1226
1182
|
class: "table-cell-controls"
|
|
1227
1183
|
}, [e(j, {
|
|
1228
1184
|
trigger: "click",
|
|
1229
1185
|
placement: "bottom",
|
|
1230
1186
|
style: ie,
|
|
1231
|
-
onCommand: (
|
|
1232
|
-
|
|
1187
|
+
onCommand: (M) => {
|
|
1188
|
+
M === "move-left" ? r("left") : M === "move-right" ? r("right") : M === "insert-left" ? F?.chain().focus().addColumnBefore().run() : M === "insert-right" ? F?.chain().focus().addColumnAfter().run() : M === "delete" && F?.chain().focus().deleteColumn().run();
|
|
1233
1189
|
}
|
|
1234
1190
|
}, {
|
|
1235
1191
|
default: () => [e("button", {
|
|
1236
1192
|
class: "tcc-btn tcc-btn--col"
|
|
1237
|
-
}, [e(
|
|
1193
|
+
}, [e(p, null, null)])],
|
|
1238
1194
|
dropdown: () => e(W, null, {
|
|
1239
1195
|
default: () => [e(E, {
|
|
1240
1196
|
command: "move-left",
|
|
1241
1197
|
disabled: se
|
|
1242
1198
|
}, {
|
|
1243
|
-
default: () => [
|
|
1199
|
+
default: () => [m("移动列到左侧")]
|
|
1244
1200
|
}), e(E, {
|
|
1245
1201
|
command: "move-right",
|
|
1246
|
-
disabled:
|
|
1202
|
+
disabled: $
|
|
1247
1203
|
}, {
|
|
1248
|
-
default: () => [
|
|
1204
|
+
default: () => [m("移动列到右侧")]
|
|
1249
1205
|
}), e(E, {
|
|
1250
1206
|
command: "insert-left"
|
|
1251
1207
|
}, {
|
|
1252
|
-
default: () => [
|
|
1208
|
+
default: () => [m("在左侧插入一列")]
|
|
1253
1209
|
}), e(E, {
|
|
1254
1210
|
command: "insert-right"
|
|
1255
1211
|
}, {
|
|
1256
|
-
default: () => [
|
|
1212
|
+
default: () => [m("在右侧插入一列")]
|
|
1257
1213
|
}), e(E, {
|
|
1258
1214
|
command: "delete",
|
|
1259
1215
|
divided: !0
|
|
1260
1216
|
}, {
|
|
1261
|
-
default: () => [
|
|
1217
|
+
default: () => [m("删除列")]
|
|
1262
1218
|
})]
|
|
1263
1219
|
})
|
|
1264
1220
|
}), e(j, {
|
|
1265
1221
|
trigger: "click",
|
|
1266
1222
|
placement: "right",
|
|
1267
|
-
style:
|
|
1268
|
-
onCommand: (
|
|
1269
|
-
|
|
1223
|
+
style: re,
|
|
1224
|
+
onCommand: (M) => {
|
|
1225
|
+
M === "move-up" ? v("up") : M === "move-down" ? v("down") : M === "insert-above" ? F?.chain().focus().addRowBefore().run() : M === "insert-below" ? F?.chain().focus().addRowAfter().run() : M === "delete" && F?.chain().focus().deleteRow().run();
|
|
1270
1226
|
}
|
|
1271
1227
|
}, {
|
|
1272
1228
|
default: () => [e("button", {
|
|
1273
1229
|
class: "tcc-btn tcc-btn--row"
|
|
1274
|
-
}, [e(
|
|
1230
|
+
}, [e(s, null, null)])],
|
|
1275
1231
|
dropdown: () => e(W, null, {
|
|
1276
1232
|
default: () => [e(E, {
|
|
1277
1233
|
command: "move-up",
|
|
1278
1234
|
disabled: ce
|
|
1279
1235
|
}, {
|
|
1280
|
-
default: () => [
|
|
1236
|
+
default: () => [m("上移")]
|
|
1281
1237
|
}), e(E, {
|
|
1282
1238
|
command: "move-down",
|
|
1283
1239
|
disabled: N
|
|
1284
1240
|
}, {
|
|
1285
|
-
default: () => [
|
|
1241
|
+
default: () => [m("下移")]
|
|
1286
1242
|
}), e(E, {
|
|
1287
1243
|
command: "insert-above"
|
|
1288
1244
|
}, {
|
|
1289
|
-
default: () => [
|
|
1245
|
+
default: () => [m("在上方插入一行")]
|
|
1290
1246
|
}), e(E, {
|
|
1291
1247
|
command: "insert-below"
|
|
1292
1248
|
}, {
|
|
1293
|
-
default: () => [
|
|
1249
|
+
default: () => [m("在下方插入一行")]
|
|
1294
1250
|
}), e(E, {
|
|
1295
1251
|
command: "delete",
|
|
1296
1252
|
divided: !0
|
|
1297
1253
|
}, {
|
|
1298
|
-
default: () => [
|
|
1254
|
+
default: () => [m("删除行")]
|
|
1299
1255
|
})]
|
|
1300
1256
|
})
|
|
1301
|
-
}),
|
|
1257
|
+
}), $ && e("button", {
|
|
1302
1258
|
class: "tcc-btn tcc-btn--add",
|
|
1303
|
-
style:
|
|
1304
|
-
onClick: () =>
|
|
1305
|
-
}, [e(
|
|
1259
|
+
style: ue,
|
|
1260
|
+
onClick: () => F?.chain().focus().addColumnAfter().run()
|
|
1261
|
+
}, [e(y, null, null)]), N && e("button", {
|
|
1306
1262
|
class: "tcc-btn tcc-btn--add",
|
|
1307
1263
|
style: ae,
|
|
1308
|
-
onClick: () =>
|
|
1309
|
-
}, [e(
|
|
1264
|
+
onClick: () => F?.chain().focus().addRowAfter().run()
|
|
1265
|
+
}, [e(y, null, null)])]);
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
}), Yt = {
|
|
1269
|
+
name: "table",
|
|
1270
|
+
install: () => ({
|
|
1271
|
+
extensions: [Se.configure({ resizable: !0 }), Ze, De, Re],
|
|
1272
|
+
controlComponent: ft
|
|
1273
|
+
}),
|
|
1274
|
+
toolbarComponent: pt
|
|
1275
|
+
}, ht = /* @__PURE__ */ c({
|
|
1276
|
+
name: "MathIcon",
|
|
1277
|
+
setup(t, {
|
|
1278
|
+
attrs: l
|
|
1279
|
+
}) {
|
|
1280
|
+
return () => e("svg", b({
|
|
1281
|
+
width: "24",
|
|
1282
|
+
height: "24",
|
|
1283
|
+
viewBox: "0 0 24 24",
|
|
1284
|
+
fill: "currentColor",
|
|
1285
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
1286
|
+
}, l), [e("path", {
|
|
1287
|
+
"fill-rule": "evenodd",
|
|
1288
|
+
"clip-rule": "evenodd",
|
|
1289
|
+
d: "M9 4.8c.1-.5.5-.8 1-.8h10a1 1 0 1 1 0 2h-9.2L8.3 19.2a1 1 0 0 1-1.7.4l-3.4-4.2a1 1 0 0 1 1.6-1.2l2 2.5L9 4.8Zm9.7 5.5c.4.4.4 1 0 1.4L17 13.5l1.8 1.8a1 1 0 1 1-1.4 1.4L15.5 15l-1.8 1.8a1 1 0 0 1-1.4-1.4l1.8-1.8-1.8-1.8a1 1 0 0 1 1.4-1.4l1.8 1.8 1.8-1.8a1 1 0 0 1 1.4 0Z",
|
|
1290
|
+
fill: "currentColor"
|
|
1291
|
+
}, null)]);
|
|
1292
|
+
}
|
|
1293
|
+
}), mt = /* @__PURE__ */ c({
|
|
1294
|
+
name: "MathButton",
|
|
1295
|
+
setup() {
|
|
1296
|
+
const t = H("editor"), l = H("openMathDialog");
|
|
1297
|
+
return () => e(w, {
|
|
1298
|
+
icon: ht,
|
|
1299
|
+
tooltip: "数学公式",
|
|
1300
|
+
isActive: t?.value?.isActive("inlineMath") || t?.value?.isActive("blockMath"),
|
|
1301
|
+
onClick: () => l?.()
|
|
1302
|
+
}, null);
|
|
1303
|
+
}
|
|
1304
|
+
}), gt = /* @__PURE__ */ c({
|
|
1305
|
+
name: "MathEditDialog",
|
|
1306
|
+
props: {
|
|
1307
|
+
visible: {
|
|
1308
|
+
type: Boolean,
|
|
1309
|
+
required: !0
|
|
1310
|
+
},
|
|
1311
|
+
latex: {
|
|
1312
|
+
type: String,
|
|
1313
|
+
required: !0
|
|
1314
|
+
},
|
|
1315
|
+
pos: {
|
|
1316
|
+
type: Number,
|
|
1317
|
+
default: null
|
|
1318
|
+
},
|
|
1319
|
+
type: {
|
|
1320
|
+
type: String,
|
|
1321
|
+
required: !0
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
emits: ["update:visible"],
|
|
1325
|
+
setup(t, {
|
|
1326
|
+
emit: l
|
|
1327
|
+
}) {
|
|
1328
|
+
const n = H("editor"), o = k(""), i = k("inline");
|
|
1329
|
+
R(() => t.latex, (s) => {
|
|
1330
|
+
o.value = s;
|
|
1331
|
+
}, {
|
|
1332
|
+
immediate: !0
|
|
1333
|
+
}), R(() => t.type, (s) => {
|
|
1334
|
+
i.value = s;
|
|
1335
|
+
}, {
|
|
1336
|
+
immediate: !0
|
|
1337
|
+
});
|
|
1338
|
+
const r = T(() => t.pos === null), v = T(() => o.value.trim() ? _e.renderToString(o.value, {
|
|
1339
|
+
displayMode: i.value === "block",
|
|
1340
|
+
throwOnError: !1
|
|
1341
|
+
}) : ""), p = () => {
|
|
1342
|
+
const s = n?.value;
|
|
1343
|
+
if (!(!s || !o.value.trim())) {
|
|
1344
|
+
if (r.value)
|
|
1345
|
+
i.value === "inline" ? s.chain().focus().insertInlineMath({
|
|
1346
|
+
latex: o.value
|
|
1347
|
+
}).run() : s.chain().focus().insertBlockMath({
|
|
1348
|
+
latex: o.value
|
|
1349
|
+
}).run();
|
|
1350
|
+
else if (i.value === t.type)
|
|
1351
|
+
t.type === "inline" ? s.commands.updateInlineMath({
|
|
1352
|
+
latex: o.value,
|
|
1353
|
+
pos: t.pos
|
|
1354
|
+
}) : s.commands.updateBlockMath({
|
|
1355
|
+
latex: o.value,
|
|
1356
|
+
pos: t.pos
|
|
1357
|
+
});
|
|
1358
|
+
else {
|
|
1359
|
+
const y = t.pos;
|
|
1360
|
+
t.type === "inline" ? s.chain().focus().deleteInlineMath({
|
|
1361
|
+
pos: y
|
|
1362
|
+
}).insertBlockMath({
|
|
1363
|
+
latex: o.value
|
|
1364
|
+
}).run() : s.chain().focus().deleteBlockMath({
|
|
1365
|
+
pos: y
|
|
1366
|
+
}).insertInlineMath({
|
|
1367
|
+
latex: o.value
|
|
1368
|
+
}).run();
|
|
1369
|
+
}
|
|
1370
|
+
l("update:visible", !1);
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
return () => e(Be, {
|
|
1374
|
+
modelValue: t.visible,
|
|
1375
|
+
title: r.value ? "插入数学公式" : "编辑数学公式",
|
|
1376
|
+
width: "520px",
|
|
1377
|
+
"onUpdate:modelValue": (s) => l("update:visible", s)
|
|
1378
|
+
}, {
|
|
1379
|
+
default: () => [e("div", {
|
|
1380
|
+
class: "math-dialog"
|
|
1381
|
+
}, [e(ye, {
|
|
1382
|
+
modelValue: i.value,
|
|
1383
|
+
"onUpdate:modelValue": (s) => {
|
|
1384
|
+
i.value = s;
|
|
1385
|
+
}
|
|
1386
|
+
}, {
|
|
1387
|
+
default: () => [e(q, {
|
|
1388
|
+
value: "inline"
|
|
1389
|
+
}, {
|
|
1390
|
+
default: () => [m("行内公式")]
|
|
1391
|
+
}), e(q, {
|
|
1392
|
+
value: "block"
|
|
1393
|
+
}, {
|
|
1394
|
+
default: () => [m("块级公式")]
|
|
1395
|
+
})]
|
|
1396
|
+
}), e(X, {
|
|
1397
|
+
modelValue: o.value,
|
|
1398
|
+
type: "textarea",
|
|
1399
|
+
rows: 3,
|
|
1400
|
+
placeholder: "请输入 LaTeX 公式,例如:E=mc^2",
|
|
1401
|
+
"onUpdate:modelValue": (s) => {
|
|
1402
|
+
o.value = s;
|
|
1403
|
+
}
|
|
1404
|
+
}, null), e("div", {
|
|
1405
|
+
class: ["math-preview", {
|
|
1406
|
+
"math-preview--empty": !v.value
|
|
1407
|
+
}]
|
|
1408
|
+
}, [v.value ? e("div", {
|
|
1409
|
+
innerHTML: v.value
|
|
1410
|
+
}, null) : e("span", {
|
|
1411
|
+
class: "math-preview__placeholder"
|
|
1412
|
+
}, [m("预览将在此处显示")])])])],
|
|
1413
|
+
footer: () => e(de, null, [e(Z, {
|
|
1414
|
+
onClick: () => l("update:visible", !1)
|
|
1415
|
+
}, {
|
|
1416
|
+
default: () => [m("取消")]
|
|
1417
|
+
}), e(Z, {
|
|
1418
|
+
type: "primary",
|
|
1419
|
+
disabled: !o.value.trim(),
|
|
1420
|
+
onClick: p
|
|
1421
|
+
}, {
|
|
1422
|
+
default: () => [m("确认")]
|
|
1423
|
+
})])
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
}), e1 = {
|
|
1427
|
+
name: "math",
|
|
1428
|
+
toolbarComponent: mt,
|
|
1429
|
+
install(t) {
|
|
1430
|
+
const l = k(!1), n = k(""), o = k(null), i = k("inline"), r = (p = {}) => {
|
|
1431
|
+
t.readonly.value || (n.value = p.latex ?? "", o.value = p.pos ?? null, i.value = p.type ?? "inline", l.value = !0);
|
|
1432
|
+
};
|
|
1433
|
+
t.provide("openMathDialog", r);
|
|
1434
|
+
const v = c({
|
|
1435
|
+
name: "MathEditDialogWrapper",
|
|
1436
|
+
setup: () => () => pe(gt, {
|
|
1437
|
+
visible: l.value,
|
|
1438
|
+
latex: n.value,
|
|
1439
|
+
pos: o.value,
|
|
1440
|
+
type: i.value,
|
|
1441
|
+
"onUpdate:visible": (p) => {
|
|
1442
|
+
l.value = p;
|
|
1443
|
+
}
|
|
1444
|
+
})
|
|
1445
|
+
});
|
|
1446
|
+
return {
|
|
1447
|
+
extensions: [
|
|
1448
|
+
Ue.configure({
|
|
1449
|
+
inlineOptions: {
|
|
1450
|
+
onClick: (p, s) => r({ latex: p.attrs.latex, pos: s, type: "inline" })
|
|
1451
|
+
},
|
|
1452
|
+
blockOptions: {
|
|
1453
|
+
onClick: (p, s) => r({ latex: p.attrs.latex, pos: s, type: "block" })
|
|
1454
|
+
}
|
|
1455
|
+
})
|
|
1456
|
+
],
|
|
1457
|
+
controlComponent: v
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
}, wt = /* @__PURE__ */ c({
|
|
1461
|
+
name: "ImageUploadView",
|
|
1462
|
+
props: he,
|
|
1463
|
+
setup(t) {
|
|
1464
|
+
const l = T(() => t.node.attrs.accept), n = T(() => t.node.attrs.limit), o = T(() => t.node.attrs.maxSize), i = k([]), r = k(), v = k(!1), p = async (a) => {
|
|
1465
|
+
if (o.value > 0 && a.size > o.value)
|
|
1466
|
+
return t.extension.options.onError?.(new Error(`文件大小超出限制 ${o.value / 1024 / 1024}MB`)), null;
|
|
1467
|
+
const d = crypto.randomUUID();
|
|
1468
|
+
i.value.push({
|
|
1469
|
+
id: d,
|
|
1470
|
+
file: a,
|
|
1471
|
+
progress: 0,
|
|
1472
|
+
status: "uploading"
|
|
1473
|
+
});
|
|
1474
|
+
try {
|
|
1475
|
+
const f = t.extension.options.upload;
|
|
1476
|
+
if (!f) throw new Error("未配置 upload 函数");
|
|
1477
|
+
const h = await f(a);
|
|
1478
|
+
if (!h) throw new Error("上传失败:未返回 URL");
|
|
1479
|
+
const B = i.value.find((V) => V.id === d);
|
|
1480
|
+
return B && (B.status = "success", B.progress = 100), t.extension.options.onSuccess?.(h), h;
|
|
1481
|
+
} catch (f) {
|
|
1482
|
+
const h = i.value.find((B) => B.id === d);
|
|
1483
|
+
return h && (h.status = "error", h.progress = 0), t.extension.options.onError?.(f instanceof Error ? f : new Error("上传失败")), null;
|
|
1484
|
+
}
|
|
1485
|
+
}, s = async (a) => {
|
|
1486
|
+
if (!a.length) return;
|
|
1487
|
+
if (a.length > n.value) {
|
|
1488
|
+
t.extension.options.onError?.(new Error(`最多上传 ${n.value} 个文件`));
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
const d = (await Promise.all(a.map(p))).filter((f) => !!f);
|
|
1492
|
+
if (d.length > 0) {
|
|
1493
|
+
const f = t.getPos();
|
|
1494
|
+
if (typeof f != "number") return;
|
|
1495
|
+
const h = d.map((B) => ({
|
|
1496
|
+
type: "image",
|
|
1497
|
+
attrs: {
|
|
1498
|
+
src: B
|
|
1499
|
+
}
|
|
1500
|
+
}));
|
|
1501
|
+
t.editor.chain().focus().deleteRange({
|
|
1502
|
+
from: f,
|
|
1503
|
+
to: f + t.node.nodeSize
|
|
1504
|
+
}).insertContentAt(f, h).run();
|
|
1505
|
+
}
|
|
1506
|
+
}, y = () => {
|
|
1507
|
+
i.value.length === 0 && r.value && (r.value.value = "", r.value.click());
|
|
1508
|
+
}, u = (a) => {
|
|
1509
|
+
const d = a.target.files;
|
|
1510
|
+
d && s(Array.from(d));
|
|
1511
|
+
}, C = (a) => {
|
|
1512
|
+
a.preventDefault(), v.value = !0;
|
|
1513
|
+
}, g = (a) => {
|
|
1514
|
+
a.currentTarget.contains(a.relatedTarget) || (v.value = !1);
|
|
1515
|
+
}, I = (a) => {
|
|
1516
|
+
a.preventDefault(), v.value = !1;
|
|
1517
|
+
const d = Array.from(a.dataTransfer?.files ?? []);
|
|
1518
|
+
d.length && s(d);
|
|
1519
|
+
}, x = (a) => {
|
|
1520
|
+
i.value = i.value.filter((d) => d.id !== a);
|
|
1521
|
+
};
|
|
1522
|
+
return () => e(me, {
|
|
1523
|
+
class: "tiptap-image-upload"
|
|
1524
|
+
}, {
|
|
1525
|
+
default: () => [e("div", {
|
|
1526
|
+
onClick: y
|
|
1527
|
+
}, [i.value.length ? e("div", {
|
|
1528
|
+
class: "tiptap-image-upload-previews"
|
|
1529
|
+
}, [i.value.map((a) => e("div", {
|
|
1530
|
+
key: a.id,
|
|
1531
|
+
class: "tiptap-image-upload-preview"
|
|
1532
|
+
}, [a.status === "uploading" && e("div", {
|
|
1533
|
+
class: "tiptap-image-upload-progress",
|
|
1534
|
+
style: {
|
|
1535
|
+
width: `${a.progress}%`
|
|
1536
|
+
}
|
|
1537
|
+
}, null), e("div", {
|
|
1538
|
+
class: "tiptap-image-upload-preview-content"
|
|
1539
|
+
}, [e("span", {
|
|
1540
|
+
class: "tiptap-image-upload-text"
|
|
1541
|
+
}, [a.file.name]), e("span", {
|
|
1542
|
+
class: "tiptap-image-upload-subtext"
|
|
1543
|
+
}, [a.status === "uploading" ? `${a.progress}%` : a.status === "error" ? "上传失败" : "上传成功"]), e("button", {
|
|
1544
|
+
class: "tiptap-image-upload-remove",
|
|
1545
|
+
onClick: (d) => {
|
|
1546
|
+
d.stopPropagation(), x(a.id);
|
|
1547
|
+
}
|
|
1548
|
+
}, [m("×")])])]))]) : e("div", {
|
|
1549
|
+
class: ["tiptap-image-upload-drag-area", {
|
|
1550
|
+
"drag-active": v.value
|
|
1551
|
+
}],
|
|
1552
|
+
onDragover: C,
|
|
1553
|
+
onDragleave: g,
|
|
1554
|
+
onDrop: I
|
|
1555
|
+
}, [e("div", {
|
|
1556
|
+
class: "tiptap-image-upload-content"
|
|
1557
|
+
}, [e("span", {
|
|
1558
|
+
class: "tiptap-image-upload-text"
|
|
1559
|
+
}, [e("em", null, [m("点击上传")]), m(" 或拖拽图片到此处")]), e("span", {
|
|
1560
|
+
class: "tiptap-image-upload-subtext"
|
|
1561
|
+
}, [m("最多 "), n.value, m(" 个文件"), o.value ? `,每个不超过 ${o.value / 1024 / 1024}MB` : ""])])]), e("input", {
|
|
1562
|
+
ref: r,
|
|
1563
|
+
type: "file",
|
|
1564
|
+
accept: l.value,
|
|
1565
|
+
multiple: n.value > 1,
|
|
1566
|
+
onChange: u,
|
|
1567
|
+
onClick: (a) => a.stopPropagation()
|
|
1568
|
+
}, null)])]
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
}), bt = Pe.create({
|
|
1572
|
+
name: "imageUpload",
|
|
1573
|
+
group: "block",
|
|
1574
|
+
draggable: !0,
|
|
1575
|
+
selectable: !0,
|
|
1576
|
+
atom: !0,
|
|
1577
|
+
addOptions() {
|
|
1578
|
+
return {
|
|
1579
|
+
type: "image",
|
|
1580
|
+
accept: "image/*",
|
|
1581
|
+
limit: 1,
|
|
1582
|
+
maxSize: 0,
|
|
1583
|
+
upload: (t) => new Promise((l) => {
|
|
1584
|
+
const n = new FileReader();
|
|
1585
|
+
n.onloadend = () => l(n.result), n.readAsDataURL(t);
|
|
1586
|
+
}),
|
|
1587
|
+
onError: void 0,
|
|
1588
|
+
onSuccess: void 0,
|
|
1589
|
+
HTMLAttributes: {}
|
|
1590
|
+
};
|
|
1591
|
+
},
|
|
1592
|
+
addAttributes() {
|
|
1593
|
+
return {
|
|
1594
|
+
accept: {
|
|
1595
|
+
default: this.options.accept
|
|
1596
|
+
},
|
|
1597
|
+
limit: {
|
|
1598
|
+
default: this.options.limit
|
|
1599
|
+
},
|
|
1600
|
+
maxSize: {
|
|
1601
|
+
default: this.options.maxSize
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
},
|
|
1605
|
+
parseHTML() {
|
|
1606
|
+
return [{
|
|
1607
|
+
tag: 'div[data-type="image-upload"]'
|
|
1608
|
+
}];
|
|
1609
|
+
},
|
|
1610
|
+
renderHTML({
|
|
1611
|
+
HTMLAttributes: t
|
|
1612
|
+
}) {
|
|
1613
|
+
return ["div", ze({
|
|
1614
|
+
"data-type": "image-upload"
|
|
1615
|
+
}, t)];
|
|
1616
|
+
},
|
|
1617
|
+
addNodeView() {
|
|
1618
|
+
return ge(wt);
|
|
1619
|
+
},
|
|
1620
|
+
addCommands() {
|
|
1621
|
+
return {
|
|
1622
|
+
setImageUploadNode: () => ({
|
|
1623
|
+
commands: t
|
|
1624
|
+
}) => t.insertContent({
|
|
1625
|
+
type: this.name
|
|
1626
|
+
})
|
|
1627
|
+
};
|
|
1628
|
+
},
|
|
1629
|
+
addKeyboardShortcuts() {
|
|
1630
|
+
return {
|
|
1631
|
+
Enter: ({
|
|
1632
|
+
editor: t
|
|
1633
|
+
}) => {
|
|
1634
|
+
const {
|
|
1635
|
+
selection: l
|
|
1636
|
+
} = t.state, {
|
|
1637
|
+
nodeAfter: n
|
|
1638
|
+
} = l.$from;
|
|
1639
|
+
if (n?.type.name === "imageUpload" && t.isActive("imageUpload")) {
|
|
1640
|
+
const o = t.view.nodeDOM(l.$from.pos);
|
|
1641
|
+
if (o instanceof HTMLElement) {
|
|
1642
|
+
const i = o.firstChild;
|
|
1643
|
+
if (i instanceof HTMLElement)
|
|
1644
|
+
return i.click(), !0;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
return !1;
|
|
1648
|
+
}
|
|
1310
1649
|
};
|
|
1311
1650
|
}
|
|
1312
|
-
}),
|
|
1313
|
-
name: "
|
|
1651
|
+
}), xt = /* @__PURE__ */ c({
|
|
1652
|
+
name: "ImagePlusIcon",
|
|
1314
1653
|
setup(t, {
|
|
1315
1654
|
attrs: l
|
|
1316
1655
|
}) {
|
|
@@ -1323,144 +1662,21 @@ const f1 = /* @__PURE__ */ p({
|
|
|
1323
1662
|
}, l), [e("path", {
|
|
1324
1663
|
"fill-rule": "evenodd",
|
|
1325
1664
|
"clip-rule": "evenodd",
|
|
1326
|
-
d: "
|
|
1665
|
+
d: "M20 2C20 1.44772 19.5523 1 19 1C18.4477 1 18 1.44772 18 2V4H16C15.4477 4 15 4.44772 15 5C15 5.55228 15.4477 6 16 6H18V8C18 8.55228 18.4477 9 19 9C19.5523 9 20 8.55228 20 8V6H22C22.5523 6 23 5.55228 23 5C23 4.44772 22.5523 4 22 4H20V2ZM5 4C4.73478 4 4.48043 4.10536 4.29289 4.29289C4.10536 4.48043 4 4.73478 4 5V19C4 19.2652 4.10536 19.5196 4.29289 19.7071C4.48043 19.8946 4.73478 20 5 20H5.58579L14.379 11.2068C14.9416 10.6444 15.7045 10.3284 16.5 10.3284C17.2955 10.3284 18.0584 10.6444 18.621 11.2068L20 12.5858V12C20 11.4477 20.4477 11 21 11C21.5523 11 22 11.4477 22 12V14.998C22 14.9994 22 15.0007 22 15.002V19C22 19.7957 21.6839 20.5587 21.1213 21.1213C20.5587 21.6839 19.7957 22 19 22H6.00219C6.00073 22 5.99927 22 5.99781 22H5C4.20435 22 3.44129 21.6839 2.87868 21.1213C2.31607 20.5587 2 19.7957 2 19V5C2 4.20435 2.31607 3.44129 2.87868 2.87868C3.44129 2.31607 4.20435 2 5 2H12C12.5523 2 13 2.44772 13 3C13 3.55228 12.5523 4 12 4H5ZM8.41422 20H19C19.2652 20 19.5196 19.8946 19.7071 19.7071C19.8946 19.5196 20 19.2652 20 19V15.4142L17.207 12.6212C17.0195 12.4338 16.7651 12.3284 16.5 12.3284C16.2349 12.3284 15.9806 12.4337 15.7931 12.6211L8.41422 20ZM6.87868 6.87868C7.44129 6.31607 8.20435 6 9 6C9.79565 6 10.5587 6.31607 11.1213 6.87868C11.6839 7.44129 12 8.20435 12 9C12 9.79565 11.6839 10.5587 11.1213 11.1213C10.5587 11.6839 9.79565 12 9 12C8.20435 12 7.44129 11.6839 6.87868 11.1213C6.31607 10.5587 6 9.79565 6 9C6 8.20435 6.31607 7.44129 6.87868 6.87868ZM9 8C8.73478 8 8.48043 8.10536 8.29289 8.29289C8.10536 8.48043 8 8.73478 8 9C8 9.26522 8.10536 9.51957 8.29289 9.70711C8.48043 9.89464 8.73478 10 9 10C9.26522 10 9.51957 9.89464 9.70711 9.70711C9.89464 9.51957 10 9.26522 10 9C10 8.73478 9.89464 8.48043 9.70711 8.29289C9.51957 8.10536 9.26522 8 9 8Z",
|
|
1327
1666
|
fill: "currentColor"
|
|
1328
1667
|
}, null)]);
|
|
1329
1668
|
}
|
|
1330
|
-
}),
|
|
1331
|
-
name: "
|
|
1669
|
+
}), kt = /* @__PURE__ */ c({
|
|
1670
|
+
name: "ImageButton",
|
|
1332
1671
|
setup() {
|
|
1333
|
-
const t =
|
|
1334
|
-
return () => e(w, {
|
|
1335
|
-
icon:
|
|
1336
|
-
tooltip: "
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
}, null);
|
|
1340
|
-
}
|
|
1341
|
-
}), m1 = /* @__PURE__ */ p({
|
|
1342
|
-
name: "MathEditDialog",
|
|
1343
|
-
props: {
|
|
1344
|
-
visible: {
|
|
1345
|
-
type: Boolean,
|
|
1346
|
-
required: !0
|
|
1347
|
-
},
|
|
1348
|
-
latex: {
|
|
1349
|
-
type: String,
|
|
1350
|
-
required: !0
|
|
1351
|
-
},
|
|
1352
|
-
pos: {
|
|
1353
|
-
type: Number,
|
|
1354
|
-
default: null
|
|
1355
|
-
},
|
|
1356
|
-
type: {
|
|
1357
|
-
type: String,
|
|
1358
|
-
required: !0
|
|
1359
|
-
}
|
|
1360
|
-
},
|
|
1361
|
-
emits: ["update:visible"],
|
|
1362
|
-
setup(t, {
|
|
1363
|
-
emit: l
|
|
1364
|
-
}) {
|
|
1365
|
-
const n = A("editor"), o = y(""), u = y("inline");
|
|
1366
|
-
D(() => t.latex, (c) => {
|
|
1367
|
-
o.value = c;
|
|
1368
|
-
}, {
|
|
1369
|
-
immediate: !0
|
|
1370
|
-
}), D(() => t.type, (c) => {
|
|
1371
|
-
u.value = c;
|
|
1372
|
-
}, {
|
|
1373
|
-
immediate: !0
|
|
1374
|
-
});
|
|
1375
|
-
const d = F(() => t.pos === null), f = F(() => o.value.trim() ? _e.renderToString(o.value, {
|
|
1376
|
-
displayMode: u.value === "block",
|
|
1377
|
-
throwOnError: !1
|
|
1378
|
-
}) : ""), m = () => {
|
|
1379
|
-
const c = n?.value;
|
|
1380
|
-
if (!(!c || !o.value.trim())) {
|
|
1381
|
-
if (d.value)
|
|
1382
|
-
u.value === "inline" ? c.chain().focus().insertInlineMath({
|
|
1383
|
-
latex: o.value
|
|
1384
|
-
}).run() : c.chain().focus().insertBlockMath({
|
|
1385
|
-
latex: o.value
|
|
1386
|
-
}).run();
|
|
1387
|
-
else if (u.value === t.type)
|
|
1388
|
-
t.type === "inline" ? c.commands.updateInlineMath({
|
|
1389
|
-
latex: o.value,
|
|
1390
|
-
pos: t.pos
|
|
1391
|
-
}) : c.commands.updateBlockMath({
|
|
1392
|
-
latex: o.value,
|
|
1393
|
-
pos: t.pos
|
|
1394
|
-
});
|
|
1395
|
-
else {
|
|
1396
|
-
const H = t.pos;
|
|
1397
|
-
t.type === "inline" ? c.chain().focus().deleteInlineMath({
|
|
1398
|
-
pos: H
|
|
1399
|
-
}).insertBlockMath({
|
|
1400
|
-
latex: o.value
|
|
1401
|
-
}).run() : c.chain().focus().deleteBlockMath({
|
|
1402
|
-
pos: H
|
|
1403
|
-
}).insertInlineMath({
|
|
1404
|
-
latex: o.value
|
|
1405
|
-
}).run();
|
|
1406
|
-
}
|
|
1407
|
-
l("update:visible", !1);
|
|
1408
|
-
}
|
|
1409
|
-
};
|
|
1410
|
-
return () => e(Se, {
|
|
1411
|
-
modelValue: t.visible,
|
|
1412
|
-
title: d.value ? "插入数学公式" : "编辑数学公式",
|
|
1413
|
-
width: "520px",
|
|
1414
|
-
"onUpdate:modelValue": (c) => l("update:visible", c)
|
|
1415
|
-
}, {
|
|
1416
|
-
default: () => [e("div", {
|
|
1417
|
-
class: "math-dialog"
|
|
1418
|
-
}, [e(Ue, {
|
|
1419
|
-
modelValue: u.value,
|
|
1420
|
-
"onUpdate:modelValue": (c) => {
|
|
1421
|
-
u.value = c;
|
|
1422
|
-
}
|
|
1423
|
-
}, {
|
|
1424
|
-
default: () => [e(q, {
|
|
1425
|
-
value: "inline"
|
|
1426
|
-
}, {
|
|
1427
|
-
default: () => [g("行内公式")]
|
|
1428
|
-
}), e(q, {
|
|
1429
|
-
value: "block"
|
|
1430
|
-
}, {
|
|
1431
|
-
default: () => [g("块级公式")]
|
|
1432
|
-
})]
|
|
1433
|
-
}), e(X, {
|
|
1434
|
-
modelValue: o.value,
|
|
1435
|
-
type: "textarea",
|
|
1436
|
-
rows: 3,
|
|
1437
|
-
placeholder: "请输入 LaTeX 公式,例如:E=mc^2",
|
|
1438
|
-
"onUpdate:modelValue": (c) => {
|
|
1439
|
-
o.value = c;
|
|
1440
|
-
}
|
|
1441
|
-
}, null), e("div", {
|
|
1442
|
-
class: ["math-preview", {
|
|
1443
|
-
"math-preview--empty": !f.value
|
|
1444
|
-
}]
|
|
1445
|
-
}, [f.value ? e("div", {
|
|
1446
|
-
innerHTML: f.value
|
|
1447
|
-
}, null) : e("span", {
|
|
1448
|
-
class: "math-preview__placeholder"
|
|
1449
|
-
}, [g("预览将在此处显示")])])])],
|
|
1450
|
-
footer: () => e(de, null, [e(Z, {
|
|
1451
|
-
onClick: () => l("update:visible", !1)
|
|
1452
|
-
}, {
|
|
1453
|
-
default: () => [g("取消")]
|
|
1454
|
-
}), e(Z, {
|
|
1455
|
-
type: "primary",
|
|
1456
|
-
disabled: !o.value.trim(),
|
|
1457
|
-
onClick: m
|
|
1458
|
-
}, {
|
|
1459
|
-
default: () => [g("确认")]
|
|
1460
|
-
})])
|
|
1461
|
-
});
|
|
1672
|
+
const t = H("editor");
|
|
1673
|
+
return () => e("div", null, [e(w, {
|
|
1674
|
+
icon: xt,
|
|
1675
|
+
tooltip: "图片",
|
|
1676
|
+
onClick: () => t?.value?.commands.setImageUploadNode()
|
|
1677
|
+
}, null)]);
|
|
1462
1678
|
}
|
|
1463
|
-
}),
|
|
1679
|
+
}), Ht = [{
|
|
1464
1680
|
value: "left",
|
|
1465
1681
|
title: "居左",
|
|
1466
1682
|
Icon: le
|
|
@@ -1473,12 +1689,12 @@ const f1 = /* @__PURE__ */ p({
|
|
|
1473
1689
|
title: "居右",
|
|
1474
1690
|
Icon: oe
|
|
1475
1691
|
}], _ = (t) => t.preventDefault();
|
|
1476
|
-
function
|
|
1692
|
+
function Bt(t) {
|
|
1477
1693
|
if (!t.isActive("image")) return null;
|
|
1478
1694
|
const {
|
|
1479
1695
|
selection: l
|
|
1480
1696
|
} = t.state;
|
|
1481
|
-
if (!(l instanceof
|
|
1697
|
+
if (!(l instanceof Ie) || l.node.type.name !== "image") return null;
|
|
1482
1698
|
const n = l.node;
|
|
1483
1699
|
return {
|
|
1484
1700
|
pos: l.from,
|
|
@@ -1487,11 +1703,11 @@ function b1(t) {
|
|
|
1487
1703
|
align: n.attrs.align ?? "left"
|
|
1488
1704
|
};
|
|
1489
1705
|
}
|
|
1490
|
-
function
|
|
1706
|
+
function yt(t) {
|
|
1491
1707
|
const l = t.startsWith("data:") ? "image.png" : t.split("/").pop()?.split("?")[0] || "image.png", n = document.createElement("a");
|
|
1492
1708
|
n.href = t, n.download = l, document.body.appendChild(n), n.click(), document.body.removeChild(n);
|
|
1493
1709
|
}
|
|
1494
|
-
const
|
|
1710
|
+
const At = () => e("svg", {
|
|
1495
1711
|
width: "16",
|
|
1496
1712
|
height: "16",
|
|
1497
1713
|
viewBox: "0 0 24 24",
|
|
@@ -1509,7 +1725,7 @@ const x1 = () => e("svg", {
|
|
|
1509
1725
|
y1: "15",
|
|
1510
1726
|
x2: "12",
|
|
1511
1727
|
y2: "3"
|
|
1512
|
-
}, null)]),
|
|
1728
|
+
}, null)]), Mt = () => e("svg", {
|
|
1513
1729
|
width: "16",
|
|
1514
1730
|
height: "16",
|
|
1515
1731
|
viewBox: "0 0 24 24",
|
|
@@ -1522,7 +1738,7 @@ const x1 = () => e("svg", {
|
|
|
1522
1738
|
points: "1 4 1 10 7 10"
|
|
1523
1739
|
}, null), e("path", {
|
|
1524
1740
|
d: "M3.51 15a9 9 0 1 0 .49-4.1L1 10"
|
|
1525
|
-
}, null)]),
|
|
1741
|
+
}, null)]), It = () => e("svg", {
|
|
1526
1742
|
width: "16",
|
|
1527
1743
|
height: "16",
|
|
1528
1744
|
viewBox: "0 0 24 24",
|
|
@@ -1539,314 +1755,133 @@ const x1 = () => e("svg", {
|
|
|
1539
1755
|
d: "M10 11v6M14 11v6"
|
|
1540
1756
|
}, null), e("path", {
|
|
1541
1757
|
d: "M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"
|
|
1542
|
-
}, null)]),
|
|
1758
|
+
}, null)]), Lt = /* @__PURE__ */ c({
|
|
1543
1759
|
name: "ImageControls",
|
|
1544
1760
|
setup() {
|
|
1545
|
-
const t =
|
|
1761
|
+
const t = H("editor"), l = H("readonly"), n = k(null);
|
|
1546
1762
|
function o() {
|
|
1547
|
-
const
|
|
1548
|
-
if (!
|
|
1763
|
+
const i = t?.value;
|
|
1764
|
+
if (!i) {
|
|
1549
1765
|
n.value = null;
|
|
1550
1766
|
return;
|
|
1551
1767
|
}
|
|
1552
|
-
n.value =
|
|
1768
|
+
n.value = Bt(i);
|
|
1553
1769
|
}
|
|
1554
|
-
return
|
|
1555
|
-
const
|
|
1556
|
-
|
|
1557
|
-
|
|
1770
|
+
return G((i) => {
|
|
1771
|
+
const r = t?.value;
|
|
1772
|
+
r && (r.on("transaction", o), i(() => {
|
|
1773
|
+
r.off("transaction", o);
|
|
1558
1774
|
}));
|
|
1559
1775
|
}), () => {
|
|
1560
|
-
const
|
|
1561
|
-
if (!
|
|
1562
|
-
const
|
|
1563
|
-
if (!
|
|
1776
|
+
const i = n.value;
|
|
1777
|
+
if (!i) return null;
|
|
1778
|
+
const r = t?.value;
|
|
1779
|
+
if (!r) return null;
|
|
1564
1780
|
const {
|
|
1565
|
-
pos:
|
|
1566
|
-
nodeSize:
|
|
1567
|
-
src:
|
|
1568
|
-
align:
|
|
1569
|
-
} =
|
|
1570
|
-
if (!
|
|
1571
|
-
const
|
|
1572
|
-
if (!
|
|
1573
|
-
const
|
|
1781
|
+
pos: v,
|
|
1782
|
+
nodeSize: p,
|
|
1783
|
+
src: s,
|
|
1784
|
+
align: y
|
|
1785
|
+
} = i, u = l?.value ?? !1, C = r.view.nodeDOM(v);
|
|
1786
|
+
if (!C || !(C instanceof HTMLElement)) return null;
|
|
1787
|
+
const g = C.querySelector("[data-resize-wrapper]") ?? C, I = r.view.dom.closest(".tiptap-editor");
|
|
1788
|
+
if (!I) return null;
|
|
1789
|
+
const x = g.getBoundingClientRect(), a = I.getBoundingClientRect(), d = {
|
|
1574
1790
|
position: "absolute",
|
|
1575
|
-
top: `${
|
|
1576
|
-
left: `${
|
|
1791
|
+
top: `${x.top - a.top}px`,
|
|
1792
|
+
left: `${x.left - a.left + x.width / 2}px`,
|
|
1577
1793
|
transform: "translate(-50%, calc(-100% - 8px))",
|
|
1578
1794
|
zIndex: 20
|
|
1579
1795
|
};
|
|
1580
1796
|
return e("div", {
|
|
1581
1797
|
class: "image-controls",
|
|
1582
|
-
style:
|
|
1583
|
-
}, [!
|
|
1584
|
-
value:
|
|
1798
|
+
style: d
|
|
1799
|
+
}, [!u && Ht.map(({
|
|
1800
|
+
value: f,
|
|
1585
1801
|
title: h,
|
|
1586
1802
|
Icon: B
|
|
1587
1803
|
}) => e("button", {
|
|
1588
|
-
key:
|
|
1589
|
-
class: ["image-controls-btn",
|
|
1804
|
+
key: f,
|
|
1805
|
+
class: ["image-controls-btn", y === f && "is-active"],
|
|
1590
1806
|
title: h,
|
|
1591
1807
|
onMousedown: _,
|
|
1592
|
-
onClick: () =>
|
|
1593
|
-
align:
|
|
1808
|
+
onClick: () => r.chain().focus().updateAttributes("image", {
|
|
1809
|
+
align: f
|
|
1594
1810
|
}).run()
|
|
1595
|
-
}, [e(B, null, null)])), !
|
|
1811
|
+
}, [e(B, null, null)])), !u && e("span", {
|
|
1596
1812
|
class: "image-controls-separator"
|
|
1597
1813
|
}, null), e("button", {
|
|
1598
1814
|
class: "image-controls-btn",
|
|
1599
1815
|
title: "下载",
|
|
1600
1816
|
onMousedown: _,
|
|
1601
|
-
onClick: () =>
|
|
1602
|
-
}, [e(
|
|
1817
|
+
onClick: () => yt(s)
|
|
1818
|
+
}, [e(At, null, null)]), !u && e("button", {
|
|
1603
1819
|
class: "image-controls-btn",
|
|
1604
1820
|
title: "重新上传",
|
|
1605
1821
|
onMousedown: _,
|
|
1606
|
-
onClick: () =>
|
|
1607
|
-
from:
|
|
1608
|
-
to:
|
|
1609
|
-
}).insertContentAt(
|
|
1822
|
+
onClick: () => r.chain().focus().deleteRange({
|
|
1823
|
+
from: v,
|
|
1824
|
+
to: v + p
|
|
1825
|
+
}).insertContentAt(v, {
|
|
1610
1826
|
type: "imageUpload"
|
|
1611
1827
|
}).run()
|
|
1612
|
-
}, [e(
|
|
1828
|
+
}, [e(Mt, null, null)]), !u && e("button", {
|
|
1613
1829
|
class: "image-controls-btn",
|
|
1614
1830
|
title: "删除",
|
|
1615
1831
|
onMousedown: _,
|
|
1616
|
-
onClick: () =>
|
|
1617
|
-
from:
|
|
1618
|
-
to:
|
|
1832
|
+
onClick: () => r.chain().focus().deleteRange({
|
|
1833
|
+
from: v,
|
|
1834
|
+
to: v + p
|
|
1619
1835
|
}).run()
|
|
1620
|
-
}, [e(
|
|
1621
|
-
};
|
|
1622
|
-
}
|
|
1623
|
-
}), B1 = /* @__PURE__ */ p({
|
|
1624
|
-
name: "CodeBlockIcon",
|
|
1625
|
-
setup(t, {
|
|
1626
|
-
attrs: l
|
|
1627
|
-
}) {
|
|
1628
|
-
return () => e("svg", b({
|
|
1629
|
-
width: "24",
|
|
1630
|
-
height: "24",
|
|
1631
|
-
viewBox: "0 0 24 24",
|
|
1632
|
-
fill: "none",
|
|
1633
|
-
stroke: "currentColor",
|
|
1634
|
-
"stroke-width": "2",
|
|
1635
|
-
"stroke-linecap": "round",
|
|
1636
|
-
"stroke-linejoin": "round",
|
|
1637
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
1638
|
-
}, l), [e("polyline", {
|
|
1639
|
-
points: "16 18 22 12 16 6"
|
|
1640
|
-
}, null), e("polyline", {
|
|
1641
|
-
points: "8 6 2 12 8 18"
|
|
1642
|
-
}, null)]);
|
|
1643
|
-
}
|
|
1644
|
-
}), M1 = /* @__PURE__ */ p({
|
|
1645
|
-
name: "CodeBlockButton",
|
|
1646
|
-
setup() {
|
|
1647
|
-
const t = A("editor");
|
|
1648
|
-
return () => e(w, {
|
|
1649
|
-
icon: B1,
|
|
1650
|
-
tooltip: "代码块",
|
|
1651
|
-
isActive: t?.value?.isActive("codeBlock"),
|
|
1652
|
-
onClick: () => t?.value?.chain().focus().toggleCodeBlock().run()
|
|
1653
|
-
}, null);
|
|
1654
|
-
}
|
|
1655
|
-
}), L1 = /* @__PURE__ */ p({
|
|
1656
|
-
name: "BubbleMenuBar",
|
|
1657
|
-
setup() {
|
|
1658
|
-
const t = A("editor"), l = A("readonly");
|
|
1659
|
-
return () => t?.value ? e(Oe, {
|
|
1660
|
-
editor: t.value,
|
|
1661
|
-
class: "bubble-menu",
|
|
1662
|
-
options: {
|
|
1663
|
-
placement: "top",
|
|
1664
|
-
offset: {
|
|
1665
|
-
mainAxis: 8
|
|
1666
|
-
}
|
|
1667
|
-
},
|
|
1668
|
-
shouldShow: (n) => {
|
|
1669
|
-
if (l?.value) return !1;
|
|
1670
|
-
const {
|
|
1671
|
-
editor: o,
|
|
1672
|
-
from: u,
|
|
1673
|
-
to: d
|
|
1674
|
-
} = n;
|
|
1675
|
-
return !(u === d || o.isActive("image") || o.isActive("table"));
|
|
1676
|
-
}
|
|
1677
|
-
}, {
|
|
1678
|
-
default: () => [e("div", {
|
|
1679
|
-
class: "bubble-menu-content"
|
|
1680
|
-
}, [e(w, {
|
|
1681
|
-
icon: Q,
|
|
1682
|
-
tooltip: "粗体",
|
|
1683
|
-
isActive: t.value.isActive("bold"),
|
|
1684
|
-
onClick: () => t.value?.chain().focus().toggleBold().run()
|
|
1685
|
-
}, null), e(w, {
|
|
1686
|
-
icon: Y,
|
|
1687
|
-
tooltip: "斜体",
|
|
1688
|
-
isActive: t.value.isActive("italic"),
|
|
1689
|
-
onClick: () => t.value?.chain().focus().toggleItalic().run()
|
|
1690
|
-
}, null), e(w, {
|
|
1691
|
-
icon: ee,
|
|
1692
|
-
tooltip: "删除线",
|
|
1693
|
-
isActive: t.value.isActive("strike"),
|
|
1694
|
-
onClick: () => t.value?.chain().focus().toggleStrike().run()
|
|
1695
|
-
}, null), e(w, {
|
|
1696
|
-
icon: te,
|
|
1697
|
-
tooltip: "下划线",
|
|
1698
|
-
isActive: t.value.isActive("underline"),
|
|
1699
|
-
onClick: () => t.value?.chain().focus().toggleUnderline().run()
|
|
1700
|
-
}, null)])]
|
|
1701
|
-
}) : null;
|
|
1702
|
-
}
|
|
1703
|
-
}), I1 = He(ye), q1 = /* @__PURE__ */ p({
|
|
1704
|
-
name: "TiptapEditor",
|
|
1705
|
-
props: {
|
|
1706
|
-
modelValue: {
|
|
1707
|
-
type: String,
|
|
1708
|
-
default: ""
|
|
1709
|
-
},
|
|
1710
|
-
placeholder: {
|
|
1711
|
-
type: String,
|
|
1712
|
-
default: "请输入内容..."
|
|
1713
|
-
},
|
|
1714
|
-
upload: {
|
|
1715
|
-
type: Function,
|
|
1716
|
-
default: void 0
|
|
1717
|
-
},
|
|
1718
|
-
readonly: {
|
|
1719
|
-
type: Boolean,
|
|
1720
|
-
default: !1
|
|
1721
|
-
},
|
|
1722
|
-
toolbar: {
|
|
1723
|
-
type: Array,
|
|
1724
|
-
default: void 0
|
|
1725
|
-
}
|
|
1726
|
-
},
|
|
1727
|
-
emits: ["update:modelValue"],
|
|
1728
|
-
setup(t, {
|
|
1729
|
-
emit: l
|
|
1730
|
-
}) {
|
|
1731
|
-
const n = {
|
|
1732
|
-
"undo-redo": Ge,
|
|
1733
|
-
"text-style": e1,
|
|
1734
|
-
"code-block": M1,
|
|
1735
|
-
list: u1,
|
|
1736
|
-
"text-align": l1,
|
|
1737
|
-
image: a1,
|
|
1738
|
-
table: p1,
|
|
1739
|
-
math: g1
|
|
1740
|
-
}, o = F(() => t.toolbar ?? Ne), u = (r, x) => {
|
|
1741
|
-
if (r === "|")
|
|
1742
|
-
return e("div", {
|
|
1743
|
-
key: `separator-${x}`,
|
|
1744
|
-
class: "tiptap-separator"
|
|
1745
|
-
}, null);
|
|
1746
|
-
if (typeof r == "object" && r.type === "custom") {
|
|
1747
|
-
const a = r.component;
|
|
1748
|
-
return e(a, {
|
|
1749
|
-
key: r.key ?? `custom-${x}`
|
|
1750
|
-
}, null);
|
|
1751
|
-
}
|
|
1752
|
-
const k = n[r];
|
|
1753
|
-
return k ? e(k, {
|
|
1754
|
-
key: r
|
|
1755
|
-
}, null) : null;
|
|
1756
|
-
}, d = y(!1), f = y(""), m = y(null), c = y("inline"), H = F(() => t.readonly ?? !1), i = (r = {}) => {
|
|
1757
|
-
H.value || (f.value = r.latex ?? "", m.value = r.pos ?? null, c.value = r.type ?? "inline", d.value = !0);
|
|
1836
|
+
}, [e(It, null, null)])]);
|
|
1758
1837
|
};
|
|
1759
|
-
P("openMathDialog", i), P("readonly", H);
|
|
1760
|
-
const s = he({
|
|
1761
|
-
content: t.modelValue,
|
|
1762
|
-
editable: !t.readonly,
|
|
1763
|
-
extensions: [pe.configure({
|
|
1764
|
-
codeBlock: !1,
|
|
1765
|
-
link: {
|
|
1766
|
-
openOnClick: !1,
|
|
1767
|
-
enableClickSelection: !0
|
|
1768
|
-
}
|
|
1769
|
-
}), ke.configure({
|
|
1770
|
-
placeholder: t.placeholder
|
|
1771
|
-
}), xe.configure({
|
|
1772
|
-
lowlight: I1,
|
|
1773
|
-
defaultLanguage: "plaintext"
|
|
1774
|
-
}), be.configure({
|
|
1775
|
-
types: ["heading", "paragraph"]
|
|
1776
|
-
}), me, we.configure({
|
|
1777
|
-
nested: !0
|
|
1778
|
-
}), Pe.configure({
|
|
1779
|
-
allowBase64: !0,
|
|
1780
|
-
resize: {
|
|
1781
|
-
enabled: !0,
|
|
1782
|
-
directions: ["top", "right", "bottom", "left", "top-right", "top-left", "bottom-right", "bottom-left"],
|
|
1783
|
-
minWidth: 50,
|
|
1784
|
-
minHeight: 50,
|
|
1785
|
-
alwaysPreserveAspectRatio: !1
|
|
1786
|
-
}
|
|
1787
|
-
}), ze.configure({
|
|
1788
|
-
...t.upload ? {
|
|
1789
|
-
upload: t.upload
|
|
1790
|
-
} : {}
|
|
1791
|
-
}), Ve.configure({
|
|
1792
|
-
resizable: !0
|
|
1793
|
-
}), Ee, Fe, Te, Ze.configure({
|
|
1794
|
-
inlineOptions: {
|
|
1795
|
-
onClick: (r, x) => i({
|
|
1796
|
-
latex: r.attrs.latex,
|
|
1797
|
-
pos: x,
|
|
1798
|
-
type: "inline"
|
|
1799
|
-
})
|
|
1800
|
-
},
|
|
1801
|
-
blockOptions: {
|
|
1802
|
-
onClick: (r, x) => i({
|
|
1803
|
-
latex: r.attrs.latex,
|
|
1804
|
-
pos: x,
|
|
1805
|
-
type: "block"
|
|
1806
|
-
})
|
|
1807
|
-
}
|
|
1808
|
-
})],
|
|
1809
|
-
onUpdate: ({
|
|
1810
|
-
editor: r
|
|
1811
|
-
}) => {
|
|
1812
|
-
l("update:modelValue", r.getHTML());
|
|
1813
|
-
}
|
|
1814
|
-
});
|
|
1815
|
-
return P("editor", s), D(() => t.modelValue, (r) => {
|
|
1816
|
-
s.value && r !== s.value.getHTML() && s.value.commands.setContent(r, {
|
|
1817
|
-
emitUpdate: !1
|
|
1818
|
-
});
|
|
1819
|
-
}), D(() => t.readonly, (r) => {
|
|
1820
|
-
s.value?.setEditable(!r);
|
|
1821
|
-
}), () => e("div", {
|
|
1822
|
-
class: "tiptap-editor"
|
|
1823
|
-
}, [!t.readonly && e("div", {
|
|
1824
|
-
class: "tiptap-toolbar"
|
|
1825
|
-
}, [o.value.map((r, x) => u(r, x))]), e(ge, {
|
|
1826
|
-
class: "tiptap-content",
|
|
1827
|
-
editor: s.value
|
|
1828
|
-
}, null), e(L1, null, null), e(f1, null, null), e(A1, null, null), e(m1, {
|
|
1829
|
-
visible: d.value,
|
|
1830
|
-
latex: f.value,
|
|
1831
|
-
pos: m.value,
|
|
1832
|
-
type: c.value,
|
|
1833
|
-
"onUpdate:visible": (r) => {
|
|
1834
|
-
d.value = r;
|
|
1835
|
-
}
|
|
1836
|
-
}, null)]);
|
|
1837
1838
|
}
|
|
1838
1839
|
});
|
|
1840
|
+
function t1(t) {
|
|
1841
|
+
return {
|
|
1842
|
+
name: "image",
|
|
1843
|
+
install: () => ({
|
|
1844
|
+
extensions: [
|
|
1845
|
+
Ne.configure({
|
|
1846
|
+
allowBase64: !0,
|
|
1847
|
+
resize: {
|
|
1848
|
+
enabled: !0,
|
|
1849
|
+
directions: ["top", "right", "bottom", "left", "top-right", "top-left", "bottom-right", "bottom-left"],
|
|
1850
|
+
minWidth: 50,
|
|
1851
|
+
minHeight: 50,
|
|
1852
|
+
alwaysPreserveAspectRatio: !1
|
|
1853
|
+
}
|
|
1854
|
+
}),
|
|
1855
|
+
bt.configure({ ...t ? { upload: t } : {} })
|
|
1856
|
+
],
|
|
1857
|
+
controlComponent: Lt
|
|
1858
|
+
}),
|
|
1859
|
+
toolbarComponent: kt
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
const l1 = {
|
|
1863
|
+
name: "separator",
|
|
1864
|
+
install: () => ({
|
|
1865
|
+
extensions: []
|
|
1866
|
+
}),
|
|
1867
|
+
toolbarComponent: /* @__PURE__ */ c({
|
|
1868
|
+
name: "ToolbarSeparator",
|
|
1869
|
+
setup: () => () => e("div", {
|
|
1870
|
+
class: "tiptap-separator"
|
|
1871
|
+
}, null)
|
|
1872
|
+
})
|
|
1873
|
+
};
|
|
1839
1874
|
export {
|
|
1840
|
-
|
|
1841
|
-
Ne as DEFAULT_TOOLBAR_CONFIG,
|
|
1875
|
+
Qt as CodeBlockFeature,
|
|
1842
1876
|
w as IconButton,
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1877
|
+
t1 as ImageFeature,
|
|
1878
|
+
Ne as ImageWithAlign,
|
|
1879
|
+
Xt as ListFeature,
|
|
1880
|
+
e1 as MathFeature,
|
|
1881
|
+
l1 as SeparatorFeature,
|
|
1882
|
+
Yt as TableFeature,
|
|
1883
|
+
Jt as TextAlignFeature,
|
|
1884
|
+
Gt as TextStyleFeature,
|
|
1885
|
+
qt as TiptapEditor,
|
|
1886
|
+
Kt as UndoRedoFeature
|
|
1852
1887
|
};
|