editor-svg 1.0.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.
Files changed (472) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintrc +46 -0
  3. package/.prettierrc +8 -0
  4. package/AGENTS.md +186 -0
  5. package/CHANGELOG.md +2543 -0
  6. package/CLAUDE.md +110 -0
  7. package/LICENSE +21 -0
  8. package/README.md +110 -0
  9. package/cypress/e2e/control/checkbox.cy.ts +46 -0
  10. package/cypress/e2e/control/select.cy.ts +56 -0
  11. package/cypress/e2e/control/text.cy.ts +43 -0
  12. package/cypress/e2e/editor.cy.ts +67 -0
  13. package/cypress/e2e/menus/block.cy.ts +38 -0
  14. package/cypress/e2e/menus/checkbox.cy.ts +33 -0
  15. package/cypress/e2e/menus/codeblock.cy.ts +34 -0
  16. package/cypress/e2e/menus/date.cy.ts +28 -0
  17. package/cypress/e2e/menus/format.cy.ts +40 -0
  18. package/cypress/e2e/menus/hyperlink.cy.ts +39 -0
  19. package/cypress/e2e/menus/image.cy.ts +25 -0
  20. package/cypress/e2e/menus/latex.cy.ts +34 -0
  21. package/cypress/e2e/menus/pagebreak.cy.ts +21 -0
  22. package/cypress/e2e/menus/painter.cy.ts +53 -0
  23. package/cypress/e2e/menus/print.cy.ts +25 -0
  24. package/cypress/e2e/menus/row.cy.ts +103 -0
  25. package/cypress/e2e/menus/search.cy.ts +112 -0
  26. package/cypress/e2e/menus/separator.cy.ts +32 -0
  27. package/cypress/e2e/menus/table.cy.ts +25 -0
  28. package/cypress/e2e/menus/text.cy.ts +304 -0
  29. package/cypress/e2e/menus/title.cy.ts +43 -0
  30. package/cypress/e2e/menus/undoRedo.cy.ts +49 -0
  31. package/cypress/e2e/menus/watermark.cy.ts +64 -0
  32. package/cypress/fixtures/example.json +3 -0
  33. package/cypress/fixtures/test.png +0 -0
  34. package/cypress/global.d.ts +13 -0
  35. package/cypress/support/commands.ts +5 -0
  36. package/cypress/support/e2e.ts +1 -0
  37. package/cypress/tsconfig.json +21 -0
  38. package/cypress.config.ts +10 -0
  39. package/docs/.vitepress/config.ts +191 -0
  40. package/docs/.vitepress/theme/components/DeepWikiBadge.vue +21 -0
  41. package/docs/.vitepress/theme/components/ZreadBadge.vue +21 -0
  42. package/docs/.vitepress/theme/index.ts +27 -0
  43. package/docs/en/guide/api-common.md +49 -0
  44. package/docs/en/guide/api-instance.md +34 -0
  45. package/docs/en/guide/command-execute.md +1167 -0
  46. package/docs/en/guide/command-get.md +355 -0
  47. package/docs/en/guide/contextmenu-custom.md +44 -0
  48. package/docs/en/guide/contextmenu-internal.md +61 -0
  49. package/docs/en/guide/eventbus.md +260 -0
  50. package/docs/en/guide/i18n.md +112 -0
  51. package/docs/en/guide/listener.md +126 -0
  52. package/docs/en/guide/option.md +214 -0
  53. package/docs/en/guide/override.md +57 -0
  54. package/docs/en/guide/plugin-custom.md +25 -0
  55. package/docs/en/guide/plugin-internal.md +125 -0
  56. package/docs/en/guide/schema.md +237 -0
  57. package/docs/en/guide/shortcut-custom.md +22 -0
  58. package/docs/en/guide/shortcut-internal.md +189 -0
  59. package/docs/en/guide/start.md +97 -0
  60. package/docs/en/index.md +43 -0
  61. package/docs/guide/api-common.md +49 -0
  62. package/docs/guide/api-instance.md +34 -0
  63. package/docs/guide/command-execute.md +1157 -0
  64. package/docs/guide/command-get.md +353 -0
  65. package/docs/guide/contextmenu-custom.md +44 -0
  66. package/docs/guide/contextmenu-internal.md +61 -0
  67. package/docs/guide/eventbus.md +260 -0
  68. package/docs/guide/i18n.md +111 -0
  69. package/docs/guide/listener.md +126 -0
  70. package/docs/guide/option.md +214 -0
  71. package/docs/guide/override.md +57 -0
  72. package/docs/guide/plugin-custom.md +25 -0
  73. package/docs/guide/plugin-internal.md +125 -0
  74. package/docs/guide/schema.md +237 -0
  75. package/docs/guide/shortcut-custom.md +22 -0
  76. package/docs/guide/shortcut-internal.md +189 -0
  77. package/docs/guide/start.md +97 -0
  78. package/docs/index.md +43 -0
  79. package/docs/public/favicon.png +0 -0
  80. package/favicon.png +0 -0
  81. package/index.html +435 -0
  82. package/package.json +55 -0
  83. package/pnpm-lock.yaml +4113 -0
  84. package/scripts/release.js +41 -0
  85. package/scripts/verifyCommit.js +19 -0
  86. package/src/assets/images/alignment.svg +1 -0
  87. package/src/assets/images/arrow-left.svg +1 -0
  88. package/src/assets/images/arrow-right.svg +1 -0
  89. package/src/assets/images/block.svg +1 -0
  90. package/src/assets/images/bold.svg +1 -0
  91. package/src/assets/images/catalog.svg +1 -0
  92. package/src/assets/images/center.svg +1 -0
  93. package/src/assets/images/checkbox.svg +1 -0
  94. package/src/assets/images/close.svg +1 -0
  95. package/src/assets/images/codeblock.svg +1 -0
  96. package/src/assets/images/color.svg +1 -0
  97. package/src/assets/images/control.svg +1 -0
  98. package/src/assets/images/date.svg +1 -0
  99. package/src/assets/images/exit-fullscreen.svg +1 -0
  100. package/src/assets/images/format.svg +1 -0
  101. package/src/assets/images/highlight.svg +1 -0
  102. package/src/assets/images/hyperlink.svg +1 -0
  103. package/src/assets/images/image.svg +1 -0
  104. package/src/assets/images/italic.svg +1 -0
  105. package/src/assets/images/justify.svg +7 -0
  106. package/src/assets/images/latex.svg +1 -0
  107. package/src/assets/images/left.svg +1 -0
  108. package/src/assets/images/line-dash-dot-dot.svg +1 -0
  109. package/src/assets/images/line-dash-dot.svg +1 -0
  110. package/src/assets/images/line-dash-large-gap.svg +1 -0
  111. package/src/assets/images/line-dash-small-gap.svg +1 -0
  112. package/src/assets/images/line-dot.svg +1 -0
  113. package/src/assets/images/line-double.svg +1 -0
  114. package/src/assets/images/line-single.svg +1 -0
  115. package/src/assets/images/line-wavy.svg +1 -0
  116. package/src/assets/images/list.svg +1 -0
  117. package/src/assets/images/option.svg +1 -0
  118. package/src/assets/images/page-break.svg +1 -0
  119. package/src/assets/images/page-mode.svg +1 -0
  120. package/src/assets/images/page-scale-add.svg +1 -0
  121. package/src/assets/images/page-scale-minus.svg +1 -0
  122. package/src/assets/images/painter.svg +1 -0
  123. package/src/assets/images/paper-direction.svg +1 -0
  124. package/src/assets/images/paper-margin.svg +1 -0
  125. package/src/assets/images/paper-size.svg +1 -0
  126. package/src/assets/images/print.svg +1 -0
  127. package/src/assets/images/radio.svg +4 -0
  128. package/src/assets/images/redo.svg +1 -0
  129. package/src/assets/images/request-fullscreen.svg +1 -0
  130. package/src/assets/images/right.svg +1 -0
  131. package/src/assets/images/row-margin.svg +1 -0
  132. package/src/assets/images/search.svg +1 -0
  133. package/src/assets/images/separator.svg +1 -0
  134. package/src/assets/images/signature-undo.svg +1 -0
  135. package/src/assets/images/signature.svg +1 -0
  136. package/src/assets/images/size-add.svg +1 -0
  137. package/src/assets/images/size-minus.svg +1 -0
  138. package/src/assets/images/strikeout.svg +1 -0
  139. package/src/assets/images/subscript.svg +1 -0
  140. package/src/assets/images/superscript.svg +1 -0
  141. package/src/assets/images/table.svg +1 -0
  142. package/src/assets/images/title.svg +1 -0
  143. package/src/assets/images/trash.svg +1 -0
  144. package/src/assets/images/underline.svg +1 -0
  145. package/src/assets/images/undo.svg +1 -0
  146. package/src/assets/images/watermark.svg +1 -0
  147. package/src/assets/images/word-tool.svg +1 -0
  148. package/src/assets/snapshots/main_v0.2.1.png +0 -0
  149. package/src/assets/snapshots/main_v0.2.2.png +0 -0
  150. package/src/assets/snapshots/main_v0.3.0.png +0 -0
  151. package/src/assets/snapshots/main_v0.3.1.png +0 -0
  152. package/src/assets/snapshots/main_v0.5.0.png +0 -0
  153. package/src/assets/snapshots/main_v0.5.1.png +0 -0
  154. package/src/assets/snapshots/main_v0.6.0.png +0 -0
  155. package/src/assets/snapshots/main_v0.6.1.png +0 -0
  156. package/src/assets/snapshots/main_v0.7.0.png +0 -0
  157. package/src/assets/snapshots/main_v0.7.1.png +0 -0
  158. package/src/assets/snapshots/main_v0.7.2.png +0 -0
  159. package/src/assets/snapshots/main_v0.7.3.png +0 -0
  160. package/src/assets/snapshots/main_v0.7.4.png +0 -0
  161. package/src/assets/snapshots/main_v0.7.6.png +0 -0
  162. package/src/assets/snapshots/main_v0.7.7.png +0 -0
  163. package/src/assets/snapshots/main_v0.8.0.png +0 -0
  164. package/src/assets/snapshots/main_v0.8.5.png +0 -0
  165. package/src/assets/snapshots/main_v0.8.6.png +0 -0
  166. package/src/assets/snapshots/main_v0.8.7.png +0 -0
  167. package/src/assets/snapshots/main_v0.8.8.png +0 -0
  168. package/src/assets/snapshots/main_v0.9.0.png +0 -0
  169. package/src/assets/snapshots/main_v0.9.1.png +0 -0
  170. package/src/assets/snapshots/main_v0.9.2.png +0 -0
  171. package/src/assets/snapshots/main_v0.9.23.png +0 -0
  172. package/src/assets/snapshots/main_v0.9.28.png +0 -0
  173. package/src/assets/snapshots/main_v0.9.29.png +0 -0
  174. package/src/assets/snapshots/main_v0.9.3.png +0 -0
  175. package/src/assets/snapshots/main_v0.9.30.png +0 -0
  176. package/src/assets/snapshots/main_v0.9.32.png +0 -0
  177. package/src/assets/snapshots/main_v0.9.35.png +0 -0
  178. package/src/assets/snapshots/main_v0.9.4.png +0 -0
  179. package/src/assets/snapshots/main_v0.9.5.png +0 -0
  180. package/src/assets/snapshots/main_v0.9.6.png +0 -0
  181. package/src/assets/snapshots/main_v0.9.8.png +0 -0
  182. package/src/components/dialog/Dialog.ts +171 -0
  183. package/src/components/dialog/dialog.css +131 -0
  184. package/src/components/signature/Signature.ts +340 -0
  185. package/src/components/signature/signature.css +132 -0
  186. package/src/editor/assets/css/block/block.css +21 -0
  187. package/src/editor/assets/css/contextmenu/contextmenu.css +196 -0
  188. package/src/editor/assets/css/control/calculator.css +85 -0
  189. package/src/editor/assets/css/control/select.css +44 -0
  190. package/src/editor/assets/css/date/datePicker.css +233 -0
  191. package/src/editor/assets/css/hyperlink/hyperlink.css +26 -0
  192. package/src/editor/assets/css/index.css +78 -0
  193. package/src/editor/assets/css/previewer/previewer.css +122 -0
  194. package/src/editor/assets/css/resizer/resizer.css +74 -0
  195. package/src/editor/assets/css/table/table.css +155 -0
  196. package/src/editor/assets/css/zone/zone.css +61 -0
  197. package/src/editor/assets/images/close.svg +1 -0
  198. package/src/editor/assets/images/delete-col.svg +1 -0
  199. package/src/editor/assets/images/delete-row-col.svg +1 -0
  200. package/src/editor/assets/images/delete-row.svg +1 -0
  201. package/src/editor/assets/images/delete-table.svg +1 -0
  202. package/src/editor/assets/images/image-change.svg +1 -0
  203. package/src/editor/assets/images/image-download.svg +1 -0
  204. package/src/editor/assets/images/image-next.svg +1 -0
  205. package/src/editor/assets/images/image-pre.svg +1 -0
  206. package/src/editor/assets/images/image.svg +1 -0
  207. package/src/editor/assets/images/insert-bottom-row.svg +1 -0
  208. package/src/editor/assets/images/insert-left-col.svg +1 -0
  209. package/src/editor/assets/images/insert-right-col.svg +1 -0
  210. package/src/editor/assets/images/insert-row-col.svg +1 -0
  211. package/src/editor/assets/images/insert-top-row.svg +1 -0
  212. package/src/editor/assets/images/merge-cancel-cell.svg +1 -0
  213. package/src/editor/assets/images/merge-cell.svg +1 -0
  214. package/src/editor/assets/images/original-size.svg +1 -0
  215. package/src/editor/assets/images/print.svg +1 -0
  216. package/src/editor/assets/images/rotate.svg +1 -0
  217. package/src/editor/assets/images/submenu-dropdown.svg +1 -0
  218. package/src/editor/assets/images/table-border-all.svg +1 -0
  219. package/src/editor/assets/images/table-border-dash.svg +1 -0
  220. package/src/editor/assets/images/table-border-empty.svg +1 -0
  221. package/src/editor/assets/images/table-border-external.svg +1 -0
  222. package/src/editor/assets/images/table-border-internal.svg +1 -0
  223. package/src/editor/assets/images/table-border-td-back.svg +1 -0
  224. package/src/editor/assets/images/table-border-td-bottom.svg +1 -0
  225. package/src/editor/assets/images/table-border-td-forward.svg +1 -0
  226. package/src/editor/assets/images/table-border-td-left.svg +1 -0
  227. package/src/editor/assets/images/table-border-td-right.svg +1 -0
  228. package/src/editor/assets/images/table-border-td-top.svg +1 -0
  229. package/src/editor/assets/images/table-border-td.svg +1 -0
  230. package/src/editor/assets/images/vertical-align-bottom.svg +1 -0
  231. package/src/editor/assets/images/vertical-align-middle.svg +1 -0
  232. package/src/editor/assets/images/vertical-align-top.svg +1 -0
  233. package/src/editor/assets/images/vertical-align.svg +1 -0
  234. package/src/editor/assets/images/zoom-in.svg +1 -0
  235. package/src/editor/assets/images/zoom-out.svg +1 -0
  236. package/src/editor/core/actuator/Actuator.ts +21 -0
  237. package/src/editor/core/actuator/handlers/positionContextChange.ts +13 -0
  238. package/src/editor/core/command/Command.ts +312 -0
  239. package/src/editor/core/command/CommandAdapt.ts +2733 -0
  240. package/src/editor/core/contextmenu/ContextMenu.ts +363 -0
  241. package/src/editor/core/contextmenu/menus/controlMenus.ts +25 -0
  242. package/src/editor/core/contextmenu/menus/globalMenus.ts +66 -0
  243. package/src/editor/core/contextmenu/menus/hyperlinkMenus.ts +58 -0
  244. package/src/editor/core/contextmenu/menus/imageMenus.ts +134 -0
  245. package/src/editor/core/contextmenu/menus/tableMenus.ts +331 -0
  246. package/src/editor/core/cursor/Cursor.ts +248 -0
  247. package/src/editor/core/cursor/CursorAgent.ts +75 -0
  248. package/src/editor/core/draw/Draw.ts +2934 -0
  249. package/src/editor/core/draw/control/Control.ts +1767 -0
  250. package/src/editor/core/draw/control/checkbox/CheckboxControl.ts +154 -0
  251. package/src/editor/core/draw/control/date/DateControl.ts +363 -0
  252. package/src/editor/core/draw/control/interactive/ControlSearch.ts +214 -0
  253. package/src/editor/core/draw/control/number/Calculator.ts +183 -0
  254. package/src/editor/core/draw/control/number/NumberControl.ts +183 -0
  255. package/src/editor/core/draw/control/radio/RadioControl.ts +68 -0
  256. package/src/editor/core/draw/control/richtext/Border.ts +52 -0
  257. package/src/editor/core/draw/control/select/SelectControl.ts +567 -0
  258. package/src/editor/core/draw/control/text/TextControl.ts +280 -0
  259. package/src/editor/core/draw/frame/Background.ts +117 -0
  260. package/src/editor/core/draw/frame/Badge.ts +88 -0
  261. package/src/editor/core/draw/frame/Footer.ts +155 -0
  262. package/src/editor/core/draw/frame/Header.ts +158 -0
  263. package/src/editor/core/draw/frame/LineNumber.ts +43 -0
  264. package/src/editor/core/draw/frame/Margin.ts +53 -0
  265. package/src/editor/core/draw/frame/PageBorder.ts +47 -0
  266. package/src/editor/core/draw/frame/PageNumber.ts +88 -0
  267. package/src/editor/core/draw/frame/Placeholder.ts +114 -0
  268. package/src/editor/core/draw/frame/Watermark.ts +188 -0
  269. package/src/editor/core/draw/graffiti/Graffiti.ts +125 -0
  270. package/src/editor/core/draw/interactive/Area.ts +312 -0
  271. package/src/editor/core/draw/interactive/Group.ts +198 -0
  272. package/src/editor/core/draw/interactive/Search.ts +527 -0
  273. package/src/editor/core/draw/particle/CheckboxParticle.ts +111 -0
  274. package/src/editor/core/draw/particle/HyperlinkParticle.ts +86 -0
  275. package/src/editor/core/draw/particle/ImageParticle.ts +280 -0
  276. package/src/editor/core/draw/particle/LabelParticle.ts +79 -0
  277. package/src/editor/core/draw/particle/LineBreakParticle.ts +55 -0
  278. package/src/editor/core/draw/particle/ListParticle.ts +255 -0
  279. package/src/editor/core/draw/particle/PageBreakParticle.ts +54 -0
  280. package/src/editor/core/draw/particle/RadioParticle.ts +99 -0
  281. package/src/editor/core/draw/particle/SeparatorParticle.ts +37 -0
  282. package/src/editor/core/draw/particle/SubscriptParticle.ts +23 -0
  283. package/src/editor/core/draw/particle/SuperscriptParticle.ts +23 -0
  284. package/src/editor/core/draw/particle/TextParticle.ts +174 -0
  285. package/src/editor/core/draw/particle/WhiteSpaceParticle.ts +32 -0
  286. package/src/editor/core/draw/particle/block/BlockParticle.ts +76 -0
  287. package/src/editor/core/draw/particle/block/modules/BaseBlock.ts +280 -0
  288. package/src/editor/core/draw/particle/block/modules/IFrameBlock.ts +47 -0
  289. package/src/editor/core/draw/particle/block/modules/VideoBlock.ts +61 -0
  290. package/src/editor/core/draw/particle/date/DateParticle.ts +111 -0
  291. package/src/editor/core/draw/particle/date/DatePicker.ts +577 -0
  292. package/src/editor/core/draw/particle/latex/LaTexParticle.ts +43 -0
  293. package/src/editor/core/draw/particle/latex/utils/LaTexUtils.ts +1196 -0
  294. package/src/editor/core/draw/particle/latex/utils/hershey.ts +1632 -0
  295. package/src/editor/core/draw/particle/latex/utils/symbols.ts +318 -0
  296. package/src/editor/core/draw/particle/previewer/Previewer.ts +582 -0
  297. package/src/editor/core/draw/particle/table/TableOperate.ts +988 -0
  298. package/src/editor/core/draw/particle/table/TableParticle.ts +558 -0
  299. package/src/editor/core/draw/particle/table/TableTool.ts +551 -0
  300. package/src/editor/core/draw/richtext/AbstractRichText.ts +59 -0
  301. package/src/editor/core/draw/richtext/Highlight.ts +24 -0
  302. package/src/editor/core/draw/richtext/Strikeout.ts +28 -0
  303. package/src/editor/core/draw/richtext/Underline.ts +106 -0
  304. package/src/editor/core/event/CanvasEvent.ts +215 -0
  305. package/src/editor/core/event/GlobalEvent.ts +173 -0
  306. package/src/editor/core/event/eventbus/EventBus.ts +50 -0
  307. package/src/editor/core/event/handlers/click.ts +234 -0
  308. package/src/editor/core/event/handlers/composition.ts +45 -0
  309. package/src/editor/core/event/handlers/copy.ts +72 -0
  310. package/src/editor/core/event/handlers/cut.ts +47 -0
  311. package/src/editor/core/event/handlers/drag.ts +66 -0
  312. package/src/editor/core/event/handlers/drop.ts +28 -0
  313. package/src/editor/core/event/handlers/input.ts +129 -0
  314. package/src/editor/core/event/handlers/keydown/backspace.ts +161 -0
  315. package/src/editor/core/event/handlers/keydown/delete.ts +119 -0
  316. package/src/editor/core/event/handlers/keydown/end.ts +69 -0
  317. package/src/editor/core/event/handlers/keydown/enter.ts +126 -0
  318. package/src/editor/core/event/handlers/keydown/home.ts +69 -0
  319. package/src/editor/core/event/handlers/keydown/index.ts +85 -0
  320. package/src/editor/core/event/handlers/keydown/left.ts +162 -0
  321. package/src/editor/core/event/handlers/keydown/right.ts +178 -0
  322. package/src/editor/core/event/handlers/keydown/tab.ts +41 -0
  323. package/src/editor/core/event/handlers/keydown/updown.ts +342 -0
  324. package/src/editor/core/event/handlers/mousedown.ts +262 -0
  325. package/src/editor/core/event/handlers/mouseleave.ts +14 -0
  326. package/src/editor/core/event/handlers/mousemove.ts +133 -0
  327. package/src/editor/core/event/handlers/mouseup.ts +341 -0
  328. package/src/editor/core/event/handlers/paste.ts +231 -0
  329. package/src/editor/core/history/HistoryManager.ts +61 -0
  330. package/src/editor/core/i18n/I18n.ts +51 -0
  331. package/src/editor/core/i18n/lang/en.json +92 -0
  332. package/src/editor/core/i18n/lang/zh-CN.json +92 -0
  333. package/src/editor/core/listener/Listener.ts +41 -0
  334. package/src/editor/core/observer/ImageObserver.ts +19 -0
  335. package/src/editor/core/observer/MouseObserver.ts +56 -0
  336. package/src/editor/core/observer/ScrollObserver.ts +88 -0
  337. package/src/editor/core/observer/SelectionObserver.ts +143 -0
  338. package/src/editor/core/override/Override.ts +14 -0
  339. package/src/editor/core/plugin/Plugin.ts +17 -0
  340. package/src/editor/core/position/Position.ts +870 -0
  341. package/src/editor/core/range/RangeManager.ts +723 -0
  342. package/src/editor/core/register/Register.ts +28 -0
  343. package/src/editor/core/shortcut/Shortcut.ts +80 -0
  344. package/src/editor/core/shortcut/keys/listKeys.ts +22 -0
  345. package/src/editor/core/shortcut/keys/richtextKeys.ts +102 -0
  346. package/src/editor/core/shortcut/keys/titleKeys.ts +62 -0
  347. package/src/editor/core/worker/WorkerManager.ts +96 -0
  348. package/src/editor/core/worker/works/catalog.ts +189 -0
  349. package/src/editor/core/worker/works/group.ts +34 -0
  350. package/src/editor/core/worker/works/value.ts +32 -0
  351. package/src/editor/core/worker/works/wordCount.ts +132 -0
  352. package/src/editor/core/zone/Zone.ts +183 -0
  353. package/src/editor/core/zone/ZoneTip.ts +108 -0
  354. package/src/editor/dataset/constant/Background.ts +10 -0
  355. package/src/editor/dataset/constant/Badge.ts +6 -0
  356. package/src/editor/dataset/constant/Checkbox.ts +12 -0
  357. package/src/editor/dataset/constant/Common.ts +44 -0
  358. package/src/editor/dataset/constant/ContextMenu.ts +61 -0
  359. package/src/editor/dataset/constant/Control.ts +14 -0
  360. package/src/editor/dataset/constant/Cursor.ts +11 -0
  361. package/src/editor/dataset/constant/Editor.ts +19 -0
  362. package/src/editor/dataset/constant/Element.ts +173 -0
  363. package/src/editor/dataset/constant/Footer.ts +10 -0
  364. package/src/editor/dataset/constant/Graffiti.ts +6 -0
  365. package/src/editor/dataset/constant/Group.ts +10 -0
  366. package/src/editor/dataset/constant/Header.ts +10 -0
  367. package/src/editor/dataset/constant/ImgCaption.ts +8 -0
  368. package/src/editor/dataset/constant/Label.ts +8 -0
  369. package/src/editor/dataset/constant/LineBreak.ts +7 -0
  370. package/src/editor/dataset/constant/LineNumber.ts +11 -0
  371. package/src/editor/dataset/constant/List.ts +26 -0
  372. package/src/editor/dataset/constant/PageBorder.ts +8 -0
  373. package/src/editor/dataset/constant/PageBreak.ts +7 -0
  374. package/src/editor/dataset/constant/PageNumber.ts +22 -0
  375. package/src/editor/dataset/constant/Placeholder.ts +9 -0
  376. package/src/editor/dataset/constant/Radio.ts +12 -0
  377. package/src/editor/dataset/constant/Regular.ts +23 -0
  378. package/src/editor/dataset/constant/Separator.ts +6 -0
  379. package/src/editor/dataset/constant/Shortcut.ts +3 -0
  380. package/src/editor/dataset/constant/Table.ts +9 -0
  381. package/src/editor/dataset/constant/Title.ts +38 -0
  382. package/src/editor/dataset/constant/Watermark.ts +17 -0
  383. package/src/editor/dataset/constant/WhiteSpace.ts +7 -0
  384. package/src/editor/dataset/constant/Zone.ts +5 -0
  385. package/src/editor/dataset/enum/Area.ts +5 -0
  386. package/src/editor/dataset/enum/Background.ts +11 -0
  387. package/src/editor/dataset/enum/Block.ts +4 -0
  388. package/src/editor/dataset/enum/Common.ts +30 -0
  389. package/src/editor/dataset/enum/Control.ts +39 -0
  390. package/src/editor/dataset/enum/Editor.ts +51 -0
  391. package/src/editor/dataset/enum/Element.ts +21 -0
  392. package/src/editor/dataset/enum/ElementStyle.ts +12 -0
  393. package/src/editor/dataset/enum/Event.ts +5 -0
  394. package/src/editor/dataset/enum/KeyMap.ts +85 -0
  395. package/src/editor/dataset/enum/LineNumber.ts +4 -0
  396. package/src/editor/dataset/enum/List.ts +23 -0
  397. package/src/editor/dataset/enum/Observer.ts +6 -0
  398. package/src/editor/dataset/enum/Row.ts +7 -0
  399. package/src/editor/dataset/enum/Text.ts +13 -0
  400. package/src/editor/dataset/enum/Title.ts +8 -0
  401. package/src/editor/dataset/enum/VerticalAlign.ts +5 -0
  402. package/src/editor/dataset/enum/Watermark.ts +4 -0
  403. package/src/editor/dataset/enum/table/Table.ts +19 -0
  404. package/src/editor/dataset/enum/table/TableTool.ts +4 -0
  405. package/src/editor/index.ts +241 -0
  406. package/src/editor/interface/Area.ts +68 -0
  407. package/src/editor/interface/Background.ts +9 -0
  408. package/src/editor/interface/Badge.ts +17 -0
  409. package/src/editor/interface/Block.ts +18 -0
  410. package/src/editor/interface/Catalog.ts +11 -0
  411. package/src/editor/interface/Checkbox.ts +17 -0
  412. package/src/editor/interface/Command.ts +3 -0
  413. package/src/editor/interface/Common.ts +43 -0
  414. package/src/editor/interface/Control.ts +250 -0
  415. package/src/editor/interface/Cursor.ts +7 -0
  416. package/src/editor/interface/Draw.ts +86 -0
  417. package/src/editor/interface/Editor.ts +172 -0
  418. package/src/editor/interface/Element.ts +273 -0
  419. package/src/editor/interface/Event.ts +27 -0
  420. package/src/editor/interface/EventBus.ts +46 -0
  421. package/src/editor/interface/Footer.ts +9 -0
  422. package/src/editor/interface/Graffiti.ts +15 -0
  423. package/src/editor/interface/Group.ts +8 -0
  424. package/src/editor/interface/Header.ts +9 -0
  425. package/src/editor/interface/Label.ts +8 -0
  426. package/src/editor/interface/LineBreak.ts +5 -0
  427. package/src/editor/interface/LineNumber.ts +10 -0
  428. package/src/editor/interface/Listener.ts +88 -0
  429. package/src/editor/interface/Margin.ts +1 -0
  430. package/src/editor/interface/PageBorder.ts +8 -0
  431. package/src/editor/interface/PageBreak.ts +5 -0
  432. package/src/editor/interface/PageNumber.ts +16 -0
  433. package/src/editor/interface/Placeholder.ts +7 -0
  434. package/src/editor/interface/Plugin.ts +8 -0
  435. package/src/editor/interface/Position.ts +113 -0
  436. package/src/editor/interface/Previewer.ts +15 -0
  437. package/src/editor/interface/Radio.ts +17 -0
  438. package/src/editor/interface/Range.ts +61 -0
  439. package/src/editor/interface/Row.ts +25 -0
  440. package/src/editor/interface/Search.ts +36 -0
  441. package/src/editor/interface/Separator.ts +4 -0
  442. package/src/editor/interface/Text.ts +15 -0
  443. package/src/editor/interface/Title.ts +32 -0
  444. package/src/editor/interface/Watermark.ts +16 -0
  445. package/src/editor/interface/WhiteSpace.ts +5 -0
  446. package/src/editor/interface/Zone.ts +3 -0
  447. package/src/editor/interface/contextmenu/ContextMenu.ts +76 -0
  448. package/src/editor/interface/i18n/I18n.ts +7 -0
  449. package/src/editor/interface/shortcut/Shortcut.ts +14 -0
  450. package/src/editor/interface/table/Colgroup.ts +4 -0
  451. package/src/editor/interface/table/Table.ts +9 -0
  452. package/src/editor/interface/table/Td.ts +36 -0
  453. package/src/editor/interface/table/Tr.ts +11 -0
  454. package/src/editor/types/index.d.ts +5 -0
  455. package/src/editor/utils/clipboard.ts +94 -0
  456. package/src/editor/utils/element.ts +1877 -0
  457. package/src/editor/utils/hotkey.ts +5 -0
  458. package/src/editor/utils/index.ts +445 -0
  459. package/src/editor/utils/option.ts +253 -0
  460. package/src/editor/utils/paragraph.ts +28 -0
  461. package/src/editor/utils/print.ts +99 -0
  462. package/src/editor/utils/ua.ts +13 -0
  463. package/src/main.ts +2053 -0
  464. package/src/mock.ts +611 -0
  465. package/src/plugins/copy/index.ts +30 -0
  466. package/src/plugins/markdown/index.ts +118 -0
  467. package/src/style.css +1079 -0
  468. package/src/utils/index.ts +45 -0
  469. package/src/utils/prism.ts +89 -0
  470. package/src/vite-env.d.ts +1 -0
  471. package/tsconfig.json +25 -0
  472. package/vite.config.ts +46 -0
@@ -0,0 +1,988 @@
1
+ import { ElementType, IElement, TableBorder, VerticalAlign } from '../../../..'
2
+ import { ZERO } from '../../../../dataset/constant/Common'
3
+ import { TABLE_CONTEXT_ATTR } from '../../../../dataset/constant/Element'
4
+ import { TdBorder, TdSlash } from '../../../../dataset/enum/table/Table'
5
+ import { DeepRequired } from '../../../../interface/Common'
6
+ import { IEditorOption } from '../../../../interface/Editor'
7
+ import { IColgroup } from '../../../../interface/table/Colgroup'
8
+ import { ITd } from '../../../../interface/table/Td'
9
+ import { ITr } from '../../../../interface/table/Tr'
10
+ import { cloneProperty, getUUID } from '../../../../utils'
11
+ import {
12
+ formatElementContext,
13
+ formatElementList
14
+ } from '../../../../utils/element'
15
+ import { Position } from '../../../position/Position'
16
+ import { RangeManager } from '../../../range/RangeManager'
17
+ import { Draw } from '../../Draw'
18
+ import { TableParticle } from './TableParticle'
19
+ import { TableTool } from './TableTool'
20
+
21
+ export class TableOperate {
22
+ private draw: Draw
23
+ private range: RangeManager
24
+ private position: Position
25
+ private tableTool: TableTool
26
+ private tableParticle: TableParticle
27
+ private options: DeepRequired<IEditorOption>
28
+
29
+ constructor(draw: Draw) {
30
+ this.draw = draw
31
+ this.range = draw.getRange()
32
+ this.position = draw.getPosition()
33
+ this.tableTool = draw.getTableTool()
34
+ this.tableParticle = draw.getTableParticle()
35
+ this.options = draw.getOptions()
36
+ }
37
+
38
+ public insertTable(row: number, col: number) {
39
+ const { startIndex, endIndex } = this.range.getRange()
40
+ if (!~startIndex && !~endIndex) return
41
+ const { defaultTrMinHeight } = this.options.table
42
+ const elementList = this.draw.getElementList()
43
+ let offsetX = 0
44
+ if (elementList[startIndex]?.listId) {
45
+ const positionList = this.position.getPositionList()
46
+ const { rowIndex } = positionList[startIndex]
47
+ const rowList = this.draw.getRowList()
48
+ const row = rowList[rowIndex]
49
+ offsetX = row?.offsetX || 0
50
+ }
51
+ const innerWidth = this.draw.getContextInnerWidth() - offsetX
52
+ // colgroup
53
+ const colgroup: IColgroup[] = []
54
+ const colWidth = innerWidth / col
55
+ for (let c = 0; c < col; c++) {
56
+ colgroup.push({
57
+ width: colWidth
58
+ })
59
+ }
60
+ // trlist
61
+ const trList: ITr[] = []
62
+ for (let r = 0; r < row; r++) {
63
+ const tdList: ITd[] = []
64
+ const tr: ITr = {
65
+ height: defaultTrMinHeight,
66
+ tdList
67
+ }
68
+ for (let c = 0; c < col; c++) {
69
+ tdList.push({
70
+ colspan: 1,
71
+ rowspan: 1,
72
+ value: []
73
+ })
74
+ }
75
+ trList.push(tr)
76
+ }
77
+ const element: IElement = {
78
+ type: ElementType.TABLE,
79
+ value: '',
80
+ colgroup,
81
+ trList
82
+ }
83
+ // 格式化element
84
+ formatElementList([element], {
85
+ editorOptions: this.options
86
+ })
87
+ formatElementContext(elementList, [element], startIndex, {
88
+ editorOptions: this.options
89
+ })
90
+ const curIndex = startIndex + 1
91
+ this.draw.spliceElementList(
92
+ elementList,
93
+ curIndex,
94
+ startIndex === endIndex ? 0 : endIndex - startIndex,
95
+ [element]
96
+ )
97
+ this.range.setRange(curIndex, curIndex)
98
+ this.draw.render({ curIndex, isSetCursor: false })
99
+ }
100
+
101
+ public insertTableTopRow() {
102
+ const positionContext = this.position.getPositionContext()
103
+ if (!positionContext.isTable) return
104
+ const { index, trIndex, tableId } = positionContext
105
+ const originalElementList = this.draw.getOriginalElementList()
106
+ const element = originalElementList[index!]
107
+ const curTrList = element.trList!
108
+ const curTr = curTrList[trIndex!]
109
+ // 之前跨行的增加跨行数
110
+ if (curTr.tdList.length < element.colgroup!.length) {
111
+ const curTrNo = curTr.tdList[0].rowIndex!
112
+ for (let t = 0; t < trIndex!; t++) {
113
+ const tr = curTrList[t]
114
+ for (let d = 0; d < tr.tdList.length; d++) {
115
+ const td = tr.tdList[d]
116
+ if (td.rowspan > 1 && td.rowIndex! + td.rowspan >= curTrNo + 1) {
117
+ td.rowspan += 1
118
+ }
119
+ }
120
+ }
121
+ }
122
+ // 增加当前行
123
+ const newTrId = getUUID()
124
+ const newTr: ITr = {
125
+ height: curTr.height,
126
+ id: newTrId,
127
+ tdList: []
128
+ }
129
+ for (let t = 0; t < curTr.tdList.length; t++) {
130
+ const curTd = curTr.tdList[t]
131
+ const newTdId = getUUID()
132
+ newTr.tdList.push({
133
+ id: newTdId,
134
+ rowspan: 1,
135
+ colspan: curTd.colspan,
136
+ value: [
137
+ {
138
+ value: ZERO,
139
+ size: 16,
140
+ tableId,
141
+ trId: newTrId,
142
+ tdId: newTdId
143
+ }
144
+ ]
145
+ })
146
+ }
147
+ curTrList.splice(trIndex!, 0, newTr)
148
+ // 重新设置上下文
149
+ this.position.setPositionContext({
150
+ isTable: true,
151
+ index,
152
+ trIndex,
153
+ tdIndex: 0,
154
+ tdId: newTr.tdList[0].id,
155
+ trId: newTr.id,
156
+ tableId
157
+ })
158
+ this.range.setRange(0, 0)
159
+ // 重新渲染
160
+ this.draw.render({ curIndex: 0 })
161
+ this.tableTool.render()
162
+ }
163
+
164
+ public insertTableBottomRow() {
165
+ const positionContext = this.position.getPositionContext()
166
+ if (!positionContext.isTable) return
167
+ const { index, trIndex, tableId } = positionContext
168
+ const originalElementList = this.draw.getOriginalElementList()
169
+ const element = originalElementList[index!]
170
+ const curTrList = element.trList!
171
+ const curTr = curTrList[trIndex!]
172
+ const anchorTr =
173
+ curTrList.length - 1 === trIndex ? curTr : curTrList[trIndex! + 1]
174
+ // 之前/当前行跨行的增加跨行数
175
+ if (anchorTr.tdList.length < element.colgroup!.length) {
176
+ const curTrNo = anchorTr.tdList[0].rowIndex!
177
+ for (let t = 0; t < trIndex! + 1; t++) {
178
+ const tr = curTrList[t]
179
+ for (let d = 0; d < tr.tdList.length; d++) {
180
+ const td = tr.tdList[d]
181
+ if (td.rowspan > 1 && td.rowIndex! + td.rowspan >= curTrNo + 1) {
182
+ td.rowspan += 1
183
+ }
184
+ }
185
+ }
186
+ }
187
+ // 增加当前行
188
+ const newTrId = getUUID()
189
+ const newTr: ITr = {
190
+ height: anchorTr.height,
191
+ id: newTrId,
192
+ tdList: []
193
+ }
194
+ for (let t = 0; t < anchorTr.tdList.length; t++) {
195
+ const curTd = anchorTr.tdList[t]
196
+ const newTdId = getUUID()
197
+ newTr.tdList.push({
198
+ id: newTdId,
199
+ rowspan: 1,
200
+ colspan: curTd.colspan,
201
+ value: [
202
+ {
203
+ value: ZERO,
204
+ size: 16,
205
+ tableId,
206
+ trId: newTrId,
207
+ tdId: newTdId
208
+ }
209
+ ]
210
+ })
211
+ }
212
+ curTrList.splice(trIndex! + 1, 0, newTr)
213
+ // 重新设置上下文
214
+ this.position.setPositionContext({
215
+ isTable: true,
216
+ index,
217
+ trIndex: trIndex! + 1,
218
+ tdIndex: 0,
219
+ tdId: newTr.tdList[0].id,
220
+ trId: newTr.id,
221
+ tableId: element.id
222
+ })
223
+ this.range.setRange(0, 0)
224
+ // 重新渲染
225
+ this.draw.render({ curIndex: 0 })
226
+ }
227
+
228
+ public adjustColWidth(element: IElement) {
229
+ if (element.type !== ElementType.TABLE) return
230
+ const { defaultColMinWidth } = this.options.table
231
+ const colgroup = element.colgroup!
232
+ const colgroupWidth = colgroup.reduce((pre, cur) => pre + cur.width, 0)
233
+ const width = this.draw.getOriginalInnerWidth()
234
+ if (colgroupWidth > width) {
235
+ // 过滤大于最小宽度的列(可能减少宽度的列)
236
+ const greaterMinWidthCol = colgroup.filter(
237
+ col => col.width > defaultColMinWidth
238
+ )
239
+ // 均分多余宽度
240
+ const adjustWidth = (colgroupWidth - width) / greaterMinWidthCol.length
241
+ for (let g = 0; g < colgroup.length; g++) {
242
+ const group = colgroup[g]
243
+ // 小于最小宽度的列不处理
244
+ if (group.width - adjustWidth >= defaultColMinWidth) {
245
+ group.width -= adjustWidth
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ public insertTableLeftCol() {
252
+ const positionContext = this.position.getPositionContext()
253
+ if (!positionContext.isTable) return
254
+ const { index, tdIndex, tableId } = positionContext
255
+ const originalElementList = this.draw.getOriginalElementList()
256
+ const element = originalElementList[index!]
257
+ const curTrList = element.trList!
258
+ const curTdIndex = tdIndex!
259
+ // 增加列
260
+ for (let t = 0; t < curTrList.length; t++) {
261
+ const tr = curTrList[t]
262
+ const tdId = getUUID()
263
+ tr.tdList.splice(curTdIndex, 0, {
264
+ id: tdId,
265
+ rowspan: 1,
266
+ colspan: 1,
267
+ value: [
268
+ {
269
+ value: ZERO,
270
+ size: 16,
271
+ tableId,
272
+ trId: tr.id,
273
+ tdId
274
+ }
275
+ ]
276
+ })
277
+ }
278
+ // 重新计算宽度
279
+ const { defaultColMinWidth } = this.options.table
280
+ const colgroup = element.colgroup!
281
+ colgroup.splice(curTdIndex, 0, {
282
+ width: defaultColMinWidth
283
+ })
284
+ this.adjustColWidth(element)
285
+ // 重新设置上下文
286
+ this.position.setPositionContext({
287
+ isTable: true,
288
+ index,
289
+ trIndex: 0,
290
+ tdIndex: curTdIndex,
291
+ tdId: curTrList[0].tdList[curTdIndex].id,
292
+ trId: curTrList[0].id,
293
+ tableId
294
+ })
295
+ this.range.setRange(0, 0)
296
+ // 重新渲染
297
+ this.draw.render({ curIndex: 0 })
298
+ this.tableTool.render()
299
+ }
300
+
301
+ public insertTableRightCol() {
302
+ const positionContext = this.position.getPositionContext()
303
+ if (!positionContext.isTable) return
304
+ const { index, tdIndex, tableId } = positionContext
305
+ const originalElementList = this.draw.getOriginalElementList()
306
+ const element = originalElementList[index!]
307
+ const curTrList = element.trList!
308
+ const curTdIndex = tdIndex! + 1
309
+ // 增加列
310
+ for (let t = 0; t < curTrList.length; t++) {
311
+ const tr = curTrList[t]
312
+ const tdId = getUUID()
313
+ tr.tdList.splice(curTdIndex, 0, {
314
+ id: tdId,
315
+ rowspan: 1,
316
+ colspan: 1,
317
+ value: [
318
+ {
319
+ value: ZERO,
320
+ size: 16,
321
+ tableId,
322
+ trId: tr.id,
323
+ tdId
324
+ }
325
+ ]
326
+ })
327
+ }
328
+ // 重新计算宽度
329
+ const { defaultColMinWidth } = this.options.table
330
+ const colgroup = element.colgroup!
331
+ colgroup.splice(curTdIndex, 0, {
332
+ width: defaultColMinWidth
333
+ })
334
+ this.adjustColWidth(element)
335
+ // 重新设置上下文
336
+ this.position.setPositionContext({
337
+ isTable: true,
338
+ index,
339
+ trIndex: 0,
340
+ tdIndex: curTdIndex,
341
+ tdId: curTrList[0].tdList[curTdIndex].id,
342
+ trId: curTrList[0].id,
343
+ tableId: element.id
344
+ })
345
+ this.range.setRange(0, 0)
346
+ // 重新渲染
347
+ this.draw.render({ curIndex: 0 })
348
+ }
349
+
350
+ public deleteTableRow() {
351
+ const positionContext = this.position.getPositionContext()
352
+ if (!positionContext.isTable) return
353
+ const { index, trIndex, tdIndex } = positionContext
354
+ const originalElementList = this.draw.getOriginalElementList()
355
+ const element = originalElementList[index!]
356
+ const trList = element.trList!
357
+ const curTr = trList[trIndex!]
358
+ const curTdRowIndex = curTr.tdList[tdIndex!].rowIndex!
359
+ // 如果是最后一行,直接删除整个表格(如果是拆分表格按照正常逻辑走)
360
+ if (trList.length <= 1 && element.pagingIndex === 0) {
361
+ this.deleteTable()
362
+ return
363
+ }
364
+ // 之前行缩小rowspan
365
+ for (let r = 0; r < curTdRowIndex; r++) {
366
+ const tr = trList[r]
367
+ const tdList = tr.tdList
368
+ for (let d = 0; d < tdList.length; d++) {
369
+ const td = tdList[d]
370
+ if (td.rowIndex! + td.rowspan > curTdRowIndex) {
371
+ td.rowspan--
372
+ }
373
+ }
374
+ }
375
+ // 补跨行
376
+ for (let d = 0; d < curTr.tdList.length; d++) {
377
+ const td = curTr.tdList[d]
378
+ if (td.rowspan > 1) {
379
+ const tdId = getUUID()
380
+ const nextTr = trList[trIndex! + 1]
381
+ nextTr.tdList.splice(d, 0, {
382
+ id: tdId,
383
+ rowspan: td.rowspan - 1,
384
+ colspan: td.colspan,
385
+ value: [
386
+ {
387
+ value: ZERO,
388
+ size: 16,
389
+ tableId: element.id,
390
+ trId: nextTr.id,
391
+ tdId
392
+ }
393
+ ]
394
+ })
395
+ }
396
+ }
397
+ // 删除当前行
398
+ trList.splice(trIndex!, 1)
399
+ // 重新设置上下文
400
+ this.position.setPositionContext({
401
+ isTable: false
402
+ })
403
+ this.range.clearRange()
404
+ // 重新渲染
405
+ this.draw.render({
406
+ curIndex: positionContext.index
407
+ })
408
+ this.tableTool.dispose()
409
+ }
410
+
411
+ public deleteTableCol() {
412
+ const positionContext = this.position.getPositionContext()
413
+ if (!positionContext.isTable) return
414
+ const { index, tdIndex, trIndex } = positionContext
415
+ const originalElementList = this.draw.getOriginalElementList()
416
+ const element = originalElementList[index!]
417
+ const curTrList = element.trList!
418
+ const curTd = curTrList[trIndex!].tdList[tdIndex!]
419
+ const curColIndex = curTd.colIndex!
420
+ // 如果是最后一列,直接删除整个表格
421
+ const moreTdTr = curTrList.find(tr => tr.tdList.length > 1)
422
+ if (!moreTdTr) {
423
+ this.deleteTable()
424
+ return
425
+ }
426
+ // 缩小colspan或删除与当前列重叠的单元格
427
+ for (let t = 0; t < curTrList.length; t++) {
428
+ const tr = curTrList[t]
429
+ for (let d = 0; d < tr.tdList.length; d++) {
430
+ const td = tr.tdList[d]
431
+ if (
432
+ td.colIndex! <= curColIndex &&
433
+ td.colIndex! + td.colspan > curColIndex
434
+ ) {
435
+ if (td.colspan > 1) {
436
+ td.colspan--
437
+ } else {
438
+ tr.tdList.splice(d, 1)
439
+ }
440
+ }
441
+ }
442
+ }
443
+ element.colgroup?.splice(curColIndex, 1)
444
+ // 重新设置上下文
445
+ this.position.setPositionContext({
446
+ isTable: false
447
+ })
448
+ this.range.setRange(0, 0)
449
+ // 重新渲染
450
+ this.draw.render({
451
+ curIndex: positionContext.index
452
+ })
453
+ this.tableTool.dispose()
454
+ }
455
+
456
+ public deleteTable() {
457
+ const positionContext = this.position.getPositionContext()
458
+ if (!positionContext.isTable) return
459
+ const originalElementList = this.draw.getOriginalElementList()
460
+ const tableElement = originalElementList[positionContext.index!]
461
+ // 需要删除的表格数量(拆分表格)及位置
462
+ let deleteCount = 1
463
+ let deleteStartIndex = positionContext.index!
464
+ if (tableElement.pagingId) {
465
+ // 开始删除的下标位置
466
+ deleteStartIndex = positionContext.index! - tableElement.pagingIndex!
467
+ // 计算删除的表格数量
468
+ for (let i = deleteStartIndex + 1; i < originalElementList.length; i++) {
469
+ if (originalElementList[i].pagingId === tableElement.pagingId) {
470
+ deleteCount++
471
+ } else {
472
+ break
473
+ }
474
+ }
475
+ }
476
+ // 删除
477
+ originalElementList.splice(deleteStartIndex, deleteCount)
478
+ const curIndex = deleteStartIndex - 1
479
+ this.position.setPositionContext({
480
+ isTable: false,
481
+ index: curIndex
482
+ })
483
+ this.range.setRange(curIndex, curIndex)
484
+ this.draw.render({ curIndex })
485
+ this.tableTool.dispose()
486
+ }
487
+
488
+ public mergeTableCell() {
489
+ const positionContext = this.position.getPositionContext()
490
+ if (!positionContext.isTable) return
491
+ const {
492
+ isCrossRowCol,
493
+ startTdIndex,
494
+ endTdIndex,
495
+ startTrIndex,
496
+ endTrIndex
497
+ } = this.range.getRange()
498
+ if (!isCrossRowCol) return
499
+ const { index } = positionContext
500
+ const originalElementList = this.draw.getOriginalElementList()
501
+ const element = originalElementList[index!]
502
+ const curTrList = element.trList!
503
+ let startTd = curTrList[startTrIndex!].tdList[startTdIndex!]
504
+ let endTd = curTrList[endTrIndex!].tdList[endTdIndex!]
505
+ // 交换起始位置
506
+ if (startTd.x! > endTd.x! || startTd.y! > endTd.y!) {
507
+ // prettier-ignore
508
+ [startTd, endTd] = [endTd, startTd]
509
+ }
510
+ const startColIndex = startTd.colIndex!
511
+ const endColIndex = endTd.colIndex! + (endTd.colspan - 1)
512
+ const startRowIndex = startTd.rowIndex!
513
+ const endRowIndex = endTd.rowIndex! + (endTd.rowspan - 1)
514
+ // 选区行列
515
+ const rowCol: ITd[][] = []
516
+ for (let t = 0; t < curTrList.length; t++) {
517
+ const tr = curTrList[t]
518
+ const tdList: ITd[] = []
519
+ for (let d = 0; d < tr.tdList.length; d++) {
520
+ const td = tr.tdList[d]
521
+ const tdColIndex = td.colIndex!
522
+ const tdRowIndex = td.rowIndex!
523
+ if (
524
+ tdColIndex >= startColIndex &&
525
+ tdColIndex <= endColIndex &&
526
+ tdRowIndex >= startRowIndex &&
527
+ tdRowIndex <= endRowIndex
528
+ ) {
529
+ tdList.push(td)
530
+ }
531
+ }
532
+ if (tdList.length) {
533
+ rowCol.push(tdList)
534
+ }
535
+ }
536
+ if (!rowCol.length) return
537
+ // 是否是矩形
538
+ const lastRow = rowCol[rowCol.length - 1]
539
+ const leftTop = rowCol[0][0]
540
+ const rightBottom = lastRow[lastRow.length - 1]
541
+ const startX = leftTop.x!
542
+ const startY = leftTop.y!
543
+ const endX = rightBottom.x! + rightBottom.width!
544
+ const endY = rightBottom.y! + rightBottom.height!
545
+ for (let t = 0; t < rowCol.length; t++) {
546
+ const tr = rowCol[t]
547
+ for (let d = 0; d < tr.length; d++) {
548
+ const td = tr[d]
549
+ const tdStartX = td.x!
550
+ const tdStartY = td.y!
551
+ const tdEndX = tdStartX + td.width!
552
+ const tdEndY = tdStartY + td.height!
553
+ // 存在不符合项
554
+ if (
555
+ startX > tdStartX ||
556
+ startY > tdStartY ||
557
+ endX < tdEndX ||
558
+ endY < tdEndY
559
+ ) {
560
+ return
561
+ }
562
+ }
563
+ }
564
+ // 合并单元格
565
+ const mergeTdIdList: string[] = []
566
+ const anchorTd = rowCol[0][0]
567
+ const anchorElement = anchorTd.value[0]
568
+ for (let t = 0; t < rowCol.length; t++) {
569
+ const tr = rowCol[t]
570
+ for (let d = 0; d < tr.length; d++) {
571
+ const td = tr[d]
572
+ const isAnchorTd = t === 0 && d === 0
573
+ // 缓存待删除单元id并合并单元格内容
574
+ if (!isAnchorTd) {
575
+ mergeTdIdList.push(td.id!)
576
+ // 被合并单元格没内容时忽略换行符
577
+ const startTdValueIndex = td.value.length > 1 ? 0 : 1
578
+ // 复制表格属性后追加
579
+ for (let d = startTdValueIndex; d < td.value.length; d++) {
580
+ const tdElement = td.value[d]
581
+ cloneProperty<IElement>(
582
+ TABLE_CONTEXT_ATTR,
583
+ anchorElement,
584
+ tdElement
585
+ )
586
+ anchorTd.value.push(tdElement)
587
+ }
588
+ }
589
+ // 列合并
590
+ if (t === 0 && d !== 0) {
591
+ anchorTd.colspan += td.colspan
592
+ }
593
+ // 行合并
594
+ if (t !== 0) {
595
+ if (anchorTd.colIndex === td.colIndex) {
596
+ anchorTd.rowspan += td.rowspan
597
+ }
598
+ }
599
+ }
600
+ }
601
+ // 移除多余单元格
602
+ for (let t = 0; t < curTrList.length; t++) {
603
+ const tr = curTrList[t]
604
+ let d = 0
605
+ while (d < tr.tdList.length) {
606
+ const td = tr.tdList[d]
607
+ if (mergeTdIdList.includes(td.id!)) {
608
+ tr.tdList.splice(d, 1)
609
+ d--
610
+ }
611
+ d++
612
+ }
613
+ }
614
+ // 设置上下文信息
615
+ this.position.setPositionContext({
616
+ ...positionContext,
617
+ trIndex: anchorTd.trIndex,
618
+ tdIndex: anchorTd.tdIndex
619
+ })
620
+ const curIndex = anchorTd.value.length - 1
621
+ this.range.setRange(curIndex, curIndex)
622
+ // 重新渲染
623
+ this.draw.render()
624
+ this.tableTool.render()
625
+ }
626
+
627
+ public cancelMergeTableCell() {
628
+ const positionContext = this.position.getPositionContext()
629
+ if (!positionContext.isTable) return
630
+ const { index, tdIndex, trIndex } = positionContext
631
+ const originalElementList = this.draw.getOriginalElementList()
632
+ const element = originalElementList[index!]
633
+ const curTrList = element.trList!
634
+ const curTr = curTrList[trIndex!]!
635
+ const curTd = curTr.tdList[tdIndex!]
636
+ if (curTd.rowspan === 1 && curTd.colspan === 1) return
637
+ const colspan = curTd.colspan
638
+ // 设置跨列
639
+ if (curTd.colspan > 1) {
640
+ for (let c = 1; c < curTd.colspan; c++) {
641
+ const tdId = getUUID()
642
+ curTr.tdList.splice(tdIndex! + c, 0, {
643
+ id: tdId,
644
+ rowspan: 1,
645
+ colspan: 1,
646
+ value: [
647
+ {
648
+ value: ZERO,
649
+ size: 16,
650
+ tableId: element.id,
651
+ trId: curTr.id,
652
+ tdId
653
+ }
654
+ ]
655
+ })
656
+ }
657
+ curTd.colspan = 1
658
+ }
659
+ // 设置跨行
660
+ if (curTd.rowspan > 1) {
661
+ for (let r = 1; r < curTd.rowspan; r++) {
662
+ const tr = curTrList[trIndex! + r]
663
+ for (let c = 0; c < colspan; c++) {
664
+ const tdId = getUUID()
665
+ tr.tdList.splice(curTd.colIndex!, 0, {
666
+ id: tdId,
667
+ rowspan: 1,
668
+ colspan: 1,
669
+ value: [
670
+ {
671
+ value: ZERO,
672
+ size: 16,
673
+ tableId: element.id,
674
+ trId: tr.id,
675
+ tdId
676
+ }
677
+ ]
678
+ })
679
+ }
680
+ }
681
+ curTd.rowspan = 1
682
+ }
683
+ // 重新渲染
684
+ const curIndex = curTd.value.length - 1
685
+ this.range.setRange(curIndex, curIndex)
686
+ this.draw.render()
687
+ this.tableTool.render()
688
+ }
689
+
690
+ public splitVerticalTableCell() {
691
+ const positionContext = this.position.getPositionContext()
692
+ if (!positionContext.isTable) return
693
+ // 暂时忽略跨行列选择
694
+ const range = this.range.getRange()
695
+ if (range.isCrossRowCol) return
696
+ const { index, tdIndex, trIndex } = positionContext
697
+ const originalElementList = this.draw.getOriginalElementList()
698
+ const element = originalElementList[index!]
699
+ const curTrList = element.trList!
700
+ const curTr = curTrList[trIndex!]!
701
+ const curTd = curTr.tdList[tdIndex!]
702
+ // 增加列属性
703
+ element.colgroup!.splice(tdIndex! + 1, 0, {
704
+ width: this.options.table.defaultColMinWidth
705
+ })
706
+ // 同行增加td,非同行增加跨列数
707
+ for (let t = 0; t < curTrList.length; t++) {
708
+ const tr = curTrList[t]
709
+ let d = 0
710
+ while (d < tr.tdList.length) {
711
+ const td = tr.tdList[d]
712
+ // 非同行:存在交叉时增加跨列数
713
+ if (td.rowIndex !== curTd.rowIndex) {
714
+ if (
715
+ td.colIndex! <= curTd.colIndex! &&
716
+ td.colIndex! + td.colspan > curTd.colIndex!
717
+ ) {
718
+ td.colspan++
719
+ }
720
+ } else {
721
+ // 当前单元格:往右插入td
722
+ if (td.id === curTd.id) {
723
+ const tdId = getUUID()
724
+ curTr.tdList.splice(d + curTd.colspan, 0, {
725
+ id: tdId,
726
+ rowspan: curTd.rowspan,
727
+ colspan: 1,
728
+ value: [
729
+ {
730
+ value: ZERO,
731
+ size: 16,
732
+ tableId: element.id,
733
+ trId: tr.id,
734
+ tdId
735
+ }
736
+ ]
737
+ })
738
+ d++
739
+ }
740
+ }
741
+ d++
742
+ }
743
+ }
744
+ // 重新渲染
745
+ this.draw.render()
746
+ this.tableTool.render()
747
+ }
748
+
749
+ public splitHorizontalTableCell() {
750
+ const positionContext = this.position.getPositionContext()
751
+ if (!positionContext.isTable) return
752
+ // 暂时忽略跨行列选择
753
+ const range = this.range.getRange()
754
+ if (range.isCrossRowCol) return
755
+ const { index, tdIndex, trIndex } = positionContext
756
+ const originalElementList = this.draw.getOriginalElementList()
757
+ const element = originalElementList[index!]
758
+ const curTrList = element.trList!
759
+ const curTr = curTrList[trIndex!]!
760
+ const curTd = curTr.tdList[tdIndex!]
761
+ // 追加的行跳出循环
762
+ let appendTrIndex = -1
763
+ // 交叉行增加rowspan,当前单元格往下追加一行tr
764
+ let t = 0
765
+ while (t < curTrList.length) {
766
+ if (t === appendTrIndex) {
767
+ t++
768
+ continue
769
+ }
770
+ const tr = curTrList[t]
771
+ let d = 0
772
+ while (d < tr.tdList.length) {
773
+ const td = tr.tdList[d]
774
+ if (td.id === curTd.id) {
775
+ const trId = getUUID()
776
+ const tdId = getUUID()
777
+ curTrList.splice(t + curTd.rowspan, 0, {
778
+ id: trId,
779
+ height: this.options.table.defaultTrMinHeight,
780
+ tdList: [
781
+ {
782
+ id: tdId,
783
+ rowspan: 1,
784
+ colspan: curTd.colspan,
785
+ value: [
786
+ {
787
+ value: ZERO,
788
+ size: 16,
789
+ tableId: element.id,
790
+ trId,
791
+ tdId
792
+ }
793
+ ]
794
+ }
795
+ ]
796
+ })
797
+ appendTrIndex = t + curTd.rowspan
798
+ } else if (
799
+ td.rowIndex! >= curTd.rowIndex! &&
800
+ td.rowIndex! < curTd.rowIndex! + curTd.rowspan &&
801
+ td.rowIndex! + td.rowspan >= curTd.rowIndex! + curTd.rowspan
802
+ ) {
803
+ // 1. 循环td上方大于等于当前td上方 && 小于当前td的下方=>存在交叉
804
+ // 2. 循环td下方大于或等于当前td下方
805
+ td.rowspan++
806
+ }
807
+ d++
808
+ }
809
+ t++
810
+ }
811
+ // 重新渲染
812
+ this.draw.render()
813
+ this.tableTool.render()
814
+ }
815
+
816
+ public tableTdVerticalAlign(payload: VerticalAlign) {
817
+ const rowCol = this.tableParticle.getRangeRowCol()
818
+ if (!rowCol) return
819
+ for (let r = 0; r < rowCol.length; r++) {
820
+ const row = rowCol[r]
821
+ for (let c = 0; c < row.length; c++) {
822
+ const td = row[c]
823
+ if (
824
+ !td ||
825
+ td.verticalAlign === payload ||
826
+ (!td.verticalAlign && payload === VerticalAlign.TOP)
827
+ ) {
828
+ continue
829
+ }
830
+ // 重设垂直对齐方式
831
+ td.verticalAlign = payload
832
+ }
833
+ }
834
+ const { endIndex } = this.range.getRange()
835
+ this.draw.render({
836
+ curIndex: endIndex
837
+ })
838
+ }
839
+
840
+ public tableBorderType(payload: TableBorder) {
841
+ const positionContext = this.position.getPositionContext()
842
+ if (!positionContext.isTable) return
843
+ const { index } = positionContext
844
+ const originalElementList = this.draw.getOriginalElementList()
845
+ const element = originalElementList[index!]
846
+ if (
847
+ (!element.borderType && payload === TableBorder.ALL) ||
848
+ element.borderType === payload
849
+ ) {
850
+ return
851
+ }
852
+ element.borderType = payload
853
+ const { endIndex } = this.range.getRange()
854
+ this.draw.render({
855
+ curIndex: endIndex
856
+ })
857
+ }
858
+
859
+ public tableBorderColor(payload: string) {
860
+ const positionContext = this.position.getPositionContext()
861
+ if (!positionContext.isTable) return
862
+ const { index } = positionContext
863
+ const originalElementList = this.draw.getOriginalElementList()
864
+ const element = originalElementList[index!]
865
+ if (
866
+ (!element.borderColor &&
867
+ payload === this.options.table.defaultBorderColor) ||
868
+ element.borderColor === payload
869
+ ) {
870
+ return
871
+ }
872
+ element.borderColor = payload
873
+ const { endIndex } = this.range.getRange()
874
+ this.draw.render({
875
+ curIndex: endIndex,
876
+ isCompute: false
877
+ })
878
+ }
879
+
880
+ public tableTdBorderType(payload: TdBorder) {
881
+ const rowCol = this.tableParticle.getRangeRowCol()
882
+ if (!rowCol) return
883
+ const tdList = rowCol.flat()
884
+ // 存在则设置边框类型,否则取消设置
885
+ const isSetBorderType = tdList.some(
886
+ td => !td.borderTypes?.includes(payload)
887
+ )
888
+ tdList.forEach(td => {
889
+ if (!td.borderTypes) {
890
+ td.borderTypes = []
891
+ }
892
+ const borderTypeIndex = td.borderTypes.findIndex(type => type === payload)
893
+ if (isSetBorderType) {
894
+ if (!~borderTypeIndex) {
895
+ td.borderTypes.push(payload)
896
+ }
897
+ } else {
898
+ if (~borderTypeIndex) {
899
+ td.borderTypes.splice(borderTypeIndex, 1)
900
+ }
901
+ }
902
+ // 不存在边框设置时删除字段
903
+ if (!td.borderTypes.length) {
904
+ delete td.borderTypes
905
+ }
906
+ })
907
+ const { endIndex } = this.range.getRange()
908
+ this.draw.render({
909
+ curIndex: endIndex
910
+ })
911
+ }
912
+
913
+ public tableTdSlashType(payload: TdSlash) {
914
+ const rowCol = this.tableParticle.getRangeRowCol()
915
+ if (!rowCol) return
916
+ const tdList = rowCol.flat()
917
+ // 存在则设置单元格斜线类型,否则取消设置
918
+ const isSetTdSlashType = tdList.some(
919
+ td => !td.slashTypes?.includes(payload)
920
+ )
921
+ tdList.forEach(td => {
922
+ if (!td.slashTypes) {
923
+ td.slashTypes = []
924
+ }
925
+ const slashTypeIndex = td.slashTypes.findIndex(type => type === payload)
926
+ if (isSetTdSlashType) {
927
+ if (!~slashTypeIndex) {
928
+ td.slashTypes.push(payload)
929
+ }
930
+ } else {
931
+ if (~slashTypeIndex) {
932
+ td.slashTypes.splice(slashTypeIndex, 1)
933
+ }
934
+ }
935
+ // 不存在斜线设置时删除字段
936
+ if (!td.slashTypes.length) {
937
+ delete td.slashTypes
938
+ }
939
+ })
940
+ const { endIndex } = this.range.getRange()
941
+ this.draw.render({
942
+ curIndex: endIndex
943
+ })
944
+ }
945
+
946
+ public tableTdBackgroundColor(payload: string) {
947
+ const rowCol = this.tableParticle.getRangeRowCol()
948
+ if (!rowCol) return
949
+ for (let r = 0; r < rowCol.length; r++) {
950
+ const row = rowCol[r]
951
+ for (let c = 0; c < row.length; c++) {
952
+ const col = row[c]
953
+ col.backgroundColor = payload
954
+ }
955
+ }
956
+ const { endIndex } = this.range.getRange()
957
+ this.range.setRange(endIndex, endIndex)
958
+ this.draw.render({
959
+ isCompute: false
960
+ })
961
+ }
962
+
963
+ public tableSelectAll() {
964
+ const positionContext = this.position.getPositionContext()
965
+ const { index, tableId, isTable } = positionContext
966
+ if (!isTable || !tableId) return
967
+ const { startIndex, endIndex } = this.range.getRange()
968
+ const originalElementList = this.draw.getOriginalElementList()
969
+ const trList = originalElementList[index!].trList!
970
+ // 最后单元格位置
971
+ const endTrIndex = trList.length - 1
972
+ const endTdIndex = trList[endTrIndex].tdList.length - 1
973
+ this.range.replaceRange({
974
+ startIndex,
975
+ endIndex,
976
+ tableId,
977
+ startTdIndex: 0,
978
+ endTdIndex,
979
+ startTrIndex: 0,
980
+ endTrIndex
981
+ })
982
+ this.draw.render({
983
+ isSetCursor: false,
984
+ isCompute: false,
985
+ isSubmitHistory: false
986
+ })
987
+ }
988
+ }