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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/CONTRIBUTING.md +170 -22
  2. package/{LICENSE.txt → LICENSE} +9 -9
  3. package/README.md +168 -30
  4. package/dist/suneditor.min.css +1 -1
  5. package/dist/suneditor.min.js +1 -1
  6. package/package.json +47 -21
  7. package/src/assets/design/color.css +121 -0
  8. package/src/assets/design/index.css +3 -0
  9. package/src/assets/design/size.css +35 -0
  10. package/src/assets/design/typography.css +37 -0
  11. package/src/assets/icons/defaultIcons.js +232 -0
  12. package/src/assets/suneditor-contents.css +181 -46
  13. package/src/assets/suneditor.css +1403 -650
  14. package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
  15. package/src/core/base/eventHandlers/handler_ww_clipboard.js +23 -4
  16. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +49 -10
  17. package/src/core/base/eventHandlers/handler_ww_key_input.js +422 -224
  18. package/src/core/base/eventHandlers/handler_ww_mouse.js +83 -36
  19. package/src/core/base/eventManager.js +520 -179
  20. package/src/core/base/history.js +95 -41
  21. package/src/core/class/char.js +26 -11
  22. package/src/core/class/component.js +345 -137
  23. package/src/core/class/format.js +683 -519
  24. package/src/core/class/html.js +485 -305
  25. package/src/core/class/menu.js +133 -47
  26. package/src/core/class/nodeTransform.js +90 -71
  27. package/src/core/class/offset.js +408 -92
  28. package/src/core/class/selection.js +216 -106
  29. package/src/core/class/shortcuts.js +68 -8
  30. package/src/core/class/toolbar.js +106 -116
  31. package/src/core/class/ui.js +422 -0
  32. package/src/core/class/viewer.js +178 -74
  33. package/src/core/editor.js +496 -389
  34. package/src/core/section/actives.js +123 -27
  35. package/src/core/section/constructor.js +615 -206
  36. package/src/core/section/context.js +28 -23
  37. package/src/core/section/documentType.js +561 -0
  38. package/src/editorInjector/_classes.js +19 -5
  39. package/src/editorInjector/_core.js +71 -7
  40. package/src/editorInjector/index.js +63 -1
  41. package/src/events.js +622 -0
  42. package/src/helper/clipboard.js +59 -0
  43. package/src/helper/converter.js +202 -26
  44. package/src/helper/dom/domCheck.js +304 -0
  45. package/src/helper/dom/domQuery.js +669 -0
  46. package/src/helper/dom/domUtils.js +557 -0
  47. package/src/helper/dom/index.js +12 -0
  48. package/src/helper/env.js +46 -56
  49. package/src/helper/index.js +10 -4
  50. package/src/helper/keyCodeMap.js +183 -0
  51. package/src/helper/numbers.js +12 -8
  52. package/src/helper/unicode.js +9 -5
  53. package/src/langs/ckb.js +74 -4
  54. package/src/langs/cs.js +72 -2
  55. package/src/langs/da.js +73 -3
  56. package/src/langs/de.js +73 -4
  57. package/src/langs/en.js +23 -3
  58. package/src/langs/es.js +73 -4
  59. package/src/langs/fa.js +75 -3
  60. package/src/langs/fr.js +73 -3
  61. package/src/langs/he.js +73 -4
  62. package/src/langs/hu.js +230 -0
  63. package/src/langs/index.js +7 -3
  64. package/src/langs/it.js +70 -1
  65. package/src/langs/ja.js +72 -4
  66. package/src/langs/km.js +230 -0
  67. package/src/langs/ko.js +22 -2
  68. package/src/langs/lv.js +74 -5
  69. package/src/langs/nl.js +73 -4
  70. package/src/langs/pl.js +73 -4
  71. package/src/langs/pt_br.js +70 -1
  72. package/src/langs/ro.js +74 -5
  73. package/src/langs/ru.js +73 -4
  74. package/src/langs/se.js +73 -4
  75. package/src/langs/tr.js +73 -1
  76. package/src/langs/{ua.js → uk.js} +75 -6
  77. package/src/langs/ur.js +77 -8
  78. package/src/langs/zh_cn.js +74 -5
  79. package/src/modules/ApiManager.js +77 -54
  80. package/src/modules/Browser.js +667 -0
  81. package/src/modules/ColorPicker.js +162 -102
  82. package/src/modules/Controller.js +273 -142
  83. package/src/modules/Figure.js +925 -484
  84. package/src/modules/FileManager.js +121 -69
  85. package/src/modules/HueSlider.js +113 -61
  86. package/src/modules/Modal.js +291 -122
  87. package/src/modules/ModalAnchorEditor.js +383 -234
  88. package/src/modules/SelectMenu.js +270 -168
  89. package/src/modules/_DragHandle.js +2 -1
  90. package/src/modules/index.js +3 -3
  91. package/src/plugins/browser/audioGallery.js +83 -0
  92. package/src/plugins/browser/fileBrowser.js +103 -0
  93. package/src/plugins/browser/fileGallery.js +83 -0
  94. package/src/plugins/browser/imageGallery.js +81 -0
  95. package/src/plugins/browser/videoGallery.js +103 -0
  96. package/src/plugins/command/blockquote.js +40 -27
  97. package/src/plugins/command/exportPDF.js +134 -0
  98. package/src/plugins/command/fileUpload.js +229 -162
  99. package/src/plugins/command/list_bulleted.js +83 -47
  100. package/src/plugins/command/list_numbered.js +83 -47
  101. package/src/plugins/dropdown/align.js +66 -54
  102. package/src/plugins/dropdown/backgroundColor.js +63 -49
  103. package/src/plugins/dropdown/font.js +71 -47
  104. package/src/plugins/dropdown/fontColor.js +63 -48
  105. package/src/plugins/dropdown/formatBlock.js +70 -33
  106. package/src/plugins/dropdown/hr.js +92 -51
  107. package/src/plugins/dropdown/layout.js +37 -26
  108. package/src/plugins/dropdown/lineHeight.js +54 -38
  109. package/src/plugins/dropdown/list.js +60 -45
  110. package/src/plugins/dropdown/paragraphStyle.js +51 -30
  111. package/src/plugins/dropdown/table.js +2003 -813
  112. package/src/plugins/dropdown/template.js +38 -26
  113. package/src/plugins/dropdown/textStyle.js +43 -31
  114. package/src/plugins/field/mention.js +147 -86
  115. package/src/plugins/index.js +32 -6
  116. package/src/plugins/input/fontSize.js +161 -108
  117. package/src/plugins/input/pageNavigator.js +70 -0
  118. package/src/plugins/modal/audio.js +358 -173
  119. package/src/plugins/modal/drawing.js +531 -0
  120. package/src/plugins/modal/embed.js +886 -0
  121. package/src/plugins/modal/image.js +674 -362
  122. package/src/plugins/modal/link.js +100 -71
  123. package/src/plugins/modal/math.js +367 -167
  124. package/src/plugins/modal/video.js +691 -335
  125. package/src/plugins/popup/anchor.js +222 -0
  126. package/src/suneditor.js +50 -13
  127. package/src/themes/dark.css +122 -0
  128. package/src/typedef.js +130 -0
  129. package/types/assets/icons/defaultIcons.d.ts +153 -0
  130. package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
  131. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
  132. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
  133. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
  134. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
  135. package/types/core/base/eventManager.d.ts +385 -0
  136. package/types/core/base/history.d.ts +81 -0
  137. package/types/core/class/char.d.ts +60 -0
  138. package/types/core/class/component.d.ts +212 -0
  139. package/types/core/class/format.d.ts +616 -0
  140. package/types/core/class/html.d.ts +422 -0
  141. package/types/core/class/menu.d.ts +126 -0
  142. package/types/core/class/nodeTransform.d.ts +93 -0
  143. package/types/core/class/offset.d.ts +522 -0
  144. package/types/core/class/selection.d.ts +188 -0
  145. package/types/core/class/shortcuts.d.ts +142 -0
  146. package/types/core/class/toolbar.d.ts +189 -0
  147. package/types/core/class/ui.d.ts +164 -0
  148. package/types/core/class/viewer.d.ts +140 -0
  149. package/types/core/editor.d.ts +610 -0
  150. package/types/core/section/actives.d.ts +46 -0
  151. package/types/core/section/constructor.d.ts +777 -0
  152. package/types/core/section/context.d.ts +45 -0
  153. package/types/core/section/documentType.d.ts +178 -0
  154. package/types/editorInjector/_classes.d.ts +41 -0
  155. package/types/editorInjector/_core.d.ts +92 -0
  156. package/types/editorInjector/index.d.ts +71 -0
  157. package/types/events.d.ts +273 -0
  158. package/types/helper/clipboard.d.ts +12 -0
  159. package/types/helper/converter.d.ts +197 -0
  160. package/types/helper/dom/domCheck.d.ts +189 -0
  161. package/types/helper/dom/domQuery.d.ts +223 -0
  162. package/types/helper/dom/domUtils.d.ts +226 -0
  163. package/types/helper/dom/index.d.ts +9 -0
  164. package/types/helper/env.d.ts +132 -0
  165. package/types/helper/index.d.ts +174 -0
  166. package/types/helper/keyCodeMap.d.ts +110 -0
  167. package/types/helper/numbers.d.ts +46 -0
  168. package/types/helper/unicode.d.ts +28 -0
  169. package/types/index.d.ts +120 -0
  170. package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +173 -103
  171. package/types/langs/ckb.d.ts +3 -0
  172. package/types/langs/cs.d.ts +3 -0
  173. package/types/langs/da.d.ts +3 -0
  174. package/types/langs/de.d.ts +3 -0
  175. package/types/langs/en.d.ts +3 -0
  176. package/types/langs/es.d.ts +3 -0
  177. package/types/langs/fa.d.ts +3 -0
  178. package/types/langs/fr.d.ts +3 -0
  179. package/types/langs/he.d.ts +3 -0
  180. package/types/langs/hu.d.ts +3 -0
  181. package/types/langs/index.d.ts +54 -0
  182. package/types/langs/it.d.ts +3 -0
  183. package/types/langs/ja.d.ts +3 -0
  184. package/types/langs/km.d.ts +3 -0
  185. package/types/langs/ko.d.ts +3 -0
  186. package/types/langs/lv.d.ts +3 -0
  187. package/types/langs/nl.d.ts +3 -0
  188. package/types/langs/pl.d.ts +3 -0
  189. package/types/langs/pt_br.d.ts +3 -0
  190. package/types/langs/ro.d.ts +3 -0
  191. package/types/langs/ru.d.ts +3 -0
  192. package/types/langs/se.d.ts +3 -0
  193. package/types/langs/tr.d.ts +3 -0
  194. package/types/langs/uk.d.ts +3 -0
  195. package/types/langs/ur.d.ts +3 -0
  196. package/types/langs/zh_cn.d.ts +3 -0
  197. package/types/modules/ApiManager.d.ts +125 -0
  198. package/types/modules/Browser.d.ts +326 -0
  199. package/types/modules/ColorPicker.d.ts +131 -0
  200. package/types/modules/Controller.d.ts +251 -0
  201. package/types/modules/Figure.d.ts +517 -0
  202. package/types/modules/FileManager.d.ts +202 -0
  203. package/types/modules/HueSlider.d.ts +136 -0
  204. package/types/modules/Modal.d.ts +111 -0
  205. package/types/modules/ModalAnchorEditor.d.ts +236 -0
  206. package/types/modules/SelectMenu.d.ts +194 -0
  207. package/types/modules/_DragHandle.d.ts +7 -0
  208. package/types/modules/index.d.ts +26 -0
  209. package/types/plugins/browser/audioGallery.d.ts +55 -0
  210. package/types/plugins/browser/fileBrowser.d.ts +64 -0
  211. package/types/plugins/browser/fileGallery.d.ts +55 -0
  212. package/types/plugins/browser/imageGallery.d.ts +51 -0
  213. package/types/plugins/browser/videoGallery.d.ts +57 -0
  214. package/types/plugins/command/blockquote.d.ts +28 -0
  215. package/types/plugins/command/exportPDF.d.ts +46 -0
  216. package/types/plugins/command/fileUpload.d.ts +156 -0
  217. package/types/plugins/command/list_bulleted.d.ts +46 -0
  218. package/types/plugins/command/list_numbered.d.ts +46 -0
  219. package/types/plugins/dropdown/align.d.ts +60 -0
  220. package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
  221. package/types/plugins/dropdown/font.d.ts +54 -0
  222. package/types/plugins/dropdown/fontColor.d.ts +63 -0
  223. package/types/plugins/dropdown/formatBlock.d.ts +54 -0
  224. package/types/plugins/dropdown/hr.d.ts +71 -0
  225. package/types/plugins/dropdown/layout.d.ts +40 -0
  226. package/types/plugins/dropdown/lineHeight.d.ts +50 -0
  227. package/types/plugins/dropdown/list.d.ts +39 -0
  228. package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
  229. package/types/plugins/dropdown/table.d.ts +627 -0
  230. package/types/plugins/dropdown/template.d.ts +40 -0
  231. package/types/plugins/dropdown/textStyle.d.ts +41 -0
  232. package/types/plugins/field/mention.d.ts +102 -0
  233. package/types/plugins/index.d.ts +107 -0
  234. package/types/plugins/input/fontSize.d.ts +170 -0
  235. package/types/plugins/input/pageNavigator.d.ts +28 -0
  236. package/types/plugins/modal/audio.d.ts +269 -0
  237. package/types/plugins/modal/drawing.d.ts +246 -0
  238. package/types/plugins/modal/embed.d.ts +387 -0
  239. package/types/plugins/modal/image.d.ts +451 -0
  240. package/types/plugins/modal/link.d.ts +128 -0
  241. package/types/plugins/modal/math.d.ts +193 -0
  242. package/types/plugins/modal/video.d.ts +485 -0
  243. package/types/plugins/popup/anchor.d.ts +56 -0
  244. package/types/suneditor.d.ts +51 -0
  245. package/types/typedef.d.ts +233 -0
  246. package/.eslintignore +0 -7
  247. package/.eslintrc.json +0 -64
  248. package/src/assets/icons/_default.js +0 -194
  249. package/src/core/base/events.js +0 -320
  250. package/src/core/class/notice.js +0 -42
  251. package/src/helper/domUtils.js +0 -1177
  252. package/src/modules/FileBrowser.js +0 -271
  253. package/src/plugins/command/exportPdf.js +0 -168
  254. package/src/plugins/fileBrowser/imageGallery.js +0 -81
  255. package/src/themes/test.css +0 -61
  256. package/typings/CommandPlugin.d.ts +0 -8
  257. package/typings/DialogPlugin.d.ts +0 -20
  258. package/typings/FileBrowserPlugin.d.ts +0 -30
  259. package/typings/Module.d.ts +0 -15
  260. package/typings/Plugin.d.ts +0 -42
  261. package/typings/SubmenuPlugin.d.ts +0 -8
  262. package/typings/_classes.d.ts +0 -17
  263. package/typings/_colorPicker.d.ts +0 -60
  264. package/typings/_core.d.ts +0 -55
  265. package/typings/align.d.ts +0 -5
  266. package/typings/audio.d.ts +0 -5
  267. package/typings/backgroundColor.d.ts +0 -5
  268. package/typings/blockquote.d.ts +0 -5
  269. package/typings/char.d.ts +0 -39
  270. package/typings/component.d.ts +0 -38
  271. package/typings/context.d.ts +0 -39
  272. package/typings/converter.d.ts +0 -33
  273. package/typings/dialog.d.ts +0 -28
  274. package/typings/domUtils.d.ts +0 -361
  275. package/typings/editor.d.ts +0 -7
  276. package/typings/editor.ts +0 -542
  277. package/typings/env.d.ts +0 -70
  278. package/typings/eventManager.d.ts +0 -37
  279. package/typings/events.d.ts +0 -262
  280. package/typings/fileBrowser.d.ts +0 -42
  281. package/typings/fileManager.d.ts +0 -67
  282. package/typings/font.d.ts +0 -5
  283. package/typings/fontColor.d.ts +0 -5
  284. package/typings/fontSize.d.ts +0 -5
  285. package/typings/format.d.ts +0 -191
  286. package/typings/formatBlock.d.ts +0 -5
  287. package/typings/history.d.ts +0 -48
  288. package/typings/horizontalRule.d.ts +0 -5
  289. package/typings/image.d.ts +0 -5
  290. package/typings/imageGallery.d.ts +0 -5
  291. package/typings/index.d.ts +0 -21
  292. package/typings/index.modules.d.ts +0 -11
  293. package/typings/index.plugins.d.ts +0 -58
  294. package/typings/lineHeight.d.ts +0 -5
  295. package/typings/link.d.ts +0 -5
  296. package/typings/list.d.ts +0 -5
  297. package/typings/math.d.ts +0 -5
  298. package/typings/mediaContainer.d.ts +0 -25
  299. package/typings/mention.d.ts +0 -5
  300. package/typings/node.d.ts +0 -57
  301. package/typings/notice.d.ts +0 -16
  302. package/typings/numbers.d.ts +0 -29
  303. package/typings/offset.d.ts +0 -24
  304. package/typings/options.d.ts +0 -589
  305. package/typings/paragraphStyle.d.ts +0 -5
  306. package/typings/resizing.d.ts +0 -141
  307. package/typings/selection.d.ts +0 -94
  308. package/typings/shortcuts.d.ts +0 -13
  309. package/typings/suneditor.d.ts +0 -9
  310. package/typings/table.d.ts +0 -5
  311. package/typings/template.d.ts +0 -5
  312. package/typings/textStyle.d.ts +0 -5
  313. package/typings/toolbar.d.ts +0 -32
  314. package/typings/unicode.d.ts +0 -25
  315. package/typings/video.d.ts +0 -5
@@ -1,46 +1,58 @@
1
1
  import EditorInjector from '../../editorInjector';
2
- import { domUtils } from '../../helper';
2
+ import { dom } from '../../helper';
3
3
 
4
- const Template = function (editor, pluginOptions) {
5
- // plugin bisic properties
6
- EditorInjector.call(this, editor);
7
- this.title = this.lang.template;
8
- this.icon = 'template';
4
+ /**
5
+ * @class
6
+ * @description Template Plugin, Apply a template to the selection.
7
+ */
8
+ class Template extends EditorInjector {
9
+ static key = 'template';
10
+ static type = 'dropdown';
11
+ static className = '';
9
12
 
10
- // members
11
- this.selectedIndex = -1;
12
- this.items = pluginOptions.items;
13
+ /**
14
+ * @constructor
15
+ * @param {__se__EditorCore} editor - The root editor instance
16
+ * @param {Object} pluginOptions
17
+ * @param {Array<{name: string, html: string}>} pluginOptions.items - Template list
18
+ */
19
+ constructor(editor, pluginOptions) {
20
+ // plugin bisic properties
21
+ super(editor);
22
+ this.title = this.lang.template;
23
+ this.icon = 'template';
13
24
 
14
- // create HTML
15
- const menu = CreateHTML(this.items);
25
+ // members
26
+ this.selectedIndex = -1;
27
+ this.items = pluginOptions.items;
16
28
 
17
- // init
18
- this.menu.initDropdownTarget(Template, menu);
19
- };
29
+ // create HTML
30
+ const menu = CreateHTML(this.items);
31
+
32
+ // init
33
+ this.menu.initDropdownTarget(Template, menu);
34
+ }
20
35
 
21
- Template.key = 'template';
22
- Template.type = 'dropdown';
23
- Template.className = '';
24
- Template.prototype = {
25
36
  /**
26
- * @override core
37
+ * @editorMethod Editor.core
38
+ * @description Executes the main execution method of the plugin.
39
+ * - Called when an item in the "dropdown" menu is clicked.
40
+ * @param {HTMLElement} target - The plugin's toolbar button element
27
41
  */
28
42
  action(target) {
29
- const index = target.getAttribute('data-value') * 1;
43
+ const index = Number(target.getAttribute('data-value'));
30
44
  const temp = this.items[(this.selectedIndex = index)];
31
45
 
32
46
  if (temp.html) {
33
- this.html.insert(temp.html);
47
+ this.html.insert(temp.html, { selectInserted: false, skipCharCount: false, skipCleaning: false });
34
48
  } else {
35
49
  this.menu.dropdownOff();
36
50
  throw Error('[SUNEDITOR.template.fail] cause : "templates[i].html not found"');
37
51
  }
38
52
 
39
53
  this.menu.dropdownOff();
40
- },
41
-
42
- constructor: Template
43
- };
54
+ }
55
+ }
44
56
 
45
57
  function CreateHTML(templateList) {
46
58
  if (!templateList || templateList.length === 0) {
@@ -65,7 +77,7 @@ function CreateHTML(templateList) {
65
77
  }
66
78
  list += '</ul></div>';
67
79
 
68
- return domUtils.createElement('DIV', { class: 'se-list-layer' }, list);
80
+ return dom.utils.createElement('DIV', { class: 'se-list-layer' }, list);
69
81
  }
70
82
 
71
83
  export default Template;
@@ -1,28 +1,40 @@
1
1
  import EditorInjector from '../../editorInjector';
2
- import { domUtils } from '../../helper';
2
+ import { dom } from '../../helper';
3
3
 
4
- const TextStyle = function (editor, pluginOptions) {
5
- // plugin bisic properties
6
- EditorInjector.call(this, editor);
7
- this.title = this.lang.textStyle;
8
- this.icon = 'text_style';
4
+ /**
5
+ * @class
6
+ * @description Text style Plugin, Applies a tag that specifies text styles to a selection.
7
+ */
8
+ class TextStyle extends EditorInjector {
9
+ static key = 'textStyle';
10
+ static type = 'dropdown';
11
+ static className = '';
9
12
 
10
- // create HTML
11
- const menu = CreateHTML(editor, pluginOptions.items);
13
+ /**
14
+ * @constructor
15
+ * @param {__se__EditorCore} editor - The root editor instance
16
+ * @param {Object} pluginOptions
17
+ * @param {Array<{name: string, html: string}>} pluginOptions.items - Template list
18
+ */
19
+ constructor(editor, pluginOptions) {
20
+ // plugin bisic properties
21
+ super(editor);
22
+ this.title = this.lang.textStyle;
23
+ this.icon = 'text_style';
12
24
 
13
- // members
14
- this.styleList = menu.querySelectorAll('li button');
25
+ // create HTML
26
+ const menu = CreateHTML(editor, pluginOptions.items);
15
27
 
16
- // init
17
- this.menu.initDropdownTarget(TextStyle, menu);
18
- };
28
+ // members
29
+ this.styleList = menu.querySelectorAll('li button');
30
+
31
+ // init
32
+ this.menu.initDropdownTarget(TextStyle, menu);
33
+ }
19
34
 
20
- TextStyle.key = 'textStyle';
21
- TextStyle.type = 'dropdown';
22
- TextStyle.className = '';
23
- TextStyle.prototype = {
24
35
  /**
25
- * @override dropdown
36
+ * @editorMethod Modules.Dropdown
37
+ * @description Executes the method that is called when a plugin's dropdown menu is opened.
26
38
  */
27
39
  on() {
28
40
  const styleButtonList = this.styleList;
@@ -39,7 +51,7 @@ TextStyle.prototype = {
39
51
  while (node && !this.format.isLine(node) && !this.component.is(node)) {
40
52
  if (node.nodeName.toLowerCase() === btn.getAttribute('data-command').toLowerCase()) {
41
53
  value = data[v];
42
- if (/^\./.test(value) ? domUtils.hasClass(node, value.replace(/^\./, '')) : node.style[value]) {
54
+ if (/^\./.test(value) ? dom.utils.hasClass(node, value.replace(/^\./, '')) : /** @type {HTMLElement} */ (node).style[value]) {
43
55
  active = true;
44
56
  break;
45
57
  }
@@ -50,16 +62,18 @@ TextStyle.prototype = {
50
62
  if (!active) break;
51
63
  }
52
64
 
53
- active ? domUtils.addClass(btn, 'active') : domUtils.removeClass(btn, 'active');
65
+ active ? dom.utils.addClass(btn, 'active') : dom.utils.removeClass(btn, 'active');
54
66
  }
55
- },
67
+ }
56
68
 
57
69
  /**
58
- * @override core
59
- * @param {Element} target Target command button
70
+ * @editorMethod Editor.core
71
+ * @description Executes the main execution method of the plugin.
72
+ * - Called when an item in the "dropdown" menu is clicked.
73
+ * @param {HTMLElement} target - The plugin's toolbar button element
60
74
  */
61
75
  action(target) {
62
- const tempElement = target.firstElementChild;
76
+ const tempElement = /** @type {HTMLElement} */ (target.firstElementChild);
63
77
  const checkStyles = tempElement.style.cssText.replace(/:.+(;|$)/g, ',').split(',');
64
78
  checkStyles.pop();
65
79
 
@@ -68,15 +82,13 @@ TextStyle.prototype = {
68
82
  checkStyles.push('.' + classes[i]);
69
83
  }
70
84
 
71
- const newNode = domUtils.hasClass(target, 'active') ? null : tempElement.cloneNode(false);
85
+ const newNode = dom.utils.hasClass(target, 'active') ? null : tempElement.cloneNode(false);
72
86
  const removeNodes = newNode ? null : [tempElement.nodeName];
73
- this.format.applyTextStyle(newNode, checkStyles, removeNodes, true);
87
+ this.format.applyInlineElement(newNode, { stylesToModify: checkStyles, nodesToRemove: removeNodes, strictRemove: true });
74
88
 
75
89
  this.menu.dropdownOff();
76
- },
77
-
78
- constructor: TextStyle
79
- };
90
+ }
91
+ }
80
92
 
81
93
  function CreateHTML({ lang }, items) {
82
94
  const defaultList = {
@@ -131,7 +143,7 @@ function CreateHTML({ lang }, items) {
131
143
  }
132
144
  list += '</ul></div>';
133
145
 
134
- return domUtils.createElement('DIV', { class: 'se-dropdown se-list-layer se-list-format' }, list);
146
+ return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer se-list-format' }, list);
135
147
  }
136
148
 
137
149
  export default TextStyle;
@@ -1,65 +1,93 @@
1
1
  import EditorInjector from '../../editorInjector';
2
2
  import { ApiManager, SelectMenu, Controller } from '../../modules';
3
- import { domUtils, converter } from '../../helper';
3
+ import { dom, converter } from '../../helper';
4
4
 
5
5
  const { debounce } = converter;
6
6
 
7
- const Mention = function (editor, pluginOptions) {
8
- EditorInjector.call(this, editor);
9
- // plugin basic properties
10
- this.title = this.lang.mention;
11
- this.icon = 'mention';
12
-
13
- // members
14
- this.triggerText = pluginOptions.triggerText || '@';
15
- this.limitSize = pluginOptions.limitSize || 5;
16
- this.searchStartLength = pluginOptions.searchStartLength || 0;
17
- this.delayTime = typeof pluginOptions.delayTime === 'number' ? pluginOptions.delayTime : 200;
18
- this.apiUrl = pluginOptions.apiUrl?.replace(/\s/g, '').replace(/\{limitSize\}/i, this.limitSize) || '';
19
- this._delay = 0;
20
- this._lastAtPos = 0;
21
- this._anchorOffset = 0;
22
- this._anchorNode = null;
23
- // members - api, caching
24
- this.apiManager = new ApiManager(this, { headers: pluginOptions.apiHeaders });
25
- this.cachingData = pluginOptions.useCachingData ?? true ? new Map() : null;
26
- this.cachingFieldData = pluginOptions.useCachingFieldData ?? true ? new Map([['', []]]) : null;
27
-
28
- // controller
29
- const controllerEl = CreateHTML_controller();
30
- this.selectMenu = new SelectMenu(this, { position: 'right-bottom', dir: 'ltr', closeMethod: () => this.controller.close() });
31
- this.controller = new Controller(
32
- this,
33
- controllerEl,
34
- {
35
- position: 'bottom',
36
- initMethod: () => {
37
- this.apiManager.cancel();
38
- this.selectMenu.close();
39
- }
40
- },
41
- null
42
- );
43
- this.selectMenu.on(controllerEl.firstElementChild, SelectMention.bind(this));
44
-
45
- // onInput debounce
46
- this.onInput = debounce(this.onInput.bind(this), this.delayTime);
47
- };
48
-
49
- Mention.key = 'mention';
50
- Mention.type = 'field';
51
- Mention.className = '';
52
- Mention.prototype = {
7
+ /**
8
+ * @class
9
+ * @description Mention Plugin
10
+ * - A plugin that provides a mention feature using `@` or a custom trigger character.
11
+ * - Displays a mention list when the trigger character is typed.
12
+ * - Supports fetching mention data from an API or a predefined data array.
13
+ * - Uses caching for optimized performance.
14
+ */
15
+ class Mention extends EditorInjector {
16
+ static key = 'mention';
17
+ static type = 'field';
18
+ static className = '';
19
+
20
+ /**
21
+ * @constructor
22
+ * @param {__se__EditorCore} editor - The root editor instance
23
+ * @param {Object} pluginOptions
24
+ * @param {string=} [pluginOptions.triggerText="@"] The character that triggers the mention list. Default is '@'.
25
+ * @param {number=} [pluginOptions.limitSize=5] The number of items to display in the mention list. Default is 5.
26
+ * @param {number=} [pluginOptions.searchStartLength=0] The number of characters to start searching for the mention list. Default is 0.
27
+ * @param {number=} [pluginOptions.delayTime=200] The time to wait before displaying the mention list. Default is 200ms.
28
+ * @param {Array<{key: string, name: string, url: string}>=} pluginOptions.data Use data without using API.
29
+ * @param {string=} pluginOptions.apiUrl The URL to call the mention list. Default is ''.
30
+ * @param {Object<string, string>=} pluginOptions.apiHeaders The headers to send with the API call. Default is {}.
31
+ * @param {boolean=} [pluginOptions.useCachingData=true] Whether to cache the mention list data. Default is true.
32
+ * @param {boolean=} [pluginOptions.useCachingFieldData=true] Whether to cache the mention list data in the field. Default is true.
33
+ */
34
+ constructor(editor, pluginOptions) {
35
+ super(editor);
36
+ // plugin basic properties
37
+ this.title = this.lang.mention;
38
+ this.icon = 'mention';
39
+
40
+ // members
41
+ this.triggerText = pluginOptions.triggerText || '@';
42
+ this.limitSize = pluginOptions.limitSize || 5;
43
+ this.searchStartLength = pluginOptions.searchStartLength || 0;
44
+ this.delayTime = typeof pluginOptions.delayTime === 'number' ? pluginOptions.delayTime : 200;
45
+ this.directData = pluginOptions.data;
46
+ this.apiUrl = pluginOptions.apiUrl?.replace(/\s/g, '').replace(/\{limitSize\}/i, String(this.limitSize)) || '';
47
+ this._delay = 0;
48
+ this._lastAtPos = 0;
49
+ this._anchorOffset = 0;
50
+ this._anchorNode = null;
51
+ // members - api, caching
52
+ this.apiManager = new ApiManager(this, { headers: pluginOptions.apiHeaders });
53
+ this.cachingData = pluginOptions.useCachingData ?? true ? new Map() : null;
54
+ this.cachingFieldData = pluginOptions.useCachingFieldData ?? true ? [] : null;
55
+
56
+ // controller
57
+ const controllerEl = CreateHTML_controller();
58
+ this.selectMenu = new SelectMenu(this, { position: 'right-bottom', dir: 'ltr', closeMethod: () => this.controller.close() });
59
+ this.controller = new Controller(
60
+ this,
61
+ controllerEl,
62
+ {
63
+ position: 'bottom',
64
+ initMethod: () => {
65
+ this.apiManager.cancel();
66
+ this.selectMenu.close();
67
+ }
68
+ },
69
+ null
70
+ );
71
+ this.selectMenu.on(controllerEl.firstElementChild, this.#SelectMention.bind(this));
72
+
73
+ // onInput debounce
74
+ this.onInput = debounce(this.onInput.bind(this), this.delayTime);
75
+ }
76
+
53
77
  /**
54
- * @override core
78
+ * @editorMethod Editor.EventManager
79
+ * @description Executes the event function of "input".
80
+ * @returns {Promise<boolean>}
55
81
  */
56
82
  async onInput() {
57
- this.apiManager.cancel();
83
+ if (!this.directData) {
84
+ this.apiManager.cancel();
85
+ }
58
86
 
59
87
  const sel = this.selection.get();
60
88
  if (!sel.rangeCount) {
61
89
  this.selectMenu.close();
62
- return;
90
+ return true;
63
91
  }
64
92
 
65
93
  const anchorNode = sel.anchorNode;
@@ -70,11 +98,11 @@ Mention.prototype = {
70
98
  if (lastAtPos > -1) {
71
99
  const mentionQuery = textBeforeCursor.substring(lastAtPos + 1, anchorOffset);
72
100
  const beforeText = textBeforeCursor[lastAtPos - 1]?.trim();
73
- if (!/\s/.test(mentionQuery) && (!beforeText || domUtils.isZeroWith(beforeText))) {
101
+ if (!/\s/.test(mentionQuery) && (!beforeText || dom.check.isZeroWidth(beforeText))) {
74
102
  if (mentionQuery.length < this.searchStartLength) return true;
75
103
 
76
104
  const anchorParent = anchorNode.parentNode;
77
- if (domUtils.isAnchor(anchorParent) && !anchorParent.getAttribute('data-se-mention')) {
105
+ if (dom.check.isAnchor(anchorParent) && !anchorParent.getAttribute('data-se-mention')) {
78
106
  return true;
79
107
  }
80
108
 
@@ -92,21 +120,45 @@ Mention.prototype = {
92
120
 
93
121
  this.selectMenu.close();
94
122
  return true;
95
- },
123
+ }
96
124
 
125
+ /**
126
+ * @private
127
+ * @description Generates the mention list based on user input.
128
+ * - Fetches data from cache, direct data, or an API.
129
+ * - Creates and opens the mention dropdown.
130
+ * - Caches the fetched data for future use.
131
+ * @param {string} value - The mention query text.
132
+ * @param {Node} targetNode - The node where the mention is triggered.
133
+ * @returns {Promise<boolean>} - Returns `true` if the mention list is displayed, `false` otherwise.
134
+ */
97
135
  async _createMentionList(value, targetNode) {
136
+ const limit = this.limitSize;
137
+ const lowerValue = value.toLowerCase();
98
138
  let response = null;
99
139
  if (this.cachingData) {
100
140
  response = this.cachingData.get(value);
101
141
  }
102
142
 
103
143
  if (!response) {
104
- const xmlHttp = await this.apiManager.asyncCall({ method: 'GET', url: this._createUrl(value) });
105
- response = JSON.parse(xmlHttp.responseText);
144
+ if (this.directData) {
145
+ response = this.directData.filter((item) => item.key.toLowerCase().startsWith(lowerValue)).slice(0, limit);
146
+ } else {
147
+ const xmlHttp = await this.apiManager.asyncCall({ method: 'GET', url: this._createUrl(value) });
148
+ response = JSON.parse(xmlHttp.responseText);
149
+ }
106
150
  }
107
151
 
108
152
  if (this.cachingFieldData) {
109
- response = this.cachingFieldData.get('').concat(response).splice(0, this.limitSize);
153
+ const uniqueKeys = new Set();
154
+ response = this.cachingFieldData
155
+ .concat(response)
156
+ .filter(({ key }) => {
157
+ if (uniqueKeys.has(key)) return false;
158
+ uniqueKeys.add(key);
159
+ return key.toLowerCase().startsWith(lowerValue);
160
+ })
161
+ .slice(0, limit);
110
162
  }
111
163
 
112
164
  if (!response?.length) {
@@ -135,47 +187,56 @@ Mention.prototype = {
135
187
  if (this.cachingData) this.cachingData.set(value, list);
136
188
  return true;
137
189
  }
138
- },
190
+ }
139
191
 
192
+ /**
193
+ * @private
194
+ * @description Constructs the API request URL with the mention query.
195
+ * @param {string} key - The mention query text.
196
+ * @returns {string} - The formatted API request URL.
197
+ */
140
198
  _createUrl(key) {
141
199
  return this.apiUrl.replace(/\{key\}/i, key);
142
- },
143
-
144
- constructor: Mention
145
- };
146
-
147
- function SelectMention(item) {
148
- if (!item) return false;
149
-
150
- let oA = null;
151
- const { key, name, url } = item;
152
- const anchorParent = this._anchorNode.parentNode;
153
-
154
- if (domUtils.isAnchor(anchorParent)) {
155
- oA = anchorParent;
156
- oA.setAttribute('data-se-mention', key);
157
- oA.setAttribute('href', url);
158
- oA.setAttribute('title', name);
159
- oA.textContent = this.triggerText + key;
160
- } else {
161
- this.selection.setRange(this._anchorNode, this._lastAtPos, this._anchorNode, this._anchorOffset);
162
- oA = domUtils.createElement('A', { 'data-se-mention': key, href: url, title: name, target: '_blank' }, this.triggerText + key);
163
- if (!this.html.insertNode(oA, null, false)) return false;
164
200
  }
165
201
 
166
- this.selectMenu.close();
202
+ /**
203
+ * @description Inserts a mention link into the editor when a user selects a mention from the list.
204
+ * @param {{ key: string, name: string, url: string }} item - The selected mention item.
205
+ * @returns {boolean} - Returns `false` if insertion fails, otherwise completes execution.
206
+ */
207
+ #SelectMention(item) {
208
+ if (!item) return false;
209
+
210
+ let oA = null;
211
+ const { key, name, url } = item;
212
+ const anchorParent = this._anchorNode.parentNode;
213
+
214
+ if (dom.check.isAnchor(anchorParent)) {
215
+ oA = anchorParent;
216
+ oA.setAttribute('data-se-mention', key);
217
+ oA.setAttribute('href', url);
218
+ oA.setAttribute('title', name);
219
+ oA.textContent = this.triggerText + key;
220
+ } else {
221
+ this.selection.setRange(this._anchorNode, this._lastAtPos, this._anchorNode, this._anchorOffset);
222
+ oA = dom.utils.createElement('A', { 'data-se-mention': key, href: url, title: name, target: '_blank' }, this.triggerText + key);
223
+ if (!this.html.insertNode(oA, { afterNode: null, skipCharCount: false })) return false;
224
+ }
225
+
226
+ this.selectMenu.close();
167
227
 
168
- const space = domUtils.createTextNode('\u00A0');
169
- oA.parentNode.insertBefore(space, oA.nextSibling);
170
- this.selection.setRange(space, 1, space, 1);
228
+ const space = dom.utils.createTextNode('\u00A0');
229
+ oA.parentNode.insertBefore(space, oA.nextSibling);
230
+ this.selection.setRange(space, 1, space, 1);
171
231
 
172
- if (this.cachingFieldData) {
173
- this.cachingFieldData.get('').push(item);
232
+ if (this.cachingFieldData && !this.cachingFieldData.some((data) => data.key === item.key)) {
233
+ this.cachingFieldData.push(item);
234
+ }
174
235
  }
175
236
  }
176
237
 
177
238
  function CreateHTML_controller() {
178
- return domUtils.createElement('DIV', { class: 'se-controller se-empty-controller' }, '<div></div>');
239
+ return dom.utils.createElement('DIV', { class: 'se-controller se-empty-controller' }, '<div></div>');
179
240
  }
180
241
 
181
242
  export default Mention;
@@ -1,6 +1,6 @@
1
1
  // command
2
2
  import blockquote from './command/blockquote';
3
- import exportPdf from './command/exportPdf';
3
+ import exportPDF from './command/exportPDF';
4
4
  import fileUpload from './command/fileUpload';
5
5
  import list_bulleted from './command/list_bulleted';
6
6
  import list_numbered from './command/list_numbered';
@@ -28,17 +28,27 @@ import link from './modal/link';
28
28
  import image from './modal/image';
29
29
  import video from './modal/video';
30
30
  import audio from './modal/audio';
31
+ import embed from './modal/embed';
31
32
  import math from './modal/math';
33
+ import drawing from './modal/drawing';
32
34
 
33
35
  // file browser
34
- import imageGallery from './fileBrowser/imageGallery';
36
+ import imageGallery from './browser/imageGallery';
37
+ import videoGallery from './browser/videoGallery';
38
+ import audioGallery from './browser/audioGallery';
39
+ import fileGallery from './browser/fileGallery';
40
+ import fileBrowser from './browser/fileBrowser';
35
41
 
36
42
  // input
37
43
  import fontSize from './input/fontSize';
44
+ import pageNavigator from './input/pageNavigator';
45
+
46
+ // popup
47
+ import anchor from './popup/anchor';
38
48
 
39
49
  export {
40
50
  blockquote,
41
- exportPdf,
51
+ exportPDF,
42
52
  fileUpload,
43
53
  list_bulleted,
44
54
  list_numbered,
@@ -60,13 +70,21 @@ export {
60
70
  image,
61
71
  video,
62
72
  audio,
73
+ embed,
63
74
  math,
75
+ drawing,
64
76
  imageGallery,
65
- fontSize
77
+ videoGallery,
78
+ audioGallery,
79
+ fileGallery,
80
+ fileBrowser,
81
+ fontSize,
82
+ pageNavigator,
83
+ anchor
66
84
  };
67
85
  export default {
68
86
  blockquote,
69
- exportPdf,
87
+ exportPDF,
70
88
  fileUpload,
71
89
  list_bulleted,
72
90
  list_numbered,
@@ -88,7 +106,15 @@ export default {
88
106
  image,
89
107
  video,
90
108
  audio,
109
+ embed,
91
110
  math,
111
+ drawing,
92
112
  imageGallery,
93
- fontSize
113
+ videoGallery,
114
+ audioGallery,
115
+ fileGallery,
116
+ fileBrowser,
117
+ fontSize,
118
+ pageNavigator,
119
+ anchor
94
120
  };