@coze-editor/react-components 0.1.0-alpha.0fd19e
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/LICENSE +21 -0
- package/dist/esm/index.js +1475 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +149 -0
- package/dist/index.d.ts +149 -0
- package/dist/index.js +1474 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1474 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var index_exports = {};
|
|
31
|
+
__export(index_exports, {
|
|
32
|
+
ActiveLinePlaceholder: () => ActiveLinePlaceholder,
|
|
33
|
+
CursorInlayHint: () => CursorInlayHint,
|
|
34
|
+
CursorMirror: () => CursorMirror,
|
|
35
|
+
DiagnosticMarkers: () => DiagnosticMarkers,
|
|
36
|
+
DiffView: () => DiffView,
|
|
37
|
+
EmbededLineView: () => EmbededLineView,
|
|
38
|
+
EmbededLineViewSide: () => EmbededLineViewSide,
|
|
39
|
+
FoldGutter: () => FoldGutter,
|
|
40
|
+
Gutter: () => Gutter,
|
|
41
|
+
GutterLineMarker: () => GutterLineMarker,
|
|
42
|
+
GutterPlacement: () => GutterPlacement,
|
|
43
|
+
LineWidget: () => LineWidget,
|
|
44
|
+
Markers: () => Markers,
|
|
45
|
+
Mention: () => Mention,
|
|
46
|
+
Placeholder: () => Placeholder,
|
|
47
|
+
PositionMirror: () => PositionMirror,
|
|
48
|
+
RefElement: () => RefElement,
|
|
49
|
+
SelectionSide: () => import_extensions.SelectionSide,
|
|
50
|
+
getCurrentMentionReplaceRange: () => getCurrentMentionReplaceRange
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(index_exports);
|
|
53
|
+
|
|
54
|
+
// src/cursor-mirror/index.tsx
|
|
55
|
+
var import_react = require("react");
|
|
56
|
+
var import_dom = require("@floating-ui/dom");
|
|
57
|
+
var import_react2 = require("@coze-editor/react");
|
|
58
|
+
var import_extensions = require("@coze-editor/extensions");
|
|
59
|
+
var CursorMirror = (0, import_react.forwardRef)(function CursorMirror2({ side, onChange, onVisibleChange }, ref) {
|
|
60
|
+
const injector = (0, import_react2.useInjector)();
|
|
61
|
+
const editor = (0, import_react2.useEditor)();
|
|
62
|
+
const [dom] = (0, import_react.useState)(() => document.createElement("div"));
|
|
63
|
+
const domRef = (0, import_react.useRef)(dom);
|
|
64
|
+
domRef.current = dom;
|
|
65
|
+
const onChangeRef = (0, import_react.useRef)(onChange);
|
|
66
|
+
onChangeRef.current = onChange;
|
|
67
|
+
const onVisibleChangeRef = (0, import_react.useRef)(onVisibleChange);
|
|
68
|
+
onVisibleChangeRef.current = onVisibleChange;
|
|
69
|
+
(0, import_react.useImperativeHandle)(ref, () => domRef.current);
|
|
70
|
+
(0, import_react.useLayoutEffect)(
|
|
71
|
+
() => injector.inject([
|
|
72
|
+
import_extensions.elementAtPosition.of({
|
|
73
|
+
dom: domRef.current,
|
|
74
|
+
pos: side
|
|
75
|
+
}),
|
|
76
|
+
import_extensions.positionElementLayer
|
|
77
|
+
]),
|
|
78
|
+
[injector, side]
|
|
79
|
+
);
|
|
80
|
+
(0, import_react.useEffect)(() => {
|
|
81
|
+
const floating = document.createElement("div");
|
|
82
|
+
document.body.appendChild(floating);
|
|
83
|
+
const dispose = (0, import_dom.autoUpdate)(
|
|
84
|
+
domRef.current,
|
|
85
|
+
floating,
|
|
86
|
+
() => {
|
|
87
|
+
if (typeof onChangeRef.current === "function") {
|
|
88
|
+
onChangeRef.current();
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{ animationFrame: true }
|
|
92
|
+
);
|
|
93
|
+
return () => {
|
|
94
|
+
document.body.removeChild(floating);
|
|
95
|
+
dispose();
|
|
96
|
+
};
|
|
97
|
+
}, []);
|
|
98
|
+
(0, import_react.useEffect)(() => {
|
|
99
|
+
if (!editor) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const view = editor.$view;
|
|
103
|
+
const observer = new IntersectionObserver(
|
|
104
|
+
(entries) => {
|
|
105
|
+
entries.forEach((entry) => {
|
|
106
|
+
if (typeof onVisibleChangeRef.current === "function") {
|
|
107
|
+
onVisibleChangeRef.current(entry.isIntersecting);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
root: view.scrollDOM,
|
|
113
|
+
threshold: 0
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
observer.observe(domRef.current);
|
|
117
|
+
return () => {
|
|
118
|
+
observer.disconnect();
|
|
119
|
+
};
|
|
120
|
+
}, [editor]);
|
|
121
|
+
return null;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// src/position-mirror/index.tsx
|
|
125
|
+
var import_react3 = require("react");
|
|
126
|
+
var import_dom2 = require("@floating-ui/dom");
|
|
127
|
+
var import_react4 = require("@coze-editor/react");
|
|
128
|
+
var import_extensions2 = require("@coze-editor/extensions");
|
|
129
|
+
var PositionMirror = (0, import_react3.forwardRef)(function CursorMirror3({ position, onChange, onVisibleChange }, ref) {
|
|
130
|
+
const injector = (0, import_react4.useInjector)();
|
|
131
|
+
const editor = (0, import_react4.useEditor)();
|
|
132
|
+
const [dom] = (0, import_react3.useState)(() => {
|
|
133
|
+
const el = document.createElement("div");
|
|
134
|
+
el.classList.add("cm-position-mirror");
|
|
135
|
+
return el;
|
|
136
|
+
});
|
|
137
|
+
const domRef = (0, import_react3.useRef)(dom);
|
|
138
|
+
domRef.current = dom;
|
|
139
|
+
const onChangeRef = (0, import_react3.useRef)(onChange);
|
|
140
|
+
onChangeRef.current = onChange;
|
|
141
|
+
const onVisibleChangeRef = (0, import_react3.useRef)(onVisibleChange);
|
|
142
|
+
onVisibleChangeRef.current = onVisibleChange;
|
|
143
|
+
(0, import_react3.useImperativeHandle)(ref, () => domRef.current);
|
|
144
|
+
(0, import_react3.useLayoutEffect)(
|
|
145
|
+
() => injector.inject([
|
|
146
|
+
import_extensions2.elementAtPosition.of({
|
|
147
|
+
dom: domRef.current,
|
|
148
|
+
pos: position
|
|
149
|
+
}),
|
|
150
|
+
import_extensions2.positionElementLayer
|
|
151
|
+
]),
|
|
152
|
+
[injector, position]
|
|
153
|
+
);
|
|
154
|
+
(0, import_react3.useEffect)(() => {
|
|
155
|
+
const floating = document.createElement("div");
|
|
156
|
+
document.body.appendChild(floating);
|
|
157
|
+
const dispose = (0, import_dom2.autoUpdate)(
|
|
158
|
+
domRef.current,
|
|
159
|
+
floating,
|
|
160
|
+
() => {
|
|
161
|
+
if (typeof onChangeRef.current === "function") {
|
|
162
|
+
onChangeRef.current();
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{ animationFrame: true }
|
|
166
|
+
);
|
|
167
|
+
return () => {
|
|
168
|
+
document.body.removeChild(floating);
|
|
169
|
+
dispose();
|
|
170
|
+
};
|
|
171
|
+
}, []);
|
|
172
|
+
(0, import_react3.useEffect)(() => {
|
|
173
|
+
if (!editor) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const view = editor.$view;
|
|
177
|
+
const observer = new IntersectionObserver(
|
|
178
|
+
(entries) => {
|
|
179
|
+
entries.forEach((entry) => {
|
|
180
|
+
if (typeof onVisibleChangeRef.current === "function") {
|
|
181
|
+
onVisibleChangeRef.current(entry.isIntersecting);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
root: view.scrollDOM,
|
|
187
|
+
threshold: 0
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
observer.observe(domRef.current);
|
|
191
|
+
return () => {
|
|
192
|
+
observer.disconnect();
|
|
193
|
+
};
|
|
194
|
+
}, [editor]);
|
|
195
|
+
return null;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// src/cursor-inlay-hint/index.tsx
|
|
199
|
+
var import_react_dom = require("react-dom");
|
|
200
|
+
var import_react5 = require("react");
|
|
201
|
+
var import_react_hooks = require("@coze-editor/react-hooks");
|
|
202
|
+
var import_react6 = require("@coze-editor/react");
|
|
203
|
+
var import_view = require("@codemirror/view");
|
|
204
|
+
var InlayHintWidget = class extends import_view.WidgetType {
|
|
205
|
+
constructor(element) {
|
|
206
|
+
super();
|
|
207
|
+
this.element = element;
|
|
208
|
+
}
|
|
209
|
+
eq(other) {
|
|
210
|
+
return this.element === other.element;
|
|
211
|
+
}
|
|
212
|
+
toDOM() {
|
|
213
|
+
return this.element;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
function CursorInlayHint({ children }) {
|
|
217
|
+
const injector = (0, import_react6.useInjector)();
|
|
218
|
+
const element = (0, import_react_hooks.useHTMLElement)("span");
|
|
219
|
+
(0, import_react5.useLayoutEffect)(
|
|
220
|
+
() => injector.inject([
|
|
221
|
+
import_view.EditorView.decorations.compute(
|
|
222
|
+
["selection"],
|
|
223
|
+
(state) => import_view.Decoration.set([
|
|
224
|
+
import_view.Decoration.widget({
|
|
225
|
+
widget: new InlayHintWidget(element),
|
|
226
|
+
side: 1
|
|
227
|
+
}).range(state.selection.main.head)
|
|
228
|
+
])
|
|
229
|
+
)
|
|
230
|
+
]),
|
|
231
|
+
[injector]
|
|
232
|
+
);
|
|
233
|
+
return (0, import_react_dom.createPortal)(children, element);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/markers/markers.tsx
|
|
237
|
+
var import_react7 = require("react");
|
|
238
|
+
var import_react_hooks2 = require("@coze-editor/react-hooks");
|
|
239
|
+
var import_react8 = require("@coze-editor/react");
|
|
240
|
+
var import_extensions3 = require("@coze-editor/extensions");
|
|
241
|
+
function Markers({ markers }) {
|
|
242
|
+
const injector = (0, import_react8.useInjector)();
|
|
243
|
+
const field = (0, import_react_hooks2.useStateField)((0, import_react7.useCallback)(() => markers, [markers]));
|
|
244
|
+
(0, import_react7.useLayoutEffect)(
|
|
245
|
+
() => injector.inject([field, import_extensions3.mergeableMarkers.from(field)]),
|
|
246
|
+
[injector, field]
|
|
247
|
+
);
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/markers/diagnostic-markers.tsx
|
|
252
|
+
var import_react9 = __toESM(require("react"));
|
|
253
|
+
var import_hash_sum = __toESM(require("hash-sum"));
|
|
254
|
+
var import_react10 = require("@coze-editor/react");
|
|
255
|
+
var import_view2 = require("@codemirror/view");
|
|
256
|
+
function DiagnosticMarkers({ markers }) {
|
|
257
|
+
const theme = (0, import_react9.useMemo)(() => {
|
|
258
|
+
const colors = getColors(markers);
|
|
259
|
+
return colors.reduce((memo, color) => {
|
|
260
|
+
const className = getClassNameFromColor(color);
|
|
261
|
+
memo[`& .${className}`] = {
|
|
262
|
+
backgroundPosition: "left bottom",
|
|
263
|
+
backgroundRepeat: "repeat-x",
|
|
264
|
+
paddingBottom: "0.7px",
|
|
265
|
+
backgroundImage: underline(color)
|
|
266
|
+
};
|
|
267
|
+
return memo;
|
|
268
|
+
}, {});
|
|
269
|
+
}, [markers]);
|
|
270
|
+
const injector = (0, import_react10.useInjector)();
|
|
271
|
+
(0, import_react9.useLayoutEffect)(
|
|
272
|
+
() => injector.inject([import_view2.EditorView.theme(theme)]),
|
|
273
|
+
[injector, theme]
|
|
274
|
+
);
|
|
275
|
+
const finalMarkers = (0, import_react9.useMemo)(
|
|
276
|
+
() => markers.map((marker) => {
|
|
277
|
+
const className = getClassNameFromColor(marker.color ?? "red");
|
|
278
|
+
return {
|
|
279
|
+
from: marker.from,
|
|
280
|
+
to: marker.to,
|
|
281
|
+
className
|
|
282
|
+
};
|
|
283
|
+
}),
|
|
284
|
+
[markers]
|
|
285
|
+
);
|
|
286
|
+
return /* @__PURE__ */ import_react9.default.createElement(Markers, { markers: finalMarkers });
|
|
287
|
+
}
|
|
288
|
+
var isString = (v) => Boolean(v);
|
|
289
|
+
function getColors(markers) {
|
|
290
|
+
return [
|
|
291
|
+
.../* @__PURE__ */ new Set([
|
|
292
|
+
...markers.map((marker) => marker.color).filter((v) => isString(v)),
|
|
293
|
+
"red"
|
|
294
|
+
])
|
|
295
|
+
];
|
|
296
|
+
}
|
|
297
|
+
function getClassNameFromColor(color) {
|
|
298
|
+
return `cm-sdk-diagnostic-marker-${(0, import_hash_sum.default)(color)}`;
|
|
299
|
+
}
|
|
300
|
+
function svg(content, attrs) {
|
|
301
|
+
return `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" ${attrs}>${encodeURIComponent(content)}</svg>')`;
|
|
302
|
+
}
|
|
303
|
+
function underline(color) {
|
|
304
|
+
return svg(
|
|
305
|
+
`<path d="m0 2.5 l2 -1.5 l1 0 l2 1.5 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>`,
|
|
306
|
+
'width="6" height="3"'
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/gutter/gutter.tsx
|
|
311
|
+
var import_react_dom2 = require("react-dom");
|
|
312
|
+
var import_react11 = __toESM(require("react"));
|
|
313
|
+
var import_utils = require("jotai/utils");
|
|
314
|
+
var import_jotai2 = require("jotai");
|
|
315
|
+
var import_react_hooks3 = require("@coze-editor/react-hooks");
|
|
316
|
+
var import_react12 = require("@coze-editor/react");
|
|
317
|
+
var import_view4 = require("@codemirror/view");
|
|
318
|
+
var import_state3 = require("@codemirror/state");
|
|
319
|
+
|
|
320
|
+
// src/gutter/right-gutter.ts
|
|
321
|
+
var import_state = require("@codemirror/state");
|
|
322
|
+
var import_view3 = require("@codemirror/view");
|
|
323
|
+
var GutterMarker = class extends import_state.RangeValue {
|
|
324
|
+
/// @internal
|
|
325
|
+
compare(other) {
|
|
326
|
+
return this == other || this.constructor == other.constructor && this.eq(other);
|
|
327
|
+
}
|
|
328
|
+
/// Compare this marker to another marker of the same type.
|
|
329
|
+
eq(other) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
/// This property can be used to add CSS classes to the gutter
|
|
333
|
+
/// element that contains this marker.
|
|
334
|
+
elementClass;
|
|
335
|
+
/// Called if the marker has a `toDOM` method and its representation
|
|
336
|
+
/// was removed from a gutter.
|
|
337
|
+
destroy(dom) {
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
GutterMarker.prototype.elementClass = "";
|
|
341
|
+
GutterMarker.prototype.toDOM = void 0;
|
|
342
|
+
GutterMarker.prototype.mapMode = import_state.MapMode.TrackBefore;
|
|
343
|
+
GutterMarker.prototype.startSide = GutterMarker.prototype.endSide = -1;
|
|
344
|
+
GutterMarker.prototype.point = true;
|
|
345
|
+
var gutterLineClass = import_state.Facet.define();
|
|
346
|
+
var gutterWidgetClass = import_state.Facet.define();
|
|
347
|
+
var defaults = {
|
|
348
|
+
class: "",
|
|
349
|
+
renderEmptyElements: false,
|
|
350
|
+
elementStyle: "",
|
|
351
|
+
markers: () => import_state.RangeSet.empty,
|
|
352
|
+
lineMarker: () => null,
|
|
353
|
+
widgetMarker: () => null,
|
|
354
|
+
lineMarkerChange: null,
|
|
355
|
+
initialSpacer: null,
|
|
356
|
+
updateSpacer: null,
|
|
357
|
+
domEventHandlers: {}
|
|
358
|
+
};
|
|
359
|
+
var activeGutters = import_state.Facet.define();
|
|
360
|
+
function gutter(config) {
|
|
361
|
+
return [gutters(), activeGutters.of({ ...defaults, ...config })];
|
|
362
|
+
}
|
|
363
|
+
var unfixGutters = import_state.Facet.define({
|
|
364
|
+
combine: (values) => values.some((x) => x)
|
|
365
|
+
});
|
|
366
|
+
function gutters(config) {
|
|
367
|
+
const result = [
|
|
368
|
+
gutterView,
|
|
369
|
+
// right gutter theme
|
|
370
|
+
import_view3.EditorView.baseTheme({
|
|
371
|
+
".cm-right-gutters": {
|
|
372
|
+
flexShrink: 0,
|
|
373
|
+
display: "flex",
|
|
374
|
+
height: "100%",
|
|
375
|
+
boxSizing: "border-box",
|
|
376
|
+
insetInlineStart: 0,
|
|
377
|
+
zIndex: 200
|
|
378
|
+
},
|
|
379
|
+
".cm-right-gutter": {
|
|
380
|
+
display: "flex !important",
|
|
381
|
+
// Necessary -- prevents margin collapsing
|
|
382
|
+
flexDirection: "column",
|
|
383
|
+
flexShrink: 0,
|
|
384
|
+
boxSizing: "border-box",
|
|
385
|
+
minHeight: "100%",
|
|
386
|
+
overflow: "hidden"
|
|
387
|
+
},
|
|
388
|
+
".cm-rightGutterElement": {
|
|
389
|
+
boxSizing: "border-box"
|
|
390
|
+
}
|
|
391
|
+
})
|
|
392
|
+
];
|
|
393
|
+
if (config && config.fixed === false) result.push(unfixGutters.of(true));
|
|
394
|
+
return result;
|
|
395
|
+
}
|
|
396
|
+
var gutterView = import_view3.ViewPlugin.fromClass(class {
|
|
397
|
+
constructor(view) {
|
|
398
|
+
this.view = view;
|
|
399
|
+
this.prevViewport = view.viewport;
|
|
400
|
+
this.dom = document.createElement("div");
|
|
401
|
+
this.dom.className = "cm-right-gutters";
|
|
402
|
+
this.dom.setAttribute("aria-hidden", "true");
|
|
403
|
+
this.dom.style.minHeight = this.view.contentHeight / this.view.scaleY + "px";
|
|
404
|
+
this.gutters = view.state.facet(activeGutters).map((conf) => new SingleGutterView(view, conf));
|
|
405
|
+
for (const gutter2 of this.gutters) this.dom.appendChild(gutter2.dom);
|
|
406
|
+
this.fixed = !view.state.facet(unfixGutters);
|
|
407
|
+
if (this.fixed) {
|
|
408
|
+
this.dom.style.position = "sticky";
|
|
409
|
+
}
|
|
410
|
+
this.syncGutters(false);
|
|
411
|
+
view.scrollDOM.appendChild(this.dom);
|
|
412
|
+
}
|
|
413
|
+
gutters;
|
|
414
|
+
dom;
|
|
415
|
+
fixed;
|
|
416
|
+
prevViewport;
|
|
417
|
+
update(update) {
|
|
418
|
+
if (this.updateGutters(update)) {
|
|
419
|
+
const vpA = this.prevViewport, vpB = update.view.viewport;
|
|
420
|
+
const vpOverlap = Math.min(vpA.to, vpB.to) - Math.max(vpA.from, vpB.from);
|
|
421
|
+
this.syncGutters(vpOverlap < (vpB.to - vpB.from) * 0.8);
|
|
422
|
+
}
|
|
423
|
+
if (update.geometryChanged) {
|
|
424
|
+
this.dom.style.minHeight = this.view.contentHeight / this.view.scaleY + "px";
|
|
425
|
+
}
|
|
426
|
+
if (this.view.state.facet(unfixGutters) != !this.fixed) {
|
|
427
|
+
this.fixed = !this.fixed;
|
|
428
|
+
this.dom.style.position = this.fixed ? "sticky" : "";
|
|
429
|
+
}
|
|
430
|
+
this.prevViewport = update.view.viewport;
|
|
431
|
+
}
|
|
432
|
+
syncGutters(detach) {
|
|
433
|
+
const before = this.dom.previousSibling;
|
|
434
|
+
if (detach) this.dom.remove();
|
|
435
|
+
const lineClasses = import_state.RangeSet.iter(this.view.state.facet(gutterLineClass), this.view.viewport.from);
|
|
436
|
+
let classSet = [];
|
|
437
|
+
const contexts = this.gutters.map((gutter2) => new UpdateContext(gutter2, this.view.viewport, -this.view.documentPadding.top));
|
|
438
|
+
for (const line of this.view.viewportLineBlocks) {
|
|
439
|
+
if (classSet.length) classSet = [];
|
|
440
|
+
if (Array.isArray(line.type)) {
|
|
441
|
+
let first = true;
|
|
442
|
+
for (const b of line.type) {
|
|
443
|
+
if (b.type == import_view3.BlockType.Text && first) {
|
|
444
|
+
advanceCursor(lineClasses, classSet, b.from);
|
|
445
|
+
for (const cx of contexts) cx.line(this.view, b, classSet);
|
|
446
|
+
first = false;
|
|
447
|
+
} else if (b.widget) {
|
|
448
|
+
for (const cx of contexts) cx.widget(this.view, b);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
} else if (line.type == import_view3.BlockType.Text) {
|
|
452
|
+
advanceCursor(lineClasses, classSet, line.from);
|
|
453
|
+
for (const cx of contexts) cx.line(this.view, line, classSet);
|
|
454
|
+
} else if (line.widget) {
|
|
455
|
+
for (const cx of contexts) cx.widget(this.view, line);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
for (const cx of contexts) cx.finish();
|
|
459
|
+
if (detach) {
|
|
460
|
+
this.view.scrollDOM.insertBefore(this.dom, (before == null ? void 0 : before.nextSibling) ?? null);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
updateGutters(update) {
|
|
464
|
+
const prev = update.startState.facet(activeGutters), cur = update.state.facet(activeGutters);
|
|
465
|
+
let change = update.docChanged || update.heightChanged || update.viewportChanged || !import_state.RangeSet.eq(
|
|
466
|
+
update.startState.facet(gutterLineClass),
|
|
467
|
+
update.state.facet(gutterLineClass),
|
|
468
|
+
update.view.viewport.from,
|
|
469
|
+
update.view.viewport.to
|
|
470
|
+
);
|
|
471
|
+
if (prev == cur) {
|
|
472
|
+
for (const gutter2 of this.gutters) if (gutter2.update(update)) change = true;
|
|
473
|
+
} else {
|
|
474
|
+
change = true;
|
|
475
|
+
const gutters2 = [];
|
|
476
|
+
for (const conf of cur) {
|
|
477
|
+
const known = prev.indexOf(conf);
|
|
478
|
+
if (known < 0) {
|
|
479
|
+
gutters2.push(new SingleGutterView(this.view, conf));
|
|
480
|
+
} else {
|
|
481
|
+
this.gutters[known].update(update);
|
|
482
|
+
gutters2.push(this.gutters[known]);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
for (const g of this.gutters) {
|
|
486
|
+
g.dom.remove();
|
|
487
|
+
if (gutters2.indexOf(g) < 0) g.destroy();
|
|
488
|
+
}
|
|
489
|
+
for (const g of gutters2) this.dom.appendChild(g.dom);
|
|
490
|
+
this.gutters = gutters2;
|
|
491
|
+
}
|
|
492
|
+
return change;
|
|
493
|
+
}
|
|
494
|
+
destroy() {
|
|
495
|
+
for (const view of this.gutters) view.destroy();
|
|
496
|
+
this.dom.remove();
|
|
497
|
+
}
|
|
498
|
+
}, {
|
|
499
|
+
provide: (plugin) => import_view3.EditorView.scrollMargins.of((view) => {
|
|
500
|
+
const value = view.plugin(plugin);
|
|
501
|
+
if (!value || value.gutters.length == 0 || !value.fixed) return null;
|
|
502
|
+
return view.textDirection == import_view3.Direction.LTR ? { left: value.dom.offsetWidth * view.scaleX } : { right: value.dom.offsetWidth * view.scaleX };
|
|
503
|
+
})
|
|
504
|
+
});
|
|
505
|
+
function asArray(val) {
|
|
506
|
+
return Array.isArray(val) ? val : [val];
|
|
507
|
+
}
|
|
508
|
+
function advanceCursor(cursor, collect, pos) {
|
|
509
|
+
while (cursor.value && cursor.from <= pos) {
|
|
510
|
+
if (cursor.from == pos) collect.push(cursor.value);
|
|
511
|
+
cursor.next();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
var UpdateContext = class {
|
|
515
|
+
constructor(gutter2, viewport, height) {
|
|
516
|
+
this.gutter = gutter2;
|
|
517
|
+
this.height = height;
|
|
518
|
+
this.cursor = import_state.RangeSet.iter(gutter2.markers, viewport.from);
|
|
519
|
+
}
|
|
520
|
+
cursor;
|
|
521
|
+
i = 0;
|
|
522
|
+
addElement(view, block, markers) {
|
|
523
|
+
const { gutter: gutter2 } = this, above = (block.top - this.height) / view.scaleY, height = block.height / view.scaleY;
|
|
524
|
+
if (this.i == gutter2.elements.length) {
|
|
525
|
+
const newElt = new GutterElement(view, height, above, markers);
|
|
526
|
+
gutter2.elements.push(newElt);
|
|
527
|
+
gutter2.dom.appendChild(newElt.dom);
|
|
528
|
+
} else {
|
|
529
|
+
gutter2.elements[this.i].update(view, height, above, markers);
|
|
530
|
+
}
|
|
531
|
+
this.height = block.bottom;
|
|
532
|
+
this.i++;
|
|
533
|
+
}
|
|
534
|
+
line(view, line, extraMarkers) {
|
|
535
|
+
let localMarkers = [];
|
|
536
|
+
advanceCursor(this.cursor, localMarkers, line.from);
|
|
537
|
+
if (extraMarkers.length) localMarkers = localMarkers.concat(extraMarkers);
|
|
538
|
+
const forLine = this.gutter.config.lineMarker(view, line, localMarkers);
|
|
539
|
+
if (forLine) localMarkers.unshift(forLine);
|
|
540
|
+
const gutter2 = this.gutter;
|
|
541
|
+
if (localMarkers.length == 0 && !gutter2.config.renderEmptyElements) return;
|
|
542
|
+
this.addElement(view, line, localMarkers);
|
|
543
|
+
}
|
|
544
|
+
widget(view, block) {
|
|
545
|
+
const marker = this.gutter.config.widgetMarker(view, block.widget, block);
|
|
546
|
+
let markers = marker ? [marker] : null;
|
|
547
|
+
for (const cls of view.state.facet(gutterWidgetClass)) {
|
|
548
|
+
const marker2 = cls(view, block.widget, block);
|
|
549
|
+
if (marker2) (markers || (markers = [])).push(marker2);
|
|
550
|
+
}
|
|
551
|
+
if (markers) this.addElement(view, block, markers);
|
|
552
|
+
}
|
|
553
|
+
finish() {
|
|
554
|
+
const gutter2 = this.gutter;
|
|
555
|
+
while (gutter2.elements.length > this.i) {
|
|
556
|
+
const last = gutter2.elements.pop();
|
|
557
|
+
gutter2.dom.removeChild(last.dom);
|
|
558
|
+
last.destroy();
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
var SingleGutterView = class {
|
|
563
|
+
constructor(view, config) {
|
|
564
|
+
this.view = view;
|
|
565
|
+
this.config = config;
|
|
566
|
+
this.dom = document.createElement("div");
|
|
567
|
+
this.dom.className = "cm-right-gutter" + (this.config.class ? " " + this.config.class : "");
|
|
568
|
+
for (const prop in config.domEventHandlers) {
|
|
569
|
+
this.dom.addEventListener(prop, (event) => {
|
|
570
|
+
let target = event.target, y;
|
|
571
|
+
if (target != this.dom && this.dom.contains(target)) {
|
|
572
|
+
while (target.parentNode != this.dom) target = target.parentNode;
|
|
573
|
+
const rect = target.getBoundingClientRect();
|
|
574
|
+
y = (rect.top + rect.bottom) / 2;
|
|
575
|
+
} else {
|
|
576
|
+
y = event.clientY;
|
|
577
|
+
}
|
|
578
|
+
const line = view.lineBlockAtHeight(y - view.documentTop);
|
|
579
|
+
if (config.domEventHandlers[prop](view, line, event)) event.preventDefault();
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
this.markers = asArray(config.markers(view));
|
|
583
|
+
if (config.initialSpacer) {
|
|
584
|
+
this.spacer = new GutterElement(view, 0, 0, [config.initialSpacer(view)]);
|
|
585
|
+
this.dom.appendChild(this.spacer.dom);
|
|
586
|
+
this.spacer.dom.style.cssText += "visibility: hidden; pointer-events: none";
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
dom;
|
|
590
|
+
elements = [];
|
|
591
|
+
markers;
|
|
592
|
+
spacer = null;
|
|
593
|
+
update(update) {
|
|
594
|
+
const prevMarkers = this.markers;
|
|
595
|
+
this.markers = asArray(this.config.markers(update.view));
|
|
596
|
+
if (this.spacer && this.config.updateSpacer) {
|
|
597
|
+
const updated = this.config.updateSpacer(this.spacer.markers[0], update);
|
|
598
|
+
if (updated != this.spacer.markers[0]) this.spacer.update(update.view, 0, 0, [updated]);
|
|
599
|
+
}
|
|
600
|
+
const vp = update.view.viewport;
|
|
601
|
+
return !import_state.RangeSet.eq(this.markers, prevMarkers, vp.from, vp.to) || (this.config.lineMarkerChange ? this.config.lineMarkerChange(update) : false);
|
|
602
|
+
}
|
|
603
|
+
destroy() {
|
|
604
|
+
for (const elt of this.elements) elt.destroy();
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
var GutterElement = class {
|
|
608
|
+
dom;
|
|
609
|
+
height = -1;
|
|
610
|
+
above = 0;
|
|
611
|
+
markers = [];
|
|
612
|
+
constructor(view, height, above, markers) {
|
|
613
|
+
this.dom = document.createElement("div");
|
|
614
|
+
this.dom.className = "cm-rightGutterElement";
|
|
615
|
+
this.update(view, height, above, markers);
|
|
616
|
+
}
|
|
617
|
+
update(view, height, above, markers) {
|
|
618
|
+
if (this.height != height) {
|
|
619
|
+
this.height = height;
|
|
620
|
+
this.dom.style.height = height + "px";
|
|
621
|
+
}
|
|
622
|
+
if (this.above != above)
|
|
623
|
+
this.dom.style.marginTop = (this.above = above) ? above + "px" : "";
|
|
624
|
+
if (!sameMarkers(this.markers, markers)) this.setMarkers(view, markers);
|
|
625
|
+
}
|
|
626
|
+
setMarkers(view, markers) {
|
|
627
|
+
let cls = "cm-rightGutterElement", domPos = this.dom.firstChild;
|
|
628
|
+
for (let iNew = 0, iOld = 0; ; ) {
|
|
629
|
+
let skipTo = iOld, marker = iNew < markers.length ? markers[iNew++] : null, matched = false;
|
|
630
|
+
if (marker) {
|
|
631
|
+
const c = marker.elementClass;
|
|
632
|
+
if (c) cls += " " + c;
|
|
633
|
+
for (let i = iOld; i < this.markers.length; i++)
|
|
634
|
+
if (this.markers[i].compare(marker)) {
|
|
635
|
+
skipTo = i;
|
|
636
|
+
matched = true;
|
|
637
|
+
break;
|
|
638
|
+
}
|
|
639
|
+
} else {
|
|
640
|
+
skipTo = this.markers.length;
|
|
641
|
+
}
|
|
642
|
+
while (iOld < skipTo) {
|
|
643
|
+
const next = this.markers[iOld++];
|
|
644
|
+
if (next.toDOM) {
|
|
645
|
+
next.destroy(domPos);
|
|
646
|
+
const after = domPos.nextSibling;
|
|
647
|
+
domPos.remove();
|
|
648
|
+
domPos = after;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (!marker) break;
|
|
652
|
+
if (marker.toDOM) {
|
|
653
|
+
if (matched) domPos = domPos.nextSibling;
|
|
654
|
+
else this.dom.insertBefore(marker.toDOM(view), domPos);
|
|
655
|
+
}
|
|
656
|
+
if (matched) iOld++;
|
|
657
|
+
}
|
|
658
|
+
this.dom.className = cls;
|
|
659
|
+
this.markers = markers;
|
|
660
|
+
}
|
|
661
|
+
destroy() {
|
|
662
|
+
this.setMarkers(null, []);
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
function sameMarkers(a, b) {
|
|
666
|
+
if (a.length != b.length) return false;
|
|
667
|
+
for (let i = 0; i < a.length; i++) if (!a[i].compare(b[i])) return false;
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
var activeLineGutterMarker = new class extends GutterMarker {
|
|
671
|
+
elementClass = "cm-activeLineRightGutter";
|
|
672
|
+
}();
|
|
673
|
+
var activeLineGutterHighlighter = gutterLineClass.compute(["selection"], (state) => {
|
|
674
|
+
const marks = [];
|
|
675
|
+
let last = -1;
|
|
676
|
+
for (const range of state.selection.ranges) {
|
|
677
|
+
const linePos = state.doc.lineAt(range.head).from;
|
|
678
|
+
if (linePos > last) {
|
|
679
|
+
last = linePos;
|
|
680
|
+
marks.push(activeLineGutterMarker.range(linePos));
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return import_state.RangeSet.of(marks);
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// src/gutter/atoms.ts
|
|
687
|
+
var import_jotai = require("jotai");
|
|
688
|
+
var import_state2 = require("@codemirror/state");
|
|
689
|
+
var facetAtom = (0, import_jotai.atom)(import_state2.Facet.define());
|
|
690
|
+
|
|
691
|
+
// src/gutter/gutter.tsx
|
|
692
|
+
var DOMGutterLineMarker = class extends GutterMarker {
|
|
693
|
+
constructor(dom) {
|
|
694
|
+
super();
|
|
695
|
+
this.dom = dom;
|
|
696
|
+
}
|
|
697
|
+
eq(other) {
|
|
698
|
+
return this.dom === other.dom;
|
|
699
|
+
}
|
|
700
|
+
toDOM() {
|
|
701
|
+
return this.dom;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
function HydrateAtoms({ markers, children }) {
|
|
705
|
+
(0, import_utils.useHydrateAtoms)([[facetAtom, markers]]);
|
|
706
|
+
return /* @__PURE__ */ import_react11.default.createElement(import_react11.default.Fragment, null, children);
|
|
707
|
+
}
|
|
708
|
+
var GutterPlacement = /* @__PURE__ */ ((GutterPlacement2) => {
|
|
709
|
+
GutterPlacement2["Left"] = "left";
|
|
710
|
+
GutterPlacement2["Right"] = "right";
|
|
711
|
+
return GutterPlacement2;
|
|
712
|
+
})(GutterPlacement || {});
|
|
713
|
+
function Gutter({
|
|
714
|
+
defaultClassName,
|
|
715
|
+
placement = "left" /* Left */,
|
|
716
|
+
children
|
|
717
|
+
}) {
|
|
718
|
+
const [markersFacet] = (0, import_react11.useState)(
|
|
719
|
+
() => import_state3.Facet.define()
|
|
720
|
+
);
|
|
721
|
+
(0, import_react_hooks3.useInjectorEffect)(
|
|
722
|
+
(injector) => {
|
|
723
|
+
const gutter2 = placement === "right" /* Right */ ? gutter : import_view4.gutter;
|
|
724
|
+
return injector.inject([
|
|
725
|
+
gutter2({
|
|
726
|
+
class: defaultClassName ?? "",
|
|
727
|
+
markers(view) {
|
|
728
|
+
const specs = view.state.facet(markersFacet);
|
|
729
|
+
const { lines } = view.state.doc;
|
|
730
|
+
let markers = import_state3.RangeSet.empty;
|
|
731
|
+
for (const spec of specs) {
|
|
732
|
+
const { lineNumber } = spec;
|
|
733
|
+
if (lineNumber < 1 || lineNumber > lines) {
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
const line = view.state.doc.line(spec.lineNumber);
|
|
737
|
+
markers = markers.update({
|
|
738
|
+
add: [new DOMGutterLineMarker(spec.dom).range(line.from)],
|
|
739
|
+
sort: true
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
return markers;
|
|
743
|
+
}
|
|
744
|
+
})
|
|
745
|
+
]);
|
|
746
|
+
},
|
|
747
|
+
[placement]
|
|
748
|
+
);
|
|
749
|
+
return /* @__PURE__ */ import_react11.default.createElement(import_jotai2.Provider, null, /* @__PURE__ */ import_react11.default.createElement(HydrateAtoms, { markers: markersFacet }, children));
|
|
750
|
+
}
|
|
751
|
+
function GutterLineMarker({
|
|
752
|
+
lineNumber,
|
|
753
|
+
children
|
|
754
|
+
}) {
|
|
755
|
+
const facet = (0, import_jotai2.useAtomValue)(facetAtom);
|
|
756
|
+
const editor = (0, import_react12.useEditor)();
|
|
757
|
+
const compartment = (0, import_react_hooks3.useCompartment)();
|
|
758
|
+
const elementRef = (0, import_react_hooks3.useLatest)((0, import_react_hooks3.useHTMLElement)());
|
|
759
|
+
(0, import_react_hooks3.useInjectorEffect)((injector) => injector.inject([compartment.of([])]), []);
|
|
760
|
+
(0, import_react11.useEffect)(() => {
|
|
761
|
+
if (!editor) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
editor.$view.dispatch({
|
|
765
|
+
effects: compartment.reconfigure(
|
|
766
|
+
facet.of({
|
|
767
|
+
lineNumber,
|
|
768
|
+
dom: elementRef.current
|
|
769
|
+
})
|
|
770
|
+
)
|
|
771
|
+
});
|
|
772
|
+
}, [editor, compartment, lineNumber]);
|
|
773
|
+
return (0, import_react_dom2.createPortal)(children, elementRef.current);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/fold-gutter/index.tsx
|
|
777
|
+
var import_react_dom3 = require("react-dom");
|
|
778
|
+
var import_react13 = __toESM(require("react"));
|
|
779
|
+
var import_uuid = require("@lukeed/uuid");
|
|
780
|
+
var import_utils2 = require("@coze-editor/utils");
|
|
781
|
+
var import_react_hooks4 = require("@coze-editor/react-hooks");
|
|
782
|
+
var import_react14 = require("@coze-editor/react");
|
|
783
|
+
var import_view5 = require("@codemirror/view");
|
|
784
|
+
var import_state4 = require("@codemirror/state");
|
|
785
|
+
var import_language = require("@codemirror/language");
|
|
786
|
+
function FluentTriangleDown12Filled(props) {
|
|
787
|
+
return /* @__PURE__ */ import_react13.default.createElement(
|
|
788
|
+
"svg",
|
|
789
|
+
{
|
|
790
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
791
|
+
width: "8px",
|
|
792
|
+
height: "8px",
|
|
793
|
+
viewBox: "0 0 12 12",
|
|
794
|
+
...props
|
|
795
|
+
},
|
|
796
|
+
/* @__PURE__ */ import_react13.default.createElement(
|
|
797
|
+
"path",
|
|
798
|
+
{
|
|
799
|
+
fill: "currentColor",
|
|
800
|
+
d: "M5.214 10.541a.903.903 0 0 0 1.572 0l4.092-7.169C11.226 2.762 10.789 2 10.09 2H1.91c-.698 0-1.135.762-.787 1.372z"
|
|
801
|
+
}
|
|
802
|
+
)
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
function FluentTriangleRight12Filled(props) {
|
|
806
|
+
return /* @__PURE__ */ import_react13.default.createElement(
|
|
807
|
+
"svg",
|
|
808
|
+
{
|
|
809
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
810
|
+
width: "8px",
|
|
811
|
+
height: "8px",
|
|
812
|
+
viewBox: "0 0 12 12",
|
|
813
|
+
...props
|
|
814
|
+
},
|
|
815
|
+
/* @__PURE__ */ import_react13.default.createElement(
|
|
816
|
+
"path",
|
|
817
|
+
{
|
|
818
|
+
fill: "currentColor",
|
|
819
|
+
d: "M10.541 6.786a.903.903 0 0 0 0-1.572L3.372 1.122C2.762.774 2 1.211 2 1.91v8.182c0 .698.762 1.135 1.372.787z"
|
|
820
|
+
}
|
|
821
|
+
)
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
function defaultRenderMarker(open) {
|
|
825
|
+
return open ? /* @__PURE__ */ import_react13.default.createElement(FluentTriangleDown12Filled, null) : /* @__PURE__ */ import_react13.default.createElement(FluentTriangleRight12Filled, null);
|
|
826
|
+
}
|
|
827
|
+
function defaultRenderPlaceholder() {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
function FoldGutter({
|
|
831
|
+
renderMarker = defaultRenderMarker,
|
|
832
|
+
renderPlaceholder = defaultRenderPlaceholder,
|
|
833
|
+
opacityTransition = false,
|
|
834
|
+
opacityTransitionDuration = 300
|
|
835
|
+
}) {
|
|
836
|
+
const connector = (0, import_react_hooks4.usePortalConnector)({ sync: true });
|
|
837
|
+
const connectorRef = (0, import_react_hooks4.useLatest)(connector);
|
|
838
|
+
const renderMarkerRef = (0, import_react_hooks4.useLatest)(renderMarker);
|
|
839
|
+
const renderPlaceholderRef = (0, import_react_hooks4.useLatest)(renderPlaceholder);
|
|
840
|
+
const [opacity, setOpacity] = (0, import_react13.useState)(0);
|
|
841
|
+
const setOpacityRef = (0, import_react_hooks4.useLatest)(setOpacity);
|
|
842
|
+
const injector = (0, import_react14.useInjector)();
|
|
843
|
+
const { Portal } = connector;
|
|
844
|
+
(0, import_react13.useEffect)(() => {
|
|
845
|
+
if (!opacityTransition || !opacityTransitionDuration) {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
return injector.inject([
|
|
849
|
+
import_view5.EditorView.theme({
|
|
850
|
+
".cm-foldGutter": {
|
|
851
|
+
transition: `opacity ${opacityTransitionDuration / 1e3}s ease`
|
|
852
|
+
}
|
|
853
|
+
})
|
|
854
|
+
]);
|
|
855
|
+
}, [injector, opacityTransition, opacityTransitionDuration]);
|
|
856
|
+
(0, import_react_hooks4.useInjectorEffect)(
|
|
857
|
+
(injector2) => {
|
|
858
|
+
if (!opacityTransition) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
return injector2.inject([
|
|
862
|
+
import_state4.Prec.lowest(
|
|
863
|
+
import_view5.EditorView.theme({
|
|
864
|
+
".cm-foldGutter": {
|
|
865
|
+
opacity
|
|
866
|
+
}
|
|
867
|
+
})
|
|
868
|
+
)
|
|
869
|
+
]);
|
|
870
|
+
},
|
|
871
|
+
[opacityTransition, opacity]
|
|
872
|
+
);
|
|
873
|
+
(0, import_react_hooks4.useInjectorEffect)((injector2) => {
|
|
874
|
+
const disposes = [];
|
|
875
|
+
return (0, import_utils2.disposeAll)([
|
|
876
|
+
injector2.inject([
|
|
877
|
+
import_state4.Prec.low(
|
|
878
|
+
import_view5.EditorView.theme({
|
|
879
|
+
".cm-foldGutter .cm-gutterElement": {
|
|
880
|
+
display: "flex",
|
|
881
|
+
alignItems: "center",
|
|
882
|
+
cursor: "pointer"
|
|
883
|
+
}
|
|
884
|
+
})
|
|
885
|
+
),
|
|
886
|
+
(0, import_language.foldGutter)({
|
|
887
|
+
markerDOM(open) {
|
|
888
|
+
const dom = document.createElement("span");
|
|
889
|
+
dom.setAttribute("aria-expanded", open ? "true" : "false");
|
|
890
|
+
const id = (0, import_uuid.v4)();
|
|
891
|
+
connectorRef.current.connect(
|
|
892
|
+
id,
|
|
893
|
+
(0, import_react_dom3.createPortal)(renderMarkerRef.current(open), dom)
|
|
894
|
+
);
|
|
895
|
+
disposes.push(() => {
|
|
896
|
+
connectorRef.current.disconnect(id);
|
|
897
|
+
});
|
|
898
|
+
return dom;
|
|
899
|
+
},
|
|
900
|
+
domEventHandlers: {
|
|
901
|
+
mouseenter() {
|
|
902
|
+
setOpacityRef.current(1);
|
|
903
|
+
return true;
|
|
904
|
+
},
|
|
905
|
+
mouseleave() {
|
|
906
|
+
setOpacityRef.current(0);
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}),
|
|
911
|
+
(0, import_language.codeFolding)({
|
|
912
|
+
placeholderDOM(view, onclick) {
|
|
913
|
+
const dom = document.createElement("span");
|
|
914
|
+
const id = (0, import_uuid.v4)();
|
|
915
|
+
connectorRef.current.connect(
|
|
916
|
+
id,
|
|
917
|
+
(0, import_react_dom3.createPortal)(renderPlaceholderRef.current(), dom)
|
|
918
|
+
);
|
|
919
|
+
disposes.push(() => {
|
|
920
|
+
connectorRef.current.disconnect(id);
|
|
921
|
+
});
|
|
922
|
+
dom.addEventListener("click", onclick, false);
|
|
923
|
+
disposes.push(() => {
|
|
924
|
+
dom.removeEventListener("click", onclick, false);
|
|
925
|
+
});
|
|
926
|
+
return dom;
|
|
927
|
+
}
|
|
928
|
+
})
|
|
929
|
+
]),
|
|
930
|
+
...disposes
|
|
931
|
+
]);
|
|
932
|
+
}, []);
|
|
933
|
+
return /* @__PURE__ */ import_react13.default.createElement(Portal, null);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/placeholder/index.tsx
|
|
937
|
+
var import_react_dom4 = require("react-dom");
|
|
938
|
+
var import_react_hooks5 = require("@coze-editor/react-hooks");
|
|
939
|
+
var import_extension_placeholder = require("@coze-editor/extension-placeholder");
|
|
940
|
+
function Placeholder({ children }) {
|
|
941
|
+
const element = (0, import_react_hooks5.useHTMLElement)("span");
|
|
942
|
+
(0, import_react_hooks5.useInjectorEffect)(
|
|
943
|
+
(injector) => injector.inject([(0, import_extension_placeholder.placeholder)(() => element)]),
|
|
944
|
+
[]
|
|
945
|
+
);
|
|
946
|
+
return (0, import_react_dom4.createPortal)(children, element);
|
|
947
|
+
}
|
|
948
|
+
function ActiveLinePlaceholder({
|
|
949
|
+
children
|
|
950
|
+
}) {
|
|
951
|
+
const element = (0, import_react_hooks5.useHTMLElement)("span");
|
|
952
|
+
(0, import_react_hooks5.useInjectorEffect)(
|
|
953
|
+
(injector) => injector.inject([(0, import_extension_placeholder.activeLinePlaceholder)(() => element)]),
|
|
954
|
+
[]
|
|
955
|
+
);
|
|
956
|
+
return (0, import_react_dom4.createPortal)(children, element);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// src/ref-element/index.tsx
|
|
960
|
+
var import_react15 = require("react");
|
|
961
|
+
var import_react_hooks6 = require("@coze-editor/react-hooks");
|
|
962
|
+
var RefElement = (0, import_react15.forwardRef)(({ element }, ref) => {
|
|
963
|
+
const domRef = (0, import_react_hooks6.useLatest)(element);
|
|
964
|
+
(0, import_react15.useImperativeHandle)(ref, () => domRef.current);
|
|
965
|
+
return null;
|
|
966
|
+
});
|
|
967
|
+
RefElement.displayName = "RefElement";
|
|
968
|
+
|
|
969
|
+
// src/line-widget/index.tsx
|
|
970
|
+
var import_react_dom5 = require("react-dom");
|
|
971
|
+
var import_react16 = require("react");
|
|
972
|
+
var import_react_hooks7 = require("@coze-editor/react-hooks");
|
|
973
|
+
var import_react17 = require("@coze-editor/react");
|
|
974
|
+
|
|
975
|
+
// src/line-widget/cursor-widget/state.ts
|
|
976
|
+
var import_view7 = require("@codemirror/view");
|
|
977
|
+
var import_state5 = require("@codemirror/state");
|
|
978
|
+
|
|
979
|
+
// src/line-widget/cursor-widget/widget-decoration.ts
|
|
980
|
+
var import_view6 = require("@codemirror/view");
|
|
981
|
+
var CustomDivWidget = class extends import_view6.WidgetType {
|
|
982
|
+
customDOM;
|
|
983
|
+
constructor(customDOM) {
|
|
984
|
+
super();
|
|
985
|
+
this.customDOM = customDOM;
|
|
986
|
+
}
|
|
987
|
+
toDOM() {
|
|
988
|
+
const div = document.createElement("div");
|
|
989
|
+
div.className = "cursor-widget-wrapper";
|
|
990
|
+
div.setAttribute("style", "caret-color: initial;");
|
|
991
|
+
if (this.customDOM) {
|
|
992
|
+
div.appendChild(this.customDOM);
|
|
993
|
+
}
|
|
994
|
+
return div;
|
|
995
|
+
}
|
|
996
|
+
eq(widget) {
|
|
997
|
+
return widget.customDOM === this.customDOM;
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
var createBlockWidget = (config, pos) => {
|
|
1001
|
+
if (typeof pos !== "number") {
|
|
1002
|
+
return import_view6.Decoration.none;
|
|
1003
|
+
}
|
|
1004
|
+
return import_view6.Decoration.set(
|
|
1005
|
+
import_view6.Decoration.widget({
|
|
1006
|
+
widget: new CustomDivWidget(config.createDOM()),
|
|
1007
|
+
side: config.side,
|
|
1008
|
+
block: true,
|
|
1009
|
+
config
|
|
1010
|
+
}).range(pos)
|
|
1011
|
+
);
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
// src/line-widget/cursor-widget/state.ts
|
|
1015
|
+
var setWidgetEffect = import_state5.StateEffect.define();
|
|
1016
|
+
var getPos = (state, num) => state.doc.line(num).from;
|
|
1017
|
+
var cursorWidgetState = (facet) => import_state5.StateField.define({
|
|
1018
|
+
create(state) {
|
|
1019
|
+
return createBlockWidget(
|
|
1020
|
+
facet.config,
|
|
1021
|
+
typeof facet.config.lineNumber === "number" ? getPos(state, facet.config.lineNumber) : void 0
|
|
1022
|
+
);
|
|
1023
|
+
},
|
|
1024
|
+
update(widget, tr) {
|
|
1025
|
+
tr.effects.forEach((effect) => {
|
|
1026
|
+
if (effect.is(setWidgetEffect) && effect.value.id === facet.id) {
|
|
1027
|
+
widget = createBlockWidget(
|
|
1028
|
+
{
|
|
1029
|
+
...facet.config,
|
|
1030
|
+
side: effect.value.side,
|
|
1031
|
+
lineNumber: effect.value.lineNumber
|
|
1032
|
+
},
|
|
1033
|
+
typeof effect.value.lineNumber === "number" ? getPos(tr.state, effect.value.lineNumber) : void 0
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
return widget.update({
|
|
1038
|
+
filter: (from, to) => 0 <= from && to <= tr.state.doc.length
|
|
1039
|
+
});
|
|
1040
|
+
},
|
|
1041
|
+
provide: (f) => import_view7.EditorView.decorations.from(f)
|
|
1042
|
+
});
|
|
1043
|
+
var setWidgetLineNumber = (id, lineNumber, side) => ({
|
|
1044
|
+
effects: [setWidgetEffect.of({ lineNumber, id, side })]
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// src/line-widget/cursor-widget/common.ts
|
|
1048
|
+
var nextID = 1;
|
|
1049
|
+
var ConfigFacet = class {
|
|
1050
|
+
constructor(config) {
|
|
1051
|
+
this.config = config;
|
|
1052
|
+
}
|
|
1053
|
+
id = nextID++;
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// src/line-widget/cursor-widget/index.ts
|
|
1057
|
+
var cursorBlockWidget = (config) => {
|
|
1058
|
+
const facet = new ConfigFacet(config);
|
|
1059
|
+
return {
|
|
1060
|
+
setWidgetLineNumber: (lineNumber, side) => setWidgetLineNumber(facet.id, lineNumber, side),
|
|
1061
|
+
extension: [cursorWidgetState(facet)]
|
|
1062
|
+
};
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
// src/line-widget/index.tsx
|
|
1066
|
+
function LineWidget({ children, lineNumber, side }) {
|
|
1067
|
+
const setWidgetLineNumberRef = (0, import_react16.useRef)(null);
|
|
1068
|
+
const injector = (0, import_react17.useInjector)();
|
|
1069
|
+
const editor = (0, import_react17.useEditor)();
|
|
1070
|
+
(0, import_react16.useEffect)(() => {
|
|
1071
|
+
var _a;
|
|
1072
|
+
if (setWidgetLineNumberRef.current && (editor == null ? void 0 : editor.$view)) {
|
|
1073
|
+
(_a = editor.$view) == null ? void 0 : _a.dispatch(setWidgetLineNumberRef.current(lineNumber, side));
|
|
1074
|
+
}
|
|
1075
|
+
}, [lineNumber, side]);
|
|
1076
|
+
const element = (0, import_react_hooks7.useHTMLElement)("span");
|
|
1077
|
+
(0, import_react16.useLayoutEffect)(() => {
|
|
1078
|
+
const { extension, setWidgetLineNumber: setWidgetLineNumber2 } = cursorBlockWidget({
|
|
1079
|
+
side,
|
|
1080
|
+
lineNumber,
|
|
1081
|
+
createDOM: () => element
|
|
1082
|
+
});
|
|
1083
|
+
setWidgetLineNumberRef.current = setWidgetLineNumber2;
|
|
1084
|
+
return injector.inject(extension);
|
|
1085
|
+
}, [injector]);
|
|
1086
|
+
return (0, import_react_dom5.createPortal)(children, element);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// src/diff-view/index.tsx
|
|
1090
|
+
var import_react18 = require("react");
|
|
1091
|
+
var import_react19 = require("@coze-editor/react");
|
|
1092
|
+
|
|
1093
|
+
// src/diff-view/extension.ts
|
|
1094
|
+
var import_view8 = require("@codemirror/view");
|
|
1095
|
+
var import_state7 = require("@codemirror/state");
|
|
1096
|
+
var import_merge = require("@codemirror/merge");
|
|
1097
|
+
var diffView = (props) => {
|
|
1098
|
+
const { original = "" } = props;
|
|
1099
|
+
return [
|
|
1100
|
+
(0, import_merge.unifiedMergeView)({
|
|
1101
|
+
original,
|
|
1102
|
+
gutter: false
|
|
1103
|
+
}),
|
|
1104
|
+
import_state7.EditorState.phrases.of({
|
|
1105
|
+
Accept: "^Y",
|
|
1106
|
+
Reject: "^N"
|
|
1107
|
+
}),
|
|
1108
|
+
import_view8.EditorView.theme({
|
|
1109
|
+
".cm-deletedChunk": {
|
|
1110
|
+
paddingLeft: "2px",
|
|
1111
|
+
backgroundColor: "rgba(220, 68, 50, 0.2)"
|
|
1112
|
+
},
|
|
1113
|
+
".cm-deletedChunk .cm-chunkButtons": {
|
|
1114
|
+
position: "static",
|
|
1115
|
+
display: "flex"
|
|
1116
|
+
},
|
|
1117
|
+
".cm-deletedChunk .cm-chunkButtons button": {
|
|
1118
|
+
flex: "1",
|
|
1119
|
+
margin: "0px"
|
|
1120
|
+
},
|
|
1121
|
+
".cm-deletedChunk .cm-chunkButtons button:first-child": {
|
|
1122
|
+
marginRight: "2px"
|
|
1123
|
+
},
|
|
1124
|
+
".cm-deletedChunk del": {
|
|
1125
|
+
textDecoration: "none",
|
|
1126
|
+
backgroundColor: "rgba(220, 68, 50, 0.4)"
|
|
1127
|
+
},
|
|
1128
|
+
"&.cm-merge-b .cm-changedLine": {
|
|
1129
|
+
backgroundColor: "rgba(33, 170, 33, 0.2)"
|
|
1130
|
+
},
|
|
1131
|
+
".cm-insertedLine .cm-changedText": {
|
|
1132
|
+
background: "none",
|
|
1133
|
+
backgroundColor: "rgba(33, 170, 33, 0.4)"
|
|
1134
|
+
}
|
|
1135
|
+
})
|
|
1136
|
+
];
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
// src/diff-view/index.tsx
|
|
1140
|
+
function DiffView({ original }) {
|
|
1141
|
+
const injector = (0, import_react19.useInjector)();
|
|
1142
|
+
(0, import_react18.useLayoutEffect)(() => injector.inject(diffView({ original })), []);
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// src/mention/extension.ts
|
|
1147
|
+
var import_utils3 = require("@coze-editor/utils");
|
|
1148
|
+
var import_state8 = require("@codemirror/state");
|
|
1149
|
+
|
|
1150
|
+
// src/mention/is.ts
|
|
1151
|
+
function hasTriggerCharacters(options) {
|
|
1152
|
+
return Array.isArray(options.triggerCharacters);
|
|
1153
|
+
}
|
|
1154
|
+
function hasTrigger(options) {
|
|
1155
|
+
return typeof options.trigger === "function";
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/mention/extension.ts
|
|
1159
|
+
var validForReg = /^[\u4e00-\u9fa5a-zA-Z0-9_']*$/;
|
|
1160
|
+
function defaultValidFor(text) {
|
|
1161
|
+
return validForReg.test(text);
|
|
1162
|
+
}
|
|
1163
|
+
var fields = import_state8.Facet.define();
|
|
1164
|
+
function mention(options) {
|
|
1165
|
+
const mentionConfig = import_state8.Facet.define({
|
|
1166
|
+
combine: import_utils3.FacetCombineStrategy.Last
|
|
1167
|
+
});
|
|
1168
|
+
const field = import_state8.StateField.define({
|
|
1169
|
+
create() {
|
|
1170
|
+
return {
|
|
1171
|
+
show: false,
|
|
1172
|
+
triggerContext: void 0
|
|
1173
|
+
};
|
|
1174
|
+
},
|
|
1175
|
+
update(value, tr) {
|
|
1176
|
+
const options2 = tr.startState.facet(mentionConfig);
|
|
1177
|
+
const { search = true, onOpenChange, onSearch } = options2;
|
|
1178
|
+
let { show } = value;
|
|
1179
|
+
let triggerContext = void 0;
|
|
1180
|
+
if (tr.docChanged) {
|
|
1181
|
+
if (hasTriggerCharacters(options2)) {
|
|
1182
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
1183
|
+
const insertString = inserted.toString();
|
|
1184
|
+
if (fromA === toA && options2.triggerCharacters.includes(insertString)) {
|
|
1185
|
+
triggerContext = {
|
|
1186
|
+
from: fromB,
|
|
1187
|
+
to: toB,
|
|
1188
|
+
triggerCharacter: insertString,
|
|
1189
|
+
cursorPosition: tr.state.selection.main.head
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1193
|
+
} else if (hasTrigger(options2)) {
|
|
1194
|
+
triggerContext = options2.trigger(tr);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
const isSelectUserEvent = tr.isUserEvent("select");
|
|
1198
|
+
const newValue = {
|
|
1199
|
+
show: value.show,
|
|
1200
|
+
triggerContext: value.triggerContext ? { ...value.triggerContext } : void 0
|
|
1201
|
+
};
|
|
1202
|
+
if (triggerContext) {
|
|
1203
|
+
newValue.triggerContext = triggerContext;
|
|
1204
|
+
show = true;
|
|
1205
|
+
if (typeof onSearch === "function") {
|
|
1206
|
+
onSearch({
|
|
1207
|
+
value: ""
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
} else if (tr.docChanged && value.triggerContext && search) {
|
|
1211
|
+
if (newValue.triggerContext) {
|
|
1212
|
+
const newFrom = tr.changes.mapPos(
|
|
1213
|
+
value.triggerContext.from,
|
|
1214
|
+
1,
|
|
1215
|
+
import_state8.MapMode.TrackAfter
|
|
1216
|
+
);
|
|
1217
|
+
const newTo = tr.changes.mapPos(
|
|
1218
|
+
value.triggerContext.to,
|
|
1219
|
+
1,
|
|
1220
|
+
import_state8.MapMode.Simple
|
|
1221
|
+
);
|
|
1222
|
+
if (typeof newFrom === "number" && typeof newTo === "number") {
|
|
1223
|
+
newValue.triggerContext.from = newFrom;
|
|
1224
|
+
newValue.triggerContext.to = newTo;
|
|
1225
|
+
} else {
|
|
1226
|
+
show = false;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
if (show === true) {
|
|
1230
|
+
const validFor = typeof search === "object" ? search.validFor : defaultValidFor;
|
|
1231
|
+
const from = value.triggerContext.cursorPosition;
|
|
1232
|
+
const to = tr.state.selection.main.head;
|
|
1233
|
+
if (to >= from) {
|
|
1234
|
+
const text = tr.state.sliceDoc(from, to);
|
|
1235
|
+
if (validFor(text, from, to, tr.state)) {
|
|
1236
|
+
show = true;
|
|
1237
|
+
if (typeof onSearch === "function") {
|
|
1238
|
+
onSearch({
|
|
1239
|
+
value: text
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
show = false;
|
|
1244
|
+
}
|
|
1245
|
+
} else {
|
|
1246
|
+
show = false;
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
} else if (isSelectUserEvent) {
|
|
1250
|
+
show = false;
|
|
1251
|
+
}
|
|
1252
|
+
if (show === false) {
|
|
1253
|
+
newValue.triggerContext = void 0;
|
|
1254
|
+
}
|
|
1255
|
+
if (show !== value.show) {
|
|
1256
|
+
newValue.show = show;
|
|
1257
|
+
if (typeof onOpenChange === "function") {
|
|
1258
|
+
onOpenChange({
|
|
1259
|
+
value: show,
|
|
1260
|
+
state: tr.state,
|
|
1261
|
+
triggerContext: newValue.triggerContext ? {
|
|
1262
|
+
from: newValue.triggerContext.from,
|
|
1263
|
+
to: newValue.triggerContext.to,
|
|
1264
|
+
triggerCharacter: newValue.triggerContext.triggerCharacter
|
|
1265
|
+
} : void 0
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
return newValue;
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
return [mentionConfig.of(options), field, fields.of(field)];
|
|
1273
|
+
}
|
|
1274
|
+
function getCurrentMentionReplaceRange(state) {
|
|
1275
|
+
const allFields = state.facet(fields);
|
|
1276
|
+
for (const field of allFields) {
|
|
1277
|
+
const fieldState = state.field(field, false);
|
|
1278
|
+
if (fieldState && fieldState.triggerContext && typeof fieldState.triggerContext.from === "number" && typeof fieldState.triggerContext.to === "number") {
|
|
1279
|
+
return {
|
|
1280
|
+
from: fieldState.triggerContext.from,
|
|
1281
|
+
to: fieldState.triggerContext.to
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/mention/react.tsx
|
|
1288
|
+
var import_react_hooks8 = require("@coze-editor/react-hooks");
|
|
1289
|
+
function Mention(props) {
|
|
1290
|
+
const propsRef = (0, import_react_hooks8.useLatest)(props);
|
|
1291
|
+
(0, import_react_hooks8.useInjectorEffect)((injector) => {
|
|
1292
|
+
const sharedOptions = {
|
|
1293
|
+
search: props.search,
|
|
1294
|
+
onOpenChange(...args) {
|
|
1295
|
+
if (typeof propsRef.current.onOpenChange === "function") {
|
|
1296
|
+
return propsRef.current.onOpenChange(...args);
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
onSearch(...args) {
|
|
1300
|
+
if (typeof propsRef.current.onSearch === "function") {
|
|
1301
|
+
return propsRef.current.onSearch(...args);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
return injector.inject([
|
|
1306
|
+
mention(
|
|
1307
|
+
hasTrigger(props) ? {
|
|
1308
|
+
...sharedOptions,
|
|
1309
|
+
trigger(tr) {
|
|
1310
|
+
if (hasTrigger(propsRef.current)) {
|
|
1311
|
+
return propsRef.current.trigger(tr);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
} : {
|
|
1315
|
+
...sharedOptions,
|
|
1316
|
+
triggerCharacters: props.triggerCharacters ?? []
|
|
1317
|
+
}
|
|
1318
|
+
)
|
|
1319
|
+
]);
|
|
1320
|
+
});
|
|
1321
|
+
return null;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
// src/embeded-line-view/react.tsx
|
|
1325
|
+
var import_react_dom6 = require("react-dom");
|
|
1326
|
+
var import_react21 = require("react");
|
|
1327
|
+
var import_react_hooks9 = require("@coze-editor/react-hooks");
|
|
1328
|
+
var import_react22 = require("@coze-editor/react");
|
|
1329
|
+
var import_view9 = require("@codemirror/view");
|
|
1330
|
+
var import_state9 = require("@codemirror/state");
|
|
1331
|
+
var DOMWidget = class extends import_view9.WidgetType {
|
|
1332
|
+
constructor(options) {
|
|
1333
|
+
super();
|
|
1334
|
+
this.options = options;
|
|
1335
|
+
}
|
|
1336
|
+
toDOM() {
|
|
1337
|
+
return this.options.dom;
|
|
1338
|
+
}
|
|
1339
|
+
eq(other) {
|
|
1340
|
+
return this.options.dom === other.options.dom;
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
var EmbededLineViewSide = /* @__PURE__ */ ((EmbededLineViewSide2) => {
|
|
1344
|
+
EmbededLineViewSide2["Before"] = "before";
|
|
1345
|
+
EmbededLineViewSide2["After"] = "after";
|
|
1346
|
+
return EmbededLineViewSide2;
|
|
1347
|
+
})(EmbededLineViewSide || {});
|
|
1348
|
+
var updateEffect = import_state9.StateEffect.define();
|
|
1349
|
+
var EmbededLineView = (0, import_react21.forwardRef)(function EmbededLineView2({ children }, ref) {
|
|
1350
|
+
const dom = (0, import_react_hooks9.useHTMLElement)("div");
|
|
1351
|
+
const domRef = (0, import_react_hooks9.useLatest)(dom);
|
|
1352
|
+
const editor = (0, import_react22.useEditor)();
|
|
1353
|
+
const editorRef = (0, import_react_hooks9.useLatest)(editor);
|
|
1354
|
+
(0, import_react21.useImperativeHandle)(ref, () => ({
|
|
1355
|
+
update({ visible, line, side }) {
|
|
1356
|
+
var _a;
|
|
1357
|
+
(_a = editorRef.current) == null ? void 0 : _a.$view.dispatch({
|
|
1358
|
+
effects: updateEffect.of({
|
|
1359
|
+
visible,
|
|
1360
|
+
line: line ?? 1,
|
|
1361
|
+
side: side ?? "before" /* Before */
|
|
1362
|
+
})
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
}));
|
|
1366
|
+
(0, import_react_hooks9.useInjectorEffect)((injector) => {
|
|
1367
|
+
const field = import_state9.StateField.define({
|
|
1368
|
+
create() {
|
|
1369
|
+
return {
|
|
1370
|
+
position: 0,
|
|
1371
|
+
side: "before" /* Before */,
|
|
1372
|
+
decorations: import_view9.Decoration.none
|
|
1373
|
+
};
|
|
1374
|
+
},
|
|
1375
|
+
update(value, tr) {
|
|
1376
|
+
const newPosition = tr.changes.mapPos(
|
|
1377
|
+
value.position,
|
|
1378
|
+
-1,
|
|
1379
|
+
import_state9.MapMode.Simple
|
|
1380
|
+
);
|
|
1381
|
+
let newValue = value;
|
|
1382
|
+
if (typeof newPosition === "number" && newPosition !== value.position) {
|
|
1383
|
+
const docLine = tr.state.doc.lineAt(newPosition);
|
|
1384
|
+
let decoPos = 0;
|
|
1385
|
+
if (value.side === "after" /* After */) {
|
|
1386
|
+
decoPos = docLine.to;
|
|
1387
|
+
} else {
|
|
1388
|
+
decoPos = docLine.from;
|
|
1389
|
+
}
|
|
1390
|
+
newValue = {
|
|
1391
|
+
...value,
|
|
1392
|
+
position: newPosition,
|
|
1393
|
+
decorations: import_view9.Decoration.set([
|
|
1394
|
+
import_view9.Decoration.widget({
|
|
1395
|
+
widget: new DOMWidget({
|
|
1396
|
+
dom: domRef.current
|
|
1397
|
+
}),
|
|
1398
|
+
block: true,
|
|
1399
|
+
side: value.side === "after" /* After */ ? 1 : -1
|
|
1400
|
+
}).range(decoPos)
|
|
1401
|
+
])
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
for (const effect of tr.effects) {
|
|
1405
|
+
if (effect.is(updateEffect)) {
|
|
1406
|
+
const { visible, line, side } = effect.value;
|
|
1407
|
+
if (!visible) {
|
|
1408
|
+
return {
|
|
1409
|
+
position: newValue.position,
|
|
1410
|
+
side,
|
|
1411
|
+
decorations: import_view9.Decoration.none
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
if (line < 1 || line > tr.startState.doc.lines) {
|
|
1415
|
+
continue;
|
|
1416
|
+
}
|
|
1417
|
+
const docLine = tr.startState.doc.line(line);
|
|
1418
|
+
let decoPos = 0;
|
|
1419
|
+
if (side === "after" /* After */) {
|
|
1420
|
+
decoPos = docLine.to;
|
|
1421
|
+
} else {
|
|
1422
|
+
decoPos = docLine.from;
|
|
1423
|
+
}
|
|
1424
|
+
return {
|
|
1425
|
+
position: decoPos,
|
|
1426
|
+
side,
|
|
1427
|
+
decorations: import_view9.Decoration.set([
|
|
1428
|
+
import_view9.Decoration.widget({
|
|
1429
|
+
widget: new DOMWidget({
|
|
1430
|
+
dom: domRef.current
|
|
1431
|
+
}),
|
|
1432
|
+
block: true,
|
|
1433
|
+
side: newValue.side === "after" /* After */ ? 1 : -1
|
|
1434
|
+
}).range(decoPos)
|
|
1435
|
+
])
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
return newValue;
|
|
1440
|
+
},
|
|
1441
|
+
provide(f) {
|
|
1442
|
+
return import_view9.EditorView.decorations.compute(
|
|
1443
|
+
[f],
|
|
1444
|
+
(state) => state.field(f).decorations
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
return injector.inject([field]);
|
|
1449
|
+
}, []);
|
|
1450
|
+
return (0, import_react_dom6.createPortal)(children, dom);
|
|
1451
|
+
});
|
|
1452
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1453
|
+
0 && (module.exports = {
|
|
1454
|
+
ActiveLinePlaceholder,
|
|
1455
|
+
CursorInlayHint,
|
|
1456
|
+
CursorMirror,
|
|
1457
|
+
DiagnosticMarkers,
|
|
1458
|
+
DiffView,
|
|
1459
|
+
EmbededLineView,
|
|
1460
|
+
EmbededLineViewSide,
|
|
1461
|
+
FoldGutter,
|
|
1462
|
+
Gutter,
|
|
1463
|
+
GutterLineMarker,
|
|
1464
|
+
GutterPlacement,
|
|
1465
|
+
LineWidget,
|
|
1466
|
+
Markers,
|
|
1467
|
+
Mention,
|
|
1468
|
+
Placeholder,
|
|
1469
|
+
PositionMirror,
|
|
1470
|
+
RefElement,
|
|
1471
|
+
SelectionSide,
|
|
1472
|
+
getCurrentMentionReplaceRange
|
|
1473
|
+
});
|
|
1474
|
+
//# sourceMappingURL=index.js.map
|