jodit 3.2.37 → 3.2.44

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 (69) hide show
  1. package/README.md +2 -0
  2. package/build/jodit.min.css +2 -2
  3. package/build/jodit.min.js +2 -2
  4. package/package.json +1 -1
  5. package/src/Config.ts +6 -0
  6. package/src/Jodit.ts +18 -11
  7. package/src/index.ts +1 -0
  8. package/src/langs/ar.ts +1 -0
  9. package/src/langs/cs_cz.ts +2 -1
  10. package/src/langs/de.ts +1 -0
  11. package/src/langs/es.ts +1 -0
  12. package/src/langs/fr.ts +1 -0
  13. package/src/langs/hu.ts +2 -0
  14. package/src/langs/index.ts +2 -1
  15. package/src/langs/it.ts +223 -0
  16. package/src/langs/nl.ts +1 -0
  17. package/src/langs/pt_br.ts +1 -0
  18. package/src/langs/ru.ts +1 -0
  19. package/src/langs/tr.ts +1 -0
  20. package/src/langs/zh_cn.ts +1 -0
  21. package/src/modules/Create.ts +13 -2
  22. package/src/modules/Dom.ts +1 -1
  23. package/src/modules/Uploader.ts +22 -5
  24. package/src/modules/Widget.ts +64 -15
  25. package/src/modules/dialog/dialog.ts +5 -5
  26. package/src/modules/filebrowser/config.ts +698 -0
  27. package/src/modules/filebrowser/fileBrowser.ts +31 -685
  28. package/src/modules/helpers/checker/hasBrowserColorPicker.ts +27 -0
  29. package/src/modules/helpers/checker/index.ts +2 -1
  30. package/src/modules/helpers/html/cleanFromWord.ts +34 -21
  31. package/src/modules/helpers/html/clear.ts +2 -2
  32. package/src/modules/popup/popup.ts +1 -1
  33. package/src/modules/toolbar/button.ts +17 -8
  34. package/src/modules/toolbar/collection.ts +10 -0
  35. package/src/modules/view/panel.ts +1 -1
  36. package/src/plugins/hotkeys.ts +1 -1
  37. package/src/plugins/iframe.ts +4 -1
  38. package/src/plugins/resizer.ts +20 -10
  39. package/src/plugins/size.ts +10 -10
  40. package/src/plugins/source.ts +2 -4
  41. package/src/plugins/table.ts +78 -26
  42. package/src/styles/icons/index.ts +2 -0
  43. package/src/styles/icons/palette.svg +13 -0
  44. package/src/styles/modules/btn.less +3 -3
  45. package/src/styles/modules/dropdownlist.less +11 -0
  46. package/src/styles/modules/icon.less +10 -3
  47. package/src/styles/modules/toolbar.less +17 -1
  48. package/src/styles/plugins/table.less +2 -1
  49. package/src/styles/widgets/colorpicker.less +27 -5
  50. package/src/types/create.d.ts +2 -0
  51. package/src/types/fileBrowser.d.ts +5 -5
  52. package/src/types/toolbar.d.ts +3 -1
  53. package/src/types/view.d.ts +5 -4
  54. package/src/utils/lang-loader.js +1 -1
  55. package/test/bootstrap.js +50 -34
  56. package/test/test.html +2 -1
  57. package/test/tests/commandsTest.js +2 -2
  58. package/test/tests/editorTest.js +1 -65
  59. package/test/tests/enterTest.js +9 -9
  60. package/test/tests/filebrowserTest.js +1 -1
  61. package/test/tests/iframeTest.js +1 -11
  62. package/test/tests/imageTest.js +20 -20
  63. package/test/tests/interfaceTest.js +132 -12
  64. package/test/tests/plugins/dragAndDropElement.js +1 -1
  65. package/test/tests/plugins/size.js +110 -0
  66. package/test/tests/pluginsTest.js +6 -6
  67. package/test/tests/tableTest.js +17 -17
  68. package/test/tests/uploaderTest.js +38 -4
  69. package/webpack.config.js +0 -1
@@ -25,695 +25,23 @@ import {
25
25
  ISourcesFiles,
26
26
  } from '../../types/fileBrowser';
27
27
 
28
- import { IControlType } from '../../types/toolbar';
29
- import { ActionBox, IDictionary, IPermissions } from '../../types/types';
28
+ import { ActionBox, IPermissions } from '../../types/types';
30
29
  import { IUploader, IUploaderOptions } from '../../types/uploader';
31
- import { IViewBased } from '../../types/view';
32
30
  import { ImageEditor } from '../ImageEditor';
33
31
  import { LocalStorageProvider } from '../storage/localStorageProvider';
34
32
  import { Storage } from '../storage/storage';
35
33
  import { each } from '../helpers/each';
36
34
  import { normalizePath, normalizeRelativePath } from '../helpers/normalize/';
37
35
  import { $$ } from '../helpers/selector';
38
- import { normalizeURL } from '../helpers/normalize/normalizeURL';
39
36
  import { ctrlKey } from '../helpers/ctrlKey';
40
37
  import { extend } from '../helpers/extend';
41
- import { debounce } from '../helpers/async/debounce';
42
38
  import { setTimeout } from '../helpers/async/setTimeout';
43
- import { humanSizeToBytes } from '../helpers';
44
39
  import { ViewWithToolbar } from '../view/viewWithToolbar';
45
40
  import { IJodit } from '../../types';
41
+ import './config';
46
42
 
47
- declare module '../../Config' {
48
- interface Config {
49
- /**
50
- * Filebrowser module settings
51
- *
52
- * @property{int} filebrowser.howLongShowMsg=3000 How long toWYSIWYG show an error message
53
- * in the status bar (ms)
54
- * @property{boolean} filebrowser.sort=function (a, b, sortBy, parent) { return b.changed - a.changed;}
55
- * Items sort functions
56
- * @property{boolean} filebrowser.sortBy='changed' Sort by field
57
- * @property{boolean} filebrowser.filter=function (item, searchWord)
58
- * { return item.name.toLowerCase().indexOf(searchWord.toLowerCase()) !== -1} Filter items
59
- * @property{boolean} filebrowser.showFileName=true Show filename in thumbs
60
- * @property{boolean} filebrowser.showFileSize=true Show filesize in thumbs
61
- * @property{boolean} filebrowser.showFileChangeTime=true Show the last modification time in thumbs
62
- *
63
- * @property {boolean} filebrowser.editImage=true use
64
- * {@link ImageEditor|Image editor module} - crop and resize image
65
- * @property {boolean} filebrowser.preview=true Show preview button in context menu
66
- * @property {boolean} filebrowser.showPreviewNavigation=true Show navigation buttons in preview
67
- * @property {boolean} filebrowser.showSelectButtonInPreview=true Show select button in preview
68
- * @property {boolean} filebrowser.contextMenu=true use context menu
69
- * @property {boolean} filebrowser.createNewFolder=true
70
- * The ability toWYSIWYG create a directory of the web browser
71
- * @property {boolean} filebrowser.deleteFolder=true
72
- * The ability toWYSIWYG delete directories from the web browser
73
- * @property {boolean} filebrowser.moveFolder=true The ability toWYSIWYG move directories from the web browser
74
- * @property {boolean} filebrowser.moveFile=true The ability toWYSIWYG move file from the web browser
75
- * @property {boolean} filebrowser.showFoldersPanel=true Show folders panel
76
- * @property {int|string} filebrowser.width=763px The width of the web browser
77
- * @property {int|string} filebrowser.height=400px The height of the file browser
78
- * @property {Array<string>} filebrowser.buttons="[
79
- * 'filebrowser.upload',
80
- * 'filebrowser.remove',
81
- * 'filebrowser.update',
82
- * 'filebrowser.select',
83
- * 'filebrowser.edit',
84
- * '|',
85
- * 'filebrowser.tiles',
86
- * 'filebrowser.list',
87
- * '|',
88
- * 'filebrowser.filter',
89
- * '|',
90
- * 'filebrowser.sort',
91
- * ]" Toolbar browser
92
- * @example
93
- * ```javascript
94
- * var editor = new Jodit('#editor', {
95
- * filebrowser: {
96
- * buttons: ['filebrowser.upload', 'filebrowser.remove', 'filebrowser.update',
97
- * {
98
- * name: 'deleteall',
99
- * icon: 'remove',
100
- * exec: function (editor) {
101
- * $files.find('a').each(function () {
102
- * editor.filebrowserюremove(editor.filebrowser.currentPath, $(this).data('name'));
103
- * });
104
- * editor.filebrowser.loadTree();
105
- * },
106
- * }],
107
- * }
108
- * })
109
- * ```
110
- * @property{function} filebrowser.isSuccess method toWYSIWYG check - whether the response positive
111
- * @property{function} filebrowser.getMessage method for receiving a message from the response
112
- * @example
113
- * ```javascript
114
- * new Jodit('#editor', {
115
- * filebrowser: {
116
- * isSuccess: function (resp) {
117
- * return resp.status == 1;
118
- * },
119
- * getMessage: function (resp) {
120
- * return resp.message;
121
- * },
122
- * }
123
- * })
124
- * ```
125
- * @property{string} filebrowser.view='tiles' Filelist view - `tiles` or `list`
126
- * @property{object} filebrowser.ajax The default settings for AJAX connections toWYSIWYG the server.
127
- * Most of the settings like here {@link http://api.jquery.com/jQuery.ajax/|jQuery.ajax} but is not jQuery.ajax
128
- * @property{function(data)} filebrowser.ajax.prepareData Method of preparation
129
- * of data toWYSIWYG be sent toWYSIWYG the server
130
- * @property{function(data)} filebrowser.ajax.process The method of processing the
131
- * data obtained after administration of the server. Must return this PlainObject format
132
- * ```json
133
- * {
134
- * files: resp.files || [], // {array} The names of files or folders, files can
135
- * be ['image.jpg', 'image.jpg2', 'image3.jpg' ...] and [{file: 'image.jpg', thumb: '_thumbs/image.jpg'},
136
- * {file: 'image2.jpg', thumb: '_thumbs/image2.jpg'} ...]
137
- * path: resp.path, // {string} Real relative path
138
- * baseurl: resp.baseurl, // {string} Base url for filebrowser
139
- * error: resp.error, // {int}
140
- * msg: resp.msg // {string}
141
- * };
142
- * ```
143
- * @property {string} filebrowser.ajax.url='' Address entry point on the server for AJAX connection
144
- * @property {object} filebrowser.ajax.data={} Default data toWYSIWYG send toWYSIWYG the server
145
- * @property {(json|text)} filebrowser.ajax.dataType='json' The format of the returned data
146
- * @property {object} filebrowser.ajax.headers={} An object of additional header key/value pairs toWYSIWYG
147
- * send along with requests using the `XMLHttpRequest` transport. The header `X-Requested-With: XMLHttpRequest`
148
- * is always added, but its default `XMLHttpRequest` value can be changed here.
149
- * @property {object} filebrowser.resize Settings for AJAX connections toWYSIWYG the server toWYSIWYG resize
150
- * image. By default, the uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax} c параметром
151
- * action=create
152
- * @property {object} filebrowser.crop Settings for AJAX connections toWYSIWYG the server toWYSIWYG crop image.
153
- * By default, the uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax} c параметром
154
- * action=create
155
- * @property {object} filebrowser.create Settings for AJAX connections toWYSIWYG the server toWYSIWYG create
156
- * the category . By default, the uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax}
157
- * c параметром action=create
158
- * @property {object} filebrowser.move Settings for AJAX connections toWYSIWYG the server for the moving
159
- * image or category . By default uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax}
160
- * c параметром action=move
161
- * @property {object} filebrowser.remove Settings for AJAX connections toWYSIWYG the server toWYSIWYG
162
- * delete the image or category . By default uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax}
163
- * c параметром action=remove
164
- * @property {object} filebrowser.folder Settings for AJAX connections toWYSIWYG the server toWYSIWYG
165
- * download the list of categories .
166
- * By default uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax}
167
- * c параметром action=folder
168
- * @property {object} filebrowser.items Settings for AJAX connections toWYSIWYG the server toWYSIWYG download
169
- * the image list in the specified category . By default uses
170
- * {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax} c параметром action=items
171
- * @property {object} filebrowser.uploader=null Settings Module {@link module:Uploader|Uploader}
172
- * for fast uploading images in category via Drag&Drop file in the file browser. The default settings of
173
- * the module {@link module:Uploader|Uploader}
174
- * @example
175
- * ```javascript
176
- * // default values
177
- * {
178
- * isSuccess: function (resp) {
179
- * return !resp.error;
180
- * },
181
- * getMessage: function (resp) {
182
- * return resp.msg;
183
- * },
184
- * ajax: {
185
- * url: '',
186
- * async: true,
187
- * data: {},
188
- * contentType : 'application/x-www-form-urlencoded; charset=UTF-8',
189
- * headers : {},
190
- * method : 'POST',
191
- * processData : true,
192
- * dataType: 'json',
193
- * headers: {},
194
- * prepareData: function (data) {
195
- * return data;
196
- * },
197
- * process: function (resp) {
198
- * return {
199
- * files: resp.files || [],
200
- * path: resp.path,
201
- * baseurl: resp.baseurl,
202
- * error: resp.error,
203
- * msg: resp.msg
204
- * };
205
- * }
206
- * },
207
- * resize: {
208
- * data: {action: 'imageResize'},
209
- * },
210
- * crop: {
211
- * data: {action: 'imageCrop'},
212
- * },
213
- * create: {
214
- * data: {action: 'folderCreate'},
215
- * },
216
- * move: {
217
- * data: {action: 'fileMove'},
218
- * },
219
- * remove: {
220
- * data: {action: 'fileRemove'},
221
- * },
222
- * items: {
223
- * data: {action: 'files'},
224
- * },
225
- * folders: {
226
- * data: {action: 'folders'},
227
- * },
228
- * uploader: null // use default Uploader's settings
229
- * }
230
- * ```
231
- * @example
232
- * ```javascript
233
- * new Jodit('#editor2', {
234
- * filebrowser: {
235
- * isSuccess: function (resp) {
236
- * return resp.length !== 0;
237
- * },
238
- * getMessage: function (resp) {
239
- * return resp;
240
- * },
241
- * ajax: {
242
- * url: 'ajax.php',
243
- * method: 'GET',
244
- * dataType: 'text',
245
- * headers: {
246
- * 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
247
- * },
248
- * data: {
249
- * someparameter: 1
250
- * },
251
- * prepareData: function (data) {
252
- * data.someparameter++;
253
- * return data;
254
- * },
255
- * process: function (resp) {
256
- * return resp.split('|'); // return items list
257
- * },
258
- * }
259
- * }
260
- * })
261
- * ```
262
- * @example
263
- * ```javascript
264
- * var editor = new Jodit('#jodit', {
265
- * uploader: {
266
- * url: 'connector/upload.php',
267
- * baseurl: 'images/'
268
- * },
269
- * filebrowser: {
270
- * create: {
271
- * url: 'connector/create.php',
272
- * },
273
- * move: {
274
- * url: 'connector/move.php',
275
- * },
276
- * remove: {
277
- * url: 'connector/remove.php',
278
- * },
279
- * items: {
280
- * url: 'connector/items.php',
281
- * },
282
- * folder: {
283
- * url: 'connector/tree.php',
284
- * }
285
- * }
286
- * });
287
- * ```
288
- *
289
- */
290
- filebrowser: IFileBrowserOptions;
291
- }
292
- }
293
-
43
+ export const ITEM_CLASS = 'jodit_filebrowser_files_item';
294
44
  const DEFAULT_SOURCE_NAME = 'default';
295
- const ITEM_CLASS = 'jodit_filebrowser_files_item';
296
-
297
- Config.prototype.filebrowser = {
298
- filter(item: string | ISourceFile, search: string) {
299
- search = search.toLowerCase();
300
- if (typeof item === 'string') {
301
- return item.toLowerCase().indexOf(search) !== -1;
302
- }
303
- if (typeof item.name === 'string') {
304
- return item.name.toLowerCase().indexOf(search) !== -1;
305
- }
306
- if (typeof item.file === 'string') {
307
- return item.file.toLowerCase().indexOf(search) !== -1;
308
- }
309
- return true;
310
- },
311
-
312
- sortBy: 'changed',
313
-
314
- sort(this: FileBrowser, a: any, b: any, sortBy: string): number {
315
- const compareStr = (f: string, s: string): number => {
316
- if (f < s) {
317
- return -1;
318
- }
319
-
320
- if (f > s) {
321
- return 1;
322
- }
323
-
324
- return 0;
325
- };
326
-
327
- let first: Date, second: Date;
328
-
329
- if (typeof a === 'string') {
330
- return compareStr(a.toLowerCase(), b.toLowerCase());
331
- }
332
-
333
- if (a[sortBy] === undefined || sortBy === 'name') {
334
- if (typeof a.name === 'string') {
335
- return compareStr(a.name.toLowerCase(), b.name.toLowerCase());
336
- }
337
- if (typeof a.file === 'string') {
338
- return compareStr(a.file.toLowerCase(), b.file.toLowerCase());
339
- }
340
- return 0;
341
- }
342
-
343
- switch (sortBy) {
344
- case 'changed':
345
- first = new Date(a.changed);
346
- second = new Date(b.changed);
347
-
348
- return second.getTime() - first.getTime();
349
- case 'size':
350
- return humanSizeToBytes(a.size) - humanSizeToBytes(b.size);
351
- }
352
-
353
- return 0;
354
- },
355
-
356
- editImage: true,
357
- preview: true,
358
- showPreviewNavigation: true,
359
- showSelectButtonInPreview: true,
360
- contextMenu: true,
361
-
362
- howLongShowMsg: 3000,
363
-
364
- createNewFolder: true,
365
- deleteFolder: true,
366
- moveFolder: true,
367
- moveFile: true,
368
- showFoldersPanel: true,
369
-
370
- width: 763,
371
- height: 400,
372
- buttons: [
373
- 'filebrowser.upload',
374
- 'filebrowser.remove',
375
- 'filebrowser.update',
376
- 'filebrowser.select',
377
- 'filebrowser.edit',
378
- '|',
379
- 'filebrowser.tiles',
380
- 'filebrowser.list',
381
- '|',
382
- 'filebrowser.filter',
383
- '|',
384
- 'filebrowser.sort',
385
- ],
386
- removeButtons: [],
387
- fullsize: false,
388
- showTooltip: true,
389
-
390
- view: null,
391
-
392
- isSuccess(this: FileBrowser, resp: IFileBrowserAnswer): boolean {
393
- return resp.success;
394
- },
395
-
396
- getMessage(this: FileBrowser, resp: IFileBrowserAnswer) {
397
- return resp.data.messages !== undefined &&
398
- Array.isArray(resp.data.messages)
399
- ? resp.data.messages.join(' ')
400
- : '';
401
- },
402
-
403
- showFileName: true,
404
- showFileSize: true,
405
- showFileChangeTime: true,
406
-
407
- getThumbTemplate(
408
- this: FileBrowser,
409
- item: ISourceFile,
410
- source: ISource,
411
- source_name: string
412
- ): string {
413
- let name: string = '',
414
- thumb: string = '',
415
- info: string,
416
- thumbIsAbsolute: boolean = !!item.thumbIsAbsolute,
417
- fileIsAbsolute: boolean = !!item.fileIsAbsolute;
418
- const timestamp: string = new Date().getTime().toString();
419
-
420
- if (item.file !== undefined) {
421
- name = item.file;
422
- thumb = item.file;
423
- }
424
- if (item.thumb) {
425
- thumb = item.thumb;
426
- }
427
-
428
- info =
429
- '<div class="' +
430
- ITEM_CLASS +
431
- '-info">' +
432
- (this.options.showFileName
433
- ? `<span class="${ITEM_CLASS}-info-filename">${name}</span>`
434
- : '') +
435
- (this.options.showFileSize && item.size
436
- ? '<span class="' +
437
- ITEM_CLASS +
438
- '-info-filesize">' +
439
- item.size +
440
- '</span>'
441
- : '') +
442
- (this.options.showFileChangeTime && item.changed
443
- ? '<span class="' +
444
- ITEM_CLASS +
445
- '-info-filechanged">' +
446
- (typeof item.changed === 'number' ? new Date(item.changed).toLocaleString() : item.changed) +
447
- '</span>'
448
- : '') +
449
- '</div>';
450
-
451
- const imageURL: string = fileIsAbsolute
452
- ? name
453
- : normalizeURL(source.baseurl + source.path + name);
454
-
455
- return (
456
- '<a ' +
457
- 'data-is-file="' +
458
- (item.isImage ? 0 : 1) +
459
- '" ' +
460
- 'draggable="true" ' +
461
- 'class="' +
462
- ITEM_CLASS +
463
- '" ' +
464
- 'href="' +
465
- imageURL +
466
- '" ' +
467
- 'data-source="' +
468
- source_name +
469
- '" ' +
470
- 'data-path="' +
471
- normalizePath(source.path ? source.path + '/' : '/') +
472
- '" ' +
473
- 'data-name="' +
474
- name +
475
- '" ' +
476
- 'title="' +
477
- name +
478
- '" ' +
479
- 'data-url="' +
480
- imageURL +
481
- '">' +
482
- '<img ' +
483
- 'data-is-file="' +
484
- (item.isImage ? 0 : 1) +
485
- '" ' +
486
- 'data-src="' +
487
- imageURL +
488
- '" ' +
489
- 'src="' +
490
- (thumbIsAbsolute
491
- ? thumb
492
- :
493
- (normalizeURL(source.baseurl + source.path + thumb) +
494
- '?_tmst=' +
495
- timestamp)) +
496
- '" ' +
497
- 'alt="' +
498
- name +
499
- '"' +
500
- '/>' +
501
- (this.options.showFileName ||
502
- (this.options.showFileSize && item.size) ||
503
- (this.options.showFileChangeTime && item.changed)
504
- ? info
505
- : '') +
506
- '</a>'
507
- );
508
- },
509
-
510
- ajax: {
511
- url: '',
512
- async: true,
513
-
514
- data: {},
515
- cache: true,
516
- contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
517
-
518
- method: 'POST',
519
- processData: true,
520
- dataType: 'json',
521
-
522
- headers: {},
523
-
524
- prepareData(this: IUploader, data: any) {
525
- return data;
526
- },
527
-
528
- process(this: IUploader, resp: IFileBrowserAnswer): IFileBrowserAnswer {
529
- return resp;
530
- },
531
- },
532
- create: {
533
- data: { action: 'folderCreate' },
534
- },
535
- getLocalFileByUrl: {
536
- data: { action: 'getLocalFileByUrl' },
537
- },
538
- resize: {
539
- data: { action: 'imageResize' },
540
- },
541
- crop: {
542
- data: { action: 'imageCrop' },
543
- },
544
- move: {
545
- data: { action: 'fileMove' },
546
- },
547
- fileRemove: {
548
- data: { action: 'fileRemove' },
549
- },
550
- folderRemove: {
551
- data: { action: 'folderRemove' },
552
- },
553
- items: {
554
- data: { action: 'files' },
555
- },
556
- folder: {
557
- data: { action: 'folders' },
558
- },
559
- permissions: {
560
- data: { action: 'permissions' },
561
- },
562
-
563
- uploader: null, // use default Uploader's settings
564
- } as IFileBrowserOptions;
565
-
566
- Config.prototype.controls.filebrowser = {
567
- upload: {
568
- icon: 'plus',
569
- isInput: true,
570
- exec: () => {
571
- // do nothing
572
- },
573
- isDisable: (browser: IFileBrowser): boolean =>
574
- !browser.canI('FileUpload'),
575
- getContent: (
576
- filebrowser: IViewBased,
577
- control: IControlType
578
- ): HTMLElement => {
579
- const btn: HTMLElement = filebrowser.create.fromHTML(
580
- '<span class="jodit_upload_button">' +
581
- ToolbarIcon.getIcon('plus') +
582
- '<input type="file" accept="' +
583
- (filebrowser.buffer.fileBrowserOnlyImages
584
- ? 'image/*'
585
- : '*') +
586
- '" tabindex="-1" dir="auto" multiple=""/>' +
587
- '</span>'
588
- ),
589
- input: HTMLInputElement = btn.querySelector(
590
- 'input'
591
- ) as HTMLInputElement;
592
-
593
- filebrowser.events
594
- .on('updateToolbar', () => {
595
- if (control && control.isDisable) {
596
- control.isDisable(filebrowser, control)
597
- ? input.setAttribute('disabled', 'disabled')
598
- : input.removeAttribute('disabled');
599
- }
600
- })
601
- .fire('bindUploader.filebrowser', btn);
602
-
603
- return btn;
604
- },
605
- } as IControlType,
606
- remove: {
607
- icon: 'bin',
608
- isDisable: (browser: IFileBrowser): boolean => {
609
- return (
610
- browser.getActiveElements().length === 0 ||
611
- !browser.canI('FileRemove')
612
- );
613
- },
614
- exec: (editor: IViewBased) => {
615
- editor.events.fire('fileRemove.filebrowser');
616
- },
617
- } as IControlType,
618
- update: {
619
- exec: (editor: IViewBased) => {
620
- editor.events.fire('update.filebrowser');
621
- },
622
- } as IControlType,
623
- select: {
624
- icon: 'check',
625
- isDisable: (browser: IFileBrowser): boolean =>
626
- browser.getActiveElements().length === 0,
627
- exec: (editor: IViewBased) => {
628
- editor.events.fire('select.filebrowser');
629
- },
630
- } as IControlType,
631
- edit: {
632
- icon: 'pencil',
633
- isDisable: (browser: IFileBrowser): boolean => {
634
- const selected: HTMLElement[] = browser.getActiveElements();
635
- return (
636
- selected.length !== 1 ||
637
- selected[0].getAttribute('data-is-file') === '1' ||
638
- !(
639
- (browser as FileBrowser).canI('ImageCrop') ||
640
- (browser as FileBrowser).canI('ImageResize')
641
- )
642
- );
643
- },
644
- exec: editor => {
645
- editor.events.fire('edit.filebrowser');
646
- },
647
- } as IControlType,
648
- tiles: {
649
- icon: 'th',
650
- isActive: (filebrowser: IFileBrowser): boolean =>
651
- filebrowser.buffer.fileBrowserView === 'tiles',
652
- exec: (filebrowser: IFileBrowser) => {
653
- filebrowser.events.fire('view.filebrowser', 'tiles');
654
- },
655
- } as IControlType,
656
- list: {
657
- icon: 'th-list',
658
- isActive: (filebrowser: IFileBrowser): boolean =>
659
- filebrowser.buffer.fileBrowserView === 'list',
660
- exec: (filebrowser: IFileBrowser) => {
661
- filebrowser.events.fire('view.filebrowser', 'list');
662
- },
663
- } as IControlType,
664
- filter: {
665
- isInput: true,
666
- getContent: (filebrowser: IFileBrowser): HTMLElement => {
667
- const input: HTMLInputElement = filebrowser.create.element(
668
- 'input',
669
- {
670
- class: 'jodit_input',
671
- placeholder: filebrowser.i18n('Filter'),
672
- }
673
- );
674
-
675
- filebrowser.events.on(
676
- input,
677
- 'keydown mousedown',
678
- debounce(() => {
679
- filebrowser.events.fire('filter.filebrowser', input.value);
680
- }, filebrowser.defaultTimeout)
681
- );
682
-
683
- return input;
684
- },
685
- } as IControlType,
686
- sort: {
687
- isInput: true,
688
- getContent: (filebrowser: IFileBrowser): HTMLElement => {
689
- const select: HTMLSelectElement = filebrowser.create.fromHTML(
690
- '<select class="jodit_input">' +
691
- '<option value="changed">' +
692
- filebrowser.i18n('Sort by changed') +
693
- '</option>' +
694
- '<option value="name">' +
695
- filebrowser.i18n('Sort by name') +
696
- '</option>' +
697
- '<option value="size">' +
698
- filebrowser.i18n('Sort by size') +
699
- '</option>' +
700
- '</select>'
701
- ) as HTMLSelectElement;
702
-
703
- filebrowser.events
704
- .on('sort.filebrowser', (value: string) => {
705
- if (select.value !== value) {
706
- select.value = value;
707
- }
708
- })
709
- .on(select, 'change', () => {
710
- filebrowser.events.fire('sort.filebrowser', select.value);
711
- });
712
-
713
- return select;
714
- },
715
- } as IControlType,
716
- } as IDictionary<IControlType>;
717
45
 
718
46
  export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
719
47
  /**
@@ -1222,17 +550,20 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1222
550
  * @param {string} path Relative toWYSIWYG the directory where you want toWYSIWYG move the file / folder
1223
551
  * @param {string} source Source
1224
552
  */
1225
- move = (filepath: string, path: string, source: string): Promise<void> => {
1226
- if (!this.options.move) {
553
+ move = (filepath: string, path: string, source: string, isFile: boolean): Promise<void> => {
554
+ const mode: 'fileMove' | 'folderMove' = isFile ? 'fileMove' : 'folderMove';
555
+
556
+ const option = this.options[mode];
557
+ if (!option) {
1227
558
  return Promise.reject('Set Move api options');
1228
559
  }
1229
560
 
1230
- this.options.move.data.from = filepath;
1231
- this.options.move.data.path = path;
1232
- this.options.move.data.source = source;
561
+ option.data.from = filepath;
562
+ option.data.path = path;
563
+ option.data.source = source;
1233
564
 
1234
565
  return this.send(
1235
- 'move',
566
+ isFile ? 'fileMove' : 'folderMove',
1236
567
  resp => {
1237
568
  if (this.options.isSuccess(resp)) {
1238
569
  this.loadTree(path, source);
@@ -1648,7 +979,9 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1648
979
  this.tree,
1649
980
  'dragstart',
1650
981
  function(this: HTMLAnchorElement) {
1651
- self.dragger = this;
982
+ if (self.options.moveFolder) {
983
+ self.dragger = this;
984
+ }
1652
985
  },
1653
986
  'a'
1654
987
  )
@@ -1656,7 +989,9 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1656
989
  this.tree,
1657
990
  'drop',
1658
991
  function(this: HTMLAnchorElement): boolean | void {
1659
- if (self.options.moveFolder && self.dragger) {
992
+ if (
993
+ (self.options.moveFile || self.options.moveFolder) && self.dragger
994
+ ) {
1660
995
  let path: string =
1661
996
  self.dragger.getAttribute('data-path') || '';
1662
997
 
@@ -1681,8 +1016,11 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1681
1016
  self.move(
1682
1017
  path,
1683
1018
  this.getAttribute('data-path') || '',
1684
- this.getAttribute('data-source') || ''
1019
+ this.getAttribute('data-source') || '',
1020
+ self.dragger.classList.contains(ITEM_CLASS)
1685
1021
  );
1022
+
1023
+ self.dragger = false;
1686
1024
  }
1687
1025
  },
1688
1026
  'a'
@@ -1936,6 +1274,13 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1936
1274
  },
1937
1275
  'a'
1938
1276
  )
1277
+ .on(
1278
+ self.files, 'dragstart', function () {
1279
+ if (self.options.moveFile) {
1280
+ self.dragger = this;
1281
+ }
1282
+ },
1283
+ 'a')
1939
1284
  .on(self.dialog.container, 'drop', (e: DragEvent) =>
1940
1285
  e.preventDefault()
1941
1286
  );
@@ -1947,7 +1292,8 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
1947
1292
  'crop',
1948
1293
  'resize',
1949
1294
  'create',
1950
- 'move',
1295
+ 'fileMove',
1296
+ 'folderMove',
1951
1297
  'fileRemove',
1952
1298
  'folderRemove',
1953
1299
  'folder',