@agent-arts/editor 0.0.5 → 0.1.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 +482 -269
- package/dist/editor.umd.cjs +2 -2
- package/dist/index.d.ts +84 -15
- package/package.json +3 -3
package/dist/editor.js
CHANGED
|
@@ -1,203 +1,95 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var r = (
|
|
4
|
-
import { StateEffect as
|
|
5
|
-
import { EditorView as
|
|
6
|
-
import { history as
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
r(this, "view");
|
|
12
|
-
r(this, "allBlocks", /* @__PURE__ */ new Map());
|
|
13
|
-
r(this, "options");
|
|
14
|
-
this.options = e, e.initialBlocks && e.initialBlocks.forEach((i) => this.allBlocks.set(i.block.id, i.block));
|
|
15
|
-
const t = {
|
|
16
|
-
updateBlockText: (i, s) => {
|
|
17
|
-
const c = this.allBlocks.get(i);
|
|
18
|
-
c && (c.presetText = s, this.allBlocks.set(i, c), this.options.onBlockUpdated && this.options.onBlockUpdated(i, s));
|
|
19
|
-
},
|
|
20
|
-
openPopup: (i, s) => {
|
|
21
|
-
this.options.onOpenPopup(i, s);
|
|
22
|
-
},
|
|
23
|
-
deleteBlock: (i) => {
|
|
24
|
-
this.allBlocks.delete(i), this.options.onBlockDeleted && this.options.onBlockDeleted(i);
|
|
25
|
-
}
|
|
26
|
-
}, o = N(e.initialDoc, t, e.initialBlocks || []), l = f.updateListener.of((i) => {
|
|
27
|
-
i.docChanged && i.changes.iterChanges((s, c, d, a, m) => {
|
|
28
|
-
const b = m.sliceString(0);
|
|
29
|
-
m.length === 1 && (b === "{" ? this.options.onTriggerPluginPopup(s) : b === "/" && this.options.onTriggerAIDialog(s));
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
this.view = new f({
|
|
33
|
-
state: o.update({
|
|
34
|
-
effects: u.appendConfig.of(l)
|
|
35
|
-
}).state,
|
|
36
|
-
parent: e.parent
|
|
37
|
-
});
|
|
1
|
+
var I = Object.defineProperty;
|
|
2
|
+
var F = (o, t, e) => t in o ? I(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
|
+
var r = (o, t, e) => F(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { StateEffect as k, Facet as x, StateField as y, EditorState as R } from "@codemirror/state";
|
|
5
|
+
import { EditorView as u, Decoration as d, WidgetType as E, ViewPlugin as $, keymap as _, drawSelection as G } from "@codemirror/view";
|
|
6
|
+
import { history as W, defaultKeymap as N, historyKeymap as z } from "@codemirror/commands";
|
|
7
|
+
const C = k.define(), A = k.define();
|
|
8
|
+
class g extends E {
|
|
9
|
+
constructor(t, e) {
|
|
10
|
+
super(), this.block = t, this.callbacks = e;
|
|
38
11
|
}
|
|
39
|
-
|
|
40
|
-
const e =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
effects: y.of(e),
|
|
50
|
-
selection: { anchor: t + 1 }
|
|
51
|
-
}), this.view.focus(), e;
|
|
52
|
-
}
|
|
53
|
-
addPluginBlock(e, t) {
|
|
54
|
-
return this.view.dispatch({
|
|
55
|
-
changes: { from: e, to: e + 1, insert: " " },
|
|
56
|
-
effects: v.of({ pos: e, block: t }),
|
|
57
|
-
selection: { anchor: e + 1 }
|
|
58
|
-
}), this.view.focus(), t;
|
|
59
|
-
}
|
|
60
|
-
syncBlock(e) {
|
|
61
|
-
this.allBlocks.set(e.id, { ...e }), this.view.dispatch({
|
|
62
|
-
effects: x.of(e)
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
getBlock(e) {
|
|
66
|
-
return this.allBlocks.get(e);
|
|
67
|
-
}
|
|
68
|
-
coordsAtPos(e) {
|
|
69
|
-
return this.view.coordsAtPos(e);
|
|
70
|
-
}
|
|
71
|
-
getData() {
|
|
72
|
-
return H(this.view, this.allBlocks);
|
|
73
|
-
}
|
|
74
|
-
destroy() {
|
|
75
|
-
this.view.destroy();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
const y = u.define(), x = u.define(), v = u.define();
|
|
79
|
-
class h extends B {
|
|
80
|
-
constructor(e, t) {
|
|
81
|
-
super(), this.block = e, this.callbacks = t;
|
|
82
|
-
}
|
|
83
|
-
toDOM(e) {
|
|
84
|
-
const t = document.createElement("span");
|
|
85
|
-
t.className = "cm-inline-block", t.setAttribute("data-block-id", this.block.id);
|
|
86
|
-
const o = document.createElement("input");
|
|
87
|
-
o.type = "text", o.className = "block-input", o.value = this.block.presetText || "", o.placeholder = this.block.placeholder || "请输入...";
|
|
88
|
-
const l = (i) => {
|
|
89
|
-
const s = document.createElement("span");
|
|
90
|
-
s.style.visibility = "hidden", s.style.position = "absolute", s.style.whiteSpace = "pre", s.style.font = "inherit", s.textContent = i || o.placeholder, document.body.appendChild(s);
|
|
91
|
-
const c = s.offsetWidth;
|
|
92
|
-
return document.body.removeChild(s), c + 10;
|
|
12
|
+
toDOM(t) {
|
|
13
|
+
const e = document.createElement("span");
|
|
14
|
+
e.className = "cm-inline-block", e.setAttribute("data-block-id", this.block.id);
|
|
15
|
+
const i = document.createElement("input");
|
|
16
|
+
i.type = "text", i.className = "block-input", i.value = this.block.presetText || "", i.placeholder = this.block.placeholder || "请输入...";
|
|
17
|
+
const l = (s) => {
|
|
18
|
+
const n = document.createElement("span");
|
|
19
|
+
n.style.visibility = "hidden", n.style.position = "absolute", n.style.whiteSpace = "pre", n.style.font = "inherit", n.textContent = s || i.placeholder, document.body.appendChild(n);
|
|
20
|
+
const c = n.offsetWidth;
|
|
21
|
+
return document.body.removeChild(n), c + 10;
|
|
93
22
|
};
|
|
94
|
-
return
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
const s =
|
|
23
|
+
return i.style.width = `${l(i.value)}px`, i.oninput = (s) => {
|
|
24
|
+
const n = s.target.value;
|
|
25
|
+
i.style.width = `${l(n)}px`, this.callbacks.updateBlockText(this.block.id, n);
|
|
26
|
+
}, i.onfocus = () => {
|
|
27
|
+
const s = e.getBoundingClientRect();
|
|
99
28
|
this.callbacks.openPopup(this.block.id, s);
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
this.callbacks.openPopup(this.block.id,
|
|
106
|
-
},
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
selection: { anchor: s }
|
|
115
|
-
}));
|
|
29
|
+
}, i.onmousedown = (s) => {
|
|
30
|
+
s.stopPropagation();
|
|
31
|
+
}, i.onclick = (s) => {
|
|
32
|
+
s.stopPropagation();
|
|
33
|
+
const n = e.getBoundingClientRect();
|
|
34
|
+
this.callbacks.openPopup(this.block.id, n);
|
|
35
|
+
}, i.onkeydown = (s) => {
|
|
36
|
+
if (s.key === "Backspace" && i.value === "") {
|
|
37
|
+
s.preventDefault();
|
|
38
|
+
const n = t.posAtDOM(e);
|
|
39
|
+
this.callbacks.deleteBlock(this.block.id), t.dispatch({
|
|
40
|
+
changes: { from: n, to: n + 1 },
|
|
41
|
+
selection: { anchor: n }
|
|
42
|
+
});
|
|
116
43
|
}
|
|
117
|
-
},
|
|
118
|
-
}
|
|
119
|
-
ignoreEvent(e) {
|
|
120
|
-
return !0;
|
|
44
|
+
}, e.appendChild(i), e;
|
|
121
45
|
}
|
|
122
|
-
|
|
123
|
-
class W extends B {
|
|
124
|
-
constructor(e) {
|
|
125
|
-
super(), this.block = e;
|
|
126
|
-
}
|
|
127
|
-
toDOM() {
|
|
128
|
-
const e = document.createElement("span");
|
|
129
|
-
e.className = `cm-plugin-block cm-plugin-block-${this.block.type}`, e.setAttribute("data-block-id", this.block.id);
|
|
130
|
-
const t = document.createElement("i");
|
|
131
|
-
t.className = this.block.type === "plugin" ? "icon-plugin" : "icon-workflow", e.appendChild(t);
|
|
132
|
-
const o = document.createTextNode(this.block.name);
|
|
133
|
-
return e.appendChild(o), e;
|
|
134
|
-
}
|
|
135
|
-
ignoreEvent(e) {
|
|
46
|
+
ignoreEvent() {
|
|
136
47
|
return !0;
|
|
137
48
|
}
|
|
138
49
|
}
|
|
139
|
-
const
|
|
140
|
-
combine: (
|
|
141
|
-
}),
|
|
142
|
-
combine: (
|
|
143
|
-
}),
|
|
144
|
-
create(
|
|
145
|
-
const
|
|
146
|
-
if (!
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
50
|
+
const w = x.define({
|
|
51
|
+
combine: (o) => o[0]
|
|
52
|
+
}), D = x.define({
|
|
53
|
+
combine: (o) => o.length ? o[0] : []
|
|
54
|
+
}), v = y.define({
|
|
55
|
+
create(o) {
|
|
56
|
+
const t = o.facet(w), e = o.facet(D);
|
|
57
|
+
if (!e || e.length === 0) return d.none;
|
|
58
|
+
const i = e.slice().sort((l, s) => l.pos - s.pos).map(({ pos: l, len: s, block: n }) => {
|
|
59
|
+
const c = new g(n, t);
|
|
60
|
+
return d.replace({ widget: c }).range(l, l + (s || 1));
|
|
61
|
+
});
|
|
62
|
+
return d.set(i, !0);
|
|
151
63
|
},
|
|
152
|
-
update(
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
for (
|
|
156
|
-
if (
|
|
157
|
-
const l =
|
|
158
|
-
widget: new
|
|
64
|
+
update(o, t) {
|
|
65
|
+
const e = t.state.facet(w);
|
|
66
|
+
o = o.map(t.changes);
|
|
67
|
+
for (const i of t.effects)
|
|
68
|
+
if (i.is(C)) {
|
|
69
|
+
const l = t.state.selection.main.head - 1, s = d.replace({
|
|
70
|
+
widget: new g(i.value, e)
|
|
159
71
|
}).range(l, l + 1);
|
|
160
|
-
|
|
161
|
-
} else if (
|
|
162
|
-
const l =
|
|
163
|
-
let
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
}),
|
|
168
|
-
filter: (
|
|
169
|
-
const
|
|
170
|
-
return !(
|
|
72
|
+
o = o.update({ add: [s] });
|
|
73
|
+
} else if (i.is(A)) {
|
|
74
|
+
const l = i.value;
|
|
75
|
+
let s = null;
|
|
76
|
+
o.between(0, t.state.doc.length, (n, c, a) => {
|
|
77
|
+
const h = a.spec.widget;
|
|
78
|
+
h instanceof g && h.block.id === l.id && (s = n);
|
|
79
|
+
}), s !== null && (o = o.update({
|
|
80
|
+
filter: (n, c, a) => {
|
|
81
|
+
const h = a.spec.widget;
|
|
82
|
+
return !(h instanceof g && h.block.id === l.id);
|
|
171
83
|
},
|
|
172
|
-
add: [
|
|
173
|
-
widget: new
|
|
174
|
-
}).range(
|
|
84
|
+
add: [d.replace({
|
|
85
|
+
widget: new g(l, e)
|
|
86
|
+
}).range(s, s + 1)]
|
|
175
87
|
}));
|
|
176
|
-
} else if (o.is(v)) {
|
|
177
|
-
const { pos: l, block: i } = o.value, s = e.changes.mapPos(l), c = p.replace({
|
|
178
|
-
widget: new W(i)
|
|
179
|
-
}).range(s, s + 1);
|
|
180
|
-
n = n.update({ add: [c] });
|
|
181
88
|
}
|
|
182
|
-
return
|
|
89
|
+
return o;
|
|
183
90
|
},
|
|
184
|
-
provide: (
|
|
185
|
-
}),
|
|
186
|
-
const t = n.state.selection.main.head;
|
|
187
|
-
if (t === 0) return !1;
|
|
188
|
-
let o = null, l = null;
|
|
189
|
-
const i = n.state.field(k, !1);
|
|
190
|
-
return i && i.between(t - 1, t, (s, c, d) => {
|
|
191
|
-
const a = d.spec.widget;
|
|
192
|
-
a instanceof h && (o = a.block.id, l = s);
|
|
193
|
-
}), o && l !== null ? (e.deleteBlock(o), n.dispatch({
|
|
194
|
-
changes: { from: l, to: l + 1 },
|
|
195
|
-
selection: { anchor: l }
|
|
196
|
-
}), !0) : !1;
|
|
197
|
-
}, M = f.theme({
|
|
198
|
-
"&": { height: "100%", outline: "none" },
|
|
199
|
-
".cm-content": { padding: "20px", fontSize: "16px" },
|
|
200
|
-
".cm-line": { padding: "4px 0" },
|
|
91
|
+
provide: (o) => u.decorations.from(o)
|
|
92
|
+
}), H = u.theme({
|
|
201
93
|
".cm-inline-block": {
|
|
202
94
|
display: "inline-block",
|
|
203
95
|
backgroundColor: "#f3f0ff",
|
|
@@ -229,76 +121,71 @@ const g = w.define({
|
|
|
229
121
|
".block-input::placeholder": {
|
|
230
122
|
color: "#b2a1ff",
|
|
231
123
|
opacity: 0.7
|
|
232
|
-
}
|
|
233
|
-
".cm-header-1": { fontSize: "1.5em", color: "#008c99", fontWeight: "bold" }
|
|
124
|
+
}
|
|
234
125
|
});
|
|
235
|
-
function
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
D.of([
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{
|
|
242
|
-
key: "Backspace",
|
|
243
|
-
run: (i) => F(i, e)
|
|
244
|
-
}
|
|
245
|
-
]),
|
|
246
|
-
R({ base: $, codeLanguages: I }),
|
|
247
|
-
g.of(e),
|
|
248
|
-
S.of(t),
|
|
249
|
-
k,
|
|
250
|
-
M
|
|
126
|
+
function O(o) {
|
|
127
|
+
return [
|
|
128
|
+
w.of(o.callbacks),
|
|
129
|
+
D.of(o.initialBlocks || []),
|
|
130
|
+
v,
|
|
131
|
+
H
|
|
251
132
|
];
|
|
252
|
-
return C.create({
|
|
253
|
-
doc: n,
|
|
254
|
-
extensions: o
|
|
255
|
-
});
|
|
256
133
|
}
|
|
257
|
-
function
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
134
|
+
function j(o) {
|
|
135
|
+
const t = [], e = o.state.field(v, !1);
|
|
136
|
+
return e && e.between(0, o.state.doc.length, (i, l, s) => {
|
|
137
|
+
const n = s.spec.widget;
|
|
138
|
+
n instanceof g && t.push({ pos: i, len: l - i, block: n.block });
|
|
139
|
+
}), t;
|
|
262
140
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
141
|
+
class rt {
|
|
142
|
+
constructor(t) {
|
|
143
|
+
r(this, "editingBlock", { id: "", placeholder: "", presetText: "" });
|
|
144
|
+
this.callbacks = t;
|
|
145
|
+
}
|
|
146
|
+
show(t, e, i) {
|
|
147
|
+
this.editingBlock = { ...t };
|
|
148
|
+
const l = {
|
|
149
|
+
top: `${e.bottom - i.top + 10}px`,
|
|
150
|
+
left: `${e.left - i.left}px`
|
|
151
|
+
};
|
|
152
|
+
this.callbacks.onShow(this.editingBlock, l);
|
|
153
|
+
}
|
|
154
|
+
hide() {
|
|
155
|
+
this.callbacks.onHide();
|
|
156
|
+
}
|
|
157
|
+
updateEditingBlock(t) {
|
|
158
|
+
this.editingBlock = { ...this.editingBlock, ...t };
|
|
159
|
+
}
|
|
273
160
|
}
|
|
274
|
-
class
|
|
275
|
-
constructor(
|
|
161
|
+
class at {
|
|
162
|
+
constructor(t) {
|
|
276
163
|
r(this, "isGenerating", !1);
|
|
277
164
|
r(this, "aiStreamTimer", null);
|
|
278
165
|
r(this, "currentResponse", "");
|
|
279
|
-
this.callbacks =
|
|
166
|
+
this.callbacks = t;
|
|
280
167
|
}
|
|
281
|
-
show(
|
|
168
|
+
show(t, e, i) {
|
|
282
169
|
const l = {
|
|
283
|
-
top: `${
|
|
284
|
-
left: `${
|
|
170
|
+
top: `${e.bottom - i.top + 10}px`,
|
|
171
|
+
left: `${e.left - i.left}px`
|
|
285
172
|
};
|
|
286
|
-
this.callbacks.onShow(
|
|
173
|
+
this.callbacks.onShow(t, l);
|
|
287
174
|
}
|
|
288
175
|
hide() {
|
|
289
176
|
this.stopResponse(), this.callbacks.onHide();
|
|
290
177
|
}
|
|
291
|
-
sendQuestion(
|
|
292
|
-
if (!
|
|
178
|
+
sendQuestion(t) {
|
|
179
|
+
if (!t || this.isGenerating) return;
|
|
293
180
|
this.isGenerating = !0, this.callbacks.onLoading(!0), this.currentResponse = "", this.callbacks.onStream("");
|
|
294
|
-
const
|
|
181
|
+
const e = `你是一个资深旅游向导,积累了丰富的在地经验,擅长结合用户需求定制专属旅行方案,曾帮助1000+人解决旅行难题,被旅行者亲切称为"旅行百事通"。
|
|
295
182
|
|
|
296
183
|
## 核心性格与风格
|
|
297
184
|
- **性格特点**:热情开朗、专业耐心,擅长用轻松幽默的方式化解旅行焦虑(如:"别慌!机票改签我有3个小窍门,保准帮你搞定~"),遇到用户疑问会像朋友般细致拆解细节(如:"你担心的高原反应,我去年在西藏徒步时总结过4个缓解方法...")。
|
|
298
185
|
- **语言风格**:口语化且富有感染力,常用"宝藏地""小众玩法"等旅行圈`;
|
|
299
|
-
let
|
|
186
|
+
let i = 0;
|
|
300
187
|
this.aiStreamTimer = setInterval(() => {
|
|
301
|
-
this.callbacks.onLoading(!1),
|
|
188
|
+
this.callbacks.onLoading(!1), i < e.length ? (this.currentResponse += e[i], this.callbacks.onStream(this.currentResponse), i++) : this.finishGeneration();
|
|
302
189
|
}, 30);
|
|
303
190
|
}
|
|
304
191
|
stopResponse() {
|
|
@@ -314,8 +201,194 @@ class Q {
|
|
|
314
201
|
this.stopResponse();
|
|
315
202
|
}
|
|
316
203
|
}
|
|
317
|
-
|
|
318
|
-
|
|
204
|
+
function V(o) {
|
|
205
|
+
return [
|
|
206
|
+
q(o.onTriggerAIDialog),
|
|
207
|
+
U(o.onTriggerAIDialog),
|
|
208
|
+
K
|
|
209
|
+
];
|
|
210
|
+
}
|
|
211
|
+
function q(o) {
|
|
212
|
+
return u.updateListener.of((t) => {
|
|
213
|
+
t.docChanged && t.changes.iterChanges((e, i, l, s, n) => {
|
|
214
|
+
if (n.length !== 1) return;
|
|
215
|
+
n.sliceString(0) === "/" && o(e);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
const K = u.theme({
|
|
220
|
+
".cm-ai-selection-trigger": {
|
|
221
|
+
position: "absolute",
|
|
222
|
+
zIndex: "10",
|
|
223
|
+
display: "none",
|
|
224
|
+
width: "32px",
|
|
225
|
+
height: "32px",
|
|
226
|
+
alignItems: "center",
|
|
227
|
+
justifyContent: "center",
|
|
228
|
+
borderRadius: "8px",
|
|
229
|
+
backgroundColor: "#fff",
|
|
230
|
+
boxShadow: "0 6px 24px rgba(0, 0, 0, 0.12)",
|
|
231
|
+
border: "1px solid rgba(0, 0, 0, 0.06)"
|
|
232
|
+
},
|
|
233
|
+
".cm-ai-selection-trigger button": {
|
|
234
|
+
width: "100%",
|
|
235
|
+
height: "100%",
|
|
236
|
+
border: "none",
|
|
237
|
+
background: "transparent",
|
|
238
|
+
cursor: "pointer",
|
|
239
|
+
display: "flex",
|
|
240
|
+
alignItems: "center",
|
|
241
|
+
justifyContent: "center",
|
|
242
|
+
padding: "0"
|
|
243
|
+
},
|
|
244
|
+
".cm-ai-selection-trigger button:hover": {
|
|
245
|
+
backgroundColor: "#f3f4f6",
|
|
246
|
+
borderRadius: "8px"
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
function U(o) {
|
|
250
|
+
return $.fromClass(class {
|
|
251
|
+
constructor(t) {
|
|
252
|
+
r(this, "dom");
|
|
253
|
+
r(this, "button");
|
|
254
|
+
r(this, "lastFrom", -1);
|
|
255
|
+
r(this, "lastTo", -1);
|
|
256
|
+
r(this, "measureScheduled", !1);
|
|
257
|
+
this.view = t, this.dom = document.createElement("div"), this.dom.className = "cm-ai-selection-trigger", this.button = document.createElement("button"), this.button.type = "button";
|
|
258
|
+
const e = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
259
|
+
e.setAttribute("width", "16"), e.setAttribute("height", "16"), e.setAttribute("viewBox", "0 0 24 24"), e.setAttribute("fill", "none"), e.setAttribute("stroke", "#111827"), e.setAttribute("stroke-width", "2"), e.setAttribute("stroke-linecap", "round"), e.setAttribute("stroke-linejoin", "round"), e.innerHTML = '<path d="M5 12l1.5.5L7 14l.5-1.5L9 12l-1.5-.5L7 10l-.5 1.5L5 12z"/><path d="M12 4l2 6 6 2-6 2-2 6-2-6-6-2 6-2 2-6z"/>', this.button.appendChild(e), this.dom.appendChild(this.button), this.view.dom.appendChild(this.dom), this.dom.addEventListener("mousedown", (i) => {
|
|
260
|
+
i.preventDefault(), i.stopPropagation();
|
|
261
|
+
}), this.button.addEventListener("click", (i) => {
|
|
262
|
+
i.preventDefault(), i.stopPropagation();
|
|
263
|
+
const { from: l, empty: s } = this.view.state.selection.main;
|
|
264
|
+
s || (o(l), this.hide());
|
|
265
|
+
}), this.scheduleMeasure(!0);
|
|
266
|
+
}
|
|
267
|
+
update(t) {
|
|
268
|
+
(t.selectionSet || t.viewportChanged || t.focusChanged || t.docChanged) && this.scheduleMeasure(!1);
|
|
269
|
+
}
|
|
270
|
+
destroy() {
|
|
271
|
+
this.dom.remove();
|
|
272
|
+
}
|
|
273
|
+
hide() {
|
|
274
|
+
this.dom.style.display = "none";
|
|
275
|
+
}
|
|
276
|
+
show() {
|
|
277
|
+
this.dom.style.display = "flex";
|
|
278
|
+
}
|
|
279
|
+
scheduleMeasure(t) {
|
|
280
|
+
const { from: e, to: i, empty: l } = this.view.state.selection.main;
|
|
281
|
+
if (l || !this.view.hasFocus) {
|
|
282
|
+
this.hide();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
!t && e === this.lastFrom && i === this.lastTo && this.dom.style.display !== "none" || (this.lastFrom = e, this.lastTo = i, !this.measureScheduled && (this.measureScheduled = !0, this.view.requestMeasure({
|
|
286
|
+
read: (s) => {
|
|
287
|
+
const n = s.coordsAtPos(e);
|
|
288
|
+
if (!n) return null;
|
|
289
|
+
const c = s.dom.getBoundingClientRect();
|
|
290
|
+
return { coords: n, editorRect: c };
|
|
291
|
+
},
|
|
292
|
+
write: (s) => {
|
|
293
|
+
this.measureScheduled = !1;
|
|
294
|
+
const { empty: n } = this.view.state.selection.main;
|
|
295
|
+
if (n || !this.view.hasFocus) {
|
|
296
|
+
this.hide();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (!s) {
|
|
300
|
+
this.hide();
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const { coords: c, editorRect: a } = s, h = 32, m = 32, p = 6, b = Math.min(
|
|
304
|
+
Math.max(c.left - a.left, p),
|
|
305
|
+
Math.max(p, a.width - h - p)
|
|
306
|
+
), f = Math.max(c.top - a.top - m - 10, p);
|
|
307
|
+
this.dom.style.left = `${b}px`, this.dom.style.top = `${f}px`, this.show();
|
|
308
|
+
}
|
|
309
|
+
})));
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const M = k.define();
|
|
314
|
+
class B extends E {
|
|
315
|
+
constructor(t) {
|
|
316
|
+
super(), this.block = t;
|
|
317
|
+
}
|
|
318
|
+
toDOM() {
|
|
319
|
+
const t = document.createElement("span");
|
|
320
|
+
t.className = `cm-plugin-block cm-plugin-block-${this.block.type}`, t.setAttribute("data-block-id", this.block.id);
|
|
321
|
+
const e = document.createElement("i");
|
|
322
|
+
e.className = this.block.type === "plugin" ? "icon-plugin" : "icon-workflow", t.appendChild(e);
|
|
323
|
+
const i = document.createTextNode(this.block.name);
|
|
324
|
+
return t.appendChild(i), t;
|
|
325
|
+
}
|
|
326
|
+
ignoreEvent() {
|
|
327
|
+
return !0;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const L = x.define({
|
|
331
|
+
combine: (o) => o.length ? o[0] : []
|
|
332
|
+
}), S = y.define({
|
|
333
|
+
create(o) {
|
|
334
|
+
const t = o.facet(L);
|
|
335
|
+
if (!t || t.length === 0) return d.none;
|
|
336
|
+
const e = t.slice().sort((i, l) => i.pos - l.pos).map(({ pos: i, len: l, block: s }) => d.replace({ widget: new B(s) }).range(i, i + (l || 1)));
|
|
337
|
+
return d.set(e, !0);
|
|
338
|
+
},
|
|
339
|
+
update(o, t) {
|
|
340
|
+
o = o.map(t.changes);
|
|
341
|
+
for (const e of t.effects)
|
|
342
|
+
if (e.is(M)) {
|
|
343
|
+
const { pos: i, block: l } = e.value, s = t.changes.mapPos(i), n = d.replace({
|
|
344
|
+
widget: new B(l)
|
|
345
|
+
}).range(s, s + 1);
|
|
346
|
+
o = o.update({ add: [n] });
|
|
347
|
+
}
|
|
348
|
+
return o;
|
|
349
|
+
},
|
|
350
|
+
provide: (o) => u.decorations.from(o)
|
|
351
|
+
});
|
|
352
|
+
function Q(o) {
|
|
353
|
+
return [
|
|
354
|
+
L.of(o.initialBlocks || []),
|
|
355
|
+
S
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
function J(o) {
|
|
359
|
+
return [
|
|
360
|
+
u.updateListener.of((t) => {
|
|
361
|
+
t.docChanged && t.changes.iterChanges((e, i, l, s, n) => {
|
|
362
|
+
if (n.length !== 1) return;
|
|
363
|
+
n.sliceString(0) === "{" && o.onTriggerPluginPopup(e);
|
|
364
|
+
});
|
|
365
|
+
})
|
|
366
|
+
];
|
|
367
|
+
}
|
|
368
|
+
function X(o) {
|
|
369
|
+
const t = [], e = o.state.field(S, !1);
|
|
370
|
+
return e && e.between(0, o.state.doc.length, (i, l, s) => {
|
|
371
|
+
const n = s.spec.widget;
|
|
372
|
+
n instanceof B && t.push({ pos: i, len: l - i, block: n.block });
|
|
373
|
+
}), t;
|
|
374
|
+
}
|
|
375
|
+
function Y(o) {
|
|
376
|
+
const t = [], e = /\{\{(.+?)\}\}/g;
|
|
377
|
+
let i;
|
|
378
|
+
for (; (i = e.exec(o)) !== null; )
|
|
379
|
+
t.push({
|
|
380
|
+
pos: i.index,
|
|
381
|
+
len: i[0].length,
|
|
382
|
+
block: {
|
|
383
|
+
id: `var-${i[1]}-${i.index}`,
|
|
384
|
+
name: i[1],
|
|
385
|
+
type: "plugin"
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
return t;
|
|
389
|
+
}
|
|
390
|
+
class dt {
|
|
391
|
+
constructor(t) {
|
|
319
392
|
r(this, "plugins", [
|
|
320
393
|
{ id: "plugin-1", name: "LinkReaderPlugin", type: "plugin" }
|
|
321
394
|
]);
|
|
@@ -323,15 +396,15 @@ class J {
|
|
|
323
396
|
{ id: "workflow-1", name: "condition_1_872", type: "workflow" }
|
|
324
397
|
]);
|
|
325
398
|
r(this, "triggerPos", 0);
|
|
326
|
-
this.callbacks =
|
|
399
|
+
this.callbacks = t;
|
|
327
400
|
}
|
|
328
|
-
show(
|
|
329
|
-
this.triggerPos =
|
|
401
|
+
show(t, e, i) {
|
|
402
|
+
this.triggerPos = t;
|
|
330
403
|
const l = {
|
|
331
|
-
top: `${
|
|
332
|
-
left: `${
|
|
404
|
+
top: `${e.bottom - i.top + 10}px`,
|
|
405
|
+
left: `${e.left - i.left}px`
|
|
333
406
|
};
|
|
334
|
-
this.callbacks.onShow(
|
|
407
|
+
this.callbacks.onShow(t, l);
|
|
335
408
|
}
|
|
336
409
|
hide() {
|
|
337
410
|
this.callbacks.onHide();
|
|
@@ -340,37 +413,177 @@ class J {
|
|
|
340
413
|
return this.triggerPos;
|
|
341
414
|
}
|
|
342
415
|
}
|
|
343
|
-
class
|
|
344
|
-
constructor(
|
|
345
|
-
r(this, "
|
|
346
|
-
this
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
416
|
+
class ht {
|
|
417
|
+
constructor(t) {
|
|
418
|
+
r(this, "view");
|
|
419
|
+
r(this, "allBlocks", /* @__PURE__ */ new Map());
|
|
420
|
+
r(this, "options");
|
|
421
|
+
this.options = t;
|
|
422
|
+
const e = Y(t.initialDoc), i = [
|
|
423
|
+
...t.initialBlocks || [],
|
|
424
|
+
...e
|
|
425
|
+
];
|
|
426
|
+
t.initialBlocks && t.initialBlocks.forEach((n) => {
|
|
427
|
+
"type" in n.block || this.allBlocks.set(n.block.id, n.block);
|
|
428
|
+
});
|
|
350
429
|
const l = {
|
|
351
|
-
|
|
352
|
-
|
|
430
|
+
updateBlockText: (n, c) => {
|
|
431
|
+
const a = this.allBlocks.get(n);
|
|
432
|
+
a && (a.presetText = c, this.allBlocks.set(n, a), this.options.onBlockUpdated && this.options.onBlockUpdated(n, c));
|
|
433
|
+
},
|
|
434
|
+
openPopup: (n, c) => {
|
|
435
|
+
this.options.onOpenPopup(n, c);
|
|
436
|
+
},
|
|
437
|
+
deleteBlock: (n) => {
|
|
438
|
+
this.allBlocks.delete(n), this.options.onBlockDeleted && this.options.onBlockDeleted(n);
|
|
439
|
+
}
|
|
440
|
+
}, s = ot(t.initialDoc, l, i);
|
|
441
|
+
this.view = new u({
|
|
442
|
+
state: s.update({
|
|
443
|
+
effects: k.appendConfig.of([
|
|
444
|
+
...J({ onTriggerPluginPopup: (n) => this.options.onTriggerPluginPopup(n) }),
|
|
445
|
+
...V({ onTriggerAIDialog: (n) => this.options.onTriggerAIDialog(n) })
|
|
446
|
+
])
|
|
447
|
+
}).state,
|
|
448
|
+
parent: t.parent
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
addBlock() {
|
|
452
|
+
const t = {
|
|
453
|
+
id: Math.random().toString(36).slice(2, 11),
|
|
454
|
+
placeholder: "请输入编辑块内容为空时的提示文案",
|
|
455
|
+
presetText: ""
|
|
353
456
|
};
|
|
354
|
-
this.
|
|
457
|
+
this.allBlocks.set(t.id, t);
|
|
458
|
+
const { from: e, to: i } = this.view.state.selection.main;
|
|
459
|
+
return this.view.dispatch({
|
|
460
|
+
changes: { from: e, to: i, insert: " " },
|
|
461
|
+
effects: C.of(t),
|
|
462
|
+
selection: { anchor: e + 1 }
|
|
463
|
+
}), this.view.focus(), t;
|
|
355
464
|
}
|
|
356
|
-
|
|
357
|
-
this.
|
|
465
|
+
addPluginBlock(t, e) {
|
|
466
|
+
return this.view.dispatch({
|
|
467
|
+
changes: { from: t, to: t + 1, insert: " " },
|
|
468
|
+
effects: M.of({ pos: t, block: e }),
|
|
469
|
+
selection: { anchor: t + 1 }
|
|
470
|
+
}), this.view.focus(), e;
|
|
471
|
+
}
|
|
472
|
+
syncBlock(t) {
|
|
473
|
+
this.allBlocks.set(t.id, { ...t }), this.view.dispatch({
|
|
474
|
+
effects: A.of(t)
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
getBlock(t) {
|
|
478
|
+
return this.allBlocks.get(t);
|
|
479
|
+
}
|
|
480
|
+
coordsAtPos(t) {
|
|
481
|
+
return this.view.coordsAtPos(t);
|
|
482
|
+
}
|
|
483
|
+
getData() {
|
|
484
|
+
return it(this.view);
|
|
485
|
+
}
|
|
486
|
+
destroy() {
|
|
487
|
+
this.view.destroy();
|
|
358
488
|
}
|
|
359
|
-
|
|
360
|
-
|
|
489
|
+
}
|
|
490
|
+
const Z = (o, t) => {
|
|
491
|
+
const { from: e, empty: i } = o.state.selection.main;
|
|
492
|
+
if (!i) return !1;
|
|
493
|
+
const l = e;
|
|
494
|
+
if (l === 0) return !1;
|
|
495
|
+
let s = null, n = null, c = 1;
|
|
496
|
+
const a = (h) => {
|
|
497
|
+
h && h.between(l - 1, l, (m, p, b) => {
|
|
498
|
+
const f = b.spec.widget;
|
|
499
|
+
if (f && f.block && f.block.id && m < l && p >= l)
|
|
500
|
+
return s = f.block.id, n = m, c = p - m, !1;
|
|
501
|
+
});
|
|
502
|
+
};
|
|
503
|
+
return a(o.state.field(v, !1)), s || a(o.state.field(S, !1)), s && n !== null ? (t.deleteBlock(s), o.dispatch({
|
|
504
|
+
changes: { from: n, to: n + c },
|
|
505
|
+
selection: { anchor: n }
|
|
506
|
+
}), !0) : !1;
|
|
507
|
+
}, tt = u.theme({
|
|
508
|
+
"&": { height: "100%", outline: "none", position: "relative" },
|
|
509
|
+
".cm-content": { padding: "20px", fontSize: "16px" },
|
|
510
|
+
".cm-line": { padding: "4px 0" },
|
|
511
|
+
".cm-header-1": { fontSize: "1.5em", color: "#008c99", fontWeight: "bold" },
|
|
512
|
+
".cm-bold": { fontWeight: "bold" }
|
|
513
|
+
}), T = d.mark({ class: "cm-bold" });
|
|
514
|
+
function P(o) {
|
|
515
|
+
const t = [];
|
|
516
|
+
for (let e = 1; e <= o.lines; e++) {
|
|
517
|
+
const i = o.line(e), l = i.text;
|
|
518
|
+
/^#+\s+/.test(l) && t.push(T.range(i.from, i.to));
|
|
519
|
+
const s = /\*\*(.*?)\*\*/g;
|
|
520
|
+
let n;
|
|
521
|
+
for (; (n = s.exec(l)) !== null; )
|
|
522
|
+
t.push(T.range(i.from + n.index, i.from + n.index + n[0].length));
|
|
361
523
|
}
|
|
524
|
+
return d.set(t.sort((e, i) => e.from - i.from), !0);
|
|
525
|
+
}
|
|
526
|
+
const et = y.define({
|
|
527
|
+
create(o) {
|
|
528
|
+
return P(o.doc);
|
|
529
|
+
},
|
|
530
|
+
update(o, t) {
|
|
531
|
+
return t.docChanged ? P(t.state.doc) : o.map(t.changes);
|
|
532
|
+
},
|
|
533
|
+
provide: (o) => u.decorations.from(o)
|
|
534
|
+
});
|
|
535
|
+
function ot(o, t, e = []) {
|
|
536
|
+
const i = e.filter((c) => !("type" in c.block && "name" in c.block)), l = e.filter((c) => "type" in c.block && "name" in c.block), s = [
|
|
537
|
+
W(),
|
|
538
|
+
_.of([
|
|
539
|
+
{
|
|
540
|
+
key: "Backspace",
|
|
541
|
+
run: (c) => Z(c, t)
|
|
542
|
+
},
|
|
543
|
+
...N,
|
|
544
|
+
...z
|
|
545
|
+
]),
|
|
546
|
+
G(),
|
|
547
|
+
...O({ callbacks: t, initialBlocks: i }),
|
|
548
|
+
...Q({ initialBlocks: l }),
|
|
549
|
+
et,
|
|
550
|
+
tt
|
|
551
|
+
];
|
|
552
|
+
return R.create({
|
|
553
|
+
doc: o,
|
|
554
|
+
extensions: s
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
function it(o) {
|
|
558
|
+
var l;
|
|
559
|
+
const t = o.state.doc.toString(), e = j(o), i = X(o);
|
|
560
|
+
return {
|
|
561
|
+
content: t,
|
|
562
|
+
editorBlocks: e,
|
|
563
|
+
pluginBlocks: i,
|
|
564
|
+
html: ((l = o.dom.querySelector(".cm-content")) == null ? void 0 : l.innerHTML) || ""
|
|
565
|
+
};
|
|
362
566
|
}
|
|
363
567
|
export {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
H as
|
|
375
|
-
|
|
568
|
+
at as AIDialogPlugin,
|
|
569
|
+
ht as CustomEditor,
|
|
570
|
+
rt as EditBlockPlugin,
|
|
571
|
+
dt as LibraryBlockPlugin,
|
|
572
|
+
C as addBlockEffect,
|
|
573
|
+
M as addPluginBlockEffect,
|
|
574
|
+
V as aiDialogExtensions,
|
|
575
|
+
ot as createEditorState,
|
|
576
|
+
O as editBlockExtensions,
|
|
577
|
+
v as editBlockField,
|
|
578
|
+
H as editBlockTheme,
|
|
579
|
+
tt as editorTheme,
|
|
580
|
+
j as getEditorBlocks,
|
|
581
|
+
it as getEditorData,
|
|
582
|
+
X as getPluginBlocks,
|
|
583
|
+
et as markdownStyleField,
|
|
584
|
+
Y as parseTemplateVariables,
|
|
585
|
+
Q as pluginBlockExtensions,
|
|
586
|
+
S as pluginBlockField,
|
|
587
|
+
J as pluginPopupTriggerExtensions,
|
|
588
|
+
A as updateBlockEffect
|
|
376
589
|
};
|
package/dist/editor.umd.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(c,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("@codemirror/state"),require("@codemirror/view"),require("@codemirror/commands")):typeof define=="function"&&define.amd?define(["exports","@codemirror/state","@codemirror/view","@codemirror/commands"],d):(c=typeof globalThis<"u"?globalThis:c||self,d(c.AgentArtsEditor={},c.CMState,c.CMView,c.CMCommands))})(this,function(c,d,r,w){"use strict";var X=Object.defineProperty;var Y=(c,d,r)=>d in c?X(c,d,{enumerable:!0,configurable:!0,writable:!0,value:r}):c[d]=r;var h=(c,d,r)=>Y(c,typeof d!="symbol"?d+"":d,r);const y=d.StateEffect.define(),E=d.StateEffect.define();class g extends r.WidgetType{constructor(e,i){super(),this.block=e,this.callbacks=i}toDOM(e){const i=document.createElement("span");i.className="cm-inline-block",i.setAttribute("data-block-id",this.block.id);const t=document.createElement("input");t.type="text",t.className="block-input",t.value=this.block.presetText||"",t.placeholder=this.block.placeholder||"请输入...";const l=s=>{const n=document.createElement("span");n.style.visibility="hidden",n.style.position="absolute",n.style.whiteSpace="pre",n.style.font="inherit",n.textContent=s||t.placeholder,document.body.appendChild(n);const a=n.offsetWidth;return document.body.removeChild(n),a+10};return t.style.width=`${l(t.value)}px`,t.oninput=s=>{const n=s.target.value;t.style.width=`${l(n)}px`,this.callbacks.updateBlockText(this.block.id,n)},t.onfocus=()=>{const s=i.getBoundingClientRect();this.callbacks.openPopup(this.block.id,s)},t.onmousedown=s=>{s.stopPropagation()},t.onclick=s=>{s.stopPropagation();const n=i.getBoundingClientRect();this.callbacks.openPopup(this.block.id,n)},t.onkeydown=s=>{if(s.key==="Backspace"&&t.value===""){s.preventDefault();const n=e.posAtDOM(i);this.callbacks.deleteBlock(this.block.id),e.dispatch({changes:{from:n,to:n+1},selection:{anchor:n}})}},i.appendChild(t),i}ignoreEvent(){return!0}}const x=d.Facet.define({combine:o=>o[0]}),D=d.Facet.define({combine:o=>o.length?o[0]:[]}),b=d.StateField.define({create(o){const e=o.facet(x),i=o.facet(D);if(!i||i.length===0)return r.Decoration.none;const t=i.slice().sort((l,s)=>l.pos-s.pos).map(({pos:l,len:s,block:n})=>{const a=new g(n,e);return r.Decoration.replace({widget:a}).range(l,l+(s||1))});return r.Decoration.set(t,!0)},update(o,e){const i=e.state.facet(x);o=o.map(e.changes);for(const t of e.effects)if(t.is(y)){const l=e.state.selection.main.head-1,s=r.Decoration.replace({widget:new g(t.value,i)}).range(l,l+1);o=o.update({add:[s]})}else if(t.is(E)){const l=t.value;let s=null;o.between(0,e.state.doc.length,(n,a,u)=>{const f=u.spec.widget;f instanceof g&&f.block.id===l.id&&(s=n)}),s!==null&&(o=o.update({filter:(n,a,u)=>{const f=u.spec.widget;return!(f instanceof g&&f.block.id===l.id)},add:[r.Decoration.replace({widget:new g(l,i)}).range(s,s+1)]}))}return o},provide:o=>r.EditorView.decorations.from(o)}),C=r.EditorView.theme({".cm-inline-block":{display:"inline-block",backgroundColor:"#f3f0ff",color:"#8066ff",padding:"0 8px",margin:"0 4px",borderRadius:"4px",cursor:"pointer",border:"1px solid transparent",transition:"all 0.2s",fontSize:"15px",verticalAlign:"middle"},".cm-inline-block:hover":{backgroundColor:"#e9e4ff",borderColor:"#8066ff"},".block-input":{background:"transparent",border:"none",outline:"none",color:"inherit",font:"inherit",padding:"4px 0",width:"auto",minWidth:"20px",textAlign:"center"},".block-input::placeholder":{color:"#b2a1ff",opacity:.7}});function A(o){return[x.of(o.callbacks),D.of(o.initialBlocks||[]),b,C]}function F(o){const e=[],i=o.state.field(b,!1);return i&&i.between(0,o.state.doc.length,(t,l,s)=>{const n=s.spec.widget;n instanceof g&&e.push({pos:t,len:l-t,block:n.block})}),e}class j{constructor(e){h(this,"editingBlock",{id:"",placeholder:"",presetText:""});this.callbacks=e}show(e,i,t){this.editingBlock={...e};const l={top:`${i.bottom-t.top+10}px`,left:`${i.left-t.left}px`};this.callbacks.onShow(this.editingBlock,l)}hide(){this.callbacks.onHide()}updateEditingBlock(e){this.editingBlock={...this.editingBlock,...e}}}class q{constructor(e){h(this,"isGenerating",!1);h(this,"aiStreamTimer",null);h(this,"currentResponse","");this.callbacks=e}show(e,i,t){const l={top:`${i.bottom-t.top+10}px`,left:`${i.left-t.left}px`};this.callbacks.onShow(e,l)}hide(){this.stopResponse(),this.callbacks.onHide()}sendQuestion(e){if(!e||this.isGenerating)return;this.isGenerating=!0,this.callbacks.onLoading(!0),this.currentResponse="",this.callbacks.onStream("");const i=`你是一个资深旅游向导,积累了丰富的在地经验,擅长结合用户需求定制专属旅行方案,曾帮助1000+人解决旅行难题,被旅行者亲切称为"旅行百事通"。
|
|
2
2
|
|
|
3
3
|
## 核心性格与风格
|
|
4
4
|
- **性格特点**:热情开朗、专业耐心,擅长用轻松幽默的方式化解旅行焦虑(如:"别慌!机票改签我有3个小窍门,保准帮你搞定~"),遇到用户疑问会像朋友般细致拆解细节(如:"你担心的高原反应,我去年在西藏徒步时总结过4个缓解方法...")。
|
|
5
|
-
- **语言风格**:口语化且富有感染力,常用"宝藏地""小众玩法"等旅行圈`;let t=0;this.aiStreamTimer=setInterval(()=>{this.callbacks.onLoading(!1),t<
|
|
5
|
+
- **语言风格**:口语化且富有感染力,常用"宝藏地""小众玩法"等旅行圈`;let t=0;this.aiStreamTimer=setInterval(()=>{this.callbacks.onLoading(!1),t<i.length?(this.currentResponse+=i[t],this.callbacks.onStream(this.currentResponse),t++):this.finishGeneration()},30)}stopResponse(){this.aiStreamTimer&&(clearInterval(this.aiStreamTimer),this.aiStreamTimer=null),this.isGenerating=!1,this.callbacks.onLoading(!1),this.callbacks.onStop()}finishGeneration(){this.aiStreamTimer&&(clearInterval(this.aiStreamTimer),this.aiStreamTimer=null),this.isGenerating=!1,this.callbacks.onLoading(!1),this.callbacks.onComplete()}getIsGenerating(){return this.isGenerating}destroy(){this.stopResponse()}}function M(o){return[H(o.onTriggerAIDialog),K(o.onTriggerAIDialog),O]}function H(o){return r.EditorView.updateListener.of(e=>{e.docChanged&&e.changes.iterChanges((i,t,l,s,n)=>{if(n.length!==1)return;n.sliceString(0)==="/"&&o(i)})})}const O=r.EditorView.theme({".cm-ai-selection-trigger":{position:"absolute",zIndex:"10",display:"none",width:"32px",height:"32px",alignItems:"center",justifyContent:"center",borderRadius:"8px",backgroundColor:"#fff",boxShadow:"0 6px 24px rgba(0, 0, 0, 0.12)",border:"1px solid rgba(0, 0, 0, 0.06)"},".cm-ai-selection-trigger button":{width:"100%",height:"100%",border:"none",background:"transparent",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",padding:"0"},".cm-ai-selection-trigger button:hover":{backgroundColor:"#f3f4f6",borderRadius:"8px"}});function K(o){return r.ViewPlugin.fromClass(class{constructor(e){h(this,"dom");h(this,"button");h(this,"lastFrom",-1);h(this,"lastTo",-1);h(this,"measureScheduled",!1);this.view=e,this.dom=document.createElement("div"),this.dom.className="cm-ai-selection-trigger",this.button=document.createElement("button"),this.button.type="button";const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","16"),i.setAttribute("height","16"),i.setAttribute("viewBox","0 0 24 24"),i.setAttribute("fill","none"),i.setAttribute("stroke","#111827"),i.setAttribute("stroke-width","2"),i.setAttribute("stroke-linecap","round"),i.setAttribute("stroke-linejoin","round"),i.innerHTML='<path d="M5 12l1.5.5L7 14l.5-1.5L9 12l-1.5-.5L7 10l-.5 1.5L5 12z"/><path d="M12 4l2 6 6 2-6 2-2 6-2-6-6-2 6-2 2-6z"/>',this.button.appendChild(i),this.dom.appendChild(this.button),this.view.dom.appendChild(this.dom),this.dom.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),this.button.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const{from:l,empty:s}=this.view.state.selection.main;s||(o(l),this.hide())}),this.scheduleMeasure(!0)}update(e){(e.selectionSet||e.viewportChanged||e.focusChanged||e.docChanged)&&this.scheduleMeasure(!1)}destroy(){this.dom.remove()}hide(){this.dom.style.display="none"}show(){this.dom.style.display="flex"}scheduleMeasure(e){const{from:i,to:t,empty:l}=this.view.state.selection.main;if(l||!this.view.hasFocus){this.hide();return}!e&&i===this.lastFrom&&t===this.lastTo&&this.dom.style.display!=="none"||(this.lastFrom=i,this.lastTo=t,!this.measureScheduled&&(this.measureScheduled=!0,this.view.requestMeasure({read:s=>{const n=s.coordsAtPos(i);if(!n)return null;const a=s.dom.getBoundingClientRect();return{coords:n,editorRect:a}},write:s=>{this.measureScheduled=!1;const{empty:n}=this.view.state.selection.main;if(n||!this.view.hasFocus){this.hide();return}if(!s){this.hide();return}const{coords:a,editorRect:u}=s,f=32,k=32,p=6,P=Math.min(Math.max(a.left-u.left,p),Math.max(p,u.width-f-p)),m=Math.max(a.top-u.top-k-10,p);this.dom.style.left=`${P}px`,this.dom.style.top=`${m}px`,this.show()}})))}})}const S=d.StateEffect.define();class T extends r.WidgetType{constructor(e){super(),this.block=e}toDOM(){const e=document.createElement("span");e.className=`cm-plugin-block cm-plugin-block-${this.block.type}`,e.setAttribute("data-block-id",this.block.id);const i=document.createElement("i");i.className=this.block.type==="plugin"?"icon-plugin":"icon-workflow",e.appendChild(i);const t=document.createTextNode(this.block.name);return e.appendChild(t),e}ignoreEvent(){return!0}}const v=d.Facet.define({combine:o=>o.length?o[0]:[]}),B=d.StateField.define({create(o){const e=o.facet(v);if(!e||e.length===0)return r.Decoration.none;const i=e.slice().sort((t,l)=>t.pos-l.pos).map(({pos:t,len:l,block:s})=>r.Decoration.replace({widget:new T(s)}).range(t,t+(l||1)));return r.Decoration.set(i,!0)},update(o,e){o=o.map(e.changes);for(const i of e.effects)if(i.is(S)){const{pos:t,block:l}=i.value,s=e.changes.mapPos(t),n=r.Decoration.replace({widget:new T(l)}).range(s,s+1);o=o.update({add:[n]})}return o},provide:o=>r.EditorView.decorations.from(o)});function L(o){return[v.of(o.initialBlocks||[]),B]}function I(o){return[r.EditorView.updateListener.of(e=>{e.docChanged&&e.changes.iterChanges((i,t,l,s,n)=>{if(n.length!==1)return;n.sliceString(0)==="{"&&o.onTriggerPluginPopup(i)})})]}function $(o){const e=[],i=o.state.field(B,!1);return i&&i.between(0,o.state.doc.length,(t,l,s)=>{const n=s.spec.widget;n instanceof T&&e.push({pos:t,len:l-t,block:n.block})}),e}function R(o){const e=[],i=/\{\{(.+?)\}\}/g;let t;for(;(t=i.exec(o))!==null;)e.push({pos:t.index,len:t[0].length,block:{id:`var-${t[1]}-${t.index}`,name:t[1],type:"plugin"}});return e}class U{constructor(e){h(this,"plugins",[{id:"plugin-1",name:"LinkReaderPlugin",type:"plugin"}]);h(this,"workflows",[{id:"workflow-1",name:"condition_1_872",type:"workflow"}]);h(this,"triggerPos",0);this.callbacks=e}show(e,i,t){this.triggerPos=e;const l={top:`${i.bottom-t.top+10}px`,left:`${i.left-t.left}px`};this.callbacks.onShow(e,l)}hide(){this.callbacks.onHide()}getTriggerPos(){return this.triggerPos}}class Q{constructor(e){h(this,"view");h(this,"allBlocks",new Map);h(this,"options");this.options=e;const i=R(e.initialDoc),t=[...e.initialBlocks||[],...i];e.initialBlocks&&e.initialBlocks.forEach(n=>{"type"in n.block||this.allBlocks.set(n.block.id,n.block)});const l={updateBlockText:(n,a)=>{const u=this.allBlocks.get(n);u&&(u.presetText=a,this.allBlocks.set(n,u),this.options.onBlockUpdated&&this.options.onBlockUpdated(n,a))},openPopup:(n,a)=>{this.options.onOpenPopup(n,a)},deleteBlock:n=>{this.allBlocks.delete(n),this.options.onBlockDeleted&&this.options.onBlockDeleted(n)}},s=N(e.initialDoc,l,t);this.view=new r.EditorView({state:s.update({effects:d.StateEffect.appendConfig.of([...I({onTriggerPluginPopup:n=>this.options.onTriggerPluginPopup(n)}),...M({onTriggerAIDialog:n=>this.options.onTriggerAIDialog(n)})])}).state,parent:e.parent})}addBlock(){const e={id:Math.random().toString(36).slice(2,11),placeholder:"请输入编辑块内容为空时的提示文案",presetText:""};this.allBlocks.set(e.id,e);const{from:i,to:t}=this.view.state.selection.main;return this.view.dispatch({changes:{from:i,to:t,insert:" "},effects:y.of(e),selection:{anchor:i+1}}),this.view.focus(),e}addPluginBlock(e,i){return this.view.dispatch({changes:{from:e,to:e+1,insert:" "},effects:S.of({pos:e,block:i}),selection:{anchor:e+1}}),this.view.focus(),i}syncBlock(e){this.allBlocks.set(e.id,{...e}),this.view.dispatch({effects:E.of(e)})}getBlock(e){return this.allBlocks.get(e)}coordsAtPos(e){return this.view.coordsAtPos(e)}getData(){return z(this.view)}destroy(){this.view.destroy()}}const J=(o,e)=>{const{from:i,empty:t}=o.state.selection.main;if(!t)return!1;const l=i;if(l===0)return!1;let s=null,n=null,a=1;const u=f=>{f&&f.between(l-1,l,(k,p,P)=>{const m=P.spec.widget;if(m&&m.block&&m.block.id&&k<l&&p>=l)return s=m.block.id,n=k,a=p-k,!1})};return u(o.state.field(b,!1)),s||u(o.state.field(B,!1)),s&&n!==null?(e.deleteBlock(s),o.dispatch({changes:{from:n,to:n+a},selection:{anchor:n}}),!0):!1},V=r.EditorView.theme({"&":{height:"100%",outline:"none",position:"relative"},".cm-content":{padding:"20px",fontSize:"16px"},".cm-line":{padding:"4px 0"},".cm-header-1":{fontSize:"1.5em",color:"#008c99",fontWeight:"bold"},".cm-bold":{fontWeight:"bold"}}),_=r.Decoration.mark({class:"cm-bold"});function G(o){const e=[];for(let i=1;i<=o.lines;i++){const t=o.line(i),l=t.text;/^#+\s+/.test(l)&&e.push(_.range(t.from,t.to));const s=/\*\*(.*?)\*\*/g;let n;for(;(n=s.exec(l))!==null;)e.push(_.range(t.from+n.index,t.from+n.index+n[0].length))}return r.Decoration.set(e.sort((i,t)=>i.from-t.from),!0)}const W=d.StateField.define({create(o){return G(o.doc)},update(o,e){return e.docChanged?G(e.state.doc):o.map(e.changes)},provide:o=>r.EditorView.decorations.from(o)});function N(o,e,i=[]){const t=i.filter(a=>!("type"in a.block&&"name"in a.block)),l=i.filter(a=>"type"in a.block&&"name"in a.block),s=[w.history(),r.keymap.of([{key:"Backspace",run:a=>J(a,e)},...w.defaultKeymap,...w.historyKeymap]),r.drawSelection(),...A({callbacks:e,initialBlocks:t}),...L({initialBlocks:l}),W,V];return d.EditorState.create({doc:o,extensions:s})}function z(o){var l;const e=o.state.doc.toString(),i=F(o),t=$(o);return{content:e,editorBlocks:i,pluginBlocks:t,html:((l=o.dom.querySelector(".cm-content"))==null?void 0:l.innerHTML)||""}}c.AIDialogPlugin=q,c.CustomEditor=Q,c.EditBlockPlugin=j,c.LibraryBlockPlugin=U,c.addBlockEffect=y,c.addPluginBlockEffect=S,c.aiDialogExtensions=M,c.createEditorState=N,c.editBlockExtensions=A,c.editBlockField=b,c.editBlockTheme=C,c.editorTheme=V,c.getEditorBlocks=F,c.getEditorData=z,c.getPluginBlocks=$,c.markdownStyleField=W,c.parseTemplateVariables=R,c.pluginBlockExtensions=L,c.pluginBlockField=B,c.pluginPopupTriggerExtensions=I,c.updateBlockEffect=E,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ pos: number;
|
|
|
13
13
|
block: PluginBlock;
|
|
14
14
|
}>;
|
|
15
15
|
|
|
16
|
+
export declare function aiDialogExtensions(options: {
|
|
17
|
+
onTriggerAIDialog: (pos: number) => void;
|
|
18
|
+
}): Extension[];
|
|
19
|
+
|
|
16
20
|
export declare class AIDialogPlugin {
|
|
17
21
|
private callbacks;
|
|
18
22
|
private isGenerating;
|
|
@@ -43,21 +47,21 @@ export declare interface AIResponseCallbacks {
|
|
|
43
47
|
onHide: () => void;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
export declare const blockField: StateField<DecorationSet>;
|
|
47
|
-
|
|
48
50
|
export declare interface CodeMirrorCallbacks {
|
|
49
51
|
updateBlockText: (id: string, text: string) => void;
|
|
50
52
|
openPopup: (id: string, rect: DOMRect) => void;
|
|
51
53
|
deleteBlock: (id: string) => void;
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
/**
|
|
57
|
+
* 创建编辑器状态
|
|
58
|
+
*/
|
|
54
59
|
export declare function createEditorState(initialDoc: string, callbacks: CodeMirrorCallbacks, initialBlocks?: {
|
|
55
60
|
pos: number;
|
|
56
|
-
|
|
61
|
+
len?: number;
|
|
62
|
+
block: EditorBlock | PluginBlock;
|
|
57
63
|
}[]): EditorState;
|
|
58
64
|
|
|
59
|
-
export declare function createEditorView(parent: HTMLElement, state: EditorState): EditorView;
|
|
60
|
-
|
|
61
65
|
export declare class CustomEditor {
|
|
62
66
|
view: EditorView;
|
|
63
67
|
allBlocks: Map<string, EditorBlock>;
|
|
@@ -69,10 +73,17 @@ export declare class CustomEditor {
|
|
|
69
73
|
getBlock(id: string): EditorBlock | undefined;
|
|
70
74
|
coordsAtPos(pos: number): Rect | null;
|
|
71
75
|
getData(): {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
content: string;
|
|
77
|
+
editorBlocks: {
|
|
78
|
+
pos: number;
|
|
79
|
+
len?: number;
|
|
80
|
+
block: EditorBlock;
|
|
81
|
+
}[];
|
|
82
|
+
pluginBlocks: {
|
|
83
|
+
pos: number;
|
|
84
|
+
len?: number;
|
|
85
|
+
block: PluginBlock;
|
|
86
|
+
}[];
|
|
76
87
|
html: string;
|
|
77
88
|
};
|
|
78
89
|
destroy(): void;
|
|
@@ -83,7 +94,8 @@ export declare interface CustomEditorOptions {
|
|
|
83
94
|
initialDoc: string;
|
|
84
95
|
initialBlocks?: {
|
|
85
96
|
pos: number;
|
|
86
|
-
|
|
97
|
+
len?: number;
|
|
98
|
+
block: EditorBlock | PluginBlock;
|
|
87
99
|
}[];
|
|
88
100
|
onOpenPopup: (id: string, rect: DOMRect) => void;
|
|
89
101
|
onTriggerPluginPopup: (pos: number) => void;
|
|
@@ -100,6 +112,17 @@ export declare interface EditBlockCallbacks {
|
|
|
100
112
|
onHide: () => void;
|
|
101
113
|
}
|
|
102
114
|
|
|
115
|
+
export declare function editBlockExtensions(options: {
|
|
116
|
+
callbacks: CodeMirrorCallbacks;
|
|
117
|
+
initialBlocks?: {
|
|
118
|
+
pos: number;
|
|
119
|
+
len?: number;
|
|
120
|
+
block: EditorBlock;
|
|
121
|
+
}[];
|
|
122
|
+
}): Extension[];
|
|
123
|
+
|
|
124
|
+
export declare const editBlockField: StateField<DecorationSet>;
|
|
125
|
+
|
|
103
126
|
export declare class EditBlockPlugin {
|
|
104
127
|
private callbacks;
|
|
105
128
|
editingBlock: EditorBlock;
|
|
@@ -109,6 +132,8 @@ export declare class EditBlockPlugin {
|
|
|
109
132
|
updateEditingBlock(block: Partial<EditorBlock>): void;
|
|
110
133
|
}
|
|
111
134
|
|
|
135
|
+
export declare const editBlockTheme: Extension;
|
|
136
|
+
|
|
112
137
|
export declare interface EditorBlock {
|
|
113
138
|
id: string;
|
|
114
139
|
placeholder: string;
|
|
@@ -117,14 +142,36 @@ export declare interface EditorBlock {
|
|
|
117
142
|
|
|
118
143
|
export declare const editorTheme: Extension;
|
|
119
144
|
|
|
120
|
-
export declare function
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
145
|
+
export declare function getEditorBlocks(view: EditorView): {
|
|
146
|
+
pos: number;
|
|
147
|
+
len?: number;
|
|
148
|
+
block: EditorBlock;
|
|
149
|
+
}[];
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 获取编辑器数据
|
|
153
|
+
*/
|
|
154
|
+
export declare function getEditorData(view: EditorView): {
|
|
155
|
+
content: string;
|
|
156
|
+
editorBlocks: {
|
|
157
|
+
pos: number;
|
|
158
|
+
len?: number;
|
|
159
|
+
block: EditorBlock;
|
|
160
|
+
}[];
|
|
161
|
+
pluginBlocks: {
|
|
162
|
+
pos: number;
|
|
163
|
+
len?: number;
|
|
164
|
+
block: PluginBlock;
|
|
165
|
+
}[];
|
|
125
166
|
html: string;
|
|
126
167
|
};
|
|
127
168
|
|
|
169
|
+
export declare function getPluginBlocks(view: EditorView): {
|
|
170
|
+
pos: number;
|
|
171
|
+
len?: number;
|
|
172
|
+
block: PluginBlock;
|
|
173
|
+
}[];
|
|
174
|
+
|
|
128
175
|
export declare interface LibraryBlockCallbacks {
|
|
129
176
|
onShow: (pos: number, style: {
|
|
130
177
|
top: string;
|
|
@@ -155,12 +202,34 @@ export declare class LibraryBlockPlugin {
|
|
|
155
202
|
getTriggerPos(): number;
|
|
156
203
|
}
|
|
157
204
|
|
|
205
|
+
export declare const markdownStyleField: StateField<DecorationSet>;
|
|
206
|
+
|
|
207
|
+
export declare function parseTemplateVariables(doc: string): {
|
|
208
|
+
pos: number;
|
|
209
|
+
len: number;
|
|
210
|
+
block: PluginBlock;
|
|
211
|
+
}[];
|
|
212
|
+
|
|
158
213
|
export declare interface PluginBlock {
|
|
159
214
|
id: string;
|
|
160
215
|
name: string;
|
|
161
216
|
type: 'plugin' | 'workflow';
|
|
162
217
|
}
|
|
163
218
|
|
|
219
|
+
export declare function pluginBlockExtensions(options: {
|
|
220
|
+
initialBlocks?: {
|
|
221
|
+
pos: number;
|
|
222
|
+
len?: number;
|
|
223
|
+
block: PluginBlock;
|
|
224
|
+
}[];
|
|
225
|
+
}): Extension[];
|
|
226
|
+
|
|
227
|
+
export declare const pluginBlockField: StateField<DecorationSet>;
|
|
228
|
+
|
|
229
|
+
export declare function pluginPopupTriggerExtensions(options: {
|
|
230
|
+
onTriggerPluginPopup: (pos: number) => void;
|
|
231
|
+
}): Extension[];
|
|
232
|
+
|
|
164
233
|
export declare const updateBlockEffect: StateEffectType<EditorBlock>;
|
|
165
234
|
|
|
166
235
|
export { }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-arts/editor",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "A prompt editor based on CodeMirror 6, support Vue.js 3 and Angular.",
|
|
5
5
|
"author": "AgentArts Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"ai-agent"
|
|
23
23
|
],
|
|
24
24
|
"type": "module",
|
|
25
|
+
"sideEffects": false,
|
|
25
26
|
"main": "./dist/editor.umd.cjs",
|
|
26
27
|
"module": "./dist/editor.js",
|
|
27
28
|
"types": "./dist/index.d.ts",
|
|
@@ -43,12 +44,11 @@
|
|
|
43
44
|
"scripts": {
|
|
44
45
|
"dev": "vite",
|
|
45
46
|
"build": "vite build",
|
|
47
|
+
"build:watch": "vite build --watch",
|
|
46
48
|
"preview": "vite preview"
|
|
47
49
|
},
|
|
48
50
|
"dependencies": {
|
|
49
51
|
"@codemirror/commands": "^6.3.3",
|
|
50
|
-
"@codemirror/lang-markdown": "^6.2.3",
|
|
51
|
-
"@codemirror/language-data": "^6.3.1",
|
|
52
52
|
"@codemirror/state": "^6.4.0",
|
|
53
53
|
"@codemirror/view": "^6.23.0"
|
|
54
54
|
},
|