cherry-muse 1.0.1

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.
Files changed (226) hide show
  1. package/LICENSE +162 -0
  2. package/README.md +139 -0
  3. package/dist/addons/cherry-code-block-card-plugin.js +1 -0
  4. package/dist/addons/cherry-code-block-echarts-plugin.js +1 -0
  5. package/dist/addons/cherry-code-block-mermaid-plugin.js +1 -0
  6. package/dist/cherry-markdown.core.common.js +1 -0
  7. package/dist/cherry-markdown.core.js +1 -0
  8. package/dist/cherry-markdown.css +4089 -0
  9. package/dist/cherry-markdown.engine.core.common.js +1 -0
  10. package/dist/cherry-markdown.engine.core.esm.js +1 -0
  11. package/dist/cherry-markdown.engine.core.js +1 -0
  12. package/dist/cherry-markdown.esm.js +1 -0
  13. package/dist/cherry-markdown.js +70837 -0
  14. package/dist/cherry-markdown.js.map +1 -0
  15. package/dist/cherry-markdown.min.css +1 -0
  16. package/dist/cherry-markdown.min.js +1 -0
  17. package/dist/stats.html +4838 -0
  18. package/examples/scripts/pinyin/README.md +53 -0
  19. package/package.json +167 -0
  20. package/src/Cherry.config.js +411 -0
  21. package/src/Cherry.js +788 -0
  22. package/src/CherryStatic.js +70 -0
  23. package/src/Editor.js +746 -0
  24. package/src/Engine.js +334 -0
  25. package/src/Event.js +74 -0
  26. package/src/Factory.js +180 -0
  27. package/src/Logger.js +31 -0
  28. package/src/Previewer.js +1147 -0
  29. package/src/Sanitizer.js +4 -0
  30. package/src/Sanitizer.node.js +7 -0
  31. package/src/Stats.js +101 -0
  32. package/src/Theme.js +46 -0
  33. package/src/UrlCache.js +98 -0
  34. package/src/addons/cherry-code-block-card-plugin.js +213 -0
  35. package/src/addons/cherry-code-block-echarts-plugin.js +161 -0
  36. package/src/addons/cherry-code-block-mermaid-plugin.js +118 -0
  37. package/src/core/HookCenter.js +303 -0
  38. package/src/core/HooksConfig.js +106 -0
  39. package/src/core/ParagraphBase.js +314 -0
  40. package/src/core/SentenceBase.js +65 -0
  41. package/src/core/SyntaxBase.js +197 -0
  42. package/src/core/hooks/AutoLink.js +251 -0
  43. package/src/core/hooks/BackgroundColor.js +46 -0
  44. package/src/core/hooks/Badge.js +100 -0
  45. package/src/core/hooks/Blockquote.js +113 -0
  46. package/src/core/hooks/Br.js +85 -0
  47. package/src/core/hooks/CodeBlock.js +876 -0
  48. package/src/core/hooks/Color.js +78 -0
  49. package/src/core/hooks/CommentReference.js +96 -0
  50. package/src/core/hooks/Detail.js +138 -0
  51. package/src/core/hooks/Emoji.config.js +9388 -0
  52. package/src/core/hooks/Emoji.js +223 -0
  53. package/src/core/hooks/Emphasis.js +113 -0
  54. package/src/core/hooks/Footnote.js +125 -0
  55. package/src/core/hooks/FrontMatter.js +52 -0
  56. package/src/core/hooks/FrontMatterVars.js +82 -0
  57. package/src/core/hooks/Header.js +229 -0
  58. package/src/core/hooks/HighLight.js +37 -0
  59. package/src/core/hooks/Hr.js +52 -0
  60. package/src/core/hooks/HtmlBlock.js +159 -0
  61. package/src/core/hooks/Iframe.js +80 -0
  62. package/src/core/hooks/Image.js +276 -0
  63. package/src/core/hooks/InlineCode.js +45 -0
  64. package/src/core/hooks/InlineMath.js +142 -0
  65. package/src/core/hooks/Link.js +169 -0
  66. package/src/core/hooks/List.js +260 -0
  67. package/src/core/hooks/Mark.js +55 -0
  68. package/src/core/hooks/MathBlock.js +97 -0
  69. package/src/core/hooks/Panel.js +170 -0
  70. package/src/core/hooks/Paragraph.js +84 -0
  71. package/src/core/hooks/Ruby.js +34 -0
  72. package/src/core/hooks/Size.js +84 -0
  73. package/src/core/hooks/Strikethrough.js +54 -0
  74. package/src/core/hooks/Sub.js +47 -0
  75. package/src/core/hooks/SuggestList.js +317 -0
  76. package/src/core/hooks/Suggester.js +759 -0
  77. package/src/core/hooks/Sup.js +47 -0
  78. package/src/core/hooks/Table.js +315 -0
  79. package/src/core/hooks/Toc.js +290 -0
  80. package/src/core/hooks/Transfer.js +47 -0
  81. package/src/core/hooks/Underline.js +37 -0
  82. package/src/index.core.js +29 -0
  83. package/src/index.engine.core.js +62 -0
  84. package/src/index.engine.js +30 -0
  85. package/src/index.js +28 -0
  86. package/src/locales/index.js +21 -0
  87. package/src/locales/zh_CN.js +170 -0
  88. package/src/sass/cherry.scss +122 -0
  89. package/src/sass/components/bubble.scss +122 -0
  90. package/src/sass/components/codemirror.scss +628 -0
  91. package/src/sass/components/dropdown.scss +37 -0
  92. package/src/sass/components/editor.scss +78 -0
  93. package/src/sass/components/preview.scss +71 -0
  94. package/src/sass/components/prism.scss +142 -0
  95. package/src/sass/components/stats.scss +32 -0
  96. package/src/sass/components/toc.scss +184 -0
  97. package/src/sass/components/toolbar.scss +117 -0
  98. package/src/sass/core/AutoLink.scss +20 -0
  99. package/src/sass/core/BackgroundColor.scss +0 -0
  100. package/src/sass/core/Badge.scss +116 -0
  101. package/src/sass/core/Blockquote.scss +12 -0
  102. package/src/sass/core/Br.scss +0 -0
  103. package/src/sass/core/Card.scss +219 -0
  104. package/src/sass/core/CodeBlock.scss +205 -0
  105. package/src/sass/core/Color.scss +37 -0
  106. package/src/sass/core/CommentReference.scss +0 -0
  107. package/src/sass/core/Detail.scss +107 -0
  108. package/src/sass/core/Emoji.scss +127 -0
  109. package/src/sass/core/Emphasis.scss +9 -0
  110. package/src/sass/core/Footnote.scss +21 -0
  111. package/src/sass/core/FrontMatterVars.scss +19 -0
  112. package/src/sass/core/Header.scss +103 -0
  113. package/src/sass/core/HighLight.scss +0 -0
  114. package/src/sass/core/Hr.scss +10 -0
  115. package/src/sass/core/HtmlBlock.scss +0 -0
  116. package/src/sass/core/Iframe.scss +36 -0
  117. package/src/sass/core/Image.scss +59 -0
  118. package/src/sass/core/InlineCode.scss +10 -0
  119. package/src/sass/core/InlineMath.scss +11 -0
  120. package/src/sass/core/Link.scss +16 -0
  121. package/src/sass/core/List.scss +61 -0
  122. package/src/sass/core/Mark.scss +15 -0
  123. package/src/sass/core/MathBlock.scss +0 -0
  124. package/src/sass/core/Panel.scss +150 -0
  125. package/src/sass/core/Paragraph.scss +6 -0
  126. package/src/sass/core/Ruby.scss +0 -0
  127. package/src/sass/core/Size.scss +8 -0
  128. package/src/sass/core/Strikethrough.scss +0 -0
  129. package/src/sass/core/Sub.scss +5 -0
  130. package/src/sass/core/Suggester.scss +62 -0
  131. package/src/sass/core/Sup.scss +5 -0
  132. package/src/sass/core/Table.scss +127 -0
  133. package/src/sass/core/Toc.scss +28 -0
  134. package/src/sass/core/Transfer.scss +0 -0
  135. package/src/sass/core/Underline.scss +0 -0
  136. package/src/sass/google-fonts.scss +34 -0
  137. package/src/sass/index.scss +3 -0
  138. package/src/sass/prism/dark.scss +131 -0
  139. package/src/sass/prism/light.scss +143 -0
  140. package/src/sass/variables/colors.scss +96 -0
  141. package/src/toolbars/Bubble.js +232 -0
  142. package/src/toolbars/BubbleTable.js +147 -0
  143. package/src/toolbars/HookCenter.js +185 -0
  144. package/src/toolbars/MenuBase.js +357 -0
  145. package/src/toolbars/PreviewerBubble.js +558 -0
  146. package/src/toolbars/Toc.js +246 -0
  147. package/src/toolbars/Toolbar.js +401 -0
  148. package/src/toolbars/hooks/Audio.js +53 -0
  149. package/src/toolbars/hooks/Badge.js +80 -0
  150. package/src/toolbars/hooks/BarTable.js +41 -0
  151. package/src/toolbars/hooks/Bold.js +70 -0
  152. package/src/toolbars/hooks/Br.js +34 -0
  153. package/src/toolbars/hooks/Card.js +64 -0
  154. package/src/toolbars/hooks/CheckList.js +41 -0
  155. package/src/toolbars/hooks/Code.js +46 -0
  156. package/src/toolbars/hooks/Color.js +285 -0
  157. package/src/toolbars/hooks/Copy.js +139 -0
  158. package/src/toolbars/hooks/Detail.js +70 -0
  159. package/src/toolbars/hooks/ECharts.js +303 -0
  160. package/src/toolbars/hooks/Emoji.js +303 -0
  161. package/src/toolbars/hooks/Export.js +47 -0
  162. package/src/toolbars/hooks/File.js +54 -0
  163. package/src/toolbars/hooks/Formula.js +36 -0
  164. package/src/toolbars/hooks/FullScreen.js +55 -0
  165. package/src/toolbars/hooks/Graph.js +281 -0
  166. package/src/toolbars/hooks/H1.js +71 -0
  167. package/src/toolbars/hooks/H2.js +71 -0
  168. package/src/toolbars/hooks/H3.js +71 -0
  169. package/src/toolbars/hooks/Header.js +100 -0
  170. package/src/toolbars/hooks/Hr.js +35 -0
  171. package/src/toolbars/hooks/Iframe.js +35 -0
  172. package/src/toolbars/hooks/Image.js +60 -0
  173. package/src/toolbars/hooks/Insert.js +36 -0
  174. package/src/toolbars/hooks/Italic.js +70 -0
  175. package/src/toolbars/hooks/LineTable.js +41 -0
  176. package/src/toolbars/hooks/Link.js +46 -0
  177. package/src/toolbars/hooks/List.js +55 -0
  178. package/src/toolbars/hooks/Ol.js +41 -0
  179. package/src/toolbars/hooks/Panel.js +155 -0
  180. package/src/toolbars/hooks/Quote.js +45 -0
  181. package/src/toolbars/hooks/Redo.js +33 -0
  182. package/src/toolbars/hooks/Ruby.js +59 -0
  183. package/src/toolbars/hooks/Size.js +100 -0
  184. package/src/toolbars/hooks/Split.js +37 -0
  185. package/src/toolbars/hooks/Strikethrough.js +65 -0
  186. package/src/toolbars/hooks/Sub.js +58 -0
  187. package/src/toolbars/hooks/Sup.js +58 -0
  188. package/src/toolbars/hooks/SwitchModel.js +78 -0
  189. package/src/toolbars/hooks/Table.js +56 -0
  190. package/src/toolbars/hooks/Toc.js +35 -0
  191. package/src/toolbars/hooks/TogglePreview.js +79 -0
  192. package/src/toolbars/hooks/Ul.js +41 -0
  193. package/src/toolbars/hooks/Underline.js +65 -0
  194. package/src/toolbars/hooks/Undo.js +30 -0
  195. package/src/toolbars/hooks/Video.js +53 -0
  196. package/src/utils/LazyLoadImg.js +341 -0
  197. package/src/utils/autoindent.js +58 -0
  198. package/src/utils/codeBlockContentHandler.js +351 -0
  199. package/src/utils/config.js +98 -0
  200. package/src/utils/copy.js +55 -0
  201. package/src/utils/dialog.js +196 -0
  202. package/src/utils/dom.js +162 -0
  203. package/src/utils/downloadUtil.js +23 -0
  204. package/src/utils/env.js +22 -0
  205. package/src/utils/error.js +61 -0
  206. package/src/utils/event.js +38 -0
  207. package/src/utils/export.js +115 -0
  208. package/src/utils/file.js +121 -0
  209. package/src/utils/formulaUtilsHandler.js +230 -0
  210. package/src/utils/htmlparser.js +977 -0
  211. package/src/utils/image.js +99 -0
  212. package/src/utils/imgSizeHandler.js +279 -0
  213. package/src/utils/jsonUtils.js +17 -0
  214. package/src/utils/lineFeed.js +49 -0
  215. package/src/utils/listContentHandler.js +227 -0
  216. package/src/utils/lookbehind-replace.js +81 -0
  217. package/src/utils/mathjax.js +89 -0
  218. package/src/utils/myersDiff.js +211 -0
  219. package/src/utils/pasteHelper.js +253 -0
  220. package/src/utils/recount-pos.js +59 -0
  221. package/src/utils/regexp.js +295 -0
  222. package/src/utils/sanitize.js +477 -0
  223. package/src/utils/selection.js +50 -0
  224. package/src/utils/svgUtils.js +96 -0
  225. package/src/utils/tableContentHandler.js +592 -0
  226. package/tools/README.md +3 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ function mergeMarginBottom(bottom, top) {
17
+ const currentBottom = parseFloat(bottom);
18
+ const nextTop = parseFloat(top);
19
+ if (nextTop >= 0) {
20
+ // 不受合并影响
21
+ return currentBottom;
22
+ }
23
+ if (currentBottom >= 0) {
24
+ return currentBottom + nextTop;
25
+ }
26
+ // 同时为负数,取最小的
27
+ return Math.min(currentBottom, nextTop);
28
+ }
29
+
30
+ function mergeMarginTop(bottom, top) {
31
+ const prevBottom = parseFloat(bottom);
32
+ const currentTop = parseFloat(top);
33
+ if (currentTop < 0) {
34
+ // 负数的margin都被上一个区块吸收了
35
+ return 0;
36
+ }
37
+ if (prevBottom >= 0) {
38
+ // 如果当前margin-top比上一个margin-bottom要大,则只合并部分;反之合并全部,归属于上一个区块
39
+ return Math.max(currentTop - prevBottom, 0);
40
+ }
41
+ // 上一个margin-bottom为负数不受影响
42
+ return currentTop;
43
+ }
44
+ /**
45
+ * 用于解决块级元素边距合并问题
46
+ * @param {HTMLElement} element
47
+ */
48
+ export function getBlockTopAndHeightWithMargin(element) {
49
+ const prevSibling = element.previousElementSibling;
50
+ const nextSibling = element.nextElementSibling;
51
+ if (!prevSibling) {
52
+ const style = getComputedStyle(element);
53
+ const rect = element.getBoundingClientRect();
54
+ if (!nextSibling) {
55
+ return {
56
+ // marginBottom可能为负数
57
+ height: Math.max(parseFloat(style.marginTop) + rect.height + parseFloat(style.marginBottom), 0),
58
+ offsetTop: element.offsetTop - Math.abs(parseFloat(style.marginTop)),
59
+ };
60
+ }
61
+ const nextSibStyle = getComputedStyle(nextSibling);
62
+ const marginBottom = mergeMarginBottom(style.marginBottom, nextSibStyle.marginTop);
63
+ return {
64
+ height: Math.max(parseFloat(style.marginTop) + rect.height + marginBottom, 0), // marginBottom可能为负数
65
+ offsetTop: element.offsetTop - Math.abs(parseFloat(style.marginTop)),
66
+ };
67
+ }
68
+ const style = getComputedStyle(element);
69
+ const rect = element.getBoundingClientRect();
70
+ const prevSibStyle = getComputedStyle(prevSibling);
71
+ const marginTop = mergeMarginTop(prevSibStyle.marginBottom, style.marginTop);
72
+ if (!nextSibling) {
73
+ return {
74
+ height: Math.max(marginTop + rect.height + parseFloat(style.marginBottom), 0), // marginBottom可能为负数
75
+ offsetTop: element.offsetTop - Math.abs(parseFloat(style.marginTop)),
76
+ };
77
+ }
78
+ const nextSibStyle = getComputedStyle(nextSibling);
79
+ const marginBottom = mergeMarginBottom(style.marginBottom, nextSibStyle.marginTop);
80
+ return {
81
+ height: Math.max(marginTop + rect.height + marginBottom, 0), // marginBottom可能为负数
82
+ offsetTop: element.offsetTop - Math.abs(marginTop),
83
+ };
84
+ }
85
+
86
+ /**
87
+ * document.elementsFromPoint polyfill
88
+ * ref: https://github.com/JSmith01/elementsfrompoint-polyfill/blob/master/index.js
89
+ * @param {number} x
90
+ * @param {number} y
91
+ */
92
+ export function elementsFromPoint(x, y) {
93
+ // see https://caniuse.com/#search=elementsFromPoint
94
+ if (typeof document.elementsFromPoint === 'function') {
95
+ return document.elementsFromPoint(x, y);
96
+ }
97
+
98
+ if (typeof (/** @type {any}*/ (document).msElementsFromPoint) === 'function') {
99
+ const nodeList = /** @type {any}*/ (document).msElementsFromPoint(x, y);
100
+ return nodeList !== null ? Array.from(nodeList) : nodeList;
101
+ }
102
+ const elements = [];
103
+ const pointerEvents = [];
104
+ /** @type {HTMLElement} */
105
+ let ele;
106
+ do {
107
+ const currentElement = /** @type {HTMLElement} */ (document.elementFromPoint(x, y));
108
+ if (ele !== currentElement) {
109
+ ele = currentElement;
110
+ elements.push(ele);
111
+ pointerEvents.push(ele.style.pointerEvents);
112
+ ele.style.pointerEvents = 'none';
113
+ } else {
114
+ ele = null;
115
+ }
116
+ } while (ele);
117
+ elements.forEach((e, index) => {
118
+ e.style.pointerEvents = pointerEvents[index];
119
+ });
120
+ return elements;
121
+ }
122
+
123
+ export function getHTML(who, deep) {
124
+ if (!who || !who.tagName) {
125
+ return '';
126
+ }
127
+ let txt;
128
+ let ax;
129
+ let el = document.createElement('div');
130
+ el.appendChild(who.cloneNode(false));
131
+ txt = el.innerHTML;
132
+ if (deep) {
133
+ ax = txt.indexOf('>') + 1;
134
+ txt = txt.substring(0, ax) + who.innerHTML + txt.substring(ax);
135
+ }
136
+ el = null;
137
+ return txt;
138
+ }
139
+
140
+ /**
141
+ * @template {keyof HTMLElementTagNameMap} K
142
+ * @param {K} tagName 标签名
143
+ * @param {string} className 元素类名
144
+ * @param {Record<string,string>} attributes 附加属性
145
+ * @returns {HTMLElementTagNameMap[K]}
146
+ */
147
+ export function createElement(tagName, className = '', attributes = {}) {
148
+ const element = document.createElement(tagName);
149
+ element.className = className;
150
+ if (typeof attributes !== 'undefined') {
151
+ Object.keys(attributes).forEach((key) => {
152
+ const value = attributes[key];
153
+ if (key.startsWith('data-')) {
154
+ const dataName = key.replace(/^data-/, '');
155
+ element.dataset[dataName] = value;
156
+ return;
157
+ }
158
+ element.setAttribute(key, value);
159
+ });
160
+ }
161
+ return element;
162
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export function downloadByATag(url, fileName) {
18
+ const a = document.createElement('a');
19
+ a.href = url;
20
+ a.download = fileName;
21
+ a.click();
22
+ a.remove();
23
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * 判断当前是否浏览器环境
18
+ * @returns
19
+ */
20
+ export function isBrowser() {
21
+ return typeof window === 'object';
22
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * 三个地方的错误异常校验
18
+ * 1. markdown 对象参数校验
19
+ * 2. editText 用户输入校验,执行engine过程以防异常
20
+ * 3. 自定义hook校验 对外开发者开发标准校验
21
+ */
22
+
23
+ export const $expectTarget = (target, Constructor) => {
24
+ if (
25
+ (!Array.isArray(target) && typeof target !== Constructor.name.toLowerCase()) ||
26
+ (!Array.isArray(target) && Constructor.name.toLowerCase() === 'array')
27
+ ) {
28
+ throw new TypeError(`parameter given must be ${Constructor.name}`);
29
+ }
30
+
31
+ return true;
32
+ };
33
+
34
+ export const $expectInherit = (target, parent) => {
35
+ if (!(target instanceof parent)) {
36
+ throw new Error('the hook does not correctly inherit');
37
+ }
38
+ return true;
39
+ };
40
+
41
+ export const $expectInstance = (target) => {
42
+ if (typeof target !== 'object') {
43
+ throw new Error('the hook must be a instance, not a class');
44
+ }
45
+ return true;
46
+ };
47
+
48
+ // ref: https://github.com/mdlavin/nested-error-stacks
49
+ export default class NestedError extends Error {
50
+ constructor(message, nested) {
51
+ super(message);
52
+ this.name = 'Error';
53
+ this.stack = this.buildStackTrace(nested);
54
+ }
55
+
56
+ buildStackTrace(nested) {
57
+ const stack = nested && nested.stack ? nested.stack : '';
58
+ const newStack = `${this.stack}\nCaused By: ${stack}`;
59
+ return newStack;
60
+ }
61
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export function addEvent(elm, evType, fn, useCapture) {
17
+ if (elm.addEventListener) {
18
+ elm.addEventListener(evType, fn, useCapture); // DOM2.0
19
+ return true;
20
+ }
21
+
22
+ if (elm.attachEvent) {
23
+ const r = elm.attachEvent(`on${evType}`, fn); // IE5+
24
+ return r;
25
+ }
26
+ elm[`on${evType}`] = fn; // DOM 0
27
+ }
28
+
29
+ export function removeEvent(elm, evType, fn, useCapture) {
30
+ if (elm.removeEventListener) {
31
+ elm.removeEventListener(evType, fn, useCapture); // DOM2.0
32
+ } else if (elm.detachEvent) {
33
+ const r = elm.detachEvent(`on${evType}`, fn); // IE5+
34
+ return r;
35
+ } else {
36
+ elm[`on${evType}`] = null; // DOM 0
37
+ }
38
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * 先把body上的内容隐藏起来
19
+ * @returns {Array} displayList 记录body子元素原始的显隐信息
20
+ */
21
+ const hideBodyChildren = () => {
22
+ const displayList = [];
23
+ /** @type {HTMLElement[]}*/ (Array.from(document.body.children)).forEach((dom, index) => {
24
+ displayList[index] = dom.style.display;
25
+ dom.style.display = 'none';
26
+ });
27
+ return displayList;
28
+ };
29
+
30
+ /**
31
+ * 复原body上被隐藏的内容
32
+ * @param {Array} displayList 记录body子元素原始的显隐信息
33
+ */
34
+ const undoHideBodyChildren = (displayList = []) => {
35
+ /** @type {HTMLElement[]}*/ (Array.from(document.body.children)).forEach((dom, index) => {
36
+ if (typeof displayList[index] !== 'undefined') {
37
+ dom.style.display = displayList[index];
38
+ }
39
+ });
40
+ };
41
+
42
+ /**
43
+ * 将预览区域的内容放在body上准备后续导出操作
44
+ * @param {HTMLElement} previewDom 预览区域的dom
45
+ * @param {function} cb 准备好导出后开始执行导出操作
46
+ */
47
+ const getReadyToExport = (previewDom, cb) => {
48
+ const cherryPreviewer = /** @type {HTMLElement}*/ (previewDom.cloneNode(true));
49
+ // 强制去掉预览区的隐藏class
50
+ cherryPreviewer.className = cherryPreviewer.className.replace('cherry-previewer--hidden', '');
51
+ cherryPreviewer.style.width = '100%';
52
+ const mmls = cherryPreviewer.querySelectorAll('mjx-assistive-mml');
53
+ // a fix for html2canvas
54
+ mmls.forEach((e) => {
55
+ if (e instanceof HTMLElement) e.style.setProperty('visibility', 'hidden');
56
+ });
57
+ const cherryWrapper = document.createElement('div');
58
+ cherryWrapper.appendChild(cherryPreviewer);
59
+ const displayList = hideBodyChildren();
60
+ document.body.appendChild(cherryWrapper);
61
+ const bodyOverflow = document.body.style.overflow;
62
+ document.body.style.overflow = 'visible';
63
+ cb(cherryPreviewer, () => {
64
+ cherryWrapper.remove();
65
+ undoHideBodyChildren(displayList);
66
+ document.body.style.overflow = bodyOverflow;
67
+ });
68
+ };
69
+
70
+ /**
71
+ * 利用window.print导出成PDF
72
+ * @param {HTMLElement} previewDom 预览区域的dom
73
+ * @param {String} fileName 导出PDF文件名
74
+ */
75
+ export function exportPDF(previewDom, fileName) {
76
+ const oldTitle = document.title;
77
+ document.title = fileName;
78
+ getReadyToExport(previewDom, (/** @type {HTMLElement}*/ cherryPreviewer, /** @type {function}*/ thenFinish) => {
79
+ window.print();
80
+ thenFinish();
81
+ document.title = oldTitle;
82
+ });
83
+ }
84
+
85
+ /**
86
+ * 导出 markdown 文件
87
+ * @param {String} markdownText markdown文本
88
+ * @param {String} fileName 导出markdown文件名
89
+ */
90
+ export function exportMarkdownFile(markdownText, fileName) {
91
+ const blob = new Blob([markdownText], { type: 'text/markdown;charset=utf-8' });
92
+ const aLink = document.createElement('a');
93
+ aLink.style.display = 'none';
94
+ aLink.href = URL.createObjectURL(blob);
95
+ aLink.download = `${fileName}.md`;
96
+ document.body.appendChild(aLink);
97
+ aLink.click();
98
+ document.body.removeChild(aLink);
99
+ }
100
+
101
+ /**
102
+ * 导出预览区 HTML 文件
103
+ * @param {String} HTMLText HTML文本
104
+ * @param {String} fileName 导出HTML文件名
105
+ */
106
+ export function exportHTMLFile(HTMLText, fileName) {
107
+ const blob = new Blob([HTMLText], { type: 'text/markdown;charset=utf-8' });
108
+ const aLink = document.createElement('a');
109
+ aLink.style.display = 'none';
110
+ aLink.href = URL.createObjectURL(blob);
111
+ aLink.download = `${fileName}.html`;
112
+ document.body.appendChild(aLink);
113
+ aLink.click();
114
+ document.body.removeChild(aLink);
115
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export function splitFileName(filename) {
17
+ // 使用正则表达式匹配文件名和扩展名
18
+ const result = /^(.+?)(\.[^.]*$|$)/.exec(filename);
19
+
20
+ // 如果没有扩展名,返回原始文件名
21
+ if (!result) return { title: filename, ext: null };
22
+
23
+ // 返回文件名和扩展名
24
+ return { title: result[1], ext: result[2] ? result[2].substring(1) : null };
25
+ }
26
+ /**
27
+ * 上传文件的逻辑,如果有callback,则不再走默认的替换文本的逻辑,而是调用callback
28
+ * @param {string} type 上传文件的类型
29
+ */
30
+ export function handleUpload(editor, type = 'image', accept = '*', callback = null) {
31
+ // type为上传文件类型 image|video|audio|pdf|word
32
+ const input = document.createElement('input');
33
+ input.type = 'file';
34
+ input.id = 'fileUpload';
35
+ input.value = '';
36
+ input.style.display = 'none';
37
+ input.accept = accept;
38
+ // document.body.appendChild(input);
39
+ input.addEventListener('change', (event) => {
40
+ // @ts-ignore
41
+ const [file] = event.target.files;
42
+ // 文件上传后的回调函数可以由调用方自己实现
43
+ editor.options.fileUpload(file, (url, params = {}) => {
44
+ // 文件上传的默认回调行数,调用方可以完全不使用该函数
45
+ if (typeof url !== 'string' || !url) {
46
+ return;
47
+ }
48
+ if (callback) {
49
+ return callback(file.name, url, params);
50
+ }
51
+ let code = '';
52
+ if (type === 'image') {
53
+ // 如果是图片,则返回固定的图片markdown源码
54
+ code = `![${file.name}](${url})`;
55
+ } else if (type === 'video') {
56
+ // 如果是视频,则返回固定的视频markdown源码
57
+ code = `!video[${file.name}](${url})`;
58
+ } else if (type === 'audio') {
59
+ // 如果是音频,则返回固定的音频markdown源码
60
+ code = `!audio[${file.name}](${url})`;
61
+ } else {
62
+ const { title, ext } = splitFileName(file.name);
63
+ // 默认返回超链接
64
+ code = `!file[${title}|${ext}](${url})`;
65
+ }
66
+
67
+ // 替换选中区域
68
+ // @ts-ignore
69
+ editor.editor.doc.replaceSelection(code);
70
+ });
71
+ });
72
+ input.click();
73
+ }
74
+
75
+ /**
76
+ * 解析params参数
77
+ * @param params
78
+ */
79
+ export function handleParams(params) {
80
+ const ret = [];
81
+ if (params?.isBorder) {
82
+ ret.push('#B');
83
+ }
84
+ if (params?.isShadow) {
85
+ ret.push('#S');
86
+ }
87
+ if (params?.isRadius) {
88
+ ret.push('#R');
89
+ }
90
+ if (params?.width) {
91
+ ret.push(`#${params.width}`);
92
+ }
93
+ if (params?.height) {
94
+ if (!params.width) {
95
+ ret.push('#auto');
96
+ }
97
+ ret.push(`#${params.height}`);
98
+ }
99
+ return ret.join(' ');
100
+ }
101
+
102
+ export function handleFileUploadCallback(url, params, file) {
103
+ const name = params?.name ?? file.name;
104
+ let type = '';
105
+ let poster = '';
106
+ if (/video/i.test(file.type)) {
107
+ type = '!video';
108
+ poster = params?.poster ? `{poster=${params.poster}}` : '';
109
+ }
110
+ if (/audio/i.test(file.type)) {
111
+ type = '!audio';
112
+ }
113
+ if (/image/i.test(file.type)) {
114
+ type = '!';
115
+ }
116
+ if (/file/i.test(file.type)) {
117
+ type = '!file';
118
+ }
119
+ const style = type ? handleParams(params) : '';
120
+ return `${type}[${name}${style}](${url})${poster}`;
121
+ }