@ant-design/agentic-ui 2.21.0 → 2.22.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.
Files changed (28) hide show
  1. package/dist/MarkdownEditor/editor/elements/TagPopup/index.js +4 -4
  2. package/dist/MarkdownEditor/editor/elements/TagPopup/style.js +14 -12
  3. package/dist/MarkdownEditor/editor/parser/parse/applyContextPropsAndConfig.d.ts +8 -0
  4. package/dist/MarkdownEditor/editor/parser/parse/applyContextPropsAndConfig.js +58 -0
  5. package/dist/MarkdownEditor/editor/parser/parse/parseBlockElements.d.ts +67 -0
  6. package/dist/MarkdownEditor/editor/parser/parse/parseBlockElements.js +289 -0
  7. package/dist/MarkdownEditor/editor/parser/parse/parseElements.d.ts +27 -0
  8. package/dist/MarkdownEditor/editor/parser/parse/parseElements.js +83 -0
  9. package/dist/MarkdownEditor/editor/parser/parse/parseEmptyLines.d.ts +9 -0
  10. package/dist/MarkdownEditor/editor/parser/parse/parseEmptyLines.js +60 -0
  11. package/dist/MarkdownEditor/editor/parser/parse/parseFootnote.d.ts +10 -0
  12. package/dist/MarkdownEditor/editor/parser/parse/parseFootnote.js +12 -0
  13. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.d.ts +63 -0
  14. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.js +759 -0
  15. package/dist/MarkdownEditor/editor/parser/parse/parseMath.d.ts +24 -0
  16. package/dist/MarkdownEditor/editor/parser/parse/parseMath.js +58 -0
  17. package/dist/MarkdownEditor/editor/parser/parse/parseMedia.d.ts +27 -0
  18. package/dist/MarkdownEditor/editor/parser/parse/parseMedia.js +127 -0
  19. package/dist/MarkdownEditor/editor/parser/parse/parseTable.js +36 -3
  20. package/dist/MarkdownEditor/editor/parser/parse/parseText.d.ts +26 -0
  21. package/dist/MarkdownEditor/editor/parser/parse/parseText.js +304 -0
  22. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.d.ts +3 -40
  23. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +128 -1855
  24. package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +131 -18
  25. package/dist/MarkdownEditor/editor/parser/remarkParse.js +24 -17
  26. package/dist/MarkdownEditor/editor/plugins/elements.js +1 -1
  27. package/dist/Plugins/code/components/CodeToolbar.js +3 -16
  28. package/package.json +1 -1
@@ -0,0 +1,759 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _array_without_holes(arr) {
10
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
11
+ }
12
+ function _define_property(obj, key, value) {
13
+ if (key in obj) {
14
+ Object.defineProperty(obj, key, {
15
+ value: value,
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true
19
+ });
20
+ } else {
21
+ obj[key] = value;
22
+ }
23
+ return obj;
24
+ }
25
+ function _iterable_to_array(iter) {
26
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
27
+ }
28
+ function _iterable_to_array_limit(arr, i) {
29
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
30
+ if (_i == null) return;
31
+ var _arr = [];
32
+ var _n = true;
33
+ var _d = false;
34
+ var _s, _e;
35
+ try {
36
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
37
+ _arr.push(_s.value);
38
+ if (i && _arr.length === i) break;
39
+ }
40
+ } catch (err) {
41
+ _d = true;
42
+ _e = err;
43
+ } finally{
44
+ try {
45
+ if (!_n && _i["return"] != null) _i["return"]();
46
+ } finally{
47
+ if (_d) throw _e;
48
+ }
49
+ }
50
+ return _arr;
51
+ }
52
+ function _non_iterable_rest() {
53
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
54
+ }
55
+ function _non_iterable_spread() {
56
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
57
+ }
58
+ function _object_spread(target) {
59
+ for(var i = 1; i < arguments.length; i++){
60
+ var source = arguments[i] != null ? arguments[i] : {};
61
+ var ownKeys = Object.keys(source);
62
+ if (typeof Object.getOwnPropertySymbols === "function") {
63
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
64
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
65
+ }));
66
+ }
67
+ ownKeys.forEach(function(key) {
68
+ _define_property(target, key, source[key]);
69
+ });
70
+ }
71
+ return target;
72
+ }
73
+ function ownKeys(object, enumerableOnly) {
74
+ var keys = Object.keys(object);
75
+ if (Object.getOwnPropertySymbols) {
76
+ var symbols = Object.getOwnPropertySymbols(object);
77
+ if (enumerableOnly) {
78
+ symbols = symbols.filter(function(sym) {
79
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
80
+ });
81
+ }
82
+ keys.push.apply(keys, symbols);
83
+ }
84
+ return keys;
85
+ }
86
+ function _object_spread_props(target, source) {
87
+ source = source != null ? source : {};
88
+ if (Object.getOwnPropertyDescriptors) {
89
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
90
+ } else {
91
+ ownKeys(Object(source)).forEach(function(key) {
92
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
93
+ });
94
+ }
95
+ return target;
96
+ }
97
+ function _sliced_to_array(arr, i) {
98
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
99
+ }
100
+ function _to_consumable_array(arr) {
101
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
102
+ }
103
+ function _unsupported_iterable_to_array(o, minLen) {
104
+ if (!o) return;
105
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
106
+ var n = Object.prototype.toString.call(o).slice(8, -1);
107
+ if (n === "Object" && o.constructor) n = o.constructor.name;
108
+ if (n === "Map" || n === "Set") return Array.from(n);
109
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
110
+ }
111
+ import json5 from "json5";
112
+ import { htmlToFragmentList } from "../../plugins/insertParsedHtmlNodes";
113
+ import { EditorUtils } from "../../utils";
114
+ import partialJsonParse from "../json-parse";
115
+ /**
116
+ * 解码 URI 组件,处理错误情况
117
+ */ export var decodeURIComponentUrl = function(url) {
118
+ try {
119
+ return decodeURIComponent(url);
120
+ } catch (e) {
121
+ console.error('Failed to decode URI component:', e);
122
+ return url;
123
+ }
124
+ };
125
+ /**
126
+ * 检测和解析 think 标签
127
+ * @param str - 要检测的字符串
128
+ * @returns think 标签的内容,如果不是 think 标签则返回 null
129
+ */ var findThinkElement = function(str) {
130
+ try {
131
+ // 匹配 <think>内容</think> 格式
132
+ var thinkMatch = str.match(/^\s*<think>([\s\S]*?)<\/think>\s*$/);
133
+ if (thinkMatch) {
134
+ return {
135
+ content: thinkMatch[1].trim()
136
+ };
137
+ }
138
+ return null;
139
+ } catch (e) {
140
+ return null;
141
+ }
142
+ };
143
+ /**
144
+ * 检测和解析 answer 标签
145
+ * @param str - 要检测的字符串
146
+ * @returns answer 标签的内容,如果不是 answer 标签则返回 null
147
+ */ var findAnswerElement = function(str) {
148
+ try {
149
+ // 匹配 <answer>内容</answer> 格式
150
+ var answerMatch = str.match(/^\s*<answer>([\s\S]*?)<\/answer>\s*$/);
151
+ if (answerMatch) {
152
+ return {
153
+ content: answerMatch[1].trim()
154
+ };
155
+ }
156
+ return null;
157
+ } catch (e) {
158
+ return null;
159
+ }
160
+ };
161
+ /**
162
+ * 从 HTML 字符串中提取媒体元素属性
163
+ */ var extractMediaAttributes = function(str) {
164
+ var _str_match, _str_match1, _str_match2, _str_match3, _str_match4;
165
+ return {
166
+ height: (_str_match = str.match(/height="(\d+)"/)) === null || _str_match === void 0 ? void 0 : _str_match[1],
167
+ width: (_str_match1 = str.match(/width="(\d+)"/)) === null || _str_match1 === void 0 ? void 0 : _str_match1[1],
168
+ align: (_str_match2 = str.match(/data-align="(\w+)"/)) === null || _str_match2 === void 0 ? void 0 : _str_match2[1],
169
+ alt: (_str_match3 = str.match(/alt="([^"\n]+)"/)) === null || _str_match3 === void 0 ? void 0 : _str_match3[1],
170
+ controls: str.match(/controls/),
171
+ autoplay: str.match(/autoplay/),
172
+ loop: str.match(/loop/),
173
+ muted: str.match(/muted/),
174
+ poster: (_str_match4 = str.match(/poster="([^"\n]+)"/)) === null || _str_match4 === void 0 ? void 0 : _str_match4[1]
175
+ };
176
+ };
177
+ /**
178
+ * 构建媒体元素对象
179
+ */ var buildMediaElement = function(url, tagName, attrs) {
180
+ var result = {
181
+ url: url,
182
+ align: attrs.align,
183
+ alt: attrs.alt,
184
+ tagName: tagName,
185
+ controls: !!attrs.controls,
186
+ autoplay: !!attrs.autoplay,
187
+ loop: !!attrs.loop,
188
+ muted: !!attrs.muted,
189
+ poster: attrs.poster
190
+ };
191
+ // 只有当值存在时才设置,避免类型错误
192
+ if (attrs.height) {
193
+ result.height = +attrs.height;
194
+ }
195
+ if (attrs.width) {
196
+ result.width = +attrs.width;
197
+ }
198
+ return result;
199
+ };
200
+ /**
201
+ * 从字符串中提取视频源 URL
202
+ */ var extractVideoSource = function(str, tagName) {
203
+ // 首先尝试从标签本身获取 src 属性
204
+ var url = str.match(/src="([^"\n]+)"/);
205
+ // 如果是 video 标签且没有找到 src,尝试从 source 标签中获取
206
+ if (tagName === 'video' && !url) {
207
+ var sourceMatch = str.match(/<source[^>]*src="([^"\n]+)"[^>]*>/);
208
+ if (sourceMatch) {
209
+ url = sourceMatch;
210
+ }
211
+ }
212
+ return url === null || url === void 0 ? void 0 : url[1];
213
+ };
214
+ /**
215
+ * 查找并解析媒体元素(img/video/iframe)
216
+ */ export var findImageElement = function(str) {
217
+ try {
218
+ // 首先尝试匹配包含 source 标签的 video 格式
219
+ var videoWithSourceMatch = str.match(/^\s*<video[^>\n]*>[\s\S]*?<source[^>]*src="([^"\n]+)"[^>]*>[\s\S]*?<\/video>\s*$/);
220
+ if (videoWithSourceMatch) {
221
+ var attrs = extractMediaAttributes(str);
222
+ return buildMediaElement(videoWithSourceMatch[1], 'video', attrs);
223
+ }
224
+ // 尝试匹配各种媒体标签格式
225
+ var patterns = [
226
+ /^\s*<(img|video|iframe)[^>\n]*>.*?<\/(?:img|video|iframe)>\s*$/,
227
+ /^\s*<(img|video|iframe)[^>\n]*\/?>(.*<\/(?:img|video|iframe)>)?\s*$/,
228
+ /^\s*<(img|video|iframe)[^>\n]*\/>\s*$/,
229
+ /^\s*<(img|video|iframe)[^>\n]*>\s*$/
230
+ ];
231
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
232
+ try {
233
+ for(var _iterator = patterns[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
234
+ var pattern = _step.value;
235
+ var match = str.match(pattern);
236
+ if (match) {
237
+ var _match__match;
238
+ var tagName = (_match__match = match[0].match(/<(img|video|iframe)/)) === null || _match__match === void 0 ? void 0 : _match__match[1];
239
+ var url = extractVideoSource(match[0], tagName);
240
+ var attrs1 = extractMediaAttributes(match[0]);
241
+ return buildMediaElement(url, tagName, attrs1);
242
+ }
243
+ }
244
+ } catch (err) {
245
+ _didIteratorError = true;
246
+ _iteratorError = err;
247
+ } finally{
248
+ try {
249
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
250
+ _iterator.return();
251
+ }
252
+ } finally{
253
+ if (_didIteratorError) {
254
+ throw _iteratorError;
255
+ }
256
+ }
257
+ }
258
+ return null;
259
+ } catch (e) {
260
+ console.error('Failed to parse media element:', e);
261
+ return null;
262
+ }
263
+ };
264
+ /**
265
+ * 根据媒体元素信息创建编辑器节点
266
+ */ export var createMediaNodeFromElement = function(mediaElement) {
267
+ if (!mediaElement) return null;
268
+ // 根据标签类型确定媒体类型
269
+ var mediaTypeMap = {
270
+ video: 'video',
271
+ iframe: 'iframe',
272
+ img: 'image'
273
+ };
274
+ var mediaType = mediaTypeMap[mediaElement.tagName] || 'image';
275
+ return EditorUtils.createMediaNode(decodeURIComponentUrl(mediaElement.url || ''), mediaType, {
276
+ align: mediaElement.align,
277
+ alt: mediaElement.alt,
278
+ height: mediaElement.height,
279
+ width: mediaElement.width,
280
+ controls: mediaElement.controls,
281
+ autoplay: mediaElement.autoplay,
282
+ loop: mediaElement.loop,
283
+ muted: mediaElement.muted,
284
+ poster: mediaElement.poster
285
+ });
286
+ };
287
+ /**
288
+ * 标准 HTML 元素列表
289
+ * 这些标签会被正常解析为 HTML,其他标签会被当作普通文本处理
290
+ */ export var STANDARD_HTML_ELEMENTS = new Set([
291
+ // 文档结构
292
+ 'html',
293
+ 'head',
294
+ 'body',
295
+ 'title',
296
+ 'meta',
297
+ 'link',
298
+ 'style',
299
+ 'script',
300
+ // 内容分区
301
+ 'header',
302
+ 'nav',
303
+ 'main',
304
+ 'section',
305
+ 'article',
306
+ 'aside',
307
+ 'footer',
308
+ 'h1',
309
+ 'h2',
310
+ 'h3',
311
+ 'h4',
312
+ 'h5',
313
+ 'h6',
314
+ // 文本内容
315
+ 'div',
316
+ 'p',
317
+ 'hr',
318
+ 'pre',
319
+ 'blockquote',
320
+ // 列表
321
+ 'ul',
322
+ 'ol',
323
+ 'li',
324
+ 'dl',
325
+ 'dt',
326
+ 'dd',
327
+ // 表格
328
+ 'table',
329
+ 'thead',
330
+ 'tbody',
331
+ 'tfoot',
332
+ 'tr',
333
+ 'th',
334
+ 'td',
335
+ 'caption',
336
+ 'colgroup',
337
+ 'col',
338
+ // 表单
339
+ 'form',
340
+ 'input',
341
+ 'textarea',
342
+ 'button',
343
+ 'select',
344
+ 'option',
345
+ 'label',
346
+ 'fieldset',
347
+ 'legend',
348
+ // 内联文本语义
349
+ 'a',
350
+ 'em',
351
+ 'strong',
352
+ 'small',
353
+ 'mark',
354
+ 'del',
355
+ 'ins',
356
+ 'sub',
357
+ 'sup',
358
+ 'i',
359
+ 'b',
360
+ 'u',
361
+ 's',
362
+ 'code',
363
+ 'kbd',
364
+ 'samp',
365
+ 'var',
366
+ 'span',
367
+ 'br',
368
+ 'wbr',
369
+ // 图片和多媒体
370
+ 'img',
371
+ 'video',
372
+ 'audio',
373
+ 'source',
374
+ 'track',
375
+ 'iframe',
376
+ 'embed',
377
+ 'object',
378
+ 'param',
379
+ 'picture',
380
+ // 其他
381
+ 'canvas',
382
+ 'svg',
383
+ 'math',
384
+ 'details',
385
+ 'summary',
386
+ 'dialog',
387
+ 'menu',
388
+ 'menuitem',
389
+ // 字体
390
+ 'font'
391
+ ]);
392
+ /**
393
+ * 检查 HTML 标签是否为标准元素
394
+ * @param htmlString - HTML 字符串
395
+ * @returns 是否为标准 HTML 元素
396
+ */ export function isStandardHtmlElement(htmlString) {
397
+ // 提取标签名(支持开始标签和结束标签)
398
+ var tagMatch = htmlString.match(/<\/?(\w+)/);
399
+ if (!tagMatch) return false;
400
+ var tagName = tagMatch[1].toLowerCase();
401
+ return STANDARD_HTML_ELEMENTS.has(tagName);
402
+ }
403
+ /**
404
+ * 解析 HTML 注释中的上下文属性
405
+ */ var parseCommentContextProps = function(value, processedValue) {
406
+ var _processedValue_trim, _processedValue_trim1;
407
+ var isComment = value && (processedValue === null || processedValue === void 0 ? void 0 : (_processedValue_trim = processedValue.trim()) === null || _processedValue_trim === void 0 ? void 0 : _processedValue_trim.endsWith('-->')) && ((_processedValue_trim1 = processedValue.trim()) === null || _processedValue_trim1 === void 0 ? void 0 : _processedValue_trim1.startsWith('<!--'));
408
+ if (!isComment) {
409
+ return {};
410
+ }
411
+ try {
412
+ return json5.parse(value);
413
+ } catch (e) {
414
+ try {
415
+ return partialJsonParse(value);
416
+ } catch (parseError) {
417
+ console.warn('Failed to parse HTML comment as JSON or partial JSON:', {
418
+ value: value,
419
+ error: parseError
420
+ });
421
+ }
422
+ console.warn('HTML comment parse fallback attempted:', e);
423
+ }
424
+ return {};
425
+ };
426
+ /**
427
+ * 处理块级 HTML 元素
428
+ */ var handleBlockHtml = function(currentElement, processedValue, isUnclosedComment) {
429
+ var thinkElement = findThinkElement(currentElement.value);
430
+ if (thinkElement) {
431
+ return {
432
+ type: 'code',
433
+ language: 'think',
434
+ value: thinkElement.content,
435
+ children: [
436
+ {
437
+ text: thinkElement.content
438
+ }
439
+ ]
440
+ };
441
+ }
442
+ var answerElement = findAnswerElement(currentElement.value);
443
+ if (answerElement) {
444
+ return {
445
+ text: answerElement.content
446
+ };
447
+ }
448
+ var mediaElement = findImageElement(currentElement.value);
449
+ if (mediaElement) {
450
+ return createMediaNodeFromElement(mediaElement);
451
+ }
452
+ if (currentElement.value === '<br/>') {
453
+ return {
454
+ type: 'paragraph',
455
+ children: [
456
+ {
457
+ text: ''
458
+ }
459
+ ]
460
+ };
461
+ }
462
+ if (currentElement.value.match(/^<\/(img|video|iframe)>/)) {
463
+ return null;
464
+ }
465
+ var commentValue = isUnclosedComment ? processedValue : currentElement.value;
466
+ var isComment = commentValue.trim().startsWith('<!--') && commentValue.trim().endsWith('-->');
467
+ if (isComment || isStandardHtmlElement(commentValue)) {
468
+ return commentValue.match(/<\/?(table|div|ul|li|ol|p|strong)[^\n>]*?>/) ? htmlToFragmentList(commentValue, '') : {
469
+ type: 'code',
470
+ language: 'html',
471
+ render: true,
472
+ value: commentValue,
473
+ children: [
474
+ {
475
+ text: commentValue
476
+ }
477
+ ]
478
+ };
479
+ }
480
+ return {
481
+ text: currentElement.value
482
+ };
483
+ };
484
+ /**
485
+ * 应用元素配置属性(纯函数版本)
486
+ */ var applyElementConfig = function(el, contextProps, processedValue, isUnclosedComment, currentElement) {
487
+ var _valueToCheck_trim;
488
+ if (!el || Array.isArray(el)) {
489
+ return el;
490
+ }
491
+ var isPlainText = 'text' in el && Object.keys(el).length === 1;
492
+ if (isPlainText) {
493
+ return el;
494
+ }
495
+ var valueToCheck = isUnclosedComment ? processedValue : currentElement === null || currentElement === void 0 ? void 0 : currentElement.value;
496
+ var otherProps = _object_spread({}, contextProps);
497
+ // 只有当 finished === false 时才设置 finished 属性,否则删除
498
+ if (isUnclosedComment) {
499
+ otherProps.finished = false;
500
+ }
501
+ var result = _object_spread_props(_object_spread({}, el), {
502
+ isConfig: valueToCheck === null || valueToCheck === void 0 ? void 0 : (_valueToCheck_trim = valueToCheck.trim()) === null || _valueToCheck_trim === void 0 ? void 0 : _valueToCheck_trim.startsWith('<!--')
503
+ });
504
+ // 只有当 otherProps 有内容时才设置,避免类型错误
505
+ if (Object.keys(otherProps).length > 0) {
506
+ result.otherProps = otherProps;
507
+ }
508
+ return result;
509
+ };
510
+ /**
511
+ * 处理 span 标签的样式属性(纯函数版本)
512
+ */ var processSpanTag = function(str, tag, htmlTag) {
513
+ try {
514
+ var styles = str.match(/style="([^"\n]+)"/);
515
+ if (!styles) {
516
+ return htmlTag;
517
+ }
518
+ var stylesMap = new Map(styles[1].split(';').map(function(item) {
519
+ return item.split(':').map(function(item) {
520
+ return item.trim();
521
+ });
522
+ }));
523
+ var color = stylesMap.get('color');
524
+ if (color) {
525
+ return _to_consumable_array(htmlTag).concat([
526
+ {
527
+ tag: tag,
528
+ color: color
529
+ }
530
+ ]);
531
+ }
532
+ } catch (e) {
533
+ console.warn('Failed to parse span style attribute:', {
534
+ str: str,
535
+ error: e
536
+ });
537
+ }
538
+ return htmlTag;
539
+ };
540
+ /**
541
+ * 处理 a 标签的链接属性(纯函数版本)
542
+ */ var processATag = function(str, tag, htmlTag) {
543
+ var url = str.match(/href="([\w:./_\-#\\]+)"/);
544
+ if (url) {
545
+ return _to_consumable_array(htmlTag).concat([
546
+ {
547
+ tag: tag,
548
+ url: url[1]
549
+ }
550
+ ]);
551
+ }
552
+ return htmlTag;
553
+ };
554
+ /**
555
+ * 处理 font 标签的颜色属性(纯函数版本)
556
+ */ var processFontTag = function(str, tag, htmlTag) {
557
+ var colorMatch = str.match(/color="([^"\n]+)"/) || str.match(/color=([^"\n]+)/);
558
+ if (colorMatch) {
559
+ return _to_consumable_array(htmlTag).concat([
560
+ {
561
+ tag: tag,
562
+ color: colorMatch[1].replaceAll('>', '')
563
+ }
564
+ ]);
565
+ }
566
+ return htmlTag;
567
+ };
568
+ /**
569
+ * HTML 标签处理器映射表
570
+ */ var htmlTagProcessors = {
571
+ span: processSpanTag,
572
+ a: processATag,
573
+ font: processFontTag
574
+ };
575
+ /**
576
+ * 处理HTML标签并添加到标签栈中(纯函数版本)
577
+ * @param str - HTML标签字符串
578
+ * @param tag - 标签名称
579
+ * @param htmlTag - HTML标签栈
580
+ * @returns 返回新的标签栈数组
581
+ */ var processHtmlTag = function(str, tag, htmlTag) {
582
+ var processor = htmlTagProcessors[tag];
583
+ if (processor) {
584
+ return processor(str, tag, htmlTag);
585
+ }
586
+ return _to_consumable_array(htmlTag).concat([
587
+ {
588
+ tag: tag
589
+ }
590
+ ]);
591
+ };
592
+ /**
593
+ * 处理内联HTML元素(纯函数版本)
594
+ * @param currentElement - 当前处理的HTML元素
595
+ * @param htmlTag - HTML标签栈
596
+ * @returns 返回处理后的元素对象和新的标签栈,如果是标签则返回null
597
+ */ var processInlineHtml = function(currentElement, htmlTag) {
598
+ var value = currentElement.value;
599
+ if (value.match(/<br\/?>/)) {
600
+ return {
601
+ el: {
602
+ type: 'break',
603
+ children: [
604
+ {
605
+ text: '\n'
606
+ }
607
+ ]
608
+ },
609
+ htmlTag: htmlTag
610
+ };
611
+ }
612
+ var answerElement = findAnswerElement(value);
613
+ if (answerElement) {
614
+ return {
615
+ el: {
616
+ text: answerElement.content
617
+ },
618
+ htmlTag: htmlTag
619
+ };
620
+ }
621
+ if (!isStandardHtmlElement(value)) {
622
+ return {
623
+ el: {
624
+ text: value
625
+ },
626
+ htmlTag: htmlTag
627
+ };
628
+ }
629
+ var htmlMatch = value.match(/<\/?(b|i|del|font|code|span|sup|sub|strong|a)[^\n>]*?>/);
630
+ if (htmlMatch) {
631
+ var _htmlMatch = _sliced_to_array(htmlMatch, 2), str = _htmlMatch[0], tag = _htmlMatch[1];
632
+ var isClosingTag = str.startsWith('</');
633
+ var isMatchingTag = isClosingTag && htmlTag.length && htmlTag[htmlTag.length - 1].tag === tag;
634
+ var newHtmlTag = htmlTag;
635
+ if (isMatchingTag) {
636
+ newHtmlTag = htmlTag.slice(0, -1);
637
+ }
638
+ if (!isClosingTag) {
639
+ newHtmlTag = processHtmlTag(str, tag, newHtmlTag);
640
+ }
641
+ return {
642
+ el: null,
643
+ htmlTag: newHtmlTag
644
+ };
645
+ }
646
+ var mediaElement = findImageElement(value);
647
+ return {
648
+ el: mediaElement ? createMediaNodeFromElement(mediaElement) : {
649
+ text: value
650
+ },
651
+ htmlTag: htmlTag
652
+ };
653
+ };
654
+ /**
655
+ * 查找附件链接
656
+ */ export var findAttachment = function(str) {
657
+ try {
658
+ var match = str.match(/^\s*<a[^>\n]*download[^>\n]*\/?>(.*<\/a>:?)?\s*$/);
659
+ if (match) {
660
+ var url = match[0].match(/href="([^"\n]+)"/);
661
+ var size = match[0].match(/data-size="(\d+)"/);
662
+ if (url) {
663
+ return {
664
+ url: url[1],
665
+ size: Number((size === null || size === void 0 ? void 0 : size[1]) || 0)
666
+ };
667
+ }
668
+ }
669
+ return null;
670
+ } catch (e) {
671
+ return null;
672
+ }
673
+ };
674
+ /**
675
+ * 处理HTML节点
676
+ * @param currentElement - 当前处理的HTML元素
677
+ * @param parent - 父级元素,用于判断上下文
678
+ * @param htmlTag - HTML标签栈,用于跟踪嵌套的HTML标签
679
+ * @returns 返回包含解析后元素和上下文属性的对象
680
+ */ export var handleHtml = function(currentElement, parent, htmlTag) {
681
+ var _currentElement_value;
682
+ var trimmedValue = (currentElement === null || currentElement === void 0 ? void 0 : (_currentElement_value = currentElement.value) === null || _currentElement_value === void 0 ? void 0 : _currentElement_value.trim()) || '';
683
+ var isUnclosedComment = trimmedValue.startsWith('<!--') && !trimmedValue.endsWith('-->');
684
+ var processedValue = isUnclosedComment ? trimmedValue + '-->' : (currentElement === null || currentElement === void 0 ? void 0 : currentElement.value) || '';
685
+ var value = (processedValue === null || processedValue === void 0 ? void 0 : processedValue.replace('<!--', '').replace('-->', '').trim()) || '{}';
686
+ var contextProps = parseCommentContextProps(value, processedValue);
687
+ var isBlockLevel = !parent || [
688
+ 'listItem',
689
+ 'blockquote'
690
+ ].includes(parent.type);
691
+ var el;
692
+ var updatedHtmlTag = htmlTag;
693
+ if (isBlockLevel) {
694
+ el = handleBlockHtml(currentElement, processedValue, isUnclosedComment);
695
+ } else {
696
+ var inlineResult = processInlineHtml(currentElement, htmlTag);
697
+ el = inlineResult.el;
698
+ updatedHtmlTag = inlineResult.htmlTag;
699
+ }
700
+ var configuredEl = applyElementConfig(el, contextProps, processedValue, isUnclosedComment, currentElement);
701
+ return {
702
+ el: configuredEl,
703
+ contextProps: contextProps,
704
+ htmlTag: updatedHtmlTag
705
+ };
706
+ };
707
+ /**
708
+ * 预处理特殊标签(think/answer),将其转换为代码块格式
709
+ * @param markdown - 原始 Markdown 字符串
710
+ * @param tagName - 标签名称(think 或 answer)
711
+ * @returns 处理后的 Markdown 字符串
712
+ */ export function preprocessSpecialTags(markdown, tagName) {
713
+ var tagRegex = new RegExp("<".concat(tagName, ">([\\s\\S]*?)<\\/").concat(tagName, ">"), 'g');
714
+ return markdown === null || markdown === void 0 ? void 0 : markdown.replace(tagRegex, function(match, content) {
715
+ var trimmedContent = content.trim();
716
+ // 如果内容中包含代码块标记(三个反引号),需要进行转义
717
+ // 策略:使用特殊标记替换代码块,保持原始格式
718
+ var processedContent = trimmedContent === null || trimmedContent === void 0 ? void 0 : trimmedContent.replace(/```(\w*)\n?([\s\S]*?)```/g, function(_, lang, code) {
719
+ // 使用特殊标记包裹,保留语言和代码内容
720
+ // 格式:【CODE_BLOCK:lang】code【/CODE_BLOCK】
721
+ var marker = '\u200B'; // 零宽空格,用于标记
722
+ return "".concat(marker, "【CODE_BLOCK:").concat(lang || '', "】\n").concat(code, "\n【/CODE_BLOCK】").concat(marker);
723
+ });
724
+ // 构建对应类型的代码块
725
+ return "```".concat(tagName, "\n").concat(processedContent, "\n```");
726
+ });
727
+ }
728
+ /**
729
+ * 预处理 <think> 标签,将其转换为 ```think 代码块格式
730
+ * @param markdown - 原始 Markdown 字符串
731
+ * @returns 处理后的 Markdown 字符串
732
+ */ export function preprocessThinkTags(markdown) {
733
+ return preprocessSpecialTags(markdown, 'think');
734
+ }
735
+ /**
736
+ * 预处理所有非标准 HTML 标签,提取其内容(删除标签本身)
737
+ * @param markdown - 原始 Markdown 字符串
738
+ * @returns 处理后的 Markdown 字符串
739
+ */ export function preprocessNonStandardHtmlTags(markdown) {
740
+ var result = markdown;
741
+ var hasNonStandardTags = true;
742
+ // 循环处理,直到没有非标准标签(处理嵌套情况)
743
+ while(hasNonStandardTags){
744
+ var before = result;
745
+ // 匹配所有 HTML 标签对:<tagname>content</tagname>
746
+ result = result.replace(/<(\w+)>([\s\S]*?)<\/\1>/g, function(match, tagName, content) {
747
+ // 检查是否为标准 HTML 元素
748
+ if (STANDARD_HTML_ELEMENTS.has(tagName.toLowerCase())) {
749
+ // 标准元素保持不变
750
+ return match;
751
+ }
752
+ // 非标准元素只保留内容(不 trim,保持原始格式)
753
+ return content;
754
+ });
755
+ // 如果没有变化,说明处理完成
756
+ hasNonStandardTags = before !== result;
757
+ }
758
+ return result;
759
+ }