public/src/modules/uploadHelpers.js
'use strict';
define('uploadHelpers', ['alerts'], function (alerts) {
const uploadHelpers = {};
uploadHelpers.init = function (options) {
const formEl = options.uploadFormEl;
if (!formEl.length) {
return;
}
formEl.attr('action', config.relative_path + options.route);
if (options.dragDropAreaEl) {
uploadHelpers.handleDragDrop({
container: options.dragDropAreaEl,
callback: function (upload) {
uploadHelpers.ajaxSubmit({
uploadForm: formEl,
upload: upload,
callback: options.callback,
});
},
});
}
if (options.pasteEl) {
uploadHelpers.handlePaste({
container: options.pasteEl,
callback: function (upload) {
uploadHelpers.ajaxSubmit({
uploadForm: formEl,
upload: upload,
callback: options.callback,
});
},
});
}
if (options.uploadBtnEl) {
const fileInput = formEl.find('input[name="files[]"]');
options.uploadBtnEl.on('click', function () {
fileInput.trigger('click');
});
fileInput.on('change', function (e) {
const files = (e.target || {}).files ||
($(this).val() ? [{ name: $(this).val(), type: utils.fileMimeType($(this).val()) }] : null);
if (files) {
uploadHelpers.ajaxSubmit({
uploadForm: formEl,
upload: {
files: files,
fileNames: Array.from(files).map(f => f.name),
},
callback: options.callback,
});
}
});
}
};
uploadHelpers.handleDragDrop = function (options) {
let draggingDocument = false;
const postContainer = options.container;
const drop = options.container.find('.imagedrop');
postContainer.on('dragenter', function onDragEnter() {
if (draggingDocument) {
return;
}
drop.css('top', '0px');
drop.css('height', postContainer.height() + 'px');
drop.css('line-height', postContainer.height() + 'px');
drop.show();
drop.on('dragleave', function () {
drop.hide();
drop.off('dragleave');
});
});
drop.on('drop', function onDragDrop(e) {
e.preventDefault();
const files = e.originalEvent.dataTransfer.files;
if (files.length) {
let formData;
if (window.FormData) {
formData = new FormData();
for (var i = 0; i < files.length; ++i) {
formData.append('files[]', files[i], files[i].name);
}
}
options.callback({
files: files,
formData: formData,
});
}
drop.hide();
return false;
});
function cancel(e) {
e.preventDefault();
return false;
}
$(document)
.off('dragstart')
.on('dragstart', function () {
draggingDocument = true;
})
.off('dragend')
.on('dragend, mouseup', function () {
draggingDocument = false;
});
drop.on('dragover', cancel);
drop.on('dragenter', cancel);
};
uploadHelpers.handlePaste = function (options) {
const container = options.container;
container.on('paste', function (event) {
const items = (event.clipboardData || event.originalEvent.clipboardData || {}).items;
const files = [];
const fileNames = [];
let formData = null;
if (window.FormData) {
formData = new FormData();
}
[].forEach.call(items, function (item) {
const file = item.getAsFile();
if (file) {
const fileName = utils.generateUUID() + '-' + file.name;
if (formData) {
formData.append('files[]', file, fileName);
}
files.push(file);
fileNames.push(fileName);
}
});
if (files.length) {
options.callback({
files: files,
fileNames: fileNames,
formData: formData,
});
}
});
};
uploadHelpers.ajaxSubmit = function (options) {
const files = [...options.upload.files];
for (let i = 0; i < files.length; ++i) {
const isImage = files[i].type.match(/image./);
if ((isImage && !app.user.privileges['upload:post:image']) || (!isImage && !app.user.privileges['upload:post:file'])) {
return alerts.error('[[error:no-privileges]]');
}
if (!app.user.isAdmin && files[i].size > parseInt(config.maximumFileSize, 10) * 1024) {
options.uploadForm[0].reset();
return alerts.error('[[error:file-too-big, ' + config.maximumFileSize + ']]');
}
}
const alert_id = Date.now();
options.uploadForm.off('submit').on('submit', function () {
$(this).ajaxSubmit({
headers: {
'x-csrf-token': config.csrf_token,
},
resetForm: true,
clearForm: true,
formData: options.upload.formData,
error: function (xhr) {
let errorMsg = (xhr.responseJSON &&
(xhr.responseJSON.error || (xhr.responseJSON.status && xhr.responseJSON.status.message))) ||
'[[error:parse-error]]';
if (xhr && xhr.status === 413) {
errorMsg = xhr.statusText || 'Request Entity Too Large';
}
alerts.error(errorMsg);
alerts.remove(alert_id);
},
uploadProgress: function (event, position, total, percent) {
alerts.alert({
alert_id: alert_id,
message: '[[modules:composer.uploading, ' + percent + '%]]',
});
},
success: function (res) {
const uploads = res.response.images;
if (uploads && uploads.length) {
for (var i = 0; i < uploads.length; ++i) {
uploads[i].filename = files[i].name;
uploads[i].isImage = /image./.test(files[i].type);
}
}
options.callback(uploads);
},
complete: function () {
options.uploadForm[0].reset();
setTimeout(alerts.remove, 100, alert_id);
},
});
return false;
});
options.uploadForm.submit();
};
return uploadHelpers;
});