@8btc/mditor 0.0.11 → 0.0.13

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.
@@ -27,6 +27,7 @@
27
27
  .vditor-reset {
28
28
  color: rgba(252, 252, 252, 0.9);
29
29
  text-autospace: normal;
30
+
30
31
  h1,
31
32
  h2,
32
33
  h3,
@@ -68,9 +69,11 @@
68
69
  .vditor-reset table tr {
69
70
  /* background-color: #2f363d; */
70
71
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
72
+
71
73
  th {
72
74
  color: #ffffff;
73
75
  }
76
+
74
77
  td {
75
78
  color: #fafafa;
76
79
  }
@@ -151,8 +154,10 @@
151
154
  width: 1rem;
152
155
  height: 1rem;
153
156
  border-radius: 0.25rem;
154
- border: 1px solid #0a0a0a; /* 未选中时黑色边框 */
155
- background-color: transparent; /* 未选中不填充背景 */
157
+ border: 1px solid #0a0a0a;
158
+ /* 未选中时黑色边框 */
159
+ background-color: transparent;
160
+ /* 未选中不填充背景 */
156
161
  position: relative;
157
162
  vertical-align: middle;
158
163
  margin-right: 0.38rem;
@@ -160,7 +165,8 @@
160
165
  }
161
166
 
162
167
  .vditor-task input[type="checkbox"]:checked {
163
- background-color: #fafafa; /* 选中时白底 */
168
+ background-color: #fafafa;
169
+ /* 选中时白底 */
164
170
  }
165
171
 
166
172
  .vditor-task input[type="checkbox"]:checked::after {
@@ -175,3 +181,13 @@
175
181
  top: 50%;
176
182
  transform: translate(-50%, -60%) rotate(45deg);
177
183
  }
184
+
185
+ .vditor-selection-popover__input .vditor-selection-popover__send {
186
+ color: #0a0a0a;
187
+ }
188
+
189
+ .vditor--linenumber {
190
+ .vditor-line-highlight {
191
+ color: #0a0a0a;
192
+ }
193
+ }
package/dist/index.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.8 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.13 - A markdown editor written in TypeScript.
3
3
  *
4
4
  * MIT License
5
5
  *
@@ -25,7 +25,7 @@
25
25
  *
26
26
  */
27
27
  /*!
28
- * Vditor v0.0.8 - A markdown editor written in TypeScript.
28
+ * Vditor v0.0.13 - A markdown editor written in TypeScript.
29
29
  *
30
30
  * MIT License
31
31
  *
@@ -1831,7 +1831,7 @@
1831
1831
  top: 0;
1832
1832
  width: 3em;
1833
1833
  text-align: right;
1834
- color: var(--second-color);
1834
+ color: rgba(252, 252, 252, 0.65);
1835
1835
  font-size: 0.75rem;
1836
1836
  line-height: inherit;
1837
1837
  -webkit-user-select: none;
@@ -1842,7 +1842,7 @@
1842
1842
  }
1843
1843
  .vditor--linenumber .vditor-reset .vditor-line-highlight {
1844
1844
  background-color: #fff3cd !important;
1845
- transition: background-color 0.3s ease-in-out;
1845
+ transition: background-color color 0.3s ease-in-out;
1846
1846
  }
1847
1847
  /* 数学右键菜单全局样式(参考 ECharts 菜单风格) */
1848
1848
  .vditor-math-menu {
@@ -1921,7 +1921,7 @@
1921
1921
  z-index: 4;
1922
1922
  display: none;
1923
1923
  padding: 0;
1924
- border-radius: 12px;
1924
+ border-radius: 8px;
1925
1925
  background-color: var(--panel-background-color);
1926
1926
  box-shadow: var(--panel-shadow);
1927
1927
  border: 1px solid var(--border-color);
@@ -1930,9 +1930,87 @@
1930
1930
  user-select: none;
1931
1931
  white-space: nowrap;
1932
1932
  transform-origin: top left;
1933
+ opacity: 0;
1933
1934
  transition: opacity 150ms cubic-bezier(0.2, 0, 0.13, 1.5), transform 150ms cubic-bezier(0.2, 0, 0.13, 1.5);
1935
+ flex-direction: column;
1936
+ flex-wrap: nowrap;
1937
+ }
1938
+ .vditor-selection-popover__actions {
1934
1939
  display: flex;
1940
+ flex-direction: row;
1935
1941
  align-items: center;
1942
+ width: 100%;
1943
+ border-bottom: 1px solid var(--border-color);
1944
+ }
1945
+ .vditor-selection-popover__input {
1946
+ display: flex;
1947
+ flex-direction: column;
1948
+ width: 327px;
1949
+ padding: 12px;
1950
+ gap: 8px;
1951
+ align-items: flex-end;
1952
+ box-sizing: border-box;
1953
+ }
1954
+ .vditor-selection-popover__input textarea {
1955
+ flex: 1;
1956
+ width: 100%;
1957
+ height: 60px;
1958
+ background: transparent;
1959
+ border: none;
1960
+ resize: none;
1961
+ outline: none;
1962
+ color: var(--textarea-text-color);
1963
+ font-size: 14px;
1964
+ line-height: 20px;
1965
+ padding: 0;
1966
+ margin: 0;
1967
+ }
1968
+ .vditor-selection-popover__input textarea::-moz-placeholder {
1969
+ color: #585a5a;
1970
+ }
1971
+ .vditor-selection-popover__input textarea::placeholder {
1972
+ color: #585a5a;
1973
+ }
1974
+ .vditor-selection-popover__input .vditor-selection-popover__send {
1975
+ display: flex;
1976
+ align-items: center;
1977
+ justify-content: center;
1978
+ width: 32px;
1979
+ height: 32px;
1980
+ border: none;
1981
+ background: var(--toolbar-icon-hover-color);
1982
+ border-radius: 8px;
1983
+ color: #fff;
1984
+ cursor: pointer;
1985
+ padding: 0;
1986
+ transition: opacity 0.2s;
1987
+ }
1988
+ .vditor-selection-popover__input .vditor-selection-popover__send:hover {
1989
+ opacity: 0.8;
1990
+ }
1991
+ .vditor-selection-popover__input .vditor-selection-popover__send[disabled] {
1992
+ opacity: 0.5;
1993
+ cursor: not-allowed;
1994
+ pointer-events: none;
1995
+ }
1996
+ .vditor-selection-popover__input .vditor-selection-popover__send--loading {
1997
+ pointer-events: none;
1998
+ opacity: 0.8;
1999
+ }
2000
+ .vditor-selection-popover__input .vditor-selection-popover__send--loading svg {
2001
+ animation: vditor-rotate 1s linear infinite;
2002
+ }
2003
+ .vditor-selection-popover__input .vditor-selection-popover__send svg {
2004
+ width: 16px;
2005
+ height: 16px;
2006
+ }
2007
+ @keyframes vditor-rotate {
2008
+ from {
2009
+ transform: rotate(0deg);
2010
+ }
2011
+ to {
2012
+ transform: rotate(360deg);
2013
+ }
1936
2014
  }
1937
2015
  .vditor-selection-popover__btn {
1938
2016
  display: flex;
@@ -1948,7 +2026,6 @@
1948
2026
  background: transparent;
1949
2027
  color: var(--textarea-text-color);
1950
2028
  cursor: pointer;
1951
- border-radius: 8px;
1952
2029
  outline: none;
1953
2030
  font-size: 14px;
1954
2031
  font-weight: 500;
@@ -1966,6 +2043,37 @@
1966
2043
  .vditor-selection-popover__btn + .vditor-selection-popover__btn {
1967
2044
  border-left: 1px solid var(--border-color);
1968
2045
  }
2046
+ .vditor-reset .vditor-selection-tag {
2047
+ display: inline-flex;
2048
+ align-items: center;
2049
+ gap: 0.31rem;
2050
+ padding: 0.25rem 0.5rem;
2051
+ background-color: #f6f8fa;
2052
+ border: 1px solid #d1d5da;
2053
+ border-radius: 0.25rem;
2054
+ font-size: 0.875rem;
2055
+ line-height: 1.25rem;
2056
+ color: #0a0a0a;
2057
+ font-family: mononoki, Consolas, "Liberation Mono", Menlo, Courier, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols", "JetBrains Mono", "Fira Code", "Source Code Pro", monospace;
2058
+ margin: 0.25rem 0.25rem 0.25rem 0;
2059
+ }
2060
+ .vditor-reset .vditor-selection-tag__file {
2061
+ color: #0a0a0a;
2062
+ font-weight: 500;
2063
+ }
2064
+ .vditor-reset .vditor-selection-tag__lines {
2065
+ color: #586069;
2066
+ }
2067
+ .vditor--dark .vditor-reset .vditor-selection-tag {
2068
+ background-color: #2f363d;
2069
+ border-color: #141414;
2070
+ }
2071
+ .vditor--dark .vditor-reset .vditor-selection-tag .vditor-selection-tag__file {
2072
+ color: #fafafa;
2073
+ }
2074
+ .vditor--dark .vditor-reset .vditor-selection-tag .vditor-selection-tag__lines {
2075
+ color: #b9b9b9;
2076
+ }
1969
2077
  details > summary {
1970
2078
  list-style: none;
1971
2079
  }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.8 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.13 - 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.8";
2828
+ var _VDITOR_VERSION = "0.0.13";
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.8");
3130
+ Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.13");
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:
@@ -7836,6 +7877,22 @@ var processCodeRender = function (previewPanel, vditor) {
7836
7877
  math: vditor.options.preview.math,
7837
7878
  });
7838
7879
  }
7880
+ else if (language === "selection") {
7881
+ // 渲染文件选择标签
7882
+ var content = previewPanel.textContent.trim();
7883
+ var lines = content.split('\n');
7884
+ var tags = lines.map(function (line) {
7885
+ var match = line.trim().match(/^(.+?)\s+(\d+-\d+)$/);
7886
+ if (match) {
7887
+ var filename = match[1], lineRange = match[2];
7888
+ 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>");
7889
+ }
7890
+ return '';
7891
+ }).filter(function (tag) { return tag; }).join('');
7892
+ if (tags) {
7893
+ previewPanel.innerHTML = tags;
7894
+ }
7895
+ }
7839
7896
  else {
7840
7897
  var cRender = vditor.options.customRenders.find(function (item) {
7841
7898
  if (item.language === language) {
@@ -11767,15 +11824,11 @@ var hotkeyEvent = function (vditor, editorElement) {
11767
11824
  * - 防抖间隔使用 options.selectionPopover.debounceDelay(默认 150ms)
11768
11825
  */
11769
11826
  var selectEvent = function (vditor, editorElement) {
11770
- var _a, _b;
11771
11827
  var debounceTimer = 0;
11772
- var delay = (_b = (_a = vditor.options.selectionPopover) === null || _a === void 0 ? void 0 : _a.debounceDelay) !== null && _b !== void 0 ? _b : 150;
11773
- /**
11774
- * 统一处理选择状态:根据选区内容显示/隐藏选择浮窗
11775
- * - 鼠标拖选、键盘选择、触摸选择、系统 selectionchange
11776
- */
11777
11828
  var handleSelection = function () {
11829
+ var _a, _b;
11778
11830
  window.clearTimeout(debounceTimer);
11831
+ var delay = (_b = (_a = vditor.options.selectionPopover) === null || _a === void 0 ? void 0 : _a.debounceDelay) !== null && _b !== void 0 ? _b : 150;
11779
11832
  debounceTimer = window.setTimeout(function () {
11780
11833
  var _a;
11781
11834
  var selectText = getSelectText(vditor[vditor.currentMode].element);
@@ -11798,44 +11851,17 @@ var selectEvent = function (vditor, editorElement) {
11798
11851
  }
11799
11852
  }, delay);
11800
11853
  };
11801
- // 鼠标拖选结束
11802
- editorElement.addEventListener("mouseup", function () { return handleSelection(); });
11803
- // 触摸选择结束(移动端)
11804
- editorElement.addEventListener("touchend", function () { return handleSelection(); }, {
11805
- passive: true,
11854
+ editorElement.addEventListener("selectstart", function (event) {
11855
+ editorElement.onmouseup = handleSelection;
11806
11856
  });
11807
- // 键盘选择(Shift+方向键/Home/End 等)
11808
11857
  editorElement.addEventListener("keyup", function (event) {
11809
- if (event.isComposing) {
11810
- return;
11858
+ if (event.shiftKey && (event.key.startsWith("Arrow") || event.key === "Home" || event.key === "End")) {
11859
+ handleSelection();
11811
11860
  }
11812
- handleSelection();
11813
- });
11814
- // 系统选区变化(跨端通用,仅处理编辑器内选区)
11815
- document.addEventListener("selectionchange", function () {
11816
- if (!(0,selection/* selectIsEditor */.Gb)(vditor[vditor.currentMode].element)) {
11817
- return;
11861
+ else if (!event.shiftKey && (event.key.startsWith("Arrow") || event.key === "Escape")) {
11862
+ // Cancel selection or move cursor without selection
11863
+ handleSelection();
11818
11864
  }
11819
- handleSelection();
11820
- });
11821
- // 点击空白区域时隐藏浮窗并清理选区
11822
- editorElement.addEventListener("click", function () {
11823
- var selection = window.getSelection();
11824
- var hadSelection = !!selection && selection.toString().trim() !== "";
11825
- window.setTimeout(function () {
11826
- var selectText = getSelectText(vditor[vditor.currentMode].element);
11827
- if (!selectText.trim()) {
11828
- if (vditor.currentMode === "wysiwyg") {
11829
- vditor.wysiwyg.hideSelectionPopover();
11830
- }
11831
- if (hadSelection) {
11832
- try {
11833
- selection.removeAllRanges();
11834
- }
11835
- catch (_a) { }
11836
- }
11837
- }
11838
- }, 0);
11839
11865
  });
11840
11866
  };
11841
11867
 
@@ -15263,6 +15289,8 @@ var Outline = /** @class */ (function () {
15263
15289
 
15264
15290
  // EXTERNAL MODULE: ./src/ts/markdown/mediaRender.ts
15265
15291
  var mediaRender = __webpack_require__(280);
15292
+ // EXTERNAL MODULE: ./src/ts/markdown/selectionRender.ts
15293
+ var selectionRender = __webpack_require__(616);
15266
15294
  ;// CONCATENATED MODULE: ./src/ts/preview/index.ts
15267
15295
 
15268
15296
 
@@ -15281,6 +15309,7 @@ var mediaRender = __webpack_require__(280);
15281
15309
 
15282
15310
 
15283
15311
 
15312
+
15284
15313
  var Preview = /** @class */ (function () {
15285
15314
  /**
15286
15315
  * 构造预览区域容器,注册复制与点击事件。
@@ -15444,8 +15473,11 @@ var Preview = /** @class */ (function () {
15444
15473
  if (vditor.options.preview.render.media.enable) {
15445
15474
  (0,mediaRender/* mediaRender */.Y)(vditor.preview.previewElement);
15446
15475
  }
15476
+ (0,selectionRender/* selectionRender */.V)(vditor.preview.previewElement);
15447
15477
  vditor.options.customRenders.forEach(function (item) {
15448
- item.render(vditor.preview.previewElement, vditor);
15478
+ {
15479
+ item.render(vditor.preview.previewElement, vditor);
15480
+ }
15449
15481
  });
15450
15482
  // toc render
15451
15483
  var editorElement = vditor.preview.element;
@@ -17936,17 +17968,58 @@ var WYSIWYG = /** @class */ (function () {
17936
17968
  var _a;
17937
17969
  this.composingLock = false;
17938
17970
  this.commentIds = [];
17971
+ this.vditor = vditor;
17939
17972
  var divElement = document.createElement("div");
17940
17973
  divElement.className = "vditor-wysiwyg";
17941
17974
  if ((_a = vditor.options.lineNumber) === null || _a === void 0 ? void 0 : _a.enable) {
17942
17975
  divElement.classList.add("vditor--linenumber");
17943
17976
  }
17944
- 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 <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>");
17977
+ 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>");
17945
17978
  this.element = divElement.firstElementChild;
17946
17979
  this.popover = divElement.firstElementChild
17947
17980
  .nextElementSibling;
17948
17981
  this.selectPopover = divElement.lastElementChild;
17982
+ this.popoverInput = this.selectPopover.querySelector("textarea");
17983
+ this.popoverSendBtn = this.selectPopover.querySelector(".vditor-selection-popover__send");
17949
17984
  this.bindEvent(vditor);
17985
+ // 绑定发送按钮事件
17986
+ if (this.popoverSendBtn) {
17987
+ this.popoverSendBtn.setAttribute("disabled", "disabled");
17988
+ this.popoverSendBtn.onclick = function (event) {
17989
+ event.stopPropagation();
17990
+ if (vditor.options.ai) {
17991
+ vditor.options.ai({
17992
+ value: _this.popoverInput.value,
17993
+ content: _this.selectionContent,
17994
+ lines: _this.selectionLines,
17995
+ });
17996
+ }
17997
+ _this.hideSelectionPopover();
17998
+ };
17999
+ // 阻止点击 popover 内任何区域时导致编辑器失去焦点
18000
+ // 但不影响 textarea 获取焦点和按钮点击
18001
+ this.selectPopover.addEventListener("mousedown", function (event) {
18002
+ var target = event.target;
18003
+ // 如果点击的是 textarea 或 button,允许默认行为
18004
+ if (target.tagName === "TEXTAREA" || target.tagName === "BUTTON") {
18005
+ return;
18006
+ }
18007
+ // 其他情况阻止默认行为,防止编辑器失去焦点
18008
+ event.preventDefault();
18009
+ event.stopPropagation();
18010
+ });
18011
+ // 输入验证
18012
+ if (this.popoverInput) {
18013
+ this.popoverInput.addEventListener("input", function () {
18014
+ if (_this.popoverInput.value.trim().length > 0) {
18015
+ _this.popoverSendBtn.removeAttribute("disabled");
18016
+ }
18017
+ else {
18018
+ _this.popoverSendBtn.setAttribute("disabled", "disabled");
18019
+ }
18020
+ });
18021
+ }
18022
+ }
17950
18023
  focusEvent(vditor, this.element);
17951
18024
  dblclickEvent(vditor, this.element);
17952
18025
  blurEvent(vditor, this.element);
@@ -17956,16 +18029,18 @@ var WYSIWYG = /** @class */ (function () {
17956
18029
  copyEvent(vditor, this.element, this.copy);
17957
18030
  cutEvent(vditor, this.element, this.copy);
17958
18031
  // 选择浮窗按钮事件绑定
17959
- var aiBtn = this.selectPopover.querySelector('[data-action="ai"]');
17960
- if (aiBtn) {
17961
- /**
17962
- * AI编辑按钮占位事件
17963
- * - 当前仅输出日志,不执行编辑逻辑
17964
- */
17965
- aiBtn.onclick = function () {
17966
- console.log("[Selection AI Edit] clicked");
17967
- };
17968
- }
18032
+ // const aiBtn = this.selectPopover.querySelector(
18033
+ // '[data-action="ai"]'
18034
+ // ) as HTMLButtonElement | null;
18035
+ // if (aiBtn) {
18036
+ // /**
18037
+ // * AI编辑按钮占位事件
18038
+ // * - 当前仅输出日志,不执行编辑逻辑
18039
+ // */
18040
+ // aiBtn.onclick = () => {
18041
+ // console.log("[Selection AI Edit] clicked");
18042
+ // };
18043
+ // }
17969
18044
  var copyBtn = this.selectPopover.querySelector('[data-action="copy"]');
17970
18045
  if (copyBtn) {
17971
18046
  /**
@@ -18137,32 +18212,91 @@ var WYSIWYG = /** @class */ (function () {
18137
18212
  if (range.toString().trim() === "") {
18138
18213
  return;
18139
18214
  }
18215
+ // 捕获选区内容(在选区丢失前)
18216
+ var fragment = range.cloneContents();
18217
+ var tempContainer = document.createElement("div");
18218
+ tempContainer.appendChild(fragment);
18219
+ this.selectionContent = this.vditor.lute
18220
+ .VditorDOM2Md(tempContainer.innerHTML)
18221
+ .trim();
18222
+ if (!this.selectionContent) {
18223
+ this.selectionContent = range.toString().trim();
18224
+ }
18225
+ // 捕获行号
18226
+ var getBlockIndex = function (node, editor) {
18227
+ var target = node;
18228
+ var directChild = null;
18229
+ // 向上遍历查找行号或直接子元素
18230
+ while (target && target.parentElement !== editor) {
18231
+ if (target instanceof Element &&
18232
+ target.hasAttribute("data-linenumber")) {
18233
+ return parseInt(target.getAttribute("data-linenumber"), 10);
18234
+ }
18235
+ target = target.parentNode;
18236
+ if (target && target.parentElement === editor) {
18237
+ directChild = target;
18238
+ }
18239
+ }
18240
+ // 检查直接子元素
18241
+ if (directChild && directChild.hasAttribute("data-linenumber")) {
18242
+ return parseInt(directChild.getAttribute("data-linenumber"), 10);
18243
+ }
18244
+ // 回退到使用子元素索引
18245
+ if (directChild) {
18246
+ return Array.from(editor.children).indexOf(directChild) + 1;
18247
+ }
18248
+ return 0;
18249
+ };
18250
+ var startLine = getBlockIndex(range.startContainer, this.element);
18251
+ var endLine = getBlockIndex(range.endContainer, this.element);
18252
+ this.selectionLines = [startLine, endLine];
18140
18253
  var editorRect = this.element.getBoundingClientRect();
18141
18254
  var rect = range.getBoundingClientRect();
18142
- var top = Math.max(-8, rect.top - editorRect.top - 21);
18143
- var left = Math.min(rect.right - editorRect.left - this.selectPopover.clientWidth, this.element.clientWidth - this.selectPopover.clientWidth);
18255
+ // 计算浮窗尺寸
18256
+ this.selectPopover.style.display = "flex";
18257
+ this.selectPopover.style.opacity = "0";
18258
+ var popoverHeight = this.selectPopover.offsetHeight;
18259
+ var popoverWidth = this.selectPopover.offsetWidth;
18260
+ // 理想位置:选区上方居中
18261
+ var top = rect.top - editorRect.top - popoverHeight - 8;
18262
+ var left = rect.left - editorRect.left + rect.width / 2 - popoverWidth / 2;
18263
+ // 边界检查:顶部超出则翻转到底部
18264
+ if (top < 0) {
18265
+ top = rect.bottom - editorRect.top + 8;
18266
+ }
18267
+ // 边界检查:左右限制
18268
+ var maxLeft = this.element.clientWidth - popoverWidth;
18269
+ left = Math.max(0, Math.min(left, maxLeft));
18144
18270
  this.selectPopover.style.top = "".concat(top, "px");
18145
- this.selectPopover.style.left = "".concat(Math.max(0, left), "px");
18146
- this.selectPopover.style.display = "block";
18147
- this.selectPopover.style.transition =
18148
- "opacity 150ms cubic-bezier(0.2, 0, 0.13, 1.5), transform 150ms cubic-bezier(0.2, 0, 0.13, 1.5)";
18271
+ this.selectPopover.style.left = "".concat(left, "px");
18272
+ // 强制重排以触发过渡动画
18273
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
18274
+ this.selectPopover.offsetHeight;
18149
18275
  this.selectPopover.style.opacity = "1";
18150
18276
  this.selectPopover.style.transform = "scale(1)";
18151
- this.popover.setAttribute("data-top", (rect.top - editorRect.top - 21).toString());
18152
- this.selectPopover.setAttribute("data-top", (rect.top - editorRect.top - 21).toString());
18277
+ this.popover.setAttribute("data-top", top.toString());
18278
+ this.selectPopover.setAttribute("data-top", top.toString());
18153
18279
  };
18154
18280
  /**
18155
18281
  * 隐藏选择浮窗(淡出)
18156
18282
  */
18157
18283
  WYSIWYG.prototype.hideSelectionPopover = function () {
18158
18284
  var _this = this;
18159
- if (this.selectPopover.style.display !== "block") {
18285
+ if (this.selectPopover.style.display !== "flex") {
18160
18286
  return;
18161
18287
  }
18162
18288
  this.selectPopover.style.opacity = "0";
18163
18289
  this.selectPopover.style.transform = "scale(0.95)";
18164
18290
  window.setTimeout(function () {
18165
18291
  _this.selectPopover.setAttribute("style", "display:none");
18292
+ // Reset state
18293
+ if (_this.popoverInput) {
18294
+ _this.popoverInput.value = "";
18295
+ }
18296
+ if (_this.popoverSendBtn) {
18297
+ _this.popoverSendBtn.classList.remove("vditor-selection-popover__send--loading");
18298
+ _this.popoverSendBtn.setAttribute("disabled", "disabled");
18299
+ }
18166
18300
  }, 150);
18167
18301
  };
18168
18302
  /**
@@ -18399,7 +18533,7 @@ var WYSIWYG = /** @class */ (function () {
18399
18533
  window.addEventListener("scroll", (this.scrollListener = function () {
18400
18534
  hidePanel(vditor, ["hint"]);
18401
18535
  if (_this.popover.style.display !== "block" ||
18402
- _this.selectPopover.style.display !== "block") {
18536
+ _this.selectPopover.style.display !== "flex") {
18403
18537
  return;
18404
18538
  }
18405
18539
  var top = parseInt(_this.popover.getAttribute("data-top"), 10);
@@ -18410,7 +18544,7 @@ var WYSIWYG = /** @class */ (function () {
18410
18544
  if (_this.popover.style.display === "block") {
18411
18545
  _this.popover.style.top = popoverTop;
18412
18546
  }
18413
- if (_this.selectPopover.style.display === "block") {
18547
+ if (_this.selectPopover.style.display === "flex") {
18414
18548
  _this.selectPopover.style.top = popoverTop;
18415
18549
  }
18416
18550
  }
@@ -18423,7 +18557,7 @@ var WYSIWYG = /** @class */ (function () {
18423
18557
  if (_this.popover.style.display === "block") {
18424
18558
  _this.popover.style.top = popoverTop1;
18425
18559
  }
18426
- if (_this.selectPopover.style.display === "block") {
18560
+ if (_this.selectPopover.style.display === "flex") {
18427
18561
  _this.selectPopover.style.top = popoverTop1;
18428
18562
  }
18429
18563
  }));