/**
* ---------------------------------------------------------------------
* GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2015-2020 Teclib' and contributors.
*
* http://glpi-project.org
*
* based on GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* GLPI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLPI. If not, see .
* ---------------------------------------------------------------------
*/
/* global fileType, getExtIcon, getSize, isImage, stopEvent, Uint8Array */
function uploadFile(file, editor, input_name) {
var returnTag = false;
//Create formdata from file to send with ajax request
var formdata = new FormData();
formdata.append('filename[0]', file, file.name);
formdata.append('name', 'filename');
// upload file with ajax
$.ajax({
type: 'POST',
url: CFG_GLPI.root_doc+'/ajax/fileupload.php',
data: formdata,
processData: false,
contentType: false,
dataType: 'JSON',
async: false,
success: function(data) {
$.each(data, function(index, element) {
if (element[0].error === undefined) {
returnTag = '';
var tag = getFileTag(element);
//if is an image add tag
if (isImage(file)) {
returnTag = tag.tag;
}
//display uploaded file
displayUploadedFile(element[0], tag, editor, input_name);
} else {
returnTag = false;
alert(element[0].error);
}
});
},
error: function (request) {
// If this is an error on the return
if ("responseText" in request && request.responseText.length > 0) {
alert(request.responseText);
} else {
// Error before sending request #3866
alert(request.statusText);
}
}
});
return returnTag;
}
/**
* Gets the file tag.
*
* @param {(boolean|string)} data receive from uploadFile
* @return {(boolean|string)} The file tag.
*/
var getFileTag = function(data) {
var returnString = '';
$.ajax({
type: 'POST',
url: CFG_GLPI.root_doc+'/ajax/getFileTag.php',
data: {'data':data},
dataType: 'JSON',
async: false,
success: function(data) {
returnString = data[0];
},
error: function (request) {
console.warn(request.responseText);
returnString=false;
}
});
return returnString;
};
/**
* Display list of uploaded file with their size
*
* @param {JSON} file The file
* @param {String} tag The tag
* @param {Object} editor The TinyMCE editor instance
* @param {String} input_name Name of generated input hidden (default filename)
*/
var fileindex = 0;
var displayUploadedFile = function(file, tag, editor, input_name) {
// default argument(s)
input_name = (typeof input_name === 'undefined' || input_name == null) ? 'filename' : input_name;
// find the nearest fileupload_info where to append file list
var current_dom_point = $(editor.targetElm);
var iteration = 0;
var filecontainer;
do {
current_dom_point = current_dom_point.parent();
filecontainer = current_dom_point.find('.fileupload_info');
iteration++;
} while (filecontainer.length <= 0 && iteration < 30);
if (filecontainer.length) {
var ext = file.name.split('.').pop();
var p = $('
')
.attr('id',file.id)
.html(
getExtIcon(ext)
+ ' '
+ ''+file.display
+ ''
+ ' ('
+ getSize(file.size)+') '
).appendTo(filecontainer);
// File
$('')
.attr('type', 'hidden')
.attr('name', '_'+input_name+'['+fileindex+']')
.attr('value', file.name).appendTo(p);
// Prefix
$('')
.attr('type', 'hidden')
.attr('name', '_prefix_'+input_name+'['+fileindex+']')
.attr('value', file.prefix).appendTo(p);
// Tag
$('')
.attr('type', 'hidden')
.attr('name', '_tag_'+input_name+'['+fileindex+']')
.attr('value', tag.name)
.appendTo(p);
// Delete button
var elementsIdToRemove = {0:file.id, 1:file.id+'2'};
$('').click(function() {
deleteImagePasted(elementsIdToRemove, tag.tag, editor);
}).appendTo(p);
fileindex++;
}
};
/**
* Remove image pasted or droped
*
* @param {Array} elementsIdToRemove The elements identifier to remove
* @param {string} tagToRemove The tag to remove
* @param {Object} editor The editor
*/
var deleteImagePasted = function(elementsIdToRemove, tagToRemove, editor) {
// Remove file display lines
$.each(elementsIdToRemove, function (index, element) {
$('#'+element).remove();
});
if (typeof editor !== "undefined"
&& typeof editor.dom !== "undefined") {
editor.setContent(editor.getContent().replace('
'+tagToRemove+'
', ''));
var regex = new RegExp('#', 'g');
editor.dom.remove(tagToRemove.replace(regex, ''));
}
};
/**
* Insert an (uploaded) image in the the tinymce 'editor'
*
* @param {Object} TinyMCE editor instance
* @param {Blob} fileImg
* @param {string} tag
*/
var insertImgFromFile = function(editor, fileImg, tag) {
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(fileImg);
var regex = new RegExp('#', 'g');
var maxHeight = $(tinyMCE.activeEditor.getContainer()).height() - 60;
var maxWidth = $(tinyMCE.activeEditor.getContainer()).width() - 120;
if (window.FileReader && window.File && window.FileList && window.Blob ) {
// indicate loading in tinymce
editor.setProgressState(true);
var reader = new FileReader();
reader.onload = (function(theFile) {
var image = new Image();
image.src = theFile.target.result;
image.onload = function() {
// access image size here
var imgWidth = this.width;
var imgHeight = this.height;
var ratio = 0;
if (imgWidth > maxWidth) {
ratio = maxWidth / imgWidth; // get ratio for scaling image
imgHeight = imgHeight * ratio; // Reset height to match scaled image
imgWidth = imgWidth * ratio; // Reset width to match scaled image
}
// Check if current height is larger than max
if (imgHeight > maxHeight) {
ratio = maxHeight / imgHeight; // get ratio for scaling image
imgWidth = imgWidth * ratio; // Reset width to match scaled image
imgHeight = imgHeight * ratio; // Reset height to match scaled image
}
editor.execCommand(
'mceInsertContent',
false,
""
);
// loading done, remove indicator
editor.setProgressState(false);
};
});
reader.readAsDataURL(fileImg);
} else {
console.warn('thanks to update your browser to get preview of image');
}
};
/**
* Convert dataURI to BLOB
*
* @param {Object} dataURI The data uri
* @return {Blob} { description_of_the_return_value }
*/
var dataURItoBlob = function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
} else {
byteString = unescape(dataURI.split(',')[1]);
}
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var imgExt = mimeString.split('/')[1];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var file = new Blob([ia], {type:mimeString});
file.name = 'image_paste' + Math.floor((Math.random() * 10000000) + 1) + '.' + imgExt;
return file;
};
/**
* Function to check if data paste on TinyMCE is an image
*
* @param String content The img tag
* @return String mimeType return mimeType of data
*/
var isImageFromPaste = function(content) {
return content.match(new RegExp('').append(content).find('img');
if (foundImage.length > 0) {
return foundImage.attr('src');
}
return '';
};
/**
* Insert an image file into the specified tinyMce editor
* @param {Object} editor The tinyMCE editor
* @param {Blob} image The image to insert
*/
var insertImageInTinyMCE = function(editor, image) {
//make ajax call for upload doc
var input_name = $(editor.targetElm).attr('name');
var tag = uploadFile(image, editor, input_name);
if (tag !== false) {
insertImgFromFile(editor, image, tag);
}
return tag;
};
/**
* Plugin for tinyMce editor who intercept paste event
* to check if a file upload can be proceeded
* @param {[Object]} editor TinyMCE editor
*/
if (typeof tinyMCE != 'undefined') {
tinyMCE.PluginManager.add('glpi_upload_doc', function(editor) {
editor.on('PastePreProcess', function(event) {
//Check if data is an image
if (isImageFromPaste(event.content)) {
stopEvent(event);
//extract base64 data
var base64 = extractSrcFromImgTag(event.content);
//transform to blob and insert into editor
if (base64.length) {
var file = dataURItoBlob(base64);
insertImageInTinyMCE(editor, file);
}
} else if (isImageBlobFromPaste(event.content)) {
stopEvent(event);
var src = extractSrcFromImgTag(event.content);
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (this.status !== 200) {
console.error("paste error");
return;
}
var imgData = new Uint8Array(this.response);
// fileType.fromBuffer() returns a promise (async method)
fileType.fromBuffer(imgData).then(function(imgType) {
if (!imgType || !imgType.ext || !imgType.mime) {
// Unable to retrieve file ext
console.error("paste error");
return;
}
var file = new Blob([imgData.buffer], {type: imgType.mime});
file.name = 'image_paste' + Math.floor((Math.random() * 10000000) + 1) + '.' + imgType.ext;
insertImageInTinyMCE(editor, file);
});
};
xhr.send();
}
});
});
}
$(function() {
// set a function to track drag hover event
$(document).bind('dragover', function (event) {
event.preventDefault();
var dropZone = $('.dropzone');
var foundDropzone;
var timeout = window.dropZoneTimeout;
if (!timeout) {
dropZone.addClass('dragin');
} else {
clearTimeout(timeout);
}
var found = false;
var node = event.target;
do {
if ($(node).hasClass('draghoverable')) {
found = true;
foundDropzone = $(node);
break;
}
node = node.parentNode;
} while (node !== null);
dropZone.removeClass('dragin draghover');
if (found) {
foundDropzone.addClass('draghover');
}
});
// remove dragover styles on drop
$(document).bind('drop', function(event) {
event.preventDefault();
$('.draghoverable').removeClass('draghover');
// if file present, insert it in filelist
if (typeof event.originalEvent.dataTransfer.files !== 'undefined') {
$.each(event.originalEvent.dataTransfer.files, function(index, element) {
var input_name = null;
var input_file = $(event.target).find('input[type=file][name]');
if (input_file.length) {
input_name = input_file.attr('name').replace('[]', '');
}
uploadFile(
element,
{targetElm: $(event.target).find('.fileupload_info')},
input_name
);
});
}
});
});