@cherry-markdown/cherry-markdown-dev 0.9.0-dev.202504110650.834443a → 0.9.0-dev.202504160300.d23d141

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 (327) hide show
  1. package/README.md +2 -2
  2. package/dist/addons/advance/cherry-table-echarts-plugin.js +1 -1
  3. package/dist/addons/cherry-code-block-mermaid-plugin.js +1 -1
  4. package/dist/cherry-markdown.core.common.js +1 -1
  5. package/dist/cherry-markdown.core.js +1 -1
  6. package/dist/cherry-markdown.engine.core.common.js +1 -1
  7. package/dist/cherry-markdown.engine.core.esm.js +1 -1
  8. package/dist/cherry-markdown.engine.core.js +1 -1
  9. package/dist/cherry-markdown.esm.js +1 -1
  10. package/dist/cherry-markdown.js +1 -1
  11. package/dist/cherry-markdown.min.js +1 -1
  12. package/dist/fonts/ch-icon.eot +0 -0
  13. package/dist/fonts/ch-icon.ttf +0 -0
  14. package/dist/fonts/ch-icon.woff +0 -0
  15. package/dist/fonts/ch-icon.woff2 +0 -0
  16. package/package.json +1 -3
  17. package/src/Cherry.config.js +0 -634
  18. package/src/Cherry.js +0 -1104
  19. package/src/CherryStatic.js +0 -70
  20. package/src/Editor.js +0 -748
  21. package/src/Engine.js +0 -402
  22. package/src/Event.js +0 -140
  23. package/src/Factory.js +0 -180
  24. package/src/Logger.js +0 -31
  25. package/src/Previewer.js +0 -1192
  26. package/src/Sanitizer.js +0 -4
  27. package/src/Sanitizer.node.js +0 -7
  28. package/src/UrlCache.js +0 -98
  29. package/src/addons/advance/cherry-table-echarts-plugin.js +0 -170
  30. package/src/addons/cherry-code-block-mermaid-plugin.js +0 -158
  31. package/src/addons/cherry-code-block-plantuml-plugin.js +0 -106
  32. package/src/core/HookCenter.js +0 -297
  33. package/src/core/HooksConfig.js +0 -105
  34. package/src/core/ParagraphBase.js +0 -332
  35. package/src/core/SentenceBase.js +0 -65
  36. package/src/core/SyntaxBase.js +0 -194
  37. package/src/core/hooks/AutoLink.js +0 -232
  38. package/src/core/hooks/BackgroundColor.js +0 -46
  39. package/src/core/hooks/Blockquote.js +0 -70
  40. package/src/core/hooks/Br.js +0 -85
  41. package/src/core/hooks/CodeBlock.js +0 -456
  42. package/src/core/hooks/Color.js +0 -46
  43. package/src/core/hooks/CommentReference.js +0 -96
  44. package/src/core/hooks/Detail.js +0 -108
  45. package/src/core/hooks/Emoji.config.js +0 -1825
  46. package/src/core/hooks/Emoji.js +0 -119
  47. package/src/core/hooks/Emphasis.js +0 -113
  48. package/src/core/hooks/Footnote.js +0 -125
  49. package/src/core/hooks/FrontMatter.js +0 -51
  50. package/src/core/hooks/Header.js +0 -234
  51. package/src/core/hooks/HighLight.js +0 -37
  52. package/src/core/hooks/Hr.js +0 -52
  53. package/src/core/hooks/HtmlBlock.js +0 -199
  54. package/src/core/hooks/Image.js +0 -174
  55. package/src/core/hooks/InlineCode.js +0 -48
  56. package/src/core/hooks/InlineMath.js +0 -108
  57. package/src/core/hooks/Link.js +0 -160
  58. package/src/core/hooks/List.js +0 -264
  59. package/src/core/hooks/MathBlock.js +0 -104
  60. package/src/core/hooks/Panel.js +0 -145
  61. package/src/core/hooks/Paragraph.js +0 -84
  62. package/src/core/hooks/Ruby.js +0 -34
  63. package/src/core/hooks/Size.js +0 -51
  64. package/src/core/hooks/Strikethrough.js +0 -54
  65. package/src/core/hooks/Sub.js +0 -47
  66. package/src/core/hooks/SuggestList.js +0 -333
  67. package/src/core/hooks/Suggester.js +0 -707
  68. package/src/core/hooks/Sup.js +0 -47
  69. package/src/core/hooks/Table.js +0 -275
  70. package/src/core/hooks/Toc.js +0 -292
  71. package/src/core/hooks/Transfer.js +0 -47
  72. package/src/core/hooks/Underline.js +0 -37
  73. package/src/index.core.js +0 -29
  74. package/src/index.engine.core.js +0 -68
  75. package/src/index.engine.js +0 -28
  76. package/src/index.js +0 -32
  77. package/src/libs/mermaidAPI.8.4.8.js +0 -1
  78. package/src/libs/mermaidAPI.8.5.2.js +0 -42
  79. package/src/libs/rawdeflate.js +0 -1663
  80. package/src/locales/en_US.js +0 -139
  81. package/src/locales/index.js +0 -25
  82. package/src/locales/ru_RU.js +0 -139
  83. package/src/locales/zh_CN.js +0 -142
  84. package/src/sass/base.scss +0 -26
  85. package/src/sass/bubble_formula.scss +0 -166
  86. package/src/sass/ch-icon.scss +0 -118
  87. package/src/sass/cherry.scss +0 -1116
  88. package/src/sass/components/bubble.scss +0 -173
  89. package/src/sass/components/shortcut_key_config.scss +0 -108
  90. package/src/sass/formula_utils_bubble.scss +0 -82
  91. package/src/sass/icon_template.scss +0 -24
  92. package/src/sass/icons/uEA03-list.svg +0 -19
  93. package/src/sass/icons/uEA04-check.svg +0 -14
  94. package/src/sass/icons/uEA09-square.svg +0 -10
  95. package/src/sass/icons/uEA0A-bold.svg +0 -20
  96. package/src/sass/icons/uEA0B-code.svg +0 -18
  97. package/src/sass/icons/uEA0C-color.svg +0 -13
  98. package/src/sass/icons/uEA0D-header.svg +0 -8
  99. package/src/sass/icons/uEA0E-image.svg +0 -15
  100. package/src/sass/icons/uEA0F-italic.svg +0 -8
  101. package/src/sass/icons/uEA10-link.svg +0 -16
  102. package/src/sass/icons/uEA11-ol.svg +0 -21
  103. package/src/sass/icons/uEA12-size.svg +0 -11
  104. package/src/sass/icons/uEA13-strike.svg +0 -16
  105. package/src/sass/icons/uEA14-table.svg +0 -12
  106. package/src/sass/icons/uEA15-ul.svg +0 -17
  107. package/src/sass/icons/uEA16-underline.svg +0 -13
  108. package/src/sass/icons/uEA17-word.svg +0 -16
  109. package/src/sass/icons/uEA18-blockquote.svg +0 -11
  110. package/src/sass/icons/uEA19-font.svg +0 -10
  111. package/src/sass/icons/uEA1F-insertClass.svg +0 -39
  112. package/src/sass/icons/uEA20-insertFlow.svg +0 -8
  113. package/src/sass/icons/uEA21-insertFormula.svg +0 -23
  114. package/src/sass/icons/uEA22-insertGantt.svg +0 -13
  115. package/src/sass/icons/uEA23-insertGraph.svg +0 -13
  116. package/src/sass/icons/uEA24-insertPie.svg +0 -19
  117. package/src/sass/icons/uEA25-insertSeq.svg +0 -20
  118. package/src/sass/icons/uEA26-insertState.svg +0 -35
  119. package/src/sass/icons/uEA27-line.svg +0 -11
  120. package/src/sass/icons/uEA28-preview.svg +0 -18
  121. package/src/sass/icons/uEA29-previewClose.svg +0 -24
  122. package/src/sass/icons/uEA2A-toc.svg +0 -24
  123. package/src/sass/icons/uEA2D-sub.svg +0 -15
  124. package/src/sass/icons/uEA2E-sup.svg +0 -15
  125. package/src/sass/icons/uEA2F-h1.svg +0 -16
  126. package/src/sass/icons/uEA30-h2.svg +0 -20
  127. package/src/sass/icons/uEA31-h3.svg +0 -23
  128. package/src/sass/icons/uEA32-h4.svg +0 -16
  129. package/src/sass/icons/uEA33-h5.svg +0 -20
  130. package/src/sass/icons/uEA34-h6.svg +0 -17
  131. package/src/sass/icons/uEA35-video.svg +0 -20
  132. package/src/sass/icons/uEA36-insert.svg +0 -25
  133. package/src/sass/icons/uEA37-little_table.svg +0 -30
  134. package/src/sass/icons/uEA38-pdf.svg +0 -27
  135. package/src/sass/icons/uEA39-checklist.svg +0 -22
  136. package/src/sass/icons/uEA40-close.svg +0 -12
  137. package/src/sass/icons/uEA41-fullscreen.svg +0 -81
  138. package/src/sass/icons/uEA42-minscreen.svg +0 -77
  139. package/src/sass/icons/uEA43-insertChart.svg +0 -23
  140. package/src/sass/icons/uEA44-question.svg +0 -25
  141. package/src/sass/icons/uEA45-settings.svg +0 -32
  142. package/src/sass/icons/uEA46-ok.svg +0 -7
  143. package/src/sass/icons/uEA47-br.svg +0 -22
  144. package/src/sass/icons/uEA48-normal.svg +0 -15
  145. package/src/sass/icons/uEA49-undo.svg +0 -19
  146. package/src/sass/icons/uEA50-redo.svg +0 -21
  147. package/src/sass/icons/uEA51-copy.svg +0 -6
  148. package/src/sass/icons/uEA52-phone.svg +0 -5
  149. package/src/sass/icons/uEA53-cherry-table-delete.svg +0 -17
  150. package/src/sass/icons/uEA54-cherry-table-insert-bottom.svg +0 -16
  151. package/src/sass/icons/uEA55-cherry-table-insert-left.svg +0 -15
  152. package/src/sass/icons/uEA56-cherry-table-insert-right.svg +0 -16
  153. package/src/sass/icons/uEA57-cherry-table-insert-top.svg +0 -16
  154. package/src/sass/icons/uEA58-sort-s.svg +0 -13
  155. package/src/sass/icons/uEA59-pinyin.svg +0 -1
  156. package/src/sass/icons/uEA5A-create.svg +0 -24
  157. package/src/sass/icons/uEA5B-download.svg +0 -34
  158. package/src/sass/icons/uEA5C-edit.svg +0 -3
  159. package/src/sass/icons/uEA5D-export.svg +0 -53
  160. package/src/sass/icons/uEA5E-folder-open.svg +0 -3
  161. package/src/sass/icons/uEA5F-folder.svg +0 -3
  162. package/src/sass/icons/uEA60-help.svg +0 -5
  163. package/src/sass/icons/uEA61-pen-fill.svg +0 -13
  164. package/src/sass/icons/uEA62-pen.svg +0 -3
  165. package/src/sass/icons/uEA64-tips.svg +0 -5
  166. package/src/sass/icons/uEA65-warn.svg +0 -5
  167. package/src/sass/icons/uEA66-mistake.svg +0 -4
  168. package/src/sass/icons/uEA67-success.svg +0 -4
  169. package/src/sass/icons/uEA68-danger.svg +0 -4
  170. package/src/sass/icons/uEA69-info.svg +0 -5
  171. package/src/sass/icons/uEA6A-primary.svg +0 -5
  172. package/src/sass/icons/uEA6B-warning.svg +0 -5
  173. package/src/sass/icons/uEA6C-justify.svg +0 -19
  174. package/src/sass/icons/uEA6D-justifyCenter.svg +0 -19
  175. package/src/sass/icons/uEA6E-justifyLeft.svg +0 -19
  176. package/src/sass/icons/uEA6F-justifyRight.svg +0 -19
  177. package/src/sass/icons/uEA70-chevronsLeft.svg +0 -1
  178. package/src/sass/icons/uEA71-chevronsRight.svg +0 -1
  179. package/src/sass/icons/uEA72-trendingUp.svg +0 -1
  180. package/src/sass/icons/uEA74-codeBlock.svg +0 -1
  181. package/src/sass/icons/uEA75-expand.svg +0 -3
  182. package/src/sass/icons/uEA76-unExpand.svg +0 -3
  183. package/src/sass/icons/uEA77-swap-vert.svg +0 -1
  184. package/src/sass/icons/uEA78-swap.svg +0 -1
  185. package/src/sass/icons/uEA79-keyboard.svg +0 -1
  186. package/src/sass/icons/uEA7A-command.svg +0 -1
  187. package/src/sass/icons/uEA7B-search.svg +0 -1
  188. package/src/sass/index.scss +0 -3
  189. package/src/sass/markdown.scss +0 -668
  190. package/src/sass/markdown_pure.scss +0 -9
  191. package/src/sass/prettyprint/prettyprint.scss +0 -118
  192. package/src/sass/previewer.scss +0 -179
  193. package/src/sass/print.scss +0 -13
  194. package/src/sass/prism/coy.scss +0 -220
  195. package/src/sass/prism/dark.scss +0 -132
  196. package/src/sass/prism/default.scss +0 -143
  197. package/src/sass/prism/funky.scss +0 -133
  198. package/src/sass/prism/okaidia.scss +0 -126
  199. package/src/sass/prism/one-dark.scss +0 -440
  200. package/src/sass/prism/one-light.scss +0 -428
  201. package/src/sass/prism/solarized-light.scss +0 -153
  202. package/src/sass/prism/tomorrow-night.scss +0 -125
  203. package/src/sass/prism/twilight.scss +0 -202
  204. package/src/sass/prism/vs-dark.scss +0 -275
  205. package/src/sass/prism/vs-light.scss +0 -168
  206. package/src/sass/themes/blue.scss +0 -411
  207. package/src/sass/themes/dark.scss +0 -517
  208. package/src/sass/themes/default.scss +0 -255
  209. package/src/sass/themes/green.scss +0 -395
  210. package/src/sass/themes/light.scss +0 -368
  211. package/src/sass/themes/red.scss +0 -397
  212. package/src/sass/themes/violet.scss +0 -410
  213. package/src/sass/variable.scss +0 -84
  214. package/src/toolbars/Bubble.js +0 -234
  215. package/src/toolbars/BubbleFormula.js +0 -298
  216. package/src/toolbars/BubbleTable.js +0 -147
  217. package/src/toolbars/FloatMenu.js +0 -131
  218. package/src/toolbars/HiddenToolbar.js +0 -36
  219. package/src/toolbars/HookCenter.js +0 -231
  220. package/src/toolbars/MenuBase.js +0 -569
  221. package/src/toolbars/PreviewerBubble.js +0 -608
  222. package/src/toolbars/ShortcutKeyConfigPanel.js +0 -345
  223. package/src/toolbars/Sidebar.js +0 -36
  224. package/src/toolbars/Toc.js +0 -242
  225. package/src/toolbars/Toolbar.js +0 -449
  226. package/src/toolbars/ToolbarRight.js +0 -37
  227. package/src/toolbars/hooks/Audio.js +0 -79
  228. package/src/toolbars/hooks/BarTable.js +0 -41
  229. package/src/toolbars/hooks/Bold.js +0 -73
  230. package/src/toolbars/hooks/Br.js +0 -34
  231. package/src/toolbars/hooks/ChangeLocale.js +0 -62
  232. package/src/toolbars/hooks/ChatGpt.js +0 -182
  233. package/src/toolbars/hooks/CheckList.js +0 -41
  234. package/src/toolbars/hooks/Code.js +0 -49
  235. package/src/toolbars/hooks/CodeTheme.js +0 -66
  236. package/src/toolbars/hooks/Color.js +0 -298
  237. package/src/toolbars/hooks/Copy.js +0 -141
  238. package/src/toolbars/hooks/Detail.js +0 -69
  239. package/src/toolbars/hooks/DrawIo.js +0 -57
  240. package/src/toolbars/hooks/Export.js +0 -49
  241. package/src/toolbars/hooks/File.js +0 -79
  242. package/src/toolbars/hooks/Formula.js +0 -69
  243. package/src/toolbars/hooks/FullScreen.js +0 -50
  244. package/src/toolbars/hooks/Graph.js +0 -263
  245. package/src/toolbars/hooks/H1.js +0 -71
  246. package/src/toolbars/hooks/H2.js +0 -71
  247. package/src/toolbars/hooks/H3.js +0 -71
  248. package/src/toolbars/hooks/Header.js +0 -118
  249. package/src/toolbars/hooks/Hr.js +0 -35
  250. package/src/toolbars/hooks/Image.js +0 -91
  251. package/src/toolbars/hooks/InlineCode.js +0 -53
  252. package/src/toolbars/hooks/Insert.js +0 -193
  253. package/src/toolbars/hooks/Italic.js +0 -72
  254. package/src/toolbars/hooks/Justify.js +0 -49
  255. package/src/toolbars/hooks/LineTable.js +0 -41
  256. package/src/toolbars/hooks/Link.js +0 -49
  257. package/src/toolbars/hooks/List.js +0 -55
  258. package/src/toolbars/hooks/MobilePreview.js +0 -44
  259. package/src/toolbars/hooks/Ol.js +0 -41
  260. package/src/toolbars/hooks/Panel.js +0 -140
  261. package/src/toolbars/hooks/Pdf.js +0 -78
  262. package/src/toolbars/hooks/Publish.js +0 -123
  263. package/src/toolbars/hooks/QuickTable.js +0 -43
  264. package/src/toolbars/hooks/Quote.js +0 -45
  265. package/src/toolbars/hooks/Redo.js +0 -33
  266. package/src/toolbars/hooks/Ruby.js +0 -59
  267. package/src/toolbars/hooks/Search.js +0 -53
  268. package/src/toolbars/hooks/Settings.js +0 -220
  269. package/src/toolbars/hooks/ShortcutKey.js +0 -62
  270. package/src/toolbars/hooks/Size.js +0 -118
  271. package/src/toolbars/hooks/Split.js +0 -37
  272. package/src/toolbars/hooks/Strikethrough.js +0 -71
  273. package/src/toolbars/hooks/Sub.js +0 -58
  274. package/src/toolbars/hooks/Sup.js +0 -58
  275. package/src/toolbars/hooks/SwitchModel.js +0 -56
  276. package/src/toolbars/hooks/Table.js +0 -56
  277. package/src/toolbars/hooks/Theme.js +0 -62
  278. package/src/toolbars/hooks/Toc.js +0 -35
  279. package/src/toolbars/hooks/TogglePreview.js +0 -91
  280. package/src/toolbars/hooks/Ul.js +0 -41
  281. package/src/toolbars/hooks/Underline.js +0 -68
  282. package/src/toolbars/hooks/Undo.js +0 -30
  283. package/src/toolbars/hooks/Video.js +0 -79
  284. package/src/toolbars/hooks/Word.js +0 -78
  285. package/src/toolbars/hooks/WordCount.js +0 -106
  286. package/src/utils/autoindent.js +0 -58
  287. package/src/utils/cm-search-replace.js +0 -794
  288. package/src/utils/code-preview-language-setting.js +0 -180
  289. package/src/utils/codeBlockContentHandler.js +0 -400
  290. package/src/utils/config.js +0 -174
  291. package/src/utils/copy.js +0 -55
  292. package/src/utils/dialog.js +0 -214
  293. package/src/utils/dom.js +0 -163
  294. package/src/utils/downloadUtil.js +0 -23
  295. package/src/utils/env.js +0 -22
  296. package/src/utils/error.js +0 -61
  297. package/src/utils/event.js +0 -38
  298. package/src/utils/export.js +0 -166
  299. package/src/utils/file.js +0 -164
  300. package/src/utils/formulaUtilsHandler.js +0 -232
  301. package/src/utils/htmlparser.js +0 -976
  302. package/src/utils/image.js +0 -99
  303. package/src/utils/imgSizeHandler.js +0 -279
  304. package/src/utils/lazyLoadImg.js +0 -327
  305. package/src/utils/lineFeed.js +0 -49
  306. package/src/utils/listContentHandler.js +0 -227
  307. package/src/utils/lookbehind-replace.js +0 -81
  308. package/src/utils/mathjax.js +0 -89
  309. package/src/utils/myersDiff.js +0 -211
  310. package/src/utils/pasteHelper.js +0 -253
  311. package/src/utils/platformTransform.js +0 -71
  312. package/src/utils/recount-pos.js +0 -59
  313. package/src/utils/regexp.js +0 -295
  314. package/src/utils/sanitize.js +0 -477
  315. package/src/utils/selection.js +0 -50
  316. package/src/utils/shortcutKey.js +0 -291
  317. package/src/utils/svgUtils.js +0 -96
  318. package/src/utils/tableContentHandler.js +0 -876
  319. package/test/core/CommonMark.spec.ts +0 -62
  320. package/test/core/hooks/AutoLink.spec.ts +0 -28
  321. package/test/core/hooks/List.spec.ts +0 -79
  322. package/test/core/hooks/__snapshots__/List.spec.ts.snap +0 -11
  323. package/test/example.md +0 -778
  324. package/test/node.js +0 -10
  325. package/test/suites/commonmark.spec.json +0 -5218
  326. package/test/tsconfig.test.json +0 -6
  327. package/test/utils/regexp.spec.ts +0 -28
@@ -1,876 +0,0 @@
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
- import { getTableRule, getCodeBlockRule } from '@/utils/regexp';
17
-
18
- /**
19
- * 用于在表格上出现编辑区,并提供拖拽行列的功能
20
- */
21
- export default class TableHandler {
22
- /**
23
- * 用来存放所有的数据
24
- */
25
- tableEditor = {
26
- info: {}, // 当前点击的预览区域table的相关信息
27
- tableCodes: [], // 编辑器内所有的表格语法
28
- editorDom: {}, // 编辑器容器
29
- };
30
-
31
- constructor(trigger, target, container, previewerDom, codeMirror, tableElement, cherry) {
32
- // 触发方式 click / hover
33
- this.trigger = trigger;
34
- this.target = target;
35
- this.previewerDom = previewerDom;
36
- this.container = container;
37
- this.codeMirror = codeMirror;
38
- this.$initReg();
39
- this.$findTableInEditor();
40
- this.tableElement = tableElement;
41
- this.$cherry = cherry;
42
- }
43
-
44
- emit(type, event = {}, callback = () => {}) {
45
- switch (type) {
46
- case 'keyup':
47
- return this.trigger === 'click' && this.$onInputChange(event);
48
- case 'remove':
49
- return this.$remove();
50
- case 'scroll':
51
- return this.$refreshPosition();
52
- case 'previewUpdate':
53
- return this.$refreshPosition();
54
- case 'mousedown':
55
- return;
56
- case 'mouseup':
57
- return this.trigger === 'click' && this.$tryRemoveMe(event, callback);
58
- }
59
- }
60
-
61
- $tryRemoveMe(event, callback) {
62
- if (!/textarea/i.test(event.target.tagName)) {
63
- this.$remove();
64
- callback();
65
- }
66
- }
67
-
68
- /**
69
- * 获取目标dom的位置信息和尺寸信息
70
- */
71
- $getPosition(node = this.tableEditor.info.tdNode) {
72
- const position = node.getBoundingClientRect();
73
- const editorPosition = this.previewerDom.parentNode.getBoundingClientRect();
74
- return {
75
- top: position.top - editorPosition.top,
76
- height: position.height,
77
- width: position.width,
78
- left: position.left - editorPosition.left,
79
- maxHeight: editorPosition.height,
80
- };
81
- }
82
-
83
- setStyle(element, property, value) {
84
- const info = element.getBoundingClientRect();
85
- if (info[property] !== value) {
86
- element.style[property] = value;
87
- }
88
- }
89
-
90
- /**
91
- * TODO: 这里是分别对文本框、操作符号和选项设置偏移,应该作为一个整体来设置
92
- */
93
- $setInputOffset() {
94
- const tdInfo = this.$getPosition();
95
- const { inputDiv } = this.tableEditor.editorDom;
96
- // 设置文本框的偏移及大小
97
- this.setStyle(inputDiv, 'width', `${tdInfo.width}px`);
98
- this.setStyle(inputDiv, 'height', `${tdInfo.height}px`);
99
- this.setStyle(inputDiv, 'top', `${tdInfo.top}px`);
100
- this.setStyle(inputDiv, 'left', `${tdInfo.left}px`);
101
-
102
- // 根据是否超出边界来显示或者隐藏元素
103
- const isWithinBounds = tdInfo.top >= 0 && tdInfo.top + tdInfo.height <= tdInfo.maxHeight;
104
- this.setStyle(inputDiv, 'display', isWithinBounds ? '' : 'none');
105
- }
106
-
107
- /**
108
- * 刷新操作符位置
109
- */
110
- $setSymbolOffset() {
111
- const container = this.tableEditor.editorDom.symbolContainer;
112
- const { tableNode, trNode, isTHead } = this.tableEditor.info;
113
- const tableInfo = this.$getPosition(tableNode);
114
- const trInfo = this.$getPosition(trNode);
115
- const tdInfo = this.$getPosition();
116
- const previewerRect = this.previewerDom.getBoundingClientRect();
117
- // 设置容器宽高
118
- this.setStyle(this.container, 'width', `${tableInfo.width}px`);
119
- this.setStyle(this.container, 'height', `${tableInfo.height}px`);
120
- this.setStyle(this.container, 'top', `${tableInfo.top}px`);
121
- this.setStyle(this.container, 'left', `${tableInfo.left}px`);
122
-
123
- // 判断是否在预览区内
124
- const isWithinBounds = (symbol) => {
125
- const symbolRect = symbol.getBoundingClientRect();
126
- const boundMap = {
127
- top: [previewerRect.top, previewerRect.top + previewerRect.height - symbolRect.height],
128
- left: [previewerRect.left, previewerRect.left + previewerRect.width - symbolRect.width],
129
- };
130
- return Object.entries(boundMap).every(([key, [min, max]]) => symbolRect[key] >= min && symbolRect[key] <= max);
131
- };
132
-
133
- // 设置操作符位置与控制显隐
134
- container.childNodes.forEach((node) => {
135
- const { index, type, dir } = node.dataset;
136
- const propDict = {
137
- Row: ['left', 'right'],
138
- Col: ['top', 'bottom'],
139
- };
140
- const offset = {
141
- outer: 20,
142
- radius: 7,
143
- };
144
- this.setStyle(node, propDict[dir][index], `-${offset.outer}px`);
145
- this.setStyle(node, 'display', '');
146
- const refreshMap = {
147
- LastRow: () => this.setStyle(node, 'top', `${trInfo.top - tableInfo.top - offset.radius}px`),
148
- NextRow: () => this.setStyle(node, 'top', `${trInfo.top - tableInfo.top + trInfo.height - offset.radius}px`),
149
- LastCol: () => this.setStyle(node, 'left', `${tdInfo.left - tableInfo.left - offset.radius}px`),
150
- NextCol: () => this.setStyle(node, 'left', `${tdInfo.left - tableInfo.left + tdInfo.width - offset.radius}px`),
151
- };
152
- const oper = `${type}${dir}`;
153
- refreshMap[oper]();
154
- this.setStyle(node, 'display', isWithinBounds(node) ? '' : 'none');
155
- if (isTHead && oper === 'LastRow') {
156
- this.setStyle(node, 'display', 'none');
157
- }
158
- });
159
- }
160
-
161
- /**
162
- * 刷新定位
163
- */
164
- $refreshPosition() {
165
- if (this.trigger === 'click') {
166
- this.$setInputOffset();
167
- return;
168
- }
169
- this.$setSymbolOffset();
170
- this.$setDeleteButtonPosition();
171
- }
172
-
173
- $remove() {
174
- this.tableEditor = { info: {}, tableCodes: [], editorDom: {} };
175
- }
176
-
177
- /**
178
- * 收集编辑器中的表格语法,并记录表格语法的开始的offset
179
- */
180
- $collectTableCode() {
181
- const tableCodes = [];
182
- this.codeMirror
183
- .getValue()
184
- .replace(this.codeBlockReg, (whole, ...args) => {
185
- // 先把代码块里的表格语法关键字干掉
186
- return whole.replace(/\|/g, '.');
187
- })
188
- .replace(this.tableReg, function (whole, ...args) {
189
- const match = whole.replace(/^\n*/, '');
190
- const offsetBegin = args[args.length - 2] + whole.match(/^\n*/)[0].length;
191
- tableCodes.push({
192
- code: match,
193
- offset: offsetBegin,
194
- });
195
- });
196
- this.tableEditor.tableCodes = tableCodes;
197
- }
198
-
199
- /**
200
- * 获取预览区域被点击的table对象,并记录table的顺位
201
- */
202
- $collectTableDom() {
203
- const list = Array.from(this.previewerDom.querySelectorAll('table.cherry-table'));
204
- const tableNode = this.$getClosestNode(this.target, 'TABLE');
205
- if (tableNode === false) {
206
- return false;
207
- }
208
- const columns = Array.from(this.target.parentElement.childNodes).filter((child) => {
209
- // 计算列数
210
- return child.tagName.toLowerCase() === 'td';
211
- }).length;
212
-
213
- this.tableEditor.info = {
214
- tableNode,
215
- tdNode: this.target,
216
- trNode: this.target.parentElement,
217
- tdIndex: Array.from(this.target.parentElement.childNodes).indexOf(this.target),
218
- trIndex: Array.from(this.target.parentElement.parentElement.childNodes).indexOf(this.target.parentElement),
219
- isTHead: this.target.parentElement.parentElement.tagName !== 'TBODY',
220
- totalTables: list.length,
221
- tableIndex: list.indexOf(tableNode),
222
- tableText: tableNode.textContent.replace(/[\s]/g, ''),
223
- columns,
224
- };
225
- }
226
-
227
- /**
228
- * 选中对应单元格、所在行、所在列的内容
229
- * @param {Number} index
230
- * @param {String} type 'td': 当前单元格, 'table': 当前表格
231
- * @param {Boolean} select 是否选中编辑器中的代码
232
- */
233
- $setSelection(index, type = 'table', select = true) {
234
- const tableCode = this.tableEditor.tableCodes[index];
235
- const whole = this.codeMirror.getValue();
236
- const selectTdInfo = this.tableEditor.info;
237
- const beginLine = whole.slice(0, tableCode.offset).match(/\n/g)?.length ?? 0;
238
- const { preLine, preCh, plusCh, currentTd } = this.$getTdOffset(
239
- tableCode.code,
240
- selectTdInfo.isTHead,
241
- selectTdInfo.trIndex,
242
- selectTdInfo.tdIndex,
243
- );
244
- if (type === 'table') {
245
- const endLine = beginLine + tableCode.code.match(/\n/g).length;
246
- const endCh = tableCode.code.match(/[^\n]+\n*$/)[0].length;
247
- this.tableEditor.info.selection = [
248
- { line: beginLine, ch: 0 },
249
- { line: endLine, ch: endCh },
250
- ];
251
- } else {
252
- this.tableEditor.info.selection = [
253
- { line: beginLine + preLine, ch: preCh },
254
- { line: beginLine + preLine, ch: preCh + plusCh },
255
- ];
256
- }
257
- select && this.codeMirror.setSelection(...this.tableEditor.info.selection);
258
- this.tableEditor.info.code = currentTd;
259
- }
260
-
261
- /**
262
- * 获取对应单元格的偏移量
263
- * @param {String} tableCode
264
- * @param {Boolean} isTHead
265
- * @param {Number} trIndex
266
- * @param {Number} tdIndex
267
- */
268
- $getTdOffset(tableCode, isTHead, trIndex, tdIndex) {
269
- const codes = tableCode.split(/\n/);
270
- const targetTr = isTHead ? 0 : trIndex + 2;
271
- const tds = codes[targetTr].split(/\|/);
272
- const needPlus1 = /^\s*$/.test(tds[0]);
273
- const targetTd = needPlus1 ? tdIndex + 1 : tdIndex;
274
- const current = tds[targetTd];
275
- const pre = [];
276
- for (let i = 0; i < targetTd; i++) {
277
- pre.push(tds[i]);
278
- }
279
- return {
280
- preLine: targetTr,
281
- preCh: needPlus1 ? pre.join('|').length + 1 : pre.join('|').length,
282
- plusCh: current.length,
283
- currentTd: current,
284
- };
285
- }
286
-
287
- /**
288
- * 在编辑器里找到对应的表格源码,并让编辑器选中
289
- */
290
- $findTableInEditor() {
291
- this.$collectTableDom();
292
- this.$collectTableCode();
293
- // 暂时不考虑代码块中包含表格、人为输入表格html语法、tapd特色表格语法的情况
294
- // 也就是说,出现上述情况时,表格的所见即所得编辑功能失效
295
- if (this.tableEditor.info.totalTables !== this.tableEditor.tableCodes.length) {
296
- return false;
297
- }
298
- this.$setSelection(this.tableEditor.info.tableIndex, 'td', this.trigger === 'click');
299
- }
300
-
301
- $initReg() {
302
- this.tableReg = this.tableReg ? this.tableReg : getTableRule(true);
303
- this.codeBlockReg = this.codeBlockReg ? this.codeBlockReg : getCodeBlockRule().reg;
304
- }
305
-
306
- showBubble() {
307
- if (this.trigger === 'click') {
308
- this.$drawEditor();
309
- return;
310
- }
311
- this.$drawSymbol();
312
- this.$drawSortSymbol();
313
- this.$drawDelete();
314
- }
315
-
316
- /**
317
- * 判断是否处于编辑状态
318
- * @returns {boolean}
319
- */
320
- $isEditing() {
321
- return this.tableEditor.editing;
322
- }
323
-
324
- /**
325
- * 把表格上的input单行文本框和操作符号画出来
326
- */
327
- $drawEditor() {
328
- const dom = document.createElement('div');
329
- dom.className = 'cherry-previewer-table-content-handler__input';
330
- const input = document.createElement('textarea');
331
- dom.appendChild(input);
332
- this.tableEditor.editorDom.inputDiv = dom;
333
- this.tableEditor.editorDom.inputDom = input;
334
- this.$updateEditorPosition();
335
- this.container.appendChild(this.tableEditor.editorDom.inputDiv);
336
- this.tableEditor.editorDom.inputDom.value = this.tableEditor.info.code.replace(/<br>/g, '\n');
337
- this.tableEditor.editorDom.inputDom.focus();
338
- }
339
-
340
- $onInputChange(e) {
341
- if (e.target.tagName !== 'TEXTAREA') {
342
- return;
343
- }
344
- this.codeMirror.replaceSelection(e.target.value.replace(/\n/g, '<br>'), 'around');
345
- }
346
-
347
- /**
348
- * 更新编辑器的位置(尺寸和位置)
349
- */
350
- $updateEditorPosition() {
351
- this.$setInputOffset();
352
- const tdStyle = getComputedStyle(this.tableEditor.info.tdNode);
353
- this.tableEditor.editorDom.inputDom.style.textAlign = tdStyle.textAlign || 'left';
354
- this.tableEditor.editorDom.inputDom.style.fontSize = tdStyle.fontSize || '16px';
355
- this.tableEditor.editorDom.inputDom.style.fontFamily = tdStyle.fontFamily;
356
- this.tableEditor.editorDom.inputDom.style.lineHeight = tdStyle.lineHeight;
357
- this.tableEditor.editorDom.inputDom.style.padding = tdStyle.padding;
358
- // 左对齐的时候,paddingRight设置成0,反之paddingLeft设置成0
359
- if (/left/.test(tdStyle.textAlign)) {
360
- this.tableEditor.editorDom.inputDom.style.paddingRight = '0px';
361
- }
362
- if (/right/.test(tdStyle.textAlign)) {
363
- this.tableEditor.editorDom.inputDom.style.paddingLeft = '0px';
364
- }
365
- if (/center/.test(tdStyle.textAlign)) {
366
- this.tableEditor.editorDom.inputDom.style.paddingLeft = '0px';
367
- this.tableEditor.editorDom.inputDom.style.paddingRight = '0px';
368
- }
369
- this.tableEditor.editorDom.inputDom.style.paddingBottom = '0px';
370
- }
371
-
372
- $getClosestNode(node, targetNodeName) {
373
- if (!node || !node.tagName) {
374
- return false;
375
- }
376
- if (node.tagName === targetNodeName) {
377
- return node;
378
- }
379
- if (node.parentNode.tagName === 'BODY') {
380
- return false;
381
- }
382
- return this.$getClosestNode(node.parentNode, targetNodeName);
383
- }
384
-
385
- /**
386
- * 绘制操作符号
387
- */
388
- $drawSymbol() {
389
- const types = ['Last', 'Next'];
390
- const dirs = ['Row', 'Col'];
391
- const textDict = {
392
- Row: 'Row',
393
- Col: 'Col',
394
- };
395
- const symbols = dirs.map((_, index) => types.map((type) => dirs.map((dir) => [`${index}`, type, dir]))).flat(2);
396
- const container = document.createElement('ul');
397
- container.className = 'cherry-previewer-table-hover-handler-container';
398
- symbols.forEach(([index, type, dir]) => {
399
- const li = document.createElement('li');
400
- li.setAttribute('data-index', index);
401
- li.setAttribute('data-type', type);
402
- li.setAttribute('data-dir', dir);
403
- li.className = 'cherry-previewer-table-hover-handler__symbol';
404
- li.title = this.$cherry.locale[`add${textDict[dir]}`];
405
- li.innerHTML = '+';
406
- li.addEventListener('click', (e) => {
407
- const { target } = e;
408
- if (!(target instanceof HTMLElement)) {
409
- return;
410
- }
411
- const { type, dir } = target.dataset;
412
- this[`$add${type}${dir}`]();
413
- });
414
- container.appendChild(li);
415
- }, true);
416
- this.tableEditor.editorDom.symbolContainer = container;
417
- this.container.appendChild(this.tableEditor.editorDom.symbolContainer);
418
- this.$setSymbolOffset();
419
- }
420
- $drawSortSymbol() {
421
- // const types = ['RowLeft', 'RowRight', 'ColUp', 'ColDown']; // 不要底部的拖拽按钮了,貌似没啥用
422
- const types = ['RowLeft', 'RowRight', 'ColUp'];
423
-
424
- const container = document.createElement('ul');
425
- container.className = 'cherry-previewer-table-hover-handler-sort-container';
426
- types.forEach((type) => {
427
- const sortSymbol = document.createElement('li');
428
- sortSymbol.setAttribute('data-type', type);
429
- sortSymbol.className = 'cherry-previewer-table-hover-handler__sort ch-icon';
430
- sortSymbol.draggable = true;
431
- if (type.startsWith('Row')) {
432
- sortSymbol.title = this.$cherry.locale.moveRow;
433
- sortSymbol.classList.add('ch-icon-swap-vert');
434
- sortSymbol.addEventListener('mouseover', () => {
435
- const { tdNode } = this.tableEditor.info;
436
- tdNode.draggable = true;
437
-
438
- tdNode.parentNode.style.backgroundColor = 'rgb(206,226,248)';
439
- });
440
- sortSymbol.addEventListener('mouseleave', () => {
441
- const { tdNode } = this.tableEditor.info;
442
- tdNode.draggable = false;
443
- tdNode.parentNode.style.backgroundColor = '';
444
- });
445
- sortSymbol.addEventListener('mousedown', (e) => {
446
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
447
- this.$dragLine();
448
- });
449
- } else {
450
- sortSymbol.title = this.$cherry.locale.moveCol;
451
- sortSymbol.classList.add('ch-icon-swap');
452
- const highLightTrDom = [];
453
- sortSymbol.addEventListener('mouseover', () => {
454
- const { tdNode } = this.tableEditor.info;
455
- tdNode.draggable = true;
456
-
457
- const index = Array.from(tdNode.parentNode.children).indexOf(tdNode);
458
-
459
- Array.from(tdNode.parentNode.parentNode.parentNode.children)
460
- .map((item) => item.children)
461
- .forEach((item) => {
462
- Array.from(item).forEach((tr) => {
463
- highLightTrDom.push(tr);
464
- });
465
- });
466
- highLightTrDom.forEach((tr) => (tr.children[index].style.backgroundColor = 'rgb(206,226,248)'));
467
- });
468
- sortSymbol.addEventListener('mouseleave', () => {
469
- const { tdNode } = this.tableEditor.info;
470
- tdNode.draggable = false;
471
- const index = Array.from(tdNode.parentNode.children).indexOf(tdNode);
472
- highLightTrDom.forEach((tr) => (tr.children[index].style.backgroundColor = ''));
473
- });
474
- sortSymbol.addEventListener('mousedown', (e) => {
475
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
476
- this.$dragCol();
477
- });
478
- }
479
- container.appendChild(sortSymbol);
480
- });
481
- this.tableEditor.editorDom.sortContainer = container;
482
- this.container.appendChild(this.tableEditor.editorDom.sortContainer);
483
- this.$setSortSymbolsPosition();
484
- }
485
- $setSortSymbolsPosition() {
486
- const container = this.tableEditor.editorDom.sortContainer;
487
- const { tableNode, tdNode, isTHead } = this.tableEditor.info;
488
- const tableInfo = this.$getPosition(tableNode);
489
- const tdInfo = this.$getPosition(tdNode);
490
-
491
- this.setStyle(this.container, 'width', `${tableInfo.width}px`);
492
- this.setStyle(this.container, 'height', `${tableInfo.height}px`);
493
- this.setStyle(this.container, 'top', `${tableInfo.top}px`);
494
- this.setStyle(this.container, 'left', `${tableInfo.left}px`);
495
-
496
- container.childNodes.forEach((node) => {
497
- const { type } = node.dataset;
498
-
499
- switch (type) {
500
- case 'RowLeft':
501
- this.setStyle(node, 'top', `${tdInfo.top - tableInfo.top + tdInfo.height / 2 - node.offsetHeight / 2}px`);
502
- this.setStyle(node, 'left', `${-node.offsetWidth / 2}px`);
503
- break;
504
- case 'RowRight':
505
- this.setStyle(node, 'top', `${tdInfo.top - tableInfo.top + tdInfo.height / 2 - node.offsetHeight / 2}px`);
506
- this.setStyle(node, 'left', `${tableInfo.width - node.offsetWidth / 2}px`);
507
- break;
508
- case 'ColUp':
509
- this.setStyle(node, 'left', `${tdInfo.left - tableInfo.left + tdInfo.width / 2 - node.offsetWidth / 2}px`);
510
- this.setStyle(node, 'top', `${-node.offsetHeight / 2}px`);
511
- break;
512
- case 'ColDown':
513
- this.setStyle(node, 'left', `${tdInfo.left - tableInfo.left + tdInfo.width / 2 - node.offsetWidth / 2}px`);
514
- this.setStyle(node, 'top', `${tableInfo.height - node.offsetHeight / 2}px`);
515
-
516
- break;
517
- }
518
- if (isTHead && type.startsWith('Row')) {
519
- this.setStyle(node, 'display', 'none');
520
- }
521
- });
522
- }
523
- /**
524
- * 添加上一行
525
- */
526
- $addLastRow() {
527
- const [{ line }] = this.tableEditor.info.selection;
528
- const newRow = `${'|'.repeat(this.tableEditor.info.columns)}\n`;
529
- this.codeMirror.replaceRange(newRow, { line, ch: 0 });
530
- this.$findTableInEditor();
531
- this.$setSelection(this.tableEditor.info.tableIndex, 'td');
532
- }
533
-
534
- /**
535
- * 添加下一行
536
- */
537
- $addNextRow() {
538
- const [, { line }] = this.tableEditor.info.selection;
539
- const newRow = `${'|'.repeat(this.tableEditor.info.columns)}\n`;
540
- this.codeMirror.replaceRange(newRow, { line: line + 1, ch: 0 });
541
- this.$findTableInEditor();
542
- this.$setSelection(this.tableEditor.info.tableIndex, 'td');
543
- }
544
-
545
- /**
546
- * 添加上一列
547
- */
548
- $addLastCol() {
549
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
550
- const selection = this.codeMirror.getSelection();
551
- const lines = selection.split('\n');
552
- const newLines = lines.map((line, index) => {
553
- const cells = line.split('|');
554
- const replaceItem = 1 === index ? ':-:' : '';
555
- cells.splice(this.tableEditor.info.tdIndex + 1, 0, replaceItem);
556
- return cells.join('|');
557
- });
558
- const newText = newLines.join('\n');
559
- this.codeMirror.replaceSelection(newText);
560
- this.$findTableInEditor();
561
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
562
- }
563
-
564
- /**
565
- * 添加下一列
566
- */
567
- $addNextCol() {
568
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
569
- const selection = this.codeMirror.getSelection();
570
- const lines = selection.split('\n');
571
- const newLines = lines.map((line, index) => {
572
- const cells = line.split('|');
573
- const replaceItem = 1 === index ? ':-:' : '';
574
- cells.splice(this.tableEditor.info.tdIndex + 2, 0, replaceItem);
575
- return cells.join('|');
576
- });
577
- const newText = newLines.join('\n');
578
- this.codeMirror.replaceSelection(newText);
579
- this.$findTableInEditor();
580
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
581
- }
582
-
583
- /**
584
- * 高亮当前列
585
- */
586
- $highlightColumn() {
587
- const { tableNode, tdIndex } = this.tableEditor.info;
588
- const { rows } = tableNode;
589
- rows[0].cells[tdIndex].style.borderTop = '1px solid red';
590
- rows[rows.length - 1].cells[tdIndex].style.borderBottom = '1px solid red';
591
- for (let i = 0; i < rows.length; i++) {
592
- const { cells } = rows[i];
593
- if (cells[tdIndex]) {
594
- if (tdIndex === 0) cells[tdIndex].style.borderLeft = '1px solid red';
595
- else cells[tdIndex - 1].style.borderRight = '1px solid red';
596
- cells[tdIndex].style.borderRight = '1px solid red';
597
- }
598
- }
599
- }
600
-
601
- /**
602
- * 取消高亮当前列
603
- */
604
- $cancelHighlightColumn() {
605
- const { tableNode, tdIndex } = this.tableEditor.info;
606
- if (tableNode) {
607
- const { rows } = tableNode;
608
- for (let i = 0; i < rows.length; i++) {
609
- const { cells } = rows[i];
610
- if (cells[tdIndex]) {
611
- if (tdIndex !== 0) cells[tdIndex - 1].style.border = '';
612
- cells[tdIndex].style.border = ''; // 恢复原始边框
613
- }
614
- }
615
- }
616
- }
617
-
618
- /**
619
- * 高亮当前行
620
- */
621
- $highlightRow() {
622
- this.$doHighlightRow('1px solid red');
623
- }
624
-
625
- /**
626
- * 取消高亮当前行
627
- */
628
- $cancelHighlightRow() {
629
- this.$doHighlightRow('');
630
- }
631
-
632
- $doHighlightRow(style = '') {
633
- const { trNode, tableNode } = this.tableEditor.info;
634
- const tds = trNode.cells;
635
- const preTds = trNode.previousElementSibling?.cells || tableNode.tHead.firstChild.cells;
636
- for (let i = 0; i < tds.length; i++) {
637
- if (preTds[i]) preTds[i].style.borderBottom = style;
638
- tds[i].style.borderBottom = style;
639
- }
640
- tds[0].style.borderLeft = style;
641
- tds[tds.length - 1].style.borderRight = style;
642
- }
643
-
644
- /**
645
- * 添加删除按钮
646
- */
647
- $drawDelete() {
648
- const types = ['top', 'bottom', 'right'];
649
- const buttons = types.map((type) => [type]);
650
- const container = document.createElement('div');
651
- container.className = 'cherry-previewer-table-hover-handler-delete-container';
652
- buttons.forEach(([type]) => {
653
- const button = document.createElement('button');
654
- button.setAttribute('data-type', type);
655
- button.className = 'cherry-previewer-table-hover-handler__delete ch-icon ch-icon-cherry-table-delete';
656
- if (/(right|left)/.test(type)) {
657
- button.title = this.$cherry.locale.deleteRow;
658
- button.addEventListener('click', () => {
659
- this.$deleteCurrentRow();
660
- });
661
- button.addEventListener('mouseover', () => {
662
- this.$highlightRow();
663
- });
664
- button.addEventListener('mouseout', () => {
665
- this.$cancelHighlightRow();
666
- });
667
- } else {
668
- button.title = this.$cherry.locale.deleteColumn;
669
- button.addEventListener('click', () => {
670
- this.$deleteCurrentColumn();
671
- });
672
- button.addEventListener('mouseover', () => {
673
- this.$highlightColumn();
674
- });
675
- button.addEventListener('mouseout', () => {
676
- this.$cancelHighlightColumn();
677
- });
678
- }
679
- container.appendChild(button);
680
- });
681
- this.tableEditor.editorDom.deleteContainer = container;
682
- this.container.appendChild(this.tableEditor.editorDom.deleteContainer);
683
- this.$setDeleteButtonPosition();
684
- }
685
-
686
- /**
687
- * 设置删除按钮的位置
688
- */
689
- $setDeleteButtonPosition() {
690
- const container = this.tableEditor.editorDom.deleteContainer;
691
- const { tableNode, tdNode, isTHead } = this.tableEditor.info;
692
- const tableInfo = this.$getPosition(tableNode);
693
- const tdInfo = this.$getPosition(tdNode);
694
- // 设置容器宽高
695
- this.setStyle(this.container, 'width', `${tableInfo.width}px`);
696
- this.setStyle(this.container, 'height', `${tableInfo.height}px`);
697
- this.setStyle(this.container, 'top', `${tableInfo.top}px`);
698
- this.setStyle(this.container, 'left', `${tableInfo.left}px`);
699
-
700
- // 设置删除按钮位置
701
- container.childNodes.forEach((node) => {
702
- const { type } = node.dataset;
703
- const offset = {
704
- outer: 20,
705
- };
706
- if (/(right|left)/.test(type)) {
707
- if (isTHead) {
708
- this.setStyle(node, 'display', 'none');
709
- }
710
- this.setStyle(node, 'top', `${tdInfo.top - tableInfo.top + tdInfo.height / 2 - node.offsetHeight / 2}px`);
711
- this.setStyle(node, `${type}`, `-${node.offsetWidth + 5}px`);
712
- } else {
713
- this.setStyle(node, `${type}`, `-${offset.outer}px`);
714
- this.setStyle(node, 'left', `${tdInfo.left - tableInfo.left + tdInfo.width / 2 - node.offsetWidth / 2}px`);
715
- }
716
- });
717
- }
718
-
719
- /**
720
- * 删除当前行
721
- */
722
- $deleteCurrentRow() {
723
- const { tableIndex, trIndex } = this.tableEditor.info;
724
- this.$setSelection(tableIndex, 'table');
725
- const selection = this.codeMirror.getSelection();
726
- const table = selection.split('\n');
727
- table.splice(trIndex + 2, 1);
728
- const newText = table.join('\n');
729
- this.codeMirror.replaceSelection(newText);
730
- }
731
-
732
- /**
733
- * 删除当前列
734
- */
735
- $deleteCurrentColumn() {
736
- const { tableIndex, tdIndex } = this.tableEditor.info;
737
- this.$setSelection(tableIndex, 'table');
738
- const selection = this.codeMirror.getSelection();
739
- const table = selection.split('\n');
740
- const rows = table.map((row) => row.split('|').slice(1, -1));
741
- rows.forEach((row) => {
742
- if (tdIndex >= 0 && tdIndex < row.length) {
743
- row.splice(tdIndex, 1);
744
- }
745
- });
746
- const newTable = rows.map((row) => (row.length === 0 ? '' : `|${row.join('|')}|`));
747
- const newText = newTable.join('\n');
748
- this.codeMirror.replaceSelection(newText);
749
- }
750
-
751
- /**
752
- * 拖拽列
753
- */
754
- $dragCol() {
755
- const oldTdIndex = this.tableEditor.info.tdIndex;
756
- const thNode = this.target.parentElement;
757
- const lines = this.codeMirror.getSelection().split(/\n/);
758
- const { tdNode } = this.tableEditor.info;
759
- const that = this;
760
- tdNode.setAttribute('draggable', true);
761
-
762
- function handleDragLeave(event) {
763
- that.setStyle(event.target, 'border', '1px solid #dfe6ee');
764
- }
765
-
766
- function handleDragOver(event) {
767
- event.preventDefault();
768
- const tdIndex = Array.from(event.target.parentElement.childNodes).indexOf(event.target);
769
- that.$dragSymbol(event.target, oldTdIndex, tdIndex, 'Col');
770
- thNode.setAttribute('draggable', false);
771
- }
772
-
773
- function handleDrop(event) {
774
- event.preventDefault();
775
- const tdIndex = Array.from(event.target.parentElement.childNodes).indexOf(event.target);
776
- const newLines = lines.map((line, index) => {
777
- const cells = line
778
- .split('|')
779
- .map((item) => (item === '' ? 'CHERRY_MARKDOWN_PENDING_TEXT_FOR_EMPTY_CELL' : item))
780
- .slice(1, -1);
781
- return `|${that.$operateLines(oldTdIndex, tdIndex, cells).join('|')}|`;
782
- });
783
- const newText = newLines.join('\n').replace(/CHERRY_MARKDOWN_PENDING_TEXT_FOR_EMPTY_CELL/g, '');
784
- that.codeMirror.replaceSelection(newText);
785
- that.setStyle(event.target, 'border', '1px solid #dfe6ee');
786
- that.$findTableInEditor();
787
- that.$setSelection(that.tableEditor.info.tableIndex, 'table');
788
-
789
- thNode.removeEventListener('dragleave', handleDragLeave);
790
- thNode.removeEventListener('dragover', handleDragOver);
791
- }
792
-
793
- thNode.addEventListener('dragleave', handleDragLeave);
794
- thNode.addEventListener('dragover', handleDragOver);
795
- thNode.addEventListener('drop', handleDrop, { once: true });
796
- }
797
-
798
- /**
799
- * 拖拽行
800
- */
801
- $dragLine() {
802
- const { trNode } = this.tableEditor.info;
803
- trNode.setAttribute('draggable', true);
804
- this.$setSelection(this.tableEditor.info.tableIndex, 'table');
805
- const oldTrIndex = this.tableEditor.info.trIndex + 2;
806
- const tBody = trNode.parentElement;
807
- const lines = this.codeMirror.getSelection().split(/\n/);
808
- const that = this;
809
-
810
- function handleDragLeave(event) {
811
- that.setStyle(event.target.parentElement, 'border', '1px solid #dfe6ee');
812
- }
813
-
814
- function handleDragOver(event) {
815
- event.preventDefault();
816
- const trIndex =
817
- Array.from(event.target.parentElement.parentElement.childNodes).indexOf(event.target.parentElement) + 2;
818
- that.$dragSymbol(event.target, oldTrIndex, trIndex, 'Line');
819
- trNode.setAttribute('draggable', false);
820
- }
821
-
822
- function handleDrop(event) {
823
- event.preventDefault();
824
- const trIndex =
825
- Array.from(event.target.parentElement.parentElement.childNodes).indexOf(event.target.parentElement) + 2;
826
- const newText = that.$operateLines(oldTrIndex, trIndex, lines).join('\n');
827
- that.codeMirror.replaceSelection(newText);
828
-
829
- that.$findTableInEditor();
830
- that.$setSelection(that.tableEditor.info.tableIndex, 'table');
831
- that.setStyle(event.target.parentElement, 'border', '1px solid #dfe6ee');
832
-
833
- tBody.removeEventListener('dragleave', handleDragLeave);
834
- tBody.removeEventListener('dragover', handleDragOver);
835
- }
836
-
837
- tBody.addEventListener('dragleave', handleDragLeave);
838
- tBody.addEventListener('dragover', handleDragOver);
839
- tBody.addEventListener('drop', handleDrop, { once: true });
840
- }
841
-
842
- $dragSymbol(objTarget, oldIndex, index, type) {
843
- const { target } = this;
844
- if (target !== objTarget && oldIndex !== index) {
845
- if ((target.tagName === 'TH' || target.tagName === 'TD') && type === 'Col') {
846
- if (oldIndex < index) {
847
- this.setStyle(objTarget, 'border', `1px solid #dfe6ee`);
848
- this.setStyle(objTarget, 'border-right', `2px solid #6897bb`);
849
- } else if (oldIndex > index) {
850
- this.setStyle(objTarget, 'border', `1px solid #dfe6ee`);
851
- this.setStyle(objTarget, 'border-left', `2px solid #6897bb`);
852
- }
853
- } else if (target.tagName === 'TD' && type === 'Line') {
854
- if (oldIndex < index) {
855
- this.setStyle(objTarget.parentElement, 'border', `1px solid #dfe6ee`);
856
- this.setStyle(objTarget.parentElement, 'border-bottom', `2px solid #6897bb`);
857
- } else if (oldIndex > index) {
858
- this.setStyle(objTarget.parentElement, 'border', `1px solid #dfe6ee`);
859
- this.setStyle(objTarget.parentElement, 'border-top', `2px solid #6897bb`);
860
- }
861
- }
862
- }
863
- }
864
-
865
- $operateLines(oldIndex, index, lines) {
866
- if (oldIndex < index) {
867
- lines.splice(index + 1, 0, lines[oldIndex]);
868
- lines.splice(oldIndex, 1);
869
- } else if (oldIndex > index) {
870
- const line = lines[oldIndex];
871
- lines.splice(oldIndex, 1);
872
- lines.splice(index, 0, line);
873
- }
874
- return lines;
875
- }
876
- }