From: Marcel Werk Date: Thu, 16 Feb 2012 19:07:54 +0000 (+0100) Subject: Added javascript upload handler (work in progress) X-Git-Tag: 2.0.0_Beta_1~1335 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c1aaf7a7dcb62b2cf3552b44966f62274fe98bb2;p=GitHub%2FWoltLab%2FWCF.git Added javascript upload handler (work in progress) --- diff --git a/wcfsetup/install/files/js/WCF.js b/wcfsetup/install/files/js/WCF.js index 7b48e9245f..e317eafe7e 100644 --- a/wcfsetup/install/files/js/WCF.js +++ b/wcfsetup/install/files/js/WCF.js @@ -3885,6 +3885,227 @@ WCF.InlineEditor = Class.extend({ } }); +/** + * Default implementation for ajax file uploads + * + * @param jquery buttonSelector + * @param jquery fileListSelector + * @param string className + * @param jquery options + */ +WCF.Upload = Class.extend({ + /** + * name of the upload field + * @var string + */ + _name: '__files[]', + + /** + * button selector + * @var jquery + */ + _buttonSelector: null, + + /** + * file list selector + * @var jquery + */ + _fileListSelector: null, + + /** + * upload file + * @var jquery + */ + _fileUpload: null, + + /** + * class name + * @var string + */ + _className: '', + + /** + * additional options + * @var jquery + */ + _options: {}, + + /** + * upload matrix + * @var array + */ + _uploadMatrix: [], + + /** + * True, if your browser supports ajax file uploads. False, if your browser sucks. + * @var boolean + */ + _supportsAJAXUpload: true, + + /** + * fallback overlay for stupid browsers + * @var jquery + */ + _overlay: null, + + /** + * Initializes a new upload handler. + */ + init: function(buttonSelector, fileListSelector, className, options) { + this._buttonSelector = buttonSelector; + this._fileListSelector = fileListSelector; + this._className = className; + this._options = $.extend(true, { + action: 'upload', + multiple: false, + url: 'index.php/AJAXUpload/?t=' + SECURITY_TOKEN + SID_ARG_2ND + }, options); + + // check for ajax upload support + var $xhr = new XMLHttpRequest(); + this._supportsAJAXUpload = ($xhr && ('upload' in $xhr) && ('onprogress' in $xhr.upload)); + + // create upload button + this._createButton(); + }, + + /** + * Creates the upload button. + */ + _createButton: function() { + if (this._supportsAJAXUpload) { + this._fileUpload = $(''); + this._fileUpload.change($.proxy(this._upload, this)); + var $button = $('

Upload

'); + $button.append(this._fileUpload); + } + else { + var $button = $('

Upload

'); + $button.click($.proxy(this._showOverlay, this)); + } + + this._insertButton($button); + }, + + /** + * Inserts the upload button. + */ + _insertButton: function(button) { + this._buttonSelector.append(button); + }, + + /** + * Callback for file uploads. + */ + _upload: function() { + var $files = this._fileUpload.prop('files'); + + if ($files.length > 0) { + var $fd = new FormData(); + var self = this; + var $uploadID = this._uploadMatrix.length; + this._uploadMatrix[$uploadID] = []; + + for (var $i = 0; $i < $files.length; $i++) { + this._uploadMatrix[$uploadID].push(this._initFile($files[$i])); + $fd.append('__files[]', $files[$i]); + } + $fd.append('actionName', this._options.action); + $fd.append('className', this._className); + + $.ajax({ + type: 'POST', + url: this._options.url, + enctype: 'multipart/form-data', + data: $fd, + contentType: false, + processData: false, + success: $.proxy(this._success, this), + error: $.proxy(this._error, this), + xhr: function() { + var $xhr = $.ajaxSettings.xhr(); + if ($xhr) { + $xhr.upload.addEventListener('progress', function(event) { + self._progress(event, $uploadID); + }, false); + } + return $xhr; + } + }); + } + }, + + /** + * Callback for success event + */ + _success: function(data, textStatus, jqXHR) { + console.debug(jqXHR.responseText); + }, + + /** + * Callback for error event + */ + _error: function(jqXHR, textStatus, errorThrown) { + console.debug(jqXHR.responseText); + }, + + /** + * Callback for progress event + */ + _progress: function(event, uploadID) { + var $percentComplete = Math.round(event.loaded * 100 / event.total); + + for (var $i = 0; $i < this._uploadMatrix[uploadID].length; $i++) { + this._uploadMatrix[uploadID][$i].find('progress').attr('value', $percentComplete); + } + }, + + + _initFile: function(file) { + var $li = $('
  • '+file.name+' ('+file.size+')
  • '); + this._fileListSelector.append($li); + + return $li; + }, + + /** + * Shows the fallback overlay (work in progress) + */ + _showOverlay: function() { + var $self = this; + if (!this._overlay) { + // create overlay + this._overlay = $('
    '); + } + + // create iframe + var $iframe = $(''); // width: 300px; height: 100px; border: 5px solid red + $iframe.attr('name', $iframe.wcfIdentify()); + $('body').append($iframe); + this._overlay.find('form').attr('target', $iframe.wcfIdentify()); + + // add events (iframe onload) + $iframe.load(function() { + console.debug('iframe ready'); + console.debug($iframe.contents()); + }); + + this._overlay.find('form').submit(function() { + $iframe.data('loading', true); + $self._overlay.wcfDialog('close'); + }); + + this._overlay.wcfDialog({ + title: 'Upload', + onClose: function() { + if (!$iframe.data('loading')) { + $iframe.remove(); + } + } + }); + } +}); + /** * Provides a toggleable sidebar. */