@jx3box/jx3box-editor 3.0.3 → 3.0.4
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/package.json
CHANGED
package/src/Article.vue
CHANGED
|
@@ -66,6 +66,7 @@ import execLazyload from "./assets/js/img";
|
|
|
66
66
|
import execFilterIframe from "./assets/js/iframe";
|
|
67
67
|
import execFilterLink from "./assets/js/a";
|
|
68
68
|
import execSplitPages from "./assets/js/nextpage";
|
|
69
|
+
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor";
|
|
69
70
|
|
|
70
71
|
// 扩展文本
|
|
71
72
|
import renderFoldBlock from "./assets/js/fold";
|
|
@@ -244,8 +245,9 @@ export default {
|
|
|
244
245
|
},
|
|
245
246
|
renderMarkdownChunk: async function (chunk) {
|
|
246
247
|
const temp = document.createElement("div");
|
|
248
|
+
const normalizedChunk = normalizeMarkdownForVditor(chunk);
|
|
247
249
|
|
|
248
|
-
await Vditor.preview(temp,
|
|
250
|
+
await Vditor.preview(temp, normalizedChunk, {
|
|
249
251
|
mode: "light",
|
|
250
252
|
lang: "zh_CN",
|
|
251
253
|
hljs: {
|
|
@@ -254,7 +256,9 @@ export default {
|
|
|
254
256
|
style: "github",
|
|
255
257
|
},
|
|
256
258
|
markdown: {
|
|
259
|
+
mark: true,
|
|
257
260
|
sanitize: true,
|
|
261
|
+
toc: true,
|
|
258
262
|
},
|
|
259
263
|
icon: "ant",
|
|
260
264
|
});
|
package/src/Markdown.vue
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
import Vditor from "vditor";
|
|
36
36
|
import "vditor/dist/index.css";
|
|
37
37
|
import "github-markdown-css/github-markdown-light.css";
|
|
38
|
+
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor";
|
|
38
39
|
|
|
39
40
|
const { __cms } = JX3BOX;
|
|
40
41
|
const UPLOAD_API = `${__cms}api/cms/upload`;
|
|
@@ -130,6 +131,7 @@ export default {
|
|
|
130
131
|
previewVisible: false,
|
|
131
132
|
isRebuildingEditor: false,
|
|
132
133
|
isUploadingImage: false,
|
|
134
|
+
previewRenderVersion: 0,
|
|
133
135
|
counterElement: null,
|
|
134
136
|
counterClickListener: null,
|
|
135
137
|
counterClickTimestamps: [],
|
|
@@ -235,7 +237,9 @@ export default {
|
|
|
235
237
|
style: "github",
|
|
236
238
|
},
|
|
237
239
|
markdown: {
|
|
240
|
+
mark: true,
|
|
238
241
|
sanitize: true,
|
|
242
|
+
toc: true,
|
|
239
243
|
},
|
|
240
244
|
mode: this.getPreviewMode(),
|
|
241
245
|
},
|
|
@@ -300,7 +304,7 @@ export default {
|
|
|
300
304
|
if (this.editor.getValue() === nextValue) return;
|
|
301
305
|
this.editor.setValue(nextValue);
|
|
302
306
|
if (this.previewVisible) {
|
|
303
|
-
this.
|
|
307
|
+
this.renderPreviewContent();
|
|
304
308
|
}
|
|
305
309
|
},
|
|
306
310
|
getToolbarButton(name) {
|
|
@@ -356,9 +360,38 @@ export default {
|
|
|
356
360
|
|
|
357
361
|
this.syncEditorPanels();
|
|
358
362
|
if (this.previewVisible) {
|
|
359
|
-
this.
|
|
363
|
+
this.renderPreviewContent();
|
|
360
364
|
}
|
|
361
365
|
},
|
|
366
|
+
renderPreviewContent: async function () {
|
|
367
|
+
if (!this.editorReady || !this.editor) return;
|
|
368
|
+
|
|
369
|
+
const previewRoot = this.$refs.editorHost?.querySelector?.(".vditor-preview");
|
|
370
|
+
const previewBody = previewRoot?.querySelector?.(".vditor-reset") || previewRoot;
|
|
371
|
+
if (!previewBody) return;
|
|
372
|
+
|
|
373
|
+
const version = ++this.previewRenderVersion;
|
|
374
|
+
const normalizedMarkdown = normalizeMarkdownForVditor(this.editor.getValue());
|
|
375
|
+
|
|
376
|
+
await Vditor.preview(previewBody, normalizedMarkdown, {
|
|
377
|
+
mode: "light",
|
|
378
|
+
lang: "zh_CN",
|
|
379
|
+
hljs: {
|
|
380
|
+
enable: true,
|
|
381
|
+
lineNumber: false,
|
|
382
|
+
style: "github",
|
|
383
|
+
},
|
|
384
|
+
markdown: {
|
|
385
|
+
mark: true,
|
|
386
|
+
sanitize: true,
|
|
387
|
+
toc: true,
|
|
388
|
+
},
|
|
389
|
+
icon: "ant",
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
if (version !== this.previewRenderVersion) return;
|
|
393
|
+
previewBody.classList.add("markdown-body");
|
|
394
|
+
},
|
|
362
395
|
togglePreview() {
|
|
363
396
|
this.previewVisible = !this.previewVisible;
|
|
364
397
|
|
|
@@ -528,8 +561,8 @@ export default {
|
|
|
528
561
|
}
|
|
529
562
|
|
|
530
563
|
.vditor-toolbar {
|
|
531
|
-
|
|
532
|
-
|
|
564
|
+
display: flex;
|
|
565
|
+
align-items: center;
|
|
533
566
|
padding: 10px 12px;
|
|
534
567
|
background: #f6f8fa;
|
|
535
568
|
border-bottom: 1px solid #d8dee4;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const PROTECTED_SEGMENT_REGEXP = /(```[\s\S]*?```|~~~[\s\S]*?~~~|`[^`\n]*`|\$\$[\s\S]*?\$\$|\$[^$\n]+\$)/g;
|
|
2
|
+
|
|
3
|
+
function replaceUnderline(text) {
|
|
4
|
+
return text.replace(/\+\+([^\n+][^\n]*?)\+\+/g, "<u>$1</u>");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function replaceSuperscript(text) {
|
|
8
|
+
return text.replace(
|
|
9
|
+
/(^|[^\w\\])([A-Za-z0-9)\]}\u4e00-\u9fa5]+)\^([^^\s][^^]*?)\^/g,
|
|
10
|
+
(match, prefix, base, value) => {
|
|
11
|
+
return `${prefix}${base}<sup>${value}</sup>`;
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function replaceSubscript(text) {
|
|
17
|
+
return text.replace(/(^|[^\w\\])([A-Za-z0-9)\]}\u4e00-\u9fa5]+)~([^~\s][^~]*?)~/g, (match, prefix, base, value) => {
|
|
18
|
+
return `${prefix}${base}<sub>${value}</sub>`;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizePlainMarkdown(text) {
|
|
23
|
+
return [replaceUnderline, replaceSuperscript, replaceSubscript].reduce((result, transform) => {
|
|
24
|
+
return transform(result);
|
|
25
|
+
}, text);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function normalizeMarkdownForVditor(markdown) {
|
|
29
|
+
const source = String(markdown || "");
|
|
30
|
+
if (!source) return "";
|
|
31
|
+
|
|
32
|
+
const segments = source.split(PROTECTED_SEGMENT_REGEXP);
|
|
33
|
+
|
|
34
|
+
return segments
|
|
35
|
+
.map((segment, index) => {
|
|
36
|
+
return index % 2 === 1 ? segment : normalizePlainMarkdown(segment);
|
|
37
|
+
})
|
|
38
|
+
.join("");
|
|
39
|
+
}
|