Merge "Remove mention of IE9 support"
[lhc/web/wiklou.git] / resources / src / mediawiki.widgets / mw.widgets.TitleWidget.js
index 3a4581d..83a2612 100644 (file)
@@ -22,6 +22,7 @@
         * @cfg {boolean} [showRedirectTargets=true] Show the targets of redirects
         * @cfg {boolean} [showImages] Show page images
         * @cfg {boolean} [showDescriptions] Show page descriptions
+        * @cfg {boolean} [showMissing=true] Show missing pages
         * @cfg {boolean} [excludeCurrentPage] Exclude the current page from suggestions
         * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title (if set to true,
         *  the widget will marks itself red for invalid inputs, including an empty query).
                this.showRedirectTargets = config.showRedirectTargets !== false;
                this.showImages = !!config.showImages;
                this.showDescriptions = !!config.showDescriptions;
+               this.showMissing = config.showMissing !== false;
                this.excludeCurrentPage = !!config.excludeCurrentPage;
                this.validateTitle = config.validateTitle !== undefined ? config.validateTitle : true;
                this.cache = config.cache;
                this.api = config.api || new mw.Api();
+               // Supports: IE10, FF28, Chrome23
+               this.compare = window.Intl && Intl.Collator ?
+                       new Intl.Collator( mw.config.get( 'wgContentLanguage' ), { sensitivity: 'base' } ).compare :
+                       null;
 
                // Initialization
                this.$element.addClass( 'mw-widget-titleWidget' );
                                // Do nothing. This is just so OOUI doesn't break due to abort being undefined.
                        } };
 
-               if ( mw.Title.newFromText( query ) ) {
-                       return this.getInterwikiPrefixesPromise().then( function ( interwikiPrefixes ) {
-                               var params,
-                                       interwiki = query.substring( 0, query.indexOf( ':' ) );
-                               if (
-                                       interwiki && interwiki !== '' &&
-                                       interwikiPrefixes.indexOf( interwiki ) !== -1
-                               ) {
-                                       return $.Deferred().resolve( { query: {
-                                               pages: [ {
-                                                       title: query
-                                               } ]
-                                       } } ).promise( promiseAbortObject );
-                               } else {
-                                       params = {
-                                               action: 'query',
-                                               prop: [ 'info', 'pageprops' ],
-                                               generator: 'prefixsearch',
-                                               gpssearch: query,
-                                               gpsnamespace: widget.namespace !== null ? widget.namespace : undefined,
-                                               gpslimit: widget.limit,
-                                               ppprop: 'disambiguation'
-                                       };
-                                       if ( widget.showRedirectTargets ) {
-                                               params.redirects = true;
-                                       }
-                                       if ( widget.showImages ) {
-                                               params.prop.push( 'pageimages' );
-                                               params.pithumbsize = 80;
-                                               params.pilimit = widget.limit;
-                                       }
-                                       if ( widget.showDescriptions ) {
-                                               params.prop.push( 'pageterms' );
-                                               params.wbptterms = 'description';
-                                       }
-                                       req = api.get( params );
-                                       promiseAbortObject.abort = req.abort.bind( req ); // TODO ew
-                                       return req.then( function ( ret ) {
-                                               if ( ret.query === undefined ) {
-                                                       ret = api.get( { action: 'query', titles: query } );
-                                                       promiseAbortObject.abort = ret.abort.bind( ret );
-                                               }
-                                               return ret;
-                                       } );
-                               }
-                       } ).promise( promiseAbortObject );
-               } else {
+               if ( !mw.Title.newFromText( query ) ) {
                        // Don't send invalid titles to the API.
                        // Just pretend it returned nothing so we can show the 'invalid title' section
                        return $.Deferred().resolve( {} ).promise( promiseAbortObject );
                }
+
+               return this.getInterwikiPrefixesPromise().then( function ( interwikiPrefixes ) {
+                       var interwiki = query.substring( 0, query.indexOf( ':' ) );
+                       if (
+                               interwiki && interwiki !== '' &&
+                               interwikiPrefixes.indexOf( interwiki ) !== -1
+                       ) {
+                               return $.Deferred().resolve( { query: {
+                                       pages: [ {
+                                               title: query
+                                       } ]
+                               } } ).promise( promiseAbortObject );
+                       } else {
+                               req = api.get( widget.getApiParams( query ) );
+                               promiseAbortObject.abort = req.abort.bind( req ); // TODO ew
+                               return req.then( function ( ret ) {
+                                       if ( widget.showMissing && ret.query === undefined ) {
+                                               ret = api.get( { action: 'query', titles: query } );
+                                               promiseAbortObject.abort = ret.abort.bind( ret );
+                                       }
+                                       return ret;
+                               } );
+                       }
+               } ).promise( promiseAbortObject );
+       };
+
+       /**
+        * Get API params for a given query
+        *
+        * @param {string} query User query
+        * @return {Object} API params
+        */
+       mw.widgets.TitleWidget.prototype.getApiParams = function ( query ) {
+               var params = {
+                       action: 'query',
+                       prop: [ 'info', 'pageprops' ],
+                       generator: 'prefixsearch',
+                       gpssearch: query,
+                       gpsnamespace: this.namespace !== null ? this.namespace : undefined,
+                       gpslimit: this.limit,
+                       ppprop: 'disambiguation'
+               };
+               if ( this.showRedirectTargets ) {
+                       params.redirects = true;
+               }
+               if ( this.showImages ) {
+                       params.prop.push( 'pageimages' );
+                       params.pithumbsize = 80;
+                       params.pilimit = this.limit;
+               }
+               if ( this.showDescriptions ) {
+                       params.prop.push( 'pageterms' );
+                       params.wbptterms = 'description';
+               }
+               return params;
        };
 
        /**
 
                for ( index in data.pages ) {
                        suggestionPage = data.pages[ index ];
+
                        // When excludeCurrentPage is set, don't list the current page unless the user has type the full title
                        if ( this.excludeCurrentPage && suggestionPage.title === currentPageName && suggestionPage.title !== titleObj.getPrefixedText() ) {
                                continue;
                                imageUrl: OO.getProp( suggestionPage, 'thumbnail', 'source' ),
                                description: OO.getProp( suggestionPage, 'terms', 'description' ),
                                // Sort index
-                               index: suggestionPage.index
+                               index: suggestionPage.index,
+                               originalData: suggestionPage
                        };
 
                        // Throw away pages from wrong namespaces. This can happen when 'showRedirectTargets' is true
                                        disambiguation: false,
                                        description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title ),
                                        // Sort index, just below its target
-                                       index: suggestionPage.index + 0.5
+                                       index: suggestionPage.index + 0.5,
+                                       originalData: suggestionPage
                                };
                                titles.push( redirects[ i ] );
                        }
                } );
 
                // If not found, run value through mw.Title to avoid treating a match as a
-               // mismatch where normalisation would make them matching (bug 48476)
+               // mismatch where normalisation would make them matching (T50476)
 
                pageExistsExact = (
                        Object.prototype.hasOwnProperty.call( pageData, this.getQueryValue() ) &&
 
                for ( i = 0, len = titles.length; i < len; i++ ) {
                        page = pageData[ titles[ i ] ] || {};
-                       items.push( new mw.widgets.TitleOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
+                       items.push( this.createOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
                }
 
                return items;
        };
 
+       /**
+        * Create a menu option widget with specified data
+        *
+        * @param {Object} data Data for option widget
+        * @return {OO.ui.MenuOptionWidget} Data for option widget
+        */
+       mw.widgets.TitleWidget.prototype.createOptionWidget = function ( data ) {
+               return new mw.widgets.TitleOptionWidget( data );
+       };
+
        /**
         * Get menu option widget data from the title and page data
         *
                                mwTitle.getRelativeText( this.namespace ) :
                                title,
                        url: mwTitle.getUrl(),
+                       showImages: this.showImages,
                        imageUrl: this.showImages ? data.imageUrl : null,
                        description: this.showDescriptions ? description : null,
                        missing: data.missing,
                        redirect: data.redirect,
                        disambiguation: data.disambiguation,
-                       query: this.getQueryValue()
+                       query: this.getQueryValue(),
+                       compare: this.compare
                };
        };