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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/CONTRIBUTING.md +170 -22
  2. package/{LICENSE.txt → LICENSE} +9 -9
  3. package/README.md +168 -30
  4. package/dist/suneditor.min.css +1 -1
  5. package/dist/suneditor.min.js +1 -1
  6. package/package.json +47 -21
  7. package/src/assets/design/color.css +121 -0
  8. package/src/assets/design/index.css +3 -0
  9. package/src/assets/design/size.css +35 -0
  10. package/src/assets/design/typography.css +37 -0
  11. package/src/assets/icons/defaultIcons.js +232 -0
  12. package/src/assets/suneditor-contents.css +181 -46
  13. package/src/assets/suneditor.css +1403 -650
  14. package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
  15. package/src/core/base/eventHandlers/handler_ww_clipboard.js +23 -4
  16. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +49 -10
  17. package/src/core/base/eventHandlers/handler_ww_key_input.js +422 -224
  18. package/src/core/base/eventHandlers/handler_ww_mouse.js +83 -36
  19. package/src/core/base/eventManager.js +520 -179
  20. package/src/core/base/history.js +95 -41
  21. package/src/core/class/char.js +26 -11
  22. package/src/core/class/component.js +345 -137
  23. package/src/core/class/format.js +683 -519
  24. package/src/core/class/html.js +485 -305
  25. package/src/core/class/menu.js +133 -47
  26. package/src/core/class/nodeTransform.js +90 -71
  27. package/src/core/class/offset.js +408 -92
  28. package/src/core/class/selection.js +216 -106
  29. package/src/core/class/shortcuts.js +68 -8
  30. package/src/core/class/toolbar.js +106 -116
  31. package/src/core/class/ui.js +422 -0
  32. package/src/core/class/viewer.js +178 -74
  33. package/src/core/editor.js +496 -389
  34. package/src/core/section/actives.js +123 -27
  35. package/src/core/section/constructor.js +615 -206
  36. package/src/core/section/context.js +28 -23
  37. package/src/core/section/documentType.js +561 -0
  38. package/src/editorInjector/_classes.js +19 -5
  39. package/src/editorInjector/_core.js +71 -7
  40. package/src/editorInjector/index.js +63 -1
  41. package/src/events.js +622 -0
  42. package/src/helper/clipboard.js +59 -0
  43. package/src/helper/converter.js +202 -26
  44. package/src/helper/dom/domCheck.js +304 -0
  45. package/src/helper/dom/domQuery.js +669 -0
  46. package/src/helper/dom/domUtils.js +557 -0
  47. package/src/helper/dom/index.js +12 -0
  48. package/src/helper/env.js +46 -56
  49. package/src/helper/index.js +10 -4
  50. package/src/helper/keyCodeMap.js +183 -0
  51. package/src/helper/numbers.js +12 -8
  52. package/src/helper/unicode.js +9 -5
  53. package/src/langs/ckb.js +74 -4
  54. package/src/langs/cs.js +72 -2
  55. package/src/langs/da.js +73 -3
  56. package/src/langs/de.js +73 -4
  57. package/src/langs/en.js +23 -3
  58. package/src/langs/es.js +73 -4
  59. package/src/langs/fa.js +75 -3
  60. package/src/langs/fr.js +73 -3
  61. package/src/langs/he.js +73 -4
  62. package/src/langs/hu.js +230 -0
  63. package/src/langs/index.js +7 -3
  64. package/src/langs/it.js +70 -1
  65. package/src/langs/ja.js +72 -4
  66. package/src/langs/km.js +230 -0
  67. package/src/langs/ko.js +22 -2
  68. package/src/langs/lv.js +74 -5
  69. package/src/langs/nl.js +73 -4
  70. package/src/langs/pl.js +73 -4
  71. package/src/langs/pt_br.js +70 -1
  72. package/src/langs/ro.js +74 -5
  73. package/src/langs/ru.js +73 -4
  74. package/src/langs/se.js +73 -4
  75. package/src/langs/tr.js +73 -1
  76. package/src/langs/{ua.js → uk.js} +75 -6
  77. package/src/langs/ur.js +77 -8
  78. package/src/langs/zh_cn.js +74 -5
  79. package/src/modules/ApiManager.js +77 -54
  80. package/src/modules/Browser.js +667 -0
  81. package/src/modules/ColorPicker.js +162 -102
  82. package/src/modules/Controller.js +273 -142
  83. package/src/modules/Figure.js +925 -484
  84. package/src/modules/FileManager.js +121 -69
  85. package/src/modules/HueSlider.js +113 -61
  86. package/src/modules/Modal.js +291 -122
  87. package/src/modules/ModalAnchorEditor.js +383 -234
  88. package/src/modules/SelectMenu.js +270 -168
  89. package/src/modules/_DragHandle.js +2 -1
  90. package/src/modules/index.js +3 -3
  91. package/src/plugins/browser/audioGallery.js +83 -0
  92. package/src/plugins/browser/fileBrowser.js +103 -0
  93. package/src/plugins/browser/fileGallery.js +83 -0
  94. package/src/plugins/browser/imageGallery.js +81 -0
  95. package/src/plugins/browser/videoGallery.js +103 -0
  96. package/src/plugins/command/blockquote.js +40 -27
  97. package/src/plugins/command/exportPDF.js +134 -0
  98. package/src/plugins/command/fileUpload.js +229 -162
  99. package/src/plugins/command/list_bulleted.js +83 -47
  100. package/src/plugins/command/list_numbered.js +83 -47
  101. package/src/plugins/dropdown/align.js +66 -54
  102. package/src/plugins/dropdown/backgroundColor.js +63 -49
  103. package/src/plugins/dropdown/font.js +71 -47
  104. package/src/plugins/dropdown/fontColor.js +63 -48
  105. package/src/plugins/dropdown/formatBlock.js +70 -33
  106. package/src/plugins/dropdown/hr.js +92 -51
  107. package/src/plugins/dropdown/layout.js +37 -26
  108. package/src/plugins/dropdown/lineHeight.js +54 -38
  109. package/src/plugins/dropdown/list.js +60 -45
  110. package/src/plugins/dropdown/paragraphStyle.js +51 -30
  111. package/src/plugins/dropdown/table.js +2003 -813
  112. package/src/plugins/dropdown/template.js +38 -26
  113. package/src/plugins/dropdown/textStyle.js +43 -31
  114. package/src/plugins/field/mention.js +147 -86
  115. package/src/plugins/index.js +32 -6
  116. package/src/plugins/input/fontSize.js +161 -108
  117. package/src/plugins/input/pageNavigator.js +70 -0
  118. package/src/plugins/modal/audio.js +358 -173
  119. package/src/plugins/modal/drawing.js +531 -0
  120. package/src/plugins/modal/embed.js +886 -0
  121. package/src/plugins/modal/image.js +674 -362
  122. package/src/plugins/modal/link.js +100 -71
  123. package/src/plugins/modal/math.js +367 -167
  124. package/src/plugins/modal/video.js +691 -335
  125. package/src/plugins/popup/anchor.js +222 -0
  126. package/src/suneditor.js +50 -13
  127. package/src/themes/dark.css +122 -0
  128. package/src/typedef.js +130 -0
  129. package/types/assets/icons/defaultIcons.d.ts +153 -0
  130. package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
  131. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
  132. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
  133. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
  134. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
  135. package/types/core/base/eventManager.d.ts +385 -0
  136. package/types/core/base/history.d.ts +81 -0
  137. package/types/core/class/char.d.ts +60 -0
  138. package/types/core/class/component.d.ts +212 -0
  139. package/types/core/class/format.d.ts +616 -0
  140. package/types/core/class/html.d.ts +422 -0
  141. package/types/core/class/menu.d.ts +126 -0
  142. package/types/core/class/nodeTransform.d.ts +93 -0
  143. package/types/core/class/offset.d.ts +522 -0
  144. package/types/core/class/selection.d.ts +188 -0
  145. package/types/core/class/shortcuts.d.ts +142 -0
  146. package/types/core/class/toolbar.d.ts +189 -0
  147. package/types/core/class/ui.d.ts +164 -0
  148. package/types/core/class/viewer.d.ts +140 -0
  149. package/types/core/editor.d.ts +610 -0
  150. package/types/core/section/actives.d.ts +46 -0
  151. package/types/core/section/constructor.d.ts +777 -0
  152. package/types/core/section/context.d.ts +45 -0
  153. package/types/core/section/documentType.d.ts +178 -0
  154. package/types/editorInjector/_classes.d.ts +41 -0
  155. package/types/editorInjector/_core.d.ts +92 -0
  156. package/types/editorInjector/index.d.ts +71 -0
  157. package/types/events.d.ts +273 -0
  158. package/types/helper/clipboard.d.ts +12 -0
  159. package/types/helper/converter.d.ts +197 -0
  160. package/types/helper/dom/domCheck.d.ts +189 -0
  161. package/types/helper/dom/domQuery.d.ts +223 -0
  162. package/types/helper/dom/domUtils.d.ts +226 -0
  163. package/types/helper/dom/index.d.ts +9 -0
  164. package/types/helper/env.d.ts +132 -0
  165. package/types/helper/index.d.ts +174 -0
  166. package/types/helper/keyCodeMap.d.ts +110 -0
  167. package/types/helper/numbers.d.ts +46 -0
  168. package/types/helper/unicode.d.ts +28 -0
  169. package/types/index.d.ts +120 -0
  170. package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +173 -103
  171. package/types/langs/ckb.d.ts +3 -0
  172. package/types/langs/cs.d.ts +3 -0
  173. package/types/langs/da.d.ts +3 -0
  174. package/types/langs/de.d.ts +3 -0
  175. package/types/langs/en.d.ts +3 -0
  176. package/types/langs/es.d.ts +3 -0
  177. package/types/langs/fa.d.ts +3 -0
  178. package/types/langs/fr.d.ts +3 -0
  179. package/types/langs/he.d.ts +3 -0
  180. package/types/langs/hu.d.ts +3 -0
  181. package/types/langs/index.d.ts +54 -0
  182. package/types/langs/it.d.ts +3 -0
  183. package/types/langs/ja.d.ts +3 -0
  184. package/types/langs/km.d.ts +3 -0
  185. package/types/langs/ko.d.ts +3 -0
  186. package/types/langs/lv.d.ts +3 -0
  187. package/types/langs/nl.d.ts +3 -0
  188. package/types/langs/pl.d.ts +3 -0
  189. package/types/langs/pt_br.d.ts +3 -0
  190. package/types/langs/ro.d.ts +3 -0
  191. package/types/langs/ru.d.ts +3 -0
  192. package/types/langs/se.d.ts +3 -0
  193. package/types/langs/tr.d.ts +3 -0
  194. package/types/langs/uk.d.ts +3 -0
  195. package/types/langs/ur.d.ts +3 -0
  196. package/types/langs/zh_cn.d.ts +3 -0
  197. package/types/modules/ApiManager.d.ts +125 -0
  198. package/types/modules/Browser.d.ts +326 -0
  199. package/types/modules/ColorPicker.d.ts +131 -0
  200. package/types/modules/Controller.d.ts +251 -0
  201. package/types/modules/Figure.d.ts +517 -0
  202. package/types/modules/FileManager.d.ts +202 -0
  203. package/types/modules/HueSlider.d.ts +136 -0
  204. package/types/modules/Modal.d.ts +111 -0
  205. package/types/modules/ModalAnchorEditor.d.ts +236 -0
  206. package/types/modules/SelectMenu.d.ts +194 -0
  207. package/types/modules/_DragHandle.d.ts +7 -0
  208. package/types/modules/index.d.ts +26 -0
  209. package/types/plugins/browser/audioGallery.d.ts +55 -0
  210. package/types/plugins/browser/fileBrowser.d.ts +64 -0
  211. package/types/plugins/browser/fileGallery.d.ts +55 -0
  212. package/types/plugins/browser/imageGallery.d.ts +51 -0
  213. package/types/plugins/browser/videoGallery.d.ts +57 -0
  214. package/types/plugins/command/blockquote.d.ts +28 -0
  215. package/types/plugins/command/exportPDF.d.ts +46 -0
  216. package/types/plugins/command/fileUpload.d.ts +156 -0
  217. package/types/plugins/command/list_bulleted.d.ts +46 -0
  218. package/types/plugins/command/list_numbered.d.ts +46 -0
  219. package/types/plugins/dropdown/align.d.ts +60 -0
  220. package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
  221. package/types/plugins/dropdown/font.d.ts +54 -0
  222. package/types/plugins/dropdown/fontColor.d.ts +63 -0
  223. package/types/plugins/dropdown/formatBlock.d.ts +54 -0
  224. package/types/plugins/dropdown/hr.d.ts +71 -0
  225. package/types/plugins/dropdown/layout.d.ts +40 -0
  226. package/types/plugins/dropdown/lineHeight.d.ts +50 -0
  227. package/types/plugins/dropdown/list.d.ts +39 -0
  228. package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
  229. package/types/plugins/dropdown/table.d.ts +627 -0
  230. package/types/plugins/dropdown/template.d.ts +40 -0
  231. package/types/plugins/dropdown/textStyle.d.ts +41 -0
  232. package/types/plugins/field/mention.d.ts +102 -0
  233. package/types/plugins/index.d.ts +107 -0
  234. package/types/plugins/input/fontSize.d.ts +170 -0
  235. package/types/plugins/input/pageNavigator.d.ts +28 -0
  236. package/types/plugins/modal/audio.d.ts +269 -0
  237. package/types/plugins/modal/drawing.d.ts +246 -0
  238. package/types/plugins/modal/embed.d.ts +387 -0
  239. package/types/plugins/modal/image.d.ts +451 -0
  240. package/types/plugins/modal/link.d.ts +128 -0
  241. package/types/plugins/modal/math.d.ts +193 -0
  242. package/types/plugins/modal/video.d.ts +485 -0
  243. package/types/plugins/popup/anchor.d.ts +56 -0
  244. package/types/suneditor.d.ts +51 -0
  245. package/types/typedef.d.ts +233 -0
  246. package/.eslintignore +0 -7
  247. package/.eslintrc.json +0 -64
  248. package/src/assets/icons/_default.js +0 -194
  249. package/src/core/base/events.js +0 -320
  250. package/src/core/class/notice.js +0 -42
  251. package/src/helper/domUtils.js +0 -1177
  252. package/src/modules/FileBrowser.js +0 -271
  253. package/src/plugins/command/exportPdf.js +0 -168
  254. package/src/plugins/fileBrowser/imageGallery.js +0 -81
  255. package/src/themes/test.css +0 -61
  256. package/typings/CommandPlugin.d.ts +0 -8
  257. package/typings/DialogPlugin.d.ts +0 -20
  258. package/typings/FileBrowserPlugin.d.ts +0 -30
  259. package/typings/Module.d.ts +0 -15
  260. package/typings/Plugin.d.ts +0 -42
  261. package/typings/SubmenuPlugin.d.ts +0 -8
  262. package/typings/_classes.d.ts +0 -17
  263. package/typings/_colorPicker.d.ts +0 -60
  264. package/typings/_core.d.ts +0 -55
  265. package/typings/align.d.ts +0 -5
  266. package/typings/audio.d.ts +0 -5
  267. package/typings/backgroundColor.d.ts +0 -5
  268. package/typings/blockquote.d.ts +0 -5
  269. package/typings/char.d.ts +0 -39
  270. package/typings/component.d.ts +0 -38
  271. package/typings/context.d.ts +0 -39
  272. package/typings/converter.d.ts +0 -33
  273. package/typings/dialog.d.ts +0 -28
  274. package/typings/domUtils.d.ts +0 -361
  275. package/typings/editor.d.ts +0 -7
  276. package/typings/editor.ts +0 -542
  277. package/typings/env.d.ts +0 -70
  278. package/typings/eventManager.d.ts +0 -37
  279. package/typings/events.d.ts +0 -262
  280. package/typings/fileBrowser.d.ts +0 -42
  281. package/typings/fileManager.d.ts +0 -67
  282. package/typings/font.d.ts +0 -5
  283. package/typings/fontColor.d.ts +0 -5
  284. package/typings/fontSize.d.ts +0 -5
  285. package/typings/format.d.ts +0 -191
  286. package/typings/formatBlock.d.ts +0 -5
  287. package/typings/history.d.ts +0 -48
  288. package/typings/horizontalRule.d.ts +0 -5
  289. package/typings/image.d.ts +0 -5
  290. package/typings/imageGallery.d.ts +0 -5
  291. package/typings/index.d.ts +0 -21
  292. package/typings/index.modules.d.ts +0 -11
  293. package/typings/index.plugins.d.ts +0 -58
  294. package/typings/lineHeight.d.ts +0 -5
  295. package/typings/link.d.ts +0 -5
  296. package/typings/list.d.ts +0 -5
  297. package/typings/math.d.ts +0 -5
  298. package/typings/mediaContainer.d.ts +0 -25
  299. package/typings/mention.d.ts +0 -5
  300. package/typings/node.d.ts +0 -57
  301. package/typings/notice.d.ts +0 -16
  302. package/typings/numbers.d.ts +0 -29
  303. package/typings/offset.d.ts +0 -24
  304. package/typings/options.d.ts +0 -589
  305. package/typings/paragraphStyle.d.ts +0 -5
  306. package/typings/resizing.d.ts +0 -141
  307. package/typings/selection.d.ts +0 -94
  308. package/typings/shortcuts.d.ts +0 -13
  309. package/typings/suneditor.d.ts +0 -9
  310. package/typings/table.d.ts +0 -5
  311. package/typings/template.d.ts +0 -5
  312. package/typings/textStyle.d.ts +0 -5
  313. package/typings/toolbar.d.ts +0 -32
  314. package/typings/unicode.d.ts +0 -25
  315. package/typings/video.d.ts +0 -5
@@ -2,32 +2,92 @@
2
2
  * @fileoverview Shortcuts class
3
3
  */
4
4
 
5
- const Shortcuts = function (editor) {
5
+ import { keyCodeMap } from '../../helper';
6
+
7
+ /**
8
+ * @typedef {Omit<Shortcuts & Partial<__se__EditorInjector>, 'shortcuts'>} ShortcutsThis
9
+ */
10
+
11
+ /**
12
+ * @typedef {Object} ShortcutInfo
13
+ * @property {boolean} c - Whether the [Ctrl, Command] key is pressed.
14
+ * @property {boolean} s - Whether the [Shift] key is pressed.
15
+ * @property {boolean} space - Whether the [Space] key is pressed.
16
+ * @property {boolean} enter - Whether the Enter key is pressed.
17
+ * @property {string} command - The command key. (e.g. "bold")
18
+ * @property {boolean} edge - Whether the cursor is at the end of the line.
19
+ * @property {string=} key - The key pressed (e.g., "1.").
20
+ * @property {string=} keyCode - The keyEvent.code.
21
+ * @property {string|((...args: *) => *)=} method - A plugin's "shortcut" method that is called instead of the default "editor.run" method.
22
+ * @property {string} plugin - The plugin name.
23
+ * @property {string} type - Plugin's type. ("command", "dropdown", "modal", "browser", "input", "field", "popup").
24
+ * @property {Node} button - The plugin command button.
25
+ * @property {Array<string>} r - An array of key codes generated with the reverseButtons option, used to reverse the action for a specific key combination.
26
+ * @property {string} textTrigger - Whether the event was triggered by a text input (e.g., mention like @ab).
27
+ */
28
+
29
+ /**
30
+ * @constructor
31
+ * @this {ShortcutsThis}
32
+ * @description Shortcuts class
33
+ * @param {__se__EditorCore} editor - The root editor instance
34
+ */
35
+ function Shortcuts(editor) {
6
36
  this.editor = editor;
7
37
  this.isDisabled = false;
8
- };
38
+ }
9
39
 
10
40
  Shortcuts.prototype = {
11
41
  /**
42
+ * @this {ShortcutsThis}
12
43
  * @description If there is a shortcut function, run it.
13
- * @param {number} keyCode event.keyCode
14
- * @param {boolean} shift Whether to press shift key
44
+ * @param {KeyboardEvent} event Keyboard event object
45
+ * @param {boolean} ctrl Whether the Ctrl key is pressed
46
+ * @param {boolean} shift Whether the Shift key is pressed
47
+ * @param {string} keyCode The keyEvent.code.
48
+ * @param {string} text The text content of the key
49
+ * @param {boolean} edge Whether the cursor is at the end of the line
50
+ * @param {HTMLElement} line The current line node
51
+ * @param {Range} range The current range object
15
52
  * @returns {boolean} Whether to execute shortcuts
16
53
  */
17
- command(keyCode, shift) {
54
+ command(event, ctrl, shift, keyCode, text, edge, line, range) {
18
55
  if (this.isDisabled) return false;
19
56
 
20
- const info = this.editor.shortcutsKeyMap.get(keyCode + (shift ? 1000 : 0));
21
- if (!info || (!shift && info.s)) return false;
57
+ /** @type {ShortcutInfo} */
58
+ let info = null;
59
+
60
+ if (ctrl) {
61
+ info = this.editor.shortcutsKeyMap.get(keyCode + (shift ? '1000' : ''));
62
+ } else {
63
+ info = this.editor.shortcutsKeyMap.get(text) || this.editor.shortcutsKeyMap.get(text + event.key);
64
+ }
65
+
66
+ if (!info || (!shift && info.s) || (info.space && !keyCodeMap.isSpace(keyCode)) || (info.enter && !keyCodeMap.isEnter(keyCode)) || (info.textTrigger && !event.key.trim()) || (info.edge && !edge)) return false;
67
+
68
+ if (info.plugin && typeof info.method === 'string') {
69
+ this.editor.plugins[info.plugin][info.method]?.({ range, line, info, event, keyCode });
70
+ } else if (typeof info.method === 'function') {
71
+ info.method({ range, line, info, event, keyCode, editor: this.editor });
72
+ } else {
73
+ this.editor.run(info.command, info.type, info.button);
74
+ }
22
75
 
23
- this.editor.run(info.c, info.t, info.e);
24
76
  return true;
25
77
  },
26
78
 
79
+ /**
80
+ * @this {ShortcutsThis}
81
+ * @description Disable the shortcut activation.
82
+ */
27
83
  disable() {
28
84
  this.isDisabled = true;
29
85
  },
30
86
 
87
+ /**
88
+ * @this {ShortcutsThis}
89
+ * @description Enable the shortcut activation.
90
+ */
31
91
  enable() {
32
92
  this.isDisabled = false;
33
93
  },
@@ -2,13 +2,29 @@
2
2
  * @fileoverview Toolbar class
3
3
  */
4
4
 
5
- import { domUtils, env } from '../../helper';
5
+ import { dom, env } from '../../helper';
6
6
  import CoreInjector from '../../editorInjector/_core';
7
7
  import { CreateToolBar, UpdateButton } from '../section/constructor';
8
8
 
9
- const { _w, _d } = env;
9
+ const { _w } = env;
10
10
 
11
- const Toolbar = function (editor, { keyName, balloon, inline, balloonAlways, res }) {
11
+ /**
12
+ * @typedef {Omit<Toolbar & Partial<__se__EditorInjector>, 'toolbar' | 'subToolbar'>} ToolbarThis
13
+ */
14
+
15
+ /**
16
+ * @constructor
17
+ * @this {ToolbarThis}
18
+ * @description Toolbar class
19
+ * @param {__se__EditorCore} editor - The root editor instance
20
+ * @param {Object} options - toolbar options
21
+ * @param {String} options.keyName - toolbar key name
22
+ * @param {Boolean} options.balloon - balloon toolbar
23
+ * @param {Boolean} options.inline - inline toolbar
24
+ * @param {Boolean} options.balloonAlways - balloon toolbar always show
25
+ * @param {Array<Node>} options.res - responsive toolbar button list
26
+ */
27
+ function Toolbar(editor, { keyName, balloon, inline, balloonAlways, res }) {
12
28
  CoreInjector.call(this, editor);
13
29
 
14
30
  // members
@@ -21,6 +37,7 @@ const Toolbar = function (editor, { keyName, balloon, inline, balloonAlways, res
21
37
  this._responsiveCurrentSize = 'default';
22
38
  this._originRes = res;
23
39
  this._rButtonArray = res;
40
+ this._rButtonsInfo = null;
24
41
  this._rButtonsize = null;
25
42
  this._sticky = false;
26
43
  this._isViewPortSize = 'visualViewport' in _w;
@@ -35,10 +52,11 @@ const Toolbar = function (editor, { keyName, balloon, inline, balloonAlways, res
35
52
  };
36
53
 
37
54
  this._setResponsive();
38
- };
55
+ }
39
56
 
40
57
  Toolbar.prototype = {
41
58
  /**
59
+ * @this {ToolbarThis}
42
60
  * @description Disable the toolbar
43
61
  */
44
62
  disable() {
@@ -46,17 +64,19 @@ Toolbar.prototype = {
46
64
  this._moreLayerOff();
47
65
  this.menu.dropdownOff();
48
66
  this.menu.containerOff();
49
- domUtils.setDisabled(this.context.get(this.keyName + '.buttonTray').querySelectorAll('.se-menu-list .se-toolbar-btn[data-type]'), true);
67
+ dom.utils.setDisabled(this.context.get(this.keyName + '.buttonTray').querySelectorAll('.se-menu-list .se-toolbar-btn[data-type]'), true);
50
68
  },
51
69
 
52
70
  /**
71
+ * @this {ToolbarThis}
53
72
  * @description Enable the toolbar
54
73
  */
55
74
  enable() {
56
- domUtils.setDisabled(this.context.get(this.keyName + '.buttonTray').querySelectorAll('.se-menu-list .se-toolbar-btn[data-type]'), false);
75
+ dom.utils.setDisabled(this.context.get(this.keyName + '.buttonTray').querySelectorAll('.se-menu-list .se-toolbar-btn[data-type]'), false);
57
76
  },
58
77
 
59
78
  /**
79
+ * @this {ToolbarThis}
60
80
  * @description Show the toolbar
61
81
  */
62
82
  show() {
@@ -73,6 +93,7 @@ Toolbar.prototype = {
73
93
  },
74
94
 
75
95
  /**
96
+ * @this {ToolbarThis}
76
97
  * @description Hide the toolbar
77
98
  */
78
99
  hide() {
@@ -83,7 +104,7 @@ Toolbar.prototype = {
83
104
  } else {
84
105
  this.context.get(this.keyName + '.main').style.display = 'none';
85
106
  if (!this.isSub) this.editor.frameContext.get('_stickyDummy').style.display = 'none';
86
- if (this.editorisBalloon) {
107
+ if (this._isBalloon) {
87
108
  this._balloonOffset = {
88
109
  top: 0,
89
110
  left: 0
@@ -93,20 +114,7 @@ Toolbar.prototype = {
93
114
  },
94
115
 
95
116
  /**
96
- * @desscription Show or hide the toolbar
97
- * @param {boolean} isShow Show or hide
98
- * @private
99
- */
100
- _visible(isShow) {
101
- const toolbar = this.context.get(this.keyName + '.main');
102
- if (isShow) {
103
- domUtils.removeClass(toolbar, 'se-toolbar-onscroll-hide');
104
- } else {
105
- domUtils.addClass(toolbar, 'se-toolbar-onscroll-hide');
106
- }
107
- },
108
-
109
- /**
117
+ * @this {ToolbarThis}
110
118
  * @description Reset buttons of the responsive toolbar.
111
119
  */
112
120
  resetResponsiveToolbar() {
@@ -115,7 +123,7 @@ Toolbar.prototype = {
115
123
  const responsiveSize = this._rButtonsize;
116
124
  if (responsiveSize) {
117
125
  let w = 0;
118
- if (((this._isBalloon || this._isInline) && this.options.get('toolbar_width') === 'auto') || (this._isSubBalloon && this.options.get('toolbar.sub_width') === 'auto')) {
126
+ if (((this._isBalloon || this._isInline) && this.options.get('toolbar_width') === 'auto') || (this.editor.isSubBalloon && this.options.get('toolbar.sub_width') === 'auto')) {
119
127
  w = this.editor.frameContext.get('topArea').offsetWidth;
120
128
  } else {
121
129
  w = this.context.get(this.keyName + '.main').offsetWidth;
@@ -131,15 +139,16 @@ Toolbar.prototype = {
131
139
 
132
140
  if (this._responsiveCurrentSize !== responsiveWidth) {
133
141
  this._responsiveCurrentSize = responsiveWidth;
134
- this.setButtons(this._rButtonArray[responsiveWidth]);
142
+ this.setButtons(this._rButtonsInfo[responsiveWidth]);
135
143
  // this.viewer._resetFullScreenHeight();
136
144
  }
137
145
  }
138
146
  },
139
147
 
140
148
  /**
149
+ * @this {ToolbarThis}
141
150
  * @description Reset the buttons on the toolbar. (Editor is not reloaded)
142
- * You cannot set a new plugin for the button.
151
+ * - You cannot set a new plugin for the button.
143
152
  * @param {Array} buttonList Button list
144
153
  */
145
154
  setButtons(buttonList) {
@@ -150,13 +159,13 @@ Toolbar.prototype = {
150
159
  const { options, icons, lang, isSub } = this;
151
160
  const newToolbar = CreateToolBar(buttonList, this.plugins, options, icons, lang, true);
152
161
 
153
- const shortcutss = options.get('shortcuts');
154
- newToolbar.updateButtons.forEach((v) => UpdateButton(v.button, v.plugin, this.icons, this.lang, shortcutss[v.key]));
162
+ newToolbar.updateButtons.forEach((v) => UpdateButton(v.button, v.plugin, this.icons, this.lang));
155
163
 
156
164
  let cmdButtons;
157
165
  if (isSub) cmdButtons = this.editor.subAllCommandButtons = new Map();
158
166
  else cmdButtons = this.editor.allCommandButtons = new Map();
159
167
  this.editor.commandTargets = new Map();
168
+ this.editor.shortcutsKeyMap = new Map();
160
169
  this.editor.__saveCommandButtons(cmdButtons, newToolbar.buttonTray);
161
170
 
162
171
  this.context.get(this.keyName + '.main').replaceChild(newToolbar.buttonTray, this.context.get(this.keyName + '.buttonTray'));
@@ -170,19 +179,27 @@ Toolbar.prototype = {
170
179
  this.editor.effectNode = null;
171
180
  this.viewer._setButtonsActive();
172
181
  if (this.status.hasFocus) this.eventManager.applyTagEffect();
173
- if (this.editor.frameContext.get('isReadOnly')) domUtils.setDisabled(this.editor._controllerOnDisabledButtons, true);
182
+ if (this.editor.frameContext.get('isReadOnly')) this.ui.setControllerOnDisabledButtons(true);
174
183
 
175
184
  this.triggerEvent('onSetToolbarButtons', { buttonTray: newToolbar.buttonTray, frameContext: this.editor.frameContext });
176
185
  },
177
186
 
187
+ /**
188
+ * @private
189
+ * @this {ToolbarThis}
190
+ * @description Reset the sticky toolbar position based on the editor state.
191
+ */
178
192
  _resetSticky() {
193
+ const wrapper = this.editor.frameContext.get('wrapper');
194
+ if (!wrapper) return;
195
+
179
196
  const toolbar = this.context.get(this.keyName + '.main');
180
197
  if (this.editor.frameContext.get('isFullScreen') || toolbar.offsetWidth === 0 || this.options.get('toolbar_sticky') < 0) return;
181
198
 
182
199
  const currentScrollY = this._isViewPortSize ? _w.visualViewport.pageTop : _w.scrollY;
183
200
 
184
201
  const minHeight = this.editor.frameContext.get('_minHeight');
185
- const editorHeight = this.editor.frameContext.get('wrapper').offsetHeight;
202
+ const editorHeight = wrapper.offsetHeight;
186
203
  const editorOffset = this.offset.getGlobal(this.editor.frameContext.get('topArea'));
187
204
  const y = currentScrollY + this.options.get('toolbar_sticky');
188
205
  const t = (this._isBalloon || this._isInline ? editorOffset.top : this.offset.getGlobal(this.options.get('toolbar_container')).top) - (this._isInline ? toolbar.offsetHeight : 0);
@@ -201,6 +218,11 @@ Toolbar.prototype = {
201
218
  }
202
219
  },
203
220
 
221
+ /**
222
+ * @private
223
+ * @this {ToolbarThis}
224
+ * @description Enable sticky toolbar mode and adjust position.
225
+ */
204
226
  _onSticky(inlineOffset) {
205
227
  const toolbar = this.context.get(this.keyName + '.main');
206
228
 
@@ -213,10 +235,16 @@ Toolbar.prototype = {
213
235
  const toolbarTopPosition = this.options.get('toolbar_sticky') + inlineOffset + this.__getViewportTop();
214
236
  toolbar.style.top = `${toolbarTopPosition}px`;
215
237
  toolbar.style.width = this._isInline ? this._inlineToolbarAttr.width : toolbar.offsetWidth + 'px';
216
- domUtils.addClass(toolbar, 'se-toolbar-sticky');
238
+ dom.utils.addClass(toolbar, 'se-toolbar-sticky');
217
239
  this._sticky = true;
218
240
  },
219
241
 
242
+ /**
243
+ * @private
244
+ * @this {ToolbarThis}
245
+ * @description Get the viewport's top offset.
246
+ * @returns {number}
247
+ */
220
248
  __getViewportTop() {
221
249
  if (this._isViewPortSize) {
222
250
  return _w.visualViewport.offsetTop;
@@ -224,6 +252,11 @@ Toolbar.prototype = {
224
252
  return 0;
225
253
  },
226
254
 
255
+ /**
256
+ * @private
257
+ * @this {ToolbarThis}
258
+ * @description Disable sticky toolbar mode.
259
+ */
227
260
  _offSticky() {
228
261
  const stickyDummy = !this.options.get('toolbar_container') ? this.editor.frameContext.get('_stickyDummy') : this.context.get('_stickyDummy');
229
262
  stickyDummy.style.display = 'none';
@@ -233,10 +266,15 @@ Toolbar.prototype = {
233
266
  toolbar.style.width = this._isInline ? this._inlineToolbarAttr.width : '';
234
267
  this.editor.frameContext.get('wrapper').style.marginTop = '';
235
268
 
236
- domUtils.removeClass(toolbar, 'se-toolbar-sticky');
269
+ dom.utils.removeClass(toolbar, 'se-toolbar-sticky');
237
270
  this._sticky = false;
238
271
  },
239
272
 
273
+ /**
274
+ * @private
275
+ * @this {ToolbarThis}
276
+ * @description Set up responsive behavior for the toolbar buttons.
277
+ */
240
278
  _setResponsive() {
241
279
  if (this._rButtonArray?.length === 0) {
242
280
  this._rButtonArray = null;
@@ -246,7 +284,7 @@ Toolbar.prototype = {
246
284
  this._responsiveCurrentSize = 'default';
247
285
  const _rButtonsize = (this._rButtonsize = []);
248
286
  const _responsiveButtons = this._originRes;
249
- const buttonsObj = (this._rButtonArray = {
287
+ const buttonsObj = (this._rButtonsInfo = {
250
288
  default: _responsiveButtons[0]
251
289
  });
252
290
 
@@ -257,13 +295,15 @@ Toolbar.prototype = {
257
295
  buttonsObj[size] = buttonGroup[1];
258
296
  }
259
297
 
260
- _rButtonsize
261
- .sort(function (a, b) {
262
- return a - b;
263
- })
264
- .unshift('default');
298
+ _rButtonsize.sort((a, b) => a - b).unshift('default');
265
299
  },
266
300
 
301
+ /**
302
+ * @private
303
+ * @this {ToolbarThis}
304
+ * @description Show the balloon toolbar based on the current selection.
305
+ * @param {?Range=} rangeObj - Selection range
306
+ */
267
307
  _showBalloon(rangeObj) {
268
308
  if (!this._isBalloon || this.editor.opendControllers.length > 0) {
269
309
  return;
@@ -280,50 +320,31 @@ Toolbar.prototype = {
280
320
  } else if (selection.focusNode === selection.anchorNode) {
281
321
  isDirTop = selection.focusOffset < selection.anchorOffset;
282
322
  } else {
283
- const childNodes = domUtils.getListChildNodes(range.commonAncestorContainer, null);
284
- isDirTop = domUtils.getArrayIndex(childNodes, selection.focusNode) < domUtils.getArrayIndex(childNodes, selection.anchorNode);
285
- }
286
-
287
- toolbar.style.top = '-10000px';
288
- if (toolbar.style.display !== 'block') {
289
- toolbar.style.visibility = 'hidden';
290
- toolbar.style.display = 'block';
323
+ const childNodes = dom.query.getListChildNodes(range.commonAncestorContainer, null);
324
+ isDirTop = dom.utils.getArrayIndex(childNodes, selection.focusNode) < dom.utils.getArrayIndex(childNodes, selection.anchorNode);
291
325
  }
292
326
 
293
327
  this._setBalloonOffset(isDirTop, range);
294
328
 
295
329
  this.triggerEvent('onShowToolbar', { toolbar, mode: 'balloon', frameContext: this.editor.frameContext });
296
-
297
- _w.setTimeout(() => {
298
- toolbar.style.visibility = '';
299
- }, 0);
300
330
  },
301
331
 
332
+ /**
333
+ * @private
334
+ * @this {ToolbarThis}
335
+ * @description Adjust the balloon toolbar's position.
336
+ * @param {boolean} positionTop - Whether the toolbar should be positioned above the selection
337
+ * @param {Range} [range] - Selection range
338
+ */
302
339
  _setBalloonOffset(positionTop, range) {
303
- const isFullScreen = this.editor.frameContext.get('isFullScreen');
304
- range = range || this.selection.getRange();
305
- const rectsObj = this.selection.getRects(range, positionTop ? 'start' : 'end');
306
- positionTop = rectsObj.position === 'start';
307
340
  const toolbar = this.context.get(this.keyName + '.main');
308
341
  const topArea = this.editor.frameContext.get('topArea');
309
- const rects = rectsObj.rects;
310
- const scrollLeft = isFullScreen ? 0 : rectsObj.scrollLeft;
311
- const scrollTop = isFullScreen ? 0 : rectsObj.scrollTop;
312
- const editorWidth = topArea.offsetWidth;
313
342
  const offsets = this.offset.getGlobal(topArea);
314
343
  const stickyTop = offsets.top;
315
- const editorLeft = offsets.left;
316
- const toolbarWidth = toolbar.offsetWidth;
317
- const toolbarHeight = toolbar.offsetHeight;
318
-
319
- this._setBalloonPosition(positionTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop);
320
- if (this.isSub && this.offset.getGlobal(toolbar).top - offsets.top < 0) {
321
- positionTop = !positionTop;
322
- this._setBalloonPosition(positionTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop);
323
- }
324
344
 
325
- if (toolbarWidth !== toolbar.offsetWidth || toolbarHeight !== toolbar.offsetHeight) {
326
- this._setBalloonPosition(positionTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop);
345
+ if (!this.offset.setRangePosition(toolbar, range, { position: positionTop ? 'top' : 'bottom', addTop: stickyTop })) {
346
+ this.hide();
347
+ return;
327
348
  }
328
349
 
329
350
  if (this.options.get('toolbar_container')) {
@@ -351,51 +372,11 @@ Toolbar.prototype = {
351
372
  };
352
373
  },
353
374
 
354
- _setBalloonPosition(isDirTop, rects, toolbarEl, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop) {
355
- const padding = 1;
356
- const arrow = this.context.get(this.keyName + '._arrow');
357
- const arrowMargin = Math.round(arrow.offsetWidth / 2);
358
- const toolbarWidth = toolbarEl.offsetWidth;
359
- const toolbarHeight = rects.noText && !isDirTop ? 0 : toolbarEl.offsetHeight;
360
-
361
- const absoluteLeft = (isDirTop ? rects.left : rects.right) - editorLeft - toolbarWidth / 2 + scrollLeft;
362
- const overRight = absoluteLeft + toolbarWidth - editorWidth;
363
-
364
- let t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop;
365
- const l = absoluteLeft < 0 ? padding : overRight < 0 ? absoluteLeft : absoluteLeft - overRight - padding - 1;
366
-
367
- let resetTop = false;
368
- const space = t + (isDirTop ? this.offset.getGlobal(this.editor.frameContext.get('topArea')).top : toolbarEl.offsetHeight - this.editor.frameContext.get('wysiwyg').offsetHeight);
369
- if (!isDirTop && space > 0 && this._getPageBottomSpace() < space) {
370
- isDirTop = true;
371
- resetTop = true;
372
- } else if (isDirTop && _d.documentElement.offsetTop > space) {
373
- isDirTop = false;
374
- resetTop = true;
375
- }
376
-
377
- if (resetTop) t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop;
378
-
379
- toolbarEl.style.left = Math.floor(l) + 'px';
380
- toolbarEl.style.top = Math.floor(t) + 'px';
381
-
382
- if (isDirTop) {
383
- domUtils.removeClass(arrow, 'se-arrow-up');
384
- domUtils.addClass(arrow, 'se-arrow-down');
385
- } else {
386
- domUtils.removeClass(arrow, 'se-arrow-down');
387
- domUtils.addClass(arrow, 'se-arrow-up');
388
- }
389
-
390
- const arrow_left = Math.floor(toolbarWidth / 2 + (absoluteLeft - l));
391
- arrow.style.left = (arrow_left + arrowMargin > toolbarEl.offsetWidth ? toolbarEl.offsetWidth - arrowMargin : arrow_left < arrowMargin ? arrowMargin : arrow_left) + 'px';
392
- },
393
-
394
- _getPageBottomSpace() {
395
- const topArea = this.editor.frameContext.get('topArea');
396
- return _d.documentElement.scrollHeight - (this.offset.getGlobal(topArea).top + topArea.offsetHeight);
397
- },
398
-
375
+ /**
376
+ * @private
377
+ * @this {ToolbarThis}
378
+ * @description Show the inline toolbar mode.
379
+ */
399
380
  _showInline() {
400
381
  if (!this._isInline) return;
401
382
 
@@ -416,20 +397,29 @@ Toolbar.prototype = {
416
397
  toolbar.style.visibility = '';
417
398
  },
418
399
 
400
+ /**
401
+ * @private
402
+ * @this {ToolbarThis}
403
+ * @description Show a more options layer for toolbar buttons.
404
+ * @param {Node} button - Button element
405
+ * @param {Node} layer - More options layer element
406
+ */
419
407
  _moreLayerOn(button, layer) {
420
408
  this._moreLayerOff();
421
- this.currentMoreLayerActiveButton = button;
422
- layer.style.display = 'block';
409
+ this.currentMoreLayerActiveButton = /** @type {HTMLButtonElement} */ (button);
410
+ /** @type {HTMLElement} */ (layer).style.display = 'block';
423
411
  },
424
412
 
425
413
  /**
426
- * @description Disable more layer
414
+ * @private
415
+ * @this {ToolbarThis}
416
+ * @description Hide the currently active more options layer.
427
417
  */
428
418
  _moreLayerOff() {
429
419
  if (this.currentMoreLayerActiveButton) {
430
420
  const layer = this.context.get(this.keyName + '.main').querySelector('.' + this.currentMoreLayerActiveButton.getAttribute('data-command'));
431
421
  layer.style.display = 'none';
432
- domUtils.removeClass(this.currentMoreLayerActiveButton, 'on');
422
+ dom.utils.removeClass(this.currentMoreLayerActiveButton, 'on');
433
423
  this.currentMoreLayerActiveButton = null;
434
424
  }
435
425
  },