edu360-web-ui 1.0.95 → 1.0.96

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.
@@ -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,
@@ -88463,8 +88523,8 @@ const commonExtensions = () => [
88463
88523
  bulletList: false,
88464
88524
  orderedList: false,
88465
88525
  listItem: false,
88466
- strike: true,
88467
- // 确保启用中划线
88526
+ strike: false,
88527
+ // 禁用默认中划线,使用自定义版本
88468
88528
  bold: true,
88469
88529
  // 确保启用粗体
88470
88530
  italic: true
@@ -88474,12 +88534,10 @@ const commonExtensions = () => [
88474
88534
  // 文本样式扩展
88475
88535
  Color,
88476
88536
  // 颜色选择扩展
88477
- index_default$9.configure({
88478
- HTMLAttributes: {
88479
- class: "underline"
88480
- }
88481
- }),
88482
- // 下划线功能
88537
+ CustomUnderline,
88538
+ // 自定义下划线功能
88539
+ CustomStrike,
88540
+ // 自定义中划线功能
88483
88541
  FontSize,
88484
88542
  // 自定义字体大小
88485
88543
  // 图片功能配置
@@ -88530,12 +88588,12 @@ const commonExtensions = () => [
88530
88588
  nested: false
88531
88589
  }),
88532
88590
  AutoOrderedOnEnter,
88533
- index_default$2.configure({
88591
+ CustomTextAlign.configure({
88534
88592
  types: ["heading", "paragraph"],
88535
88593
  alignments: ["left", "center", "right", "justify"],
88536
88594
  defaultAlignment: "left"
88537
88595
  }),
88538
- index_default$b.configure({
88596
+ index_default$c.configure({
88539
88597
  openOnClick: false,
88540
88598
  defaultProtocol: "https"
88541
88599
  })
@@ -97292,8 +97350,8 @@ function parseContentToJSON(content, type, extensions) {
97292
97350
  return json2.content || [];
97293
97351
  } else if (type === "html") {
97294
97352
  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"]
97353
+ 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"],
97354
+ ALLOWED_ATTR: ["href", "src", "alt", "title", "style", "class", "data-type"]
97297
97355
  });
97298
97356
  const json2 = generateJSON(data, extensions);
97299
97357
  return json2.content || [];
@@ -97307,7 +97365,9 @@ function loadContentInChunks({
97307
97365
  extensions,
97308
97366
  chunkSize = 50,
97309
97367
  onProgress,
97310
- onComplete
97368
+ onComplete,
97369
+ isPaste = false
97370
+ // 新增:标识是否为粘贴操作
97311
97371
  }) {
97312
97372
  if (!editor || !content) return;
97313
97373
  let blocks;
@@ -97331,14 +97391,34 @@ function loadContentInChunks({
97331
97391
  onComplete == null ? void 0 : onComplete();
97332
97392
  return;
97333
97393
  }
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);
97394
+ try {
97395
+ const beforeSize = editor.state.doc.content.size;
97396
+ if (pos < 0 || pos > beforeSize) {
97397
+ pos = beforeSize;
97398
+ }
97399
+ editor.chain().focus().insertContentAt(pos, chunk).run();
97400
+ index += chunkSize;
97401
+ onProgress == null ? void 0 : onProgress(Math.min(index / total, 1));
97402
+ let nextPos;
97403
+ if (isPaste) {
97404
+ const afterSize = editor.state.doc.content.size;
97405
+ const insertedSize = afterSize - beforeSize;
97406
+ if (insertedSize <= 0 || insertedSize > beforeSize * 2) {
97407
+ nextPos = editor.state.doc.content.size;
97408
+ } else {
97409
+ nextPos = pos + insertedSize;
97410
+ }
97411
+ } else {
97412
+ nextPos = editor.state.doc.content.size;
97413
+ }
97414
+ if ("requestIdleCallback" in window) {
97415
+ requestIdleCallback(() => insertChunk(nextPos), { timeout: 50 });
97416
+ } else {
97417
+ setTimeout(() => insertChunk(nextPos), 0);
97418
+ }
97419
+ } catch (error2) {
97420
+ console.error("[分块插入] 插入失败:", error2);
97421
+ onComplete == null ? void 0 : onComplete();
97342
97422
  }
97343
97423
  }
97344
97424
  insertChunk(insertPos);
@@ -107898,6 +107978,7 @@ const _sfc_main$6 = {
107898
107978
  };
107899
107979
  const emit = __emit;
107900
107980
  const handleDocUpload = () => {
107981
+ if (isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")) return;
107901
107982
  emit("toggleLoading", true);
107902
107983
  emit("closemenu");
107903
107984
  };
@@ -107929,6 +108010,7 @@ const _sfc_main$6 = {
107929
108010
  });
107930
108011
  };
107931
108012
  const handleJupyterUpload = () => {
108013
+ if (isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")) return;
107932
108014
  emit("toggleLoading", true);
107933
108015
  closePopover();
107934
108016
  emit("closemenu");
@@ -108350,7 +108432,7 @@ const _sfc_main$6 = {
108350
108432
  accept: ".doc,.docx",
108351
108433
  "on-success": uploadDocSuccess,
108352
108434
  "before-upload": handleDocUpload,
108353
- disabled: isActive2("codeBlock") || isActive2("table")
108435
+ disabled: isActive2("codeBlock") || isActive2("table") || isActive2("bulletList") || isActive2("orderedList") || isActive2("taskList")
108354
108436
  }, {
108355
108437
  default: withCtx(() => [
108356
108438
  createElementVNode("div", {
@@ -108407,7 +108489,7 @@ const _sfc_main$6 = {
108407
108489
  };
108408
108490
  }
108409
108491
  };
108410
- const BlockMenu = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-7f8a1002"]]);
108492
+ const BlockMenu = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-49f2614c"]]);
108411
108493
  function BlockMenuPlugin(editor, options) {
108412
108494
  const PLUGIN_KEY = new PluginKey("blockMenu");
108413
108495
  let wrapperEl = options.wrapperEl || null;
@@ -108857,7 +108939,7 @@ const CustomImage = index_default$6.extend({
108857
108939
  }
108858
108940
  });
108859
108941
  createLowlight();
108860
- index_default$a.extend({
108942
+ index_default$b.extend({
108861
108943
  content: "inline*"
108862
108944
  // 只允许 inline node
108863
108945
  });
@@ -108865,6 +108947,117 @@ const CustomTableCell = index_default$4.extend({
108865
108947
  content: "(paragraph | bulletList | orderedList)*"
108866
108948
  // 列表允许嵌套
108867
108949
  });
108950
+ function isMarkdown(text2) {
108951
+ if (!text2 || text2.length < 3) return false;
108952
+ const patterns = [
108953
+ /^#{1,6}\s+/m,
108954
+ // 标题 # ## ###
108955
+ /^\*\*[^*]+\*\*/m,
108956
+ // 粗体 **text**
108957
+ /^__[^_]+__/m,
108958
+ // 粗体 __text__
108959
+ /^\*[^*]+\*/m,
108960
+ // 斜体 *text*
108961
+ /^_[^_]+_/m,
108962
+ // 斜体 _text_
108963
+ /^\[.+\]\(.+\)/m,
108964
+ // 链接 [text](url)
108965
+ /^!\[.*\]\(.+\)/m,
108966
+ // 图片 ![alt](url)
108967
+ /^```/m,
108968
+ // 代码块 ```
108969
+ /^`[^`]+`/m,
108970
+ // 行内代码 `code`
108971
+ /^[-*+]\s+/m,
108972
+ // 无序列表 - * +
108973
+ /^\d+\.\s+/m,
108974
+ // 有序列表 1. 2.
108975
+ /^>\s+/m,
108976
+ // 引用 >
108977
+ /^\|.+\|.+\|/m,
108978
+ // 表格 | col1 | col2 |
108979
+ /^---+$/m,
108980
+ // 分隔线 ---
108981
+ /^___+$/m,
108982
+ // 分隔线 ___
108983
+ /^\*\*\*+$/m
108984
+ // 分隔线 ***
108985
+ ];
108986
+ const matchCount = patterns.filter((pattern) => pattern.test(text2)).length;
108987
+ return matchCount >= 2;
108988
+ }
108989
+ function parseMarkdownTables(text2) {
108990
+ if (!text2.includes("|")) {
108991
+ return text2;
108992
+ }
108993
+ const lines = text2.split("\n");
108994
+ let result = [];
108995
+ let i = 0;
108996
+ const separatorRegex = /^\|[\s:|-]+\|$/;
108997
+ while (i < lines.length) {
108998
+ const line = lines[i];
108999
+ const trimmedLine = line.trim();
109000
+ if (trimmedLine[0] === "|" && trimmedLine[trimmedLine.length - 1] === "|") {
109001
+ const tableRows = [];
109002
+ while (i < lines.length) {
109003
+ const currentLine = lines[i].trim();
109004
+ if (currentLine[0] !== "|" || currentLine[currentLine.length - 1] !== "|") {
109005
+ break;
109006
+ }
109007
+ if (separatorRegex.test(currentLine)) {
109008
+ tableRows.push({ type: "separator", content: currentLine });
109009
+ } else {
109010
+ tableRows.push({ type: "data", content: currentLine });
109011
+ }
109012
+ i++;
109013
+ }
109014
+ if (tableRows.length > 0) {
109015
+ const tableHtml = convertTableToHtml(tableRows);
109016
+ result.push(tableHtml);
109017
+ }
109018
+ } else {
109019
+ result.push(trimmedLine);
109020
+ i++;
109021
+ }
109022
+ }
109023
+ return result.join("\n");
109024
+ }
109025
+ function convertTableToHtml(rows, hasHeaderSeparator) {
109026
+ if (rows.length === 0) return "";
109027
+ const htmlParts = ["<table>"];
109028
+ let hasHeader = false;
109029
+ let headerProcessed = false;
109030
+ for (let i = 0; i < rows.length; i++) {
109031
+ const row = rows[i];
109032
+ if (row.type === "separator") {
109033
+ hasHeader = true;
109034
+ continue;
109035
+ }
109036
+ const content = row.content;
109037
+ const cells = content.substring(1, content.length - 1).split("|");
109038
+ if (hasHeader && !headerProcessed) {
109039
+ htmlParts.push("<thead><tr>");
109040
+ for (let j2 = 0; j2 < cells.length; j2++) {
109041
+ htmlParts.push("<th>", cells[j2].trim(), "</th>");
109042
+ }
109043
+ htmlParts.push("</tr></thead><tbody>");
109044
+ headerProcessed = true;
109045
+ } else {
109046
+ if (!headerProcessed) {
109047
+ htmlParts.push("<tbody>");
109048
+ headerProcessed = true;
109049
+ }
109050
+ htmlParts.push("<tr>");
109051
+ for (let j2 = 0; j2 < cells.length; j2++) {
109052
+ htmlParts.push("<td>", cells[j2].trim(), "</td>");
109053
+ }
109054
+ htmlParts.push("</tr>");
109055
+ }
109056
+ }
109057
+ htmlParts.push("</tbody></table>");
109058
+ return htmlParts.join("");
109059
+ }
109060
+ const PASTE_CHUNK_THRESHOLD = 200;
108868
109061
  const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2 = false, showMenu = [], placeholder = "", blockMenuFn, editorWrapper, checkSlashTrigger } = {}) => {
108869
109062
  const editor = new Editor2({
108870
109063
  // 配置编辑器扩展功能
@@ -108881,8 +109074,8 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108881
109074
  bulletList: false,
108882
109075
  orderedList: false,
108883
109076
  listItem: false,
108884
- strike: true,
108885
- // 确保启用中划线
109077
+ strike: false,
109078
+ // 禁用默认中划线,使用自定义版本
108886
109079
  bold: true,
108887
109080
  // 确保启用粗体
108888
109081
  italic: true
@@ -108908,12 +109101,10 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108908
109101
  // 文本样式扩展
108909
109102
  Color,
108910
109103
  // 颜色选择扩展
108911
- index_default$9.configure({
108912
- HTMLAttributes: {
108913
- class: "underline"
108914
- }
108915
- }),
108916
- // 下划线功能
109104
+ CustomUnderline,
109105
+ // 自定义下划线功能
109106
+ CustomStrike,
109107
+ // 自定义中划线功能
108917
109108
  FontSize,
108918
109109
  // 自定义字体大小
108919
109110
  // 图片功能配置
@@ -108966,12 +109157,12 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
108966
109157
  nested: false
108967
109158
  }),
108968
109159
  AutoOrderedOnEnter,
108969
- index_default$2.configure({
109160
+ CustomTextAlign.configure({
108970
109161
  types: ["heading", "paragraph"],
108971
109162
  alignments: ["left", "center", "right", "justify"],
108972
109163
  defaultAlignment: "left"
108973
109164
  }),
108974
- index_default$b.configure({
109165
+ index_default$c.configure({
108975
109166
  openOnClick: false,
108976
109167
  defaultProtocol: "https"
108977
109168
  }),
@@ -109008,7 +109199,7 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
109008
109199
  editorProps: {
109009
109200
  // --- 修改这里 ---
109010
109201
  handlePaste: (view, event, slice2) => {
109011
- var _a3;
109202
+ var _a3, _b;
109012
109203
  const currentSize = getTextLength(view.state.doc);
109013
109204
  const pastedSize = slice2.content.size;
109014
109205
  if (currentSize + pastedSize > limit) {
@@ -109017,35 +109208,143 @@ const createEditor = ({ content = "", info = {}, limit = 50, isInline: isInline2
109017
109208
  }
109018
109209
  const items = Array.from(((_a3 = event.clipboardData) == null ? void 0 : _a3.items) || []);
109019
109210
  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
109211
+ if (imageItem) {
109212
+ event.preventDefault();
109213
+ const file = imageItem.getAsFile();
109214
+ if (!file) {
109215
+ return false;
109035
109216
  }
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);
109217
+ const formData = new FormData();
109218
+ formData.append("file", file);
109219
+ const params = {
109220
+ config: {
109221
+ apiHost: info.apiHost,
109222
+ token: info.token,
109223
+ getFileContent: info.uploadUrl
109224
+ }
109225
+ };
109226
+ uploadImageApi(params, formData).then((res) => {
109227
+ if (res && res.data && res.data.show_url) {
109228
+ editor.chain().focus().setImage({ src: res.data.show_url }).run();
109229
+ } else {
109230
+ console.error("Image upload failed or response format is incorrect.", res);
109231
+ ElMessage.error("图片上传失败");
109232
+ }
109233
+ }).catch((error2) => {
109234
+ console.error("Error during image upload:", error2);
109042
109235
  ElMessage.error("图片上传失败");
109236
+ });
109237
+ return true;
109238
+ }
109239
+ const text2 = (_b = event.clipboardData) == null ? void 0 : _b.getData("text/plain");
109240
+ if (text2 && isMarkdown(text2)) {
109241
+ event.preventDefault();
109242
+ try {
109243
+ let textWithTables;
109244
+ try {
109245
+ textWithTables = parseMarkdownTables(text2);
109246
+ } catch (tableError) {
109247
+ console.error("[粘贴] 表格解析失败:", tableError);
109248
+ textWithTables = text2;
109249
+ }
109250
+ let html2;
109251
+ try {
109252
+ const md = new MarkdownIt({
109253
+ html: true,
109254
+ // 允许 HTML 标签
109255
+ linkify: true,
109256
+ // 自动转换 URL 为链接
109257
+ typographer: false,
109258
+ // 禁用排版,提升性能
109259
+ breaks: false
109260
+ // 不转换单个换行符为 <br>
109261
+ });
109262
+ html2 = md.render(textWithTables);
109263
+ } catch (mdError) {
109264
+ console.error("[粘贴] Markdown-it 渲染失败:", mdError);
109265
+ throw mdError;
109266
+ }
109267
+ let json2;
109268
+ try {
109269
+ json2 = generateJSON(html2, [
109270
+ index_default$8.configure({
109271
+ codeBlock: false,
109272
+ strike: false,
109273
+ bulletList: false,
109274
+ orderedList: false,
109275
+ listItem: false
109276
+ }),
109277
+ CustomUnderline,
109278
+ CustomStrike,
109279
+ TableKit,
109280
+ CustomTextAlign,
109281
+ BulletList,
109282
+ OrderedList,
109283
+ ListItem
109284
+ ]);
109285
+ } catch (jsonError) {
109286
+ console.error("[粘贴] generateJSON 失败:", jsonError);
109287
+ console.error("[粘贴] HTML 内容:", html2);
109288
+ throw jsonError;
109289
+ }
109290
+ if (json2 && json2.content) {
109291
+ const contentLength = json2.content.length;
109292
+ if (contentLength > PASTE_CHUNK_THRESHOLD) {
109293
+ ElMessage.info(`正在插入 ${contentLength} 个内容块...`);
109294
+ if (blockMenuFn) {
109295
+ blockMenuFn(true);
109296
+ }
109297
+ const originalEditable = editor.isEditable;
109298
+ editor.setEditable(false);
109299
+ loadContentInChunks({
109300
+ editor,
109301
+ content: json2.content,
109302
+ type: "json",
109303
+ extensions: [],
109304
+ // 不需要传扩展,因为内容已经是 JSON 格式
109305
+ chunkSize: 100,
109306
+ // 进一步增加到 100 个节点,大幅提升插入速度
109307
+ isPaste: true,
109308
+ // 标识为粘贴操作
109309
+ onProgress: (progress) => {
109310
+ if (progress === 1) {
109311
+ const totalTime = performance.now() - startTime;
109312
+ console.log(`[粘贴] 总耗时: ${totalTime.toFixed(2)}ms`);
109313
+ editor.setEditable(originalEditable);
109314
+ ElMessage.success("内容已插入完成");
109315
+ if (blockMenuFn) {
109316
+ blockMenuFn(false);
109317
+ }
109318
+ }
109319
+ },
109320
+ onComplete: () => {
109321
+ editor.setEditable(originalEditable);
109322
+ if (blockMenuFn) {
109323
+ blockMenuFn(false);
109324
+ }
109325
+ }
109326
+ });
109327
+ } else {
109328
+ editor.chain().focus().insertContent(json2.content).run();
109329
+ setTimeout(() => {
109330
+ editor.view.updateState(editor.state);
109331
+ const { tr: tr2 } = editor.state;
109332
+ editor.view.dispatch(tr2);
109333
+ editor.commands.focus();
109334
+ }, 0);
109335
+ }
109336
+ }
109337
+ } catch (error2) {
109338
+ try {
109339
+ editor.chain().focus().insertContent(text2).run();
109340
+ ElMessage.warning("Markdown 解析失败,已作为纯文本插入");
109341
+ } catch (insertError) {
109342
+ ElMessage.error("内容插入失败,请检查控制台");
109343
+ }
109043
109344
  }
109044
- }).catch((error2) => {
109045
- console.error("Error during image upload:", error2);
109046
- ElMessage.error("图片上传失败");
109047
- });
109048
- return true;
109345
+ return true;
109346
+ }
109347
+ return false;
109049
109348
  },
109050
109349
  handleDOMEvents: {
109051
109350
  // beforeinput: (view, event) => {
@@ -112148,6 +112447,7 @@ const _sfc_main = {
112148
112447
  function applySourceCode() {
112149
112448
  try {
112150
112449
  isLoading.value = true;
112450
+ editor.commands.clearContent();
112151
112451
  loadContentInChunks({
112152
112452
  editor,
112153
112453
  content: sourceCode.value,
@@ -112327,7 +112627,7 @@ const _sfc_main = {
112327
112627
  };
112328
112628
  }
112329
112629
  };
112330
- const TiptapVue = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8ba51e61"]]);
112630
+ const TiptapVue = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4855cd8e"]]);
112331
112631
  const components = [
112332
112632
  {
112333
112633
  name: "TiptapVue",