suneditor 3.0.0-alpha.2 → 3.0.0-alpha.20

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 (306) hide show
  1. package/.eslintrc.json +4 -3
  2. package/CONTRIBUTING.md +4 -2
  3. package/README.md +19 -11
  4. package/README_V3_TEMP.md +705 -0
  5. package/dist/suneditor.min.css +1 -0
  6. package/dist/suneditor.min.js +1 -0
  7. package/example.md +587 -0
  8. package/package.json +15 -9
  9. package/src/assets/icons/_default.js +166 -131
  10. package/src/assets/{suneditor-content.css → suneditor-contents.css} +182 -45
  11. package/src/assets/suneditor.css +1195 -556
  12. package/src/assets/variables.css +138 -0
  13. package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
  14. package/src/core/base/eventHandlers/handler_ww_clipboard.js +29 -4
  15. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +59 -15
  16. package/src/core/base/eventHandlers/handler_ww_key_input.js +426 -212
  17. package/src/core/base/eventHandlers/handler_ww_mouse.js +108 -32
  18. package/src/core/base/eventManager.js +540 -209
  19. package/src/core/base/events.js +616 -320
  20. package/src/core/base/history.js +93 -39
  21. package/src/core/class/char.js +29 -13
  22. package/src/core/class/component.js +332 -145
  23. package/src/core/class/format.js +671 -509
  24. package/src/core/class/html.js +504 -290
  25. package/src/core/class/menu.js +114 -47
  26. package/src/core/class/nodeTransform.js +111 -66
  27. package/src/core/class/offset.js +409 -105
  28. package/src/core/class/selection.js +220 -108
  29. package/src/core/class/shortcuts.js +68 -8
  30. package/src/core/class/toolbar.js +106 -116
  31. package/src/core/class/ui.js +330 -0
  32. package/src/core/class/viewer.js +178 -74
  33. package/src/core/editor.js +489 -384
  34. package/src/core/section/actives.js +118 -22
  35. package/src/core/section/constructor.js +504 -170
  36. package/src/core/section/context.js +28 -23
  37. package/src/core/section/documentType.js +561 -0
  38. package/src/editorInjector/_classes.js +19 -5
  39. package/src/editorInjector/_core.js +71 -7
  40. package/src/editorInjector/index.js +63 -1
  41. package/src/helper/converter.js +137 -19
  42. package/src/helper/dom/domCheck.js +294 -0
  43. package/src/helper/dom/domQuery.js +609 -0
  44. package/src/helper/dom/domUtils.js +533 -0
  45. package/src/helper/dom/index.js +12 -0
  46. package/src/helper/env.js +42 -19
  47. package/src/helper/index.js +7 -4
  48. package/src/helper/keyCodeMap.js +183 -0
  49. package/src/helper/numbers.js +8 -8
  50. package/src/helper/unicode.js +5 -5
  51. package/src/langs/ckb.js +69 -3
  52. package/src/langs/cs.js +67 -1
  53. package/src/langs/da.js +68 -2
  54. package/src/langs/de.js +68 -3
  55. package/src/langs/en.js +29 -1
  56. package/src/langs/es.js +68 -3
  57. package/src/langs/fa.js +70 -2
  58. package/src/langs/fr.js +68 -2
  59. package/src/langs/he.js +68 -3
  60. package/src/langs/hu.js +226 -0
  61. package/src/langs/index.js +3 -2
  62. package/src/langs/it.js +65 -0
  63. package/src/langs/ja.js +68 -3
  64. package/src/langs/ko.js +66 -1
  65. package/src/langs/lv.js +68 -3
  66. package/src/langs/nl.js +68 -3
  67. package/src/langs/pl.js +68 -3
  68. package/src/langs/pt_br.js +65 -0
  69. package/src/langs/ro.js +69 -4
  70. package/src/langs/ru.js +68 -3
  71. package/src/langs/se.js +68 -3
  72. package/src/langs/tr.js +68 -0
  73. package/src/langs/ua.js +68 -3
  74. package/src/langs/ur.js +71 -6
  75. package/src/langs/zh_cn.js +69 -4
  76. package/src/modules/ApiManager.js +77 -54
  77. package/src/modules/Browser.js +667 -0
  78. package/src/modules/ColorPicker.js +162 -102
  79. package/src/modules/Controller.js +233 -136
  80. package/src/modules/Figure.js +913 -489
  81. package/src/modules/FileManager.js +141 -72
  82. package/src/modules/HueSlider.js +113 -61
  83. package/src/modules/Modal.js +292 -113
  84. package/src/modules/ModalAnchorEditor.js +380 -230
  85. package/src/modules/SelectMenu.js +270 -168
  86. package/src/modules/_DragHandle.js +2 -1
  87. package/src/modules/index.js +3 -3
  88. package/src/plugins/browser/audioGallery.js +83 -0
  89. package/src/plugins/browser/fileBrowser.js +103 -0
  90. package/src/plugins/browser/fileGallery.js +83 -0
  91. package/src/plugins/browser/imageGallery.js +81 -0
  92. package/src/plugins/browser/videoGallery.js +103 -0
  93. package/src/plugins/command/blockquote.js +40 -27
  94. package/src/plugins/command/exportPDF.js +134 -0
  95. package/src/plugins/command/fileUpload.js +226 -158
  96. package/src/plugins/command/list_bulleted.js +93 -47
  97. package/src/plugins/command/list_numbered.js +93 -47
  98. package/src/plugins/dropdown/align.js +66 -54
  99. package/src/plugins/dropdown/backgroundColor.js +76 -45
  100. package/src/plugins/dropdown/font.js +71 -47
  101. package/src/plugins/dropdown/fontColor.js +78 -46
  102. package/src/plugins/dropdown/formatBlock.js +74 -33
  103. package/src/plugins/dropdown/hr.js +102 -51
  104. package/src/plugins/dropdown/layout.js +37 -26
  105. package/src/plugins/dropdown/lineHeight.js +54 -38
  106. package/src/plugins/dropdown/list.js +60 -45
  107. package/src/plugins/dropdown/paragraphStyle.js +51 -30
  108. package/src/plugins/dropdown/table.js +1269 -777
  109. package/src/plugins/dropdown/template.js +38 -26
  110. package/src/plugins/dropdown/textStyle.js +43 -31
  111. package/src/plugins/field/mention.js +144 -82
  112. package/src/plugins/index.js +32 -6
  113. package/src/plugins/input/fontSize.js +161 -108
  114. package/src/plugins/input/pageNavigator.js +70 -0
  115. package/src/plugins/modal/audio.js +341 -169
  116. package/src/plugins/modal/drawing.js +530 -0
  117. package/src/plugins/modal/embed.js +886 -0
  118. package/src/plugins/modal/image.js +673 -358
  119. package/src/plugins/modal/link.js +100 -71
  120. package/src/plugins/modal/math.js +384 -168
  121. package/src/plugins/modal/video.js +693 -336
  122. package/src/plugins/popup/anchor.js +222 -0
  123. package/src/suneditor.js +54 -12
  124. package/src/themes/dark.css +85 -0
  125. package/src/typedef.js +86 -0
  126. package/types/assets/icons/_default.d.ts +152 -0
  127. package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
  128. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
  129. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
  130. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
  131. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
  132. package/types/core/base/eventManager.d.ts +377 -0
  133. package/types/core/base/events.d.ts +297 -0
  134. package/types/core/base/history.d.ts +81 -0
  135. package/types/core/class/char.d.ts +60 -0
  136. package/types/core/class/component.d.ts +259 -0
  137. package/types/core/class/format.d.ts +615 -0
  138. package/types/core/class/html.d.ts +377 -0
  139. package/types/core/class/menu.d.ts +118 -0
  140. package/types/core/class/nodeTransform.d.ts +93 -0
  141. package/types/core/class/offset.d.ts +512 -0
  142. package/types/core/class/selection.d.ts +188 -0
  143. package/types/core/class/shortcuts.d.ts +142 -0
  144. package/types/core/class/toolbar.d.ts +189 -0
  145. package/types/core/class/ui.d.ts +144 -0
  146. package/types/core/class/viewer.d.ts +140 -0
  147. package/types/core/editor.d.ts +606 -0
  148. package/types/core/section/actives.d.ts +46 -0
  149. package/types/core/section/constructor.d.ts +748 -0
  150. package/types/core/section/context.d.ts +45 -0
  151. package/types/core/section/documentType.d.ts +178 -0
  152. package/types/editorInjector/_classes.d.ts +41 -0
  153. package/types/editorInjector/_core.d.ts +92 -0
  154. package/types/editorInjector/index.d.ts +71 -0
  155. package/types/helper/converter.d.ts +150 -0
  156. package/types/helper/dom/domCheck.d.ts +182 -0
  157. package/types/helper/dom/domQuery.d.ts +214 -0
  158. package/types/helper/dom/domUtils.d.ts +211 -0
  159. package/types/helper/dom/index.d.ts +9 -0
  160. package/types/helper/env.d.ts +149 -0
  161. package/types/helper/index.d.ts +163 -0
  162. package/types/helper/keyCodeMap.d.ts +110 -0
  163. package/types/helper/numbers.d.ts +43 -0
  164. package/types/helper/unicode.d.ts +28 -0
  165. package/types/index.d.ts +0 -0
  166. package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +170 -103
  167. package/types/langs/ckb.d.ts +384 -0
  168. package/types/langs/cs.d.ts +384 -0
  169. package/types/langs/da.d.ts +384 -0
  170. package/types/langs/de.d.ts +384 -0
  171. package/types/langs/en.d.ts +384 -0
  172. package/types/langs/es.d.ts +384 -0
  173. package/types/langs/fa.d.ts +384 -0
  174. package/types/langs/fr.d.ts +384 -0
  175. package/types/langs/he.d.ts +384 -0
  176. package/types/langs/hu.d.ts +384 -0
  177. package/types/langs/index.d.ts +48 -0
  178. package/types/langs/it.d.ts +384 -0
  179. package/types/langs/ja.d.ts +384 -0
  180. package/types/langs/ko.d.ts +384 -0
  181. package/types/langs/lv.d.ts +384 -0
  182. package/types/langs/nl.d.ts +384 -0
  183. package/types/langs/pl.d.ts +384 -0
  184. package/types/langs/pt_br.d.ts +384 -0
  185. package/types/langs/ro.d.ts +384 -0
  186. package/types/langs/ru.d.ts +384 -0
  187. package/types/langs/se.d.ts +384 -0
  188. package/types/langs/tr.d.ts +384 -0
  189. package/types/langs/ua.d.ts +384 -0
  190. package/types/langs/ur.d.ts +384 -0
  191. package/types/langs/zh_cn.d.ts +384 -0
  192. package/types/modules/ApiManager.d.ts +125 -0
  193. package/types/modules/Browser.d.ts +326 -0
  194. package/types/modules/ColorPicker.d.ts +131 -0
  195. package/types/modules/Controller.d.ts +231 -0
  196. package/types/modules/Figure.d.ts +504 -0
  197. package/types/modules/FileManager.d.ts +202 -0
  198. package/types/modules/HueSlider.d.ts +136 -0
  199. package/types/modules/Modal.d.ts +117 -0
  200. package/types/modules/ModalAnchorEditor.d.ts +236 -0
  201. package/types/modules/SelectMenu.d.ts +194 -0
  202. package/types/modules/_DragHandle.d.ts +7 -0
  203. package/types/modules/index.d.ts +26 -0
  204. package/types/plugins/browser/audioGallery.d.ts +55 -0
  205. package/types/plugins/browser/fileBrowser.d.ts +64 -0
  206. package/types/plugins/browser/fileGallery.d.ts +55 -0
  207. package/types/plugins/browser/imageGallery.d.ts +51 -0
  208. package/types/plugins/browser/videoGallery.d.ts +57 -0
  209. package/types/plugins/command/blockquote.d.ts +28 -0
  210. package/types/plugins/command/exportPDF.d.ts +46 -0
  211. package/types/plugins/command/fileUpload.d.ts +156 -0
  212. package/types/plugins/command/list_bulleted.d.ts +56 -0
  213. package/types/plugins/command/list_numbered.d.ts +56 -0
  214. package/types/plugins/dropdown/align.d.ts +60 -0
  215. package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
  216. package/types/plugins/dropdown/font.d.ts +54 -0
  217. package/types/plugins/dropdown/fontColor.d.ts +63 -0
  218. package/types/plugins/dropdown/formatBlock.d.ts +58 -0
  219. package/types/plugins/dropdown/hr.d.ts +81 -0
  220. package/types/plugins/dropdown/layout.d.ts +40 -0
  221. package/types/plugins/dropdown/lineHeight.d.ts +50 -0
  222. package/types/plugins/dropdown/list.d.ts +39 -0
  223. package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
  224. package/types/plugins/dropdown/table.d.ts +579 -0
  225. package/types/plugins/dropdown/template.d.ts +40 -0
  226. package/types/plugins/dropdown/textStyle.d.ts +41 -0
  227. package/types/plugins/field/mention.d.ts +102 -0
  228. package/types/plugins/index.d.ts +107 -0
  229. package/types/plugins/input/fontSize.d.ts +170 -0
  230. package/types/plugins/input/pageNavigator.d.ts +28 -0
  231. package/types/plugins/modal/audio.d.ts +269 -0
  232. package/types/plugins/modal/drawing.d.ts +246 -0
  233. package/types/plugins/modal/embed.d.ts +387 -0
  234. package/types/plugins/modal/image.d.ts +451 -0
  235. package/types/plugins/modal/link.d.ts +128 -0
  236. package/types/plugins/modal/math.d.ts +193 -0
  237. package/types/plugins/modal/video.d.ts +485 -0
  238. package/types/plugins/popup/anchor.d.ts +56 -0
  239. package/types/suneditor.d.ts +51 -0
  240. package/types/typedef-global.d.ts +144 -0
  241. package/src/core/class/notice.js +0 -42
  242. package/src/helper/domUtils.js +0 -1177
  243. package/src/modules/FileBrowser.js +0 -271
  244. package/src/plugins/command/exportPdf.js +0 -168
  245. package/src/plugins/fileBrowser/imageGallery.js +0 -81
  246. package/src/themes/test.css +0 -61
  247. package/typings/CommandPlugin.d.ts +0 -8
  248. package/typings/DialogPlugin.d.ts +0 -20
  249. package/typings/FileBrowserPlugin.d.ts +0 -30
  250. package/typings/Module.d.ts +0 -15
  251. package/typings/Plugin.d.ts +0 -42
  252. package/typings/SubmenuPlugin.d.ts +0 -8
  253. package/typings/_classes.d.ts +0 -17
  254. package/typings/_colorPicker.d.ts +0 -60
  255. package/typings/_core.d.ts +0 -55
  256. package/typings/align.d.ts +0 -5
  257. package/typings/audio.d.ts +0 -5
  258. package/typings/backgroundColor.d.ts +0 -5
  259. package/typings/blockquote.d.ts +0 -5
  260. package/typings/char.d.ts +0 -39
  261. package/typings/component.d.ts +0 -38
  262. package/typings/context.d.ts +0 -39
  263. package/typings/converter.d.ts +0 -33
  264. package/typings/dialog.d.ts +0 -28
  265. package/typings/domUtils.d.ts +0 -361
  266. package/typings/editor.d.ts +0 -7
  267. package/typings/editor.ts +0 -542
  268. package/typings/env.d.ts +0 -70
  269. package/typings/eventManager.d.ts +0 -37
  270. package/typings/events.d.ts +0 -262
  271. package/typings/fileBrowser.d.ts +0 -42
  272. package/typings/fileManager.d.ts +0 -67
  273. package/typings/font.d.ts +0 -5
  274. package/typings/fontColor.d.ts +0 -5
  275. package/typings/fontSize.d.ts +0 -5
  276. package/typings/format.d.ts +0 -191
  277. package/typings/formatBlock.d.ts +0 -5
  278. package/typings/history.d.ts +0 -48
  279. package/typings/horizontalRule.d.ts +0 -5
  280. package/typings/image.d.ts +0 -5
  281. package/typings/imageGallery.d.ts +0 -5
  282. package/typings/index.d.ts +0 -21
  283. package/typings/index.modules.d.ts +0 -11
  284. package/typings/index.plugins.d.ts +0 -58
  285. package/typings/lineHeight.d.ts +0 -5
  286. package/typings/link.d.ts +0 -5
  287. package/typings/list.d.ts +0 -5
  288. package/typings/math.d.ts +0 -5
  289. package/typings/mediaContainer.d.ts +0 -25
  290. package/typings/mention.d.ts +0 -5
  291. package/typings/node.d.ts +0 -57
  292. package/typings/notice.d.ts +0 -16
  293. package/typings/numbers.d.ts +0 -29
  294. package/typings/offset.d.ts +0 -24
  295. package/typings/options.d.ts +0 -589
  296. package/typings/paragraphStyle.d.ts +0 -5
  297. package/typings/resizing.d.ts +0 -141
  298. package/typings/selection.d.ts +0 -94
  299. package/typings/shortcuts.d.ts +0 -13
  300. package/typings/suneditor.d.ts +0 -9
  301. package/typings/table.d.ts +0 -5
  302. package/typings/template.d.ts +0 -5
  303. package/typings/textStyle.d.ts +0 -5
  304. package/typings/toolbar.d.ts +0 -32
  305. package/typings/unicode.d.ts +0 -25
  306. package/typings/video.d.ts +0 -5
@@ -3,9 +3,27 @@
3
3
  */
4
4
 
5
5
  import CoreInjector from '../../editorInjector/_core';
6
- import { domUtils, unicode, numbers, env } from '../../helper';
6
+ import { dom, unicode, numbers, env } from '../../helper';
7
7
 
8
- const Format = function (editor) {
8
+ /**
9
+ * @typedef {Omit<Format & Partial<__se__EditorInjector>, 'format'>} FormatThis
10
+ */
11
+
12
+ /**
13
+ * @typedef {Object} NodeStyleContainerType
14
+ * @property {?Node=} ancestor
15
+ * @property {?number=} offset
16
+ * @property {?Node=} container
17
+ * @property {?Node=} endContainer
18
+ */
19
+
20
+ /**
21
+ * @constructor
22
+ * @this {FormatThis}
23
+ * @description Classes related to editor formats such as line creation, line retrieval from selected range, etc.
24
+ * @param {__se__EditorCore} editor - The root editor instance
25
+ */
26
+ function Format(editor) {
9
27
  CoreInjector.call(this, editor);
10
28
 
11
29
  // members
@@ -17,12 +35,13 @@ const Format = function (editor) {
17
35
  this._formatClosureBlockCheck = this.options.get('formatClosureBlock').reg;
18
36
  this._formatClosureBrLineCheck = this.options.get('formatClosureBrLine').reg;
19
37
  this._textStyleTagsCheck = new RegExp('^(' + this.options.get('textStyleTags') + ')$', 'i');
20
- };
38
+ }
21
39
 
22
40
  Format.prototype = {
23
41
  /**
42
+ * @this {FormatThis}
24
43
  * @description Replace the line tag of the current selection.
25
- * @param {Element} element Line element (P, DIV..)
44
+ * @param {Node} element Line element (P, DIV..)
26
45
  */
27
46
  setLine(element) {
28
47
  if (!this.isLine(element)) {
@@ -40,8 +59,8 @@ Format.prototype = {
40
59
  node = lines[i];
41
60
 
42
61
  if ((node.nodeName !== value || (node.className.match(/(\s|^)__se__format__[^\s]+/) || [''])[0].trim() !== className) && !this.component.is(node)) {
43
- newFormat = element.cloneNode(false);
44
- domUtils.copyFormatAttributes(newFormat, node);
62
+ newFormat = /** @type {HTMLElement} */ (element.cloneNode(false));
63
+ dom.utils.copyFormatAttributes(newFormat, node);
45
64
  newFormat.innerHTML = node.innerHTML;
46
65
 
47
66
  node.parentNode.replaceChild(newFormat, node);
@@ -52,15 +71,21 @@ Format.prototype = {
52
71
  newFormat = null;
53
72
  }
54
73
 
55
- this.selection.setRange(domUtils.getNodeFromPath(info.firstPath, first), info.startOffset, domUtils.getNodeFromPath(info.lastPath, last), info.endOffset);
74
+ this.selection.setRange(dom.query.getNodeFromPath(info.firstPath, first), info.startOffset, dom.query.getNodeFromPath(info.lastPath, last), info.endOffset);
56
75
  this.history.push(false);
76
+
77
+ // document type
78
+ if (this.editor.frameContext.has('documentType-use-header')) {
79
+ this.editor.frameContext.get('documentType').reHeader();
80
+ }
57
81
  },
58
82
 
59
83
  /**
84
+ * @this {FormatThis}
60
85
  * @description If a parent node that contains an argument node finds a format node (format.isLine), it returns that node.
61
86
  * @param {Node} node Reference node.
62
- * @param {Function|null} validation Additional validation function.
63
- * @returns {Element|null}
87
+ * @param {?(current: Node) => boolean=} validation Additional validation function.
88
+ * @returns {HTMLElement|null}
64
89
  */
65
90
  getLine(node, validation) {
66
91
  if (!node) return null;
@@ -71,9 +96,9 @@ Format.prototype = {
71
96
  }
72
97
 
73
98
  while (node) {
74
- if (domUtils.isWysiwygFrame(node)) return null;
75
- if (this.isBlock(node)) return node.firstElementChild;
76
- if (this.isLine(node) && validation(node)) return node;
99
+ if (dom.check.isWysiwygFrame(node)) return null;
100
+ if (this.isBlock(node)) return /** @type {HTMLElement} */ (node.firstElementChild);
101
+ if (this.isLine(node) && validation(node)) return /** @type {HTMLElement} */ (node);
77
102
 
78
103
  node = node.parentNode;
79
104
  }
@@ -82,8 +107,9 @@ Format.prototype = {
82
107
  },
83
108
 
84
109
  /**
110
+ * @this {FormatThis}
85
111
  * @description Replace the br-line tag of the current selection.
86
- * @param {Element} element BR-Line element (PRE..)
112
+ * @param {Node} element BR-Line element (PRE..)
87
113
  */
88
114
  setBrLine(element) {
89
115
  if (!this.isBrLine(element)) {
@@ -93,7 +119,7 @@ Format.prototype = {
93
119
  const lines = this._lineWork().lines;
94
120
  const len = lines.length - 1;
95
121
  let parentNode = lines[len].parentNode;
96
- let freeElement = element.cloneNode(false);
122
+ let freeElement = /** @type {HTMLElement} */ (element.cloneNode(false));
97
123
  const focusElement = freeElement;
98
124
 
99
125
  for (let i = len, f, html, before, next, inner, isComp, first = true; i >= 0; i--) {
@@ -102,7 +128,7 @@ Format.prototype = {
102
128
 
103
129
  isComp = this.component.is(f);
104
130
  html = isComp ? '' : f.innerHTML.replace(/(?!>)\s+(?=<)|\n/g, ' ');
105
- before = domUtils.getParentElement(f, (current) => current.parentNode === parentNode);
131
+ before = dom.query.getParentElement(f, (current) => current.parentNode === parentNode);
106
132
 
107
133
  if (parentNode !== f.parentNode || isComp) {
108
134
  if (this.isLine(parentNode)) {
@@ -113,13 +139,13 @@ Format.prototype = {
113
139
  parentNode = f.parentNode;
114
140
  }
115
141
 
116
- next = freeElement.nextSibling;
117
- if (next && freeElement.nodeName === next.nodeName && domUtils.isSameAttributes(freeElement, next)) {
142
+ next = /** @type {HTMLElement} */ (freeElement.nextSibling);
143
+ if (next && freeElement.nodeName === next.nodeName && dom.check.isSameAttributes(freeElement, next)) {
118
144
  freeElement.innerHTML += '<BR>' + next.innerHTML;
119
- domUtils.removeItem(next);
145
+ dom.utils.removeItem(next);
120
146
  }
121
147
 
122
- freeElement = element.cloneNode(false);
148
+ freeElement = /** @type {HTMLElement} */ (element.cloneNode(false));
123
149
  first = true;
124
150
  }
125
151
 
@@ -128,20 +154,20 @@ Format.prototype = {
128
154
 
129
155
  if (i === 0) {
130
156
  parentNode.insertBefore(freeElement, f);
131
- next = f.nextSibling;
132
- if (next && freeElement.nodeName === next.nodeName && domUtils.isSameAttributes(freeElement, next)) {
157
+ next = /** @type {HTMLElement} */ (f.nextSibling);
158
+ if (next && freeElement.nodeName === next.nodeName && dom.check.isSameAttributes(freeElement, next)) {
133
159
  freeElement.innerHTML += '<BR>' + next.innerHTML;
134
- domUtils.removeItem(next);
160
+ dom.utils.removeItem(next);
135
161
  }
136
162
 
137
- const prev = freeElement.previousSibling;
138
- if (prev && freeElement.nodeName === prev.nodeName && domUtils.isSameAttributes(freeElement, prev)) {
163
+ const prev = /** @type {HTMLElement} */ (freeElement.previousSibling);
164
+ if (prev && freeElement.nodeName === prev.nodeName && dom.check.isSameAttributes(freeElement, prev)) {
139
165
  prev.innerHTML += '<BR>' + freeElement.innerHTML;
140
- domUtils.removeItem(freeElement);
166
+ dom.utils.removeItem(freeElement);
141
167
  }
142
168
  }
143
169
 
144
- if (!isComp) domUtils.removeItem(f);
170
+ if (!isComp) dom.utils.removeItem(f);
145
171
  if (html) first = false;
146
172
  }
147
173
 
@@ -150,10 +176,11 @@ Format.prototype = {
150
176
  },
151
177
 
152
178
  /**
153
- * @description If a parent node that contains an argument node finds a free format node (format.isBrLine), it returns that node.
179
+ * @this {FormatThis}
180
+ * @description If a parent node that contains an argument node finds a "brLine" (format.isBrLine), it returns that node.
154
181
  * @param {Node} element Reference node.
155
- * @param {Function|null} validation Additional validation function.
156
- * @returns {Element|null}
182
+ * @param {?(current: Node) => boolean=} validation Additional validation function.
183
+ * @returns {HTMLBRElement|null}
157
184
  */
158
185
  getBrLine(element, validation) {
159
186
  if (!element) return null;
@@ -164,8 +191,8 @@ Format.prototype = {
164
191
  }
165
192
 
166
193
  while (element) {
167
- if (domUtils.isWysiwygFrame(element)) return null;
168
- if (this.isBrLine(element) && validation(element)) return element;
194
+ if (dom.check.isWysiwygFrame(element)) return null;
195
+ if (this.isBrLine(element) && validation(element)) return /** @type {HTMLBRElement} */ (element);
169
196
 
170
197
  element = element.parentNode;
171
198
  }
@@ -174,12 +201,13 @@ Format.prototype = {
174
201
  },
175
202
 
176
203
  /**
177
- * @description Append format element to sibling node of argument element.
178
- * If the "lineNode" argument value is present, the tag of that argument value is inserted,
179
- * If not, the currently selected format tag is inserted.
180
- * @param {Element} element Insert as siblings of that element
181
- * @param {string|Element|null} lineNode Node name or node obejct to be inserted
182
- * @returns {Element}
204
+ * @this {FormatThis}
205
+ * @description Append "line" element to sibling node of argument element.
206
+ * - If the "lineNode" argument value is present, the tag of that argument value is inserted,
207
+ * - If not, the currently selected format tag is inserted.
208
+ * @param {Node} element Insert as siblings of that element
209
+ * @param {?string|Node=} lineNode Node name or node obejct to be inserted
210
+ * @returns {HTMLElement}
183
211
  */
184
212
  addLine(element, lineNode) {
185
213
  if (!element || !element.parentNode) return null;
@@ -187,32 +215,27 @@ Format.prototype = {
187
215
  const currentFormatEl = this.getLine(this.selection.getNode(), null);
188
216
  let oFormat = null;
189
217
  if (!this.isBrLine(element) && this.isBrLine(currentFormatEl || element.parentNode)) {
190
- oFormat = domUtils.createElement('BR');
218
+ oFormat = dom.utils.createElement('BR');
191
219
  } else {
192
- const oFormatName = lineNode
193
- ? typeof lineNode === 'string'
194
- ? lineNode
195
- : lineNode.nodeName
196
- : this.isLine(currentFormatEl) && !this.isBlock(currentFormatEl) && !this.isBrLine(currentFormatEl)
197
- ? currentFormatEl.nodeName
198
- : this.options.get('defaultLine');
199
- oFormat = domUtils.createElement(oFormatName, null, '<br>');
220
+ const oFormatName = lineNode ? (typeof lineNode === 'string' ? lineNode : lineNode.nodeName) : this.isLineOnly(currentFormatEl) ? currentFormatEl.nodeName : this.options.get('defaultLine');
221
+ oFormat = dom.utils.createElement(oFormatName, null, '<br>');
200
222
  if ((lineNode && typeof lineNode !== 'string') || (!lineNode && this.isLine(currentFormatEl))) {
201
- domUtils.copyTagAttributes(oFormat, lineNode || currentFormatEl, ['id']);
223
+ dom.utils.copyTagAttributes(oFormat, /** @type {Node} */ (lineNode || currentFormatEl), ['id']);
202
224
  }
203
225
  }
204
226
 
205
- if (domUtils.isTableCell(element)) element.insertBefore(oFormat, element.nextElementSibling);
206
- else element.parentNode.insertBefore(oFormat, element.nextElementSibling);
227
+ if (dom.check.isTableCell(element)) element.insertBefore(oFormat, element.nextElementSibling);
228
+ else element.parentNode.insertBefore(oFormat, /** @type {HTMLElement} */ (element).nextElementSibling);
207
229
 
208
230
  return oFormat;
209
231
  },
210
232
 
211
233
  /**
234
+ * @this {FormatThis}
212
235
  * @description If a parent node that contains an argument node finds a format node (format.isBlock), it returns that node.
213
236
  * @param {Node} element Reference node.
214
- * @param {Function|null} validation Additional validation function.
215
- * @returns {Element|null}
237
+ * @param {?(current: Node) => boolean=} validation Additional validation function.
238
+ * @returns {HTMLElement|null}
216
239
  */
217
240
  getBlock(element, validation) {
218
241
  if (!element) return null;
@@ -223,7 +246,7 @@ Format.prototype = {
223
246
  }
224
247
 
225
248
  while (element) {
226
- if (domUtils.isWysiwygFrame(element)) return null;
249
+ if (dom.check.isWysiwygFrame(element)) return null;
227
250
  if (this.isBlock(element) && !/^(THEAD|TBODY|TR)$/i.test(element.nodeName) && validation(element)) return element;
228
251
  element = element.parentNode;
229
252
  }
@@ -232,25 +255,26 @@ Format.prototype = {
232
255
  },
233
256
 
234
257
  /**
235
- * @description Appended all selected format Element to the argument element and insert
236
- * @param {Element} block Element of wrap the arguments (BLOCKQUOTE...)
258
+ * @this {FormatThis}
259
+ * @description Appended all selected "line" element to the argument element("block") and insert
260
+ * @param {Node} blockElement Element of wrap the arguments (BLOCKQUOTE...)
237
261
  */
238
- applyBlock(block) {
262
+ applyBlock(blockElement) {
239
263
  this.selection.getRangeAndAddLine(this.selection.getRange(), null);
240
- const rangeLines = this.getLinesAndComponents(false);
264
+ const rangeLines = /** @type {Element[]} */ (this.getLinesAndComponents(false));
241
265
  if (!rangeLines || rangeLines.length === 0) return;
242
266
 
243
267
  linesLoop: for (let i = 0, len = rangeLines.length, line, nested, fEl, lEl, f, l; i < len; i++) {
244
268
  line = rangeLines[i];
245
- if (!domUtils.isListCell(line)) continue;
269
+ if (!dom.check.isListCell(line)) continue;
246
270
 
247
271
  nested = line.lastElementChild;
248
- if (nested && domUtils.isListCell(line.nextElementSibling) && rangeLines.includes(line.nextElementSibling)) {
272
+ if (nested && dom.check.isListCell(line.nextElementSibling) && rangeLines.includes(line.nextElementSibling)) {
249
273
  lEl = nested.lastElementChild;
250
274
  if (rangeLines.includes(lEl)) {
251
275
  let list = null;
252
276
  while ((list = lEl.lastElementChild)) {
253
- if (domUtils.isList(list)) {
277
+ if (dom.check.isList(list)) {
254
278
  if (rangeLines.includes(list.lastElementChild)) {
255
279
  lEl = list.lastElementChild;
256
280
  } else {
@@ -278,7 +302,7 @@ Format.prototype = {
278
302
  standTag = this.getBlock(last, null) || this.getLine(last, null);
279
303
  }
280
304
 
281
- if (domUtils.isTableCell(standTag)) {
305
+ if (dom.check.isTableCell(standTag)) {
282
306
  beforeTag = null;
283
307
  pElement = standTag;
284
308
  } else {
@@ -286,14 +310,14 @@ Format.prototype = {
286
310
  pElement = standTag.parentNode;
287
311
  }
288
312
 
289
- block = block.cloneNode(false);
290
- let parentDepth = domUtils.getNodeDepth(standTag);
313
+ const block = /** @type {HTMLElement} */ (blockElement.cloneNode(false));
314
+ let parentDepth = dom.query.getNodeDepth(standTag);
291
315
  let listParent = null;
292
316
  const lineArr = [];
293
317
  const removeItems = (parent, origin, before) => {
294
318
  let cc = null;
295
- if (parent !== origin && !domUtils.isTableElements(origin)) {
296
- if (origin && domUtils.getNodeDepth(parent) === domUtils.getNodeDepth(origin)) return before;
319
+ if (parent !== origin && !dom.check.isTableElements(origin)) {
320
+ if (origin && dom.query.getNodeDepth(parent) === dom.query.getNodeDepth(origin)) return before;
297
321
  cc = this.nodeTransform.removeAllParents(origin, null, parent);
298
322
  }
299
323
 
@@ -305,9 +329,9 @@ Format.prototype = {
305
329
  originParent = line.parentNode;
306
330
  if (!originParent || block.contains(originParent)) continue;
307
331
 
308
- depth = domUtils.getNodeDepth(line);
332
+ depth = dom.query.getNodeDepth(line);
309
333
 
310
- if (domUtils.isList(originParent)) {
334
+ if (dom.check.isList(originParent)) {
311
335
  if (listParent === null) {
312
336
  if (nextList) {
313
337
  listParent = nextList;
@@ -329,14 +353,14 @@ Format.prototype = {
329
353
 
330
354
  let list = originParent.parentNode,
331
355
  p;
332
- while (domUtils.isList(list)) {
333
- p = domUtils.createElement(list.nodeName);
356
+ while (dom.check.isList(list)) {
357
+ p = dom.utils.createElement(list.nodeName);
334
358
  p.appendChild(listParent);
335
359
  listParent = p;
336
360
  list = list.parentNode;
337
361
  }
338
362
 
339
- const edge = this.removeBlock(originParent, lineArr, null, true, true);
363
+ const edge = this.removeBlock(originParent, { selectedFormats: lineArr, newBlockElement: null, shouldDelete: true, skipHistory: true });
340
364
 
341
365
  if (parentDepth >= depth) {
342
366
  parentDepth = depth;
@@ -380,12 +404,12 @@ Format.prototype = {
380
404
 
381
405
  this.editor.effectNode = null;
382
406
  this.nodeTransform.mergeSameTags(block, null, false);
383
- this.nodeTransform.mergeNestedTags(block, (current) => domUtils.isList(current));
407
+ this.nodeTransform.mergeNestedTags(block, (current) => dom.check.isList(current));
384
408
 
385
409
  // Nested list
386
- if (beforeTag && domUtils.getNodeDepth(beforeTag) > 0 && (domUtils.isList(beforeTag.parentNode) || domUtils.isList(beforeTag.parentNode.parentNode))) {
387
- const depthFormat = domUtils.getParentElement(beforeTag, (current) => this.isBlock(current) && !domUtils.isList(current));
388
- const splitRange = this.nodeTransform.split(beforeTag, null, !depthFormat ? 0 : domUtils.getNodeDepth(depthFormat) + 1);
410
+ if (beforeTag && dom.query.getNodeDepth(beforeTag) > 0 && (dom.check.isList(beforeTag.parentNode) || dom.check.isList(beforeTag.parentNode.parentNode))) {
411
+ const depthFormat = dom.query.getParentElement(beforeTag, (current) => this.isBlock(current) && !dom.check.isList(current));
412
+ const splitRange = this.nodeTransform.split(beforeTag, null, !depthFormat ? 0 : dom.query.getNodeDepth(depthFormat) + 1);
389
413
  splitRange.parentNode.insertBefore(block, splitRange);
390
414
  } else {
391
415
  // basic
@@ -393,7 +417,7 @@ Format.prototype = {
393
417
  removeItems(block, beforeTag);
394
418
  }
395
419
 
396
- const edge = domUtils.getEdgeChildNodes(block.firstElementChild, block.lastElementChild);
420
+ const edge = dom.query.getEdgeChildNodes(block.firstElementChild, block.lastElementChild);
397
421
  if (rangeLines.length > 1) {
398
422
  this.selection.setRange(edge.sc, 0, edge.ec, edge.ec.textContent.length);
399
423
  } else {
@@ -404,35 +428,43 @@ Format.prototype = {
404
428
  },
405
429
 
406
430
  /**
407
- * @description The elements of the "selectedFormats" array are detached from the "rangeElement" element. ("LI" tags are converted to "P" tags)
408
- * When "selectedFormats" is null, all elements are detached and return {cc: parentNode, sc: nextSibling, ec: previousSibling, removeArray: [Array of removed elements]}.
409
- * @param {Element} rangeElement Range format element (PRE, BLOCKQUOTE, OL, UL...)
410
- * @param {Array|null} selectedFormats Array of format elements (P, DIV, LI...) to remove.
411
- * If null, Applies to all elements and return {cc: parentNode, sc: nextSibling, ec: previousSibling}
412
- * @param {Element|null} newRangeElement The node(rangeElement) to replace the currently wrapped node.
413
- * @param {boolean} remove If true, deleted without detached.
414
- * @param {boolean} notHistoryPush When true, it does not update the history stack and the selection object and return EdgeNodes (domUtils.getEdgeChildNodes)
415
- * @returns {Object}
431
+ * @this {FormatThis}
432
+ * @description The elements of the "selectedFormats" array are detached from the "blockElement" element. ("LI" tags are converted to "P" tags)
433
+ * - When "selectedFormats" is null, all elements are detached and return {cc: parentNode, sc: nextSibling, ec: previousSibling, removeArray: [Array of removed elements]}.
434
+ * @param {Node} blockElement "block" element (PRE, BLOCKQUOTE, OL, UL...)
435
+ * @param {Object} [options] Options
436
+ * @param {Array<Node>} [options.selectedFormats=null] Array of "line" elements (P, DIV, LI...) to remove.
437
+ * - If null, Applies to all elements and return {cc: parentNode, sc: nextSibling, ec: previousSibling}
438
+ * @param {Node} [options.newBlockElement=null] The node(blockElement) to replace the currently wrapped node.
439
+ * @param {boolean} [options.shouldDelete=false] If true, deleted without detached.
440
+ * @param {boolean} [options.skipHistory=false] When true, it does not update the history stack and the selection object and return EdgeNodes (dom-query-GetEdgeChildNodes)
441
+ * @returns {{cc: Node, sc: Node, so: number, ec: Node, eo: number, removeArray: Array<Node>|null}} Node information after deletion
442
+ * - cc: Common parent container node
443
+ * - sc: Start container node
444
+ * - so: Start offset
445
+ * - ec: End container node
446
+ * - eo: End offset
447
+ * - removeArray: Array of removed elements
416
448
  */
417
- removeBlock(rangeElement, selectedFormats, newRangeElement, remove, notHistoryPush) {
449
+ removeBlock(blockElement, { selectedFormats, newBlockElement, shouldDelete, skipHistory } = {}) {
418
450
  const range = this.selection.getRange();
419
451
  let so = range.startOffset;
420
452
  let eo = range.endOffset;
421
453
 
422
- let children = domUtils.getListChildNodes(rangeElement, (current) => current.parentNode === rangeElement);
423
- let parent = rangeElement.parentNode;
454
+ let children = dom.query.getListChildNodes(blockElement, (current) => current.parentNode === blockElement);
455
+ let parent = blockElement.parentNode;
424
456
  let firstNode = null;
425
457
  let lastNode = null;
426
- let rangeEl = rangeElement.cloneNode(false);
458
+ let rangeEl = /** @type {HTMLElement} */ (blockElement.cloneNode(false));
427
459
 
428
460
  const removeArray = [];
429
- const newList = domUtils.isList(newRangeElement);
461
+ const newList = dom.check.isList(newBlockElement);
430
462
  let insertedNew = false;
431
463
  let reset = false;
432
464
  let moveComplete = false;
433
465
 
434
466
  const appendNode = (parentEl, insNode, sibling, originNode) => {
435
- if (domUtils.isZeroWith(insNode)) {
467
+ if (dom.check.isZeroWidth(insNode)) {
436
468
  insNode.innerHTML = unicode.zeroWidthSpace;
437
469
  so = eo = 1;
438
470
  }
@@ -449,7 +481,7 @@ Format.prototype = {
449
481
 
450
482
  while (insChildren[0]) {
451
483
  c = insChildren[0];
452
- if (this._notTextNode(c) && !domUtils.isBreak(c) && !domUtils.isListCell(format)) {
484
+ if (this._notTextNode(c) && !dom.check.isBreak(c) && !dom.check.isListCell(format)) {
453
485
  if (format.childNodes.length > 0) {
454
486
  if (!first) first = format;
455
487
  parentEl.insertBefore(format, sibling);
@@ -463,7 +495,7 @@ Format.prototype = {
463
495
  }
464
496
 
465
497
  if (format.childNodes.length > 0) {
466
- if (domUtils.isListCell(parentEl) && domUtils.isListCell(format) && domUtils.isList(sibling)) {
498
+ if (dom.check.isListCell(parentEl) && dom.check.isListCell(format) && dom.check.isList(sibling)) {
467
499
  if (newList) {
468
500
  first = sibling;
469
501
  while (sibling) {
@@ -474,13 +506,13 @@ Format.prototype = {
474
506
  } else {
475
507
  const originNext = originNode.nextElementSibling;
476
508
  const detachRange = this._removeNestedList(originNode, false);
477
- if (rangeElement !== detachRange || originNext !== originNode.nextElementSibling) {
509
+ if (blockElement !== detachRange || originNext !== originNode.nextElementSibling) {
478
510
  const fChildren = format.childNodes;
479
511
  while (fChildren[0]) {
480
512
  originNode.appendChild(fChildren[0]);
481
513
  }
482
514
 
483
- rangeElement = detachRange;
515
+ blockElement = detachRange;
484
516
  reset = true;
485
517
  }
486
518
  }
@@ -497,12 +529,12 @@ Format.prototype = {
497
529
  // detach loop
498
530
  for (let i = 0, len = children.length, insNode, lineIndex, next; i < len; i++) {
499
531
  insNode = children[i];
500
- if (insNode.nodeType === 3 && domUtils.isList(rangeEl)) continue;
532
+ if (insNode.nodeType === 3 && dom.check.isList(rangeEl)) continue;
501
533
 
502
534
  moveComplete = false;
503
- if (remove && i === 0) {
535
+ if (shouldDelete && i === 0) {
504
536
  if (!selectedFormats || selectedFormats.length === len || selectedFormats[0] === insNode) {
505
- firstNode = rangeElement.previousSibling;
537
+ firstNode = blockElement.previousSibling;
506
538
  } else {
507
539
  firstNode = rangeEl;
508
540
  }
@@ -510,35 +542,41 @@ Format.prototype = {
510
542
 
511
543
  if (selectedFormats) lineIndex = selectedFormats.indexOf(insNode);
512
544
  if (selectedFormats && lineIndex === -1) {
513
- if (!rangeEl) rangeEl = rangeElement.cloneNode(false);
545
+ if (!rangeEl) rangeEl = /** @type {HTMLElement} */ (blockElement.cloneNode(false));
514
546
  rangeEl.appendChild(insNode);
515
547
  } else {
516
548
  if (selectedFormats) next = selectedFormats[lineIndex + 1];
517
549
  if (rangeEl && rangeEl.children.length > 0) {
518
- parent.insertBefore(rangeEl, rangeElement);
550
+ parent.insertBefore(rangeEl, blockElement);
519
551
  rangeEl = null;
520
552
  }
521
553
 
522
- if (!newList && domUtils.isListCell(insNode)) {
523
- if (next && domUtils.getNodeDepth(insNode) !== domUtils.getNodeDepth(next) && (domUtils.isListCell(parent) || domUtils.getArrayItem(insNode.children, domUtils.isList, false))) {
554
+ if (!newList && dom.check.isListCell(insNode)) {
555
+ if (next && dom.query.getNodeDepth(insNode) !== dom.query.getNodeDepth(next) && (dom.check.isListCell(parent) || dom.utils.arrayFind(insNode.children, dom.check.isList))) {
524
556
  const insNext = insNode.nextElementSibling;
525
557
  const detachRange = this._removeNestedList(insNode, false);
526
- if (rangeElement !== detachRange || insNext !== insNode.nextElementSibling) {
527
- rangeElement = detachRange;
558
+ if (blockElement !== detachRange || insNext !== insNode.nextElementSibling) {
559
+ blockElement = detachRange;
528
560
  reset = true;
529
561
  }
530
562
  } else {
531
563
  const inner = insNode;
532
- insNode = domUtils.createElement(
533
- remove ? inner.nodeName : domUtils.isList(rangeElement.parentNode) || domUtils.isListCell(rangeElement.parentNode) ? 'LI' : domUtils.isTableCell(rangeElement.parentNode) ? 'DIV' : this.options.get('defaultLine')
564
+ insNode = dom.utils.createElement(
565
+ shouldDelete
566
+ ? inner.nodeName
567
+ : dom.check.isList(blockElement.parentNode) || dom.check.isListCell(blockElement.parentNode)
568
+ ? 'LI'
569
+ : dom.check.isTableCell(blockElement.parentNode)
570
+ ? 'DIV'
571
+ : this.options.get('defaultLine')
534
572
  );
535
- const isCell = domUtils.isListCell(insNode);
573
+ const isCell = dom.check.isListCell(insNode);
536
574
  const innerChildren = inner.childNodes;
537
575
  while (innerChildren[0]) {
538
- if (domUtils.isList(innerChildren[0]) && !isCell) break;
576
+ if (dom.check.isList(innerChildren[0]) && !isCell) break;
539
577
  insNode.appendChild(innerChildren[0]);
540
578
  }
541
- domUtils.copyFormatAttributes(insNode, inner);
579
+ dom.utils.copyFormatAttributes(insNode, inner);
542
580
  moveComplete = true;
543
581
  }
544
582
  } else {
@@ -546,15 +584,15 @@ Format.prototype = {
546
584
  }
547
585
 
548
586
  if (!reset) {
549
- if (!remove) {
550
- if (newRangeElement) {
587
+ if (!shouldDelete) {
588
+ if (newBlockElement) {
551
589
  if (!insertedNew) {
552
- parent.insertBefore(newRangeElement, rangeElement);
590
+ parent.insertBefore(newBlockElement, blockElement);
553
591
  insertedNew = true;
554
592
  }
555
- insNode = appendNode(newRangeElement, insNode, null, children[i]);
593
+ insNode = appendNode(newBlockElement, insNode, null, children[i]);
556
594
  } else {
557
- insNode = appendNode(parent, insNode, rangeElement, children[i]);
595
+ insNode = appendNode(parent, insNode, blockElement, children[i]);
558
596
  }
559
597
 
560
598
  if (!reset) {
@@ -569,14 +607,14 @@ Format.prototype = {
569
607
  }
570
608
  } else {
571
609
  removeArray.push(insNode);
572
- domUtils.removeItem(children[i]);
610
+ dom.utils.removeItem(children[i]);
573
611
  }
574
612
 
575
613
  if (reset) {
576
614
  reset = moveComplete = false;
577
- children = domUtils.getListChildNodes(rangeElement, (current) => current.parentNode === rangeElement);
578
- rangeEl = rangeElement.cloneNode(false);
579
- parent = rangeElement.parentNode;
615
+ children = dom.query.getListChildNodes(blockElement, (current) => current.parentNode === blockElement);
616
+ rangeEl = /** @type {HTMLElement} */ (blockElement.cloneNode(false));
617
+ parent = blockElement.parentNode;
580
618
  i = -1;
581
619
  len = children.length;
582
620
  continue;
@@ -585,24 +623,24 @@ Format.prototype = {
585
623
  }
586
624
  }
587
625
 
588
- const rangeParent = rangeElement.parentNode;
589
- let rangeRight = rangeElement.nextSibling;
626
+ const rangeParent = blockElement.parentNode;
627
+ let rangeRight = blockElement.nextSibling;
590
628
  if (rangeEl?.children.length > 0) {
591
629
  rangeParent.insertBefore(rangeEl, rangeRight);
592
630
  }
593
631
 
594
- if (newRangeElement) firstNode = newRangeElement.previousSibling;
595
- else if (!firstNode) firstNode = rangeElement.previousSibling;
596
- rangeRight = rangeElement.nextSibling !== rangeEl ? rangeElement.nextSibling : rangeEl ? rangeEl.nextSibling : null;
632
+ if (newBlockElement) firstNode = newBlockElement.previousSibling;
633
+ else if (!firstNode) firstNode = blockElement.previousSibling;
634
+ rangeRight = blockElement.nextSibling !== rangeEl ? blockElement.nextSibling : rangeEl ? rangeEl.nextSibling : null;
597
635
 
598
- if (rangeElement.children.length === 0 || rangeElement.textContent.length === 0) {
599
- domUtils.removeItem(rangeElement);
636
+ if (/** @type {HTMLElement} */ (blockElement).children.length === 0 || blockElement.textContent.length === 0) {
637
+ dom.utils.removeItem(blockElement);
600
638
  } else {
601
- this.nodeTransform.removeEmptyNode(rangeElement, null, false);
639
+ this.nodeTransform.removeEmptyNode(blockElement, null, false);
602
640
  }
603
641
 
604
642
  let edge = null;
605
- if (remove) {
643
+ if (shouldDelete) {
606
644
  edge = {
607
645
  cc: rangeParent,
608
646
  sc: firstNode,
@@ -614,7 +652,7 @@ Format.prototype = {
614
652
  } else {
615
653
  if (!firstNode) firstNode = lastNode;
616
654
  if (!lastNode) lastNode = firstNode;
617
- const childEdge = domUtils.getEdgeChildNodes(firstNode, lastNode.parentNode ? firstNode : lastNode);
655
+ const childEdge = dom.query.getEdgeChildNodes(firstNode, lastNode.parentNode ? firstNode : lastNode);
618
656
  edge = {
619
657
  cc: (childEdge.sc || childEdge.ec).parentNode,
620
658
  sc: childEdge.sc,
@@ -626,9 +664,9 @@ Format.prototype = {
626
664
  }
627
665
 
628
666
  this.editor.effectNode = null;
629
- if (notHistoryPush) return edge;
667
+ if (skipHistory) return edge;
630
668
 
631
- if (!remove && edge) {
669
+ if (!shouldDelete && edge) {
632
670
  if (!selectedFormats) {
633
671
  this.selection.setRange(edge.sc, 0, edge.sc, 0);
634
672
  } else {
@@ -640,9 +678,10 @@ Format.prototype = {
640
678
  },
641
679
 
642
680
  /**
643
- * @description Append all selected format Element to the list and insert.
681
+ * @this {FormatThis}
682
+ * @description Append all selected "line" element to the list and insert.
644
683
  * @param {string} type List type. (ol | ul):[listStyleType]
645
- * @param {Element} selectedCells Format elements or list cells.
684
+ * @param {Array<Node>} selectedCells "line" elements or list cells.
646
685
  * @param {boolean} nested If true, indenting existing list cells.
647
686
  */
648
687
  applyList(type, selectedCells, nested) {
@@ -650,7 +689,7 @@ Format.prototype = {
650
689
  const listStyle = type.split(':')[1] || '';
651
690
 
652
691
  let range = this.selection.getRange();
653
- let selectedFormats = !selectedCells ? this.getLinesAndComponents(false) : selectedCells;
692
+ let selectedFormats = /** @type {Array<HTMLElement>} */ (!selectedCells ? this.getLinesAndComponents(false) : selectedCells);
654
693
 
655
694
  if (selectedFormats.length === 0) {
656
695
  if (selectedCells) return;
@@ -659,18 +698,18 @@ Format.prototype = {
659
698
  if (selectedFormats.length === 0) return;
660
699
  }
661
700
 
662
- domUtils.sortNodeByDepth(selectedFormats, true);
701
+ dom.query.sortNodeByDepth(selectedFormats, true);
663
702
 
664
703
  // merge
665
704
  const firstSel = selectedFormats[0];
666
705
  const lastSel = selectedFormats[selectedFormats.length - 1];
667
- let topEl = (domUtils.isListCell(firstSel) || this.component.is(firstSel)) && !firstSel.previousElementSibling ? firstSel.parentNode.previousElementSibling : firstSel.previousElementSibling;
668
- let bottomEl = (domUtils.isListCell(lastSel) || this.component.is(lastSel)) && !lastSel.nextElementSibling ? lastSel.parentNode.nextElementSibling : lastSel.nextElementSibling;
706
+ let topEl = (dom.check.isListCell(firstSel) || this.component.is(firstSel)) && !firstSel.previousElementSibling ? firstSel.parentElement.previousElementSibling : firstSel.previousElementSibling;
707
+ let bottomEl = (dom.check.isListCell(lastSel) || this.component.is(lastSel)) && !lastSel.nextElementSibling ? lastSel.parentElement.nextElementSibling : lastSel.nextElementSibling;
669
708
 
670
709
  const isCollapsed = range.collapsed;
671
710
  const originRange = {
672
711
  sc: range.startContainer,
673
- so: range.startContainer === range.endContainer && domUtils.isZeroWith(range.startContainer) && range.startOffset === 0 && range.endOffset === 1 ? range.endOffset : range.startOffset,
712
+ so: range.startContainer === range.endContainer && dom.check.isZeroWidth(range.startContainer) && range.startOffset === 0 && range.endOffset === 1 ? range.endOffset : range.startOffset,
674
713
  ec: range.endContainer,
675
714
  eo: range.endOffset
676
715
  };
@@ -678,7 +717,7 @@ Format.prototype = {
678
717
  let isRemove = true;
679
718
 
680
719
  for (let i = 0, len = selectedFormats.length; i < len; i++) {
681
- if (!domUtils.isList(this.getBlock(selectedFormats[i], (current) => this.getBlock(current) && current !== selectedFormats[i]))) {
720
+ if (!dom.check.isList(this.getBlock(selectedFormats[i], (current) => this.getBlock(current) && current !== selectedFormats[i]))) {
682
721
  isRemove = false;
683
722
  break;
684
723
  }
@@ -706,85 +745,85 @@ Format.prototype = {
706
745
  };
707
746
 
708
747
  if (!cancel) {
709
- tempList = domUtils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
748
+ tempList = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
710
749
  }
711
750
 
712
751
  for (let i = 0, len = selectedFormats.length, r, o; i < len; i++) {
713
752
  o = this.getBlock(selectedFormats[i], passComponent);
714
- if (!o || !domUtils.isList(o)) continue;
753
+ if (!o || !dom.check.isList(o)) continue;
715
754
 
716
755
  if (!r) {
717
756
  r = o;
718
757
  rangeArr = {
719
758
  r: r,
720
- f: [domUtils.getParentElement(selectedFormats[i], 'LI')]
759
+ f: [dom.query.getParentElement(selectedFormats[i], 'LI')]
721
760
  };
722
761
  } else {
723
762
  if (r !== o) {
724
- if (nested && domUtils.isListCell(o.parentNode)) {
763
+ if (nested && dom.check.isListCell(o.parentNode)) {
725
764
  this._detachNested(rangeArr.f);
726
765
  } else {
727
- afterRange = this.removeBlock(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true);
766
+ afterRange = this.removeBlock(rangeArr.f[0].parentElement, { selectedFormats: rangeArr.f, newBlockElement: tempList, shouldDelete: false, skipHistory: true });
728
767
  }
729
768
 
730
769
  o = selectedFormats[i].parentNode;
731
770
  if (!cancel) {
732
- tempList = domUtils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
771
+ tempList = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
733
772
  }
734
773
 
735
774
  r = o;
736
775
  rangeArr = {
737
776
  r: r,
738
- f: [domUtils.getParentElement(selectedFormats[i], 'LI')]
777
+ f: [dom.query.getParentElement(selectedFormats[i], 'LI')]
739
778
  };
740
779
  } else {
741
- rangeArr.f.push(domUtils.getParentElement(selectedFormats[i], 'LI'));
780
+ rangeArr.f.push(dom.query.getParentElement(selectedFormats[i], 'LI'));
742
781
  }
743
782
  }
744
783
 
745
784
  if (i === len - 1) {
746
- if (nested && domUtils.isListCell(o.parentNode)) {
785
+ if (nested && dom.check.isListCell(o.parentNode)) {
747
786
  this._detachNested(rangeArr.f);
748
787
  } else {
749
- afterRange = this.removeBlock(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true);
788
+ afterRange = this.removeBlock(rangeArr.f[0].parentElement, { selectedFormats: rangeArr.f, newBlockElement: tempList, shouldDelete: false, skipHistory: true });
750
789
  }
751
790
  }
752
791
  }
753
792
  } else {
754
793
  const topElParent = topEl ? topEl.parentNode : topEl;
755
794
  const bottomElParent = bottomEl ? bottomEl.parentNode : bottomEl;
756
- topEl = topElParent && !domUtils.isWysiwygFrame(topElParent) && topElParent.nodeName === listTag ? topElParent : topEl;
757
- bottomEl = bottomElParent && !domUtils.isWysiwygFrame(bottomElParent) && bottomElParent.nodeName === listTag ? bottomElParent : bottomEl;
795
+ topEl = /** @type {HTMLElement} */ (topElParent && !dom.check.isWysiwygFrame(topElParent) && topElParent.nodeName === listTag ? topElParent : topEl);
796
+ bottomEl = /** @type {HTMLElement} */ (bottomElParent && !dom.check.isWysiwygFrame(bottomElParent) && bottomElParent.nodeName === listTag ? bottomElParent : bottomEl);
758
797
 
759
798
  const mergeTop = topEl?.tagName === listTag;
760
799
  const mergeBottom = bottomEl?.tagName === listTag;
761
800
 
762
- let list = mergeTop ? topEl : domUtils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
801
+ let list = mergeTop ? topEl : dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
763
802
  let firstList = null;
764
803
  let topNumber = null;
765
804
  // let lastList = null;
766
805
  // let bottomNumber = null;
767
806
 
768
807
  const passComponent = (current) => {
769
- return !this.component.is(current) && !domUtils.isList(current);
808
+ return !this.component.is(current) && !dom.check.isList(current);
770
809
  };
771
810
 
772
811
  for (let i = 0, len = selectedFormats.length, newCell, fTag, isCell, next, originParent, nextParent, parentTag, siblingTag, rangeTag; i < len; i++) {
773
812
  fTag = selectedFormats[i];
774
813
  if (fTag.childNodes.length === 0 && !this._isIgnoreNodeChange(fTag)) {
775
- domUtils.removeItem(fTag);
814
+ dom.utils.removeItem(fTag);
776
815
  continue;
777
816
  }
778
817
  next = selectedFormats[i + 1];
779
818
  originParent = fTag.parentNode;
780
819
  nextParent = next ? next.parentNode : null;
781
- isCell = domUtils.isListCell(fTag);
820
+ isCell = dom.check.isListCell(fTag);
782
821
  rangeTag = this.isBlock(originParent) ? originParent : null;
783
- parentTag = isCell && !domUtils.isWysiwygFrame(originParent) ? originParent.parentNode : originParent;
784
- siblingTag = isCell && !domUtils.isWysiwygFrame(originParent) ? (!next || domUtils.isListCell(parentTag) ? originParent : originParent.nextSibling) : fTag.nextSibling;
822
+ parentTag = isCell && !dom.check.isWysiwygFrame(originParent) ? originParent.parentNode : originParent;
823
+ siblingTag = isCell && !dom.check.isWysiwygFrame(originParent) ? (!next || dom.check.isListCell(parentTag) ? originParent : originParent.nextSibling) : fTag.nextSibling;
785
824
 
786
- newCell = domUtils.createElement('LI');
787
- domUtils.copyFormatAttributes(newCell, fTag);
825
+ newCell = dom.utils.createElement('LI');
826
+ dom.utils.copyFormatAttributes(newCell, fTag);
788
827
  if (this.component.is(fTag)) {
789
828
  const isHR = /^HR$/i.test(fTag.nodeName);
790
829
  if (!isHR) newCell.innerHTML = '<br>';
@@ -801,22 +840,22 @@ Format.prototype = {
801
840
  // if (!next) lastList = list;
802
841
  if (!next || parentTag !== nextParent || this.isBlock(siblingTag)) {
803
842
  if (!firstList) firstList = list;
804
- if ((!mergeTop || !next || parentTag !== nextParent) && !(next && domUtils.isList(nextParent) && nextParent === originParent)) {
843
+ if ((!mergeTop || !next || parentTag !== nextParent) && !(next && dom.check.isList(nextParent) && nextParent === originParent)) {
805
844
  if (list.parentNode !== parentTag) parentTag.insertBefore(list, siblingTag);
806
845
  }
807
846
  }
808
847
 
809
- domUtils.removeItem(fTag);
848
+ dom.utils.removeItem(fTag);
810
849
  if (mergeTop && topNumber === null) topNumber = list.children.length - 1;
811
850
  if (
812
851
  next &&
813
852
  (this.getBlock(nextParent, passComponent) !== this.getBlock(originParent, passComponent) ||
814
- (domUtils.isList(nextParent) && domUtils.isList(originParent) && domUtils.getNodeDepth(nextParent) !== domUtils.getNodeDepth(originParent)))
853
+ (dom.check.isList(nextParent) && dom.check.isList(originParent) && dom.query.getNodeDepth(nextParent) !== dom.query.getNodeDepth(originParent)))
815
854
  ) {
816
- list = domUtils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
855
+ list = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
817
856
  }
818
857
 
819
- if (rangeTag?.children.length === 0) domUtils.removeItem(rangeTag);
858
+ if (rangeTag?.children.length === 0) dom.utils.removeItem(rangeTag);
820
859
  }
821
860
 
822
861
  if (topNumber) {
@@ -827,22 +866,25 @@ Format.prototype = {
827
866
  // bottomNumber = list.children.length - 1;
828
867
  list.innerHTML += bottomEl.innerHTML;
829
868
  // lastList = list.children[bottomNumber] || lastList;
830
- domUtils.removeItem(bottomEl);
869
+ dom.utils.removeItem(bottomEl);
831
870
  }
832
871
  }
833
872
 
834
873
  this.editor.effectNode = null;
835
- return !isRemove || !isCollapsed ? originRange : afterRange;
874
+ return !isRemove || !isCollapsed ? originRange : afterRange || originRange;
836
875
  },
837
876
 
838
877
  /**
878
+ * @this {FormatThis}
839
879
  * @description "selectedCells" array are detached from the list element.
840
- * The return value is applied when the first and last lines of "selectedFormats" are "LI" respectively.
841
- * @param {Array} selectedCells Array of format elements (LI, P...) to remove.
842
- * @param {boolean} remove If true, It does not just remove the list, it deletes the content.
843
- * @returns {Object} {sc: <LI>, ec: <LI>}.
880
+ * - The return value is applied when the first and last lines of "selectedFormats" are "LI" respectively.
881
+ * @param {Array<Node>} selectedCells Array of ["line", li] elements(LI, P...) to remove.
882
+ * @param {boolean} shouldDelete If true, It does not just remove the list, it deletes the content.
883
+ * @returns {{sc: Node, ec: Node}} Node information after deletion
884
+ * - sc: Start container node
885
+ * - ec: End container node
844
886
  */
845
- removeList(selectedCells, remove) {
887
+ removeList(selectedCells, shouldDelete) {
846
888
  let rangeArr = {};
847
889
  let listFirst = false;
848
890
  let listLast = false;
@@ -855,17 +897,17 @@ Format.prototype = {
855
897
  for (let i = 0, len = selectedCells.length, r, o, lastIndex, isList; i < len; i++) {
856
898
  lastIndex = i === len - 1;
857
899
  o = this.getBlock(selectedCells[i], passComponent);
858
- isList = domUtils.isList(o);
900
+ isList = dom.check.isList(o);
859
901
  if (!r && isList) {
860
902
  r = o;
861
903
  rangeArr = {
862
904
  r: r,
863
- f: [domUtils.getParentElement(selectedCells[i], 'LI')]
905
+ f: [dom.query.getParentElement(selectedCells[i], 'LI')]
864
906
  };
865
907
  if (i === 0) listFirst = true;
866
908
  } else if (r && isList) {
867
909
  if (r !== o) {
868
- const edge = this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, null, remove, true);
910
+ const edge = this.removeBlock(rangeArr.f[0].parentNode, { selectedFormats: rangeArr.f, newBlockElement: null, shouldDelete, skipHistory: true });
869
911
  o = selectedCells[i].parentNode;
870
912
  if (listFirst) {
871
913
  first = edge.sc;
@@ -877,20 +919,20 @@ Format.prototype = {
877
919
  r = o;
878
920
  rangeArr = {
879
921
  r: r,
880
- f: [domUtils.getParentElement(selectedCells[i], 'LI')]
922
+ f: [dom.query.getParentElement(selectedCells[i], 'LI')]
881
923
  };
882
924
  if (lastIndex) listLast = true;
883
925
  } else {
884
926
  r = null;
885
927
  }
886
928
  } else {
887
- rangeArr.f.push(domUtils.getParentElement(selectedCells[i], 'LI'));
929
+ rangeArr.f.push(dom.query.getParentElement(selectedCells[i], 'LI'));
888
930
  if (lastIndex) listLast = true;
889
931
  }
890
932
  }
891
933
 
892
- if (lastIndex && domUtils.isList(r)) {
893
- const edge = this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, null, remove, true);
934
+ if (lastIndex && dom.check.isList(r)) {
935
+ const edge = this.removeBlock(rangeArr.f[0].parentNode, { selectedFormats: rangeArr.f, newBlockElement: null, shouldDelete, skipHistory: true });
894
936
  if (listLast || len === 1) last = edge.ec;
895
937
  if (listFirst) first = edge.sc || last;
896
938
  }
@@ -903,8 +945,9 @@ Format.prototype = {
903
945
  },
904
946
 
905
947
  /**
948
+ * @this {FormatThis}
906
949
  * @description Indent more the selected lines.
907
- * margin size - 'status.indentSize'px
950
+ * - margin size : 'status.indentSize'px
908
951
  */
909
952
  indent() {
910
953
  const range = this.selection.getRange();
@@ -927,8 +970,9 @@ Format.prototype = {
927
970
  },
928
971
 
929
972
  /**
973
+ * @this {FormatThis}
930
974
  * @description Indent less the selected lines.
931
- * margin size - "status.indentSize"px
975
+ * - margin size - "status.indentSize"px
932
976
  */
933
977
  outdent() {
934
978
  const range = this.selection.getRange();
@@ -951,44 +995,50 @@ Format.prototype = {
951
995
  },
952
996
 
953
997
  /**
954
- * @description Add, update, and delete style node from selected text. (a, span, strong, ect.)
955
- * 1. If there is a node in the "styleNode" argument, a node with the same tags and attributes as "styleNode" is added to the selection text.
956
- * 2. If it is in the same tag, only the tag's attributes are changed without adding a tag.
957
- * 3. If the "styleNode" argument is null, the node of the selection is update or remove without adding a new node.
958
- * 4. The same style as the style attribute of the "styleArray" argument is deleted.
959
- * (Styles should be put with attribute names from css. ["background-color"])
960
- * 5. The same class name as the class attribute of the "styleArray" argument is deleted.
961
- * (The class name is preceded by "." [".className"])
962
- * 6. Use a list of styles and classes of "styleNode" in "styleArray" to avoid duplicate property values.
963
- * 7. If a node with all styles and classes removed has the same tag name as "styleNode" or "removeNodeArray", or "styleNode" is null, that node is deleted.
964
- * 8. Regardless of the style and class of the node, the tag with the same name as the "removeNodeArray" argument value is deleted.
965
- * 9. If the "strictRemove" argument is true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
966
- *10. It won't work if the parent node has the same class and same value style.
967
- * However, if there is a value in "removeNodeArray", it works and the text node is separated even if there is no node to replace.
968
- * @param {Element|null} styleNode The element to be added to the selection. If it is null, only delete the node.
969
- * @param {Array|null} styleArray The style or className attribute name Array to check (['font-size'], ['.className'], ['font-family', 'color', '.className']...])
970
- * @param {Array|null} removeNodeArray An array of node names to remove types from, remove all formats when "styleNode" is null and there is an empty array or null value. (['span'], ['strong', 'em'] ...])
971
- * @param {Boolean|null} strictRemove If true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
998
+ * @this {FormatThis}
999
+ * @description Adds, updates, or deletes style nodes from selected text (a, span, strong, etc.).
1000
+ * @param {?Node} styleNode The element to be added to the selection. If null, only existing nodes are modified or removed.
1001
+ * @param {Object} [options] Options
1002
+ * @param {Array<string>} [options.stylesToModify=null] Array of style or class names to check and modify.
1003
+ * (e.g., ['font-size'], ['.className'], ['font-family', 'color', '.className'])
1004
+ * @param {Array<string>} [options.nodesToRemove=null] Array of node names to remove.
1005
+ * If empty array or null when styleNode is null, all formats are removed.
1006
+ * (e.g., ['span'], ['strong', 'em'])
1007
+ * @param {boolean} [options.strictRemove=false] If true, only removes nodes from nodesToRemove if all styles and classes are removed.
1008
+ * @returns {HTMLElement} The element that was added to or modified in the selection.
1009
+ *
1010
+ * @details
1011
+ * 1. If styleNode is provided, a node with the same tags and attributes is added to the selected text.
1012
+ * 2. If the same tag already exists, only its attributes are updated.
1013
+ * 3. If styleNode is null, existing nodes are updated or removed without adding new ones.
1014
+ * 4. Styles matching those in stylesToModify are removed. (Use CSS attribute names, e.g., "background-color")
1015
+ * 5. Classes matching those in stylesToModify (prefixed with ".") are removed.
1016
+ * 6. stylesToModify is used to avoid duplicate property values from styleNode.
1017
+ * 7. Nodes with all styles and classes removed are deleted if they match styleNode, are in nodesToRemove, or if styleNode is null.
1018
+ * 8. Tags matching names in nodesToRemove are deleted regardless of their style and class.
1019
+ * 9. If strictRemove is true, nodes in nodesToRemove are only removed if all their styles and classes are removed.
1020
+ * 10. The function won't modify nodes if the parent has the same class and style values.
1021
+ * - However, if nodesToRemove has values, it will work and separate text nodes even if there's no node to replace.
972
1022
  */
973
- applyTextStyle(styleNode, styleArray, removeNodeArray, strictRemove) {
974
- if (domUtils.getParentElement(this.selection.getNode(), domUtils.isNonEditable)) return;
1023
+ applyInlineElement(styleNode, { stylesToModify, nodesToRemove, strictRemove } = {}) {
1024
+ if (dom.query.getParentElement(this.selection.getNode(), dom.check.isNonEditable)) return;
975
1025
 
976
1026
  this.selection._resetRangeToTextNode();
977
1027
  let range = this.selection.getRangeAndAddLine(this.selection.getRange(), null);
978
- styleArray = styleArray?.length > 0 ? styleArray : false;
979
- removeNodeArray = removeNodeArray?.length > 0 ? removeNodeArray : false;
1028
+ stylesToModify = stylesToModify?.length > 0 ? stylesToModify : null;
1029
+ nodesToRemove = nodesToRemove?.length > 0 ? nodesToRemove : null;
980
1030
 
981
1031
  const isRemoveNode = !styleNode;
982
- const isRemoveFormat = isRemoveNode && !removeNodeArray && !styleArray;
1032
+ const isRemoveFormat = isRemoveNode && !nodesToRemove && !stylesToModify;
983
1033
  let startCon = range.startContainer;
984
1034
  let startOff = range.startOffset;
985
1035
  let endCon = range.endContainer;
986
1036
  let endOff = range.endOffset;
987
1037
 
988
- if ((isRemoveFormat && range.collapsed && this.isLine(startCon.parentNode) && this.isLine(endCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && domUtils.isNonEditable(startCon))) {
1038
+ if ((isRemoveFormat && range.collapsed && this.isLine(startCon.parentNode) && this.isLine(endCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && dom.check.isNonEditable(startCon))) {
989
1039
  const format = startCon.parentNode;
990
1040
  if (
991
- !domUtils.isListCell(format) ||
1041
+ !dom.check.isListCell(format) ||
992
1042
  !env.getValues(format.style).some((k) => {
993
1043
  return this._listKebab.includes(k);
994
1044
  })
@@ -998,7 +1048,7 @@ Format.prototype = {
998
1048
  }
999
1049
 
1000
1050
  if (range.collapsed && !isRemoveFormat) {
1001
- if (startCon.nodeType === 1 && !domUtils.isBreak(startCon) && !this.component.is(startCon)) {
1051
+ if (startCon.nodeType === 1 && !dom.check.isBreak(startCon) && !this.component.is(startCon)) {
1002
1052
  let afterNode = null;
1003
1053
  const focusNode = startCon.childNodes[startOff];
1004
1054
 
@@ -1006,11 +1056,11 @@ Format.prototype = {
1006
1056
  if (!focusNode.nextSibling) {
1007
1057
  afterNode = null;
1008
1058
  } else {
1009
- afterNode = domUtils.isBreak(focusNode) ? focusNode : focusNode.nextSibling;
1059
+ afterNode = dom.check.isBreak(focusNode) ? focusNode : focusNode.nextSibling;
1010
1060
  }
1011
1061
  }
1012
1062
 
1013
- const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
1063
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
1014
1064
  startCon.insertBefore(zeroWidth, afterNode);
1015
1065
  this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
1016
1066
 
@@ -1032,37 +1082,40 @@ Format.prototype = {
1032
1082
  }
1033
1083
 
1034
1084
  if (isRemoveNode) {
1035
- styleNode = domUtils.createElement('DIV');
1085
+ styleNode = dom.utils.createElement('DIV');
1036
1086
  }
1037
1087
 
1038
1088
  const wRegExp = RegExp;
1039
1089
  const newNodeName = styleNode.nodeName;
1040
1090
 
1041
1091
  /* checked same style property */
1042
- if (!isRemoveFormat && startCon === endCon && !removeNodeArray && styleNode) {
1092
+ if (!isRemoveFormat && startCon === endCon && !nodesToRemove && styleNode) {
1043
1093
  let sNode = startCon;
1044
1094
  let checkCnt = 0;
1045
1095
  const checkAttrs = [];
1046
1096
 
1047
- const checkStyles = styleNode.style;
1097
+ const checkStyles = /** @type {HTMLElement} */ (styleNode).style;
1048
1098
  for (let i = 0, len = checkStyles.length; i < len; i++) {
1049
1099
  checkAttrs.push(checkStyles[i]);
1050
1100
  }
1051
1101
 
1052
- const ckeckClasses = styleNode.classList;
1102
+ const checkClassName = /** @type {HTMLElement} */ (styleNode).className;
1103
+ const ckeckClasses = /** @type {HTMLElement} */ (styleNode).classList;
1053
1104
  for (let i = 0, len = ckeckClasses.length; i < len; i++) {
1054
1105
  checkAttrs.push('.' + ckeckClasses[i]);
1055
1106
  }
1056
1107
 
1057
1108
  if (checkAttrs.length > 0) {
1058
- while (!this.isLine(sNode) && !domUtils.isWysiwygFrame(sNode)) {
1109
+ while (!this.isLine(sNode) && !dom.check.isWysiwygFrame(sNode)) {
1059
1110
  for (let i = 0; i < checkAttrs.length; i++) {
1060
1111
  if (sNode.nodeType === 1) {
1061
1112
  const s = checkAttrs[i];
1062
1113
  const classReg = /^\./.test(s) ? new wRegExp('\\s*' + s.replace(/^\./, '') + '(\\s+|$)', 'ig') : false;
1114
+ const sNodeStyle = /** @type {HTMLElement} */ (sNode).style;
1115
+ const sNodeClassName = /** @type {HTMLElement} */ (sNode).className;
1063
1116
 
1064
- const styleCheck = isRemoveNode ? !!sNode.style[s] : !!sNode.style[s] && !!styleNode.style[s] && sNode.style[s] === styleNode.style[s];
1065
- const classCheck = classReg === false ? false : isRemoveNode ? !!sNode.className.match(classReg) : !!sNode.className.match(classReg) && !!styleNode.className.match(classReg);
1117
+ const styleCheck = isRemoveNode ? !!sNodeStyle[s] : !!sNodeStyle[s] && !!checkStyles[s] && sNodeStyle[s] === checkStyles[s];
1118
+ const classCheck = classReg === false ? false : isRemoveNode ? !!sNodeClassName.match(classReg) : !!sNodeClassName.match(classReg) && !!checkClassName.match(classReg);
1066
1119
  if (styleCheck || classCheck) {
1067
1120
  checkCnt++;
1068
1121
  }
@@ -1075,16 +1128,22 @@ Format.prototype = {
1075
1128
  }
1076
1129
  }
1077
1130
 
1078
- let start = {},
1079
- end = {};
1080
- let newNode,
1081
- styleRegExp = '',
1082
- classRegExp = '',
1083
- removeNodeRegExp = null;
1131
+ let newNode;
1132
+ /** @type {NodeStyleContainerType} */
1133
+ let start = {};
1134
+ /** @type {NodeStyleContainerType} */
1135
+ let end = {};
1084
1136
 
1085
- if (styleArray) {
1086
- for (let i = 0, len = styleArray.length, s; i < len; i++) {
1087
- s = styleArray[i];
1137
+ /** @type {string|RegExp} */
1138
+ let styleRegExp;
1139
+ /** @type {string|RegExp} */
1140
+ let classRegExp;
1141
+ /** @type {string|RegExp} */
1142
+ let removeNodeRegExp;
1143
+
1144
+ if (stylesToModify) {
1145
+ for (let i = 0, len = stylesToModify.length, s; i < len; i++) {
1146
+ s = stylesToModify[i];
1088
1147
  if (/^\./.test(s)) {
1089
1148
  classRegExp += (classRegExp ? '|' : '\\s*(?:') + s.replace(/^\./, '');
1090
1149
  } else {
@@ -1103,17 +1162,16 @@ Format.prototype = {
1103
1162
  }
1104
1163
  }
1105
1164
 
1106
- if (removeNodeArray) {
1107
- removeNodeRegExp = '^(?:' + removeNodeArray[0];
1108
- for (let i = 1; i < removeNodeArray.length; i++) {
1109
- removeNodeRegExp += '|' + removeNodeArray[i];
1165
+ if (nodesToRemove) {
1166
+ removeNodeRegExp = '^(?:' + nodesToRemove[0];
1167
+ for (let i = 1; i < nodesToRemove.length; i++) {
1168
+ removeNodeRegExp += '|' + nodesToRemove[i];
1110
1169
  }
1111
1170
  removeNodeRegExp += ')$';
1112
1171
  removeNodeRegExp = new wRegExp(removeNodeRegExp, 'i');
1113
1172
  }
1114
1173
 
1115
1174
  /** validation check function*/
1116
- const wBoolean = Boolean;
1117
1175
  const _removeCheck = {
1118
1176
  v: false
1119
1177
  };
@@ -1121,12 +1179,12 @@ Format.prototype = {
1121
1179
  const vNode = checkNode.cloneNode(false);
1122
1180
 
1123
1181
  // all path
1124
- if (vNode.nodeType === 3 || domUtils.isBreak(vNode)) return vNode;
1182
+ if (vNode.nodeType === 3 || dom.check.isBreak(vNode)) return vNode;
1125
1183
  // all remove
1126
1184
  if (isRemoveFormat) return null;
1127
1185
 
1128
1186
  // remove node check
1129
- const tagRemove = (!removeNodeRegExp && isRemoveNode) || removeNodeRegExp?.test(vNode.nodeName);
1187
+ const tagRemove = (!removeNodeRegExp && isRemoveNode) || /** @type {RegExp} */ (removeNodeRegExp)?.test(vNode.nodeName);
1130
1188
 
1131
1189
  // tag remove
1132
1190
  if (tagRemove && !strictRemove) {
@@ -1159,7 +1217,7 @@ Format.prototype = {
1159
1217
  }
1160
1218
 
1161
1219
  // change
1162
- if (style || classes || vNode.nodeName !== newNodeName || wBoolean(styleRegExp) !== wBoolean(originStyle) || wBoolean(classRegExp) !== wBoolean(originClasses)) {
1220
+ if (style || classes || vNode.nodeName !== newNodeName || Boolean(styleRegExp) !== Boolean(originStyle) || Boolean(classRegExp) !== Boolean(originClasses)) {
1163
1221
  if (styleRegExp && originStyle.length > 0) vNode.style.cssText = style;
1164
1222
  if (!vNode.style.cssText) {
1165
1223
  vNode.removeAttribute('style');
@@ -1191,7 +1249,7 @@ Format.prototype = {
1191
1249
  endOff = range.endOffset;
1192
1250
 
1193
1251
  if (!this.getLine(startCon, null)) {
1194
- startCon = domUtils.getEdgeChild(
1252
+ startCon = dom.query.getEdgeChild(
1195
1253
  lineNodes[0],
1196
1254
  function (current) {
1197
1255
  return current.nodeType === 3;
@@ -1202,7 +1260,7 @@ Format.prototype = {
1202
1260
  }
1203
1261
 
1204
1262
  if (!this.getLine(endCon, null)) {
1205
- endCon = domUtils.getEdgeChild(
1263
+ endCon = dom.query.getEdgeChild(
1206
1264
  lineNodes[lineNodes.length - 1],
1207
1265
  function (current) {
1208
1266
  return current.nodeType === 3;
@@ -1223,10 +1281,10 @@ Format.prototype = {
1223
1281
  (isRemoveNode &&
1224
1282
  (function (inst, arr) {
1225
1283
  for (let n = 0, len = arr.length; n < len; n++) {
1226
- if (inst._isNonSplitNode(arr[n]) || inst._sn_isSizeNode(arr[n])) return true;
1284
+ if (inst._isNonSplitNode(arr[n])) return true;
1227
1285
  }
1228
1286
  return false;
1229
- })(this, removeNodeArray));
1287
+ })(this, nodesToRemove));
1230
1288
 
1231
1289
  const isSizeNode = isRemoveNode || this._sn_isSizeNode(newNode);
1232
1290
  const _getMaintainedNode = this._sn_getMaintainedNode.bind(this, isRemoveAnchor, isSizeNode);
@@ -1234,7 +1292,7 @@ Format.prototype = {
1234
1292
 
1235
1293
  // one line
1236
1294
  if (oneLine) {
1237
- if (this._sn_resetCommonListCell(lineNodes[0], styleArray)) range = this.selection.setRange(startCon, startOff, endCon, endOff);
1295
+ if (this._sn_resetCommonListCell(lineNodes[0], stylesToModify)) range = this.selection.setRange(startCon, startOff, endCon, endOff);
1238
1296
 
1239
1297
  const newRange = this._setNode_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
1240
1298
  start.container = newRange.startContainer;
@@ -1242,15 +1300,15 @@ Format.prototype = {
1242
1300
  end.container = newRange.endContainer;
1243
1301
  end.offset = newRange.endOffset;
1244
1302
 
1245
- if (start.container === end.container && domUtils.isZeroWith(start.container)) {
1303
+ if (start.container === end.container && dom.check.isZeroWidth(start.container)) {
1246
1304
  start.offset = end.offset = 1;
1247
1305
  }
1248
1306
  this._sn_setCommonListStyle(newRange.ancestor, null);
1249
1307
  } else {
1250
1308
  // multi line
1251
1309
  let appliedCommonList = false;
1252
- if (endLength > 0 && this._sn_resetCommonListCell(lineNodes[endLength], styleArray)) appliedCommonList = true;
1253
- if (this._sn_resetCommonListCell(lineNodes[0], styleArray)) appliedCommonList = true;
1310
+ if (endLength > 0 && this._sn_resetCommonListCell(lineNodes[endLength], stylesToModify)) appliedCommonList = true;
1311
+ if (this._sn_resetCommonListCell(lineNodes[0], stylesToModify)) appliedCommonList = true;
1254
1312
  if (appliedCommonList) this.selection.setRange(startCon, startOff, endCon, endOff);
1255
1313
 
1256
1314
  // end
@@ -1261,7 +1319,7 @@ Format.prototype = {
1261
1319
 
1262
1320
  // mid
1263
1321
  for (let i = endLength - 1, newRange; i > 0; i--) {
1264
- this._sn_resetCommonListCell(lineNodes[i], styleArray);
1322
+ this._sn_resetCommonListCell(lineNodes[i], stylesToModify);
1265
1323
  newNode = styleNode.cloneNode(false);
1266
1324
  newRange = this._setNode_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
1267
1325
  if (newRange.endContainer && newRange.ancestor.contains(newRange.endContainer)) {
@@ -1293,36 +1351,40 @@ Format.prototype = {
1293
1351
  }
1294
1352
 
1295
1353
  // set range
1296
- this.editor._offCurrentController();
1354
+ this.ui._offCurrentController();
1297
1355
  this.selection.setRange(start.container, start.offset, end.container, end.offset);
1298
1356
  this.history.push(false);
1357
+
1358
+ return /** @type {HTMLElement} */ (newNode);
1299
1359
  },
1300
1360
 
1301
1361
  /**
1362
+ * @this {FormatThis}
1302
1363
  * @description Remove format of the currently selected text.
1303
1364
  */
1304
- removeTextStyle() {
1305
- this.applyTextStyle(null, null, null, null);
1365
+ removeInlineElement() {
1366
+ this.applyInlineElement(null, { stylesToModify: null, nodesToRemove: null, strictRemove: null });
1306
1367
  },
1307
1368
 
1308
1369
  /**
1370
+ * @this {FormatThis}
1309
1371
  * @description Check if the container and offset values are the edges of the "line"
1310
- * @param {Node} container The node of the selection object. (range.startContainer..)
1372
+ * @param {Node} node The node of the selection object. (range.startContainer..)
1311
1373
  * @param {number} offset The offset of the selection object. (selection.getRange().startOffset...)
1312
- * @param {string} dir Select check point - "front": Front edge, "end": End edge, undefined: Both edge.
1313
- * @returns {boolean}
1374
+ * @param {"front"|"end"} dir Select check point - "front": Front edge, "end": End edge, undefined: Both edge.
1375
+ * @returns {node is HTMLElement}
1314
1376
  */
1315
1377
  isEdgeLine(node, offset, dir) {
1316
- if (!domUtils.isEdgePoint(node, offset, dir)) return false;
1378
+ if (!dom.check.isEdgePoint(node, offset, dir)) return false;
1317
1379
 
1318
- const result = [];
1319
- dir = dir === 'front' ? 'previousSibling' : 'nextSibling';
1320
- while (node && !this.isLine(node) && !domUtils.isWysiwygFrame(node)) {
1321
- if (!node[dir] || (domUtils.isBreak(node[dir]) && !node[dir][dir])) {
1322
- if (node.nodeType === 1) result.push(node.cloneNode(false));
1380
+ let result = false;
1381
+ const siblingType = dir === 'front' ? 'previousSibling' : 'nextSibling';
1382
+ while (node && !this.isLine(node) && !dom.check.isWysiwygFrame(node)) {
1383
+ if (!node[siblingType] || (dom.check.isBreak(node[siblingType]) && !node[siblingType][siblingType])) {
1384
+ result = true;
1323
1385
  node = node.parentNode;
1324
1386
  } else {
1325
- return null;
1387
+ return false;
1326
1388
  }
1327
1389
  }
1328
1390
 
@@ -1330,102 +1392,115 @@ Format.prototype = {
1330
1392
  },
1331
1393
 
1332
1394
  /**
1395
+ * @this {FormatThis}
1333
1396
  * @description It is judged whether it is a node related to the text style.
1334
1397
  * @param {Node|string} element The node to check
1335
- * @returns {boolean}
1398
+ * @returns {element is HTMLElement}
1336
1399
  */
1337
1400
  isTextStyleNode(element) {
1338
1401
  return typeof element === 'string' ? this._textStyleTagsCheck.test(element) : element && element.nodeType === 1 && this._textStyleTagsCheck.test(element.nodeName);
1339
1402
  },
1340
1403
 
1341
1404
  /**
1342
- * @description It is judged whether it is the format element (P, DIV, H[1-6], PRE, LI | class="__se__format__line_xxx")
1343
- * Format element also contain "free format Element"
1405
+ * @this {FormatThis}
1406
+ * @description It is judged whether it is the "line" element.
1407
+ * - (P, DIV, H[1-6], PRE, LI | class="__se__format__line_xxx")
1408
+ * - "line" element also contain "brLine" element
1344
1409
  * @param {Node|string} element The node to check
1345
- * @returns {boolean}
1410
+ * @returns {element is HTMLElement}
1346
1411
  */
1347
1412
  isLine(element) {
1413
+ if (this.isBlock(element)) return false;
1348
1414
  return typeof element === 'string'
1349
1415
  ? this._formatLineCheck.test(element)
1350
- : element && element.nodeType === 1 && (this._formatLineCheck.test(element.nodeName) || domUtils.hasClass(element, '__se__format__line_.+|__se__format__br_line_.+')) && !this._nonFormat(element);
1416
+ : element && element.nodeType === 1 && (this._formatLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__line_.+|__se__format__br_line_.+')) && !this._nonFormat(element);
1351
1417
  },
1352
1418
 
1353
1419
  /**
1354
- * @description It is judged whether it is the only format element, not block (td, th, li)
1355
- * Format element also contain "free format Element"
1420
+ * @this {FormatThis}
1421
+ * @description It is judged whether it is the only "line" element, not "brLine".
1356
1422
  * @param {Node|string} element The node to check
1357
- * @returns {boolean}
1423
+ * @returns {element is HTMLElement}
1358
1424
  */
1359
1425
  isLineOnly(element) {
1360
- return this._formatLineCheck.test(element) && !this._formatBlockCheck.test(element);
1426
+ return this.isLine(element) && !this.isBrLine(element);
1361
1427
  },
1362
1428
 
1363
1429
  /**
1364
- * @description It is judged whether it is the free format element. (PRE | class="__se__format__br_line_xxx")
1365
- * Free format elements is included in the format element.
1366
- * Free format elements's line break is "BR" tag.
1367
- * Entering the Enter key in the space on the last line ends "Free Format" and appends "Format".
1430
+ * @this {FormatThis}
1431
+ * @description It is judged whether it is the "brLine" element.
1432
+ * - (PRE | class="__se__format__br_line_xxx")
1433
+ * - "brLine" elements is included in the "line" element.
1434
+ * - "brLine" elements's line break is "BR" tag.
1435
+ * ※ Entering the Enter key in the space on the last line ends "brLine" and appends "line".
1368
1436
  * @param {Node|string} element The node to check
1369
- * @returns {boolean}
1437
+ * @returns {element is HTMLElement}
1370
1438
  */
1371
1439
  isBrLine(element) {
1372
1440
  return typeof element === 'string'
1373
1441
  ? this._formatBrLineCheck.test(element)
1374
- : element && element.nodeType === 1 && (this._formatBrLineCheck.test(element.nodeName) || domUtils.hasClass(element, '__se__format__br_line_.+')) && !this._nonFormat(element);
1442
+ : element && element.nodeType === 1 && (this._formatBrLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__br_line_.+')) && !this._nonFormat(element);
1375
1443
  },
1376
1444
 
1377
1445
  /**
1378
- * @description It is judged whether it is the range format element. (BLOCKQUOTE, OL, UL, FIGCAPTION, TABLE, THEAD, TBODY, TR, TH, TD | class="__se__format__block_xxx")
1379
- * Range format element is wrap the "format element" and "component"
1446
+ * @this {FormatThis}
1447
+ * @description It is judged whether it is the "block" element.
1448
+ * - (BLOCKQUOTE, OL, UL, FIGCAPTION, TABLE, THEAD, TBODY, TR, TH, TD | class="__se__format__block_xxx")
1449
+ * - "block" is wrap the "line" and "component"
1380
1450
  * @param {Node|string} element The node to check
1381
- * @returns {boolean}
1451
+ * @returns {element is HTMLElement}
1382
1452
  */
1383
1453
  isBlock(element) {
1384
1454
  return typeof element === 'string'
1385
1455
  ? this._formatBlockCheck.test(element)
1386
- : element && element.nodeType === 1 && (this._formatBlockCheck.test(element.nodeName) || domUtils.hasClass(element, '__se__format__block_.+')) && !this._nonFormat(element);
1456
+ : element && element.nodeType === 1 && (this._formatBlockCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__block_.+')) && !this._nonFormat(element);
1387
1457
  },
1388
1458
 
1389
1459
  /**
1390
- * @description It is judged whether it is the closure range format element. (TH, TD | class="__se__format__block_closure_xxx")
1391
- * Closure range format elements is included in the range format element.
1392
- * - Closure range format element is wrap the "format element" and "component"
1393
- * You cannot exit this format with the Enter key or Backspace key.
1394
- * Use it only in special cases. ([ex] format of table cells)
1460
+ * @this {FormatThis}
1461
+ * @description It is judged whether it is the "closureBlock" element.
1462
+ * - (TH, TD | class="__se__format__block_closure_xxx")
1463
+ * - "closureBlock" elements is included in the "block".
1464
+ * - "closureBlock" element is wrap the "line" and "component"
1465
+ * - ※ You cannot exit this format with the Enter key or Backspace key.
1466
+ * - ※ Use it only in special cases. ([ex] format of table cells)
1395
1467
  * @param {Node|string} element The node to check
1396
- * @returns {boolean}
1468
+ * @returns {element is HTMLElement}
1397
1469
  */
1398
1470
  isClosureBlock(element) {
1399
1471
  return typeof element === 'string'
1400
1472
  ? this._formatClosureBlockCheck.test(element)
1401
- : element && element.nodeType === 1 && (this._formatClosureBlockCheck.test(element.nodeName) || domUtils.hasClass(element, '__se__format__block_closure_.+')) && !this._nonFormat(element);
1473
+ : element && element.nodeType === 1 && (this._formatClosureBlockCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__block_closure_.+')) && !this._nonFormat(element);
1402
1474
  },
1403
1475
 
1404
1476
  /**
1405
- * @description It is judged whether it is the closure free format element. (class="__se__format__br_line__closure_xxx")
1406
- * Closure free format elements is included in the free format element.
1407
- * - Closure free format elements's line break is "BR" tag.
1408
- * You cannot exit this format with the Enter key or Backspace key.
1409
- * Use it only in special cases. ([ex] format of table cells)
1477
+ * @this {FormatThis}
1478
+ * @description It is judged whether it is the "closureBrLine" element.
1479
+ * - (class="__se__format__br_line__closure_xxx")
1480
+ * - "closureBrLine" elements is included in the "brLine".
1481
+ * - "closureBrLine" elements's line break is "BR" tag.
1482
+ * - ※ You cannot exit this format with the Enter key or Backspace key.
1483
+ * - ※ Use it only in special cases. ([ex] format of table cells)
1410
1484
  * @param {Node|string} element The node to check
1411
- * @returns {boolean}
1485
+ * @returns {element is HTMLElement}
1412
1486
  */
1413
1487
  isClosureBrLine(element) {
1414
1488
  return typeof element === 'string'
1415
1489
  ? this._formatClosureBrLineCheck.test(element)
1416
- : element && element.nodeType === 1 && (this._formatClosureBrLineCheck.test(element.nodeName) || domUtils.hasClass(element, '__se__format__br_line__closure_.+')) && !this._nonFormat(element);
1490
+ : element && element.nodeType === 1 && (this._formatClosureBrLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__br_line__closure_.+')) && !this._nonFormat(element);
1417
1491
  },
1418
1492
 
1419
1493
  /**
1494
+ * @this {FormatThis}
1420
1495
  * @description Returns a "line" array from selected range.
1421
- * @param {Function|null} validation The validation function. (Replaces the default validation format.isLine(current))
1422
- * @returns {Array}
1496
+ * @param {?(current: Node) => boolean=} validation The validation function. (Replaces the default validation format.isLine(current))
1497
+ * @returns {Array<HTMLElement>}
1423
1498
  */
1424
1499
  getLines(validation) {
1425
1500
  if (!this.selection._resetRangeToTextNode()) return [];
1426
1501
  let range = this.selection.getRange();
1427
1502
 
1428
- if (domUtils.isWysiwygFrame(range.startContainer)) {
1503
+ if (dom.check.isWysiwygFrame(range.startContainer)) {
1429
1504
  const children = this.editor.frameContext.get('wysiwyg').children;
1430
1505
  if (children.length === 0) return [];
1431
1506
 
@@ -1438,11 +1513,11 @@ Format.prototype = {
1438
1513
  const commonCon = range.commonAncestorContainer;
1439
1514
 
1440
1515
  // get line nodes
1441
- const lineNodes = domUtils.getListChildren(commonCon, (current) => {
1516
+ const lineNodes = dom.query.getListChildren(commonCon, (current) => {
1442
1517
  return validation ? validation(current) : this.isLine(current);
1443
1518
  });
1444
1519
 
1445
- if (!domUtils.isWysiwygFrame(commonCon) && !this.isBlock(commonCon)) lineNodes.unshift(this.getLine(commonCon, null));
1520
+ if (!dom.check.isWysiwygFrame(commonCon) && !this.isBlock(commonCon)) lineNodes.unshift(this.getLine(commonCon, null));
1446
1521
  if (startCon === endCon || lineNodes.length === 1) return lineNodes;
1447
1522
 
1448
1523
  const startLine = this.getLine(startCon, null);
@@ -1451,13 +1526,13 @@ Format.prototype = {
1451
1526
  let endIdx = null;
1452
1527
 
1453
1528
  const onlyTable = function (current) {
1454
- return domUtils.isTableElements(current) ? /^TABLE$/i.test(current.nodeName) : true;
1529
+ return dom.check.isTableElements(current) ? /^TABLE$/i.test(current.nodeName) : true;
1455
1530
  };
1456
1531
 
1457
1532
  let startRangeEl = this.getBlock(startLine, onlyTable);
1458
1533
  let endRangeEl = this.getBlock(endLine, onlyTable);
1459
- if (domUtils.isTableElements(startRangeEl) && domUtils.isListCell(startRangeEl.parentNode)) startRangeEl = startRangeEl.parentNode;
1460
- if (domUtils.isTableElements(endRangeEl) && domUtils.isListCell(endRangeEl.parentNode)) endRangeEl = endRangeEl.parentNode;
1534
+ if (dom.check.isTableElements(startRangeEl) && dom.check.isListCell(startRangeEl.parentNode)) startRangeEl = startRangeEl.parentNode;
1535
+ if (dom.check.isTableElements(endRangeEl) && dom.check.isListCell(endRangeEl.parentNode)) endRangeEl = endRangeEl.parentNode;
1461
1536
 
1462
1537
  const sameRange = startRangeEl === endRangeEl;
1463
1538
  for (let i = 0, len = lineNodes.length, line; i < len; i++) {
@@ -1481,18 +1556,19 @@ Format.prototype = {
1481
1556
  },
1482
1557
 
1483
1558
  /**
1559
+ * @this {FormatThis}
1484
1560
  * @description Get lines and components from the selected range. (P, DIV, H[1-6], OL, UL, TABLE..)
1485
- * If some of the component are included in the selection, get the entire that component.
1561
+ * - If some of the component are included in the selection, get the entire that component.
1486
1562
  * @param {boolean} removeDuplicate If true, if there is a parent and child tag among the selected elements, the child tag is excluded.
1487
- * @returns {Array}
1563
+ * @returns {Array<HTMLElement>}
1488
1564
  */
1489
1565
  getLinesAndComponents(removeDuplicate) {
1490
1566
  const commonCon = this.selection.getRange().commonAncestorContainer;
1491
- const myComponent = domUtils.getParentElement(commonCon, this.component.is.bind(this.component));
1492
- const selectedLines = domUtils.isTableElements(commonCon)
1567
+ const myComponent = dom.query.getParentElement(commonCon, this.component.is.bind(this.component));
1568
+ const selectedLines = dom.check.isTableElements(commonCon)
1493
1569
  ? this.getLines(null)
1494
1570
  : this.getLines((current) => {
1495
- const component = domUtils.getParentElement(current, this.component.is.bind(this.component));
1571
+ const component = dom.query.getParentElement(current, this.component.is.bind(this.component));
1496
1572
  return (this.isLine(current) && (!component || component === myComponent)) || (this.component.is(current) && !this.getLine(current));
1497
1573
  });
1498
1574
 
@@ -1513,59 +1589,71 @@ Format.prototype = {
1513
1589
  },
1514
1590
 
1515
1591
  /**
1592
+ * @private
1593
+ * @this {FormatThis}
1516
1594
  * @description A function that distinguishes areas where "selection" should not be placed
1517
- * @param {Element} element Element
1595
+ * @param {Node} element Element
1518
1596
  * @returns {boolean}
1519
- * @private
1520
1597
  */
1521
1598
  _isExcludeSelectionElement(element) {
1522
1599
  return !/FIGCAPTION/i.test(element.nodeName) && (this.component.is(element) || /FIGURE/i.test(element.nodeName));
1523
1600
  },
1524
1601
 
1525
1602
  /**
1603
+ * @private
1604
+ * @this {FormatThis}
1526
1605
  * @description A function that distinguishes non-formatting HTML elements or tags from formatting ones.
1527
- * @param {Element} element Element
1606
+ * @param {Node} element Element
1528
1607
  * @returns {boolean}
1529
- * @private
1530
1608
  */
1531
1609
  _nonFormat(element) {
1532
- return domUtils.isExcludeFormat(element) || this.component.is(element) || domUtils.isWysiwygFrame(element);
1610
+ return dom.check.isExcludeFormat(element) || this.component.is(element) || dom.check.isWysiwygFrame(element);
1533
1611
  },
1534
1612
 
1535
1613
  /**
1614
+ * @private
1615
+ * @this {FormatThis}
1536
1616
  * @description Nodes that must remain undetached when changing text nodes (A, Label, Code, Span:font-size)
1537
- * @param {Node|String} element Element to check
1617
+ * @param {Node|string} element Element to check
1538
1618
  * @returns {boolean}
1539
- * @private
1540
1619
  */
1541
1620
  _isNonSplitNode(element) {
1542
- return element && element.nodeType !== 3 && /^(a|label|code|summary)$/i.test(typeof element === 'string' ? element : element.nodeName);
1621
+ if (!element) return false;
1622
+ const checkRegExp = /^(a|label|code|summary)$/i;
1623
+ if (typeof element === 'string') return checkRegExp.test(element);
1624
+ return element.nodeType === 1 && checkRegExp.test(element.nodeName);
1543
1625
  },
1544
1626
 
1545
1627
  /**
1628
+ * @private
1629
+ * @this {FormatThis}
1546
1630
  * @description Nodes without text
1547
- * @param {Node} element Element to check
1631
+ * @param {Node|string} element Element to check
1548
1632
  * @returns {boolean}
1549
- * @private
1550
1633
  */
1551
1634
  _notTextNode(element) {
1552
- return element && element.nodeType !== 3 && (this.component.is(element) || /^(br|input|select|canvas|img|iframe|audio|video)$/i.test(typeof element === 'string' ? element : element.nodeName));
1635
+ if (!element) return false;
1636
+ const checkRegExp = /^(br|input|select|canvas|img|iframe|audio|video)$/i;
1637
+ if (typeof element === 'string') return checkRegExp.test(element);
1638
+ return element.nodeType === 1 && (this.component.is(element) || checkRegExp.test(element.nodeName));
1553
1639
  },
1554
1640
 
1555
1641
  /**
1642
+ * @private
1643
+ * @this {FormatThis}
1556
1644
  * @description Nodes that need to be added without modification when changing text nodes
1557
1645
  * @param {Node} element Element to check
1558
1646
  * @returns {boolean}
1559
- * @private
1560
1647
  */
1561
1648
  _isIgnoreNodeChange(element) {
1562
- return element && element.nodeType !== 3 && (domUtils.isNonEditable(element) || !this.isTextStyleNode(element));
1649
+ return element && element.nodeType === 1 && (dom.check.isNonEditable(element) || !this.isTextStyleNode(element) || this.component.is(element));
1563
1650
  },
1564
1651
 
1565
1652
  /**
1566
- * @description Get current selected lines and selected node info.
1567
- * @returns { lines: Array.<Element>, firstNode: Node, lastNode: Node, firstPath: Array.<number>, lastPath: Array.<number>, startOffset: number, endOffset: number }
1568
1653
  * @private
1654
+ * @this {FormatThis}
1655
+ * @description Get current selected lines and selected node info.
1656
+ * @returns {{lines: Array<HTMLElement>, firstNode: Node, lastNode: Node, firstPath: Array<number>, lastPath: Array<number>, startOffset: number, endOffset: number}}
1569
1657
  */
1570
1658
  _lineWork() {
1571
1659
  let range = this.selection.getRange();
@@ -1580,10 +1668,10 @@ Format.prototype = {
1580
1668
  const startOffset = range.startOffset;
1581
1669
  const endOffset = range.endOffset;
1582
1670
 
1583
- let first = selectedFormsts[0];
1584
- let last = selectedFormsts[selectedFormsts.length - 1];
1585
- const firstPath = domUtils.getNodePath(range.startContainer, first, null, null);
1586
- const lastPath = domUtils.getNodePath(range.endContainer, last, null, null);
1671
+ let first = /** @type {Node} */ (selectedFormsts[0]);
1672
+ let last = /** @type {Node} */ (selectedFormsts[selectedFormsts.length - 1]);
1673
+ const firstPath = dom.query.getNodePath(range.startContainer, first, null);
1674
+ const lastPath = dom.query.getNodePath(range.endContainer, last, null);
1587
1675
 
1588
1676
  // remove selected list
1589
1677
  const rlist = this.removeList(selectedFormsts, false);
@@ -1591,7 +1679,7 @@ Format.prototype = {
1591
1679
  if (rlist.ec) last = rlist.ec;
1592
1680
 
1593
1681
  // change format tag
1594
- this.selection.setRange(domUtils.getNodeFromPath(firstPath, first), startOffset, domUtils.getNodeFromPath(lastPath, last), endOffset);
1682
+ this.selection.setRange(dom.query.getNodeFromPath(firstPath, first), startOffset, dom.query.getNodeFromPath(lastPath, last), endOffset);
1595
1683
 
1596
1684
  return {
1597
1685
  lines: this.getLinesAndComponents(false),
@@ -1604,6 +1692,22 @@ Format.prototype = {
1604
1692
  };
1605
1693
  },
1606
1694
 
1695
+ /**
1696
+ * @private
1697
+ * @this {FormatThis}
1698
+ * @description Attaches a nested list structure by merging adjacent lists if applicable.
1699
+ * - Ensures that the nested list is placed correctly in the document structure.
1700
+ * @param {Element} originList The original list element where the nested list is inserted.
1701
+ * @param {Element} innerList The nested list element.
1702
+ * @param {Element} prev The previous sibling element.
1703
+ * @param {Element} next The next sibling element.
1704
+ * @param {{s: Array<number> | null, e: Array<number> | null, sl: Node | null, el: Node | null}} nodePath Object storing the start and end node paths.
1705
+ * - s : Start node path.
1706
+ * - e : End node path.
1707
+ * - sl : Start node's parent element.
1708
+ * - el : End node's parent element.
1709
+ * @returns {Node} The attached inner list.
1710
+ */
1607
1711
  _attachNested(originList, innerList, prev, next, nodePath) {
1608
1712
  let insertPrev = false;
1609
1713
 
@@ -1629,7 +1733,7 @@ Format.prototype = {
1629
1733
  }
1630
1734
 
1631
1735
  if (!insertPrev) {
1632
- if (domUtils.isListCell(prev)) {
1736
+ if (dom.check.isListCell(prev)) {
1633
1737
  originList = prev;
1634
1738
  next = null;
1635
1739
  }
@@ -1637,29 +1741,40 @@ Format.prototype = {
1637
1741
  originList.insertBefore(innerList, next);
1638
1742
 
1639
1743
  if (!nodePath.s) {
1640
- nodePath.s = domUtils.getNodePath(innerList.firstElementChild.firstChild, originList, null);
1744
+ nodePath.s = dom.query.getNodePath(innerList.firstElementChild.firstChild, originList, null);
1641
1745
  nodePath.sl = originList;
1642
1746
  }
1643
1747
 
1644
- const slPath = originList.contains(nodePath.sl) ? domUtils.getNodePath(nodePath.sl, originList) : null;
1645
- nodePath.e = domUtils.getNodePath(innerList.lastElementChild.firstChild, originList, null);
1748
+ const slPath = originList.contains(nodePath.sl) ? dom.query.getNodePath(nodePath.sl, originList) : null;
1749
+ nodePath.e = dom.query.getNodePath(innerList.lastElementChild.firstChild, originList, null);
1646
1750
  nodePath.el = originList;
1647
1751
 
1648
1752
  this.nodeTransform.mergeSameTags(originList, [nodePath.s, nodePath.e, slPath], false);
1649
1753
  this.nodeTransform.mergeNestedTags(originList);
1650
- if (slPath) nodePath.sl = domUtils.getNodeFromPath(slPath, originList);
1754
+ if (slPath) nodePath.sl = dom.query.getNodeFromPath(slPath, originList);
1651
1755
  }
1652
1756
 
1653
1757
  return innerList;
1654
1758
  },
1655
1759
 
1760
+ /**
1761
+ * @private
1762
+ * @this {FormatThis}
1763
+ * @description Detaches a nested list structure by extracting list items from their parent list.
1764
+ * - Ensures proper restructuring of the list elements.
1765
+ * @param {Array<HTMLElement>} cells The list items to be detached.
1766
+ * @returns {{cc: Node, sc: Node, ec: Node}} An object containing reference nodes for repositioning.
1767
+ * - cc : The parent node of the first list item.
1768
+ * - sc : The first list item.
1769
+ * - ec : The last list item.
1770
+ */
1656
1771
  _detachNested(cells) {
1657
1772
  const first = cells[0];
1658
1773
  const last = cells[cells.length - 1];
1659
1774
  const next = last.nextElementSibling;
1660
- const originList = first.parentNode;
1661
- const sibling = originList.parentNode.nextElementSibling;
1662
- const parentNode = originList.parentNode.parentNode;
1775
+ const originList = first.parentElement;
1776
+ const sibling = originList.parentElement.nextElementSibling;
1777
+ const parentNode = originList.parentElement.parentElement;
1663
1778
 
1664
1779
  for (let c = 0, cLen = cells.length; c < cLen; c++) {
1665
1780
  parentNode.insertBefore(cells[c], sibling);
@@ -1668,17 +1783,17 @@ Format.prototype = {
1668
1783
  if (next && originList.children.length > 0) {
1669
1784
  const newList = originList.cloneNode(false);
1670
1785
  const children = originList.childNodes;
1671
- const index = domUtils.getPositionIndex(next);
1786
+ const index = dom.query.getPositionIndex(next);
1672
1787
  while (children[index]) {
1673
1788
  newList.appendChild(children[index]);
1674
1789
  }
1675
1790
  last.appendChild(newList);
1676
1791
  }
1677
1792
 
1678
- if (originList.children.length === 0) domUtils.removeItem(originList);
1793
+ if (originList.children.length === 0) dom.utils.removeItem(originList);
1679
1794
  this.nodeTransform.mergeSameTags(parentNode);
1680
1795
 
1681
- const edge = domUtils.getEdgeChildNodes(first, last);
1796
+ const edge = dom.query.getEdgeChildNodes(first, last);
1682
1797
 
1683
1798
  return {
1684
1799
  cc: first.parentNode,
@@ -1688,19 +1803,20 @@ Format.prototype = {
1688
1803
  },
1689
1804
 
1690
1805
  /**
1806
+ * @private
1807
+ * @this {FormatThis}
1691
1808
  * @description Nest list cells or cancel nested cells.
1692
1809
  * @param selectedCells List cells.
1693
1810
  * @param nested Nested or cancel nested.
1694
- * @private
1695
1811
  */
1696
1812
  _applyNestedList(selectedCells, nested) {
1697
1813
  selectedCells = !selectedCells
1698
1814
  ? this.getLines().filter(function (el) {
1699
- return domUtils.isListCell(el);
1815
+ return dom.check.isListCell(el);
1700
1816
  })
1701
1817
  : selectedCells;
1702
1818
  const cellsLen = selectedCells.length;
1703
- if (cellsLen === 0 || (!nested && !domUtils.isListCell(selectedCells[0].previousElementSibling) && !domUtils.isListCell(selectedCells[cellsLen - 1].nextElementSibling))) {
1819
+ if (cellsLen === 0 || (!nested && !dom.check.isListCell(selectedCells[0].previousElementSibling) && !dom.check.isListCell(selectedCells[cellsLen - 1].nextElementSibling))) {
1704
1820
  return {
1705
1821
  sc: selectedCells[0],
1706
1822
  so: 0,
@@ -1714,7 +1830,7 @@ Format.prototype = {
1714
1830
  let range = null;
1715
1831
 
1716
1832
  if (nested) {
1717
- if (originList !== lastCell.parentNode && domUtils.isList(lastCell.parentNode.parentNode) && lastCell.nextElementSibling) {
1833
+ if (originList !== lastCell.parentNode && dom.check.isList(lastCell.parentNode.parentNode) && lastCell.nextElementSibling) {
1718
1834
  lastCell = lastCell.nextElementSibling;
1719
1835
  while (lastCell) {
1720
1836
  selectedCells.push(lastCell);
@@ -1723,7 +1839,7 @@ Format.prototype = {
1723
1839
  }
1724
1840
  range = this.applyList(originList.nodeName + ':' + originList.style.listStyleType, selectedCells, true);
1725
1841
  } else {
1726
- let innerList = domUtils.createElement(originList.nodeName);
1842
+ let innerList = dom.utils.createElement(originList.nodeName);
1727
1843
  let prev = selectedCells[0].previousElementSibling;
1728
1844
  let next = lastCell.nextElementSibling;
1729
1845
  const nodePath = {
@@ -1738,7 +1854,7 @@ Format.prototype = {
1738
1854
  if (c.parentNode !== originList) {
1739
1855
  this._attachNested(originList, innerList, prev, next, nodePath);
1740
1856
  originList = c.parentNode;
1741
- innerList = domUtils.createElement(originList.nodeName);
1857
+ innerList = dom.utils.createElement(originList.nodeName);
1742
1858
  }
1743
1859
 
1744
1860
  prev = c.previousElementSibling;
@@ -1748,8 +1864,8 @@ Format.prototype = {
1748
1864
 
1749
1865
  this._attachNested(originList, innerList, prev, next, nodePath);
1750
1866
 
1751
- const sc = domUtils.getNodeFromPath(nodePath.s, nodePath.sl);
1752
- const ec = domUtils.getNodeFromPath(nodePath.e, nodePath.el);
1867
+ const sc = dom.query.getNodeFromPath(nodePath.s, nodePath.sl);
1868
+ const ec = dom.query.getNodeFromPath(nodePath.e, nodePath.el);
1753
1869
  range = {
1754
1870
  sc: sc,
1755
1871
  so: 0,
@@ -1762,12 +1878,13 @@ Format.prototype = {
1762
1878
  },
1763
1879
 
1764
1880
  /**
1881
+ * @private
1882
+ * @this {FormatThis}
1765
1883
  * @description Detach Nested all nested lists under the "baseNode".
1766
- * Returns a list with nested removed.
1767
- * @param {Node} baseNode Element on which to base.
1884
+ * - Returns a list with nested removed.
1885
+ * @param {HTMLElement} baseNode Element on which to base.
1768
1886
  * @param {boolean} all If true, it also detach all nested lists of a returned list.
1769
- * @returns {Element}
1770
- * @private
1887
+ * @returns {Node} Result element
1771
1888
  */
1772
1889
  _removeNestedList(baseNode, all) {
1773
1890
  const rNode = DeleteNestedList(baseNode);
@@ -1776,7 +1893,7 @@ Format.prototype = {
1776
1893
  if (rNode) {
1777
1894
  rangeElement = rNode.cloneNode(false);
1778
1895
  cNodes = rNode.childNodes;
1779
- const index = domUtils.getPositionIndex(baseNode);
1896
+ const index = dom.query.getPositionIndex(baseNode);
1780
1897
  while (cNodes[index]) {
1781
1898
  rangeElement.appendChild(cNodes[index]);
1782
1899
  }
@@ -1786,13 +1903,13 @@ Format.prototype = {
1786
1903
 
1787
1904
  let rChildren;
1788
1905
  if (!all) {
1789
- const depth = domUtils.getNodeDepth(baseNode) + 2;
1790
- rChildren = domUtils.getListChildren(baseNode, (current) => {
1791
- return domUtils.isListCell(current) && !current.previousElementSibling && domUtils.getNodeDepth(current) === depth;
1906
+ const depth = dom.query.getNodeDepth(baseNode) + 2;
1907
+ rChildren = dom.query.getListChildren(baseNode, (current) => {
1908
+ return dom.check.isListCell(current) && !current.previousElementSibling && dom.query.getNodeDepth(current) === depth;
1792
1909
  });
1793
1910
  } else {
1794
- rChildren = domUtils.getListChildren(rangeElement, (current) => {
1795
- return domUtils.isListCell(current) && !current.previousElementSibling;
1911
+ rChildren = dom.query.getListChildren(rangeElement, (current) => {
1912
+ return dom.check.isListCell(current) && !current.previousElementSibling;
1796
1913
  });
1797
1914
  }
1798
1915
 
@@ -1802,17 +1919,19 @@ Format.prototype = {
1802
1919
 
1803
1920
  if (rNode) {
1804
1921
  rNode.parentNode.insertBefore(rangeElement, rNode.nextSibling);
1805
- if (cNodes?.length === 0) domUtils.removeItem(rNode);
1922
+ if (cNodes?.length === 0) dom.utils.removeItem(rNode);
1806
1923
  }
1807
1924
 
1808
1925
  return rangeElement === baseNode ? rangeElement.parentNode : rangeElement;
1809
1926
  },
1810
1927
 
1811
1928
  /**
1929
+ * @private
1930
+ * @this {FormatThis}
1812
1931
  * @description wraps text nodes of line selected text.
1813
- * @param {Element} element The node of the line that contains the selected text node.
1814
- * @param {Element} newInnerNode The dom that will wrap the selected text area
1815
- * @param {Function} validation Check if the node should be stripped.
1932
+ * @param {Node} element The node of the line that contains the selected text node.
1933
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
1934
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
1816
1935
  * @param {Node} startCon The startContainer property of the selection object.
1817
1936
  * @param {number} startOff The startOffset property of the selection object.
1818
1937
  * @param {Node} endCon The endContainer property of the selection object.
@@ -1821,24 +1940,23 @@ Format.prototype = {
1821
1940
  * @param {boolean} isRemoveNode "newInnerNode" is remove node?
1822
1941
  * @param {boolean} collapsed range.collapsed
1823
1942
  * @returns {{ancestor: *, startContainer: *, startOffset: *, endContainer: *, endOffset: *}}
1824
- * @private
1825
1943
  */
1826
1944
  _setNode_oneLine(element, newInnerNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
1827
1945
  // not add tag
1828
1946
  let parentCon = startCon.parentNode;
1829
- while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !domUtils.isWysiwygFrame(parentCon.parentNode)) {
1947
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
1830
1948
  if (parentCon.nodeName === newInnerNode.nodeName) break;
1831
1949
  parentCon = parentCon.parentNode;
1832
1950
  }
1833
1951
 
1834
1952
  if (!isRemoveNode && parentCon === endCon.parentNode && parentCon.nodeName === newInnerNode.nodeName) {
1835
- if (domUtils.isZeroWith(startCon.textContent.slice(0, startOff)) && domUtils.isZeroWith(endCon.textContent.slice(endOff))) {
1953
+ if (dom.check.isZeroWidth(startCon.textContent.slice(0, startOff)) && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
1836
1954
  const children = parentCon.childNodes;
1837
1955
  let sameTag = false;
1838
1956
 
1839
1957
  for (let i = 0, len = children.length, c, s, e, z; i < len; i++) {
1840
1958
  c = children[i];
1841
- z = !domUtils.isZeroWith(c);
1959
+ z = !dom.check.isZeroWidth(c);
1842
1960
  if (c === startCon) {
1843
1961
  s = true;
1844
1962
  continue;
@@ -1854,7 +1972,7 @@ Format.prototype = {
1854
1972
  }
1855
1973
 
1856
1974
  if (sameTag) {
1857
- domUtils.copyTagAttributes(parentCon, newInnerNode);
1975
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
1858
1976
 
1859
1977
  return {
1860
1978
  ancestor: element,
@@ -1886,7 +2004,7 @@ Format.prototype = {
1886
2004
  const wRegExp = RegExp;
1887
2005
  function checkCss(vNode) {
1888
2006
  const regExp = new wRegExp('(?:;|^|\\s)(?:' + cssText + 'null)\\s*:[^;]*\\s*(?:;|$)', 'ig');
1889
- let style = '';
2007
+ let style = false;
1890
2008
 
1891
2009
  if (regExp && vNode.style.cssText.length > 0) {
1892
2010
  style = regExp.test(vNode.style.cssText);
@@ -1908,12 +2026,17 @@ Format.prototype = {
1908
2026
  if (!startPass && child === startContainer) {
1909
2027
  let line = pNode;
1910
2028
  anchorNode = _getMaintainedNode(child);
1911
- const prevNode = domUtils.createTextNode(startContainer.nodeType === 1 ? '' : startContainer.substringData(0, startOffset));
1912
- const textNode = domUtils.createTextNode(
1913
- startContainer.nodeType === 1
1914
- ? ''
1915
- : startContainer.substringData(startOffset, isSameNode ? (endOffset >= startOffset ? endOffset - startOffset : startContainer.data.length - startOffset) : startContainer.data.length - startOffset)
1916
- );
2029
+
2030
+ let _prevText = '';
2031
+ let _nextText = '';
2032
+ if (startContainer.nodeType === 3) {
2033
+ const sText = /** @type {Text} */ (startContainer);
2034
+ _prevText = sText.substringData(0, startOffset);
2035
+ _nextText = sText.substringData(startOffset, isSameNode ? (endOffset >= startOffset ? endOffset - startOffset : sText.data.length - startOffset) : sText.data.length - startOffset);
2036
+ }
2037
+
2038
+ const prevNode = dom.utils.createTextNode(_prevText);
2039
+ const textNode = dom.utils.createTextNode(_nextText);
1917
2040
 
1918
2041
  if (anchorNode) {
1919
2042
  const a = _getMaintainedNode(ancestor);
@@ -1933,7 +2056,7 @@ Format.prototype = {
1933
2056
  anchorNode = anchorNode.cloneNode(false);
1934
2057
  }
1935
2058
 
1936
- if (!domUtils.isZeroWith(prevNode)) {
2059
+ if (!dom.check.isZeroWidth(prevNode)) {
1937
2060
  ancestor.appendChild(prevNode);
1938
2061
  }
1939
2062
 
@@ -1941,16 +2064,16 @@ Format.prototype = {
1941
2064
  if (prevAnchorNode) anchorNode = prevAnchorNode;
1942
2065
  if (anchorNode) line = anchorNode;
1943
2066
 
1944
- newNode = child;
2067
+ newNode = /** @type {HTMLElement} */ (child);
1945
2068
  pCurrent = [];
1946
2069
  cssText = '';
1947
2070
  while (newNode !== line && newNode !== el && newNode !== null) {
1948
2071
  vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
1949
2072
  if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
1950
2073
  pCurrent.push(vNode);
1951
- cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
2074
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
1952
2075
  }
1953
- newNode = newNode.parentNode;
2076
+ newNode = newNode.parentElement;
1954
2077
  }
1955
2078
 
1956
2079
  const childNode = pCurrent.pop() || textNode;
@@ -1981,8 +2104,17 @@ Format.prototype = {
1981
2104
  // endContainer
1982
2105
  if (!endPass && child === endContainer) {
1983
2106
  anchorNode = _getMaintainedNode(child);
1984
- const afterNode = domUtils.createTextNode(endContainer.nodeType === 1 ? '' : endContainer.substringData(endOffset, endContainer.length - endOffset));
1985
- const textNode = domUtils.createTextNode(isSameNode || endContainer.nodeType === 1 ? '' : endContainer.substringData(0, endOffset));
2107
+
2108
+ let _prevText = '';
2109
+ let _nextText = '';
2110
+ if (endContainer.nodeType === 3) {
2111
+ const eText = /** @type {Text} */ (endContainer);
2112
+ _prevText = eText.substringData(endOffset, eText.length - endOffset);
2113
+ _nextText = isSameNode ? '' : eText.substringData(0, endOffset);
2114
+ }
2115
+
2116
+ const afterNode = dom.utils.createTextNode(_prevText);
2117
+ const textNode = dom.utils.createTextNode(_nextText);
1986
2118
 
1987
2119
  if (anchorNode) {
1988
2120
  anchorNode = anchorNode.cloneNode(false);
@@ -1992,8 +2124,8 @@ Format.prototype = {
1992
2124
  nNodeArray.push(newInnerNode);
1993
2125
  }
1994
2126
 
1995
- if (!domUtils.isZeroWith(afterNode)) {
1996
- newNode = child;
2127
+ if (!dom.check.isZeroWidth(afterNode)) {
2128
+ newNode = /** @type {HTMLElement} */ (child);
1997
2129
  cssText = '';
1998
2130
  pCurrent = [];
1999
2131
  const anchors = [];
@@ -2001,9 +2133,9 @@ Format.prototype = {
2001
2133
  if (newNode.nodeType === 1 && checkCss(newNode)) {
2002
2134
  if (_isMaintainedNode(newNode)) anchors.push(newNode.cloneNode(false));
2003
2135
  else pCurrent.push(newNode.cloneNode(false));
2004
- cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
2136
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
2005
2137
  }
2006
- newNode = newNode.parentNode;
2138
+ newNode = newNode.parentElement;
2007
2139
  }
2008
2140
  pCurrent = pCurrent.concat(anchors);
2009
2141
 
@@ -2025,16 +2157,16 @@ Format.prototype = {
2025
2157
  }
2026
2158
  }
2027
2159
 
2028
- newNode = child;
2160
+ newNode = /** @type {HTMLElement} */ (child);
2029
2161
  pCurrent = [];
2030
2162
  cssText = '';
2031
2163
  while (newNode !== pNode && newNode !== el && newNode !== null) {
2032
2164
  vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
2033
2165
  if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
2034
2166
  pCurrent.push(vNode);
2035
- cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
2167
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
2036
2168
  }
2037
- newNode = newNode.parentNode;
2169
+ newNode = newNode.parentElement;
2038
2170
  }
2039
2171
 
2040
2172
  const childNode = pCurrent.pop() || textNode;
@@ -2071,7 +2203,7 @@ Format.prototype = {
2071
2203
 
2072
2204
  // other
2073
2205
  if (startPass) {
2074
- if (child.nodeType === 1 && !domUtils.isBreak(child)) {
2206
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) {
2075
2207
  if (inst._isIgnoreNodeChange(child)) {
2076
2208
  pNode.appendChild(child.cloneNode(true));
2077
2209
  if (!collapsed) {
@@ -2085,21 +2217,21 @@ Format.prototype = {
2085
2217
  continue;
2086
2218
  }
2087
2219
 
2088
- newNode = child;
2220
+ newNode = /** @type {HTMLElement} */ (child);
2089
2221
  pCurrent = [];
2090
2222
  cssText = '';
2091
2223
  const anchors = [];
2092
2224
  while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
2093
2225
  vNode = endPass ? newNode.cloneNode(false) : validation(newNode);
2094
- if (newNode.nodeType === 1 && !domUtils.isBreak(child) && vNode && checkCss(newNode)) {
2226
+ if (newNode.nodeType === 1 && !dom.check.isBreak(child) && vNode && checkCss(newNode)) {
2095
2227
  if (_isMaintainedNode(newNode)) {
2096
2228
  if (!anchorNode) anchors.push(vNode);
2097
2229
  } else {
2098
2230
  pCurrent.push(vNode);
2099
2231
  }
2100
- cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
2232
+ cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
2101
2233
  }
2102
- newNode = newNode.parentNode;
2234
+ newNode = newNode.parentElement;
2103
2235
  }
2104
2236
  pCurrent = pCurrent.concat(anchors);
2105
2237
 
@@ -2111,7 +2243,7 @@ Format.prototype = {
2111
2243
  appendNode = newNode;
2112
2244
  }
2113
2245
 
2114
- if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode) && !domUtils.isZeroWith(newInnerNode)) {
2246
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode) && !dom.check.isZeroWidth(newInnerNode)) {
2115
2247
  newInnerNode = newInnerNode.cloneNode(false);
2116
2248
  pNode.appendChild(newInnerNode);
2117
2249
  nNodeArray.push(newInnerNode);
@@ -2126,7 +2258,7 @@ Format.prototype = {
2126
2258
  childNode.appendChild(newInnerNode);
2127
2259
  pNode.appendChild(childNode);
2128
2260
  nNodeArray.push(newInnerNode);
2129
- if (newInnerNode.children.length > 0) ancestor = newNode;
2261
+ if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
2130
2262
  else ancestor = newInnerNode;
2131
2263
  } else if (childNode === child) {
2132
2264
  if (!endPass) ancestor = newInnerNode;
@@ -2141,7 +2273,7 @@ Format.prototype = {
2141
2273
 
2142
2274
  if (anchorNode && child.nodeType === 3) {
2143
2275
  if (_getMaintainedNode(child)) {
2144
- const ancestorAnchorNode = domUtils.getParentElement(ancestor, (c) => {
2276
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
2145
2277
  return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
2146
2278
  });
2147
2279
  anchorNode.appendChild(ancestorAnchorNode);
@@ -2156,7 +2288,7 @@ Format.prototype = {
2156
2288
 
2157
2289
  cloneNode = child.cloneNode(false);
2158
2290
  ancestor.appendChild(cloneNode);
2159
- if (child.nodeType === 1 && !domUtils.isBreak(child)) coverNode = cloneNode;
2291
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = cloneNode;
2160
2292
 
2161
2293
  recursionFunc(child, coverNode);
2162
2294
  }
@@ -2181,7 +2313,7 @@ Format.prototype = {
2181
2313
  let textNode, textNode_s, textNode_e;
2182
2314
 
2183
2315
  if (collapsed) {
2184
- textNode = domUtils.createTextNode(unicode.zeroWidthSpace);
2316
+ textNode = dom.utils.createTextNode(unicode.zeroWidthSpace);
2185
2317
  pNode.replaceChild(textNode, removeNode);
2186
2318
  } else {
2187
2319
  const rChildren = removeNode.childNodes;
@@ -2190,7 +2322,7 @@ Format.prototype = {
2190
2322
  textNode_e = rChildren[0];
2191
2323
  pNode.insertBefore(textNode_e, removeNode);
2192
2324
  }
2193
- domUtils.removeItem(removeNode);
2325
+ dom.utils.removeItem(removeNode);
2194
2326
  }
2195
2327
 
2196
2328
  if (i === 0) {
@@ -2224,8 +2356,8 @@ Format.prototype = {
2224
2356
  // endContainer reset
2225
2357
  const endConReset = isRemoveFormat || endContainer.textContent.length === 0;
2226
2358
 
2227
- if (!domUtils.isBreak(endContainer) && endContainer.textContent.length === 0) {
2228
- domUtils.removeItem(endContainer);
2359
+ if (!dom.check.isBreak(endContainer) && endContainer.textContent.length === 0) {
2360
+ dom.utils.removeItem(endContainer);
2229
2361
  endContainer = startContainer;
2230
2362
  }
2231
2363
  endOffset = endConReset ? endContainer.textContent.length : endOffset;
@@ -2235,7 +2367,7 @@ Format.prototype = {
2235
2367
  s: 0,
2236
2368
  e: 0
2237
2369
  };
2238
- const startPath = domUtils.getNodePath(startContainer, pNode, newStartOffset);
2370
+ const startPath = dom.query.getNodePath(startContainer, pNode, newStartOffset);
2239
2371
 
2240
2372
  const mergeEndCon = !endContainer.parentNode;
2241
2373
  if (mergeEndCon) endContainer = startContainer;
@@ -2243,7 +2375,7 @@ Format.prototype = {
2243
2375
  s: 0,
2244
2376
  e: 0
2245
2377
  };
2246
- const endPath = domUtils.getNodePath(endContainer, pNode, !mergeEndCon && !endConReset ? newEndOffset : null);
2378
+ const endPath = dom.query.getNodePath(endContainer, pNode, !mergeEndCon && !endConReset ? newEndOffset : null);
2247
2379
 
2248
2380
  startOffset += newStartOffset.s;
2249
2381
  endOffset = collapsed ? startOffset : mergeEndCon ? startContainer.textContent.length : endConReset ? endOffset + newStartOffset.s : endOffset + newEndOffset.s;
@@ -2253,8 +2385,8 @@ Format.prototype = {
2253
2385
 
2254
2386
  element.parentNode.replaceChild(pNode, element);
2255
2387
 
2256
- startContainer = domUtils.getNodeFromPath(startPath, pNode);
2257
- endContainer = domUtils.getNodeFromPath(endPath, pNode);
2388
+ startContainer = dom.query.getNodeFromPath(startPath, pNode);
2389
+ endContainer = dom.query.getNodeFromPath(endPath, pNode);
2258
2390
 
2259
2391
  return {
2260
2392
  ancestor: pNode,
@@ -2266,31 +2398,31 @@ Format.prototype = {
2266
2398
  },
2267
2399
 
2268
2400
  /**
2401
+ * @private
2402
+ * @this {FormatThis}
2269
2403
  * @description wraps first line selected text.
2270
- * @param {Element} element The node of the line that contains the selected text node.
2271
- * @param {Element} newInnerNode The dom that will wrap the selected text area
2272
- * @param {Function} validation Check if the node should be stripped.
2404
+ * @param {Node} element The node of the line that contains the selected text node.
2405
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
2406
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
2273
2407
  * @param {Node} startCon The startContainer property of the selection object.
2274
2408
  * @param {number} startOff The startOffset property of the selection object.
2275
2409
  * @param {boolean} isRemoveFormat Is the remove all formats command?
2276
2410
  * @param {boolean} isRemoveNode "newInnerNode" is remove node?
2277
- * @returns {null|Node} If end container is renewed, returned renewed node
2278
- * @returns {Object} { ancestor, container, offset, endContainer }
2279
- * @private
2411
+ * @returns {NodeStyleContainerType} { ancestor, container, offset, endContainer }
2280
2412
  */
2281
2413
  _setNode_startLine(element, newInnerNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, _endContainer) {
2282
2414
  // not add tag
2283
2415
  let parentCon = startCon.parentNode;
2284
- while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !domUtils.isWysiwygFrame(parentCon.parentNode)) {
2416
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
2285
2417
  if (parentCon.nodeName === newInnerNode.nodeName) break;
2286
2418
  parentCon = parentCon.parentNode;
2287
2419
  }
2288
2420
 
2289
- if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.nextSibling && domUtils.isZeroWith(startCon.textContent.slice(0, startOff))) {
2421
+ if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.nextSibling && dom.check.isZeroWidth(startCon.textContent.slice(0, startOff))) {
2290
2422
  let sameTag = false;
2291
2423
  let s = startCon.previousSibling;
2292
2424
  while (s) {
2293
- if (!domUtils.isZeroWith(s)) {
2425
+ if (!dom.check.isZeroWidth(s)) {
2294
2426
  sameTag = false;
2295
2427
  break;
2296
2428
  }
@@ -2298,7 +2430,7 @@ Format.prototype = {
2298
2430
  }
2299
2431
 
2300
2432
  if (sameTag) {
2301
- domUtils.copyTagAttributes(parentCon, newInnerNode);
2433
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
2302
2434
 
2303
2435
  return {
2304
2436
  ancestor: element,
@@ -2325,11 +2457,11 @@ Format.prototype = {
2325
2457
  const childNodes = current.childNodes;
2326
2458
 
2327
2459
  for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
2328
- const child = childNodes[i];
2460
+ const child = /** @type {HTMLElement} */ (childNodes[i]);
2329
2461
  if (!child) continue;
2330
2462
  let coverNode = ancestor;
2331
2463
 
2332
- if (passNode && !domUtils.isBreak(child)) {
2464
+ if (passNode && !dom.check.isBreak(child)) {
2333
2465
  if (child.nodeType === 1) {
2334
2466
  if (inst._isIgnoreNodeChange(child)) {
2335
2467
  newInnerNode = newInnerNode.cloneNode(false);
@@ -2340,8 +2472,8 @@ Format.prototype = {
2340
2472
 
2341
2473
  // end container
2342
2474
  if (_endContainer && child.contains(_endContainer)) {
2343
- const endPath = domUtils.getNodePath(_endContainer, child);
2344
- _endContainer = domUtils.getNodeFromPath(endPath, cloneChild);
2475
+ const endPath = dom.query.getNodePath(_endContainer, child);
2476
+ _endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
2345
2477
  }
2346
2478
  } else {
2347
2479
  recursionFunc(child, child);
@@ -2399,7 +2531,7 @@ Format.prototype = {
2399
2531
 
2400
2532
  if (anchorNode && child.nodeType === 3) {
2401
2533
  if (_getMaintainedNode(child)) {
2402
- const ancestorAnchorNode = domUtils.getParentElement(ancestor, (c) => {
2534
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
2403
2535
  return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
2404
2536
  });
2405
2537
  anchorNode.appendChild(ancestorAnchorNode);
@@ -2416,8 +2548,17 @@ Format.prototype = {
2416
2548
  if (!passNode && child === container) {
2417
2549
  let line = pNode;
2418
2550
  anchorNode = _getMaintainedNode(child);
2419
- const prevNode = domUtils.createTextNode(container.nodeType === 1 ? '' : container.substringData(0, offset));
2420
- const textNode = domUtils.createTextNode(container.nodeType === 1 ? '' : container.substringData(offset, container.length - offset));
2551
+
2552
+ let _prevText = '';
2553
+ let _nextText = '';
2554
+ if (container.nodeType === 3) {
2555
+ const cText = /** @type {Text} */ (container);
2556
+ _prevText = cText.substringData(0, offset);
2557
+ _nextText = cText.substringData(offset, cText.length - offset);
2558
+ }
2559
+
2560
+ const prevNode = dom.utils.createTextNode(_prevText);
2561
+ const textNode = dom.utils.createTextNode(_nextText);
2421
2562
 
2422
2563
  if (anchorNode) {
2423
2564
  const a = _getMaintainedNode(ancestor);
@@ -2437,7 +2578,7 @@ Format.prototype = {
2437
2578
  anchorNode = anchorNode.cloneNode(false);
2438
2579
  }
2439
2580
 
2440
- if (!domUtils.isZeroWith(prevNode)) {
2581
+ if (!dom.check.isZeroWidth(prevNode)) {
2441
2582
  ancestor.appendChild(prevNode);
2442
2583
  }
2443
2584
 
@@ -2470,7 +2611,7 @@ Format.prototype = {
2470
2611
  ancestor = newInnerNode;
2471
2612
  }
2472
2613
 
2473
- if (domUtils.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
2614
+ if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
2474
2615
  line.appendChild(newInnerNode);
2475
2616
 
2476
2617
  container = textNode;
@@ -2484,7 +2625,7 @@ Format.prototype = {
2484
2625
  vNode = !passNode ? child.cloneNode(false) : validation(child);
2485
2626
  if (vNode) {
2486
2627
  ancestor.appendChild(vNode);
2487
- if (child.nodeType === 1 && !domUtils.isBreak(child)) coverNode = vNode;
2628
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
2488
2629
  }
2489
2630
 
2490
2631
  recursionFunc(child, coverNode);
@@ -2512,7 +2653,7 @@ Format.prototype = {
2512
2653
  while (rChildren[0]) {
2513
2654
  pNode.insertBefore(rChildren[0], removeNode);
2514
2655
  }
2515
- domUtils.removeItem(removeNode);
2656
+ dom.utils.removeItem(removeNode);
2516
2657
 
2517
2658
  if (i === 0) container = textNode;
2518
2659
  }
@@ -2527,13 +2668,13 @@ Format.prototype = {
2527
2668
  if (element.childNodes) {
2528
2669
  container = element.childNodes[0];
2529
2670
  } else {
2530
- container = domUtils.createTextNode(unicode.zeroWidthSpace);
2671
+ container = dom.utils.createTextNode(unicode.zeroWidthSpace);
2531
2672
  element.appendChild(container);
2532
2673
  }
2533
2674
  } else {
2534
2675
  this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
2535
2676
 
2536
- if (domUtils.isZeroWith(pNode.textContent)) {
2677
+ if (dom.check.isZeroWidth(pNode.textContent)) {
2537
2678
  container = pNode.firstChild;
2538
2679
  offset = 0;
2539
2680
  }
@@ -2543,7 +2684,7 @@ Format.prototype = {
2543
2684
  s: 0,
2544
2685
  e: 0
2545
2686
  };
2546
- const path = domUtils.getNodePath(container, pNode, offsets);
2687
+ const path = dom.query.getNodePath(container, pNode, offsets);
2547
2688
  offset += offsets.s;
2548
2689
 
2549
2690
  // tag merge
@@ -2551,7 +2692,7 @@ Format.prototype = {
2551
2692
 
2552
2693
  element.parentNode.replaceChild(pNode, element);
2553
2694
 
2554
- container = domUtils.getNodeFromPath(path, pNode);
2695
+ container = dom.query.getNodeFromPath(path, pNode);
2555
2696
  offset += newOffsets[0];
2556
2697
  }
2557
2698
 
@@ -2564,38 +2705,39 @@ Format.prototype = {
2564
2705
  },
2565
2706
 
2566
2707
  /**
2708
+ * @private
2709
+ * @this {FormatThis}
2567
2710
  * @description wraps mid lines selected text.
2568
- * @param {Element} element The node of the line that contains the selected text node.
2569
- * @param {Element} newInnerNode The dom that will wrap the selected text area
2570
- * @param {Function} validation Check if the node should be stripped.
2711
+ * @param {HTMLElement} element The node of the line that contains the selected text node.
2712
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
2713
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
2571
2714
  * @param {boolean} isRemoveFormat Is the remove all formats command?
2572
2715
  * @param {boolean} isRemoveNode "newInnerNode" is remove node?
2573
2716
  * @param {Node} _endContainer Offset node of last line already modified (end.container)
2574
- * @returns {Object} { ancestor, endContainer: "If end container is renewed, returned renewed node" }
2575
- * @private
2717
+ * @returns {NodeStyleContainerType} { ancestor, endContainer: "If end container is renewed, returned renewed node" }
2576
2718
  */
2577
2719
  _setNode_middleLine(element, newInnerNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, _endContainer) {
2578
2720
  // not add tag
2579
2721
  if (!isRemoveNode) {
2580
2722
  // end container path
2581
2723
  let endPath = null;
2582
- if (_endContainer && element.contains(_endContainer)) endPath = domUtils.getNodePath(_endContainer, element);
2724
+ if (_endContainer && element.contains(_endContainer)) endPath = dom.query.getNodePath(_endContainer, element);
2583
2725
 
2584
2726
  const tempNode = element.cloneNode(true);
2585
- const newNodeName = newInnerNode.nodeName;
2586
- const newCssText = newInnerNode.style.cssText;
2587
- const newClass = newInnerNode.className;
2727
+ const newNodeName = /** @type {HTMLElement} */ (newInnerNode).nodeName;
2728
+ const newCssText = /** @type {HTMLElement} */ (newInnerNode).style.cssText;
2729
+ const newClass = /** @type {HTMLElement} */ (newInnerNode).className;
2588
2730
 
2589
2731
  let children = tempNode.childNodes;
2590
2732
  let i = 0,
2591
2733
  len = children.length;
2592
2734
  for (let child; i < len; i++) {
2593
- child = children[i];
2735
+ child = /** @type {HTMLElement} */ (children[i]);
2594
2736
  if (child.nodeType === 3) break;
2595
2737
  if (child.nodeName === newNodeName) {
2596
2738
  child.style.cssText += newCssText;
2597
- domUtils.addClass(child, newClass);
2598
- } else if (!domUtils.isBreak(child) && this._isIgnoreNodeChange(child)) {
2739
+ dom.utils.addClass(child, newClass);
2740
+ } else if (!dom.check.isBreak(child) && this._isIgnoreNodeChange(child)) {
2599
2741
  continue;
2600
2742
  } else if (len === 1) {
2601
2743
  children = child.childNodes;
@@ -2608,10 +2750,10 @@ Format.prototype = {
2608
2750
  }
2609
2751
 
2610
2752
  if (len > 0 && i === len) {
2611
- element.innerHTML = tempNode.innerHTML;
2753
+ element.innerHTML = /** @type {HTMLElement} */ (tempNode).innerHTML;
2612
2754
  return {
2613
2755
  ancestor: element,
2614
- endContainer: endPath ? domUtils.getNodeFromPath(endPath, element) : null
2756
+ endContainer: endPath ? dom.query.getNodeFromPath(endPath, element) : null
2615
2757
  };
2616
2758
  }
2617
2759
  }
@@ -2628,11 +2770,11 @@ Format.prototype = {
2628
2770
  const childNodes = current.childNodes;
2629
2771
 
2630
2772
  for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
2631
- const child = childNodes[i];
2773
+ const child = /** @type {HTMLElement} */ (childNodes[i]);
2632
2774
  if (!child) continue;
2633
2775
  let coverNode = ancestor;
2634
2776
 
2635
- if (!domUtils.isBreak(child) && inst._isIgnoreNodeChange(child)) {
2777
+ if (!dom.check.isBreak(child) && inst._isIgnoreNodeChange(child)) {
2636
2778
  if (newInnerNode.childNodes.length > 0) {
2637
2779
  pNode.appendChild(newInnerNode);
2638
2780
  newInnerNode = newInnerNode.cloneNode(false);
@@ -2646,8 +2788,8 @@ Format.prototype = {
2646
2788
 
2647
2789
  // end container
2648
2790
  if (_endContainer && child.contains(_endContainer)) {
2649
- const endPath = domUtils.getNodePath(_endContainer, child);
2650
- _endContainer = domUtils.getNodeFromPath(endPath, cloneChild);
2791
+ const endPath = dom.query.getNodePath(_endContainer, child);
2792
+ _endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
2651
2793
  }
2652
2794
 
2653
2795
  continue;
@@ -2660,7 +2802,7 @@ Format.prototype = {
2660
2802
  }
2661
2803
  }
2662
2804
 
2663
- if (!domUtils.isBreak(child)) recursionFunc(child, coverNode);
2805
+ if (!dom.check.isBreak(child)) recursionFunc(child, coverNode);
2664
2806
  }
2665
2807
  })(element, newInnerNode);
2666
2808
 
@@ -2681,7 +2823,7 @@ Format.prototype = {
2681
2823
  while (rChildren[0]) {
2682
2824
  pNode.insertBefore(rChildren[0], removeNode);
2683
2825
  }
2684
- domUtils.removeItem(removeNode);
2826
+ dom.utils.removeItem(removeNode);
2685
2827
  }
2686
2828
  } else if (isRemoveNode) {
2687
2829
  newInnerNode = newInnerNode.firstChild;
@@ -2702,30 +2844,31 @@ Format.prototype = {
2702
2844
  },
2703
2845
 
2704
2846
  /**
2847
+ * @private
2848
+ * @this {FormatThis}
2705
2849
  * @description wraps last line selected text.
2706
- * @param {Element} element The node of the line that contains the selected text node.
2707
- * @param {Element} newInnerNode The dom that will wrap the selected text area
2708
- * @param {Function} validation Check if the node should be stripped.
2850
+ * @param {Node} element The node of the line that contains the selected text node.
2851
+ * @param {Node} newInnerNode The dom that will wrap the selected text area
2852
+ * @param {(current: Node) => Node|null} validation Check if the node should be stripped.
2709
2853
  * @param {Node} endCon The endContainer property of the selection object.
2710
2854
  * @param {number} endOff The endOffset property of the selection object.
2711
2855
  * @param {boolean} isRemoveFormat Is the remove all formats command?
2712
2856
  * @param {boolean} isRemoveNode "newInnerNode" is remove node?
2713
- * @returns {Object} { ancestor, container, offset }
2714
- * @private
2857
+ * @returns {NodeStyleContainerType} { ancestor, container, offset }
2715
2858
  */
2716
2859
  _setNode_endLine(element, newInnerNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
2717
2860
  // not add tag
2718
2861
  let parentCon = endCon.parentNode;
2719
- while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !domUtils.isWysiwygFrame(parentCon.parentNode)) {
2862
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
2720
2863
  if (parentCon.nodeName === newInnerNode.nodeName) break;
2721
2864
  parentCon = parentCon.parentNode;
2722
2865
  }
2723
2866
 
2724
- if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.previousSibling && domUtils.isZeroWith(endCon.textContent.slice(endOff))) {
2867
+ if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.previousSibling && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
2725
2868
  let sameTag = false;
2726
2869
  let e = endCon.nextSibling;
2727
2870
  while (e) {
2728
- if (!domUtils.isZeroWith(e)) {
2871
+ if (!dom.check.isZeroWidth(e)) {
2729
2872
  sameTag = false;
2730
2873
  break;
2731
2874
  }
@@ -2733,7 +2876,7 @@ Format.prototype = {
2733
2876
  }
2734
2877
 
2735
2878
  if (sameTag) {
2736
- domUtils.copyTagAttributes(parentCon, newInnerNode);
2879
+ dom.utils.copyTagAttributes(parentCon, newInnerNode);
2737
2880
 
2738
2881
  return {
2739
2882
  ancestor: element,
@@ -2764,7 +2907,7 @@ Format.prototype = {
2764
2907
  if (!child) continue;
2765
2908
  let coverNode = ancestor;
2766
2909
 
2767
- if (passNode && !domUtils.isBreak(child)) {
2910
+ if (passNode && !dom.check.isBreak(child)) {
2768
2911
  if (child.nodeType === 1) {
2769
2912
  if (inst._isIgnoreNodeChange(child)) {
2770
2913
  newInnerNode = newInnerNode.cloneNode(false);
@@ -2818,7 +2961,7 @@ Format.prototype = {
2818
2961
  childNode.appendChild(newInnerNode);
2819
2962
  pNode.insertBefore(childNode, pNode.firstChild);
2820
2963
  nNodeArray.push(newInnerNode);
2821
- if (newInnerNode.children.length > 0) ancestor = newNode;
2964
+ if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
2822
2965
  else ancestor = newInnerNode;
2823
2966
  } else if (isTopNode) {
2824
2967
  newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
@@ -2829,7 +2972,7 @@ Format.prototype = {
2829
2972
 
2830
2973
  if (anchorNode && child.nodeType === 3) {
2831
2974
  if (_getMaintainedNode(child)) {
2832
- const ancestorAnchorNode = domUtils.getParentElement(ancestor, (c) => {
2975
+ const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
2833
2976
  return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
2834
2977
  });
2835
2978
  anchorNode.appendChild(ancestorAnchorNode);
@@ -2845,8 +2988,17 @@ Format.prototype = {
2845
2988
  // endContainer
2846
2989
  if (!passNode && child === container) {
2847
2990
  anchorNode = _getMaintainedNode(child);
2848
- const afterNode = domUtils.createTextNode(container.nodeType === 1 ? '' : container.substringData(offset, container.length - offset));
2849
- const textNode = domUtils.createTextNode(container.nodeType === 1 ? '' : container.substringData(0, offset));
2991
+
2992
+ let _prevText = '';
2993
+ let _nextText = '';
2994
+ if (container.nodeType === 3) {
2995
+ const cText = /** @type {Text} */ (container);
2996
+ _prevText = cText.substringData(offset, cText.length - offset);
2997
+ _nextText = cText.substringData(0, offset);
2998
+ }
2999
+
3000
+ const afterNode = dom.utils.createTextNode(_prevText);
3001
+ const textNode = dom.utils.createTextNode(_nextText);
2850
3002
 
2851
3003
  if (anchorNode) {
2852
3004
  anchorNode = anchorNode.cloneNode(false);
@@ -2871,7 +3023,7 @@ Format.prototype = {
2871
3023
  nNodeArray.push(newInnerNode);
2872
3024
  }
2873
3025
 
2874
- if (!domUtils.isZeroWith(afterNode)) {
3026
+ if (!dom.check.isZeroWidth(afterNode)) {
2875
3027
  ancestor.insertBefore(afterNode, ancestor.firstChild);
2876
3028
  }
2877
3029
 
@@ -2900,7 +3052,7 @@ Format.prototype = {
2900
3052
  ancestor = newInnerNode;
2901
3053
  }
2902
3054
 
2903
- if (domUtils.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
3055
+ if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
2904
3056
 
2905
3057
  if (anchorNode) {
2906
3058
  anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
@@ -2921,7 +3073,7 @@ Format.prototype = {
2921
3073
  vNode = !passNode ? child.cloneNode(false) : validation(child);
2922
3074
  if (vNode) {
2923
3075
  ancestor.insertBefore(vNode, ancestor.firstChild);
2924
- if (child.nodeType === 1 && !domUtils.isBreak(child)) coverNode = vNode;
3076
+ if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
2925
3077
  }
2926
3078
 
2927
3079
  recursionFunc(child, coverNode);
@@ -2949,7 +3101,7 @@ Format.prototype = {
2949
3101
  textNode = rChildren[0];
2950
3102
  pNode.insertBefore(textNode, removeNode);
2951
3103
  }
2952
- domUtils.removeItem(removeNode);
3104
+ dom.utils.removeItem(removeNode);
2953
3105
 
2954
3106
  if (i === nNodeArray.length - 1) {
2955
3107
  container = textNode;
@@ -2967,7 +3119,7 @@ Format.prototype = {
2967
3119
  if (element.childNodes) {
2968
3120
  container = element.childNodes[0];
2969
3121
  } else {
2970
- container = domUtils.createTextNode(unicode.zeroWidthSpace);
3122
+ container = dom.utils.createTextNode(unicode.zeroWidthSpace);
2971
3123
  element.appendChild(container);
2972
3124
  }
2973
3125
  } else {
@@ -2982,10 +3134,10 @@ Format.prototype = {
2982
3134
 
2983
3135
  this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
2984
3136
 
2985
- if (domUtils.isZeroWith(pNode.textContent)) {
3137
+ if (dom.check.isZeroWidth(pNode.textContent)) {
2986
3138
  container = pNode.firstChild;
2987
3139
  offset = container.textContent.length;
2988
- } else if (domUtils.isZeroWith(container)) {
3140
+ } else if (dom.check.isZeroWidth(container)) {
2989
3141
  container = newInnerNode;
2990
3142
  offset = 1;
2991
3143
  }
@@ -2995,7 +3147,7 @@ Format.prototype = {
2995
3147
  s: 0,
2996
3148
  e: 0
2997
3149
  };
2998
- const path = domUtils.getNodePath(container, pNode, offsets);
3150
+ const path = dom.query.getNodePath(container, pNode, offsets);
2999
3151
  offset += offsets.s;
3000
3152
 
3001
3153
  // tag merge
@@ -3003,7 +3155,7 @@ Format.prototype = {
3003
3155
 
3004
3156
  element.parentNode.replaceChild(pNode, element);
3005
3157
 
3006
- container = domUtils.getNodeFromPath(path, pNode);
3158
+ container = dom.query.getNodeFromPath(path, pNode);
3007
3159
  offset += newOffsets[0];
3008
3160
  }
3009
3161
 
@@ -3015,57 +3167,59 @@ Format.prototype = {
3015
3167
  },
3016
3168
 
3017
3169
  /**
3170
+ * @private
3171
+ * @this {FormatThis}
3018
3172
  * @description Node with font-size style
3019
3173
  * @param {Node} element Element to check
3020
3174
  * @returns {boolean}
3021
- * @private
3022
3175
  */
3023
3176
  _sn_isSizeNode(element) {
3024
- return element && typeof element !== 'string' && element.nodeType !== 3 && this.isTextStyleNode(element) && element.style.fontSize;
3177
+ return element && typeof element !== 'string' && element.nodeType !== 3 && this.isTextStyleNode(element) && !!element.style.fontSize;
3025
3178
  },
3026
3179
 
3027
3180
  /**
3028
- * @description Return the parent maintained tag. (bind and use a util object)
3029
- * @param {Element} element Element
3030
- * @returns {Element}
3031
3181
  * @private
3182
+ * @this {FormatThis}
3183
+ * @description Return the parent maintained tag. (bind and use a util object)
3184
+ * @param {boolean} _isRemove is remove anchor
3185
+ * @param {boolean} _isSizeNode is size span node
3186
+ * @param {Node} element Element
3187
+ * @returns {Node|null}
3032
3188
  */
3033
3189
  _sn_getMaintainedNode(_isRemove, _isSizeNode, element) {
3034
3190
  if (!element || _isRemove) return null;
3035
- return domUtils.getParentElement(element, this._isNonSplitNode) || (!_isSizeNode ? domUtils.getParentElement(element, this._sn_isSizeNode.bind(this)) : null);
3191
+ return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) || (!_isSizeNode ? dom.query.getParentElement(element, this._sn_isSizeNode.bind(this)) : null);
3036
3192
  },
3037
3193
 
3038
3194
  /**
3039
- * @description Check if element is a tag that should be persisted. (bind and use a util object)
3040
- * @param {Element} element Element
3041
- * @returns {Element}
3042
3195
  * @private
3196
+ * @this {FormatThis}
3197
+ * @description Check if element is a tag that should be persisted. (bind and use a util object)
3198
+ * @param {boolean} _isRemove is remove anchor
3199
+ * @param {boolean} _isSizeNode is size span node
3200
+ * @param {Node} element Element
3201
+ * @returns {boolean}
3043
3202
  */
3044
3203
  _sn_isMaintainedNode(_isRemove, _isSizeNode, element) {
3045
3204
  if (!element || _isRemove || element.nodeType !== 1) return false;
3046
3205
  const anchor = this._isNonSplitNode(element);
3047
- return domUtils.getParentElement(element, this._isNonSplitNode) ? anchor : anchor || (!_isSizeNode ? this._sn_isSizeNode(element) : false);
3206
+ return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) ? anchor : anchor || (!_isSizeNode ? this._sn_isSizeNode(element) : false);
3048
3207
  },
3049
3208
 
3050
3209
  /**
3051
- * @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)
3052
- * @param {Element} el List cell element. <li>
3053
- * @param {Element|null} child Variable for recursive call. ("null" on the first call)
3054
3210
  * @private
3211
+ * @this {FormatThis}
3212
+ * @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)
3213
+ * @param {Node} el List cell element. <li>
3214
+ * @param {?Node} child Variable for recursive call. ("null" on the first call)
3055
3215
  */
3056
3216
  _sn_setCommonListStyle(el, child) {
3057
- if (!domUtils.isListCell(el)) return;
3058
-
3059
- const children = domUtils.getArrayItem(
3060
- (child || el).childNodes,
3061
- function (current) {
3062
- return !domUtils.isBreak(current);
3063
- },
3064
- true
3065
- );
3217
+ if (!dom.check.isListCell(el)) return;
3218
+
3219
+ const children = dom.utils.arrayFilter((child || el).childNodes, (current) => !dom.check.isBreak(current));
3066
3220
  child = children[0];
3067
3221
 
3068
- if (!child || children.length > 1 || child.nodeType !== 1) return;
3222
+ if (!dom.check.isElement(child) || children.length > 1) return;
3069
3223
 
3070
3224
  // set cell style---
3071
3225
  const childStyle = child.style;
@@ -3100,27 +3254,22 @@ Format.prototype = {
3100
3254
  while (ch.length > 0) {
3101
3255
  p.insertBefore(ch[0], n);
3102
3256
  }
3103
- domUtils.removeItem(child);
3257
+ dom.utils.removeItem(child);
3104
3258
  }
3105
3259
  },
3106
3260
 
3107
3261
  /**
3262
+ * @private
3263
+ * @this {FormatThis}
3108
3264
  * @description Watch the applied text nodes and adjust the common styles of the list.
3109
- * @param {Element} el "LI" element
3265
+ * @param {Node} el "LI" element
3110
3266
  * @param {Array|null} styleArray Refer style array
3111
- * @private
3112
3267
  */
3113
3268
  _sn_resetCommonListCell(el, styleArray) {
3114
- if (!domUtils.isListCell(el)) return;
3269
+ if (!dom.check.isListCell(el)) return;
3115
3270
  if (!styleArray) styleArray = this._listKebab;
3116
3271
 
3117
- const children = domUtils.getArrayItem(
3118
- el.childNodes,
3119
- function (current) {
3120
- return !domUtils.isBreak(current);
3121
- },
3122
- true
3123
- );
3272
+ const children = dom.utils.arrayFilter(el.childNodes, (current) => !dom.check.isBreak(current));
3124
3273
  const elStyles = el.style;
3125
3274
 
3126
3275
  const ec = [],
@@ -3136,7 +3285,7 @@ Format.prototype = {
3136
3285
  if (!ec.length) return;
3137
3286
 
3138
3287
  // reset cell style---
3139
- const refer = domUtils.createElement('SPAN');
3288
+ const refer = dom.utils.createElement('SPAN');
3140
3289
  for (let i = 0, len = ec.length; i < len; i++) {
3141
3290
  refer.style[ec[i]] = elStyles[ek[i]];
3142
3291
  elStyles.removeProperty(ek[i]);
@@ -3146,7 +3295,7 @@ Format.prototype = {
3146
3295
  let r = null,
3147
3296
  appliedEl = false;
3148
3297
  for (let i = 0, len = children.length, c, s; i < len; i++) {
3149
- c = children[i];
3298
+ c = /** @type {HTMLElement} */ (children[i]);
3150
3299
  if (this.options.get('_defaultStyleTagMap')[c.nodeName.toLowerCase()]) continue;
3151
3300
 
3152
3301
  s = env.getValues(c.style);
@@ -3183,48 +3332,60 @@ Format.prototype = {
3183
3332
  constructor: Format
3184
3333
  };
3185
3334
 
3335
+ /**
3336
+ * @private
3337
+ * @param {Node} baseNode Node
3338
+ */
3186
3339
  function DeleteNestedList(baseNode) {
3187
3340
  const baseParent = baseNode.parentNode;
3188
- let sibling = baseParent;
3189
- let parent = sibling.parentNode;
3341
+ let parent = baseParent.parentNode;
3342
+ let siblingNode = /** @type {*} */ (baseParent);
3190
3343
  let liSibling, liParent, child, index, c;
3191
3344
 
3192
- while (domUtils.isListCell(parent)) {
3193
- index = domUtils.getPositionIndex(baseNode);
3345
+ while (dom.check.isListCell(parent)) {
3346
+ index = dom.query.getPositionIndex(baseNode);
3194
3347
  liSibling = parent.nextElementSibling;
3195
3348
  liParent = parent.parentNode;
3196
- child = sibling;
3349
+ child = siblingNode;
3350
+
3197
3351
  while (child) {
3198
- sibling = sibling.nextSibling;
3199
- if (domUtils.isList(child)) {
3352
+ siblingNode = siblingNode.nextSibling;
3353
+ if (dom.check.isList(child)) {
3200
3354
  c = child.childNodes;
3201
3355
  while (c[index]) {
3202
3356
  liParent.insertBefore(c[index], liSibling);
3203
3357
  }
3204
- if (c.length === 0) domUtils.removeItem(child);
3358
+ if (c.length === 0) dom.utils.removeItem(child);
3205
3359
  } else {
3206
3360
  liParent.appendChild(child);
3207
3361
  }
3208
- child = sibling;
3362
+ child = siblingNode;
3209
3363
  }
3210
- sibling = liParent;
3364
+
3211
3365
  parent = liParent.parentNode;
3212
3366
  }
3213
3367
 
3214
- if (baseParent.children.length === 0) domUtils.removeItem(baseParent);
3368
+ if (baseParent.children.length === 0) dom.utils.removeItem(baseParent);
3215
3369
 
3216
3370
  return liParent;
3217
3371
  }
3218
3372
 
3373
+ /**
3374
+ * @private
3375
+ * @param {Array<HTMLElement>} lines - Line elements
3376
+ * @param {number} size - Margin size
3377
+ * @param {string} dir - Direction
3378
+ * @returns
3379
+ */
3219
3380
  function SetLineMargin(lines, size, dir) {
3220
3381
  const cells = [];
3221
3382
 
3222
3383
  for (let i = 0, len = lines.length, f, margin; i < len; i++) {
3223
3384
  f = lines[i];
3224
- if (!domUtils.isListCell(f)) {
3385
+ if (!dom.check.isListCell(f)) {
3225
3386
  margin = /\d+/.test(f.style[dir]) ? numbers.get(f.style[dir], 0) : 0;
3226
3387
  margin += size;
3227
- domUtils.setStyle(f, dir, margin <= 0 ? '' : margin + 'px');
3388
+ dom.utils.setStyle(f, dir, margin <= 0 ? '' : margin + 'px');
3228
3389
  } else {
3229
3390
  if (size < 0 || f.previousElementSibling) {
3230
3391
  cells.push(f);
@@ -3236,6 +3397,7 @@ function SetLineMargin(lines, size, dir) {
3236
3397
  }
3237
3398
 
3238
3399
  /**
3400
+ * @private
3239
3401
  * @description Strip remove node
3240
3402
  * @param {Node} removeNode The remove node
3241
3403
  * @private