suneditor 2.46.2 → 3.0.0-alpha.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 (289) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.json +64 -0
  3. package/CONTRIBUTING.md +36 -0
  4. package/LICENSE.txt +1 -1
  5. package/README.md +11 -1560
  6. package/package.json +94 -70
  7. package/src/assets/icons/_default.js +194 -0
  8. package/src/assets/suneditor-content.css +642 -0
  9. package/src/assets/suneditor.css +3378 -0
  10. package/src/core/base/eventHandlers/handler_toolbar.js +114 -0
  11. package/src/core/base/eventHandlers/handler_ww_clipboard.js +31 -0
  12. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +69 -0
  13. package/src/core/base/eventHandlers/handler_ww_key_input.js +978 -0
  14. package/src/core/base/eventHandlers/handler_ww_mouse.js +118 -0
  15. package/src/core/base/eventManager.js +1129 -0
  16. package/src/core/base/events.js +320 -0
  17. package/src/core/base/history.js +301 -0
  18. package/src/core/class/char.js +146 -0
  19. package/src/core/class/component.js +624 -0
  20. package/src/core/class/format.js +3255 -0
  21. package/src/core/class/html.js +1621 -0
  22. package/src/core/class/menu.js +260 -0
  23. package/src/core/class/nodeTransform.js +379 -0
  24. package/src/core/class/notice.js +42 -0
  25. package/src/core/class/offset.js +578 -0
  26. package/src/core/class/selection.js +508 -0
  27. package/src/core/class/shortcuts.js +38 -0
  28. package/src/core/class/toolbar.js +440 -0
  29. package/src/core/class/viewer.js +646 -0
  30. package/src/core/editor.js +1588 -0
  31. package/src/core/section/actives.js +107 -0
  32. package/src/core/section/constructor.js +1237 -0
  33. package/src/core/section/context.js +97 -0
  34. package/src/editorInjector/_classes.js +22 -0
  35. package/src/editorInjector/_core.js +28 -0
  36. package/src/editorInjector/index.js +13 -0
  37. package/src/helper/converter.js +313 -0
  38. package/src/helper/domUtils.js +1177 -0
  39. package/src/helper/env.js +250 -0
  40. package/src/helper/index.js +19 -0
  41. package/src/helper/numbers.js +68 -0
  42. package/src/helper/unicode.js +43 -0
  43. package/src/langs/ckb.js +161 -0
  44. package/src/langs/cs.js +161 -0
  45. package/src/langs/da.js +161 -0
  46. package/src/langs/de.js +162 -0
  47. package/src/langs/en.js +199 -0
  48. package/src/langs/es.js +162 -0
  49. package/src/langs/fa.js +159 -0
  50. package/src/langs/fr.js +161 -0
  51. package/src/langs/he.js +162 -0
  52. package/src/{lang → langs}/index.js +0 -2
  53. package/src/langs/it.js +162 -0
  54. package/src/langs/ja.js +162 -0
  55. package/src/langs/ko.js +162 -0
  56. package/src/langs/lv.js +162 -0
  57. package/src/langs/nl.js +162 -0
  58. package/src/langs/pl.js +162 -0
  59. package/src/langs/pt_br.js +162 -0
  60. package/src/langs/ro.js +162 -0
  61. package/src/langs/ru.js +162 -0
  62. package/src/langs/se.js +162 -0
  63. package/src/langs/tr.js +159 -0
  64. package/src/langs/ua.js +162 -0
  65. package/src/langs/ur.js +162 -0
  66. package/src/langs/zh_cn.js +162 -0
  67. package/src/modules/ApiManager.js +168 -0
  68. package/src/modules/ColorPicker.js +302 -0
  69. package/src/modules/Controller.js +315 -0
  70. package/src/modules/Figure.js +1174 -0
  71. package/src/modules/FileBrowser.js +271 -0
  72. package/src/modules/FileManager.js +290 -0
  73. package/src/modules/HueSlider.js +513 -0
  74. package/src/modules/Modal.js +177 -0
  75. package/src/modules/ModalAnchorEditor.js +494 -0
  76. package/src/modules/SelectMenu.js +447 -0
  77. package/src/modules/_DragHandle.js +16 -0
  78. package/src/modules/index.js +14 -0
  79. package/src/plugins/command/blockquote.js +47 -47
  80. package/src/plugins/command/exportPdf.js +168 -0
  81. package/src/plugins/command/fileUpload.js +389 -0
  82. package/src/plugins/command/list_bulleted.js +112 -0
  83. package/src/plugins/command/list_numbered.js +115 -0
  84. package/src/plugins/dropdown/align.js +143 -0
  85. package/src/plugins/dropdown/backgroundColor.js +73 -0
  86. package/src/plugins/dropdown/font.js +113 -0
  87. package/src/plugins/dropdown/fontColor.js +73 -0
  88. package/src/plugins/dropdown/formatBlock.js +141 -0
  89. package/src/plugins/dropdown/hr.js +111 -0
  90. package/src/plugins/dropdown/layout.js +72 -0
  91. package/src/plugins/dropdown/lineHeight.js +114 -0
  92. package/src/plugins/dropdown/list.js +107 -0
  93. package/src/plugins/dropdown/paragraphStyle.js +117 -0
  94. package/src/plugins/dropdown/table.js +2810 -0
  95. package/src/plugins/dropdown/template.js +71 -0
  96. package/src/plugins/dropdown/textStyle.js +137 -0
  97. package/src/plugins/field/mention.js +172 -0
  98. package/src/plugins/fileBrowser/imageGallery.js +76 -59
  99. package/src/plugins/index.js +86 -24
  100. package/src/plugins/input/fontSize.js +357 -0
  101. package/src/plugins/modal/audio.js +492 -0
  102. package/src/plugins/modal/image.js +1062 -0
  103. package/src/plugins/modal/link.js +211 -0
  104. package/src/plugins/modal/math.js +347 -0
  105. package/src/plugins/modal/video.js +870 -0
  106. package/src/suneditor.js +62 -67
  107. package/src/themes/test.css +61 -0
  108. package/typings/CommandPlugin.d.ts +8 -0
  109. package/typings/DialogPlugin.d.ts +20 -0
  110. package/typings/FileBrowserPlugin.d.ts +30 -0
  111. package/typings/Lang.d.ts +124 -0
  112. package/typings/Module.d.ts +15 -0
  113. package/typings/Plugin.d.ts +42 -0
  114. package/typings/SubmenuPlugin.d.ts +8 -0
  115. package/typings/_classes.d.ts +17 -0
  116. package/typings/_colorPicker.d.ts +60 -0
  117. package/typings/_core.d.ts +55 -0
  118. package/typings/align.d.ts +5 -0
  119. package/{src/plugins/dialog → typings}/audio.d.ts +1 -1
  120. package/typings/backgroundColor.d.ts +5 -0
  121. package/{src/plugins/command → typings}/blockquote.d.ts +1 -1
  122. package/typings/char.d.ts +39 -0
  123. package/typings/component.d.ts +38 -0
  124. package/typings/context.d.ts +39 -0
  125. package/typings/converter.d.ts +33 -0
  126. package/typings/dialog.d.ts +28 -0
  127. package/typings/domUtils.d.ts +361 -0
  128. package/typings/editor.d.ts +7 -0
  129. package/typings/editor.ts +542 -0
  130. package/typings/env.d.ts +70 -0
  131. package/typings/eventManager.d.ts +37 -0
  132. package/typings/events.d.ts +262 -0
  133. package/typings/fileBrowser.d.ts +42 -0
  134. package/typings/fileManager.d.ts +67 -0
  135. package/typings/font.d.ts +5 -0
  136. package/typings/fontColor.d.ts +5 -0
  137. package/typings/fontSize.d.ts +5 -0
  138. package/typings/format.d.ts +191 -0
  139. package/typings/formatBlock.d.ts +5 -0
  140. package/typings/history.d.ts +48 -0
  141. package/typings/horizontalRule.d.ts +5 -0
  142. package/{src/plugins/dialog → typings}/image.d.ts +1 -1
  143. package/{src/plugins/fileBrowser → typings}/imageGallery.d.ts +1 -1
  144. package/typings/index.d.ts +21 -0
  145. package/{src/plugins/modules/index.d.ts → typings/index.modules.d.ts} +3 -3
  146. package/typings/index.plugins.d.ts +58 -0
  147. package/typings/lineHeight.d.ts +5 -0
  148. package/{src/plugins/dialog → typings}/link.d.ts +1 -1
  149. package/typings/list.d.ts +5 -0
  150. package/{src/plugins/dialog → typings}/math.d.ts +1 -1
  151. package/typings/mediaContainer.d.ts +25 -0
  152. package/typings/node.d.ts +57 -0
  153. package/typings/notice.d.ts +16 -0
  154. package/typings/numbers.d.ts +29 -0
  155. package/typings/offset.d.ts +24 -0
  156. package/typings/options.d.ts +589 -0
  157. package/typings/paragraphStyle.d.ts +5 -0
  158. package/typings/resizing.d.ts +141 -0
  159. package/typings/selection.d.ts +94 -0
  160. package/typings/shortcuts.d.ts +13 -0
  161. package/typings/suneditor.d.ts +9 -0
  162. package/typings/table.d.ts +5 -0
  163. package/typings/template.d.ts +5 -0
  164. package/typings/textStyle.d.ts +5 -0
  165. package/typings/toolbar.d.ts +32 -0
  166. package/typings/unicode.d.ts +25 -0
  167. package/{src/plugins/dialog → typings}/video.d.ts +1 -1
  168. package/dist/css/suneditor.min.css +0 -1
  169. package/dist/suneditor.min.js +0 -2
  170. package/src/assets/css/suneditor-contents.css +0 -562
  171. package/src/assets/css/suneditor.css +0 -566
  172. package/src/assets/defaultIcons.js +0 -103
  173. package/src/lang/Lang.d.ts +0 -144
  174. package/src/lang/ckb.d.ts +0 -5
  175. package/src/lang/ckb.js +0 -188
  176. package/src/lang/cs.d.ts +0 -5
  177. package/src/lang/cs.js +0 -188
  178. package/src/lang/da.d.ts +0 -5
  179. package/src/lang/da.js +0 -191
  180. package/src/lang/de.d.ts +0 -5
  181. package/src/lang/de.js +0 -188
  182. package/src/lang/en.d.ts +0 -5
  183. package/src/lang/en.js +0 -188
  184. package/src/lang/es.d.ts +0 -5
  185. package/src/lang/es.js +0 -188
  186. package/src/lang/fa.d.ts +0 -5
  187. package/src/lang/fa.js +0 -188
  188. package/src/lang/fr.d.ts +0 -5
  189. package/src/lang/fr.js +0 -188
  190. package/src/lang/he.d.ts +0 -5
  191. package/src/lang/he.js +0 -188
  192. package/src/lang/index.d.ts +0 -23
  193. package/src/lang/it.d.ts +0 -5
  194. package/src/lang/it.js +0 -188
  195. package/src/lang/ja.d.ts +0 -5
  196. package/src/lang/ja.js +0 -188
  197. package/src/lang/ko.d.ts +0 -5
  198. package/src/lang/ko.js +0 -188
  199. package/src/lang/lv.d.ts +0 -5
  200. package/src/lang/lv.js +0 -188
  201. package/src/lang/nl.d.ts +0 -5
  202. package/src/lang/nl.js +0 -188
  203. package/src/lang/pl.d.ts +0 -5
  204. package/src/lang/pl.js +0 -188
  205. package/src/lang/pt_br.d.ts +0 -5
  206. package/src/lang/pt_br.js +0 -189
  207. package/src/lang/ro.d.ts +0 -5
  208. package/src/lang/ro.js +0 -188
  209. package/src/lang/ru.d.ts +0 -5
  210. package/src/lang/ru.js +0 -188
  211. package/src/lang/se.d.ts +0 -5
  212. package/src/lang/se.js +0 -191
  213. package/src/lang/tr.d.ts +0 -5
  214. package/src/lang/tr.js +0 -191
  215. package/src/lang/ua.d.ts +0 -5
  216. package/src/lang/ua.js +0 -188
  217. package/src/lang/ur.d.ts +0 -5
  218. package/src/lang/ur.js +0 -188
  219. package/src/lang/zh_cn.d.ts +0 -5
  220. package/src/lang/zh_cn.js +0 -187
  221. package/src/lib/constructor.js +0 -954
  222. package/src/lib/context.d.ts +0 -42
  223. package/src/lib/context.js +0 -71
  224. package/src/lib/core.d.ts +0 -1135
  225. package/src/lib/core.js +0 -9395
  226. package/src/lib/history.d.ts +0 -48
  227. package/src/lib/history.js +0 -219
  228. package/src/lib/util.d.ts +0 -678
  229. package/src/lib/util.js +0 -2131
  230. package/src/options.d.ts +0 -608
  231. package/src/plugins/CommandPlugin.d.ts +0 -8
  232. package/src/plugins/DialogPlugin.d.ts +0 -20
  233. package/src/plugins/FileBrowserPlugin.d.ts +0 -30
  234. package/src/plugins/Module.d.ts +0 -15
  235. package/src/plugins/Plugin.d.ts +0 -42
  236. package/src/plugins/SubmenuPlugin.d.ts +0 -8
  237. package/src/plugins/dialog/audio.js +0 -559
  238. package/src/plugins/dialog/image.js +0 -1126
  239. package/src/plugins/dialog/link.js +0 -223
  240. package/src/plugins/dialog/math.js +0 -295
  241. package/src/plugins/dialog/mention.js +0 -242
  242. package/src/plugins/dialog/video.js +0 -979
  243. package/src/plugins/index.d.ts +0 -79
  244. package/src/plugins/modules/_anchor.js +0 -461
  245. package/src/plugins/modules/_colorPicker.d.ts +0 -60
  246. package/src/plugins/modules/_colorPicker.js +0 -201
  247. package/src/plugins/modules/_notice.d.ts +0 -21
  248. package/src/plugins/modules/_notice.js +0 -72
  249. package/src/plugins/modules/_selectMenu.js +0 -119
  250. package/src/plugins/modules/component.d.ts +0 -25
  251. package/src/plugins/modules/component.js +0 -81
  252. package/src/plugins/modules/dialog.d.ts +0 -28
  253. package/src/plugins/modules/dialog.js +0 -175
  254. package/src/plugins/modules/fileBrowser.d.ts +0 -42
  255. package/src/plugins/modules/fileBrowser.js +0 -374
  256. package/src/plugins/modules/fileManager.d.ts +0 -67
  257. package/src/plugins/modules/fileManager.js +0 -326
  258. package/src/plugins/modules/index.js +0 -9
  259. package/src/plugins/modules/resizing.d.ts +0 -154
  260. package/src/plugins/modules/resizing.js +0 -903
  261. package/src/plugins/submenu/align.d.ts +0 -5
  262. package/src/plugins/submenu/align.js +0 -160
  263. package/src/plugins/submenu/font.d.ts +0 -5
  264. package/src/plugins/submenu/font.js +0 -123
  265. package/src/plugins/submenu/fontColor.d.ts +0 -5
  266. package/src/plugins/submenu/fontColor.js +0 -101
  267. package/src/plugins/submenu/fontSize.d.ts +0 -5
  268. package/src/plugins/submenu/fontSize.js +0 -112
  269. package/src/plugins/submenu/formatBlock.d.ts +0 -5
  270. package/src/plugins/submenu/formatBlock.js +0 -273
  271. package/src/plugins/submenu/hiliteColor.d.ts +0 -5
  272. package/src/plugins/submenu/hiliteColor.js +0 -102
  273. package/src/plugins/submenu/horizontalRule.d.ts +0 -5
  274. package/src/plugins/submenu/horizontalRule.js +0 -98
  275. package/src/plugins/submenu/lineHeight.d.ts +0 -5
  276. package/src/plugins/submenu/lineHeight.js +0 -104
  277. package/src/plugins/submenu/list.d.ts +0 -5
  278. package/src/plugins/submenu/list.js +0 -456
  279. package/src/plugins/submenu/paragraphStyle.d.ts +0 -5
  280. package/src/plugins/submenu/paragraphStyle.js +0 -135
  281. package/src/plugins/submenu/table.d.ts +0 -5
  282. package/src/plugins/submenu/table.js +0 -1431
  283. package/src/plugins/submenu/template.d.ts +0 -5
  284. package/src/plugins/submenu/template.js +0 -72
  285. package/src/plugins/submenu/textStyle.d.ts +0 -5
  286. package/src/plugins/submenu/textStyle.js +0 -167
  287. package/src/suneditor.d.ts +0 -9
  288. package/src/suneditor_build.js +0 -18
  289. /package/{src/plugins/dialog → typings}/mention.d.ts +0 -0
@@ -0,0 +1,1129 @@
1
+ /**
2
+ * @fileoverview eventManager class
3
+ */
4
+
5
+ import CoreInjector from '../../editorInjector/_core';
6
+ import { domUtils, unicode, numbers, env, converter } from '../../helper';
7
+ import { _DragHandle } from '../../modules';
8
+
9
+ // event handlers
10
+ import { ButtonsHandler, OnClick_menuTray, OnClick_toolbar } from './eventHandlers/handler_toolbar';
11
+ import { OnMouseDown_wysiwyg, OnMouseUp_wysiwyg, OnClick_wysiwyg, OnMouseMove_wysiwyg, OnMouseLeave_wysiwyg } from './eventHandlers/handler_ww_mouse';
12
+ import { OnInput_wysiwyg, OnKeyDown_wysiwyg, OnKeyUp_wysiwyg } from './eventHandlers/handler_ww_key_input';
13
+ import { OnPaste_wysiwyg, OnCopy_wysiwyg, OnCut_wysiwyg } from './eventHandlers/handler_ww_clipboard';
14
+ import { OnDragOver_wysiwyg, OnDrop_wysiwyg } from './eventHandlers/handler_ww_dragDrop';
15
+
16
+ const { _w, ON_OVER_COMPONENT, isMobile } = env;
17
+
18
+ const EventManager = function (editor) {
19
+ CoreInjector.call(this, editor);
20
+ this._events = [];
21
+ this._onButtonsCheck = new RegExp(`^(${Object.keys(editor.options.get('_defaultStyleTagMap')).join('|')})$`, 'i');
22
+ this._onShortcutKey = false;
23
+ this.isComposing = false; // Old browsers: When there is no 'e.isComposing' in the keyup event.
24
+ this._balloonDelay = null;
25
+ this._wwFrameObserver = null;
26
+ this._toolbarObserver = null;
27
+ this._lineBreakDir = null;
28
+ this._lineBreakComp = null;
29
+ this._formatAttrsTemp = null;
30
+ this._resizeClientY = 0;
31
+ this.__resize_editor = null;
32
+ this.__close_move = null;
33
+ this.__geckoActiveEvent = null;
34
+ this.__scrollparents = [];
35
+ this.__cacheStyleNodes = [];
36
+ this.__selectionSyncEvent = null;
37
+ // input plugins
38
+ this._inputFocus = false;
39
+ this.__inputPlugin = null;
40
+ this.__inputBlurEvent = null;
41
+ this.__inputKeyEvent = null;
42
+ // viewport
43
+ this._vitualKeyboardHeight = 0;
44
+ this.__focusTemp = this.carrierWrapper.querySelector('.__se__focus__temp__');
45
+ this.__retainTimer = null;
46
+ this.__eventDoc = null;
47
+ // this.__scrollID = '';
48
+ };
49
+
50
+ EventManager.prototype = {
51
+ /**
52
+ * @description Register for an event.
53
+ * Only events registered with this method are unregistered or re-registered when methods such as 'setOptions', 'destroy' are called.
54
+ * @param {Element|Array.<Element>} target Target element
55
+ * @param {string} type Event type
56
+ * @param {Function} listener Event handler
57
+ * @param {boolean|undefined} useCapture Event useCapture option
58
+ * @return {boolean}
59
+ */
60
+ addEvent(target, type, listener, useCapture) {
61
+ if (!target) return false;
62
+ if (!numbers.is(target.length) || target.nodeName || (!Array.isArray(target) && target.length < 1)) target = [target];
63
+ if (target.length === 0) return false;
64
+
65
+ const len = target.length;
66
+ for (let i = 0; i < len; i++) {
67
+ target[i].addEventListener(type, listener, useCapture);
68
+ this._events.push({
69
+ target: target[i],
70
+ type: type,
71
+ handler: listener,
72
+ useCapture: useCapture
73
+ });
74
+ }
75
+
76
+ return {
77
+ target: len > 1 ? target : target[0],
78
+ type: type,
79
+ listener,
80
+ handler: listener,
81
+ useCapture: useCapture
82
+ };
83
+ },
84
+
85
+ /**
86
+ * @description Remove event
87
+ * @param {object} params { target, type, listener, useCapture } = this.addEvent()
88
+ * @returns {null}
89
+ */
90
+ removeEvent(params) {
91
+ if (!params) return;
92
+
93
+ let target = params.target;
94
+ const type = params.type;
95
+ const listener = params.listener;
96
+ const useCapture = params.useCapture;
97
+
98
+ if (!target) return false;
99
+ if (!numbers.is(target.length) || target.nodeName || (!Array.isArray(target) && target.length < 1)) target = [target];
100
+ if (target.length === 0) return false;
101
+
102
+ for (let i = 0, len = target.length; i < len; i++) {
103
+ target[i].removeEventListener(type, listener, useCapture);
104
+ }
105
+
106
+ return null;
107
+ },
108
+
109
+ /**
110
+ * @description Add an event to document.
111
+ * When created as an Iframe, the same event is added to the document in the Iframe.
112
+ * @param {string} type Event type
113
+ * @param {Function} listener Event listener
114
+ * @param {boolean|undefined} useCapture Use event capture
115
+ * @return {type, listener, useCapture}
116
+ */
117
+ addGlobalEvent(type, listener, useCapture) {
118
+ if (this.editor.frameOptions.get('iframe')) {
119
+ this.editor.frameContext.get('_ww').addEventListener(type, listener, useCapture);
120
+ }
121
+ this._w.addEventListener(type, listener, useCapture);
122
+ return {
123
+ type: type,
124
+ listener: listener,
125
+ useCapture: useCapture
126
+ };
127
+ },
128
+
129
+ /**
130
+ * @description Remove events from document.
131
+ * When created as an Iframe, the event of the document inside the Iframe is also removed.
132
+ * @param {string|object} type Event type
133
+ * @param {Function} listener Event listener
134
+ * @param {boolean|undefined} useCapture Use event capture
135
+ */
136
+ removeGlobalEvent(type, listener, useCapture) {
137
+ if (!type) return;
138
+
139
+ if (typeof type === 'object') {
140
+ listener = type.listener;
141
+ useCapture = type.useCapture;
142
+ type = type.type;
143
+ }
144
+ if (this.editor.frameOptions.get('iframe')) {
145
+ this.editor.frameContext.get('_ww').removeEventListener(type, listener, useCapture);
146
+ }
147
+ this._w.removeEventListener(type, listener, useCapture);
148
+ },
149
+
150
+ /**
151
+ * @description Activates the corresponding button with the tags information of the current cursor position,
152
+ * such as 'bold', 'underline', etc., and executes the 'active' method of the plugins.
153
+ * @param {Node|null} selectionNode selectionNode
154
+ * @returns {Node|undefined} selectionNode
155
+ */
156
+ applyTagEffect(selectionNode) {
157
+ selectionNode = selectionNode || this.selection.getNode();
158
+ if (selectionNode === this.editor.effectNode) return;
159
+ this.editor.effectNode = selectionNode;
160
+
161
+ const marginDir = this.options.get('_rtl') ? 'marginRight' : 'marginLeft';
162
+ const plugins = this.plugins;
163
+ const commandTargets = this.editor.commandTargets;
164
+ const classOnCheck = this._onButtonsCheck;
165
+ const styleCommand = this.options.get('_styleCommandMap');
166
+ const commandMapNodes = [];
167
+ const currentNodes = [];
168
+
169
+ const styleTags = this.options.get('_textStyleTags');
170
+ const styleNodes = [];
171
+
172
+ const activeCommands = this.editor.activeCommands;
173
+ const cLen = activeCommands.length;
174
+ let nodeName = '';
175
+
176
+ while (selectionNode.firstChild) {
177
+ selectionNode = selectionNode.firstChild;
178
+ }
179
+
180
+ if (this.component.is(selectionNode) && !this.component.__selectionSelected) {
181
+ const component = this.component.get(selectionNode);
182
+ this.component.select(component.target, component.pluginName, false);
183
+ return;
184
+ }
185
+
186
+ const fc = this.editor.frameContext;
187
+ const notReadonly = !fc.get('isReadOnly');
188
+ for (let element = selectionNode; !domUtils.isWysiwygFrame(element); element = element.parentNode) {
189
+ if (!element) break;
190
+ if (element.nodeType !== 1 || domUtils.isBreak(element)) continue;
191
+ if (this._isNonFocusNode(element)) {
192
+ this.editor.blur();
193
+ return;
194
+ }
195
+
196
+ nodeName = element.nodeName.toLowerCase();
197
+ currentNodes.push(nodeName);
198
+ if (styleTags.includes(nodeName) && !this.format.isLine(nodeName)) styleNodes.push(element);
199
+
200
+ /* Active plugins */
201
+ if (notReadonly) {
202
+ for (let c = 0, name; c < cLen; c++) {
203
+ name = activeCommands[c];
204
+ if (
205
+ !commandMapNodes.includes(name) &&
206
+ commandTargets.get(name) &&
207
+ commandTargets.get(name).filter((e) => {
208
+ return plugins[name]?.active(element, e);
209
+ }).length > 0
210
+ ) {
211
+ commandMapNodes.push(name);
212
+ }
213
+ }
214
+ }
215
+
216
+ /** indent, outdent */
217
+ if (this.format.isLine(element)) {
218
+ /* Outdent */
219
+ if (!commandMapNodes.includes('outdent') && commandTargets.has('outdent') && (domUtils.isListCell(element) || (element.style[marginDir] && numbers.get(element.style[marginDir], 0) > 0))) {
220
+ if (
221
+ commandTargets.get('outdent').filter(function (e) {
222
+ if (domUtils.isImportantDisabled(e)) return false;
223
+ e.removeAttribute('disabled');
224
+ return true;
225
+ }).length > 0
226
+ ) {
227
+ commandMapNodes.push('outdent');
228
+ }
229
+ }
230
+ /* Indent */
231
+ if (!commandMapNodes.includes('indent') && commandTargets.has('indent')) {
232
+ const indentDisable = domUtils.isListCell(element) && !element.previousElementSibling;
233
+ if (
234
+ commandTargets.get('indent').filter(function (e) {
235
+ if (domUtils.isImportantDisabled(e)) return false;
236
+ if (indentDisable) {
237
+ e.setAttribute('disabled', true);
238
+ } else {
239
+ e.removeAttribute('disabled');
240
+ }
241
+ return true;
242
+ }).length > 0
243
+ ) {
244
+ commandMapNodes.push('indent');
245
+ }
246
+ }
247
+
248
+ continue;
249
+ }
250
+
251
+ /** default active buttons [strong, ins, em, del, sub, sup] */
252
+ if (classOnCheck.test(nodeName)) {
253
+ nodeName = styleCommand[nodeName] || nodeName;
254
+ commandMapNodes.push(nodeName);
255
+ domUtils.addClass(commandTargets.get(nodeName), 'active');
256
+ }
257
+ }
258
+
259
+ this._setKeyEffect(commandMapNodes);
260
+
261
+ // cache style nodes
262
+ this.__cacheStyleNodes = styleNodes.reverse();
263
+
264
+ /** save current nodes */
265
+ this.status.currentNodes = currentNodes.reverse();
266
+ this.status.currentNodesMap = commandMapNodes;
267
+
268
+ /** Displays the current node structure to statusbar */
269
+ if (this.editor.frameOptions.get('statusbar_showPathLabel') && fc.get('navigation')) {
270
+ fc.get('navigation').textContent = this.options.get('_rtl') ? this.status.currentNodes.reverse().join(' < ') : this.status.currentNodes.join(' > ');
271
+ }
272
+
273
+ return selectionNode;
274
+ },
275
+
276
+ /**
277
+ * @description Gives an active effect when the mouse down event is blocked. (Used when "env.isGecko" is true)
278
+ * @param {Element} target Target element
279
+ * @private
280
+ */
281
+ _injectActiveEvent(target) {
282
+ domUtils.addClass(target, '__se__active');
283
+ this.__geckoActiveEvent = this.addGlobalEvent('mouseup', () => {
284
+ domUtils.removeClass(target, '__se__active');
285
+ this.__geckoActiveEvent = this.removeGlobalEvent(this.__geckoActiveEvent);
286
+ });
287
+ },
288
+
289
+ /**
290
+ * @description remove class, display text.
291
+ * @param {Array|null} ignoredList Igonred button list
292
+ * @private
293
+ */
294
+ _setKeyEffect(ignoredList) {
295
+ const activeCommands = this.editor.activeCommands;
296
+ const commandTargets = this.editor.commandTargets;
297
+ const plugins = this.plugins;
298
+ for (let i = 0, len = activeCommands.length, k, c, p; i < len; i++) {
299
+ k = activeCommands[i];
300
+ if (ignoredList.includes(k) || !(c = commandTargets.get(k))) continue;
301
+
302
+ p = plugins[k];
303
+ for (let j = 0, jLen = c.length, e; j < jLen; j++) {
304
+ e = c[j];
305
+ if (!e || e.length === 0) continue;
306
+ if (p) {
307
+ p.active(null, e);
308
+ } else if (/^outdent$/i.test(k)) {
309
+ if (!domUtils.isImportantDisabled(e)) e.setAttribute('disabled', true);
310
+ } else if (/^indent$/i.test(k)) {
311
+ if (!domUtils.isImportantDisabled(e)) e.removeAttribute('disabled');
312
+ } else {
313
+ domUtils.removeClass(e, 'active');
314
+ }
315
+ }
316
+ }
317
+ },
318
+
319
+ _showToolbarBalloonDelay() {
320
+ if (this._balloonDelay) {
321
+ _w.clearTimeout(this._balloonDelay);
322
+ }
323
+
324
+ this._balloonDelay = _w.setTimeout(() => {
325
+ _w.clearTimeout(this._balloonDelay);
326
+ this._balloonDelay = null;
327
+ if (this.editor.isSubBalloon) this.subToolbar._showBalloon();
328
+ else this.toolbar._showBalloon();
329
+ }, 250);
330
+ },
331
+
332
+ _toggleToolbarBalloon() {
333
+ this.selection._init();
334
+ const range = this.selection.getRange();
335
+ const hasSubMode = this.options.has('_subMode');
336
+
337
+ if (this.menu._bindControllersOff || (!(hasSubMode ? this.editor.isSubBalloonAlways : this.editor.isBalloonAlways) && range.collapsed)) {
338
+ if (hasSubMode) this._hideToolbar_sub();
339
+ else this._hideToolbar();
340
+ } else {
341
+ if (hasSubMode) this.subToolbar._showBalloon(range);
342
+ else this.toolbar._showBalloon(range);
343
+ }
344
+ },
345
+
346
+ _hideToolbar() {
347
+ if (!this.editor._notHideToolbar && !this.editor.frameContext.get('isFullScreen')) {
348
+ this.toolbar.hide();
349
+ }
350
+ },
351
+
352
+ _hideToolbar_sub() {
353
+ if (this.subToolbar && !this.editor._notHideToolbar) {
354
+ this.subToolbar.hide();
355
+ }
356
+ },
357
+
358
+ _isNonFocusNode(node) {
359
+ return node.nodeType === 1 && node.getAttribute('data-se-non-focus') === 'true';
360
+ },
361
+
362
+ _isUneditableNode(range, isFront) {
363
+ const container = isFront ? range.startContainer : range.endContainer;
364
+ const offset = isFront ? range.startOffset : range.endOffset;
365
+ const siblingKey = isFront ? 'previousSibling' : 'nextSibling';
366
+ const isElement = container.nodeType === 1;
367
+ let siblingNode;
368
+
369
+ if (isElement) {
370
+ siblingNode = this._isUneditableNode_getSibling(container.childNodes[offset], siblingKey, container);
371
+ return siblingNode && siblingNode.nodeType === 1 && siblingNode.getAttribute('contenteditable') === 'false' ? siblingNode : null;
372
+ } else {
373
+ siblingNode = this._isUneditableNode_getSibling(container, siblingKey, container);
374
+ return domUtils.isEdgePoint(container, offset, isFront ? 'front' : 'end') && siblingNode && siblingNode.nodeType === 1 && siblingNode.getAttribute('contenteditable') === 'false' ? siblingNode : null;
375
+ }
376
+ },
377
+
378
+ _isUneditableNode_getSibling(selectNode, siblingKey, container) {
379
+ if (!selectNode) return null;
380
+ let siblingNode = selectNode[siblingKey];
381
+
382
+ if (!siblingNode) {
383
+ siblingNode = this.format.getLine(container);
384
+ siblingNode = siblingNode ? siblingNode[siblingKey] : null;
385
+ if (siblingNode && !this.component.is(siblingNode)) siblingNode = siblingKey === 'previousSibling' ? siblingNode.firstChild : siblingNode.lastChild;
386
+ else return null;
387
+ }
388
+
389
+ return siblingNode;
390
+ },
391
+
392
+ // FireFox - table delete, Chrome - image, video, audio
393
+ _hardDelete() {
394
+ const range = this.selection.getRange();
395
+ const sc = range.startContainer;
396
+ const ec = range.endContainer;
397
+
398
+ // table
399
+ const sCell = this.format.getBlock(sc);
400
+ const eCell = this.format.getBlock(ec);
401
+ const sIsCell = domUtils.isTableCell(sCell);
402
+ const eIsCell = domUtils.isTableCell(eCell);
403
+ const ancestor = range.commonAncestorContainer;
404
+ if (((sIsCell && !sCell.previousElementSibling && !sCell.parentElement.previousElementSibling) || (eIsCell && !eCell.nextElementSibling && !eCell.parentElement.nextElementSibling)) && sCell !== eCell) {
405
+ if (!sIsCell) {
406
+ domUtils.removeItem(domUtils.getParentElement(eCell, (current) => ancestor === current.parentNode));
407
+ } else if (!eIsCell) {
408
+ domUtils.removeItem(domUtils.getParentElement(sCell, (current) => ancestor === current.parentNode));
409
+ } else {
410
+ domUtils.removeItem(domUtils.getParentElement(sCell, (current) => ancestor === current.parentNode));
411
+ this.editor._nativeFocus();
412
+ return true;
413
+ }
414
+ }
415
+
416
+ // component
417
+ const sComp = sc.nodeType === 1 ? domUtils.getParentElement(sc, '.se-component') : null;
418
+ const eComp = ec.nodeType === 1 ? domUtils.getParentElement(ec, '.se-component') : null;
419
+ if (sComp) domUtils.removeItem(sComp);
420
+ if (eComp) domUtils.removeItem(eComp);
421
+
422
+ return false;
423
+ },
424
+
425
+ /**
426
+ * @description If there is no default format, add a line and move 'selection'.
427
+ * @param {string|null} formatName Format tag name (default: 'P')
428
+ * @private
429
+ */
430
+ _setDefaultLine(formatName) {
431
+ if (this.editor._fileManager.pluginRegExp.test(this.editor.currentControllerName)) return;
432
+
433
+ const range = this.selection.getRange();
434
+ const commonCon = range.commonAncestorContainer;
435
+ const startCon = range.startContainer;
436
+ const rangeEl = this.format.getBlock(commonCon, null);
437
+ let focusNode, offset, format;
438
+
439
+ if (rangeEl) {
440
+ format = domUtils.createElement(formatName || this.options.get('defaultLine'));
441
+ format.innerHTML = rangeEl.innerHTML;
442
+ if (format.childNodes.length === 0) format.innerHTML = unicode.zeroWidthSpace;
443
+
444
+ rangeEl.innerHTML = format.outerHTML;
445
+ format = rangeEl.firstChild;
446
+ focusNode = domUtils.getEdgeChildNodes(format, null).sc;
447
+
448
+ if (!focusNode) {
449
+ focusNode = domUtils.createTextNode(unicode.zeroWidthSpace);
450
+ format.insertBefore(focusNode, format.firstChild);
451
+ }
452
+
453
+ offset = focusNode.textContent.length;
454
+ this.selection.setRange(focusNode, offset, focusNode, offset);
455
+ return;
456
+ }
457
+
458
+ const fileComponent = domUtils.getParentElement(commonCon, this.component.is.bind(this.component));
459
+ if (fileComponent && commonCon.nodeType === 3) {
460
+ const siblingEl = commonCon.nextElementSibling ? fileComponent : fileComponent.nextElementSibling;
461
+ const el = domUtils.createElement(this.options.get('defaultLine'), null, commonCon);
462
+ fileComponent.parentElement.insertBefore(el, siblingEl);
463
+ this.editor.focusEdge(el);
464
+ return;
465
+ } else if (commonCon.nodeType === 1 && commonCon.getAttribute('data-se-embed') === 'true') {
466
+ let el = commonCon.nextElementSibling;
467
+ if (!this.format.isLine(el)) el = this.format.addLine(commonCon, this.options.get('defaultLine'));
468
+ this.selection.setRange(el.firstChild, 0, el.firstChild, 0);
469
+ return;
470
+ }
471
+
472
+ if ((this.format.isBlock(startCon) || domUtils.isWysiwygFrame(startCon)) && (this.component.is(startCon.children[range.startOffset]) || this.component.is(startCon.children[range.startOffset - 1]))) return;
473
+ if (domUtils.getParentElement(commonCon, domUtils.isExcludeFormat)) return null;
474
+
475
+ if (this.format.isBlock(commonCon) && commonCon.childNodes.length <= 1) {
476
+ let br = null;
477
+ if (commonCon.childNodes.length === 1 && domUtils.isBreak(commonCon.firstChild)) {
478
+ br = commonCon.firstChild;
479
+ } else {
480
+ br = domUtils.createTextNode(unicode.zeroWidthSpace);
481
+ commonCon.appendChild(br);
482
+ }
483
+
484
+ this.selection.setRange(br, 1, br, 1);
485
+ return;
486
+ }
487
+
488
+ try {
489
+ if (commonCon.nodeType === 3) {
490
+ format = domUtils.createElement(formatName || this.options.get('defaultLine'));
491
+ commonCon.parentNode.insertBefore(format, commonCon);
492
+ format.appendChild(commonCon);
493
+ }
494
+
495
+ if (domUtils.isBreak(format.nextSibling)) domUtils.removeItem(format.nextSibling);
496
+ if (domUtils.isBreak(format.previousSibling)) domUtils.removeItem(format.previousSibling);
497
+ if (domUtils.isBreak(focusNode)) {
498
+ const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
499
+ focusNode.parentNode.insertBefore(zeroWidth, focusNode);
500
+ focusNode = zeroWidth;
501
+ }
502
+ } catch (e) {
503
+ this.editor.execCommand('formatBlock', false, formatName || this.options.get('defaultLine'));
504
+ this.selection.removeRange();
505
+ this.selection._init();
506
+ }
507
+
508
+ if (format) {
509
+ if (domUtils.isBreak(format.nextSibling)) domUtils.removeItem(format.nextSibling);
510
+ if (domUtils.isBreak(format.previousSibling)) domUtils.removeItem(format.previousSibling);
511
+ if (domUtils.isBreak(focusNode)) {
512
+ const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
513
+ focusNode.parentNode.insertBefore(zeroWidth, focusNode);
514
+ focusNode = zeroWidth;
515
+ }
516
+ }
517
+
518
+ this.editor.effectNode = null;
519
+ this.editor._nativeFocus();
520
+ },
521
+
522
+ _dataTransferAction(type, e, data, frameContext) {
523
+ const plainText = data.getData('text/plain');
524
+ const cleanData = data.getData('text/html');
525
+ try {
526
+ this._setClipboardData(type, e, plainText, cleanData, data, frameContext);
527
+ e.preventDefault();
528
+ e.stopPropagation();
529
+ return false;
530
+ } catch (err) {
531
+ console.warn('[SUNEDITOR.paste.error]', err);
532
+ }
533
+ },
534
+
535
+ async _setClipboardData(type, e, plainText, cleanData, data, frameContext) {
536
+ // MS word, OneNode, Excel
537
+ const MSData = /class=["']*Mso(Normal|List)/i.test(cleanData) || /content=["']*Word.Document/i.test(cleanData) || /content=["']*OneNote.File/i.test(cleanData) || /content=["']*Excel.Sheet/i.test(cleanData);
538
+ const onlyText = !cleanData;
539
+
540
+ if (!onlyText) {
541
+ cleanData = cleanData.replace(/^<html>\r?\n?<body>\r?\n?\x3C!--StartFragment-->|\x3C!--EndFragment-->\r?\n?<\/body>\r?\n?<\/html>$/g, '');
542
+ if (MSData) {
543
+ cleanData = cleanData.replace(/\n/g, ' ');
544
+ plainText = plainText.replace(/\n/g, ' ');
545
+ }
546
+ cleanData = this.html.clean(cleanData, false, null, null);
547
+ } else {
548
+ cleanData = converter.htmlToEntity(plainText).replace(/\n/g, '<br>');
549
+ }
550
+
551
+ const maxCharCount = this.char.test(this.editor.frameOptions.get('charCounter_type') === 'byte-html' ? cleanData : plainText, false);
552
+ // user event - paste
553
+ if (type === 'paste') {
554
+ const value = await this.triggerEvent('onPaste', { frameContext, event: e, cleanData, maxCharCount });
555
+ if (value === false) {
556
+ return false;
557
+ } else if (typeof value === 'string') {
558
+ if (!value) return false;
559
+ cleanData = value;
560
+ }
561
+ }
562
+ // user event - drop
563
+ if (type === 'drop') {
564
+ const value = await this.triggerEvent('onDrop', { frameContext, event: e, cleanData, maxCharCount });
565
+ if (value === false) {
566
+ return false;
567
+ } else if (typeof value === 'string') {
568
+ if (!value) return false;
569
+ cleanData = value;
570
+ }
571
+ }
572
+
573
+ // files
574
+ const files = data.files;
575
+ if (files.length > 0 && !MSData) {
576
+ for (let i = 0, len = files.length; i < len; i++) {
577
+ this._callPluginEvent('onPastAndDrop', { frameContext, event: e, file: files[i] });
578
+ }
579
+
580
+ return false;
581
+ }
582
+
583
+ if (!maxCharCount) {
584
+ return false;
585
+ }
586
+
587
+ if (cleanData) {
588
+ this.html.insert(cleanData, false, true, true);
589
+ return false;
590
+ }
591
+ },
592
+
593
+ _addCommonEvents() {
594
+ const buttonsHandler = ButtonsHandler.bind(this);
595
+ const toolbarHandler = OnClick_toolbar.bind(this);
596
+
597
+ /** menu event */
598
+ this.addEvent(this.context.get('menuTray'), 'mousedown', buttonsHandler, false);
599
+ this.addEvent(this.context.get('menuTray'), 'click', OnClick_menuTray.bind(this), true);
600
+
601
+ /** toolbar event */
602
+ this.addEvent(this.context.get('toolbar.main'), 'mousedown', buttonsHandler, false);
603
+ this.addEvent(this.context.get('toolbar.main'), 'click', toolbarHandler, false);
604
+ // subToolbar
605
+ if (this.options.has('_subMode')) {
606
+ this.addEvent(this.context.get('toolbar.sub.main'), 'mousedown', buttonsHandler, false);
607
+ this.addEvent(this.context.get('toolbar.sub.main'), 'click', toolbarHandler, false);
608
+ }
609
+
610
+ /** set response toolbar */
611
+ this.toolbar._setResponsive();
612
+
613
+ /** observer */
614
+ if (env.isResizeObserverSupported) {
615
+ this._toolbarObserver = new ResizeObserver(() => {
616
+ _w.setTimeout(() => {
617
+ this.toolbar.resetResponsiveToolbar();
618
+ }, 0);
619
+ });
620
+ this._wwFrameObserver = new ResizeObserver((entries) => {
621
+ _w.setTimeout(() => {
622
+ entries.forEach((e) => {
623
+ this.editor.__callResizeFunction(this.editor.frameRoots.get(e.target.getAttribute('data-root-key')), -1, e);
624
+ });
625
+ }, 0);
626
+ });
627
+ }
628
+
629
+ /** window event */
630
+ this.addEvent(_w, 'resize', OnResize_window.bind(this), false);
631
+ this.addEvent(_w, 'scroll', OnScroll_window.bind(this), false);
632
+ if (env.isMobile) {
633
+ this.addEvent(_w.visualViewport, 'resize', OnResize_viewport.bind(this), false);
634
+ this.addEvent(_w.visualViewport, 'scroll', OnScroll_viewport.bind(this), false);
635
+ this.addEvent(_w.visualViewport, 'scroll', converter.debounce(OnScroll_viewport_onKeyboardOn.bind(this), 200), false);
636
+ }
637
+ },
638
+
639
+ _addFrameEvents(fc) {
640
+ const isIframe = fc.get('options').get('iframe');
641
+ const eventWysiwyg = isIframe ? fc.get('_ww') : fc.get('wysiwyg');
642
+ fc.set('eventWysiwyg', eventWysiwyg);
643
+ const codeArea = fc.get('code');
644
+ const dragCursor = this.editor.carrierWrapper.querySelector('.se-drag-cursor');
645
+
646
+ /** editor area */
647
+ const wwMouseMove = OnMouseMove_wysiwyg.bind(this, fc);
648
+ this.addEvent(eventWysiwyg, 'mousemove', wwMouseMove, false);
649
+ this.addEvent(eventWysiwyg, 'mouseleave', OnMouseLeave_wysiwyg.bind(this, fc), false);
650
+ this.addEvent(eventWysiwyg, 'mousedown', OnMouseDown_wysiwyg.bind(this, fc), false);
651
+ this.addEvent(eventWysiwyg, 'mouseup', OnMouseUp_wysiwyg.bind(this, fc), false);
652
+ this.addEvent(eventWysiwyg, 'click', OnClick_wysiwyg.bind(this, fc), false);
653
+ this.addEvent(eventWysiwyg, 'input', OnInput_wysiwyg.bind(this, fc), false);
654
+ this.addEvent(eventWysiwyg, 'keydown', OnKeyDown_wysiwyg.bind(this, fc), false);
655
+ this.addEvent(eventWysiwyg, 'keyup', OnKeyUp_wysiwyg.bind(this, fc), false);
656
+ this.addEvent(eventWysiwyg, 'paste', OnPaste_wysiwyg.bind(this, fc), false);
657
+ this.addEvent(eventWysiwyg, 'copy', OnCopy_wysiwyg.bind(this, fc), false);
658
+ this.addEvent(eventWysiwyg, 'cut', OnCut_wysiwyg.bind(this, fc), false);
659
+ this.addEvent(eventWysiwyg, 'dragover', OnDragOver_wysiwyg.bind(this, dragCursor, isIframe ? this.editor.frameContext.get('topArea') : null), false);
660
+ this.addEvent(eventWysiwyg, 'drop', OnDrop_wysiwyg.bind(this, fc, dragCursor), false);
661
+ this.addEvent(eventWysiwyg, 'scroll', OnScroll_wysiwyg.bind(this, fc, eventWysiwyg), { passive: true, useCapture: false });
662
+ this.addEvent(eventWysiwyg, 'focus', OnFocus_wysiwyg.bind(this, fc), false);
663
+ this.addEvent(eventWysiwyg, 'blur', OnBlur_wysiwyg.bind(this, fc), false);
664
+ this.addEvent(codeArea, 'mousedown', OnFocus_code.bind(this, fc), false);
665
+
666
+ /** drag handle */
667
+ const dragHandle = this.editor.frameContext.get('wrapper').querySelector('.se-drag-handle');
668
+ this.addEvent(
669
+ dragHandle,
670
+ 'wheel',
671
+ (event) => {
672
+ event.preventDefault();
673
+ this.component.deselect();
674
+ },
675
+ false
676
+ );
677
+
678
+ /** line breaker */
679
+ this.addEvent(
680
+ [fc.get('lineBreaker_t'), fc.get('lineBreaker_b')],
681
+ 'mousedown',
682
+ (e) => {
683
+ e.preventDefault();
684
+ },
685
+ false
686
+ );
687
+ this.addEvent(fc.get('lineBreaker_t'), 'mousedown', DisplayLineBreak.bind(this, 't'), false);
688
+ this.addEvent(fc.get('lineBreaker_b'), 'mousedown', DisplayLineBreak.bind(this, 'b'), false);
689
+
690
+ /** Events are registered mobile. */
691
+ if (isMobile) {
692
+ this.addEvent(eventWysiwyg, 'touchstart', wwMouseMove, {
693
+ passive: true,
694
+ useCapture: false
695
+ });
696
+ }
697
+
698
+ /** code view area auto line */
699
+ if (!this.options.get('hasCodeMirror')) {
700
+ const codeNumbers = fc.get('codeNumbers');
701
+ const cvAuthHeight = this.viewer._codeViewAutoHeight.bind(this.viewer, fc.get('code'), codeNumbers, this.editor.frameOptions.get('height') === 'auto');
702
+
703
+ this.addEvent(codeArea, 'keydown', cvAuthHeight, false);
704
+ this.addEvent(codeArea, 'keyup', cvAuthHeight, false);
705
+ this.addEvent(codeArea, 'paste', cvAuthHeight, false);
706
+
707
+ /** code view numbers */
708
+ if (codeNumbers) this.addEvent(codeArea, 'scroll', this.viewer._scrollLineNumbers.bind(codeArea, codeNumbers), false);
709
+ }
710
+
711
+ if (fc.has('statusbar')) this.__addStatusbarEvent(fc, fc.get('options'));
712
+
713
+ const OnScrollAbs = OnScroll_Abs.bind(this);
714
+ let scrollParent = fc.get('originElement');
715
+ while ((scrollParent = domUtils.getScrollParent(scrollParent.parentElement))) {
716
+ this.__scrollparents.push(scrollParent);
717
+ this.addEvent(scrollParent, 'scroll', OnScrollAbs, false);
718
+ }
719
+
720
+ /** focus temp (mobile) */
721
+ this.addEvent(this.__focusTemp, 'focus', (e) => e.preventDefault(), false);
722
+
723
+ /** document event */
724
+ if (this.__eventDoc !== fc.get('_wd')) {
725
+ this.__eventDoc = fc.get('_wd');
726
+ this.addEvent(this.__eventDoc, 'selectionchange', OnSelectionchange_document.bind(this, this.__eventDoc), false);
727
+ }
728
+ },
729
+
730
+ __addStatusbarEvent(fc, fo) {
731
+ if (/\d+/.test(fo.get('height')) && fo.get('statusbar_resizeEnable')) {
732
+ fo.set('__statusbarEvent', this.addEvent(fc.get('statusbar'), 'mousedown', OnMouseDown_statusbar.bind(this), false));
733
+ } else {
734
+ domUtils.addClass(fc.get('statusbar'), 'se-resizing-none');
735
+ }
736
+ },
737
+
738
+ _removeAllEvents() {
739
+ for (let i = 0, len = this._events.length, e; i < len; i++) {
740
+ e = this._events[i];
741
+ e.target.removeEventListener(e.type, e.handler, e.useCapture);
742
+ }
743
+
744
+ this._events = [];
745
+
746
+ if (this._wwFrameObserver) {
747
+ this._wwFrameObserver.disconnect();
748
+ this._wwFrameObserver = null;
749
+ }
750
+
751
+ if (this._toolbarObserver) {
752
+ this._toolbarObserver.disconnect();
753
+ this._toolbarObserver = null;
754
+ }
755
+ },
756
+
757
+ _moveContainer(eventWysiwyg) {
758
+ const y = eventWysiwyg.scrollY || eventWysiwyg.scrollTop || 0;
759
+ const x = eventWysiwyg.scrollX || eventWysiwyg.scrollLeft || 0;
760
+
761
+ if (this.editor.isBalloon) {
762
+ this.context.get('toolbar.main').style.top = this.toolbar._balloonOffset.top - y + 'px';
763
+ this.context.get('toolbar.main').style.left = this.toolbar._balloonOffset.left - x + 'px';
764
+ } else if (this.editor.isSubBalloon) {
765
+ this.context.get('toolbar.sub.main').style.top = this.subToolbar._balloonOffset.top - y + 'px';
766
+ this.context.get('toolbar.sub.main').style.left = this.subToolbar._balloonOffset.left - x + 'px';
767
+ }
768
+
769
+ if (this.editor._controllerTargetContext !== this.editor.frameContext.get('topArea')) {
770
+ this.editor._offCurrentController();
771
+ }
772
+
773
+ if (this.editor._lineBreaker_t) {
774
+ const t_style = this.editor._lineBreaker_t.style;
775
+ if (t_style.display !== 'none') {
776
+ const t_offset = (this.editor._lineBreaker_t.getAttribute('data-offset') || ',').split(',');
777
+ t_style.top = numbers.get(t_style.top, 0) - (y - numbers.get(t_offset[0], 0)) + 'px';
778
+ t_style.left = numbers.get(t_style.left, 0) - (x - numbers.get(t_offset[1], 0)) + 'px';
779
+ this.editor._lineBreaker_t.setAttribute('data-offset', y + ',' + x);
780
+ }
781
+ }
782
+
783
+ if (this.editor._lineBreaker_b) {
784
+ const b_style = this.editor._lineBreaker_b.style;
785
+ if (b_style.display !== 'none') {
786
+ const b_offset = (this.editor._lineBreaker_b.getAttribute('data-offset') || ',').split(',');
787
+ b_style.top = numbers.get(b_style.top, 0) - (y - numbers.get(b_offset[0], 0)) + 'px';
788
+ b_style[b_offset[1]] = numbers.get(b_style[b_offset[1]], 0) - (x - numbers.get(b_offset[2], 0)) + 'px';
789
+ this.editor._lineBreaker_b.setAttribute('data-offset', y + ',' + b_offset[1] + ',' + x);
790
+ }
791
+ }
792
+
793
+ const openCont = this.editor.opendControllers;
794
+ for (let i = 0; i < openCont.length; i++) {
795
+ if (!openCont[i].notInCarrier) continue;
796
+ openCont[i].form.style.top = openCont[i].inst.__offset.top - y + 'px';
797
+ openCont[i].form.style.left = openCont[i].inst.__offset.left - x + 'px';
798
+ }
799
+ },
800
+
801
+ _scrollContainer() {
802
+ const openCont = this.editor.opendControllers;
803
+ if (!openCont.length) return;
804
+
805
+ this.__rePositionController(openCont);
806
+
807
+ // if (isMobile) {
808
+ // this.__rePositionController(openCont);
809
+ // } else {
810
+ // if (this.__scrollID) _w.clearTimeout(this.__scrollID);
811
+
812
+ // if (_DragHandle.get('__dragHandler') && !domUtils.hasClass(_DragHandle.get('__dragHandler'), 'se-drag-handle-full')) _DragHandle.get('__dragHandler').style.display = 'none';
813
+
814
+ // for (let i = 0; i < openCont.length; i++) {
815
+ // if (openCont[i].notInCarrier) continue;
816
+ // openCont[i].inst?.hide();
817
+ // }
818
+
819
+ // this.__scrollID = _w.setTimeout(() => {
820
+ // _w.clearTimeout(this.__scrollID);
821
+ // this.__scrollID = '';
822
+ // this.__rePositionController(openCont);
823
+ // }, 250);
824
+ // }
825
+ },
826
+
827
+ __rePositionController(cont) {
828
+ if (_DragHandle.get('__dragMove')) _DragHandle.get('__dragMove')();
829
+ for (let i = 0; i < cont.length; i++) {
830
+ if (cont[i].notInCarrier) continue;
831
+ cont[i].inst?.show();
832
+ }
833
+ },
834
+
835
+ _resetFrameStatus() {
836
+ if (!env.isResizeObserverSupported) {
837
+ this.toolbar.resetResponsiveToolbar();
838
+ if (this.options.get('_subMode')) this.subToolbar.resetResponsiveToolbar();
839
+ }
840
+
841
+ const toolbar = this.context.get('toolbar.main');
842
+ const isToolbarHidden = toolbar.style.display === 'none' || (this.editor.isInline && !this.toolbar._inlineToolbarAttr.isShow);
843
+ if (toolbar.offsetWidth === 0 && !isToolbarHidden) return;
844
+
845
+ const fc = this.editor.frameContext;
846
+ const fileBrowser = fc.get('fileBrowser');
847
+ if (fileBrowser && fileBrowser.area.style.display === 'block') {
848
+ fileBrowser.body.style.maxHeight = domUtils.getClientSize().h - fileBrowser.header.offsetHeight - 50 + 'px';
849
+ }
850
+
851
+ if (this.menu.currentDropdownActiveButton && this.menu.currentDropdown) {
852
+ this.menu._setMenuPosition(this.menu.currentDropdownActiveButton, this.menu.currentDropdown);
853
+ }
854
+
855
+ if (this.viewer._resetFullScreenHeight()) return;
856
+
857
+ if (fc.get('isCodeView') && this.editor.isInline) {
858
+ this.toolbar._showInline();
859
+ return;
860
+ }
861
+
862
+ this.editor._iframeAutoHeight(fc);
863
+
864
+ if (this.toolbar._sticky) {
865
+ this.context.get('toolbar.main').style.width = fc.get('topArea').offsetWidth - 2 + 'px';
866
+ this.toolbar._resetSticky();
867
+ }
868
+ },
869
+
870
+ _setSelectionSync() {
871
+ this.removeGlobalEvent(this.__selectionSyncEvent);
872
+ this.__selectionSyncEvent = this.addGlobalEvent('mouseup', () => {
873
+ this.selection._init();
874
+ this.removeGlobalEvent(this.__selectionSyncEvent);
875
+ });
876
+ },
877
+
878
+ _retainStyleNodes(formatEl, _styleNodes) {
879
+ const el = _styleNodes[0].cloneNode(false);
880
+ let n = el;
881
+ for (let i = 1, len = _styleNodes.length, t; i < len; i++) {
882
+ t = _styleNodes[i].cloneNode(false);
883
+ n.appendChild(t);
884
+ n = t;
885
+ }
886
+
887
+ const zeroWidth = domUtils.createTextNode(unicode.zeroWidthSpace);
888
+ formatEl.innerHTML = n.innerHTML = '';
889
+ n.appendChild(zeroWidth);
890
+ formatEl.appendChild(el);
891
+
892
+ this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
893
+ },
894
+
895
+ _clearRetainStyleNodes(formatEl) {
896
+ formatEl.innerHTML = '<br>';
897
+ this.selection.setRange(formatEl, 0, formatEl, 0);
898
+ },
899
+
900
+ _callPluginEvent(name, e) {
901
+ const eventPlugins = this.editor._onPluginEvents.get(name);
902
+ for (let i = 0; i < eventPlugins.length; i++) {
903
+ if (eventPlugins[i](e) === false) return false;
904
+ }
905
+ },
906
+
907
+ _overComponentSelect(target) {
908
+ const figure = domUtils.getParentElement(target, domUtils.isFigure);
909
+ let info = this.component.get(target);
910
+ if (info || figure) {
911
+ if (!info) info = this.component.get(figure);
912
+ if (info && !domUtils.hasClass(info.container, 'se-component-selected')) {
913
+ this.editor._offCurrentController();
914
+ _DragHandle.set('__overInfo', ON_OVER_COMPONENT);
915
+ this.component.select(info.target, info.pluginName, false);
916
+ }
917
+ } else if (_DragHandle.get('__overInfo') !== null && !domUtils.hasClass(target, 'se-drag-handle')) {
918
+ this.component.deselect();
919
+ _DragHandle.set('__overInfo', null);
920
+ }
921
+ },
922
+
923
+ __removeInput() {
924
+ this._inputFocus = this.editor._antiBlur = false;
925
+ this.__inputBlurEvent = this.removeEvent(this.__inputBlurEvent);
926
+ this.__inputKeyEvent = this.removeEvent(this.__inputKeyEvent);
927
+ this.__inputPlugin = null;
928
+ },
929
+
930
+ __enterPrevent(e) {
931
+ e.preventDefault();
932
+ if (!isMobile) return;
933
+
934
+ this.__focusTemp.focus();
935
+ },
936
+
937
+ constructor: EventManager
938
+ };
939
+
940
+ function OnScroll_wysiwyg(frameContext, eventWysiwyg, e) {
941
+ this._moveContainer(eventWysiwyg);
942
+ this._scrollContainer();
943
+
944
+ // plugin event
945
+ this._callPluginEvent('onScroll', { frameContext, event: e });
946
+
947
+ // user event
948
+ this.triggerEvent('onScroll', { frameContext, event: e });
949
+ }
950
+
951
+ function OnFocus_wysiwyg(frameContext, e) {
952
+ const rootKey = frameContext.get('key');
953
+
954
+ if (this._inputFocus) {
955
+ if (this.editor.isInline) {
956
+ this._w.setTimeout(() => {
957
+ this.toolbar._showInline();
958
+ }, 0);
959
+ }
960
+ return;
961
+ }
962
+
963
+ if (this.status.rootKey === rootKey && this.editor._antiBlur) return;
964
+
965
+ this.editor._offCurrentController();
966
+ this.status.hasFocus = true;
967
+
968
+ domUtils.removeClass(this.editor.commandTargets.get('codeView'), 'active');
969
+ domUtils.setDisabled(this.editor._codeViewDisabledButtons, false);
970
+
971
+ this.editor.changeFrameContext(rootKey);
972
+ this.history.resetButtons(rootKey, null);
973
+
974
+ this._w.setTimeout(() => {
975
+ if (this.editor.isInline) this.toolbar._showInline();
976
+
977
+ // user event
978
+ this.triggerEvent('onFocus', { frameContext, event: e });
979
+ // plugin event
980
+ this._callPluginEvent('onFocus', { frameContext, event: e });
981
+ }, 0);
982
+ }
983
+
984
+ function OnBlur_wysiwyg(frameContext, e) {
985
+ if (this._inputFocus || this.editor._antiBlur || frameContext.get('isCodeView')) return;
986
+
987
+ this.status.hasFocus = false;
988
+ this.editor.effectNode = null;
989
+ this.editor._offCurrentController();
990
+ if (this.editor.isInline || this.editor.isBalloon) this._hideToolbar();
991
+ if (this.editor.isSubBalloon) this._hideToolbar_sub();
992
+
993
+ this._setKeyEffect([]);
994
+
995
+ this.status.currentNodes = [];
996
+ this.status.currentNodesMap = [];
997
+
998
+ this.editor.applyFrameRoots((root) => {
999
+ if (root.get('navigation')) root.get('navigation').textContent = '';
1000
+ });
1001
+
1002
+ this.history.check(frameContext.get('key'), this.status._range);
1003
+
1004
+ // user event
1005
+ this.triggerEvent('onBlur', { frameContext, event: e });
1006
+ // plugin event
1007
+ this._callPluginEvent('onBlur', { frameContext, event: e });
1008
+ }
1009
+
1010
+ function OnMouseDown_statusbar(e) {
1011
+ e.stopPropagation();
1012
+ this._resizeClientY = e.clientY;
1013
+ this.editor.enableBackWrapper('ns-resize');
1014
+ this.__resize_editor = this.addGlobalEvent('mousemove', __resizeEditor.bind(this));
1015
+ this.__close_move = this.addGlobalEvent('mouseup', __closeMove.bind(this));
1016
+ }
1017
+
1018
+ function __resizeEditor(e) {
1019
+ const fc = this.editor.frameContext;
1020
+ const resizeInterval = fc.get('wrapper').offsetHeight + (e.clientY - this._resizeClientY);
1021
+ const h = resizeInterval < fc.get('_minHeight') ? fc.get('_minHeight') : resizeInterval;
1022
+ fc.get('wysiwygFrame').style.height = fc.get('code').style.height = h + 'px';
1023
+ this._resizeClientY = e.clientY;
1024
+ if (!env.isResizeObserverSupported) this.editor.__callResizeFunction(h, null);
1025
+ }
1026
+
1027
+ function __closeMove() {
1028
+ this.editor.disableBackWrapper();
1029
+ if (this.__resize_editor) this.__resize_editor = this.removeGlobalEvent(this.__resize_editor);
1030
+ if (this.__close_move) this.__close_move = this.removeGlobalEvent(this.__close_move);
1031
+ }
1032
+
1033
+ function DisplayLineBreak(dir, e) {
1034
+ e.preventDefault();
1035
+
1036
+ const component = this._lineBreakComp;
1037
+ if (!component) return;
1038
+
1039
+ dir = !dir ? this._lineBreakDir : dir;
1040
+ const isList = domUtils.isListCell(component.parentNode);
1041
+ const format = domUtils.createElement(isList ? 'BR' : domUtils.isTableCell(component.parentNode) ? 'DIV' : this.options.get('defaultLine'));
1042
+ if (!isList) format.innerHTML = '<br>';
1043
+
1044
+ if (this.editor.frameOptions.get('charCounter_type') === 'byte-html' && !this.char.check(format.outerHTML)) return;
1045
+
1046
+ component.parentNode.insertBefore(format, dir === 't' ? component : component.nextSibling);
1047
+ this.component.deselect();
1048
+
1049
+ const focusEl = isList ? format : format.firstChild;
1050
+ this.selection.setRange(focusEl, 1, focusEl, 1);
1051
+ this.history.push(false);
1052
+ }
1053
+
1054
+ function OnResize_window() {
1055
+ if (isMobile) {
1056
+ this._scrollContainer();
1057
+ } else {
1058
+ this.editor._offCurrentController();
1059
+ }
1060
+
1061
+ if (this.editor.isBalloon) this.toolbar.hide();
1062
+ else if (this.editor.isSubBalloon) this.subToolbar.hide();
1063
+
1064
+ this._resetFrameStatus();
1065
+ }
1066
+
1067
+ function OnScroll_window() {
1068
+ if (this.options.get('toolbar_sticky') > -1) {
1069
+ if (this._vitualKeyboardHeight && this.toolbar._sticky) {
1070
+ this.toolbar._visible(false);
1071
+ } else {
1072
+ this.toolbar._resetSticky();
1073
+ }
1074
+ }
1075
+
1076
+ if (this.editor.isBalloon && this.context.get('toolbar.main').style.display === 'block') {
1077
+ this.toolbar._setBalloonOffset(this.toolbar._balloonOffset.position === 'top');
1078
+ } else if (this.editor.isSubBalloon && this.context.get('toolbar.sub.main').style.display === 'block') {
1079
+ this.subToolbar._setBalloonOffset(this.subToolbar._balloonOffset.position === 'top');
1080
+ }
1081
+
1082
+ this._scrollContainer();
1083
+ }
1084
+
1085
+ function OnResize_viewport() {
1086
+ this._vitualKeyboardHeight = _w.innerHeight - _w.visualViewport.height;
1087
+ }
1088
+
1089
+ function OnScroll_viewport() {
1090
+ if (this.options.get('toolbar_sticky') > -1) {
1091
+ if (this._vitualKeyboardHeight && this.toolbar._sticky) {
1092
+ this.toolbar._visible(false);
1093
+ } else {
1094
+ this.toolbar._resetSticky();
1095
+ }
1096
+ }
1097
+ }
1098
+
1099
+ function OnScroll_viewport_onKeyboardOn() {
1100
+ this.toolbar._visible(true);
1101
+ if (this._vitualKeyboardHeight && this.options.get('toolbar_sticky') > -1) {
1102
+ this.toolbar._resetSticky();
1103
+ }
1104
+ }
1105
+
1106
+ function OnSelectionchange_document(_wd) {
1107
+ const selection = _wd.getSelection();
1108
+ let anchorNode = selection.anchorNode;
1109
+
1110
+ this.editor.applyFrameRoots((root) => {
1111
+ if (anchorNode && root.get('wysiwyg').contains(anchorNode)) {
1112
+ anchorNode = null;
1113
+ this.selection._init();
1114
+ this.applyTagEffect();
1115
+ }
1116
+ });
1117
+ }
1118
+
1119
+ function OnScroll_Abs() {
1120
+ this._scrollContainer();
1121
+ }
1122
+
1123
+ function OnFocus_code(frameContext) {
1124
+ this.editor.changeFrameContext(frameContext.get('key'));
1125
+ domUtils.addClass(this.editor.commandTargets.get('codeView'), 'active');
1126
+ domUtils.setDisabled(this.editor._codeViewDisabledButtons, true);
1127
+ }
1128
+
1129
+ export default EventManager;