mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 14:33:59 +00:00
Merge "Use image sources from the fileRepo API"
This commit is contained in:
commit
6e21afb908
|
@ -23,11 +23,6 @@ ve.init.mw.Platform = function VeInitMwPlatform() {
|
|||
this.externalLinkUrlProtocolsRegExp = new RegExp( '^' + mw.config.get( 'wgUrlProtocols' ) );
|
||||
this.modulesUrl = mw.config.get( 'wgExtensionAssetsPath' ) + '/VisualEditor/modules';
|
||||
this.parsedMessages = {};
|
||||
this.mediaSources = [
|
||||
//TODO: Bug 50673
|
||||
{ 'url': mw.util.wikiScript( 'api' ) },
|
||||
{ 'url': '//commons.wikimedia.org/w/api.php' }
|
||||
];
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -92,16 +87,6 @@ ve.init.mw.Platform.prototype.getUserLanguages = function () {
|
|||
return langs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of URLs to MediaWiki API entry points where media can be found.
|
||||
*
|
||||
* @method
|
||||
* @returns {string[]} API URLs
|
||||
*/
|
||||
ve.init.mw.Platform.prototype.getMediaSources = function () {
|
||||
return this.mediaSources;
|
||||
};
|
||||
|
||||
/* Initialization */
|
||||
|
||||
ve.init.platform = new ve.init.mw.Platform();
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/*global mw */
|
||||
|
||||
/**
|
||||
* Dialog for inserting MediaWiki media objects.
|
||||
*
|
||||
|
@ -24,6 +26,7 @@ ve.ui.MWMediaInsertDialog = function VeUiMWMediaInsertDialog( windowSet, config
|
|||
|
||||
// Properties
|
||||
this.item = null;
|
||||
this.sources = {};
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -59,15 +62,21 @@ ve.ui.MWMediaInsertDialog.prototype.initialize = function () {
|
|||
// Parent method
|
||||
ve.ui.MWDialog.prototype.initialize.call( this );
|
||||
|
||||
// Properties
|
||||
this.search = new ve.ui.MWMediaSearchWidget( { '$': this.$ } );
|
||||
// Widget
|
||||
this.search = new ve.ui.MWMediaSearchWidget( {
|
||||
'$': this.$
|
||||
} );
|
||||
|
||||
// Initialization
|
||||
this.search.$element.addClass( 've-ui-mwMediaInsertDialog-select' );
|
||||
|
||||
// Events
|
||||
this.search.connect( this, { 'select': 'onSearchSelect' } );
|
||||
|
||||
// Initialization
|
||||
this.search.$element.addClass( 've-ui-mwMediaInsertDialog-select' );
|
||||
this.$spinner = this.$( '<div>' ).addClass( 've-specialchar-spinner' );
|
||||
this.$body.append( this.$spinner );
|
||||
this.$body.append( this.search.$element );
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -77,10 +86,82 @@ ve.ui.MWMediaInsertDialog.prototype.setup = function ( data ) {
|
|||
// Parent method
|
||||
ve.ui.MWDialog.prototype.setup.call( this, data );
|
||||
|
||||
// Initialization
|
||||
this.search.getQuery().$input.focus().select();
|
||||
this.search.getResults().selectItem();
|
||||
this.search.getResults().highlightItem();
|
||||
// Show a spinner while we check for file repos.
|
||||
// this will only be done once per session.
|
||||
//
|
||||
// This is in .setup rather than .initialize so that
|
||||
// the user has visual indication (spinner) during the
|
||||
// ajax request
|
||||
this.$spinner.show();
|
||||
this.search.$element.hide();
|
||||
|
||||
// Get the repos from the API first
|
||||
// The ajax request will only be done once per session
|
||||
this.getFileRepos().done( ve.bind( function ( repos ) {
|
||||
if ( repos ) {
|
||||
this.sources = repos;
|
||||
this.search.setSources( this.sources );
|
||||
}
|
||||
// Done, hide the spinner
|
||||
this.$spinner.hide();
|
||||
|
||||
// Show the search and query the media sources
|
||||
this.search.$element.show();
|
||||
this.search.queryMediaSources();
|
||||
|
||||
// Initialization
|
||||
// This must be done only after there are proper
|
||||
// sources defined
|
||||
this.search.getQuery().$input.focus().select();
|
||||
this.search.getResults().selectItem();
|
||||
this.search.getResults().highlightItem();
|
||||
}, this ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the object of file repos to use for the media search
|
||||
* @returns {jQuery.Promise}
|
||||
*/
|
||||
ve.ui.MWMediaInsertDialog.prototype.getFileRepos = function () {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// We will only ask for the ajax call if this.sources
|
||||
// isn't already set up
|
||||
if ( $.isEmptyObject( this.sources ) ) {
|
||||
// Take sources from api.php?action=query&meta=filerepoinfo&format=jsonfm
|
||||
// The decision whether to take 'url' or 'apiurl' per each repository is made
|
||||
// in the MWMediaSearchWidget depending on whether it is local and has apiurl
|
||||
// defined at all.
|
||||
$.ajax( {
|
||||
'url': mw.util.wikiScript( 'api' ),
|
||||
'data': {
|
||||
'action': 'query',
|
||||
'meta': 'filerepoinfo',
|
||||
'format': 'json'
|
||||
},
|
||||
'dataType': 'json',
|
||||
'type': 'POST',
|
||||
// Wait up to 100 seconds before giving up
|
||||
'timeout': 100000,
|
||||
'cache': false
|
||||
} )
|
||||
.done( function ( resp ) {
|
||||
deferred.resolve( resp.query.repos );
|
||||
} )
|
||||
.fail( function () {
|
||||
deferred.resolve( [ {
|
||||
'url': mw.util.wikiScript( 'api' ),
|
||||
'local': true }
|
||||
] );
|
||||
} );
|
||||
} else {
|
||||
// There was no need to ask for the resources again
|
||||
// return false so we can skip setting the sources
|
||||
deferred.resolve( false );
|
||||
}
|
||||
|
||||
return deferred.promise();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ ve.ui.MWMediaSearchWidget = function VeUiMWMediaSearchWidget( config ) {
|
|||
OO.ui.SearchWidget.call( this, config );
|
||||
|
||||
// Properties
|
||||
this.sources = ve.copy( ve.init.platform.getMediaSources() );
|
||||
this.sources = {};
|
||||
this.size = config.size || 150;
|
||||
this.queryTimeout = null;
|
||||
this.titles = {};
|
||||
|
@ -39,7 +39,6 @@ ve.ui.MWMediaSearchWidget = function VeUiMWMediaSearchWidget( config ) {
|
|||
|
||||
// Initialization
|
||||
this.$element.addClass( 've-ui-mwMediaSearchWidget' );
|
||||
this.queryMediaSources();
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -48,6 +47,14 @@ OO.inheritClass( ve.ui.MWMediaSearchWidget, OO.ui.SearchWidget );
|
|||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Set the fileRepo sources for the media search
|
||||
* @param {Object} sources The sources object
|
||||
*/
|
||||
ve.ui.MWMediaSearchWidget.prototype.setSources = function ( sources ) {
|
||||
this.sources = sources;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle select widget select events.
|
||||
*
|
||||
|
@ -89,7 +96,7 @@ ve.ui.MWMediaSearchWidget.prototype.onResultsScroll = function () {
|
|||
* @method
|
||||
*/
|
||||
ve.ui.MWMediaSearchWidget.prototype.queryMediaSources = function () {
|
||||
var i, len, source,
|
||||
var i, len, source, url,
|
||||
value = this.query.getValue();
|
||||
|
||||
if ( value === '' ) {
|
||||
|
@ -98,39 +105,50 @@ ve.ui.MWMediaSearchWidget.prototype.queryMediaSources = function () {
|
|||
|
||||
for ( i = 0, len = this.sources.length; i < len; i++ ) {
|
||||
source = this.sources[i];
|
||||
if ( source.request ) {
|
||||
source.request.abort();
|
||||
// If we don't have either 'apiurl' or 'scriptDirUrl'
|
||||
// the source is invalid, and we will skip it
|
||||
if ( source.apiurl || source.scriptDirUrl ) {
|
||||
if ( source.request ) {
|
||||
source.request.abort();
|
||||
}
|
||||
if ( !source.gsroffset ) {
|
||||
source.gsroffset = 0;
|
||||
}
|
||||
if ( source.local ) {
|
||||
url = mw.util.wikiScript( 'api' );
|
||||
} else {
|
||||
// If 'apiurl' is set, use that. Otherwise, build the url
|
||||
// from scriptDirUrl and /api.php suffix
|
||||
url = source.apiurl || ( source.scriptDirUrl + '/api.php' );
|
||||
}
|
||||
this.query.pushPending();
|
||||
source.request = $.ajax( {
|
||||
'url': url,
|
||||
'data': {
|
||||
'format': 'json',
|
||||
'action': 'query',
|
||||
'generator': 'search',
|
||||
'gsrsearch': value,
|
||||
'gsrnamespace': 6,
|
||||
'gsrlimit': 15,
|
||||
'gsroffset': source.gsroffset,
|
||||
'prop': 'imageinfo',
|
||||
'iiprop': 'dimensions|url',
|
||||
'iiurlheight': this.size
|
||||
},
|
||||
// This request won't be cached since the JSON-P callback is unique. However make sure
|
||||
// to allow jQuery to cache otherwise so it won't e.g. add "&_=(random)" which will
|
||||
// trigger a MediaWiki API error for invalid parameter "_".
|
||||
'cache': true,
|
||||
// TODO: Only use JSON-P for cross-domain.
|
||||
// jQuery has this logic built-in (if url is not same-origin ..)
|
||||
// but isn't working for some reason.
|
||||
'dataType': 'jsonp'
|
||||
} )
|
||||
.done( ve.bind( this.onMediaQueryDone, this, source ) )
|
||||
.always( ve.bind( this.onMediaQueryAlways, this, source ) );
|
||||
source.value = value;
|
||||
}
|
||||
if ( !source.gsroffset ) {
|
||||
source.gsroffset = 0;
|
||||
}
|
||||
this.query.pushPending();
|
||||
source.request = $.ajax( {
|
||||
'url': source.url,
|
||||
'data': {
|
||||
'format': 'json',
|
||||
'action': 'query',
|
||||
'generator': 'search',
|
||||
'gsrsearch': value,
|
||||
'gsrnamespace': 6,
|
||||
'gsrlimit': 15,
|
||||
'gsroffset': source.gsroffset,
|
||||
'prop': 'imageinfo',
|
||||
'iiprop': 'dimensions|url',
|
||||
'iiurlheight': this.size
|
||||
},
|
||||
// This request won't be cached since the JSON-P callback is unique. However make sure
|
||||
// to allow jQuery to cache otherwise so it won't e.g. add "&_=(random)" which will
|
||||
// trigger a MediaWiki API error for invalid parameter "_".
|
||||
'cache': true,
|
||||
// TODO: Only use JSON-P for cross-domain.
|
||||
// jQuery has this logic built-in (if url is not same-origin ..)
|
||||
// but isn't working for some reason.
|
||||
'dataType': 'jsonp'
|
||||
} )
|
||||
.done( ve.bind( this.onMediaQueryDone, this, source ) )
|
||||
.always( ve.bind( this.onMediaQueryAlways, this, source ) );
|
||||
source.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue