edu360-web-ui 1.0.95 → 1.0.97

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.
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var _a2;
5
- import { ref, defineComponent, provide, markRaw, reactive, h as h$2, render as render$1, getCurrentInstance, watchEffect, nextTick, unref, onBeforeUnmount, customRef, shallowRef, onMounted, watch, onUnmounted, createBlock, openBlock, normalizeClass, withCtx, createElementVNode, createCommentVNode, createVNode, createTextVNode, toDisplayString, createElementBlock, Fragment as Fragment$1, renderList, resolveComponent, resolveDirective, normalizeStyle, withDirectives, vShow, withModifiers, Teleport, computed, isRef, createApp, renderSlot } from "vue";
5
+ import { ref, defineComponent, provide, markRaw, reactive, h as h$2, render as render$1, getCurrentInstance, watchEffect, nextTick, unref, onBeforeUnmount, customRef, shallowRef, onMounted, watch, onUnmounted, createBlock, openBlock, normalizeClass, withCtx, createElementVNode, createElementBlock, createCommentVNode, createVNode, createTextVNode, toDisplayString, Fragment as Fragment$1, renderList, resolveComponent, resolveDirective, normalizeStyle, withDirectives, vShow, withModifiers, Teleport, computed, isRef, createApp, renderSlot } from "vue";
6
6
  import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessage, ElInput, ElButton, ElCard, ElForm, ElFormItem, ElTooltip, ElUpload, ElPopover, ElDrawer, ElTable, ElTableColumn, ElColorPicker, ElButtonGroup, ElLoading, ElDialog } from "element-plus";
7
7
  function OrderedMap(content) {
8
8
  this.content = content;
@@ -17591,7 +17591,7 @@ var CodeBlock = Node3.create({
17591
17591
  ];
17592
17592
  }
17593
17593
  });
17594
- var index_default$c = CodeBlock;
17594
+ var index_default$d = CodeBlock;
17595
17595
  var Document = Node3.create({
17596
17596
  name: "doc",
17597
17597
  topNode: true,
@@ -19378,7 +19378,7 @@ var Link = Mark2.create({
19378
19378
  return plugins;
19379
19379
  }
19380
19380
  });
19381
- var index_default$b = Link;
19381
+ var index_default$c = Link;
19382
19382
  var __defProp2 = Object.defineProperty;
19383
19383
  var __export = (target, all3) => {
19384
19384
  for (var name in all3)
@@ -20028,7 +20028,7 @@ var Paragraph = Node3.create({
20028
20028
  };
20029
20029
  }
20030
20030
  });
20031
- var index_default$a = Paragraph;
20031
+ var index_default$b = Paragraph;
20032
20032
  var inputRegex$2 = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/;
20033
20033
  var pasteRegex$1 = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g;
20034
20034
  var Strike = Mark2.create({
@@ -20094,6 +20094,7 @@ var Strike = Mark2.create({
20094
20094
  ];
20095
20095
  }
20096
20096
  });
20097
+ var index_default$a = Strike;
20097
20098
  var Text = Node3.create({
20098
20099
  name: "text",
20099
20100
  group: "inline"
@@ -21821,6 +21822,22 @@ var Highlight = Mark2.create({
21821
21822
  }
21822
21823
  });
21823
21824
  var index_default$7 = Highlight;
21825
+ const CustomUnderline = index_default$9.extend({
21826
+ parseHTML() {
21827
+ return [
21828
+ {
21829
+ tag: "u"
21830
+ },
21831
+ {
21832
+ style: "text-decoration",
21833
+ getAttrs: (value) => value === "underline" && null
21834
+ }
21835
+ ];
21836
+ },
21837
+ renderHTML({ HTMLAttributes }) {
21838
+ return ["u", HTMLAttributes, 0];
21839
+ }
21840
+ });
21824
21841
  var inputRegex = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/;
21825
21842
  var Image = Node3.create({
21826
21843
  name: "image",
@@ -24518,6 +24535,49 @@ var TextAlign = Extension.create({
24518
24535
  }
24519
24536
  });
24520
24537
  var index_default$2 = TextAlign;
24538
+ const CustomTextAlign = index_default$2.extend({
24539
+ addGlobalAttributes() {
24540
+ return [
24541
+ {
24542
+ types: this.options.types,
24543
+ attributes: {
24544
+ textAlign: {
24545
+ default: this.options.defaultAlignment,
24546
+ parseHTML: (element) => element.style.textAlign || this.options.defaultAlignment,
24547
+ renderHTML: (attributes) => {
24548
+ if (attributes.textAlign === this.options.defaultAlignment) {
24549
+ return {};
24550
+ }
24551
+ return { style: `text-align: ${attributes.textAlign}` };
24552
+ }
24553
+ }
24554
+ }
24555
+ }
24556
+ ];
24557
+ }
24558
+ });
24559
+ const CustomStrike = index_default$a.extend({
24560
+ parseHTML() {
24561
+ return [
24562
+ {
24563
+ tag: "s"
24564
+ },
24565
+ {
24566
+ tag: "del"
24567
+ },
24568
+ {
24569
+ tag: "strike"
24570
+ },
24571
+ {
24572
+ style: "text-decoration",
24573
+ getAttrs: (value) => value === "line-through" && null
24574
+ }
24575
+ ];
24576
+ },
24577
+ renderHTML({ HTMLAttributes }) {
24578
+ return ["s", HTMLAttributes, 0];
24579
+ }
24580
+ });
24521
24581
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
24522
24582
  function getDefaultExportFromCjs(x) {
24523
24583
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -26185,7 +26245,7 @@ function LowlightPlugin({
26185
26245
  });
26186
26246
  return lowlightPlugin;
26187
26247
  }
26188
- var CodeBlockLowlight = index_default$c.extend({
26248
+ var CodeBlockLowlight = index_default$d.extend({
26189
26249
  addOptions() {
26190
26250
  var _a3;
26191
26251
  return {
@@ -77512,7 +77572,7 @@ function sendQuery(config2, payload, query, done) {
77512
77572
  } else {
77513
77573
  resources = config2.resources.slice(startIndex).concat(config2.resources.slice(0, startIndex));
77514
77574
  }
77515
- const startTime = Date.now();
77575
+ const startTime2 = Date.now();
77516
77576
  let status = "pending";
77517
77577
  let queriesSent = 0;
77518
77578
  let lastError;
@@ -77550,7 +77610,7 @@ function sendQuery(config2, payload, query, done) {
77550
77610
  }
77551
77611
  function getQueryStatus() {
77552
77612
  return {
77553
- startTime,
77613
+ startTime: startTime2,
77554
77614
  payload,
77555
77615
  status,
77556
77616
  queriesSent,
@@ -78316,7 +78376,10 @@ const _export_sfc = (sfc, props) => {
78316
78376
  return target;
78317
78377
  };
78318
78378
  const _hoisted_1$9 = { class: "code-block-view-cont" };
78319
- const _hoisted_2$8 = { class: "code-toolbar" };
78379
+ const _hoisted_2$8 = {
78380
+ key: 0,
78381
+ class: "code-toolbar"
78382
+ };
78320
78383
  const _hoisted_3$6 = { class: "code-toolbar-right" };
78321
78384
  const _hoisted_4$4 = { class: "el-dropdown-link" };
78322
78385
  const _hoisted_5$4 = { style: { "height": "300px" } };
@@ -78331,6 +78394,7 @@ const _sfc_main$b = {
78331
78394
  setup(__props) {
78332
78395
  const props = __props;
78333
78396
  let showType = props.extension.options.type;
78397
+ let isInline2 = props.extension.options.isInline;
78334
78398
  const languages = ["javascript", "typescript", "python", "vue", "html", "css", "php", "java", "c", "cpp", "go", "ruby", "xml", "json", "markdown", "bash", "shell", "sql", "kotlin", "rust", "yaml", "dart", "lua", "swift", "scala", "r", "perl"];
78335
78399
  const lang = ref(props.node.attrs.language || "javascript");
78336
78400
  const updateLanguage = (data) => {
@@ -78381,7 +78445,7 @@ const _sfc_main$b = {
78381
78445
  }, {
78382
78446
  default: withCtx(() => [
78383
78447
  createElementVNode("div", _hoisted_1$9, [
78384
- createElementVNode("div", _hoisted_2$8, [
78448
+ !unref(isInline2) ? (openBlock(), createElementBlock("div", _hoisted_2$8, [
78385
78449
  _cache[0] || (_cache[0] = createElementVNode("div", null, null, -1)),
78386
78450
  createElementVNode("div", _hoisted_3$6, [
78387
78451
  unref(showType) != "ai" ? (openBlock(), createBlock(unref(ElDropdown), {
@@ -78437,16 +78501,16 @@ const _sfc_main$b = {
78437
78501
  height: "14"
78438
78502
  })) : createCommentVNode("", true)
78439
78503
  ])
78440
- ]),
78504
+ ])) : createCommentVNode("", true),
78441
78505
  createElementVNode("pre", {
78442
- class: "hljs",
78506
+ class: normalizeClass(["hljs", { "no-toolbar": unref(isInline2) }]),
78443
78507
  ref_key: "preBlock",
78444
78508
  ref: preBlock
78445
78509
  }, [
78446
78510
  _cache[1] || (_cache[1] = createTextVNode(" ", -1)),
78447
78511
  createVNode(unref(NodeViewContent), { class: "code-content" }),
78448
78512
  _cache[2] || (_cache[2] = createTextVNode("\n", -1))
78449
- ], 512)
78513
+ ], 2)
78450
78514
  ])
78451
78515
  ]),
78452
78516
  _: 1
@@ -78454,7 +78518,7 @@ const _sfc_main$b = {
78454
78518
  };
78455
78519
  }
78456
78520
  };
78457
- const CodeBlockView = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-5cd3fd6f"]]);
78521
+ const CodeBlockView = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-41168052"]]);
78458
78522
  function dart(hljs2) {
78459
78523
  const SUBST = {
78460
78524
  className: "subst",
@@ -88463,8 +88527,8 @@ const commonExtensions = () => [
88463
88527
  bulletList: false,
88464
88528
  orderedList: false,
88465
88529
  listItem: false,
88466
- strike: true,
88467
- // 确保启用中划线
88530
+ strike: false,
88531
+ // 禁用默认中划线,使用自定义版本
88468
88532
  bold: true,
88469
88533
  // 确保启用粗体
88470
88534
  italic: true
@@ -88474,12 +88538,10 @@ const commonExtensions = () => [
88474
88538
  // 文本样式扩展
88475
88539
  Color,
88476
88540
  // 颜色选择扩展
88477
- index_default$9.configure({
88478
- HTMLAttributes: {
88479
- class: "underline"
88480
- }
88481
- }),
88482
- // 下划线功能
88541
+ CustomUnderline,
88542
+ // 自定义下划线功能
88543
+ CustomStrike,
88544
+ // 自定义中划线功能
88483
88545
  FontSize,
88484
88546
  // 自定义字体大小
88485
88547
  // 图片功能配置
@@ -88530,12 +88592,12 @@ const commonExtensions = () => [
88530
88592
  nested: false
88531
88593
  }),
88532
88594
  AutoOrderedOnEnter,
88533
- index_default$2.configure({
88595
+ CustomTextAlign.configure({
88534
88596
  types: ["heading", "paragraph"],
88535
88597
  alignments: ["left", "center", "right", "justify"],
88536
88598
  defaultAlignment: "left"
88537
88599
  }),
88538
- index_default$b.configure({
88600
+ index_default$c.configure({
88539
88601
  openOnClick: false,
88540
88602
  defaultProtocol: "https"
88541
88603
  })
@@ -97292,8 +97354,8 @@ function parseContentToJSON(content, type, extensions) {
97292
97354
  return json2.content || [];
97293
97355
  } else if (type === "html") {
97294
97356
  let data = purify.sanitize(content, {
97295
- ALLOWED_TAGS: ["b", "i", "em", "strong", "a", "p", "h1", "h2", "h3", "h5", "h6", "ul", "ol", "li", "img", "pre", "code", "div", "text", "span", "font", "table", "thead", "tbody", "tr", "th", "td", "br"],
97296
- ALLOWED_ATTR: ["href", "src", "alt", "title"]
97357
+ ALLOWED_TAGS: ["b", "i", "em", "strong", "a", "p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "li", "img", "pre", "code", "div", "text", "span", "font", "table", "thead", "tbody", "tr", "th", "td", "br", "u", "s", "del", "strike", "mark"],
97358
+ ALLOWED_ATTR: ["href", "src", "alt", "title", "style", "class", "data-type"]
97297
97359
  });
97298
97360
  const json2 = generateJSON(data, extensions);
97299
97361
  return json2.content || [];
@@ -97307,7 +97369,9 @@ function loadContentInChunks({
97307
97369
  extensions,
97308
97370
  chunkSize = 50,
97309
97371
  onProgress,
97310
- onComplete
97372
+ onComplete,
97373
+ isPaste = false
97374
+ // 新增:标识是否为粘贴操作
97311
97375
  }) {
97312
97376
  if (!editor || !content) return;
97313
97377
  let blocks;
@@ -97331,14 +97395,34 @@ function loadContentInChunks({
97331
97395
  onComplete == null ? void 0 : onComplete();
97332
97396
  return;
97333
97397
  }
97334
- editor.chain().insertContentAt(pos, chunk).run();
97335
- index += chunkSize;
97336
- onProgress == null ? void 0 : onProgress(Math.min(index / total, 1));
97337
- const nextPos = editor.state.doc.content.size;
97338
- if ("requestIdleCallback" in window) {
97339
- requestIdleCallback(() => insertChunk(nextPos));
97340
- } else {
97341
- setTimeout(() => insertChunk(nextPos), 16);
97398
+ try {
97399
+ const beforeSize = editor.state.doc.content.size;
97400
+ if (pos < 0 || pos > beforeSize) {
97401
+ pos = beforeSize;
97402
+ }
97403
+ editor.chain().focus().insertContentAt(pos, chunk).run();
97404
+ index += chunkSize;
97405
+ onProgress == null ? void 0 : onProgress(Math.min(index / total, 1));
97406
+ let nextPos;
97407
+ if (isPaste) {
97408
+ const afterSize = editor.state.doc.content.size;
97409
+ const insertedSize = afterSize - beforeSize;
97410
+ if (insertedSize <= 0 || insertedSize > beforeSize * 2) {
97411
+ nextPos = editor.state.doc.content.size;
97412
+ } else {
97413
+ nextPos = pos + insertedSize;
97414
+ }
97415
+ } else {
97416
+ nextPos = editor.state.doc.content.size;
97417
+ }
97418
+ if ("requestIdleCallback" in window) {
97419
+ requestIdleCallback(() => insertChunk(nextPos), { timeout: 50 });
97420
+ } else {
97421
+ setTimeout(() => insertChunk(nextPos), 0);
97422
+ }
97423
+ } catch (error2) {
97424
+ console.error("[分块插入] 插入失败:", error2);
97425
+ onComplete == null ? void 0 : onComplete();
97342
97426
  }
97343
97427
  }
97344
97428
  insertChunk(insertPos);
@@ -107898,6 +107982,7 @@ const _sfc_main$6 = {
107898
107982
  };
107899
107983
  const emit = __emit;
107900
107984
  const handleDocUpload = () => {
107985
+ if (isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")) return;
107901
107986
  emit("toggleLoading", true);
107902
107987
  emit("closemenu");
107903
107988
  };
@@ -107929,6 +108014,7 @@ const _sfc_main$6 = {
107929
108014
  });
107930
108015
  };
107931
108016
  const handleJupyterUpload = () => {
108017
+ if (isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")) return;
107932
108018
  emit("toggleLoading", true);
107933
108019
  closePopover();
107934
108020
  emit("closemenu");
@@ -108350,7 +108436,7 @@ const _sfc_main$6 = {
108350
108436
  accept: ".doc,.docx",
108351
108437
  "on-success": uploadDocSuccess,
108352
108438
  "before-upload": handleDocUpload,
108353
- disabled: isActive2("codeBlock") || isActive2("table")
108439
+ disabled: isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")
108354
108440
  }, {
108355
108441
  default: withCtx(() => [
108356
108442
  createElementVNode("div", {
@@ -108407,7 +108493,7 @@ const _sfc_main$6 = {
108407
108493
  };
108408
108494
  }
108409
108495
  };
108410
- const BlockMenu = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-7f8a1002"]]);
108496
+ const BlockMenu = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-49f2614c"]]);
108411
108497
  function BlockMenuPlugin(editor, options) {
108412
108498
  const PLUGIN_KEY = new PluginKey("blockMenu");
108413
108499
  let wrapperEl = options.wrapperEl || null;
@@ -108857,7 +108943,7 @@ const CustomImage = index_default$6.extend({
108857
108943
  }
108858
108944
  });
108859
108945
  createLowlight();
108860
- index_default$a.extend({
108946
+ index_default$b.extend({
108861
108947
  content: "inline*"
108862
108948
  // 只允许 inline node
108863
108949
  });
@@ -108865,6 +108951,117 @@ const CustomTableCell = index_default$4.extend({
108865
108951
  content: "(paragraph | bulletList | orderedList)*"
108866
108952
  // 列表允许嵌套
108867
108953
  });
108954
+ function isMarkdown(text2) {
108955
+ if (!text2 || text2.length < 3) return false;
108956
+ const patterns = [
108957
+ /^#{1,6}\s+/m,
108958
+ // 标题 # ## ###
108959
+ /^\*\*[^*]+\*\*/m,
108960
+ // 粗体 **text**
108961
+ /^__[^_]+__/m,
108962
+ // 粗体 __text__
108963
+ /^\*[^*]+\*/m,
108964
+ // 斜体 *text*
108965
+ /^_[^_]+_/m,
108966
+ // 斜体 _text_
108967
+ /^\[.+\]\(.+\)/m,
108968
+ // 链接 [text](url)
108969
+ /^!\[.*\]\(.+\)/m,
108970
+ // 图片 ![alt](url)
108971
+ /^```/m,
108972
+ // 代码块 ```
108973
+ /^`[^`]+`/m,
108974
+ // 行内代码 `code`
108975
+ /^[-*+]\s+/m,
108976
+ // 无序列表 - * +
108977
+ /^\d+\.\s+/m,
108978
+ // 有序列表 1. 2.
108979
+ /^>\s+/m,
108980
+ // 引用 >
108981
+ /^\|.+\|.+\|/m,
108982
+ // 表格 | col1 | col2 |
108983
+ /^---+$/m,
108984
+ // 分隔线 ---
108985
+ /^___+$/m,
108986
+ // 分隔线 ___
108987
+ /^\*\*\*+$/m
108988
+ // 分隔线 ***
108989
+ ];
108990
+ const matchCount = patterns.filter((pattern) => pattern.test(text2)).length;
108991
+ return matchCount >= 2;
108992
+ }
108993
+ function parseMarkdownTables(text2) {
108994
+ if (!text2.includes("|")) {
108995
+ return text2;
108996
+ }
108997
+ const lines = text2.split("\n");
108998
+ let result = [];
108999
+ let i = 0;
109000
+ const separatorRegex = /^\|[\s:|-]+\|$/;
109001
+ while (i < lines.length) {
109002
+ const line = lines[i];
109003
+ const trimmedLine = line.trim();
109004
+ if (trimmedLine[0] === "|" && trimmedLine[trimmedLine.length - 1] === "|") {
109005
+ const tableRows = [];
109006
+ while (i < lines.length) {
109007
+ const currentLine = lines[i].trim();
109008
+ if (currentLine[0] !== "|" || currentLine[currentLine.length - 1] !== "|") {
109009
+ break;
109010
+ }
109011
+ if (separatorRegex.test(currentLine)) {
109012
+ tableRows.push({ type: "separator", content: currentLine });
109013
+ } else {
109014
+ tableRows.push({ type: "data", content: currentLine });
109015
+ }
109016
+ i++;
109017
+ }
109018
+ if (tableRows.length > 0) {
109019
+ const tableHtml = convertTableToHtml(tableRows);
109020
+ result.push(tableHtml);
109021
+ }
109022
+ } else {
109023
+ result.push(trimmedLine);
109024
+ i++;
109025
+ }
109026
+ }
109027
+ return result.join("\n");
109028
+ }
109029
+ function convertTableToHtml(rows, hasHeaderSeparator) {
109030
+ if (rows.length === 0) return "";
109031
+ const htmlParts = ["<table>"];
109032
+ let hasHeader = false;
109033
+ let headerProcessed = false;
109034
+ for (let i = 0; i < rows.length; i++) {
109035
+ const row = rows[i];
109036
+ if (row.type === "separator") {
109037
+ hasHeader = true;
109038
+ continue;
109039
+ }
109040
+ const content = row.content;
109041
+ const cells = content.substring(1, content.length - 1).split("|");
109042
+ if (hasHeader && !headerProcessed) {
109043
+ htmlParts.push("<thead><tr>");
109044
+ for (let j2 = 0; j2 < cells.length; j2++) {
109045
+ htmlParts.push("<th>", cells[j2].trim(), "</th>");
109046
+ }
109047
+ htmlParts.push("</tr></thead><tbody>");
109048
+ headerProcessed = true;
109049
+ } else {
109050
+ if (!headerProcessed) {
109051
+ htmlParts.push("<tbody>");
109052
+ headerProcessed = true;
109053
+ }
109054
+ htmlParts.push("<tr>");
109055
+ for (let j2 = 0; j2 < cells.length; j2++) {
109056
+ htmlParts.push("<td>", cells[j2].trim(), "</td>");
109057
+ }
109058
+ htmlParts.push("</tr>");
109059
+ }
109060
+ }
109061
+ htmlParts.push("</tbody></table>");
109062
+ return htmlParts.join("");
109063
+ }
109064
+ const PASTE_CHUNK_THRESHOLD = 200;
108868
109065
  const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2 = false, showMenu = [], placeholder = "", blockMenuFn, editorWrapper, checkSlashTrigger } = {}) => {
108869
109066
  const editor = new Editor2({
108870
109067
  // 配置编辑器扩展功能
@@ -108881,8 +109078,8 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108881
109078
  bulletList: false,
108882
109079
  orderedList: false,
108883
109080
  listItem: false,
108884
- strike: true,
108885
- // 确保启用中划线
109081
+ strike: false,
109082
+ // 禁用默认中划线,使用自定义版本
108886
109083
  bold: true,
108887
109084
  // 确保启用粗体
108888
109085
  italic: true
@@ -108895,7 +109092,7 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108895
109092
  doc2.content.firstChild.type.name === "paragraph" && doc2.content.firstChild.content.size === 0;
108896
109093
  if (!docEmpty) return null;
108897
109094
  if (node === doc2.content.firstChild) {
108898
- return "输入“/”插入内容";
109095
+ return placeholder || "输入“/”插入内容";
108899
109096
  }
108900
109097
  return null;
108901
109098
  },
@@ -108908,12 +109105,10 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108908
109105
  // 文本样式扩展
108909
109106
  Color,
108910
109107
  // 颜色选择扩展
108911
- index_default$9.configure({
108912
- HTMLAttributes: {
108913
- class: "underline"
108914
- }
108915
- }),
108916
- // 下划线功能
109108
+ CustomUnderline,
109109
+ // 自定义下划线功能
109110
+ CustomStrike,
109111
+ // 自定义中划线功能
108917
109112
  FontSize,
108918
109113
  // 自定义字体大小
108919
109114
  // 图片功能配置
@@ -108939,7 +109134,9 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108939
109134
  index_default$5,
108940
109135
  index_default$3,
108941
109136
  index_default$4,
108942
- CodeBlockCustom,
109137
+ CodeBlockCustom.configure({
109138
+ isInline: isInline2
109139
+ }),
108943
109140
  BulletList.configure({
108944
109141
  HTMLAttributes: {
108945
109142
  class: "bullet-list"
@@ -108966,12 +109163,12 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108966
109163
  nested: false
108967
109164
  }),
108968
109165
  AutoOrderedOnEnter,
108969
- index_default$2.configure({
109166
+ CustomTextAlign.configure({
108970
109167
  types: ["heading", "paragraph"],
108971
109168
  alignments: ["left", "center", "right", "justify"],
108972
109169
  defaultAlignment: "left"
108973
109170
  }),
108974
- index_default$b.configure({
109171
+ index_default$c.configure({
108975
109172
  openOnClick: false,
108976
109173
  defaultProtocol: "https"
108977
109174
  }),
@@ -109008,7 +109205,7 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
109008
109205
  editorProps: {
109009
109206
  // --- 修改这里 ---
109010
109207
  handlePaste: (view, event, slice2) => {
109011
- var _a3;
109208
+ var _a3, _b;
109012
109209
  const currentSize = getTextLength(view.state.doc);
109013
109210
  const pastedSize = slice2.content.size;
109014
109211
  if (currentSize + pastedSize > limit) {
@@ -109017,35 +109214,143 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
109017
109214
  }
109018
109215
  const items = Array.from(((_a3 = event.clipboardData) == null ? void 0 : _a3.items) || []);
109019
109216
  const imageItem = items.find((item) => item.type.startsWith("image/"));
109020
- if (!imageItem) {
109021
- return false;
109022
- }
109023
- event.preventDefault();
109024
- const file = imageItem.getAsFile();
109025
- if (!file) {
109026
- return false;
109027
- }
109028
- const formData = new FormData();
109029
- formData.append("file", file);
109030
- const params = {
109031
- config: {
109032
- apiHost: info.apiHost,
109033
- token: info.token,
109034
- getFileContent: info.uploadUrl
109217
+ if (imageItem) {
109218
+ event.preventDefault();
109219
+ const file = imageItem.getAsFile();
109220
+ if (!file) {
109221
+ return false;
109035
109222
  }
109036
- };
109037
- uploadImageApi(params, formData).then((res) => {
109038
- if (res && res.data && res.data.show_url) {
109039
- editor.chain().focus().setImage({ src: res.data.show_url }).run();
109040
- } else {
109041
- console.error("Image upload failed or response format is incorrect.", res);
109223
+ const formData = new FormData();
109224
+ formData.append("file", file);
109225
+ const params = {
109226
+ config: {
109227
+ apiHost: info.apiHost,
109228
+ token: info.token,
109229
+ getFileContent: info.uploadUrl
109230
+ }
109231
+ };
109232
+ uploadImageApi(params, formData).then((res) => {
109233
+ if (res && res.data && res.data.show_url) {
109234
+ editor.chain().focus().setImage({ src: res.data.show_url }).run();
109235
+ } else {
109236
+ console.error("Image upload failed or response format is incorrect.", res);
109237
+ ElMessage.error("图片上传失败");
109238
+ }
109239
+ }).catch((error2) => {
109240
+ console.error("Error during image upload:", error2);
109042
109241
  ElMessage.error("图片上传失败");
109242
+ });
109243
+ return true;
109244
+ }
109245
+ const text2 = (_b = event.clipboardData) == null ? void 0 : _b.getData("text/plain");
109246
+ if (text2 && isMarkdown(text2)) {
109247
+ event.preventDefault();
109248
+ try {
109249
+ let textWithTables;
109250
+ try {
109251
+ textWithTables = parseMarkdownTables(text2);
109252
+ } catch (tableError) {
109253
+ console.error("[粘贴] 表格解析失败:", tableError);
109254
+ textWithTables = text2;
109255
+ }
109256
+ let html2;
109257
+ try {
109258
+ const md = new MarkdownIt({
109259
+ html: true,
109260
+ // 允许 HTML 标签
109261
+ linkify: true,
109262
+ // 自动转换 URL 为链接
109263
+ typographer: false,
109264
+ // 禁用排版,提升性能
109265
+ breaks: false
109266
+ // 不转换单个换行符为 <br>
109267
+ });
109268
+ html2 = md.render(textWithTables);
109269
+ } catch (mdError) {
109270
+ console.error("[粘贴] Markdown-it 渲染失败:", mdError);
109271
+ throw mdError;
109272
+ }
109273
+ let json2;
109274
+ try {
109275
+ json2 = generateJSON(html2, [
109276
+ index_default$8.configure({
109277
+ codeBlock: false,
109278
+ strike: false,
109279
+ bulletList: false,
109280
+ orderedList: false,
109281
+ listItem: false
109282
+ }),
109283
+ CustomUnderline,
109284
+ CustomStrike,
109285
+ TableKit,
109286
+ CustomTextAlign,
109287
+ BulletList,
109288
+ OrderedList,
109289
+ ListItem
109290
+ ]);
109291
+ } catch (jsonError) {
109292
+ console.error("[粘贴] generateJSON 失败:", jsonError);
109293
+ console.error("[粘贴] HTML 内容:", html2);
109294
+ throw jsonError;
109295
+ }
109296
+ if (json2 && json2.content) {
109297
+ const contentLength = json2.content.length;
109298
+ if (contentLength > PASTE_CHUNK_THRESHOLD) {
109299
+ ElMessage.info(`正在插入 ${contentLength} 个内容块...`);
109300
+ if (blockMenuFn) {
109301
+ blockMenuFn(true);
109302
+ }
109303
+ const originalEditable = editor.isEditable;
109304
+ editor.setEditable(false);
109305
+ loadContentInChunks({
109306
+ editor,
109307
+ content: json2.content,
109308
+ type: "json",
109309
+ extensions: [],
109310
+ // 不需要传扩展,因为内容已经是 JSON 格式
109311
+ chunkSize: 100,
109312
+ // 进一步增加到 100 个节点,大幅提升插入速度
109313
+ isPaste: true,
109314
+ // 标识为粘贴操作
109315
+ onProgress: (progress) => {
109316
+ if (progress === 1) {
109317
+ const totalTime = performance.now() - startTime;
109318
+ console.log(`[粘贴] 总耗时: ${totalTime.toFixed(2)}ms`);
109319
+ editor.setEditable(originalEditable);
109320
+ ElMessage.success("内容已插入完成");
109321
+ if (blockMenuFn) {
109322
+ blockMenuFn(false);
109323
+ }
109324
+ }
109325
+ },
109326
+ onComplete: () => {
109327
+ editor.setEditable(originalEditable);
109328
+ if (blockMenuFn) {
109329
+ blockMenuFn(false);
109330
+ }
109331
+ }
109332
+ });
109333
+ } else {
109334
+ editor.chain().focus().insertContent(json2.content).run();
109335
+ setTimeout(() => {
109336
+ editor.view.updateState(editor.state);
109337
+ const { tr: tr2 } = editor.state;
109338
+ editor.view.dispatch(tr2);
109339
+ editor.commands.focus();
109340
+ }, 0);
109341
+ }
109342
+ }
109343
+ } catch (error2) {
109344
+ try {
109345
+ editor.chain().focus().insertContent(text2).run();
109346
+ ElMessage.warning("Markdown 解析失败,已作为纯文本插入");
109347
+ } catch (insertError) {
109348
+ ElMessage.error("内容插入失败,请检查控制台");
109349
+ }
109043
109350
  }
109044
- }).catch((error2) => {
109045
- console.error("Error during image upload:", error2);
109046
- ElMessage.error("图片上传失败");
109047
- });
109048
- return true;
109351
+ return true;
109352
+ }
109353
+ return false;
109049
109354
  },
109050
109355
  handleDOMEvents: {
109051
109356
  // beforeinput: (view, event) => {
@@ -112092,7 +112397,8 @@ const _sfc_main = {
112092
112397
  if (slashState.value.isOpen) {
112093
112398
  closeSlashMenu();
112094
112399
  }
112095
- emit("update:content", editor2.getHTML());
112400
+ let length = getTextLength(editor2.state.doc);
112401
+ emit("update:content", editor2.getHTML(), length);
112096
112402
  });
112097
112403
  let floatAiStatus = ref(false);
112098
112404
  const showAi = () => {
@@ -112148,6 +112454,7 @@ const _sfc_main = {
112148
112454
  function applySourceCode() {
112149
112455
  try {
112150
112456
  isLoading.value = true;
112457
+ editor.commands.clearContent();
112151
112458
  loadContentInChunks({
112152
112459
  editor,
112153
112460
  content: sourceCode.value,
@@ -112327,7 +112634,7 @@ const _sfc_main = {
112327
112634
  };
112328
112635
  }
112329
112636
  };
112330
- const TiptapVue = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8ba51e61"]]);
112637
+ const TiptapVue = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-20dc593e"]]);
112331
112638
  const components = [
112332
112639
  {
112333
112640
  name: "TiptapVue",