CKEDITOR.plugins.add('studip-upload', {
icons: 'upload',
hidpi: true,
lang: 'de,en',
init: function(editor){
var lang = editor.lang['studip-upload'];
// utilities
var isString = function(object) {
return (typeof object) === 'string';
},
isImage = function(mime_type){
return isString(mime_type) && mime_type.match('^image');
},
isSVG = function(mime_type){
return isString(mime_type) && mime_type === 'image/svg+xml';
},
insertNode = function($node){
editor.insertHtml($('
').append($node).html() + ' ');
},
insertImage = function(file){
insertNode($('
![]()
').attr({
src: file.url,
alt: file.name,
title: file.name
}));
},
insertLink = function(file){
insertNode($('
').attr({
href: file.url,
type: file.type,
target: '_blank',
rel: 'nofollow'
}).append(file.name));
},
insertFile = function(file){
// NOTE StudIP sends SVGs as application/octet-stream
if (isImage(file.type) && !isSVG(file.type)) {
insertImage(file);
} else {
insertLink(file);
}
},
//Ajax-call for img-upload via copy paste
uploadFromBase64 = function(studipUpload_url, formDataToUpload, node) {
$.ajax({
url: studipUpload_url,
data: formDataToUpload,
type:"POST",
contentType:false,
async: false,
processData:false,
cache:false,
dataType:"json",
error:function(err){
console.error(err);
},
success: function(data) {
if (data.files.length > 0) {
jQuery(node).attr('alt', data.files[0].name);
jQuery(node).attr('src', data.files[0].url);
}
}
});
},
convertSrcDataToBlob = function (src_data) {
//Split the data by the first comma, then check if the
//string base64 is in the first part. If so, get the mime type
//and decode the base64 data of the second part.
var data_parts = src_data.split(',', 2);
if (data_parts[0].indexOf('base64') === -1) {
//We cannot continue.
return false;
}
var mime_type = data_parts[0].match(/data\:([^;]*)\;/)[1];
if (!mime_type) {
//We cannot continue.
return false;
}
if ((mime_type != 'image/png') && (mime_type != 'image/jpeg')) {
//We do not serve such mime types here!
return false;
}
var blob = atob(data_parts[1]);
if (!blob) {
//There are no data in blob.
return false;
}
var uint8_blob = new Uint8Array(blob.length);
if (!uint8_blob) {
//No uint8 data can be created from the blob.
return false;
}
for (var i = 0; i < blob.length; i++) {
uint8_blob[i] = blob.charCodeAt(i);
}
//Now the binary data is in the correct format.
return new Blob([uint8_blob], {type: mime_type});
},
extractAndConvertSrcAttribute = function (node) {
var src_attr = jQuery(node).attr('src');
if (src_attr) {
var blob = convertSrcDataToBlob(src_attr);
if (blob === false) {
//Leave the element as it is.
return;
} else {
var form_data_to_upload = new FormData();
form_data_to_upload.append("files[]", blob);
uploadFromBase64(editor.config.studipUpload_url, form_data_to_upload, node);
}
}
},
handleUploads = function(fileList){
var errors = [];
$.each(fileList, function(index, file){
if (file.url) {
insertFile(file);
} else {
errors.push(file.name + ': ' + file.error);
}
});
if (errors.length) {
alert(lang.uploadError + '\n\n' + errors.join('\n'));
}
};
editor.on('instanceReady', function(event){
var $container = $(event.editor.container.$);
// install upload handler
$('')
.attr({
class: 'fileupload',
type: 'file',
name: 'files[]',
multiple: true
})
.css('display', 'none')
.appendTo($container)
.fileupload({
dropZone: $container,
url: editor.config.studipUpload_url,
singleFileUploads: false,
dataType: 'json',
done: function(e, data){
if (data.result.files) {
handleUploads(data.result.files);
} else {
alert(lang.uploadFailed + '\n\n' + data.result);
}
},
fail: function (e, data) {
alert(
lang.uploadFailed + '\n\n'
+ lang.error + ' '
+ data.errorThrown.message
);
}
});
});
// avoid multiple uploads of the same file via drag and drop
editor.on('beforeDestroy', function(event){
$(event.editor.container.$).find('.fileupload').fileupload('destroy');
});
// ckeditor
editor.addCommand('upload', { // command handler
exec: function(editor){
$(editor.container.$).find('.fileupload').click();
}
});
editor.ui.addButton('upload', { // toolbar button
label: lang.buttonLabel,
command: 'upload',
toolbar: 'insert,80'
});
//Handle the CKEditor paste event to be able to treat the image
//uploading different than uploading "usual" HTML.
editor.on('paste', function(event) {
//There are two cases, because different browsers behave different
//when copying data from the clipboard.
if (event.data.dataValue) {
var nodes = null;
try {
nodes = jQuery(event.data.dataValue);
} catch (error) {
//If jQuery cannot build a node from the data that is
//supposed to be HTML, do nothing.
return;
}
if (nodes.length < 1) {
//jQuery could not build a node out of the HTML snippet.
//Do nothing either.
return;
}
jQuery(nodes).each(function(index) {
if (this.tagName == 'IMG') {
extractAndConvertSrcAttribute(this);
} else {
//Traverse the child nodes and look for img nodes.
jQuery(this).find('img').each(function (index) {
extractAndConvertSrcAttribute(this);
});
}
});
event.data.dataValue = jQuery('').append(nodes).html();
} else {
if (event.data.dataTransfer._.files.length > 0) {
for (i = 0; i < event.data.dataTransfer._.files.length; i++) {
var reader = new FileReader();
reader.readAsDataURL(event.data.dataTransfer._.files[i]);
reader.onload = function () {
var input = reader.result;
var blob = convertSrcDataToBlob(input);
if (blob === false) {
//TODO: Prevent the pasted element from appearing.
} else {
var formDataToUpload = new FormData();
formDataToUpload.append("files[]", blob);
var node = jQuery('
');
uploadFromBase64(editor.config.studipUpload_url, formDataToUpload, node);
event.editor.insertHtml(
jQuery('').append(node).html()
);
}
}
}
}
}
});
}
});