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,754 @@
1
+ import { dom, unicode, env, numbers } from '../../../helper';
2
+ const { _w } = env;
3
+
4
+ /**
5
+ * @description Selection, Range related class
6
+ */
7
+ class Selection_ {
8
+ #kernel;
9
+ #$;
10
+ #store;
11
+
12
+ #shadowRoot;
13
+ #instanceCheck;
14
+ #context;
15
+ #frameContext;
16
+ #options;
17
+ #frameOptions;
18
+
19
+ #scrollMargin = 0;
20
+ #hasScrollParents = false;
21
+
22
+ /**
23
+ * @constructor
24
+ * @param {SunEditor.Kernel} kernel
25
+ */
26
+ constructor(kernel) {
27
+ this.#kernel = kernel;
28
+ this.#$ = kernel.$;
29
+ this.#store = kernel.store;
30
+
31
+ this.#shadowRoot = this.#$.contextProvider.shadowRoot;
32
+ this.#instanceCheck = this.#$.instanceCheck;
33
+ this.#context = this.#$.context;
34
+ this.#frameContext = this.#$.frameContext;
35
+ this.#options = this.#$.options;
36
+ this.#frameOptions = this.#$.frameOptions;
37
+
38
+ // members
39
+ /** @type {Range} */
40
+ this.range = null;
41
+ /** @type {HTMLElement|Text} */
42
+ this.selectionNode = null;
43
+
44
+ /** @internal */
45
+ this.__iframeFocus = false;
46
+ }
47
+
48
+ /**
49
+ * @description Get window selection obejct
50
+ * @returns {Selection}
51
+ */
52
+ get() {
53
+ let selection = null;
54
+
55
+ if (typeof this.#shadowRoot?.getSelection === 'function') {
56
+ selection = this.#shadowRoot.getSelection();
57
+ } else {
58
+ selection = this.#frameContext.get('_ww').getSelection();
59
+ }
60
+
61
+ if (!selection) return null;
62
+ if (!this.#store.get('_range') && !this.#frameContext.get('wysiwyg').contains(selection.focusNode)) {
63
+ selection.removeAllRanges();
64
+ selection.addRange(this.#createDefaultRange());
65
+ }
66
+ return selection;
67
+ }
68
+
69
+ /**
70
+ * @description Check if the range object is valid
71
+ * @param {*} range Range object
72
+ * @returns {range is Range}
73
+ */
74
+ isRange(range) {
75
+ // return /Range/.test(Object.prototype.toString.call(range?.__proto__));
76
+ return this.#instanceCheck.isRange(range);
77
+ }
78
+
79
+ /**
80
+ * @description Get current editor's range object
81
+ * @returns {Range}
82
+ */
83
+ getRange() {
84
+ const range = this.#store.get('_range') || this.#createDefaultRange();
85
+ const selection = this.get();
86
+ if (range.collapsed === selection.isCollapsed || !this.#frameContext.get('wysiwyg').contains(selection.focusNode)) {
87
+ if (this.#$.component.is(range.startContainer)) {
88
+ const compInfo = this.#$.component.get(range.startContainer);
89
+ const container = compInfo?.container;
90
+ if (!container) return range;
91
+ return this.setRange(container, 0, container, 1);
92
+ }
93
+
94
+ return range;
95
+ }
96
+
97
+ if (selection.rangeCount > 0) {
98
+ const selectionRange = selection.getRangeAt(0);
99
+ this.#store.set('_range', selectionRange);
100
+ return selectionRange;
101
+ } else {
102
+ const sc = selection.anchorNode,
103
+ ec = selection.focusNode,
104
+ so = selection.anchorOffset,
105
+ eo = selection.focusOffset;
106
+ const compareValue = dom.query.compareElements(sc, ec);
107
+ const rightDir = compareValue.ancestor && (compareValue.result === 0 ? so <= eo : compareValue.result > 1 ? true : false);
108
+ return this.setRange(rightDir ? sc : ec, rightDir ? so : eo, rightDir ? ec : sc, rightDir ? eo : so);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * @description Set current editor's range object and return.
114
+ * @param {Node|Range} startCon Range object or The `startContainer` property of the selection object
115
+ * @param {number} [startOff] The `startOffset` property of the selection object.
116
+ * @param {Node} [endCon] The `endContainer` property of the selection object.
117
+ * @param {number} [endOff] The `endOffset` property of the selection object.
118
+ * @returns {Range}
119
+ * @example
120
+ * // Set range using container and offset
121
+ * const textNode = editor.selection.getNode();
122
+ * editor.selection.setRange(textNode, 0, textNode, 5);
123
+ *
124
+ * // Set range using Range object
125
+ * const range = document.createRange();
126
+ * range.selectNodeContents(someElement);
127
+ * editor.selection.setRange(range);
128
+ *
129
+ * // Collapse cursor to start of element
130
+ * editor.selection.setRange(element, 0, element, 0);
131
+ */
132
+ setRange(startCon, startOff, endCon, endOff) {
133
+ /** @type {Node} */
134
+ let sc;
135
+ /** @type {number} */
136
+ let so;
137
+ /** @type {Node} */
138
+ let ec;
139
+ /** @type {number} */
140
+ let eo;
141
+
142
+ if (this.isRange(startCon)) {
143
+ const r = /** @type {Range} */ (startCon);
144
+ sc = r.startContainer;
145
+ so = r.startOffset;
146
+ ec = r.endContainer;
147
+ eo = r.endOffset;
148
+ } else {
149
+ sc = /** @type {Node} */ (startCon);
150
+ so = startOff;
151
+ ec = endCon;
152
+ eo = endOff;
153
+ }
154
+
155
+ if (!sc || !ec) return;
156
+ if ((dom.check.isBreak(sc) || sc.nodeType === 3) && so > sc.textContent.length) so = sc.textContent.length;
157
+ if ((dom.check.isBreak(ec) || ec.nodeType === 3) && eo > ec.textContent.length) eo = ec.textContent.length;
158
+ if (this.#$.format.isLine(sc)) {
159
+ sc = sc.childNodes[so > 0 ? sc.childNodes.length - 1 : 0] || sc;
160
+ so = so > 0 ? (sc.nodeType === 1 && !dom.check.isBreak(sc) ? 1 : sc.textContent ? sc.textContent.length : 0) : 0;
161
+ }
162
+ if (this.#$.format.isLine(ec)) {
163
+ ec = ec.childNodes[eo > 0 ? ec.childNodes.length - 1 : 0] || ec;
164
+ eo = eo > 0 ? (ec.nodeType === 1 && !dom.check.isBreak(ec) ? 1 : ec.textContent ? ec.textContent.length : 0) : 0;
165
+ }
166
+
167
+ const range = this.#frameContext.get('_wd').createRange();
168
+
169
+ try {
170
+ so = Math.min(so, sc.textContent?.length || 0);
171
+ eo = eo > 0 && (ec.textContent?.length || 0) === 0 && ec.nodeType === 1 ? 1 : Math.min(Math.max(eo, 0), ec.textContent?.length || 0);
172
+ range.setStart(sc, so);
173
+ range.setEnd(ec, eo);
174
+ this.#store.set('hasFocus', true);
175
+ } catch (error) {
176
+ console.warn('[SUNEDITOR.selection.focus.warn]', error.message);
177
+ this.#$.focusManager.nativeFocus();
178
+ return;
179
+ }
180
+
181
+ const selection = this.get();
182
+
183
+ if (selection.removeAllRanges) {
184
+ selection.removeAllRanges();
185
+ }
186
+
187
+ selection.addRange(range);
188
+ this.#store.set('_range', range);
189
+ this.#rangeInfo(range, this.get());
190
+
191
+ if (this.#frameOptions.get('iframe')) this.__focus();
192
+
193
+ return range;
194
+ }
195
+
196
+ /**
197
+ * @description Remove range object and button effect
198
+ */
199
+ removeRange() {
200
+ this.#store.set('_range', null);
201
+ this.#store.set('_lastSelectionNode', null);
202
+ this.selectionNode = null;
203
+ if (this.#store.get('hasFocus')) this.get().removeAllRanges();
204
+ this.#kernel._eventOrchestrator.selectionState.reset();
205
+ }
206
+
207
+ /**
208
+ * @description Returns the range (container and offset) near the given target node.
209
+ * - If the target node has a next sibling, it returns the next sibling with an offset of 0.
210
+ * - If there is no next sibling but a previous sibling exists, it returns the previous sibling with an offset of 1.
211
+ * @param {Node} target Target node whose neighboring range is to be determined.
212
+ * @returns {{container: Node, offset: number}|null} An object containing the nearest container node and its offset.
213
+ */
214
+ getNearRange(target) {
215
+ const next = target.nextSibling;
216
+ const prev = target.previousSibling;
217
+ if (next) {
218
+ return {
219
+ container: next,
220
+ offset: 0,
221
+ };
222
+ } else if (prev) {
223
+ return {
224
+ container: prev,
225
+ offset: 1,
226
+ };
227
+ }
228
+
229
+ return null;
230
+ }
231
+
232
+ /**
233
+ * @description If the `range` object is a non-editable area, add a line at the top of the editor and update the `range` object.
234
+ * @param {Range} range core.getRange()
235
+ * @param {?Node} [container] If there is `container` argument, it creates a line in front of the container.
236
+ * @returns {Range} a new `range` or argument `range`.
237
+ */
238
+ getRangeAndAddLine(range, container) {
239
+ if (this.#isNone(range)) {
240
+ const parent = container?.parentElement || this.#frameContext.get('wysiwyg');
241
+ const op = dom.utils.createElement(this.#options.get('defaultLine'), null, '<br>');
242
+ parent.insertBefore(op, container && container !== parent ? (!(/** @type {HTMLElement} */ (container).previousElementSibling) ? container : /** @type {HTMLElement} */ (container).nextElementSibling) : parent.firstElementChild);
243
+ this.setRange(op.firstElementChild, 0, op.firstElementChild, 1);
244
+ range = this.#store.get('_range');
245
+ }
246
+ return range;
247
+ }
248
+
249
+ /**
250
+ * @description Get current select node
251
+ * @returns {HTMLElement|Text}
252
+ */
253
+ getNode() {
254
+ if (!this.#frameContext.get('wysiwyg').contains(this.selectionNode)) this.init();
255
+ if (!this.selectionNode) {
256
+ const selectionNode = /** @type {HTMLElement|Text} */ (dom.query.getEdgeChild(this.#frameContext.get('wysiwyg').firstChild, (current) => current.childNodes.length === 0 || current.nodeType === 3, false));
257
+ if (!selectionNode) {
258
+ this.init();
259
+ } else {
260
+ this.selectionNode = selectionNode;
261
+ return selectionNode;
262
+ }
263
+ }
264
+ return this.selectionNode;
265
+ }
266
+
267
+ /**
268
+ * @description Get the Rects object.
269
+ * @param {?(Range|Node)} target `Range` | `Node` | `null`
270
+ * @param {"start"|"end"} position It is based on the position of the rect object to be returned in case of range selection.
271
+ * @returns {{rects: import('./offset').RectsInfo, position: "start"|"end", scrollLeft: number, scrollTop: number}}
272
+ * @example
273
+ * // Get rects at start of selection
274
+ * const { rects, position, scrollLeft, scrollTop } = editor.selection.getRects(null, 'start');
275
+ * console.log(rects.left, rects.top, rects.right, rects.bottom);
276
+ *
277
+ * // Get rects for specific node
278
+ * const node = editor.selection.getNode();
279
+ * const rectsInfo = editor.selection.getRects(node, 'end');
280
+ *
281
+ * // Use rects for positioning UI elements
282
+ * const { rects } = editor.selection.getRects(null, 'start');
283
+ * tooltip.style.left = rects.left + 'px';
284
+ * tooltip.style.top = rects.top + 'px';
285
+ */
286
+ getRects(target, position) {
287
+ const targetAbs = dom.check.isElement(/** @type {Node} */ (target)) ? _w.getComputedStyle(target).position === 'absolute' : false;
288
+ target = /** @type {Range} */ (!target || dom.check.isText(/** @type {Node} */ (target)) ? this.getRange() : target);
289
+ const globalScroll = this.#$.offset.getGlobalScroll();
290
+ let isStartPosition = position === 'start';
291
+ let scrollLeft = globalScroll.left;
292
+ let scrollTop = globalScroll.top;
293
+
294
+ let rects = /** @type {*} */ (target).getClientRects();
295
+ rects = rects[isStartPosition ? 0 : rects.length - 1];
296
+
297
+ if (!rects) {
298
+ const node = this.getNode();
299
+ if (this.#$.format.isLine(node)) {
300
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
301
+ this.#$.html.insertNode(zeroWidth, { afterNode: null, skipCharCount: true });
302
+ this.setRange(zeroWidth, 1, zeroWidth, 1);
303
+ this.init();
304
+ rects = this.getRange().getClientRects();
305
+ rects = rects[isStartPosition ? 0 : rects.length - 1];
306
+ }
307
+
308
+ if (!rects) {
309
+ const nodeOffset = this.#$.offset.get(node);
310
+ rects = {
311
+ left: nodeOffset.left,
312
+ top: nodeOffset.top,
313
+ right: nodeOffset.left + /** @type {HTMLElement} */ (node).offsetWidth,
314
+ bottom: nodeOffset.top + /** @type {HTMLElement} */ (node).offsetHeight,
315
+ noText: true,
316
+ };
317
+ scrollLeft = 0;
318
+ scrollTop = 0;
319
+ }
320
+
321
+ isStartPosition = true;
322
+ }
323
+
324
+ const iframeRects = /^iframe$/i.test(this.#frameContext.get('wysiwygFrame').nodeName) ? this.#frameContext.get('wysiwygFrame').getClientRects()[0] : null;
325
+ if (!targetAbs && iframeRects) {
326
+ rects = {
327
+ left: rects.left + iframeRects.left,
328
+ top: rects.top + iframeRects.top,
329
+ right: rects.right + iframeRects.right - iframeRects.width,
330
+ bottom: rects.bottom + iframeRects.bottom - iframeRects.height,
331
+ };
332
+ }
333
+
334
+ return {
335
+ rects: rects,
336
+ position: isStartPosition ? 'start' : 'end',
337
+ scrollLeft: scrollLeft,
338
+ scrollTop: scrollTop,
339
+ };
340
+ }
341
+
342
+ /**
343
+ * @description Get the custom range object of the event.
344
+ * @param {DragEvent} e Event object
345
+ * @returns {{sc: Node, so: number, ec: Node, eo: number}} {sc: `startContainer`, so: `startOffset`, ec: `endContainer`, eo: `endOffset`}
346
+ */
347
+ getDragEventLocationRange(e) {
348
+ const wd = this.#frameContext.get('_wd');
349
+ let r, sc, so, ec, eo;
350
+
351
+ if (wd.caretPositionFromPoint) {
352
+ r = wd.caretPositionFromPoint(e.clientX, e.clientY);
353
+ sc = r.offsetNode;
354
+ so = r.offset;
355
+ ec = r.offsetNode;
356
+ eo = r.offset;
357
+ } else if (wd.caretRangeFromPoint) {
358
+ r = wd.caretRangeFromPoint(e.clientX, e.clientY);
359
+ sc = r.startContainer;
360
+ so = r.startOffset;
361
+ ec = r.endContainer;
362
+ eo = r.endOffset;
363
+ }
364
+
365
+ return {
366
+ sc,
367
+ so,
368
+ ec,
369
+ eo,
370
+ };
371
+ }
372
+
373
+ /**
374
+ * @description Scroll to the corresponding selection or range position.
375
+ * @param {Selection|Range|Node} ref selection or range object
376
+ * @param {Object<string, *>} [scrollOption] option of scrollTo
377
+ * @example
378
+ * // Scroll to current selection smoothly
379
+ * editor.selection.scrollTo(editor.selection.get());
380
+ *
381
+ * // Scroll to specific node
382
+ * const targetNode = document.querySelector('.target-element');
383
+ * editor.selection.scrollTo(targetNode);
384
+ *
385
+ * // Scroll with custom options
386
+ * editor.selection.scrollTo(editor.selection.getRange(), {
387
+ * behavior: 'auto',
388
+ * block: 'center'
389
+ * });
390
+ */
391
+ scrollTo(ref, scrollOption) {
392
+ if (this.#instanceCheck.isSelection(ref)) {
393
+ ref = ref.getRangeAt(0);
394
+ } else if (this.#instanceCheck.isNode(ref)) {
395
+ ref = this.setRange(ref, 1, ref, 1);
396
+ } else if (typeof ref?.startContainer === 'undefined') {
397
+ console.warn('[SUNEDITOR.html.scrollTo.warn] "selectionRange" must be Selection or Range or Node object.', ref);
398
+ }
399
+
400
+ const el = dom.query.getParentElement(ref?.startContainer, (current) => current.nodeType === 1);
401
+ if (!el) return;
402
+
403
+ scrollOption = { behavior: 'smooth', block: 'nearest', inline: 'nearest', ...scrollOption };
404
+
405
+ const ww = this.#frameContext.get('_ww');
406
+ const wwFrame = this.#frameContext.get('wysiwygFrame');
407
+ const isIframe = this.#frameOptions.get('iframe');
408
+ const isAutoHeight = !this.#store.get('isScrollable')(this.#frameContext);
409
+ const viewportHeight = this.#store.get('currentViewportHeight');
410
+ const scrollY = isAutoHeight ? _w.scrollY : isIframe ? ww.scrollY : wwFrame.scrollTop;
411
+ const realToolbarHeight = this.#context.get('toolbar_main').offsetHeight;
412
+ const toolbarHeight = this.#$.toolbar.isSticky ? realToolbarHeight : 0;
413
+ const positionToolbarHeight = this.#$.toolbar.isSticky ? toolbarHeight + this.#options.get('toolbar_sticky') : toolbarHeight;
414
+ const statusbarHeight = this.#frameContext.get('statusbar')?.offsetHeight || 0;
415
+
416
+ if (this.#hasScrollParents) {
417
+ el?.scrollIntoView(scrollOption);
418
+
419
+ if (scrollOption?.behavior === 'auto' && scrollY !== _w.scrollY) {
420
+ if (positionToolbarHeight && scrollY > _w.scrollY) {
421
+ _w.scrollBy(0, -positionToolbarHeight);
422
+ } else if (isAutoHeight) {
423
+ _w.scrollBy(0, statusbarHeight);
424
+ }
425
+ }
426
+
427
+ return;
428
+ }
429
+
430
+ // --- When there is no upper scroll and it is an iframe ---
431
+ const PADDING = this.#scrollMargin;
432
+ const viewHeight = isAutoHeight ? viewportHeight : wwFrame.offsetHeight;
433
+ const elH = el.offsetHeight || 0;
434
+
435
+ const behavior = scrollOption?.behavior;
436
+ if (isAutoHeight) {
437
+ if (isIframe) {
438
+ const rect = this.getRects(ref, 'end').rects;
439
+ const topMargin = rect.top + elH - positionToolbarHeight;
440
+ const bottomMargin = viewHeight - PADDING - (rect.top + elH);
441
+ if (topMargin >= 0 && bottomMargin >= 0) return;
442
+
443
+ const newScrollTop = scrollY - (topMargin < 0 ? -(topMargin - PADDING) : bottomMargin);
444
+ _w.scrollTo({
445
+ top: newScrollTop < scrollY ? newScrollTop - positionToolbarHeight : newScrollTop,
446
+ behavior,
447
+ });
448
+ } else {
449
+ const rect = this.#$.offset.getGlobal(el);
450
+ const scrollMargin = viewHeight + scrollY - rect.top - elH;
451
+
452
+ if (scrollMargin - PADDING > 0 && viewHeight > scrollMargin + PADDING + positionToolbarHeight) return;
453
+
454
+ const newScrollTop = scrollMargin <= PADDING ? scrollY - scrollMargin + PADDING + statusbarHeight : scrollY - scrollMargin + (viewHeight - elH - PADDING);
455
+ _w.scrollTo({
456
+ top: newScrollTop < scrollY ? newScrollTop - positionToolbarHeight : newScrollTop,
457
+ behavior,
458
+ });
459
+ }
460
+ } else {
461
+ // local scroll
462
+ const { rects } = this.getRects(el, 'start');
463
+ const { top } = this.#$.offset.getLocal(el);
464
+ const innerTop = top < 0 && rects.top < 0 ? top : rects.top;
465
+
466
+ const keepLocalScroll = innerTop - PADDING > 0 && innerTop + PADDING <= viewHeight;
467
+ const rectScroll = innerTop - PADDING > 0 ? innerTop + PADDING - viewHeight : innerTop - (toolbarHeight + elH);
468
+ let newScrollTop = scrollY + rectScroll;
469
+
470
+ // frame scroll
471
+ const gy = _w.scrollY;
472
+ const globalRect = this.#$.offset.getGlobal();
473
+ const topMargin = gy - globalRect.top + realToolbarHeight;
474
+ const bottomMargin = globalRect.top + globalRect.height - (gy + viewportHeight) + realToolbarHeight;
475
+
476
+ // set frame scroll
477
+ if (topMargin > 0) {
478
+ const newFrameY = (keepLocalScroll ? innerTop : innerTop + scrollY - newScrollTop) - elH - PADDING - topMargin;
479
+ if (newFrameY < 0) {
480
+ newScrollTop += realToolbarHeight;
481
+ _w.scrollTo({
482
+ top: gy + newFrameY,
483
+ behavior: 'smooth',
484
+ });
485
+ }
486
+ }
487
+ if (bottomMargin > 0) {
488
+ const newFrameY = (keepLocalScroll ? innerTop : innerTop + scrollY - newScrollTop) + elH + PADDING - (globalRect.height - bottomMargin);
489
+ if (newFrameY > 0) {
490
+ newScrollTop += statusbarHeight;
491
+ _w.scrollTo({
492
+ top: gy + newFrameY,
493
+ behavior: 'smooth',
494
+ });
495
+ }
496
+ }
497
+
498
+ // set local scroll
499
+ if (!keepLocalScroll) {
500
+ (isIframe ? ww : wwFrame).scrollTo({
501
+ top: newScrollTop,
502
+ behavior,
503
+ });
504
+ }
505
+ }
506
+ }
507
+
508
+ /**
509
+ * @description Normalizes and resets the selection range to properly target text nodes instead of element nodes for accurate text editing.
510
+ * @returns {boolean} Returns `false` if there is no valid selection.
511
+ */
512
+ resetRangeToTextNode() {
513
+ let rangeObj = this.getRange();
514
+ if (this.#isNone(rangeObj)) {
515
+ if (!dom.check.isWysiwygFrame(rangeObj.startContainer) || !dom.check.isWysiwygFrame(rangeObj.endContainer)) return false;
516
+ const ww = /** @type {HTMLElement} */ (rangeObj.commonAncestorContainer);
517
+ const first = ww.children[rangeObj.startOffset];
518
+ const end = ww.children[rangeObj.endOffset];
519
+ if (!(rangeObj = this.setRange(first, 0, end, first === end ? 0 : 1))) return false;
520
+ }
521
+
522
+ const range = rangeObj;
523
+ const collapsed = range.collapsed;
524
+ let startCon = range.startContainer;
525
+ let startOff = range.startOffset;
526
+ let endCon = range.endContainer;
527
+ let endOff = range.endOffset;
528
+ let tempCon, tempOffset, tempChild;
529
+
530
+ if (this.#$.format.isLine(startCon)) {
531
+ if (!startCon.childNodes[startOff]) {
532
+ startCon = startCon.lastChild || startCon;
533
+ startOff = startCon.textContent.length;
534
+ } else {
535
+ startCon = startCon.childNodes[startOff] || startCon;
536
+ startOff = 0;
537
+ }
538
+ while (startCon?.nodeType === 1 && startCon.firstChild) {
539
+ startCon = startCon.firstChild || startCon;
540
+ startOff = 0;
541
+ }
542
+ }
543
+ if (this.#$.format.isLine(endCon)) {
544
+ endCon = endCon.childNodes[endOff] || endCon.lastChild || endCon;
545
+ while (endCon?.nodeType === 1 && endCon.lastChild) {
546
+ endCon = endCon.lastChild;
547
+ }
548
+ if (collapsed) endOff = 0;
549
+ else if (endOff > 0) endOff = endCon.textContent.length;
550
+ }
551
+
552
+ // startContainer
553
+ tempCon = dom.check.isWysiwygFrame(startCon) ? this.#frameContext.get('wysiwyg').firstChild : startCon;
554
+ tempOffset = startOff;
555
+
556
+ if (dom.check.isBreak(tempCon) || (tempCon.nodeType === 1 && tempCon.childNodes.length > 0)) {
557
+ const onlyBreak = dom.check.isBreak(tempCon);
558
+ if (!onlyBreak) {
559
+ const tempConCache = tempCon;
560
+ while (tempCon && !dom.check.isBreak(tempCon) && tempCon.nodeType === 1) {
561
+ tempChild = tempCon.childNodes;
562
+ if (tempChild.length === 0) break;
563
+ tempCon =
564
+ tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] || !/FIGURE/i.test(tempChild[0].nodeName) ? tempChild[0] : /** @type {HTMLElement} */ (tempCon).previousElementSibling || tempCon.previousSibling || startCon;
565
+ tempOffset = tempOffset > 0 ? tempCon.textContent.length : tempOffset;
566
+ }
567
+
568
+ let format = this.#$.format.getLine(tempCon, null);
569
+ if (format === this.#$.format.getBlock(format, null)) {
570
+ tempCon ||= tempConCache;
571
+ format = dom.utils.createElement(dom.query.getParentElement(tempCon, dom.check.isTableCell) ? 'DIV' : this.#options.get('defaultLine'));
572
+ tempCon.parentNode.insertBefore(format, tempCon);
573
+ if (tempCon !== tempConCache) format.appendChild(tempCon);
574
+ }
575
+ }
576
+
577
+ if (dom.check.isBreak(tempCon) || this.#$.component.is(tempCon)) {
578
+ const emptyText = dom.utils.createTextNode(unicode.zeroWidthSpace);
579
+ tempCon.parentNode.insertBefore(emptyText, tempCon);
580
+ tempCon = emptyText;
581
+ if (onlyBreak) {
582
+ if (startCon === endCon) {
583
+ endCon = tempCon;
584
+ endOff = 1;
585
+ }
586
+ }
587
+ }
588
+ }
589
+
590
+ // set startContainer
591
+ startCon = tempCon;
592
+ startOff = tempOffset;
593
+
594
+ // endContainer
595
+ tempCon = dom.check.isWysiwygFrame(endCon) ? this.#frameContext.get('wysiwyg').lastChild : endCon;
596
+ tempOffset = endOff;
597
+
598
+ if (dom.check.isBreak(tempCon) || (tempCon.nodeType === 1 && tempCon.childNodes.length > 0)) {
599
+ const onlyBreak = dom.check.isBreak(tempCon);
600
+ if (!onlyBreak) {
601
+ while (tempCon && !dom.check.isBreak(tempCon) && tempCon.nodeType === 1) {
602
+ tempChild = tempCon.childNodes;
603
+ if (tempChild.length === 0) break;
604
+ tempCon =
605
+ tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] || !/FIGURE/i.test(tempChild[0].nodeName) ? tempChild[0] : /** @type {HTMLElement} */ (tempCon).previousElementSibling || tempCon.previousSibling || startCon;
606
+ tempOffset = tempOffset > 0 ? tempCon.textContent.length : tempOffset;
607
+ }
608
+
609
+ let format = this.#$.format.getLine(tempCon, null);
610
+ if (format === this.#$.format.getBlock(format, null)) {
611
+ format = dom.utils.createElement(dom.check.isTableCell(format) ? 'DIV' : this.#options.get('defaultLine'));
612
+ tempCon.parentNode.insertBefore(format, tempCon);
613
+ format.appendChild(tempCon);
614
+ }
615
+ }
616
+
617
+ if (dom.check.isBreak(tempCon)) {
618
+ const emptyText = dom.utils.createTextNode(unicode.zeroWidthSpace);
619
+ tempCon.parentNode.insertBefore(emptyText, tempCon);
620
+ tempCon = emptyText;
621
+ tempOffset = 1;
622
+ if (onlyBreak && !tempCon.previousSibling) {
623
+ dom.utils.removeItem(endCon);
624
+ }
625
+ }
626
+ }
627
+
628
+ // set endContainer
629
+ endCon = tempCon;
630
+ endOff = tempOffset;
631
+
632
+ // set Range
633
+ this.setRange(startCon, startOff, endCon, endOff);
634
+ return true;
635
+ }
636
+
637
+ /**
638
+ * @description Saving the range object and the currently selected node of editor
639
+ */
640
+ init() {
641
+ const activeEl = this.#frameContext.get('_wd').activeElement;
642
+ if (dom.check.isInputElement(activeEl)) {
643
+ this.selectionNode = activeEl;
644
+ return activeEl;
645
+ }
646
+
647
+ const selection = this.get();
648
+
649
+ if (!selection) return null;
650
+ let range = null;
651
+
652
+ if (selection.rangeCount > 0) {
653
+ range = selection.getRangeAt(0);
654
+ } else {
655
+ range = this.#createDefaultRange();
656
+ }
657
+
658
+ this.#rangeInfo(range, selection);
659
+ }
660
+
661
+ /**
662
+ Ï * @description Set `range` and `selection` info.
663
+ * @param {Range} range range object.
664
+ * @param {Selection} selection selection object.
665
+ */
666
+ #rangeInfo(range, selection) {
667
+ let selectionNode = null;
668
+ this.#store.set('_range', range);
669
+
670
+ if (range.collapsed) {
671
+ if (dom.check.isWysiwygFrame(range.commonAncestorContainer)) selectionNode = range.commonAncestorContainer.children[range.startOffset] || range.commonAncestorContainer;
672
+ else selectionNode = range.commonAncestorContainer;
673
+ } else {
674
+ selectionNode = selection.anchorNode;
675
+ }
676
+
677
+ this.selectionNode = /** @type {HTMLElement|Text} */ (selectionNode);
678
+ }
679
+
680
+ /**
681
+ * @description Returns `true` if there is no valid selection.
682
+ * @param {Range} range selection.getRange()
683
+ * @returns {boolean}
684
+ */
685
+ #isNone(range) {
686
+ const comm = /** @type {HTMLElement} */ (range.commonAncestorContainer);
687
+ return (
688
+ (dom.check.isWysiwygFrame(range.startContainer) && dom.check.isWysiwygFrame(range.endContainer)) ||
689
+ /FIGURE/i.test(comm.nodeName) ||
690
+ (this.#$.pluginManager.fileInfo.regExp.test(comm.nodeName) && (!this.#$.pluginManager.fileInfo.tagAttrs[comm.nodeName] || this.#$.pluginManager.fileInfo.tagAttrs[comm.nodeName]?.every((v) => comm.hasAttribute(v)))) ||
691
+ this.#$.component.is(comm)
692
+ );
693
+ }
694
+
695
+ /**
696
+ * @description Return the range object of editor's first child node
697
+ * @returns {Range}
698
+ */
699
+ #createDefaultRange() {
700
+ const wysiwyg = this.#frameContext.get('wysiwyg');
701
+ const range = this.#frameContext.get('_wd').createRange();
702
+
703
+ let firstFormat = wysiwyg.firstElementChild;
704
+ let focusEl = null;
705
+ if (!firstFormat) {
706
+ focusEl = dom.utils.createElement('BR');
707
+ firstFormat = dom.utils.createElement(this.#options.get('defaultLine'), null, focusEl);
708
+ wysiwyg.appendChild(firstFormat);
709
+ } else {
710
+ focusEl = firstFormat.firstChild;
711
+ if (!focusEl) {
712
+ focusEl = dom.utils.createElement('BR');
713
+ firstFormat.appendChild(focusEl);
714
+ }
715
+ }
716
+
717
+ range.setStart(focusEl, 0);
718
+ range.setEnd(focusEl, 0);
719
+
720
+ return range;
721
+ }
722
+
723
+ /**
724
+ * @internal
725
+ * @description Sets focus to the editor's wysiwyg contenteditable area and restores the last selection range within iframe context.
726
+ */
727
+ __focus() {
728
+ try {
729
+ this.__iframeFocus = true;
730
+ const caption = dom.query.getParentElement(this.getNode(), 'figcaption');
731
+ if (caption) {
732
+ caption.focus();
733
+ } else {
734
+ this.#frameContext.get('wysiwyg').focus();
735
+ }
736
+ } finally {
737
+ // Defer flag reset — iframe.focus() triggers synchronous focus/blur events that check this flag
738
+ _w.setTimeout(() => (this.__iframeFocus = false), 0);
739
+ }
740
+ }
741
+
742
+ /**
743
+ * @internal
744
+ * @description Initialize the scroll information when the editor first loads
745
+ */
746
+ __init() {
747
+ this.#hasScrollParents = this.#kernel._eventOrchestrator.scrollparents?.length > 0;
748
+ this.#scrollMargin = !this.#frameContext?.get('wysiwyg')
749
+ ? 40
750
+ : (numbers.get(_w.getComputedStyle(this.#frameContext.get('wysiwyg')).scrollMargin, 0) || 40) + numbers.get(_w.getComputedStyle(this.#frameContext.get('wrapper')).paddingBottom, 0);
751
+ }
752
+ }
753
+
754
+ export default Selection_;