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,944 @@
1
+ import KernelInjector from '../kernel/kernelInjector';
2
+ import { dom, unicode, numbers, env, converter } from '../../helper';
3
+ import { _DragHandle } from '../../modules/ui';
4
+
5
+ // event handlers
6
+ import { ButtonsHandler, OnClick_menuTray, OnClick_toolbar } from '../event/handlers/handler_toolbar';
7
+ import { OnMouseDown_wysiwyg, OnMouseUp_wysiwyg, OnClick_wysiwyg, OnMouseMove_wysiwyg, OnMouseLeave_wysiwyg } from '../event/handlers/handler_ww_mouse';
8
+ import { OnBeforeInput_wysiwyg, OnInput_wysiwyg } from '../event/handlers/handler_ww_input';
9
+ import { OnKeyDown_wysiwyg, OnKeyUp_wysiwyg } from '../event/handlers/handler_ww_key';
10
+ import { OnPaste_wysiwyg, OnCopy_wysiwyg, OnCut_wysiwyg } from '../event/handlers/handler_ww_clipboard';
11
+ import { OnDragOver_wysiwyg, OnDragEnd_wysiwyg, OnDrop_wysiwyg } from '../event/handlers/handler_ww_dragDrop';
12
+
13
+ // logic
14
+ import DefaultLineManager from '../event/support/defaultLineManager';
15
+ import SelectionState from '../event/support/selectionState';
16
+
17
+ const { _w, isMobile, isTouchDevice } = env;
18
+
19
+ /**
20
+ * @description Event orchestrator
21
+ */
22
+ class EventOrchestrator extends KernelInjector {
23
+ #store;
24
+ #contextProvider;
25
+ #context;
26
+ #options;
27
+ #eventManager;
28
+ #toolbar;
29
+ #ui;
30
+ #menu;
31
+
32
+ /** @type {number} */
33
+ #balloonDelay = null;
34
+ /** @type {?SunEditor.Event.GlobalInfo} */
35
+ #close_move = null;
36
+ /** @type {?SunEditor.Event.GlobalInfo} */
37
+ #selectionSyncEvent = null;
38
+ /** @type {?SunEditor.Event.GlobalInfo} */
39
+ #resize_editor = null;
40
+
41
+ /**
42
+ * @constructor
43
+ * @param {SunEditor.Kernel} kernel
44
+ */
45
+ constructor(kernel) {
46
+ super(kernel);
47
+
48
+ this.#store = this.$.store;
49
+ this.#contextProvider = this.$.contextProvider;
50
+ this.#context = this.$.context;
51
+ this.#options = this.$.options;
52
+ this.#eventManager = this.$.eventManager;
53
+ this.#toolbar = this.$.toolbar;
54
+ this.#ui = this.$.ui;
55
+ this.#menu = this.$.menu;
56
+
57
+ /**
58
+ * @description Old browsers: When there is no `e.isComposing` in the `keyup` event
59
+ * @type {boolean}
60
+ */
61
+ this.isComposing = false;
62
+
63
+ /**
64
+ * @description An array of parent containers that can be scrolled (in descending order)
65
+ * @type {Array<Element>}
66
+ */
67
+ this.scrollparents = [];
68
+
69
+ // logic services (internal - receive EventManager reference)
70
+ this.defaultLineManager = new DefaultLineManager(this);
71
+ this.selectionState = new SelectionState(this);
72
+
73
+ // internal members
74
+ /** @internal @type {boolean} */
75
+ this._onShortcutKey = false;
76
+ /** @internal @type {boolean} */
77
+ this._handledInBefore = false;
78
+ /** @internal @type {ResizeObserver} */
79
+ this._wwFrameObserver = null;
80
+ /** @internal @type {ResizeObserver} */
81
+ this._toolbarObserver = null;
82
+ /** @internal @type {?Element} */
83
+ this._lineBreakComp = null;
84
+ /** @internal @type {?Object<string, *>} */
85
+ this._formatAttrsTemp = null;
86
+ /** @internal @type {number} */
87
+ this._resizeClientY = 0;
88
+ /** @internal @type {Array<Node>} */
89
+ this.__cacheStyleNodes = [];
90
+ this.__onDownEv = null;
91
+
92
+ // input plugins
93
+ /** @internal @type {boolean} */
94
+ this._inputFocus = false;
95
+ /** @internal @type {?Object<string, *>} */
96
+ this.__inputPlugin = null;
97
+ /** @internal @type {?SunEditor.Event.Info=} */
98
+ this.__inputBlurEvent = null;
99
+ /** @internal @type {?SunEditor.Event.Info=} */
100
+ this.__inputKeyEvent = null;
101
+
102
+ // viewport
103
+ /** @type {number|void} */
104
+ this.__retainTimer = null;
105
+ /** @type {Document} */
106
+ this.__eventDoc = null;
107
+ /** @type {string} */
108
+ this.__secopy = null;
109
+ }
110
+
111
+ /**
112
+ * @description Activates the corresponding button with the tags information of the current cursor position,
113
+ * - such as `bold`, `underline`, etc., and executes the `active` method of the plugins.
114
+ * @param {?Node} [selectionNode] selectionNode
115
+ * @returns {Node|undefined} selectionNode
116
+ */
117
+ applyTagEffect(selectionNode) {
118
+ return this.selectionState.update(selectionNode);
119
+ }
120
+
121
+ /**
122
+ * @internal
123
+ * @description Show toolbar-balloon with delay.
124
+ */
125
+ _showToolbarBalloonDelay() {
126
+ if (this.#balloonDelay) {
127
+ _w.clearTimeout(this.#balloonDelay);
128
+ }
129
+
130
+ this.#balloonDelay = _w.setTimeout(() => {
131
+ _w.clearTimeout(this.#balloonDelay);
132
+ this.#balloonDelay = null;
133
+ if (this.#store.mode.isSubBalloon) this.$.subToolbar._showBalloon();
134
+ else this.#toolbar._showBalloon();
135
+ }, 250);
136
+ }
137
+
138
+ /**
139
+ * @internal
140
+ * @description Show or hide the toolbar-balloon.
141
+ */
142
+ _toggleToolbarBalloon() {
143
+ this.$.selection.init();
144
+ const range = this.$.selection.getRange();
145
+ const hasSubMode = this.#options.has('_subMode');
146
+
147
+ if (!(hasSubMode ? this.#store.mode.isSubBalloonAlways : this.#store.mode.isBalloonAlways) && range.collapsed) {
148
+ if (hasSubMode) this._hideToolbar_sub();
149
+ else this._hideToolbar();
150
+ } else {
151
+ if (hasSubMode) this.$.subToolbar._showBalloon(range);
152
+ else this.#toolbar._showBalloon(range);
153
+ }
154
+ }
155
+
156
+ /**
157
+ * @internal
158
+ * @description Hide the toolbar.
159
+ */
160
+ _hideToolbar() {
161
+ if (!this.#ui.isPreventToolbarHide && !this.$.frameContext.get('isFullScreen')) {
162
+ this.#toolbar.hide();
163
+ }
164
+ }
165
+
166
+ /**
167
+ * @internal
168
+ * @description Hide the Sub-Toolbar.
169
+ */
170
+ _hideToolbar_sub() {
171
+ if (this.$.subToolbar && !this.#ui.isPreventToolbarHide) {
172
+ this.$.subToolbar.hide();
173
+ }
174
+ }
175
+
176
+ /**
177
+ * @internal
178
+ * @description If there is no default format, add a `line` and move `selection`.
179
+ * @param {?string} formatName Format tag name (default: `P`)
180
+ */
181
+ _setDefaultLine(formatName) {
182
+ return this.defaultLineManager.execute(formatName);
183
+ }
184
+
185
+ /**
186
+ * @internal
187
+ * @description Handles data transfer actions for `paste` and `drop` events.
188
+ * - It processes clipboard data, triggers relevant events, and inserts cleaned data into the editor.
189
+ * @param {"paste"|"drop"} type The type of event
190
+ * @param {Event} e The original event object
191
+ * @param {DataTransfer} clipboardData The clipboard data object
192
+ * @param {SunEditor.FrameContext} frameContext The frame context
193
+ * @returns {Promise<boolean>} Resolves to `false` if processing is complete, otherwise allows default behavior
194
+ */
195
+ async _dataTransferAction(type, e, clipboardData, frameContext) {
196
+ try {
197
+ this.#ui.showLoading();
198
+ await this.#setClipboardData(type, e, clipboardData, frameContext);
199
+ e.preventDefault();
200
+ e.stopPropagation();
201
+ return false;
202
+ } catch (err) {
203
+ console.warn('[SUNEDITOR.paste.error]', err);
204
+ } finally {
205
+ this.#ui.hideLoading();
206
+ }
207
+ }
208
+
209
+ /**
210
+ * @internal
211
+ * @description Processes clipboard data for `paste` and `drop` events, handling text and HTML cleanup.
212
+ * - Supports specific handling for content from Microsoft Office applications.
213
+ * @param {"paste"|"drop"} type The type of event
214
+ * @param {Event} e The original event object
215
+ * @param {DataTransfer} clipboardData The clipboard data object
216
+ * @param {SunEditor.FrameContext} frameContext The frame context
217
+ * @returns {Promise<boolean>} Resolves to `false` if processing is complete, otherwise allows default behavior
218
+ */
219
+ async #setClipboardData(type, e, clipboardData, frameContext) {
220
+ e.preventDefault();
221
+ e.stopPropagation();
222
+
223
+ let plainText = clipboardData.getData('text/plain');
224
+ let cleanData = clipboardData.getData('text/html');
225
+ const onlyText = !cleanData;
226
+
227
+ // SE copy data
228
+ const SEData = this.__secopy === plainText;
229
+ // MS word, OneNode, Excel
230
+ const MSData = /class=["']*Mso(Normal|List)/i.test(cleanData) || /content=["']*Word.Document/i.test(cleanData) || /content=["']*OneNote.File/i.test(cleanData) || /content=["']*Excel.Sheet/i.test(cleanData);
231
+ // from
232
+ const from = SEData ? 'SE' : MSData ? 'MS' : '';
233
+
234
+ if (onlyText) {
235
+ cleanData = converter.htmlToEntity(plainText).replace(/\n/g, '<br>');
236
+ } else {
237
+ cleanData = cleanData.replace(/^<html>\r?\n?<body>\r?\n?\x3C!--StartFragment-->|\x3C!--EndFragment-->\r?\n?<\/body>\r?\n?<\/html>$/g, '');
238
+ if (MSData) {
239
+ cleanData = cleanData.replace(/\n/g, ' ');
240
+ plainText = plainText.replace(/\n/g, ' ');
241
+ }
242
+ }
243
+
244
+ if (!SEData) {
245
+ const autoLinkify = this.#options.get('autoLinkify');
246
+ if (autoLinkify) {
247
+ const domParser = new DOMParser().parseFromString(cleanData, 'text/html');
248
+ dom.query.getListChildNodes(domParser.body, converter.textToAnchor, null);
249
+ cleanData = domParser.body.innerHTML;
250
+ }
251
+ }
252
+
253
+ if (!onlyText) {
254
+ cleanData = this.$.html.clean(cleanData, { forceFormat: false, whitelist: null, blacklist: null });
255
+ }
256
+
257
+ const maxCharCount = this.$.char.test(this.$.frameOptions.get('charCounter_type') === 'byte-html' ? cleanData : plainText, false);
258
+ // user event - paste
259
+ if (type === 'paste') {
260
+ const value = await this.#eventManager.triggerEvent('onPaste', { frameContext, event: e, data: cleanData, maxCharCount, from });
261
+ if (value === false) {
262
+ return false;
263
+ } else if (typeof value === 'string') {
264
+ if (!value) return false;
265
+ cleanData = value;
266
+ }
267
+ }
268
+ // user event - drop
269
+ if (type === 'drop') {
270
+ const value = await this.#eventManager.triggerEvent('onDrop', { frameContext, event: e, data: cleanData, maxCharCount, from });
271
+ if (value === false) {
272
+ return false;
273
+ } else if (typeof value === 'string') {
274
+ if (!value) return false;
275
+ cleanData = value;
276
+ }
277
+ }
278
+
279
+ // files
280
+ const files = clipboardData.files;
281
+ if (files.length > 0 && !MSData) {
282
+ for (let i = 0, len = files.length; i < len; i++) {
283
+ await this._callPluginEventAsync('onFilePasteAndDrop', { frameContext, event: e, file: files[i] });
284
+ }
285
+
286
+ return false;
287
+ }
288
+
289
+ if (!maxCharCount) {
290
+ return false;
291
+ }
292
+
293
+ if (cleanData) {
294
+ const domParser = new DOMParser().parseFromString(cleanData, 'text/html');
295
+ if ((await this._callPluginEventAsync('onPaste', { frameContext, event: e, data: cleanData, doc: domParser })) !== false) {
296
+ this.$.html.insert(cleanData, { selectInserted: false, skipCharCount: true, skipCleaning: true });
297
+ }
298
+
299
+ // document type
300
+ if (frameContext.has('documentType_use_header')) {
301
+ frameContext.get('documentType').reHeader();
302
+ }
303
+ return false;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * @internal
309
+ * @description Registers common UI events such as toolbar and menu interactions.
310
+ * - Adds event listeners for various UI elements, sets up observers, and configures window events.
311
+ */
312
+ _addCommonEvents() {
313
+ const buttonsHandler = ButtonsHandler.bind(this);
314
+ const toolbarHandler = OnClick_toolbar.bind(this);
315
+
316
+ /** menu event */
317
+ this.#eventManager.addEvent(this.#context.get('menuTray'), 'mousedown', buttonsHandler, false);
318
+ this.#eventManager.addEvent(this.#context.get('menuTray'), 'click', OnClick_menuTray.bind(this), true);
319
+
320
+ /** toolbar event */
321
+ this.#eventManager.addEvent(this.#context.get('toolbar_main'), 'mousedown', buttonsHandler, false);
322
+ this.#eventManager.addEvent(this.#context.get('toolbar_main'), 'click', toolbarHandler, false);
323
+ // subToolbar
324
+ if (this.#options.has('_subMode')) {
325
+ this.#eventManager.addEvent(this.#context.get('toolbar_sub_main'), 'mousedown', buttonsHandler, false);
326
+ this.#eventManager.addEvent(this.#context.get('toolbar_sub_main'), 'click', toolbarHandler, false);
327
+ }
328
+
329
+ /** set response toolbar */
330
+ this.#toolbar._setResponsive();
331
+
332
+ /** observer */
333
+ if (env.isResizeObserverSupported) {
334
+ this._toolbarObserver = new ResizeObserver(() => {
335
+ // Defer to avoid ResizeObserver loop limit — layout must settle before recalculating responsive buttons
336
+ _w.setTimeout(() => {
337
+ this.#toolbar.resetResponsiveToolbar();
338
+ }, 0);
339
+ });
340
+ this._wwFrameObserver = new ResizeObserver((entries) => {
341
+ // Defer to avoid ResizeObserver loop limit — measure final height after reflow completes
342
+ _w.setTimeout(() => {
343
+ entries.forEach((e) => {
344
+ this.#ui._emitResizeEvent(this.$.frameRoots.get(e.target.getAttribute('data-root-key')), -1, e);
345
+ });
346
+ }, 0);
347
+ });
348
+ }
349
+
350
+ /** modal outside click */
351
+ if (this.#options.get('closeModalOutsideClick')) {
352
+ this.#eventManager.addEvent(
353
+ this.#contextProvider.carrierWrapper.querySelector('.se-modal .se-modal-inner'),
354
+ 'click',
355
+ (e) => {
356
+ if (e.target === this.#contextProvider.carrierWrapper.querySelector('.se-modal .se-modal-inner')) {
357
+ this.#ui.offCurrentModal();
358
+ }
359
+ },
360
+ false,
361
+ );
362
+ }
363
+
364
+ /** global event */
365
+ this.#eventManager.addEvent(_w, 'resize', this.#OnResize_window.bind(this), false);
366
+ this.#eventManager.addEvent(_w.visualViewport, 'resize', this.#OnResize_viewport.bind(this), false);
367
+ this.#eventManager.addEvent(_w, 'scroll', this.#OnScroll_window.bind(this), false);
368
+ if (isTouchDevice) {
369
+ this.#eventManager.addEvent(_w.visualViewport, 'scroll', this.#OnMobileScroll_viewport.bind(this), false);
370
+ }
371
+ }
372
+
373
+ /**
374
+ * @internal
375
+ * @description Registers event listeners for the editor's frame, including text `input`, selection, and UI interactions.
376
+ * - Handles events inside an `iframe` or within the standard wysiwyg editor.
377
+ * @param {SunEditor.FrameContext} fc The frame context object
378
+ */
379
+ _addFrameEvents(fc) {
380
+ const isIframe = fc.get('options').get('iframe');
381
+ const eventWysiwyg = isIframe ? fc.get('_ww') : fc.get('wysiwyg');
382
+ fc.set('eventWysiwyg', /** @type {SunEditor.EventWysiwyg} */ (eventWysiwyg));
383
+ const codeArea = fc.get('code');
384
+ const dragCursor = this.#contextProvider.carrierWrapper.querySelector('.se-drag-cursor');
385
+
386
+ /** editor area */
387
+ const wwMouseMove = OnMouseMove_wysiwyg.bind(this, fc);
388
+ this.#eventManager.addEvent(eventWysiwyg, 'mousemove', wwMouseMove, false);
389
+ this.#eventManager.addEvent(eventWysiwyg, 'mouseleave', OnMouseLeave_wysiwyg.bind(this, fc), false);
390
+ this.#eventManager.addEvent(eventWysiwyg, 'mousedown', OnMouseDown_wysiwyg.bind(this, fc), false);
391
+ this.#eventManager.addEvent(eventWysiwyg, 'mouseup', OnMouseUp_wysiwyg.bind(this, fc), false);
392
+ this.#eventManager.addEvent(eventWysiwyg, 'click', OnClick_wysiwyg.bind(this, fc), false);
393
+ this.#eventManager.addEvent(eventWysiwyg, 'beforeinput', OnBeforeInput_wysiwyg.bind(this, fc), false);
394
+ this.#eventManager.addEvent(eventWysiwyg, 'input', OnInput_wysiwyg.bind(this, fc), false);
395
+ this.#eventManager.addEvent(eventWysiwyg, 'keydown', OnKeyDown_wysiwyg.bind(this, fc), false);
396
+ this.#eventManager.addEvent(eventWysiwyg, 'keyup', OnKeyUp_wysiwyg.bind(this, fc), false);
397
+ this.#eventManager.addEvent(eventWysiwyg, 'paste', OnPaste_wysiwyg.bind(this, fc), false);
398
+ this.#eventManager.addEvent(eventWysiwyg, 'copy', OnCopy_wysiwyg.bind(this, fc), false);
399
+ this.#eventManager.addEvent(eventWysiwyg, 'cut', OnCut_wysiwyg.bind(this, fc), false);
400
+ this.#eventManager.addEvent(
401
+ eventWysiwyg,
402
+ 'dragover',
403
+ OnDragOver_wysiwyg.bind(this, fc, dragCursor, isIframe ? this.$.frameContext.get('topArea') : null, !this.#options.get('toolbar_container') && !this.#store.mode.isBalloon && !this.#store.mode.isInline),
404
+ false,
405
+ );
406
+ this.#eventManager.addEvent(eventWysiwyg, 'dragend', OnDragEnd_wysiwyg.bind(this, dragCursor), false);
407
+ this.#eventManager.addEvent(eventWysiwyg, 'drop', OnDrop_wysiwyg.bind(this, fc, dragCursor), false);
408
+ this.#eventManager.addEvent(eventWysiwyg, 'scroll', this.#OnScroll_wysiwyg.bind(this, fc, eventWysiwyg), { passive: true, capture: false });
409
+ this.#eventManager.addEvent(eventWysiwyg, 'focus', this.#OnFocus_wysiwyg.bind(this, fc), false);
410
+ this.#eventManager.addEvent(eventWysiwyg, 'blur', this.#OnBlur_wysiwyg.bind(this, fc), false);
411
+ this.#eventManager.addEvent(codeArea, 'mousedown', this.#OnFocus_code.bind(this, fc), false);
412
+
413
+ /** drag handle */
414
+ const dragHandle = fc.get('wrapper').querySelector('.se-drag-handle');
415
+ this.#eventManager.addEvent(
416
+ dragHandle,
417
+ 'wheel',
418
+ (event) => {
419
+ event.preventDefault();
420
+ this.$.component.deselect();
421
+ },
422
+ false,
423
+ );
424
+
425
+ /** line breaker */
426
+ this.#eventManager.addEvent(fc.get('lineBreaker_t'), 'pointerdown', this.#DisplayLineBreak.bind(this, 't'), false);
427
+ this.#eventManager.addEvent(fc.get('lineBreaker_b'), 'pointerdown', this.#DisplayLineBreak.bind(this, 'b'), false);
428
+
429
+ /** Events are registered mobile. */
430
+ if (isTouchDevice) {
431
+ this.#eventManager.addEvent(eventWysiwyg, 'touchstart', wwMouseMove, {
432
+ passive: true,
433
+ capture: false,
434
+ });
435
+ }
436
+
437
+ /** code view area auto line */
438
+ if (!this.#options.get('hasCodeMirror')) {
439
+ const codeNumbers = fc.get('codeNumbers');
440
+ const cvAuthHeight = this.$.viewer._codeViewAutoHeight.bind(this.$.viewer, fc.get('code'), codeNumbers, this.$.frameOptions.get('height') === 'auto');
441
+
442
+ this.#eventManager.addEvent(codeArea, 'keydown', cvAuthHeight, false);
443
+ this.#eventManager.addEvent(codeArea, 'keyup', cvAuthHeight, false);
444
+ this.#eventManager.addEvent(codeArea, 'paste', cvAuthHeight, false);
445
+
446
+ /** code view numbers */
447
+ if (codeNumbers) this.#eventManager.addEvent(codeArea, 'scroll', this.$.viewer._scrollLineNumbers.bind(codeArea, codeNumbers), false);
448
+ }
449
+
450
+ if (fc.has('statusbar')) this.__addStatusbarEvent(fc, fc.get('options'));
451
+
452
+ const OnScrollAbs = this.#OnScroll_Abs.bind(this);
453
+ const scrollParents = dom.query.getScrollParents(fc.get('originElement'));
454
+ for (const parent of scrollParents) {
455
+ this.scrollparents.push(parent);
456
+ this.#eventManager.addEvent(parent, 'scroll', OnScrollAbs, false);
457
+ }
458
+
459
+ /** focus temp (mobile) */
460
+ this.#eventManager.addEvent(this.__focusTemp, 'focus', (e) => e.preventDefault(), false);
461
+
462
+ /** document event */
463
+ if (this.__eventDoc !== fc.get('_wd')) {
464
+ this.__eventDoc = fc.get('_wd');
465
+ this.#eventManager.addEvent(this.__eventDoc, 'selectionchange', this.#OnSelectionchange_document.bind(this, this.__eventDoc), false);
466
+ }
467
+ }
468
+
469
+ /**
470
+ * @internal
471
+ * @description Adds event listeners for resizing the status bar if resizing is enabled.
472
+ * - If resizing is not enabled, applies a `se-resizing-none` class.
473
+ * @param {SunEditor.FrameContext} fc The frame context object
474
+ * @param {SunEditor.FrameOptions} fo The frame options object
475
+ */
476
+ __addStatusbarEvent(fc, fo) {
477
+ if (/\d+/.test(fo.get('height')) && fo.get('statusbar_resizeEnable')) {
478
+ fo.set('__statusbarEvent', this.#eventManager.addEvent(fc.get('statusbar'), 'mousedown', this.#OnMouseDown_statusbar.bind(this), false));
479
+ } else {
480
+ dom.utils.addClass(fc.get('statusbar'), 'se-resizing-none');
481
+ }
482
+ }
483
+
484
+ /**
485
+ * @internal
486
+ * @description Removes all registered event listeners from the editor.
487
+ * - Disconnects observers and clears stored event references.
488
+ */
489
+ _removeAllEvents() {
490
+ this.#eventManager._init();
491
+
492
+ if (this._wwFrameObserver) {
493
+ this._wwFrameObserver.disconnect();
494
+ this._wwFrameObserver = null;
495
+ }
496
+
497
+ if (this._toolbarObserver) {
498
+ this._toolbarObserver.disconnect();
499
+ this._toolbarObserver = null;
500
+ }
501
+
502
+ // clear timers
503
+ if (this.#balloonDelay) {
504
+ _w.clearTimeout(this.#balloonDelay);
505
+ this.#balloonDelay = null;
506
+ }
507
+
508
+ if (this.__retainTimer) {
509
+ _w.clearTimeout(this.__retainTimer);
510
+ this.__retainTimer = null;
511
+ }
512
+
513
+ // remove global events
514
+
515
+ this.#selectionSyncEvent &&= this.#eventManager.removeGlobalEvent(this.#selectionSyncEvent);
516
+ this.#resize_editor &&= this.#eventManager.removeGlobalEvent(this.#resize_editor);
517
+ this.#close_move &&= this.#eventManager.removeGlobalEvent(this.#close_move);
518
+
519
+ // clear cached references
520
+ this._formatAttrsTemp = null;
521
+ this.__cacheStyleNodes = null;
522
+ this.__inputPlugin = null;
523
+ this.__inputBlurEvent = null;
524
+ this.__inputKeyEvent = null;
525
+ this.__focusTemp = null;
526
+ this.__eventDoc = null;
527
+ this.__secopy = null;
528
+ this._lineBreakComp = null;
529
+ this.scrollparents = null;
530
+ }
531
+
532
+ /**
533
+ * @internal
534
+ * @description Synchronizes the selection state by resetting it on `mouseup`.
535
+ * - Ensures selection updates correctly across different interactions.
536
+ */
537
+ _setSelectionSync() {
538
+ this.#eventManager.removeGlobalEvent(this.#selectionSyncEvent);
539
+ this.#selectionSyncEvent = this.#eventManager.addGlobalEvent('mouseup', () => {
540
+ this.$.selection.init();
541
+ this.#eventManager.removeGlobalEvent(this.#selectionSyncEvent);
542
+ });
543
+ }
544
+
545
+ /**
546
+ * @internal
547
+ * @description Retains the style nodes for formatting consistency when applying styles.
548
+ * - Preserves nested styling by cloning and restructuring the style nodes.
549
+ * @param {HTMLElement} formatEl The format element where styles should be retained
550
+ * @param {Array<Node>} _styleNodes The list of style nodes to retain
551
+ */
552
+ _retainStyleNodes(formatEl, _styleNodes) {
553
+ const el = _styleNodes[0].cloneNode(false);
554
+ let n = el;
555
+ for (let i = 1, len = _styleNodes.length, t; i < len; i++) {
556
+ t = _styleNodes[i].cloneNode(false);
557
+ n.appendChild(t);
558
+ n = t;
559
+ }
560
+
561
+ const { parent, inner } = this.$.nodeTransform.createNestedNode(_styleNodes, null);
562
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
563
+ inner.appendChild(zeroWidth);
564
+
565
+ formatEl.innerHTML = '';
566
+ formatEl.appendChild(parent);
567
+
568
+ this.$.selection.setRange(zeroWidth, 1, zeroWidth, 1);
569
+ }
570
+
571
+ /**
572
+ * @internal
573
+ * @description Clears retained style nodes by replacing content with a single `line` break.
574
+ * - Resets the selection to the start of the cleared element.
575
+ * @param {HTMLElement} formatEl The format element where styles should be cleared
576
+ */
577
+ _clearRetainStyleNodes(formatEl) {
578
+ formatEl.innerHTML = '<br>';
579
+ this.$.selection.setRange(formatEl, 0, formatEl, 0);
580
+ }
581
+
582
+ /**
583
+ * @internal
584
+ * @description Calls a registered plugin event synchronously.
585
+ * @param {string} name The name of the plugin event
586
+ * @param {SunEditor.EventParams.PluginEvent} e The event payload
587
+ * @returns {boolean|undefined} Returns `false` if any handler stops the event
588
+ */
589
+ _callPluginEvent(name, e) {
590
+ return this.$.pluginManager.emitEvent(name, e);
591
+ }
592
+
593
+ /**
594
+ * @internal
595
+ * @description Calls a registered plugin event asynchronously.
596
+ * @param {string} name The name of the plugin event
597
+ * @param {SunEditor.EventParams.PluginEvent} e The event payload
598
+ * @returns {Promise<boolean|undefined>} Returns `false` if any handler stops the event
599
+ */
600
+ async _callPluginEventAsync(name, e) {
601
+ return await this.$.pluginManager.emitEventAsync(name, e);
602
+ }
603
+
604
+ /**
605
+ * @internal
606
+ * @description Removes input event listeners and resets input-related properties.
607
+ */
608
+ __removeInput() {
609
+ this.#store.set('_preventBlur', false);
610
+ this._inputFocus = false;
611
+ this.__inputBlurEvent = this.#eventManager.removeEvent(this.__inputBlurEvent);
612
+ this.__inputKeyEvent = this.#eventManager.removeEvent(this.__inputKeyEvent);
613
+ this.__inputPlugin = null;
614
+ }
615
+
616
+ /**
617
+ * @internal
618
+ * @description Focus Event Postprocessing
619
+ * @param {SunEditor.FrameContext} frameContext - frame context object
620
+ * @param {FocusEvent} event - Focus event object
621
+ */
622
+ __postFocusEvent(frameContext, event) {
623
+ if (this.#store.mode.isInline || this.#store.mode.isBalloonAlways) this.#toolbar.show();
624
+ if (this.#store.mode.isSubBalloonAlways) this.$.subToolbar.show();
625
+
626
+ // user event
627
+ this.#eventManager.triggerEvent('onFocus', { frameContext, event });
628
+ // plugin event
629
+ this._callPluginEvent('onFocus', { frameContext, event });
630
+ }
631
+
632
+ /**
633
+ * @internal
634
+ * @description Blur Event Postprocessing
635
+ * @param {SunEditor.FrameContext} frameContext - frame context object
636
+ * @param {FocusEvent} event - Focus event object
637
+ */
638
+ __postBlurEvent(frameContext, event) {
639
+ if (this.#store.mode.isInline || this.#store.mode.isBalloon) this._hideToolbar();
640
+ if (this.#store.mode.isSubBalloon) this._hideToolbar_sub();
641
+
642
+ // user event
643
+ this.#eventManager.triggerEvent('onBlur', { frameContext, event });
644
+ // plugin event
645
+ this._callPluginEvent('onBlur', { frameContext, event });
646
+ }
647
+
648
+ /**
649
+ * @internal
650
+ * @description Records the current viewport size.
651
+ */
652
+ __setViewportSize() {
653
+ this.#store.set('currentViewportHeight', numbers.get(_w.visualViewport.height, 0));
654
+ }
655
+
656
+ /**
657
+ * @description Handles the scrolling of the editor container.
658
+ * - Repositions open controllers if necessary.
659
+ */
660
+ #scrollContainer() {
661
+ if (this.#menu.currentDropdownActiveButton && this.#menu.currentDropdown) {
662
+ this.#menu.__resetMenuPosition(this.#menu.currentDropdownActiveButton, this.#menu.currentDropdown);
663
+ }
664
+
665
+ this.#ui._repositionControllers();
666
+ }
667
+
668
+ /**
669
+ * @description Resets the frame status, adjusting toolbar and UI elements based on the current state.
670
+ * - Handles `inline` editor adjustments, fullscreen mode, and responsive toolbar updates.
671
+ */
672
+ #resetFrameStatus() {
673
+ if (!env.isResizeObserverSupported) {
674
+ this.#toolbar.resetResponsiveToolbar();
675
+ if (this.#options.get('_subMode')) this.$.subToolbar.resetResponsiveToolbar();
676
+ }
677
+
678
+ const toolbar = this.#context.get('toolbar_main');
679
+ const isToolbarHidden = toolbar.style.display === 'none' || (this.#store.mode.isInline && !this.#toolbar.inlineToolbarAttr.isShow);
680
+ if (toolbar.offsetWidth === 0 && !isToolbarHidden) return;
681
+
682
+ const opendBrowser = this.#ui.opendBrowser;
683
+ if (opendBrowser && opendBrowser.area.style.display === 'block') {
684
+ opendBrowser.body.style.maxHeight = dom.utils.getClientSize().h - opendBrowser.header.offsetHeight - 50 + 'px';
685
+ }
686
+
687
+ if (this.#menu.currentDropdownActiveButton && this.#menu.currentDropdown) {
688
+ this.#menu.__resetMenuPosition(this.#menu.currentDropdownActiveButton, this.#menu.currentDropdown);
689
+ }
690
+
691
+ if (this.$.viewer._resetFullScreenHeight()) return;
692
+
693
+ const fc = this.$.frameContext;
694
+ if (fc.get('isCodeView') && this.#store.mode.isInline) {
695
+ this.#toolbar._showInline();
696
+ return;
697
+ }
698
+
699
+ this.#ui._iframeAutoHeight(fc);
700
+
701
+ if (this.#toolbar.isSticky) {
702
+ this.#context.get('toolbar_main').style.width = fc.get('topArea').offsetWidth - 2 + 'px';
703
+ this.#toolbar._resetSticky();
704
+ }
705
+ }
706
+
707
+ /**
708
+ * @param {SunEditor.FrameContext} frameContext - frame context object
709
+ * @param {SunEditor.EventWysiwyg} eventWysiwyg - wysiwyg event object
710
+ * @param {Event} e - Event object
711
+ */
712
+ #OnScroll_wysiwyg(frameContext, eventWysiwyg, e) {
713
+ this.#ui._syncScrollPosition(eventWysiwyg);
714
+ this.#scrollContainer();
715
+
716
+ // plugin event
717
+ this._callPluginEvent('onScroll', { frameContext, event: e });
718
+
719
+ // document type page
720
+ if (frameContext.has('documentType_use_page')) {
721
+ frameContext.get('documentType').scrollPage();
722
+ }
723
+
724
+ // user event
725
+ this.#eventManager.triggerEvent('onScroll', { frameContext, event: e });
726
+ }
727
+
728
+ /**
729
+ * @param {SunEditor.FrameContext} frameContext - frame context object
730
+ * @param {FocusEvent} e - Focus event object
731
+ */
732
+ #OnFocus_wysiwyg(frameContext, e) {
733
+ if (this.$.selection.__iframeFocus || frameContext.get('isReadOnly') || frameContext.get('isDisabled')) {
734
+ e.preventDefault();
735
+ return false;
736
+ }
737
+
738
+ this.#store.set('hasFocus', true);
739
+ this.$.component.__prevent = false;
740
+ this.#eventManager.triggerEvent('onNativeFocus', { frameContext, event: e });
741
+
742
+ const rootKey = frameContext.get('key');
743
+
744
+ if (this._inputFocus) {
745
+ if (this.#store.mode.isInline) {
746
+ // Defer inline toolbar show — browser focus event fires before selection is finalized
747
+ _w.setTimeout(() => {
748
+ this.#toolbar._showInline();
749
+ }, 0);
750
+ }
751
+ return;
752
+ }
753
+
754
+ if ((this.#store.get('rootKey') === rootKey && this.#store.get('_preventBlur')) || this.#store.get('_preventFocus')) return;
755
+ this.#store.set('_preventFocus', true);
756
+
757
+ dom.utils.removeClass(this.$.commandDispatcher.targets.get('codeView'), 'active');
758
+ this.#ui._toggleCodeViewButtons(false);
759
+
760
+ this.$.facade.changeFrameContext(rootKey);
761
+ this.$.history.resetButtons(rootKey, null);
762
+
763
+ // Defer focus event emission — allow blur handler on the previous frame to complete first
764
+ _w.setTimeout(() => {
765
+ this.__postFocusEvent(frameContext, e);
766
+ }, 0);
767
+ }
768
+
769
+ /**
770
+ * @param {SunEditor.FrameContext} frameContext - frame context object
771
+ * @param {FocusEvent} e - Focus event object
772
+ */
773
+ #OnBlur_wysiwyg(frameContext, e) {
774
+ if (frameContext.get('isCodeView') || frameContext.get('isReadOnly') || frameContext.get('isDisabled')) return;
775
+
776
+ this.#store.set('hasFocus', false);
777
+ this.#store.set('_lastSelectionNode', null);
778
+ this.#eventManager.triggerEvent('onNativeBlur', { frameContext, event: e });
779
+
780
+ if (this._inputFocus || this.#store.get('_preventBlur')) return;
781
+ this.#store.set('_preventFocus', false);
782
+
783
+ this.selectionState.reset();
784
+
785
+ this.#store.set('currentNodes', []);
786
+ this.#store.set('currentNodesMap', []);
787
+
788
+ this.#ui.offCurrentController();
789
+
790
+ this.#contextProvider.applyToRoots((root) => {
791
+ if (root.get('navigation')) root.get('navigation').textContent = '';
792
+ });
793
+
794
+ this.$.history.check(frameContext.get('key'), this.#store.get('_range'));
795
+
796
+ this.__postBlurEvent(frameContext, e);
797
+ }
798
+
799
+ /**
800
+ * @param {MouseEvent} e - Event object
801
+ */
802
+ #OnMouseDown_statusbar(e) {
803
+ e.stopPropagation();
804
+ this._resizeClientY = e.clientY;
805
+ this.#ui.enableBackWrapper('ns-resize');
806
+ this.#resize_editor = this.#eventManager.addGlobalEvent('mousemove', this.#__resizeEditor.bind(this));
807
+ this.#close_move = this.#eventManager.addGlobalEvent('mouseup', this.#__closeMove.bind(this));
808
+ }
809
+
810
+ /**
811
+ * @param {MouseEvent} e - Event object
812
+ */
813
+ #__resizeEditor(e) {
814
+ const fc = this.$.frameContext;
815
+ const resizeInterval = fc.get('wrapper').offsetHeight + (e.clientY - this._resizeClientY);
816
+ const h = resizeInterval < fc.get('_minHeight') ? fc.get('_minHeight') : resizeInterval;
817
+ fc.get('wysiwygFrame').style.height = fc.get('code').style.height = h + 'px';
818
+ this._resizeClientY = e.clientY;
819
+ if (!env.isResizeObserverSupported) this.#ui._emitResizeEvent(fc, h, null);
820
+ }
821
+
822
+ #__closeMove() {
823
+ this.#ui.disableBackWrapper();
824
+ this.#resize_editor &&= this.#eventManager.removeGlobalEvent(this.#resize_editor);
825
+ this.#close_move &&= this.#eventManager.removeGlobalEvent(this.#close_move);
826
+ }
827
+
828
+ /**
829
+ * @param {"t"|"b"} dir - Direction
830
+ * @param {PointerEvent} e - Pointer event object
831
+ */
832
+ #DisplayLineBreak(dir, e) {
833
+ e.preventDefault();
834
+
835
+ const component = this._lineBreakComp;
836
+ if (!component) return;
837
+
838
+ const isList = dom.check.isListCell(component.parentElement);
839
+ const format = dom.utils.createElement(isList ? 'BR' : dom.check.isTableCell(component.parentElement) ? 'DIV' : this.#options.get('defaultLine'));
840
+ if (!isList) format.innerHTML = '<br>';
841
+
842
+ if (this.$.frameOptions.get('charCounter_type') === 'byte-html' && !this.$.char.check(format.outerHTML)) return;
843
+
844
+ component.parentNode.insertBefore(format, dir === 't' ? component : component.nextSibling);
845
+ this.$.component.deselect();
846
+
847
+ try {
848
+ const focusEl = isList ? format : format.firstChild;
849
+ this.$.selection.setRange(focusEl, 1, focusEl, 1);
850
+ this.$.history.push(false);
851
+ } catch (err) {
852
+ console.warn('[SUNEDITOR.lineBreaker.error]', err);
853
+ }
854
+ }
855
+
856
+ #OnResize_window() {
857
+ this.#store.set('initViewportHeight', _w.visualViewport.height);
858
+
859
+ if (!isMobile) {
860
+ this.#ui.offCurrentController();
861
+ }
862
+
863
+ if (this.#store.mode.isBalloon) this.#toolbar.hide();
864
+ else if (this.#store.mode.isSubBalloon) this.$.subToolbar.hide();
865
+
866
+ this.#resetFrameStatus();
867
+ }
868
+
869
+ #OnResize_viewport() {
870
+ if (isMobile && this.#options.get('toolbar_sticky') > -1) {
871
+ this.#toolbar._resetSticky();
872
+ this.#menu.__restoreMenuPosition();
873
+ }
874
+
875
+ this.#scrollContainer();
876
+ this.__setViewportSize();
877
+ }
878
+
879
+ #OnScroll_window() {
880
+ if (this.#options.get('toolbar_sticky') > -1) {
881
+ this.#toolbar._resetSticky();
882
+ }
883
+
884
+ if (this.#store.mode.isBalloon && this.#context.get('toolbar_main').style.display === 'block') {
885
+ this.#toolbar._setBalloonOffset(this.#toolbar.balloonOffset.position === 'top');
886
+ } else if (this.#store.mode.isSubBalloon && this.#context.get('toolbar_sub_main').style.display === 'block') {
887
+ this.$.subToolbar._setBalloonOffset(this.$.subToolbar.balloonOffset.position === 'top');
888
+ }
889
+
890
+ this.#scrollContainer();
891
+
892
+ // document type page
893
+ if (this.$.frameContext.has('documentType_use_page')) {
894
+ this.$.frameContext.get('documentType').scrollWindow();
895
+ }
896
+ }
897
+
898
+ #OnMobileScroll_viewport() {
899
+ if (this.#options.get('toolbar_sticky') > -1) {
900
+ this.#toolbar._resetSticky();
901
+ this.#menu.__restoreMenuPosition();
902
+ }
903
+ }
904
+
905
+ /**
906
+ * @param {Document} _wd - Wysiwyg document
907
+ */
908
+ #OnSelectionchange_document(_wd) {
909
+ const selection = _wd.getSelection();
910
+ let anchorNode = selection.anchorNode;
911
+
912
+ this.#contextProvider.applyToRoots((root) => {
913
+ if (anchorNode && root.get('wysiwyg').contains(anchorNode)) {
914
+ if (root.get('isReadOnly') || root.get('isDisabled')) return;
915
+
916
+ anchorNode = null;
917
+ this.$.selection.init();
918
+ this.applyTagEffect();
919
+
920
+ // document type
921
+ if (root.has('documentType_use_header')) {
922
+ const el = dom.query.getParentElement(this.$.selection.selectionNode, this.$.format.isLine.bind(this.$.format));
923
+ root.get('documentType').on(el);
924
+ }
925
+ }
926
+ });
927
+ }
928
+
929
+ #OnScroll_Abs() {
930
+ this.#menu.dropdownOff();
931
+ this.#scrollContainer();
932
+ }
933
+
934
+ /**
935
+ * @param {SunEditor.FrameContext} frameContext - frame context object
936
+ */
937
+ #OnFocus_code(frameContext) {
938
+ this.$.facade.changeFrameContext(frameContext.get('key'));
939
+ dom.utils.addClass(this.$.commandDispatcher.targets.get('codeView'), 'active');
940
+ this.#ui._toggleCodeViewButtons(true);
941
+ }
942
+ }
943
+
944
+ export default EventOrchestrator;