Bartosz Dziewoński has uploaded a new change for review.
https://gerrit.wikimedia.org/r/232403
Change subject: mediawiki.api.uploadWithFormData: Implement in terms of
existing mw.Api functionality
......................................................................
mediawiki.api.uploadWithFormData: Implement in terms of existing mw.Api
functionality
* mw.Api#ajax can already handle FormData, if instructed to, since
d19432a332c21935d42087db706e50c5259063ea (which seems to have been a
part of mobile uploads experiments).
* MobileFrontend's api.js already had code to provide upload progress
events while using mw.Api, lifted it from there.
With this change, we should be able to just use mw.ForeignApi (being
added in Ic20b9682d28633baa87d22e6e9fb71ce507da58d) to upload to a
different wiki. (Assuming that the browser supports FormData.)
Additionally:
* Improve detection of whether we can use FormData: if we are given a
HTMLInputElement, try to get a File from it before we fall back to
iframe form upload.
* mediawiki.api.edit: In #postWithEditToken, pass through the
ajaxOptions parameter to #postWithToken.
Change-Id: Ib9abe32ee3320c67ac0a4544c942b844a5550562
---
M resources/src/mediawiki.api/mediawiki.api.edit.js
M resources/src/mediawiki.api/mediawiki.api.upload.js
2 files changed, 43 insertions(+), 77 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/03/232403/1
diff --git a/resources/src/mediawiki.api/mediawiki.api.edit.js
b/resources/src/mediawiki.api/mediawiki.api.edit.js
index dbe45bf..e6161e4 100644
--- a/resources/src/mediawiki.api/mediawiki.api.edit.js
+++ b/resources/src/mediawiki.api/mediawiki.api.edit.js
@@ -11,10 +11,11 @@
* cached token and start over.
*
* @param {Object} params API parameters
+ * @param {Object} [ajaxOptions]
* @return {jQuery.Promise} See #post
*/
- postWithEditToken: function ( params ) {
- return this.postWithToken( 'edit', params );
+ postWithEditToken: function ( params, ajaxOptions ) {
+ return this.postWithToken( 'edit', params, ajaxOptions
);
},
/**
diff --git a/resources/src/mediawiki.api/mediawiki.api.upload.js
b/resources/src/mediawiki.api/mediawiki.api.upload.js
index cec352a..43764a4 100644
--- a/resources/src/mediawiki.api/mediawiki.api.upload.js
+++ b/resources/src/mediawiki.api/mediawiki.api.upload.js
@@ -48,29 +48,6 @@
}
/**
- * Parse response from an XHR to the server.
- * @private
- * @param {Event} e
- * @return {Object}
- */
- function parseXHRResponse( e ) {
- var response;
-
- try {
- response = $.parseJSON( e.target.responseText );
- } catch ( error ) {
- response = {
- error: {
- code: e.target.code,
- info: e.target.responseText
- }
- };
- }
-
- return response;
- }
-
- /**
* Process the result of the form submission, returned to an iframe.
* This is the iframe's onload event.
*
@@ -116,20 +93,25 @@
* @return {jQuery.Promise}
*/
upload: function ( file, data ) {
- var iframe, formData;
+ var isFileInput, canUseFormData;
+
+ isFileInput = file.nodeType === Node.ELEMENT_NODE;
+
+ if ( formDataAvailable() && isFileInput && file.files )
{
+ file = file.files[0];
+ }
if ( !file ) {
return $.Deferred().reject( 'No file' );
}
- iframe = file.nodeType && file.nodeType ===
Node.ELEMENT_NODE;
- formData = formDataAvailable() && file instanceof
window.File;
+ canUseFormData = formDataAvailable() && file instanceof
window.File;
- if ( !iframe && !formData ) {
+ if ( !isFileInput && !canUseFormData ) {
return $.Deferred().reject( 'Unsupported
argument type passed to mw.Api.upload' );
}
- if ( formData ) {
+ if ( canUseFormData ) {
return this.uploadWithFormData( file, data );
}
@@ -242,11 +224,10 @@
* Uploads a file using the FormData API.
* @param {File} file
* @param {Object} data
+ * @return {jQuery.Promise}
*/
uploadWithFormData: function ( file, data ) {
- var key, xhr,
- api = this,
- formData = new FormData(),
+ var key,
deferred = $.Deferred();
for ( key in data ) {
@@ -256,58 +237,42 @@
}
data = $.extend( {}, this.defaults.parameters, {
action: 'upload' }, data );
-
- $.each( data, function ( key, val ) {
- formData.append( key, val );
- } );
+ data.file = file;
if ( !data.filename && !data.stash ) {
return $.Deferred().reject( 'Filename not
included in file data.' );
}
- formData.append( 'file', file );
-
- xhr = new XMLHttpRequest();
-
- xhr.upload.addEventListener( 'progress', function ( e )
{
- if ( e.lengthComputable ) {
- deferred.notify( e.loaded / e.total );
- }
- }, false );
-
- xhr.addEventListener( 'abort', function ( e ) {
- deferred.reject( parseXHRResponse( e ) );
- }, false );
-
- xhr.addEventListener( 'load', function ( e ) {
- var result = parseXHRResponse( e );
-
- if ( result.error || result.warnings ) {
- if ( result.error && result.error.code
=== 'badtoken' ) {
- api.badToken( 'edit' );
+ // Use this.postWithEditToken() or this.post()
+ this[ this.needToken() ? 'postWithEditToken' : 'post'
]( data, {
+ // Use FormData (if we got here, we know that
it's available)
+ contentType: 'multipart/form-data',
+ // Provide upload progress notifications
+ xhr: function () {
+ var xhr = $.ajaxSettings.xhr();
+ if ( xhr.upload ) {
+ // need to bind this event
before we open the connection (see note at
+ //
https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
+ xhr.upload.addEventListener(
'progress', function ( ev ) {
+ if (
ev.lengthComputable ) {
+
deferred.notify( ev.loaded / ev.total );
+ }
+ } );
}
-
- deferred.reject( result.error ||
result.warnings );
- } else {
- deferred.notify( 1 );
- deferred.resolve( result );
+ return xhr;
}
- }, false );
-
- xhr.addEventListener( 'error', function ( e ) {
- deferred.reject( parseXHRResponse( e ) );
- }, false );
-
- xhr.open( 'POST', this.defaults.ajax.url, true );
-
- if ( this.needToken() ) {
- this.getEditToken().then( function ( token ) {
- formData.append( 'token', token );
- xhr.send( formData );
+ } )
+ .done( function ( result ) {
+ if ( result.error || result.warnings ) {
+ deferred.reject( result.error
|| result.warnings );
+ } else {
+ deferred.notify( 1 );
+ deferred.resolve( result );
+ }
+ } )
+ .fail( function ( result ) {
+ deferred.reject( result );
} );
- } else {
- xhr.send( formData );
- }
return deferred.promise();
},
--
To view, visit https://gerrit.wikimedia.org/r/232403
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib9abe32ee3320c67ac0a4544c942b844a5550562
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits