summaryrefslogtreecommitdiff
path: root/resources/mediawiki.api/mediawiki.api.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/mediawiki.api/mediawiki.api.js')
-rw-r--r--resources/mediawiki.api/mediawiki.api.js133
1 files changed, 79 insertions, 54 deletions
diff --git a/resources/mediawiki.api/mediawiki.api.js b/resources/mediawiki.api/mediawiki.api.js
index 225093b3..a184e3ca 100644
--- a/resources/mediawiki.api/mediawiki.api.js
+++ b/resources/mediawiki.api/mediawiki.api.js
@@ -1,6 +1,7 @@
-/* mw.Api objects represent the API of a particular MediaWiki server. */
-
-( function( $, mw, undefined ) {
+/**
+ * mw.Api objects represent the API of a particular MediaWiki server.
+ */
+( function ( mw, $ ) {
/**
* @var defaultOptions {Object}
@@ -21,14 +22,7 @@
ajax: {
url: mw.util.wikiScript( 'api' ),
- ok: function() {},
-
- // caller can supply handlers for http transport error or api errors
- err: function( code, result ) {
- mw.log( 'mw.Api error: ' + code, 'debug' );
- },
-
- timeout: 30000, // 30 seconds
+ timeout: 30 * 1000, // 30 seconds
dataType: 'json'
}
@@ -53,7 +47,7 @@
* @param options {Object} See defaultOptions documentation above. Ajax options can also be
* overridden for each individual request to jQuery.ajax() later on.
*/
- mw.Api = function( options ) {
+ mw.Api = function ( options ) {
if ( options === undefined ) {
options = {};
@@ -73,34 +67,31 @@
mw.Api.prototype = {
/**
- * For api queries, in simple cases the caller just passes a success callback.
- * In complex cases they pass an object with a success property as callback and
- * probably other options.
- * Normalize the argument so that it's always the latter case.
+ * Normalize the ajax options for compatibility and/or convenience methods.
*
- * @param {Object|Function} An object contaning one or more of options.ajax,
+ * @param {undefined|Object|Function} An object contaning one or more of options.ajax,
* or just a success function (options.ajax.ok).
* @return {Object} Normalized ajax options.
*/
- normalizeAjaxOptions: function( arg ) {
- var opt = arg;
+ normalizeAjaxOptions: function ( arg ) {
+ // Arg argument is usually empty
+ // (before MW 1.20 it was often used to pass ok/err callbacks)
+ var opts = arg || {};
+ // Options can also be a success callback handler
if ( typeof arg === 'function' ) {
- opt = { 'ok': arg };
+ opts = { ok: arg };
}
- if ( !opt.ok ) {
- throw new Error( 'ajax options must include ok callback' );
- }
- return opt;
+ return opts;
},
/**
* Perform API get request
*
* @param {Object} request parameters
- * @param {Object|Function} ajax options, or just a success function
- * @return {jqXHR}
+ * @param {Object|Function} [optional] ajax options
+ * @return {jQuery.Promise}
*/
- get: function( parameters, ajaxOptions ) {
+ get: function ( parameters, ajaxOptions ) {
ajaxOptions = this.normalizeAjaxOptions( ajaxOptions );
ajaxOptions.type = 'GET';
return this.ajax( parameters, ajaxOptions );
@@ -111,10 +102,10 @@
* @todo Post actions for nonlocal will need proxy
*
* @param {Object} request parameters
- * @param {Object|Function} ajax options, or just a success function
- * @return {jqXHR}
+ * @param {Object|Function} [optional] ajax options
+ * @return {jQuery.Promise}
*/
- post: function( parameters, ajaxOptions ) {
+ post: function ( parameters, ajaxOptions ) {
ajaxOptions = this.normalizeAjaxOptions( ajaxOptions );
ajaxOptions.type = 'POST';
return this.ajax( parameters, ajaxOptions );
@@ -125,39 +116,72 @@
*
* @param {Object} request parameters
* @param {Object} ajax options
- * @return {jqXHR}
+ * @return {jQuery.Promise}
+ * - done: API response data as first argument
+ * - fail: errorcode as first arg, details (string or object) as second arg.
*/
- ajax: function( parameters, ajaxOptions ) {
+ ajax: function ( parameters, ajaxOptions ) {
+ var token,
+ apiDeferred = $.Deferred();
+
parameters = $.extend( {}, this.defaults.parameters, parameters );
ajaxOptions = $.extend( {}, this.defaults.ajax, ajaxOptions );
+ // Ensure that token parameter is last (per [[mw:API:Edit#Token]]).
+ if ( parameters.token ) {
+ token = parameters.token;
+ delete parameters.token;
+ }
// Some deployed MediaWiki >= 1.17 forbid periods in URLs, due to an IE XSS bug
// So let's escape them here. See bug #28235
// This works because jQuery accepts data as a query string or as an Object
ajaxOptions.data = $.param( parameters ).replace( /\./g, '%2E' );
- ajaxOptions.error = function( xhr, textStatus, exception ) {
- ajaxOptions.err( 'http', {
- xhr: xhr,
- textStatus: textStatus,
- exception: exception
+ // If we extracted a token parameter, add it back in.
+ if ( token ) {
+ ajaxOptions.data += '&token=' + encodeURIComponent( token );
+ }
+
+ // Backwards compatibility: Before MediaWiki 1.20,
+ // callbacks were done with the 'ok' and 'err' property in ajaxOptions.
+ if ( ajaxOptions.ok ) {
+ apiDeferred.done( ajaxOptions.ok );
+ delete ajaxOptions.ok;
+ }
+ if ( ajaxOptions.err ) {
+ apiDeferred.fail( ajaxOptions.err );
+ delete ajaxOptions.err;
+ }
+
+ // Make the AJAX request
+ $.ajax( ajaxOptions )
+ // If AJAX fails, reject API call with error code 'http'
+ // and details in second argument.
+ .fail( function ( xhr, textStatus, exception ) {
+ apiDeferred.reject( 'http', {
+ xhr: xhr,
+ textStatus: textStatus,
+ exception: exception
+ } );
+ } )
+ // AJAX success just means "200 OK" response, also check API error codes
+ .done( function ( result ) {
+ if ( result === undefined || result === null || result === '' ) {
+ apiDeferred.reject( 'ok-but-empty',
+ 'OK response but empty result (check HTTP headers?)'
+ );
+ } else if ( result.error ) {
+ var code = result.error.code === undefined ? 'unknown' : result.error.code;
+ apiDeferred.reject( code, result );
+ } else {
+ apiDeferred.resolve( result );
+ }
} );
- };
-
- // Success just means 200 OK; also check for output and API errors
- ajaxOptions.success = function( result ) {
- if ( result === undefined || result === null || result === '' ) {
- ajaxOptions.err( 'ok-but-empty',
- 'OK response but empty result (check HTTP headers?)' );
- } else if ( result.error ) {
- var code = result.error.code === undefined ? 'unknown' : result.error.code;
- ajaxOptions.err( code, result );
- } else {
- ajaxOptions.ok( result );
- }
- };
-
- return $.ajax( ajaxOptions );
+
+ // Return the Promise
+ return apiDeferred.promise().fail( function ( code, details ) {
+ mw.log( 'mw.Api error: ', code, details );
+ });
}
};
@@ -197,6 +221,7 @@
'file-too-large',
'filetype-missing',
'filetype-banned',
+ 'filetype-banned-type',
'filename-tooshort',
'illegal-filename',
'verification-error',
@@ -221,4 +246,4 @@
'exists'
];
-})( jQuery, mediaWiki );
+}( mediaWiki, jQuery ) );