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
@@ -1,21 +1,97 @@
1
- import { domUtils, env, unicode } from '../../../helper';
1
+ import { dom, env, unicode, keyCodeMap } from '../../../helper';
2
2
 
3
3
  const { _w, isOSX_IOS } = env;
4
- const DIRECTION_KEYCODE = /^(8|3[2-9]|40|46)$/;
5
- const DIR_KEYCODE = /^(3[7-9]|40)$/;
6
- const DELETE_KEYCODE = /^(8|46)$/;
7
- const NON_TEXT_KEYCODE = /^(8|13|1[6-9]|20|27|3[3-9]|40|45|46|11[2-9]|12[0-3]|144|145|229)$/;
8
- const HISTORY_IGNORE_KEYCODE = /^(1[6-9]|20|27|3[3-9]|40|45|11[2-9]|12[0-3]|144|145|229)$/;
9
4
  const FRONT_ZEROWIDTH = new RegExp(unicode.zeroWidthSpace + '+', '');
5
+
6
+ const keyState = {
7
+ ctrl: false,
8
+ alt: false
9
+ };
10
10
  let _styleNodes = null;
11
11
 
12
- export function OnInput_wysiwyg(frameContext, e) {
13
- if (frameContext.get('isReadOnly') || frameContext.get('isDisabled')) {
12
+ /**
13
+ * @typedef {Omit<import('../eventManager').default & Partial<__se__EditorInjector>, 'eventManager'>} EventManagerThis_handler_ww_key_input
14
+ */
15
+
16
+ /**
17
+ * @private
18
+ * @param {HTMLElement} formatEl - Format element
19
+ * @returns {Node}
20
+ */
21
+ function LineDelete_next(formatEl) {
22
+ const focusNode = formatEl.lastChild;
23
+ const next = formatEl.nextElementSibling;
24
+
25
+ if (!next) return focusNode;
26
+
27
+ if (dom.check.isZeroWidth(next)) {
28
+ dom.utils.removeItem(next);
29
+ return focusNode;
30
+ }
31
+
32
+ const nextChild = next.childNodes;
33
+ while (nextChild[0]) {
34
+ formatEl.appendChild(nextChild[0]);
35
+ }
36
+
37
+ dom.utils.removeItem(next);
38
+
39
+ return focusNode;
40
+ }
41
+
42
+ /**
43
+ * @private
44
+ * @param {HTMLElement} formatEl - Format element
45
+ * @returns {{focusNode: Node, focusOffset: number}}
46
+ */
47
+ function LineDelete_prev(formatEl) {
48
+ const formatChild = formatEl.childNodes;
49
+ const prev = formatEl.previousElementSibling;
50
+ let focusNode = formatChild[0];
51
+ let focusOffset = 0;
52
+
53
+ if (!prev) return { focusNode, focusOffset };
54
+
55
+ if (dom.check.isZeroWidth(prev)) {
56
+ dom.utils.removeItem(prev);
57
+ return { focusNode, focusOffset };
58
+ }
59
+
60
+ if (formatChild.length > 1 || formatChild[0]?.textContent.length > 0) {
61
+ while (formatChild[0]) {
62
+ prev.appendChild(formatChild[0]);
63
+ }
64
+ } else {
65
+ focusNode = prev.lastChild;
66
+ focusOffset = focusNode.textContent.length;
67
+ }
68
+
69
+ dom.utils.removeItem(formatEl);
70
+
71
+ return { focusNode, focusOffset };
72
+ }
73
+
74
+ /**
75
+ * @private
76
+ * @this {EventManagerThis_handler_ww_key_input}
77
+ * @param {__se__FrameContext} fc - Frame context object
78
+ * @param {InputEvent} e - Event object
79
+ */
80
+ export async function OnInput_wysiwyg(fc, e) {
81
+ if (fc.get('isReadOnly') || fc.get('isDisabled')) {
14
82
  e.preventDefault();
15
83
  e.stopPropagation();
16
84
  return false;
17
85
  }
18
86
 
87
+ const range = this.selection.getRange();
88
+ const selectionNode = this.selection.getNode();
89
+ const formatEl = this.format.getLine(selectionNode, null);
90
+ if (!formatEl && range.collapsed && !this.component.is(selectionNode) && !dom.check.isList(selectionNode)) {
91
+ const rangeEl = this.format.getBlock(selectionNode, null);
92
+ this._setDefaultLine(this.format.isBlock(rangeEl) ? 'DIV' : this.options.get('defaultLine'));
93
+ }
94
+
19
95
  this.selection._init();
20
96
 
21
97
  const data = (e.data === null ? '' : e.data === undefined ? ' ' : e.data) || '';
@@ -26,27 +102,33 @@ export function OnInput_wysiwyg(frameContext, e) {
26
102
  }
27
103
 
28
104
  // user event
29
- if (this.triggerEvent('onInput', { frameContext, event: e, data }) === false) return;
105
+ if ((await this.triggerEvent('onInput', { frameContext: fc, event: e, data })) === false) return;
30
106
  // plugin event
31
- if (this._callPluginEvent('onInput', { frameContext, event: e, data }) === false) return;
107
+ if (this._callPluginEvent('onInput', { frameContext: fc, event: e, data }) === false) return;
32
108
 
33
109
  this.history.push(true);
34
110
  }
35
111
 
36
- export function OnKeyDown_wysiwyg(frameContext, e) {
112
+ /**
113
+ * @private
114
+ * @this {EventManagerThis_handler_ww_key_input}
115
+ * @param {__se__FrameContext} fc - Frame context object
116
+ * @param {KeyboardEvent} e - Event object
117
+ */
118
+ export async function OnKeyDown_wysiwyg(fc, e) {
37
119
  if (this.editor.selectMenuOn || !e.isTrusted) return;
38
120
 
39
121
  let selectionNode = this.selection.getNode();
40
- if (domUtils.isInputElement(selectionNode)) return;
122
+ if (dom.check.isInputElement(selectionNode)) return;
41
123
  if (this.menu.currentDropdownName) return;
42
124
 
43
- const keyCode = e.keyCode;
44
- const shift = e.shiftKey;
45
- const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
46
- const alt = e.altKey;
47
- this.isComposing = keyCode === 229;
125
+ const keyCode = e.code;
126
+ const shift = keyCodeMap.isShift(e);
127
+ const ctrl = (keyState.ctrl = keyCodeMap.isCtrl(e));
128
+ const alt = (keyState.alt = keyCodeMap.isAlt(e));
129
+ this.isComposing = keyCodeMap.isComposing(e);
48
130
 
49
- if (!ctrl && frameContext.get('isReadOnly') && !DIRECTION_KEYCODE.test(keyCode)) {
131
+ if (!ctrl && fc.get('isReadOnly') && !keyCodeMap.isDirectionKey(keyCode)) {
50
132
  e.preventDefault();
51
133
  return false;
52
134
  }
@@ -60,29 +142,42 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
60
142
  }
61
143
 
62
144
  // user event
63
- if (this.triggerEvent('onKeyDown', { frameContext, event: e }) === false) return;
145
+ if ((await this.triggerEvent('onKeyDown', { frameContext: fc, event: e })) === false) return;
146
+
147
+ /** default key action */
148
+ if (keyCodeMap.isEnter(keyCode) && this.format.isLine(this.selection.getRange()?.startContainer)) {
149
+ this.selection._resetRangeToTextNode();
150
+ selectionNode = this.selection.getNode();
151
+ }
152
+
153
+ const range = this.selection.getRange();
154
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
155
+ let formatEl = /** @type {HTMLElement} */ (this.format.getLine(selectionNode, null) || selectionNode);
156
+ let rangeEl = this.format.getBlock(formatEl, null);
64
157
 
65
158
  /** Shortcuts */
66
- if (ctrl && this.shortcuts.command(keyCode, shift)) {
159
+ if (ctrl && !keyCodeMap.isNonTextKey(keyCode) && this.shortcuts.command(e, ctrl, shift, keyCode, '', false, null, null)) {
67
160
  this._onShortcutKey = true;
68
161
  e.preventDefault();
69
162
  e.stopPropagation();
70
163
  return false;
164
+ } else if (!ctrl && !keyCodeMap.isNonTextKey(keyCode) && this.format.isLine(formatEl) && range.collapsed && dom.check.isEdgePoint(range.startContainer, 0, 'front')) {
165
+ const keyword = /** @type {Text} */ (range.startContainer).substringData?.(0, range.startOffset);
166
+ if (keyword && this.shortcuts.command(e, false, shift, keyCode, keyword, true, formatEl, range)) {
167
+ this._onShortcutKey = true;
168
+ e.preventDefault();
169
+ e.stopPropagation();
170
+ return false;
171
+ }
71
172
  } else if (this._onShortcutKey) {
72
173
  this._onShortcutKey = false;
73
174
  }
74
175
 
75
- /** default key action */
76
- const range = this.selection.getRange();
77
- const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
78
- let formatEl = this.format.getLine(selectionNode, null) || selectionNode;
79
- let rangeEl = this.format.getBlock(formatEl, null);
80
-
81
176
  // plugin event
82
- if (this._callPluginEvent('onKeyDown', { frameContext, event: e, range, line: formatEl }) === false) return;
177
+ if (this._callPluginEvent('onKeyDown', { frameContext: fc, event: e, range, line: formatEl }) === false) return;
83
178
 
84
179
  switch (keyCode) {
85
- case 8 /** backspace key */: {
180
+ case 'Backspace' /** backspace key */: {
86
181
  this.component.deselect();
87
182
  _styleNodes = this.__cacheStyleNodes;
88
183
  if (selectRange && this._hardDelete()) {
@@ -91,18 +186,46 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
91
186
  break;
92
187
  }
93
188
 
94
- if (!this.format.isLine(formatEl) && !frameContext.get('wysiwyg').firstElementChild && !this.component.is(selectionNode) && this._setDefaultLine(this.options.get('defaultLine')) !== null) {
189
+ if (!this.format.isLine(formatEl) && !fc.get('wysiwyg').firstElementChild && !this.component.is(selectionNode) && this._setDefaultLine(this.options.get('defaultLine')) !== null) {
95
190
  e.preventDefault();
96
191
  e.stopPropagation();
97
192
  return false;
98
193
  }
99
194
 
195
+ // line delete
196
+ if (this.format.isLine(formatEl) && (!range.collapsed || dom.check.isEdgePoint(range.endContainer, range.endOffset, 'front')) && !range.endContainer.previousSibling && this.format.isLine(formatEl.previousElementSibling)) {
197
+ e.preventDefault();
198
+ e.stopPropagation();
199
+
200
+ let focusNode;
201
+ if (!range.collapsed) {
202
+ const rInfo = this.html.remove();
203
+ if (rInfo.commonCon !== rInfo.container && formatEl.parentElement) {
204
+ if (formatEl.contains(range.startContainer)) {
205
+ focusNode = LineDelete_next(formatEl);
206
+ this.selection.setRange(focusNode, focusNode.textContent.length, focusNode, focusNode.textContent.length);
207
+ } else {
208
+ const prevInfo = LineDelete_prev(formatEl);
209
+ this.selection.setRange(prevInfo.focusNode, prevInfo.focusOffset, prevInfo.focusNode, prevInfo.focusOffset);
210
+ }
211
+ }
212
+ this.history.push(true);
213
+ return;
214
+ }
215
+
216
+ const prevInfo = LineDelete_prev(formatEl);
217
+ this.selection.setRange(prevInfo.focusNode, prevInfo.focusOffset, prevInfo.focusNode, prevInfo.focusOffset);
218
+ this.history.push(true);
219
+
220
+ return;
221
+ }
222
+
100
223
  if (
101
224
  !selectRange &&
102
225
  !formatEl.previousElementSibling &&
103
226
  range.startOffset === 0 &&
104
227
  !selectionNode.previousSibling &&
105
- !domUtils.isListCell(formatEl) &&
228
+ !dom.check.isListCell(formatEl) &&
106
229
  this.format.isLine(formatEl) &&
107
230
  (!this.format.isBrLine(formatEl) || this.format.isClosureBrLine(formatEl))
108
231
  ) {
@@ -113,7 +236,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
113
236
  return false;
114
237
  }
115
238
  // maintain default format
116
- if (domUtils.isWysiwygFrame(formatEl.parentNode) && formatEl.childNodes.length <= 1 && (!formatEl.firstChild || domUtils.isZeroWith(formatEl.textContent))) {
239
+ if (dom.check.isWysiwygFrame(formatEl.parentNode) && formatEl.childNodes.length <= 1 && (!formatEl.firstChild || dom.check.isZeroWidth(formatEl.textContent))) {
117
240
  e.preventDefault();
118
241
  e.stopPropagation();
119
242
 
@@ -124,7 +247,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
124
247
  formatEl.removeAttribute(attrs[0].name);
125
248
  }
126
249
  } else {
127
- formatEl.parentElement.replaceChild(domUtils.createElement(this.options.get('defaultLine'), null, '<br>'), formatEl);
250
+ formatEl.parentNode.replaceChild(dom.utils.createElement(this.options.get('defaultLine'), null, '<br>'), formatEl);
128
251
  }
129
252
 
130
253
  this.editor._nativeFocus();
@@ -134,12 +257,12 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
134
257
 
135
258
  // clean remove tag
136
259
  const startCon = range.startContainer;
137
- if (formatEl && !formatEl.previousElementSibling && range.startOffset === 0 && startCon.nodeType === 3 && domUtils.isZeroWith(startCon)) {
260
+ if (formatEl && !formatEl.previousElementSibling && range.startOffset === 0 && startCon.nodeType === 3 && dom.check.isZeroWidth(startCon)) {
138
261
  let prev = startCon.parentNode.previousSibling;
139
262
  const next = startCon.parentNode.nextSibling;
140
263
  if (!prev) {
141
264
  if (!next) {
142
- prev = domUtils.createElement('BR');
265
+ prev = dom.utils.createElement('BR');
143
266
  formatEl.appendChild(prev);
144
267
  } else {
145
268
  prev = next;
@@ -160,13 +283,13 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
160
283
 
161
284
  // line component
162
285
  if (!selectRange && formatEl && (range.startOffset === 0 || selectionNode === formatEl)) {
163
- const sel = selectionNode === formatEl ? this._isUneditableNode(range, true) : domUtils.isEdgePoint(range.startContainer, range.startOffset) ? domUtils.getPreviousDeepestNode(range.startContainer) : null;
286
+ const sel = selectionNode === formatEl ? this._isUneditableNode(range, true) : dom.check.isEdgePoint(range.startContainer, range.startOffset) ? dom.query.getPreviousDeepestNode(range.startContainer) : null;
164
287
  if (this.component.is(sel)) {
165
288
  const fileComponentInfo = this.component.get(sel);
166
289
  if (fileComponentInfo) {
167
290
  e.preventDefault();
168
291
  e.stopPropagation();
169
- if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName, false) === false) this.editor.blur();
292
+ if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName) === false) this.editor.blur();
170
293
  break;
171
294
  }
172
295
  }
@@ -180,7 +303,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
180
303
  }
181
304
 
182
305
  // format attributes
183
- if (!selectRange && this.format.isEdgeLine(range.startContainer, range.startOffset, 'start')) {
306
+ if (!selectRange && this.format.isEdgeLine(range.startContainer, range.startOffset, 'front')) {
184
307
  if (this.format.isLine(formatEl.previousElementSibling)) {
185
308
  this._formatAttrsTemp = formatEl.previousElementSibling.attributes;
186
309
  }
@@ -190,12 +313,12 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
190
313
  const commonCon = range.commonAncestorContainer;
191
314
  formatEl = this.format.getLine(range.startContainer, null);
192
315
  rangeEl = this.format.getBlock(formatEl, null);
193
- if (rangeEl && formatEl && !domUtils.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
316
+ if (rangeEl && formatEl && !dom.check.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
194
317
  if (
195
- domUtils.isListCell(formatEl) &&
196
- domUtils.isList(rangeEl) &&
197
- (domUtils.isListCell(rangeEl.parentNode) || formatEl.previousElementSibling) &&
198
- (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.previousSibling || domUtils.isList(selectionNode.previousSibling)))) &&
318
+ dom.check.isListCell(formatEl) &&
319
+ dom.check.isList(rangeEl) &&
320
+ (dom.check.isListCell(rangeEl.parentElement) || formatEl.previousElementSibling) &&
321
+ (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.previousSibling || dom.check.isList(selectionNode.previousSibling)))) &&
199
322
  (this.format.getLine(range.startContainer, null) !== this.format.getLine(range.endContainer, null) ? rangeEl.contains(range.startContainer) : range.startOffset === 0 && range.collapsed)
200
323
  ) {
201
324
  if (range.startContainer !== range.endContainer) {
@@ -208,22 +331,22 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
208
331
 
209
332
  this.history.push(true);
210
333
  } else {
211
- let prev = formatEl.previousElementSibling || rangeEl.parentNode;
212
- if (domUtils.isListCell(prev)) {
334
+ let prev = formatEl.previousElementSibling || rangeEl.parentElement;
335
+ if (dom.check.isListCell(prev)) {
213
336
  e.preventDefault();
214
337
 
215
338
  let prevLast = prev;
216
- if (!prev.contains(formatEl) && domUtils.isListCell(prevLast) && domUtils.isList(prevLast.lastElementChild)) {
217
- prevLast = prevLast.lastElementChild.lastElementChild;
218
- while (domUtils.isListCell(prevLast) && domUtils.isList(prevLast.lastElementChild)) {
219
- prevLast = prevLast.lastElementChild && prevLast.lastElementChild.lastElementChild;
339
+ if (!prev.contains(formatEl) && dom.check.isListCell(prevLast) && dom.check.isList(prevLast.lastElementChild)) {
340
+ prevLast = /** @type {HTMLLIElement} */ (prevLast.lastElementChild.lastElementChild);
341
+ while (dom.check.isListCell(prevLast) && dom.check.isList(prevLast.lastElementChild)) {
342
+ prevLast = /** @type {HTMLLIElement} */ (prevLast.lastElementChild && prevLast.lastElementChild.lastElementChild);
220
343
  }
221
344
  prev = prevLast;
222
345
  }
223
346
 
224
347
  let con = prev === rangeEl.parentNode ? rangeEl.previousSibling : prev.lastChild;
225
348
  if (!con) {
226
- con = domUtils.createTextNode(unicode.zeroWidthSpace);
349
+ con = dom.utils.createTextNode(unicode.zeroWidthSpace);
227
350
  rangeEl.parentNode.insertBefore(con, rangeEl.parentNode.firstChild);
228
351
  }
229
352
  const offset = con.nodeType === 3 ? con.textContent.length : 1;
@@ -235,8 +358,8 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
235
358
  after = child;
236
359
  }
237
360
 
238
- domUtils.removeItem(formatEl);
239
- if (rangeEl.children.length === 0) domUtils.removeItem(rangeEl);
361
+ dom.utils.removeItem(formatEl);
362
+ if (rangeEl.children.length === 0) dom.utils.removeItem(rangeEl);
240
363
 
241
364
  this.selection.setRange(con, offset, con, offset);
242
365
  this.history.push(true);
@@ -250,9 +373,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
250
373
  if (!selectRange && range.startOffset === 0) {
251
374
  let detach = true;
252
375
  let comm = commonCon;
253
- while (comm && comm !== rangeEl && !domUtils.isWysiwygFrame(comm)) {
376
+ while (comm && comm !== rangeEl && !dom.check.isWysiwygFrame(comm)) {
254
377
  if (comm.previousSibling) {
255
- if (comm.previousSibling.nodeType === 1 || !domUtils.isZeroWith(comm.previousSibling.textContent.trim())) {
378
+ if (comm.previousSibling.nodeType === 1 || !dom.check.isZeroWidth(comm.previousSibling.textContent.trim())) {
256
379
  detach = false;
257
380
  break;
258
381
  }
@@ -262,7 +385,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
262
385
 
263
386
  if (detach && rangeEl.parentNode) {
264
387
  e.preventDefault();
265
- this.format.removeBlock(rangeEl, domUtils.isListCell(formatEl) ? [formatEl] : null, null, false, false);
388
+ this.format.removeBlock(rangeEl, { selectedFormats: dom.check.isListCell(formatEl) ? [formatEl] : null, newBlockElement: null, shouldDelete: false, skipHistory: false });
266
389
  this.history.push(true);
267
390
  break;
268
391
  }
@@ -274,33 +397,33 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
274
397
  const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode;
275
398
  const prev = formatEl.previousSibling;
276
399
  // select file component
277
- const ignoreZWS = (commonCon.nodeType === 3 || domUtils.isBreak(commonCon)) && !commonCon.previousSibling && range.startOffset === 0;
400
+ const ignoreZWS = (commonCon.nodeType === 3 || dom.check.isBreak(commonCon)) && !commonCon.previousSibling && range.startOffset === 0;
278
401
  if (sel && !sel.previousSibling && ((commonCon && this.component.is(commonCon.previousSibling)) || (ignoreZWS && this.component.is(prev)))) {
279
402
  const fileComponentInfo = this.component.get(prev);
280
403
  if (fileComponentInfo) {
281
404
  e.preventDefault();
282
405
  e.stopPropagation();
283
- if (formatEl.textContent.length === 0) domUtils.removeItem(formatEl);
284
- if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName, false) === false) this.editor.blur();
406
+ if (formatEl.textContent.length === 0) dom.utils.removeItem(formatEl);
407
+ if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName) === false) this.editor.blur();
285
408
  } else if (this.component.is(prev)) {
286
409
  e.preventDefault();
287
410
  e.stopPropagation();
288
- domUtils.removeItem(prev);
411
+ dom.utils.removeItem(prev);
289
412
  }
290
413
  break;
291
414
  }
292
415
  // delete nonEditable
293
- if (sel && domUtils.isNonEditable(sel.previousSibling)) {
416
+ if (sel && dom.check.isNonEditable(sel.previousSibling)) {
294
417
  e.preventDefault();
295
418
  e.stopPropagation();
296
- domUtils.removeItem(sel.previousSibling);
419
+ dom.utils.removeItem(sel.previousSibling);
297
420
  break;
298
421
  }
299
422
  }
300
423
 
301
424
  break;
302
425
  }
303
- case 46 /** delete key */: {
426
+ case 'Delete' /** delete key */: {
304
427
  this.component.deselect();
305
428
  _styleNodes = this.__cacheStyleNodes;
306
429
  if (selectRange && this._hardDelete()) {
@@ -309,16 +432,49 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
309
432
  break;
310
433
  }
311
434
 
435
+ if (!selectRange && this.format.isEdgeLine(range.endContainer, range.endOffset, 'end') && !formatEl.nextSibling) {
436
+ e.preventDefault();
437
+ e.stopPropagation();
438
+ return;
439
+ }
440
+
441
+ // line delete
442
+ if (this.format.isLine(formatEl) && (!range.collapsed || dom.check.isEdgePoint(range.startContainer, range.endOffset, 'end')) && !range.startContainer.nextSibling && this.format.isLine(formatEl.nextElementSibling)) {
443
+ e.preventDefault();
444
+ e.stopPropagation();
445
+
446
+ let focusNode;
447
+ if (!range.collapsed) {
448
+ const rInfo = this.html.remove();
449
+ if (rInfo.commonCon !== rInfo.container && formatEl.parentElement) {
450
+ if (formatEl.contains(range.startContainer)) {
451
+ focusNode = LineDelete_next(formatEl);
452
+ this.selection.setRange(focusNode, focusNode.textContent.length, focusNode, focusNode.textContent.length);
453
+ } else {
454
+ const prevInfo = LineDelete_prev(formatEl);
455
+ this.selection.setRange(prevInfo.focusNode, prevInfo.focusOffset, prevInfo.focusNode, prevInfo.focusOffset);
456
+ }
457
+ }
458
+ this.history.push(true);
459
+ return;
460
+ }
461
+
462
+ LineDelete_next(formatEl);
463
+ this.history.push(true);
464
+
465
+ return;
466
+ }
467
+
312
468
  // line component
313
469
  if (!selectRange && formatEl && (range.endOffset === range.endContainer.textContent.length || selectionNode === formatEl)) {
314
- const sel = selectionNode === formatEl ? this._isUneditableNode(range, false) : domUtils.isEdgePoint(range.endContainer, range.endOffset) ? domUtils.getNextDeepestNode(range.endContainer, null) : null;
470
+ const sel = selectionNode === formatEl ? this._isUneditableNode(range, false) : dom.check.isEdgePoint(range.endContainer, range.endOffset) ? dom.query.getNextDeepestNode(range.endContainer, null) : null;
315
471
  if (this.component.is(sel)) {
316
472
  const fileComponentInfo = this.component.get(sel);
317
473
  if (fileComponentInfo) {
318
474
  e.preventDefault();
319
475
  e.stopPropagation();
320
- if (domUtils.isZeroWith(formatEl.textContent)) domUtils.removeItem(formatEl);
321
- if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName, false) === false) this.editor.blur();
476
+ if (dom.check.isZeroWidth(formatEl.textContent)) dom.utils.removeItem(formatEl);
477
+ if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName) === false) this.editor.blur();
322
478
  break;
323
479
  }
324
480
  }
@@ -333,7 +489,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
333
489
 
334
490
  // component
335
491
  if (
336
- (this.format.isLine(selectionNode) || selectionNode.nextSibling === null || (domUtils.isZeroWith(selectionNode.nextSibling) && selectionNode.nextSibling.nextSibling === null)) &&
492
+ (this.format.isLine(selectionNode) || selectionNode.nextSibling === null || (dom.check.isZeroWidth(selectionNode.nextSibling) && selectionNode.nextSibling.nextSibling === null)) &&
337
493
  range.startOffset === selectionNode.textContent.length
338
494
  ) {
339
495
  const nextEl = formatEl.nextElementSibling;
@@ -341,12 +497,12 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
341
497
  if (this.component.is(nextEl)) {
342
498
  e.preventDefault();
343
499
 
344
- if (domUtils.isZeroWith(formatEl)) {
345
- domUtils.removeItem(formatEl);
500
+ if (dom.check.isZeroWidth(formatEl)) {
501
+ dom.utils.removeItem(formatEl);
346
502
  // table component
347
- if (domUtils.isTable(nextEl)) {
348
- let cell = domUtils.getEdgeChild(nextEl, domUtils.isTableCell, false);
349
- cell = cell.firstElementChild || cell;
503
+ if (dom.check.isTable(nextEl)) {
504
+ let cell = /** @type {HTMLElement} */ (dom.query.getEdgeChild(nextEl, dom.check.isTableCell, false));
505
+ cell = /** @type {HTMLElement} */ (cell.firstElementChild || cell);
350
506
  this.selection.setRange(cell, 0, cell, 0);
351
507
  break;
352
508
  }
@@ -356,28 +512,28 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
356
512
  const fileComponentInfo = this.component.get(nextEl);
357
513
  if (fileComponentInfo) {
358
514
  e.stopPropagation();
359
- if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName, false) === false) this.editor.blur();
515
+ if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName) === false) this.editor.blur();
360
516
  } else if (this.component.is(nextEl)) {
361
517
  e.stopPropagation();
362
- domUtils.removeItem(nextEl);
518
+ dom.utils.removeItem(nextEl);
363
519
  }
364
520
 
365
521
  break;
366
522
  }
367
523
  }
368
524
 
369
- if (!selectRange && (domUtils.isEdgePoint(range.endContainer, range.endOffset) || (selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : false))) {
525
+ if (!selectRange && (dom.check.isEdgePoint(range.endContainer, range.endOffset) || (selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : false))) {
370
526
  const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] || selectionNode : selectionNode;
371
527
  // delete nonEditable
372
- if (sel && domUtils.isNonEditable(sel.nextSibling)) {
528
+ if (sel && dom.check.isNonEditable(sel.nextSibling)) {
373
529
  e.preventDefault();
374
530
  e.stopPropagation();
375
- domUtils.removeItem(sel.nextSibling);
531
+ dom.utils.removeItem(sel.nextSibling);
376
532
  break;
377
533
  } else if (this.component.is(sel)) {
378
534
  e.preventDefault();
379
535
  e.stopPropagation();
380
- domUtils.removeItem(sel);
536
+ dom.utils.removeItem(sel);
381
537
  break;
382
538
  }
383
539
  }
@@ -393,36 +549,35 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
393
549
  formatEl = this.format.getLine(range.startContainer, null);
394
550
  rangeEl = this.format.getBlock(formatEl, null);
395
551
  if (
396
- domUtils.isListCell(formatEl) &&
397
- domUtils.isList(rangeEl) &&
552
+ dom.check.isListCell(formatEl) &&
553
+ dom.check.isList(rangeEl) &&
398
554
  (selectionNode === formatEl ||
399
555
  (selectionNode.nodeType === 3 &&
400
- (!selectionNode.nextSibling || domUtils.isList(selectionNode.nextSibling)) &&
556
+ (!selectionNode.nextSibling || dom.check.isList(selectionNode.nextSibling)) &&
401
557
  (this.format.getLine(range.startContainer, null) !== this.format.getLine(range.endContainer, null) ? rangeEl.contains(range.endContainer) : range.endOffset === selectionNode.textContent.length && range.collapsed)))
402
558
  ) {
403
559
  if (range.startContainer !== range.endContainer) this.html.remove();
404
560
 
405
- let next = domUtils.getArrayItem(formatEl.children, domUtils.isList, false);
406
- next = next || formatEl.nextElementSibling || rangeEl.parentNode.nextElementSibling;
407
- if (next && (domUtils.isList(next) || domUtils.getArrayItem(next.children, domUtils.isList, false))) {
561
+ const next = /** @type {HTMLElement} */ (dom.utils.arrayFind(formatEl.children, dom.check.isList) || formatEl.nextElementSibling || rangeEl.parentElement.nextElementSibling);
562
+ if (next && (dom.check.isList(next) || dom.utils.arrayFind(next.children, dom.check.isList))) {
408
563
  e.preventDefault();
409
564
 
410
565
  let con, children;
411
- if (domUtils.isList(next)) {
566
+ if (dom.check.isList(next)) {
412
567
  const child = next.firstElementChild;
413
568
  children = child.childNodes;
414
569
  con = children[0];
415
570
  while (children[0]) {
416
571
  formatEl.insertBefore(children[0], next);
417
572
  }
418
- domUtils.removeItem(child);
573
+ dom.utils.removeItem(child);
419
574
  } else {
420
575
  con = next.firstChild;
421
576
  children = next.childNodes;
422
577
  while (children[0]) {
423
578
  formatEl.appendChild(children[0]);
424
579
  }
425
- domUtils.removeItem(next);
580
+ dom.utils.removeItem(next);
426
581
  }
427
582
  this.selection.setRange(con, 0, con, 0);
428
583
  this.history.push(true);
@@ -432,18 +587,18 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
432
587
 
433
588
  break;
434
589
  }
435
- case 9 /** tab key */: {
590
+ case 'Tab' /** tab key */: {
436
591
  if (this.options.get('tabDisable')) break;
437
592
  e.preventDefault();
438
- if (ctrl || alt || domUtils.isWysiwygFrame(selectionNode)) break;
593
+ if (ctrl || alt || dom.check.isWysiwygFrame(selectionNode)) break;
439
594
 
440
- const isEdge = !range.collapsed || domUtils.isEdgePoint(range.startContainer, range.startOffset);
595
+ const isEdge = !range.collapsed || dom.check.isEdgePoint(range.startContainer, range.startOffset);
441
596
  const selectedFormats = this.format.getLines(null);
442
597
  selectionNode = this.selection.getNode();
443
598
  const cells = [];
444
599
  const lines = [];
445
- const fc = domUtils.isListCell(selectedFormats[0]),
446
- lc = domUtils.isListCell(selectedFormats[selectedFormats.length - 1]);
600
+ const firstCell = dom.check.isListCell(selectedFormats[0]),
601
+ lastCell = dom.check.isListCell(selectedFormats[selectedFormats.length - 1]);
447
602
  let r = {
448
603
  sc: range.startContainer,
449
604
  so: range.startOffset,
@@ -452,7 +607,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
452
607
  };
453
608
  for (let i = 0, len = selectedFormats.length, f; i < len; i++) {
454
609
  f = selectedFormats[i];
455
- if (domUtils.isListCell(f)) {
610
+ if (dom.check.isListCell(f)) {
456
611
  if (!f.previousElementSibling && !shift) {
457
612
  continue;
458
613
  } else {
@@ -468,41 +623,50 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
468
623
  r = this.format._applyNestedList(cells, shift);
469
624
  }
470
625
 
471
- // Lines tab(4)
626
+ // Lines tab
472
627
  if (lines.length > 0) {
473
628
  if (!shift) {
474
- const tabText = domUtils.createTextNode(new Array(this.status.tabSize + 1).join('\u00A0'));
475
629
  if (lines.length === 1) {
476
- const textRange = this.html.insertNode(tabText, null, false);
477
- if (!textRange) return false;
478
- if (!fc) {
630
+ let tabSize = this.status.tabSize + 1;
631
+ if (this.options.get('syncTabIndent')) {
632
+ const baseIndex = dom.query.findTextIndexOnLine(formatEl, range.startContainer, range.startOffset, this.component.is.bind(this.component));
633
+ const prevTabEndIndex = this.format.isLine(formatEl.previousElementSibling) ? dom.query.findTabEndIndex(formatEl.previousElementSibling, baseIndex, 2) : 0;
634
+ if (prevTabEndIndex > baseIndex) {
635
+ tabSize = prevTabEndIndex - baseIndex + 1;
636
+ }
637
+ }
638
+
639
+ const tabText = dom.utils.createTextNode(new Array(tabSize).join('\u00A0'));
640
+ if (!this.html.insertNode(tabText, { afterNode: null, skipCharCount: false })) return false;
641
+ if (!firstCell) {
479
642
  r.sc = tabText;
480
- r.so = textRange.endOffset;
643
+ r.so = tabText.length;
481
644
  }
482
- if (!lc) {
645
+ if (!lastCell) {
483
646
  r.ec = tabText;
484
- r.eo = textRange.endOffset;
647
+ r.eo = tabText.length;
485
648
  }
486
649
  } else {
650
+ const tabText = dom.utils.createTextNode(new Array(this.status.tabSize + 1).join('\u00A0'));
487
651
  const len = lines.length - 1;
488
652
  for (let i = 0, child; i <= len; i++) {
489
653
  child = lines[i].firstChild;
490
654
  if (!child) continue;
491
655
 
492
- if (domUtils.isBreak(child)) {
656
+ if (dom.check.isBreak(child)) {
493
657
  lines[i].insertBefore(tabText.cloneNode(false), child);
494
658
  } else {
495
659
  child.textContent = tabText.textContent + child.textContent;
496
660
  }
497
661
  }
498
662
 
499
- const firstChild = domUtils.getEdgeChild(lines[0], 'text', false);
500
- const endChild = domUtils.getEdgeChild(lines[len], 'text', true);
501
- if (!fc && firstChild) {
663
+ const firstChild = dom.query.getEdgeChild(lines[0], 'text', false);
664
+ const endChild = dom.query.getEdgeChild(lines[len], 'text', true);
665
+ if (!firstCell && firstChild) {
502
666
  r.sc = firstChild;
503
667
  r.so = 0;
504
668
  }
505
- if (!lc && endChild) {
669
+ if (!lastCell && endChild) {
506
670
  r.ec = endChild;
507
671
  r.eo = endChild.textContent.length;
508
672
  }
@@ -514,10 +678,10 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
514
678
  for (let c = 0, cLen = line.length, child; c < cLen; c++) {
515
679
  child = line[c];
516
680
  if (!child) break;
517
- if (domUtils.isZeroWith(child)) continue;
681
+ if (dom.check.isZeroWidth(child)) continue;
518
682
 
519
683
  if (/^\s{1,4}$/.test(child.textContent)) {
520
- domUtils.removeItem(child);
684
+ dom.utils.removeItem(child);
521
685
  } else if (/^\s{1,4}/.test(child.textContent)) {
522
686
  child.textContent = child.textContent.replace(/^\s{1,4}/, '');
523
687
  }
@@ -526,13 +690,13 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
526
690
  }
527
691
  }
528
692
 
529
- const firstChild = domUtils.getEdgeChild(lines[0], 'text', false);
530
- const endChild = domUtils.getEdgeChild(lines[len], 'text', true);
531
- if (!fc && firstChild) {
693
+ const firstChild = dom.query.getEdgeChild(lines[0], 'text', false);
694
+ const endChild = dom.query.getEdgeChild(lines[len], 'text', true);
695
+ if (!firstCell && firstChild) {
532
696
  r.sc = firstChild;
533
697
  r.so = 0;
534
698
  }
535
- if (!lc && endChild) {
699
+ if (!lastCell && endChild) {
536
700
  r.ec = endChild;
537
701
  r.eo = endChild.textContent.length;
538
702
  }
@@ -544,7 +708,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
544
708
 
545
709
  break;
546
710
  }
547
- case 13 /** enter key */: {
711
+ case 'Enter' /** enter key */: {
548
712
  this.component.deselect();
549
713
  const brBlock = this.format.getBrLine(selectionNode, null);
550
714
 
@@ -563,27 +727,16 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
563
727
  }
564
728
 
565
729
  if (!shift) {
566
- const formatEndEdge = this.format.isEdgeLine(range.endContainer, range.endOffset, 'end');
567
- const formatStartEdge = this.format.isEdgeLine(range.startContainer, range.startOffset, 'start');
730
+ const formatEndEdge = !range.endContainer.nextSibling && this.format.isEdgeLine(range.endContainer, range.endOffset, 'end');
731
+ const formatStartEdge = !range.startContainer.previousSibling && this.format.isEdgeLine(range.startContainer, range.startOffset, 'front');
568
732
 
569
733
  // add default format line
570
734
  if (formatEndEdge && (/^H[1-6]$/i.test(formatEl.nodeName) || /^HR$/i.test(formatEl.nodeName))) {
571
735
  this.__enterPrevent(e);
572
- let temp = null;
573
736
  const newFormat = this.format.addLine(formatEl, this.options.get('defaultLine'));
574
-
575
- if (formatEndEdge && formatEndEdge.length > 0) {
576
- temp = formatEndEdge.pop();
577
- const innerNode = temp;
578
- while (formatEndEdge.length > 0) {
579
- temp = temp.appendChild(formatEndEdge.pop());
580
- }
581
- newFormat.appendChild(innerNode);
582
- }
583
-
584
- temp = !temp ? newFormat.firstChild : temp.appendChild(newFormat.firstChild);
585
- if (domUtils.isBreak(temp)) {
586
- const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
737
+ const temp = newFormat.firstChild;
738
+ if (dom.check.isBreak(temp)) {
739
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
587
740
  temp.parentNode.insertBefore(zeroWidth, temp);
588
741
  this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
589
742
  } else {
@@ -591,14 +744,14 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
591
744
  }
592
745
 
593
746
  // enter scroll
594
- this.selection.scrollTo(range);
747
+ this.__enterScrollTo(range);
595
748
  break;
596
- } else if (rangeEl && formatEl && !domUtils.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
749
+ } else if (rangeEl && formatEl && !dom.check.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
597
750
  const rangeEnt = this.selection.getRange();
598
- if (domUtils.isEdgePoint(rangeEnt.endContainer, rangeEnt.endOffset) && domUtils.isList(selectionNode.nextSibling)) {
751
+ if (dom.check.isEdgePoint(rangeEnt.endContainer, rangeEnt.endOffset) && dom.check.isList(selectionNode.nextSibling)) {
599
752
  this.__enterPrevent(e);
600
- const br = domUtils.createElement('BR');
601
- const newEl = domUtils.createElement('LI', null, br);
753
+ const br = dom.utils.createElement('BR');
754
+ const newEl = dom.utils.createElement('LI', null, br);
602
755
 
603
756
  formatEl.parentNode.insertBefore(newEl, formatEl.nextElementSibling);
604
757
  newEl.appendChild(selectionNode.nextSibling);
@@ -606,42 +759,42 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
606
759
  this.selection.setRange(br, 1, br, 1);
607
760
 
608
761
  // enter scroll
609
- this.selection.scrollTo(range);
762
+ this.__enterScrollTo(range);
610
763
  break;
611
764
  }
612
765
 
613
766
  if (
614
- (rangeEnt.commonAncestorContainer.nodeType === 3 ? !rangeEnt.commonAncestorContainer.nextElementSibling : true) &&
615
- domUtils.isZeroWith(formatEl.innerText.trim()) &&
616
- !domUtils.isListCell(formatEl.nextElementSibling)
767
+ (rangeEnt.commonAncestorContainer.nodeType === 3 ? !(/** @type {HTMLElement} */ (rangeEnt.commonAncestorContainer).nextElementSibling) : true) &&
768
+ dom.check.isZeroWidth(formatEl.innerText.trim()) &&
769
+ !dom.check.isListCell(formatEl.nextElementSibling)
617
770
  ) {
618
771
  this.__enterPrevent(e);
619
772
  let newEl = null;
620
773
 
621
- if (domUtils.isListCell(rangeEl.parentNode)) {
622
- const parentLi = formatEl.parentNode.parentNode;
623
- rangeEl = parentLi.parentNode;
624
- const newListCell = domUtils.createElement('LI');
774
+ if (dom.check.isListCell(rangeEl.parentElement)) {
775
+ const parentLi = formatEl.parentNode.parentElement;
776
+ rangeEl = parentLi.parentElement;
777
+ const newListCell = dom.utils.createElement('LI');
625
778
  newListCell.innerHTML = '<br>';
626
- domUtils.copyTagAttributes(newListCell, formatEl, this.options.get('lineAttrReset'));
779
+ dom.utils.copyTagAttributes(newListCell, formatEl, this.options.get('lineAttrReset'));
627
780
  newEl = newListCell;
628
781
  rangeEl.insertBefore(newEl, parentLi.nextElementSibling);
629
782
  } else {
630
783
  let newFormat;
631
- if (domUtils.isTableCell(rangeEl.parentNode)) {
784
+ if (dom.check.isTableCell(rangeEl.parentElement)) {
632
785
  newFormat = 'DIV';
633
- } else if (domUtils.isList(rangeEl.parentNode)) {
786
+ } else if (dom.check.isList(rangeEl.parentElement)) {
634
787
  newFormat = 'LI';
635
- } else if (this.format.isLine(rangeEl.nextElementSibling) && !this.format.isBlock(rangeEl.nextElementSibling)) {
788
+ } else if (this.format.isLine(rangeEl.nextElementSibling)) {
636
789
  newFormat = rangeEl.nextElementSibling.nodeName;
637
- } else if (this.format.isLine(rangeEl.previousElementSibling) && !this.format.isBlock(rangeEl.previousElementSibling)) {
790
+ } else if (this.format.isLine(rangeEl.previousElementSibling)) {
638
791
  newFormat = rangeEl.previousElementSibling.nodeName;
639
792
  } else {
640
793
  newFormat = this.options.get('defaultLine');
641
794
  }
642
795
 
643
- newEl = domUtils.createElement(newFormat);
644
- const edge = this.format.removeBlock(rangeEl, [formatEl], null, true, true);
796
+ newEl = dom.utils.createElement(newFormat);
797
+ const edge = this.format.removeBlock(rangeEl, { selectedFormats: [formatEl], newBlockElement: null, shouldDelete: true, skipHistory: true });
645
798
  edge.cc.insertBefore(newEl, edge.ec);
646
799
  }
647
800
 
@@ -667,29 +820,30 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
667
820
  ((selectionFormat &&
668
821
  range.collapsed &&
669
822
  children.length - 1 <= offset + 1 &&
670
- domUtils.isBreak(children[offset]) &&
671
- (!children[offset + 1] || ((!children[offset + 2] || domUtils.isZeroWith(children[offset + 2].textContent)) && children[offset + 1].nodeType === 3 && domUtils.isZeroWith(children[offset + 1].textContent))) &&
823
+ dom.check.isBreak(children[offset]) &&
824
+ (!children[offset + 1] || ((!children[offset + 2] || dom.check.isZeroWidth(children[offset + 2].textContent)) && children[offset + 1].nodeType === 3 && dom.check.isZeroWidth(children[offset + 1].textContent))) &&
672
825
  offset > 0 &&
673
- domUtils.isBreak(children[offset - 1])) ||
826
+ dom.check.isBreak(children[offset - 1])) ||
674
827
  (!selectionFormat &&
675
- domUtils.isZeroWith(selectionNode.textContent) &&
676
- domUtils.isBreak(prev) &&
677
- (domUtils.isBreak(prev.previousSibling) || !domUtils.isZeroWith(prev.previousSibling.textContent)) &&
678
- (!next || (!domUtils.isBreak(next) && domUtils.isZeroWith(next.textContent)))))
828
+ dom.check.isZeroWidth(selectionNode.textContent) &&
829
+ dom.check.isBreak(prev) &&
830
+ (dom.check.isBreak(prev.previousSibling) || !dom.check.isZeroWidth(prev.previousSibling?.textContent)) &&
831
+ (!next || (!dom.check.isBreak(next) && dom.check.isZeroWidth(next.textContent)))))
679
832
  ) {
680
- if (selectionFormat) domUtils.removeItem(children[offset - 1]);
681
- else domUtils.removeItem(selectionNode);
682
- const newEl = this.format.addLine(brBlock, this.format.isLine(brBlock.nextElementSibling) && !this.format.isBlock(brBlock.nextElementSibling) ? brBlock.nextElementSibling : null);
683
- domUtils.copyFormatAttributes(newEl, brBlock);
833
+ if (selectionFormat) dom.utils.removeItem(children[offset - 1]);
834
+ else dom.utils.removeItem(selectionNode);
835
+ const brBlockNext = /** @type {HTMLElement} */ (brBlock).nextElementSibling;
836
+ const newEl = this.format.addLine(brBlock, this.format.isLine(brBlockNext) ? brBlockNext : null);
837
+ dom.utils.copyFormatAttributes(newEl, brBlock);
684
838
  this.selection.setRange(newEl, 1, newEl, 1);
685
839
 
686
840
  // enter scroll
687
- this.selection.scrollTo(range);
841
+ this.__enterScrollTo(range);
688
842
  break;
689
843
  }
690
844
 
691
845
  if (selectionFormat) {
692
- this.html.insert(range.collapsed && domUtils.isBreak(range.startContainer.childNodes[range.startOffset - 1]) ? '<br>' : '<br><br>', false, true, true);
846
+ this.html.insert(range.collapsed && dom.check.isBreak(range.startContainer.childNodes[range.startOffset - 1]) ? '<br>' : '<br><br>', { selectInserted: false, skipCharCount: true, skipCleaning: true });
693
847
 
694
848
  let focusNode = wSelection.focusNode;
695
849
  const wOffset = wSelection.focusOffset;
@@ -700,12 +854,12 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
700
854
  this.selection.setRange(focusNode, 1, focusNode, 1);
701
855
  } else {
702
856
  const focusNext = wSelection.focusNode.nextSibling;
703
- const br = domUtils.createElement('BR');
704
- this.html.insertNode(br, null, true);
857
+ const br = dom.utils.createElement('BR');
858
+ this.html.insertNode(br, { afterNode: null, skipCharCount: true });
705
859
 
706
860
  const brPrev = br.previousSibling,
707
861
  brNext = br.nextSibling;
708
- if (!domUtils.isBreak(focusNext) && !domUtils.isBreak(brPrev) && (!brNext || domUtils.isZeroWith(brNext))) {
862
+ if (!dom.check.isBreak(focusNext) && !dom.check.isBreak(brPrev) && (!brNext || dom.check.isZeroWidth(brNext))) {
709
863
  br.parentNode.insertBefore(br.cloneNode(false), br);
710
864
  this.selection.setRange(br, 1, br, 1);
711
865
  } else {
@@ -716,26 +870,26 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
716
870
  this._onShortcutKey = true;
717
871
 
718
872
  // enter scroll
719
- this.selection.scrollTo(range);
873
+ this.__enterScrollTo(range);
720
874
  break;
721
875
  }
722
876
 
723
877
  // set format attrs - edge
724
878
  if (range.collapsed && (formatStartEdge || formatEndEdge)) {
725
879
  this.__enterPrevent(e);
726
- const focusBR = domUtils.createElement('BR');
727
- const newFormat = domUtils.createElement(formatEl.nodeName, null, focusBR);
880
+ const focusBR = dom.utils.createElement('BR');
881
+ const newFormat = dom.utils.createElement(formatEl.nodeName, null, focusBR);
728
882
 
729
- domUtils.copyTagAttributes(newFormat, formatEl, this.options.get('lineAttrReset'));
883
+ dom.utils.copyTagAttributes(newFormat, formatEl, this.options.get('lineAttrReset'));
730
884
 
731
885
  let child = focusBR;
732
886
  do {
733
- if (!domUtils.isBreak(selectionNode) && selectionNode.nodeType === 1) {
734
- const f = selectionNode.cloneNode(false);
887
+ if (!dom.check.isBreak(selectionNode) && selectionNode.nodeType === 1) {
888
+ const f = /** @type {HTMLElement} */ (selectionNode.cloneNode(false));
735
889
  f.appendChild(child);
736
890
  child = f;
737
891
  }
738
- selectionNode = selectionNode.parentNode;
892
+ selectionNode = selectionNode.parentElement;
739
893
  } while (formatEl !== selectionNode && formatEl.contains(selectionNode));
740
894
 
741
895
  newFormat.appendChild(child);
@@ -748,37 +902,42 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
748
902
  }
749
903
 
750
904
  // enter scroll
751
- this.selection.scrollTo(range);
905
+ this.__enterScrollTo(range);
752
906
  break;
753
907
  }
754
908
 
755
909
  if (formatEl) {
756
910
  e.stopPropagation();
757
911
 
912
+ /** @type {HTMLElement} */
758
913
  let newEl;
759
914
  let offset = 0;
760
915
  if (!range.collapsed) {
761
916
  const isMultiLine = this.format.getLine(range.startContainer, null) !== this.format.getLine(range.endContainer, null);
762
- const newFormat = formatEl.cloneNode(false);
917
+ const newFormat = /** @type {HTMLElement} */ (formatEl.cloneNode(false));
763
918
  newFormat.innerHTML = '<br>';
764
- const rcon = this.html.remove();
919
+ const commonCon = /** @type {HTMLElement} */ (range.commonAncestorContainer);
920
+ const rcon =
921
+ commonCon === range.startContainer && commonCon === range.endContainer && dom.check.isZeroWidth(commonCon)
922
+ ? { container: commonCon, offset: range.endOffset, prevContainer: commonCon.previousElementSibling, commonCon: commonCon }
923
+ : this.html.remove();
765
924
  newEl = this.format.getLine(rcon.container, null);
766
925
  if (!newEl) {
767
- if (domUtils.isWysiwygFrame(rcon.container)) {
926
+ if (dom.check.isWysiwygFrame(rcon.container)) {
768
927
  this.__enterPrevent(e);
769
- frameContext.get('wysiwyg').appendChild(newFormat);
928
+ fc.get('wysiwyg').appendChild(newFormat);
770
929
  newEl = newFormat;
771
- domUtils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
930
+ dom.utils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
772
931
  this.selection.setRange(newEl, offset, newEl, offset);
773
932
  }
774
933
 
775
934
  // enter scroll
776
- this.selection.scrollTo(range);
935
+ this.__enterScrollTo(range);
777
936
  break;
778
937
  }
779
938
 
780
939
  const innerRange = this.format.getBlock(rcon.container);
781
- newEl = newEl.contains(innerRange) ? domUtils.getEdgeChild(innerRange, this.format.getLine.bind(this.format)) : newEl;
940
+ newEl = newEl.contains(innerRange) ? dom.query.getEdgeChild(innerRange, this.format.getLine.bind(this.format), false) : newEl;
782
941
  if (isMultiLine) {
783
942
  if (formatEndEdge && !formatStartEdge) {
784
943
  newEl.parentNode.insertBefore(newFormat, !rcon.prevContainer || rcon.container === rcon.prevContainer ? newEl.nextElementSibling : newEl);
@@ -799,93 +958,103 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
799
958
  newEl.parentNode.insertBefore(newFormat, rcon.prevContainer && rcon.container === rcon.prevContainer ? newEl.nextElementSibling : newEl);
800
959
  newEl = newFormat;
801
960
  offset = 0;
961
+ } else if (formatEndEdge) {
962
+ newEl = newEl.parentNode.insertBefore(newFormat, newEl.nextElementSibling);
963
+ newEl = newFormat;
964
+ offset = 0;
802
965
  } else {
803
- newEl = this.nodeTransform.split(rcon.container, rcon.offset, domUtils.getNodeDepth(formatEl));
966
+ newEl = this.nodeTransform.split(rcon.container, rcon.offset, dom.query.getNodeDepth(formatEl));
804
967
  }
805
968
  }
806
969
  } else {
807
- if (domUtils.isZeroWith(formatEl)) {
970
+ if (dom.check.isZeroWidth(formatEl)) {
808
971
  newEl = this.format.addLine(formatEl, formatEl.cloneNode(false));
809
972
  } else {
810
- newEl = this.nodeTransform.split(range.endContainer, range.endOffset, domUtils.getNodeDepth(formatEl));
973
+ newEl = this.nodeTransform.split(range.endContainer, range.endOffset, dom.query.getNodeDepth(formatEl));
811
974
  }
812
975
  }
813
976
 
814
977
  this.__enterPrevent(e);
815
- domUtils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
978
+ dom.utils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
816
979
  this.selection.setRange(newEl, offset, newEl, offset);
817
980
 
818
981
  // enter scroll
819
- this.selection.scrollTo(range);
982
+ this.__enterScrollTo(range);
820
983
  break;
821
984
  }
822
985
  }
823
986
 
824
987
  if (selectRange) {
825
988
  // enter scroll
826
- this.selection.scrollTo(range);
989
+ this.__enterScrollTo(range);
827
990
  break;
828
991
  }
829
992
 
830
- if (rangeEl && domUtils.getParentElement(rangeEl, 'FIGCAPTION') && domUtils.getParentElement(rangeEl, domUtils.isList)) {
993
+ if (rangeEl && dom.query.getParentElement(rangeEl, 'FIGCAPTION') && dom.query.getParentElement(rangeEl, dom.check.isList)) {
831
994
  this.__enterPrevent(e);
832
995
  formatEl = this.format.addLine(formatEl, null);
833
996
  this.selection.setRange(formatEl, 0, formatEl, 0);
834
997
 
835
998
  // enter scroll
836
- this.selection.scrollTo(range);
999
+ this.__enterScrollTo(range);
837
1000
  }
838
1001
 
839
1002
  break;
840
1003
  }
841
1004
  }
842
1005
 
843
- if (shift && (isOSX_IOS ? alt : ctrl) && keyCode === 32) {
1006
+ if (shift && (isOSX_IOS ? alt : ctrl) && keyCodeMap.isSpace(keyCode)) {
844
1007
  e.preventDefault();
845
1008
  e.stopPropagation();
846
- const nbsp = this.html.insertNode(domUtils.createTextNode('\u00a0'), null, true);
847
- if (nbsp && nbsp.container) {
848
- this.selection.setRange(nbsp.container, nbsp.endOffset, nbsp.container, nbsp.endOffset);
1009
+ const nbsp = this.html.insertNode(dom.utils.createTextNode('\u00a0'), { afterNode: null, skipCharCount: true });
1010
+ if (nbsp) {
1011
+ this.selection.setRange(nbsp, nbsp.length, nbsp, nbsp.length);
849
1012
  return;
850
1013
  }
851
1014
  }
852
1015
 
853
- if (!ctrl && !alt && !selectRange && !NON_TEXT_KEYCODE.test(keyCode) && domUtils.isBreak(range.commonAncestorContainer)) {
854
- const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
855
- this.html.insertNode(zeroWidth, null, true);
1016
+ if (!ctrl && !alt && !selectRange && !keyCodeMap.isNonTextKey(keyCode) && dom.check.isBreak(range.commonAncestorContainer)) {
1017
+ const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
1018
+ this.html.insertNode(zeroWidth, { afterNode: null, skipCharCount: true });
856
1019
  this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
857
1020
  }
858
1021
 
859
- // next component
860
- if (!DIR_KEYCODE.test(keyCode)) return;
1022
+ // document type
1023
+ if (fc.has('documentType-use-header') && !range.collapsed && !ctrl && !alt && !shift && !keyCodeMap.isDirectionKey(keyCode)) {
1024
+ _w.setTimeout(() => {
1025
+ fc.get('documentType').reHeader();
1026
+ }, 0);
1027
+ return;
1028
+ }
861
1029
 
1030
+ // next component
862
1031
  let cmponentInfo = null;
863
1032
  switch (keyCode) {
864
- case 38 /** up key */:
1033
+ case 'ArrowUp' /** up key */:
865
1034
  if (this.component.is(formatEl.previousElementSibling)) {
866
1035
  cmponentInfo = this.component.get(formatEl.previousElementSibling);
867
1036
  }
868
1037
  break;
869
- case 37 /** left key */:
870
- if (domUtils.isEdgePoint(selectionNode, range.startOffset, 'front')) {
871
- const prevEl = selectionNode.previousElementSibling;
872
- if (prevEl && this.component.is(prevEl)) {
873
- cmponentInfo = this.component.get(prevEl);
1038
+ case 'ArrowLeft' /** left key */:
1039
+ if (dom.check.isEdgePoint(selectionNode, range.startOffset, 'front')) {
1040
+ const prevEl = selectionNode.previousElementSibling || dom.query.getPreviousDeepestNode(selectionNode);
1041
+ if (prevEl) {
1042
+ if (this.component.is(prevEl)) cmponentInfo = this.component.get(prevEl);
874
1043
  } else if (this.component.is(formatEl.previousElementSibling)) {
875
1044
  cmponentInfo = this.component.get(formatEl.previousElementSibling);
876
1045
  }
877
1046
  }
878
1047
  break;
879
- case 40 /** down key */:
1048
+ case 'ArrowDown' /** down key */:
880
1049
  if (this.component.is(formatEl.nextElementSibling)) {
881
1050
  cmponentInfo = this.component.get(formatEl.nextElementSibling);
882
1051
  }
883
1052
  break;
884
- case 39 /** right key */:
885
- if (domUtils.isEdgePoint(selectionNode, range.endOffset, 'end')) {
886
- const nextEl = selectionNode.nextElementSibling;
887
- if (nextEl && this.component.is(nextEl)) {
888
- cmponentInfo = this.component.get(nextEl);
1053
+ case 'ArrowRight' /** right key */:
1054
+ if (dom.check.isEdgePoint(selectionNode, range.endOffset, 'end')) {
1055
+ const nextEl = selectionNode.nextElementSibling || dom.query.getNextDeepestNode(selectionNode);
1056
+ if (nextEl) {
1057
+ if (this.component.is(nextEl)) cmponentInfo = this.component.get(nextEl);
889
1058
  } else if (this.component.is(formatEl.nextElementSibling)) {
890
1059
  cmponentInfo = this.component.get(formatEl.nextElementSibling);
891
1060
  }
@@ -895,25 +1064,34 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
895
1064
 
896
1065
  if (cmponentInfo && !cmponentInfo.options?.isInputComponent) {
897
1066
  e.preventDefault();
898
- if (this.component.select(cmponentInfo.target, cmponentInfo.pluginName, false) === false) this.editor.blur();
1067
+ if (this.component.select(cmponentInfo.target, cmponentInfo.pluginName) === false) this.editor.blur();
899
1068
  }
900
1069
  }
901
1070
 
902
- export function OnKeyUp_wysiwyg(frameContext, e) {
1071
+ /**
1072
+ * @private
1073
+ * @this {EventManagerThis_handler_ww_key_input}
1074
+ * @param {__se__FrameContext} fc - Frame context object
1075
+ * @param {KeyboardEvent} e - Event object
1076
+ */
1077
+ export async function OnKeyUp_wysiwyg(fc, e) {
903
1078
  if (this._onShortcutKey || this.menu.currentDropdownName) return;
904
1079
 
905
- const keyCode = e.keyCode;
906
- const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
907
- const alt = e.altKey;
1080
+ const keyCode = e.code;
1081
+ const ctrl = keyCodeMap.isCtrl(e);
1082
+ const alt = keyCodeMap.isAlt(e);
1083
+
1084
+ if (ctrl) keyState.ctrl = false;
1085
+ if (alt) keyState.alt = false;
908
1086
 
909
- if (frameContext.get('isReadOnly')) return;
1087
+ if (fc.get('isReadOnly')) return;
910
1088
 
911
1089
  const range = this.selection.getRange();
912
1090
  let selectionNode = this.selection.getNode();
913
1091
 
914
- if ((this.editor.isBalloon || this.editor.isSubBalloon) && (((this.editor.isBalloonAlways || this.editor.isSubBalloonAlways) && keyCode !== 27) || !range.collapsed)) {
1092
+ if ((this.editor.isBalloon || this.editor.isSubBalloon) && (((this.editor.isBalloonAlways || this.editor.isSubBalloonAlways) && !keyCodeMap.isEsc(keyCode)) || !range.collapsed)) {
915
1093
  if (this.editor.isBalloonAlways || this.editor.isSubBalloonAlways) {
916
- if (keyCode !== 27) this._showToolbarBalloonDelay();
1094
+ if (!keyCodeMap.isEsc(keyCode)) this._showToolbarBalloonDelay();
917
1095
  } else {
918
1096
  if (this.editor.isSubBalloon) this.subToolbar._showBalloon();
919
1097
  else this.toolbar._showBalloon();
@@ -922,18 +1100,26 @@ export function OnKeyUp_wysiwyg(frameContext, e) {
922
1100
  }
923
1101
 
924
1102
  /** when format tag deleted */
925
- if (keyCode === 8 && domUtils.isWysiwygFrame(selectionNode) && selectionNode.textContent === '' && selectionNode.children.length === 0) {
1103
+ if (keyCodeMap.isBackspace(keyCode) && dom.check.isWysiwygFrame(selectionNode) && selectionNode.textContent === '' && selectionNode.children.length === 0) {
926
1104
  e.preventDefault();
927
1105
  e.stopPropagation();
928
1106
 
929
1107
  selectionNode.innerHTML = '';
930
1108
 
931
- const oFormatTag = domUtils.createElement(this.format.isLine(this.status.currentNodes[0]) && !domUtils.isListCell(this.status.currentNodes[0]) ? this.status.currentNodes[0] : this.options.get('defaultLine'), null, '<br>');
1109
+ const oFormatTag = dom.utils.createElement(this.format.isLine(this.status.currentNodes[0]) && !dom.check.isListCell(this.status.currentNodes[0]) ? this.status.currentNodes[0] : this.options.get('defaultLine'), null, '<br>');
932
1110
  selectionNode.appendChild(oFormatTag);
933
1111
  this.selection.setRange(oFormatTag, 0, oFormatTag, 0);
934
1112
  this.applyTagEffect();
935
1113
 
936
1114
  this.history.push(false);
1115
+
1116
+ // document type
1117
+ if (fc.has('documentType-use-header')) {
1118
+ if (keyCodeMap.isDocumentTypeObserverKey(keyCode)) {
1119
+ fc.get('documentType').reHeader();
1120
+ }
1121
+ }
1122
+
937
1123
  return;
938
1124
  }
939
1125
 
@@ -943,7 +1129,7 @@ export function OnKeyUp_wysiwyg(frameContext, e) {
943
1129
 
944
1130
  if (formatEl && attrs) {
945
1131
  for (let i = 0, len = attrs.length; i < len; i++) {
946
- if (keyCode === 13 && /^id$/i.test(attrs[i].name)) {
1132
+ if (keyCodeMap.isEnter(keyCode) && /^id$/i.test(attrs[i].name)) {
947
1133
  formatEl.removeAttribute('id');
948
1134
  continue;
949
1135
  }
@@ -952,11 +1138,11 @@ export function OnKeyUp_wysiwyg(frameContext, e) {
952
1138
  this._formatAttrsTemp = null;
953
1139
  }
954
1140
 
955
- if (!formatEl && range.collapsed && !this.component.is(selectionNode) && !domUtils.isList(selectionNode) && this._setDefaultLine(this.format.isBlock(rangeEl) ? 'DIV' : this.options.get('defaultLine')) !== null) {
1141
+ if (!formatEl && range.collapsed && !this.component.is(selectionNode) && !dom.check.isList(selectionNode) && this._setDefaultLine(this.format.isBlock(rangeEl) ? 'DIV' : this.options.get('defaultLine')) !== null) {
956
1142
  selectionNode = this.selection.getNode();
957
1143
  }
958
1144
 
959
- const textKey = !ctrl && !alt && !NON_TEXT_KEYCODE.test(keyCode);
1145
+ const textKey = !keyState.ctrl && !keyState.alt && !keyCodeMap.isNonTextKey(keyCode);
960
1146
  if (textKey && selectionNode.nodeType === 3 && unicode.zeroWidthRegExp.test(selectionNode.textContent) && !(e.isComposing !== undefined ? e.isComposing : this.isComposing)) {
961
1147
  let so = range.startOffset,
962
1148
  eo = range.endOffset;
@@ -967,7 +1153,7 @@ export function OnKeyUp_wysiwyg(frameContext, e) {
967
1153
  this.selection.setRange(selectionNode, so < 0 ? 0 : so, selectionNode, eo < 0 ? 0 : eo);
968
1154
  }
969
1155
 
970
- if (DELETE_KEYCODE.test(keyCode) && domUtils.isZeroWith(formatEl?.textContent) && !formatEl.previousElementSibling) {
1156
+ if (keyCodeMap.isRemoveKey(keyCode) && dom.check.isZeroWidth(formatEl?.textContent) && !formatEl.previousElementSibling) {
971
1157
  const rsMode = this.options.get('retainStyleMode');
972
1158
  if (rsMode !== 'none' && _styleNodes?.length > 0) {
973
1159
  if (rsMode === 'repeat') {
@@ -991,12 +1177,24 @@ export function OnKeyUp_wysiwyg(frameContext, e) {
991
1177
 
992
1178
  this.char.test('', false);
993
1179
 
1180
+ // document type
1181
+ if (fc.has('documentType-use-header')) {
1182
+ if (keyCodeMap.isDocumentTypeObserverKey(keyCode)) {
1183
+ fc.get('documentType').reHeader();
1184
+ const el = dom.query.getParentElement(this.selection.selectionNode, this.format.isLine.bind(this.format));
1185
+ fc.get('documentType').on(el);
1186
+ } else {
1187
+ const el = dom.query.getParentElement(selectionNode, (current) => current.nodeType === 1);
1188
+ fc.get('documentType').onChangeText(el);
1189
+ }
1190
+ }
1191
+
994
1192
  // user event
995
- if (this.triggerEvent('onKeyUp', { frameContext, event: e }) === false) return;
1193
+ if ((await this.triggerEvent('onKeyUp', { frameContext: fc, event: e })) === false) return;
996
1194
  // plugin event
997
- if (this._callPluginEvent('onKeyUp', { frameContext, event: e, range, line: formatEl }) === false) return;
1195
+ if (this._callPluginEvent('onKeyUp', { frameContext: fc, event: e, range, line: formatEl }) === false) return;
998
1196
 
999
- if (!ctrl && !alt && !HISTORY_IGNORE_KEYCODE.test(keyCode)) {
1197
+ if (keyCodeMap.isHistoryRelevantKey(keyCode)) {
1000
1198
  this.history.push(true);
1001
1199
  }
1002
1200
  }