2 * MediaWiki Widgets - APIResultsQueue class.
4 * @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org
9 * @classdesc API results queue.
12 * @mixes OO.EventEmitter
15 * @param {Object} [config] Configuration options
16 * @param {number} config.limit The default number of results to fetch
17 * @param {number} config.threshold The default number of extra results
18 * that the queue should always strive to have on top of the
19 * individual requests for items.
21 mw.widgets.APIResultsQueue = function MwWidgetsAPIResultsQueue( config ) {
22 config = config || {};
24 this.fileRepoPromise = null;
26 this.providerPromises = [];
31 this.limit = config.limit || 20;
32 this.setThreshold( config.threshold || 10 );
35 OO.EventEmitter.call( this );
39 OO.mixinClass( mw.widgets.APIResultsQueue, OO.EventEmitter );
44 * Set up the queue and its resources.
45 * This should be overridden if there are any setup steps to perform.
47 * @return {jQuery.Promise} Promise that resolves when the resources
48 * are set up. Note: The promise must have an .abort() functionality.
50 mw.widgets.APIResultsQueue.prototype.setup = function () {
51 return $.Deferred().resolve().promise( { abort: function () {} } );
55 * Get items from the queue.
57 * @param {number} [howMany] How many items to retrieve. Defaults to the
58 * default limit supplied on initialization.
59 * @return {jQuery.Promise} Promise that resolves into an array of items.
61 mw.widgets.APIResultsQueue.prototype.get = function ( howMany ) {
62 let fetchingPromise = null;
64 howMany = howMany || this.limit;
66 // Check if the queue has enough items
67 if ( this.queue.length < howMany + this.threshold ) {
68 // Call for more results
69 fetchingPromise = this.queryProviders( howMany + this.threshold )
72 this.queue = this.queue.concat.apply( this.queue, items );
76 return $.when( fetchingPromise )
77 .then( () => this.queue.splice( 0, howMany ) );
82 * Get results from all providers.
84 * @param {number} [howMany] How many items to retrieve. Defaults to the
85 * default limit supplied on initialization.
86 * @return {jQuery.Promise} Promise that is resolved into an array
87 * of fetched items. Note: The promise must have an .abort() functionality.
89 mw.widgets.APIResultsQueue.prototype.queryProviders = function ( howMany ) {
90 // Make sure there are resources set up
93 // Abort previous requests
94 for ( let i = 0, iLen = this.providerPromises.length; i < iLen; i++ ) {
95 this.providerPromises[ i ].abort();
97 this.providerPromises = [];
98 // Set up the query to all providers
99 for ( let j = 0, jLen = this.providers.length; j < jLen; j++ ) {
100 if ( !this.providers[ j ].isDepleted() ) {
101 this.providerPromises.push(
102 this.providers[ j ].getResults( howMany )
107 return $.when( ...this.providerPromises )
108 .then( Array.prototype.concat.bind( [] ) );
113 * Set the search query for all the providers.
115 * This also makes sure to abort any previous promises.
117 * @param {Object} params API search parameters
119 mw.widgets.APIResultsQueue.prototype.setParams = function ( params ) {
120 if ( !OO.compare( params, this.params, true ) ) {
122 this.params = Object.assign( this.params, params );
126 for ( let i = 0, iLen = this.providerPromises.length; i < iLen; i++ ) {
127 this.providerPromises[ i ].abort();
130 for ( let j = 0, jLen = this.providers.length; j < jLen; j++ ) {
131 this.providers[ j ].setUserParams( this.params );
137 * Reset the queue and all its providers.
139 mw.widgets.APIResultsQueue.prototype.reset = function () {
143 for ( let i = 0, iLen = this.providerPromises.length; i < iLen; i++ ) {
144 this.providerPromises[ i ].abort();
147 for ( let j = 0, jLen = this.providers.length; j < jLen; j++ ) {
148 this.providers[ j ].reset();
153 * Get the data parameters sent to the API.
155 * @return {Object} params API search parameters
157 mw.widgets.APIResultsQueue.prototype.getParams = function () {
164 * @param {mw.widgets.APIResultsProvider[]} providers An array of providers
166 mw.widgets.APIResultsQueue.prototype.setProviders = function ( providers ) {
167 this.providers = providers;
168 for ( let i = 0, len = this.providers.length; i < len; i++ ) {
169 this.providers[ i ].setUserParams( this.params );
170 this.providers[ i ].setLang( this.lang );
175 * Add a provider to the group.
177 * @param {mw.widgets.APIResultsProvider} provider A provider object
179 mw.widgets.APIResultsQueue.prototype.addProvider = function ( provider ) {
180 this.providers.push( provider );
181 provider.setUserParams( this.params );
182 provider.setLang( this.lang );
188 * @return {mw.widgets.APIResultsProvider[]} providers An array of providers
190 mw.widgets.APIResultsQueue.prototype.getProviders = function () {
191 return this.providers;
195 * Get the queue size.
197 * @return {number} Queue size
199 mw.widgets.APIResultsQueue.prototype.getQueueSize = function () {
200 return this.queue.length;
204 * Set queue threshold.
206 * @param {number} threshold Queue threshold, below which we will
209 mw.widgets.APIResultsQueue.prototype.setThreshold = function ( threshold ) {
210 this.threshold = threshold;
214 * Get queue threshold.
216 * @return {number} threshold Queue threshold, below which we will
219 mw.widgets.APIResultsQueue.prototype.getThreshold = function () {
220 return this.threshold;
224 * Set language for the query results.
226 * @param {string|undefined} lang Language
228 mw.widgets.APIResultsQueue.prototype.setLang = function ( lang ) {
230 for ( let i = 0, len = this.providers.length; i < len; i++ ) {
231 this.providers[ i ].setLang( this.lang );
236 * Get language for the query results.
238 * @return {string|undefined} lang Language
240 mw.widgets.APIResultsQueue.prototype.getLang = function () {