diff --git a/MultimediaViewer.php b/MultimediaViewer.php index f67b30dca..f770db06f 100644 --- a/MultimediaViewer.php +++ b/MultimediaViewer.php @@ -740,6 +740,9 @@ $wgResourceModules += array( 'messages' => array( 'multimediaviewer-file-page', 'multimediaviewer-desc-nil', + + // messages that are gender-dependent (we need to check if they really depend on the gender): + 'multimediaviewer-userpage-link', ), ), diff --git a/resources/mmv/mmv.js b/resources/mmv/mmv.js index 7697265d0..ed64043e3 100755 --- a/resources/mmv/mmv.js +++ b/resources/mmv/mmv.js @@ -67,8 +67,10 @@ * @property {mw.mmv.provider.UserInfo} * @private */ - this.userInfoProvider = new mw.mmv.provider.UserInfo( new mw.mmv.Api( 'userinfo' ), - { maxage: apiCacheMaxAge } ); + this.userInfoProvider = new mw.mmv.provider.UserInfo( new mw.mmv.Api( 'userinfo' ), { + useApi: this.needGender(), + maxage: apiCacheMaxAge + } ); /** * @property {mw.mmv.provider.ImageUsage} @@ -82,7 +84,7 @@ * @private */ this.globalUsageProvider = new mw.mmv.provider.GlobalUsage( new mw.mmv.Api( 'globalusage' ), { - doNotUseApi: !mw.config.get( 'wgMultimediaViewer' ).globalUsageAvailable, + useApi: mw.config.get( 'wgMultimediaViewer' ).globalUsageAvailable, maxage: apiCacheMaxAge } ); // replace with this one to test global usage on a local wiki without going through all the @@ -112,6 +114,22 @@ MMVP = MultimediaViewer.prototype; + /** + * Check if we need to fetch gender information. This relies on the fact that + * multimediaviewer-userpage-link is the only message which takes a gender parameter. + * @return {boolean} + * FIXME there has to be a better way than this + */ + MMVP.needGender = function () { + var male, female, unknown; + + male = mw.message( 'multimediaviewer-userpage-link', '_', 'male' ).text(); + female = mw.message( 'multimediaviewer-userpage-link', '_', 'female' ).text(); + unknown = mw.message( 'multimediaviewer-userpage-link', '_', 'unknown' ).text(); + + return male !== female || male !== unknown || female !== unknown; + }; + /** * Initialize the lightbox interface given an array of thumbnail * objects. diff --git a/resources/mmv/provider/mmv.provider.GlobalUsage.js b/resources/mmv/provider/mmv.provider.GlobalUsage.js index 07a03f762..bbd356634 100644 --- a/resources/mmv/provider/mmv.provider.GlobalUsage.js +++ b/resources/mmv/provider/mmv.provider.GlobalUsage.js @@ -30,7 +30,7 @@ * @cfg {number} [apiLimit=100] number of entries to get from the API. If there are * more pages than this, we won't have an accurate count. * (Also, influences query performance.) - * @cfg {boolean} [doNotUseApi=false] If true, always returns an empty result immediately, + * @cfg {boolean} [useApi=true] If false, always returns an empty result immediately, * without doing an actual API call. Used when the GlobalUsage extension (and thus the * API) is not available. * @cfg {number} [dataLimit=10] number of entries to actually put into the model. @@ -39,7 +39,7 @@ */ function GlobalUsage( api, options ) { options = $.extend( { - doNotUseApi: false, + useApi: true, apiLimit: 100, dataLimit: 10 }, options ); @@ -57,7 +57,7 @@ var provider = this, fileUsage; - if ( this.options.doNotUseApi ) { + if ( !this.options.useApi ) { fileUsage = new mw.mmv.model.FileUsage( file, mw.mmv.model.FileUsage.Scope.GLOBAL, [], 0, false ); fileUsage.fake = true; diff --git a/resources/mmv/provider/mmv.provider.UserInfo.js b/resources/mmv/provider/mmv.provider.UserInfo.js index e4b17ff30..b64d7b429 100644 --- a/resources/mmv/provider/mmv.provider.UserInfo.js +++ b/resources/mmv/provider/mmv.provider.UserInfo.js @@ -15,7 +15,7 @@ * along with MultimediaViewer. If not, see . */ -( function ( mw, oo ) { +( function ( mw, $, oo ) { /** * Gets user information (currently just the gender). @@ -25,10 +25,14 @@ * @constructor * @param {mw.Api} api * @param {Object} [options] + * @cfg {boolean} [useApi=true] If false, always returns an empty result immediately, + * without doing an actual API call. Used when the current language does not have genders. * @cfg {number} [maxage] cache expiration time, in seconds * Will be used for both client-side cache (maxage) and reverse proxies (s-maxage) */ function UserInfo( api, options ) { + options = $.extend( { useApi: true }, options ); + mw.mmv.provider.Api.call( this, api, options ); } oo.inheritClass( UserInfo, mw.mmv.provider.Api ); @@ -40,10 +44,22 @@ * @return {jQuery.Promise.} user */ UserInfo.prototype.get = function( username, repoInfo ) { - var provider = this, + var user, + provider = this, ajaxOptions = {}, cacheKey = username; + if ( !this.options.useApi ) { + // Create a user object with unknown gender without doing an API request. + // This is used when the language does not use genders, so it would be a waste of time. + // (This might maybe result in incorrect text if the message does not have a translation + // and the fallback language does have genders, but that's an extremely rare edge case + // we can just ignore.) + user = new mw.mmv.model.User( username, mw.mmv.model.User.Gender.UNKNOWN ); + user.fake = true; + return $.Deferred().resolve( user ); + } + // For local/shared db images the user should be visible via a local API request, // maybe. (In practice we have Wikimedia users who haven't completed the SUL // merge process yet, and other sites might even use a shared DB for images @@ -75,4 +91,4 @@ }; mw.mmv.provider.UserInfo = UserInfo; -}( mediaWiki, OO ) ); +}( mediaWiki, jQuery, OO ) ); diff --git a/tests/qunit/mmv/provider/mmv.provider.GlobalUsage.test.js b/tests/qunit/mmv/provider/mmv.provider.GlobalUsage.test.js index 558e04090..23f42a711 100644 --- a/tests/qunit/mmv/provider/mmv.provider.GlobalUsage.test.js +++ b/tests/qunit/mmv/provider/mmv.provider.GlobalUsage.test.js @@ -155,15 +155,16 @@ } ); } ); - QUnit.asyncTest( 'GlobalUsage doNotUseApi test', 2, function ( assert ) { - var api = {}, - options = { doNotUseApi: true }, + QUnit.asyncTest( 'GlobalUsage useApi test', 3, function ( assert ) { + var api = { get: this.sandbox.stub().throws( 'API was invoked' ) }, + options = { useApi: false }, file = new mw.Title( 'File:Stuff.jpg' ), globalUsageProvider = new mw.mmv.provider.GlobalUsage( api, options ); globalUsageProvider.get( file ).done( function( fileUsage ) { assert.strictEqual( fileUsage.pages.length, 0, 'Does not return any pages' ); assert.ok( fileUsage.fake ); + assert.ok( !api.get.called, 'API was not called' ); QUnit.start(); } ); } ); diff --git a/tests/qunit/mmv/provider/mmv.provider.UserInfo.test.js b/tests/qunit/mmv/provider/mmv.provider.UserInfo.test.js index 07362c558..0933bb901 100644 --- a/tests/qunit/mmv/provider/mmv.provider.UserInfo.test.js +++ b/tests/qunit/mmv/provider/mmv.provider.UserInfo.test.js @@ -148,4 +148,19 @@ QUnit.start(); } ); } ); + + QUnit.asyncTest( 'UserInfo fake test', 4, function ( assert ) { + var api = { get: this.sandbox.stub().throws( 'API was invoked' ) }, + username = 'Catrope', + repoInfo = {}, + userInfoProvider = new mw.mmv.provider.UserInfo( api, { useApi: false } ); + + userInfoProvider.get( username, repoInfo ).done( function( user ) { + assert.strictEqual( user.username, 'Catrope', 'username is set correctly' ); + assert.strictEqual( user.gender, mw.mmv.model.User.Gender.UNKNOWN, 'gender is set to unknown' ); + assert.ok( user.fake, 'fake flag is set' ); + assert.ok( !api.get.called, 'API was not called' ); + QUnit.start(); + } ); + } ); }( mediaWiki, jQuery ) );