@8btc/mditor 0.0.12 → 0.0.14

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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.12 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.14 - A markdown editor written in TypeScript.
3
3
  *
4
4
  * MIT License
5
5
  *
@@ -2486,6 +2486,8 @@ var speechRender = function (element, lang) {
2486
2486
  });
2487
2487
  };
2488
2488
 
2489
+ // EXTERNAL MODULE: ./src/ts/markdown/selectionRender.ts
2490
+ var selectionRender = __webpack_require__(616);
2489
2491
  ;// CONCATENATED MODULE: ./src/ts/markdown/previewRender.ts
2490
2492
  var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
2491
2493
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -2543,6 +2545,7 @@ var __generator = (undefined && undefined.__generator) || function (thisArg, bod
2543
2545
 
2544
2546
 
2545
2547
 
2548
+
2546
2549
 
2547
2550
 
2548
2551
  var mergeOptions = function (options) {
@@ -2673,6 +2676,7 @@ var previewRender = function (previewElement, markdown, options) { return __awai
2673
2676
  (0,mindmapRender/* mindmapRender */.P)(previewElement, mergedOptions.cdn, mergedOptions.mode);
2674
2677
  (0,plantumlRender/* plantumlRender */.B)(previewElement, mergedOptions.cdn);
2675
2678
  (0,abcRender/* abcRender */.Q)(previewElement, mergedOptions.cdn);
2679
+ (0,selectionRender/* selectionRender */.V)(previewElement);
2676
2680
  if (mergedOptions.render.media.enable) {
2677
2681
  (0,mediaRender/* mediaRender */.Y)(previewElement);
2678
2682
  }
@@ -2733,6 +2737,7 @@ var attachLineNumbers = __webpack_require__(626);
2733
2737
 
2734
2738
 
2735
2739
 
2740
+
2736
2741
 
2737
2742
 
2738
2743
  var Vditor = /** @class */ (function () {
@@ -2793,6 +2798,8 @@ var Vditor = /** @class */ (function () {
2793
2798
  Vditor.mediaRender = mediaRender/* mediaRender */.Y;
2794
2799
  /** 对选中的文字进行阅读 */
2795
2800
  Vditor.speechRender = speechRender;
2801
+ /** 渲染 selection 代码块为文件选择标签 */
2802
+ Vditor.selectionRender = selectionRender/* selectionRender */.V;
2796
2803
  /** 对图片进行懒加载 */
2797
2804
  Vditor.lazyLoadImageRender = lazyLoadImageRender;
2798
2805
  /** Markdown 文本转换为 HTML,该方法需使用[异步编程](https://ld246.com/article/1546828434083?r=Vaness) */
@@ -2818,7 +2825,7 @@ var Vditor = /** @class */ (function () {
2818
2825
  /* harmony export */ "H": () => (/* binding */ _VDITOR_VERSION),
2819
2826
  /* harmony export */ "g": () => (/* binding */ Constants)
2820
2827
  /* harmony export */ });
2821
- var _VDITOR_VERSION = "0.0.12";
2828
+ var _VDITOR_VERSION = "0.0.14";
2822
2829
 
2823
2830
  var Constants = /** @class */ (function () {
2824
2831
  function Constants() {
@@ -3120,7 +3127,7 @@ var Constants = /** @class */ (function () {
3120
3127
  "c#",
3121
3128
  "bat",
3122
3129
  ];
3123
- Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.12");
3130
+ Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.14");
3124
3131
  Constants.MARKDOWN_OPTIONS = {
3125
3132
  autoSpace: false,
3126
3133
  gfmAutoLink: true,
@@ -5981,6 +5988,40 @@ var plantumlRender = function (element, cdn) {
5981
5988
  };
5982
5989
 
5983
5990
 
5991
+ /***/ }),
5992
+
5993
+ /***/ 616:
5994
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5995
+
5996
+ "use strict";
5997
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5998
+ /* harmony export */ "V": () => (/* binding */ selectionRender)
5999
+ /* harmony export */ });
6000
+ /**
6001
+ * 渲染 selection 代码块为文件选择标签
6002
+ */
6003
+ var selectionRender = function (element) {
6004
+ element.querySelectorAll("pre > code.language-selection").forEach(function (codeElement) {
6005
+ var preElement = codeElement.parentElement;
6006
+ var content = codeElement.textContent.trim();
6007
+ var lines = content.split('\n');
6008
+ var tags = lines.map(function (line) {
6009
+ var match = line.trim().match(/^(.+?)\s+(\d+-\d+)$/);
6010
+ if (match) {
6011
+ var filename = match[1], lineRange = match[2];
6012
+ return "<div class=\"vditor-selection-tag\">\n <span class=\"vditor-selection-tag__file\">".concat(filename, "</span>\n <span class=\"vditor-selection-tag__lines\">").concat(lineRange, "</span>\n </div>");
6013
+ }
6014
+ return '';
6015
+ }).filter(function (tag) { return tag; }).join('');
6016
+ if (tags) {
6017
+ var container = document.createElement('div');
6018
+ container.innerHTML = tags;
6019
+ preElement.parentNode.replaceChild(container, preElement);
6020
+ }
6021
+ });
6022
+ };
6023
+
6024
+
5984
6025
  /***/ }),
5985
6026
 
5986
6027
  /***/ 214:
@@ -6203,16 +6244,28 @@ var addStyle = function (url, id) {
6203
6244
  /* harmony export */ "g": () => (/* binding */ attachLineNumbersToBlocksThrottled)
6204
6245
  /* harmony export */ });
6205
6246
  /**
6206
- * 为编辑区域添加行号标记:
6207
- * - 为所有包含 `data-block` 的块级节点写入 `data-linenumber`
6208
- * - 额外为每个 `ul` 的直接 `li` 子元素写入 `data-linenumber`(不修改 `ul` 本身)
6209
- * 通过解析传入的 Markdown 源文本,建立内容到源文件行号的映射,
6210
- * 兼顾多行文本、嵌套列表、重复内容及空白/特殊字符,并提供基础错误保护。
6247
+ * 功能:为编辑区域批量添加行号与列表/表格标记(O(n))
6248
+ * - 块级:为所有 `data-block` 写入 `data-linenumber`
6249
+ * - 列表:为 `ul/ol > li` 写入 `data-linenumber`、`data-list-level`、`data-list-number`
6250
+ * - 表格:为 `table` 的 `tr` 写入 `data-linenumber`(不为 `th` 设置)
6251
+ * - 性能:一次解析 Markdown 建索引,批量收集并一次性更新属性,缓存避免重复计算
6252
+ * - 精度:支持嵌套列表、换行列表项、多级序号;表格跨页连续行号,容忍合并单元格
6211
6253
  */
6212
6254
  var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6255
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
6213
6256
  if (!root || !sourceMarkdown) {
6214
6257
  return;
6215
6258
  }
6259
+ var t0 = performance.now();
6260
+ var computeHash = function (s) {
6261
+ var h = 0;
6262
+ for (var i = 0; i < s.length; i++) {
6263
+ h = (h * 31 + s.charCodeAt(i)) | 0;
6264
+ }
6265
+ return "".concat(s.length, ":").concat(h);
6266
+ };
6267
+ var GLOBAL_CACHE = globalThis.__VDITOR_LINE_CACHE__ || new Map();
6268
+ globalThis.__VDITOR_LINE_CACHE__ = GLOBAL_CACHE;
6216
6269
  var ZWSP = "\u200b";
6217
6270
  var normalize = function (text) {
6218
6271
  return text
@@ -6223,7 +6276,10 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6223
6276
  .replace(/[\t\f\v ]+/g, " ");
6224
6277
  };
6225
6278
  var srcNorm = normalize(sourceMarkdown);
6226
- var srcLines = srcNorm.split("\n");
6279
+ var tNorm = performance.now();
6280
+ var hash = computeHash(srcNorm);
6281
+ var cached = GLOBAL_CACHE.get(hash);
6282
+ var srcLines = (_a = cached === null || cached === void 0 ? void 0 : cached.srcLines) !== null && _a !== void 0 ? _a : srcNorm.split("\n");
6227
6283
  var stripInlineMD = function (text) {
6228
6284
  return (text
6229
6285
  .replace(/\\([*_`~])/g, "$1")
@@ -6252,15 +6308,17 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6252
6308
  .replace(/[{}]/g, "")
6253
6309
  .trim());
6254
6310
  };
6255
- var strippedLines = srcLines.map(function (l) { return stripInlineMD(l); });
6256
- var lineLookup = new Map();
6257
- for (var i = 0; i < strippedLines.length; i++) {
6258
- var key = strippedLines[i];
6259
- if (!lineLookup.has(key)) {
6260
- lineLookup.set(key, [i + 1]);
6261
- }
6262
- else {
6263
- lineLookup.get(key).push(i + 1);
6311
+ var strippedLines = (_b = cached === null || cached === void 0 ? void 0 : cached.strippedLines) !== null && _b !== void 0 ? _b : srcLines.map(function (l) { return stripInlineMD(l); });
6312
+ var lineLookup = (_c = cached === null || cached === void 0 ? void 0 : cached.lineLookup) !== null && _c !== void 0 ? _c : new Map();
6313
+ if (!cached) {
6314
+ for (var i = 0; i < strippedLines.length; i++) {
6315
+ var key = strippedLines[i];
6316
+ if (!lineLookup.has(key)) {
6317
+ lineLookup.set(key, [i + 1]);
6318
+ }
6319
+ else {
6320
+ lineLookup.get(key).push(i + 1);
6321
+ }
6264
6322
  }
6265
6323
  }
6266
6324
  var usedLines = new Set();
@@ -6292,20 +6350,25 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6292
6350
  * 预处理:收集 Markdown 中所有无序列表(ul)行及其去除行内标记后的内容,构建快速查找结构。
6293
6351
  * 仅匹配以 `*`、`-`、`+` 开头的条目,支持任务列表如 `- [ ]`、`* [x]`。
6294
6352
  */
6295
- var unorderedListEntries = [];
6296
- var unorderedLookup = new Map();
6353
+ var unorderedListEntries = (_d = cached === null || cached === void 0 ? void 0 : cached.unorderedListEntries) !== null && _d !== void 0 ? _d : [];
6354
+ var unorderedLookup = (_e = cached === null || cached === void 0 ? void 0 : cached.unorderedLookup) !== null && _e !== void 0 ? _e : new Map();
6297
6355
  var usedUnorderedLines = new Set();
6298
- for (var i = 0; i < srcLines.length; i++) {
6299
- var raw = srcLines[i];
6300
- var m = raw.match(/^\s*[*+-]\s+(?:\[(?: |x|X)\]\s+)?(.*)$/);
6301
- if (m && typeof m[1] === "string") {
6302
- var contentStripped = stripInlineForList(m[1]);
6303
- unorderedListEntries.push({ ln: i + 1, content: contentStripped });
6304
- if (!unorderedLookup.has(contentStripped)) {
6305
- unorderedLookup.set(contentStripped, [i + 1]);
6306
- }
6307
- else {
6308
- unorderedLookup.get(contentStripped).push(i + 1);
6356
+ if (!cached) {
6357
+ for (var i = 0; i < srcLines.length; i++) {
6358
+ var raw = srcLines[i];
6359
+ var m = raw.match(/^\s*[*+-]\s+(?:\[(?: |x|X)\]\s+)?(.*)$/);
6360
+ if (m && typeof m[1] === "string") {
6361
+ var contentStripped = stripInlineForList(m[1]);
6362
+ unorderedListEntries.push({
6363
+ ln: i + 1,
6364
+ content: contentStripped,
6365
+ });
6366
+ if (!unorderedLookup.has(contentStripped)) {
6367
+ unorderedLookup.set(contentStripped, [i + 1]);
6368
+ }
6369
+ else {
6370
+ unorderedLookup.get(contentStripped).push(i + 1);
6371
+ }
6309
6372
  }
6310
6373
  }
6311
6374
  }
@@ -6346,44 +6409,48 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6346
6409
  /**
6347
6410
  * 预处理:收集 Markdown 中所有有序列表(ol)行及其内容,支持 `1.` 或 `1)` 以及任务列表前缀。
6348
6411
  */
6349
- var orderedListEntries = [];
6350
- var orderedLookup = new Map();
6412
+ var orderedListEntries = (_f = cached === null || cached === void 0 ? void 0 : cached.orderedListEntries) !== null && _f !== void 0 ? _f : [];
6413
+ var orderedLookup = (_g = cached === null || cached === void 0 ? void 0 : cached.orderedLookup) !== null && _g !== void 0 ? _g : new Map();
6351
6414
  var usedOrderedLines = new Set();
6352
6415
  var ORDERED_RE = /\s*\d+(?:[.)、.。]|[\uFF0E\uFF09\u3001])\s+(?:\[(?: |x|X)\]\s+)?(.*)/;
6353
6416
  var ORDERED_FULL = new RegExp("^".concat(ORDERED_RE.source, "$"));
6354
- for (var i = 0; i < srcLines.length; i++) {
6355
- var raw = srcLines[i];
6356
- var m = raw.match(ORDERED_FULL);
6357
- if (m && typeof m[1] === "string") {
6358
- var contentStripped = stripInlineForList(m[1]);
6359
- orderedListEntries.push({ ln: i + 1, content: contentStripped });
6360
- if (!orderedLookup.has(contentStripped)) {
6361
- orderedLookup.set(contentStripped, [i + 1]);
6362
- }
6363
- else {
6364
- orderedLookup.get(contentStripped).push(i + 1);
6417
+ if (!cached) {
6418
+ for (var i = 0; i < srcLines.length; i++) {
6419
+ var raw = srcLines[i];
6420
+ var m = raw.match(ORDERED_FULL);
6421
+ if (m && typeof m[1] === "string") {
6422
+ var contentStripped = stripInlineForList(m[1]);
6423
+ orderedListEntries.push({
6424
+ ln: i + 1,
6425
+ content: contentStripped,
6426
+ });
6427
+ if (!orderedLookup.has(contentStripped)) {
6428
+ orderedLookup.set(contentStripped, [i + 1]);
6429
+ }
6430
+ else {
6431
+ orderedLookup.get(contentStripped).push(i + 1);
6432
+ }
6365
6433
  }
6366
6434
  }
6367
6435
  }
6368
- console.debug("[LineNumber][ol:index]", {
6369
- total: orderedListEntries.length,
6370
- });
6371
- var orderedGroups = [];
6372
- for (var i = 0; i < srcLines.length;) {
6373
- var raw = srcLines[i];
6374
- if (ORDERED_FULL.test(raw)) {
6375
- var group = [];
6376
- while (i < srcLines.length && ORDERED_FULL.test(srcLines[i])) {
6377
- group.push(i + 1);
6378
- i++;
6436
+ var orderedGroups = (_h = cached === null || cached === void 0 ? void 0 : cached.orderedGroups) !== null && _h !== void 0 ? _h : [];
6437
+ if (!cached) {
6438
+ for (var i = 0; i < srcLines.length;) {
6439
+ var raw = srcLines[i];
6440
+ if (ORDERED_FULL.test(raw)) {
6441
+ var group = [];
6442
+ while (i < srcLines.length && ORDERED_FULL.test(srcLines[i])) {
6443
+ group.push(i + 1);
6444
+ i++;
6445
+ }
6446
+ if (group.length > 0) {
6447
+ orderedGroups.push(group);
6448
+ }
6379
6449
  }
6380
- if (group.length > 0) {
6381
- orderedGroups.push(group);
6450
+ else {
6451
+ i++;
6382
6452
  }
6383
6453
  }
6384
- else {
6385
- i++;
6386
- }
6387
6454
  }
6388
6455
  /**
6389
6456
  * 为给定文本在有序列表候选中选择行号,精确匹配优先,包含匹配回退。
@@ -6435,6 +6502,7 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6435
6502
  });
6436
6503
  return buf;
6437
6504
  };
6505
+ var attrUpdates = [];
6438
6506
  var blocks = root.querySelectorAll("[data-block]");
6439
6507
  blocks.forEach(function (el) {
6440
6508
  try {
@@ -6443,22 +6511,26 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6443
6511
  if (dataType === "math-block" || dataType === "code-block") {
6444
6512
  return;
6445
6513
  }
6446
- // 仅 li 需要行号:跳过并清理 ul/ol 自身及其内部嵌套的 p/div 等块
6447
6514
  var tagName = container.tagName;
6448
6515
  if (tagName === "UL" || tagName === "OL") {
6449
- container.removeAttribute("data-linenumber");
6516
+ if (container.getAttribute("data-linenumber")) {
6517
+ attrUpdates.push([container, "data-linenumber", ""]);
6518
+ }
6450
6519
  return;
6451
6520
  }
6452
6521
  var liAncestor = container.closest("li");
6453
6522
  if (liAncestor) {
6454
- container.removeAttribute("data-linenumber");
6523
+ if (container.getAttribute("data-linenumber")) {
6524
+ attrUpdates.push([container, "data-linenumber", ""]);
6525
+ }
6455
6526
  return;
6456
6527
  }
6457
6528
  var text = container.textContent || "";
6458
6529
  var normText = normalize(text);
6459
- // 跳过纯空白块
6460
6530
  if (!normText.trim()) {
6461
- container.removeAttribute("data-linenumber");
6531
+ if (container.getAttribute("data-linenumber")) {
6532
+ attrUpdates.push([container, "data-linenumber", ""]);
6533
+ }
6462
6534
  return;
6463
6535
  }
6464
6536
  var lineNumber = -1;
@@ -6485,13 +6557,18 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6485
6557
  }
6486
6558
  if (lineNumber !== -1) {
6487
6559
  usedLines.add(lineNumber);
6488
- container.setAttribute("data-linenumber", String(lineNumber));
6560
+ var cur = container.getAttribute("data-linenumber");
6561
+ var val = String(lineNumber);
6562
+ if (cur !== val) {
6563
+ attrUpdates.push([container, "data-linenumber", val]);
6564
+ }
6489
6565
  }
6490
6566
  }
6491
6567
  catch (_a) {
6492
6568
  void 0;
6493
6569
  }
6494
6570
  });
6571
+ var tBlockDone = performance.now();
6495
6572
  /**
6496
6573
  * 为所有 `ul` 下的每个直接 `li` 子元素追加 `data-linenumber`,不修改 `ul` 本身。
6497
6574
  * 支持多层嵌套与非文本起始节点(如加粗/行内代码)。
@@ -6500,60 +6577,93 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6500
6577
  ulElements.forEach(function (ul) {
6501
6578
  try {
6502
6579
  var children = Array.from(ul.children);
6503
- for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
6504
- var child = children_1[_i];
6580
+ var _loop_1 = function (child) {
6505
6581
  if (child.tagName !== "LI")
6506
- continue;
6582
+ return "continue";
6507
6583
  var li = child;
6508
6584
  var rawText = getImmediateLiText(li);
6509
6585
  var norm = normalize(rawText);
6510
6586
  var firstLine = norm.split("\n").find(function (l) { return l.trim().length > 0; }) || norm;
6511
6587
  var ln = findUnorderedListLineNumber(firstLine);
6588
+ var level = (function () {
6589
+ var depth = 0;
6590
+ var p = li;
6591
+ while (p) {
6592
+ p = p.parentElement;
6593
+ if (!p)
6594
+ break;
6595
+ var tag = p.tagName;
6596
+ if (tag === "UL" || tag === "OL")
6597
+ depth++;
6598
+ }
6599
+ return depth;
6600
+ })();
6601
+ var levelStr = String(level);
6602
+ var curLevel = li.getAttribute("data-list-level");
6603
+ if (curLevel !== levelStr) {
6604
+ attrUpdates.push([li, "data-list-level", levelStr]);
6605
+ }
6512
6606
  if (ln !== -1) {
6513
6607
  usedUnorderedLines.add(ln);
6514
- li.setAttribute("data-linenumber", String(ln));
6608
+ var curLn = li.getAttribute("data-linenumber");
6609
+ var val = String(ln);
6610
+ if (curLn !== val) {
6611
+ attrUpdates.push([li, "data-linenumber", val]);
6612
+ }
6515
6613
  }
6516
6614
  else {
6517
- li.setAttribute("data-linenumber", "");
6615
+ if (li.getAttribute("data-linenumber")) {
6616
+ attrUpdates.push([li, "data-linenumber", ""]);
6617
+ }
6518
6618
  }
6619
+ };
6620
+ for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
6621
+ var child = children_1[_i];
6622
+ _loop_1(child);
6519
6623
  }
6520
6624
  }
6521
6625
  catch (_a) {
6522
6626
  void 0;
6523
6627
  }
6524
6628
  });
6629
+ var tUlDone = performance.now();
6525
6630
  /**
6526
6631
  * 为所有 `ol` 下的每个直接 `li` 子元素追加 `data-linenumber`,不修改 `ol` 本身。
6527
6632
  */
6528
6633
  var olElements = root.querySelectorAll("ol");
6634
+ var orderedIndexMap = new WeakMap();
6529
6635
  olElements.forEach(function (ol) {
6530
6636
  try {
6531
6637
  var currentGroupIdx = -1;
6532
6638
  var lastAssigned_1 = -1;
6639
+ var startAttr = Number(ol.getAttribute("start"));
6640
+ var start = Number.isFinite(startAttr) && startAttr > 0 ? startAttr : 1;
6533
6641
  var children = Array.from(ol.children);
6642
+ var seq = start;
6534
6643
  for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
6535
6644
  var child = children_2[_i];
6536
6645
  if (child.tagName !== "LI")
6537
6646
  continue;
6647
+ orderedIndexMap.set(child, seq++);
6648
+ }
6649
+ var _loop_2 = function (child) {
6650
+ if (child.tagName !== "LI")
6651
+ return "continue";
6538
6652
  var li = child;
6539
6653
  var rawText = getImmediateLiText(li);
6540
6654
  var norm = normalize(rawText);
6541
6655
  var firstLine = norm.split("\n").find(function (l) { return l.trim().length > 0; }) || norm;
6542
6656
  var stripped0 = stripInlineForList(firstLine);
6543
6657
  var stripped = stripped0 || stripInlineMD(firstLine);
6544
- var candidates = orderedLookup.get(stripped) || [];
6545
- var available = candidates.filter(function (n) { return !usedOrderedLines.has(n); });
6658
+ orderedLookup.get(stripped);
6546
6659
  var ln = findOrderedListLineNumber(firstLine);
6547
6660
  if (ln !== -1) {
6548
6661
  usedOrderedLines.add(ln);
6549
- li.setAttribute("data-linenumber", String(ln));
6550
- // 成功映射日志
6551
- console.debug("[LineNumber][ol>li]", {
6552
- text: firstLine,
6553
- stripped: stripped,
6554
- line: ln,
6555
- });
6556
- // 记录当前组
6662
+ var cur = li.getAttribute("data-linenumber");
6663
+ var val = String(ln);
6664
+ if (cur !== val) {
6665
+ attrUpdates.push([li, "data-linenumber", val]);
6666
+ }
6557
6667
  for (var gi = 0; gi < orderedGroups.length; gi++) {
6558
6668
  if (orderedGroups[gi].includes(ln)) {
6559
6669
  currentGroupIdx = gi;
@@ -6563,13 +6673,11 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6563
6673
  lastAssigned_1 = ln;
6564
6674
  }
6565
6675
  else {
6566
- // 顺序回退:基于当前组或猜测组,按序分配下一未使用行
6567
6676
  var assigned = -1;
6568
6677
  var pickNextFromGroup = function (gi) {
6569
6678
  if (gi < 0 || gi >= orderedGroups.length)
6570
6679
  return -1;
6571
6680
  var lines = orderedGroups[gi];
6572
- // 优先从上次分配后续查找
6573
6681
  var startIdx = 0;
6574
6682
  if (lastAssigned_1 !== -1) {
6575
6683
  var idx = lines.indexOf(lastAssigned_1);
@@ -6591,7 +6699,6 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6591
6699
  assigned = pickNextFromGroup(currentGroupIdx);
6592
6700
  }
6593
6701
  if (assigned === -1) {
6594
- // 猜测组:选择拥有可用行的首个组
6595
6702
  for (var gi = 0; gi < orderedGroups.length && assigned === -1; gi++) {
6596
6703
  var cand = pickNextFromGroup(gi);
6597
6704
  if (cand !== -1) {
@@ -6602,39 +6709,229 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
6602
6709
  }
6603
6710
  if (assigned !== -1) {
6604
6711
  usedOrderedLines.add(assigned);
6605
- li.setAttribute("data-linenumber", String(assigned));
6606
- console.debug("[LineNumber][ol>li][fallback-seq]", {
6607
- text: firstLine,
6608
- stripped: stripped,
6609
- line: assigned,
6610
- group: currentGroupIdx,
6611
- });
6712
+ var cur = li.getAttribute("data-linenumber");
6713
+ var val = String(assigned);
6714
+ if (cur !== val) {
6715
+ attrUpdates.push([li, "data-linenumber", val]);
6716
+ }
6612
6717
  lastAssigned_1 = assigned;
6613
6718
  }
6614
6719
  else {
6615
- li.setAttribute("data-linenumber", "");
6616
- // 失败诊断日志
6617
- console.warn("[LineNumber][ol>li][missing]", {
6618
- text: firstLine,
6619
- stripped: stripped,
6620
- candidates: candidates,
6621
- available: available,
6622
- reason: !stripped0
6623
- ? "empty-after-strip"
6624
- : candidates.length === 0
6625
- ? "no-index-candidates"
6626
- : available.length === 0
6627
- ? "all-candidates-consumed"
6628
- : "fallback-no-match",
6629
- });
6720
+ if (li.getAttribute("data-linenumber")) {
6721
+ attrUpdates.push([li, "data-linenumber", ""]);
6722
+ }
6630
6723
  }
6631
6724
  }
6725
+ var level = (function () {
6726
+ var depth = 0;
6727
+ var p = li;
6728
+ while (p) {
6729
+ p = p.parentElement;
6730
+ if (!p)
6731
+ break;
6732
+ var tag = p.tagName;
6733
+ if (tag === "UL" || tag === "OL")
6734
+ depth++;
6735
+ }
6736
+ return depth;
6737
+ })();
6738
+ var levelStr = String(level);
6739
+ var curLevel = li.getAttribute("data-list-level");
6740
+ if (curLevel !== levelStr) {
6741
+ attrUpdates.push([li, "data-list-level", levelStr]);
6742
+ }
6743
+ var numbering = (function () {
6744
+ var _a;
6745
+ var parts = [];
6746
+ var node = li;
6747
+ while (node) {
6748
+ var parentOl = node.closest("ol");
6749
+ if (!parentOl)
6750
+ break;
6751
+ var parentLi = ((_a = parentOl.parentElement) === null || _a === void 0 ? void 0 : _a.closest("li")) ||
6752
+ parentOl.parentElement;
6753
+ var idx = orderedIndexMap.get(node);
6754
+ if (typeof idx === "number") {
6755
+ parts.push(idx);
6756
+ }
6757
+ node = parentLi;
6758
+ }
6759
+ return parts.reverse().join(".");
6760
+ })();
6761
+ var curNum = li.getAttribute("data-list-number") || "";
6762
+ if (numbering && curNum !== numbering) {
6763
+ attrUpdates.push([li, "data-list-number", numbering]);
6764
+ }
6765
+ };
6766
+ for (var _a = 0, children_3 = children; _a < children_3.length; _a++) {
6767
+ var child = children_3[_a];
6768
+ _loop_2(child);
6632
6769
  }
6633
6770
  }
6771
+ catch (_b) {
6772
+ void 0;
6773
+ }
6774
+ });
6775
+ var tOlDone = performance.now();
6776
+ var tableRowLookup = (_j = cached === null || cached === void 0 ? void 0 : cached.tableRowLookup) !== null && _j !== void 0 ? _j : new Map();
6777
+ var tableGroups = (_k = cached === null || cached === void 0 ? void 0 : cached.tableGroups) !== null && _k !== void 0 ? _k : [];
6778
+ if (!cached) {
6779
+ var isTableRowLine = function (line) {
6780
+ return /^\s*\|.*\|\s*$/.test(line);
6781
+ };
6782
+ var isAlignLine = function (line) {
6783
+ return /^\s*\|?(?:\s*:?-{2,}:?\s*\|)+\s*:?-{2,}:?\s*\|?\s*$/.test(line);
6784
+ };
6785
+ for (var i = 0; i < srcLines.length;) {
6786
+ var header = srcLines[i];
6787
+ var align = srcLines[i + 1];
6788
+ if (isTableRowLine(header) && isAlignLine(align || "")) {
6789
+ var groupRows = [i + 1];
6790
+ var groupRowTexts = [
6791
+ stripInlineMD(header.replace(/^\s*\|?|\|?\s*$/g, "")),
6792
+ ];
6793
+ i += 2;
6794
+ while (i < srcLines.length && isTableRowLine(srcLines[i])) {
6795
+ groupRows.push(i + 1);
6796
+ groupRowTexts.push(stripInlineMD(srcLines[i].replace(/^\s*\|?|\|?\s*$/g, "")));
6797
+ i++;
6798
+ }
6799
+ tableGroups.push({
6800
+ rows: groupRows,
6801
+ rowTexts: groupRowTexts,
6802
+ });
6803
+ for (var t = 0; t < groupRowTexts.length; t++) {
6804
+ var key = groupRowTexts[t];
6805
+ var ln = groupRows[t];
6806
+ var arr = tableRowLookup.get(key);
6807
+ if (arr)
6808
+ arr.push(ln);
6809
+ else
6810
+ tableRowLookup.set(key, [ln]);
6811
+ }
6812
+ }
6813
+ else {
6814
+ i++;
6815
+ }
6816
+ }
6817
+ }
6818
+ var usedTableLines = new Set();
6819
+ var tIndexDone = performance.now();
6820
+ var tables = root.querySelectorAll("table");
6821
+ var groupPtr = 0;
6822
+ tables.forEach(function (table) {
6823
+ try {
6824
+ var trs = table.querySelectorAll("tr");
6825
+ trs.forEach(function (tr) {
6826
+ var cells = Array.from(tr.cells);
6827
+ var rowText = cells.map(function (c) { return c.textContent || ""; }).join("|");
6828
+ var normRow = stripInlineMD(normalize(rowText));
6829
+ var ln = pickFirstUnused(tableRowLookup.get(normRow));
6830
+ if (ln === -1) {
6831
+ while (groupPtr < tableGroups.length &&
6832
+ tableGroups[groupPtr].rows.every(function (r) {
6833
+ return usedTableLines.has(r);
6834
+ })) {
6835
+ groupPtr++;
6836
+ }
6837
+ if (groupPtr < tableGroups.length) {
6838
+ var g = tableGroups[groupPtr];
6839
+ var chosen = -1;
6840
+ for (var k = 0; k < g.rows.length; k++) {
6841
+ var cand = g.rows[k];
6842
+ if (!usedTableLines.has(cand)) {
6843
+ chosen = cand;
6844
+ break;
6845
+ }
6846
+ }
6847
+ ln = chosen;
6848
+ }
6849
+ }
6850
+ if (ln !== -1) {
6851
+ usedTableLines.add(ln);
6852
+ var cur = tr.getAttribute("data-linenumber");
6853
+ var val = String(ln);
6854
+ if (cur !== val) {
6855
+ attrUpdates.push([
6856
+ tr,
6857
+ "data-linenumber",
6858
+ val,
6859
+ ]);
6860
+ }
6861
+ }
6862
+ else {
6863
+ var cur = tr.getAttribute("data-linenumber");
6864
+ if (cur) {
6865
+ attrUpdates.push([
6866
+ tr,
6867
+ "data-linenumber",
6868
+ "",
6869
+ ]);
6870
+ }
6871
+ }
6872
+ var ths = tr.querySelectorAll("th");
6873
+ ths.forEach(function (th) {
6874
+ var curTh = th.getAttribute("data-linenumber");
6875
+ if (curTh) {
6876
+ attrUpdates.push([
6877
+ th,
6878
+ "data-linenumber",
6879
+ "",
6880
+ ]);
6881
+ }
6882
+ });
6883
+ });
6884
+ }
6634
6885
  catch (_a) {
6635
6886
  void 0;
6636
6887
  }
6637
6888
  });
6889
+ var tTableDone = performance.now();
6890
+ for (var _i = 0, attrUpdates_1 = attrUpdates; _i < attrUpdates_1.length; _i++) {
6891
+ var _l = attrUpdates_1[_i], el = _l[0], attr = _l[1], val = _l[2];
6892
+ if (val === "") {
6893
+ el.removeAttribute(attr);
6894
+ }
6895
+ else {
6896
+ el.setAttribute(attr, val);
6897
+ }
6898
+ }
6899
+ var tApplyDone = performance.now();
6900
+ if (!cached) {
6901
+ GLOBAL_CACHE.set(hash, {
6902
+ srcNorm: srcNorm,
6903
+ srcLines: srcLines,
6904
+ strippedLines: strippedLines,
6905
+ lineLookup: lineLookup,
6906
+ unorderedListEntries: unorderedListEntries,
6907
+ unorderedLookup: unorderedLookup,
6908
+ orderedListEntries: orderedListEntries,
6909
+ orderedLookup: orderedLookup,
6910
+ orderedGroups: orderedGroups,
6911
+ tableRowLookup: tableRowLookup,
6912
+ tableGroups: tableGroups,
6913
+ });
6914
+ }
6915
+ console.log("[LineNumber][perf]", {
6916
+ cached: !!cached,
6917
+ times: {
6918
+ normalize: Math.round((tNorm - t0) * 100) / 100,
6919
+ index: Math.round((tIndexDone - tNorm) * 100) / 100,
6920
+ blocks: Math.round((tBlockDone - tIndexDone) * 100) / 100,
6921
+ ul: Math.round((tUlDone - tBlockDone) * 100) / 100,
6922
+ ol: Math.round((tOlDone - tUlDone) * 100) / 100,
6923
+ table: Math.round((tTableDone - tIndexDone) * 100) / 100,
6924
+ apply: Math.round((tApplyDone - tTableDone) * 100) / 100,
6925
+ total: Math.round((tApplyDone - t0) * 100) / 100,
6926
+ },
6927
+ counts: {
6928
+ blocks: blocks.length,
6929
+ ul: ulElements.length,
6930
+ ol: olElements.length,
6931
+ tables: tables.length,
6932
+ updates: attrUpdates.length,
6933
+ },
6934
+ });
6638
6935
  };
6639
6936
  /**
6640
6937
  * 节流后的行号更新函数,避免频繁更新 data-linenumber
@@ -15248,31 +15545,8 @@ var Outline = /** @class */ (function () {
15248
15545
 
15249
15546
  // EXTERNAL MODULE: ./src/ts/markdown/mediaRender.ts
15250
15547
  var mediaRender = __webpack_require__(280);
15251
- ;// CONCATENATED MODULE: ./src/ts/markdown/selectionRender.ts
15252
- /**
15253
- * 渲染 selection 代码块为文件选择标签
15254
- */
15255
- var selectionRender = function (element) {
15256
- element.querySelectorAll("pre > code.language-selection").forEach(function (codeElement) {
15257
- var preElement = codeElement.parentElement;
15258
- var content = codeElement.textContent.trim();
15259
- var lines = content.split('\n');
15260
- var tags = lines.map(function (line) {
15261
- var match = line.trim().match(/^(.+?)\s+(\d+-\d+)$/);
15262
- if (match) {
15263
- var filename = match[1], lineRange = match[2];
15264
- return "<div class=\"vditor-selection-tag\">\n <span class=\"vditor-selection-tag__file\">".concat(filename, "</span>\n <span class=\"vditor-selection-tag__lines\">").concat(lineRange, "</span>\n </div>");
15265
- }
15266
- return '';
15267
- }).filter(function (tag) { return tag; }).join('');
15268
- if (tags) {
15269
- var container = document.createElement('div');
15270
- container.innerHTML = tags;
15271
- preElement.parentNode.replaceChild(container, preElement);
15272
- }
15273
- });
15274
- };
15275
-
15548
+ // EXTERNAL MODULE: ./src/ts/markdown/selectionRender.ts
15549
+ var selectionRender = __webpack_require__(616);
15276
15550
  ;// CONCATENATED MODULE: ./src/ts/preview/index.ts
15277
15551
 
15278
15552
 
@@ -15455,7 +15729,7 @@ var Preview = /** @class */ (function () {
15455
15729
  if (vditor.options.preview.render.media.enable) {
15456
15730
  (0,mediaRender/* mediaRender */.Y)(vditor.preview.previewElement);
15457
15731
  }
15458
- selectionRender(vditor.preview.previewElement);
15732
+ (0,selectionRender/* selectionRender */.V)(vditor.preview.previewElement);
15459
15733
  vditor.options.customRenders.forEach(function (item) {
15460
15734
  {
15461
15735
  item.render(vditor.preview.previewElement, vditor);
@@ -17947,7 +18221,7 @@ var wysiwyg_generator = (undefined && undefined.__generator) || function (thisAr
17947
18221
  var WYSIWYG = /** @class */ (function () {
17948
18222
  function WYSIWYG(vditor) {
17949
18223
  var _this = this;
17950
- var _a, _b;
18224
+ var _a;
17951
18225
  this.composingLock = false;
17952
18226
  this.commentIds = [];
17953
18227
  this.vditor = vditor;
@@ -17956,7 +18230,7 @@ var WYSIWYG = /** @class */ (function () {
17956
18230
  if ((_a = vditor.options.lineNumber) === null || _a === void 0 ? void 0 : _a.enable) {
17957
18231
  divElement.classList.add("vditor--linenumber");
17958
18232
  }
17959
- divElement.innerHTML = "<pre class=\"vditor-reset\" placeholder=\"".concat(vditor.options.placeholder, "\"\n contenteditable=\"true\" spellcheck=\"false\"></pre>\n<div class=\"vditor-panel vditor-panel--none\"></div>\n<div class=\"vditor-selection-popover\">\n <div class=\"vditor-selection-popover__actions\">\n <button type=\"button\" data-action=\"ai\" aria-label=\"AI\u7F16\u8F91\" class=\"vditor-selection-popover__btn\" disabled>\u2728 AI\u7F16\u8F91</button>\n <button type=\"button\" data-action=\"cut\" aria-label=\"\u526A\u5207\" class=\"vditor-selection-popover__btn\">\u526A\u5207</button>\n <button type=\"button\" data-action=\"copy\" aria-label=\"\u590D\u5236\" class=\"vditor-selection-popover__btn\">\u590D\u5236</button>\n </div>\n <div class=\"vditor-selection-popover__input\">\n <textarea placeholder=\"\u8BF7\u8F93\u5165\u60A8\u60F3\u4FEE\u6539\u7684\u5185\u5BB9\"></textarea>\n <button class=\"vditor-selection-popover__send\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-sparkles-icon lucide-sparkles\"><path d=\"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\"/><path d=\"M20 2v4\"/><path d=\"M22 4h-4\"/><circle cx=\"4\" cy=\"20\" r=\"2\"/></svg>\n </button>\n </div>\n</div>");
18233
+ divElement.innerHTML = "<pre class=\"vditor-reset\" placeholder=\"".concat(vditor.options.placeholder, "\"\n contenteditable=\"true\" spellcheck=\"false\"></pre>\n<div class=\"vditor-panel vditor-panel--none\"></div>\n<div class=\"vditor-selection-popover\">\n <div class=\"vditor-selection-popover__actions\">\n <button type=\"button\" data-action=\"ai\" aria-label=\"AI\u7F16\u8F91\" class=\"vditor-selection-popover__btn\">\u2728 AI\u7F16\u8F91</button>\n <button type=\"button\" data-action=\"cut\" aria-label=\"\u526A\u5207\" class=\"vditor-selection-popover__btn\">\u526A\u5207</button>\n <button type=\"button\" data-action=\"copy\" aria-label=\"\u590D\u5236\" class=\"vditor-selection-popover__btn\">\u590D\u5236</button>\n </div>\n <div class=\"vditor-selection-popover__input\">\n <textarea placeholder=\"\u8BF7\u8F93\u5165\u60A8\u60F3\u4FEE\u6539\u7684\u5185\u5BB9\"></textarea>\n <button class=\"vditor-selection-popover__send\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-sparkles-icon lucide-sparkles\"><path d=\"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\"/><path d=\"M20 2v4\"/><path d=\"M22 4h-4\"/><circle cx=\"4\" cy=\"20\" r=\"2\"/></svg>\n </button>\n </div>\n</div>");
17960
18234
  this.element = divElement.firstElementChild;
17961
18235
  this.popover = divElement.firstElementChild
17962
18236
  .nextElementSibling;
@@ -17978,9 +18252,16 @@ var WYSIWYG = /** @class */ (function () {
17978
18252
  }
17979
18253
  _this.hideSelectionPopover();
17980
18254
  };
17981
- // 阻止点击输入区域时清除选区
17982
- (_b = this.selectPopover
17983
- .querySelector(".vditor-selection-popover__input")) === null || _b === void 0 ? void 0 : _b.addEventListener("mousedown", function (event) {
18255
+ // 阻止点击 popover 内任何区域时导致编辑器失去焦点
18256
+ // 但不影响 textarea 获取焦点和按钮点击
18257
+ this.selectPopover.addEventListener("mousedown", function (event) {
18258
+ var target = event.target;
18259
+ // 如果点击的是 textarea 或 button,允许默认行为
18260
+ if (target.tagName === "TEXTAREA" || target.tagName === "BUTTON") {
18261
+ return;
18262
+ }
18263
+ // 其他情况阻止默认行为,防止编辑器失去焦点
18264
+ event.preventDefault();
17984
18265
  event.stopPropagation();
17985
18266
  });
17986
18267
  // 输入验证
@@ -18004,16 +18285,18 @@ var WYSIWYG = /** @class */ (function () {
18004
18285
  copyEvent(vditor, this.element, this.copy);
18005
18286
  cutEvent(vditor, this.element, this.copy);
18006
18287
  // 选择浮窗按钮事件绑定
18007
- var aiBtn = this.selectPopover.querySelector('[data-action="ai"]');
18008
- if (aiBtn) {
18009
- /**
18010
- * AI编辑按钮占位事件
18011
- * - 当前仅输出日志,不执行编辑逻辑
18012
- */
18013
- aiBtn.onclick = function () {
18014
- console.log("[Selection AI Edit] clicked");
18015
- };
18016
- }
18288
+ // const aiBtn = this.selectPopover.querySelector(
18289
+ // '[data-action="ai"]'
18290
+ // ) as HTMLButtonElement | null;
18291
+ // if (aiBtn) {
18292
+ // /**
18293
+ // * AI编辑按钮占位事件
18294
+ // * - 当前仅输出日志,不执行编辑逻辑
18295
+ // */
18296
+ // aiBtn.onclick = () => {
18297
+ // console.log("[Selection AI Edit] clicked");
18298
+ // };
18299
+ // }
18017
18300
  var copyBtn = this.selectPopover.querySelector('[data-action="copy"]');
18018
18301
  if (copyBtn) {
18019
18302
  /**