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,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,64 +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
-
27
- // controller
28
- const controllerEl = CreateHTML_controller();
29
- this.selectMenu = new SelectMenu(this, { position: 'right-bottom', dir: 'ltr', closeMethod: () => this.controller.close() });
30
- this.controller = new Controller(
31
- this,
32
- controllerEl,
33
- {
34
- position: 'bottom',
35
- initMethod: () => {
36
- this.apiManager.cancel();
37
- this.selectMenu.close();
38
- }
39
- },
40
- null
41
- );
42
- this.selectMenu.on(controllerEl.firstElementChild, SelectMention.bind(this));
43
-
44
- // onInput debounce
45
- this.onInput = debounce(this.onInput.bind(this), this.delayTime);
46
- };
47
-
48
- Mention.key = 'mention';
49
- Mention.type = 'field';
50
- Mention.className = '';
51
- 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 ? new Map([['', []]]) : 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
+
52
77
  /**
53
- * @override core
78
+ * @editorMethod Editor.EventManager
79
+ * @description Executes the event function of "input".
80
+ * @returns {Promise<boolean>}
54
81
  */
55
82
  async onInput() {
56
- this.apiManager.cancel();
83
+ if (!this.directData) {
84
+ this.apiManager.cancel();
85
+ }
57
86
 
58
87
  const sel = this.selection.get();
59
88
  if (!sel.rangeCount) {
60
89
  this.selectMenu.close();
61
- return;
90
+ return true;
62
91
  }
63
92
 
64
93
  const anchorNode = sel.anchorNode;
@@ -69,11 +98,11 @@ Mention.prototype = {
69
98
  if (lastAtPos > -1) {
70
99
  const mentionQuery = textBeforeCursor.substring(lastAtPos + 1, anchorOffset);
71
100
  const beforeText = textBeforeCursor[lastAtPos - 1]?.trim();
72
- if (!/\s/.test(mentionQuery) && (!beforeText || domUtils.isZeroWith(beforeText))) {
101
+ if (!/\s/.test(mentionQuery) && (!beforeText || dom.check.isZeroWidth(beforeText))) {
73
102
  if (mentionQuery.length < this.searchStartLength) return true;
74
103
 
75
104
  const anchorParent = anchorNode.parentNode;
76
- if (domUtils.isAnchor(anchorParent) && !anchorParent.getAttribute('data-se-mention')) {
105
+ if (dom.check.isAnchor(anchorParent) && !anchorParent.getAttribute('data-se-mention')) {
77
106
  return true;
78
107
  }
79
108
 
@@ -91,8 +120,18 @@ Mention.prototype = {
91
120
 
92
121
  this.selectMenu.close();
93
122
  return true;
94
- },
123
+ }
95
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
+ */
96
135
  async _createMentionList(value, targetNode) {
97
136
  let response = null;
98
137
  if (this.cachingData) {
@@ -100,8 +139,18 @@ Mention.prototype = {
100
139
  }
101
140
 
102
141
  if (!response) {
103
- const xmlHttp = await this.apiManager.asyncCall({ method: 'GET', url: this._createUrl(value) });
104
- response = JSON.parse(xmlHttp.responseText);
142
+ if (this.directData) {
143
+ const limit = this.limitSize;
144
+ this.directData.filter((item) => item.key.toLowerCase().startsWith(value.toLowerCase())).slice(0, limit);
145
+ response = this.directData;
146
+ } else {
147
+ const xmlHttp = await this.apiManager.asyncCall({ method: 'GET', url: this._createUrl(value) });
148
+ response = JSON.parse(xmlHttp.responseText);
149
+ }
150
+ }
151
+
152
+ if (this.cachingFieldData) {
153
+ response = this.cachingFieldData.get('').concat(response).splice(0, this.limitSize);
105
154
  }
106
155
 
107
156
  if (!response?.length) {
@@ -130,43 +179,56 @@ Mention.prototype = {
130
179
  if (this.cachingData) this.cachingData.set(value, list);
131
180
  return true;
132
181
  }
133
- },
182
+ }
134
183
 
184
+ /**
185
+ * @private
186
+ * @description Constructs the API request URL with the mention query.
187
+ * @param {string} key - The mention query text.
188
+ * @returns {string} - The formatted API request URL.
189
+ */
135
190
  _createUrl(key) {
136
191
  return this.apiUrl.replace(/\{key\}/i, key);
137
- },
138
-
139
- constructor: Mention
140
- };
141
-
142
- function SelectMention(item) {
143
- if (!item) return false;
144
-
145
- let oA = null;
146
- const { key, name, url } = item;
147
- const anchorParent = this._anchorNode.parentNode;
148
-
149
- if (domUtils.isAnchor(anchorParent)) {
150
- oA = anchorParent;
151
- oA.setAttribute('data-se-mention', key);
152
- oA.setAttribute('href', url);
153
- oA.setAttribute('title', name);
154
- oA.textContent = this.triggerText + key;
155
- } else {
156
- this.selection.setRange(this._anchorNode, this._lastAtPos, this._anchorNode, this._anchorOffset);
157
- oA = domUtils.createElement('A', { 'data-se-mention': key, href: url, title: name, target: '_blank' }, this.triggerText + key);
158
- if (!this.html.insertNode(oA, null, false)) return false;
159
192
  }
160
193
 
161
- this.selectMenu.close();
194
+ /**
195
+ * @description Inserts a mention link into the editor when a user selects a mention from the list.
196
+ * @param {{ key: string, name: string, url: string }} item - The selected mention item.
197
+ * @returns {boolean} - Returns `false` if insertion fails, otherwise completes execution.
198
+ */
199
+ #SelectMention(item) {
200
+ if (!item) return false;
201
+
202
+ let oA = null;
203
+ const { key, name, url } = item;
204
+ const anchorParent = this._anchorNode.parentNode;
205
+
206
+ if (dom.check.isAnchor(anchorParent)) {
207
+ oA = anchorParent;
208
+ oA.setAttribute('data-se-mention', key);
209
+ oA.setAttribute('href', url);
210
+ oA.setAttribute('title', name);
211
+ oA.textContent = this.triggerText + key;
212
+ } else {
213
+ this.selection.setRange(this._anchorNode, this._lastAtPos, this._anchorNode, this._anchorOffset);
214
+ oA = dom.utils.createElement('A', { 'data-se-mention': key, href: url, title: name, target: '_blank' }, this.triggerText + key);
215
+ if (!this.html.insertNode(oA, { afterNode: null, skipCharCount: false })) return false;
216
+ }
217
+
218
+ this.selectMenu.close();
162
219
 
163
- const space = domUtils.createTextNode('\u00A0');
164
- oA.parentNode.insertBefore(space, oA.nextSibling);
165
- this.selection.setRange(space, 1, space, 1);
220
+ const space = dom.utils.createTextNode('\u00A0');
221
+ oA.parentNode.insertBefore(space, oA.nextSibling);
222
+ this.selection.setRange(space, 1, space, 1);
223
+
224
+ if (this.cachingFieldData) {
225
+ this.cachingFieldData.get('').push(item);
226
+ }
227
+ }
166
228
  }
167
229
 
168
230
  function CreateHTML_controller() {
169
- return domUtils.createElement('DIV', { class: 'se-controller se-empty-controller' }, '<div></div>');
231
+ return dom.utils.createElement('DIV', { class: 'se-controller se-empty-controller' }, '<div></div>');
170
232
  }
171
233
 
172
234
  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
  };