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,844 @@
1
+ import { dom, numbers, converter, env } from '../../../../helper';
2
+ import { SelectMenu } from '../../../../modules/ui';
3
+
4
+ import * as Constants from '../shared/table.constants';
5
+ import { CreateBorderMenu, CreateBorderFormatMenu } from '../render/table.menu';
6
+ import { CreateHTML_controller_properties } from '../render/table.html';
7
+ import { ColorPicker, Controller } from '../../../../modules/contract';
8
+ import { CreateCellsString, InvalidateTableCache } from '../shared/table.utils';
9
+
10
+ const { _w } = env;
11
+
12
+ /**
13
+ * @description Manages table and cell styling including borders, colors, alignment, and property controllers.
14
+ */
15
+ export class TableStyleService {
16
+ #main;
17
+ #state;
18
+ #$;
19
+
20
+ /**
21
+ * @constructor
22
+ * @param {import('../index').default} main Table index
23
+ * @param {Object} options - Options
24
+ * @param {import('../index').TablePluginOptions} options.pluginOptions - Plugin options
25
+ * @param {HTMLElement} options.controller_table - Controller table element
26
+ */
27
+ constructor(main, { pluginOptions, controller_table }) {
28
+ this.#main = main;
29
+ this.#state = main.state;
30
+ this.#$ = main.$;
31
+
32
+ this.sliderType = '';
33
+ /** @type {HTMLButtonElement} */
34
+ this.resizeButton = controller_table.querySelector('._se_table_resize');
35
+ /** @type {HTMLSpanElement} */
36
+ this.resizeText = controller_table.querySelector('._se_table_resize > span > span');
37
+ /** @type {HTMLButtonElement} */
38
+ this.columnFixedButton = controller_table.querySelector('._se_table_fixed_column');
39
+ /** @type {HTMLButtonElement} */
40
+ this.headerButton = controller_table.querySelector('._se_table_header');
41
+ /** @type {HTMLButtonElement} */
42
+ this.captionButton = controller_table.querySelector('._se_table_caption');
43
+
44
+ // props
45
+ const controller_props = CreateHTML_controller_properties(this.#$);
46
+ const propsTargets = [this.#main.controller_table, this.#main.controller_cell];
47
+ this.controller_props = new Controller(this, this.#$, controller_props.html, { position: 'bottom', parents: propsTargets, isInsideForm: true });
48
+ this.controller_props_title = controller_props.controller_props_title;
49
+
50
+ // color picker
51
+ const colorForm = dom.utils.createElement('DIV', { class: 'se-controller se-list-layer' }, null);
52
+ this.controller_colorPicker = new Controller(this, this.#$, colorForm, {
53
+ position: 'bottom',
54
+ parents: [this.controller_props].concat(propsTargets),
55
+ isInsideForm: true,
56
+ isWWTarget: false,
57
+ initMethod: () => {
58
+ this.colorPicker.hueSlider.close();
59
+ dom.utils.removeClass(this.controller_colorPicker.currentTarget, 'on');
60
+ },
61
+ });
62
+
63
+ this.colorPicker = new ColorPicker(this, this.#$, '', {
64
+ form: colorForm,
65
+ colorList: pluginOptions.colorList || Constants.DEFAULT_COLOR_LIST,
66
+ splitNum: 5,
67
+ disableRemove: true,
68
+ hueSliderOptions: { controllerOptions: { isOutsideForm: true, parents: [this.controller_colorPicker], parentsHide: true } },
69
+ });
70
+
71
+ // members - SelectMenu - properties - border style
72
+ const borderMenu = CreateBorderMenu();
73
+ const borderButton = controller_props.borderButton;
74
+ this.selectMenu_props_border = new SelectMenu(this.#$, { checkList: false, position: 'bottom-center' });
75
+ this.selectMenu_props_border.on(borderButton, this.#OnPropsBorderEdit.bind(this));
76
+ this.selectMenu_props_border.create(borderMenu.items, borderMenu.menus);
77
+
78
+ // members - SelectMenu - properties - border format
79
+ const borderFormatMenu = CreateBorderFormatMenu(this.#$.lang, this.#$.icons, []);
80
+ const borderFormatButton = controller_props.borderFormatButton;
81
+ this.selectMenu_props_border_format = new SelectMenu(this.#$, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 5 });
82
+ this.selectMenu_props_border_format.on(borderFormatButton, this.#OnPropsBorderFormatEdit.bind(this, 'all'));
83
+ this.selectMenu_props_border_format.create(borderFormatMenu.items, borderFormatMenu.menus);
84
+
85
+ const borderFormatMenu_oneCell = CreateBorderFormatMenu(this.#$.lang, this.#$.icons, Constants.BORDER_FORMAT_INSIDE);
86
+ this.selectMenu_props_border_format_oneCell = new SelectMenu(this.#$, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 6 });
87
+ this.selectMenu_props_border_format_oneCell.on(borderFormatButton, this.#OnPropsBorderFormatEdit.bind(this, 'outside'));
88
+ this.selectMenu_props_border_format_oneCell.create(borderFormatMenu_oneCell.items, borderFormatMenu_oneCell.menus);
89
+
90
+ // memberts - elements..
91
+ this.maxText = this.#$.lang.maxSize;
92
+ this.minText = this.#$.lang.minSize;
93
+ this.propTargets = {
94
+ cell_alignment: controller_props.cell_alignment,
95
+ cell_alignment_vertical: controller_props.cell_alignment_vertical,
96
+ cell_alignment_table_text: controller_props.cell_alignment_table_text,
97
+ border_format: borderFormatButton,
98
+ border_style: controller_props.border_style,
99
+ border_color: controller_props.border_color,
100
+ border_width: controller_props.border_width,
101
+ back_color: controller_props.back_color,
102
+ font_color: controller_props.font_color,
103
+ palette_border_button: controller_props.palette_border_button,
104
+ font_bold: controller_props.font_bold,
105
+ font_underline: controller_props.font_underline,
106
+ font_italic: controller_props.font_italic,
107
+ font_strike: controller_props.font_strike,
108
+ };
109
+ this._propsCache = [];
110
+ this._currentFontStyles = [];
111
+ this._propsAlignCache = '';
112
+ this._propsVerticalAlignCache = '';
113
+ this._typeCache = '';
114
+ }
115
+
116
+ get #selectionService() {
117
+ return this.#main.selectionService;
118
+ }
119
+
120
+ /**
121
+ * @hook Modules.ColorPicker
122
+ * @type {SunEditor.Hook.ColorPicker.Action}
123
+ */
124
+ colorPickerAction(color) {
125
+ this.applyColorPicker(color);
126
+ }
127
+
128
+ /**
129
+ * @hook Modules.Controller
130
+ * @type {SunEditor.Hook.Controller.Action}
131
+ */
132
+ controllerAction(target) {
133
+ const command = target.getAttribute('data-command');
134
+ if (!command) return;
135
+
136
+ const value = target.getAttribute('data-value');
137
+
138
+ switch (command) {
139
+ case 'props_onborder_format':
140
+ this.openBorderFormatMenu();
141
+ break;
142
+ case 'props_onborder_style':
143
+ this.openBorderStyleMenu();
144
+ break;
145
+ case 'props_onpalette':
146
+ this.openColorPalette(target, value);
147
+ break;
148
+ case 'props_font_style':
149
+ this.toggleFontStyle(value);
150
+ break;
151
+ case 'props_submit':
152
+ this.submitProps(target);
153
+ break;
154
+ case 'props_align':
155
+ this.setAlignProps(target.getAttribute('data-value'));
156
+ break;
157
+ case 'props_align_vertical':
158
+ this.setVerticalAlignProps(target.getAttribute('data-value'));
159
+ break;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * @description Opens the table properties dialog.
165
+ * @param {HTMLElement} target - The target element (usually the table).
166
+ */
167
+ openTableProps(target) {
168
+ if (this.controller_props.currentTarget === target && this.controller_props.form?.style.display === 'block') {
169
+ this.controller_props.close();
170
+ } else {
171
+ this.controller_props_title.textContent = this.#$.lang.tableProperties;
172
+ this.#setCtrlProps('table');
173
+ this.controller_props.open(target, this.#main.controller_table.form, { isWWTarget: false, initMethod: null, addOffset: null });
174
+ }
175
+ }
176
+
177
+ /**
178
+ * @description Opens the cell properties dialog.
179
+ * @param {HTMLElement} target - The target element (usually the table cell).
180
+ */
181
+ openCellProps(target) {
182
+ if (this.controller_props.currentTarget === target && this.controller_props.form?.style.display === 'block') {
183
+ this.controller_props.close();
184
+ } else {
185
+ this.controller_props_title.textContent = this.#$.lang.cellProperties;
186
+ this.#setCtrlProps('cell');
187
+ this.controller_props.open(target, this.#main.controller_cell.form, { isWWTarget: false, initMethod: null, addOffset: null });
188
+ }
189
+ }
190
+
191
+ /**
192
+ * @description Opens the border format menu.
193
+ */
194
+ openBorderFormatMenu() {
195
+ if (this._propsCache.length === 1) {
196
+ this.selectMenu_props_border_format_oneCell.open();
197
+ } else {
198
+ this.selectMenu_props_border_format.open();
199
+ }
200
+ }
201
+
202
+ /**
203
+ * @description Opens the border style menu.
204
+ */
205
+ openBorderStyleMenu() {
206
+ this.selectMenu_props_border.open();
207
+ }
208
+
209
+ /**
210
+ * @description Handles color selection from the color palette.
211
+ * @param {Node} button The button triggering the color palette.
212
+ * @param {string} type The type of color selection.
213
+ */
214
+ openColorPalette(button, type) {
215
+ const { back_color, font_color, border_color } = this.propTargets;
216
+ const color = type === 'border' ? border_color : type === 'back' ? back_color : font_color;
217
+
218
+ if (this.controller_colorPicker.isOpen && type === this.sliderType) {
219
+ this.controller_colorPicker.close();
220
+ } else {
221
+ this.sliderType = type;
222
+ dom.utils.addClass(button, 'on');
223
+ this.colorPicker.init(color?.value || '', button);
224
+ this.controller_colorPicker.open(button, null, { isWWTarget: false, initMethod: null, addOffset: null });
225
+ }
226
+ }
227
+
228
+ /**
229
+ * @description Toggles the font style.
230
+ * @param {string} value - The style to toggle (`bold`|`underline`|`italic`|`strike`).
231
+ */
232
+ toggleFontStyle(value) {
233
+ dom.utils.toggleClass(this.propTargets[`font_${value}`], 'on');
234
+ }
235
+
236
+ /**
237
+ * @description Toggles the visibility of the table header (`<thead>`). If the header is present, it is removed; if absent, it is added.
238
+ */
239
+ toggleHeader() {
240
+ const btn = this.headerButton;
241
+ const active = dom.utils.hasClass(btn, 'active');
242
+ const table = this.#main._element;
243
+ InvalidateTableCache(table);
244
+
245
+ if (!active) {
246
+ const header = dom.utils.createElement('THEAD');
247
+ header.innerHTML = '<tr>' + CreateCellsString('th', this.#state.logical_cellCnt) + '</tr>';
248
+ table.insertBefore(header, table.querySelector('tbody'));
249
+ } else {
250
+ dom.utils.removeItem(table.querySelector('thead'));
251
+ }
252
+
253
+ dom.utils.toggleClass(btn, 'active');
254
+
255
+ if (/TH/i.test(this.#state.tdElement.nodeName)) {
256
+ this.#main._closeController();
257
+ } else {
258
+ this.#main._setCellControllerPosition(this.#state.tdElement, false);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * @description Toggles the visibility of the table caption (`<caption>`). If the caption is present, it is removed; if absent, it is added.
264
+ */
265
+ toggleCaption() {
266
+ const btn = this.captionButton;
267
+ const active = dom.utils.hasClass(btn, 'active');
268
+ const table = this.#main._element;
269
+
270
+ if (!active) {
271
+ const caption = dom.utils.createElement('CAPTION', { class: `se-table-caption-${this.#main.captionPosition}` });
272
+ caption.innerHTML = '<div><br></div>';
273
+ table.insertBefore(caption, table.firstElementChild);
274
+ } else {
275
+ dom.utils.removeItem(table.querySelector('caption'));
276
+ }
277
+
278
+ dom.utils.toggleClass(btn, 'active');
279
+ this.#main._setCellControllerPosition(this.#state.tdElement, false);
280
+ }
281
+
282
+ /**
283
+ * @description Resets the header button state.
284
+ * @param {HTMLTableElement} table - The table element.
285
+ */
286
+ resetHeaderButton(table) {
287
+ if (table.querySelector('thead')) dom.utils.addClass(this.headerButton, 'active');
288
+ else dom.utils.removeClass(this.headerButton, 'active');
289
+ }
290
+
291
+ /**
292
+ * @description Resets the caption button state.
293
+ * @param {HTMLTableElement} table - The table element.
294
+ */
295
+ resetCaptionButton(table) {
296
+ if (table.querySelector('caption')) dom.utils.addClass(this.captionButton, 'active');
297
+ else dom.utils.removeClass(this.captionButton, 'active');
298
+ }
299
+
300
+ /**
301
+ * @description Resets the alignment properties for table cells.
302
+ */
303
+ resetPropsAlign() {
304
+ const { cell_alignment } = this.propTargets;
305
+ const left = cell_alignment.querySelector('[data-value="left"]');
306
+ const right = cell_alignment.querySelector('[data-value="right"]');
307
+ const l_parent = left.parentElement;
308
+ const r_parent = right.parentElement;
309
+ l_parent.appendChild(right);
310
+ r_parent.appendChild(left);
311
+ }
312
+
313
+ /**
314
+ * @description Reverts the properties to their previous state.
315
+ */
316
+ revertProps() {
317
+ const propsCache = this._propsCache;
318
+ for (let i = 0, len = propsCache.length; i < len; i++) {
319
+ propsCache[i][0].style.cssText = propsCache[i][1];
320
+ }
321
+ // alignment
322
+ this.#setAlignProps(this.propTargets.cell_alignment, this._propsAlignCache, true);
323
+ this.#setAlignProps(this.propTargets.cell_alignment_vertical, this._propsVerticalAlignCache, true);
324
+ if (dom.check.isTable(propsCache[0][0]) && this.#state.figureElement) {
325
+ this.#state.figureElement.style.float = this._propsAlignCache;
326
+ }
327
+ }
328
+
329
+ /**
330
+ * @description Applies the color from the color picker.
331
+ * @param {any} color - The color string or object.
332
+ */
333
+ applyColorPicker(color) {
334
+ const target = this.propTargets[`${this.sliderType}_color`];
335
+ target.style.borderColor = target.value = color;
336
+ this.controller_colorPicker.close();
337
+ }
338
+
339
+ /**
340
+ * @description Sets the alignment properties.
341
+ * @param {string} value - The alignment value.
342
+ */
343
+ setAlignProps(value) {
344
+ this.#setAlignProps(this.propTargets.cell_alignment, value, false);
345
+ }
346
+
347
+ /**
348
+ * @description Sets the vertical alignment properties.
349
+ * @param {string} value - The vertical alignment value.
350
+ */
351
+ setVerticalAlignProps(value) {
352
+ this.#setAlignProps(this.propTargets.cell_alignment_vertical, value, false);
353
+ }
354
+
355
+ /**
356
+ * @description Updates table layout styles.
357
+ * @param {string} styles - Styles to update.
358
+ * @param {boolean} isMaxWidth - Whether the table is set to maximum width.
359
+ * @param {boolean} isFixedColumn - Whether the table has fixed column width.
360
+ * @param {boolean} ondisplay - Whether to update display.
361
+ */
362
+ setTableLayout(styles, isMaxWidth, isFixedColumn, ondisplay) {
363
+ if (styles.includes('width')) {
364
+ const targets = this.#state.figureElement;
365
+ if (!targets) return;
366
+
367
+ let sizeIcon, text;
368
+ if (!isMaxWidth) {
369
+ sizeIcon = this.#$.icons.expansion;
370
+ text = this.maxText;
371
+ if (!ondisplay) targets.style.width = 'max-content';
372
+ } else {
373
+ sizeIcon = this.#$.icons.reduction;
374
+ text = this.minText;
375
+ if (!ondisplay) targets.style.width = '100%';
376
+ }
377
+
378
+ dom.utils.changeElement(this.resizeButton.firstElementChild, sizeIcon);
379
+ dom.utils.changeTxt(this.resizeText, text);
380
+ }
381
+
382
+ if (styles.includes('column')) {
383
+ if (!isFixedColumn) {
384
+ dom.utils.removeClass(this.#main._element, 'se-table-layout-fixed');
385
+ dom.utils.addClass(this.#main._element, 'se-table-layout-auto');
386
+ dom.utils.removeClass(this.columnFixedButton, 'active');
387
+ } else {
388
+ dom.utils.removeClass(this.#main._element, 'se-table-layout-auto');
389
+ dom.utils.addClass(this.#main._element, 'se-table-layout-fixed');
390
+ dom.utils.addClass(this.columnFixedButton, 'active');
391
+ }
392
+ }
393
+ }
394
+
395
+ /**
396
+ * @description Applies properties to table cells.
397
+ * @param {HTMLButtonElement} target The target element.
398
+ */
399
+ submitProps(target) {
400
+ try {
401
+ target.disabled = true;
402
+
403
+ const isTable = this.#main.controller_table.form.contains(this.controller_props.currentTarget);
404
+ const targets = isTable ? [this.#main._element] : this.#state.selectedCells;
405
+ const tr = /** @type {HTMLTableCellElement} */ (targets[0]);
406
+ const trStyles = _w.getComputedStyle(tr);
407
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical } = this.propTargets;
408
+
409
+ const borderFormat = border_format.getAttribute('se-border-format') || '';
410
+ const hasFormat = borderFormat !== 'all';
411
+ const borderStyle = (border_style.textContent === 'none' ? '' : border_style.textContent) || '';
412
+ const isNoneFormat = borderFormat === 'none' || !borderStyle;
413
+
414
+ const cellAlignment = cell_alignment.getAttribute('se-cell-align') || '';
415
+ const cellAlignmentVertical = cell_alignment_vertical.getAttribute('se-cell-align') || '';
416
+ const borderColor = isNoneFormat ? '' : border_color.value.trim() || trStyles.borderColor;
417
+ let borderWidth = isNoneFormat ? '' : border_width.value.trim() || trStyles.borderWidth;
418
+ borderWidth = borderWidth + (numbers.is(borderWidth) ? Constants.DEFAULT_BORDER_UNIT : '');
419
+ const backColor = back_color.value.trim();
420
+ const fontColor = font_color.value.trim();
421
+ const hasBorder = hasFormat && !isNoneFormat && borderWidth;
422
+ const borderCss = `${borderWidth} ${borderStyle} ${borderColor}`;
423
+ const cells = {
424
+ left: [],
425
+ top: [],
426
+ right: [],
427
+ bottom: [],
428
+ middle: [],
429
+ all: null,
430
+ };
431
+
432
+ if (!isTable) {
433
+ const trRow = /** @type {HTMLTableRowElement} */ (tr.parentElement);
434
+ // --- target cells roof
435
+ let { rs, re, cs, ce } = this.#state.ref || {
436
+ rs: trRow.rowIndex || 0,
437
+ re: trRow.rowIndex || 0,
438
+ cs: tr.cellIndex || 0,
439
+ ce: tr.cellIndex || 0,
440
+ };
441
+ const mergeInfo = new Array(re - rs + 1).fill(0).map(() => new Array(ce - cs + 1).fill(0));
442
+ const cellStartIndex = cs;
443
+ re -= rs;
444
+ rs -= rs;
445
+ ce -= cs;
446
+ cs -= cs;
447
+ let prevRow = /** @type {HTMLElement} */ (trRow);
448
+ for (let i = 0, cellCnt = 0, len = targets.length, e, es, rowIndex = 0, cellIndex, colspan, rowspan; i < len; i++, cellCnt++) {
449
+ e = /** @type {HTMLTableCellElement} */ (targets[i]);
450
+ colspan = e.colSpan;
451
+ rowspan = e.rowSpan;
452
+ cellIndex = e.cellIndex - cellStartIndex;
453
+
454
+ if (prevRow !== e.parentElement) {
455
+ rowIndex++;
456
+ cellCnt = 0;
457
+ prevRow = e.parentElement;
458
+ }
459
+
460
+ let c = 0;
461
+ while (c <= cellIndex) {
462
+ cellIndex += mergeInfo[rowIndex][c] || 0;
463
+ c++;
464
+ }
465
+
466
+ try {
467
+ if (rowspan > 1) {
468
+ const rowspanNum = rowspan - 1;
469
+ for (let r = rowIndex; r <= rowIndex + rowspanNum; r++) {
470
+ mergeInfo[r][cellIndex] += colspan - (rowIndex === r ? 1 : 0);
471
+ }
472
+ } else if (colspan > 1) {
473
+ mergeInfo[rowIndex][cellIndex] += colspan - 1;
474
+ }
475
+ } catch {
476
+ // ignore error
477
+ }
478
+
479
+ const isBottom = rowIndex + rowspan - 1 === re;
480
+ if (rowIndex === rs) cells.top.push(e);
481
+ if (rowIndex === re || isBottom) cells.bottom.push(e);
482
+ if (cellIndex === cs) cells.left.push(e);
483
+ if (cellIndex === ce || cellIndex + colspan - 1 === ce) cells.right.push(e);
484
+ if (!isBottom && rowIndex !== rs && rowIndex !== re && cellIndex !== cs && cellIndex !== ce) cells.middle.push(e);
485
+
486
+ // --- set styles
487
+ es = e.style;
488
+ // alignment
489
+ es.textAlign = cellAlignment;
490
+ es.verticalAlign = cellAlignmentVertical;
491
+ // back
492
+ es.backgroundColor = backColor;
493
+ // font
494
+ es.color = fontColor;
495
+ // font style
496
+ this.#setFontStyle(es);
497
+ // border
498
+ if (hasBorder) continue;
499
+ // border - all || none
500
+ if (isNoneFormat) {
501
+ es.border = es.borderLeft = es.borderTop = es.borderRight = es.borderBottom = '';
502
+ } else {
503
+ es.border = borderCss;
504
+ }
505
+ }
506
+
507
+ if (cells.middle.length === 0) {
508
+ cells.middle = targets;
509
+ }
510
+ } else {
511
+ // -- table styles
512
+ const es = tr.style;
513
+ // alignment
514
+ if (this.#state.figureElement) {
515
+ this.#state.figureElement.style.float = cellAlignment;
516
+ this.#state.figureElement.style.verticalAlign = cellAlignmentVertical;
517
+ }
518
+ // back
519
+ es.backgroundColor = backColor;
520
+ // font
521
+ es.color = fontColor;
522
+ // font style
523
+ this.#setFontStyle(es);
524
+ // border
525
+ if (!hasBorder) {
526
+ // border - all || none
527
+ if (isNoneFormat) {
528
+ es.border = es.borderLeft = es.borderTop = es.borderRight = es.borderBottom = '';
529
+ } else {
530
+ es.border = borderCss;
531
+ }
532
+ }
533
+
534
+ cells.left = cells.top = cells.right = cells.bottom = targets;
535
+ }
536
+
537
+ cells.all = targets;
538
+
539
+ // border format
540
+ if (hasBorder) {
541
+ this.#setBorderStyles(cells, borderFormat, borderCss);
542
+ }
543
+
544
+ this.#main.historyPush();
545
+
546
+ // set cells style
547
+ this.controller_props.close();
548
+ if (this.#state.tdElement) {
549
+ this.#selectionService.recallStyleSelectedCells();
550
+ this.#main.setCellInfo(this.#state.tdElement, true);
551
+ dom.utils.addClass(this.#state.tdElement, 'se-selected-cell-focus');
552
+ }
553
+ } catch (err) {
554
+ console.warn('[SUNEDITOR.plugins.table.setProps.error]', err);
555
+ } finally {
556
+ target.disabled = false;
557
+ }
558
+ }
559
+
560
+ /**
561
+ * @description Closes the properties dialog.
562
+ */
563
+ closeProps() {
564
+ this.controller_props.close();
565
+ this.controller_colorPicker.close();
566
+ }
567
+
568
+ /**
569
+ * @description Updates control properties.
570
+ * @param {string} type The type of control property.
571
+ */
572
+ #setCtrlProps(type) {
573
+ this._typeCache = type;
574
+ const isTable = type === 'table';
575
+ const targets = isTable ? [this.#main._element] : this.#state.selectedCells;
576
+ if (!targets?.[0]) return;
577
+
578
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, cell_alignment_table_text, font_bold, font_underline, font_italic, font_strike } = this.propTargets;
579
+ const { border, backgroundColor, color, textAlign, verticalAlign, fontWeight, textDecoration, fontStyle } = _w.getComputedStyle(targets[0]);
580
+ const cellBorder = this.#getBorderStyle(border);
581
+
582
+ /** @type {HTMLElement} */ (cell_alignment.querySelector('[data-value="justify"]')).style.display = isTable ? 'none' : '';
583
+ cell_alignment_table_text.style.display = isTable ? '' : 'none';
584
+ if (isTable) cell_alignment_vertical.style.display = 'none';
585
+ else cell_alignment_vertical.style.display = '';
586
+
587
+ let b_color = converter.rgb2hex(cellBorder.c),
588
+ b_style = cellBorder.s,
589
+ b_width = cellBorder.w,
590
+ backColor = converter.rgb2hex(backgroundColor),
591
+ fontColor = converter.rgb2hex(color),
592
+ bold = /.+/.test(fontWeight),
593
+ underline = /underline/i.test(textDecoration),
594
+ strike = /line-through/i.test(textDecoration),
595
+ italic = /italic/i.test(fontStyle),
596
+ align = isTable ? this.#state.figureElement?.style.float : textAlign,
597
+ align_v = verticalAlign;
598
+ this._propsCache = [];
599
+
600
+ const tempColorStyles = _w.getComputedStyle(this.#$.eventManager.__focusTemp);
601
+ for (let i = 0, t, isBreak; (t = targets[i]); i++) {
602
+ // eslint-disable-next-line no-shadow
603
+ const { cssText, border, backgroundColor, color, textAlign, verticalAlign, fontWeight, textDecoration, fontStyle } = t.style;
604
+ this._propsCache.push([t, cssText]);
605
+ if (isBreak) continue;
606
+
607
+ const { c, s, w } = this.#getBorderStyle(border);
608
+
609
+ // colors
610
+ let hexBackColor = backgroundColor;
611
+ let hexColor = color;
612
+ if (hexBackColor) {
613
+ this.#$.eventManager.__focusTemp.style.backgroundColor = hexBackColor;
614
+ hexBackColor = tempColorStyles.backgroundColor;
615
+ }
616
+ if (hexColor) {
617
+ this.#$.eventManager.__focusTemp.style.color = hexColor;
618
+ hexColor = tempColorStyles.color;
619
+ }
620
+
621
+ if (b_color && cellBorder.c !== c) b_color = '';
622
+ if (b_style && cellBorder.s !== s) b_style = '';
623
+ if (b_width && cellBorder.w !== w) b_width = '';
624
+ if (backColor !== converter.rgb2hex(hexBackColor)) backColor = '';
625
+ if (fontColor !== converter.rgb2hex(hexColor)) fontColor = '';
626
+ if (align !== (isTable ? this.#state.figureElement?.style.float : textAlign)) align = '';
627
+ if (align_v && align_v !== verticalAlign) align_v = '';
628
+ if (bold && bold !== /.+/.test(fontWeight)) bold = false;
629
+ if (underline && underline !== /underline/i.test(textDecoration)) underline = false;
630
+ if (strike && strike !== /line-through/i.test(textDecoration)) strike = false;
631
+ if (italic && italic !== /italic/i.test(fontStyle)) italic = false;
632
+ if (!b_color || !b_style || !b_width || !backColor || !fontColor) {
633
+ isBreak = true;
634
+ }
635
+ }
636
+
637
+ // border - format
638
+ border_format.firstElementChild.innerHTML = this.#$.icons[Constants.BORDER_FORMATS[targets.length === 1 ? 'outside' : 'all']];
639
+ border_format.setAttribute('se-border-format', 'all');
640
+ dom.utils.removeClass(border_format, 'active');
641
+
642
+ // border - styles
643
+ b_style ||= Constants.BORDER_LIST[0];
644
+ border_style.textContent = b_style;
645
+ border_color.style.borderColor = border_color.value = b_color;
646
+ border_width.value = b_width;
647
+ this.#disableBorderProps(b_style === Constants.BORDER_LIST[0]);
648
+
649
+ // back, font color
650
+ back_color.value = back_color.style.borderColor = backColor;
651
+ font_color.value = font_color.style.borderColor = fontColor;
652
+
653
+ // font style
654
+ if (bold) dom.utils.addClass(font_bold, 'on');
655
+ if (underline) dom.utils.addClass(font_underline, 'on');
656
+ if (strike) dom.utils.addClass(font_strike, 'on');
657
+ if (italic) dom.utils.addClass(font_italic, 'on');
658
+
659
+ // align
660
+ this.#setAlignProps(cell_alignment, (this._propsAlignCache = align), true);
661
+ this.#setAlignProps(cell_alignment_vertical, (this._propsVerticalAlignCache = align_v), true);
662
+ }
663
+
664
+ /**
665
+ * @description Sets font styles.
666
+ * @param {CSSStyleDeclaration} styles The style object to modify.
667
+ */
668
+ #setFontStyle(styles) {
669
+ const { font_bold, font_italic, font_strike, font_underline } = this.propTargets;
670
+ styles.fontWeight = dom.utils.hasClass(font_bold, 'on') ? 'bold' : '';
671
+ styles.fontStyle = dom.utils.hasClass(font_italic, 'on') ? 'italic' : '';
672
+ styles.textDecoration = ((dom.utils.hasClass(font_strike, 'on') ? 'line-through ' : '') + (dom.utils.hasClass(font_underline, 'on') ? 'underline' : '')).trim();
673
+ }
674
+
675
+ /**
676
+ * @description Gets the border style.
677
+ * @param {string} borderStyle The border style string.
678
+ * @returns {{w: string, s: string, c: string}} The parsed border style object.
679
+ * - `w`: The border width.
680
+ * - `s`: The border style.
681
+ * - `c`: The border color.
682
+ */
683
+ #getBorderStyle(borderStyle) {
684
+ const parts = borderStyle.split(/\s(?![^()]*\))/);
685
+ let w = '',
686
+ s = '',
687
+ c = '';
688
+
689
+ if (parts.length === 3) {
690
+ w = parts[0];
691
+ s = parts[1];
692
+ c = parts[2];
693
+ } else if (parts.length === 2) {
694
+ if (/\d/.test(parts[0])) {
695
+ w = parts[0];
696
+ s = parts[1];
697
+ } else {
698
+ s = parts[0];
699
+ c = parts[1];
700
+ }
701
+ } else if (parts.length === 1) {
702
+ if (/\d/.test(parts[0])) {
703
+ w = parts[0];
704
+ } else {
705
+ s = parts[0];
706
+ }
707
+ }
708
+
709
+ return { w, s, c: converter.rgb2hex(c) };
710
+ }
711
+
712
+ /**
713
+ * @description Sets border format and styles.
714
+ * @param {{left: Node[], top: Node[], right: Node[], bottom: Node[], all: Node[]}} cells The table cells categorized by border positions.
715
+ * @param {string} borderKey Border style (`all`|`inside`|`horizon`|`vertical`|`outside`|`left`|`top`|`right`|`bottom`)
716
+ * @param {string} s The border style value.
717
+ */
718
+ #setBorderStyles(cells, borderKey, s) {
719
+ const { left, top, right, bottom, all } = cells;
720
+ switch (borderKey) {
721
+ case 'inside':
722
+ if (all.length === 1) return;
723
+ dom.utils.setStyle(
724
+ all.filter((c) => !bottom.includes(c)),
725
+ Constants.BORDER_NS.b,
726
+ s,
727
+ );
728
+ dom.utils.setStyle(
729
+ all.filter((c) => !right.includes(c)),
730
+ Constants.BORDER_NS.r,
731
+ s,
732
+ );
733
+ break;
734
+ case 'horizon':
735
+ if (all.length === 1) return;
736
+ dom.utils.setStyle(
737
+ all.filter((c) => !bottom.includes(c)),
738
+ Constants.BORDER_NS.b,
739
+ s,
740
+ );
741
+ break;
742
+ case 'vertical':
743
+ if (all.length === 1) return;
744
+ dom.utils.setStyle(
745
+ all.filter((c) => !right.includes(c)),
746
+ Constants.BORDER_NS.r,
747
+ s,
748
+ );
749
+ break;
750
+ case 'outside':
751
+ dom.utils.setStyle(left, Constants.BORDER_NS.l, s);
752
+ dom.utils.setStyle(top, Constants.BORDER_NS.t, s);
753
+ dom.utils.setStyle(right, Constants.BORDER_NS.r, s);
754
+ dom.utils.setStyle(bottom, Constants.BORDER_NS.b, s);
755
+ break;
756
+ case 'left':
757
+ dom.utils.setStyle(left, Constants.BORDER_NS.l, s);
758
+ break;
759
+ case 'top':
760
+ dom.utils.setStyle(top, Constants.BORDER_NS.t, s);
761
+ break;
762
+ case 'right':
763
+ dom.utils.setStyle(right, Constants.BORDER_NS.r, s);
764
+ break;
765
+ case 'bottom':
766
+ dom.utils.setStyle(bottom, Constants.BORDER_NS.b, s);
767
+ break;
768
+ }
769
+ }
770
+
771
+ /**
772
+ * @description Disables or enables border properties.
773
+ * @param {boolean} disabled Whether to disable or enable border properties.
774
+ */
775
+ #disableBorderProps(disabled) {
776
+ const { border_color, border_width, palette_border_button } = this.propTargets;
777
+ if (disabled) {
778
+ border_color.disabled = true;
779
+ border_width.disabled = true;
780
+ palette_border_button.disabled = true;
781
+ border_width.disabled = true;
782
+ } else {
783
+ border_color.disabled = false;
784
+ border_width.disabled = false;
785
+ palette_border_button.disabled = false;
786
+ border_width.disabled = false;
787
+ }
788
+ }
789
+
790
+ /**
791
+ * @description Sets text alignment properties.
792
+ * @param {Element} el The element to apply alignment to.
793
+ * @param {string} align The alignment value.
794
+ * @param {boolean} reset Whether to reset the alignment.
795
+ */
796
+ #setAlignProps(el, align, reset) {
797
+ dom.utils.removeClass(el.querySelectorAll('button'), 'on');
798
+
799
+ if (!reset && el.getAttribute('se-cell-align') === align) {
800
+ el.setAttribute('se-cell-align', '');
801
+ return;
802
+ }
803
+
804
+ dom.utils.addClass(el.querySelector(`[data-value="${align}"]`), 'on');
805
+ el.setAttribute('se-cell-align', align);
806
+ }
807
+
808
+ /**
809
+ * @description Handles border style changes in table properties.
810
+ * @param {string} command The border style command.
811
+ */
812
+ #OnPropsBorderEdit(command) {
813
+ this.propTargets.border_style.textContent = command;
814
+ this.#disableBorderProps(command === Constants.BORDER_LIST[0]);
815
+ this.selectMenu_props_border.close();
816
+ }
817
+
818
+ /**
819
+ * @description Handles border format changes in table properties.
820
+ * @param {string} defaultCommand The default border format command.
821
+ * @param {string} command The new border format command.
822
+ */
823
+ #OnPropsBorderFormatEdit(defaultCommand, command) {
824
+ const { border_format } = this.propTargets;
825
+
826
+ border_format.setAttribute('se-border-format', command);
827
+ border_format.firstElementChild.innerHTML = this.#$.icons[Constants.BORDER_FORMATS[command]];
828
+ if (command !== defaultCommand) dom.utils.addClass(border_format, 'active');
829
+ else dom.utils.removeClass(border_format, 'active');
830
+
831
+ this.selectMenu_props_border_format.close();
832
+ this.selectMenu_props_border_format_oneCell.close();
833
+ }
834
+
835
+ /**
836
+ * @description Initialize the style service (resets properties).
837
+ */
838
+ init() {
839
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, font_bold, font_underline, font_italic, font_strike } = this.propTargets;
840
+ dom.utils.removeClass([border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, font_bold, font_underline, font_italic, font_strike], 'on');
841
+ }
842
+ }
843
+
844
+ export default TableStyleService;