/*! * @name ElkArte Forum * @copyright ElkArte Forum contributors * @license BSD http://opensource.org/licenses/BSD-3-Clause * * @version 1.1 */ /** * This file contains javascript associated with the drag drop of files functionality * while posting */ /** * Simply invoke the constructor by calling new dragDropAttachment */ (function() { var dragDropAttachment = (function(params) { // Few internal global vars var allowedExtensions = [], curFileNum = 0, totalSizeAllowed = null, individualSizeAllowed = null, numOfAttachmentAllowed = null, totalAttachSizeUploaded = 0, numAttachUploaded = 0, filesUploadedSuccessfully = [], uploadInProgress = false, attachmentQueue = [], board = 0, topic = 0, oTxt = {}, errorMsg = '', // @deprecated since 1.1 - here just for backward compatibility fileDisplayTemplate = '
', oEvents = {}, $str, /** * public function, accessible with prototype chain * @param {object} params * * allowedExtensions - types of attachments allowed * totalSizeAllowed - maximum size of total attachments allowed * individualSizeAllowed - maximum individual file size allowed * numOfAttachmentAllowed - number of files that can be attached in a post * totalAttachSizeUploaded - total size of already attached files(modifying post) * numAttachUploaded - number of already attached files(modifying post) */ init = function(params) { if (typeof params.events !== 'undefined') { for (var event in params.events) { if (params.events.hasOwnProperty(event)) { addEventListener(event, params.events[event]); } } } allowedExtensions = (params.allowedExtensions === '') ? [] : params.allowedExtensions.toLowerCase().replace(/\s/g, '').split(','); totalSizeAllowed = (params.totalSizeAllowed === '') ? null : params.totalSizeAllowed; individualSizeAllowed = (params.individualSizeAllowed === '') ? null : params.individualSizeAllowed; numOfAttachmentAllowed = (params.numOfAttachmentAllowed === '') ? null : params.numOfAttachmentAllowed; totalAttachSizeUploaded = params.totalAttachSizeUploaded / 1024; numAttachUploaded = params.numAttachUploaded; filesUploadedSuccessfully = []; if (typeof params.topic !== 'undefined') topic = params.topic; if (typeof params.fileDisplayTemplate !== 'undefined') fileDisplayTemplate = params.fileDisplayTemplate; $str = $(fileDisplayTemplate); board = params.board; oTxt = params.oTxt; if (typeof params.existingSelector !== 'undefined') processExisting($(params.existingSelector)); }, /** * private function * * Takes already uploaded files (e.g. when editing a message) * and creates the "D&D" interface * * @param {object} $files Array of elements of existing input files */ processExisting = function ($files) { $files.each(function(idx, value) { var status = new createStatusbar({}), $file = $(this); status.setFileNameSize($file.parent().text(), $file.data('size')); status.setProgress(100); var $button = status.getButton(), data = { curFileNum: curFileNum++, attachid: $file.data('attachid'), size: $file.data('size') }; $button.addClass('abort'); status.onUploadSuccess(data); filesUploadedSuccessfully.push(data); $file.closest('dd').remove(); }); }, /** * private function * * Uploads the file to server and updates the UI * * @param {object} formData current file with data to upload * @param {object} status current progress bar UI instance * @param {int} fileSize current progress bar UI instance * @param {string} fileName current progress bar UI instance */ sendFileToServer = function(formData, status, fileSize, fileName) { var jqXHR = $.ajax({ xhr: function() { var xhrobj = $.ajaxSettings.xhr(); if (xhrobj.upload) { // Set up a progress event listener to update the UI xhrobj.upload.addEventListener('progress', function(event) { var percent = 0, position = event.loaded || event.position, total = event.total; if (event.lengthComputable) percent = Math.ceil(position / total * 100); status.setProgress(percent); }, false); } return xhrobj; }, url: elk_scripturl + '?action=attachment;sa=ulattach;api;' + elk_session_var + '=' + elk_session_id + ';board=' + board, type: "POST", dataType: "json", contentType: false, processData: false, cache: false, data: formData, context: { 'fileName': fileName, 'fileSize': fileSize } }).done(function(resp) { if (typeof(resp) !== 'object') resp = JSON.parse(resp); // Well its done, lets make sure the server says so as well if (resp.result) { var curFileNum = filesUploadedSuccessfully.length, data = resp.data; // Show its done status.setProgress(100); filesUploadedSuccessfully.push(data); data.curFileNum = curFileNum; status.onUploadSuccess(data); } else { // The server was unable to process the file, show it as not sent var errorMsgs = {}, serverErrorFiles = []; for (var err in resp.data) { if (resp.data.hasOwnProperty(err)) { errorMsgs.individualServerErr = resp.data[err].title.php_unhtmlspecialchars() + ''; for (var err in params.errorMsgs) { if (params.errorMsgs.hasOwnProperty(err)) { // Build the warning box of errors this file generated switch (err) { case 'extnError': errorMsg = wrapper + params.extnErrorFiles.join(', ') + ' : ' + params.errorMsgs[err] + '
'; break; case 'individualSizeErr': errorMsg = wrapper + params.sizeErrorFiles.join(', ') + ' : ' + params.errorMsgs[err] + ''; break; case 'individualServerErr': errorMsg = wrapper + params.errorMsgs[err] + params.serverErrorFiles.join(', ') + ''; break; default: errorMsg = wrapper + params.errorMsgs[err] + ''; break; } } // Show them what they are doing wrong $drop_attachments_error.append(errorMsg); } }, /** * private function * * Used to check if a value exists in an array * * @param {string} needle */ indexOf = function(needle) { if (typeof Array.prototype.indexOf === 'function') indexOf = Array.prototype.indexOf; else { indexOf = function(needle) { var i, index = -1; for (i = 0; i < this.length; i++) { if (this[i] === needle) { index = i; break; } } return index; }; } }, /** * public function * * Used to extend the code * * @param {string} event * @param {object} listener */ addEventListener = function(event, listener) { if (!oEvents.hasOwnProperty(event)) oEvents[event] = []; oEvents[event].push(listener); }, /** * private function * * Runs all the listeners on a certain event * * @param {string} event * @param {object} aThis * @param {object} args */ triggerEvt = function(event, aThis, args) { if (!oEvents.hasOwnProperty(event)) return; for (var i = 0; i < oEvents[event].length; i++) { oEvents[event][i].apply(aThis, args); } }; /** * Initialize the drag and drop function! */ $(function() { var obj = $(".drop_area"); // Make sure the browser supports this if (!(window.FormData && ("onprogress" in $.ajaxSettings.xhr()))) return; // All clear, show the drop zone obj.toggle(); $('.drop_attachments_no_js').hide(); // Entering the dropzone, show it obj.on('dragenter', function(e) { e.stopPropagation(); e.preventDefault(); $(this).css('opacity', '1'); }); // Hovering over, waiting waiting waiting, show we are waiting obj.on('dragover', function(e) { e.stopPropagation(); e.preventDefault(); }); // Catch what you dropped, and send it off to be processed obj.on('drop', function(e) { var files = e.originalEvent.dataTransfer.files; e.preventDefault(); $(this).css('opacity', '0.6'); //call resize function document.getElementById("file", function (event)).addEventListener("drop", function (event) { compress(event); }); handleFileUpload(files, obj); }); // Wait, where are you going? Lets show you are outside the zone obj.on('dragexit', function(e) { e.preventDefault(); $(this).css('opacity', '0.6'); }); // Rather click and select? $input = obj.find('#attachment_click'); $input.change(function(e) { e.preventDefault(); var files = $(this)[0].files; handleFileUpload(files, obj); this.value = null; }); $input.clone(true, true).appendTo('.drop_area_fileselect_text'); $input.hide(); }); init(params); return { init: init, addEventListener: addEventListener, handleFileUpload: handleFileUpload }; }); // AMD / RequireJS if ( typeof define !== 'undefined' && define.amd) { define([], function() { return dragDropAttachment; }); } // CommonJS else if ( typeof module !== 'undefined' && module.exports) { module.exports = dragDropAttachment; } // included directly via