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,723 @@
1
+ import { ElementType } from '../..'
2
+ import { ZERO } from '../../dataset/constant/Common'
3
+ import { TEXTLIKE_ELEMENT_TYPE } from '../../dataset/constant/Element'
4
+ import { ControlComponent } from '../../dataset/enum/Control'
5
+ import { EditorContext } from '../../dataset/enum/Editor'
6
+ import { IControlContext } from '../../interface/Control'
7
+ import { IEditorOption } from '../../interface/Editor'
8
+ import { IElement } from '../../interface/Element'
9
+ import { EventBusMap } from '../../interface/EventBus'
10
+ import { IRangeStyle } from '../../interface/Listener'
11
+ import {
12
+ IRange,
13
+ IRangeElementStyle,
14
+ IRangeParagraphInfo,
15
+ RangeRowArray,
16
+ RangeRowMap
17
+ } from '../../interface/Range'
18
+ import { getAnchorElement } from '../../utils/element'
19
+ import { Draw } from '../draw/Draw'
20
+ import { EventBus } from '../event/eventbus/EventBus'
21
+ import { HistoryManager } from '../history/HistoryManager'
22
+ import { Listener } from '../listener/Listener'
23
+ import { Position } from '../position/Position'
24
+
25
+ export class RangeManager {
26
+ private draw: Draw
27
+ private options: Required<IEditorOption>
28
+ private range: IRange
29
+ private listener: Listener
30
+ private eventBus: EventBus<EventBusMap>
31
+ private position: Position
32
+ private historyManager: HistoryManager
33
+ private defaultStyle: IRangeElementStyle | null
34
+
35
+ constructor(draw: Draw) {
36
+ this.draw = draw
37
+ this.options = draw.getOptions()
38
+ this.listener = draw.getListener()
39
+ this.eventBus = draw.getEventBus()
40
+ this.position = draw.getPosition()
41
+ this.historyManager = draw.getHistoryManager()
42
+ this.range = {
43
+ startIndex: -1,
44
+ endIndex: -1
45
+ }
46
+ this.defaultStyle = null
47
+ }
48
+
49
+ public getRange(): IRange {
50
+ return this.range
51
+ }
52
+
53
+ public clearRange() {
54
+ this.setRange(-1, -1)
55
+ }
56
+
57
+ public setDefaultStyle(style: IRangeElementStyle | null) {
58
+ if (!style) {
59
+ this.defaultStyle = null
60
+ } else {
61
+ this.defaultStyle = {
62
+ ...this.defaultStyle,
63
+ ...style
64
+ }
65
+ }
66
+ }
67
+
68
+ public getDefaultStyle(): IRangeElementStyle | null {
69
+ return this.defaultStyle
70
+ }
71
+
72
+ public getRangeAnchorStyle(
73
+ elementList: IElement[],
74
+ anchorIndex: number
75
+ ): IElement | null {
76
+ const anchorElement = getAnchorElement(elementList, anchorIndex)
77
+ if (!anchorElement) return null
78
+ return {
79
+ ...anchorElement,
80
+ ...this.defaultStyle
81
+ }
82
+ }
83
+
84
+ public getIsRangeChange(
85
+ startIndex: number,
86
+ endIndex: number,
87
+ tableId?: string,
88
+ startTdIndex?: number,
89
+ endTdIndex?: number,
90
+ startTrIndex?: number,
91
+ endTrIndex?: number
92
+ ): boolean {
93
+ return (
94
+ this.range.startIndex !== startIndex ||
95
+ this.range.endIndex !== endIndex ||
96
+ this.range.tableId !== tableId ||
97
+ this.range.startTdIndex !== startTdIndex ||
98
+ this.range.endTdIndex !== endTdIndex ||
99
+ this.range.startTrIndex !== startTrIndex ||
100
+ this.range.endTrIndex !== endTrIndex
101
+ )
102
+ }
103
+
104
+ public getIsCollapsed(): boolean {
105
+ const { startIndex, endIndex } = this.range
106
+ return startIndex === endIndex
107
+ }
108
+
109
+ public getIsSelection(): boolean {
110
+ const { startIndex, endIndex } = this.range
111
+ if (!~startIndex && !~endIndex) return false
112
+ return startIndex !== endIndex
113
+ }
114
+
115
+ public getSelection(): IElement[] | null {
116
+ const { startIndex, endIndex } = this.range
117
+ if (startIndex === endIndex) return null
118
+ const elementList = this.draw.getElementList()
119
+ return elementList.slice(
120
+ elementList[startIndex]?.value === ZERO ? startIndex : startIndex + 1,
121
+ endIndex + 1
122
+ )
123
+ }
124
+
125
+ public getSelectionElementList(): IElement[] | null {
126
+ if (this.range.isCrossRowCol) {
127
+ const rowCol = this.draw.getTableParticle().getRangeRowCol()
128
+ if (!rowCol) return null
129
+ const elementList: IElement[] = []
130
+ for (let r = 0; r < rowCol.length; r++) {
131
+ const row = rowCol[r]
132
+ for (let c = 0; c < row.length; c++) {
133
+ const col = row[c]
134
+ elementList.push(...col.value)
135
+ }
136
+ }
137
+ return elementList
138
+ }
139
+ return this.getSelection()
140
+ }
141
+
142
+ public getTextLikeSelection(): IElement[] | null {
143
+ const selection = this.getSelection()
144
+ if (!selection) return null
145
+ return selection.filter(
146
+ s => !s.type || TEXTLIKE_ELEMENT_TYPE.includes(s.type)
147
+ )
148
+ }
149
+
150
+ public getTextLikeSelectionElementList(): IElement[] | null {
151
+ const selection = this.getSelectionElementList()
152
+ if (!selection) return null
153
+ return selection.filter(
154
+ s => !s.type || TEXTLIKE_ELEMENT_TYPE.includes(s.type)
155
+ )
156
+ }
157
+
158
+ // 获取光标所选位置行信息
159
+ public getRangeRow(): RangeRowMap | null {
160
+ const { startIndex, endIndex } = this.range
161
+ if (!~startIndex && !~endIndex) return null
162
+ const positionList = this.position.getPositionList()
163
+ const rangeRow: RangeRowMap = new Map()
164
+ for (let p = startIndex; p < endIndex + 1; p++) {
165
+ const { pageNo, rowNo } = positionList[p]
166
+ const rowSet = rangeRow.get(pageNo)
167
+ if (!rowSet) {
168
+ rangeRow.set(pageNo, new Set([rowNo]))
169
+ } else {
170
+ if (!rowSet.has(rowNo)) {
171
+ rowSet.add(rowNo)
172
+ }
173
+ }
174
+ }
175
+ return rangeRow
176
+ }
177
+
178
+ // 获取光标所选位置元素列表
179
+ public getRangeRowElementList(): IElement[] | null {
180
+ const { startIndex, endIndex, isCrossRowCol } = this.range
181
+ if (!~startIndex && !~endIndex) return null
182
+ if (isCrossRowCol) {
183
+ return this.getSelectionElementList()
184
+ }
185
+ // 选区行信息
186
+ const rangeRow = this.getRangeRow()
187
+ if (!rangeRow) return null
188
+ const positionList = this.position.getPositionList()
189
+ const elementList = this.draw.getElementList()
190
+ // 当前选区所在行
191
+ const rowElementList: IElement[] = []
192
+ for (let p = 0; p < positionList.length; p++) {
193
+ const position = positionList[p]
194
+ const rowSet = rangeRow.get(position.pageNo)
195
+ if (!rowSet) continue
196
+ if (rowSet.has(position.rowNo)) {
197
+ rowElementList.push(elementList[p])
198
+ }
199
+ }
200
+ return rowElementList
201
+ }
202
+
203
+ // 获取选取段落信息
204
+ public getRangeParagraph(): RangeRowArray | null {
205
+ const { startIndex, endIndex } = this.range
206
+ if (!~startIndex && !~endIndex) return null
207
+ const positionList = this.position.getPositionList()
208
+ const elementList = this.draw.getElementList()
209
+ const rangeRow: RangeRowArray = new Map()
210
+ // 向上查找
211
+ let start = startIndex
212
+ while (start >= 0) {
213
+ const { pageNo, rowNo } = positionList[start]
214
+ let rowArray = rangeRow.get(pageNo)
215
+ if (!rowArray) {
216
+ rowArray = []
217
+ rangeRow.set(pageNo, rowArray)
218
+ }
219
+ if (!rowArray.includes(rowNo)) {
220
+ rowArray.unshift(rowNo)
221
+ }
222
+ const element = elementList[start]
223
+ const preElement = elementList[start - 1]
224
+ if (
225
+ (element.value === ZERO && !element.listWrap) ||
226
+ element.listId !== preElement?.listId ||
227
+ element.titleId !== preElement?.titleId
228
+ ) {
229
+ break
230
+ }
231
+ start--
232
+ }
233
+ const isCollapsed = startIndex === endIndex
234
+ // 中间选择
235
+ if (!isCollapsed) {
236
+ let middle = startIndex + 1
237
+ while (middle < endIndex) {
238
+ const { pageNo, rowNo } = positionList[middle]
239
+ let rowArray = rangeRow.get(pageNo)
240
+ if (!rowArray) {
241
+ rowArray = []
242
+ rangeRow.set(pageNo, rowArray)
243
+ }
244
+ if (!rowArray.includes(rowNo)) {
245
+ rowArray.push(rowNo)
246
+ }
247
+ middle++
248
+ }
249
+ }
250
+ // 向下查找
251
+ let end = endIndex
252
+ // 闭合选区&&首字符为换行符时继续向下查找
253
+ if (isCollapsed && elementList[startIndex].value === ZERO) {
254
+ end += 1
255
+ }
256
+ while (end < positionList.length) {
257
+ const element = elementList[end]
258
+ const nextElement = elementList[end + 1]
259
+ if (
260
+ (element.value === ZERO && !element.listWrap) ||
261
+ element.listId !== nextElement?.listId ||
262
+ element.titleId !== nextElement?.titleId
263
+ ) {
264
+ break
265
+ }
266
+ const { pageNo, rowNo } = positionList[end]
267
+ let rowArray = rangeRow.get(pageNo)
268
+ if (!rowArray) {
269
+ rowArray = []
270
+ rangeRow.set(pageNo, rowArray)
271
+ }
272
+ if (!rowArray.includes(rowNo)) {
273
+ rowArray.push(rowNo)
274
+ }
275
+ end++
276
+ }
277
+ return rangeRow
278
+ }
279
+
280
+ // 获取选区段落信息
281
+ public getRangeParagraphInfo(): IRangeParagraphInfo | null {
282
+ const { startIndex, endIndex } = this.range
283
+ if (!~startIndex && !~endIndex) return null
284
+ /// 起始元素位置
285
+ let startPositionIndex = -1
286
+ // 需要改变的元素列表
287
+ const rangeElementList: IElement[] = []
288
+ // 选区行信息
289
+ const rangeRow = this.getRangeParagraph()
290
+ if (!rangeRow) return null
291
+ const elementList = this.draw.getElementList()
292
+ const positionList = this.position.getPositionList()
293
+ for (let p = 0; p < positionList.length; p++) {
294
+ const position = positionList[p]
295
+ const rowArray = rangeRow.get(position.pageNo)
296
+ if (!rowArray) continue
297
+ if (rowArray.includes(position.rowNo)) {
298
+ if (!~startPositionIndex) {
299
+ startPositionIndex = position.index
300
+ }
301
+ rangeElementList.push(elementList[p])
302
+ }
303
+ }
304
+ if (!rangeElementList.length) return null
305
+ return {
306
+ elementList: rangeElementList,
307
+ startIndex: startPositionIndex
308
+ }
309
+ }
310
+
311
+ // 获取选区段落元素列表
312
+ public getRangeParagraphElementList(): IElement[] | null {
313
+ return this.getRangeParagraphInfo()?.elementList || null
314
+ }
315
+
316
+ // 获取选区表格
317
+ public getRangeTableElement(): IElement | null {
318
+ const positionContext = this.position.getPositionContext()
319
+ if (!positionContext.isTable) return null
320
+ const originalElementList = this.draw.getOriginalElementList()
321
+ return originalElementList[positionContext.index!]
322
+ }
323
+
324
+ public getIsSelectAll() {
325
+ const elementList = this.draw.getElementList()
326
+ const { startIndex, endIndex } = this.range
327
+ return (
328
+ startIndex === 0 &&
329
+ elementList.length - 1 === endIndex &&
330
+ !this.position.getPositionContext().isTable
331
+ )
332
+ }
333
+
334
+ public getIsPointInRange(x: number, y: number): boolean {
335
+ const { startIndex, endIndex } = this.range
336
+ const positionList = this.position.getPositionList()
337
+ for (let p = startIndex + 1; p <= endIndex; p++) {
338
+ const position = positionList[p]
339
+ if (!position) break
340
+ const {
341
+ coordinate: { leftTop, rightBottom }
342
+ } = positionList[p]
343
+ if (
344
+ x >= leftTop[0] &&
345
+ x <= rightBottom[0] &&
346
+ y >= leftTop[1] &&
347
+ y <= rightBottom[1]
348
+ ) {
349
+ return true
350
+ }
351
+ }
352
+ return false
353
+ }
354
+
355
+ public getKeywordRangeList(payload: string): IRange[] {
356
+ const searchMatchList = this.draw
357
+ .getSearch()
358
+ .getMatchList(payload, this.draw.getOriginalElementList())
359
+ const searchRangeMap: Map<string, IRange> = new Map()
360
+ for (const searchMatch of searchMatchList) {
361
+ const searchRange = searchRangeMap.get(searchMatch.groupId)
362
+ if (searchRange) {
363
+ searchRange.endIndex += 1
364
+ } else {
365
+ const { type, groupId, tableId, index, tdIndex, trIndex } = searchMatch
366
+ const range: IRange = {
367
+ startIndex: index,
368
+ endIndex: index
369
+ }
370
+ if (type === EditorContext.TABLE) {
371
+ range.tableId = tableId
372
+ range.startTdIndex = tdIndex
373
+ range.endTdIndex = tdIndex
374
+ range.startTrIndex = trIndex
375
+ range.endTrIndex = trIndex
376
+ }
377
+ searchRangeMap.set(groupId, range)
378
+ }
379
+ }
380
+ const rangeList: IRange[] = []
381
+ searchRangeMap.forEach(searchRange => {
382
+ rangeList.push(searchRange)
383
+ })
384
+ return rangeList
385
+ }
386
+
387
+ public getIsCanInput(): boolean {
388
+ const { startIndex, endIndex } = this.getRange()
389
+ if (!~startIndex && !~endIndex) return false
390
+ const elementList = this.draw.getElementList()
391
+ const startElement = elementList[startIndex]
392
+ if (startIndex === endIndex) {
393
+ return (
394
+ (startElement.controlComponent !== ControlComponent.PRE_TEXT ||
395
+ elementList[startIndex + 1]?.controlComponent !==
396
+ ControlComponent.PRE_TEXT) &&
397
+ startElement.controlComponent !== ControlComponent.POST_TEXT
398
+ )
399
+ }
400
+ const endElement = elementList[endIndex]
401
+ // 选区前后不是控件 || 选区前不是控件或是后缀&&选区后不是控件或是后缀 || 选区在控件内
402
+ return (
403
+ (!startElement.controlId && !endElement.controlId) ||
404
+ ((!startElement.controlId ||
405
+ startElement.controlComponent === ControlComponent.POSTFIX) &&
406
+ (!endElement.controlId ||
407
+ endElement.controlComponent === ControlComponent.POSTFIX)) ||
408
+ (!!startElement.controlId &&
409
+ endElement.controlId === startElement.controlId &&
410
+ endElement.controlComponent !== ControlComponent.PRE_TEXT &&
411
+ endElement.controlComponent !== ControlComponent.POST_TEXT &&
412
+ endElement.controlComponent !== ControlComponent.POSTFIX)
413
+ )
414
+ }
415
+
416
+ public setRange(
417
+ startIndex: number,
418
+ endIndex: number,
419
+ tableId?: string,
420
+ startTdIndex?: number,
421
+ endTdIndex?: number,
422
+ startTrIndex?: number,
423
+ endTrIndex?: number
424
+ ) {
425
+ // 判断光标是否改变
426
+ const isChange = this.getIsRangeChange(
427
+ startIndex,
428
+ endIndex,
429
+ tableId,
430
+ startTdIndex,
431
+ endTdIndex,
432
+ startTrIndex,
433
+ endTrIndex
434
+ )
435
+ if (isChange) {
436
+ this.range.startIndex = startIndex
437
+ this.range.endIndex = endIndex
438
+ this.range.tableId = tableId
439
+ this.range.startTdIndex = startTdIndex
440
+ this.range.endTdIndex = endTdIndex
441
+ this.range.startTrIndex = startTrIndex
442
+ this.range.endTrIndex = endTrIndex
443
+ this.range.isCrossRowCol = !!(
444
+ startTdIndex ||
445
+ endTdIndex ||
446
+ startTrIndex ||
447
+ endTrIndex
448
+ )
449
+ this.setDefaultStyle(null)
450
+ }
451
+ this.range.zone = this.draw.getZone().getZone()
452
+ // 激活控件
453
+ const control = this.draw.getControl()
454
+ if (~startIndex && ~endIndex) {
455
+ const elementList = this.draw.getElementList()
456
+ const element = elementList[startIndex]
457
+ if (element?.controlId) {
458
+ control.initControl()
459
+ return
460
+ }
461
+ }
462
+ control.destroyControl()
463
+ }
464
+
465
+ public replaceRange(range: IRange) {
466
+ this.setRange(
467
+ range.startIndex,
468
+ range.endIndex,
469
+ range.tableId,
470
+ range.startTdIndex,
471
+ range.endTdIndex,
472
+ range.startTrIndex,
473
+ range.endTrIndex
474
+ )
475
+ }
476
+
477
+ public shrinkRange() {
478
+ const { startIndex, endIndex } = this.range
479
+ if (startIndex === endIndex || (!~startIndex && !~endIndex)) return
480
+ this.replaceRange({
481
+ ...this.range,
482
+ startIndex: endIndex
483
+ })
484
+ }
485
+
486
+ public setRangeStyle() {
487
+ const rangeStyleChangeListener = this.listener.rangeStyleChange
488
+ const isSubscribeRangeStyleChange =
489
+ this.eventBus.isSubscribe('rangeStyleChange')
490
+ if (!rangeStyleChangeListener && !isSubscribeRangeStyleChange) return
491
+ // 结束光标位置
492
+ const { startIndex, endIndex, isCrossRowCol } = this.range
493
+ if (!~startIndex && !~endIndex) return
494
+ let curElement: IElement | null
495
+ if (isCrossRowCol) {
496
+ // 单元格选择以当前表格定位
497
+ const originalElementList = this.draw.getOriginalElementList()
498
+ const positionContext = this.position.getPositionContext()
499
+ curElement = originalElementList[positionContext.index!]
500
+ } else {
501
+ const index = ~endIndex ? endIndex : 0
502
+ // 行首以第一个非换行符元素定位
503
+ const elementList = this.draw.getElementList()
504
+ curElement = this.getRangeAnchorStyle(elementList, index)
505
+ }
506
+ if (!curElement) return
507
+ // 选取元素列表
508
+ const curElementList = this.getSelection() || [curElement]
509
+ // 类型
510
+ const type = curElement.type || ElementType.TEXT
511
+ // 富文本
512
+ const font = curElement.font || this.options.defaultFont
513
+ const size = curElement.size || this.options.defaultSize
514
+ const bold = !~curElementList.findIndex(el => !el.bold)
515
+ const italic = !~curElementList.findIndex(el => !el.italic)
516
+ const underline = !~curElementList.findIndex(
517
+ el => !el.underline && !el.control?.underline
518
+ )
519
+ const strikeout = !~curElementList.findIndex(el => !el.strikeout)
520
+ const color = curElement.color || null
521
+ const highlight = curElement.highlight || null
522
+ const rowFlex = curElement.rowFlex || null
523
+ const rowMargin = curElement.rowMargin ?? this.options.defaultRowMargin
524
+ const dashArray = curElement.dashArray || []
525
+ const level = curElement.level || null
526
+ const listType = curElement.listType || null
527
+ const listStyle = curElement.listStyle || null
528
+ const textDecoration = underline ? curElement.textDecoration || null : null
529
+ // 菜单
530
+ const painter = !!this.draw.getPainterStyle()
531
+ const undo = this.historyManager.isCanUndo()
532
+ const redo = this.historyManager.isCanRedo()
533
+ // 组信息
534
+ const groupIds = curElement.groupIds || null
535
+ // 扩展字段
536
+ const extension = curElement.extension ?? null
537
+ const rangeStyle: IRangeStyle = {
538
+ type,
539
+ undo,
540
+ redo,
541
+ painter,
542
+ font,
543
+ size,
544
+ bold,
545
+ italic,
546
+ underline,
547
+ strikeout,
548
+ color,
549
+ highlight,
550
+ rowFlex,
551
+ rowMargin,
552
+ dashArray,
553
+ level,
554
+ listType,
555
+ listStyle,
556
+ groupIds,
557
+ textDecoration,
558
+ extension
559
+ }
560
+ if (rangeStyleChangeListener) {
561
+ rangeStyleChangeListener(rangeStyle)
562
+ }
563
+ if (isSubscribeRangeStyleChange) {
564
+ this.eventBus.emit('rangeStyleChange', rangeStyle)
565
+ }
566
+ }
567
+
568
+ public recoveryRangeStyle() {
569
+ const rangeStyleChangeListener = this.listener.rangeStyleChange
570
+ const isSubscribeRangeStyleChange =
571
+ this.eventBus.isSubscribe('rangeStyleChange')
572
+ if (!rangeStyleChangeListener && !isSubscribeRangeStyleChange) return
573
+ const font = this.options.defaultFont
574
+ const size = this.options.defaultSize
575
+ const rowMargin = this.options.defaultRowMargin
576
+ const painter = !!this.draw.getPainterStyle()
577
+ const undo = this.historyManager.isCanUndo()
578
+ const redo = this.historyManager.isCanRedo()
579
+ const rangeStyle: IRangeStyle = {
580
+ type: null,
581
+ undo,
582
+ redo,
583
+ painter,
584
+ font,
585
+ size,
586
+ bold: false,
587
+ italic: false,
588
+ underline: false,
589
+ strikeout: false,
590
+ color: null,
591
+ highlight: null,
592
+ rowFlex: null,
593
+ rowMargin,
594
+ dashArray: [],
595
+ level: null,
596
+ listType: null,
597
+ listStyle: null,
598
+ groupIds: null,
599
+ textDecoration: null,
600
+ extension: null
601
+ }
602
+ if (rangeStyleChangeListener) {
603
+ rangeStyleChangeListener(rangeStyle)
604
+ }
605
+ if (isSubscribeRangeStyleChange) {
606
+ this.eventBus.emit('rangeStyleChange', rangeStyle)
607
+ }
608
+ }
609
+
610
+ public shrinkBoundary(context: IControlContext = {}) {
611
+ const elementList = context.elementList || this.draw.getElementList()
612
+ const range = context.range || this.getRange()
613
+ const { startIndex, endIndex } = range
614
+ if (!~startIndex && !~endIndex) return
615
+ const startElement = elementList[startIndex]
616
+ const endElement = elementList[endIndex]
617
+ if (startIndex === endIndex) {
618
+ if (startElement.controlComponent === ControlComponent.PLACEHOLDER) {
619
+ // 找到第一个placeholder字符
620
+ let index = startIndex - 1
621
+ while (index > 0) {
622
+ const preElement = elementList[index]
623
+ if (
624
+ preElement.controlId !== startElement.controlId ||
625
+ preElement.controlComponent === ControlComponent.PREFIX ||
626
+ preElement.controlComponent === ControlComponent.PRE_TEXT
627
+ ) {
628
+ range.startIndex = index
629
+ range.endIndex = index
630
+ break
631
+ }
632
+ index--
633
+ }
634
+ }
635
+ } else {
636
+ // 首、尾为占位符时,收缩到最后一个前缀字符后
637
+ if (
638
+ startElement.controlComponent === ControlComponent.PLACEHOLDER ||
639
+ endElement.controlComponent === ControlComponent.PLACEHOLDER
640
+ ) {
641
+ let index = endIndex - 1
642
+ while (index > 0) {
643
+ const preElement = elementList[index]
644
+ if (
645
+ preElement.controlId !== endElement.controlId ||
646
+ preElement.controlComponent === ControlComponent.PREFIX ||
647
+ preElement.controlComponent === ControlComponent.PRE_TEXT
648
+ ) {
649
+ range.startIndex = index
650
+ range.endIndex = index
651
+ return
652
+ }
653
+ index--
654
+ }
655
+ }
656
+ // 向右查找到第一个Value
657
+ if (startElement.controlComponent === ControlComponent.PREFIX) {
658
+ let index = startIndex + 1
659
+ while (index < elementList.length) {
660
+ const nextElement = elementList[index]
661
+ if (
662
+ nextElement.controlId !== startElement.controlId ||
663
+ nextElement.controlComponent === ControlComponent.VALUE
664
+ ) {
665
+ range.startIndex = index - 1
666
+ break
667
+ } else if (
668
+ nextElement.controlComponent === ControlComponent.PLACEHOLDER
669
+ ) {
670
+ range.startIndex = index - 1
671
+ range.endIndex = index - 1
672
+ return
673
+ }
674
+ index++
675
+ }
676
+ }
677
+ // 向左查找到第一个Value
678
+ if (endElement.controlComponent !== ControlComponent.VALUE) {
679
+ let index = startIndex - 1
680
+ while (index > 0) {
681
+ const preElement = elementList[index]
682
+ if (
683
+ preElement.controlId !== startElement.controlId ||
684
+ preElement.controlComponent === ControlComponent.VALUE
685
+ ) {
686
+ range.startIndex = index
687
+ break
688
+ } else if (
689
+ preElement.controlComponent === ControlComponent.PLACEHOLDER
690
+ ) {
691
+ range.startIndex = index
692
+ range.endIndex = index
693
+ return
694
+ }
695
+ index--
696
+ }
697
+ }
698
+ }
699
+ }
700
+
701
+ public render(
702
+ ctx: CanvasRenderingContext2D,
703
+ x: number,
704
+ y: number,
705
+ width: number,
706
+ height: number
707
+ ) {
708
+ ctx.save()
709
+ ctx.globalAlpha = this.options.rangeAlpha
710
+ ctx.fillStyle = this.options.rangeColor
711
+ ctx.fillRect(x, y, width, height)
712
+ ctx.restore()
713
+ }
714
+
715
+ public toString(): string {
716
+ const selection = this.getTextLikeSelection()
717
+ if (!selection) return ''
718
+ return selection
719
+ .map(s => s.value)
720
+ .join('')
721
+ .replace(new RegExp(ZERO, 'g'), '')
722
+ }
723
+ }