Merge "Widgets: Allow titles with name of Object.prototypes"
[lhc/web/wiklou.git] / resources / src / mediawiki.widgets / mw.widgets.TitleWidget.js
index db56bd3..190962c 100644 (file)
@@ -5,6 +5,7 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 ( function ( $, mw ) {
+       var hasOwn = Object.prototype.hasOwnProperty;
 
        /**
         * Mixin for title widgets
@@ -22,6 +23,8 @@
         * @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} [addQueryInput=true] Add exact user's input query to results
         * @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).
@@ -44,6 +47,8 @@
                this.showRedirectTargets = config.showRedirectTargets !== false;
                this.showImages = !!config.showImages;
                this.showDescriptions = !!config.showDescriptions;
+               this.showMissing = config.showMissing !== false;
+               this.addQueryInput = config.addQueryInput !== false;
                this.excludeCurrentPage = !!config.excludeCurrentPage;
                this.validateTitle = config.validateTitle !== undefined ? config.validateTitle : true;
                this.cache = config.cache;
                                // 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 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 ( 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 );
        };
 
        /**
 
                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;
                                titles.push( suggestionPage.title );
                        }
 
-                       redirects = redirectsTo[ suggestionPage.title ] || [];
+                       redirects = hasOwn.call( redirectsTo, suggestionPage.title ) ? redirectsTo[ suggestionPage.title ] : [];
                        for ( i = 0, len = redirects.length; i < len; i++ ) {
                                pageData[ redirects[ i ] ] = {
                                        missing: false,
                // mismatch where normalisation would make them matching (T50476)
 
                pageExistsExact = (
-                       Object.prototype.hasOwnProperty.call( pageData, this.getQueryValue() ) &&
+                       hasOwn.call( pageData, this.getQueryValue() ) &&
                        (
                                !pageData[ this.getQueryValue() ].missing ||
                                pageData[ this.getQueryValue() ].known
                );
                pageExists = pageExistsExact || (
                        titleObj &&
-                       Object.prototype.hasOwnProperty.call( pageData, titleObj.getPrefixedText() ) &&
+                       hasOwn.call( pageData, titleObj.getPrefixedText() ) &&
                        (
                                !pageData[ titleObj.getPrefixedText() ].missing ||
                                pageData[ titleObj.getPrefixedText() ].known
                }
 
                // Offer the exact text as a suggestion if the page exists
-               if ( pageExists && !pageExistsExact ) {
+               if ( this.addQueryInput && pageExists && !pageExistsExact ) {
                        titles.unshift( this.getQueryValue() );
                }
 
                for ( i = 0, len = titles.length; i < len; i++ ) {
-                       page = pageData[ titles[ i ] ] || {};
+                       page = hasOwn.call( pageData, titles[ i ] ) ? pageData[ titles[ i ] ] : {};
                        items.push( this.createOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
                }
 
         * @param {string} [value] Value to get a title for
         * @return {mw.Title|null} Title object, or null if value is invalid
         */
-       mw.widgets.TitleWidget.prototype.getTitle = function ( value ) {
+       mw.widgets.TitleWidget.prototype.getMWTitle = function ( value ) {
                var title = value !== undefined ? value : this.getQueryValue(),
                        // mw.Title doesn't handle null well
                        titleObj = mw.Title.newFromText( title, this.namespace !== null ? this.namespace : undefined );
         * @return {boolean} The query is valid
         */
        mw.widgets.TitleWidget.prototype.isQueryValid = function () {
-               return this.validateTitle ? !!this.getTitle() : true;
+               return this.validateTitle ? !!this.getMWTitle() : true;
        };
 
 }( jQuery, mediaWiki ) );