mw.special.apisandbox: Offer to fill in token when not given
authorBartosz Dziewoński <matma.rex@gmail.com>
Fri, 3 Mar 2017 20:32:49 +0000 (21:32 +0100)
committerBartosz Dziewoński <matma.rex@gmail.com>
Tue, 24 Apr 2018 14:36:50 +0000 (16:36 +0200)
Change-Id: I53c414f0a80ce76907d3293971a47e87aa67fb06

resources/src/mediawiki.special/mediawiki.special.apisandbox.js

index a7470da..16a93d1 100644 (file)
                                deferreds = [],
                                paramsAreForced = !!params,
                                displayParams = {},
+                               tokenWidgets = [],
                                checkPages = [ pages.main ];
 
                        // Blur any focused widget before submit, because
                        params = {};
                        while ( checkPages.length ) {
                                page = checkPages.shift();
-                               deferreds.push( page.apiCheckValid() );
+                               if ( page.tokenWidget ) {
+                                       tokenWidgets.push( page.tokenWidget );
+                               }
+                               deferreds = deferreds.concat( page.apiCheckValid() );
                                page.getQueryParams( params, displayParams );
                                subpages = page.getSubpages();
                                for ( i = 0; i < subpages.length; i++ ) {
                        }
 
                        $.when.apply( $, deferreds ).done( function () {
-                               var formatItems, menu, selectedLabel;
+                               var formatItems, menu, selectedLabel, deferred, actions, errorCount;
+
+                               // Count how many times `value` occurs in `array`.
+                               function countValues( value, array ) {
+                                       var count, i;
+                                       count = 0;
+                                       for ( i = 0; i < array.length; i++ ) {
+                                               if ( array[ i ] === value ) {
+                                                       count++;
+                                               }
+                                       }
+                                       return count;
+                               }
 
-                               if ( $.inArray( false, arguments ) !== -1 ) {
-                                       windowManager.openWindow( 'errorAlert', {
-                                               title: Util.parseMsg( 'apisandbox-submit-invalid-fields-title' ),
-                                               message: Util.parseMsg( 'apisandbox-submit-invalid-fields-message' ),
-                                               actions: [
-                                                       {
-                                                               action: 'accept',
-                                                               label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
-                                                               flags: 'primary'
+                               errorCount = countValues( false, arguments );
+                               if ( errorCount > 0 ) {
+                                       actions = [
+                                               {
+                                                       action: 'accept',
+                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                       flags: 'primary'
+                                               }
+                                       ];
+                                       if ( tokenWidgets.length ) {
+                                               // Check all token widgets' validity separately
+                                               deferred = $.when.apply( $, tokenWidgets.map( function ( w ) {
+                                                       return w.apiCheckValid();
+                                               } ) );
+
+                                               deferred.done( function () {
+                                                       // If only the tokens are invalid, offer to fix them
+                                                       var tokenErrorCount = countValues( false, arguments );
+                                                       if ( tokenErrorCount === errorCount ) {
+                                                               delete actions[ 0 ].flags;
+                                                               actions.push( {
+                                                                       action: 'fix',
+                                                                       label: mw.message( 'apisandbox-results-fixtoken' ).text(),
+                                                                       flags: 'primary'
+                                                               } );
                                                        }
-                                               ]
+                                               } );
+                                       } else {
+                                               deferred = $.Deferred().resolve();
+                                       }
+                                       deferred.always( function () {
+                                               windowManager.openWindow( 'errorAlert', {
+                                                       title: Util.parseMsg( 'apisandbox-submit-invalid-fields-title' ),
+                                                       message: Util.parseMsg( 'apisandbox-submit-invalid-fields-message' ),
+                                                       actions: actions
+                                               } ).closed.then( function ( data ) {
+                                                       if ( data && data.action === 'fix' ) {
+                                                               ApiSandbox.fixTokenAndResend();
+                                                       }
+                                               } );
                                        } );
                                        return;
                                }
        /**
         * Check that all widgets on the page are in a valid state.
         *
-        * @return {boolean}
+        * @return {jQuery.Promise[]} One promise for each widget, resolved with `false` if invalid
         */
        ApiSandbox.PageLayout.prototype.apiCheckValid = function () {
-               var that = this;
+               var promises, that = this;
 
                if ( this.paramInfo === null ) {
-                       return $.Deferred().resolve( false ).promise();
+                       return [];
                } else {
-                       return $.when.apply( $, $.map( this.widgets, function ( widget ) {
+                       promises = $.map( this.widgets, function ( widget ) {
                                return widget.apiCheckValid();
-                       } ) ).then( function () {
+                       } );
+                       $.when.apply( $, promises ).then( function () {
                                that.apiIsValid = $.inArray( false, arguments ) === -1;
                                if ( that.getOutlineItem() ) {
                                        that.getOutlineItem().setIcon( that.apiIsValid || suppressErrors ? null : 'alert' );
                                                that.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
                                        );
                                }
-                               return $.Deferred().resolve( that.apiIsValid ).promise();
                        } );
+                       return promises;
                }
        };