suneditor 3.0.0-beta.9 → 3.0.0-rc.2

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 (380) hide show
  1. package/README.md +65 -57
  2. package/dist/suneditor-contents.min.css +1 -0
  3. package/dist/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +1 -1
  5. package/package.json +110 -61
  6. package/src/assets/design/color.css +36 -17
  7. package/src/assets/design/size.css +2 -0
  8. package/src/assets/icons/defaultIcons.js +17 -2
  9. package/src/assets/suneditor-contents.css +51 -16
  10. package/src/assets/suneditor.css +116 -43
  11. package/src/core/config/contextProvider.js +288 -0
  12. package/src/core/config/eventManager.js +188 -0
  13. package/src/core/config/instanceCheck.js +59 -0
  14. package/src/core/config/optionProvider.js +452 -0
  15. package/src/core/editor.js +166 -1637
  16. package/src/core/event/actions/index.js +229 -0
  17. package/src/core/event/effects/common.registry.js +74 -0
  18. package/src/core/event/effects/keydown.registry.js +573 -0
  19. package/src/core/event/effects/ruleHelpers.js +148 -0
  20. package/src/core/event/eventOrchestrator.js +944 -0
  21. package/src/core/event/executor.js +27 -0
  22. package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +27 -28
  23. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +10 -8
  24. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +22 -23
  25. package/src/core/event/handlers/handler_ww_input.js +75 -0
  26. package/src/core/event/handlers/handler_ww_key.js +228 -0
  27. package/src/core/event/handlers/handler_ww_mouse.js +166 -0
  28. package/src/core/event/ports.js +211 -0
  29. package/src/core/event/reducers/keydown.reducer.js +97 -0
  30. package/src/core/event/rules/keydown.rule.arrow.js +63 -0
  31. package/src/core/event/rules/keydown.rule.backspace.js +208 -0
  32. package/src/core/event/rules/keydown.rule.delete.js +132 -0
  33. package/src/core/event/rules/keydown.rule.enter.js +150 -0
  34. package/src/core/event/rules/keydown.rule.tab.js +35 -0
  35. package/src/core/event/support/defaultLineManager.js +136 -0
  36. package/src/core/event/support/selectionState.js +204 -0
  37. package/src/core/kernel/coreKernel.js +320 -0
  38. package/src/core/kernel/kernelInjector.js +19 -0
  39. package/src/core/kernel/store.js +173 -0
  40. package/src/core/{class → logic/dom}/char.js +42 -45
  41. package/src/core/logic/dom/format.js +1075 -0
  42. package/src/core/{class → logic/dom}/html.js +743 -624
  43. package/src/core/logic/dom/inline.js +1847 -0
  44. package/src/core/logic/dom/listFormat.js +601 -0
  45. package/src/core/{class → logic/dom}/nodeTransform.js +92 -72
  46. package/src/core/{class → logic/dom}/offset.js +254 -317
  47. package/src/core/logic/dom/selection.js +754 -0
  48. package/src/core/logic/panel/menu.js +389 -0
  49. package/src/core/logic/panel/toolbar.js +449 -0
  50. package/src/core/logic/panel/viewer.js +761 -0
  51. package/src/core/logic/shell/_commandExecutor.js +380 -0
  52. package/src/core/logic/shell/commandDispatcher.js +241 -0
  53. package/src/core/logic/shell/component.js +970 -0
  54. package/src/core/logic/shell/focusManager.js +110 -0
  55. package/src/core/{base → logic/shell}/history.js +110 -60
  56. package/src/core/logic/shell/pluginManager.js +363 -0
  57. package/src/core/logic/shell/shortcuts.js +130 -0
  58. package/src/core/logic/shell/ui.js +904 -0
  59. package/src/core/schema/context.js +66 -0
  60. package/src/core/schema/frameContext.js +160 -0
  61. package/src/core/schema/options.js +628 -0
  62. package/src/core/section/constructor.js +194 -500
  63. package/src/core/section/documentType.js +297 -222
  64. package/src/events.js +808 -543
  65. package/src/helper/clipboard.js +27 -16
  66. package/src/helper/converter.js +100 -78
  67. package/src/helper/dom/domCheck.js +56 -30
  68. package/src/helper/dom/domQuery.js +159 -89
  69. package/src/helper/dom/domUtils.js +114 -49
  70. package/src/helper/dom/index.js +5 -1
  71. package/src/helper/env.js +26 -26
  72. package/src/helper/index.js +1 -1
  73. package/src/helper/keyCodeMap.js +25 -28
  74. package/src/helper/numbers.js +4 -8
  75. package/src/helper/unicode.js +4 -8
  76. package/src/hooks/base.js +307 -0
  77. package/src/hooks/params.js +130 -0
  78. package/src/interfaces/contracts.js +227 -0
  79. package/src/interfaces/index.js +7 -0
  80. package/src/interfaces/plugins.js +239 -0
  81. package/src/langs/ckb.js +4 -4
  82. package/src/langs/cs.js +4 -4
  83. package/src/langs/da.js +4 -4
  84. package/src/langs/de.js +4 -4
  85. package/src/langs/en.js +4 -4
  86. package/src/langs/es.js +4 -4
  87. package/src/langs/fa.js +4 -4
  88. package/src/langs/fr.js +4 -4
  89. package/src/langs/he.js +4 -4
  90. package/src/langs/hu.js +4 -4
  91. package/src/langs/it.js +4 -4
  92. package/src/langs/ja.js +4 -4
  93. package/src/langs/km.js +4 -4
  94. package/src/langs/ko.js +4 -4
  95. package/src/langs/lv.js +4 -4
  96. package/src/langs/nl.js +4 -4
  97. package/src/langs/pl.js +4 -4
  98. package/src/langs/pt_br.js +13 -13
  99. package/src/langs/ro.js +4 -4
  100. package/src/langs/ru.js +4 -4
  101. package/src/langs/se.js +4 -4
  102. package/src/langs/tr.js +4 -4
  103. package/src/langs/uk.js +4 -4
  104. package/src/langs/ur.js +4 -4
  105. package/src/langs/zh_cn.js +4 -4
  106. package/src/modules/{Browser.js → contract/Browser.js} +119 -128
  107. package/src/modules/{ColorPicker.js → contract/ColorPicker.js} +132 -142
  108. package/src/modules/contract/Controller.js +589 -0
  109. package/src/modules/{Figure.js → contract/Figure.js} +591 -411
  110. package/src/modules/{HueSlider.js → contract/HueSlider.js} +125 -86
  111. package/src/modules/contract/Modal.js +357 -0
  112. package/src/modules/contract/index.js +9 -0
  113. package/src/modules/manager/ApiManager.js +197 -0
  114. package/src/modules/{FileManager.js → manager/FileManager.js} +128 -160
  115. package/src/modules/manager/index.js +5 -0
  116. package/src/modules/{ModalAnchorEditor.js → ui/ModalAnchorEditor.js} +108 -138
  117. package/src/modules/{SelectMenu.js → ui/SelectMenu.js} +119 -120
  118. package/src/modules/{_DragHandle.js → ui/_DragHandle.js} +1 -1
  119. package/src/modules/ui/index.js +6 -0
  120. package/src/plugins/browser/audioGallery.js +23 -26
  121. package/src/plugins/browser/fileBrowser.js +25 -28
  122. package/src/plugins/browser/fileGallery.js +20 -23
  123. package/src/plugins/browser/imageGallery.js +24 -23
  124. package/src/plugins/browser/videoGallery.js +27 -29
  125. package/src/plugins/command/blockquote.js +11 -17
  126. package/src/plugins/command/exportPDF.js +26 -26
  127. package/src/plugins/command/fileUpload.js +138 -133
  128. package/src/plugins/command/list_bulleted.js +48 -44
  129. package/src/plugins/command/list_numbered.js +48 -44
  130. package/src/plugins/dropdown/align.js +64 -50
  131. package/src/plugins/dropdown/backgroundColor.js +34 -35
  132. package/src/plugins/dropdown/{formatBlock.js → blockStyle.js} +43 -37
  133. package/src/plugins/dropdown/font.js +50 -36
  134. package/src/plugins/dropdown/fontColor.js +34 -35
  135. package/src/plugins/dropdown/hr.js +55 -50
  136. package/src/plugins/dropdown/layout.js +20 -15
  137. package/src/plugins/dropdown/lineHeight.js +46 -30
  138. package/src/plugins/dropdown/list.js +32 -33
  139. package/src/plugins/dropdown/paragraphStyle.js +40 -34
  140. package/src/plugins/dropdown/table/index.js +915 -0
  141. package/src/plugins/dropdown/table/render/table.html.js +308 -0
  142. package/src/plugins/dropdown/table/render/table.menu.js +121 -0
  143. package/src/plugins/dropdown/table/services/table.cell.js +465 -0
  144. package/src/plugins/dropdown/table/services/table.clipboard.js +414 -0
  145. package/src/plugins/dropdown/table/services/table.grid.js +504 -0
  146. package/src/plugins/dropdown/table/services/table.resize.js +463 -0
  147. package/src/plugins/dropdown/table/services/table.selection.js +466 -0
  148. package/src/plugins/dropdown/table/services/table.style.js +844 -0
  149. package/src/plugins/dropdown/table/shared/table.constants.js +109 -0
  150. package/src/plugins/dropdown/table/shared/table.utils.js +219 -0
  151. package/src/plugins/dropdown/template.js +20 -15
  152. package/src/plugins/dropdown/textStyle.js +28 -22
  153. package/src/plugins/field/mention.js +54 -49
  154. package/src/plugins/index.js +5 -5
  155. package/src/plugins/input/fontSize.js +100 -97
  156. package/src/plugins/input/pageNavigator.js +13 -10
  157. package/src/plugins/modal/audio.js +208 -219
  158. package/src/plugins/modal/drawing.js +99 -104
  159. package/src/plugins/modal/embed.js +323 -312
  160. package/src/plugins/modal/image/index.js +942 -0
  161. package/src/plugins/modal/image/render/image.html.js +150 -0
  162. package/src/plugins/modal/image/services/image.size.js +198 -0
  163. package/src/plugins/modal/image/services/image.upload.js +216 -0
  164. package/src/plugins/modal/image/shared/image.constants.js +20 -0
  165. package/src/plugins/modal/link.js +74 -54
  166. package/src/plugins/modal/math.js +126 -119
  167. package/src/plugins/modal/video/index.js +858 -0
  168. package/src/plugins/modal/video/render/video.html.js +131 -0
  169. package/src/plugins/modal/video/services/video.size.js +281 -0
  170. package/src/plugins/modal/video/services/video.upload.js +92 -0
  171. package/src/plugins/popup/anchor.js +57 -49
  172. package/src/suneditor.js +73 -61
  173. package/src/themes/cobalt.css +155 -0
  174. package/src/themes/dark.css +143 -120
  175. package/src/typedef.js +214 -63
  176. package/types/assets/icons/defaultIcons.d.ts +8 -0
  177. package/types/assets/suneditor-contents.css.d.ts +1 -0
  178. package/types/assets/suneditor.css.d.ts +1 -0
  179. package/types/core/config/contextProvider.d.ts +148 -0
  180. package/types/core/config/eventManager.d.ts +68 -0
  181. package/types/core/config/instanceCheck.d.ts +33 -0
  182. package/types/core/config/optionProvider.d.ts +147 -0
  183. package/types/core/editor.d.ts +27 -586
  184. package/types/core/event/actions/index.d.ts +50 -0
  185. package/types/core/event/effects/common.registry.d.ts +56 -0
  186. package/types/core/event/effects/keydown.registry.d.ts +80 -0
  187. package/types/core/event/effects/ruleHelpers.d.ts +36 -0
  188. package/types/core/event/eventOrchestrator.d.ts +191 -0
  189. package/types/core/event/executor.d.ts +13 -0
  190. package/types/core/event/handlers/handler_toolbar.d.ts +38 -0
  191. package/types/core/event/handlers/handler_ww_clipboard.d.ts +36 -0
  192. package/types/core/event/handlers/handler_ww_dragDrop.d.ts +26 -0
  193. package/types/core/event/handlers/handler_ww_input.d.ts +38 -0
  194. package/types/core/event/handlers/handler_ww_key.d.ts +40 -0
  195. package/types/core/event/handlers/handler_ww_mouse.d.ts +47 -0
  196. package/types/core/event/ports.d.ts +256 -0
  197. package/types/core/event/reducers/keydown.reducer.d.ts +84 -0
  198. package/types/core/event/rules/keydown.rule.arrow.d.ts +19 -0
  199. package/types/core/event/rules/keydown.rule.backspace.d.ts +18 -0
  200. package/types/core/event/rules/keydown.rule.delete.d.ts +18 -0
  201. package/types/core/event/rules/keydown.rule.enter.d.ts +18 -0
  202. package/types/core/event/rules/keydown.rule.tab.d.ts +18 -0
  203. package/types/core/event/support/defaultLineManager.d.ts +22 -0
  204. package/types/core/event/support/selectionState.d.ts +29 -0
  205. package/types/core/kernel/coreKernel.d.ts +219 -0
  206. package/types/core/kernel/kernelInjector.d.ts +16 -0
  207. package/types/core/kernel/store.d.ts +170 -0
  208. package/types/core/logic/dom/char.d.ts +46 -0
  209. package/types/core/logic/dom/format.d.ts +234 -0
  210. package/types/core/logic/dom/html.d.ts +290 -0
  211. package/types/core/logic/dom/inline.d.ts +93 -0
  212. package/types/core/logic/dom/listFormat.d.ts +101 -0
  213. package/types/core/logic/dom/nodeTransform.d.ts +110 -0
  214. package/types/core/logic/dom/offset.d.ts +335 -0
  215. package/types/core/logic/dom/selection.d.ts +165 -0
  216. package/types/core/logic/panel/menu.d.ts +93 -0
  217. package/types/core/logic/panel/toolbar.d.ts +128 -0
  218. package/types/core/logic/panel/viewer.d.ts +89 -0
  219. package/types/core/logic/shell/_commandExecutor.d.ts +18 -0
  220. package/types/core/logic/shell/commandDispatcher.d.ts +65 -0
  221. package/types/core/logic/shell/component.d.ts +182 -0
  222. package/types/core/logic/shell/focusManager.d.ts +31 -0
  223. package/types/core/{base → logic/shell}/history.d.ts +13 -12
  224. package/types/core/logic/shell/pluginManager.d.ts +115 -0
  225. package/types/core/logic/shell/shortcuts.d.ts +131 -0
  226. package/types/core/logic/shell/ui.d.ts +261 -0
  227. package/types/core/schema/context.d.ts +104 -0
  228. package/types/core/schema/frameContext.d.ts +320 -0
  229. package/types/core/schema/options.d.ts +1241 -0
  230. package/types/core/section/constructor.d.ts +117 -652
  231. package/types/core/section/documentType.d.ts +43 -61
  232. package/types/events.d.ts +796 -65
  233. package/types/helper/clipboard.d.ts +5 -4
  234. package/types/helper/converter.d.ts +55 -43
  235. package/types/helper/dom/domCheck.d.ts +27 -19
  236. package/types/helper/dom/domQuery.d.ts +76 -57
  237. package/types/helper/dom/domUtils.d.ts +62 -39
  238. package/types/helper/dom/index.d.ts +87 -1
  239. package/types/helper/env.d.ts +16 -13
  240. package/types/helper/index.d.ts +8 -2
  241. package/types/helper/keyCodeMap.d.ts +24 -23
  242. package/types/helper/numbers.d.ts +4 -6
  243. package/types/helper/unicode.d.ts +4 -3
  244. package/types/hooks/base.d.ts +239 -0
  245. package/types/hooks/params.d.ts +65 -0
  246. package/types/index.d.ts +20 -117
  247. package/types/interfaces/contracts.d.ts +183 -0
  248. package/types/interfaces/index.d.ts +3 -0
  249. package/types/interfaces/plugins.d.ts +168 -0
  250. package/types/langs/_Lang.d.ts +2 -2
  251. package/types/langs/index.d.ts +2 -2
  252. package/types/modules/contract/Browser.d.ts +262 -0
  253. package/types/modules/contract/ColorPicker.d.ts +99 -0
  254. package/types/modules/contract/Controller.d.ts +204 -0
  255. package/types/modules/contract/Figure.d.ts +529 -0
  256. package/types/modules/{HueSlider.d.ts → contract/HueSlider.d.ts} +39 -28
  257. package/types/modules/contract/Modal.d.ts +62 -0
  258. package/types/modules/contract/index.d.ts +7 -0
  259. package/types/modules/manager/ApiManager.d.ts +106 -0
  260. package/types/modules/manager/FileManager.d.ts +124 -0
  261. package/types/modules/manager/index.d.ts +3 -0
  262. package/types/modules/ui/ModalAnchorEditor.d.ts +152 -0
  263. package/types/modules/ui/SelectMenu.d.ts +107 -0
  264. package/types/modules/{_DragHandle.d.ts → ui/_DragHandle.d.ts} +1 -0
  265. package/types/modules/ui/index.d.ts +4 -0
  266. package/types/plugins/browser/audioGallery.d.ts +33 -41
  267. package/types/plugins/browser/fileBrowser.d.ts +42 -50
  268. package/types/plugins/browser/fileGallery.d.ts +33 -41
  269. package/types/plugins/browser/imageGallery.d.ts +30 -37
  270. package/types/plugins/browser/videoGallery.d.ts +33 -41
  271. package/types/plugins/command/blockquote.d.ts +4 -21
  272. package/types/plugins/command/exportPDF.d.ts +23 -33
  273. package/types/plugins/command/fileUpload.d.ts +80 -100
  274. package/types/plugins/command/list_bulleted.d.ts +9 -35
  275. package/types/plugins/command/list_numbered.d.ts +9 -35
  276. package/types/plugins/dropdown/align.d.ts +23 -46
  277. package/types/plugins/dropdown/backgroundColor.d.ts +35 -53
  278. package/types/plugins/dropdown/blockStyle.d.ts +45 -0
  279. package/types/plugins/dropdown/font.d.ts +18 -41
  280. package/types/plugins/dropdown/fontColor.d.ts +35 -53
  281. package/types/plugins/dropdown/hr.d.ts +26 -52
  282. package/types/plugins/dropdown/layout.d.ts +19 -25
  283. package/types/plugins/dropdown/lineHeight.d.ts +21 -39
  284. package/types/plugins/dropdown/list.d.ts +6 -34
  285. package/types/plugins/dropdown/paragraphStyle.d.ts +34 -45
  286. package/types/plugins/dropdown/table/index.d.ts +158 -0
  287. package/types/plugins/dropdown/table/render/table.html.d.ts +71 -0
  288. package/types/plugins/dropdown/table/render/table.menu.d.ts +59 -0
  289. package/types/plugins/dropdown/table/services/table.cell.d.ts +76 -0
  290. package/types/plugins/dropdown/table/services/table.clipboard.d.ts +26 -0
  291. package/types/plugins/dropdown/table/services/table.grid.d.ts +77 -0
  292. package/types/plugins/dropdown/table/services/table.resize.d.ts +72 -0
  293. package/types/plugins/dropdown/table/services/table.selection.d.ts +59 -0
  294. package/types/plugins/dropdown/table/services/table.style.d.ts +162 -0
  295. package/types/plugins/dropdown/table/shared/table.constants.d.ts +134 -0
  296. package/types/plugins/dropdown/table/shared/table.utils.d.ts +91 -0
  297. package/types/plugins/dropdown/template.d.ts +19 -25
  298. package/types/plugins/dropdown/textStyle.d.ts +23 -30
  299. package/types/plugins/field/mention.d.ts +66 -72
  300. package/types/plugins/index.d.ts +41 -40
  301. package/types/plugins/input/fontSize.d.ts +57 -96
  302. package/types/plugins/input/pageNavigator.d.ts +5 -8
  303. package/types/plugins/modal/audio.d.ts +60 -153
  304. package/types/plugins/modal/drawing.d.ts +16 -118
  305. package/types/plugins/modal/embed.d.ts +46 -166
  306. package/types/plugins/modal/image/index.d.ts +281 -0
  307. package/types/plugins/modal/image/render/image.html.d.ts +45 -0
  308. package/types/plugins/modal/image/services/image.size.d.ts +55 -0
  309. package/types/plugins/modal/image/services/image.upload.d.ts +24 -0
  310. package/types/plugins/modal/image/shared/image.constants.d.ts +17 -0
  311. package/types/plugins/modal/link.d.ts +46 -66
  312. package/types/plugins/modal/math.d.ts +17 -86
  313. package/types/plugins/modal/{video.d.ts → video/index.d.ts} +89 -221
  314. package/types/plugins/modal/video/render/video.html.d.ts +37 -0
  315. package/types/plugins/modal/video/services/video.size.d.ts +74 -0
  316. package/types/plugins/modal/video/services/video.upload.d.ts +19 -0
  317. package/types/plugins/popup/anchor.d.ts +8 -38
  318. package/types/suneditor.d.ts +55 -24
  319. package/types/typedef.d.ts +344 -228
  320. package/CONTRIBUTING.md +0 -186
  321. package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
  322. package/src/core/base/eventHandlers/handler_ww_mouse.js +0 -194
  323. package/src/core/base/eventManager.js +0 -1523
  324. package/src/core/class/component.js +0 -856
  325. package/src/core/class/format.js +0 -3433
  326. package/src/core/class/menu.js +0 -346
  327. package/src/core/class/selection.js +0 -610
  328. package/src/core/class/shortcuts.js +0 -98
  329. package/src/core/class/toolbar.js +0 -431
  330. package/src/core/class/ui.js +0 -424
  331. package/src/core/class/viewer.js +0 -750
  332. package/src/core/section/actives.js +0 -266
  333. package/src/core/section/context.js +0 -102
  334. package/src/editorInjector/_classes.js +0 -36
  335. package/src/editorInjector/_core.js +0 -87
  336. package/src/editorInjector/index.js +0 -73
  337. package/src/modules/ApiManager.js +0 -191
  338. package/src/modules/Controller.js +0 -474
  339. package/src/modules/Modal.js +0 -346
  340. package/src/modules/index.js +0 -14
  341. package/src/plugins/dropdown/table.js +0 -4034
  342. package/src/plugins/modal/image.js +0 -1376
  343. package/src/plugins/modal/video.js +0 -1226
  344. package/types/core/base/eventHandlers/handler_toolbar.d.ts +0 -41
  345. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +0 -40
  346. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +0 -35
  347. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +0 -45
  348. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +0 -39
  349. package/types/core/base/eventManager.d.ts +0 -401
  350. package/types/core/class/char.d.ts +0 -61
  351. package/types/core/class/component.d.ts +0 -213
  352. package/types/core/class/format.d.ts +0 -623
  353. package/types/core/class/html.d.ts +0 -430
  354. package/types/core/class/menu.d.ts +0 -126
  355. package/types/core/class/nodeTransform.d.ts +0 -93
  356. package/types/core/class/offset.d.ts +0 -522
  357. package/types/core/class/selection.d.ts +0 -188
  358. package/types/core/class/shortcuts.d.ts +0 -142
  359. package/types/core/class/toolbar.d.ts +0 -189
  360. package/types/core/class/ui.d.ts +0 -164
  361. package/types/core/class/viewer.d.ts +0 -140
  362. package/types/core/section/actives.d.ts +0 -46
  363. package/types/core/section/context.d.ts +0 -45
  364. package/types/editorInjector/_classes.d.ts +0 -41
  365. package/types/editorInjector/_core.d.ts +0 -87
  366. package/types/editorInjector/index.d.ts +0 -69
  367. package/types/modules/ApiManager.d.ts +0 -125
  368. package/types/modules/Browser.d.ts +0 -326
  369. package/types/modules/ColorPicker.d.ts +0 -135
  370. package/types/modules/Controller.d.ts +0 -251
  371. package/types/modules/Figure.d.ts +0 -517
  372. package/types/modules/FileManager.d.ts +0 -202
  373. package/types/modules/Modal.d.ts +0 -111
  374. package/types/modules/ModalAnchorEditor.d.ts +0 -236
  375. package/types/modules/SelectMenu.d.ts +0 -194
  376. package/types/modules/index.d.ts +0 -26
  377. package/types/plugins/dropdown/formatBlock.d.ts +0 -55
  378. package/types/plugins/dropdown/table.d.ts +0 -627
  379. package/types/plugins/modal/image.d.ts +0 -451
  380. /package/{LICENSE → LICENSE.txt} +0 -0
@@ -0,0 +1,915 @@
1
+ import { PluginDropdownFree } from '../../../interfaces';
2
+ import { dom, numbers, env, keyCodeMap } from '../../../helper';
3
+ import { Controller, Figure } from '../../../modules/contract';
4
+ import { _DragHandle } from '../../../modules/ui';
5
+
6
+ import * as Constants from './shared/table.constants';
7
+ import { CreateCellsString, GetMaxColumns, IsResizeEls, IsTableCaption, GetLogicalCellIndex } from './shared/table.utils';
8
+ import { CreateHTML, CreateHTML_controller_table, CreateHTML_controller_cell } from './render/table.html';
9
+
10
+ import TableCellService from './services/table.cell';
11
+ import TableClipboardService from './services/table.clipboard';
12
+ import TableGridService from './services/table.grid';
13
+ import TableResizeService from './services/table.resize';
14
+ import TableSelectionService from './services/table.selection';
15
+ import TableStyleService from './services/table.style';
16
+
17
+ const { _w, ON_OVER_COMPONENT } = env;
18
+
19
+ /**
20
+ * @typedef {Object} TablePluginOptions
21
+ * @property {"x"|"y"|"xy"} [scrollType='x'] - Scroll type (`x`, `y`, `xy`)
22
+ * @property {"top"|"bottom"} [captionPosition='bottom'] - Caption position (`top`, `bottom`)
23
+ * @property {"cell"|"table"} [cellControllerPosition='cell'] - Cell controller position (`cell`, `table`)
24
+ * @property {Array} [colorList] - Color list, used in cell color picker
25
+ */
26
+
27
+ /**
28
+ * @typedef {import('./shared/table.constants').TableState} TableState
29
+ */
30
+
31
+ /**
32
+ * @class
33
+ * @description Table Plugin
34
+ */
35
+ class Table extends PluginDropdownFree {
36
+ static key = 'table';
37
+ static className = '';
38
+ static options = { isInputComponent: true };
39
+
40
+ /**
41
+ * @param {HTMLElement} node - The node to check.
42
+ * @returns {HTMLElement|null} Returns a node if the node is a valid component.
43
+ */
44
+ static component(node) {
45
+ return dom.check.isTable(node) ? node : null;
46
+ }
47
+
48
+ /** @type {HTMLElement} */
49
+ #tableMenu;
50
+ /** @type {HTMLElement} */
51
+ #tableHighlight;
52
+ /** @type {HTMLElement} */
53
+ #tableUnHighlight;
54
+ /** @type {HTMLElement} */
55
+ #tableDisplay;
56
+ /** @type {number} */
57
+ #prevUnhighlightX;
58
+
59
+ /** @type {number[]} */
60
+ #tableXY = [];
61
+ #maxWidth = true;
62
+ #fixedColumn = false;
63
+ #_s = false;
64
+
65
+ /**
66
+ * @constructor
67
+ * @param {SunEditor.Kernel} editor - The core kernel
68
+ * @param {TablePluginOptions} pluginOptions - Plugin options
69
+ */
70
+ constructor(editor, pluginOptions) {
71
+ // plugin bisic properties
72
+ super(editor);
73
+ this.title = this.$.lang.table;
74
+ this.icon = 'table';
75
+
76
+ // pluginOptions options
77
+ this.figureScrollList = ['se-scroll-figure-xy', 'se-scroll-figure-x', 'se-scroll-figure-y'];
78
+ this.figureScroll = typeof pluginOptions.scrollType === 'string' ? pluginOptions.scrollType.toLowerCase() : 'x';
79
+ this.captionPosition = pluginOptions.captionPosition !== 'bottom' ? 'top' : 'bottom';
80
+ this.cellControllerTop = (pluginOptions.cellControllerPosition !== 'cell' ? 'table' : 'cell') === 'table';
81
+
82
+ // create HTML
83
+ const menu = CreateHTML();
84
+ const commandArea = menu.querySelector('.se-controller-table-picker');
85
+ const controller_table = CreateHTML_controller_table(this.$);
86
+ const controller_cell = CreateHTML_controller_cell(this.$, this.cellControllerTop);
87
+
88
+ this.$.contextProvider.applyToRoots((e) => {
89
+ e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_CLASS.replace(/^\./, '') }));
90
+ e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_PREV_CLASS.replace(/^\./, '') }));
91
+ e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_CLASS.replace(/^\./, '') }));
92
+ e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_PREV_CLASS.replace(/^\./, '') }));
93
+ });
94
+
95
+ // members - Controller
96
+ if (this.cellControllerTop) {
97
+ this.controller_cell = new Controller(this, this.$, controller_cell.html, { position: 'top' });
98
+ this.controller_table = new Controller(this, this.$, controller_table, { position: 'top' });
99
+ this.controller_cell.sibling = this.controller_table.form;
100
+ this.controller_table.sibling = this.controller_cell.form;
101
+ this.controller_table.siblingMain = true;
102
+ } else {
103
+ this.controller_table = new Controller(this, this.$, controller_table, { position: 'top' });
104
+ this.controller_cell = new Controller(this, this.$, controller_cell.html, { position: 'bottom' });
105
+ }
106
+
107
+ this.figure = new Figure(this, this.$, null, {});
108
+
109
+ // members
110
+ /**
111
+ * @description Same value as `this._selectedTable`, but it maintains the prev table element
112
+ * @type {HTMLTableElement}
113
+ */
114
+ this._element = null;
115
+
116
+ // member - state
117
+ this.state = Constants.INITIAL_STATE;
118
+
119
+ // ------------------------------------------------ INIT ------------------------------------------------
120
+ // members - private
121
+ this.#tableMenu = menu;
122
+ this.#tableHighlight = menu.querySelector('.se-table-size-highlighted');
123
+ this.#tableUnHighlight = menu.querySelector('.se-table-size-unhighlighted');
124
+ this.#tableDisplay = menu.querySelector('.se-table-size-display');
125
+
126
+ // services
127
+ const openCellMenuFunc = _CellFormZIndex.bind(this, true);
128
+ const closeCellMenuFunc = _CellFormZIndex.bind(this, false);
129
+ const serviceOptions = { ...controller_cell, openCellMenuFunc, closeCellMenuFunc };
130
+
131
+ this.cellService = new TableCellService(this, serviceOptions);
132
+ this.clipboardService = new TableClipboardService(this);
133
+ this.gridService = new TableGridService(this, serviceOptions);
134
+ this.resizeService = new TableResizeService(this);
135
+ this.selectionService = new TableSelectionService(this);
136
+ this.styleService = new TableStyleService(this, { pluginOptions, controller_table });
137
+
138
+ // init
139
+ this.$.menu.initDropdownTarget(Table, menu);
140
+ this.$.eventManager.addEvent(commandArea, 'mousemove', this.#OnMouseMoveTablePicker.bind(this));
141
+ this.$.eventManager.addEvent(commandArea, 'click', this.#OnClickTablePicker.bind(this));
142
+ }
143
+
144
+ /**
145
+ * @template {keyof import('./shared/table.constants').TableState} K
146
+ * @param {K} key
147
+ * @param {import('./shared/table.constants').TableState[K]} value
148
+ */
149
+ setState(key, value) {
150
+ this.state[key] = value;
151
+ }
152
+
153
+ #initState() {
154
+ Object.assign(this.state, Constants.INITIAL_STATE);
155
+ }
156
+
157
+ /**
158
+ * @override
159
+ * @type {PluginDropdownFree['off']}
160
+ */
161
+ off() {
162
+ this.#resetTablePicker();
163
+ }
164
+
165
+ /**
166
+ * @hook Editor.Component
167
+ * @type {SunEditor.Hook.Component.Select}
168
+ */
169
+ componentSelect(target) {
170
+ this.#figureOpen(target);
171
+ if (!this.state.figureElement) this.setTableInfo(target);
172
+
173
+ this.#maxWidth = this.state.figureElement?.style.width === '100%';
174
+ this.#fixedColumn = dom.utils.hasClass(target, 'se-table-layout-fixed') || target.style.tableLayout === 'fixed';
175
+ this.styleService.setTableLayout(this.#maxWidth ? 'width|column' : 'width', this.#maxWidth, this.#fixedColumn, true);
176
+
177
+ if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) return;
178
+
179
+ if (!this.state.tdElement) return;
180
+ this.setCellInfo(this.state.tdElement, true);
181
+
182
+ // controller open
183
+ const btnDisabled = this.state.selectedCells?.length > 1;
184
+ const figureEl = dom.query.getParentElement(target, dom.check.isFigure);
185
+ this.controller_table.open(figureEl, null, { isWWTarget: false, initMethod: null, addOffset: null, disabled: btnDisabled });
186
+
187
+ if (!this.state.fixedCell) return;
188
+
189
+ this.cellService.setUnMergeButton();
190
+ this.controller_cell.open(this.state.tdElement, this.cellControllerTop ? figureEl : null, { isWWTarget: false, initMethod: null, addOffset: null, disabled: btnDisabled });
191
+ }
192
+
193
+ /**
194
+ * @hook Editor.Component
195
+ * @type {SunEditor.Hook.Component.Deselect}
196
+ */
197
+ componentDeselect() {
198
+ this.resetInfo();
199
+ }
200
+
201
+ /**
202
+ * @hook Editor.Component
203
+ * @type {SunEditor.Hook.Component.Destroy}
204
+ */
205
+ componentDestroy(target) {
206
+ if (!target) return;
207
+
208
+ const emptyDiv = target.parentNode;
209
+ dom.utils.removeItem(target);
210
+
211
+ this._closeTableSelectInfo();
212
+
213
+ if (emptyDiv !== this.$.frameContext.get('wysiwyg'))
214
+ this.$.nodeTransform.removeAllParents(
215
+ emptyDiv,
216
+ function (current) {
217
+ return current.childNodes.length === 0;
218
+ },
219
+ null,
220
+ );
221
+ this.$.focusManager.focus();
222
+ this.$.history.push(false);
223
+ }
224
+
225
+ /**
226
+ * @hook Editor.Component
227
+ * @type {SunEditor.Hook.Component.Copy}
228
+ */
229
+ componentCopy({ event, cloneContainer }) {
230
+ /** @type {NodeListOf<HTMLTableCellElement>} */
231
+ const selectedCells = cloneContainer.querySelectorAll('.se-selected-table-cell');
232
+ dom.utils.removeClass(selectedCells, 'se-selected-table-cell|se-selected-cell-focus');
233
+
234
+ if (selectedCells.length > 0) {
235
+ this.clipboardService.copySelectedTableCells(event, cloneContainer, selectedCells);
236
+ this.$.ui.showToast(this.$.lang.message_copy_success, 550);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * @hook Editor.EventManager
242
+ * @type {SunEditor.Hook.Event.OnPaste}
243
+ */
244
+ onPaste({ event, doc }) {
245
+ /** @type {HTMLTableCellElement} */
246
+ const targetCell = dom.query.getParentElement(dom.query.getEventTarget(event), dom.check.isTableCell);
247
+ if (!targetCell) return;
248
+
249
+ const domParserBody = doc.body;
250
+ if (domParserBody.childElementCount !== 1) return;
251
+
252
+ const componentInfo = this.$.component.get(domParserBody.firstElementChild);
253
+ if (componentInfo.pluginName !== Table.key) return;
254
+
255
+ const copyTable = /** @type {HTMLTableElement} */ (componentInfo.target);
256
+ const selectedCells = this.clipboardService.pasteTableCellMatrix(copyTable, targetCell);
257
+
258
+ // select cell
259
+ const { fixedCell, selectedCell } = this.selectionService.selectCells(selectedCells);
260
+ this.setState('selectedCells', selectedCells);
261
+ this.setState('fixedCell', fixedCell);
262
+ this.setState('selectedCell', selectedCell);
263
+ this.setState('selectedTable', dom.query.getParentElement(fixedCell, 'TABLE'));
264
+
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * @hook Editor.Core
270
+ * @type {SunEditor.Hook.Core.RetainFormat}
271
+ */
272
+ retainFormat() {
273
+ return {
274
+ query: 'table',
275
+ /** @param {HTMLTableElement} element */
276
+ method: (element) => {
277
+ const ColgroupEl = element.querySelector('colgroup');
278
+ let FigureEl = /** @type {HTMLElement} */ (dom.check.isFigure(element.parentNode) ? element.parentNode : null);
279
+
280
+ // create colgroup
281
+ if (!ColgroupEl) {
282
+ const rows = element.rows;
283
+ const maxColumnCount = GetMaxColumns(element);
284
+ const colWidths = new Array(maxColumnCount).fill(null);
285
+
286
+ for (let r = 0, rLen = rows.length, cellsCount; r < rLen; r++) {
287
+ const cellsInRow = rows[r].cells;
288
+ cellsCount = cellsInRow.length;
289
+ let currentLogicalCol = 0;
290
+ const rowColOccupancy = new Array(maxColumnCount).fill(false);
291
+
292
+ for (let c = 0; c < cellsCount; c++) {
293
+ const cell = cellsInRow[c];
294
+ const cellWidth = cell.style.width;
295
+ const colSpan = cell.colSpan || 1;
296
+
297
+ while (currentLogicalCol < maxColumnCount && rowColOccupancy[currentLogicalCol]) {
298
+ currentLogicalCol++;
299
+ }
300
+
301
+ if (currentLogicalCol >= maxColumnCount) break;
302
+ if (cellWidth && !colWidths[currentLogicalCol]) colWidths[currentLogicalCol] = cellWidth;
303
+
304
+ for (let i = 0; i < colSpan; i++) {
305
+ if (currentLogicalCol + i >= maxColumnCount || !cellWidth) continue;
306
+
307
+ rowColOccupancy[currentLogicalCol + i] = true;
308
+ const currentPxWidth = parseFloat(cellWidth);
309
+
310
+ for (let j = 0; j < colSpan; j++) {
311
+ const targetColIndex = currentLogicalCol + j;
312
+ if (targetColIndex >= maxColumnCount) continue;
313
+
314
+ const existingWidth = colWidths[targetColIndex];
315
+ if (existingWidth === null) {
316
+ colWidths[targetColIndex] = `width: ${cellWidth};`;
317
+ } else {
318
+ const existingPxWidth = parseFloat(existingWidth.replace('width: ', '').replace(';', ''));
319
+ if (colSpan === 1 && currentPxWidth !== existingPxWidth) {
320
+ colWidths[targetColIndex] = `width: ${cellWidth};`;
321
+ }
322
+ }
323
+ }
324
+ }
325
+ currentLogicalCol += colSpan;
326
+ }
327
+
328
+ if (cellsCount === maxColumnCount) break;
329
+ }
330
+
331
+ const colHTML = [];
332
+ for (let i = 0; i < maxColumnCount; i++) {
333
+ const colStyle = colWidths[i] ? ` style="${colWidths[i]}"` : '';
334
+ colHTML.push(`<col${colStyle}>`);
335
+ }
336
+
337
+ const colGroup = dom.utils.createElement('colgroup', null, colHTML.join(''));
338
+ element.insertBefore(colGroup, element.firstElementChild);
339
+
340
+ for (let r = 0; r < rows.length; r++) {
341
+ const cellsInRow = rows[r].cells;
342
+ for (let c = 0; c < cellsInRow.length; c++) {
343
+ dom.utils.setStyle(cellsInRow[c], 'width', '');
344
+ }
345
+ }
346
+ }
347
+
348
+ // figure
349
+ if (!FigureEl) {
350
+ FigureEl = dom.utils.createElement('FIGURE', { class: 'se-flex-component se-input-component' });
351
+ element.parentNode.insertBefore(FigureEl, element);
352
+ FigureEl.appendChild(element);
353
+ } else {
354
+ dom.utils.addClass(FigureEl, 'se-flex-component|se-input-component');
355
+ }
356
+
357
+ // table width
358
+ const tableWidth = element.style.width;
359
+ if (tableWidth) {
360
+ FigureEl.style.width = tableWidth === 'auto' ? 'max-content' : tableWidth;
361
+ dom.utils.setStyle(element, 'width', '');
362
+ }
363
+
364
+ // scroll
365
+ if (!this.figureScroll) {
366
+ dom.utils.removeClass(FigureEl, this.figureScrollList.join('|'));
367
+ } else {
368
+ const scrollTypeClass = `se-scroll-figure-${this.figureScroll}`;
369
+ dom.utils.addClass(FigureEl, scrollTypeClass);
370
+ dom.utils.removeClass(FigureEl, this.figureScrollList.filter((v) => v !== scrollTypeClass).join('|'));
371
+ }
372
+ },
373
+ };
374
+ }
375
+
376
+ /**
377
+ * @hook Editor.Core
378
+ * @type {SunEditor.Hook.Core.SetDir}
379
+ */
380
+ setDir() {
381
+ this.#resetTablePicker();
382
+ this.styleService.resetPropsAlign();
383
+ }
384
+
385
+ /**
386
+ * @hook Editor.EventManager
387
+ * @type {SunEditor.Hook.Event.OnMouseMove}
388
+ */
389
+ onMouseMove({ event }) {
390
+ if (this.resizeService.isResizing()) return;
391
+
392
+ const eventTarget = dom.query.getEventTarget(event);
393
+ const target = dom.query.getParentElement(eventTarget, IsResizeEls);
394
+ if (!target || event.buttons === 1) {
395
+ this.resizeService.offResizeGuide();
396
+ return;
397
+ }
398
+
399
+ if (this.resizeService.onResizeGuide(event, target) === false) return;
400
+
401
+ if (this._element) this._element.style.cursor = '';
402
+ this.resizeService.offResizeGuide();
403
+ }
404
+
405
+ /**
406
+ * @hook Editor.EventManager
407
+ * @type {SunEditor.Hook.Event.OnMouseDown}
408
+ */
409
+ onMouseDown({ event }) {
410
+ this.setState('ref', null);
411
+ this.setState('selectedCell', null);
412
+
413
+ const eventTarget = dom.query.getEventTarget(event);
414
+
415
+ if (this._element && dom.query.getParentElement(eventTarget, IsTableCaption)) {
416
+ this._closeController();
417
+ return;
418
+ }
419
+
420
+ const target = /** @type {HTMLTableCellElement} */ (dom.query.getParentElement(eventTarget, IsResizeEls));
421
+ if (!target) return;
422
+
423
+ if (!this.cellControllerTop) {
424
+ this.controller_cell.hide();
425
+ }
426
+
427
+ if (this.resizeService.readyResizeFromEdge(event, target) === false) return;
428
+
429
+ if (this.state.isShiftPressed && target !== this.state.fixedCell) return;
430
+
431
+ this.selectionService.deleteStyleSelectedCells();
432
+ if (/^TR$/i.test(target.nodeName)) return;
433
+
434
+ this.#_s = false;
435
+ this.selectionService.startCellSelection(target, false);
436
+ }
437
+
438
+ /**
439
+ * @hook Editor.EventManager
440
+ * @type {SunEditor.Hook.Event.OnMouseUp}
441
+ */
442
+ onMouseUp() {
443
+ this.setState('isShiftPressed', false);
444
+ }
445
+
446
+ /**
447
+ * @hook Editor.EventManager
448
+ * @type {SunEditor.Hook.Event.OnMouseLeave}
449
+ */
450
+ onMouseLeave() {
451
+ this.resizeService.offResizeGuide();
452
+ }
453
+
454
+ /**
455
+ * @hook Editor.EventManager
456
+ * @type {SunEditor.Hook.Event.OnKeyDown}
457
+ */
458
+ onKeyDown({ event, range, line }) {
459
+ this.setState('ref', null);
460
+
461
+ const keyCode = event.code;
462
+ const isTab = keyCodeMap.isTab(keyCode);
463
+ if (this.$.ui.selectMenuOn || this.resizeService.isResizing() || (!isTab && this.#_s) || keyCodeMap.isCtrl(event)) return;
464
+
465
+ if (!this.cellControllerTop) {
466
+ this.controller_cell.hide();
467
+ }
468
+
469
+ this.#_s = keyCodeMap.isShift(event);
470
+
471
+ // table tabkey
472
+ if (isTab) {
473
+ this.selectionService.deleteStyleSelectedCells();
474
+ const tableCell = dom.query.getParentElement(line, dom.check.isTableCell);
475
+ if (tableCell && range.collapsed && dom.check.isEdgePoint(range.startContainer, range.startOffset)) {
476
+ this._closeController();
477
+
478
+ const shift = this.#_s;
479
+ this.setState('isShiftPressed', (this.#_s = false));
480
+
481
+ /** @type {HTMLTableElement} */
482
+ const table = dom.query.getParentElement(tableCell, 'table');
483
+ /** @type {HTMLTableCellElement[]} */
484
+ const cells = dom.query.getListChildren(table, dom.check.isTableCell, null);
485
+ const idx = shift ? dom.utils.prevIndex(cells, tableCell) : dom.utils.nextIndex(cells, tableCell);
486
+
487
+ if (idx === cells.length && !shift) {
488
+ if (!dom.query.getParentElement(tableCell, 'thead')) {
489
+ const rows = table.rows;
490
+ const newRow = this.gridService.insertBodyRow(table, rows.length, this.state.cellCnt);
491
+ const firstTd = newRow.querySelector('td div');
492
+ this.$.selection.setRange(firstTd, 0, firstTd, 0);
493
+ }
494
+
495
+ event.preventDefault();
496
+ event.stopPropagation();
497
+
498
+ return false;
499
+ }
500
+
501
+ if (idx === -1 && shift) return false;
502
+
503
+ const moveCell = cells[idx];
504
+ if (!moveCell) return;
505
+
506
+ const rangeCell = moveCell.firstElementChild || moveCell;
507
+ this.$.selection.setRange(rangeCell, 0, rangeCell, 0);
508
+
509
+ event.preventDefault();
510
+ event.stopPropagation();
511
+
512
+ return false;
513
+ }
514
+ }
515
+
516
+ let cell = null;
517
+ if (!keyCodeMap.isShift(event)) {
518
+ cell = dom.query.getParentElement(line, dom.check.isTableCell);
519
+ if (!dom.utils.hasClass(cell, 'se-selected-cell-focus')) return;
520
+
521
+ this.selectionService.deleteStyleSelectedCells();
522
+ this._editorEnable(true);
523
+ this.#initService();
524
+ this._closeController();
525
+
526
+ return;
527
+ }
528
+
529
+ if (this.state.isShiftPressed || this.state.ref) return;
530
+
531
+ cell ||= /** @type {HTMLTableCellElement} */ (dom.query.getParentElement(line, dom.check.isTableCell));
532
+ if (cell) {
533
+ this.#_s = event.shiftKey;
534
+ this.setState('fixedCell', cell);
535
+ this._closeController();
536
+ this.selectionService.startCellSelection(cell, this.#_s);
537
+ return false;
538
+ }
539
+ }
540
+
541
+ /**
542
+ * @hook Editor.EventManager
543
+ * @type {SunEditor.Hook.Event.OnKeyUp}
544
+ */
545
+ onKeyUp({ line }) {
546
+ this.#_s = false;
547
+ if (this.state.isShiftPressed && dom.query.getParentElement(line, dom.check.isTableCell) === this.state.fixedCell) {
548
+ this.selectionService.deleteStyleSelectedCells();
549
+ this._editorEnable(true);
550
+ this.#initService();
551
+ }
552
+ this.setState('isShiftPressed', false);
553
+ }
554
+
555
+ /**
556
+ * @hook Editor.EventManager
557
+ * @type {SunEditor.Hook.Event.OnScroll}
558
+ */
559
+ onScroll() {
560
+ this.resizeService.offResizeGuide();
561
+ }
562
+
563
+ /**
564
+ * @hook Modules.Controller
565
+ * @type {SunEditor.Hook.Controller.Action}
566
+ */
567
+ controllerAction(target) {
568
+ const command = target.getAttribute('data-command');
569
+ if (!command) return;
570
+
571
+ switch (command) {
572
+ case 'header':
573
+ this.styleService.toggleHeader();
574
+ this.historyPush();
575
+ break;
576
+ case 'caption':
577
+ this.styleService.toggleCaption();
578
+ this.historyPush();
579
+ break;
580
+ case 'onsplit':
581
+ this.cellService.openSplitMenu();
582
+ break;
583
+ case 'oncolumn':
584
+ this.gridService.openColumnMenu();
585
+ break;
586
+ case 'onrow':
587
+ this.gridService.openRowMenu();
588
+ break;
589
+ case 'openTableProperties':
590
+ this.styleService.openTableProps(target);
591
+ break;
592
+ case 'openCellProperties':
593
+ this.styleService.openCellProps(target);
594
+ break;
595
+ case 'revert':
596
+ this.styleService.revertProps();
597
+ break;
598
+ case 'merge':
599
+ this.cellService.mergeCells(this.state.selectedCells);
600
+ break;
601
+ case 'unmerge':
602
+ this.cellService.unmergeCells(this.state.selectedCells);
603
+ break;
604
+ case 'resize':
605
+ this.#maxWidth = !this.#maxWidth;
606
+ this.styleService.setTableLayout('width', this.#maxWidth, this.#fixedColumn, false);
607
+ this.historyPush();
608
+ _w.setTimeout(() => {
609
+ this.$.component.select(this._element, Table.key, { isInput: true });
610
+ }, 0);
611
+ break;
612
+ case 'layout':
613
+ this.#fixedColumn = !this.#fixedColumn;
614
+ this.styleService.setTableLayout('column', this.#maxWidth, this.#fixedColumn, false);
615
+ this.historyPush();
616
+ _w.setTimeout(() => {
617
+ this.$.component.select(this._element, Table.key, { isInput: true });
618
+ }, 0);
619
+ break;
620
+ case 'copy':
621
+ this.$.component.copy(this.state.figureElement);
622
+ break;
623
+ case 'remove': {
624
+ this.componentDestroy(this.state.figureElement);
625
+ }
626
+ }
627
+
628
+ // [close_props]
629
+ if (!/(^revert|Properties$)/.test(command)) {
630
+ this.styleService.closeProps();
631
+ }
632
+
633
+ if (!/^(remove|on|open)/.test(command)) {
634
+ this._setCellControllerPosition(this.state.tdElement, this.state.isShiftPressed);
635
+ }
636
+ }
637
+
638
+ /**
639
+ * @description Sets various table-related information based on the provided table cell element (`<td>`). This includes updating cell, row, and table attributes, handling spanning cells, and adjusting the UI for elements like headers and captions.
640
+ * @param {HTMLTableCellElement} tdElement The target table cell (`<td>`) element from which table information will be extracted.
641
+ * @param {boolean} reset A flag indicating whether to reset the cell information. If `true`, the cell information will be reset and recalculated.
642
+ */
643
+ setCellInfo(tdElement, reset) {
644
+ const table = this.setTableInfo(tdElement);
645
+ if (!table) return;
646
+
647
+ this.setState('fixedCell', tdElement);
648
+ this.setState('trElement', /** @type {HTMLTableRowElement} */ (tdElement.parentNode));
649
+
650
+ // hedaer
651
+ this.styleService.resetHeaderButton(table);
652
+
653
+ // caption
654
+ this.styleService.resetCaptionButton(table);
655
+
656
+ // set cell info
657
+ if (reset || this.state.physical_cellCnt === 0) {
658
+ if (this.state.tdElement !== tdElement) {
659
+ this.setState('tdElement', tdElement);
660
+ }
661
+
662
+ if (!this.state.selectedCells?.length) this.setState('selectedCells', [tdElement]);
663
+
664
+ const rows = table.rows;
665
+ this.setState('trElements', rows);
666
+ const cellIndex = tdElement.cellIndex;
667
+
668
+ let cellCnt = 0;
669
+ for (let i = 0, cells = rows[0].cells, len = rows[0].cells.length; i < len; i++) {
670
+ cellCnt += cells[i].colSpan;
671
+ }
672
+
673
+ // row cnt, row index
674
+ const rowIndex = this.state.trElement.rowIndex;
675
+ this.setState('rowIndex', rowIndex);
676
+ this.setState('rowCnt', rows.length);
677
+
678
+ // cell cnt, physical cell index
679
+ this.setState('physical_cellCnt', this.state.trElement.cells.length);
680
+ this.setState('logical_cellCnt', cellCnt);
681
+ this.setState('cellCnt', cellCnt);
682
+ this.setState('physical_cellIndex', cellIndex);
683
+
684
+ // span
685
+ this.setState('current_colSpan', this.state.tdElement.colSpan - 1);
686
+ this.setState('current_rowSpan', this.state.trElement.cells[cellIndex].rowSpan - 1);
687
+
688
+ // find logical cell index
689
+ const logicalIndex = GetLogicalCellIndex(table, rowIndex, cellIndex);
690
+ this.setState('logical_cellIndex', logicalIndex);
691
+ }
692
+ }
693
+
694
+ /**
695
+ * @description Sets row-related information based on the provided table row element (`<tr>`). This includes updating the row count and the index of the selected row.
696
+ * @param {HTMLTableRowElement} trElement The target table row (`<tr>`) element from which row information will be extracted.
697
+ */
698
+ setRowInfo(trElement) {
699
+ const table = this.setTableInfo(trElement);
700
+ const rows = table.rows;
701
+ this.setState('trElements', rows);
702
+ this.setState('rowCnt', rows.length);
703
+ this.setState('rowIndex', trElement.rowIndex);
704
+ }
705
+
706
+ /**
707
+ * @description Sets the table and figure elements based on the provided cell element, and stores references to them for later use.
708
+ * @param {Node} element The target table cell (`<td>`) element from which the table info will be extracted.
709
+ * @returns {HTMLTableElement} The `<table>` element that is the parent of the provided `element`.
710
+ */
711
+ setTableInfo(element) {
712
+ const table = (this._element = dom.query.getParentElement(element, 'TABLE'));
713
+ this.setState('selectedTable', table);
714
+ this.setState('figureElement', dom.query.getParentElement(table, dom.check.isFigure) || table);
715
+ return /** @type {HTMLTableElement} */ (table);
716
+ }
717
+
718
+ /**
719
+ * @description Resets the internal state related to table cell selection,
720
+ * - clearing any selected cells and removing associated styles and event listeners.
721
+ */
722
+ resetInfo() {
723
+ this.#initService();
724
+ this.selectionService.deleteStyleSelectedCells();
725
+ this._editorEnable(true);
726
+
727
+ this._element = null;
728
+ this.#initState();
729
+
730
+ this.#tableXY = [];
731
+ this.#maxWidth = false;
732
+ this.#fixedColumn = false;
733
+ }
734
+
735
+ /**
736
+ * @description Adds a new entry to the history stack.
737
+ */
738
+ historyPush() {
739
+ this.selectionService.deleteStyleSelectedCells();
740
+ this.$.history.push(false);
741
+ this.selectionService.recallStyleSelectedCells();
742
+ }
743
+
744
+ /**
745
+ * @internal
746
+ * @description Sets the controller position for a cell.
747
+ * @param {HTMLTableCellElement} tdElement - The target table cell.
748
+ */
749
+ _setController(tdElement) {
750
+ if (!this.$.selection.get().isCollapsed && !this.state.selectedCell) {
751
+ this.selectionService.deleteStyleSelectedCells();
752
+ return;
753
+ }
754
+
755
+ this.cellService.setUnMergeButton();
756
+
757
+ this.setState('tdElement', tdElement);
758
+ if (this.state.fixedCell === tdElement) dom.utils.addClass(tdElement, 'se-selected-cell-focus');
759
+ if (!this.state.selectedCells?.length) this.setState('selectedCells', [tdElement]);
760
+ const tableElement = this.state.selectedTable || this._element || dom.query.getParentElement(tdElement, 'TABLE');
761
+ this.$.component.select(tableElement, Table.key, { isInput: true });
762
+ }
763
+
764
+ /**
765
+ * @internal
766
+ * @description Sets the position of the cell controller.
767
+ * @param {HTMLTableCellElement} tdElement - The target table cell.
768
+ * @param {boolean} reset - Whether to reset the controller position.
769
+ */
770
+ _setCellControllerPosition(tdElement, reset) {
771
+ this.setCellInfo(tdElement, reset);
772
+ if (!this.cellControllerTop) this.controller_cell.resetPosition(tdElement);
773
+ }
774
+
775
+ /**
776
+ * @description Enables or disables editor mode.
777
+ * @param {boolean} enabled Whether to enable or disable the editor.
778
+ */
779
+ _editorEnable(enabled) {
780
+ const wysiwyg = this.$.frameContext.get('wysiwyg');
781
+ wysiwyg.setAttribute('contenteditable', enabled.toString());
782
+ if (enabled) dom.utils.removeClass(wysiwyg, 'se-disabled');
783
+ else dom.utils.addClass(wysiwyg, 'se-disabled');
784
+ }
785
+
786
+ /**
787
+ * @description Closes table-related controllers.
788
+ */
789
+ _closeController() {
790
+ this.controller_table.close(true);
791
+ this.controller_cell.close(true);
792
+ }
793
+
794
+ /**
795
+ * @description Closes table-related controllers and table figure
796
+ */
797
+ _closeTableSelectInfo() {
798
+ this.$.component.deselect();
799
+ this._closeController();
800
+ }
801
+
802
+ /**
803
+ * @description Opens the figure.
804
+ * @param {Node} target - The target figure element.
805
+ */
806
+ #figureOpen(target) {
807
+ this.figure.open(target, { nonResizing: true, nonSizeInfo: true, nonBorder: true, figureTarget: true, infoOnly: false });
808
+ }
809
+
810
+ /**
811
+ * @description Resets the table picker display.
812
+ */
813
+ #resetTablePicker() {
814
+ if (!this.#tableHighlight) return;
815
+
816
+ const highlight = this.#tableHighlight.style;
817
+ const unHighlight = this.#tableUnHighlight.style;
818
+
819
+ highlight.width = '1em';
820
+ highlight.height = '1em';
821
+ unHighlight.width = '5em';
822
+ unHighlight.height = '5em';
823
+
824
+ dom.utils.changeTxt(this.#tableDisplay, '1 x 1');
825
+ }
826
+
827
+ /**
828
+ * @description Handles mouse movement within the table picker.
829
+ * @param {MouseEvent} e The mouse event.
830
+ */
831
+ #OnMouseMoveTablePicker(e) {
832
+ e.stopPropagation();
833
+
834
+ let x = Math.ceil(e.offsetX / 18);
835
+ let y = Math.ceil(e.offsetY / 18);
836
+ x = x < 1 ? 1 : x;
837
+ y = y < 1 ? 1 : y;
838
+
839
+ const isRTL = this.$.options.get('_rtl');
840
+ if (isRTL) {
841
+ x = 11 - x;
842
+ }
843
+
844
+ this.#tableHighlight.style.width = x + 'em';
845
+ this.#tableHighlight.style.height = y + 'em';
846
+
847
+ const x_u = x < 5 ? 5 : x > 8 ? 10 : x + 2;
848
+ const y_u = y < 5 ? 5 : y > 8 ? 10 : y + 2;
849
+ this.#tableUnHighlight.style.width = x_u + 'em';
850
+ this.#tableUnHighlight.style.height = y_u + 'em';
851
+
852
+ // RTL mode - menu's left position based on unhighlight width change
853
+ if (isRTL) {
854
+ const prevX_u = this.#prevUnhighlightX || 5;
855
+ const diff = x_u - prevX_u;
856
+ if (diff !== 0) {
857
+ const currentLeft = numbers.get(this.#tableMenu.style.left);
858
+ this.#tableMenu.style.left = currentLeft - diff * 18 + 'px';
859
+ this.#prevUnhighlightX = x_u;
860
+ }
861
+ }
862
+
863
+ dom.utils.changeTxt(this.#tableDisplay, x + ' x ' + y);
864
+ this.#tableXY = [x, y];
865
+ }
866
+
867
+ /**
868
+ * @description Executes the selected action when the table picker is clicked.
869
+ */
870
+ #OnClickTablePicker() {
871
+ const oTable = dom.utils.createElement('TABLE');
872
+ const x = this.#tableXY[0];
873
+ const y = this.#tableXY[1];
874
+
875
+ const body = `<tbody>${`<tr>${CreateCellsString('td', x)}</tr>`.repeat(y)}</tbody>`;
876
+ const colGroup = `<colgroup>${`<col style="width: ${numbers.get(100 / x, Constants.CELL_DECIMAL_END)}%;">`.repeat(x)}</colgroup>`;
877
+ oTable.innerHTML = colGroup + body;
878
+
879
+ // scroll
880
+ let scrollTypeClass = '';
881
+ if (this.figureScroll) {
882
+ scrollTypeClass = ` se-scroll-figure-${this.figureScroll}`;
883
+ }
884
+
885
+ const figure = dom.utils.createElement('FIGURE', { class: 'se-flex-component se-input-component' + scrollTypeClass, style: 'width: 100%;' });
886
+ figure.appendChild(oTable);
887
+ this.#maxWidth = true;
888
+
889
+ if (this.$.component.insert(figure, { insertBehavior: 'none' })) {
890
+ this.#resetTablePicker();
891
+ this.$.menu.dropdownOff();
892
+ const target = oTable.querySelector('td div');
893
+ this.$.selection.setRange(target, 0, target, 0);
894
+ }
895
+ }
896
+
897
+ /**
898
+ * @description Initializes services by calling their init methods.
899
+ */
900
+ #initService() {
901
+ this.resizeService.init();
902
+ this.selectionService.init();
903
+ this.styleService.init();
904
+ }
905
+ }
906
+
907
+ /**
908
+ * @description Adjusts the z-index of the cell controller form.
909
+ * @param {boolean} value - If `true`, brings to top; otherwise resets.
910
+ */
911
+ function _CellFormZIndex(value) {
912
+ this.controller_cell.bringToTop(value);
913
+ }
914
+
915
+ export default Table;