@wyttime04/react-vditor 0.1.0-alpha.0
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/LICENSE +21 -0
- package/README.md +362 -0
- package/dist/Vditor.js +212 -0
- package/dist/VditorPreview.js +36 -0
- package/dist/cdn.js +9 -0
- package/dist/gfm.js +121 -0
- package/dist/index.css +2179 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.js +13 -0
- package/dist/theme.js +43 -0
- package/dist/uploadImage.js +51 -0
- package/package.json +77 -0
- package/webpack-plugin/index.cjs +44 -0
- package/webpack-plugin/index.d.ts +8 -0
package/dist/gfm.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// 只支援 GFM 的預設設定。vditor 原本的附加渲染(mermaid、數學式、echarts…)一律不渲染,
|
|
2
|
+
// 顯示成普通程式碼區塊;webpack plugin 也不會輸出那些渲染套件。
|
|
3
|
+
import { UPLOAD_IMAGE, uploadImageItem } from "./uploadImage.js";
|
|
4
|
+
|
|
5
|
+
/** Lute 會把這些語言輸出成 <div class="language-xxx"> 等渲染器畫圖 */
|
|
6
|
+
const DIV_LANGUAGES = "mermaid|echarts|abc|graphviz|mindmap|flowchart|plantuml|infographic|math";
|
|
7
|
+
/** 這些語言輸出成 <pre><code class="language-xxx">,但渲染器一樣會找上門 */
|
|
8
|
+
const CODE_LANGUAGES = "smiles|wavedrom|markmap|math";
|
|
9
|
+
const DIV_PATTERN = new RegExp(`<div(?: data-code="[^"]*")? class="language-(${DIV_LANGUAGES})">([\\s\\S]*?)</div>`, "g");
|
|
10
|
+
const CODE_PATTERN = new RegExp(`<code class="language-(${CODE_LANGUAGES})">`, "g");
|
|
11
|
+
const INLINE_MATH_PATTERN = /<span class="language-math">([\s\S]*?)<\/span>/g;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 預覽用的 HTML 轉換:非 GFM 的區塊一律變成普通程式碼區塊。
|
|
15
|
+
* class 改成 language-plaintext,渲染器就找不到它們,也就不會去載入沒輸出的套件;原本的語言留在 data-lang。
|
|
16
|
+
*/
|
|
17
|
+
export const gfmTransform = html => html.replace(DIV_PATTERN, '<pre><code class="language-plaintext" data-lang="$1">$2</code></pre>').replace(CODE_PATTERN, '<code class="language-plaintext" data-lang="$1">').replace(INLINE_MATH_PATTERN, "$$$1$$");
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 預設工具列。跟 vditor 原本的相比:
|
|
21
|
+
* - 拿掉 export(寫死連 CDN)、devtools(要 echarts)、info(寫死 unpkg 的 logo)
|
|
22
|
+
* - 拿掉 emoji、record、upload、code-theme、content-theme、help
|
|
23
|
+
* - 加上只收圖片的 upload-image
|
|
24
|
+
*/
|
|
25
|
+
const TOOLBAR = ["headings", "bold", "italic", "strike", "link", "|", "list", "ordered-list", "check", "outdent", "indent", "|", "quote", "line", "code", "inline-code", "insert-before", "insert-after", "|", UPLOAD_IMAGE, "table", "|", "undo", "redo", "|", "fullscreen", "edit-mode", {
|
|
26
|
+
name: "more",
|
|
27
|
+
toolbar: ["both", "outline", "preview"]
|
|
28
|
+
}];
|
|
29
|
+
|
|
30
|
+
/** 工具列裡的 upload-image(含 more 之類的子選單)換成完整的按鈕設定 */
|
|
31
|
+
const expandToolbar = (toolbar, lang) => toolbar.map(item => {
|
|
32
|
+
if (item === UPLOAD_IMAGE || item?.name === UPLOAD_IMAGE) {
|
|
33
|
+
return uploadImageItem(item, lang);
|
|
34
|
+
}
|
|
35
|
+
return item?.toolbar ? {
|
|
36
|
+
...item,
|
|
37
|
+
toolbar: expandToolbar(item.toolbar, lang)
|
|
38
|
+
} : item;
|
|
39
|
+
});
|
|
40
|
+
const isPlainObject = value => Object.prototype.toString.call(value) === "[object Object]";
|
|
41
|
+
|
|
42
|
+
/** 物件逐層合併,陣列與其他值直接覆蓋 */
|
|
43
|
+
const merge = (base, override) => {
|
|
44
|
+
if (!isPlainObject(base) || !isPlainObject(override)) {
|
|
45
|
+
return override === undefined ? base : override;
|
|
46
|
+
}
|
|
47
|
+
const result = {
|
|
48
|
+
...base
|
|
49
|
+
};
|
|
50
|
+
Object.keys(override).forEach(key => {
|
|
51
|
+
result[key] = merge(result[key], override[key]);
|
|
52
|
+
});
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** 使用端自己的 transform 接在 gfmTransform 之後 */
|
|
57
|
+
const withGfmTransform = transform => transform ? html => transform(gfmTransform(html)) : gfmTransform;
|
|
58
|
+
|
|
59
|
+
/** 編輯器選項:GFM 預設值,再疊上使用端的選項 */
|
|
60
|
+
export const gfmEditorOptions = (options, cdn) => {
|
|
61
|
+
const merged = merge({
|
|
62
|
+
cdn,
|
|
63
|
+
lang: "zh_TW",
|
|
64
|
+
mode: "wysiwyg",
|
|
65
|
+
// 傳 HTMLElement 給 vditor 時,開快取一定要有 cache.id,否則直接拋錯
|
|
66
|
+
cache: {
|
|
67
|
+
enable: false
|
|
68
|
+
},
|
|
69
|
+
toolbar: TOOLBAR,
|
|
70
|
+
preview: {
|
|
71
|
+
actions: [],
|
|
72
|
+
markdown: {
|
|
73
|
+
footnotes: false,
|
|
74
|
+
// GFM 以外、預設開著的只有註腳
|
|
75
|
+
codeBlockPreview: false,
|
|
76
|
+
// ir / wysiwyg 的程式碼區塊不開預覽面板,否則會去渲染 mermaid 等區塊
|
|
77
|
+
mathBlockPreview: false // 同上,$$ 區塊
|
|
78
|
+
},
|
|
79
|
+
render: {
|
|
80
|
+
media: {
|
|
81
|
+
enable: false
|
|
82
|
+
}
|
|
83
|
+
} // 不把影片、音訊連結嵌成 iframe
|
|
84
|
+
}
|
|
85
|
+
}, options);
|
|
86
|
+
merged.preview = {
|
|
87
|
+
...merged.preview,
|
|
88
|
+
transform: withGfmTransform(options.preview?.transform),
|
|
89
|
+
// 內容主題不交給 vditor(它用整頁共用的 <link>),改由元件容器的 class 套用 index.css 裡局部化的主題
|
|
90
|
+
theme: {
|
|
91
|
+
...merged.preview.theme,
|
|
92
|
+
current: ""
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
merged.toolbar = expandToolbar(merged.toolbar, merged.lang);
|
|
96
|
+
return merged;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** Vditor.preview 的選項:GFM 預設值,再疊上使用端的選項 */
|
|
100
|
+
export const gfmPreviewOptions = (options, cdn) => {
|
|
101
|
+
const merged = merge({
|
|
102
|
+
cdn,
|
|
103
|
+
lang: "zh_TW",
|
|
104
|
+
mode: "light",
|
|
105
|
+
markdown: {
|
|
106
|
+
footnotes: false
|
|
107
|
+
},
|
|
108
|
+
render: {
|
|
109
|
+
media: {
|
|
110
|
+
enable: false
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, options);
|
|
114
|
+
merged.transform = withGfmTransform(options.transform);
|
|
115
|
+
// 同編輯器:內容主題改由元件容器的 class 決定
|
|
116
|
+
merged.theme = {
|
|
117
|
+
...merged.theme,
|
|
118
|
+
current: ""
|
|
119
|
+
};
|
|
120
|
+
return merged;
|
|
121
|
+
};
|