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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/.eslintrc.json +4 -3
  2. package/CONTRIBUTING.md +4 -2
  3. package/README.md +19 -11
  4. package/README_V3_TEMP.md +705 -0
  5. package/dist/suneditor.min.css +1 -0
  6. package/dist/suneditor.min.js +1 -0
  7. package/example.md +587 -0
  8. package/package.json +15 -9
  9. package/src/assets/icons/_default.js +166 -131
  10. package/src/assets/{suneditor-content.css → suneditor-contents.css} +182 -45
  11. package/src/assets/suneditor.css +1195 -556
  12. package/src/assets/variables.css +138 -0
  13. package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
  14. package/src/core/base/eventHandlers/handler_ww_clipboard.js +29 -4
  15. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +59 -15
  16. package/src/core/base/eventHandlers/handler_ww_key_input.js +426 -212
  17. package/src/core/base/eventHandlers/handler_ww_mouse.js +108 -32
  18. package/src/core/base/eventManager.js +540 -209
  19. package/src/core/base/events.js +616 -320
  20. package/src/core/base/history.js +93 -39
  21. package/src/core/class/char.js +29 -13
  22. package/src/core/class/component.js +332 -145
  23. package/src/core/class/format.js +671 -509
  24. package/src/core/class/html.js +504 -290
  25. package/src/core/class/menu.js +114 -47
  26. package/src/core/class/nodeTransform.js +111 -66
  27. package/src/core/class/offset.js +409 -105
  28. package/src/core/class/selection.js +220 -108
  29. package/src/core/class/shortcuts.js +68 -8
  30. package/src/core/class/toolbar.js +106 -116
  31. package/src/core/class/ui.js +330 -0
  32. package/src/core/class/viewer.js +178 -74
  33. package/src/core/editor.js +489 -384
  34. package/src/core/section/actives.js +118 -22
  35. package/src/core/section/constructor.js +504 -170
  36. package/src/core/section/context.js +28 -23
  37. package/src/core/section/documentType.js +561 -0
  38. package/src/editorInjector/_classes.js +19 -5
  39. package/src/editorInjector/_core.js +71 -7
  40. package/src/editorInjector/index.js +63 -1
  41. package/src/helper/converter.js +137 -19
  42. package/src/helper/dom/domCheck.js +294 -0
  43. package/src/helper/dom/domQuery.js +609 -0
  44. package/src/helper/dom/domUtils.js +533 -0
  45. package/src/helper/dom/index.js +12 -0
  46. package/src/helper/env.js +42 -19
  47. package/src/helper/index.js +7 -4
  48. package/src/helper/keyCodeMap.js +183 -0
  49. package/src/helper/numbers.js +8 -8
  50. package/src/helper/unicode.js +5 -5
  51. package/src/langs/ckb.js +69 -3
  52. package/src/langs/cs.js +67 -1
  53. package/src/langs/da.js +68 -2
  54. package/src/langs/de.js +68 -3
  55. package/src/langs/en.js +29 -1
  56. package/src/langs/es.js +68 -3
  57. package/src/langs/fa.js +70 -2
  58. package/src/langs/fr.js +68 -2
  59. package/src/langs/he.js +68 -3
  60. package/src/langs/hu.js +226 -0
  61. package/src/langs/index.js +3 -2
  62. package/src/langs/it.js +65 -0
  63. package/src/langs/ja.js +68 -3
  64. package/src/langs/ko.js +66 -1
  65. package/src/langs/lv.js +68 -3
  66. package/src/langs/nl.js +68 -3
  67. package/src/langs/pl.js +68 -3
  68. package/src/langs/pt_br.js +65 -0
  69. package/src/langs/ro.js +69 -4
  70. package/src/langs/ru.js +68 -3
  71. package/src/langs/se.js +68 -3
  72. package/src/langs/tr.js +68 -0
  73. package/src/langs/ua.js +68 -3
  74. package/src/langs/ur.js +71 -6
  75. package/src/langs/zh_cn.js +69 -4
  76. package/src/modules/ApiManager.js +77 -54
  77. package/src/modules/Browser.js +667 -0
  78. package/src/modules/ColorPicker.js +162 -102
  79. package/src/modules/Controller.js +233 -136
  80. package/src/modules/Figure.js +913 -489
  81. package/src/modules/FileManager.js +141 -72
  82. package/src/modules/HueSlider.js +113 -61
  83. package/src/modules/Modal.js +292 -113
  84. package/src/modules/ModalAnchorEditor.js +380 -230
  85. package/src/modules/SelectMenu.js +270 -168
  86. package/src/modules/_DragHandle.js +2 -1
  87. package/src/modules/index.js +3 -3
  88. package/src/plugins/browser/audioGallery.js +83 -0
  89. package/src/plugins/browser/fileBrowser.js +103 -0
  90. package/src/plugins/browser/fileGallery.js +83 -0
  91. package/src/plugins/browser/imageGallery.js +81 -0
  92. package/src/plugins/browser/videoGallery.js +103 -0
  93. package/src/plugins/command/blockquote.js +40 -27
  94. package/src/plugins/command/exportPDF.js +134 -0
  95. package/src/plugins/command/fileUpload.js +226 -158
  96. package/src/plugins/command/list_bulleted.js +93 -47
  97. package/src/plugins/command/list_numbered.js +93 -47
  98. package/src/plugins/dropdown/align.js +66 -54
  99. package/src/plugins/dropdown/backgroundColor.js +76 -45
  100. package/src/plugins/dropdown/font.js +71 -47
  101. package/src/plugins/dropdown/fontColor.js +78 -46
  102. package/src/plugins/dropdown/formatBlock.js +74 -33
  103. package/src/plugins/dropdown/hr.js +102 -51
  104. package/src/plugins/dropdown/layout.js +37 -26
  105. package/src/plugins/dropdown/lineHeight.js +54 -38
  106. package/src/plugins/dropdown/list.js +60 -45
  107. package/src/plugins/dropdown/paragraphStyle.js +51 -30
  108. package/src/plugins/dropdown/table.js +1269 -777
  109. package/src/plugins/dropdown/template.js +38 -26
  110. package/src/plugins/dropdown/textStyle.js +43 -31
  111. package/src/plugins/field/mention.js +144 -82
  112. package/src/plugins/index.js +32 -6
  113. package/src/plugins/input/fontSize.js +161 -108
  114. package/src/plugins/input/pageNavigator.js +70 -0
  115. package/src/plugins/modal/audio.js +341 -169
  116. package/src/plugins/modal/drawing.js +530 -0
  117. package/src/plugins/modal/embed.js +886 -0
  118. package/src/plugins/modal/image.js +673 -358
  119. package/src/plugins/modal/link.js +100 -71
  120. package/src/plugins/modal/math.js +384 -168
  121. package/src/plugins/modal/video.js +693 -336
  122. package/src/plugins/popup/anchor.js +222 -0
  123. package/src/suneditor.js +54 -12
  124. package/src/themes/dark.css +85 -0
  125. package/src/typedef.js +86 -0
  126. package/types/assets/icons/_default.d.ts +152 -0
  127. package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
  128. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
  129. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
  130. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
  131. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
  132. package/types/core/base/eventManager.d.ts +377 -0
  133. package/types/core/base/events.d.ts +297 -0
  134. package/types/core/base/history.d.ts +81 -0
  135. package/types/core/class/char.d.ts +60 -0
  136. package/types/core/class/component.d.ts +259 -0
  137. package/types/core/class/format.d.ts +615 -0
  138. package/types/core/class/html.d.ts +377 -0
  139. package/types/core/class/menu.d.ts +118 -0
  140. package/types/core/class/nodeTransform.d.ts +93 -0
  141. package/types/core/class/offset.d.ts +512 -0
  142. package/types/core/class/selection.d.ts +188 -0
  143. package/types/core/class/shortcuts.d.ts +142 -0
  144. package/types/core/class/toolbar.d.ts +189 -0
  145. package/types/core/class/ui.d.ts +144 -0
  146. package/types/core/class/viewer.d.ts +140 -0
  147. package/types/core/editor.d.ts +606 -0
  148. package/types/core/section/actives.d.ts +46 -0
  149. package/types/core/section/constructor.d.ts +748 -0
  150. package/types/core/section/context.d.ts +45 -0
  151. package/types/core/section/documentType.d.ts +178 -0
  152. package/types/editorInjector/_classes.d.ts +41 -0
  153. package/types/editorInjector/_core.d.ts +92 -0
  154. package/types/editorInjector/index.d.ts +71 -0
  155. package/types/helper/converter.d.ts +150 -0
  156. package/types/helper/dom/domCheck.d.ts +182 -0
  157. package/types/helper/dom/domQuery.d.ts +214 -0
  158. package/types/helper/dom/domUtils.d.ts +211 -0
  159. package/types/helper/dom/index.d.ts +9 -0
  160. package/types/helper/env.d.ts +149 -0
  161. package/types/helper/index.d.ts +163 -0
  162. package/types/helper/keyCodeMap.d.ts +110 -0
  163. package/types/helper/numbers.d.ts +43 -0
  164. package/types/helper/unicode.d.ts +28 -0
  165. package/types/index.d.ts +0 -0
  166. package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +170 -103
  167. package/types/langs/ckb.d.ts +384 -0
  168. package/types/langs/cs.d.ts +384 -0
  169. package/types/langs/da.d.ts +384 -0
  170. package/types/langs/de.d.ts +384 -0
  171. package/types/langs/en.d.ts +384 -0
  172. package/types/langs/es.d.ts +384 -0
  173. package/types/langs/fa.d.ts +384 -0
  174. package/types/langs/fr.d.ts +384 -0
  175. package/types/langs/he.d.ts +384 -0
  176. package/types/langs/hu.d.ts +384 -0
  177. package/types/langs/index.d.ts +48 -0
  178. package/types/langs/it.d.ts +384 -0
  179. package/types/langs/ja.d.ts +384 -0
  180. package/types/langs/ko.d.ts +384 -0
  181. package/types/langs/lv.d.ts +384 -0
  182. package/types/langs/nl.d.ts +384 -0
  183. package/types/langs/pl.d.ts +384 -0
  184. package/types/langs/pt_br.d.ts +384 -0
  185. package/types/langs/ro.d.ts +384 -0
  186. package/types/langs/ru.d.ts +384 -0
  187. package/types/langs/se.d.ts +384 -0
  188. package/types/langs/tr.d.ts +384 -0
  189. package/types/langs/ua.d.ts +384 -0
  190. package/types/langs/ur.d.ts +384 -0
  191. package/types/langs/zh_cn.d.ts +384 -0
  192. package/types/modules/ApiManager.d.ts +125 -0
  193. package/types/modules/Browser.d.ts +326 -0
  194. package/types/modules/ColorPicker.d.ts +131 -0
  195. package/types/modules/Controller.d.ts +231 -0
  196. package/types/modules/Figure.d.ts +504 -0
  197. package/types/modules/FileManager.d.ts +202 -0
  198. package/types/modules/HueSlider.d.ts +136 -0
  199. package/types/modules/Modal.d.ts +117 -0
  200. package/types/modules/ModalAnchorEditor.d.ts +236 -0
  201. package/types/modules/SelectMenu.d.ts +194 -0
  202. package/types/modules/_DragHandle.d.ts +7 -0
  203. package/types/modules/index.d.ts +26 -0
  204. package/types/plugins/browser/audioGallery.d.ts +55 -0
  205. package/types/plugins/browser/fileBrowser.d.ts +64 -0
  206. package/types/plugins/browser/fileGallery.d.ts +55 -0
  207. package/types/plugins/browser/imageGallery.d.ts +51 -0
  208. package/types/plugins/browser/videoGallery.d.ts +57 -0
  209. package/types/plugins/command/blockquote.d.ts +28 -0
  210. package/types/plugins/command/exportPDF.d.ts +46 -0
  211. package/types/plugins/command/fileUpload.d.ts +156 -0
  212. package/types/plugins/command/list_bulleted.d.ts +56 -0
  213. package/types/plugins/command/list_numbered.d.ts +56 -0
  214. package/types/plugins/dropdown/align.d.ts +60 -0
  215. package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
  216. package/types/plugins/dropdown/font.d.ts +54 -0
  217. package/types/plugins/dropdown/fontColor.d.ts +63 -0
  218. package/types/plugins/dropdown/formatBlock.d.ts +58 -0
  219. package/types/plugins/dropdown/hr.d.ts +81 -0
  220. package/types/plugins/dropdown/layout.d.ts +40 -0
  221. package/types/plugins/dropdown/lineHeight.d.ts +50 -0
  222. package/types/plugins/dropdown/list.d.ts +39 -0
  223. package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
  224. package/types/plugins/dropdown/table.d.ts +579 -0
  225. package/types/plugins/dropdown/template.d.ts +40 -0
  226. package/types/plugins/dropdown/textStyle.d.ts +41 -0
  227. package/types/plugins/field/mention.d.ts +102 -0
  228. package/types/plugins/index.d.ts +107 -0
  229. package/types/plugins/input/fontSize.d.ts +170 -0
  230. package/types/plugins/input/pageNavigator.d.ts +28 -0
  231. package/types/plugins/modal/audio.d.ts +269 -0
  232. package/types/plugins/modal/drawing.d.ts +246 -0
  233. package/types/plugins/modal/embed.d.ts +387 -0
  234. package/types/plugins/modal/image.d.ts +451 -0
  235. package/types/plugins/modal/link.d.ts +128 -0
  236. package/types/plugins/modal/math.d.ts +193 -0
  237. package/types/plugins/modal/video.d.ts +485 -0
  238. package/types/plugins/popup/anchor.d.ts +56 -0
  239. package/types/suneditor.d.ts +51 -0
  240. package/types/typedef-global.d.ts +144 -0
  241. package/src/core/class/notice.js +0 -42
  242. package/src/helper/domUtils.js +0 -1177
  243. package/src/modules/FileBrowser.js +0 -271
  244. package/src/plugins/command/exportPdf.js +0 -168
  245. package/src/plugins/fileBrowser/imageGallery.js +0 -81
  246. package/src/themes/test.css +0 -61
  247. package/typings/CommandPlugin.d.ts +0 -8
  248. package/typings/DialogPlugin.d.ts +0 -20
  249. package/typings/FileBrowserPlugin.d.ts +0 -30
  250. package/typings/Module.d.ts +0 -15
  251. package/typings/Plugin.d.ts +0 -42
  252. package/typings/SubmenuPlugin.d.ts +0 -8
  253. package/typings/_classes.d.ts +0 -17
  254. package/typings/_colorPicker.d.ts +0 -60
  255. package/typings/_core.d.ts +0 -55
  256. package/typings/align.d.ts +0 -5
  257. package/typings/audio.d.ts +0 -5
  258. package/typings/backgroundColor.d.ts +0 -5
  259. package/typings/blockquote.d.ts +0 -5
  260. package/typings/char.d.ts +0 -39
  261. package/typings/component.d.ts +0 -38
  262. package/typings/context.d.ts +0 -39
  263. package/typings/converter.d.ts +0 -33
  264. package/typings/dialog.d.ts +0 -28
  265. package/typings/domUtils.d.ts +0 -361
  266. package/typings/editor.d.ts +0 -7
  267. package/typings/editor.ts +0 -542
  268. package/typings/env.d.ts +0 -70
  269. package/typings/eventManager.d.ts +0 -37
  270. package/typings/events.d.ts +0 -262
  271. package/typings/fileBrowser.d.ts +0 -42
  272. package/typings/fileManager.d.ts +0 -67
  273. package/typings/font.d.ts +0 -5
  274. package/typings/fontColor.d.ts +0 -5
  275. package/typings/fontSize.d.ts +0 -5
  276. package/typings/format.d.ts +0 -191
  277. package/typings/formatBlock.d.ts +0 -5
  278. package/typings/history.d.ts +0 -48
  279. package/typings/horizontalRule.d.ts +0 -5
  280. package/typings/image.d.ts +0 -5
  281. package/typings/imageGallery.d.ts +0 -5
  282. package/typings/index.d.ts +0 -21
  283. package/typings/index.modules.d.ts +0 -11
  284. package/typings/index.plugins.d.ts +0 -58
  285. package/typings/lineHeight.d.ts +0 -5
  286. package/typings/link.d.ts +0 -5
  287. package/typings/list.d.ts +0 -5
  288. package/typings/math.d.ts +0 -5
  289. package/typings/mediaContainer.d.ts +0 -25
  290. package/typings/mention.d.ts +0 -5
  291. package/typings/node.d.ts +0 -57
  292. package/typings/notice.d.ts +0 -16
  293. package/typings/numbers.d.ts +0 -29
  294. package/typings/offset.d.ts +0 -24
  295. package/typings/options.d.ts +0 -589
  296. package/typings/paragraphStyle.d.ts +0 -5
  297. package/typings/resizing.d.ts +0 -141
  298. package/typings/selection.d.ts +0 -94
  299. package/typings/shortcuts.d.ts +0 -13
  300. package/typings/suneditor.d.ts +0 -9
  301. package/typings/table.d.ts +0 -5
  302. package/typings/template.d.ts +0 -5
  303. package/typings/textStyle.d.ts +0 -5
  304. package/typings/toolbar.d.ts +0 -32
  305. package/typings/unicode.d.ts +0 -25
  306. package/typings/video.d.ts +0 -5
@@ -1,59 +1,94 @@
1
1
  import EditorInjector from '../editorInjector';
2
- import { domUtils, env } from '../helper';
2
+ import { dom, env, keyCodeMap } from '../helper';
3
3
  import { _DragHandle } from '../modules';
4
4
 
5
- const { ON_OVER_COMPONENT } = env;
6
- const NON_RESPONSE_KEYCODE = /^(13|1[7-9]|20|27|45|11[2-9]|12[0-3]|144|145)$/;
7
- const INDEX_0 = 2147483647;
8
- const INDEX_1 = 2147483646;
9
- const INDEX_2 = 2147483645;
5
+ const { _w, ON_OVER_COMPONENT } = env;
6
+ const INDEX_0 = '2147483647';
7
+ const INDEX_1 = '2147483646';
8
+ const INDEX_2 = '2147483645';
10
9
 
11
10
  /**
12
- *
13
- * @param {*} inst
14
- * @param {*} element
15
- * @param {{position: "top" | "bottom" | "position", disabled?: boolean}} params params
16
- * When using the "top" position, there should not be an arrow on the controller.
17
- * When using the "bottom" position there should be an arrow on the controller.
11
+ * @typedef {Object} ControllerInfo
12
+ * @property {*} inst The controller instance
13
+ * @property {string} [position="bottom"] The controller position ("bottom"|"top")
14
+ * @property {HTMLElement} [form=null] The controller element
15
+ * @property {HTMLElement|Range} [target=null] The controller target element
16
+ * @property {boolean} [notInCarrier=false] If the controller is not in the "carrierWrapper", set it to true.
17
+ * @property {boolean} [isRangeTarget=false] If the target is a Range, set it to true.
18
+ * @property {boolean} [fixed=false] If the controller is fixed and should not be closed, set it to true.
18
19
  */
19
- const Controller = function (inst, element, params, _name) {
20
- EditorInjector.call(this, inst.editor);
21
-
22
- // members
23
- this.kind = _name || inst.constructor.key || inst.constructor.name;
24
- this.inst = inst;
25
- this.form = element;
26
- this.isOpen = false;
27
- this.currentTarget = null;
28
- this.currentPositionTarget = null;
29
- this.isWWTarget = params.isWWTarget ?? true;
30
- this.position = params.position;
31
- this.disabled = !!params.disabled;
32
- this.parents = params.parents || [];
33
- this.parentsHide = !!params.parentsHide;
34
- this.isInsideForm = !!params.isInsideForm;
35
- this.isOutsideForm = !!params.isOutsideForm;
36
- this._initMethod = typeof params.initMethod === 'function' ? params.initMethod : null;
37
- this.__globalEventHandlers = { keydown: CloseListener_keydown.bind(this), mousedown: CloseListener_mousedown.bind(this) };
38
- this._bindClose_key = null;
39
- this._bindClose_mouse = null;
40
- this.__offset = {};
41
- this.__addOffset = { left: 0, top: 0 };
42
-
43
- // add element
44
- this.carrierWrapper.appendChild(element);
45
-
46
- // init
47
- this.eventManager.addEvent(element, 'click', Action.bind(this));
48
- this.eventManager.addEvent(element, 'mouseenter', MouseEnter.bind(this));
49
- this.eventManager.addEvent(element, 'mouseleave', MouseLeave.bind(this));
50
- };
51
-
52
- Controller.prototype = {
20
+
21
+ /**
22
+ * @typedef {Object} ControllerParams
23
+ * @property {"top"|"bottom"} [position="bottom"] Controller position
24
+ * @property {boolean=} [isWWTarget=true] If the controller is in the WYSIWYG area, set it to true.
25
+ * @property {() => void=} [initMethod=null] Method to be called when the controller is closed.
26
+ * @property {boolean=} [disabled=false] If true, When the "controller" is opened, buttons without the "se-component-enabled" class are disabled.
27
+ * @property {Array<HTMLElement>=} [parents=[]] The parent "controller" array when "controller" is opened nested.
28
+ * @property {boolean=} [parentsHide=false] If true, the parent element is hidden when the controller is opened.
29
+ * @property {boolean=} [isInsideForm=false] If the controller is inside a form, set it to true.
30
+ * @property {boolean=} [isOutsideForm=false] If the controller is outside a form, set it to true.
31
+ */
32
+
33
+ /**
34
+ * @class
35
+ * @description Controller module class that handles the UI and interaction logic for a specific editor controller element.
36
+ */
37
+ class Controller extends EditorInjector {
38
+ /**
39
+ * @constructor
40
+ * @param {*} inst The instance object that called the constructor.
41
+ * @param {Node} element Controller element
42
+ * @param {ControllerParams} params Controller options
43
+ * @param {?string=} _name An optional name for the controller key.
44
+ */
45
+ constructor(inst, element, params, _name) {
46
+ super(inst.editor);
47
+
48
+ // members
49
+ this.kind = _name || inst.constructor.key || inst.constructor.name;
50
+ this.inst = inst;
51
+ this.form = /** @type {HTMLFormElement} */ (element);
52
+ this.isOpen = false;
53
+ this.currentTarget = null;
54
+ this.currentPositionTarget = null;
55
+ this.isWWTarget = params.isWWTarget ?? true;
56
+ this.position = params.position || 'bottom';
57
+ this.disabled = !!params.disabled;
58
+ this.parents = /** @type {Array<HTMLElement>} */ (params.parents || []);
59
+ this.parentsHide = !!params.parentsHide;
60
+ this.isInsideForm = !!params.isInsideForm;
61
+ this.isOutsideForm = !!params.isOutsideForm;
62
+ this._initMethod = typeof params.initMethod === 'function' ? params.initMethod : null;
63
+ this.__globalEventHandlers = { keydown: this.#CloseListener_keydown.bind(this), mousedown: this.#CloseListener_mousedown.bind(this) };
64
+ this._bindClose_key = null;
65
+ this._bindClose_mouse = null;
66
+ /** @type {{left?: number, top?: number, addOfffset?: {left?: number, top?: number}}} */
67
+ this.__offset = {};
68
+ this.__addOffset = { left: 0, top: 0 };
69
+ this.__shadowRootEventForm = null;
70
+ this.__shadowRootEventListener = null;
71
+
72
+ // add element
73
+ this.carrierWrapper.appendChild(element);
74
+
75
+ // init
76
+ this.eventManager.addEvent(element, 'click', this.#Action.bind(this));
77
+ this.eventManager.addEvent(element, 'mouseenter', this.#MouseEnter.bind(this));
78
+ this.eventManager.addEvent(element, 'mouseleave', this.#MouseLeave.bind(this));
79
+ }
80
+
53
81
  /**
54
82
  * @description Open a modal plugin
83
+ * @param {Node|Range} target Target element
84
+ * @param {Node} [positionTarget] Position target element
85
+ * @param {Object} [params={}] params
86
+ * @param {boolean=} params.isWWTarget If the controller is in the WYSIWYG area, set it to true.
87
+ * @param {() => void=} params.initMethod Method to be called when the controller is closed.
88
+ * @param {boolean=} params.disabled If true, When the "controller" is opened, buttons without the "se-component-enabled" class are disabled. (default: this.disabled)
89
+ * @param {{left?: number, top?: number}=} params.addOffset Additional offset values
55
90
  */
56
- open(target, positionTarget, { isWWTarget, initMethod, disabled, addOffset }) {
91
+ open(target, positionTarget, { isWWTarget, initMethod, disabled, addOffset } = {}) {
57
92
  if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) {
58
93
  return;
59
94
  }
@@ -66,9 +101,12 @@ Controller.prototype = {
66
101
  if (this.editor.isBalloon) this.toolbar.hide();
67
102
  else if (this.editor.isSubBalloon) this.subToolbar.hide();
68
103
 
69
- if (disabled ?? this.disabled) domUtils.setDisabled(this.editor._controllerOnDisabledButtons, true);
104
+ if (disabled ?? this.disabled) {
105
+ this.ui.setControllerOnDisabledButtons(true);
106
+ } else {
107
+ this.ui.setControllerOnDisabledButtons(false);
108
+ }
70
109
 
71
- this.currentTarget = target;
72
110
  this.currentPositionTarget = positionTarget || target;
73
111
  this.isWWTarget = isWWTarget ?? this.isWWTarget;
74
112
  if (typeof initMethod === 'function') this._initMethod = initMethod;
@@ -88,20 +126,25 @@ Controller.prototype = {
88
126
  }
89
127
 
90
128
  this.__addGlobalEvent();
129
+
130
+ // display controller
91
131
  this._setControllerPosition(this.form, this.currentPositionTarget);
92
- this._controllerOn(this.form, target);
132
+
133
+ const isRangeTarget = target instanceof Range;
134
+ this.currentTarget = isRangeTarget ? null : target;
135
+ this._controllerOn(this.form, target, isRangeTarget);
93
136
  this._w.setTimeout(() => _DragHandle.set('__overInfo', false), 0);
94
- },
137
+ }
95
138
 
96
139
  /**
97
140
  * @description Close a modal plugin
98
- * The plugin's "init" method is called.
141
+ * - The plugin's "init" method is called.
142
+ * @param {boolean=} force If true, parent controllers are forcibly closed.
99
143
  */
100
144
  close(force) {
101
145
  if (!this.isOpen) return;
102
146
 
103
147
  this.isOpen = false;
104
- this.editor._antiBlur = false;
105
148
  this.__offset = {};
106
149
  this.__addOffset = { left: 0, top: 0 };
107
150
 
@@ -119,114 +162,148 @@ Controller.prototype = {
119
162
  if (this.parents.length > 0) return;
120
163
  if (typeof this.inst.close === 'function') this.inst.close();
121
164
  this.component.deselect();
122
- },
165
+ }
123
166
 
124
167
  /**
125
168
  * @description Hide controller
126
169
  */
127
170
  hide() {
128
171
  this.form.style.display = 'none';
129
- },
172
+ }
130
173
 
131
174
  /**
132
175
  * @description Show controller
133
176
  */
134
177
  show() {
135
178
  this._setControllerPosition(this.form, this.currentPositionTarget);
136
- },
179
+ }
137
180
 
138
181
  /**
139
182
  * @description Reset controller position
140
- * @param {Element|undefined} target
183
+ * @param {Node=} target
141
184
  */
142
185
  resetPosition(target) {
143
186
  this._setControllerPosition(this.form, target || this.currentPositionTarget);
144
- },
187
+ }
145
188
 
146
189
  /**
190
+ * @private
147
191
  * @description Show controller at editor area (controller elements, function, "controller target element(@Required)", "controller name(@Required)", etc..)
148
- * @param {any} arguments controller elements, function..
192
+ * @param {HTMLFormElement} form Controller element
193
+ * @param {Node|Range} target Controller target element
194
+ * @param {boolean} isRangeTarget If the target is a Range, set it to true.
149
195
  */
150
- _controllerOn(form, target) {
151
- const params = {
196
+ async _controllerOn(form, target, isRangeTarget) {
197
+ /** @type {ControllerInfo} */
198
+ const info = {
152
199
  position: this.position,
153
- form: form,
154
- target: target,
155
- inst: this
200
+ inst: this,
201
+ form: /** @type {HTMLElement} */ (form),
202
+ target: /** @type {HTMLElement} */ (target),
203
+ isRangeTarget,
204
+ notInCarrier: !this.carrierWrapper.contains(form)
156
205
  };
157
206
 
158
- if (this.triggerEvent('onBeforeShowController', { caller: this.kind, frameContext: this.editor.frameContext, params }) === false) return;
207
+ if ((await this.triggerEvent('onBeforeShowController', { caller: this.kind, frameContext: this.editor.frameContext, info })) === false) return;
159
208
 
160
209
  form.style.display = 'block';
161
210
  if (this._shadowRoot) {
162
- form.addEventListener('mousedown', (e) => e.stopPropagation());
211
+ this.__shadowRootEventForm = form;
212
+ this.__shadowRootEventListener = (e) => e.stopPropagation();
213
+ form.addEventListener('mousedown', this.__shadowRootEventListener);
163
214
  }
164
215
 
165
216
  this.editor._controllerTargetContext = this.editor.frameContext.get('topArea');
166
217
 
167
218
  if (!this.isOpen) {
168
- this.editor.opendControllers.push({
169
- position: this.position,
170
- form: form,
171
- target: target,
172
- inst: this
173
- });
219
+ this.editor.opendControllers.push(info);
174
220
  }
175
221
 
176
222
  this.isOpen = true;
177
- this.editor._antiBlur = true;
178
- this.triggerEvent('onShowController', { caller: this.kind, frameContext: this.editor.frameContext, params });
179
- },
223
+ this.editor._preventBlur = true;
224
+ this.editor.status.onSelected = true;
225
+ this.triggerEvent('onShowController', { caller: this.kind, frameContext: this.editor.frameContext, info });
226
+ }
180
227
 
181
228
  /**
182
- * @description Hide controller at editor area (link button, image resize button..)
183
- * @param {KeyboardEvent|MouseEvent|null} e Event object when called from mousedown and keydown events registered in "_controllerOn"
184
229
  * @private
230
+ * @description Hide controller at editor area (link button, image resize button..)
185
231
  */
186
232
  _controllerOff() {
187
233
  this.form.style.display = 'none';
188
234
  this.editor.opendControllers = this.editor.opendControllers.filter((v) => v.form !== this.form);
189
235
  if (this.editor.currentControllerName !== this.kind && this.editor.opendControllers.length > 0) return;
190
236
 
191
- if (this.disabled) domUtils.setDisabled(this.editor._controllerOnDisabledButtons, false);
237
+ this.ui.setControllerOnDisabledButtons(false);
238
+
192
239
  this.editor.frameContext.get('lineBreaker_t').style.display = this.editor.frameContext.get('lineBreaker_b').style.display = 'none';
193
240
  this.editor.effectNode = null;
194
241
  this.editor.currentControllerName = '';
195
- this.editor._antiBlur = false;
242
+ this.editor._preventBlur = false;
196
243
  this.editor._controllerTargetContext = null;
244
+ _w.setTimeout(() => {
245
+ this.editor.status.onSelected = false;
246
+ }, 0);
247
+ if (this.__shadowRootEventForm) {
248
+ this.__shadowRootEventForm.removeEventListener('mousedown', this.__shadowRootEventListener);
249
+ this.__shadowRootEventForm = this.__shadowRootEventListener = null;
250
+ }
197
251
  if (typeof this.inst.reset === 'function') this.inst.reset();
198
- },
252
+ }
199
253
 
200
254
  /**
255
+ * @private
201
256
  * @description Specify the position of the controller.
202
- * @param {Element} controller Controller element.
203
- * @param {Element} referEl Element that is the basis of the controller's position.
257
+ * @param {HTMLElement} controller Controller element.
258
+ * @param {Node|Range} refer Element or Range that is the basis of the controller's position.
204
259
  */
205
- _setControllerPosition(controller, referEl) {
260
+ _setControllerPosition(controller, refer) {
206
261
  controller.style.zIndex = INDEX_1;
207
262
  controller.style.visibility = 'hidden';
208
263
  controller.style.display = 'block';
209
264
 
210
- if (!this.offset.setAbsPosition(controller, referEl, { addOffset: this.__addOffset, position: this.position, isWWTarget: this.isWWTarget, inst: this })) {
211
- this.hide();
212
- return;
265
+ if (this.selection.isRange(refer)) {
266
+ if (!this.offset.setRangePosition(this.form, /** @type {Range} */ (refer), { position: 'bottom' })) {
267
+ this.hide();
268
+ return;
269
+ }
270
+ } else {
271
+ if (refer && !this.offset.setAbsPosition(controller, /** @type {HTMLElement} */ (refer), { addOffset: this.__addOffset, position: this.position, isWWTarget: this.isWWTarget, inst: this })) {
272
+ this.hide();
273
+ return;
274
+ }
213
275
  }
214
276
 
215
277
  controller.style.visibility = '';
216
- },
278
+ }
217
279
 
280
+ /**
281
+ * @private
282
+ * @description Adds global event listeners.
283
+ * - When the controller is opened
284
+ */
218
285
  __addGlobalEvent() {
219
286
  this.__removeGlobalEvent();
220
287
  this._bindClose_key = this.eventManager.addGlobalEvent('keydown', this.__globalEventHandlers.keydown, true);
221
288
  this._bindClose_mouse = this.eventManager.addGlobalEvent('mousedown', this.__globalEventHandlers.mousedown, true);
222
- },
289
+ }
223
290
 
291
+ /**
292
+ * @private
293
+ * @description Removes global event listeners.
294
+ * - When the ESC key is pressed, the controller is closed.
295
+ */
224
296
  __removeGlobalEvent() {
225
297
  this.component.__removeGlobalEvent();
226
298
  if (this._bindClose_key) this._bindClose_key = this.eventManager.removeGlobalEvent(this._bindClose_key);
227
299
  if (this._bindClose_mouse) this._bindClose_mouse = this.eventManager.removeGlobalEvent(this._bindClose_mouse);
228
- },
300
+ }
229
301
 
302
+ /**
303
+ * @private
304
+ * @description Checks if the controller is fixed and should not be closed.
305
+ * @returns {boolean} True if the controller is fixed.
306
+ */
230
307
  _checkFixed() {
231
308
  if (this.editor.selectMenuOn) return true;
232
309
 
@@ -237,11 +314,17 @@ Controller.prototype = {
237
314
  }
238
315
  }
239
316
  return false;
240
- },
317
+ }
241
318
 
319
+ /**
320
+ * @private
321
+ * @description Checks if the given target is within a form or controller.
322
+ * @param {Node} target The target element.
323
+ * @returns {boolean} True if the target is inside a form or controller.
324
+ */
242
325
  _checkForm(target) {
243
- if (domUtils.isWysiwygFrame(target)) return false;
244
- if (domUtils.hasClass(target, 'se-drag-handle')) return true;
326
+ if (dom.check.isWysiwygFrame(target)) return false;
327
+ if (dom.utils.hasClass(target, 'se-drag-handle')) return true;
245
328
 
246
329
  let isParentForm = false;
247
330
  if (this.isInsideForm && this.parents?.length > 0) {
@@ -253,63 +336,77 @@ Controller.prototype = {
253
336
  });
254
337
  }
255
338
 
256
- return !isParentForm && (domUtils.getParentElement(target, '.se-controller') || target?.contains(this.inst._element));
257
- },
258
-
259
- constructor: Controller
260
- };
339
+ return !isParentForm && (!!dom.query.getParentElement(target, '.se-controller') || target?.contains(this.inst._element));
340
+ }
261
341
 
262
- // @todo
263
- Controller.CreateHTML = function () {
264
- const html = '';
265
- return domUtils.createElement('DIV', { class: '' }, html);
266
- };
342
+ /**
343
+ * @param {MouseEvent} e - Event object
344
+ */
345
+ #Action(e) {
346
+ const eventTarget = dom.query.getEventTarget(e);
347
+ const target = dom.query.getCommandTarget(eventTarget);
348
+ if (!target) return;
267
349
 
268
- function Action(e) {
269
- const target = domUtils.getCommandTarget(e.target);
270
- if (!target) return;
350
+ e.stopPropagation();
351
+ e.preventDefault();
271
352
 
272
- e.stopPropagation();
273
- e.preventDefault();
353
+ this.inst.controllerAction(target);
354
+ }
274
355
 
275
- this.inst.controllerAction(target);
276
- }
356
+ /**
357
+ * @param {MouseEvent} e - Event object
358
+ */
359
+ #MouseEnter(e) {
360
+ this.editor.currentControllerName = this.kind;
361
+ if (this.parents.length > 0 && this.isInsideForm) return;
277
362
 
278
- function MouseEnter(e) {
279
- this.editor.currentControllerName = this.kind;
280
- if (this.parents.length > 0 && this.isInsideForm) return;
281
- e.target.style.zIndex = INDEX_0;
282
- }
363
+ const eventTarget = dom.query.getEventTarget(e);
364
+ eventTarget.style.zIndex = INDEX_0;
365
+ }
283
366
 
284
- function MouseLeave(e) {
285
- if (this.parents.length > 0 && this.isInsideForm) return;
286
- e.target.style.zIndex = INDEX_2;
287
- }
367
+ /**
368
+ * @param {MouseEvent} e - Event object
369
+ */
370
+ #MouseLeave(e) {
371
+ if (this.parents.length > 0 && this.isInsideForm) return;
288
372
 
289
- function CloseListener_keydown(e) {
290
- if (this._checkFixed()) return;
291
- const keyCode = e.keyCode;
292
- const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
293
- if (ctrl || !NON_RESPONSE_KEYCODE.test(keyCode)) return;
373
+ const eventTarget = dom.query.getEventTarget(e);
374
+ eventTarget.style.zIndex = INDEX_2;
375
+ }
294
376
 
295
- if (this.form.contains(e.target) || this._checkForm(e.target)) return;
296
- if (this.editor._fileManager.pluginRegExp.test(this.kind) && keyCode !== 27) return;
377
+ /**
378
+ * @param {KeyboardEvent} e - Event object
379
+ */
380
+ #CloseListener_keydown(e) {
381
+ if (this._checkFixed()) return;
382
+ const keyCode = e.code;
383
+ const ctrl = keyCodeMap.isCtrl(e);
384
+ if (ctrl || !keyCodeMap.isNonResponseKey(keyCode)) return;
297
385
 
298
- this.close();
299
- }
386
+ const eventTarget = dom.query.getEventTarget(e);
387
+ if (this.form.contains(eventTarget) || this._checkForm(eventTarget)) return;
388
+ if (this.editor._fileManager.pluginRegExp.test(this.kind) && !keyCodeMap.isEsc(keyCode)) return;
300
389
 
301
- function CloseListener_mousedown({ target }) {
302
- if (this.inst?._element?.contains(target)) {
303
- this.isOpen = false;
304
- return;
390
+ this.close();
305
391
  }
306
392
 
307
- this.isOpen = true;
308
- if (target === this.inst._element || target === this.currentTarget || this._checkFixed() || this.form.contains(target) || this._checkForm(target)) {
309
- return;
310
- }
393
+ /**
394
+ * @param {KeyboardEvent} e - Event object
395
+ */
396
+ #CloseListener_mousedown(e) {
397
+ const eventTarget = dom.query.getEventTarget(e);
398
+ if (this.inst?._element?.contains(eventTarget)) {
399
+ this.isOpen = false;
400
+ return;
401
+ }
311
402
 
312
- this.close(true);
403
+ this.isOpen = true;
404
+ if (eventTarget === this.inst._element || eventTarget === this.currentTarget || this._checkFixed() || this.form.contains(eventTarget) || this._checkForm(eventTarget)) {
405
+ return;
406
+ }
407
+
408
+ this.close(true);
409
+ }
313
410
  }
314
411
 
315
412
  export default Controller;