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,1847 @@
1
+ import { dom, unicode, converter } from '../../../helper';
2
+
3
+ /**
4
+ * @typedef {Object} NodeStyleContainerType
5
+ * @property {?Node} [ancestor]
6
+ * @property {?number} [offset]
7
+ * @property {?Node} [container]
8
+ * @property {?Node} [endContainer]
9
+ */
10
+
11
+ /**
12
+ * @description Classes related to editor inline formats such as style node like strong, span, etc.
13
+ */
14
+ class Inline {
15
+ #$;
16
+ #options;
17
+
18
+ #listCamel;
19
+ #listKebab;
20
+
21
+ /**
22
+ * @constructor
23
+ * @param {SunEditor.Kernel} kernel
24
+ */
25
+ constructor(kernel) {
26
+ this.#$ = kernel.$;
27
+
28
+ this.#options = this.#$.options;
29
+
30
+ // members
31
+ this.#listCamel = this.#options.get('__listCommonStyle');
32
+ this.#listKebab = converter.camelToKebabCase(this.#options.get('__listCommonStyle'));
33
+ }
34
+
35
+ /**
36
+ * @description Adds, updates, or deletes style nodes from selected text (a, span, strong, etc.).
37
+ * - 1. If `styleNode` is provided, a node with the same tags and attributes is added to the selected text.
38
+ * - 2. If the same tag already exists, only its attributes are updated.
39
+ * - 3. If `styleNode` is `null`, existing nodes are updated or removed without adding new ones.
40
+ * - 4. Styles matching those in `stylesToModify` are removed. (Use CSS attribute names, e.g., `background-color`)
41
+ * - 5. Classes matching those in `stylesToModify` (prefixed with `"."`) are removed.
42
+ * - 6. `stylesToModify` is used to avoid duplicate property values from `styleNode`.
43
+ * - 7. Nodes with all styles and classes removed are deleted if they match `styleNode`, are in `nodesToRemove`, or if `styleNode` is `null`.
44
+ * - 8. Tags matching names in `nodesToRemove` are deleted regardless of their style and class.
45
+ * - 9. If `strictRemove` is `true`, nodes in `nodesToRemove` are only removed if all their styles and classes are removed.
46
+ * - 10. The function won't modify nodes if the parent has the same class and style values.
47
+ * - However, if `nodesToRemove` has values, it will work and separate text nodes even if there's no node to replace.
48
+ * @param {?Node} styleNode The element to be added to the selection. If `null`, only existing nodes are modified or removed.
49
+ * @param {Object} [options] Options
50
+ * @param {Array<string>} [options.stylesToModify=null] Array of style or class names to check and modify.
51
+ * (e.g., ['font-size'], ['.className'], ['font-family', 'color', '.className'])
52
+ * @param {Array<string>} [options.nodesToRemove=null] Array of node names to remove.
53
+ * If empty array or `null` when `styleNode` is `null`, all formats are removed.
54
+ * (e.g., ['span'], ['strong', 'em'])
55
+ * @param {boolean} [options.strictRemove=false] If `true`, only removes nodes from `nodesToRemove` if all styles and classes are removed.
56
+ * @returns {HTMLElement} The element that was added to or modified in the selection.
57
+ * @example
58
+ * // Apply bold formatting
59
+ * const bold = dom.utils.createElement('STRONG');
60
+ * editor.inline.apply(bold);
61
+ *
62
+ * // Remove specific styles
63
+ * editor.inline.apply(null, { stylesToModify: ['font-size'] });
64
+ *
65
+ * // Remove specific tags
66
+ * editor.inline.apply(null, { nodesToRemove: ['span'] });
67
+ */
68
+ apply(styleNode, { stylesToModify, nodesToRemove, strictRemove } = {}) {
69
+ if (dom.query.getParentElement(this.#$.selection.getNode(), dom.check.isNonEditable)) return;
70
+
71
+ this.#$.selection.resetRangeToTextNode();
72
+ let range = this.#$.selection.getRangeAndAddLine(this.#$.selection.getRange(), null);
73
+ stylesToModify = stylesToModify?.length > 0 ? stylesToModify : null;
74
+ nodesToRemove = nodesToRemove?.length > 0 ? nodesToRemove : null;
75
+
76
+ const isRemoveNode = !styleNode;
77
+ const isRemoveFormat = isRemoveNode && !nodesToRemove && !stylesToModify;
78
+ let startCon = range.startContainer;
79
+ let startOff = range.startOffset;
80
+ let endCon = range.endContainer;
81
+ let endOff = range.endOffset;
82
+
83
+ if ((isRemoveFormat && range.collapsed && this.#$.format.isLine(startCon.parentNode) && this.#$.format.isLine(endCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && dom.check.isNonEditable(startCon))) {
84
+ const format = startCon.parentNode;
85
+ if (!dom.check.isListCell(format) || !converter.getValues(format.style).some((k) => this.#listKebab.includes(k))) {
86
+ return;
87
+ }
88
+ }
89
+
90
+ if (range.collapsed && !isRemoveFormat) {
91
+ if (startCon.nodeType === 1 && !dom.check.isBreak(startCon) && !this.#$.component.is(startCon)) {
92
+ let afterNode = null;
93
+ const focusNode = startCon.childNodes[startOff];
94
+
95
+ if (focusNode) {
96
+ if (!focusNode.nextSibling) {
97
+ afterNode = null;
98
+ } else {
99
+ afterNode = dom.check.isBreak(focusNode) ? focusNode : focusNode.nextSibling;
100
+ }
101
+ }
102
+
103
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
104
+ startCon.insertBefore(zeroWidth, afterNode);
105
+ this.#$.selection.setRange(zeroWidth, 1, zeroWidth, 1);
106
+
107
+ range = this.#$.selection.getRange();
108
+ startCon = range.startContainer;
109
+ startOff = range.startOffset;
110
+ endCon = range.endContainer;
111
+ endOff = range.endOffset;
112
+ }
113
+ }
114
+
115
+ if (this.#$.format.isLine(startCon)) {
116
+ startCon = startCon.childNodes[startOff] || startCon.firstChild;
117
+ startOff = 0;
118
+ }
119
+ if (this.#$.format.isLine(endCon)) {
120
+ endCon = endCon.childNodes[endOff] || endCon.lastChild;
121
+ endOff = endCon.textContent.length;
122
+ }
123
+
124
+ if (isRemoveNode) {
125
+ styleNode = dom.utils.createElement('DIV');
126
+ }
127
+
128
+ const wRegExp = RegExp;
129
+ const newNodeName = styleNode.nodeName;
130
+
131
+ /* checked same style property */
132
+ if (!isRemoveFormat && startCon === endCon && !nodesToRemove && styleNode) {
133
+ let sNode = startCon;
134
+ let checkCnt = 0;
135
+ const checkAttrs = [];
136
+
137
+ const checkStyles = /** @type {HTMLElement} */ (styleNode).style;
138
+ for (let i = 0, len = checkStyles.length; i < len; i++) {
139
+ checkAttrs.push(checkStyles[i]);
140
+ }
141
+
142
+ const checkClassName = /** @type {HTMLElement} */ (styleNode).className;
143
+ const ckeckClasses = /** @type {HTMLElement} */ (styleNode).classList;
144
+ for (let i = 0, len = ckeckClasses.length; i < len; i++) {
145
+ checkAttrs.push('.' + ckeckClasses[i]);
146
+ }
147
+
148
+ if (checkAttrs.length > 0) {
149
+ while (!this.#$.format.isLine(sNode) && !dom.check.isWysiwygFrame(sNode)) {
150
+ for (let i = 0; i < checkAttrs.length; i++) {
151
+ if (sNode.nodeType === 1) {
152
+ const s = checkAttrs[i];
153
+ const classReg = /^\./.test(s) ? new wRegExp('\\s*' + s.replace(/^\./, '') + '(\\s+|$)', 'ig') : false;
154
+ const sNodeStyle = /** @type {HTMLElement} */ (sNode).style;
155
+ const sNodeClassName = /** @type {HTMLElement} */ (sNode).className;
156
+
157
+ const styleCheck = isRemoveNode ? !!sNodeStyle[s] : !!sNodeStyle[s] && !!checkStyles[s] && sNodeStyle[s] === checkStyles[s];
158
+ const classCheck = classReg === false ? false : isRemoveNode ? !!sNodeClassName.match(classReg) : !!sNodeClassName.match(classReg) && !!checkClassName.match(classReg);
159
+ if (styleCheck || classCheck) {
160
+ checkCnt++;
161
+ }
162
+ }
163
+ }
164
+ sNode = sNode.parentNode;
165
+ }
166
+
167
+ if (checkCnt >= checkAttrs.length) return;
168
+ }
169
+ }
170
+
171
+ let newNode;
172
+ /** @type {NodeStyleContainerType} */
173
+ let start = {};
174
+ /** @type {NodeStyleContainerType} */
175
+ let end = {};
176
+
177
+ /** @type {string|RegExp} */
178
+ let styleRegExp = '';
179
+ /** @type {string|RegExp} */
180
+ let classRegExp = '';
181
+ /** @type {string|RegExp} */
182
+ let removeNodeRegExp;
183
+
184
+ if (stylesToModify) {
185
+ for (let i = 0, len = stylesToModify.length, s; i < len; i++) {
186
+ s = stylesToModify[i];
187
+ if (/^\./.test(s)) {
188
+ classRegExp += (classRegExp ? '|' : '\\s*(?:') + s.replace(/^\./, '');
189
+ } else {
190
+ styleRegExp += (styleRegExp ? '|' : '(?:;|^|\\s)(?:') + s;
191
+ }
192
+ }
193
+
194
+ if (styleRegExp) {
195
+ styleRegExp += ')\\s*:[^;]*\\s*(?:;|$)';
196
+ styleRegExp = new wRegExp(styleRegExp, 'ig');
197
+ }
198
+
199
+ if (classRegExp) {
200
+ classRegExp += ')(?=\\s+|$)';
201
+ classRegExp = new wRegExp(classRegExp, 'ig');
202
+ }
203
+ }
204
+
205
+ if (nodesToRemove) {
206
+ removeNodeRegExp = '^(?:' + nodesToRemove[0];
207
+ for (let i = 1; i < nodesToRemove.length; i++) {
208
+ removeNodeRegExp += '|' + nodesToRemove[i];
209
+ }
210
+ removeNodeRegExp += ')$';
211
+ removeNodeRegExp = new wRegExp(removeNodeRegExp, 'i');
212
+ }
213
+
214
+ /** validation check function*/
215
+ const _removeCheck = {
216
+ v: false,
217
+ };
218
+ const validation = function (checkNode) {
219
+ const vNode = checkNode.cloneNode(false);
220
+
221
+ // all path
222
+ if (vNode.nodeType === 3 || dom.check.isBreak(vNode)) return vNode;
223
+ // all remove
224
+ if (isRemoveFormat) return null;
225
+
226
+ // remove node check
227
+ const tagRemove = (!removeNodeRegExp && isRemoveNode) || /** @type {RegExp} */ (removeNodeRegExp)?.test(vNode.nodeName);
228
+
229
+ // tag remove
230
+ if (tagRemove && !strictRemove) {
231
+ _removeCheck.v = true;
232
+ return null;
233
+ }
234
+
235
+ // style regexp
236
+ const originStyle = vNode.style.cssText;
237
+ let style = '';
238
+ if (styleRegExp && originStyle.length > 0) {
239
+ style = originStyle.replace(styleRegExp, '').trim();
240
+ if (style !== originStyle) _removeCheck.v = true;
241
+ }
242
+
243
+ // class check
244
+ const originClasses = vNode.className;
245
+ let classes = '';
246
+ if (classRegExp && originClasses.length > 0) {
247
+ classes = originClasses.replace(classRegExp, '').trim();
248
+ if (classes !== originClasses) _removeCheck.v = true;
249
+ }
250
+
251
+ // remove only
252
+ if (isRemoveNode) {
253
+ if ((classRegExp || !originClasses) && (styleRegExp || !originStyle) && !style && !classes && tagRemove) {
254
+ _removeCheck.v = true;
255
+ return null;
256
+ }
257
+ }
258
+
259
+ // change
260
+ if (style || classes || vNode.nodeName !== newNodeName || Boolean(styleRegExp) !== Boolean(originStyle) || Boolean(classRegExp) !== Boolean(originClasses)) {
261
+ if (styleRegExp && originStyle.length > 0) vNode.style.cssText = style;
262
+ if (!vNode.style.cssText) {
263
+ vNode.removeAttribute('style');
264
+ }
265
+
266
+ if (classRegExp && originClasses.length > 0) vNode.className = classes.trim();
267
+ if (!vNode.className.trim()) {
268
+ vNode.removeAttribute('class');
269
+ }
270
+
271
+ if (!vNode.style.cssText && !vNode.className && (vNode.nodeName === newNodeName || tagRemove)) {
272
+ _removeCheck.v = true;
273
+ return null;
274
+ }
275
+
276
+ return vNode;
277
+ }
278
+
279
+ _removeCheck.v = true;
280
+ return null;
281
+ };
282
+
283
+ // get line nodes
284
+ const lineNodes = this.#$.format.getLines(null);
285
+ if (lineNodes.length === 0) {
286
+ console.warn('[SUNEDITOR.inline.apply.warn] There is no line to apply.');
287
+ return;
288
+ }
289
+
290
+ range = this.#$.selection.getRange();
291
+ startCon = range.startContainer;
292
+ startOff = range.startOffset;
293
+ endCon = range.endContainer;
294
+ endOff = range.endOffset;
295
+
296
+ if (!this.#$.format.getLine(startCon, null)) {
297
+ startCon = dom.query.getEdgeChild(
298
+ lineNodes[0],
299
+ function (current) {
300
+ return current.nodeType === 3;
301
+ },
302
+ false,
303
+ );
304
+ startOff = 0;
305
+ }
306
+
307
+ if (!this.#$.format.getLine(endCon, null)) {
308
+ endCon = dom.query.getEdgeChild(
309
+ lineNodes.at(-1),
310
+ function (current) {
311
+ return current.nodeType === 3;
312
+ },
313
+ false,
314
+ );
315
+ endOff = endCon.textContent.length;
316
+ }
317
+
318
+ const oneLine = this.#$.format.getLine(startCon, null) === this.#$.format.getLine(endCon, null);
319
+ const endLength = lineNodes.length - (oneLine ? 0 : 1);
320
+
321
+ // node Changes
322
+ newNode = styleNode.cloneNode(false);
323
+
324
+ const isRemoveAnchor =
325
+ isRemoveFormat ||
326
+ (isRemoveNode &&
327
+ ((arr) => {
328
+ for (let n = 0, len = arr?.length; n < len; n++) {
329
+ if (this._isNonSplitNode(arr[n])) return true;
330
+ }
331
+ return false;
332
+ })(nodesToRemove));
333
+
334
+ const isSizeNode = isRemoveNode || this.#sn_isSizeNode(newNode);
335
+ const _getMaintainedNode = this.#sn_getMaintainedNode.bind(this, isRemoveAnchor, isSizeNode);
336
+ const _isMaintainedNode = this.#sn_isMaintainedNode.bind(this, isRemoveAnchor, isSizeNode);
337
+
338
+ // one line
339
+ if (oneLine) {
340
+ if (this.#sn_resetCommonListCell(lineNodes[0], stylesToModify)) range = this.#$.selection.setRange(startCon, startOff, endCon, endOff);
341
+
342
+ const newRange = this.#setNode_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
343
+ start.container = newRange.startContainer;
344
+ start.offset = newRange.startOffset;
345
+ end.container = newRange.endContainer;
346
+ end.offset = newRange.endOffset;
347
+
348
+ if (start.container === end.container && dom.check.isZeroWidth(start.container)) {
349
+ start.offset = end.offset = 1;
350
+ }
351
+ this.#sn_setCommonListStyle(newRange.ancestor, null);
352
+ } else {
353
+ // multi line
354
+ let appliedCommonList = false;
355
+ if (endLength > 0 && this.#sn_resetCommonListCell(lineNodes[endLength], stylesToModify)) appliedCommonList = true;
356
+ if (this.#sn_resetCommonListCell(lineNodes[0], stylesToModify)) appliedCommonList = true;
357
+ if (appliedCommonList) this.#$.selection.setRange(startCon, startOff, endCon, endOff);
358
+
359
+ // end
360
+ if (endLength > 0) {
361
+ newNode = styleNode.cloneNode(false);
362
+ end = this.#setNode_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
363
+ }
364
+
365
+ // mid
366
+ for (let i = endLength - 1, newRange; i > 0; i--) {
367
+ this.#sn_resetCommonListCell(lineNodes[i], stylesToModify);
368
+ newNode = styleNode.cloneNode(false);
369
+ newRange = this.#setNode_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
370
+ if (newRange.endContainer && newRange.ancestor.contains(newRange.endContainer)) {
371
+ end.ancestor = null;
372
+ end.container = newRange.endContainer;
373
+ }
374
+ this.#sn_setCommonListStyle(newRange.ancestor, null);
375
+ }
376
+
377
+ // start
378
+ newNode = styleNode.cloneNode(false);
379
+ start = this.#setNode_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
380
+
381
+ if (start.endContainer) {
382
+ end.ancestor = null;
383
+ end.container = start.endContainer;
384
+ }
385
+
386
+ if (endLength <= 0) {
387
+ end = start;
388
+ } else if (!end.container) {
389
+ end.ancestor = null;
390
+ end.container = start.container;
391
+ end.offset = start.container.textContent.length;
392
+ }
393
+
394
+ this.#sn_setCommonListStyle(start.ancestor, null);
395
+ this.#sn_setCommonListStyle(end.ancestor || this.#$.format.getLine(end.container), null);
396
+ }
397
+
398
+ // set range
399
+ this.#$.ui.offCurrentController();
400
+ this.#$.selection.setRange(start.container, start.offset, end.container, end.offset);
401
+ this.#$.history.push(false);
402
+
403
+ return /** @type {HTMLElement} */ (newNode);
404
+ }
405
+
406
+ /**
407
+ * @description Remove all inline formats (styles and tags) from the currently selected text.
408
+ * - This is a convenience method that calls `apply()` with `null` parameters to strip all formatting.
409
+ * - Removes all inline style nodes (span, strong, em, a, etc.)
410
+ * - Preserves only the plain text content
411
+ * - Works on the current selection or collapsed cursor position
412
+ */
413
+ remove() {
414
+ this.apply(null, { stylesToModify: null, nodesToRemove: null, strictRemove: null });
415
+ }
416
+
417
+ /**
418
+ * @internal
419
+ * @description Nodes that must remain undetached when changing text nodes (A, Label, Code, Span:font-size)
420
+ * @param {Node|string} element Element to check
421
+ * @returns {boolean}
422
+ */
423
+ _isNonSplitNode(element) {
424
+ if (!element) return false;
425
+ const checkRegExp = /^(a|label|code|summary)$/i;
426
+ if (typeof element === 'string') return checkRegExp.test(element);
427
+ return element.nodeType === 1 && checkRegExp.test(element.nodeName);
428
+ }
429
+
430
+ /**
431
+ * @internal
432
+ * @description Nodes that need to be added without modification when changing text nodes
433
+ * @param {Node} element Element to check
434
+ * @returns {boolean}
435
+ */
436
+ _isIgnoreNodeChange(element) {
437
+ return element && element.nodeType === 1 && (dom.check.isNonEditable(element) || !this.#$.format.isTextStyleNode(element) || this.#$.component.is(element));
438
+ }
439
+
440
+ /**
441
+ * @description wraps text nodes of line selected text.
442
+ * @param {Node} element The node of the line that contains the selected text node.
443
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
444
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
445
+ * @param {Node} startCon The `startContainer` property of the selection object.
446
+ * @param {number} startOff The `startOffset` property of the selection object.
447
+ * @param {Node} endCon The `endContainer` property of the selection object.
448
+ * @param {number} endOff The `endOffset` property of the selection object.
449
+ * @param {boolean} isRemoveFormat Is the remove all formats command?
450
+ * @param {boolean} isRemoveNode `newInnerNode` is remove node?
451
+ * @param {boolean} collapsed `range.collapsed`
452
+ * @param {Object} _removeCheck Object with `v` property tracking removal state.
453
+ * @param {(element: Node) => Node|null} _getMaintainedNode Function to get maintained parent node.
454
+ * @param {(element: Node) => boolean} _isMaintainedNode Function to check if node should be maintained.
455
+ * @returns {{ancestor: *, startContainer: *, startOffset: *, endContainer: *, endOffset: *}}
456
+ */
457
+ #setNode_oneLine(element, newInnerNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
458
+ // not add tag
459
+ let parentCon = startCon.parentNode;
460
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.#$.format.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
461
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
462
+ parentCon = parentCon.parentNode;
463
+ }
464
+
465
+ if (!isRemoveNode && !isRemoveFormat && parentCon === endCon.parentNode && parentCon.nodeName === newInnerNode.nodeName) {
466
+ if (dom.check.isZeroWidth(startCon.textContent.slice(0, startOff)) && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
467
+ const children = parentCon.childNodes;
468
+ let sameTag = true;
469
+
470
+ for (let i = 0, len = children.length, c, s, e, z; i < len; i++) {
471
+ c = children[i];
472
+ z = !dom.check.isZeroWidth(c);
473
+ if (c === startCon || c === endCon) {
474
+ if (c === startCon) s = true;
475
+ if (c === endCon) e = true;
476
+ continue;
477
+ }
478
+ if ((!s && z) || (s && e && z)) {
479
+ sameTag = false;
480
+ break;
481
+ }
482
+ }
483
+
484
+ if (sameTag) {
485
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
486
+
487
+ return {
488
+ ancestor: element,
489
+ startContainer: startCon,
490
+ startOffset: startOff,
491
+ endContainer: endCon,
492
+ endOffset: endOff,
493
+ };
494
+ }
495
+ }
496
+ }
497
+
498
+ // add tag
499
+ _removeCheck.v = false;
500
+ const inst = this;
501
+ const el = element;
502
+ const nNodeArray = [newInnerNode];
503
+ const pNode = element.cloneNode(false);
504
+ const isSameNode = startCon === endCon;
505
+ let startContainer = startCon;
506
+ let startOffset = startOff;
507
+ let endContainer = endCon;
508
+ let endOffset = endOff;
509
+ let startPass = false;
510
+ let endPass = false;
511
+ let pCurrent, newNode, appendNode, cssText, anchorNode;
512
+
513
+ const wRegExp = RegExp;
514
+ function checkCss(vNode) {
515
+ const regExp = new wRegExp('(?:;|^|\\s)(?:' + cssText + 'null)\\s*:[^;]*\\s*(?:;|$)', 'ig');
516
+ let style = false;
517
+
518
+ if (regExp && vNode.style.cssText.length > 0) {
519
+ style = regExp.test(vNode.style.cssText);
520
+ }
521
+
522
+ return !style;
523
+ }
524
+
525
+ (function recursionFunc(current, ancestor) {
526
+ const childNodes = current.childNodes;
527
+
528
+ for (let i = 0, len = childNodes.length, vNode; i < len; i++) {
529
+ const child = childNodes[i];
530
+ if (!child) continue;
531
+ let coverNode = ancestor;
532
+ let cloneNode;
533
+
534
+ // startContainer
535
+ if (!startPass && child === startContainer) {
536
+ let line = pNode;
537
+ anchorNode = _getMaintainedNode(child);
538
+
539
+ let _prevText = '';
540
+ let _nextText = '';
541
+ if (startContainer.nodeType === 3) {
542
+ const sText = /** @type {Text} */ (startContainer);
543
+ _prevText = sText.substringData(0, startOffset);
544
+ _nextText = sText.substringData(startOffset, isSameNode ? (endOffset >= startOffset ? endOffset - startOffset : sText.data.length - startOffset) : sText.data.length - startOffset);
545
+ }
546
+
547
+ const prevNode = dom.utils.createTextNode(_prevText);
548
+ const textNode = dom.utils.createTextNode(_nextText);
549
+
550
+ if (anchorNode) {
551
+ const a = _getMaintainedNode(ancestor);
552
+ if (a.parentNode !== line) {
553
+ let m = a;
554
+ let p = null;
555
+ while (m.parentNode !== line) {
556
+ ancestor = p = m.parentNode.cloneNode(false);
557
+ while (m.childNodes[0]) {
558
+ p.appendChild(m.childNodes[0]);
559
+ }
560
+ m.appendChild(p);
561
+ m = m.parentNode;
562
+ }
563
+ m.parentNode.appendChild(a);
564
+ }
565
+ anchorNode = anchorNode.cloneNode(false);
566
+ }
567
+
568
+ if (!dom.check.isZeroWidth(prevNode)) {
569
+ ancestor.appendChild(prevNode);
570
+ }
571
+
572
+ const prevAnchorNode = _getMaintainedNode(ancestor);
573
+ if (prevAnchorNode) anchorNode = prevAnchorNode;
574
+ if (anchorNode) line = anchorNode;
575
+
576
+ newNode = /** @type {HTMLElement} */ (child);
577
+ pCurrent = [];
578
+ cssText = '';
579
+ while (newNode !== line && newNode !== el && newNode !== null) {
580
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
581
+ if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
582
+ pCurrent.push(vNode);
583
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
584
+ }
585
+ newNode = newNode.parentElement;
586
+ }
587
+
588
+ const childNode = pCurrent.pop() || textNode;
589
+ appendNode = newNode = childNode;
590
+ while (pCurrent.length > 0) {
591
+ newNode = pCurrent.pop();
592
+ appendNode.appendChild(newNode);
593
+ appendNode = newNode;
594
+ }
595
+
596
+ newInnerNode.appendChild(childNode);
597
+ line.appendChild(newInnerNode);
598
+
599
+ if (anchorNode && !_getMaintainedNode(endContainer)) {
600
+ newInnerNode = newInnerNode.cloneNode(false);
601
+ pNode.appendChild(newInnerNode);
602
+ nNodeArray.push(newInnerNode);
603
+ }
604
+
605
+ startContainer = textNode;
606
+ startOffset = 0;
607
+ startPass = true;
608
+
609
+ if (newNode !== textNode) newNode.appendChild(startContainer);
610
+ if (!isSameNode) continue;
611
+ }
612
+
613
+ // endContainer
614
+ if (!endPass && child === endContainer) {
615
+ anchorNode = _getMaintainedNode(child);
616
+
617
+ let _prevText = '';
618
+ let _nextText = '';
619
+ if (endContainer.nodeType === 3) {
620
+ const eText = /** @type {Text} */ (endContainer);
621
+ _prevText = eText.substringData(endOffset, eText.length - endOffset);
622
+ _nextText = isSameNode ? '' : eText.substringData(0, endOffset);
623
+ }
624
+
625
+ const afterNode = dom.utils.createTextNode(_prevText);
626
+ const textNode = dom.utils.createTextNode(_nextText);
627
+
628
+ if (anchorNode) {
629
+ anchorNode = anchorNode.cloneNode(false);
630
+ } else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
631
+ newInnerNode = newInnerNode.cloneNode(false);
632
+ pNode.appendChild(newInnerNode);
633
+ nNodeArray.push(newInnerNode);
634
+ }
635
+
636
+ if (!dom.check.isZeroWidth(afterNode)) {
637
+ newNode = /** @type {HTMLElement} */ (child);
638
+ cssText = '';
639
+ pCurrent = [];
640
+ const anchors = [];
641
+ while (newNode !== pNode && newNode !== el && newNode !== null) {
642
+ if (newNode.nodeType === 1 && checkCss(newNode)) {
643
+ if (_isMaintainedNode(newNode)) anchors.push(newNode.cloneNode(false));
644
+ else pCurrent.push(newNode.cloneNode(false));
645
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
646
+ }
647
+ newNode = newNode.parentElement;
648
+ }
649
+ pCurrent = pCurrent.concat(anchors);
650
+
651
+ cloneNode = appendNode = newNode = pCurrent.pop() || afterNode;
652
+ while (pCurrent.length > 0) {
653
+ newNode = pCurrent.pop();
654
+ appendNode.appendChild(newNode);
655
+ appendNode = newNode;
656
+ }
657
+
658
+ pNode.appendChild(cloneNode);
659
+ newNode.textContent = afterNode.data;
660
+ }
661
+
662
+ if (anchorNode && cloneNode) {
663
+ const afterAnchorNode = _getMaintainedNode(cloneNode);
664
+ if (afterAnchorNode) {
665
+ anchorNode = afterAnchorNode;
666
+ }
667
+ }
668
+
669
+ newNode = /** @type {HTMLElement} */ (child);
670
+ pCurrent = [];
671
+ cssText = '';
672
+ while (newNode !== pNode && newNode !== el && newNode !== null) {
673
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
674
+ if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
675
+ pCurrent.push(vNode);
676
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
677
+ }
678
+ newNode = newNode.parentElement;
679
+ }
680
+
681
+ const childNode = pCurrent.pop() || textNode;
682
+ appendNode = newNode = childNode;
683
+ while (pCurrent.length > 0) {
684
+ newNode = pCurrent.pop();
685
+ appendNode.appendChild(newNode);
686
+ appendNode = newNode;
687
+ }
688
+
689
+ if (anchorNode) {
690
+ newInnerNode = newInnerNode.cloneNode(false);
691
+ newInnerNode.appendChild(childNode);
692
+ anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
693
+ pNode.appendChild(anchorNode);
694
+ nNodeArray.push(newInnerNode);
695
+ anchorNode = null;
696
+ } else {
697
+ newInnerNode.appendChild(childNode);
698
+ }
699
+
700
+ endContainer = textNode;
701
+ endOffset = textNode.data.length;
702
+ endPass = true;
703
+
704
+ if (!isRemoveFormat && collapsed) {
705
+ newInnerNode = textNode;
706
+ textNode.textContent = unicode.zeroWidthSpace;
707
+ }
708
+
709
+ if (newNode !== textNode) newNode.appendChild(endContainer);
710
+ continue;
711
+ }
712
+
713
+ // other
714
+ if (startPass) {
715
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) {
716
+ if (inst._isIgnoreNodeChange(child)) {
717
+ pNode.appendChild(child.cloneNode(true));
718
+ if (!collapsed) {
719
+ newInnerNode = newInnerNode.cloneNode(false);
720
+ pNode.appendChild(newInnerNode);
721
+ nNodeArray.push(newInnerNode);
722
+ }
723
+ } else {
724
+ recursionFunc(child, child);
725
+ }
726
+ continue;
727
+ }
728
+
729
+ newNode = /** @type {HTMLElement} */ (child);
730
+ pCurrent = [];
731
+ cssText = '';
732
+ const anchors = [];
733
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
734
+ vNode = endPass ? newNode.cloneNode(false) : validation(newNode);
735
+ if (newNode.nodeType === 1 && !dom.check.isBreak(child) && vNode && checkCss(newNode)) {
736
+ if (_isMaintainedNode(newNode)) {
737
+ if (!anchorNode) anchors.push(vNode);
738
+ } else {
739
+ pCurrent.push(vNode);
740
+ }
741
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
742
+ }
743
+ newNode = newNode.parentElement;
744
+ }
745
+ pCurrent = pCurrent.concat(anchors);
746
+
747
+ const childNode = pCurrent.pop() || child;
748
+ appendNode = newNode = childNode;
749
+ while (pCurrent.length > 0) {
750
+ newNode = pCurrent.pop();
751
+ appendNode.appendChild(newNode);
752
+ appendNode = newNode;
753
+ }
754
+
755
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode) && !dom.check.isZeroWidth(newInnerNode)) {
756
+ newInnerNode = newInnerNode.cloneNode(false);
757
+ pNode.appendChild(newInnerNode);
758
+ nNodeArray.push(newInnerNode);
759
+ }
760
+
761
+ if (!endPass && !anchorNode && _isMaintainedNode(childNode)) {
762
+ newInnerNode = newInnerNode.cloneNode(false);
763
+ const aChildren = childNode.childNodes;
764
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
765
+ newInnerNode.appendChild(aChildren[a]);
766
+ }
767
+ childNode.appendChild(newInnerNode);
768
+ pNode.appendChild(childNode);
769
+ nNodeArray.push(newInnerNode);
770
+ if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
771
+ else ancestor = newInnerNode;
772
+ } else if (childNode === child) {
773
+ if (!endPass) ancestor = newInnerNode;
774
+ else ancestor = pNode;
775
+ } else if (endPass) {
776
+ pNode.appendChild(childNode);
777
+ ancestor = newNode;
778
+ } else {
779
+ newInnerNode.appendChild(childNode);
780
+ ancestor = newNode;
781
+ }
782
+
783
+ if (anchorNode && child.nodeType === 3) {
784
+ if (_getMaintainedNode(child)) {
785
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
786
+ return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
787
+ });
788
+ anchorNode.appendChild(ancestorAnchorNode);
789
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
790
+ nNodeArray.push(newInnerNode);
791
+ pNode.appendChild(newInnerNode);
792
+ } else {
793
+ anchorNode = null;
794
+ }
795
+ }
796
+ }
797
+
798
+ cloneNode = child.cloneNode(false);
799
+ ancestor.appendChild(cloneNode);
800
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = cloneNode;
801
+
802
+ recursionFunc(child, coverNode);
803
+ }
804
+ })(element, pNode);
805
+
806
+ // not remove tag
807
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
808
+ return {
809
+ ancestor: element,
810
+ startContainer: startCon,
811
+ startOffset: startOff,
812
+ endContainer: endCon,
813
+ endOffset: endOff,
814
+ };
815
+ }
816
+
817
+ isRemoveFormat &&= isRemoveNode;
818
+
819
+ if (isRemoveFormat) {
820
+ for (let i = 0; i < nNodeArray.length; i++) {
821
+ const removeNode = nNodeArray[i];
822
+ let textNode, textNode_s, textNode_e;
823
+
824
+ if (collapsed) {
825
+ textNode = dom.utils.createTextNode(unicode.zeroWidthSpace);
826
+ pNode.replaceChild(textNode, removeNode);
827
+ } else {
828
+ const rChildren = removeNode.childNodes;
829
+ textNode_s = rChildren[0];
830
+ while (rChildren[0]) {
831
+ textNode_e = rChildren[0];
832
+ pNode.insertBefore(textNode_e, removeNode);
833
+ }
834
+ dom.utils.removeItem(removeNode);
835
+ }
836
+
837
+ if (i === 0) {
838
+ if (collapsed) {
839
+ startContainer = endContainer = textNode;
840
+ } else {
841
+ startContainer = textNode_s;
842
+ endContainer = textNode_e;
843
+ }
844
+ }
845
+ }
846
+ } else {
847
+ if (isRemoveNode) {
848
+ for (let i = 0; i < nNodeArray.length; i++) {
849
+ SN_StripRemoveNode(nNodeArray[i]);
850
+ }
851
+ }
852
+
853
+ if (collapsed) {
854
+ startContainer = endContainer = newInnerNode;
855
+ }
856
+ }
857
+
858
+ this.#$.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
859
+
860
+ if (collapsed) {
861
+ startOffset = startContainer.textContent.length;
862
+ endOffset = endContainer.textContent.length;
863
+ }
864
+
865
+ // endContainer reset
866
+ const endConReset = isRemoveFormat || endContainer.textContent.length === 0;
867
+
868
+ if (!dom.check.isBreak(endContainer) && endContainer.textContent.length === 0) {
869
+ dom.utils.removeItem(endContainer);
870
+ endContainer = startContainer;
871
+ }
872
+ endOffset = endConReset ? endContainer.textContent.length : endOffset;
873
+
874
+ // node change
875
+ const newStartOffset = {
876
+ s: 0,
877
+ e: 0,
878
+ };
879
+ const startPath = dom.query.getNodePath(startContainer, pNode, newStartOffset);
880
+
881
+ const mergeEndCon = !endContainer.parentNode;
882
+ if (mergeEndCon) endContainer = startContainer;
883
+ const newEndOffset = {
884
+ s: 0,
885
+ e: 0,
886
+ };
887
+ const endPath = dom.query.getNodePath(endContainer, pNode, !mergeEndCon && !endConReset ? newEndOffset : null);
888
+
889
+ startOffset += newStartOffset.s;
890
+ endOffset = collapsed ? startOffset : mergeEndCon ? startContainer.textContent.length : endConReset ? endOffset + newStartOffset.s : endOffset + newEndOffset.s;
891
+
892
+ // tag merge
893
+ const newOffsets = this.#$.nodeTransform.mergeSameTags(pNode, [startPath, endPath], true);
894
+
895
+ element.parentNode.replaceChild(pNode, element);
896
+
897
+ startContainer = dom.query.getNodeFromPath(startPath, pNode);
898
+ endContainer = dom.query.getNodeFromPath(endPath, pNode);
899
+
900
+ return {
901
+ ancestor: pNode,
902
+ startContainer: startContainer,
903
+ startOffset: startOffset + newOffsets[0],
904
+ endContainer: endContainer,
905
+ endOffset: endOffset + newOffsets[1],
906
+ };
907
+ }
908
+
909
+ /**
910
+ * @description wraps first line selected text.
911
+ * @param {Node} element The node of the line that contains the selected text node.
912
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
913
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
914
+ * @param {Node} startCon The `startContainer` property of the selection object.
915
+ * @param {number} startOff The `startOffset` property of the selection object.
916
+ * @param {boolean} isRemoveFormat Is the remove all formats command?
917
+ * @param {boolean} isRemoveNode `newInnerNode` is remove node?
918
+ * @param {Object} _removeCheck Object tracking removal state.
919
+ * @param {(element: Node) => Node|null} _getMaintainedNode Function to get maintained parent node.
920
+ * @param {(element: Node) => boolean} _isMaintainedNode Function to check if node should be maintained.
921
+ * @param {Node} _endContainer End container node.
922
+ * @returns {NodeStyleContainerType} { ancestor, container, offset, endContainer }
923
+ */
924
+ #setNode_startLine(element, newInnerNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, _endContainer) {
925
+ // not add tag
926
+ let parentCon = startCon.parentNode;
927
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.#$.format.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
928
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
929
+ parentCon = parentCon.parentNode;
930
+ }
931
+
932
+ if (!isRemoveNode && !isRemoveFormat && parentCon.nodeName === newInnerNode.nodeName && !this.#$.format.isLine(parentCon) && !parentCon.nextSibling && dom.check.isZeroWidth(startCon.textContent.slice(0, startOff))) {
933
+ let sameTag = true;
934
+ let s = startCon.previousSibling;
935
+ while (s) {
936
+ if (!dom.check.isZeroWidth(s)) {
937
+ sameTag = false;
938
+ break;
939
+ }
940
+ s = s.previousSibling;
941
+ }
942
+
943
+ if (sameTag) {
944
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
945
+
946
+ return {
947
+ ancestor: element,
948
+ container: startCon,
949
+ offset: startOff,
950
+ };
951
+ }
952
+ }
953
+
954
+ // add tag
955
+ _removeCheck.v = false;
956
+ const inst = this;
957
+ const el = element;
958
+ const nNodeArray = [newInnerNode];
959
+ const pNode = element.cloneNode(false);
960
+
961
+ let container = startCon;
962
+ let offset = startOff;
963
+ let passNode = false;
964
+ let pCurrent, newNode, appendNode, anchorNode;
965
+
966
+ (function recursionFunc(current, ancestor) {
967
+ const childNodes = current.childNodes;
968
+
969
+ for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
970
+ const child = /** @type {HTMLElement} */ (childNodes[i]);
971
+ if (!child) continue;
972
+ let coverNode = ancestor;
973
+
974
+ if (passNode && !dom.check.isBreak(child)) {
975
+ if (child.nodeType === 1) {
976
+ if (inst._isIgnoreNodeChange(child)) {
977
+ newInnerNode = newInnerNode.cloneNode(false);
978
+ cloneChild = child.cloneNode(true);
979
+ pNode.appendChild(cloneChild);
980
+ pNode.appendChild(newInnerNode);
981
+ nNodeArray.push(newInnerNode);
982
+
983
+ // end container
984
+ if (_endContainer && child.contains(_endContainer)) {
985
+ const endPath = dom.query.getNodePath(_endContainer, child);
986
+ _endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
987
+ }
988
+ } else {
989
+ recursionFunc(child, child);
990
+ }
991
+ continue;
992
+ }
993
+
994
+ newNode = child;
995
+ pCurrent = [];
996
+ const anchors = [];
997
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
998
+ vNode = validation(newNode);
999
+ if (newNode.nodeType === 1 && vNode) {
1000
+ if (_isMaintainedNode(newNode)) {
1001
+ if (!anchorNode) anchors.push(vNode);
1002
+ } else {
1003
+ pCurrent.push(vNode);
1004
+ }
1005
+ }
1006
+ newNode = newNode.parentNode;
1007
+ }
1008
+ pCurrent = pCurrent.concat(anchors);
1009
+
1010
+ const isTopNode = pCurrent.length > 0;
1011
+ const childNode = pCurrent.pop() || child;
1012
+ appendNode = newNode = childNode;
1013
+ while (pCurrent.length > 0) {
1014
+ newNode = pCurrent.pop();
1015
+ appendNode.appendChild(newNode);
1016
+ appendNode = newNode;
1017
+ }
1018
+
1019
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
1020
+ newInnerNode = newInnerNode.cloneNode(false);
1021
+ pNode.appendChild(newInnerNode);
1022
+ nNodeArray.push(newInnerNode);
1023
+ }
1024
+
1025
+ if (!anchorNode && _isMaintainedNode(childNode)) {
1026
+ newInnerNode = newInnerNode.cloneNode(false);
1027
+ const aChildren = childNode.childNodes;
1028
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
1029
+ newInnerNode.appendChild(aChildren[a]);
1030
+ }
1031
+ childNode.appendChild(newInnerNode);
1032
+ pNode.appendChild(childNode);
1033
+ ancestor = !_isMaintainedNode(newNode) ? newNode : newInnerNode;
1034
+ nNodeArray.push(newInnerNode);
1035
+ } else if (isTopNode) {
1036
+ newInnerNode.appendChild(childNode);
1037
+ ancestor = newNode;
1038
+ } else {
1039
+ ancestor = newInnerNode;
1040
+ }
1041
+
1042
+ if (anchorNode && child.nodeType === 3) {
1043
+ if (_getMaintainedNode(child)) {
1044
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
1045
+ return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
1046
+ });
1047
+ anchorNode.appendChild(ancestorAnchorNode);
1048
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
1049
+ nNodeArray.push(newInnerNode);
1050
+ pNode.appendChild(newInnerNode);
1051
+ } else {
1052
+ anchorNode = null;
1053
+ }
1054
+ }
1055
+ }
1056
+
1057
+ // startContainer
1058
+ if (!passNode && child === container) {
1059
+ let line = pNode;
1060
+ anchorNode = _getMaintainedNode(child);
1061
+
1062
+ let _prevText = '';
1063
+ let _nextText = '';
1064
+ if (container.nodeType === 3) {
1065
+ const cText = /** @type {Text} */ (container);
1066
+ _prevText = cText.substringData(0, offset);
1067
+ _nextText = cText.substringData(offset, cText.length - offset);
1068
+ }
1069
+
1070
+ const prevNode = dom.utils.createTextNode(_prevText);
1071
+ const textNode = dom.utils.createTextNode(_nextText);
1072
+
1073
+ if (anchorNode) {
1074
+ const a = _getMaintainedNode(ancestor);
1075
+ if (a && a.parentNode !== line) {
1076
+ let m = a;
1077
+ let p = null;
1078
+ while (m.parentNode !== line) {
1079
+ ancestor = p = m.parentNode.cloneNode(false);
1080
+ while (m.childNodes[0]) {
1081
+ p.appendChild(m.childNodes[0]);
1082
+ }
1083
+ m.appendChild(p);
1084
+ m = m.parentNode;
1085
+ }
1086
+ m.parentNode.appendChild(a);
1087
+ }
1088
+ anchorNode = anchorNode.cloneNode(false);
1089
+ }
1090
+
1091
+ if (!dom.check.isZeroWidth(prevNode)) {
1092
+ ancestor.appendChild(prevNode);
1093
+ }
1094
+
1095
+ const prevAnchorNode = _getMaintainedNode(ancestor);
1096
+ if (prevAnchorNode) anchorNode = prevAnchorNode;
1097
+ if (anchorNode) line = anchorNode;
1098
+
1099
+ newNode = ancestor;
1100
+ pCurrent = [];
1101
+ while (newNode !== line && newNode !== null) {
1102
+ vNode = validation(newNode);
1103
+ if (newNode.nodeType === 1 && vNode) {
1104
+ pCurrent.push(vNode);
1105
+ }
1106
+ newNode = newNode.parentNode;
1107
+ }
1108
+
1109
+ const childNode = pCurrent.pop() || ancestor;
1110
+ appendNode = newNode = childNode;
1111
+ while (pCurrent.length > 0) {
1112
+ newNode = pCurrent.pop();
1113
+ appendNode.appendChild(newNode);
1114
+ appendNode = newNode;
1115
+ }
1116
+
1117
+ if (childNode !== ancestor) {
1118
+ newInnerNode.appendChild(childNode);
1119
+ ancestor = newNode;
1120
+ } else {
1121
+ ancestor = newInnerNode;
1122
+ }
1123
+
1124
+ if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
1125
+ line.appendChild(newInnerNode);
1126
+
1127
+ container = textNode;
1128
+ offset = 0;
1129
+ passNode = true;
1130
+
1131
+ ancestor.appendChild(container);
1132
+ continue;
1133
+ }
1134
+
1135
+ vNode = !passNode ? child.cloneNode(false) : validation(child);
1136
+ if (vNode) {
1137
+ ancestor.appendChild(vNode);
1138
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
1139
+ }
1140
+
1141
+ recursionFunc(child, coverNode);
1142
+ }
1143
+ })(element, pNode);
1144
+
1145
+ // not remove tag
1146
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
1147
+ return {
1148
+ ancestor: element,
1149
+ container: startCon,
1150
+ offset: startOff,
1151
+ endContainer: _endContainer,
1152
+ };
1153
+ }
1154
+
1155
+ isRemoveFormat &&= isRemoveNode;
1156
+
1157
+ if (isRemoveFormat) {
1158
+ for (let i = 0; i < nNodeArray.length; i++) {
1159
+ const removeNode = nNodeArray[i];
1160
+
1161
+ const rChildren = removeNode.childNodes;
1162
+ const textNode = rChildren[0];
1163
+ while (rChildren[0]) {
1164
+ pNode.insertBefore(rChildren[0], removeNode);
1165
+ }
1166
+ dom.utils.removeItem(removeNode);
1167
+
1168
+ if (i === 0) container = textNode;
1169
+ }
1170
+ } else if (isRemoveNode) {
1171
+ newInnerNode = newInnerNode.firstChild;
1172
+ for (let i = 0; i < nNodeArray.length; i++) {
1173
+ SN_StripRemoveNode(nNodeArray[i]);
1174
+ }
1175
+ }
1176
+
1177
+ if (!isRemoveFormat && pNode.childNodes.length === 0) {
1178
+ if (element.childNodes) {
1179
+ container = element.childNodes[0];
1180
+ } else {
1181
+ container = dom.utils.createTextNode(unicode.zeroWidthSpace);
1182
+ element.appendChild(container);
1183
+ }
1184
+ } else {
1185
+ this.#$.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
1186
+
1187
+ if (dom.check.isZeroWidth(pNode.textContent)) {
1188
+ container = pNode.firstChild;
1189
+ offset = 0;
1190
+ }
1191
+
1192
+ // node change
1193
+ const offsets = {
1194
+ s: 0,
1195
+ e: 0,
1196
+ };
1197
+ const path = dom.query.getNodePath(container, pNode, offsets);
1198
+ offset += offsets.s;
1199
+
1200
+ // tag merge
1201
+ const newOffsets = this.#$.nodeTransform.mergeSameTags(pNode, [path], true);
1202
+
1203
+ element.parentNode.replaceChild(pNode, element);
1204
+
1205
+ container = dom.query.getNodeFromPath(path, pNode);
1206
+ offset += newOffsets[0];
1207
+ }
1208
+
1209
+ return {
1210
+ ancestor: pNode,
1211
+ container: container,
1212
+ offset: offset,
1213
+ endContainer: _endContainer,
1214
+ };
1215
+ }
1216
+
1217
+ /**
1218
+ * @description wraps mid lines selected text.
1219
+ * @param {HTMLElement} element The node of the line that contains the selected text node.
1220
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
1221
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
1222
+ * @param {boolean} isRemoveFormat Is the remove all formats command?
1223
+ * @param {boolean} isRemoveNode `newInnerNode` is remove node?
1224
+ * @param {Object} _removeCheck Object tracking removal state.
1225
+ * @param {Node} _endContainer Offset node of last line already modified (`end.container`)
1226
+ * @returns {NodeStyleContainerType} { ancestor, endContainer: If end container is renewed, returned renewed node }
1227
+ */
1228
+ #setNode_middleLine(element, newInnerNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, _endContainer) {
1229
+ // not add tag
1230
+ if (!isRemoveNode) {
1231
+ // end container path
1232
+ let endPath = null;
1233
+ if (_endContainer && element.contains(_endContainer)) endPath = dom.query.getNodePath(_endContainer, element);
1234
+
1235
+ const tempNode = element.cloneNode(true);
1236
+ const newNodeName = /** @type {HTMLElement} */ (newInnerNode).nodeName;
1237
+ const newCssText = /** @type {HTMLElement} */ (newInnerNode).style.cssText;
1238
+ const newClass = /** @type {HTMLElement} */ (newInnerNode).className;
1239
+
1240
+ let children = tempNode.childNodes;
1241
+ let i = 0,
1242
+ len = children.length;
1243
+ for (let child; i < len; i++) {
1244
+ child = /** @type {HTMLElement} */ (children[i]);
1245
+ if (child.nodeType === 3) break;
1246
+ if (child.nodeName === newNodeName) {
1247
+ child.style.cssText += newCssText;
1248
+ dom.utils.addClass(child, newClass);
1249
+ } else if (!dom.check.isBreak(child) && this._isIgnoreNodeChange(child)) {
1250
+ continue;
1251
+ } else if (len === 1) {
1252
+ children = child.childNodes;
1253
+ len = children.length;
1254
+ i = -1;
1255
+ continue;
1256
+ } else {
1257
+ break;
1258
+ }
1259
+ }
1260
+
1261
+ if (len > 0 && i === len) {
1262
+ element.innerHTML = /** @type {HTMLElement} */ (tempNode).innerHTML;
1263
+ return {
1264
+ ancestor: element,
1265
+ endContainer: endPath ? dom.query.getNodeFromPath(endPath, element) : null,
1266
+ };
1267
+ }
1268
+ }
1269
+
1270
+ // add tag
1271
+ _removeCheck.v = false;
1272
+ const inst = this;
1273
+ const pNode = element.cloneNode(false);
1274
+ const nNodeArray = [newInnerNode];
1275
+ let noneChange = true;
1276
+
1277
+ (function recursionFunc(current, ancestor) {
1278
+ const childNodes = current.childNodes;
1279
+
1280
+ for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
1281
+ const child = /** @type {HTMLElement} */ (childNodes[i]);
1282
+ if (!child) continue;
1283
+ let coverNode = ancestor;
1284
+
1285
+ if (!dom.check.isBreak(child) && inst._isIgnoreNodeChange(child)) {
1286
+ if (newInnerNode.childNodes.length > 0) {
1287
+ pNode.appendChild(newInnerNode);
1288
+ newInnerNode = newInnerNode.cloneNode(false);
1289
+ }
1290
+
1291
+ cloneChild = child.cloneNode(true);
1292
+ pNode.appendChild(cloneChild);
1293
+ pNode.appendChild(newInnerNode);
1294
+ nNodeArray.push(newInnerNode);
1295
+ ancestor = newInnerNode;
1296
+
1297
+ // end container
1298
+ if (_endContainer && child.contains(_endContainer)) {
1299
+ const endPath = dom.query.getNodePath(_endContainer, child);
1300
+ _endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
1301
+ }
1302
+
1303
+ continue;
1304
+ } else {
1305
+ vNode = validation(child);
1306
+ if (vNode) {
1307
+ noneChange = false;
1308
+ ancestor.appendChild(vNode);
1309
+ if (child.nodeType === 1) coverNode = vNode;
1310
+ }
1311
+ }
1312
+
1313
+ if (!dom.check.isBreak(child)) recursionFunc(child, coverNode);
1314
+ }
1315
+ })(element, newInnerNode);
1316
+
1317
+ // not remove tag
1318
+ if (noneChange || (isRemoveNode && !isRemoveFormat && !_removeCheck.v))
1319
+ return {
1320
+ ancestor: element,
1321
+ endContainer: _endContainer,
1322
+ };
1323
+
1324
+ pNode.appendChild(newInnerNode);
1325
+
1326
+ if (isRemoveFormat && isRemoveNode) {
1327
+ for (let i = 0; i < nNodeArray.length; i++) {
1328
+ const removeNode = nNodeArray[i];
1329
+
1330
+ const rChildren = removeNode.childNodes;
1331
+ while (rChildren[0]) {
1332
+ pNode.insertBefore(rChildren[0], removeNode);
1333
+ }
1334
+ dom.utils.removeItem(removeNode);
1335
+ }
1336
+ } else if (isRemoveNode) {
1337
+ newInnerNode = newInnerNode.firstChild;
1338
+ for (let i = 0; i < nNodeArray.length; i++) {
1339
+ SN_StripRemoveNode(nNodeArray[i]);
1340
+ }
1341
+ }
1342
+
1343
+ this.#$.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
1344
+ this.#$.nodeTransform.mergeSameTags(pNode, null, true);
1345
+
1346
+ // node change
1347
+ element.parentNode.replaceChild(pNode, element);
1348
+ return {
1349
+ ancestor: pNode,
1350
+ endContainer: _endContainer,
1351
+ };
1352
+ }
1353
+
1354
+ /**
1355
+ * @description wraps last line selected text.
1356
+ * @param {Node} element The node of the line that contains the selected text node.
1357
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
1358
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
1359
+ * @param {Node} endCon The `endContainer` property of the selection object.
1360
+ * @param {number} endOff The `endOffset` property of the selection object.
1361
+ * @param {boolean} isRemoveFormat Is the remove all formats command?
1362
+ * @param {boolean} isRemoveNode `newInnerNode` is remove node?
1363
+ * @param {Object} _removeCheck Object tracking removal state.
1364
+ * @param {(element: Node) => Node|null} _getMaintainedNode Function to get maintained parent node.
1365
+ * @param {(element: Node) => boolean} _isMaintainedNode Function to check if node should be maintained.
1366
+ * @returns {NodeStyleContainerType} { ancestor, container, offset }
1367
+ */
1368
+ #setNode_endLine(element, newInnerNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
1369
+ // not add tag
1370
+ let parentCon = endCon.parentNode;
1371
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.#$.format.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
1372
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
1373
+ parentCon = parentCon.parentNode;
1374
+ }
1375
+
1376
+ if (!isRemoveNode && !isRemoveFormat && parentCon.nodeName === newInnerNode.nodeName && !this.#$.format.isLine(parentCon) && !parentCon.previousSibling && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
1377
+ let sameTag = true;
1378
+ let e = endCon.nextSibling;
1379
+ while (e) {
1380
+ if (!dom.check.isZeroWidth(e)) {
1381
+ sameTag = false;
1382
+ break;
1383
+ }
1384
+ e = e.nextSibling;
1385
+ }
1386
+
1387
+ if (sameTag) {
1388
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
1389
+
1390
+ return {
1391
+ ancestor: element,
1392
+ container: endCon,
1393
+ offset: endOff,
1394
+ };
1395
+ }
1396
+ }
1397
+
1398
+ // add tag
1399
+ _removeCheck.v = false;
1400
+ const inst = this;
1401
+ const el = element;
1402
+ const nNodeArray = [newInnerNode];
1403
+ const pNode = element.cloneNode(false);
1404
+
1405
+ let container = endCon;
1406
+ let offset = endOff;
1407
+ let passNode = false;
1408
+ let pCurrent, newNode, appendNode, anchorNode;
1409
+
1410
+ (function recursionFunc(current, ancestor) {
1411
+ const childNodes = current.childNodes;
1412
+
1413
+ for (let i = childNodes.length - 1, vNode; 0 <= i; i--) {
1414
+ const child = childNodes[i];
1415
+ if (!child) continue;
1416
+ let coverNode = ancestor;
1417
+
1418
+ if (passNode && !dom.check.isBreak(child)) {
1419
+ if (child.nodeType === 1) {
1420
+ if (inst._isIgnoreNodeChange(child)) {
1421
+ newInnerNode = newInnerNode.cloneNode(false);
1422
+ const cloneChild = child.cloneNode(true);
1423
+ pNode.insertBefore(cloneChild, ancestor);
1424
+ pNode.insertBefore(newInnerNode, cloneChild);
1425
+ nNodeArray.push(newInnerNode);
1426
+ } else {
1427
+ recursionFunc(child, child);
1428
+ }
1429
+ continue;
1430
+ }
1431
+
1432
+ newNode = child;
1433
+ pCurrent = [];
1434
+ const anchors = [];
1435
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
1436
+ vNode = validation(newNode);
1437
+ if (vNode && newNode.nodeType === 1) {
1438
+ if (_isMaintainedNode(newNode)) {
1439
+ if (!anchorNode) anchors.push(vNode);
1440
+ } else {
1441
+ pCurrent.push(vNode);
1442
+ }
1443
+ }
1444
+ newNode = newNode.parentNode;
1445
+ }
1446
+ pCurrent = pCurrent.concat(anchors);
1447
+
1448
+ const isTopNode = pCurrent.length > 0;
1449
+ const childNode = pCurrent.pop() || child;
1450
+ appendNode = newNode = childNode;
1451
+ while (pCurrent.length > 0) {
1452
+ newNode = pCurrent.pop();
1453
+ appendNode.appendChild(newNode);
1454
+ appendNode = newNode;
1455
+ }
1456
+
1457
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
1458
+ newInnerNode = newInnerNode.cloneNode(false);
1459
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
1460
+ nNodeArray.push(newInnerNode);
1461
+ }
1462
+
1463
+ if (!anchorNode && _isMaintainedNode(childNode)) {
1464
+ newInnerNode = newInnerNode.cloneNode(false);
1465
+ const aChildren = childNode.childNodes;
1466
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
1467
+ newInnerNode.appendChild(aChildren[a]);
1468
+ }
1469
+ childNode.appendChild(newInnerNode);
1470
+ pNode.insertBefore(childNode, pNode.firstChild);
1471
+ nNodeArray.push(newInnerNode);
1472
+ if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
1473
+ else ancestor = newInnerNode;
1474
+ } else if (isTopNode) {
1475
+ newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
1476
+ ancestor = newNode;
1477
+ } else {
1478
+ ancestor = newInnerNode;
1479
+ }
1480
+
1481
+ if (anchorNode && child.nodeType === 3) {
1482
+ if (_getMaintainedNode(child)) {
1483
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
1484
+ return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
1485
+ });
1486
+ anchorNode.appendChild(ancestorAnchorNode);
1487
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
1488
+ nNodeArray.push(newInnerNode);
1489
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
1490
+ } else {
1491
+ anchorNode = null;
1492
+ }
1493
+ }
1494
+ }
1495
+
1496
+ // endContainer
1497
+ if (!passNode && child === container) {
1498
+ anchorNode = _getMaintainedNode(child);
1499
+
1500
+ let _prevText = '';
1501
+ let _nextText = '';
1502
+ if (container.nodeType === 3) {
1503
+ const cText = /** @type {Text} */ (container);
1504
+ _prevText = cText.substringData(offset, cText.length - offset);
1505
+ _nextText = cText.substringData(0, offset);
1506
+ }
1507
+
1508
+ const afterNode = dom.utils.createTextNode(_prevText);
1509
+ const textNode = dom.utils.createTextNode(_nextText);
1510
+
1511
+ if (anchorNode) {
1512
+ anchorNode = anchorNode.cloneNode(false);
1513
+ const a = _getMaintainedNode(ancestor);
1514
+ if (a.parentNode !== pNode) {
1515
+ let m = a;
1516
+ let p = null;
1517
+ while (m.parentNode !== pNode) {
1518
+ ancestor = p = m.parentNode.cloneNode(false);
1519
+ while (m.childNodes[0]) {
1520
+ p.appendChild(m.childNodes[0]);
1521
+ }
1522
+ m.appendChild(p);
1523
+ m = m.parentNode;
1524
+ }
1525
+ m.parentNode.insertBefore(a, m.parentNode.firstChild);
1526
+ }
1527
+ anchorNode = anchorNode.cloneNode(false);
1528
+ } else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
1529
+ newInnerNode = newInnerNode.cloneNode(false);
1530
+ pNode.appendChild(newInnerNode);
1531
+ nNodeArray.push(newInnerNode);
1532
+ }
1533
+
1534
+ if (!dom.check.isZeroWidth(afterNode)) {
1535
+ ancestor.insertBefore(afterNode, ancestor.firstChild);
1536
+ }
1537
+
1538
+ newNode = ancestor;
1539
+ pCurrent = [];
1540
+ while (newNode !== pNode && newNode !== null) {
1541
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
1542
+ if (vNode && newNode.nodeType === 1) {
1543
+ pCurrent.push(vNode);
1544
+ }
1545
+ newNode = newNode.parentNode;
1546
+ }
1547
+
1548
+ const childNode = pCurrent.pop() || ancestor;
1549
+ appendNode = newNode = childNode;
1550
+ while (pCurrent.length > 0) {
1551
+ newNode = pCurrent.pop();
1552
+ appendNode.appendChild(newNode);
1553
+ appendNode = newNode;
1554
+ }
1555
+
1556
+ if (childNode !== ancestor) {
1557
+ newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
1558
+ ancestor = newNode;
1559
+ } else {
1560
+ ancestor = newInnerNode;
1561
+ }
1562
+
1563
+ if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
1564
+
1565
+ if (anchorNode) {
1566
+ anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
1567
+ pNode.insertBefore(anchorNode, pNode.firstChild);
1568
+ anchorNode = null;
1569
+ } else {
1570
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
1571
+ }
1572
+
1573
+ container = textNode;
1574
+ offset = textNode.data.length;
1575
+ passNode = true;
1576
+
1577
+ ancestor.insertBefore(container, ancestor.firstChild);
1578
+ continue;
1579
+ }
1580
+
1581
+ vNode = !passNode ? child.cloneNode(false) : validation(child);
1582
+ if (vNode) {
1583
+ ancestor.insertBefore(vNode, ancestor.firstChild);
1584
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
1585
+ }
1586
+
1587
+ recursionFunc(child, coverNode);
1588
+ }
1589
+ })(element, pNode);
1590
+
1591
+ // not remove tag
1592
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
1593
+ return {
1594
+ ancestor: element,
1595
+ container: endCon,
1596
+ offset: endOff,
1597
+ };
1598
+ }
1599
+
1600
+ isRemoveFormat &&= isRemoveNode;
1601
+
1602
+ if (isRemoveFormat) {
1603
+ for (let i = 0; i < nNodeArray.length; i++) {
1604
+ const removeNode = nNodeArray[i];
1605
+
1606
+ const rChildren = removeNode.childNodes;
1607
+ let textNode = null;
1608
+ while (rChildren[0]) {
1609
+ textNode = rChildren[0];
1610
+ pNode.insertBefore(textNode, removeNode);
1611
+ }
1612
+ dom.utils.removeItem(removeNode);
1613
+
1614
+ if (i === nNodeArray.length - 1) {
1615
+ container = textNode;
1616
+ offset = textNode.textContent.length;
1617
+ }
1618
+ }
1619
+ } else if (isRemoveNode) {
1620
+ newInnerNode = newInnerNode.firstChild;
1621
+ for (let i = 0; i < nNodeArray.length; i++) {
1622
+ SN_StripRemoveNode(nNodeArray[i]);
1623
+ }
1624
+ }
1625
+
1626
+ if (!isRemoveFormat && pNode.childNodes.length === 0) {
1627
+ if (element.childNodes) {
1628
+ container = element.childNodes[0];
1629
+ } else {
1630
+ container = dom.utils.createTextNode(unicode.zeroWidthSpace);
1631
+ element.appendChild(container);
1632
+ }
1633
+ } else {
1634
+ if (!isRemoveNode && newInnerNode.textContent.length === 0) {
1635
+ this.#$.nodeTransform.removeEmptyNode(pNode, null, false);
1636
+ return {
1637
+ ancestor: null,
1638
+ container: null,
1639
+ offset: 0,
1640
+ };
1641
+ }
1642
+
1643
+ this.#$.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
1644
+
1645
+ if (dom.check.isZeroWidth(pNode.textContent)) {
1646
+ container = pNode.firstChild;
1647
+ offset = container.textContent.length;
1648
+ } else if (dom.check.isZeroWidth(container)) {
1649
+ container = newInnerNode;
1650
+ offset = 1;
1651
+ }
1652
+
1653
+ // node change
1654
+ const offsets = {
1655
+ s: 0,
1656
+ e: 0,
1657
+ };
1658
+ const path = dom.query.getNodePath(container, pNode, offsets);
1659
+ offset += offsets.s;
1660
+
1661
+ // tag merge
1662
+ const newOffsets = this.#$.nodeTransform.mergeSameTags(pNode, [path], true);
1663
+
1664
+ element.parentNode.replaceChild(pNode, element);
1665
+
1666
+ container = dom.query.getNodeFromPath(path, pNode);
1667
+ offset += newOffsets[0];
1668
+ }
1669
+
1670
+ return {
1671
+ ancestor: pNode,
1672
+ container: container,
1673
+ offset: container.nodeType === 1 && offset === 1 ? container.childNodes.length : offset,
1674
+ };
1675
+ }
1676
+
1677
+ /**
1678
+ * @description Node with `font-size` style
1679
+ * @param {Node} element Element to check
1680
+ * @returns {boolean}
1681
+ */
1682
+ #sn_isSizeNode(element) {
1683
+ return element && typeof element !== 'string' && element.nodeType !== 3 && this.#$.format.isTextStyleNode(element) && !!element.style.fontSize;
1684
+ }
1685
+
1686
+ /**
1687
+ * @description Return the parent maintained tag. (bind and use a util object)
1688
+ * @param {boolean} _isRemove is remove anchor
1689
+ * @param {boolean} _isSizeNode is size span node
1690
+ * @param {Node} element Element
1691
+ * @returns {Node|null}
1692
+ */
1693
+ #sn_getMaintainedNode(_isRemove, _isSizeNode, element) {
1694
+ if (!element || _isRemove) return null;
1695
+ return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) || (!_isSizeNode ? dom.query.getParentElement(element, this.#sn_isSizeNode.bind(this)) : null);
1696
+ }
1697
+
1698
+ /**
1699
+ * @description Check if element is a tag that should be persisted. (bind and use a util object)
1700
+ * @param {boolean} _isRemove is remove anchor
1701
+ * @param {boolean} _isSizeNode is size span node
1702
+ * @param {Node} element Element
1703
+ * @returns {boolean}
1704
+ */
1705
+ #sn_isMaintainedNode(_isRemove, _isSizeNode, element) {
1706
+ if (!element || _isRemove || element.nodeType !== 1) return false;
1707
+ const anchor = this._isNonSplitNode(element);
1708
+ return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) ? anchor : anchor || (!_isSizeNode ? this.#sn_isSizeNode(element) : false);
1709
+ }
1710
+
1711
+ /**
1712
+ * @description If certain styles are applied to all child nodes of the list cell, the style of the list cell is also changed. (bold, color, size)
1713
+ * @param {Node} el List cell element. `<li>`
1714
+ * @param {?Node} child Variable for recursive call. (`null` on the first call)
1715
+ */
1716
+ #sn_setCommonListStyle(el, child) {
1717
+ if (!dom.check.isListCell(el)) return;
1718
+
1719
+ const children = dom.utils.arrayFilter((child || el).childNodes, (current) => !dom.check.isBreak(current));
1720
+ child = children[0];
1721
+
1722
+ if (!dom.check.isElement(child) || children.length > 1) return;
1723
+
1724
+ // set cell style---
1725
+ const childStyle = child.style;
1726
+ const elStyle = el.style;
1727
+ const nodeName = child.nodeName.toLowerCase();
1728
+ let appliedEl = false;
1729
+
1730
+ // bold, italic
1731
+ if (this.#options.get('_defaultStyleTagMap')[nodeName] === this.#options.get('_defaultTagCommand').bold.toLowerCase()) elStyle.fontWeight = 'bold';
1732
+ if (this.#options.get('_defaultStyleTagMap')[nodeName] === this.#options.get('_defaultTagCommand').italic.toLowerCase()) elStyle.fontStyle = 'italic';
1733
+
1734
+ // styles
1735
+ const cKeys = converter.getValues(childStyle);
1736
+ if (cKeys.length > 0) {
1737
+ for (let i = 0, len = this.#listCamel.length; i < len; i++) {
1738
+ if (cKeys.includes(this.#listKebab[i])) {
1739
+ elStyle[this.#listCamel[i]] = childStyle[this.#listCamel[i]];
1740
+ childStyle.removeProperty(this.#listKebab[i]);
1741
+ appliedEl = true;
1742
+ }
1743
+ }
1744
+ }
1745
+
1746
+ this.#sn_setCommonListStyle(el, child);
1747
+ if (!appliedEl) return;
1748
+
1749
+ // common style
1750
+ if (childStyle.length === 0) {
1751
+ const ch = child.childNodes;
1752
+ const p = child.parentNode;
1753
+ const n = child.nextSibling;
1754
+ while (ch.length > 0) {
1755
+ p.insertBefore(ch[0], n);
1756
+ }
1757
+ dom.utils.removeItem(child);
1758
+ }
1759
+ }
1760
+
1761
+ /**
1762
+ * @description Watch the applied text nodes and adjust the common styles of the list.
1763
+ * @param {Node} el `LI` element
1764
+ * @param {?Array} styleArray Refer style array
1765
+ */
1766
+ #sn_resetCommonListCell(el, styleArray) {
1767
+ if (!dom.check.isListCell(el)) return;
1768
+ styleArray ||= this.#listKebab;
1769
+
1770
+ const children = dom.utils.arrayFilter(el.childNodes, (current) => !dom.check.isBreak(current));
1771
+ const elStyles = el.style;
1772
+
1773
+ const ec = [],
1774
+ ek = [],
1775
+ elKeys = converter.getValues(elStyles);
1776
+ for (let i = 0, len = this.#listKebab.length; i < len; i++) {
1777
+ if (elKeys.includes(this.#listKebab[i]) && styleArray.includes(this.#listKebab[i])) {
1778
+ ec.push(this.#listCamel[i]);
1779
+ ek.push(this.#listKebab[i]);
1780
+ }
1781
+ }
1782
+
1783
+ if (ec.length === 0) return;
1784
+
1785
+ // reset cell style---
1786
+ const refer = dom.utils.createElement('SPAN');
1787
+ for (let i = 0, len = ec.length; i < len; i++) {
1788
+ refer.style[ec[i]] = elStyles[ek[i]];
1789
+ elStyles.removeProperty(ek[i]);
1790
+ }
1791
+
1792
+ let sel = refer.cloneNode(false);
1793
+ let r = null,
1794
+ appliedEl = false;
1795
+ for (let i = 0, len = children.length, c, s; i < len; i++) {
1796
+ c = /** @type {HTMLElement} */ (children[i]);
1797
+ if (this.#options.get('_defaultStyleTagMap')[c.nodeName.toLowerCase()]) continue;
1798
+
1799
+ s = converter.getValues(c.style);
1800
+ if (
1801
+ s.length === 0 ||
1802
+ (ec.some(function (k) {
1803
+ return !s.includes(k);
1804
+ }) &&
1805
+ s.some(function (k) {
1806
+ return ec.includes(k);
1807
+ }))
1808
+ ) {
1809
+ r = c.nextSibling;
1810
+ sel.appendChild(c);
1811
+ } else if (sel.childNodes.length > 0) {
1812
+ el.insertBefore(sel, r);
1813
+ sel = refer.cloneNode(false);
1814
+ r = null;
1815
+ appliedEl = true;
1816
+ }
1817
+ }
1818
+
1819
+ if (sel.childNodes.length > 0) {
1820
+ el.insertBefore(sel, r);
1821
+ appliedEl = true;
1822
+ }
1823
+ if (elStyles.length === 0) {
1824
+ el.removeAttribute('style');
1825
+ }
1826
+
1827
+ return appliedEl;
1828
+ }
1829
+ }
1830
+
1831
+ /**
1832
+ * @description Strip remove node
1833
+ * @param {Node} removeNode The remove node
1834
+ */
1835
+ function SN_StripRemoveNode(removeNode) {
1836
+ const element = removeNode.parentNode;
1837
+ if (!removeNode || removeNode.nodeType === 3 || !element) return;
1838
+
1839
+ const children = removeNode.childNodes;
1840
+ while (children[0]) {
1841
+ element.insertBefore(children[0], removeNode);
1842
+ }
1843
+
1844
+ element.removeChild(removeNode);
1845
+ }
1846
+
1847
+ export default Inline;