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,37 +1,147 @@
1
1
  import CoreInjector from '../editorInjector/_core';
2
2
  import { CreateTooltipInner } from '../core/section/constructor';
3
+ import { dom, env, keyCodeMap } from '../helper';
4
+
5
+ const { _w } = env;
6
+ const DIRECTION_CURSOR_MAP = { w: 'ns-resize', h: 'ew-resize', c: 'nwse-resize', wRTL: 'ns-resize', hRTL: 'ew-resize', cRTL: 'nesw-resize' };
7
+
8
+ /**
9
+ * @typedef {import('../core/class/offset').OffsetGlobalInfo} OffsetGlobalInfo
10
+ */
11
+
12
+ /**
13
+ * @class
14
+ * @description Modal window module
15
+ */
16
+ class Modal extends CoreInjector {
17
+ /**
18
+ * @description Modal window module
19
+ * @param {* & {editor: __se__EditorCore}} inst The instance object that called the constructor.
20
+ * @param {Element} element Modal element
21
+ */
22
+ constructor(inst, element) {
23
+ super(inst.editor);
24
+ this.offset = this.editor.offset;
25
+ this.ui = this.editor.ui;
26
+
27
+ // members
28
+ this.inst = inst;
29
+ this.kind = inst.constructor.key || inst.constructor.name;
30
+ this.form = /** @type {HTMLElement} */ (element);
31
+ this.isUpdate = false;
32
+
33
+ /** @type {HTMLInputElement} */
34
+ this.focusElement = element.querySelector('[data-focus]');
35
+ /** @type {HTMLElement} */
36
+ this._modalArea = this.carrierWrapper.querySelector('.se-modal');
37
+ /** @type {HTMLElement} */
38
+ this._modalBack = this.carrierWrapper.querySelector('.se-modal-back');
39
+ /** @type {HTMLElement} */
40
+ this._modalInner = this.carrierWrapper.querySelector('.se-modal-inner');
41
+
42
+ this._closeListener = [this.#CloseListener.bind(this), this.#OnClick_dialog.bind(this)];
43
+ this._bindClose = null;
44
+ this._onClickEvent = null;
45
+ this._closeSignal = false;
46
+
47
+ // resie
48
+ /** @type {HTMLElement} */
49
+ this._resizeBody = null;
50
+
51
+ // add element
52
+ this._modalInner.appendChild(element);
53
+
54
+ // init
55
+ this.eventManager.addEvent(element.querySelector('form'), 'submit', this.#Action.bind(this));
56
+ this._closeSignal = !this.eventManager.addEvent(element.querySelector('[data-command="close"]'), 'click', this.close.bind(this));
57
+
58
+ // resize
59
+ if (element.querySelector('.se-modal-resize-handle-w') || element.querySelector('.se-modal-resize-handle-h') || element.querySelector('.se-modal-resize-handle-c') || element.querySelector('.se-modal-resize-form')) {
60
+ if (!(this._resizeBody = element.querySelector('.se-modal-resize-form')) && (this._resizeBody = element.querySelector('.se-modal-body'))) {
61
+ this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-w'), 'mousedown', this.#OnResizeMouseDown.bind(this, 'w'));
62
+ this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-h'), 'mousedown', this.#OnResizeMouseDown.bind(this, 'h'));
63
+ this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-c'), 'mousedown', this.#OnResizeMouseDown.bind(this, 'c'));
64
+
65
+ this._currentHandle = null;
66
+ this.__resizeDir = '';
67
+ this.__offetTop = 0;
68
+ this.__offetLeft = 0;
69
+ this.__globalEventHandlers = {
70
+ mousemove: this.#OnResize.bind(this),
71
+ mouseup: this.#OnResizeMouseUp.bind(this)
72
+ };
73
+ this._bindClose_mousemove = null;
74
+ this._bindClose_mouseup = null;
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @description Create a file input tag in the modal window.
81
+ * @param {{icons: __se__EditorCore['icons'], lang: __se__EditorCore['lang']}} param0 - icons and language object
82
+ * @param {{acceptedFormats: string, allowMultiple}} param1 - options
83
+ * - acceptedFormats: "image/*, video/*, audio/*", etc.
84
+ * - allowMultiple: true or false
85
+ * @returns {string} HTML string
86
+ */
87
+ static CreateFileInput({ icons, lang }, { acceptedFormats, allowMultiple }) {
88
+ return /*html*/ `
89
+ <div class="se-modal-form-files">
90
+ <div class="se-flex-input-wrapper">
91
+ <div class="se-input-form-abs">
92
+ <div>
93
+ <div class="se-input-file-w">
94
+ <div class="se-input-file-icon-up">${icons.upload_tray}</div>
95
+ <div class="se-input-file-icon-files">${icons.file_plus}</div>
96
+ <span class="se-input-file-cnt"></span>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ <input class="se-input-form __se__file_input" data-focus type="file" accept="${acceptedFormats}"${allowMultiple ? ' multiple="multiple"' : ''}/>
101
+ </div>
102
+ <button type="button" class="se-btn se-modal-files-edge-button se-file-remove se-tooltip" aria-label="${lang.remove}">
103
+ ${icons.selection_remove}
104
+ ${CreateTooltipInner(lang.remove)}
105
+ </button>
106
+ </div>`;
107
+ }
108
+
109
+ /**
110
+ * @description A function called when the contents of "input" have changed and you want to adjust the style.
111
+ * @param {Element} wrapper - Modal file input wrapper(.se-flex-input-wrapper)
112
+ * @param {FileList|File[]} files - FileList object
113
+ */
114
+ static OnChangeFile(wrapper, files) {
115
+ if (!wrapper || !files) return;
116
+
117
+ const fileCnt = /** @type {HTMLElement} */ (wrapper.querySelector('.se-input-file-cnt'));
118
+ const fileUp = /** @type {HTMLElement} */ (wrapper.querySelector('.se-input-file-icon-up'));
119
+ const fileSelected = /** @type {HTMLElement} */ (wrapper.querySelector('.se-input-file-icon-files'));
120
+
121
+ if (files.length > 1) {
122
+ fileUp.style.display = 'none';
123
+ fileSelected.style.display = 'inline-block';
124
+ fileCnt.style.display = '';
125
+ fileCnt.textContent = ` ..${files.length}`;
126
+ } else if (files.length > 0) {
127
+ fileUp.style.display = 'none';
128
+ fileSelected.style.display = 'none';
129
+ fileCnt.style.display = 'block';
130
+ fileCnt.textContent = files[0].name;
131
+ } else {
132
+ fileUp.style.display = 'inline-block';
133
+ fileSelected.style.display = 'none';
134
+ fileCnt.style.display = '';
135
+ fileCnt.textContent = '';
136
+ }
137
+ }
3
138
 
4
- const Modal = function (inst, element) {
5
- CoreInjector.call(this, inst.editor);
6
-
7
- // members
8
- this.inst = inst;
9
- this.kind = inst.constructor.key || inst.constructor.name;
10
- this.form = element;
11
- this.focusElement = element.querySelector('[data-focus]');
12
- this.isUpdate = false;
13
- this._modalArea = this.carrierWrapper.querySelector('.se-modal');
14
- this._modalBack = this.carrierWrapper.querySelector('.se-modal-back');
15
- this._modalInner = this.carrierWrapper.querySelector('.se-modal-inner');
16
- this._closeListener = [CloseListener.bind(this), OnClick_dialog.bind(this)];
17
- this._bindClose = null;
18
- this._onClickEvent = null;
19
- this._closeSignal = false;
20
-
21
- // add element
22
- this._modalInner.appendChild(element);
23
-
24
- // init
25
- this.eventManager.addEvent(element.querySelector('form'), 'submit', Action.bind(this));
26
- this._closeSignal = !this.eventManager.addEvent(element.querySelector('[data-command="close"]'), 'click', this.close.bind(this));
27
- };
28
-
29
- Modal.prototype = {
30
139
  /**
31
140
  * @description Open a modal plugin
141
+ * - The plugin's "init" method is called.
32
142
  */
33
143
  open() {
34
- this.editor._offCurrentModal();
144
+ this.ui._offCurrentModal();
35
145
  this._fixCurrentController(true);
36
146
 
37
147
  if (this._closeSignal) this._modalInner.addEventListener('click', this._closeListener[1]);
@@ -48,16 +158,29 @@ Modal.prototype = {
48
158
  this._modalInner.style.display = 'block';
49
159
  this.form.style.display = 'block';
50
160
 
161
+ if (this._resizeBody) {
162
+ const offset = this._saveOffset();
163
+ const { maxWidth, maxHeight } = _w.getComputedStyle(this.form);
164
+ const mw = `${this.form.offsetWidth - offset.width}px`;
165
+ const mh = `${this.form.offsetTop + (this.form.offsetHeight - this._resizeBody.offsetHeight)}px`;
166
+ // set max
167
+ if (maxWidth && typeof this.__resizeDir === 'string') dom.utils.setStyle(this._resizeBody, 'max-width', `calc(${maxWidth} - ${mw})`);
168
+ if (maxHeight) dom.utils.setStyle(this._resizeBody, 'max-height', `calc(${maxHeight} - ${mh})`);
169
+ }
170
+
51
171
  if (this.focusElement) this.focusElement.focus();
52
- },
172
+ }
53
173
 
54
174
  /**
55
175
  * @description Close a modal plugin
56
- * The plugin's "init" method is called.
176
+ * - The plugin's "init" and "off" method is called.
57
177
  */
58
178
  close() {
179
+ this.__removeGlobalEvent();
59
180
  this._fixCurrentController(false);
60
- this.editor.opendModal = null;
181
+ _w.setTimeout(() => {
182
+ this.editor.opendModal = null;
183
+ }, 0);
61
184
 
62
185
  if (this._closeSignal) this._modalInner.removeEventListener('click', this._closeListener[1]);
63
186
  if (this._bindClose) this._bindClose = this.eventManager.removeGlobalEvent(this._bindClose);
@@ -68,110 +191,166 @@ Modal.prototype = {
68
191
  this._modalArea.style.display = 'none';
69
192
 
70
193
  if (typeof this.inst.init === 'function') this.inst.init();
194
+ if (typeof this.inst.off === 'function') this.inst.off(this.isUpdate);
71
195
  this.editor.focus();
72
- },
196
+ }
73
197
 
198
+ /**
199
+ * @private
200
+ * @description Fixes the current controller's display state when the modal is opened or closed.
201
+ * @param {boolean} fixed - Whether to fix or unfix the controller.
202
+ */
74
203
  _fixCurrentController(fixed) {
75
204
  const cont = this.editor.opendControllers;
76
205
  for (let i = 0; i < cont.length; i++) {
77
206
  cont[i].fixed = fixed;
78
207
  cont[i].form.style.display = fixed ? 'none' : 'block';
79
208
  }
80
- },
209
+ }
81
210
 
82
- constructor: Modal
83
- };
211
+ /**
212
+ * @private
213
+ * @description Saves the current offset position of the modal for resizing calculations.
214
+ * @returns {OffsetGlobalInfo} Offset values including top and left positions. (offset.getGlobal)
215
+ */
216
+ _saveOffset() {
217
+ const offset = this.offset.getGlobal(this._resizeBody);
218
+ this.__offetTop = offset.top;
219
+ this.__offetLeft = offset.left;
220
+ return offset;
221
+ }
84
222
 
85
- /**
86
- * The loading bar is executed before "modalAction" is executed.
87
- * return type -
88
- * true : the loading bar and modal window are closed.
89
- * false : only the loading bar is closed.
90
- * undefined : only the modal window is closed.
91
- * -
92
- * exception occurs : the modal window and loading bar are closed.
93
- */
94
- async function Action(e) {
95
- e.preventDefault();
96
- e.stopPropagation();
223
+ /**
224
+ * @private
225
+ * @description Adds global event listeners for resizing the modal.
226
+ * @param {string} dir - The direction in which resizing is occurring.
227
+ */
228
+ __addGlobalEvent(dir) {
229
+ this.__removeGlobalEvent();
230
+ this.ui.enableBackWrapper(DIRECTION_CURSOR_MAP[dir]);
231
+ this._bindClose_mousemove = this.eventManager.addGlobalEvent('mousemove', this.__globalEventHandlers.mousemove, true);
232
+ this._bindClose_mouseup = this.eventManager.addGlobalEvent('mouseup', this.__globalEventHandlers.mouseup, true);
233
+ }
97
234
 
98
- this.editor.showLoading();
235
+ /**
236
+ * @private
237
+ * @description Removes global event listeners related to modal resizing.
238
+ */
239
+ __removeGlobalEvent() {
240
+ this.ui.disableBackWrapper();
241
+ if (this._bindClose_mousemove) this._bindClose_mousemove = this.eventManager.removeGlobalEvent(this._bindClose_mousemove);
242
+ if (this._bindClose_mouseup) this._bindClose_mouseup = this.eventManager.removeGlobalEvent(this._bindClose_mouseup);
243
+ }
99
244
 
100
- try {
101
- const result = await this.inst.modalAction();
102
- if (result === false) {
103
- this.editor.hideLoading();
104
- } else if (result === undefined) {
245
+ /**
246
+ * The loading bar is executed before "modalAction" is executed.
247
+ * return type -
248
+ * true : the loading bar and modal window are closed.
249
+ * false : only the loading bar is closed.
250
+ * undefined : only the modal window is closed.
251
+ * -
252
+ * exception occurs : the modal window and loading bar are closed.
253
+ * @param {SubmitEvent} e - Event object
254
+ */
255
+ async #Action(e) {
256
+ e.preventDefault();
257
+ e.stopPropagation();
258
+
259
+ this.ui.showLoading();
260
+
261
+ try {
262
+ const result = await this.inst.modalAction();
263
+ if (result === false) {
264
+ this.ui.hideLoading();
265
+ } else if (result === undefined) {
266
+ this.close();
267
+ } else {
268
+ this.close();
269
+ this.ui.hideLoading();
270
+ }
271
+ } catch (error) {
105
272
  this.close();
106
- } else {
273
+ this.ui.hideLoading();
274
+ throw Error(`[SUNEDITOR.Modal[${this.kind}].warn] ${error.message}`);
275
+ }
276
+ }
277
+
278
+ /**
279
+ * @param {MouseEvent} e - Event object
280
+ */
281
+ #OnClick_dialog(e) {
282
+ const eventTarget = dom.query.getEventTarget(e);
283
+ if (/close/.test(eventTarget.getAttribute('data-command')) || eventTarget === this._modalInner) {
107
284
  this.close();
108
- this.editor.hideLoading();
109
285
  }
110
- } catch (error) {
111
- this.close();
112
- this.editor.hideLoading();
113
- throw Error(`[SUNEDITOR.Modal[${this.kind}].warn] ${error.message}`);
114
286
  }
115
- }
116
287
 
117
- function OnClick_dialog(e) {
118
- if (/close/.test(e.target.getAttribute('data-command')) || e.target === this._modalInner) {
288
+ /**
289
+ * @param {KeyboardEvent} e - Event object
290
+ */
291
+ #CloseListener(e) {
292
+ if (!keyCodeMap.isEsc(e.code)) return;
119
293
  this.close();
120
294
  }
121
- }
122
295
 
123
- function CloseListener(e) {
124
- if (!/27/.test(e.keyCode)) return;
125
- this.close();
126
- }
296
+ /** ---------- Resize events ---------- */
297
+ /**
298
+ * @param {string} dir - The direction in which the resize handle is located.
299
+ * @param {MouseEvent} e - Event object
300
+ */
301
+ #OnResizeMouseDown(dir, e) {
302
+ this._currentHandle = dom.query.getEventTarget(e);
303
+ dom.utils.addClass(this._currentHandle, 'active');
304
+ this.__addGlobalEvent((this.__resizeDir = dir + (this.options.get('_rtl') ? 'RTL' : '')));
305
+ }
127
306
 
128
- // HTML Creator ======================================================================================================
129
-
130
- // Create a file input tag
131
- Modal.CreateFileInput = function ({ icons, lang }, { acceptedFormats, allowMultiple }) {
132
- return /*html*/ `
133
- <div class="se-modal-form-files">
134
- <div class="se-flex-input-wrapper">
135
- <div class="se-input-form-abs">
136
- <div>
137
- <div class="se-input-file-w">
138
- <div class="se-input-file-icon-up">${icons.upload_tray}</div>
139
- <div class="se-input-file-icon-files">${icons.file_plus}</div>
140
- <span class="se-input-file-cnt"></span>
141
- </div>
142
- </div>
143
- </div>
144
- <input class="se-input-form __se__file_input" data-focus type="file" accept="${acceptedFormats}"${allowMultiple ? ' multiple="multiple"' : ''}/>
145
- </div>
146
- <button type="button" class="se-btn se-modal-files-edge-button se-file-remove se-tooltip" aria-label="${lang.remove}">
147
- ${icons.selection_remove}
148
- ${CreateTooltipInner(lang.remove)}
149
- </button>
150
- </div>`;
151
- };
152
- Modal.OnChangeFile = function (wrapper, files) {
153
- if (!wrapper || !files) return;
154
-
155
- const fileCnt = wrapper.querySelector('.se-input-file-cnt');
156
- const fileUp = wrapper.querySelector('.se-input-file-icon-up');
157
- const fileSelected = wrapper.querySelector('.se-input-file-icon-files');
158
-
159
- if (files.length > 1) {
160
- fileUp.style.display = 'none';
161
- fileSelected.style.display = 'inline-block';
162
- fileCnt.style.display = '';
163
- fileCnt.textContent = ` ..${files.length}`;
164
- } else if (files.length > 0) {
165
- fileUp.style.display = 'none';
166
- fileSelected.style.display = 'none';
167
- fileCnt.style.display = 'block';
168
- fileCnt.textContent = files[0].name;
169
- } else {
170
- fileUp.style.display = 'inline-block';
171
- fileSelected.style.display = 'none';
172
- fileCnt.style.display = '';
173
- fileCnt.textContent = '';
307
+ /**
308
+ * @param {MouseEvent} e - Event object
309
+ */
310
+ #OnResize(e) {
311
+ switch (this.__resizeDir) {
312
+ case 'w':
313
+ case 'wRTL': {
314
+ const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
315
+ this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
316
+ break;
317
+ }
318
+ case 'h': {
319
+ const w = e.clientX - this.__offetLeft - this._resizeBody.offsetWidth;
320
+ this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
321
+ break;
322
+ }
323
+ case 'hRTL': {
324
+ const w = this.__offetLeft - e.clientX;
325
+ this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
326
+ break;
327
+ }
328
+ case 'c': {
329
+ const w = e.clientX - this.__offetLeft - this._resizeBody.offsetWidth;
330
+ const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
331
+ this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
332
+ this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
333
+ break;
334
+ }
335
+ case 'cRTL': {
336
+ const w = this.__offetLeft - e.clientX;
337
+ const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
338
+ this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
339
+ this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
340
+ break;
341
+ }
342
+ }
343
+
344
+ this._saveOffset();
345
+
346
+ if (typeof this.inst.modalResize === 'function') this.inst.modalResize();
174
347
  }
175
- };
348
+
349
+ #OnResizeMouseUp() {
350
+ dom.utils.removeClass(this._currentHandle, 'active');
351
+ this._currentHandle = null;
352
+ this.__removeGlobalEvent();
353
+ }
354
+ }
176
355
 
177
356
  export default Modal;