@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.
- package/dist/css/content-theme/dark.css +19 -3
- package/dist/index.css +114 -6
- package/dist/index.js +201 -67
- package/dist/index.min.js +1 -1
- package/dist/method.d.ts +2 -0
- package/dist/method.js +43 -3
- package/dist/method.min.js +1 -1
- package/dist/ts/markdown/selectionRender.d.ts +4 -0
- package/dist/ts/wysiwyg/index.d.ts +5 -0
- package/dist/types/index.d.ts +10 -1
- package/package.json +2 -2
- package/src/assets/less/_line-number.less +7 -5
- package/src/method.ts +4 -1
- package/src/ts/markdown/previewRender.ts +24 -22
- package/src/ts/wysiwyg/index.ts +27 -21
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
[data-linenumber]:after {
|
|
7
7
|
margin-left: -5rem !important;
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
ul,
|
|
11
|
+
ol {
|
|
10
12
|
[data-linenumber]:after {
|
|
11
13
|
margin-left: -7rem !important;
|
|
12
|
-
}
|
|
14
|
+
}
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
top: 0;
|
|
26
28
|
width: 3em;
|
|
27
29
|
text-align: right;
|
|
28
|
-
color:
|
|
30
|
+
color: rgba(252, 252, 252, 0.65);
|
|
29
31
|
font-size: 0.75rem;
|
|
30
32
|
line-height: inherit;
|
|
31
33
|
user-select: none;
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
|
|
37
39
|
.vditor-line-highlight {
|
|
38
40
|
background-color: #fff3cd !important;
|
|
39
|
-
transition: background-color 0.3s ease-in-out;
|
|
41
|
+
transition: background-color color 0.3s ease-in-out;
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
|
-
}
|
|
44
|
+
}
|
package/src/method.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { outlineRender } from "./ts/markdown/outlineRender";
|
|
|
16
16
|
import { plantumlRender } from "./ts/markdown/plantumlRender";
|
|
17
17
|
import { md2html, previewRender } from "./ts/markdown/previewRender";
|
|
18
18
|
import { speechRender } from "./ts/markdown/speechRender";
|
|
19
|
+
import { selectionRender } from "./ts/markdown/selectionRender";
|
|
19
20
|
import { previewImage } from "./ts/preview/image";
|
|
20
21
|
import { setCodeTheme } from "./ts/ui/setCodeTheme";
|
|
21
22
|
import { setContentTheme } from "./ts/ui/setContentTheme";
|
|
@@ -60,6 +61,8 @@ class Vditor {
|
|
|
60
61
|
public static mediaRender = mediaRender;
|
|
61
62
|
/** 对选中的文字进行阅读 */
|
|
62
63
|
public static speechRender = speechRender;
|
|
64
|
+
/** 渲染 selection 代码块为文件选择标签 */
|
|
65
|
+
public static selectionRender = selectionRender;
|
|
63
66
|
/** 对图片进行懒加载 */
|
|
64
67
|
public static lazyLoadImageRender = lazyLoadImageRender;
|
|
65
68
|
/** Markdown 文本转换为 HTML,该方法需使用[异步编程](https://ld246.com/article/1546828434083?r=Vaness) */
|
|
@@ -85,7 +88,7 @@ class Vditor {
|
|
|
85
88
|
} else {
|
|
86
89
|
attachLineNumbersToBlocksThrottled(root, text);
|
|
87
90
|
}
|
|
88
|
-
} catch {}
|
|
91
|
+
} catch { }
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import {Constants} from "../constants";
|
|
2
|
-
import {setContentTheme} from "../ui/setContentTheme";
|
|
3
|
-
import {addScript} from "../util/addScript";
|
|
4
|
-
import {hasClosestByClassName, hasClosestByMatchTag} from "../util/hasClosest";
|
|
5
|
-
import {merge} from "../util/merge";
|
|
6
|
-
import {abcRender} from "./abcRender";
|
|
7
|
-
import {anchorRender} from "./anchorRender";
|
|
8
|
-
import {chartRender} from "./chartRender";
|
|
9
|
-
import {codeRender} from "./codeRender";
|
|
10
|
-
import {flowchartRender} from "./flowchartRender";
|
|
11
|
-
import {graphvizRender} from "./graphvizRender";
|
|
12
|
-
import {highlightRender} from "./highlightRender";
|
|
13
|
-
import {lazyLoadImageRender} from "./lazyLoadImageRender";
|
|
14
|
-
import {mathRender} from "./mathRender";
|
|
15
|
-
import {mediaRender} from "./mediaRender";
|
|
16
|
-
import {mermaidRender} from "./mermaidRender";
|
|
17
|
-
import {markmapRender} from "./markmapRender";
|
|
18
|
-
import {SMILESRender} from "./SMILESRender";
|
|
19
|
-
import {mindmapRender} from "./mindmapRender";
|
|
20
|
-
import {plantumlRender} from "./plantumlRender";
|
|
21
|
-
import {setLute} from "./setLute";
|
|
22
|
-
import {speechRender} from "./speechRender";
|
|
1
|
+
import { Constants } from "../constants";
|
|
2
|
+
import { setContentTheme } from "../ui/setContentTheme";
|
|
3
|
+
import { addScript } from "../util/addScript";
|
|
4
|
+
import { hasClosestByClassName, hasClosestByMatchTag } from "../util/hasClosest";
|
|
5
|
+
import { merge } from "../util/merge";
|
|
6
|
+
import { abcRender } from "./abcRender";
|
|
7
|
+
import { anchorRender } from "./anchorRender";
|
|
8
|
+
import { chartRender } from "./chartRender";
|
|
9
|
+
import { codeRender } from "./codeRender";
|
|
10
|
+
import { flowchartRender } from "./flowchartRender";
|
|
11
|
+
import { graphvizRender } from "./graphvizRender";
|
|
12
|
+
import { highlightRender } from "./highlightRender";
|
|
13
|
+
import { lazyLoadImageRender } from "./lazyLoadImageRender";
|
|
14
|
+
import { mathRender } from "./mathRender";
|
|
15
|
+
import { mediaRender } from "./mediaRender";
|
|
16
|
+
import { mermaidRender } from "./mermaidRender";
|
|
17
|
+
import { markmapRender } from "./markmapRender";
|
|
18
|
+
import { SMILESRender } from "./SMILESRender";
|
|
19
|
+
import { mindmapRender } from "./mindmapRender";
|
|
20
|
+
import { plantumlRender } from "./plantumlRender";
|
|
21
|
+
import { setLute } from "./setLute";
|
|
22
|
+
import { speechRender } from "./speechRender";
|
|
23
|
+
import { selectionRender } from "./selectionRender";
|
|
23
24
|
|
|
24
25
|
const mergeOptions = (options?: IPreviewOptions) => {
|
|
25
26
|
const defaultOption: IPreviewOptions = {
|
|
@@ -142,6 +143,7 @@ export const previewRender = async (previewElement: HTMLDivElement, markdown: st
|
|
|
142
143
|
mindmapRender(previewElement, mergedOptions.cdn, mergedOptions.mode);
|
|
143
144
|
plantumlRender(previewElement, mergedOptions.cdn);
|
|
144
145
|
abcRender(previewElement, mergedOptions.cdn);
|
|
146
|
+
selectionRender(previewElement);
|
|
145
147
|
if (mergedOptions.render.media.enable) {
|
|
146
148
|
mediaRender(previewElement);
|
|
147
149
|
}
|
package/src/ts/wysiwyg/index.ts
CHANGED
|
@@ -69,7 +69,7 @@ class WYSIWYG {
|
|
|
69
69
|
<div class="vditor-panel vditor-panel--none"></div>
|
|
70
70
|
<div class="vditor-selection-popover">
|
|
71
71
|
<div class="vditor-selection-popover__actions">
|
|
72
|
-
<button type="button" data-action="ai" aria-label="AI编辑" class="vditor-selection-popover__btn"
|
|
72
|
+
<button type="button" data-action="ai" aria-label="AI编辑" class="vditor-selection-popover__btn">✨ AI编辑</button>
|
|
73
73
|
<button type="button" data-action="cut" aria-label="剪切" class="vditor-selection-popover__btn">剪切</button>
|
|
74
74
|
<button type="button" data-action="copy" aria-label="复制" class="vditor-selection-popover__btn">复制</button>
|
|
75
75
|
</div>
|
|
@@ -109,12 +109,18 @@ class WYSIWYG {
|
|
|
109
109
|
}
|
|
110
110
|
this.hideSelectionPopover();
|
|
111
111
|
};
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
// 阻止点击 popover 内任何区域时导致编辑器失去焦点
|
|
113
|
+
// 但不影响 textarea 获取焦点和按钮点击
|
|
114
|
+
this.selectPopover.addEventListener("mousedown", (event) => {
|
|
115
|
+
const target = event.target as HTMLElement;
|
|
116
|
+
// 如果点击的是 textarea 或 button,允许默认行为
|
|
117
|
+
if (target.tagName === "TEXTAREA" || target.tagName === "BUTTON") {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// 其他情况阻止默认行为,防止编辑器失去焦点
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
event.stopPropagation();
|
|
123
|
+
});
|
|
118
124
|
|
|
119
125
|
// 输入验证
|
|
120
126
|
if (this.popoverInput) {
|
|
@@ -141,18 +147,18 @@ class WYSIWYG {
|
|
|
141
147
|
cutEvent(vditor, this.element, this.copy);
|
|
142
148
|
|
|
143
149
|
// 选择浮窗按钮事件绑定
|
|
144
|
-
const aiBtn = this.selectPopover.querySelector(
|
|
145
|
-
|
|
146
|
-
) as HTMLButtonElement | null;
|
|
147
|
-
if (aiBtn) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
150
|
+
// const aiBtn = this.selectPopover.querySelector(
|
|
151
|
+
// '[data-action="ai"]'
|
|
152
|
+
// ) as HTMLButtonElement | null;
|
|
153
|
+
// if (aiBtn) {
|
|
154
|
+
// /**
|
|
155
|
+
// * AI编辑按钮占位事件
|
|
156
|
+
// * - 当前仅输出日志,不执行编辑逻辑
|
|
157
|
+
// */
|
|
158
|
+
// aiBtn.onclick = () => {
|
|
159
|
+
// console.log("[Selection AI Edit] clicked");
|
|
160
|
+
// };
|
|
161
|
+
// }
|
|
156
162
|
const copyBtn = this.selectPopover.querySelector(
|
|
157
163
|
'[data-action="copy"]'
|
|
158
164
|
) as HTMLButtonElement | null;
|
|
@@ -224,8 +230,8 @@ class WYSIWYG {
|
|
|
224
230
|
item.getAttribute("data-block") === "0" &&
|
|
225
231
|
index === contents.childNodes.length - 1 &&
|
|
226
232
|
rangeClone.endOffset <
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
rangeClone.endContainer.textContent
|
|
234
|
+
.length
|
|
229
235
|
) {
|
|
230
236
|
item.innerHTML = `<span class="vditor-comment" data-cmtids="${id}">${item.innerHTML}</span>`;
|
|
231
237
|
blockEndElement = item;
|