@ant-design/agentic-ui 2.29.10 → 2.29.11
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.
|
@@ -93,21 +93,11 @@ import { MessagesContext } from "./BubbleContext";
|
|
|
93
93
|
* ```
|
|
94
94
|
*/ export var MarkdownPreview = function(props) {
|
|
95
95
|
var _props_originData;
|
|
96
|
-
var content = props.content, extra = props.extra, typing = props.typing, htmlRef = props.htmlRef, fncProps = props.fncProps, docListNode = props.docListNode,
|
|
96
|
+
var content = props.content, extra = props.extra, typing = props.typing, htmlRef = props.htmlRef, fncProps = props.fncProps, docListNode = props.docListNode, beforeContent = props.beforeContent, afterContent = props.afterContent;
|
|
97
97
|
var MarkdownEditorRef = React.useRef(undefined);
|
|
98
98
|
var hidePadding = (useContext(MessagesContext) || {}).hidePadding;
|
|
99
99
|
var _ref = useContext(BubbleConfigContext) || {}, locale = _ref.locale, standalone = _ref.standalone;
|
|
100
100
|
var token = theme.useToken().token;
|
|
101
|
-
useEffect(function() {
|
|
102
|
-
if (isFinished) {
|
|
103
|
-
var _MarkdownEditorRef_current;
|
|
104
|
-
console.log('content', content);
|
|
105
|
-
(_MarkdownEditorRef_current = MarkdownEditorRef.current) === null || _MarkdownEditorRef_current === void 0 ? void 0 : _MarkdownEditorRef_current.store.setContent(parserMdToSchema(content).schema);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
}, [
|
|
109
|
-
isFinished
|
|
110
|
-
]);
|
|
111
101
|
var isPaddingHidden = useMemo(function() {
|
|
112
102
|
return !!extra;
|
|
113
103
|
}, [
|
|
@@ -116,7 +106,6 @@ import { MessagesContext } from "./BubbleContext";
|
|
|
116
106
|
]);
|
|
117
107
|
useEffect(function() {
|
|
118
108
|
var _MarkdownEditorRef_current;
|
|
119
|
-
console.log("updatecontent", content);
|
|
120
109
|
var schema = parserMdToSchema(content).schema;
|
|
121
110
|
(_MarkdownEditorRef_current = MarkdownEditorRef.current) === null || _MarkdownEditorRef_current === void 0 ? void 0 : _MarkdownEditorRef_current.store.updateNodeList(schema);
|
|
122
111
|
}, [
|
|
@@ -84,7 +84,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
84
84
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
85
85
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
86
86
|
}
|
|
87
|
-
import { Editor, Element, Node, Path, Range, Transforms } from "slate";
|
|
87
|
+
import { Editor, Element, Node, Path, Point, Range, Text, Transforms } from "slate";
|
|
88
88
|
import { NativeTableEditor } from "../../utils/native-table";
|
|
89
89
|
import { getListType, isListType } from "../plugins/withListsPlugin";
|
|
90
90
|
import { EditorUtils } from "./editorUtils";
|
|
@@ -273,21 +273,249 @@ import { EditorUtils } from "./editorUtils";
|
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* 查找选区内的块级节点
|
|
278
|
+
*
|
|
279
|
+
* @param editor - 编辑器实例
|
|
280
|
+
* @param selection - 当前选区
|
|
281
|
+
* @returns 找到的块级节点数组,每个元素包含 [node, path]
|
|
282
|
+
*/ function findBlockNodesInSelection(editor, selection) {
|
|
283
|
+
if (!selection) {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
var blockNodes = Array.from(Editor.nodes(editor, {
|
|
287
|
+
at: selection,
|
|
288
|
+
match: function(n) {
|
|
289
|
+
return Element.isElement(n) && !Editor.isInline(editor, n) && [
|
|
290
|
+
'paragraph',
|
|
291
|
+
'head'
|
|
292
|
+
].includes(n.type);
|
|
293
|
+
}
|
|
294
|
+
}));
|
|
295
|
+
return blockNodes;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* 处理选区并设置标题格式
|
|
299
|
+
*
|
|
300
|
+
* @param editor - 编辑器实例
|
|
301
|
+
* @param selection - 选区范围
|
|
302
|
+
* @param level - 标题级别(1-3)
|
|
303
|
+
*/ function processSelectionForHeading(editor, selection, level) {
|
|
304
|
+
var _Range_edges = _sliced_to_array(Range.edges(selection), 2), selStart = _Range_edges[0], selEnd = _Range_edges[1];
|
|
305
|
+
// 找到所有涉及选中文本的段落/标题节点
|
|
306
|
+
var blockNodes = findBlockNodesInSelection(editor, selection);
|
|
307
|
+
if (blockNodes.length === 0) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// 使用 withoutNormalizing 确保原子性操作
|
|
311
|
+
Editor.withoutNormalizing(editor, function() {
|
|
312
|
+
// 按路径倒序处理,从后往前,避免路径变化影响
|
|
313
|
+
var sortedNodes = _to_consumable_array(blockNodes).sort(function(a, b) {
|
|
314
|
+
return Path.compare(b[1], a[1]);
|
|
315
|
+
});
|
|
316
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
317
|
+
try {
|
|
318
|
+
for(var _iterator = sortedNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
319
|
+
var _step_value = _sliced_to_array(_step.value, 2), path = _step_value[1];
|
|
320
|
+
if (!Editor.hasPath(editor, path)) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
var nodeStart = Editor.start(editor, path);
|
|
324
|
+
var nodeEnd = Editor.end(editor, path);
|
|
325
|
+
// 计算节点内的实际选区范围
|
|
326
|
+
var actualStart = Point.isBefore(selStart, nodeStart) ? nodeStart : Point.isAfter(selStart, nodeEnd) ? nodeEnd : selStart;
|
|
327
|
+
var actualEnd = Point.isAfter(selEnd, nodeEnd) ? nodeEnd : Point.isBefore(selEnd, nodeStart) ? nodeStart : selEnd;
|
|
328
|
+
// 检查是否选中了整个节点
|
|
329
|
+
var isWholeNodeSelected = (Point.isBefore(selStart, nodeStart) || Point.equals(selStart, nodeStart)) && (Point.isAfter(selEnd, nodeEnd) || Point.equals(selEnd, nodeEnd));
|
|
330
|
+
if (isWholeNodeSelected) {
|
|
331
|
+
// 直接转换整个节点
|
|
332
|
+
Transforms.setNodes(editor, {
|
|
333
|
+
type: 'head',
|
|
334
|
+
level: level
|
|
335
|
+
}, {
|
|
336
|
+
at: path
|
|
337
|
+
});
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
// 如果选区不在节点内,跳过
|
|
341
|
+
if (Point.isAfter(actualStart, actualEnd) || Point.equals(actualStart, actualEnd) || Point.isBefore(actualStart, nodeStart) || Point.isAfter(actualEnd, nodeEnd)) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
// 情况1: 选中了整个节点(从开始到结束)
|
|
345
|
+
if (Point.equals(actualStart, nodeStart) && Point.equals(actualEnd, nodeEnd)) {
|
|
346
|
+
Transforms.setNodes(editor, {
|
|
347
|
+
type: 'head',
|
|
348
|
+
level: level
|
|
349
|
+
}, {
|
|
350
|
+
at: path
|
|
351
|
+
});
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
// 情况2: 只选中了节点的一部分,需要拆分
|
|
355
|
+
var isAtStart = Point.equals(actualStart, nodeStart);
|
|
356
|
+
var isAtEnd = Point.equals(actualEnd, nodeEnd);
|
|
357
|
+
if (isAtStart && isAtEnd) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
// 获取原节点的属性
|
|
361
|
+
var originalNode = Node.get(editor, path);
|
|
362
|
+
if (!Element.isElement(originalNode)) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (isAtStart) {
|
|
366
|
+
// 选中在开始位置:拆分成两个节点(选中部分 + 剩余部分)
|
|
367
|
+
// 在 actualEnd 位置拆分节点
|
|
368
|
+
Transforms.splitNodes(editor, {
|
|
369
|
+
at: actualEnd
|
|
370
|
+
});
|
|
371
|
+
// 拆分后,原节点包含选中部分,新节点包含剩余部分
|
|
372
|
+
// 将原节点(选中部分)转换为标题
|
|
373
|
+
Transforms.setNodes(editor, {
|
|
374
|
+
type: 'head',
|
|
375
|
+
level: level
|
|
376
|
+
}, {
|
|
377
|
+
at: path
|
|
378
|
+
});
|
|
379
|
+
} else if (isAtEnd) {
|
|
380
|
+
// 选中在结束位置:拆分成两个节点(前面部分 + 选中部分)
|
|
381
|
+
// 在 actualStart 位置拆分节点
|
|
382
|
+
Transforms.splitNodes(editor, {
|
|
383
|
+
at: actualStart
|
|
384
|
+
});
|
|
385
|
+
// 拆分后,原节点包含前面部分,新节点包含选中部分
|
|
386
|
+
// 将新节点(选中部分)转换为标题
|
|
387
|
+
var nextPath = Path.next(path);
|
|
388
|
+
if (Editor.hasPath(editor, nextPath)) {
|
|
389
|
+
Transforms.setNodes(editor, {
|
|
390
|
+
type: 'head',
|
|
391
|
+
level: level
|
|
392
|
+
}, {
|
|
393
|
+
at: nextPath
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
} else {
|
|
397
|
+
// 选中在中间位置:拆分成三个节点(前面部分 + 选中部分 + 后面部分)
|
|
398
|
+
// 计算选中部分的长度(字符偏移量)
|
|
399
|
+
var selectionOffset = actualEnd.offset - actualStart.offset;
|
|
400
|
+
// 第一步:在 actualStart 位置拆分节点
|
|
401
|
+
Transforms.splitNodes(editor, {
|
|
402
|
+
at: actualStart
|
|
403
|
+
});
|
|
404
|
+
// 拆分后,原节点包含前面部分,新节点包含选中部分和后面部分
|
|
405
|
+
// 新节点的路径是 Path.next(path)
|
|
406
|
+
var middlePath = Path.next(path);
|
|
407
|
+
if (!Editor.hasPath(editor, middlePath)) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
// 第二步:在新节点内计算拆分点
|
|
411
|
+
// 使用偏移量来计算:在新节点开始位置 + 选中部分的长度
|
|
412
|
+
// 需要找到对应的文本节点和偏移量
|
|
413
|
+
var splitPoint = null;
|
|
414
|
+
// 遍历新节点内的文本节点,计算正确的拆分点
|
|
415
|
+
var textNodes = Array.from(Editor.nodes(editor, {
|
|
416
|
+
at: middlePath,
|
|
417
|
+
match: function(n) {
|
|
418
|
+
return Text.isText(n);
|
|
419
|
+
}
|
|
420
|
+
}));
|
|
421
|
+
var currentOffset = 0;
|
|
422
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
423
|
+
try {
|
|
424
|
+
for(var _iterator1 = textNodes[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
425
|
+
var _step_value1 = _sliced_to_array(_step1.value, 2), textNode = _step_value1[0], textPath = _step_value1[1];
|
|
426
|
+
if (!Text.isText(textNode)) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
var text = textNode.text;
|
|
430
|
+
if (typeof text !== 'string') {
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
var textLength = text.length;
|
|
434
|
+
var nextOffset = currentOffset + textLength;
|
|
435
|
+
// 如果选中结束位置在这个文本节点内
|
|
436
|
+
if (selectionOffset <= nextOffset) {
|
|
437
|
+
var offsetInText = selectionOffset - currentOffset;
|
|
438
|
+
splitPoint = {
|
|
439
|
+
path: textPath,
|
|
440
|
+
offset: offsetInText
|
|
441
|
+
};
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
currentOffset = nextOffset;
|
|
445
|
+
}
|
|
446
|
+
} catch (err) {
|
|
447
|
+
_didIteratorError1 = true;
|
|
448
|
+
_iteratorError1 = err;
|
|
449
|
+
} finally{
|
|
450
|
+
try {
|
|
451
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
452
|
+
_iterator1.return();
|
|
453
|
+
}
|
|
454
|
+
} finally{
|
|
455
|
+
if (_didIteratorError1) {
|
|
456
|
+
throw _iteratorError1;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
// 如果找不到拆分点,使用新节点的结束位置
|
|
461
|
+
if (!splitPoint) {
|
|
462
|
+
var middleNodeEnd = Editor.end(editor, middlePath);
|
|
463
|
+
splitPoint = middleNodeEnd;
|
|
464
|
+
}
|
|
465
|
+
// 在新节点内的 splitPoint 位置拆分
|
|
466
|
+
Transforms.splitNodes(editor, {
|
|
467
|
+
at: splitPoint
|
|
468
|
+
});
|
|
469
|
+
// 拆分后,middlePath 包含选中部分,下一个节点包含后面部分
|
|
470
|
+
// 将 middlePath(选中部分)转换为标题
|
|
471
|
+
Transforms.setNodes(editor, {
|
|
472
|
+
type: 'head',
|
|
473
|
+
level: level
|
|
474
|
+
}, {
|
|
475
|
+
at: middlePath
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
} catch (err) {
|
|
480
|
+
_didIteratorError = true;
|
|
481
|
+
_iteratorError = err;
|
|
482
|
+
} finally{
|
|
483
|
+
try {
|
|
484
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
485
|
+
_iterator.return();
|
|
486
|
+
}
|
|
487
|
+
} finally{
|
|
488
|
+
if (_didIteratorError) {
|
|
489
|
+
throw _iteratorError;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
276
495
|
/**
|
|
277
496
|
* 设置标题级别
|
|
278
497
|
*
|
|
279
498
|
* 将当前段落或标题节点转换为指定级别的标题。
|
|
280
499
|
* 如果级别为4,则转换为普通段落。
|
|
500
|
+
* 如果存在选中文本,则只将选中的部分转换为标题,并拆分段落。
|
|
281
501
|
*
|
|
282
502
|
* @param editor Slate 编辑器实例
|
|
283
503
|
* @param level 标题级别(1-3)或4(表示普通段落)
|
|
284
504
|
*/ export function setHeading(editor, level) {
|
|
285
505
|
var _node_;
|
|
286
|
-
var
|
|
506
|
+
var selection = editor.selection;
|
|
507
|
+
// 如果级别为4,转换为段落
|
|
287
508
|
if (level === 4) {
|
|
288
509
|
convertToParagraph(editor);
|
|
289
510
|
return;
|
|
290
511
|
}
|
|
512
|
+
// 如果有非折叠的选区,处理选中文本
|
|
513
|
+
if (selection && !Range.isCollapsed(selection)) {
|
|
514
|
+
processSelectionForHeading(editor, selection, level);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
// 如果没有选区,保持原有行为:转换整个节点
|
|
518
|
+
var _getCurrentNodes = _sliced_to_array(getCurrentNodes(editor), 1), node = _getCurrentNodes[0];
|
|
291
519
|
if (node && [
|
|
292
520
|
'paragraph',
|
|
293
521
|
'head'
|
|
@@ -301,27 +529,6 @@ import { EditorUtils } from "./editorUtils";
|
|
|
301
529
|
}
|
|
302
530
|
}
|
|
303
531
|
export { convertToParagraph };
|
|
304
|
-
/**
|
|
305
|
-
* 查找选区内的块级节点
|
|
306
|
-
*
|
|
307
|
-
* @param editor - 编辑器实例
|
|
308
|
-
* @param selection - 当前选区
|
|
309
|
-
* @returns 找到的块级节点数组,每个元素包含 [node, path]
|
|
310
|
-
*/ function findBlockNodesInSelection(editor, selection) {
|
|
311
|
-
if (!selection) {
|
|
312
|
-
return [];
|
|
313
|
-
}
|
|
314
|
-
var blockNodes = Array.from(Editor.nodes(editor, {
|
|
315
|
-
at: selection,
|
|
316
|
-
match: function(n) {
|
|
317
|
-
return Element.isElement(n) && !Editor.isInline(editor, n) && [
|
|
318
|
-
'paragraph',
|
|
319
|
-
'head'
|
|
320
|
-
].includes(n.type);
|
|
321
|
-
}
|
|
322
|
-
}));
|
|
323
|
-
return blockNodes;
|
|
324
|
-
}
|
|
325
532
|
/**
|
|
326
533
|
* 将标题节点转换为段落节点
|
|
327
534
|
*
|