/**
* @module modules/file-browser
*/
import { Config } from 'jodit/config';
import type {
IFileBrowser,
IFileBrowserAnswer,
IFileBrowserItem,
IFileBrowserOptions,
ISource,
ISourceFile,
IControlType,
IDictionary,
IUploader,
IViewBased
} from 'jodit/types';
import { isArray, isString } from 'jodit/core/helpers/checker';
import { UIFileInput } from 'jodit/core/ui/form/inputs/file/file';
import { humanSizeToBytes } from 'jodit/core/helpers/utils/human-size-to-bytes';
declare module 'jodit/config' {
interface Config {
filebrowser: IFileBrowserOptions;
}
}
Config.prototype.filebrowser = {
namespace: '',
extraButtons: [],
filter(item: string | ISourceFile, search: string) {
search = search.toLowerCase();
if (isString(item)) {
return item.toLowerCase().indexOf(search) !== -1;
}
if (isString(item.name)) {
return item.name.toLowerCase().indexOf(search) !== -1;
}
if (isString(item.file)) {
return item.file.toLowerCase().indexOf(search) !== -1;
}
return true;
},
sortBy: 'changed-desc',
sort(this: IFileBrowser, a: any, b: any, sortBy: string): number {
const [sortAttr, arrow] = sortBy.toLowerCase().split('-'),
asc = arrow === 'asc';
const compareStr = (f: string, s: string): number => {
if (f < s) {
return asc ? -1 : 1;
}
if (f > s) {
return asc ? 1 : -1;
}
return 0;
};
if (isString(a)) {
return compareStr(a.toLowerCase(), b.toLowerCase());
}
if (a[sortAttr] === undefined || sortAttr === 'name') {
if (isString(a.name)) {
return compareStr(a.name.toLowerCase(), b.name.toLowerCase());
}
if (isString(a.file)) {
return compareStr(a.file.toLowerCase(), b.file.toLowerCase());
}
return 0;
}
switch (sortAttr) {
case 'changed': {
const f = new Date(a.changed).getTime(),
s = new Date(b.changed).getTime();
return asc ? f - s : s - f;
}
case 'size': {
const f = humanSizeToBytes(a.size),
s = humanSizeToBytes(b.size);
return asc ? f - s : s - f;
}
}
return 0;
},
editImage: true,
preview: true,
showPreviewNavigation: true,
showSelectButtonInPreview: true,
contextMenu: true,
howLongShowMsg: 3000,
createNewFolder: true,
deleteFolder: true,
renameFolder: true,
moveFolder: true,
moveFile: true,
showFoldersPanel: true,
storeLastOpenedFolder: true,
width: 859,
height: 400,
buttons: [
'filebrowser.upload',
'filebrowser.remove',
'filebrowser.update',
'filebrowser.select',
'filebrowser.edit',
'|',
'filebrowser.tiles',
'filebrowser.list',
'|',
'filebrowser.filter',
'|',
'filebrowser.sort'
],
removeButtons: [],
fullsize: false,
showTooltip: true,
view: null,
isSuccess(this: IFileBrowser, resp: IFileBrowserAnswer): boolean {
return resp.success;
},
getMessage(this: IFileBrowser, resp: IFileBrowserAnswer) {
return resp.data.messages !== undefined && isArray(resp.data.messages)
? resp.data.messages.join(' ')
: '';
},
showFileName: true,
showFileSize: true,
showFileChangeTime: true,
saveStateInStorage: {
storeLastOpenedFolder: true,
storeView: true,
storeSortBy: true
},
pixelOffsetLoadNewChunk: 200,
getThumbTemplate(
this: IFileBrowser,
item: IFileBrowserItem,
source: ISource,
source_name: string
): string {
const opt = this.options,
IC = this.files.getFullElName('item'),
showName = opt.showFileName,
showSize = opt.showFileSize && item.size,
showTime = opt.showFileChangeTime && item.time;
let name: string = '';
if (item.file !== undefined) {
name = item.file;
}
const info = `
${
showName ? `${name}` : ''
}${
showSize
? `${item.size}`
: ''
}${
showTime
? `${showTime}`
: ''
}
`;
return `
${showName || showSize || showTime ? info : ''}
`;
},
ajax: {
...Config.prototype.defaultAjaxOptions,
url: '',
async: true,
data: {},
cache: true,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
method: 'POST',
processData: true,
dataType: 'json',
headers: {},
prepareData(this: IUploader, data: any) {
return data;
},
process(this: IUploader, resp: IFileBrowserAnswer): IFileBrowserAnswer {
return resp;
}
},
create: {
data: { action: 'folderCreate' }
},
getLocalFileByUrl: {
data: { action: 'getLocalFileByUrl' }
},
resize: {
data: { action: 'imageResize' }
},
crop: {
data: { action: 'imageCrop' }
},
fileMove: {
data: { action: 'fileMove' }
},
folderMove: {
data: { action: 'folderMove' }
},
fileRename: {
data: { action: 'fileRename' }
},
folderRename: {
data: { action: 'folderRename' }
},
fileRemove: {
data: { action: 'fileRemove' }
},
folderRemove: {
data: { action: 'folderRemove' }
},
items: {
data: { action: 'files' }
},
folder: {
data: { action: 'folders' }
},
permissions: {
data: { action: 'permissions' }
}
} as IFileBrowserOptions;
Config.prototype.controls.filebrowser = {
upload: {
icon: 'plus',
isInput: true,
isDisabled: (browser: IFileBrowser): boolean =>
!browser.dataProvider.canI('FileUpload'),
getContent: (filebrowser: IFileBrowser): HTMLElement => {
const btn = new UIFileInput(filebrowser, {
onlyImages: filebrowser.state.onlyImages
});
filebrowser.e.fire('bindUploader.filebrowser', btn.container);
return btn.container;
}
} as IControlType,
remove: {
icon: 'bin',
isDisabled: (browser: IFileBrowser): boolean => {
return (
!browser.state.activeElements.length ||
!browser.dataProvider.canI('FileRemove')
);
},
exec: (editor: IFileBrowser) => {
editor.e.fire('fileRemove.filebrowser');
}
} as IControlType,
update: {
exec: (editor: IFileBrowser) => {
editor.e.fire('update.filebrowser');
}
} as IControlType,
select: {
icon: 'check',
isDisabled: (browser: IFileBrowser): boolean =>
!browser.state.activeElements.length,
exec: (editor: IViewBased) => {
editor.e.fire('select.filebrowser');
}
} as IControlType,
edit: {
icon: 'pencil',
isDisabled: (browser: IFileBrowser): boolean => {
const selected = browser.state.activeElements;
return (
selected.length !== 1 ||
!selected[0].isImage ||
!(
(browser as IFileBrowser).dataProvider.canI('ImageCrop') ||
(browser as IFileBrowser).dataProvider.canI('ImageResize')
)
);
},
exec: editor => {
editor.e.fire('edit.filebrowser');
}
} as IControlType,
tiles: {
icon: 'th',
isActive: (filebrowser: IFileBrowser): boolean =>
filebrowser.state.view === 'tiles',
exec: (filebrowser: IFileBrowser) => {
filebrowser.e.fire('view.filebrowser', 'tiles');
}
} as IControlType,
list: {
icon: 'th-list',
isActive: (filebrowser: IFileBrowser): boolean =>
filebrowser.state.view === 'list',
exec: (filebrowser: IFileBrowser) => {
filebrowser.e.fire('view.filebrowser', 'list');
}
} as IControlType,
filter: {
isInput: true,
getContent: (filebrowser: IFileBrowser, _, b): HTMLElement => {
const oldInput = b.container.querySelector('.jodit-input');
if (oldInput) {
return oldInput as HTMLElement;
}
const input = filebrowser.c.element('input', {
class: 'jodit-input',
placeholder: filebrowser.i18n('Filter')
});
input.value = filebrowser.state.filterWord;
filebrowser.e.on(
input,
'keydown mousedown',
filebrowser.async.debounce(() => {
filebrowser.e.fire('filter.filebrowser', input.value);
}, filebrowser.defaultTimeout)
);
return input;
}
} as IControlType,
sort: {
isInput: true,
getContent: (fb: IFileBrowser): HTMLElement => {
const select: HTMLSelectElement = fb.c.fromHTML(
''
) as HTMLSelectElement;
select.value = fb.state.sortBy;
fb.e
.on('sort.filebrowser', (value: string) => {
if (select.value !== value) {
select.value = value;
}
})
.on(select, 'change', () => {
fb.e.fire('sort.filebrowser', select.value);
});
return select;
}
} as IControlType
} as IDictionary;