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,331 @@
1
+ import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu'
2
+ import { EditorMode } from '../../../dataset/enum/Editor'
3
+ import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
4
+ import {
5
+ TableBorder,
6
+ TdBorder,
7
+ TdSlash
8
+ } from '../../../dataset/enum/table/Table'
9
+ import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
10
+ import { Command } from '../../command/Command'
11
+ const {
12
+ TABLE: {
13
+ BORDER,
14
+ BORDER_ALL,
15
+ BORDER_EMPTY,
16
+ BORDER_DASH,
17
+ BORDER_EXTERNAL,
18
+ BORDER_INTERNAL,
19
+ BORDER_TD,
20
+ BORDER_TD_TOP,
21
+ BORDER_TD_LEFT,
22
+ BORDER_TD_BOTTOM,
23
+ BORDER_TD_RIGHT,
24
+ BORDER_TD_BACK,
25
+ BORDER_TD_FORWARD,
26
+ VERTICAL_ALIGN,
27
+ VERTICAL_ALIGN_TOP,
28
+ VERTICAL_ALIGN_MIDDLE,
29
+ VERTICAL_ALIGN_BOTTOM,
30
+ INSERT_ROW_COL,
31
+ INSERT_TOP_ROW,
32
+ INSERT_BOTTOM_ROW,
33
+ INSERT_LEFT_COL,
34
+ INSERT_RIGHT_COL,
35
+ DELETE_ROW_COL,
36
+ DELETE_ROW,
37
+ DELETE_COL,
38
+ DELETE_TABLE,
39
+ MERGE_CELL,
40
+ CANCEL_MERGE_CELL
41
+ }
42
+ } = INTERNAL_CONTEXT_MENU_KEY
43
+
44
+ export const tableMenus: IRegisterContextMenu[] = [
45
+ {
46
+ isDivider: true
47
+ },
48
+ {
49
+ key: BORDER,
50
+ i18nPath: 'contextmenu.table.border',
51
+ icon: 'border-all',
52
+ when: payload => {
53
+ return (
54
+ !payload.isReadonly &&
55
+ payload.isInTable &&
56
+ payload.options.mode !== EditorMode.FORM
57
+ )
58
+ },
59
+ childMenus: [
60
+ {
61
+ key: BORDER_ALL,
62
+ i18nPath: 'contextmenu.table.borderAll',
63
+ icon: 'border-all',
64
+ when: () => true,
65
+ callback: (command: Command) => {
66
+ command.executeTableBorderType(TableBorder.ALL)
67
+ }
68
+ },
69
+ {
70
+ key: BORDER_EMPTY,
71
+ i18nPath: 'contextmenu.table.borderEmpty',
72
+ icon: 'border-empty',
73
+ when: () => true,
74
+ callback: (command: Command) => {
75
+ command.executeTableBorderType(TableBorder.EMPTY)
76
+ }
77
+ },
78
+ {
79
+ key: BORDER_DASH,
80
+ i18nPath: 'contextmenu.table.borderDash',
81
+ icon: 'border-dash',
82
+ when: () => true,
83
+ callback: (command: Command) => {
84
+ command.executeTableBorderType(TableBorder.DASH)
85
+ }
86
+ },
87
+ {
88
+ key: BORDER_EXTERNAL,
89
+ i18nPath: 'contextmenu.table.borderExternal',
90
+ icon: 'border-external',
91
+ when: () => true,
92
+ callback: (command: Command) => {
93
+ command.executeTableBorderType(TableBorder.EXTERNAL)
94
+ }
95
+ },
96
+ {
97
+ key: BORDER_INTERNAL,
98
+ i18nPath: 'contextmenu.table.borderInternal',
99
+ icon: 'border-internal',
100
+ when: () => true,
101
+ callback: (command: Command) => {
102
+ command.executeTableBorderType(TableBorder.INTERNAL)
103
+ }
104
+ },
105
+ {
106
+ key: BORDER_TD,
107
+ i18nPath: 'contextmenu.table.borderTd',
108
+ icon: 'border-td',
109
+ when: () => true,
110
+ childMenus: [
111
+ {
112
+ key: BORDER_TD_TOP,
113
+ i18nPath: 'contextmenu.table.borderTdTop',
114
+ icon: 'border-td-top',
115
+ when: () => true,
116
+ callback: (command: Command) => {
117
+ command.executeTableTdBorderType(TdBorder.TOP)
118
+ }
119
+ },
120
+ {
121
+ key: BORDER_TD_RIGHT,
122
+ i18nPath: 'contextmenu.table.borderTdRight',
123
+ icon: 'border-td-right',
124
+ when: () => true,
125
+ callback: (command: Command) => {
126
+ command.executeTableTdBorderType(TdBorder.RIGHT)
127
+ }
128
+ },
129
+ {
130
+ key: BORDER_TD_BOTTOM,
131
+ i18nPath: 'contextmenu.table.borderTdBottom',
132
+ icon: 'border-td-bottom',
133
+ when: () => true,
134
+ callback: (command: Command) => {
135
+ command.executeTableTdBorderType(TdBorder.BOTTOM)
136
+ }
137
+ },
138
+ {
139
+ key: BORDER_TD_LEFT,
140
+ i18nPath: 'contextmenu.table.borderTdLeft',
141
+ icon: 'border-td-left',
142
+ when: () => true,
143
+ callback: (command: Command) => {
144
+ command.executeTableTdBorderType(TdBorder.LEFT)
145
+ }
146
+ },
147
+ {
148
+ key: BORDER_TD_FORWARD,
149
+ i18nPath: 'contextmenu.table.borderTdForward',
150
+ icon: 'border-td-forward',
151
+ when: () => true,
152
+ callback: (command: Command) => {
153
+ command.executeTableTdSlashType(TdSlash.FORWARD)
154
+ }
155
+ },
156
+ {
157
+ key: BORDER_TD_BACK,
158
+ i18nPath: 'contextmenu.table.borderTdBack',
159
+ icon: 'border-td-back',
160
+ when: () => true,
161
+ callback: (command: Command) => {
162
+ command.executeTableTdSlashType(TdSlash.BACK)
163
+ }
164
+ }
165
+ ]
166
+ }
167
+ ]
168
+ },
169
+ {
170
+ key: VERTICAL_ALIGN,
171
+ i18nPath: 'contextmenu.table.verticalAlign',
172
+ icon: 'vertical-align',
173
+ when: payload => {
174
+ return (
175
+ !payload.isReadonly &&
176
+ payload.isInTable &&
177
+ payload.options.mode !== EditorMode.FORM
178
+ )
179
+ },
180
+ childMenus: [
181
+ {
182
+ key: VERTICAL_ALIGN_TOP,
183
+ i18nPath: 'contextmenu.table.verticalAlignTop',
184
+ icon: 'vertical-align-top',
185
+ when: () => true,
186
+ callback: (command: Command) => {
187
+ command.executeTableTdVerticalAlign(VerticalAlign.TOP)
188
+ }
189
+ },
190
+ {
191
+ key: VERTICAL_ALIGN_MIDDLE,
192
+ i18nPath: 'contextmenu.table.verticalAlignMiddle',
193
+ icon: 'vertical-align-middle',
194
+ when: () => true,
195
+ callback: (command: Command) => {
196
+ command.executeTableTdVerticalAlign(VerticalAlign.MIDDLE)
197
+ }
198
+ },
199
+ {
200
+ key: VERTICAL_ALIGN_BOTTOM,
201
+ i18nPath: 'contextmenu.table.verticalAlignBottom',
202
+ icon: 'vertical-align-bottom',
203
+ when: () => true,
204
+ callback: (command: Command) => {
205
+ command.executeTableTdVerticalAlign(VerticalAlign.BOTTOM)
206
+ }
207
+ }
208
+ ]
209
+ },
210
+ {
211
+ key: INSERT_ROW_COL,
212
+ i18nPath: 'contextmenu.table.insertRowCol',
213
+ icon: 'insert-row-col',
214
+ when: payload => {
215
+ return (
216
+ !payload.isReadonly &&
217
+ payload.isInTable &&
218
+ payload.options.mode !== EditorMode.FORM
219
+ )
220
+ },
221
+ childMenus: [
222
+ {
223
+ key: INSERT_TOP_ROW,
224
+ i18nPath: 'contextmenu.table.insertTopRow',
225
+ icon: 'insert-top-row',
226
+ when: () => true,
227
+ callback: (command: Command) => {
228
+ command.executeInsertTableTopRow()
229
+ }
230
+ },
231
+ {
232
+ key: INSERT_BOTTOM_ROW,
233
+ i18nPath: 'contextmenu.table.insertBottomRow',
234
+ icon: 'insert-bottom-row',
235
+ when: () => true,
236
+ callback: (command: Command) => {
237
+ command.executeInsertTableBottomRow()
238
+ }
239
+ },
240
+ {
241
+ key: INSERT_LEFT_COL,
242
+ i18nPath: 'contextmenu.table.insertLeftCol',
243
+ icon: 'insert-left-col',
244
+ when: () => true,
245
+ callback: (command: Command) => {
246
+ command.executeInsertTableLeftCol()
247
+ }
248
+ },
249
+ {
250
+ key: INSERT_RIGHT_COL,
251
+ i18nPath: 'contextmenu.table.insertRightCol',
252
+ icon: 'insert-right-col',
253
+ when: () => true,
254
+ callback: (command: Command) => {
255
+ command.executeInsertTableRightCol()
256
+ }
257
+ }
258
+ ]
259
+ },
260
+ {
261
+ key: DELETE_ROW_COL,
262
+ i18nPath: 'contextmenu.table.deleteRowCol',
263
+ icon: 'delete-row-col',
264
+ when: payload => {
265
+ return (
266
+ !payload.isReadonly &&
267
+ payload.isInTable &&
268
+ payload.options.mode !== EditorMode.FORM
269
+ )
270
+ },
271
+ childMenus: [
272
+ {
273
+ key: DELETE_ROW,
274
+ i18nPath: 'contextmenu.table.deleteRow',
275
+ icon: 'delete-row',
276
+ when: () => true,
277
+ callback: (command: Command) => {
278
+ command.executeDeleteTableRow()
279
+ }
280
+ },
281
+ {
282
+ key: DELETE_COL,
283
+ i18nPath: 'contextmenu.table.deleteCol',
284
+ icon: 'delete-col',
285
+ when: () => true,
286
+ callback: (command: Command) => {
287
+ command.executeDeleteTableCol()
288
+ }
289
+ },
290
+ {
291
+ key: DELETE_TABLE,
292
+ i18nPath: 'contextmenu.table.deleteTable',
293
+ icon: 'delete-table',
294
+ when: () => true,
295
+ callback: (command: Command) => {
296
+ command.executeDeleteTable()
297
+ }
298
+ }
299
+ ]
300
+ },
301
+ {
302
+ key: MERGE_CELL,
303
+ i18nPath: 'contextmenu.table.mergeCell',
304
+ icon: 'merge-cell',
305
+ when: payload => {
306
+ return (
307
+ !payload.isReadonly &&
308
+ payload.isCrossRowCol &&
309
+ payload.options.mode !== EditorMode.FORM
310
+ )
311
+ },
312
+ callback: (command: Command) => {
313
+ command.executeMergeTableCell()
314
+ }
315
+ },
316
+ {
317
+ key: CANCEL_MERGE_CELL,
318
+ i18nPath: 'contextmenu.table.mergeCancelCell',
319
+ icon: 'merge-cancel-cell',
320
+ when: payload => {
321
+ return (
322
+ !payload.isReadonly &&
323
+ payload.isInTable &&
324
+ payload.options.mode !== EditorMode.FORM
325
+ )
326
+ },
327
+ callback: (command: Command) => {
328
+ command.executeCancelMergeTableCell()
329
+ }
330
+ }
331
+ ]
@@ -0,0 +1,248 @@
1
+ import { CURSOR_AGENT_OFFSET_HEIGHT } from '../../dataset/constant/Cursor'
2
+ import { EDITOR_PREFIX } from '../../dataset/constant/Editor'
3
+ import { MoveDirection } from '../../dataset/enum/Observer'
4
+ import { DeepRequired } from '../../interface/Common'
5
+ import { ICursorOption } from '../../interface/Cursor'
6
+ import { IEditorOption } from '../../interface/Editor'
7
+ import { IElementPosition } from '../../interface/Element'
8
+ import { findScrollContainer, nextTick } from '../../utils'
9
+ import { isMobile } from '../../utils/ua'
10
+ import { Draw } from '../draw/Draw'
11
+ import { CanvasEvent } from '../event/CanvasEvent'
12
+ import { Position } from '../position/Position'
13
+ import { CursorAgent } from './CursorAgent'
14
+
15
+ export type IDrawCursorOption = ICursorOption & {
16
+ isShow?: boolean
17
+ isBlink?: boolean
18
+ isFocus?: boolean
19
+ hitLineStartIndex?: number
20
+ }
21
+
22
+ export interface IMoveCursorToVisibleOption {
23
+ direction: MoveDirection
24
+ cursorPosition: IElementPosition
25
+ }
26
+
27
+ export class Cursor {
28
+ private readonly ANIMATION_CLASS = `${EDITOR_PREFIX}-cursor--animation`
29
+
30
+ private draw: Draw
31
+ private container: HTMLDivElement
32
+ private options: DeepRequired<IEditorOption>
33
+ private position: Position
34
+ private cursorDom: HTMLDivElement
35
+ private cursorAgent: CursorAgent
36
+ private blinkTimeout: number | null
37
+ private hitLineStartIndex: number | undefined
38
+
39
+ constructor(draw: Draw, canvasEvent: CanvasEvent) {
40
+ this.draw = draw
41
+ this.container = draw.getContainer()
42
+ this.position = draw.getPosition()
43
+ this.options = draw.getOptions()
44
+
45
+ this.cursorDom = document.createElement('div')
46
+ this.cursorDom.classList.add(`${EDITOR_PREFIX}-cursor`)
47
+ this.container.append(this.cursorDom)
48
+ this.cursorAgent = new CursorAgent(draw, canvasEvent)
49
+ this.blinkTimeout = null
50
+ }
51
+
52
+ public getCursorDom(): HTMLDivElement {
53
+ return this.cursorDom
54
+ }
55
+
56
+ public getAgentDom(): HTMLTextAreaElement {
57
+ return this.cursorAgent.getAgentCursorDom()
58
+ }
59
+
60
+ public getAgentIsActive(): boolean {
61
+ return this.getAgentDom() === document.activeElement
62
+ }
63
+
64
+ public getAgentDomValue(): string {
65
+ return this.getAgentDom().value
66
+ }
67
+
68
+ public clearAgentDomValue() {
69
+ this.getAgentDom().value = ''
70
+ }
71
+
72
+ public getHitLineStartIndex() {
73
+ return this.hitLineStartIndex
74
+ }
75
+
76
+ private _blinkStart() {
77
+ this.cursorDom.classList.add(this.ANIMATION_CLASS)
78
+ }
79
+
80
+ private _blinkStop() {
81
+ this.cursorDom.classList.remove(this.ANIMATION_CLASS)
82
+ }
83
+
84
+ private _setBlinkTimeout() {
85
+ this._clearBlinkTimeout()
86
+ this.blinkTimeout = window.setTimeout(() => {
87
+ this._blinkStart()
88
+ }, 500)
89
+ }
90
+
91
+ private _clearBlinkTimeout() {
92
+ if (this.blinkTimeout) {
93
+ this._blinkStop()
94
+ window.clearTimeout(this.blinkTimeout)
95
+ this.blinkTimeout = null
96
+ }
97
+ }
98
+
99
+ public focus() {
100
+ // 移动端只读模式禁用聚焦避免唤起输入法,web端允许聚焦避免事件无法捕获
101
+ if (isMobile && this.draw.isReadonly()) return
102
+ const agentCursorDom = this.cursorAgent.getAgentCursorDom()
103
+ // 光标不聚焦时重新定位
104
+ if (document.activeElement !== agentCursorDom) {
105
+ agentCursorDom.focus()
106
+ agentCursorDom.setSelectionRange(0, 0)
107
+ }
108
+ }
109
+
110
+ public drawCursor(payload?: IDrawCursorOption) {
111
+ let cursorPosition = this.position.getCursorPosition()
112
+ if (!cursorPosition) return
113
+ const { scale, cursor } = this.options
114
+ const {
115
+ color,
116
+ width,
117
+ isShow = true,
118
+ isBlink = true,
119
+ isFocus = true,
120
+ hitLineStartIndex
121
+ } = { ...cursor, ...payload }
122
+ // 设置光标代理
123
+ const height = this.draw.getHeight()
124
+ const pageGap = this.draw.getPageGap()
125
+ // 光标位置
126
+ this.hitLineStartIndex = hitLineStartIndex
127
+ if (hitLineStartIndex) {
128
+ const positionList = this.position.getPositionList()
129
+ cursorPosition = positionList[hitLineStartIndex]
130
+ }
131
+ const {
132
+ metrics,
133
+ coordinate: { leftTop, rightTop },
134
+ ascent,
135
+ pageNo
136
+ } = cursorPosition
137
+ const zoneManager = this.draw.getZone()
138
+ const curPageNo = zoneManager.isMainActive()
139
+ ? pageNo
140
+ : this.draw.getPageNo()
141
+ const preY = curPageNo * (height + pageGap)
142
+ // 默认偏移高度
143
+ const defaultOffsetHeight = CURSOR_AGENT_OFFSET_HEIGHT * scale
144
+ // 增加1/4字体大小(最小为defaultOffsetHeight即默认偏移高度)
145
+ const increaseHeight = Math.min(metrics.height / 4, defaultOffsetHeight)
146
+ const cursorHeight = metrics.height + increaseHeight * 2
147
+ const agentCursorDom = this.cursorAgent.getAgentCursorDom()
148
+ if (isFocus) {
149
+ setTimeout(() => {
150
+ this.focus()
151
+ })
152
+ }
153
+ // fillText位置 + 文字基线到底部距离 - 模拟光标偏移量
154
+ const descent =
155
+ metrics.boundingBoxDescent < 0 ? 0 : metrics.boundingBoxDescent
156
+ const cursorTop =
157
+ leftTop[1] + ascent + descent - (cursorHeight - increaseHeight) + preY
158
+ const cursorLeft = hitLineStartIndex ? leftTop[0] : rightTop[0]
159
+ agentCursorDom.style.left = `${cursorLeft}px`
160
+ agentCursorDom.style.top = `${
161
+ cursorTop + cursorHeight - defaultOffsetHeight
162
+ }px`
163
+ // 模拟光标显示
164
+ if (!isShow) {
165
+ this.recoveryCursor()
166
+ return
167
+ }
168
+ // 记录旧光标位置:用于光标移动到可视范围内
169
+ const oldTop = this.cursorDom.style.top
170
+ // 设置光标位置
171
+ const isReadonly = this.draw.isReadonly()
172
+ this.cursorDom.style.width = `${width * scale}px`
173
+ this.cursorDom.style.backgroundColor = color
174
+ this.cursorDom.style.left = `${cursorLeft}px`
175
+ this.cursorDom.style.top = `${cursorTop}px`
176
+ this.cursorDom.style.display = isReadonly ? 'none' : 'block'
177
+ this.cursorDom.style.height = `${cursorHeight}px`
178
+ if (isBlink) {
179
+ this._setBlinkTimeout()
180
+ } else {
181
+ this._clearBlinkTimeout()
182
+ }
183
+ // 移动到视野范围内
184
+ nextTick(() => {
185
+ // nexttick后执行 => 避免画布没有渲染完成造成残影
186
+ this.moveCursorToVisible({
187
+ cursorPosition: cursorPosition!,
188
+ direction:
189
+ parseInt(oldTop) > cursorTop ? MoveDirection.UP : MoveDirection.DOWN
190
+ })
191
+ })
192
+ }
193
+
194
+ public recoveryCursor() {
195
+ this.cursorDom.style.display = 'none'
196
+ this._clearBlinkTimeout()
197
+ }
198
+
199
+ public moveCursorToVisible(payload: IMoveCursorToVisibleOption) {
200
+ const { cursorPosition, direction } = payload
201
+ if (!cursorPosition || !direction) return
202
+ const {
203
+ pageNo,
204
+ coordinate: { leftTop, leftBottom }
205
+ } = cursorPosition
206
+ // 查找滚动容器,如果是滚动容器是document,则限制范围为当前窗口
207
+ const scrollContainer = findScrollContainer(this.container)
208
+ const rect = {
209
+ left: 0,
210
+ right: 0,
211
+ top: 0,
212
+ bottom: 0
213
+ }
214
+ const isDocumentScroll = scrollContainer === document.documentElement
215
+ if (isDocumentScroll) {
216
+ rect.right = window.innerWidth
217
+ rect.bottom = window.innerHeight
218
+ } else {
219
+ const { left, right, top, bottom } =
220
+ scrollContainer.getBoundingClientRect()
221
+ rect.left = left
222
+ rect.right = right
223
+ rect.top = top
224
+ rect.bottom = bottom
225
+ }
226
+ // 当前页面距离滚动容器顶部距离
227
+ const prePageY =
228
+ pageNo * (this.draw.getHeight() + this.draw.getPageGap()) +
229
+ this.container.getBoundingClientRect().top
230
+ // 向上移动时:以顶部距离为准,向下移动时:以底部位置为准
231
+ const isUp = direction === MoveDirection.UP
232
+ const x = leftBottom[0] + (isDocumentScroll ? 0 : rect.left)
233
+ const y = isUp ? leftTop[1] + prePageY : leftBottom[1] + prePageY
234
+ // 可视范围根据参数调整
235
+ const { maskMargin } = this.options
236
+ rect.top += maskMargin[0]
237
+ rect.bottom -= maskMargin[2]
238
+ // 不在可视范围时,移动滚动条到合适位置
239
+ if (
240
+ !(x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom)
241
+ ) {
242
+ const { scrollLeft, scrollTop } = scrollContainer
243
+ isUp
244
+ ? scrollContainer.scroll(scrollLeft, scrollTop - (rect.top - y))
245
+ : scrollContainer.scroll(scrollLeft, scrollTop + y - rect.bottom)
246
+ }
247
+ }
248
+ }
@@ -0,0 +1,75 @@
1
+ import { EDITOR_PREFIX } from '../../dataset/constant/Editor'
2
+ import { EventBusMap } from '../../interface/EventBus'
3
+ import { Draw } from '../draw/Draw'
4
+ import { CanvasEvent } from '../event/CanvasEvent'
5
+ import { EventBus } from '../event/eventbus/EventBus'
6
+ import { pasteByEvent } from '../event/handlers/paste'
7
+
8
+ export class CursorAgent {
9
+ private draw: Draw
10
+ private container: HTMLDivElement
11
+ private agentCursorDom: HTMLTextAreaElement
12
+ private canvasEvent: CanvasEvent
13
+ private eventBus: EventBus<EventBusMap>
14
+
15
+ constructor(draw: Draw, canvasEvent: CanvasEvent) {
16
+ this.draw = draw
17
+ this.container = draw.getContainer()
18
+ this.canvasEvent = canvasEvent
19
+ this.eventBus = draw.getEventBus()
20
+ // 代理光标绘制
21
+ const agentCursorDom = document.createElement('textarea')
22
+ agentCursorDom.autocomplete = 'off'
23
+ agentCursorDom.classList.add(`${EDITOR_PREFIX}-inputarea`)
24
+ agentCursorDom.innerText = ''
25
+ this.container.append(agentCursorDom)
26
+ this.agentCursorDom = agentCursorDom
27
+ // 事件
28
+ agentCursorDom.onkeydown = (evt: KeyboardEvent) => this._keyDown(evt)
29
+ agentCursorDom.oninput = this._input.bind(this)
30
+ agentCursorDom.onpaste = (evt: ClipboardEvent) => this._paste(evt)
31
+ agentCursorDom.addEventListener(
32
+ 'compositionstart',
33
+ this._compositionstart.bind(this)
34
+ )
35
+ agentCursorDom.addEventListener(
36
+ 'compositionend',
37
+ this._compositionend.bind(this)
38
+ )
39
+ }
40
+
41
+ public getAgentCursorDom(): HTMLTextAreaElement {
42
+ return this.agentCursorDom
43
+ }
44
+
45
+ private _keyDown(evt: KeyboardEvent) {
46
+ this.canvasEvent.keydown(evt)
47
+ }
48
+
49
+ private _input(evt: Event) {
50
+ const data = (<InputEvent>evt).data
51
+ if (data) {
52
+ this.canvasEvent.input(data)
53
+ }
54
+ if (this.eventBus.isSubscribe('input')) {
55
+ this.eventBus.emit('input', evt)
56
+ }
57
+ }
58
+
59
+ private _paste(evt: ClipboardEvent) {
60
+ const isReadonly = this.draw.isReadonly()
61
+ if (isReadonly) return
62
+ const clipboardData = evt.clipboardData
63
+ if (!clipboardData) return
64
+ pasteByEvent(this.canvasEvent, evt)
65
+ evt.preventDefault()
66
+ }
67
+
68
+ private _compositionstart() {
69
+ this.canvasEvent.compositionstart()
70
+ }
71
+
72
+ private _compositionend(evt: CompositionEvent) {
73
+ this.canvasEvent.compositionend(evt)
74
+ }
75
+ }