From 075c6c01f28b383a8b07a46deec44113df65563a Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 13 Feb 2014 19:41:54 -0500 Subject: [PATCH] upload changes, show progres in composer --- public/src/modules/composer.js | 207 +++++++++++---------- public/templates/composer.tpl | 6 +- public/vendor/jquery/js/jquery.form.js | 247 ++++++++++++++++++------- src/posts.js | 17 +- src/routes/admin.js | 49 ++--- src/routes/api.js | 39 ++++ src/routes/user.js | 35 +--- 7 files changed, 357 insertions(+), 243 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 56e609a42d..cc4a156cc0 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -90,6 +90,7 @@ define(['taskbar'], function(taskbar) { }); composer.posts[uuid] = post; + composer.posts[uuid].uploadsInProgress = []; composer.load(uuid); } @@ -118,7 +119,7 @@ define(['taskbar'], function(taskbar) { var postContainer = $(composerTemplate[0]); if(config.allowFileUploads || config.hasImageUploadPlugin) { - initializeFileReader(post_uuid); + initializeDragAndDrop(post_uuid); } var postData = composer.posts[post_uuid], @@ -235,11 +236,8 @@ define(['taskbar'], function(taskbar) { $('#files').on('change', function(e) { var files = e.target.files; if(files) { - for (var i=0; i parseInt(config.maximumFileSize, 10) * 1024) { - return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs'); - } - uploadFile('posts.uploadFile', post_uuid, fileData); + fileForm[0].reset(); + uploadSubmit([blob], post_uuid, '/api/post/upload', fd); } }); - - reader.readAsDataURL(file); } - - function uploadFile(method, post_uuid, img) { - var linkStart = method === 'posts.uploadImage' ? '!' : '', - postContainer = $('#cmp-uuid-' + post_uuid), + function uploadSubmit(files, post_uuid, route, formData, callback) { + var postContainer = $('#cmp-uuid-' + post_uuid), textarea = postContainer.find('textarea'), text = textarea.val(), - imgText = linkStart + '[' + img.name + '](uploading...)'; + uploadForm = postContainer.find('#fileForm'); - text += imgText; - textarea.val(text + " "); + uploadForm.attr('action', route); - if(!composer.posts[post_uuid].uploadsInProgress) { - composer.posts[post_uuid].uploadsInProgress = []; - } + for(var i=0; i parseInt(config.maximumFileSize, 10) * 1024) { + uploadForm[0].reset(); + return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs'); + } + } - socket.emit(method, img, function(err, data) { + textarea.val(text); - var currentText = textarea.val(); + uploadForm.off('submit').submit(function() { - if(err) { - textarea.val(currentText.replace(imgText, linkStart + '[' + img.name + ']( Error : ' + err.message + ')')); - return app.alertError(err.message); + $(this).find('#postUploadCsrf').val($('#csrf_token').val()); + if(formData) { + formData.append('_csrf', $('#csrf_token').val()); } - textarea.val(currentText.replace(imgText, linkStart + '[' + data.name + '](' + data.url + ')')); + composer.posts[post_uuid].uploadsInProgress.push(1); + + $(this).ajaxSubmit({ + resetForm: true, + clearForm: true, + formData: formData, + error: function(xhr) { + app.alertError('Error uploading file! ' + xhr.status); + composer.posts[post_uuid].uploadsInProgress.pop(); + }, + + uploadProgress: function(event, position, total, percent) { + var current = textarea.val(); + for(var i=0; i -
- + + + +
diff --git a/public/vendor/jquery/js/jquery.form.js b/public/vendor/jquery/js/jquery.form.js index 11f67f02d3..e0383d44b7 100644 --- a/public/vendor/jquery/js/jquery.form.js +++ b/public/vendor/jquery/js/jquery.form.js @@ -1,7 +1,7 @@ /*! * jQuery Form Plugin - * version: 3.32.0-2013.04.09 - * @requires jQuery v1.5 or later + * version: 3.49.0-2014.02.05 + * Requires jQuery v1.5 or later * Copyright (c) 2013 M. Alsup * Examples and documentation at: http://malsup.com/jquery/form/ * Project repository: https://github.com/malsup/form @@ -9,7 +9,20 @@ * https://github.com/malsup/form#copyright-and-license */ /*global ActiveXObject */ -;(function($) { + +// AMD support +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + // using AMD; register as anon module + define(['jquery'], factory); + } else { + // no AMD; invoke directly + factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto ); + } +} + +(function($) { "use strict"; /* @@ -59,15 +72,17 @@ feature.formdata = window.FormData !== undefined; var hasProp = !!$.fn.prop; // attr2 uses prop when it can but checks the return type for -// an expected string. this accounts for the case where a form +// an expected string. this accounts for the case where a form // contains inputs with names like "action" or "method"; in those // cases "prop" returns the element $.fn.attr2 = function() { - if ( ! hasProp ) + if ( ! hasProp ) { return this.attr.apply(this, arguments); + } var val = this.prop.apply(this, arguments); - if ( ( val && val.jquery ) || typeof val === 'string' ) + if ( ( val && val.jquery ) || typeof val === 'string' ) { return val; + } return this.attr.apply(this, arguments); }; @@ -89,9 +104,12 @@ $.fn.ajaxSubmit = function(options) { if (typeof options == 'function') { options = { success: options }; } + else if ( options === undefined ) { + options = {}; + } - method = this.attr2('method'); - action = this.attr2('action'); + method = options.type || this.attr2('method'); + action = options.url || this.attr2('action'); url = (typeof action === 'string') ? $.trim(action) : ''; url = url || window.location.href || ''; @@ -103,7 +121,7 @@ $.fn.ajaxSubmit = function(options) { options = $.extend(true, { url: url, success: $.ajaxSettings.success, - type: method || 'GET', + type: method || $.ajaxSettings.type, iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' }, options); @@ -186,11 +204,27 @@ $.fn.ajaxSubmit = function(options) { } }; + if (options.error) { + var oldError = options.error; + options.error = function(xhr, status, error) { + var context = options.context || this; + oldError.apply(context, [xhr, status, error, $form]); + }; + } + + if (options.complete) { + var oldComplete = options.complete; + options.complete = function(xhr, status) { + var context = options.context || this; + oldComplete.apply(context, [xhr, status, $form]); + }; + } + // are there files to upload? // [value] (issue #113), also see comment: // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219 - var fileInputs = $('input[type=file]:enabled[value!=""]', this); + var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; }); var hasFileInputs = fileInputs.length > 0; var mp = 'multipart/form-data'; @@ -226,8 +260,9 @@ $.fn.ajaxSubmit = function(options) { $form.removeData('jqxhr').data('jqxhr', jqxhr); // clear element array - for (var k=0; k < elements.length; k++) + for (var k=0; k < elements.length; k++) { elements[k] = null; + } // fire 'notify' event this.trigger('form-submit-notify', [this, options]); @@ -235,7 +270,7 @@ $.fn.ajaxSubmit = function(options) { // utility fn for deep serialization function deepSerialize(extraData){ - var serialized = $.param(extraData).split('&'); + var serialized = $.param(extraData, options.traditional).split('&'); var len = serialized.length; var result = []; var i, part; @@ -259,9 +294,11 @@ $.fn.ajaxSubmit = function(options) { if (options.extraData) { var serializedData = deepSerialize(options.extraData); - for (i=0; i < serializedData.length; i++) - if (serializedData[i]) + for (i=0; i < serializedData.length; i++) { + if (serializedData[i]) { formdata.append(serializedData[i][0], serializedData[i][1]); + } + } } options.data = null; @@ -276,7 +313,7 @@ $.fn.ajaxSubmit = function(options) { if (options.uploadProgress) { // workaround because jqXHR does not expose upload property s.xhr = function() { - var xhr = jQuery.ajaxSettings.xhr(); + var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.addEventListener('progress', function(event) { var percent = 0; @@ -293,11 +330,18 @@ $.fn.ajaxSubmit = function(options) { } s.data = null; - var beforeSend = s.beforeSend; - s.beforeSend = function(xhr, o) { + var beforeSend = s.beforeSend; + s.beforeSend = function(xhr, o) { + //Send FormData() provided by user + if (options.formData) { + o.data = options.formData; + } + else { o.data = formdata; - if(beforeSend) - beforeSend.call(this, xhr, o); + } + if(beforeSend) { + beforeSend.call(this, xhr, o); + } }; return $.ajax(s); } @@ -307,14 +351,21 @@ $.fn.ajaxSubmit = function(options) { var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; var deferred = $.Deferred(); + // #341 + deferred.abort = function(status) { + xhr.abort(status); + }; + if (a) { // ensure that every serialized input is still enabled for (i=0; i < elements.length; i++) { el = $(elements[i]); - if ( hasProp ) + if ( hasProp ) { el.prop('disabled', false); - else + } + else { el.removeAttr('disabled'); + } } } @@ -324,10 +375,12 @@ $.fn.ajaxSubmit = function(options) { if (s.iframeTarget) { $io = $(s.iframeTarget); n = $io.attr2('name'); - if (!n) - $io.attr2('name', id); - else + if (!n) { + $io.attr2('name', id); + } + else { id = n; + } } else { $io = $('