http://www.mediawiki.org/wiki/Special:Code/MediaWiki/98840

Revision: 98840
Author:   raindrift
Date:     2011-10-04 00:31:05 +0000 (Tue, 04 Oct 2011)
Log Message:
-----------
added support for multi-file selection
fixed a bug in FormData transport's progress bar method

Modified Paths:
--------------
    trunk/extensions/UploadWizard/resources/mw.ApiUploadFormDataHandler.js
    trunk/extensions/UploadWizard/resources/mw.FormDataTransport.js
    trunk/extensions/UploadWizard/resources/mw.UploadWizard.js
    trunk/extensions/UploadWizard/resources/mw.UploadWizardUpload.js
    trunk/extensions/UploadWizard/resources/mw.UploadWizardUploadInterface.js

Modified: trunk/extensions/UploadWizard/resources/mw.ApiUploadFormDataHandler.js
===================================================================
--- trunk/extensions/UploadWizard/resources/mw.ApiUploadFormDataHandler.js      
2011-10-04 00:12:09 UTC (rev 98839)
+++ trunk/extensions/UploadWizard/resources/mw.ApiUploadFormDataHandler.js      
2011-10-04 00:31:05 UTC (rev 98840)
@@ -6,6 +6,7 @@
 mw.ApiUploadFormDataHandler = function( upload, api ) {
     this.upload = upload;
     this.api = api;
+
     this.$form = $j( this.upload.ui.form );
     this.formData = {
         action: 'upload',
@@ -15,8 +16,9 @@
 
     var _this = this;
     this.transport = new mw.FormDataTransport(
-        this.$form,
+        this.$form[0].action,
         this.formData,
+               this.upload,
         function( fraction ) { 
             _this.upload.setTransportProgress( fraction ); 
         },

Modified: trunk/extensions/UploadWizard/resources/mw.FormDataTransport.js
===================================================================
--- trunk/extensions/UploadWizard/resources/mw.FormDataTransport.js     
2011-10-04 00:12:09 UTC (rev 98839)
+++ trunk/extensions/UploadWizard/resources/mw.FormDataTransport.js     
2011-10-04 00:31:05 UTC (rev 98840)
@@ -8,13 +8,13 @@
  */
 
 
-mw.FormDataTransport = function( $form, formData, progressCb, transportedCb ) {
-    this.$form = $form;
+mw.FormDataTransport = function( postUrl, formData, uploadObject, progressCb, 
transportedCb ) {
     this.formData = formData;
     this.progressCb = progressCb;
     this.transportedCb = transportedCb;
+       this.uploadObject = uploadObject;
 
-    this.postUrl = this.$form[0].action;
+    this.postUrl = postUrl;
     this.chunkSize = 1 * 1024 * 1024; //1Mb
     this.maxRetries = 2;
     this.retries = 0;
@@ -28,7 +28,9 @@
 mw.FormDataTransport.prototype = {
     upload: function() {
         var _this = this,
-            file = this.$form.find('input[name=file]')[0].files[0];
+                       file = this.uploadObject.file;
+               var bytesAvailable = file.size;
+               
         if(file.size > this.chunkSize) {
             this.uploadChunk(0);
         } else {
@@ -79,15 +81,16 @@
             $j.each(this.formData, function(key, value) {
                 formData.append(key, value);
             });
-            formData.append('filename', file.name);
-            formData.append('file', file);
+                       formData.append('filename', file.name);
+                       formData.append('file', file);
+                       
             this.xhr.open("POST", _this.postUrl, true);
             this.xhr.send(formData);
         }
     },
     uploadChunk: function(offset) {
         var _this = this,
-            file = this.$form.find('input[name=file]')[0].files[0],
+            file = this.uploadObject.file,
             bytesAvailable = file.size,
             chunk;
 

Modified: trunk/extensions/UploadWizard/resources/mw.UploadWizard.js
===================================================================
--- trunk/extensions/UploadWizard/resources/mw.UploadWizard.js  2011-10-04 
00:12:09 UTC (rev 98839)
+++ trunk/extensions/UploadWizard/resources/mw.UploadWizard.js  2011-10-04 
00:31:05 UTC (rev 98840)
@@ -397,13 +397,13 @@
         *   we don't yet add it to the list of uploads; that only happens when 
it gets a real file.
         * @return the new upload
         */
-       newUpload: function() {
+       newUpload: function( file ) {
                var _this = this;
                if ( _this.uploads.length == _this.maxUploads ) {
                        return false;
                }
 
-               var upload = new mw.UploadWizardUpload( _this, 
'#mwe-upwiz-filelist' );
+               var upload = new mw.UploadWizardUpload( _this, 
'#mwe-upwiz-filelist', file );
                _this.uploadToAdd = upload;
 
                // we explicitly move the file input to cover the upload button
@@ -419,8 +419,7 @@
                        e.stopPropagation();
                } );
                // XXX bind to some error state
-
-
+               
                return upload;
        },
 
@@ -482,7 +481,7 @@
         */
        removeEmptyUploads: function() {
                this.removeMatchingUploads( function( upload ) {
-                       return mw.isEmpty( upload.ui.$fileInputCtrl.val() );
+                       return mw.isEmpty( upload.filename );
                } );
        },
 

Modified: trunk/extensions/UploadWizard/resources/mw.UploadWizardUpload.js
===================================================================
--- trunk/extensions/UploadWizard/resources/mw.UploadWizardUpload.js    
2011-10-04 00:12:09 UTC (rev 98839)
+++ trunk/extensions/UploadWizard/resources/mw.UploadWizardUpload.js    
2011-10-04 00:31:05 UTC (rev 98840)
@@ -7,7 +7,7 @@
  */
 ( function( $j ) {
 
-mw.UploadWizardUpload = function( wizard, filesDiv ) {
+mw.UploadWizardUpload = function( wizard, filesDiv, providedFile ) {
 
        this.index = mw.UploadWizardUpload.prototype.count;
        mw.UploadWizardUpload.prototype.count++;
@@ -22,6 +22,8 @@
        this.mimetype = undefined;
        this.extension = undefined;
        this.filename = undefined;
+       this.providedFile = providedFile;
+       this.file = undefined;
 
        this.fileKey = undefined;
 
@@ -30,7 +32,7 @@
        this.detailsWeight = 1; // default all same
 
        // details
-       this.ui = new mw.UploadWizardUploadInterface( this, filesDiv );
+       this.ui = new mw.UploadWizardUploadInterface( this, filesDiv, 
providedFile );
 
        // handler -- usually ApiUploadHandler
        // this.handler = new ( mw.UploadWizard.config[  'uploadHandlerClass'  
] )( this );
@@ -258,18 +260,18 @@
         * Checks for file validity, then extracts metadata.
         * Error out if filename or its contents are determined to be 
unacceptable
         * Proceed to thumbnail extraction and image info if acceptable
-        * @param {HTMLFileInput} file input field
+        * @param {string} the filename
+        * @param {Array} the list of files.  usually one, can be more for 
multi-file select.
         * @param {Function()} callback when ok, and upload object is ready
         * @param {Function(String, Mixed)} callback when filename or contents 
in error. Signature of string code, mixed info
         */
-       checkFile: function( fileInput, fileNameOk, fileNameErr ) {
+       checkFile: function( filename, files, fileNameOk, fileNameErr ) {
                // check if local file is acceptable
 
                var _this = this;
                
                // Check if filename is acceptable
                // TODO sanitize filename
-               var filename = fileInput.value;
                var basename = mw.UploadWizardUtil.getBasename( filename );
 
 
@@ -301,13 +303,23 @@
                        if ( $j.inArray( extension.toLowerCase(), 
mw.UploadWizard.config[ 'fileExtensions' ] ) === -1 ) {
                                fileNameErr( 'ext', extension );
                        } else {
-
                                // extract more info via fileAPI
                                if ( mw.fileApi.isAvailable() ) {
-                                       if ( fileInput.files && 
fileInput.files.length ) {
-                                               // TODO multiple files in an 
input
-                                               this.file = fileInput.files[0];
-                                       }
+
+                                       // An UploadWizardUpload object already 
exists (us) when we add a file. 
+                                       // So, when multiple files are provided 
(via select multiple), add the first file to this UploadWizardUpload
+                                       // and create new UploadWizardUpload 
objects and corresponding interfaces for the rest.
+                                       //
+                                       // don't process the very first file, 
since that's this instance's job.
+                                       $j.each( files.slice(1), function( i, 
file ) {
+                                               //_this.wizard.setUploadFilled( 
_this.wizard.newUpload( file ) );
+                                               _this.wizard.newUpload( file );
+                                       } );
+                                       _this.wizard.updateFileCounts();
+                                       
+                                       // this input will use the last one.
+                                       this.file = files[0];
+
                                        // TODO check max upload size, alert 
user if too big
                                        this.transportWeight = this.file.size;
                                        if ( !mw.isDefined( this.imageinfo ) ) {
@@ -559,10 +571,7 @@
         */
        getUploadHandler: function(){
                if( !this.uploadHandler ){
-                       if( mw.UploadWizard.config[ 'enableFirefogg' ]
-                                       &&
-                               typeof( Firefogg ) != 'undefined'
-                       ) {
+                       if( mw.UploadWizard.config[ 'enableFirefogg' ] && 
typeof( Firefogg ) != 'undefined' ) {
                                mw.log("mw.UploadWizard::getUploadHandler> 
FirefoggHandler");
                                this.uploadHandler = new mw.FirefoggHandler( 
this, this.api );                  
                        } else if( mw.UploadWizard.config[ 'enableFormData' ] &&

Modified: 
trunk/extensions/UploadWizard/resources/mw.UploadWizardUploadInterface.js
===================================================================
--- trunk/extensions/UploadWizard/resources/mw.UploadWizardUploadInterface.js   
2011-10-04 00:12:09 UTC (rev 98839)
+++ trunk/extensions/UploadWizard/resources/mw.UploadWizardUploadInterface.js   
2011-10-04 00:31:05 UTC (rev 98840)
@@ -2,25 +2,27 @@
  * Create an interface fragment corresponding to a file input, suitable for 
Upload Wizard.
  * @param upload
  * @param div to insert file interface
- * @param addInterface interface to add a new one (assumed that we start out 
there)
+ * @param providedFile a File object that this ui component should use 
(optional)
  */
-mw.UploadWizardUploadInterface = function( upload, filesDiv ) {
+mw.UploadWizardUploadInterface = function( upload, filesDiv, providedFile ) {
        var _this = this;
 
        _this.upload = upload;
 
+       _this.providedFile = providedFile;
+
        // may need to collaborate with the particular upload type sometimes
        // for the interface, as well as the uploadwizard. OY.
        _this.div = $j('<div class="mwe-upwiz-file"></div>').get(0);
        _this.isFilled = false;
 
-       _this.$fileInputCtrl = $j('<input size="1" class="mwe-upwiz-file-input" 
name="file" type="file"/>');
+       _this.$fileInputCtrl = $j('<input size="1" class="mwe-upwiz-file-input" 
name="file" type="file" multiple="1"/>');
 
        _this.initFileInputCtrl();
 
        _this.$indicator = $j( '<div class="mwe-upwiz-file-indicator"></div>' );
 
-       visibleFilenameDiv = $j('<div class="mwe-upwiz-visible-file"></div>')
+       var visibleFilenameDiv = $j('<div 
class="mwe-upwiz-visible-file"></div>')
                .append( _this.$indicator )
                .append( '<div class="mwe-upwiz-visible-file-filename">'
                           + '<div class="mwe-upwiz-file-preview"/>'
@@ -92,6 +94,11 @@
                true
        );
 
+       if( providedFile ) {
+               // if a file is already present, trigger the change event 
immediately.
+               _this.$fileInputCtrl.change();
+       }
+
 };
 
 
@@ -225,15 +232,41 @@
                var _this = this;
                _this.$fileInputCtrl.change( function() { 
                        _this.clearErrors();
-                       _this.upload.checkFile( 
-                               this, // the file input, different from _this
+                       
+                       _this.upload.checkFile(
+                               _this.getFilename(),
+                               _this.getFiles(),
                                function() { _this.fileChangedOk(); },
                                function( code, info ) { 
_this.fileChangedError( code, info ); } 
                        ); 
                } );
        },
 
+       /**
+        * Get a list of the files, defaulting to the value from the input form
+        * @return Array of file objects
+        */
+       getFiles: function() {
+               var files = [];
+               if( this.providedFile && ! this.$fileInputCtrl.get(0).value ) { 
 // default to the fileinput if it's defined.
+                        files[0] = this.providedFile;
+               } else {
+                       $j.each( this.$fileInputCtrl.get(0).files, function( i, 
file ) {
+                               files.push( file );
+                       } );
+               }
+               return files;
+       },
 
+       // get just the filename.
+       getFilename: function() {
+               if( this.providedFile && ! this.$fileInputCtrl.get(0).value ) { 
 // default to the fileinput if it's defined.
+                       return this.providedFile.fileName;
+               } else {
+                       return this.$fileInputCtrl.get(0).value;
+               }       
+       },
+
        /**
         * Run this when the value of the file input has changed and we know 
it's acceptable -- this 
         * will update interface to show as much info as possible, including 
preview.
@@ -272,7 +305,7 @@
        },
 
        fileChangedError: function( code, info ) {
-               var filename = this.$fileInputCtrl.get(0).value;
+               var filename = this.getFilename();
 
                // ok we now have a fileInputCtrl with a "bad" file in it
                // you cannot blank a file input ctrl in all browsers, so we 
@@ -281,6 +314,10 @@
                this.$fileInputCtrl.replaceWith( $newFileInput );
                this.$fileInputCtrl = $newFileInput;
                this.initFileInputCtrl();
+               
+               if( this.providedFile ) {
+                       this.providedFile = null;
+               }
 
                if ( code === 'ext' ) {
                        this.showBadExtensionError( filename, info );
@@ -395,7 +432,7 @@
         */
        updateFilename: function() {
                var _this = this;
-               var path = _this.$fileInputCtrl.val();
+               var path = this.getFilename();
                // get basename of file; some browsers do this 
C:\fakepath\something
                path = path.replace(/\w:.*\\(.*)$/,'$1');
                


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to