suneditor 3.0.0-alpha.9 → 3.0.0-beta.2

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