Merge "TraditionalImageGallery factor getCaptionHtml into own function"
[lhc/web/wiklou.git] / resources / src / mediawiki.special / mediawiki.special.apisandbox.js
index df87c9c..009f47b 100644 (file)
                 * @return {OO.ui.Widget}
                 */
                createWidgetForParameter: function ( pi, opts ) {
-                       var widget, innerWidget, finalWidget, items, $button, $content, func,
-                               multiMode = 'none';
+                       var widget, innerWidget, finalWidget, items, $content, func,
+                               multiModeButton = null,
+                               multiModeInput = null,
+                               multiModeAllowed = false;
 
                        opts = opts || {};
 
                                        $.extend( widget, WidgetMethods.textInputWidget );
                                        $.extend( widget, WidgetMethods.passwordWidget );
                                        widget.setValidation( Validators.generic );
-                                       multiMode = 'enter';
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
                                        break;
 
                                case 'integer':
                                        if ( Util.apiBool( pi.enforcerange ) ) {
                                                widget.setRange( pi.min || -Infinity, pi.max || Infinity );
                                        }
-                                       multiMode = 'enter';
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
                                        break;
 
                                case 'limit':
                                        pi.apiSandboxMax = mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max;
                                        widget.paramInfo = pi;
                                        $.extend( widget, WidgetMethods.textInputWidget );
-                                       multiMode = 'enter';
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
                                        break;
 
                                case 'timestamp':
                                        widget.paramInfo = pi;
                                        $.extend( widget, WidgetMethods.textInputWidget );
                                        $.extend( widget, WidgetMethods.dateTimeInputWidget );
-                                       multiMode = 'indicator';
+                                       multiModeAllowed = true;
                                        break;
 
                                case 'upload':
                                        break;
                        }
 
-                       if ( Util.apiBool( pi.multi ) && multiMode !== 'none' ) {
+                       if ( Util.apiBool( pi.multi ) && multiModeAllowed ) {
                                innerWidget = widget;
-                               switch ( multiMode ) {
-                                       case 'enter':
-                                               $content = innerWidget.$element;
-                                               break;
-
-                                       case 'indicator':
-                                               $button = innerWidget.$indicator;
-                                               $button.css( 'cursor', 'pointer' );
-                                               $button.attr( 'tabindex', 0 );
-                                               $button.parent().append( $button );
-                                               innerWidget.setIndicator( 'next' );
-                                               $content = innerWidget.$element;
-                                               break;
-
-                                       default:
-                                               throw new Error( 'Unknown multiMode "' + multiMode + '"' );
-                               }
+
+                               multiModeButton = new OO.ui.ButtonWidget( {
+                                       label: mw.message( 'apisandbox-add-multi' ).text()
+                               } );
+                               $content = innerWidget.$element.add( multiModeButton.$element );
 
                                widget = new OO.ui.PopupTagMultiselectWidget( {
                                        allowArbitrary: true,
                                        $overlay: true,
                                        popup: {
                                                classes: [ 'mw-apisandbox-popup' ],
+                                               padded: true,
                                                $content: $content
                                        }
                                } );
                                                return false;
                                        }
                                };
-                               switch ( multiMode ) {
-                                       case 'enter':
-                                               innerWidget.connect( null, { enter: func } );
-                                               break;
-
-                                       case 'indicator':
-                                               $button.on( {
-                                                       click: func,
-                                                       keypress: function ( e ) {
-                                                               if ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) {
-                                                                       func();
-                                                               }
-                                                       }
-                                               } );
-                                               break;
+
+                               if ( multiModeInput ) {
+                                       multiModeInput.on( 'enter', func );
                                }
+                               multiModeButton.on( 'click', func );
                        }
 
                        if ( Util.apiBool( pi.required ) || opts.nooptional ) {
                                ApiSandbox.updateUI();
                        }
 
-                       // If the hashchange event exists, use it. Otherwise, fake it.
-                       // And, of course, IE has to be dumb.
-                       if ( 'onhashchange' in window &&
-                               ( document.documentMode === undefined || document.documentMode >= 8 )
-                       ) {
-                               $( window ).on( 'hashchange', ApiSandbox.loadFromHash );
-                       } else {
-                               setInterval( function () {
-                                       if ( oldhash !== location.hash ) {
-                                               ApiSandbox.loadFromHash();
-                                       }
-                               }, 1000 );
-                       }
+                       $( window ).on( 'hashchange', ApiSandbox.loadFromHash );
 
                        $content
                                .empty()
                                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;
                }
        };