Allow API endpoint customization for mw.widgets.TitleWidget
authorSanthosh Thottingal <santhosh.thottingal@gmail.com>
Fri, 25 Nov 2016 07:02:37 +0000 (12:32 +0530)
committerEd Sanders <esanders@wikimedia.org>
Mon, 28 Nov 2016 23:34:48 +0000 (23:34 +0000)
Currently the API is not customizable and always points to
current wiki's api returned by `new mw.Api()`.

This patch allows users to specify their own API object for
querying titles e.g. searching for titles on a different
language Wikipedia when translating pages.

Change-Id: I81811cdd1a0750a8335432eee8f971ab9e0b8ee7

resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js

index 39bee7c..2ac75c5 100755 (executable)
@@ -78,7 +78,7 @@
         * @inheritdoc mw.widgets.TitleWidget
         */
        mw.widgets.SearchInputWidget.prototype.getSuggestionsPromise = function () {
-               var api = new mw.Api(),
+               var api = this.getApi(),
                        promise,
                        self = this;
 
index e1e50ea..0e5e0c5 100644 (file)
@@ -6,16 +6,6 @@
  */
 ( function ( $, mw ) {
 
-       var interwikiPrefixesPromise = new mw.Api().get( {
-               action: 'query',
-               meta: 'siteinfo',
-               siprop: 'interwikimap'
-       } ).then( function ( data ) {
-               return $.map( data.query.interwikimap, function ( interwiki ) {
-                       return interwiki.prefix;
-               } );
-       } );
-
        /**
         * Mixin for title widgets
         *
@@ -36,6 +26,7 @@
         * @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).
         * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
+        * @cfg {mw.Api} [api] API object to use, creates a default mw.Api instance if not specified
         */
        mw.widgets.TitleWidget = function MwWidgetsTitleWidget( config ) {
                // Config initialization
@@ -56,6 +47,7 @@
                this.excludeCurrentPage = !!config.excludeCurrentPage;
                this.validateTitle = config.validateTitle !== undefined ? config.validateTitle : true;
                this.cache = config.cache;
+               this.api = config.api || new mw.Api();
 
                // Initialization
                this.$element.addClass( 'mw-widget-titleWidget' );
 
        OO.initClass( mw.widgets.TitleWidget );
 
+       /* Static properties */
+
+       mw.widgets.TitleWidget.static.interwikiPrefixesPromiseCache = {};
+
        /* Methods */
 
        /**
                this.namespace = namespace;
        };
 
+       mw.widgets.TitleWidget.prototype.getInterwikiPrefixesPromise = function () {
+               var api = this.getApi(),
+                       cache = this.constructor.static.interwikiPrefixesPromiseCache,
+                       key = api.defaults.ajax.url;
+               if ( !cache.hasOwnProperty( key ) ) {
+                       cache[ key ] = api.get( {
+                               action: 'query',
+                               meta: 'siteinfo',
+                               siprop: 'interwikimap'
+                       } ).then( function ( data ) {
+                               return $.map( data.query.interwikimap, function ( interwiki ) {
+                                       return interwiki.prefix;
+                               } );
+                       } );
+               }
+               return cache[ key ];
+       };
+
        /**
         * Get a promise which resolves with an API repsonse for suggested
         * links for the current query.
         */
        mw.widgets.TitleWidget.prototype.getSuggestionsPromise = function () {
                var req,
+                       api = this.getApi(),
                        query = this.getQueryValue(),
                        widget = this,
                        promiseAbortObject = { abort: function () {
                        } };
 
                if ( mw.Title.newFromText( query ) ) {
-                       return interwikiPrefixesPromise.then( function ( interwikiPrefixes ) {
+                       return this.getInterwikiPrefixesPromise().then( function ( interwikiPrefixes ) {
                                var params,
                                        interwiki = query.substring( 0, query.indexOf( ':' ) );
                                if (
                                                params.prop.push( 'pageterms' );
                                                params.wbptterms = 'description';
                                        }
-                                       req = new mw.Api().get( params );
+                                       req = api.get( params );
                                        promiseAbortObject.abort = req.abort.bind( req ); // TODO ew
                                        return req.then( function ( ret ) {
                                                if ( ret.query === undefined ) {
-                                                       ret = new mw.Api().get( { action: 'query', titles: query } );
+                                                       ret = api.get( { action: 'query', titles: query } );
                                                        promiseAbortObject.abort = ret.abort.bind( ret );
                                                }
                                                return ret;
                }
        };
 
+       /**
+        * Get the API object for title requests
+        *
+        * @return {mw.Api} MediaWiki API
+        */
+       mw.widgets.TitleWidget.prototype.getApi = function () {
+               return this.api;
+       };
+
        /**
         * Get option widgets from the server response
         *