Merge "Respect undeclared command line options"
[lhc/web/wiklou.git] / resources / src / mediawiki / api.js
index 79aba77..10e0c56 100644 (file)
                // Keyed by ajax url and symbolic name for the individual request
                promises = {};
 
+       function mapLegacyToken( action ) {
+               // Legacy types for backward-compatibility with API action=tokens.
+               var csrfActions = [
+                       'edit',
+                       'delete',
+                       'protect',
+                       'move',
+                       'block',
+                       'unblock',
+                       'email',
+                       'import',
+                       'options'
+               ];
+               return $.inArray( action, csrfActions ) !== -1 ? 'csrf' : action;
+       }
+
        // Pre-populate with fake ajax promises to save http requests for tokens
        // we already have on the page via the user.tokens module (bug 34733).
        promises[ defaultOptions.ajax.url ] = {};
@@ -67,7 +83,6 @@
         *  each individual request by passing them to #get or #post (or directly #ajax) later on.
         */
        mw.Api = function ( options ) {
-               // TODO: Share API objects with exact same config.
                options = options || {};
 
                // Force a string if we got a mw.Uri object
                 */
                abort: function () {
                        $.each( this.requests, function ( index, request ) {
-                               request.abort();
+                               if ( request ) {
+                                       request.abort();
+                               }
                        } );
                },
 
                /**
                 * Perform API post request
                 *
-                * TODO: Post actions for non-local hostnames will need proxy.
-                *
                 * @param {Object} parameters
                 * @param {Object} [ajaxOptions]
                 * @return {jQuery.Promise}
                 *  Fail: Error code
                 */
                ajax: function ( parameters, ajaxOptions ) {
-                       var token,
+                       var token, requestIndex,
+                               api = this,
                                apiDeferred = $.Deferred(),
                                xhr, key, formData;
 
                                        }
                                } );
 
+                       requestIndex = this.requests.length;
                        this.requests.push( xhr );
+                       xhr.always( function () {
+                               api.requests[ requestIndex ] = null;
+                       } );
                        // Return the Promise
                        return apiDeferred.promise( { abort: xhr.abort } ).fail( function ( code, details ) {
                                if ( !( code === 'http' && details && details.textStatus === 'abort' ) ) {
                /**
                 * Get a token for a certain action from the API.
                 *
-                * The assert parameter is only for internal use by postWithToken.
+                * The assert parameter is only for internal use by #postWithToken.
                 *
-                * @param {string} type Token type
-                * @return {jQuery.Promise}
-                * @return {Function} return.done
-                * @return {string} return.done.token Received token.
                 * @since 1.22
+                * @param {string} type Token type
+                * @return {jQuery.Promise} Received token.
                 */
                getToken: function ( type, assert ) {
-                       var apiPromise,
-                               promiseGroup = promises[ this.defaults.ajax.url ],
-                               d = promiseGroup && promiseGroup[ type + 'Token' ];
+                       var apiPromise, promiseGroup, d;
+                       type = mapLegacyToken( type );
+                       promiseGroup = promises[ this.defaults.ajax.url ];
+                       d = promiseGroup && promiseGroup[ type + 'Token' ];
 
                        if ( !d ) {
-                               apiPromise = this.get( { action: 'tokens', type: type, assert: assert } );
-
+                               apiPromise = this.get( {
+                                       action: 'query',
+                                       meta: 'tokens',
+                                       type: type,
+                                       assert: assert
+                               } );
                                d = apiPromise
-                                       .then( function ( data ) {
-                                               if ( data.tokens && data.tokens[ type + 'token' ] ) {
-                                                       return data.tokens[ type + 'token' ];
+                                       .then( function ( res ) {
+                                               // If token type is unknown, it is omitted from the response
+                                               if ( !res.query.tokens[ type + 'token' ] ) {
+                                                       return $.Deferred().reject( 'token-missing', res );
                                                }
 
-                                               // If token type is not available for this user,
-                                               // key '...token' is either missing or set to boolean false
-                                               return $.Deferred().reject( 'token-missing', data );
+                                               return res.query.tokens[ type + 'token' ];
                                        }, function () {
                                                // Clear promise. Do not cache errors.
                                                delete promiseGroup[ type + 'Token' ];
+
                                                // Pass on to allow the caller to handle the error
                                                return this;
                                        } )
                 */
                badToken: function ( type ) {
                        var promiseGroup = promises[ this.defaults.ajax.url ];
+
+                       type = mapLegacyToken( type );
                        if ( promiseGroup ) {
                                delete promiseGroup[ type + 'Token' ];
                        }