192 lines
6.9 KiB
JavaScript
192 lines
6.9 KiB
JavaScript
/*!
|
|
* Jodit Editor (https://xdsoft.net/jodit/)
|
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
*/
|
|
import { STATUSES, ViewComponent } from "../../core/component/index.js";
|
|
import { IS_ES_NEXT, IS_IE } from "../../core/constants.js";
|
|
import { ConfigProto, error, isFunction, isJoditObject } from "../../core/helpers/index.js";
|
|
import { Config } from "../../config.js";
|
|
import { ajaxInstances, hasFiles, hasItems, processOldBrowserDrag, send, sendFiles } from "./helpers/index.js";
|
|
import "./config.js";
|
|
export class Uploader extends ViewComponent {
|
|
get j() {
|
|
return this.jodit;
|
|
}
|
|
/** @override */
|
|
className() {
|
|
return 'Uploader';
|
|
}
|
|
get o() {
|
|
return this.options;
|
|
}
|
|
/**
|
|
* It sets the path for uploading files
|
|
*/
|
|
setPath(path) {
|
|
this.path = path;
|
|
return this;
|
|
}
|
|
/**
|
|
* It sets the source for connector
|
|
*/
|
|
setSource(source) {
|
|
this.source = source;
|
|
return this;
|
|
}
|
|
/**
|
|
* Set the handlers Drag and Drop to `$form`
|
|
*
|
|
* @param form - Form or any Node on which you can drag and drop the file. In addition will be processed
|
|
* <code><input type="file" ></code>
|
|
* @param handlerSuccess - The function be called when a successful uploading files
|
|
* to the server
|
|
* @param handlerError - The function that will be called during a failed download files a server
|
|
* @example
|
|
* ```javascript
|
|
* var $form = jQuery('<form><input type="text" typpe="file"></form>');
|
|
* jQuery('body').append($form);
|
|
* Jodit.editors.someidfoeditor.uploader.bind($form[0], function (files) {
|
|
* var i;
|
|
* for (i = 0; i < data.files.length; i += 1) {
|
|
* parent.s.insertImage(data.files[i])
|
|
* }
|
|
* });
|
|
* ```
|
|
*/
|
|
bind(form, handlerSuccess, handlerError) {
|
|
const onFinally = () => {
|
|
form.classList.remove('jodit_drag_hover');
|
|
};
|
|
const self = this, onPaste = (e) => {
|
|
let i, file, extension;
|
|
const cData = e.clipboardData;
|
|
const processData = (formdata) => {
|
|
if (file) {
|
|
formdata.append('extension', extension);
|
|
formdata.append('mimetype', file.type);
|
|
}
|
|
};
|
|
// send data on server
|
|
if (!IS_IE && hasFiles(cData)) {
|
|
sendFiles(self, cData.files, handlerSuccess, handlerError).finally(onFinally);
|
|
return false;
|
|
}
|
|
if (IS_IE && !IS_ES_NEXT) {
|
|
return processOldBrowserDrag(self, cData, handlerSuccess, handlerError, onFinally);
|
|
}
|
|
if (hasItems(cData)) {
|
|
const { items } = cData;
|
|
for (i = 0; i < items.length; i += 1) {
|
|
if (items[i].kind === 'file' &&
|
|
items[i].type === 'image/png') {
|
|
file = items[i].getAsFile();
|
|
if (file) {
|
|
const mime = file.type.match(/\/([a-z0-9]+)/i);
|
|
extension = mime[1]
|
|
? mime[1].toLowerCase()
|
|
: '';
|
|
sendFiles(self, [file], handlerSuccess, handlerError, processData).finally(onFinally);
|
|
}
|
|
e.preventDefault();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
if (self.j && self.j.editor !== form) {
|
|
self.j.e.on(form, 'paste', onPaste);
|
|
}
|
|
else {
|
|
self.j.e.on('beforePaste', onPaste);
|
|
}
|
|
this.attachEvents(form, handlerSuccess, handlerError, onFinally);
|
|
}
|
|
attachEvents(form, handlerSuccess, handlerError, onFinally) {
|
|
const self = this;
|
|
self.j.e
|
|
.on(form, 'dragend dragover dragenter dragleave drop', (e) => {
|
|
e.preventDefault();
|
|
})
|
|
.on(form, 'dragover', (event) => {
|
|
if (hasFiles(event.dataTransfer) ||
|
|
hasItems(event.dataTransfer)) {
|
|
form.classList.add('jodit_drag_hover');
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
.on(form, 'dragend dragleave', (event) => {
|
|
form.classList.remove('jodit_drag_hover');
|
|
if (hasFiles(event.dataTransfer)) {
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
.on(form, 'drop', (event) => {
|
|
form.classList.remove('jodit_drag_hover');
|
|
if (hasFiles(event.dataTransfer)) {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
sendFiles(self, event.dataTransfer.files, handlerSuccess, handlerError).finally(onFinally);
|
|
}
|
|
});
|
|
const inputFile = form.querySelector('input[type=file]');
|
|
if (inputFile) {
|
|
self.j.e.on(inputFile, 'change', () => {
|
|
sendFiles(self, inputFile.files, handlerSuccess, handlerError)
|
|
.then(() => {
|
|
inputFile.value = '';
|
|
if (!/safari/i.test(navigator.userAgent)) {
|
|
inputFile.type = '';
|
|
inputFile.type = 'file';
|
|
}
|
|
})
|
|
.finally(onFinally);
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Upload images to a server by its URL, making it through the connector server.
|
|
*/
|
|
uploadRemoteImage(url, handlerSuccess, handlerError) {
|
|
const uploader = this, { o } = uploader;
|
|
const handlerE = isFunction(handlerError)
|
|
? handlerError
|
|
: o.defaultHandlerError;
|
|
send(uploader, {
|
|
action: 'fileUploadRemote',
|
|
url
|
|
})
|
|
.then(resp => {
|
|
if (o.isSuccess.call(uploader, resp)) {
|
|
const handler = isFunction(handlerSuccess)
|
|
? handlerSuccess
|
|
: o.defaultHandlerSuccess;
|
|
handler.call(uploader, o.process.call(uploader, resp));
|
|
return;
|
|
}
|
|
handlerE.call(uploader, error(o.getMessage.call(uploader, resp)));
|
|
})
|
|
.catch(e => handlerE.call(uploader, e));
|
|
}
|
|
constructor(editor, options) {
|
|
super(editor);
|
|
this.path = '';
|
|
this.source = 'default';
|
|
this.options = ConfigProto(options || {}, ConfigProto(Config.defaultOptions.uploader, isJoditObject(editor) ? editor.o.uploader : {}));
|
|
}
|
|
destruct() {
|
|
this.setStatus(STATUSES.beforeDestruct);
|
|
const instances = ajaxInstances.get(this);
|
|
if (instances) {
|
|
instances.forEach(ajax => {
|
|
try {
|
|
ajax.destruct();
|
|
}
|
|
catch (_a) { }
|
|
});
|
|
instances.clear();
|
|
}
|
|
super.destruct();
|
|
}
|
|
}
|