suneditor 2.46.1 → 3.0.0-alpha.1

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 (290) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.json +64 -0
  3. package/CONTRIBUTING.md +36 -0
  4. package/LICENSE.txt +1 -1
  5. package/README.md +174 -805
  6. package/dist/suneditor.min.css +1 -0
  7. package/dist/suneditor.min.js +1 -2
  8. package/package.json +96 -70
  9. package/src/assets/icons/_default.js +194 -0
  10. package/src/assets/suneditor-content.css +646 -0
  11. package/src/assets/suneditor.css +3378 -0
  12. package/src/core/base/eventHandlers/handler_toolbar.js +114 -0
  13. package/src/core/base/eventHandlers/handler_ww_clipboard.js +31 -0
  14. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +69 -0
  15. package/src/core/base/eventHandlers/handler_ww_key_input.js +975 -0
  16. package/src/core/base/eventHandlers/handler_ww_mouse.js +118 -0
  17. package/src/core/base/eventManager.js +1115 -0
  18. package/src/core/base/events.js +320 -0
  19. package/src/core/base/history.js +301 -0
  20. package/src/core/class/char.js +146 -0
  21. package/src/core/class/component.js +627 -0
  22. package/src/core/class/format.js +3255 -0
  23. package/src/core/class/html.js +1621 -0
  24. package/src/core/class/menu.js +260 -0
  25. package/src/core/class/nodeTransform.js +379 -0
  26. package/src/core/class/notice.js +42 -0
  27. package/src/core/class/offset.js +578 -0
  28. package/src/core/class/selection.js +508 -0
  29. package/src/core/class/shortcuts.js +38 -0
  30. package/src/core/class/toolbar.js +440 -0
  31. package/src/core/class/viewer.js +646 -0
  32. package/src/core/editor.js +1593 -0
  33. package/src/core/section/actives.js +107 -0
  34. package/src/core/section/constructor.js +1237 -0
  35. package/src/core/section/context.js +97 -0
  36. package/src/editorInjector/_classes.js +22 -0
  37. package/src/editorInjector/_core.js +28 -0
  38. package/src/editorInjector/index.js +13 -0
  39. package/src/helper/converter.js +313 -0
  40. package/src/helper/domUtils.js +1177 -0
  41. package/src/helper/env.js +250 -0
  42. package/src/helper/index.js +19 -0
  43. package/src/helper/numbers.js +68 -0
  44. package/src/helper/unicode.js +43 -0
  45. package/src/langs/ckb.js +161 -0
  46. package/src/langs/cs.js +161 -0
  47. package/src/langs/da.js +161 -0
  48. package/src/langs/de.js +162 -0
  49. package/src/langs/en.js +199 -0
  50. package/src/langs/es.js +162 -0
  51. package/src/langs/fa.js +159 -0
  52. package/src/langs/fr.js +161 -0
  53. package/src/langs/he.js +162 -0
  54. package/src/{lang → langs}/index.js +0 -2
  55. package/src/langs/it.js +162 -0
  56. package/src/langs/ja.js +162 -0
  57. package/src/langs/ko.js +162 -0
  58. package/src/langs/lv.js +162 -0
  59. package/src/langs/nl.js +162 -0
  60. package/src/langs/pl.js +162 -0
  61. package/src/langs/pt_br.js +162 -0
  62. package/src/langs/ro.js +162 -0
  63. package/src/langs/ru.js +162 -0
  64. package/src/langs/se.js +162 -0
  65. package/src/langs/tr.js +159 -0
  66. package/src/langs/ua.js +162 -0
  67. package/src/langs/ur.js +162 -0
  68. package/src/langs/zh_cn.js +162 -0
  69. package/src/modules/ApiManager.js +168 -0
  70. package/src/modules/ColorPicker.js +302 -0
  71. package/src/modules/Controller.js +315 -0
  72. package/src/modules/Figure.js +1160 -0
  73. package/src/modules/FileBrowser.js +271 -0
  74. package/src/modules/FileManager.js +290 -0
  75. package/src/modules/HueSlider.js +513 -0
  76. package/src/modules/Modal.js +177 -0
  77. package/src/modules/ModalAnchorEditor.js +494 -0
  78. package/src/modules/SelectMenu.js +447 -0
  79. package/src/modules/_DragHandle.js +16 -0
  80. package/src/modules/index.js +14 -0
  81. package/src/plugins/command/blockquote.js +47 -47
  82. package/src/plugins/command/exportPdf.js +168 -0
  83. package/src/plugins/command/fileUpload.js +389 -0
  84. package/src/plugins/command/list_bulleted.js +112 -0
  85. package/src/plugins/command/list_numbered.js +115 -0
  86. package/src/plugins/dropdown/align.js +143 -0
  87. package/src/plugins/dropdown/backgroundColor.js +73 -0
  88. package/src/plugins/dropdown/font.js +113 -0
  89. package/src/plugins/dropdown/fontColor.js +73 -0
  90. package/src/plugins/dropdown/formatBlock.js +141 -0
  91. package/src/plugins/dropdown/hr.js +111 -0
  92. package/src/plugins/dropdown/layout.js +72 -0
  93. package/src/plugins/dropdown/lineHeight.js +114 -0
  94. package/src/plugins/dropdown/list.js +107 -0
  95. package/src/plugins/dropdown/paragraphStyle.js +117 -0
  96. package/src/plugins/dropdown/table.js +2810 -0
  97. package/src/plugins/dropdown/template.js +71 -0
  98. package/src/plugins/dropdown/textStyle.js +137 -0
  99. package/src/plugins/field/mention.js +172 -0
  100. package/src/plugins/fileBrowser/imageGallery.js +76 -59
  101. package/src/plugins/index.js +86 -24
  102. package/src/plugins/input/fontSize.js +357 -0
  103. package/src/plugins/modal/audio.js +510 -0
  104. package/src/plugins/modal/image.js +1062 -0
  105. package/src/plugins/modal/link.js +211 -0
  106. package/src/plugins/modal/math.js +347 -0
  107. package/src/plugins/modal/video.js +870 -0
  108. package/src/suneditor.js +62 -67
  109. package/src/themes/test.css +61 -0
  110. package/typings/CommandPlugin.d.ts +8 -0
  111. package/typings/DialogPlugin.d.ts +20 -0
  112. package/typings/FileBrowserPlugin.d.ts +30 -0
  113. package/typings/Lang.d.ts +124 -0
  114. package/typings/Module.d.ts +15 -0
  115. package/typings/Plugin.d.ts +42 -0
  116. package/typings/SubmenuPlugin.d.ts +8 -0
  117. package/typings/_classes.d.ts +17 -0
  118. package/typings/_colorPicker.d.ts +60 -0
  119. package/typings/_core.d.ts +55 -0
  120. package/typings/align.d.ts +5 -0
  121. package/{src/plugins/dialog → typings}/audio.d.ts +1 -1
  122. package/typings/backgroundColor.d.ts +5 -0
  123. package/{src/plugins/command → typings}/blockquote.d.ts +1 -1
  124. package/typings/char.d.ts +39 -0
  125. package/typings/component.d.ts +38 -0
  126. package/typings/context.d.ts +39 -0
  127. package/typings/converter.d.ts +33 -0
  128. package/typings/dialog.d.ts +28 -0
  129. package/typings/domUtils.d.ts +361 -0
  130. package/typings/editor.d.ts +7 -0
  131. package/typings/editor.ts +542 -0
  132. package/typings/env.d.ts +70 -0
  133. package/typings/eventManager.d.ts +37 -0
  134. package/typings/events.d.ts +262 -0
  135. package/typings/fileBrowser.d.ts +42 -0
  136. package/typings/fileManager.d.ts +67 -0
  137. package/typings/font.d.ts +5 -0
  138. package/typings/fontColor.d.ts +5 -0
  139. package/typings/fontSize.d.ts +5 -0
  140. package/typings/format.d.ts +191 -0
  141. package/typings/formatBlock.d.ts +5 -0
  142. package/typings/history.d.ts +48 -0
  143. package/typings/horizontalRule.d.ts +5 -0
  144. package/{src/plugins/dialog → typings}/image.d.ts +1 -1
  145. package/{src/plugins/fileBrowser → typings}/imageGallery.d.ts +1 -1
  146. package/typings/index.d.ts +21 -0
  147. package/{src/plugins/modules/index.d.ts → typings/index.modules.d.ts} +3 -3
  148. package/typings/index.plugins.d.ts +58 -0
  149. package/typings/lineHeight.d.ts +5 -0
  150. package/{src/plugins/dialog → typings}/link.d.ts +1 -1
  151. package/typings/list.d.ts +5 -0
  152. package/{src/plugins/dialog → typings}/math.d.ts +1 -1
  153. package/typings/mediaContainer.d.ts +25 -0
  154. package/typings/node.d.ts +57 -0
  155. package/typings/notice.d.ts +16 -0
  156. package/typings/numbers.d.ts +29 -0
  157. package/typings/offset.d.ts +24 -0
  158. package/typings/options.d.ts +589 -0
  159. package/typings/paragraphStyle.d.ts +5 -0
  160. package/typings/resizing.d.ts +141 -0
  161. package/typings/selection.d.ts +94 -0
  162. package/typings/shortcuts.d.ts +13 -0
  163. package/typings/suneditor.d.ts +9 -0
  164. package/typings/table.d.ts +5 -0
  165. package/typings/template.d.ts +5 -0
  166. package/typings/textStyle.d.ts +5 -0
  167. package/typings/toolbar.d.ts +32 -0
  168. package/typings/unicode.d.ts +25 -0
  169. package/{src/plugins/dialog → typings}/video.d.ts +1 -1
  170. package/dist/css/suneditor.min.css +0 -1
  171. package/src/assets/css/suneditor-contents.css +0 -562
  172. package/src/assets/css/suneditor.css +0 -566
  173. package/src/assets/defaultIcons.js +0 -103
  174. package/src/lang/Lang.d.ts +0 -144
  175. package/src/lang/ckb.d.ts +0 -5
  176. package/src/lang/ckb.js +0 -188
  177. package/src/lang/cs.d.ts +0 -5
  178. package/src/lang/cs.js +0 -188
  179. package/src/lang/da.d.ts +0 -5
  180. package/src/lang/da.js +0 -191
  181. package/src/lang/de.d.ts +0 -5
  182. package/src/lang/de.js +0 -188
  183. package/src/lang/en.d.ts +0 -5
  184. package/src/lang/en.js +0 -188
  185. package/src/lang/es.d.ts +0 -5
  186. package/src/lang/es.js +0 -188
  187. package/src/lang/fa.d.ts +0 -5
  188. package/src/lang/fa.js +0 -188
  189. package/src/lang/fr.d.ts +0 -5
  190. package/src/lang/fr.js +0 -188
  191. package/src/lang/he.d.ts +0 -5
  192. package/src/lang/he.js +0 -188
  193. package/src/lang/index.d.ts +0 -23
  194. package/src/lang/it.d.ts +0 -5
  195. package/src/lang/it.js +0 -188
  196. package/src/lang/ja.d.ts +0 -5
  197. package/src/lang/ja.js +0 -188
  198. package/src/lang/ko.d.ts +0 -5
  199. package/src/lang/ko.js +0 -188
  200. package/src/lang/lv.d.ts +0 -5
  201. package/src/lang/lv.js +0 -188
  202. package/src/lang/nl.d.ts +0 -5
  203. package/src/lang/nl.js +0 -188
  204. package/src/lang/pl.d.ts +0 -5
  205. package/src/lang/pl.js +0 -188
  206. package/src/lang/pt_br.d.ts +0 -5
  207. package/src/lang/pt_br.js +0 -189
  208. package/src/lang/ro.d.ts +0 -5
  209. package/src/lang/ro.js +0 -188
  210. package/src/lang/ru.d.ts +0 -5
  211. package/src/lang/ru.js +0 -188
  212. package/src/lang/se.d.ts +0 -5
  213. package/src/lang/se.js +0 -191
  214. package/src/lang/tr.d.ts +0 -5
  215. package/src/lang/tr.js +0 -191
  216. package/src/lang/ua.d.ts +0 -5
  217. package/src/lang/ua.js +0 -188
  218. package/src/lang/ur.d.ts +0 -5
  219. package/src/lang/ur.js +0 -188
  220. package/src/lang/zh_cn.d.ts +0 -5
  221. package/src/lang/zh_cn.js +0 -187
  222. package/src/lib/constructor.js +0 -954
  223. package/src/lib/context.d.ts +0 -42
  224. package/src/lib/context.js +0 -71
  225. package/src/lib/core.d.ts +0 -1135
  226. package/src/lib/core.js +0 -9395
  227. package/src/lib/history.d.ts +0 -48
  228. package/src/lib/history.js +0 -219
  229. package/src/lib/util.d.ts +0 -678
  230. package/src/lib/util.js +0 -2131
  231. package/src/options.d.ts +0 -608
  232. package/src/plugins/CommandPlugin.d.ts +0 -8
  233. package/src/plugins/DialogPlugin.d.ts +0 -20
  234. package/src/plugins/FileBrowserPlugin.d.ts +0 -30
  235. package/src/plugins/Module.d.ts +0 -15
  236. package/src/plugins/Plugin.d.ts +0 -42
  237. package/src/plugins/SubmenuPlugin.d.ts +0 -8
  238. package/src/plugins/dialog/audio.js +0 -559
  239. package/src/plugins/dialog/image.js +0 -1126
  240. package/src/plugins/dialog/link.js +0 -223
  241. package/src/plugins/dialog/math.js +0 -295
  242. package/src/plugins/dialog/mention.js +0 -242
  243. package/src/plugins/dialog/video.js +0 -979
  244. package/src/plugins/index.d.ts +0 -79
  245. package/src/plugins/modules/_anchor.js +0 -461
  246. package/src/plugins/modules/_colorPicker.d.ts +0 -60
  247. package/src/plugins/modules/_colorPicker.js +0 -201
  248. package/src/plugins/modules/_notice.d.ts +0 -21
  249. package/src/plugins/modules/_notice.js +0 -72
  250. package/src/plugins/modules/_selectMenu.js +0 -119
  251. package/src/plugins/modules/component.d.ts +0 -25
  252. package/src/plugins/modules/component.js +0 -81
  253. package/src/plugins/modules/dialog.d.ts +0 -28
  254. package/src/plugins/modules/dialog.js +0 -175
  255. package/src/plugins/modules/fileBrowser.d.ts +0 -42
  256. package/src/plugins/modules/fileBrowser.js +0 -374
  257. package/src/plugins/modules/fileManager.d.ts +0 -67
  258. package/src/plugins/modules/fileManager.js +0 -326
  259. package/src/plugins/modules/index.js +0 -9
  260. package/src/plugins/modules/resizing.d.ts +0 -154
  261. package/src/plugins/modules/resizing.js +0 -903
  262. package/src/plugins/submenu/align.d.ts +0 -5
  263. package/src/plugins/submenu/align.js +0 -160
  264. package/src/plugins/submenu/font.d.ts +0 -5
  265. package/src/plugins/submenu/font.js +0 -123
  266. package/src/plugins/submenu/fontColor.d.ts +0 -5
  267. package/src/plugins/submenu/fontColor.js +0 -101
  268. package/src/plugins/submenu/fontSize.d.ts +0 -5
  269. package/src/plugins/submenu/fontSize.js +0 -112
  270. package/src/plugins/submenu/formatBlock.d.ts +0 -5
  271. package/src/plugins/submenu/formatBlock.js +0 -273
  272. package/src/plugins/submenu/hiliteColor.d.ts +0 -5
  273. package/src/plugins/submenu/hiliteColor.js +0 -102
  274. package/src/plugins/submenu/horizontalRule.d.ts +0 -5
  275. package/src/plugins/submenu/horizontalRule.js +0 -98
  276. package/src/plugins/submenu/lineHeight.d.ts +0 -5
  277. package/src/plugins/submenu/lineHeight.js +0 -104
  278. package/src/plugins/submenu/list.d.ts +0 -5
  279. package/src/plugins/submenu/list.js +0 -456
  280. package/src/plugins/submenu/paragraphStyle.d.ts +0 -5
  281. package/src/plugins/submenu/paragraphStyle.js +0 -135
  282. package/src/plugins/submenu/table.d.ts +0 -5
  283. package/src/plugins/submenu/table.js +0 -1431
  284. package/src/plugins/submenu/template.d.ts +0 -5
  285. package/src/plugins/submenu/template.js +0 -72
  286. package/src/plugins/submenu/textStyle.d.ts +0 -5
  287. package/src/plugins/submenu/textStyle.js +0 -167
  288. package/src/suneditor.d.ts +0 -9
  289. package/src/suneditor_build.js +0 -18
  290. /package/{src/plugins/dialog → typings}/mention.d.ts +0 -0
@@ -0,0 +1,271 @@
1
+ import CoreInjector from '../editorInjector/_core';
2
+ import { domUtils } from '../helper';
3
+ import ApiManager from './ApiManager';
4
+
5
+ /**
6
+ * @param {*} inst
7
+ * @param {Object} params
8
+ * @param {string} params.title - File browser window title. Required. Can be overridden in fileBrowser.
9
+ * @param {string} params.url - File server url. Required. Can be overridden in fileBrowser.
10
+ * @param {Object} params.headers - File server http header. Required. Can be overridden in fileBrowser.
11
+ * @param {string} params.listClass - Class name of list div. Required. Can be overridden in fileBrowser.
12
+ * @param {function} params.drawItemHandler - Function that defines the HTML of a file item. Required. Can be overridden in fileBrowser.
13
+ * @param {function} params.selectorHandler - Function that actions when an item is clicked. Required. Can be overridden in fileBrowser.
14
+ * @param {number} params.columnSize - Number of "div.se-file-item-column" to be created. Optional. Can be overridden in fileBrowser. Default: 4.
15
+ */
16
+ const FileBrowser = function (inst, params) {
17
+ CoreInjector.call(this, inst.editor);
18
+
19
+ // create HTML
20
+ const browserFrame = domUtils.createElement('DIV', { class: 'se-file-browser sun-editor-common' });
21
+ const content = domUtils.createElement('DIV', { class: 'se-file-browser-inner' }, CreateHTML(inst.editor));
22
+
23
+ // members
24
+ this.kind = inst.constructor.key || inst.constructor.name;
25
+ this.inst = inst;
26
+ this.area = browserFrame;
27
+ this.header = content.querySelector('.se-file-browser-header');
28
+ this.titleArea = content.querySelector('.se-file-browser-title');
29
+ this.tagArea = content.querySelector('.se-file-browser-tags');
30
+ this.body = content.querySelector('.se-file-browser-body');
31
+ this.list = content.querySelector('.se-file-browser-list');
32
+ this._loading = content.querySelector('.se-loading-box');
33
+
34
+ this.title = params.title;
35
+ this.listClass = params.listClass;
36
+ this.url = params.url;
37
+ this.urlHeader = params.headers;
38
+ this.drawItemHandler = params.drawItemHandler;
39
+ this.selectorHandler = params.selectorHandler;
40
+ this.columnSize = params.columnSize || 4;
41
+
42
+ this.items = [];
43
+ this.selectedTags = [];
44
+ this._closeSignal = false;
45
+ this._bindClose = null;
46
+ this.__globalEventHandler = (e) => {
47
+ if (!/27/.test(e.keyCode)) return;
48
+ this.close();
49
+ };
50
+ // api manager
51
+ this.apiManager = new ApiManager(this, { method: 'GET' });
52
+
53
+ // init
54
+ browserFrame.appendChild(domUtils.createElement('DIV', { class: 'se-file-browser-back' }));
55
+ browserFrame.appendChild(content);
56
+ this.carrierWrapper.appendChild(browserFrame);
57
+
58
+ this.eventManager.addEvent(this.tagArea, 'click', OnClickTag.bind(this));
59
+ this.eventManager.addEvent(this.list, 'click', OnClickFile.bind(this));
60
+ this.eventManager.addEvent(content, 'mousedown', OnMouseDown_browser.bind(this));
61
+ this.eventManager.addEvent(content, 'click', OnClick_browser.bind(this));
62
+ };
63
+
64
+ FileBrowser.prototype = {
65
+ /**
66
+ * @description Open a file browser plugin
67
+ * @param {Object|null} params {
68
+ * selectorHandler: When the function comes as an argument value, it substitutes "context.selectorHandler".
69
+ * }
70
+ */
71
+ open(params) {
72
+ if (!params) params = {};
73
+ this.__addGlobalEvent();
74
+
75
+ const listClassName = params.listClass || this.listClass;
76
+ if (!domUtils.hasClass(this.list, listClassName)) {
77
+ this.list.className = 'se-file-browser-list ' + listClassName;
78
+ }
79
+ this.titleArea.textContent = params.title || this.title;
80
+ this.area.style.display = 'block';
81
+
82
+ this._drawFileList(params.url || this.url, params.urlHeader || this.urlHeader);
83
+ },
84
+
85
+ /**
86
+ * @description Close a fileBrowser plugin
87
+ * The plugin's "init" method is called.
88
+ */
89
+ close() {
90
+ this.__removeGlobalEvent();
91
+ this.apiManager.cancel();
92
+
93
+ this.area.style.display = 'none';
94
+ this.selectedTags = [];
95
+ this.items = [];
96
+ this.list.innerHTML = this.tagArea.innerHTML = this.titleArea.textContent = '';
97
+
98
+ if (typeof this.inst.init === 'function') this.inst.init();
99
+ },
100
+
101
+ /**
102
+ * @description Show file browser loading box
103
+ */
104
+ showBrowserLoading() {
105
+ this._loading.style.display = 'block';
106
+ },
107
+
108
+ /**
109
+ * @description Close file browser loading box
110
+ */
111
+ closeBrowserLoading() {
112
+ this._loading.style.display = 'none';
113
+ },
114
+
115
+ _drawFileList(url, urlHeader) {
116
+ this.apiManager.call({ method: 'GET', url, headers: urlHeader, callBack: CallBackGet.bind(this), errorCallBack: CallBackError.bind(this) });
117
+ this.showBrowserLoading();
118
+ },
119
+
120
+ _drawListItem(items, update) {
121
+ const _tags = [];
122
+ const len = items.length;
123
+ const columnSize = this.columnSize;
124
+ const splitSize = columnSize <= 1 ? 1 : Math.round(len / columnSize) || 1;
125
+ const drawItemHandler = this.drawItemHandler;
126
+
127
+ let tagsHTML = '';
128
+ let listHTML = '<div class="se-file-item-column">';
129
+ let columns = 1;
130
+ for (let i = 0, item, tags; i < len; i++) {
131
+ item = items[i];
132
+ tags = !item.tag ? [] : typeof item.tag === 'string' ? item.tag.split(',') : item.tag;
133
+ tags = item.tag = tags.map(function (v) {
134
+ return v.trim();
135
+ });
136
+ listHTML += drawItemHandler(item);
137
+
138
+ if ((i + 1) % splitSize === 0 && columns < columnSize && i + 1 < len) {
139
+ columns++;
140
+ listHTML += '</div><div class="se-file-item-column">';
141
+ }
142
+
143
+ if (update && tags.length > 0) {
144
+ for (let t = 0, tLen = tags.length, tag; t < tLen; t++) {
145
+ tag = tags[t];
146
+ if (tag && !_tags.includes(tag)) {
147
+ _tags.push(tag);
148
+ tagsHTML += `<a title="${tag}" aria-label="${tag}">${tag}</a>`;
149
+ }
150
+ }
151
+ }
152
+ }
153
+ listHTML += '</div>';
154
+
155
+ this.list.innerHTML = listHTML;
156
+
157
+ if (update) {
158
+ this.items = items;
159
+ this.tagArea.innerHTML = tagsHTML;
160
+ }
161
+ },
162
+
163
+ __addGlobalEvent() {
164
+ this.__removeGlobalEvent();
165
+ this._bindClose = this.eventManager.addGlobalEvent('keydown', this.__globalEventHandler, true);
166
+ },
167
+
168
+ __removeGlobalEvent() {
169
+ if (this._bindClose) this._bindClose = this.eventManager.removeGlobalEvent(this._bindClose);
170
+ },
171
+
172
+ constructor: FileBrowser
173
+ };
174
+
175
+ function CallBackGet(xmlHttp) {
176
+ try {
177
+ const res = JSON.parse(xmlHttp.responseText);
178
+ if (res.result.length > 0) {
179
+ this._drawListItem(res.result, true);
180
+ } else if (res.nullMessage) {
181
+ this.list.innerHTML = res.nullMessage;
182
+ }
183
+ } catch (e) {
184
+ throw Error(`[SUNEDITOR.fileBrowser.drawList.fail] cause: "${e.message}"`);
185
+ } finally {
186
+ this.closeBrowserLoading();
187
+ this.body.style.maxHeight = domUtils.getClientSize().h - this.header.offsetHeight - 50 + 'px';
188
+ }
189
+ }
190
+
191
+ function CallBackError(res, xmlHttp) {
192
+ this.closeBrowserLoading();
193
+ throw Error(`[SUNEDITOR.fileBrowser.get.serverException] status: ${xmlHttp.status}, response: ${res.errorMessage || xmlHttp.responseText}`);
194
+ }
195
+
196
+ function OnClickTag(e) {
197
+ const target = e.target;
198
+ if (!domUtils.isAnchor(target)) return;
199
+
200
+ const tagName = target.textContent;
201
+ const selectTag = this.tagArea.querySelector('a[title="' + tagName + '"]');
202
+ const selectedTags = this.selectedTags;
203
+ const sTagIndex = selectedTags.indexOf(tagName);
204
+
205
+ if (sTagIndex > -1) {
206
+ selectedTags.splice(sTagIndex, 1);
207
+ domUtils.removeClass(selectTag, 'on');
208
+ } else {
209
+ selectedTags.push(tagName);
210
+ domUtils.addClass(selectTag, 'on');
211
+ }
212
+
213
+ this._drawListItem(
214
+ selectedTags.length === 0
215
+ ? this.items
216
+ : this.items.filter(function (item) {
217
+ return item.tag.some(function (tag) {
218
+ return selectedTags.includes(tag);
219
+ });
220
+ }),
221
+ false
222
+ );
223
+ }
224
+
225
+ function OnClickFile(e) {
226
+ e.preventDefault();
227
+ e.stopPropagation();
228
+
229
+ if (e.target === this.list) return;
230
+
231
+ const target = domUtils.getCommandTarget(e.target);
232
+ if (!target) return;
233
+
234
+ this.close();
235
+ this.selectorHandler(target);
236
+ }
237
+
238
+ function OnMouseDown_browser(e) {
239
+ if (/se-file-browser-inner/.test(e.target.className)) {
240
+ this._closeSignal = true;
241
+ } else {
242
+ this._closeSignal = false;
243
+ }
244
+ }
245
+
246
+ function OnClick_browser(e) {
247
+ e.stopPropagation();
248
+
249
+ if (/close/.test(e.target.getAttribute('data-command')) || this._closeSignal) {
250
+ this.close();
251
+ }
252
+ }
253
+
254
+ function CreateHTML({ lang, icons }) {
255
+ return /*html*/ `
256
+ <div class="se-file-browser-content">
257
+ <div class="se-file-browser-header">
258
+ <button type="button" data-command="close" class="se-btn se-file-browser-close" class="close" title="${lang.close}" aria-label="${lang.close}">
259
+ ${icons.cancel}
260
+ </button>
261
+ <span class="se-file-browser-title"></span>
262
+ <div class="se-file-browser-tags"></div>
263
+ </div>
264
+ <div class="se-file-browser-body">
265
+ <div class="se-loading-box sun-editor-common"><div class="se-loading-effect"></div></div>
266
+ <div class="se-file-browser-list"></div>
267
+ </div>
268
+ </div>`;
269
+ }
270
+
271
+ export default FileBrowser;
@@ -0,0 +1,290 @@
1
+ import CoreInjector from '../editorInjector/_core';
2
+ import ApiManager from './ApiManager';
3
+
4
+ /**
5
+ *
6
+ * @param {*} inst
7
+ * @param {{ query: string, loadHandler: Function, eventHandler: Function, figure: Figure instance | null }} params
8
+ */
9
+ const FileManager = function (inst, params) {
10
+ CoreInjector.call(this, inst.editor);
11
+
12
+ // members
13
+ inst.__fileManagement = this;
14
+ this.kind = inst.constructor.key || inst.constructor.name;
15
+ this.inst = inst;
16
+ this.component = inst.editor.component;
17
+ this.query = params.query;
18
+ this.loadHandler = params.loadHandler;
19
+ this.eventHandler = params.eventHandler;
20
+ this.infoList = [];
21
+ this.infoIndex = 0;
22
+ this.uploadFileLength = 0;
23
+ this.__updateTags = [];
24
+ // api manager
25
+ this.apiManager = new ApiManager(this, null);
26
+ };
27
+
28
+ FileManager.prototype = {
29
+ /**
30
+ * @description Upload the file to the server.
31
+ * @param {string} uploadUrl Upload server url
32
+ * @param {Object|null} uploadHeader Request header
33
+ * @param {Files|{FormData, size}} data FormData in body or Files array
34
+ * @param {Function|null} callBack Success call back function
35
+ * @param {Function|null} errorCallBack Error call back function
36
+ */
37
+ upload(uploadUrl, uploadHeader, data, callBack, errorCallBack) {
38
+ this.editor.showLoading();
39
+
40
+ let formData = null;
41
+ // create formData
42
+ if (data.length) {
43
+ formData = new FormData();
44
+ for (let i = 0, len = data.length; i < len; i++) {
45
+ formData.append('file-' + i, data[i]);
46
+ }
47
+ this.uploadFileLength = data.length;
48
+ } else {
49
+ formData = data.formData;
50
+ this.uploadFileLength = data.size;
51
+ }
52
+
53
+ this.apiManager.call({ method: 'POST', url: uploadUrl, headers: uploadHeader, data: formData, callBack, errorCallBack });
54
+ },
55
+
56
+ /**
57
+ * @description Upload the file to the server.
58
+ * @param {string} uploadUrl Upload server url
59
+ * @param {Object|null} uploadHeader Request header
60
+ * @param {Files|{FormData, size}} data FormData in body or Files array
61
+ */
62
+ async asyncUpload(uploadUrl, uploadHeader, data) {
63
+ this.editor.showLoading();
64
+
65
+ let formData = null;
66
+ // create formData
67
+ if (data.length) {
68
+ formData = new FormData();
69
+ for (let i = 0, len = data.length; i < len; i++) {
70
+ formData.append('file-' + i, data[i]);
71
+ }
72
+ this.uploadFileLength = data.length;
73
+ } else {
74
+ formData = data.formData;
75
+ this.uploadFileLength = data.size;
76
+ }
77
+
78
+ return await this.apiManager.asyncCall({ method: 'POST', url: uploadUrl, headers: uploadHeader, data: formData });
79
+ },
80
+
81
+ setFileData(element, { name, size }) {
82
+ if (!element) return;
83
+ element.setAttribute('data-se-file-name', name);
84
+ element.setAttribute('data-se-file-size', size);
85
+ },
86
+
87
+ /**
88
+ * @description Create info object of file and add it to "infoList"
89
+ * @private
90
+ * @param {Element} element
91
+ * @param {Object|null} file
92
+ */
93
+ _setInfo(element, file) {
94
+ let dataIndex = element.getAttribute('data-se-index');
95
+ let info = null;
96
+ let state = '';
97
+
98
+ if (!file) {
99
+ file = {
100
+ name: element.getAttribute('data-se-file-name') || (typeof element.src === 'string' ? element.src.split('/').pop() : ''),
101
+ size: element.getAttribute('data-se-file-size') || 0
102
+ };
103
+ }
104
+
105
+ // create
106
+ if (!dataIndex || this._componentsInfoInit) {
107
+ state = 'create';
108
+ dataIndex = this.infoIndex++;
109
+
110
+ element.setAttribute('data-se-index', dataIndex);
111
+ element.setAttribute('data-se-file-name', file.name);
112
+ element.setAttribute('data-se-file-size', file.size);
113
+
114
+ info = {
115
+ src: element.src,
116
+ index: dataIndex * 1,
117
+ name: file.name,
118
+ size: file.size
119
+ };
120
+
121
+ this.infoList.push(info);
122
+ } else {
123
+ // update
124
+ state = 'update';
125
+ dataIndex *= 1;
126
+
127
+ for (let i = 0, len = this.infoList.length; i < len; i++) {
128
+ if (dataIndex === this.infoList[i].index) {
129
+ info = this.infoList[i];
130
+ break;
131
+ }
132
+ }
133
+
134
+ if (!info) {
135
+ dataIndex = this.infoIndex++;
136
+ info = {
137
+ index: dataIndex
138
+ };
139
+ this.infoList.push(info);
140
+ }
141
+
142
+ info.src = element.src;
143
+ info.name = element.getAttribute('data-se-file-name');
144
+ info.size = element.getAttribute('data-se-file-size') * 1;
145
+ }
146
+
147
+ // method bind
148
+ info.element = element;
149
+ info.delete = function (el) {
150
+ if (typeof this.inst.destroy === 'function') this.inst.destroy.call(this.inst, el);
151
+ this._deleteInfo(el.getAttribute('data-se-index') * 1);
152
+ }.bind(this, element);
153
+ info.select = function (el) {
154
+ el.scrollIntoView(true);
155
+ if (typeof this.inst.select === 'function') this._w.setTimeout(this.inst.select.bind(this.inst, el), 0);
156
+ }.bind(this, element);
157
+
158
+ const params = { editor: this.editor, element, index: dataIndex, state, info, remainingFilesCount: --this.uploadFileLength < 0 ? 0 : this.uploadFileLength };
159
+ if (typeof this.eventHandler === 'function') {
160
+ this.eventHandler(params);
161
+ }
162
+ this.triggerEvent('onFileManagerAction', { ...params, pluginName: this.kind });
163
+ },
164
+
165
+ /**
166
+ * @description Gets the sum of the sizes of the currently saved files.
167
+ * @returns {number} Size
168
+ */
169
+ getSize() {
170
+ let size = 0;
171
+ for (let i = 0, len = this.infoList.length; i < len; i++) {
172
+ size += this.infoList[i].size * 1;
173
+ }
174
+ return size;
175
+ },
176
+
177
+ /**
178
+ * @description Checke the file's information and modify the tag that does not fit the format.
179
+ * @private
180
+ */
181
+ _checkInfo(loaded) {
182
+ const tags = [].slice.call(this.editor.frameContext.get('wysiwyg').querySelectorAll(this.query));
183
+ const infoList = this.infoList;
184
+ if (tags.length === infoList.length) {
185
+ // reset
186
+ if (this._componentsInfoReset) {
187
+ for (let i = 0, len = tags.length; i < len; i++) {
188
+ this._setInfo(tags[i], null);
189
+ }
190
+ return;
191
+ } else {
192
+ let infoUpdate = false;
193
+ for (let i = 0, len = infoList.length, info; i < len; i++) {
194
+ info = infoList[i];
195
+ if (
196
+ tags.filter(function (t) {
197
+ return info.src === t.src && info.index.toString() === t.getAttribute('data-se-index');
198
+ }).length === 0
199
+ ) {
200
+ infoUpdate = true;
201
+ break;
202
+ }
203
+ }
204
+ // pass
205
+ if (!infoUpdate) return;
206
+ }
207
+ }
208
+
209
+ // check
210
+ const currentTags = [];
211
+ const infoIndex = [];
212
+ for (let i = 0, len = infoList.length; i < len; i++) {
213
+ infoIndex[i] = infoList[i].index;
214
+ }
215
+
216
+ this.__updateTags = tags;
217
+
218
+ while (tags.length > 0) {
219
+ const tag = tags.shift();
220
+ if (!tag.getAttribute('data-se-index') || !infoIndex.includes(tag.getAttribute('data-se-index') * 1)) {
221
+ currentTags.push(this.infoIndex);
222
+ tag.removeAttribute('data-se-index');
223
+ this._setInfo(tag, null);
224
+ } else {
225
+ currentTags.push(tag.getAttribute('data-se-index') * 1);
226
+ }
227
+ }
228
+
229
+ // editor load
230
+ if (loaded && typeof this.loadHandler === 'function') {
231
+ this.loadHandler(infoList);
232
+ return;
233
+ }
234
+
235
+ for (let i = 0, dataIndex; i < infoList.length; i++) {
236
+ dataIndex = infoList[i].index;
237
+ if (currentTags.includes(dataIndex)) continue;
238
+
239
+ infoList.splice(i, 1);
240
+
241
+ const params = { editor: this.editor, element: null, index: dataIndex, state: 'delete', info: null, remainingFilesCount: 0 };
242
+ if (typeof this.eventHandler === 'function') {
243
+ this.eventHandler(params);
244
+ }
245
+ this.triggerEvent('onFileManagerAction', { ...params, pluginName: this.kind });
246
+
247
+ i--;
248
+ }
249
+ },
250
+
251
+ /**
252
+ * @description Reset info object and "infoList = []", "infoIndex = 0"
253
+ * @param {string} this.kind Plugin name
254
+ * @private
255
+ */
256
+ _resetInfo() {
257
+ const eh = typeof this.eventHandler === 'function';
258
+ const params = { editor: this.editor, element: null, state: 'delete', info: null, remainingFilesCount: 0 };
259
+ for (let i = 0, len = this.infoList.length; i < len; i++) {
260
+ if (eh) this.eventHandler({ ...params, index: this.infoList[i].index, pluginName: this.kind });
261
+ this.triggerEvent('onFileManagerAction', { ...params, index: this.infoList[i].index, pluginName: this.kind });
262
+ }
263
+
264
+ this.infoList = [];
265
+ this.infoIndex = 0;
266
+ },
267
+
268
+ /**
269
+ * @description Delete info object at "infoList"
270
+ * @param {number} index index of info object infoList[].index)
271
+ * @private
272
+ */
273
+ _deleteInfo(index) {
274
+ if (index >= 0) {
275
+ for (let i = 0, len = this.infoList.length; i < len; i++) {
276
+ if (index === this.infoList[i].index) {
277
+ this.infoList.splice(i, 1);
278
+ if (typeof this.eventHandler === 'function') {
279
+ this.eventHandler({ editor: this.editor, element: null, index, state: 'delete', info: null, remainingFilesCount: 0 });
280
+ }
281
+ return;
282
+ }
283
+ }
284
+ }
285
+ },
286
+
287
+ constructor: FileManager
288
+ };
289
+
290
+ export default FileManager;