2 * MediaWiki Widgets - MediaResourceProvider class.
4 * @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
5 * @license The MIT License (MIT); see LICENSE.txt
10 * MediaWiki media resource provider.
13 * @extends mw.widgets.APIResultsProvider
16 * @param {string} apiurl The API url
17 * @param {Object} [config] Configuration options
18 * @cfg {string} [scriptDirUrl] The url of the API script
20 mw
.widgets
.MediaResourceProvider
= function MwWidgetsMediaResourceProvider( apiurl
, config
) {
21 config
= config
|| {};
24 mw
.widgets
.MediaResourceProvider
.super.call( this, apiurl
, config
);
26 // Fetching configuration
27 this.scriptDirUrl
= config
.scriptDirUrl
;
28 this.isLocal
= config
.local
!== undefined;
31 this.setAPIurl( mw
.util
.wikiScript( 'api' ) );
33 // If 'apiurl' is set, use that. Otherwise, build the url
34 // from scriptDirUrl and /api.php suffix
35 this.setAPIurl( this.getAPIurl() || ( this.scriptDirUrl
+ '/api.php' ) );
38 this.siteInfoPromise
= null;
44 OO
.inheritClass( mw
.widgets
.MediaResourceProvider
, mw
.widgets
.APIResultsProvider
);
51 mw
.widgets
.MediaResourceProvider
.prototype.getStaticParams = function () {
55 mw
.widgets
.MediaResourceProvider
.super.prototype.getStaticParams
.call( this ),
58 iiprop
: 'dimensions|url|mediatype|extmetadata|timestamp|user',
59 iiextmetadatalanguage
: this.getLang(),
66 * Initialize the source and get the site info.
68 * Connect to the api url and retrieve the siteinfo parameters
69 * that are required for fetching results.
71 * @return {jQuery.Promise} Promise that resolves when the class
74 mw
.widgets
.MediaResourceProvider
.prototype.loadSiteInfo = function () {
77 if ( !this.siteInfoPromise
) {
78 this.siteInfoPromise
= new mw
.Api().get( {
82 .then( function ( data
) {
83 provider
.setImageSizes( data
.query
.general
.imagelimits
|| [] );
84 provider
.setThumbSizes( data
.query
.general
.thumblimits
|| [] );
85 provider
.setUserParams( {
86 // Standard width per resource
87 iiurlwidth
: provider
.getStandardWidth()
91 return this.siteInfoPromise
;
95 * Override parent method and get results from the source
97 * @param {number} [howMany] The number of items to pull from the API
98 * @return {jQuery.Promise} Promise that is resolved into an array
99 * of available results, or is rejected if no results are available.
101 mw
.widgets
.MediaResourceProvider
.prototype.getResults = function ( howMany
) {
106 return this.loadSiteInfo()
109 return $.Deferred().reject();
111 xhr
= provider
.fetchAPIresults( howMany
);
115 function ( results
) {
116 if ( !results
|| results
.length
=== 0 ) {
117 provider
.toggleDepleted( true );
122 // Process failed, return an empty promise
124 provider
.toggleDepleted( true );
125 return $.Deferred().resolve( [] );
128 .promise( { abort: function () {
137 * Get continuation API data
139 * @param {number} howMany The number of results to retrieve
140 * @return {Object} API request data
142 mw
.widgets
.MediaResourceProvider
.prototype.getContinueData = function () {
147 * Set continuation data for the next page
149 * @param {Object} continueData Continuation data
151 mw
.widgets
.MediaResourceProvider
.prototype.setContinue = function () {
157 * @param {Object[]} results API results
158 * @return {Object[]} Sorted results
160 mw
.widgets
.MediaResourceProvider
.prototype.sort = function ( results
) {
165 * Call the API for search results.
167 * @param {number} howMany The number of results to retrieve
168 * @return {jQuery.Promise} Promise that resolves with an array of objects that contain
171 mw
.widgets
.MediaResourceProvider
.prototype.fetchAPIresults = function ( howMany
) {
175 if ( !this.isValid() ) {
176 return $.Deferred().reject().promise( { abort
: $.noop
} );
179 api
= this.isLocal
? new mw
.Api() : new mw
.ForeignApi( this.getAPIurl(), { anonymous
: true } );
180 xhr
= api
.get( $.extend( {}, this.getStaticParams(), this.getUserParams(), this.getContinueData( howMany
) ) );
182 .then( function ( data
) {
183 var page
, newObj
, raw
,
187 provider
.toggleDepleted( true );
191 if ( data
.continue ) {
192 // Update the offset for next time
193 provider
.setContinue( data
.continue );
195 // This is the last available set of results. Mark as depleted!
196 provider
.toggleDepleted( true );
199 // If the source returned no results, it will not have a
202 raw
= data
.query
.pages
;
204 // Strip away the page ids
205 for ( page
in raw
) {
206 if ( !raw
[ page
].imageinfo
) {
207 // The search may give us pages that belong to the File:
208 // namespace but have no files in them, either because
209 // they were deleted or imported wrongly, or just started
210 // as pages. In that case, the response will not include
211 // imageinfo. Skip those files.
214 newObj
= raw
[ page
].imageinfo
[ 0 ];
215 newObj
.title
= raw
[ page
].title
;
216 newObj
.index
= raw
[ page
].index
;
217 results
.push( newObj
);
221 return provider
.sort( results
);
223 .promise( { abort
: xhr
.abort
} );
229 * @param {string} name
231 mw
.widgets
.MediaResourceProvider
.prototype.setName = function ( name
) {
238 * @return {string} name
240 mw
.widgets
.MediaResourceProvider
.prototype.getName = function () {
245 * Get standard width, based on the provider source's thumb sizes.
247 * @return {number|undefined} fetchWidth
249 mw
.widgets
.MediaResourceProvider
.prototype.getStandardWidth = function () {
250 return ( this.thumbSizes
&& this.thumbSizes
[ this.thumbSizes
.length
- 1 ] ) ||
251 ( this.imageSizes
&& this.imageSizes
[ 0 ] ) ||
252 // Fall back on a number
259 * @return {string} prop
261 mw
.widgets
.MediaResourceProvider
.prototype.getFetchProp = function () {
262 return this.fetchProp
;
268 * @param {string} prop
270 mw
.widgets
.MediaResourceProvider
.prototype.setFetchProp = function ( prop
) {
271 this.fetchProp
= prop
;
277 * @param {number[]} sizes Available thumbnail sizes
279 mw
.widgets
.MediaResourceProvider
.prototype.setThumbSizes = function ( sizes
) {
280 this.thumbSizes
= sizes
;
286 * @param {number[]} sizes Available image sizes
288 mw
.widgets
.MediaResourceProvider
.prototype.setImageSizes = function ( sizes
) {
289 this.imageSizes
= sizes
;
295 * @return {number[]} sizes Available thumbnail sizes
297 mw
.widgets
.MediaResourceProvider
.prototype.getThumbSizes = function () {
298 return this.thumbSizes
;
304 * @return {number[]} sizes Available image sizes
306 mw
.widgets
.MediaResourceProvider
.prototype.getImageSizes = function () {
307 return this.imageSizes
;
311 * Check if this source is valid.
313 * @return {boolean} Source is valid
315 mw
.widgets
.MediaResourceProvider
.prototype.isValid = function () {
316 return this.isLocal
||
317 // If we don't have either 'apiurl' or 'scriptDirUrl'
318 // the source is invalid, and we will skip it
319 this.apiurl
!== undefined ||
320 this.scriptDirUrl
!== undefined;
322 }( jQuery
, mediaWiki
) );